• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetTextNode(bool & bRichText)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 
GetParaIfExists()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 
GetFontIfExists()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 
IsCheckButtonAndAutoWidth()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 
GetEmbbedObj(bool bURI,bool bRaw,const WideString & wsAttr,WideString & wsValue)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