diff options
Diffstat (limited to 'fxjs/xfa/cjx_tree.cpp')
-rw-r--r-- | fxjs/xfa/cjx_tree.cpp | 243 |
1 files changed, 132 insertions, 111 deletions
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp index cc13b7aad..ec562cedd 100644 --- a/fxjs/xfa/cjx_tree.cpp +++ b/fxjs/xfa/cjx_tree.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 PDFium Authors. All rights reserved. +// Copyright 2017 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,16 +8,19 @@ #include <vector> +#include "fxjs/fxv8.h" #include "fxjs/js_resources.h" +#include "fxjs/xfa/cfxjse_class.h" #include "fxjs/xfa/cfxjse_engine.h" -#include "fxjs/xfa/cfxjse_value.h" -#include "third_party/base/ptr_util.h" +#include "third_party/base/numerics/safe_conversions.h" +#include "v8/include/cppgc/allocation.h" +#include "v8/include/v8-object.h" +#include "v8/include/v8-primitive.h" #include "xfa/fxfa/parser/cxfa_arraynodelist.h" #include "xfa/fxfa/parser/cxfa_attachnodelist.h" #include "xfa/fxfa/parser/cxfa_document.h" #include "xfa/fxfa/parser/cxfa_node.h" #include "xfa/fxfa/parser/cxfa_object.h" -#include "xfa/fxfa/parser/xfa_resolvenode_rs.h" const CJX_MethodSpec CJX_Tree::MethodSpecs[] = { {"resolveNode", resolveNode_static}, @@ -27,58 +30,56 @@ CJX_Tree::CJX_Tree(CXFA_Object* obj) : CJX_Object(obj) { DefineMethods(MethodSpecs); } -CJX_Tree::~CJX_Tree() {} +CJX_Tree::~CJX_Tree() = default; bool CJX_Tree::DynamicTypeIs(TypeTag eType) const { return eType == static_type__ || ParentType__::DynamicTypeIs(eType); } CJS_Result CJX_Tree::resolveNode( - CFX_V8* runtime, + CFXJSE_Engine* runtime, const std::vector<v8::Local<v8::Value>>& params) { if (params.size() != 1) return CJS_Result::Failure(JSMessage::kParamError); - WideString expression = runtime->ToWideString(params[0]); + WideString wsExpression = runtime->ToWideString(params[0]); CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); - CXFA_Object* refNode = GetXFAObject(); - if (refNode->GetElementType() == XFA_Element::Xfa) - refNode = pScriptContext->GetThisObject(); - - uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | - XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | - XFA_RESOLVENODE_Siblings; - XFA_RESOLVENODE_RS resolveNodeRS; - if (!pScriptContext->ResolveObjects(ToNode(refNode), - expression.AsStringView(), &resolveNodeRS, - dwFlag, nullptr)) { + CXFA_Object* pRefNode = GetXFAObject(); + if (pRefNode->GetElementType() == XFA_Element::Xfa) + pRefNode = pScriptContext->GetThisObject(); + + absl::optional<CFXJSE_Engine::ResolveResult> maybeResult = + pScriptContext->ResolveObjects( + ToNode(pRefNode), wsExpression.AsStringView(), + Mask<XFA_ResolveFlag>{ + XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes, + XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent, + XFA_ResolveFlag::kSiblings}); + if (!maybeResult.has_value()) return CJS_Result::Success(runtime->NewNull()); - } - - if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) { - CXFA_Object* pObject = resolveNodeRS.objects.front().Get(); - CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pObject); + if (maybeResult.value().type == CFXJSE_Engine::ResolveResult::Type::kNodes) { return CJS_Result::Success( - value->DirectGetValue().Get(runtime->GetIsolate())); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + maybeResult.value().objects.front().Get())); } - if (!resolveNodeRS.script_attribute.callback || - resolveNodeRS.script_attribute.eValueType != XFA_ScriptType::Object) { + if (!maybeResult.value().script_attribute.callback || + maybeResult.value().script_attribute.eValueType != + XFA_ScriptType::Object) { return CJS_Result::Success(runtime->NewNull()); } - auto pValue = pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate()); - CJX_Object* jsObject = resolveNodeRS.objects.front()->JSObject(); - (*resolveNodeRS.script_attribute.callback)( - jsObject, pValue.get(), false, resolveNodeRS.script_attribute.attribute); - return CJS_Result::Success( - pValue->DirectGetValue().Get(runtime->GetIsolate())); + v8::Local<v8::Value> pValue; + CJX_Object* jsObject = maybeResult.value().objects.front()->JSObject(); + (*maybeResult.value().script_attribute.callback)( + runtime->GetIsolate(), jsObject, &pValue, false, + maybeResult.value().script_attribute.attribute); + return CJS_Result::Success(pValue); } CJS_Result CJX_Tree::resolveNodes( - CFX_V8* runtime, + CFXJSE_Engine* runtime, const std::vector<v8::Local<v8::Value>>& params) { if (params.size() != 1) return CJS_Result::Failure(JSMessage::kParamError); @@ -88,146 +89,166 @@ CJS_Result CJX_Tree::resolveNodes( refNode = GetDocument()->GetScriptContext()->GetThisObject(); CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); - auto pValue = pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate()); - ResolveNodeList(pValue.get(), runtime->ToWideString(params[0]), - XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | - XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | - XFA_RESOLVENODE_Siblings, - ToNode(refNode)); - return CJS_Result::Success( - pValue->DirectGetValue().Get(runtime->GetIsolate())); + const Mask<XFA_ResolveFlag> kFlags = { + XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes, + XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent, + XFA_ResolveFlag::kSiblings}; + return CJS_Result::Success(ResolveNodeList(pScriptContext->GetIsolate(), + runtime->ToWideString(params[0]), + kFlags, ToNode(refNode))); } -void CJX_Tree::all(CFXJSE_Value* pValue, +void CJX_Tree::all(v8::Isolate* pIsolate, + v8::Local<v8::Value>* pValue, bool bSetting, XFA_Attribute eAttribute) { if (bSetting) { - ThrowInvalidPropertyException(); + ThrowInvalidPropertyException(pIsolate); return; } - - uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL; - WideString wsExpression = GetAttribute(XFA_Attribute::Name) + L"[*]"; - ResolveNodeList(pValue, wsExpression, dwFlag, nullptr); + const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings, + XFA_ResolveFlag::kALL}; + WideString wsExpression = GetAttributeByEnum(XFA_Attribute::Name) + L"[*]"; + *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr); } -void CJX_Tree::classAll(CFXJSE_Value* pValue, +void CJX_Tree::classAll(v8::Isolate* pIsolate, + v8::Local<v8::Value>* pValue, bool bSetting, XFA_Attribute eAttribute) { if (bSetting) { - ThrowInvalidPropertyException(); + ThrowInvalidPropertyException(pIsolate); return; } - + const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings, + XFA_ResolveFlag::kALL}; WideString wsExpression = L"#" + WideString::FromASCII(GetXFAObject()->GetClassName()) + L"[*]"; - ResolveNodeList(pValue, wsExpression, - XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL, nullptr); + *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr); } -void CJX_Tree::nodes(CFXJSE_Value* pValue, +void CJX_Tree::nodes(v8::Isolate* pIsolate, + v8::Local<v8::Value>* pValue, bool bSetting, XFA_Attribute eAttribute) { if (bSetting) { WideString wsMessage = L"Unable to set "; - FXJSE_ThrowMessage(wsMessage.ToUTF8().AsStringView()); + FXJSE_ThrowMessage(pIsolate, wsMessage.ToUTF8().AsStringView()); return; } - CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); - CXFA_AttachNodeList* pNodeList = - new CXFA_AttachNodeList(GetDocument(), ToNode(GetXFAObject())); - pValue->SetHostObject(pNodeList, pScriptContext->GetJseNormalClass()); + CXFA_Document* pDoc = GetDocument(); + auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_AttachNodeList>( + pDoc->GetHeap()->GetAllocationHandle(), pDoc, GetXFANode()); + pDoc->GetNodeOwner()->PersistList(pNodeList); + + CFXJSE_Engine* pEngine = pDoc->GetScriptContext(); + *pValue = pNodeList->JSObject()->NewBoundV8Object( + pIsolate, pEngine->GetJseNormalClass()->GetTemplate(pIsolate)); } -void CJX_Tree::parent(CFXJSE_Value* pValue, +void CJX_Tree::parent(v8::Isolate* pIsolate, + v8::Local<v8::Value>* pValue, bool bSetting, XFA_Attribute eAttribute) { if (bSetting) { - ThrowInvalidPropertyException(); + ThrowInvalidPropertyException(pIsolate); return; } - CXFA_Node* pParent = ToNode(GetXFAObject())->GetParent(); - if (!pParent) { - pValue->SetNull(); - return; - } - - pValue->Assign( - GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pParent)); + CXFA_Node* pParent = GetXFANode()->GetParent(); + *pValue = pParent ? GetDocument() + ->GetScriptContext() + ->GetOrCreateJSBindingFromMap(pParent) + .As<v8::Value>() + : fxv8::NewNullHelper(pIsolate).As<v8::Value>(); } -void CJX_Tree::index(CFXJSE_Value* pValue, +void CJX_Tree::index(v8::Isolate* pIsolate, + v8::Local<v8::Value>* pValue, bool bSetting, XFA_Attribute eAttribute) { if (bSetting) { - ThrowInvalidPropertyException(); + ThrowInvalidPropertyException(pIsolate); return; } - CXFA_Node* pNode = ToNode(GetXFAObject()); + CXFA_Node* pNode = GetXFANode(); size_t iIndex = pNode ? pNode->GetIndexByName() : 0; - pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex)); + *pValue = fxv8::NewNumberHelper(pIsolate, + pdfium::base::checked_cast<int32_t>(iIndex)); } -void CJX_Tree::classIndex(CFXJSE_Value* pValue, +void CJX_Tree::classIndex(v8::Isolate* pIsolate, + v8::Local<v8::Value>* pValue, bool bSetting, XFA_Attribute eAttribute) { if (bSetting) { - ThrowInvalidPropertyException(); + ThrowInvalidPropertyException(pIsolate); return; } - CXFA_Node* pNode = ToNode(GetXFAObject()); + CXFA_Node* pNode = GetXFANode(); size_t iIndex = pNode ? pNode->GetIndexByClassName() : 0; - pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex)); + *pValue = fxv8::NewNumberHelper(pIsolate, + pdfium::base::checked_cast<int32_t>(iIndex)); } -void CJX_Tree::somExpression(CFXJSE_Value* pValue, +void CJX_Tree::somExpression(v8::Isolate* pIsolate, + v8::Local<v8::Value>* pValue, bool bSetting, XFA_Attribute eAttribute) { if (bSetting) { - ThrowInvalidPropertyException(); + ThrowInvalidPropertyException(pIsolate); return; } - WideString wsSOMExpression = GetXFAObject()->GetSOMExpression(); - pValue->SetString(wsSOMExpression.ToUTF8().AsStringView()); + ByteString bsSOMExpression = GetXFAObject()->GetSOMExpression().ToUTF8(); + *pValue = fxv8::NewStringHelper(pIsolate, bsSOMExpression.AsStringView()); } -void CJX_Tree::ResolveNodeList(CFXJSE_Value* pValue, - WideString wsExpression, - uint32_t dwFlag, - CXFA_Node* refNode) { +v8::Local<v8::Value> CJX_Tree::ResolveNodeList(v8::Isolate* pIsolate, + WideString wsExpression, + Mask<XFA_ResolveFlag> dwFlag, + CXFA_Node* refNode) { if (!refNode) - refNode = ToNode(GetXFAObject()); - - XFA_RESOLVENODE_RS resolveNodeRS; - CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); - pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(), - &resolveNodeRS, dwFlag, nullptr); - CXFA_ArrayNodeList* pNodeList = new CXFA_ArrayNodeList(GetDocument()); - if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) { - for (auto& pObject : resolveNodeRS.objects) { - if (pObject->IsNode()) - pNodeList->Append(pObject->AsNode()); - } - } else { - if (resolveNodeRS.script_attribute.callback && - resolveNodeRS.script_attribute.eValueType == XFA_ScriptType::Object) { - for (auto& pObject : resolveNodeRS.objects) { - auto innerValue = - pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate()); - CJX_Object* jsObject = pObject->JSObject(); - (*resolveNodeRS.script_attribute.callback)( - jsObject, innerValue.get(), false, - resolveNodeRS.script_attribute.attribute); - CXFA_Object* obj = CFXJSE_Engine::ToObject(innerValue.get()); - if (obj->IsNode()) - pNodeList->Append(obj->AsNode()); + refNode = GetXFANode(); + + CXFA_Document* pDoc = GetDocument(); + auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>( + pDoc->GetHeap()->GetAllocationHandle(), pDoc); + pDoc->GetNodeOwner()->PersistList(pNodeList); + + CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext(); + absl::optional<CFXJSE_Engine::ResolveResult> maybeResult = + pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(), + dwFlag); + + if (maybeResult.has_value()) { + if (maybeResult.value().type == + CFXJSE_Engine::ResolveResult::Type::kNodes) { + for (auto& pObject : maybeResult.value().objects) { + if (pObject->IsNode()) + pNodeList->Append(pObject->AsNode()); + } + } else { + if (maybeResult.value().script_attribute.callback && + maybeResult.value().script_attribute.eValueType == + XFA_ScriptType::Object) { + for (auto& pObject : maybeResult.value().objects) { + v8::Local<v8::Value> innerValue; + CJX_Object* jsObject = pObject->JSObject(); + (*maybeResult.value().script_attribute.callback)( + pIsolate, jsObject, &innerValue, false, + maybeResult.value().script_attribute.attribute); + CXFA_Object* obj = + CFXJSE_Engine::ToObject(pScriptContext->GetIsolate(), innerValue); + if (obj->IsNode()) + pNodeList->Append(obj->AsNode()); + } } } } - pValue->SetHostObject(pNodeList, pScriptContext->GetJseNormalClass()); + return pNodeList->JSObject()->NewBoundV8Object( + pIsolate, pScriptContext->GetJseNormalClass()->GetTemplate(pIsolate)); } |