7#include "xfa/fxfa/cxfa_ffdocview.h"
12#include "core/fxcrt/fx_extension.h"
13#include "core/fxcrt/stl_util.h"
14#include "core/fxcrt/xml/cfx_xmlparser.h"
15#include "fxjs/gc/container_trace.h"
16#include "fxjs/xfa/cfxjse_engine.h"
17#include "fxjs/xfa/cjx_object.h"
18#include "third_party/base/check_op.h"
19#include "third_party/base/containers/contains.h"
20#include "xfa/fxfa/cxfa_ffapp.h"
21#include "xfa/fxfa/cxfa_ffbarcode.h"
22#include "xfa/fxfa/cxfa_ffcheckbutton.h"
23#include "xfa/fxfa/cxfa_ffdoc.h"
24#include "xfa/fxfa/cxfa_ffexclgroup.h"
25#include "xfa/fxfa/cxfa_fffield.h"
26#include "xfa/fxfa/cxfa_ffimage.h"
27#include "xfa/fxfa/cxfa_ffimageedit.h"
28#include "xfa/fxfa/cxfa_ffpageview.h"
29#include "xfa/fxfa/cxfa_ffpushbutton.h"
30#include "xfa/fxfa/cxfa_ffsignature.h"
31#include "xfa/fxfa/cxfa_fftext.h"
32#include "xfa/fxfa/cxfa_ffwidget.h"
33#include "xfa/fxfa/cxfa_ffwidgethandler.h"
34#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
35#include "xfa/fxfa/cxfa_readynodeiterator.h"
36#include "xfa/fxfa/cxfa_textprovider.h"
37#include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
38#include "xfa/fxfa/parser/cxfa_acrobat.h"
39#include "xfa/fxfa/parser/cxfa_binditems.h"
40#include "xfa/fxfa/parser/cxfa_calculate.h"
41#include "xfa/fxfa/parser/cxfa_pageset.h"
42#include "xfa/fxfa/parser/cxfa_present.h"
43#include "xfa/fxfa/parser/cxfa_subform.h"
44#include "xfa/fxfa/parser/cxfa_validate.h"
45#include "xfa/fxfa/parser/xfa_utils.h"
49bool IsValidXMLNameString(
const WideString& str) {
51 for (
const auto ch : str) {
81 m_pDocView->LockUpdate();
85 m_pDocView->UnlockUpdate();
86 m_pDocView->UpdateDocView();
94 visitor->Trace(m_pDoc);
95 visitor->Trace(m_pWidgetHandler);
96 visitor->Trace(m_pFocusNode);
97 visitor->Trace(m_pFocusWidget);
98 ContainerTrace(visitor, m_ValidateNodes);
99 ContainerTrace(visitor, m_CalculateNodes);
100 ContainerTrace(visitor, m_NewAddedNodes);
101 ContainerTrace(visitor, m_BindItems);
102 ContainerTrace(visitor, m_IndexChangedSubforms);
113 m_pDoc->GetXFADoc()->DoProtoMerge();
114 m_pDoc->GetXFADoc()->DoDataMerge();
121 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
125 InitLayout(pRootItem);
126 InitCalculate(pRootItem);
127 InitValidate(pRootItem);
145 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
149 CXFA_Subform* pSubformNode =
150 pRootItem->GetChild<CXFA_Subform>(0,
XFA_Element::Subform,
false);
154 CXFA_PageSet* pPageSetNode =
155 pSubformNode->GetFirstChildByClass<CXFA_PageSet>(
XFA_Element::PageSet);
159 RunCalculateWidgets();
162 InitLayout(pPageSetNode);
163 InitCalculate(pPageSetNode);
164 InitValidate(pPageSetNode);
170 RunCalculateWidgets();
176 m_CalculateNodes.clear();
177 if (m_pFocusNode && !m_pFocusWidget)
178 SetFocusNode(m_pFocusNode);
184 m_NullTestMsgArray.push_back(msg);
188 int32_t iCount = fxcrt::CollectionSize<int32_t>(m_NullTestMsgArray);
189 CXFA_FFApp* pApp = m_pDoc->GetApp();
191 if (pAppProvider && iCount) {
192 int32_t remaining = iCount > 7 ? iCount - 7 : 0;
195 for (int32_t i = 0; i < iCount; i++)
196 wsMsg += m_NullTestMsgArray[i] + L"\n";
200 L"Message limit exceeded. Remaining %d "
201 L"validation errors not reported."
,
208 m_NullTestMsgArray.clear();
212 if (IsUpdateLocked())
216 while (!m_NewAddedNodes.empty()) {
217 CXFA_Node* pNode = m_NewAddedNodes.front();
218 m_NewAddedNodes.pop_front();
219 InitCalculate(pNode);
224 RunSubformIndexChange();
225 RunCalculateWidgets();
231 RunEventLayoutReady();
233 m_bLayoutEvent =
false;
234 m_CalculateNodes.clear();
241 for (; pWidget; pWidget = pNext) {
268 return CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
288 m_bLayoutEvent =
true;
289 bool bChanged =
false;
292 bChanged = ResetSingleNodeData(pNode);
304 bChanged |= ResetSingleNodeData(next_node);
310 m_pDoc->SetChangeMark();
319 if (!m_pWidgetHandler) {
320 m_pWidgetHandler = cppgc::MakeGarbageCollected<CXFA_FFWidgetHandler>(
321 m_pDoc->GetHeap()->GetAllocationHandle(),
this);
323 return m_pWidgetHandler;
327 if (pNewFocus == m_pFocusWidget)
330 if (m_pFocusWidget) {
331 CXFA_ContentLayoutItem* pItem = m_pFocusWidget->GetLayoutItem();
334 if (!m_pFocusWidget->IsLoaded())
335 m_pFocusWidget->LoadWidget();
336 if (!m_pFocusWidget->OnSetFocus(m_pFocusWidget))
337 m_pFocusWidget.Clear();
340 if (m_pFocusWidget) {
341 if (!m_pFocusWidget->OnKillFocus(pNewFocus))
350 if (!pNewFocus->OnSetFocus(m_pFocusWidget))
356 m_pFocusNode = node->IsWidgetReady() ? node :
nullptr;
357 m_pFocusWidget = pNewFocus;
359 m_pFocusNode.Clear();
360 m_pFocusWidget.Clear();
374 m_pDoc->SetFocusWidget(m_pFocusWidget);
378 if (m_pFocusNode != pWidget->GetNode())
381 m_pFocusNode.Clear();
382 m_pFocusWidget.Clear();
460 if (!IsValidXMLNameString(wsName)) {
463 CFXJSE_Engine* pScriptContext = m_pDoc->GetXFADoc()->GetScriptContext();
469 WideString wsExpression = (!pRefNode ? L"$form." : L"")
+ wsName;
470 absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
471 pScriptContext->ResolveObjects(
472 pRefNode, wsExpression.AsStringView(),
473 Mask<XFA_ResolveFlag>{
474 XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
475 XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent});
476 if (!maybeResult.has_value())
479 if (maybeResult.value().type == CFXJSE_Engine::ResolveResult::Type::kNodes) {
480 CXFA_Node* pNode = maybeResult.value().objects.front()->AsNode();
489 CXFA_FFPageView* pFFPageView = pSender ? pSender
->GetPageView() :
nullptr;
490 m_pDoc->OnPageViewEvent(pFFPageView, eEvent);
495 m_pDoc->InvalidateRect(pPageView, rtInvalidate);
500 m_bInLayoutStatus =
true;
506 m_bInLayoutStatus =
false;
507 m_pDoc->OnPageViewEvent(
nullptr, CXFA_FFDoc::PageViewEvent::kStopLayout);
511 m_bInLayoutStatus =
false;
512 m_pDoc->OnPageViewEvent(
nullptr, CXFA_FFDoc::PageViewEvent::kStopLayout);
518 std::set<CXFA_Node*> seen;
519 while (!m_IndexChangedSubforms.empty()) {
520 CXFA_Node* pSubformNode = m_IndexChangedSubforms.front();
521 m_IndexChangedSubforms.pop_front();
522 bool bInserted = seen.insert(pSubformNode).second;
532 m_NewAddedNodes.push_back(pNode);
537 if (!pdfium::Contains(m_IndexChangedSubforms, pNode))
538 m_IndexChangedSubforms.push_back(pNode);
543 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
552 !m_CalculateNodes.empty() ? m_CalculateNodes.back() :
nullptr;
553 if (pCurrentNode != node)
554 m_CalculateNodes.push_back(node);
562 for (
auto& pResult : pGlobalData->m_Globals) {
563 if (!pResult->HasRemovedChildren() && pResult->IsWidgetReady())
564 AddCalculateNode(pResult);
569 while (index < m_CalculateNodes.size()) {
570 CXFA_Node* node = m_CalculateNodes[index];
573 size_t recurse = node->JSObject()->GetCalcRecursionCount() + 1;
574 node->JSObject()->SetCalcRecursionCount(recurse);
582 index = RunCalculateRecursive(++index);
588 if (!m_pDoc->IsCalculationsEnabled())
591 if (!m_CalculateNodes.empty())
592 RunCalculateRecursive(0);
594 for (CXFA_Node* node : m_CalculateNodes)
595 node->JSObject()->SetCalcRecursionCount(0);
597 m_CalculateNodes.clear();
602 if (!pdfium::Contains(m_ValidateNodes, node))
603 m_ValidateNodes.push_back(node);
613 RunCalculateWidgets();
618 if (!m_pDoc->IsValidationsEnabled())
622 m_ValidateNodes.clear();
627 if (!m_pDoc->IsValidationsEnabled())
630 while (!m_ValidateNodes.empty()) {
631 CXFA_Node* node = m_ValidateNodes.front();
632 m_ValidateNodes.pop_front();
641 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
651 while (!m_BindItems.empty()) {
652 CXFA_BindItems* item = m_BindItems.front();
653 m_BindItems.pop_front();
657 CXFA_Node* pWidgetNode = item->GetParent();
664 absl::optional<CFXJSE_Engine::ResolveResult> maybeRS =
665 pScriptContext->ResolveObjects(
666 pWidgetNode, wsRef.AsStringView(),
667 Mask<XFA_ResolveFlag>{
668 XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
669 XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent,
670 XFA_ResolveFlag::kALL});
672 if (!maybeRS.has_value() ||
673 maybeRS.value().type != CFXJSE_Engine::ResolveResult::Type::kNodes ||
674 maybeRS.value().objects.empty()) {
679 const bool bUseValue = wsLabelRef
.IsEmpty() || wsLabelRef
== wsValueRef;
680 const bool bLabelUseContent =
682 const bool bValueUseContent =
686 uint32_t uValueHash = FX_HashCode_GetW(wsValueRef.AsStringView());
687 for (
auto& refObject : maybeRS.value().objects) {
688 CXFA_Node* refNode = refObject->AsNode();
692 if (bValueUseContent) {
693 wsValue = refNode->JSObject()->GetContent(
false);
695 CXFA_Node* nodeValue = refNode->GetFirstChildByName(uValueHash);
696 wsValue = nodeValue ? nodeValue->JSObject()->GetContent(
false)
697 : refNode->JSObject()->GetContent(
false);
701 if (bLabelUseContent) {
702 wsLabel = refNode->JSObject()->GetContent(
false);
704 CXFA_Node* nodeLabel =
705 refNode->GetFirstChildByName(wsLabelRef.AsStringView());
707 wsLabel = nodeLabel->JSObject()->GetContent(
false);
712 pWidgetNode->InsertItem(wsLabel, wsValue,
false);
721 m_pDoc->SetChangeMark();
726 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
727 if (!pFormPacketNode)
730 return pFormPacketNode->GetFirstChildByClass<CXFA_Subform>(
friend class EventParamScope
static bool IsXMLNameChar(wchar_t ch, bool bFirstChar)
CXFA_Script * GetScriptIfExists()
bool TestStatusBits(Mask< XFA_WidgetStatus > val) const
CXFA_EventParam(XFA_EVENTTYPE type)
virtual WideString GetAppTitle() const =0
virtual int32_t MsgBox(const WideString &wsMessage, const WideString &wsTitle, uint32_t dwIconType, uint32_t dwButtonType)=0
CallbackIface * GetAppProvider() const
UpdateScope(CXFA_FFDocView *pDocView)
void InvalidateRect(CXFA_FFPageView *pPageView, const CFX_RectF &rtInvalidate)
CXFA_FFWidgetHandler * GetWidgetHandler()
void AddValidateNode(CXFA_Node *node)
void ResetNode(CXFA_Node *pNode)
void AddCalculateNodeNotify(CXFA_Node *pNodeChange)
CXFA_FFDoc * GetDoc() const
bool SetFocus(CXFA_FFWidget *pNewFocus)
void DeleteLayoutItem(CXFA_FFWidget *pWidget)
void AddNewFormNode(CXFA_Node *pNode)
void OnPageViewEvent(CXFA_ViewLayoutItem *pSender, CXFA_FFDoc::PageViewEvent eEvent)
CXFA_FFWidget * GetWidgetByName(const WideString &wsName, CXFA_FFWidget *pRefWidget)
CXFA_FFPageView * GetPageView(int32_t nIndex) const
void SetFocusNode(CXFA_Node *pNode)
void AddCalculateNode(CXFA_Node *node)
CXFA_LayoutProcessor * GetLayoutProcessor() const
int32_t CountPageViews() const
XFA_EventError ExecEventActivityByDeepFirst(CXFA_Node *pFormNode, XFA_EVENTTYPE eEventType, bool bIsFormReady, bool bRecursive)
CXFA_Node * GetRootSubform()
void AddNullTestMsg(const WideString &msg)
void ProcessValueChanged(CXFA_Node *node)
void UpdateUIDisplay(CXFA_Node *pNode, CXFA_FFWidget *pExcept)
CXFA_FFWidget * GetWidgetForNode(CXFA_Node *node)
void AddIndexChangedSubform(CXFA_Subform *pNode)
bool IsValidationsEnabled() const
int32_t CountPages() const
CXFA_LayoutItem * GetLayoutItem(CXFA_Node *pFormItem)
CXFA_ViewLayoutItem * GetPage(int32_t index) const
CXFA_Node * GetFirstContainerChild() const
CXFA_Node * GetNextContainerSibling() const
CXFA_Validate * GetValidateIfExists() const
CXFA_Calculate * GetCalculateIfExists() const
bool DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify)
void SetFlag(XFA_NodeFlag dwFlag)
XFA_EventError ExecuteScript(CXFA_FFDocView *pDocView, CXFA_Script *script, CXFA_EventParam *pEventParam)
bool IsUserInteractive() const
XFA_EventError ProcessEvent(CXFA_FFDocView *pDocView, XFA_AttributeValue iActivity, CXFA_EventParam *pEventParam)
bool IsWidgetReady() const
XFA_FFWidgetType GetFFWidgetType()
XFA_EventError ProcessValidate(CXFA_FFDocView *pDocView, int32_t iFlags)
XFA_EventError ProcessCalculate(CXFA_FFDocView *pDocView)
bool HasRemovedChildren() const
XFA_Element GetElementType() const
CXFA_Document * GetDocument() const
CXFA_ReadyNodeIterator(CXFA_Node *pTravelRoot)
CXFA_FFPageView * GetPageView() const
WideString & operator+=(const WideString &str)
bool operator==(const WideString &other) const
static WideString Format(const wchar_t *pFormat,...)
bool EqualsASCII(ByteStringView that) const
CXFA_FFWidget * GetFFWidget(CXFA_ContentLayoutItem *item)
@ XFA_EVENT_InitCalculate
static XFA_EventError XFA_ProcessEvent(CXFA_FFDocView *pDocView, CXFA_Node *pNode, CXFA_EventParam *pParam)
const XFA_AttributeValue kXFAEventActivity[]
CXFA_ContentLayoutItem * ToContentLayoutItem(CXFA_LayoutItem *item)
WideString operator+(const wchar_t *str1, const WideString &str2)
void XFA_EventErrorAccumulate(XFA_EventError *pAcc, XFA_EventError eNew)