7#include "xfa/fxfa/parser/xfa_utils.h"
12#include "core/fxcrt/cfx_memorystream.h"
13#include "core/fxcrt/fx_codepage.h"
14#include "core/fxcrt/fx_extension.h"
15#include "core/fxcrt/widetext_buffer.h"
16#include "core/fxcrt/xml/cfx_xmlchardata.h"
17#include "core/fxcrt/xml/cfx_xmlelement.h"
18#include "core/fxcrt/xml/cfx_xmlnode.h"
19#include "core/fxcrt/xml/cfx_xmltext.h"
20#include "fxjs/xfa/cjx_object.h"
21#include "third_party/base/check.h"
22#include "xfa/fxfa/parser/cxfa_document.h"
23#include "xfa/fxfa/parser/cxfa_localemgr.h"
24#include "xfa/fxfa/parser/cxfa_measurement.h"
25#include "xfa/fxfa/parser/cxfa_node.h"
26#include "xfa/fxfa/parser/cxfa_ui.h"
27#include "xfa/fxfa/parser/cxfa_value.h"
28#include "xfa/fxfa/parser/xfa_basic_data.h"
32const char kFormNS[] =
"http://www.xfa.org/schema/xfa-form/";
34WideString ExportEncodeAttribute(
const WideString& str) {
36 textBuf.Reserve(str.GetLength());
37 for (size_t i = 0; i < str.GetLength(); i++) {
61bool IsXMLValidChar(
wchar_t ch) {
62 return ch == 0x09 || ch == 0x0A || ch == 0x0D ||
63 (ch >= 0x20 && ch <= 0xD7FF) || (ch >= 0xE000 && ch <= 0xFFFD);
66WideString ExportEncodeContent(
const WideString& str) {
67 WideTextBuffer textBuf;
68 size_t iLen = str.GetLength();
69 for (size_t i = 0; i < iLen; i++) {
71 if (!IsXMLValidChar(ch))
76 }
else if (ch ==
'<') {
78 }
else if (ch ==
'>') {
80 }
else if (ch ==
'\'') {
82 }
else if (ch ==
'\"') {
84 }
else if (ch ==
' ') {
85 if (i && str[i - 1] !=
' ') {
98 bool bSaveInDataModel =
false;
100 return bSaveInDataModel;
102 CXFA_Node* pValueNode = pNode->GetParent();
104 return bSaveInDataModel;
106 CXFA_Node* pFieldNode = pValueNode->GetParent();
109 bSaveInDataModel =
true;
111 return bSaveInDataModel;
114bool ContentNodeNeedtoExport(
CXFA_Node* pContentNode) {
115 absl::optional<WideString> wsContent =
116 pContentNode->JSObject()->TryContent(
false,
false);
117 if (!wsContent.has_value())
120 DCHECK(pContentNode->IsContentNode());
121 CXFA_Node* pParentNode = pContentNode->GetParent();
125 CXFA_Node* pGrandParentNode = pParentNode->GetParent();
135WideString SaveAttribute(
CXFA_Node* pNode,
137 WideStringView wsName,
139 if (!bProto && !pNode->JSObject()->HasAttribute(eName))
142 absl::optional<WideString> value =
143 pNode->JSObject()->TryAttribute(eName,
false);
144 if (!value.has_value())
147 WideString wsEncoded = ExportEncodeAttribute(value.value());
148 return WideString{L" ", wsName, L"=\"", wsEncoded.AsStringView(), L"\""};
151void RegenerateFormFile_Changed(
CXFA_Node* pNode,
155 for (size_t i = 0;; ++i) {
161 (AttributeSaveInDataModel(pNode, attr) && !bSaveXML)) {
164 WideString wsAttr = WideString
::FromASCII(XFA_AttributeToName(attr)
);
165 wsAttrs += SaveAttribute(pNode, attr, wsAttr.AsStringView(), bSaveXML);
168 WideString wsChildren;
171 if (!bSaveXML && !ContentNodeNeedtoExport(pNode))
174 CXFA_Node* pRawValueNode = pNode->GetFirstChild();
175 while (pRawValueNode &&
179 pRawValueNode = pRawValueNode->GetNextSibling();
184 absl::optional<WideString> contentType =
185 pNode->JSObject()->TryAttribute(XFA_Attribute::ContentType,
false);
186 if (pRawValueNode->GetElementType() == XFA_Element::SharpxHTML &&
187 contentType.has_value() &&
188 contentType.value().EqualsASCII(
"text/html")) {
193 CFX_XMLNode* pRichTextXML = pExDataXML->GetFirstChild();
197 auto pMemStream = pdfium::MakeRetain<CFX_MemoryStream>();
200 WideString
::FromUTF8(ByteStringView(pMemStream->GetSpan()));
201 }
else if (pRawValueNode->GetElementType() == XFA_Element::Sharpxml &&
202 contentType.has_value() &&
203 contentType.value().EqualsASCII(
"text/xml")) {
204 absl::optional<WideString> rawValue =
205 pRawValueNode->JSObject()->TryAttribute(XFA_Attribute::Value,
207 if (!rawValue.has_value() || rawValue->IsEmpty())
210 std::vector<WideString> wsSelTextArray =
211 fxcrt::Split(rawValue.value(), L'\n');
213 CXFA_Node* pParentNode = pNode->GetParent();
214 CXFA_Node* pGrandparentNode = pParentNode->GetParent();
215 WideString bodyTagName =
218 bodyTagName
= L"ListBox1";
220 buf <<
"<" << bodyTagName <<
" xmlns=\"\">\n";
221 for (
const WideString& text : wsSelTextArray)
222 buf <<
"<value>" << ExportEncodeContent(text) <<
"</value>\n";
223 buf <<
"</" << bodyTagName <<
">\n";
229 wsChildren
+= ExportEncodeContent(wsValue);
236 WideString wsValue = pNode->JSObject()->GetCData(
XFA_Attribute::Value);
237 wsChildren
+= ExportEncodeContent(wsValue);
243 if (!pTemplateNode ||
249 WideTextBuffer newBuf;
250 CXFA_Node* pChildNode = pNode->GetFirstChild();
252 RegenerateFormFile_Changed(pChildNode, newBuf, bSaveXML);
255 pChildNode = pChildNode->GetNextSibling();
261 CXFA_Node* pChild = pNode->GetFirstChild();
263 RegenerateFormFile_Changed(pChild, newBuf, bSaveXML);
266 pChild = pChild->GetNextSibling();
274 WideString wsElement = WideString
::FromASCII(pNode->GetClassName()
);
277 buf << SaveAttribute(pNode,
XFA_Attribute::Name, L"name",
true);
282 buf <<
">\n" << wsChildren <<
"</" << wsElement <<
">\n";
287void RegenerateFormFile_Container(
CXFA_Node* pNode,
294 RegenerateFormFile_Changed(pNode, buf, bSaveXML);
295 size_t nLen = buf.GetLength();
297 pStream->WriteString(buf.MakeString().ToUTF8().AsStringView());
301 WideString wsElement = WideString
::FromASCII(pNode->GetClassName()
);
302 pStream->WriteString(
"<");
303 pStream->WriteString(wsElement.ToUTF8().AsStringView());
305 WideString wsOutput =
307 for (size_t i = 0;; ++i) {
314 WideString wsAttr = WideString
::FromASCII(XFA_AttributeToName(attr)
);
315 wsOutput += SaveAttribute(pNode, attr, wsAttr.AsStringView(),
false);
318 if (!wsOutput.IsEmpty())
319 pStream->WriteString(wsOutput.ToUTF8().AsStringView());
321 CXFA_Node* pChildNode = pNode->GetFirstChild();
323 pStream->WriteString(
" />\n");
327 pStream->WriteString(
">\n");
329 RegenerateFormFile_Container(pChildNode, pStream, bSaveXML);
330 pChildNode = pChildNode->GetNextSibling();
332 pStream->WriteString(
"</");
333 pStream->WriteString(wsElement.ToUTF8().AsStringView());
334 pStream->WriteString(
">\n");
337WideString RecognizeXFAVersionNumber(
CXFA_Node* pTemplateRoot) {
341 absl::optional<WideString> templateNS =
342 pTemplateRoot->JSObject()->TryNamespace();
343 if (!templateNS.has_value())
347 pTemplateRoot->GetDocument()->RecognizeXFAVersionNumber(
352 return WideString
::Format(L"%i.%i"
, eVersion / 100
, eVersion % 100
);
358 const auto* pNodeValue =
359 pNode->GetChild<CXFA_Value>(0,
XFA_Element::Value,
false);
363 CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
396 const WideString& wsQualifier,
397 WideString* wsNamespaceURI) {
402 WideString wsNSAttribute;
405 wsNSAttribute
= L"xmlns";
408 wsNSAttribute
= L"xmlns:"
+ wsQualifier;
410 for (
CFX_XMLNode* pParent = pNode; pParent != pFakeRoot;
411 pParent = pParent->GetParent()) {
426 int32_t iChildNum = 0;
427 for (
CXFA_Node* pChildNode = pDataNode->GetFirstChild(); pChildNode;
428 pChildNode = pChildNode->GetNextSibling()) {
449 pStream->WriteString(
"<form xmlns=\"");
450 pStream->WriteString(kFormNS);
452 WideString wsVersionNumber = RecognizeXFAVersionNumber(
455 wsVersionNumber
= L"2.8";
457 wsVersionNumber
+= L"/\">\n";
458 pStream->WriteString(wsVersionNumber.ToUTF8().AsStringView());
460 CXFA_Node* pChildNode = pNode->GetFirstChild();
462 RegenerateFormFile_Container(pChildNode, pStream,
false);
463 pChildNode = pChildNode->GetNextSibling();
465 pStream->WriteString(
"</form>\n");
467 RegenerateFormFile_Container(pNode, pStream, bSaveXML);
475 const auto* pUIChild =
476 pFieldNode->GetChild<CXFA_Ui>(0,
XFA_Element::Ui,
false);
480 CXFA_Node* pFirstChild = pUIChild->GetFirstChild();
486 return pFirstChild->JSObject()->GetEnum(
XFA_Attribute::Open) ==
491 nRotation = nRotation % 360;
492 nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
CFX_XMLElement * ToXMLElement(CFX_XMLNode *pNode)
bool HasAttribute(const WideString &name) const
WideString GetAttribute(const WideString &name) const
void SetAttribute(const WideString &name, const WideString &value)
void RemoveAttribute(const WideString &name)
virtual void Save(const RetainPtr< IFX_RetainableWriteStream > &pXMLStream)=0
CFX_XMLNode * GetXMLMappingNode() const
WideString GetRawValue() const
CXFA_Node * GetTemplateNodeIfExists() const
CXFA_Node * GetBindData()
XFA_FFWidgetType GetFFWidgetType()
XFA_Element GetElementType() const
CXFA_Document * GetDocument() const
XFA_ObjectType GetObjectType() const
bool IsContainerNode() const
WideString & operator+=(const WideString &str)
static WideString Format(const wchar_t *pFormat,...)
WideString & operator=(WideString &&that) noexcept
static WideString FromUTF8(ByteStringView str)
WideString & operator+=(const wchar_t *str)
static WideString FromASCII(ByteStringView str)
WideString & operator=(const wchar_t *str)
void AppendChar(wchar_t wch)
WideString MakeString() const
WideStringView AsStringView() const
WideString operator+(const wchar_t *str1, const WideString &str2)
void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node *pDataNode)
bool XFA_FDEExtension_ResolveNamespaceQualifier(CFX_XMLElement *pNode, const WideString &wsQualifier, WideString *wsNamespaceURI)
int32_t XFA_MapRotation(int32_t nRotation)
bool XFA_FieldIsMultiListBox(const CXFA_Node *pFieldNode)
void XFA_EventErrorAccumulate(XFA_EventError *pAcc, XFA_EventError eNew)
CXFA_LocaleValue XFA_GetLocaleValue(const CXFA_Node *pNode)
CXFA_LocaleValue::ValueType XFA_GetLocaleValueType(XFA_Element element)
void XFA_DataExporter_RegenerateFormFile(CXFA_Node *pNode, const RetainPtr< IFX_SeekableStream > &pStream, bool bSaveXML)