1 // Copyright 2017 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 "fxjs/xfa/cjx_node.h"
8
9 #include <memory>
10 #include <vector>
11
12 #include "core/fxcrt/cfx_memorystream.h"
13 #include "core/fxcrt/fx_codepage.h"
14 #include "fxjs/cfxjse_engine.h"
15 #include "fxjs/js_resources.h"
16 #include "third_party/base/ptr_util.h"
17 #include "xfa/fxfa/cxfa_eventparam.h"
18 #include "xfa/fxfa/cxfa_ffnotify.h"
19 #include "xfa/fxfa/parser/cxfa_document.h"
20 #include "xfa/fxfa/parser/cxfa_node.h"
21 #include "xfa/fxfa/parser/cxfa_simple_parser.h"
22 #include "xfa/fxfa/parser/xfa_utils.h"
23
24 namespace {
25
26 enum class EventAppliesToo {
27 kNone = 0,
28 kAll = 1,
29 kAllNonRecursive = 2,
30 kSubform = 3,
31 kFieldOrExclusion = 4,
32 kField = 5,
33 kSignature = 6,
34 kChoiceList = 7
35 };
36
37 struct XFA_ExecEventParaInfo {
38 public:
39 uint32_t m_uHash;
40 const wchar_t* m_lpcEventName;
41 XFA_EVENTTYPE m_eventType;
42 EventAppliesToo m_validFlags;
43 };
44
45 const XFA_ExecEventParaInfo gs_eventParaInfos[] = {
46 {0x109d7ce7, L"mouseEnter", XFA_EVENT_MouseEnter, EventAppliesToo::kField},
47 {0x1bfc72d9, L"preOpen", XFA_EVENT_PreOpen, EventAppliesToo::kChoiceList},
48 {0x2196a452, L"initialize", XFA_EVENT_Initialize, EventAppliesToo::kAll},
49 {0x27410f03, L"mouseExit", XFA_EVENT_MouseExit, EventAppliesToo::kField},
50 {0x36f1c6d8, L"preSign", XFA_EVENT_PreSign, EventAppliesToo::kSignature},
51 {0x4731d6ba, L"exit", XFA_EVENT_Exit, EventAppliesToo::kAllNonRecursive},
52 {0x7233018a, L"validate", XFA_EVENT_Validate, EventAppliesToo::kAll},
53 {0x8808385e, L"indexChange", XFA_EVENT_IndexChange,
54 EventAppliesToo::kSubform},
55 {0x891f4606, L"change", XFA_EVENT_Change,
56 EventAppliesToo::kFieldOrExclusion},
57 {0x9f693b21, L"mouseDown", XFA_EVENT_MouseDown, EventAppliesToo::kField},
58 {0xcdce56b3, L"full", XFA_EVENT_Full, EventAppliesToo::kFieldOrExclusion},
59 {0xd576d08e, L"mouseUp", XFA_EVENT_MouseUp, EventAppliesToo::kField},
60 {0xd95657a6, L"click", XFA_EVENT_Click, EventAppliesToo::kFieldOrExclusion},
61 {0xdbfbe02e, L"calculate", XFA_EVENT_Calculate, EventAppliesToo::kAll},
62 {0xe25fa7b8, L"postOpen", XFA_EVENT_PostOpen, EventAppliesToo::kChoiceList},
63 {0xe28dce7e, L"enter", XFA_EVENT_Enter, EventAppliesToo::kAllNonRecursive},
64 {0xfd54fbb7, L"postSign", XFA_EVENT_PostSign, EventAppliesToo::kSignature},
65 };
66
GetEventParaInfoByName(const WideStringView & wsEventName)67 const XFA_ExecEventParaInfo* GetEventParaInfoByName(
68 const WideStringView& wsEventName) {
69 uint32_t uHash = FX_HashCode_GetW(wsEventName, false);
70 int32_t iStart = 0;
71 int32_t iEnd = (sizeof(gs_eventParaInfos) / sizeof(gs_eventParaInfos[0])) - 1;
72 do {
73 int32_t iMid = (iStart + iEnd) / 2;
74 const XFA_ExecEventParaInfo* eventParaInfo = &gs_eventParaInfos[iMid];
75 if (uHash == eventParaInfo->m_uHash)
76 return eventParaInfo;
77 if (uHash < eventParaInfo->m_uHash)
78 iEnd = iMid - 1;
79 else
80 iStart = iMid + 1;
81 } while (iStart <= iEnd);
82 return nullptr;
83 }
84
85 } // namespace
86
87 const CJX_MethodSpec CJX_Node::MethodSpecs[] = {
88 {"applyXSL", applyXSL_static},
89 {"assignNode", assignNode_static},
90 {"clone", clone_static},
91 {"getAttribute", getAttribute_static},
92 {"getElement", getElement_static},
93 {"isPropertySpecified", isPropertySpecified_static},
94 {"loadXML", loadXML_static},
95 {"saveFilteredXML", saveFilteredXML_static},
96 {"saveXML", saveXML_static},
97 {"setAttribute", setAttribute_static},
98 {"setElement", setElement_static}};
99
CJX_Node(CXFA_Node * node)100 CJX_Node::CJX_Node(CXFA_Node* node) : CJX_Tree(node) {
101 DefineMethods(MethodSpecs, FX_ArraySize(MethodSpecs));
102 }
103
104 CJX_Node::~CJX_Node() = default;
105
GetXFANode()106 CXFA_Node* CJX_Node::GetXFANode() {
107 return static_cast<CXFA_Node*>(GetXFAObject());
108 }
109
GetXFANode() const110 const CXFA_Node* CJX_Node::GetXFANode() const {
111 return static_cast<const CXFA_Node*>(GetXFAObject());
112 }
113
applyXSL(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)114 CJS_Return CJX_Node::applyXSL(CJS_V8* runtime,
115 const std::vector<v8::Local<v8::Value>>& params) {
116 if (params.size() != 1)
117 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
118
119 // TODO(weili): check whether we need to implement this, pdfium:501.
120 return CJS_Return(true);
121 }
122
assignNode(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)123 CJS_Return CJX_Node::assignNode(
124 CJS_V8* runtime,
125 const std::vector<v8::Local<v8::Value>>& params) {
126 if (params.empty() || params.size() > 3)
127 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
128
129 // TODO(weili): check whether we need to implement this, pdfium:501.
130 return CJS_Return(true);
131 }
132
clone(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)133 CJS_Return CJX_Node::clone(CJS_V8* runtime,
134 const std::vector<v8::Local<v8::Value>>& params) {
135 if (params.size() != 1)
136 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
137
138 CXFA_Node* pCloneNode = GetXFANode()->Clone(runtime->ToBoolean(params[0]));
139 CFXJSE_Value* value =
140 GetDocument()->GetScriptContext()->GetJSValueFromMap(pCloneNode);
141 if (!value)
142 return CJS_Return(runtime->NewNull());
143 return CJS_Return(value->DirectGetValue().Get(runtime->GetIsolate()));
144 }
145
getAttribute(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)146 CJS_Return CJX_Node::getAttribute(
147 CJS_V8* runtime,
148 const std::vector<v8::Local<v8::Value>>& params) {
149 if (params.size() != 1)
150 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
151
152 WideString expression = runtime->ToWideString(params[0]);
153 return CJS_Return(runtime->NewString(
154 GetAttribute(expression.AsStringView()).UTF8Encode().AsStringView()));
155 }
156
getElement(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)157 CJS_Return CJX_Node::getElement(
158 CJS_V8* runtime,
159 const std::vector<v8::Local<v8::Value>>& params) {
160 if (params.empty() || params.size() > 2)
161 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
162
163 WideString expression = runtime->ToWideString(params[0]);
164 int32_t iValue = params.size() >= 2 ? runtime->ToInt32(params[1]) : 0;
165
166 CXFA_Node* pNode = GetOrCreateProperty<CXFA_Node>(
167 iValue, CXFA_Node::NameToElement(expression));
168 if (!pNode)
169 return CJS_Return(runtime->NewNull());
170
171 CFXJSE_Value* value =
172 GetDocument()->GetScriptContext()->GetJSValueFromMap(pNode);
173 if (!value)
174 return CJS_Return(runtime->NewNull());
175 return CJS_Return(value->DirectGetValue().Get(runtime->GetIsolate()));
176 }
177
isPropertySpecified(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)178 CJS_Return CJX_Node::isPropertySpecified(
179 CJS_V8* runtime,
180 const std::vector<v8::Local<v8::Value>>& params) {
181 if (params.empty() || params.size() > 3)
182 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
183
184 WideString expression = runtime->ToWideString(params[0]);
185 XFA_Attribute attr = CXFA_Node::NameToAttribute(expression.AsStringView());
186 if (attr != XFA_Attribute::Unknown && HasAttribute(attr))
187 return CJS_Return(runtime->NewBoolean(true));
188
189 bool bParent = params.size() < 2 || runtime->ToBoolean(params[1]);
190 int32_t iIndex = params.size() == 3 ? runtime->ToInt32(params[2]) : 0;
191 XFA_Element eType = CXFA_Node::NameToElement(expression);
192 bool bHas = !!GetOrCreateProperty<CXFA_Node>(iIndex, eType);
193 if (!bHas && bParent && GetXFANode()->GetParent()) {
194 // Also check on the parent.
195 auto* jsnode = GetXFANode()->GetParent()->JSObject();
196 bHas = jsnode->HasAttribute(attr) ||
197 !!jsnode->GetOrCreateProperty<CXFA_Node>(iIndex, eType);
198 }
199 return CJS_Return(runtime->NewBoolean(bHas));
200 }
201
loadXML(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)202 CJS_Return CJX_Node::loadXML(CJS_V8* runtime,
203 const std::vector<v8::Local<v8::Value>>& params) {
204 if (params.empty() || params.size() > 3)
205 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
206
207 ByteString expression = runtime->ToByteString(params[0]);
208 if (expression.IsEmpty())
209 return CJS_Return(true);
210
211 bool bIgnoreRoot = true;
212 if (params.size() >= 2)
213 bIgnoreRoot = runtime->ToBoolean(params[1]);
214
215 bool bOverwrite = 0;
216 if (params.size() >= 3)
217 bOverwrite = runtime->ToBoolean(params[2]);
218
219 auto pParser = pdfium::MakeUnique<CXFA_SimpleParser>(GetDocument());
220 if (!pParser)
221 return CJS_Return(true);
222
223 CFX_XMLNode* pXMLNode = pParser->ParseXMLData(expression);
224 if (!pXMLNode)
225 return CJS_Return(true);
226
227 if (bIgnoreRoot &&
228 (pXMLNode->GetType() != FX_XMLNODE_Element ||
229 XFA_RecognizeRichText(static_cast<CFX_XMLElement*>(pXMLNode)))) {
230 bIgnoreRoot = false;
231 }
232
233 CXFA_Node* pFakeRoot = GetXFANode()->Clone(false);
234 WideString wsContentType = GetCData(XFA_Attribute::ContentType);
235 if (!wsContentType.IsEmpty()) {
236 pFakeRoot->JSObject()->SetCData(XFA_Attribute::ContentType,
237 WideString(wsContentType), false, false);
238 }
239
240 std::unique_ptr<CFX_XMLNode> pFakeXMLRoot(pFakeRoot->GetXMLMappingNode());
241 if (!pFakeXMLRoot) {
242 CFX_XMLNode* pThisXMLRoot = GetXFANode()->GetXMLMappingNode();
243 pFakeXMLRoot = pThisXMLRoot ? pThisXMLRoot->Clone() : nullptr;
244 }
245 if (!pFakeXMLRoot) {
246 pFakeXMLRoot = pdfium::MakeUnique<CFX_XMLElement>(
247 WideString(GetXFANode()->GetClassName()));
248 }
249
250 if (bIgnoreRoot) {
251 CFX_XMLNode* pXMLChild = pXMLNode->GetNodeItem(CFX_XMLNode::FirstChild);
252 while (pXMLChild) {
253 CFX_XMLNode* pXMLSibling =
254 pXMLChild->GetNodeItem(CFX_XMLNode::NextSibling);
255 pXMLNode->RemoveChildNode(pXMLChild);
256 pFakeXMLRoot->InsertChildNode(pXMLChild);
257 pXMLChild = pXMLSibling;
258 }
259 } else {
260 CFX_XMLNode* pXMLParent = pXMLNode->GetNodeItem(CFX_XMLNode::Parent);
261 if (pXMLParent)
262 pXMLParent->RemoveChildNode(pXMLNode);
263
264 pFakeXMLRoot->InsertChildNode(pXMLNode);
265 }
266
267 pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot.get());
268 pFakeRoot = pParser->GetRootNode();
269 if (!pFakeRoot)
270 return CJS_Return(true);
271
272 if (bOverwrite) {
273 CXFA_Node* pChild = GetXFANode()->GetFirstChild();
274 CXFA_Node* pNewChild = pFakeRoot->GetFirstChild();
275 int32_t index = 0;
276 while (pNewChild) {
277 CXFA_Node* pItem = pNewChild->GetNextSibling();
278 pFakeRoot->RemoveChild(pNewChild, true);
279 GetXFANode()->InsertChild(index++, pNewChild);
280 pNewChild->SetFlag(XFA_NodeFlag_Initialized, true);
281 pNewChild = pItem;
282 }
283
284 while (pChild) {
285 CXFA_Node* pItem = pChild->GetNextSibling();
286 GetXFANode()->RemoveChild(pChild, true);
287 pFakeRoot->InsertChild(pChild, nullptr);
288 pChild = pItem;
289 }
290
291 if (GetXFANode()->GetPacketType() == XFA_PacketType::Form &&
292 GetXFANode()->GetElementType() == XFA_Element::ExData) {
293 CFX_XMLNode* pTempXMLNode = GetXFANode()->GetXMLMappingNode();
294 GetXFANode()->SetXMLMappingNode(pFakeXMLRoot.release());
295 GetXFANode()->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
296 if (pTempXMLNode && !pTempXMLNode->GetNodeItem(CFX_XMLNode::Parent))
297 pFakeXMLRoot.reset(pTempXMLNode);
298 else
299 pFakeXMLRoot = nullptr;
300 }
301 MoveBufferMapData(pFakeRoot, GetXFANode());
302 } else {
303 CXFA_Node* pChild = pFakeRoot->GetFirstChild();
304 while (pChild) {
305 CXFA_Node* pItem = pChild->GetNextSibling();
306 pFakeRoot->RemoveChild(pChild, true);
307 GetXFANode()->InsertChild(pChild, nullptr);
308 pChild->SetFlag(XFA_NodeFlag_Initialized, true);
309 pChild = pItem;
310 }
311 }
312
313 if (pFakeXMLRoot) {
314 pFakeRoot->SetXMLMappingNode(pFakeXMLRoot.release());
315 pFakeRoot->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
316 }
317 pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren, false);
318
319 return CJS_Return(true);
320 }
321
saveFilteredXML(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)322 CJS_Return CJX_Node::saveFilteredXML(
323 CJS_V8* runtime,
324 const std::vector<v8::Local<v8::Value>>& params) {
325 // TODO(weili): Check whether we need to implement this, pdfium:501.
326 return CJS_Return(true);
327 }
328
saveXML(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)329 CJS_Return CJX_Node::saveXML(CJS_V8* runtime,
330 const std::vector<v8::Local<v8::Value>>& params) {
331 if (params.size() > 1)
332 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
333 if (params.size() == 1 && runtime->ToWideString(params[0]) != L"pretty")
334 return CJS_Return(JSGetStringFromID(JSMessage::kValueError));
335
336 // TODO(weili): Check whether we need to save pretty print XML, pdfium:501.
337
338 WideString bsXMLHeader = L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
339 if (GetXFANode()->GetPacketType() != XFA_PacketType::Form &&
340 GetXFANode()->GetPacketType() != XFA_PacketType::Datasets) {
341 return CJS_Return(runtime->NewString(""));
342 }
343
344 CFX_XMLNode* pElement = nullptr;
345 if (GetXFANode()->GetPacketType() == XFA_PacketType::Datasets) {
346 pElement = GetXFANode()->GetXMLMappingNode();
347 if (!pElement || pElement->GetType() != FX_XMLNODE_Element) {
348 return CJS_Return(
349 runtime->NewString(bsXMLHeader.UTF8Encode().AsStringView()));
350 }
351
352 XFA_DataExporter_DealWithDataGroupNode(GetXFANode());
353 }
354
355 auto pMemoryStream = pdfium::MakeRetain<CFX_MemoryStream>(true);
356 auto pStream =
357 pdfium::MakeRetain<CFX_SeekableStreamProxy>(pMemoryStream, true);
358 pStream->SetCodePage(FX_CODEPAGE_UTF8);
359 pStream->WriteString(bsXMLHeader.AsStringView());
360
361 if (GetXFANode()->GetPacketType() == XFA_PacketType::Form)
362 XFA_DataExporter_RegenerateFormFile(GetXFANode(), pStream, nullptr, true);
363 else
364 pElement->SaveXMLNode(pStream);
365
366 return CJS_Return(runtime->NewString(
367 ByteStringView(pMemoryStream->GetBuffer(), pMemoryStream->GetSize())));
368 }
369
setAttribute(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)370 CJS_Return CJX_Node::setAttribute(
371 CJS_V8* runtime,
372 const std::vector<v8::Local<v8::Value>>& params) {
373 if (params.size() != 2)
374 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
375
376 WideString attributeValue = runtime->ToWideString(params[0]);
377 WideString attribute = runtime->ToWideString(params[1]);
378 SetAttribute(attribute.AsStringView(), attributeValue.AsStringView(), true);
379 return CJS_Return(true);
380 }
381
setElement(CJS_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)382 CJS_Return CJX_Node::setElement(
383 CJS_V8* runtime,
384 const std::vector<v8::Local<v8::Value>>& params) {
385 if (params.size() != 1 && params.size() != 2)
386 return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
387
388 // TODO(weili): check whether we need to implement this, pdfium:501.
389 return CJS_Return(true);
390 }
391
id(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)392 void CJX_Node::id(CFXJSE_Value* pValue,
393 bool bSetting,
394 XFA_Attribute eAttribute) {
395 Script_Attribute_String(pValue, bSetting, eAttribute);
396 }
397
ns(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)398 void CJX_Node::ns(CFXJSE_Value* pValue,
399 bool bSetting,
400 XFA_Attribute eAttribute) {
401 if (bSetting) {
402 ThrowInvalidPropertyException();
403 return;
404 }
405 pValue->SetString(
406 TryNamespace().value_or(WideString()).UTF8Encode().AsStringView());
407 }
408
model(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)409 void CJX_Node::model(CFXJSE_Value* pValue,
410 bool bSetting,
411 XFA_Attribute eAttribute) {
412 if (bSetting) {
413 ThrowInvalidPropertyException();
414 return;
415 }
416 pValue->Assign(GetDocument()->GetScriptContext()->GetJSValueFromMap(
417 GetXFANode()->GetModelNode()));
418 }
419
isContainer(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)420 void CJX_Node::isContainer(CFXJSE_Value* pValue,
421 bool bSetting,
422 XFA_Attribute eAttribute) {
423 if (bSetting) {
424 ThrowInvalidPropertyException();
425 return;
426 }
427 pValue->SetBoolean(GetXFANode()->IsContainerNode());
428 }
429
isNull(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)430 void CJX_Node::isNull(CFXJSE_Value* pValue,
431 bool bSetting,
432 XFA_Attribute eAttribute) {
433 if (bSetting) {
434 ThrowInvalidPropertyException();
435 return;
436 }
437 if (GetXFANode()->GetElementType() == XFA_Element::Subform) {
438 pValue->SetBoolean(false);
439 return;
440 }
441 pValue->SetBoolean(GetContent(false).IsEmpty());
442 }
443
oneOfChild(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)444 void CJX_Node::oneOfChild(CFXJSE_Value* pValue,
445 bool bSetting,
446 XFA_Attribute eAttribute) {
447 if (bSetting) {
448 ThrowInvalidPropertyException();
449 return;
450 }
451
452 std::vector<CXFA_Node*> properties = GetXFANode()->GetNodeList(
453 XFA_NODEFILTER_OneOfProperty, XFA_Element::Unknown);
454 if (!properties.empty()) {
455 pValue->Assign(GetDocument()->GetScriptContext()->GetJSValueFromMap(
456 properties.front()));
457 }
458 }
459
execSingleEventByName(const WideStringView & wsEventName,XFA_Element eType)460 int32_t CJX_Node::execSingleEventByName(const WideStringView& wsEventName,
461 XFA_Element eType) {
462 CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
463 if (!pNotify)
464 return XFA_EVENTERROR_NotExist;
465
466 const XFA_ExecEventParaInfo* eventParaInfo =
467 GetEventParaInfoByName(wsEventName);
468 if (!eventParaInfo)
469 return XFA_EVENTERROR_NotExist;
470
471 switch (eventParaInfo->m_validFlags) {
472 case EventAppliesToo::kNone:
473 return XFA_EVENTERROR_NotExist;
474 case EventAppliesToo::kAll:
475 case EventAppliesToo::kAllNonRecursive:
476 return pNotify->ExecEventByDeepFirst(
477 GetXFANode(), eventParaInfo->m_eventType, false,
478 eventParaInfo->m_validFlags == EventAppliesToo::kAll);
479 case EventAppliesToo::kSubform:
480 if (eType != XFA_Element::Subform)
481 return XFA_EVENTERROR_NotExist;
482
483 return pNotify->ExecEventByDeepFirst(
484 GetXFANode(), eventParaInfo->m_eventType, false, false);
485 case EventAppliesToo::kFieldOrExclusion: {
486 if (eType != XFA_Element::ExclGroup && eType != XFA_Element::Field)
487 return XFA_EVENTERROR_NotExist;
488
489 CXFA_Node* pParentNode = GetXFANode()->GetParent();
490 if (pParentNode &&
491 pParentNode->GetElementType() == XFA_Element::ExclGroup) {
492 // TODO(dsinclair): This seems like a bug, we do the same work twice?
493 pNotify->ExecEventByDeepFirst(GetXFANode(), eventParaInfo->m_eventType,
494 false, false);
495 }
496 return pNotify->ExecEventByDeepFirst(
497 GetXFANode(), eventParaInfo->m_eventType, false, false);
498 }
499 case EventAppliesToo::kField:
500 if (eType != XFA_Element::Field)
501 return XFA_EVENTERROR_NotExist;
502
503 return pNotify->ExecEventByDeepFirst(
504 GetXFANode(), eventParaInfo->m_eventType, false, false);
505 case EventAppliesToo::kSignature: {
506 CXFA_WidgetAcc* pWidgetAcc = GetXFANode()->GetWidgetAcc();
507 if (!pWidgetAcc)
508 return XFA_EVENTERROR_NotExist;
509
510 CXFA_Node* pUINode = pWidgetAcc->GetUIChild();
511 if (pUINode->GetElementType() != XFA_Element::Signature)
512 return XFA_EVENTERROR_NotExist;
513
514 return pNotify->ExecEventByDeepFirst(
515 GetXFANode(), eventParaInfo->m_eventType, false, false);
516 }
517 case EventAppliesToo::kChoiceList: {
518 CXFA_WidgetAcc* pWidgetAcc = GetXFANode()->GetWidgetAcc();
519 if (!pWidgetAcc)
520 return XFA_EVENTERROR_NotExist;
521
522 CXFA_Node* pUINode = pWidgetAcc->GetUIChild();
523 if (pUINode->GetElementType() != XFA_Element::ChoiceList ||
524 pWidgetAcc->IsListBox()) {
525 return XFA_EVENTERROR_NotExist;
526 }
527 return pNotify->ExecEventByDeepFirst(
528 GetXFANode(), eventParaInfo->m_eventType, false, false);
529 }
530 }
531 return XFA_EVENTERROR_NotExist;
532 }
533