xref: /aosp_15_r20/external/pdfium/fxjs/xfa/cjx_tree.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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_tree.h"
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
10*3ac0a46fSAndroid Build Coastguard Worker 
11*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/fxv8.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/js_resources.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_class.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_engine.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/numerics/safe_conversions.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/cppgc/allocation.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-object.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-primitive.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_attachnodelist.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_document.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_node.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_object.h"
24*3ac0a46fSAndroid Build Coastguard Worker 
25*3ac0a46fSAndroid Build Coastguard Worker const CJX_MethodSpec CJX_Tree::MethodSpecs[] = {
26*3ac0a46fSAndroid Build Coastguard Worker     {"resolveNode", resolveNode_static},
27*3ac0a46fSAndroid Build Coastguard Worker     {"resolveNodes", resolveNodes_static}};
28*3ac0a46fSAndroid Build Coastguard Worker 
CJX_Tree(CXFA_Object * obj)29*3ac0a46fSAndroid Build Coastguard Worker CJX_Tree::CJX_Tree(CXFA_Object* obj) : CJX_Object(obj) {
30*3ac0a46fSAndroid Build Coastguard Worker   DefineMethods(MethodSpecs);
31*3ac0a46fSAndroid Build Coastguard Worker }
32*3ac0a46fSAndroid Build Coastguard Worker 
33*3ac0a46fSAndroid Build Coastguard Worker CJX_Tree::~CJX_Tree() = default;
34*3ac0a46fSAndroid Build Coastguard Worker 
DynamicTypeIs(TypeTag eType) const35*3ac0a46fSAndroid Build Coastguard Worker bool CJX_Tree::DynamicTypeIs(TypeTag eType) const {
36*3ac0a46fSAndroid Build Coastguard Worker   return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
37*3ac0a46fSAndroid Build Coastguard Worker }
38*3ac0a46fSAndroid Build Coastguard Worker 
resolveNode(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)39*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Tree::resolveNode(
40*3ac0a46fSAndroid Build Coastguard Worker     CFXJSE_Engine* runtime,
41*3ac0a46fSAndroid Build Coastguard Worker     const std::vector<v8::Local<v8::Value>>& params) {
42*3ac0a46fSAndroid Build Coastguard Worker   if (params.size() != 1)
43*3ac0a46fSAndroid Build Coastguard Worker     return CJS_Result::Failure(JSMessage::kParamError);
44*3ac0a46fSAndroid Build Coastguard Worker 
45*3ac0a46fSAndroid Build Coastguard Worker   WideString wsExpression = runtime->ToWideString(params[0]);
46*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Object* pRefNode = GetXFAObject();
47*3ac0a46fSAndroid Build Coastguard Worker   if (pRefNode->GetElementType() == XFA_Element::Xfa)
48*3ac0a46fSAndroid Build Coastguard Worker     pRefNode = runtime->GetThisObject();
49*3ac0a46fSAndroid Build Coastguard Worker 
50*3ac0a46fSAndroid Build Coastguard Worker   absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
51*3ac0a46fSAndroid Build Coastguard Worker       runtime->ResolveObjects(
52*3ac0a46fSAndroid Build Coastguard Worker           ToNode(pRefNode), wsExpression.AsStringView(),
53*3ac0a46fSAndroid Build Coastguard Worker           Mask<XFA_ResolveFlag>{
54*3ac0a46fSAndroid Build Coastguard Worker               XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
55*3ac0a46fSAndroid Build Coastguard Worker               XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
56*3ac0a46fSAndroid Build Coastguard Worker               XFA_ResolveFlag::kSiblings});
57*3ac0a46fSAndroid Build Coastguard Worker   if (!maybeResult.has_value())
58*3ac0a46fSAndroid Build Coastguard Worker     return CJS_Result::Success(runtime->NewNull());
59*3ac0a46fSAndroid Build Coastguard Worker 
60*3ac0a46fSAndroid Build Coastguard Worker   if (maybeResult.value().type == CFXJSE_Engine::ResolveResult::Type::kNodes) {
61*3ac0a46fSAndroid Build Coastguard Worker     return CJS_Result::Success(runtime->GetOrCreateJSBindingFromMap(
62*3ac0a46fSAndroid Build Coastguard Worker         maybeResult.value().objects.front().Get()));
63*3ac0a46fSAndroid Build Coastguard Worker   }
64*3ac0a46fSAndroid Build Coastguard Worker 
65*3ac0a46fSAndroid Build Coastguard Worker   if (!maybeResult.value().script_attribute.callback ||
66*3ac0a46fSAndroid Build Coastguard Worker       maybeResult.value().script_attribute.eValueType !=
67*3ac0a46fSAndroid Build Coastguard Worker           XFA_ScriptType::Object) {
68*3ac0a46fSAndroid Build Coastguard Worker     return CJS_Result::Success(runtime->NewNull());
69*3ac0a46fSAndroid Build Coastguard Worker   }
70*3ac0a46fSAndroid Build Coastguard Worker 
71*3ac0a46fSAndroid Build Coastguard Worker   v8::Local<v8::Value> pValue;
72*3ac0a46fSAndroid Build Coastguard Worker   CJX_Object* jsObject = maybeResult.value().objects.front()->JSObject();
73*3ac0a46fSAndroid Build Coastguard Worker   (*maybeResult.value().script_attribute.callback)(
74*3ac0a46fSAndroid Build Coastguard Worker       runtime->GetIsolate(), jsObject, &pValue, false,
75*3ac0a46fSAndroid Build Coastguard Worker       maybeResult.value().script_attribute.attribute);
76*3ac0a46fSAndroid Build Coastguard Worker   return CJS_Result::Success(pValue);
77*3ac0a46fSAndroid Build Coastguard Worker }
78*3ac0a46fSAndroid Build Coastguard Worker 
resolveNodes(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)79*3ac0a46fSAndroid Build Coastguard Worker CJS_Result CJX_Tree::resolveNodes(
80*3ac0a46fSAndroid Build Coastguard Worker     CFXJSE_Engine* runtime,
81*3ac0a46fSAndroid Build Coastguard Worker     const std::vector<v8::Local<v8::Value>>& params) {
82*3ac0a46fSAndroid Build Coastguard Worker   if (params.size() != 1)
83*3ac0a46fSAndroid Build Coastguard Worker     return CJS_Result::Failure(JSMessage::kParamError);
84*3ac0a46fSAndroid Build Coastguard Worker 
85*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Object* refNode = GetXFAObject();
86*3ac0a46fSAndroid Build Coastguard Worker   if (refNode->GetElementType() == XFA_Element::Xfa)
87*3ac0a46fSAndroid Build Coastguard Worker     refNode = runtime->GetThisObject();
88*3ac0a46fSAndroid Build Coastguard Worker 
89*3ac0a46fSAndroid Build Coastguard Worker   const Mask<XFA_ResolveFlag> kFlags = {
90*3ac0a46fSAndroid Build Coastguard Worker       XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
91*3ac0a46fSAndroid Build Coastguard Worker       XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
92*3ac0a46fSAndroid Build Coastguard Worker       XFA_ResolveFlag::kSiblings};
93*3ac0a46fSAndroid Build Coastguard Worker   return CJS_Result::Success(ResolveNodeList(runtime->GetIsolate(),
94*3ac0a46fSAndroid Build Coastguard Worker                                              runtime->ToWideString(params[0]),
95*3ac0a46fSAndroid Build Coastguard Worker                                              kFlags, ToNode(refNode)));
96*3ac0a46fSAndroid Build Coastguard Worker }
97*3ac0a46fSAndroid Build Coastguard Worker 
all(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)98*3ac0a46fSAndroid Build Coastguard Worker void CJX_Tree::all(v8::Isolate* pIsolate,
99*3ac0a46fSAndroid Build Coastguard Worker                    v8::Local<v8::Value>* pValue,
100*3ac0a46fSAndroid Build Coastguard Worker                    bool bSetting,
101*3ac0a46fSAndroid Build Coastguard Worker                    XFA_Attribute eAttribute) {
102*3ac0a46fSAndroid Build Coastguard Worker   if (bSetting) {
103*3ac0a46fSAndroid Build Coastguard Worker     ThrowInvalidPropertyException(pIsolate);
104*3ac0a46fSAndroid Build Coastguard Worker     return;
105*3ac0a46fSAndroid Build Coastguard Worker   }
106*3ac0a46fSAndroid Build Coastguard Worker   const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings,
107*3ac0a46fSAndroid Build Coastguard Worker                                         XFA_ResolveFlag::kALL};
108*3ac0a46fSAndroid Build Coastguard Worker   WideString wsExpression = GetAttributeByEnum(XFA_Attribute::Name) + L"[*]";
109*3ac0a46fSAndroid Build Coastguard Worker   *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr);
110*3ac0a46fSAndroid Build Coastguard Worker }
111*3ac0a46fSAndroid Build Coastguard Worker 
classAll(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)112*3ac0a46fSAndroid Build Coastguard Worker void CJX_Tree::classAll(v8::Isolate* pIsolate,
113*3ac0a46fSAndroid Build Coastguard Worker                         v8::Local<v8::Value>* pValue,
114*3ac0a46fSAndroid Build Coastguard Worker                         bool bSetting,
115*3ac0a46fSAndroid Build Coastguard Worker                         XFA_Attribute eAttribute) {
116*3ac0a46fSAndroid Build Coastguard Worker   if (bSetting) {
117*3ac0a46fSAndroid Build Coastguard Worker     ThrowInvalidPropertyException(pIsolate);
118*3ac0a46fSAndroid Build Coastguard Worker     return;
119*3ac0a46fSAndroid Build Coastguard Worker   }
120*3ac0a46fSAndroid Build Coastguard Worker   const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings,
121*3ac0a46fSAndroid Build Coastguard Worker                                         XFA_ResolveFlag::kALL};
122*3ac0a46fSAndroid Build Coastguard Worker   WideString wsExpression =
123*3ac0a46fSAndroid Build Coastguard Worker       L"#" + WideString::FromASCII(GetXFAObject()->GetClassName()) + L"[*]";
124*3ac0a46fSAndroid Build Coastguard Worker   *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr);
125*3ac0a46fSAndroid Build Coastguard Worker }
126*3ac0a46fSAndroid Build Coastguard Worker 
nodes(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)127*3ac0a46fSAndroid Build Coastguard Worker void CJX_Tree::nodes(v8::Isolate* pIsolate,
128*3ac0a46fSAndroid Build Coastguard Worker                      v8::Local<v8::Value>* pValue,
129*3ac0a46fSAndroid Build Coastguard Worker                      bool bSetting,
130*3ac0a46fSAndroid Build Coastguard Worker                      XFA_Attribute eAttribute) {
131*3ac0a46fSAndroid Build Coastguard Worker   if (bSetting) {
132*3ac0a46fSAndroid Build Coastguard Worker     WideString wsMessage = L"Unable to set ";
133*3ac0a46fSAndroid Build Coastguard Worker     FXJSE_ThrowMessage(pIsolate, wsMessage.ToUTF8().AsStringView());
134*3ac0a46fSAndroid Build Coastguard Worker     return;
135*3ac0a46fSAndroid Build Coastguard Worker   }
136*3ac0a46fSAndroid Build Coastguard Worker 
137*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Document* pDoc = GetDocument();
138*3ac0a46fSAndroid Build Coastguard Worker   auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_AttachNodeList>(
139*3ac0a46fSAndroid Build Coastguard Worker       pDoc->GetHeap()->GetAllocationHandle(), pDoc, GetXFANode());
140*3ac0a46fSAndroid Build Coastguard Worker   pDoc->GetNodeOwner()->PersistList(pNodeList);
141*3ac0a46fSAndroid Build Coastguard Worker 
142*3ac0a46fSAndroid Build Coastguard Worker   CFXJSE_Engine* pEngine = pDoc->GetScriptContext();
143*3ac0a46fSAndroid Build Coastguard Worker   *pValue = pNodeList->JSObject()->NewBoundV8Object(
144*3ac0a46fSAndroid Build Coastguard Worker       pIsolate, pEngine->GetJseNormalClass()->GetTemplate(pIsolate));
145*3ac0a46fSAndroid Build Coastguard Worker }
146*3ac0a46fSAndroid Build Coastguard Worker 
parent(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)147*3ac0a46fSAndroid Build Coastguard Worker void CJX_Tree::parent(v8::Isolate* pIsolate,
148*3ac0a46fSAndroid Build Coastguard Worker                       v8::Local<v8::Value>* pValue,
149*3ac0a46fSAndroid Build Coastguard Worker                       bool bSetting,
150*3ac0a46fSAndroid Build Coastguard Worker                       XFA_Attribute eAttribute) {
151*3ac0a46fSAndroid Build Coastguard Worker   if (bSetting) {
152*3ac0a46fSAndroid Build Coastguard Worker     ThrowInvalidPropertyException(pIsolate);
153*3ac0a46fSAndroid Build Coastguard Worker     return;
154*3ac0a46fSAndroid Build Coastguard Worker   }
155*3ac0a46fSAndroid Build Coastguard Worker 
156*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pParent = GetXFANode()->GetParent();
157*3ac0a46fSAndroid Build Coastguard Worker   *pValue = pParent ? GetDocument()
158*3ac0a46fSAndroid Build Coastguard Worker                           ->GetScriptContext()
159*3ac0a46fSAndroid Build Coastguard Worker                           ->GetOrCreateJSBindingFromMap(pParent)
160*3ac0a46fSAndroid Build Coastguard Worker                           .As<v8::Value>()
161*3ac0a46fSAndroid Build Coastguard Worker                     : fxv8::NewNullHelper(pIsolate).As<v8::Value>();
162*3ac0a46fSAndroid Build Coastguard Worker }
163*3ac0a46fSAndroid Build Coastguard Worker 
index(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)164*3ac0a46fSAndroid Build Coastguard Worker void CJX_Tree::index(v8::Isolate* pIsolate,
165*3ac0a46fSAndroid Build Coastguard Worker                      v8::Local<v8::Value>* pValue,
166*3ac0a46fSAndroid Build Coastguard Worker                      bool bSetting,
167*3ac0a46fSAndroid Build Coastguard Worker                      XFA_Attribute eAttribute) {
168*3ac0a46fSAndroid Build Coastguard Worker   if (bSetting) {
169*3ac0a46fSAndroid Build Coastguard Worker     ThrowInvalidPropertyException(pIsolate);
170*3ac0a46fSAndroid Build Coastguard Worker     return;
171*3ac0a46fSAndroid Build Coastguard Worker   }
172*3ac0a46fSAndroid Build Coastguard Worker 
173*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pNode = GetXFANode();
174*3ac0a46fSAndroid Build Coastguard Worker   size_t iIndex = pNode ? pNode->GetIndexByName() : 0;
175*3ac0a46fSAndroid Build Coastguard Worker   *pValue = fxv8::NewNumberHelper(pIsolate,
176*3ac0a46fSAndroid Build Coastguard Worker                                   pdfium::base::checked_cast<int32_t>(iIndex));
177*3ac0a46fSAndroid Build Coastguard Worker }
178*3ac0a46fSAndroid Build Coastguard Worker 
classIndex(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)179*3ac0a46fSAndroid Build Coastguard Worker void CJX_Tree::classIndex(v8::Isolate* pIsolate,
180*3ac0a46fSAndroid Build Coastguard Worker                           v8::Local<v8::Value>* pValue,
181*3ac0a46fSAndroid Build Coastguard Worker                           bool bSetting,
182*3ac0a46fSAndroid Build Coastguard Worker                           XFA_Attribute eAttribute) {
183*3ac0a46fSAndroid Build Coastguard Worker   if (bSetting) {
184*3ac0a46fSAndroid Build Coastguard Worker     ThrowInvalidPropertyException(pIsolate);
185*3ac0a46fSAndroid Build Coastguard Worker     return;
186*3ac0a46fSAndroid Build Coastguard Worker   }
187*3ac0a46fSAndroid Build Coastguard Worker 
188*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Node* pNode = GetXFANode();
189*3ac0a46fSAndroid Build Coastguard Worker   size_t iIndex = pNode ? pNode->GetIndexByClassName() : 0;
190*3ac0a46fSAndroid Build Coastguard Worker   *pValue = fxv8::NewNumberHelper(pIsolate,
191*3ac0a46fSAndroid Build Coastguard Worker                                   pdfium::base::checked_cast<int32_t>(iIndex));
192*3ac0a46fSAndroid Build Coastguard Worker }
193*3ac0a46fSAndroid Build Coastguard Worker 
somExpression(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)194*3ac0a46fSAndroid Build Coastguard Worker void CJX_Tree::somExpression(v8::Isolate* pIsolate,
195*3ac0a46fSAndroid Build Coastguard Worker                              v8::Local<v8::Value>* pValue,
196*3ac0a46fSAndroid Build Coastguard Worker                              bool bSetting,
197*3ac0a46fSAndroid Build Coastguard Worker                              XFA_Attribute eAttribute) {
198*3ac0a46fSAndroid Build Coastguard Worker   if (bSetting) {
199*3ac0a46fSAndroid Build Coastguard Worker     ThrowInvalidPropertyException(pIsolate);
200*3ac0a46fSAndroid Build Coastguard Worker     return;
201*3ac0a46fSAndroid Build Coastguard Worker   }
202*3ac0a46fSAndroid Build Coastguard Worker 
203*3ac0a46fSAndroid Build Coastguard Worker   ByteString bsSOMExpression = GetXFAObject()->GetSOMExpression().ToUTF8();
204*3ac0a46fSAndroid Build Coastguard Worker   *pValue = fxv8::NewStringHelper(pIsolate, bsSOMExpression.AsStringView());
205*3ac0a46fSAndroid Build Coastguard Worker }
206*3ac0a46fSAndroid Build Coastguard Worker 
ResolveNodeList(v8::Isolate * pIsolate,WideString wsExpression,Mask<XFA_ResolveFlag> dwFlag,CXFA_Node * refNode)207*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> CJX_Tree::ResolveNodeList(v8::Isolate* pIsolate,
208*3ac0a46fSAndroid Build Coastguard Worker                                                WideString wsExpression,
209*3ac0a46fSAndroid Build Coastguard Worker                                                Mask<XFA_ResolveFlag> dwFlag,
210*3ac0a46fSAndroid Build Coastguard Worker                                                CXFA_Node* refNode) {
211*3ac0a46fSAndroid Build Coastguard Worker   if (!refNode)
212*3ac0a46fSAndroid Build Coastguard Worker     refNode = GetXFANode();
213*3ac0a46fSAndroid Build Coastguard Worker 
214*3ac0a46fSAndroid Build Coastguard Worker   CXFA_Document* pDoc = GetDocument();
215*3ac0a46fSAndroid Build Coastguard Worker   auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
216*3ac0a46fSAndroid Build Coastguard Worker       pDoc->GetHeap()->GetAllocationHandle(), pDoc);
217*3ac0a46fSAndroid Build Coastguard Worker   pDoc->GetNodeOwner()->PersistList(pNodeList);
218*3ac0a46fSAndroid Build Coastguard Worker 
219*3ac0a46fSAndroid Build Coastguard Worker   CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
220*3ac0a46fSAndroid Build Coastguard Worker   absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
221*3ac0a46fSAndroid Build Coastguard Worker       pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(),
222*3ac0a46fSAndroid Build Coastguard Worker                                      dwFlag);
223*3ac0a46fSAndroid Build Coastguard Worker 
224*3ac0a46fSAndroid Build Coastguard Worker   if (maybeResult.has_value()) {
225*3ac0a46fSAndroid Build Coastguard Worker     if (maybeResult.value().type ==
226*3ac0a46fSAndroid Build Coastguard Worker         CFXJSE_Engine::ResolveResult::Type::kNodes) {
227*3ac0a46fSAndroid Build Coastguard Worker       for (auto& pObject : maybeResult.value().objects) {
228*3ac0a46fSAndroid Build Coastguard Worker         if (pObject->IsNode())
229*3ac0a46fSAndroid Build Coastguard Worker           pNodeList->Append(pObject->AsNode());
230*3ac0a46fSAndroid Build Coastguard Worker       }
231*3ac0a46fSAndroid Build Coastguard Worker     } else {
232*3ac0a46fSAndroid Build Coastguard Worker       if (maybeResult.value().script_attribute.callback &&
233*3ac0a46fSAndroid Build Coastguard Worker           maybeResult.value().script_attribute.eValueType ==
234*3ac0a46fSAndroid Build Coastguard Worker               XFA_ScriptType::Object) {
235*3ac0a46fSAndroid Build Coastguard Worker         for (auto& pObject : maybeResult.value().objects) {
236*3ac0a46fSAndroid Build Coastguard Worker           v8::Local<v8::Value> innerValue;
237*3ac0a46fSAndroid Build Coastguard Worker           CJX_Object* jsObject = pObject->JSObject();
238*3ac0a46fSAndroid Build Coastguard Worker           (*maybeResult.value().script_attribute.callback)(
239*3ac0a46fSAndroid Build Coastguard Worker               pIsolate, jsObject, &innerValue, false,
240*3ac0a46fSAndroid Build Coastguard Worker               maybeResult.value().script_attribute.attribute);
241*3ac0a46fSAndroid Build Coastguard Worker           CXFA_Object* obj =
242*3ac0a46fSAndroid Build Coastguard Worker               CFXJSE_Engine::ToObject(pScriptContext->GetIsolate(), innerValue);
243*3ac0a46fSAndroid Build Coastguard Worker           if (obj->IsNode())
244*3ac0a46fSAndroid Build Coastguard Worker             pNodeList->Append(obj->AsNode());
245*3ac0a46fSAndroid Build Coastguard Worker         }
246*3ac0a46fSAndroid Build Coastguard Worker       }
247*3ac0a46fSAndroid Build Coastguard Worker     }
248*3ac0a46fSAndroid Build Coastguard Worker   }
249*3ac0a46fSAndroid Build Coastguard Worker   return pNodeList->JSObject()->NewBoundV8Object(
250*3ac0a46fSAndroid Build Coastguard Worker       pIsolate, pScriptContext->GetJseNormalClass()->GetTemplate(pIsolate));
251*3ac0a46fSAndroid Build Coastguard Worker }
252