1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2017 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cjx_node.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
10*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
11*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
12*3ac0a46fSAndroid Build Coastguard Worker
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/cfx_memorystream.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/cfx_read_only_string_stream.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_codepage.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/xml/cfx_xmldocument.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/xml/cfx_xmlelement.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/xml/cfx_xmlparser.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/fxv8.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/js_resources.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_engine.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-object.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_eventparam.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_ffdoc.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_ffnotify.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_document.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_document_builder.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_node.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/xfa_basic_data.h"
30*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/xfa_utils.h"
31*3ac0a46fSAndroid Build Coastguard Worker
32*3ac0a46fSAndroid Build Coastguard Worker namespace {
33*3ac0a46fSAndroid Build Coastguard Worker
34*3ac0a46fSAndroid Build Coastguard Worker enum class EventAppliesTo : uint8_t {
35*3ac0a46fSAndroid Build Coastguard Worker kNone = 0,
36*3ac0a46fSAndroid Build Coastguard Worker kAll = 1,
37*3ac0a46fSAndroid Build Coastguard Worker kAllNonRecursive = 2,
38*3ac0a46fSAndroid Build Coastguard Worker kSubform = 3,
39*3ac0a46fSAndroid Build Coastguard Worker kFieldOrExclusion = 4,
40*3ac0a46fSAndroid Build Coastguard Worker kField = 5,
41*3ac0a46fSAndroid Build Coastguard Worker kSignature = 6,
42*3ac0a46fSAndroid Build Coastguard Worker kChoiceList = 7
43*3ac0a46fSAndroid Build Coastguard Worker };
44*3ac0a46fSAndroid Build Coastguard Worker
45*3ac0a46fSAndroid Build Coastguard Worker struct ExecEventParaInfo {
46*3ac0a46fSAndroid Build Coastguard Worker uint32_t m_uHash; // hashed as wide string.
47*3ac0a46fSAndroid Build Coastguard Worker XFA_EVENTTYPE m_eventType;
48*3ac0a46fSAndroid Build Coastguard Worker EventAppliesTo m_validFlags;
49*3ac0a46fSAndroid Build Coastguard Worker };
50*3ac0a46fSAndroid Build Coastguard Worker
51*3ac0a46fSAndroid Build Coastguard Worker #undef PARA
52*3ac0a46fSAndroid Build Coastguard Worker #define PARA(a, b, c, d) a, c, EventAppliesTo::d
53*3ac0a46fSAndroid Build Coastguard Worker const ExecEventParaInfo kExecEventParaInfoTable[] = {
54*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x109d7ce7, "mouseEnter", XFA_EVENT_MouseEnter, kField)},
55*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x1bfc72d9, "preOpen", XFA_EVENT_PreOpen, kChoiceList)},
56*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x2196a452, "initialize", XFA_EVENT_Initialize, kAll)},
57*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x27410f03, "mouseExit", XFA_EVENT_MouseExit, kField)},
58*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x36f1c6d8, "preSign", XFA_EVENT_PreSign, kSignature)},
59*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x4731d6ba, "exit", XFA_EVENT_Exit, kAllNonRecursive)},
60*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x7233018a, "validate", XFA_EVENT_Validate, kAll)},
61*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x8808385e, "indexChange", XFA_EVENT_IndexChange, kSubform)},
62*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x891f4606, "change", XFA_EVENT_Change, kFieldOrExclusion)},
63*3ac0a46fSAndroid Build Coastguard Worker {PARA(0x9f693b21, "mouseDown", XFA_EVENT_MouseDown, kField)},
64*3ac0a46fSAndroid Build Coastguard Worker {PARA(0xcdce56b3, "full", XFA_EVENT_Full, kFieldOrExclusion)},
65*3ac0a46fSAndroid Build Coastguard Worker {PARA(0xd576d08e, "mouseUp", XFA_EVENT_MouseUp, kField)},
66*3ac0a46fSAndroid Build Coastguard Worker {PARA(0xd95657a6, "click", XFA_EVENT_Click, kFieldOrExclusion)},
67*3ac0a46fSAndroid Build Coastguard Worker {PARA(0xdbfbe02e, "calculate", XFA_EVENT_Calculate, kAll)},
68*3ac0a46fSAndroid Build Coastguard Worker {PARA(0xe25fa7b8, "postOpen", XFA_EVENT_PostOpen, kChoiceList)},
69*3ac0a46fSAndroid Build Coastguard Worker {PARA(0xe28dce7e, "enter", XFA_EVENT_Enter, kAllNonRecursive)},
70*3ac0a46fSAndroid Build Coastguard Worker {PARA(0xfd54fbb7, "postSign", XFA_EVENT_PostSign, kSignature)},
71*3ac0a46fSAndroid Build Coastguard Worker };
72*3ac0a46fSAndroid Build Coastguard Worker #undef PARA
73*3ac0a46fSAndroid Build Coastguard Worker
GetExecEventParaInfoByName(WideStringView wsEventName)74*3ac0a46fSAndroid Build Coastguard Worker const ExecEventParaInfo* GetExecEventParaInfoByName(
75*3ac0a46fSAndroid Build Coastguard Worker WideStringView wsEventName) {
76*3ac0a46fSAndroid Build Coastguard Worker if (wsEventName.IsEmpty())
77*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
78*3ac0a46fSAndroid Build Coastguard Worker
79*3ac0a46fSAndroid Build Coastguard Worker uint32_t uHash = FX_HashCode_GetW(wsEventName);
80*3ac0a46fSAndroid Build Coastguard Worker auto* result = std::lower_bound(
81*3ac0a46fSAndroid Build Coastguard Worker std::begin(kExecEventParaInfoTable), std::end(kExecEventParaInfoTable),
82*3ac0a46fSAndroid Build Coastguard Worker uHash, [](const ExecEventParaInfo& iter, const uint16_t& hash) {
83*3ac0a46fSAndroid Build Coastguard Worker return iter.m_uHash < hash;
84*3ac0a46fSAndroid Build Coastguard Worker });
85*3ac0a46fSAndroid Build Coastguard Worker if (result != std::end(kExecEventParaInfoTable) && result->m_uHash == uHash)
86*3ac0a46fSAndroid Build Coastguard Worker return result;
87*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
88*3ac0a46fSAndroid Build Coastguard Worker }
89*3ac0a46fSAndroid Build Coastguard Worker
90*3ac0a46fSAndroid Build Coastguard Worker } // namespace
91*3ac0a46fSAndroid Build Coastguard Worker
92*3ac0a46fSAndroid Build Coastguard Worker const CJX_MethodSpec CJX_Node::MethodSpecs[] = {
93*3ac0a46fSAndroid Build Coastguard Worker {"applyXSL", applyXSL_static},
94*3ac0a46fSAndroid Build Coastguard Worker {"assignNode", assignNode_static},
95*3ac0a46fSAndroid Build Coastguard Worker {"clone", clone_static},
96*3ac0a46fSAndroid Build Coastguard Worker {"getAttribute", getAttribute_static},
97*3ac0a46fSAndroid Build Coastguard Worker {"getElement", getElement_static},
98*3ac0a46fSAndroid Build Coastguard Worker {"isPropertySpecified", isPropertySpecified_static},
99*3ac0a46fSAndroid Build Coastguard Worker {"loadXML", loadXML_static},
100*3ac0a46fSAndroid Build Coastguard Worker {"saveFilteredXML", saveFilteredXML_static},
101*3ac0a46fSAndroid Build Coastguard Worker {"saveXML", saveXML_static},
102*3ac0a46fSAndroid Build Coastguard Worker {"setAttribute", setAttribute_static},
103*3ac0a46fSAndroid Build Coastguard Worker {"setElement", setElement_static}};
104*3ac0a46fSAndroid Build Coastguard Worker
CJX_Node(CXFA_Node * node)105*3ac0a46fSAndroid Build Coastguard Worker CJX_Node::CJX_Node(CXFA_Node* node) : CJX_Tree(node) {
106*3ac0a46fSAndroid Build Coastguard Worker DefineMethods(MethodSpecs);
107*3ac0a46fSAndroid Build Coastguard Worker }
108*3ac0a46fSAndroid Build Coastguard Worker
109*3ac0a46fSAndroid Build Coastguard Worker CJX_Node::~CJX_Node() = default;
110*3ac0a46fSAndroid Build Coastguard Worker
DynamicTypeIs(TypeTag eType) const111*3ac0a46fSAndroid Build Coastguard Worker bool CJX_Node::DynamicTypeIs(TypeTag eType) const {
112*3ac0a46fSAndroid Build Coastguard Worker return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
113*3ac0a46fSAndroid Build Coastguard Worker }
114*3ac0a46fSAndroid Build Coastguard Worker
applyXSL(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)115*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::applyXSL(CFXJSE_Engine* runtime,
116*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
117*3ac0a46fSAndroid Build Coastguard Worker if (params.size() != 1)
118*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
119*3ac0a46fSAndroid Build Coastguard Worker
120*3ac0a46fSAndroid Build Coastguard Worker // TODO(weili): check whether we need to implement this, pdfium:501.
121*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
122*3ac0a46fSAndroid Build Coastguard Worker }
123*3ac0a46fSAndroid Build Coastguard Worker
assignNode(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)124*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::assignNode(
125*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine* runtime,
126*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
127*3ac0a46fSAndroid Build Coastguard Worker if (params.empty() || params.size() > 3)
128*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
129*3ac0a46fSAndroid Build Coastguard Worker
130*3ac0a46fSAndroid Build Coastguard Worker // TODO(weili): check whether we need to implement this, pdfium:501.
131*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
132*3ac0a46fSAndroid Build Coastguard Worker }
133*3ac0a46fSAndroid Build Coastguard Worker
clone(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)134*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::clone(CFXJSE_Engine* runtime,
135*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
136*3ac0a46fSAndroid Build Coastguard Worker if (params.size() != 1)
137*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
138*3ac0a46fSAndroid Build Coastguard Worker
139*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pCloneNode = GetXFANode()->Clone(runtime->ToBoolean(params[0]));
140*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->GetOrCreateJSBindingFromMap(pCloneNode));
141*3ac0a46fSAndroid Build Coastguard Worker }
142*3ac0a46fSAndroid Build Coastguard Worker
getAttribute(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)143*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::getAttribute(
144*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine* runtime,
145*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
146*3ac0a46fSAndroid Build Coastguard Worker if (params.size() != 1)
147*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
148*3ac0a46fSAndroid Build Coastguard Worker
149*3ac0a46fSAndroid Build Coastguard Worker WideString expression = runtime->ToWideString(params[0]);
150*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->NewString(
151*3ac0a46fSAndroid Build Coastguard Worker GetAttributeByString(expression.AsStringView()).ToUTF8().AsStringView()));
152*3ac0a46fSAndroid Build Coastguard Worker }
153*3ac0a46fSAndroid Build Coastguard Worker
getElement(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)154*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::getElement(
155*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine* runtime,
156*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
157*3ac0a46fSAndroid Build Coastguard Worker if (params.empty() || params.size() > 2)
158*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
159*3ac0a46fSAndroid Build Coastguard Worker
160*3ac0a46fSAndroid Build Coastguard Worker WideString expression = runtime->ToWideString(params[0]);
161*3ac0a46fSAndroid Build Coastguard Worker int32_t iValue = params.size() >= 2 ? runtime->ToInt32(params[1]) : 0;
162*3ac0a46fSAndroid Build Coastguard Worker XFA_Element eElement = XFA_GetElementByName(expression.AsStringView());
163*3ac0a46fSAndroid Build Coastguard Worker if (eElement == XFA_Element::Unknown)
164*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->NewNull());
165*3ac0a46fSAndroid Build Coastguard Worker
166*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pNode = GetOrCreateProperty<CXFA_Node>(iValue, eElement);
167*3ac0a46fSAndroid Build Coastguard Worker if (!pNode)
168*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->NewNull());
169*3ac0a46fSAndroid Build Coastguard Worker
170*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->GetOrCreateJSBindingFromMap(pNode));
171*3ac0a46fSAndroid Build Coastguard Worker }
172*3ac0a46fSAndroid Build Coastguard Worker
isPropertySpecified(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)173*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::isPropertySpecified(
174*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine* runtime,
175*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
176*3ac0a46fSAndroid Build Coastguard Worker if (params.empty() || params.size() > 3)
177*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
178*3ac0a46fSAndroid Build Coastguard Worker
179*3ac0a46fSAndroid Build Coastguard Worker WideString expression = runtime->ToWideString(params[0]);
180*3ac0a46fSAndroid Build Coastguard Worker absl::optional<XFA_ATTRIBUTEINFO> attr =
181*3ac0a46fSAndroid Build Coastguard Worker XFA_GetAttributeByName(expression.AsStringView());
182*3ac0a46fSAndroid Build Coastguard Worker if (attr.has_value() && HasAttribute(attr.value().attribute))
183*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->NewBoolean(true));
184*3ac0a46fSAndroid Build Coastguard Worker
185*3ac0a46fSAndroid Build Coastguard Worker XFA_Element eType = XFA_GetElementByName(expression.AsStringView());
186*3ac0a46fSAndroid Build Coastguard Worker if (eType == XFA_Element::Unknown)
187*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->NewBoolean(false));
188*3ac0a46fSAndroid Build Coastguard Worker
189*3ac0a46fSAndroid Build Coastguard Worker bool bParent = params.size() < 2 || runtime->ToBoolean(params[1]);
190*3ac0a46fSAndroid Build Coastguard Worker int32_t iIndex = params.size() == 3 ? runtime->ToInt32(params[2]) : 0;
191*3ac0a46fSAndroid Build Coastguard Worker bool bHas = !!GetOrCreateProperty<CXFA_Node>(iIndex, eType);
192*3ac0a46fSAndroid Build Coastguard Worker if (!bHas && bParent && GetXFANode()->GetParent()) {
193*3ac0a46fSAndroid Build Coastguard Worker // Also check on the parent.
194*3ac0a46fSAndroid Build Coastguard Worker auto* jsnode = GetXFANode()->GetParent()->JSObject();
195*3ac0a46fSAndroid Build Coastguard Worker bHas = jsnode->HasAttribute(attr.value().attribute) ||
196*3ac0a46fSAndroid Build Coastguard Worker !!jsnode->GetOrCreateProperty<CXFA_Node>(iIndex, eType);
197*3ac0a46fSAndroid Build Coastguard Worker }
198*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->NewBoolean(bHas));
199*3ac0a46fSAndroid Build Coastguard Worker }
200*3ac0a46fSAndroid Build Coastguard Worker
loadXML(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)201*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::loadXML(CFXJSE_Engine* runtime,
202*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
203*3ac0a46fSAndroid Build Coastguard Worker if (params.empty() || params.size() > 3)
204*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
205*3ac0a46fSAndroid Build Coastguard Worker
206*3ac0a46fSAndroid Build Coastguard Worker ByteString expression = runtime->ToByteString(params[0]);
207*3ac0a46fSAndroid Build Coastguard Worker if (expression.IsEmpty())
208*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
209*3ac0a46fSAndroid Build Coastguard Worker
210*3ac0a46fSAndroid Build Coastguard Worker bool bIgnoreRoot = true;
211*3ac0a46fSAndroid Build Coastguard Worker if (params.size() >= 2)
212*3ac0a46fSAndroid Build Coastguard Worker bIgnoreRoot = runtime->ToBoolean(params[1]);
213*3ac0a46fSAndroid Build Coastguard Worker
214*3ac0a46fSAndroid Build Coastguard Worker bool bOverwrite = false;
215*3ac0a46fSAndroid Build Coastguard Worker if (params.size() >= 3)
216*3ac0a46fSAndroid Build Coastguard Worker bOverwrite = runtime->ToBoolean(params[2]);
217*3ac0a46fSAndroid Build Coastguard Worker
218*3ac0a46fSAndroid Build Coastguard Worker auto stream =
219*3ac0a46fSAndroid Build Coastguard Worker pdfium::MakeRetain<CFX_ReadOnlyStringStream>(std::move(expression));
220*3ac0a46fSAndroid Build Coastguard Worker
221*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLParser parser(stream);
222*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFX_XMLDocument> xml_doc = parser.Parse();
223*3ac0a46fSAndroid Build Coastguard Worker CXFA_DocumentBuilder builder(GetDocument());
224*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* pXMLNode = builder.Build(xml_doc.get());
225*3ac0a46fSAndroid Build Coastguard Worker if (!pXMLNode)
226*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
227*3ac0a46fSAndroid Build Coastguard Worker
228*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLDocument* top_xml_doc =
229*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->GetDocument()->GetNotify()->GetFFDoc()->GetXMLDocument();
230*3ac0a46fSAndroid Build Coastguard Worker top_xml_doc->AppendNodesFrom(xml_doc.get());
231*3ac0a46fSAndroid Build Coastguard Worker
232*3ac0a46fSAndroid Build Coastguard Worker if (bIgnoreRoot &&
233*3ac0a46fSAndroid Build Coastguard Worker (pXMLNode->GetType() != CFX_XMLNode::Type::kElement ||
234*3ac0a46fSAndroid Build Coastguard Worker XFA_RecognizeRichText(static_cast<CFX_XMLElement*>(pXMLNode)))) {
235*3ac0a46fSAndroid Build Coastguard Worker bIgnoreRoot = false;
236*3ac0a46fSAndroid Build Coastguard Worker }
237*3ac0a46fSAndroid Build Coastguard Worker
238*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pFakeRoot = GetXFANode()->Clone(false);
239*3ac0a46fSAndroid Build Coastguard Worker WideString wsContentType = GetCData(XFA_Attribute::ContentType);
240*3ac0a46fSAndroid Build Coastguard Worker if (!wsContentType.IsEmpty()) {
241*3ac0a46fSAndroid Build Coastguard Worker pFakeRoot->JSObject()->SetCData(XFA_Attribute::ContentType,
242*3ac0a46fSAndroid Build Coastguard Worker WideString(wsContentType));
243*3ac0a46fSAndroid Build Coastguard Worker }
244*3ac0a46fSAndroid Build Coastguard Worker
245*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
246*3ac0a46fSAndroid Build Coastguard Worker if (!pFakeXMLRoot) {
247*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* pThisXMLRoot = GetXFANode()->GetXMLMappingNode();
248*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* clone;
249*3ac0a46fSAndroid Build Coastguard Worker if (pThisXMLRoot) {
250*3ac0a46fSAndroid Build Coastguard Worker clone = pThisXMLRoot->Clone(top_xml_doc);
251*3ac0a46fSAndroid Build Coastguard Worker } else {
252*3ac0a46fSAndroid Build Coastguard Worker clone = top_xml_doc->CreateNode<CFX_XMLElement>(
253*3ac0a46fSAndroid Build Coastguard Worker WideString::FromASCII(GetXFANode()->GetClassName()));
254*3ac0a46fSAndroid Build Coastguard Worker }
255*3ac0a46fSAndroid Build Coastguard Worker pFakeXMLRoot = clone;
256*3ac0a46fSAndroid Build Coastguard Worker }
257*3ac0a46fSAndroid Build Coastguard Worker
258*3ac0a46fSAndroid Build Coastguard Worker if (bIgnoreRoot) {
259*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild();
260*3ac0a46fSAndroid Build Coastguard Worker while (pXMLChild) {
261*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* pXMLSibling = pXMLChild->GetNextSibling();
262*3ac0a46fSAndroid Build Coastguard Worker pXMLNode->RemoveChild(pXMLChild);
263*3ac0a46fSAndroid Build Coastguard Worker pFakeXMLRoot->AppendLastChild(pXMLChild);
264*3ac0a46fSAndroid Build Coastguard Worker pXMLChild = pXMLSibling;
265*3ac0a46fSAndroid Build Coastguard Worker }
266*3ac0a46fSAndroid Build Coastguard Worker } else {
267*3ac0a46fSAndroid Build Coastguard Worker pXMLNode->RemoveSelfIfParented();
268*3ac0a46fSAndroid Build Coastguard Worker pFakeXMLRoot->AppendLastChild(pXMLNode);
269*3ac0a46fSAndroid Build Coastguard Worker }
270*3ac0a46fSAndroid Build Coastguard Worker
271*3ac0a46fSAndroid Build Coastguard Worker builder.ConstructXFANode(pFakeRoot, pFakeXMLRoot);
272*3ac0a46fSAndroid Build Coastguard Worker pFakeRoot = builder.GetRootNode();
273*3ac0a46fSAndroid Build Coastguard Worker if (!pFakeRoot)
274*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
275*3ac0a46fSAndroid Build Coastguard Worker
276*3ac0a46fSAndroid Build Coastguard Worker if (bOverwrite) {
277*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pChild = GetXFANode()->GetFirstChild();
278*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pNewChild = pFakeRoot->GetFirstChild();
279*3ac0a46fSAndroid Build Coastguard Worker int32_t index = 0;
280*3ac0a46fSAndroid Build Coastguard Worker while (pNewChild) {
281*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pItem = pNewChild->GetNextSibling();
282*3ac0a46fSAndroid Build Coastguard Worker pFakeRoot->RemoveChildAndNotify(pNewChild, true);
283*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->InsertChildAndNotify(index++, pNewChild);
284*3ac0a46fSAndroid Build Coastguard Worker pNewChild->SetInitializedFlagAndNotify();
285*3ac0a46fSAndroid Build Coastguard Worker pNewChild = pItem;
286*3ac0a46fSAndroid Build Coastguard Worker }
287*3ac0a46fSAndroid Build Coastguard Worker
288*3ac0a46fSAndroid Build Coastguard Worker while (pChild) {
289*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pItem = pChild->GetNextSibling();
290*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->RemoveChildAndNotify(pChild, true);
291*3ac0a46fSAndroid Build Coastguard Worker pFakeRoot->InsertChildAndNotify(pChild, nullptr);
292*3ac0a46fSAndroid Build Coastguard Worker pChild = pItem;
293*3ac0a46fSAndroid Build Coastguard Worker }
294*3ac0a46fSAndroid Build Coastguard Worker
295*3ac0a46fSAndroid Build Coastguard Worker if (GetXFANode()->GetPacketType() == XFA_PacketType::Form &&
296*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->GetElementType() == XFA_Element::ExData) {
297*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* pTempXMLNode = GetXFANode()->GetXMLMappingNode();
298*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->SetXMLMappingNode(pFakeXMLRoot);
299*3ac0a46fSAndroid Build Coastguard Worker
300*3ac0a46fSAndroid Build Coastguard Worker if (pTempXMLNode && !pTempXMLNode->GetParent())
301*3ac0a46fSAndroid Build Coastguard Worker pFakeXMLRoot = pTempXMLNode;
302*3ac0a46fSAndroid Build Coastguard Worker else
303*3ac0a46fSAndroid Build Coastguard Worker pFakeXMLRoot = nullptr;
304*3ac0a46fSAndroid Build Coastguard Worker }
305*3ac0a46fSAndroid Build Coastguard Worker MoveBufferMapData(pFakeRoot, GetXFANode());
306*3ac0a46fSAndroid Build Coastguard Worker } else {
307*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pChild = pFakeRoot->GetFirstChild();
308*3ac0a46fSAndroid Build Coastguard Worker while (pChild) {
309*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pItem = pChild->GetNextSibling();
310*3ac0a46fSAndroid Build Coastguard Worker pFakeRoot->RemoveChildAndNotify(pChild, true);
311*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->InsertChildAndNotify(pChild, nullptr);
312*3ac0a46fSAndroid Build Coastguard Worker pChild->SetInitializedFlagAndNotify();
313*3ac0a46fSAndroid Build Coastguard Worker pChild = pItem;
314*3ac0a46fSAndroid Build Coastguard Worker }
315*3ac0a46fSAndroid Build Coastguard Worker }
316*3ac0a46fSAndroid Build Coastguard Worker
317*3ac0a46fSAndroid Build Coastguard Worker if (pFakeXMLRoot) {
318*3ac0a46fSAndroid Build Coastguard Worker pFakeRoot->SetXMLMappingNode(std::move(pFakeXMLRoot));
319*3ac0a46fSAndroid Build Coastguard Worker }
320*3ac0a46fSAndroid Build Coastguard Worker pFakeRoot->SetFlag(XFA_NodeFlag::kHasRemovedChildren);
321*3ac0a46fSAndroid Build Coastguard Worker
322*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
323*3ac0a46fSAndroid Build Coastguard Worker }
324*3ac0a46fSAndroid Build Coastguard Worker
saveFilteredXML(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)325*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::saveFilteredXML(
326*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine* runtime,
327*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
328*3ac0a46fSAndroid Build Coastguard Worker // TODO(weili): Check whether we need to implement this, pdfium:501.
329*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
330*3ac0a46fSAndroid Build Coastguard Worker }
331*3ac0a46fSAndroid Build Coastguard Worker
saveXML(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)332*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::saveXML(CFXJSE_Engine* runtime,
333*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
334*3ac0a46fSAndroid Build Coastguard Worker if (params.size() > 1)
335*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
336*3ac0a46fSAndroid Build Coastguard Worker
337*3ac0a46fSAndroid Build Coastguard Worker if (params.size() == 1 &&
338*3ac0a46fSAndroid Build Coastguard Worker !runtime->ToWideString(params[0]).EqualsASCII("pretty")) {
339*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kValueError);
340*3ac0a46fSAndroid Build Coastguard Worker }
341*3ac0a46fSAndroid Build Coastguard Worker
342*3ac0a46fSAndroid Build Coastguard Worker // TODO(weili): Check whether we need to save pretty print XML, pdfium:501.
343*3ac0a46fSAndroid Build Coastguard Worker
344*3ac0a46fSAndroid Build Coastguard Worker ByteString bsXMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
345*3ac0a46fSAndroid Build Coastguard Worker if (GetXFANode()->GetPacketType() != XFA_PacketType::Form &&
346*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->GetPacketType() != XFA_PacketType::Datasets) {
347*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(runtime->NewString(""));
348*3ac0a46fSAndroid Build Coastguard Worker }
349*3ac0a46fSAndroid Build Coastguard Worker
350*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLNode* pElement = nullptr;
351*3ac0a46fSAndroid Build Coastguard Worker if (GetXFANode()->GetPacketType() == XFA_PacketType::Datasets) {
352*3ac0a46fSAndroid Build Coastguard Worker pElement = GetXFANode()->GetXMLMappingNode();
353*3ac0a46fSAndroid Build Coastguard Worker if (!pElement || pElement->GetType() != CFX_XMLNode::Type::kElement) {
354*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(
355*3ac0a46fSAndroid Build Coastguard Worker runtime->NewString(bsXMLHeader.AsStringView()));
356*3ac0a46fSAndroid Build Coastguard Worker }
357*3ac0a46fSAndroid Build Coastguard Worker
358*3ac0a46fSAndroid Build Coastguard Worker XFA_DataExporter_DealWithDataGroupNode(GetXFANode());
359*3ac0a46fSAndroid Build Coastguard Worker }
360*3ac0a46fSAndroid Build Coastguard Worker
361*3ac0a46fSAndroid Build Coastguard Worker auto pMemoryStream = pdfium::MakeRetain<CFX_MemoryStream>();
362*3ac0a46fSAndroid Build Coastguard Worker pMemoryStream->WriteString(bsXMLHeader.AsStringView());
363*3ac0a46fSAndroid Build Coastguard Worker
364*3ac0a46fSAndroid Build Coastguard Worker if (GetXFANode()->GetPacketType() == XFA_PacketType::Form) {
365*3ac0a46fSAndroid Build Coastguard Worker XFA_DataExporter_RegenerateFormFile(GetXFANode(), pMemoryStream, true);
366*3ac0a46fSAndroid Build Coastguard Worker } else {
367*3ac0a46fSAndroid Build Coastguard Worker pElement->Save(pMemoryStream);
368*3ac0a46fSAndroid Build Coastguard Worker }
369*3ac0a46fSAndroid Build Coastguard Worker
370*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success(
371*3ac0a46fSAndroid Build Coastguard Worker runtime->NewString(ByteStringView(pMemoryStream->GetSpan())));
372*3ac0a46fSAndroid Build Coastguard Worker }
373*3ac0a46fSAndroid Build Coastguard Worker
setAttribute(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)374*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::setAttribute(
375*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine* runtime,
376*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
377*3ac0a46fSAndroid Build Coastguard Worker if (params.size() != 2)
378*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
379*3ac0a46fSAndroid Build Coastguard Worker
380*3ac0a46fSAndroid Build Coastguard Worker // Note: yes, arglist is spec'd absolutely backwards from what any sane
381*3ac0a46fSAndroid Build Coastguard Worker // person would do, namely value first, attribute second.
382*3ac0a46fSAndroid Build Coastguard Worker WideString attributeValue = runtime->ToWideString(params[0]);
383*3ac0a46fSAndroid Build Coastguard Worker WideString attribute = runtime->ToWideString(params[1]);
384*3ac0a46fSAndroid Build Coastguard Worker
385*3ac0a46fSAndroid Build Coastguard Worker // Pass them to our method, however, in the more usual manner.
386*3ac0a46fSAndroid Build Coastguard Worker SetAttributeByString(attribute.AsStringView(), attributeValue);
387*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
388*3ac0a46fSAndroid Build Coastguard Worker }
389*3ac0a46fSAndroid Build Coastguard Worker
setElement(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)390*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Node::setElement(
391*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine* runtime,
392*3ac0a46fSAndroid Build Coastguard Worker const std::vector<v8::Local<v8::Value>>& params) {
393*3ac0a46fSAndroid Build Coastguard Worker if (params.size() != 1 && params.size() != 2)
394*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Failure(JSMessage::kParamError);
395*3ac0a46fSAndroid Build Coastguard Worker
396*3ac0a46fSAndroid Build Coastguard Worker // TODO(weili): check whether we need to implement this, pdfium:501.
397*3ac0a46fSAndroid Build Coastguard Worker return CJS_Result::Success();
398*3ac0a46fSAndroid Build Coastguard Worker }
399*3ac0a46fSAndroid Build Coastguard Worker
ns(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)400*3ac0a46fSAndroid Build Coastguard Worker void CJX_Node::ns(v8::Isolate* pIsolate,
401*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value>* pValue,
402*3ac0a46fSAndroid Build Coastguard Worker bool bSetting,
403*3ac0a46fSAndroid Build Coastguard Worker XFA_Attribute eAttribute) {
404*3ac0a46fSAndroid Build Coastguard Worker if (bSetting) {
405*3ac0a46fSAndroid Build Coastguard Worker ThrowInvalidPropertyException(pIsolate);
406*3ac0a46fSAndroid Build Coastguard Worker return;
407*3ac0a46fSAndroid Build Coastguard Worker }
408*3ac0a46fSAndroid Build Coastguard Worker *pValue = fxv8::NewStringHelper(
409*3ac0a46fSAndroid Build Coastguard Worker pIsolate, TryNamespace().value_or(WideString()).ToUTF8().AsStringView());
410*3ac0a46fSAndroid Build Coastguard Worker }
411*3ac0a46fSAndroid Build Coastguard Worker
model(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)412*3ac0a46fSAndroid Build Coastguard Worker void CJX_Node::model(v8::Isolate* pIsolate,
413*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value>* pValue,
414*3ac0a46fSAndroid Build Coastguard Worker bool bSetting,
415*3ac0a46fSAndroid Build Coastguard Worker XFA_Attribute eAttribute) {
416*3ac0a46fSAndroid Build Coastguard Worker if (bSetting) {
417*3ac0a46fSAndroid Build Coastguard Worker ThrowInvalidPropertyException(pIsolate);
418*3ac0a46fSAndroid Build Coastguard Worker return;
419*3ac0a46fSAndroid Build Coastguard Worker }
420*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pModel = GetXFANode()->GetModelNode();
421*3ac0a46fSAndroid Build Coastguard Worker if (!pModel) {
422*3ac0a46fSAndroid Build Coastguard Worker *pValue = fxv8::NewNullHelper(pIsolate);
423*3ac0a46fSAndroid Build Coastguard Worker return;
424*3ac0a46fSAndroid Build Coastguard Worker }
425*3ac0a46fSAndroid Build Coastguard Worker *pValue =
426*3ac0a46fSAndroid Build Coastguard Worker GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pModel);
427*3ac0a46fSAndroid Build Coastguard Worker }
428*3ac0a46fSAndroid Build Coastguard Worker
isContainer(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)429*3ac0a46fSAndroid Build Coastguard Worker void CJX_Node::isContainer(v8::Isolate* pIsolate,
430*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value>* pValue,
431*3ac0a46fSAndroid Build Coastguard Worker bool bSetting,
432*3ac0a46fSAndroid Build Coastguard Worker XFA_Attribute eAttribute) {
433*3ac0a46fSAndroid Build Coastguard Worker if (bSetting) {
434*3ac0a46fSAndroid Build Coastguard Worker ThrowInvalidPropertyException(pIsolate);
435*3ac0a46fSAndroid Build Coastguard Worker return;
436*3ac0a46fSAndroid Build Coastguard Worker }
437*3ac0a46fSAndroid Build Coastguard Worker *pValue = fxv8::NewBooleanHelper(pIsolate, GetXFANode()->IsContainerNode());
438*3ac0a46fSAndroid Build Coastguard Worker }
439*3ac0a46fSAndroid Build Coastguard Worker
isNull(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)440*3ac0a46fSAndroid Build Coastguard Worker void CJX_Node::isNull(v8::Isolate* pIsolate,
441*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value>* pValue,
442*3ac0a46fSAndroid Build Coastguard Worker bool bSetting,
443*3ac0a46fSAndroid Build Coastguard Worker XFA_Attribute eAttribute) {
444*3ac0a46fSAndroid Build Coastguard Worker if (bSetting) {
445*3ac0a46fSAndroid Build Coastguard Worker ThrowInvalidPropertyException(pIsolate);
446*3ac0a46fSAndroid Build Coastguard Worker return;
447*3ac0a46fSAndroid Build Coastguard Worker }
448*3ac0a46fSAndroid Build Coastguard Worker if (GetXFANode()->GetElementType() == XFA_Element::Subform) {
449*3ac0a46fSAndroid Build Coastguard Worker *pValue = fxv8::NewBooleanHelper(pIsolate, false);
450*3ac0a46fSAndroid Build Coastguard Worker return;
451*3ac0a46fSAndroid Build Coastguard Worker }
452*3ac0a46fSAndroid Build Coastguard Worker *pValue = fxv8::NewBooleanHelper(pIsolate, GetContent(false).IsEmpty());
453*3ac0a46fSAndroid Build Coastguard Worker }
454*3ac0a46fSAndroid Build Coastguard Worker
oneOfChild(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)455*3ac0a46fSAndroid Build Coastguard Worker void CJX_Node::oneOfChild(v8::Isolate* pIsolate,
456*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value>* pValue,
457*3ac0a46fSAndroid Build Coastguard Worker bool bSetting,
458*3ac0a46fSAndroid Build Coastguard Worker XFA_Attribute eAttribute) {
459*3ac0a46fSAndroid Build Coastguard Worker if (bSetting) {
460*3ac0a46fSAndroid Build Coastguard Worker ThrowInvalidPropertyException(pIsolate);
461*3ac0a46fSAndroid Build Coastguard Worker return;
462*3ac0a46fSAndroid Build Coastguard Worker }
463*3ac0a46fSAndroid Build Coastguard Worker
464*3ac0a46fSAndroid Build Coastguard Worker std::vector<CXFA_Node*> properties =
465*3ac0a46fSAndroid Build Coastguard Worker GetXFANode()->GetNodeListWithFilter(XFA_NodeFilter::kOneOfProperty);
466*3ac0a46fSAndroid Build Coastguard Worker if (!properties.empty()) {
467*3ac0a46fSAndroid Build Coastguard Worker *pValue = GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
468*3ac0a46fSAndroid Build Coastguard Worker properties.front());
469*3ac0a46fSAndroid Build Coastguard Worker }
470*3ac0a46fSAndroid Build Coastguard Worker }
471*3ac0a46fSAndroid Build Coastguard Worker
execSingleEventByName(WideStringView wsEventName,XFA_Element eType)472*3ac0a46fSAndroid Build Coastguard Worker XFA_EventError CJX_Node::execSingleEventByName(WideStringView wsEventName,
473*3ac0a46fSAndroid Build Coastguard Worker XFA_Element eType) {
474*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
475*3ac0a46fSAndroid Build Coastguard Worker if (!pNotify)
476*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
477*3ac0a46fSAndroid Build Coastguard Worker
478*3ac0a46fSAndroid Build Coastguard Worker const ExecEventParaInfo* eventParaInfo =
479*3ac0a46fSAndroid Build Coastguard Worker GetExecEventParaInfoByName(wsEventName);
480*3ac0a46fSAndroid Build Coastguard Worker if (!eventParaInfo)
481*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
482*3ac0a46fSAndroid Build Coastguard Worker
483*3ac0a46fSAndroid Build Coastguard Worker switch (eventParaInfo->m_validFlags) {
484*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kNone:
485*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
486*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kAll:
487*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kAllNonRecursive:
488*3ac0a46fSAndroid Build Coastguard Worker return pNotify->ExecEventByDeepFirst(
489*3ac0a46fSAndroid Build Coastguard Worker GetXFANode(), eventParaInfo->m_eventType, false,
490*3ac0a46fSAndroid Build Coastguard Worker eventParaInfo->m_validFlags == EventAppliesTo::kAll);
491*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kSubform:
492*3ac0a46fSAndroid Build Coastguard Worker if (eType != XFA_Element::Subform)
493*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
494*3ac0a46fSAndroid Build Coastguard Worker
495*3ac0a46fSAndroid Build Coastguard Worker return pNotify->ExecEventByDeepFirst(
496*3ac0a46fSAndroid Build Coastguard Worker GetXFANode(), eventParaInfo->m_eventType, false, false);
497*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kFieldOrExclusion: {
498*3ac0a46fSAndroid Build Coastguard Worker if (eType != XFA_Element::ExclGroup && eType != XFA_Element::Field)
499*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
500*3ac0a46fSAndroid Build Coastguard Worker
501*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pParentNode = GetXFANode()->GetParent();
502*3ac0a46fSAndroid Build Coastguard Worker if (pParentNode &&
503*3ac0a46fSAndroid Build Coastguard Worker pParentNode->GetElementType() == XFA_Element::ExclGroup) {
504*3ac0a46fSAndroid Build Coastguard Worker // TODO(dsinclair): This seems like a bug, we do the same work twice?
505*3ac0a46fSAndroid Build Coastguard Worker pNotify->ExecEventByDeepFirst(GetXFANode(), eventParaInfo->m_eventType,
506*3ac0a46fSAndroid Build Coastguard Worker false, false);
507*3ac0a46fSAndroid Build Coastguard Worker }
508*3ac0a46fSAndroid Build Coastguard Worker return pNotify->ExecEventByDeepFirst(
509*3ac0a46fSAndroid Build Coastguard Worker GetXFANode(), eventParaInfo->m_eventType, false, false);
510*3ac0a46fSAndroid Build Coastguard Worker }
511*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kField:
512*3ac0a46fSAndroid Build Coastguard Worker if (eType != XFA_Element::Field)
513*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
514*3ac0a46fSAndroid Build Coastguard Worker
515*3ac0a46fSAndroid Build Coastguard Worker return pNotify->ExecEventByDeepFirst(
516*3ac0a46fSAndroid Build Coastguard Worker GetXFANode(), eventParaInfo->m_eventType, false, false);
517*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kSignature: {
518*3ac0a46fSAndroid Build Coastguard Worker if (!GetXFANode()->IsWidgetReady())
519*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
520*3ac0a46fSAndroid Build Coastguard Worker if (GetXFANode()->GetUIChildNode()->GetElementType() !=
521*3ac0a46fSAndroid Build Coastguard Worker XFA_Element::Signature) {
522*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
523*3ac0a46fSAndroid Build Coastguard Worker }
524*3ac0a46fSAndroid Build Coastguard Worker return pNotify->ExecEventByDeepFirst(
525*3ac0a46fSAndroid Build Coastguard Worker GetXFANode(), eventParaInfo->m_eventType, false, false);
526*3ac0a46fSAndroid Build Coastguard Worker }
527*3ac0a46fSAndroid Build Coastguard Worker case EventAppliesTo::kChoiceList: {
528*3ac0a46fSAndroid Build Coastguard Worker if (!GetXFANode()->IsWidgetReady())
529*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
530*3ac0a46fSAndroid Build Coastguard Worker if (GetXFANode()->GetUIChildNode()->GetElementType() !=
531*3ac0a46fSAndroid Build Coastguard Worker XFA_Element::ChoiceList) {
532*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
533*3ac0a46fSAndroid Build Coastguard Worker }
534*3ac0a46fSAndroid Build Coastguard Worker return pNotify->ExecEventByDeepFirst(
535*3ac0a46fSAndroid Build Coastguard Worker GetXFANode(), eventParaInfo->m_eventType, false, false);
536*3ac0a46fSAndroid Build Coastguard Worker }
537*3ac0a46fSAndroid Build Coastguard Worker }
538*3ac0a46fSAndroid Build Coastguard Worker return XFA_EventError::kNotExist;
539*3ac0a46fSAndroid Build Coastguard Worker }
540