1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "xfa/fxfa/cxfa_textprovider.h" 8 9 #include <algorithm> 10 #include <memory> 11 #include <vector> 12 13 #include "core/fxcrt/xml/cfx_xmlelement.h" 14 #include "core/fxcrt/xml/cfx_xmlnode.h" 15 #include "fxjs/cfxjse_engine.h" 16 #include "fxjs/cfxjse_value.h" 17 #include "fxjs/xfa/cjx_object.h" 18 #include "third_party/base/ptr_util.h" 19 #include "third_party/base/stl_util.h" 20 #include "xfa/fde/cfde_textout.h" 21 #include "xfa/fxfa/cxfa_eventparam.h" 22 #include "xfa/fxfa/cxfa_ffapp.h" 23 #include "xfa/fxfa/cxfa_ffcheckbutton.h" 24 #include "xfa/fxfa/cxfa_ffdoc.h" 25 #include "xfa/fxfa/cxfa_ffdocview.h" 26 #include "xfa/fxfa/cxfa_fffield.h" 27 #include "xfa/fxfa/cxfa_ffpageview.h" 28 #include "xfa/fxfa/cxfa_ffwidget.h" 29 #include "xfa/fxfa/cxfa_fontmgr.h" 30 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h" 31 #include "xfa/fxfa/parser/cxfa_caption.h" 32 #include "xfa/fxfa/parser/cxfa_font.h" 33 #include "xfa/fxfa/parser/cxfa_items.h" 34 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h" 35 #include "xfa/fxfa/parser/cxfa_localevalue.h" 36 #include "xfa/fxfa/parser/cxfa_node.h" 37 #include "xfa/fxfa/parser/cxfa_para.h" 38 #include "xfa/fxfa/parser/cxfa_value.h" 39 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" 40 #include "xfa/fxfa/parser/xfa_utils.h" 41 42 CXFA_Node* CXFA_TextProvider::GetTextNode(bool& bRichText) { 43 bRichText = false; 44 45 if (m_eType == XFA_TEXTPROVIDERTYPE_Text) { 46 CXFA_Node* pElementNode = m_pWidgetAcc->GetNode(); 47 CXFA_Value* pValueNode = 48 pElementNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false); 49 if (!pValueNode) 50 return nullptr; 51 52 CXFA_Node* pChildNode = pValueNode->GetFirstChild(); 53 if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) { 54 Optional<WideString> contentType = pChildNode->JSObject()->TryAttribute( 55 XFA_Attribute::ContentType, false); 56 if (contentType && *contentType == L"text/html") 57 bRichText = true; 58 } 59 return pChildNode; 60 } 61 62 if (m_eType == XFA_TEXTPROVIDERTYPE_Datasets) { 63 CXFA_Node* pBind = m_pWidgetAcc->GetNode()->GetBindData(); 64 CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode(); 65 ASSERT(pXMLNode); 66 for (CFX_XMLNode* pXMLChild = 67 pXMLNode->GetNodeItem(CFX_XMLNode::FirstChild); 68 pXMLChild; 69 pXMLChild = pXMLChild->GetNodeItem(CFX_XMLNode::NextSibling)) { 70 if (pXMLChild->GetType() == FX_XMLNODE_Element) { 71 CFX_XMLElement* pElement = static_cast<CFX_XMLElement*>(pXMLChild); 72 if (XFA_RecognizeRichText(pElement)) 73 bRichText = true; 74 } 75 } 76 return pBind; 77 } 78 79 if (m_eType == XFA_TEXTPROVIDERTYPE_Caption) { 80 CXFA_Caption* pCaptionNode = 81 m_pWidgetAcc->GetNode()->GetChild<CXFA_Caption>(0, XFA_Element::Caption, 82 false); 83 if (!pCaptionNode) 84 return nullptr; 85 86 CXFA_Value* pValueNode = 87 pCaptionNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false); 88 if (!pValueNode) 89 return nullptr; 90 91 CXFA_Node* pChildNode = pValueNode->GetFirstChild(); 92 if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) { 93 Optional<WideString> contentType = pChildNode->JSObject()->TryAttribute( 94 XFA_Attribute::ContentType, false); 95 if (contentType && *contentType == L"text/html") 96 bRichText = true; 97 } 98 return pChildNode; 99 } 100 101 CXFA_Items* pItemNode = m_pWidgetAcc->GetNode()->GetChild<CXFA_Items>( 102 0, XFA_Element::Items, false); 103 if (!pItemNode) 104 return nullptr; 105 106 CXFA_Node* pNode = pItemNode->GetFirstChild(); 107 while (pNode) { 108 WideString wsName = pNode->JSObject()->GetCData(XFA_Attribute::Name); 109 if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover && wsName == L"rollover") 110 return pNode; 111 if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == L"down") 112 return pNode; 113 114 pNode = pNode->GetNextSibling(); 115 } 116 return nullptr; 117 } 118 119 CXFA_Para* CXFA_TextProvider::GetParaIfExists() { 120 if (m_eType == XFA_TEXTPROVIDERTYPE_Text) 121 return m_pWidgetAcc->GetNode()->GetParaIfExists(); 122 123 CXFA_Caption* pNode = m_pWidgetAcc->GetNode()->GetChild<CXFA_Caption>( 124 0, XFA_Element::Caption, false); 125 return pNode->GetChild<CXFA_Para>(0, XFA_Element::Para, false); 126 } 127 128 CXFA_Font* CXFA_TextProvider::GetFontIfExists() { 129 if (m_eType == XFA_TEXTPROVIDERTYPE_Text) 130 return m_pWidgetAcc->GetNode()->GetFontIfExists(); 131 132 CXFA_Caption* pNode = m_pWidgetAcc->GetNode()->GetChild<CXFA_Caption>( 133 0, XFA_Element::Caption, false); 134 CXFA_Font* font = pNode->GetChild<CXFA_Font>(0, XFA_Element::Font, false); 135 return font ? font : m_pWidgetAcc->GetNode()->GetFontIfExists(); 136 } 137 138 bool CXFA_TextProvider::IsCheckButtonAndAutoWidth() { 139 XFA_Element eType = m_pWidgetAcc->GetUIType(); 140 if (eType != XFA_Element::CheckButton) 141 return false; 142 return !m_pWidgetAcc->GetNode()->TryWidth(); 143 } 144 145 bool CXFA_TextProvider::GetEmbbedObj(bool bURI, 146 bool bRaw, 147 const WideString& wsAttr, 148 WideString& wsValue) { 149 if (m_eType != XFA_TEXTPROVIDERTYPE_Text) 150 return false; 151 152 if (!bURI) 153 return false; 154 155 CXFA_Node* pWidgetNode = m_pWidgetAcc->GetNode(); 156 CXFA_Node* pParent = pWidgetNode->GetParent(); 157 CXFA_Document* pDocument = pWidgetNode->GetDocument(); 158 CXFA_Node* pIDNode = nullptr; 159 CXFA_WidgetAcc* pEmbAcc = nullptr; 160 if (pParent) 161 pIDNode = pDocument->GetNodeByID(pParent, wsAttr.AsStringView()); 162 163 if (!pIDNode) { 164 pIDNode = pDocument->GetNodeByID( 165 ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Form)), 166 wsAttr.AsStringView()); 167 } 168 if (pIDNode) 169 pEmbAcc = pIDNode->GetWidgetAcc(); 170 171 if (!pEmbAcc) 172 return false; 173 174 wsValue = pEmbAcc->GetValue(XFA_VALUEPICTURE_Display); 175 return true; 176 } 177