summaryrefslogtreecommitdiff
path: root/fxjs/xfa/cjx_tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fxjs/xfa/cjx_tree.cpp')
-rw-r--r--fxjs/xfa/cjx_tree.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
new file mode 100644
index 0000000000..69cbfa0652
--- /dev/null
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -0,0 +1,230 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/xfa/cjx_tree.h"
+
+#include "fxjs/cfxjse_arguments.h"
+#include "fxjs/cfxjse_engine.h"
+#include "fxjs/cfxjse_value.h"
+#include "third_party/base/ptr_util.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},
+ {"resolveNodes", resolveNodes_static},
+ {"", nullptr}};
+
+CJX_Tree::CJX_Tree(CXFA_Object* obj) : CJX_Object(obj) {
+ DefineMethods(MethodSpecs);
+}
+
+CJX_Tree::~CJX_Tree() {}
+
+void CJX_Tree::resolveNode(CFXJSE_Arguments* pArguments) {
+ int32_t iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowParamCountMismatchException(L"resolveNode");
+ return;
+ }
+ WideString wsExpression =
+ WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringView());
+ CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
+ if (!pScriptContext)
+ return;
+ 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),
+ wsExpression.AsStringView(),
+ &resolveNodeRS, dwFlag, nullptr)) {
+ pArguments->GetReturnValue()->SetNull();
+ return;
+ }
+ if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) {
+ CXFA_Object* pObject = resolveNodeRS.objects.front();
+ pArguments->GetReturnValue()->Assign(
+ pScriptContext->GetJSValueFromMap(pObject));
+ } else {
+ const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo =
+ resolveNodeRS.pScriptAttribute;
+ if (lpAttributeInfo &&
+ lpAttributeInfo->eValueType == XFA_ScriptType::Object) {
+ auto pValue =
+ pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetRuntime());
+ CJX_Object* jsObject = resolveNodeRS.objects.front()->JSObject();
+ (jsObject->*(lpAttributeInfo->callback))(pValue.get(), false,
+ lpAttributeInfo->attribute);
+ pArguments->GetReturnValue()->Assign(pValue.get());
+ } else {
+ pArguments->GetReturnValue()->SetNull();
+ }
+ }
+}
+
+void CJX_Tree::resolveNodes(CFXJSE_Arguments* pArguments) {
+ int32_t iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowParamCountMismatchException(L"resolveNodes");
+ return;
+ }
+
+ WideString wsExpression =
+ WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringView());
+ CFXJSE_Value* pValue = pArguments->GetReturnValue();
+ if (!pValue)
+ return;
+
+ CXFA_Object* refNode = GetXFAObject();
+ if (refNode->GetElementType() == XFA_Element::Xfa)
+ refNode = GetDocument()->GetScriptContext()->GetThisObject();
+
+ ResolveNodeList(pValue, wsExpression,
+ XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
+ XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
+ XFA_RESOLVENODE_Siblings,
+ ToNode(refNode));
+}
+
+void CJX_Tree::all(CFXJSE_Value* pValue,
+ bool bSetting,
+ XFA_Attribute eAttribute) {
+ if (bSetting) {
+ ThrowInvalidPropertyException();
+ return;
+ }
+
+ uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
+ WideString wsExpression = GetAttribute(XFA_Attribute::Name) + L"[*]";
+ ResolveNodeList(pValue, wsExpression, dwFlag, nullptr);
+}
+
+void CJX_Tree::classAll(CFXJSE_Value* pValue,
+ bool bSetting,
+ XFA_Attribute eAttribute) {
+ if (bSetting) {
+ ThrowInvalidPropertyException();
+ return;
+ }
+
+ WideString wsExpression = L"#" + GetXFAObject()->GetClassName() + L"[*]";
+ ResolveNodeList(pValue, wsExpression,
+ XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL, nullptr);
+}
+
+void CJX_Tree::nodes(CFXJSE_Value* pValue,
+ bool bSetting,
+ XFA_Attribute eAttribute) {
+ CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
+ if (!pScriptContext)
+ return;
+
+ if (bSetting) {
+ WideString wsMessage = L"Unable to set ";
+ FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringView());
+ return;
+ }
+
+ CXFA_AttachNodeList* pNodeList =
+ new CXFA_AttachNodeList(GetDocument(), ToNode(GetXFAObject()));
+ pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass());
+}
+
+void CJX_Tree::parent(CFXJSE_Value* pValue,
+ bool bSetting,
+ XFA_Attribute eAttribute) {
+ if (bSetting) {
+ ThrowInvalidPropertyException();
+ return;
+ }
+
+ CXFA_Node* pParent = ToNode(GetXFAObject())->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pParent) {
+ pValue->SetNull();
+ return;
+ }
+
+ pValue->Assign(GetDocument()->GetScriptContext()->GetJSValueFromMap(pParent));
+}
+
+void CJX_Tree::index(CFXJSE_Value* pValue,
+ bool bSetting,
+ XFA_Attribute eAttribute) {
+ if (bSetting) {
+ ThrowInvalidPropertyException();
+ return;
+ }
+ pValue->SetInteger(ToNode(GetXFAObject())->GetNodeSameNameIndex());
+}
+
+void CJX_Tree::classIndex(CFXJSE_Value* pValue,
+ bool bSetting,
+ XFA_Attribute eAttribute) {
+ if (bSetting) {
+ ThrowInvalidPropertyException();
+ return;
+ }
+ pValue->SetInteger(ToNode(GetXFAObject())->GetNodeSameClassIndex());
+}
+
+void CJX_Tree::somExpression(CFXJSE_Value* pValue,
+ bool bSetting,
+ XFA_Attribute eAttribute) {
+ if (bSetting) {
+ ThrowInvalidPropertyException();
+ return;
+ }
+
+ WideString wsSOMExpression;
+ GetXFAObject()->GetSOMExpression(wsSOMExpression);
+ pValue->SetString(wsSOMExpression.UTF8Encode().AsStringView());
+}
+
+void CJX_Tree::ResolveNodeList(CFXJSE_Value* pValue,
+ WideString wsExpression,
+ uint32_t dwFlag,
+ CXFA_Node* refNode) {
+ CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
+ if (!pScriptContext)
+ return;
+ if (!refNode)
+ refNode = ToNode(GetXFAObject());
+
+ XFA_RESOLVENODE_RS resolveNodeRS;
+ pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(),
+ &resolveNodeRS, dwFlag, nullptr);
+ CXFA_ArrayNodeList* pNodeList = new CXFA_ArrayNodeList(GetDocument());
+ if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) {
+ for (CXFA_Object* pObject : resolveNodeRS.objects) {
+ if (pObject->IsNode())
+ pNodeList->Append(pObject->AsNode());
+ }
+ } else {
+ if (resolveNodeRS.pScriptAttribute &&
+ resolveNodeRS.pScriptAttribute->eValueType == XFA_ScriptType::Object) {
+ for (CXFA_Object* pObject : resolveNodeRS.objects) {
+ auto pValue =
+ pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetRuntime());
+ CJX_Object* jsObject = pObject->JSObject();
+ (jsObject->*(resolveNodeRS.pScriptAttribute->callback))(
+ pValue.get(), false, resolveNodeRS.pScriptAttribute->attribute);
+
+ CXFA_Object* obj = CFXJSE_Engine::ToObject(pValue.get(), nullptr);
+ if (obj->IsNode())
+ pNodeList->Append(obj->AsNode());
+ }
+ }
+ }
+ pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass());
+}