OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fxcrt/include/fx_ext.h" | 7 #include "core/fxcrt/include/fx_ext.h" |
8 #include "xfa/fxfa/app/xfa_ffnotify.h" | 8 #include "xfa/fxfa/app/xfa_ffnotify.h" |
9 #include "xfa/fxfa/parser/cscript_datawindow.h" | 9 #include "xfa/fxfa/parser/cscript_datawindow.h" |
10 #include "xfa/fxfa/parser/cscript_eventpseudomodel.h" | 10 #include "xfa/fxfa/parser/cscript_eventpseudomodel.h" |
11 #include "xfa/fxfa/parser/cscript_hostpseudomodel.h" | 11 #include "xfa/fxfa/parser/cscript_hostpseudomodel.h" |
12 #include "xfa/fxfa/parser/cscript_layoutpseudomodel.h" | 12 #include "xfa/fxfa/parser/cscript_layoutpseudomodel.h" |
13 #include "xfa/fxfa/parser/cscript_logpseudomodel.h" | 13 #include "xfa/fxfa/parser/cscript_logpseudomodel.h" |
14 #include "xfa/fxfa/parser/cscript_signaturepseudomodel.h" | 14 #include "xfa/fxfa/parser/cscript_signaturepseudomodel.h" |
| 15 #include "xfa/fxfa/parser/cxfa_document.h" |
15 #include "xfa/fxfa/parser/cxfa_document_parser.h" | 16 #include "xfa/fxfa/parser/cxfa_document_parser.h" |
16 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h" | 17 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h" |
17 #include "xfa/fxfa/parser/cxfa_scriptcontext.h" | 18 #include "xfa/fxfa/parser/cxfa_scriptcontext.h" |
18 #include "xfa/fxfa/parser/xfa_document.h" | |
19 #include "xfa/fxfa/parser/xfa_localemgr.h" | 19 #include "xfa/fxfa/parser/xfa_localemgr.h" |
20 #include "xfa/fxfa/parser/xfa_object.h" | 20 #include "xfa/fxfa/parser/xfa_object.h" |
21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" | 21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" |
22 #include "xfa/fxfa/parser/xfa_utils.h" | 22 #include "xfa/fxfa/parser/xfa_utils.h" |
23 | 23 |
| 24 namespace { |
| 25 |
| 26 void MergeNodeRecurse(CXFA_Document* pDocument, |
| 27 CXFA_Node* pDestNodeParent, |
| 28 CXFA_Node* pProtoNode) { |
| 29 CXFA_Node* pExistingNode = nullptr; |
| 30 for (CXFA_Node* pFormChild = |
| 31 pDestNodeParent->GetNodeItem(XFA_NODEITEM_FirstChild); |
| 32 pFormChild; |
| 33 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { |
| 34 if (pFormChild->GetElementType() == pProtoNode->GetElementType() && |
| 35 pFormChild->GetNameHash() == pProtoNode->GetNameHash() && |
| 36 pFormChild->IsUnusedNode()) { |
| 37 pFormChild->ClearFlag(XFA_NodeFlag_UnusedNode); |
| 38 pExistingNode = pFormChild; |
| 39 break; |
| 40 } |
| 41 } |
| 42 |
| 43 if (pExistingNode) { |
| 44 pExistingNode->SetTemplateNode(pProtoNode); |
| 45 for (CXFA_Node* pTemplateChild = |
| 46 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild); |
| 47 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( |
| 48 XFA_NODEITEM_NextSibling)) { |
| 49 MergeNodeRecurse(pDocument, pExistingNode, pTemplateChild); |
| 50 } |
| 51 return; |
| 52 } |
| 53 CXFA_Node* pNewNode = pProtoNode->Clone(TRUE); |
| 54 pNewNode->SetTemplateNode(pProtoNode); |
| 55 pDestNodeParent->InsertChild(pNewNode, nullptr); |
| 56 } |
| 57 |
| 58 void MergeNode(CXFA_Document* pDocument, |
| 59 CXFA_Node* pDestNode, |
| 60 CXFA_Node* pProtoNode) { |
| 61 { |
| 62 CXFA_NodeIterator sIterator(pDestNode); |
| 63 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; |
| 64 pNode = sIterator.MoveToNext()) { |
| 65 pNode->SetFlag(XFA_NodeFlag_UnusedNode, true); |
| 66 } |
| 67 } |
| 68 pDestNode->SetTemplateNode(pProtoNode); |
| 69 for (CXFA_Node* pTemplateChild = |
| 70 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild); |
| 71 pTemplateChild; |
| 72 pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { |
| 73 MergeNodeRecurse(pDocument, pDestNode, pTemplateChild); |
| 74 } |
| 75 { |
| 76 CXFA_NodeIterator sIterator(pDestNode); |
| 77 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; |
| 78 pNode = sIterator.MoveToNext()) { |
| 79 pNode->ClearFlag(XFA_NodeFlag_UnusedNode); |
| 80 } |
| 81 } |
| 82 } |
| 83 |
| 84 } // namespace |
| 85 |
24 CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser) | 86 CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser) |
25 : m_pParser(pParser), | 87 : m_pParser(pParser), |
26 m_pScriptContext(nullptr), | 88 m_pScriptContext(nullptr), |
27 m_pLayoutProcessor(nullptr), | 89 m_pLayoutProcessor(nullptr), |
28 m_pRootNode(nullptr), | 90 m_pRootNode(nullptr), |
29 m_pLocalMgr(nullptr), | 91 m_pLocalMgr(nullptr), |
30 m_pScriptDataWindow(nullptr), | 92 m_pScriptDataWindow(nullptr), |
31 m_pScriptEvent(nullptr), | 93 m_pScriptEvent(nullptr), |
32 m_pScriptHost(nullptr), | 94 m_pScriptHost(nullptr), |
33 m_pScriptLog(nullptr), | 95 m_pScriptLog(nullptr), |
34 m_pScriptLayout(nullptr), | 96 m_pScriptLayout(nullptr), |
35 m_pScriptSignature(nullptr), | 97 m_pScriptSignature(nullptr), |
36 m_eCurVersionMode(XFA_VERSION_DEFAULT), | 98 m_eCurVersionMode(XFA_VERSION_DEFAULT), |
37 m_dwDocFlags(0) { | 99 m_dwDocFlags(0) { |
38 ASSERT(m_pParser); | 100 ASSERT(m_pParser); |
39 } | 101 } |
| 102 |
40 CXFA_Document::~CXFA_Document() { | 103 CXFA_Document::~CXFA_Document() { |
41 delete m_pRootNode; | 104 delete m_pRootNode; |
42 PurgeNodes(); | 105 PurgeNodes(); |
43 } | 106 } |
44 | 107 |
45 void CXFA_Document::ClearLayoutData() { | 108 void CXFA_Document::ClearLayoutData() { |
46 delete m_pLayoutProcessor; | 109 delete m_pLayoutProcessor; |
47 m_pLayoutProcessor = nullptr; | 110 m_pLayoutProcessor = nullptr; |
48 delete m_pScriptContext; | 111 delete m_pScriptContext; |
49 m_pScriptContext = nullptr; | 112 m_pScriptContext = nullptr; |
50 delete m_pLocalMgr; | 113 delete m_pLocalMgr; |
51 m_pLocalMgr = nullptr; | 114 m_pLocalMgr = nullptr; |
52 delete m_pScriptDataWindow; | 115 delete m_pScriptDataWindow; |
53 m_pScriptDataWindow = nullptr; | 116 m_pScriptDataWindow = nullptr; |
54 delete m_pScriptEvent; | 117 delete m_pScriptEvent; |
55 m_pScriptEvent = nullptr; | 118 m_pScriptEvent = nullptr; |
56 delete m_pScriptHost; | 119 delete m_pScriptHost; |
57 m_pScriptHost = nullptr; | 120 m_pScriptHost = nullptr; |
58 delete m_pScriptLog; | 121 delete m_pScriptLog; |
59 m_pScriptLog = nullptr; | 122 m_pScriptLog = nullptr; |
60 delete m_pScriptLayout; | 123 delete m_pScriptLayout; |
61 m_pScriptLayout = nullptr; | 124 m_pScriptLayout = nullptr; |
62 delete m_pScriptSignature; | 125 delete m_pScriptSignature; |
63 m_pScriptSignature = nullptr; | 126 m_pScriptSignature = nullptr; |
64 } | 127 } |
65 | 128 |
66 void CXFA_Document::SetRoot(CXFA_Node* pNewRoot) { | 129 void CXFA_Document::SetRoot(CXFA_Node* pNewRoot) { |
67 if (m_pRootNode) { | 130 if (m_pRootNode) |
68 AddPurgeNode(m_pRootNode); | 131 AddPurgeNode(m_pRootNode); |
69 } | 132 |
70 m_pRootNode = pNewRoot; | 133 m_pRootNode = pNewRoot; |
71 RemovePurgeNode(pNewRoot); | 134 RemovePurgeNode(pNewRoot); |
72 } | 135 } |
73 | 136 |
74 CFDE_XMLDoc* CXFA_Document::GetXMLDoc() const { | 137 CFDE_XMLDoc* CXFA_Document::GetXMLDoc() const { |
75 return m_pParser->GetXMLDoc(); | 138 return m_pParser->GetXMLDoc(); |
76 } | 139 } |
77 | 140 |
78 CXFA_FFNotify* CXFA_Document::GetNotify() const { | 141 CXFA_FFNotify* CXFA_Document::GetNotify() const { |
79 return m_pParser->GetNotify(); | 142 return m_pParser->GetNotify(); |
80 } | 143 } |
81 | 144 |
82 CXFA_Object* CXFA_Document::GetXFAObject(XFA_HashCode dwNodeNameHash) { | 145 CXFA_Object* CXFA_Document::GetXFAObject(XFA_HashCode dwNodeNameHash) { |
83 switch (dwNodeNameHash) { | 146 switch (dwNodeNameHash) { |
84 case XFA_HASHCODE_Data: { | 147 case XFA_HASHCODE_Data: { |
85 CXFA_Node* pDatasetsNode = ToNode(GetXFAObject(XFA_HASHCODE_Datasets)); | 148 CXFA_Node* pDatasetsNode = ToNode(GetXFAObject(XFA_HASHCODE_Datasets)); |
86 if (!pDatasetsNode) { | 149 if (!pDatasetsNode) |
87 return nullptr; | 150 return nullptr; |
88 } | 151 |
89 for (CXFA_Node* pDatasetsChild = | 152 for (CXFA_Node* pDatasetsChild = |
90 pDatasetsNode->GetFirstChildByClass(XFA_Element::DataGroup); | 153 pDatasetsNode->GetFirstChildByClass(XFA_Element::DataGroup); |
91 pDatasetsChild; | 154 pDatasetsChild; |
92 pDatasetsChild = pDatasetsChild->GetNextSameClassSibling( | 155 pDatasetsChild = pDatasetsChild->GetNextSameClassSibling( |
93 XFA_Element::DataGroup)) { | 156 XFA_Element::DataGroup)) { |
94 if (pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data) { | 157 if (pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data) |
95 continue; | 158 continue; |
96 } | 159 |
97 CFX_WideString wsNamespaceURI; | 160 CFX_WideString wsNamespaceURI; |
98 if (!pDatasetsChild->TryNamespace(wsNamespaceURI)) { | 161 if (!pDatasetsChild->TryNamespace(wsNamespaceURI)) |
99 continue; | 162 continue; |
100 } | 163 |
101 CFX_WideString wsDatasetsURI; | 164 CFX_WideString wsDatasetsURI; |
102 if (!pDatasetsNode->TryNamespace(wsDatasetsURI)) { | 165 if (!pDatasetsNode->TryNamespace(wsDatasetsURI)) |
103 continue; | 166 continue; |
104 } | 167 if (wsNamespaceURI == wsDatasetsURI) |
105 if (wsNamespaceURI == wsDatasetsURI) { | |
106 return pDatasetsChild; | 168 return pDatasetsChild; |
107 } | |
108 } | 169 } |
109 return nullptr; | 170 return nullptr; |
110 } | 171 } |
111 case XFA_HASHCODE_Record: { | 172 case XFA_HASHCODE_Record: { |
112 CXFA_Node* pData = ToNode(GetXFAObject(XFA_HASHCODE_Data)); | 173 CXFA_Node* pData = ToNode(GetXFAObject(XFA_HASHCODE_Data)); |
113 return pData ? pData->GetFirstChildByClass(XFA_Element::DataGroup) | 174 return pData ? pData->GetFirstChildByClass(XFA_Element::DataGroup) |
114 : nullptr; | 175 : nullptr; |
115 } | 176 } |
116 case XFA_HASHCODE_DataWindow: { | 177 case XFA_HASHCODE_DataWindow: { |
117 if (!m_pScriptDataWindow) | 178 if (!m_pScriptDataWindow) |
(...skipping 22 matching lines...) Expand all Loading... |
140 } | 201 } |
141 case XFA_HASHCODE_Layout: { | 202 case XFA_HASHCODE_Layout: { |
142 if (!m_pScriptLayout) | 203 if (!m_pScriptLayout) |
143 m_pScriptLayout = new CScript_LayoutPseudoModel(this); | 204 m_pScriptLayout = new CScript_LayoutPseudoModel(this); |
144 return m_pScriptLayout; | 205 return m_pScriptLayout; |
145 } | 206 } |
146 default: | 207 default: |
147 return m_pRootNode->GetFirstChildByName(dwNodeNameHash); | 208 return m_pRootNode->GetFirstChildByName(dwNodeNameHash); |
148 } | 209 } |
149 } | 210 } |
| 211 |
150 CXFA_Node* CXFA_Document::CreateNode(uint32_t dwPacket, XFA_Element eElement) { | 212 CXFA_Node* CXFA_Document::CreateNode(uint32_t dwPacket, XFA_Element eElement) { |
151 return CreateNode(XFA_GetPacketByID(dwPacket), eElement); | 213 return CreateNode(XFA_GetPacketByID(dwPacket), eElement); |
152 } | 214 } |
153 | 215 |
154 CXFA_Node* CXFA_Document::CreateNode(const XFA_PACKETINFO* pPacket, | 216 CXFA_Node* CXFA_Document::CreateNode(const XFA_PACKETINFO* pPacket, |
155 XFA_Element eElement) { | 217 XFA_Element eElement) { |
156 if (!pPacket) | 218 if (!pPacket) |
157 return nullptr; | 219 return nullptr; |
158 | 220 |
159 const XFA_ELEMENTINFO* pElement = XFA_GetElementByID(eElement); | 221 const XFA_ELEMENTINFO* pElement = XFA_GetElementByID(eElement); |
(...skipping 17 matching lines...) Expand all Loading... |
177 } | 239 } |
178 | 240 |
179 void CXFA_Document::PurgeNodes() { | 241 void CXFA_Document::PurgeNodes() { |
180 for (CXFA_Node* pNode : m_PurgeNodes) | 242 for (CXFA_Node* pNode : m_PurgeNodes) |
181 delete pNode; | 243 delete pNode; |
182 | 244 |
183 m_PurgeNodes.clear(); | 245 m_PurgeNodes.clear(); |
184 } | 246 } |
185 | 247 |
186 void CXFA_Document::SetFlag(uint32_t dwFlag, FX_BOOL bOn) { | 248 void CXFA_Document::SetFlag(uint32_t dwFlag, FX_BOOL bOn) { |
187 if (bOn) { | 249 if (bOn) |
188 m_dwDocFlags |= dwFlag; | 250 m_dwDocFlags |= dwFlag; |
189 } else { | 251 else |
190 m_dwDocFlags &= ~dwFlag; | 252 m_dwDocFlags &= ~dwFlag; |
191 } | |
192 } | 253 } |
| 254 |
193 FX_BOOL CXFA_Document::IsInteractive() { | 255 FX_BOOL CXFA_Document::IsInteractive() { |
194 if (m_dwDocFlags & XFA_DOCFLAG_HasInteractive) { | 256 if (m_dwDocFlags & XFA_DOCFLAG_HasInteractive) |
195 return !!(m_dwDocFlags & XFA_DOCFLAG_Interactive); | 257 return !!(m_dwDocFlags & XFA_DOCFLAG_Interactive); |
196 } | 258 |
197 CXFA_Node* pConfig = ToNode(GetXFAObject(XFA_HASHCODE_Config)); | 259 CXFA_Node* pConfig = ToNode(GetXFAObject(XFA_HASHCODE_Config)); |
198 if (!pConfig) { | 260 if (!pConfig) |
199 return FALSE; | 261 return FALSE; |
200 } | 262 |
201 CFX_WideString wsInteractive; | 263 CFX_WideString wsInteractive; |
202 CXFA_Node* pPresent = pConfig->GetFirstChildByClass(XFA_Element::Present); | 264 CXFA_Node* pPresent = pConfig->GetFirstChildByClass(XFA_Element::Present); |
203 if (!pPresent) { | 265 if (!pPresent) |
204 return FALSE; | 266 return FALSE; |
205 } | 267 |
206 CXFA_Node* pPDF = pPresent->GetFirstChildByClass(XFA_Element::Pdf); | 268 CXFA_Node* pPDF = pPresent->GetFirstChildByClass(XFA_Element::Pdf); |
207 if (!pPDF) { | 269 if (!pPDF) |
208 return FALSE; | 270 return FALSE; |
209 } | 271 |
210 CXFA_Node* pInteractive = pPDF->GetChild(0, XFA_Element::Interactive); | 272 CXFA_Node* pInteractive = pPDF->GetChild(0, XFA_Element::Interactive); |
211 if (pInteractive) { | 273 if (pInteractive) { |
212 m_dwDocFlags |= XFA_DOCFLAG_HasInteractive; | 274 m_dwDocFlags |= XFA_DOCFLAG_HasInteractive; |
213 if (pInteractive->TryContent(wsInteractive) && | 275 if (pInteractive->TryContent(wsInteractive) && |
214 wsInteractive == FX_WSTRC(L"1")) { | 276 wsInteractive == FX_WSTRC(L"1")) { |
215 m_dwDocFlags |= XFA_DOCFLAG_Interactive; | 277 m_dwDocFlags |= XFA_DOCFLAG_Interactive; |
216 return TRUE; | 278 return TRUE; |
217 } | 279 } |
218 } | 280 } |
219 return FALSE; | 281 return FALSE; |
220 } | 282 } |
| 283 |
221 CXFA_LocaleMgr* CXFA_Document::GetLocalMgr() { | 284 CXFA_LocaleMgr* CXFA_Document::GetLocalMgr() { |
222 if (!m_pLocalMgr) { | 285 if (!m_pLocalMgr) { |
223 CFX_WideString wsLanguage; | 286 CFX_WideString wsLanguage; |
224 GetNotify()->GetAppProvider()->GetLanguage(wsLanguage); | 287 GetNotify()->GetAppProvider()->GetLanguage(wsLanguage); |
225 m_pLocalMgr = new CXFA_LocaleMgr( | 288 m_pLocalMgr = new CXFA_LocaleMgr( |
226 ToNode(GetXFAObject(XFA_HASHCODE_LocaleSet)), wsLanguage); | 289 ToNode(GetXFAObject(XFA_HASHCODE_LocaleSet)), wsLanguage); |
227 } | 290 } |
228 return m_pLocalMgr; | 291 return m_pLocalMgr; |
229 } | 292 } |
| 293 |
230 CXFA_ScriptContext* CXFA_Document::InitScriptContext(v8::Isolate* pIsolate) { | 294 CXFA_ScriptContext* CXFA_Document::InitScriptContext(v8::Isolate* pIsolate) { |
231 if (!m_pScriptContext) | 295 if (!m_pScriptContext) |
232 m_pScriptContext = new CXFA_ScriptContext(this); | 296 m_pScriptContext = new CXFA_ScriptContext(this); |
233 m_pScriptContext->Initialize(pIsolate); | 297 m_pScriptContext->Initialize(pIsolate); |
234 return m_pScriptContext; | 298 return m_pScriptContext; |
235 } | 299 } |
| 300 |
236 CXFA_ScriptContext* CXFA_Document::GetScriptContext() { | 301 CXFA_ScriptContext* CXFA_Document::GetScriptContext() { |
237 if (!m_pScriptContext) | 302 if (!m_pScriptContext) |
238 m_pScriptContext = new CXFA_ScriptContext(this); | 303 m_pScriptContext = new CXFA_ScriptContext(this); |
239 return m_pScriptContext; | 304 return m_pScriptContext; |
240 } | 305 } |
| 306 |
241 XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber( | 307 XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber( |
242 CFX_WideString& wsTemplateNS) { | 308 CFX_WideString& wsTemplateNS) { |
243 CFX_WideStringC wsTemplateURIPrefix = | 309 CFX_WideStringC wsTemplateURIPrefix = |
244 XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI; | 310 XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI; |
245 FX_STRSIZE nPrefixLength = wsTemplateURIPrefix.GetLength(); | 311 FX_STRSIZE nPrefixLength = wsTemplateURIPrefix.GetLength(); |
246 if (CFX_WideStringC(wsTemplateNS.c_str(), wsTemplateNS.GetLength()) != | 312 if (CFX_WideStringC(wsTemplateNS.c_str(), wsTemplateNS.GetLength()) != |
247 wsTemplateURIPrefix) { | 313 wsTemplateURIPrefix) { |
248 return XFA_VERSION_UNKNOWN; | 314 return XFA_VERSION_UNKNOWN; |
249 } | 315 } |
250 FX_STRSIZE nDotPos = wsTemplateNS.Find('.', nPrefixLength); | 316 FX_STRSIZE nDotPos = wsTemplateNS.Find('.', nPrefixLength); |
251 if (nDotPos == (FX_STRSIZE)-1) { | 317 if (nDotPos == (FX_STRSIZE)-1) |
252 return XFA_VERSION_UNKNOWN; | 318 return XFA_VERSION_UNKNOWN; |
253 } | 319 |
254 int8_t iMajor = FXSYS_wtoi( | 320 int8_t iMajor = FXSYS_wtoi( |
255 wsTemplateNS.Mid(nPrefixLength, nDotPos - nPrefixLength).c_str()); | 321 wsTemplateNS.Mid(nPrefixLength, nDotPos - nPrefixLength).c_str()); |
256 int8_t iMinor = FXSYS_wtoi( | 322 int8_t iMinor = FXSYS_wtoi( |
257 wsTemplateNS.Mid(nDotPos + 1, wsTemplateNS.GetLength() - nDotPos - 2) | 323 wsTemplateNS.Mid(nDotPos + 1, wsTemplateNS.GetLength() - nDotPos - 2) |
258 .c_str()); | 324 .c_str()); |
259 XFA_VERSION eVersion = (XFA_VERSION)((int32_t)iMajor * 100 + iMinor); | 325 XFA_VERSION eVersion = (XFA_VERSION)((int32_t)iMajor * 100 + iMinor); |
260 if (eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX) { | 326 if (eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX) |
261 return XFA_VERSION_UNKNOWN; | 327 return XFA_VERSION_UNKNOWN; |
262 } | 328 |
263 m_eCurVersionMode = eVersion; | 329 m_eCurVersionMode = eVersion; |
264 return eVersion; | 330 return eVersion; |
265 } | 331 } |
| 332 |
266 CXFA_Node* CXFA_Document::GetNodeByID(CXFA_Node* pRoot, | 333 CXFA_Node* CXFA_Document::GetNodeByID(CXFA_Node* pRoot, |
267 const CFX_WideStringC& wsID) { | 334 const CFX_WideStringC& wsID) { |
268 if (!pRoot || wsID.IsEmpty()) { | 335 if (!pRoot || wsID.IsEmpty()) |
269 return nullptr; | 336 return nullptr; |
270 } | 337 |
271 CXFA_NodeIterator sIterator(pRoot); | 338 CXFA_NodeIterator sIterator(pRoot); |
272 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; | 339 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; |
273 pNode = sIterator.MoveToNext()) { | 340 pNode = sIterator.MoveToNext()) { |
274 CFX_WideStringC wsIDVal; | 341 CFX_WideStringC wsIDVal; |
275 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) { | 342 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) { |
276 if (wsIDVal == wsID) { | 343 if (wsIDVal == wsID) |
277 return pNode; | 344 return pNode; |
278 } | |
279 } | 345 } |
280 } | 346 } |
281 return nullptr; | 347 return nullptr; |
282 } | 348 } |
283 static void XFA_ProtoMerge_MergeNodeRecurse(CXFA_Document* pDocument, | 349 |
284 CXFA_Node* pDestNodeParent, | |
285 CXFA_Node* pProtoNode) { | |
286 CXFA_Node* pExistingNode = nullptr; | |
287 for (CXFA_Node* pFormChild = | |
288 pDestNodeParent->GetNodeItem(XFA_NODEITEM_FirstChild); | |
289 pFormChild; | |
290 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
291 if (pFormChild->GetElementType() == pProtoNode->GetElementType() && | |
292 pFormChild->GetNameHash() == pProtoNode->GetNameHash() && | |
293 pFormChild->IsUnusedNode()) { | |
294 pFormChild->ClearFlag(XFA_NodeFlag_UnusedNode); | |
295 pExistingNode = pFormChild; | |
296 break; | |
297 } | |
298 } | |
299 if (pExistingNode) { | |
300 pExistingNode->SetTemplateNode(pProtoNode); | |
301 for (CXFA_Node* pTemplateChild = | |
302 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
303 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( | |
304 XFA_NODEITEM_NextSibling)) { | |
305 XFA_ProtoMerge_MergeNodeRecurse(pDocument, pExistingNode, pTemplateChild); | |
306 } | |
307 return; | |
308 } | |
309 CXFA_Node* pNewNode = pProtoNode->Clone(TRUE); | |
310 pNewNode->SetTemplateNode(pProtoNode); | |
311 pDestNodeParent->InsertChild(pNewNode, nullptr); | |
312 } | |
313 static void XFA_ProtoMerge_MergeNode(CXFA_Document* pDocument, | |
314 CXFA_Node* pDestNode, | |
315 CXFA_Node* pProtoNode) { | |
316 { | |
317 CXFA_NodeIterator sIterator(pDestNode); | |
318 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; | |
319 pNode = sIterator.MoveToNext()) { | |
320 pNode->SetFlag(XFA_NodeFlag_UnusedNode, true); | |
321 } | |
322 } | |
323 pDestNode->SetTemplateNode(pProtoNode); | |
324 for (CXFA_Node* pTemplateChild = | |
325 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
326 pTemplateChild; | |
327 pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
328 XFA_ProtoMerge_MergeNodeRecurse(pDocument, pDestNode, pTemplateChild); | |
329 } | |
330 { | |
331 CXFA_NodeIterator sIterator(pDestNode); | |
332 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; | |
333 pNode = sIterator.MoveToNext()) { | |
334 pNode->ClearFlag(XFA_NodeFlag_UnusedNode); | |
335 } | |
336 } | |
337 } | |
338 void CXFA_Document::DoProtoMerge() { | 350 void CXFA_Document::DoProtoMerge() { |
339 CXFA_Node* pTemplateRoot = ToNode(GetXFAObject(XFA_HASHCODE_Template)); | 351 CXFA_Node* pTemplateRoot = ToNode(GetXFAObject(XFA_HASHCODE_Template)); |
340 if (!pTemplateRoot) { | 352 if (!pTemplateRoot) |
341 return; | 353 return; |
342 } | 354 |
343 CFX_MapPtrTemplate<uint32_t, CXFA_Node*> mIDMap; | 355 CFX_MapPtrTemplate<uint32_t, CXFA_Node*> mIDMap; |
344 CXFA_NodeSet sUseNodes; | 356 CXFA_NodeSet sUseNodes; |
345 CXFA_NodeIterator sIterator(pTemplateRoot); | 357 CXFA_NodeIterator sIterator(pTemplateRoot); |
346 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; | 358 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; |
347 pNode = sIterator.MoveToNext()) { | 359 pNode = sIterator.MoveToNext()) { |
348 CFX_WideStringC wsIDVal; | 360 CFX_WideStringC wsIDVal; |
349 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) { | 361 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) { |
350 mIDMap[FX_HashCode_GetW(wsIDVal, false)] = pNode; | 362 mIDMap[FX_HashCode_GetW(wsIDVal, false)] = pNode; |
351 } | 363 } |
352 CFX_WideStringC wsUseVal; | 364 CFX_WideStringC wsUseVal; |
353 if (pNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) { | 365 if (pNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) { |
354 sUseNodes.insert(pNode); | 366 sUseNodes.insert(pNode); |
355 } else if (pNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && | 367 } else if (pNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && |
356 !wsUseVal.IsEmpty()) { | 368 !wsUseVal.IsEmpty()) { |
357 sUseNodes.insert(pNode); | 369 sUseNodes.insert(pNode); |
358 } | 370 } |
359 } | 371 } |
| 372 |
360 for (CXFA_Node* pUseHrefNode : sUseNodes) { | 373 for (CXFA_Node* pUseHrefNode : sUseNodes) { |
361 CFX_WideString wsUseVal; | 374 CFX_WideString wsUseVal; |
362 CFX_WideStringC wsURI, wsID, wsSOM; | 375 CFX_WideStringC wsURI, wsID, wsSOM; |
363 if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && | 376 if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && |
364 !wsUseVal.IsEmpty()) { | 377 !wsUseVal.IsEmpty()) { |
365 FX_STRSIZE uSharpPos = wsUseVal.Find('#'); | 378 FX_STRSIZE uSharpPos = wsUseVal.Find('#'); |
366 if (uSharpPos < 0) { | 379 if (uSharpPos < 0) { |
367 wsURI = wsUseVal.AsStringC(); | 380 wsURI = wsUseVal.AsStringC(); |
368 } else { | 381 } else { |
369 wsURI = CFX_WideStringC(wsUseVal.c_str(), uSharpPos); | 382 wsURI = CFX_WideStringC(wsUseVal.c_str(), uSharpPos); |
370 FX_STRSIZE uLen = wsUseVal.GetLength(); | 383 FX_STRSIZE uLen = wsUseVal.GetLength(); |
371 if (uLen >= uSharpPos + 5 && | 384 if (uLen >= uSharpPos + 5 && |
372 CFX_WideStringC(wsUseVal.c_str() + uSharpPos, 5) == | 385 CFX_WideStringC(wsUseVal.c_str() + uSharpPos, 5) == |
373 FX_WSTRC(L"#som(") && | 386 FX_WSTRC(L"#som(") && |
374 wsUseVal[uLen - 1] == ')') { | 387 wsUseVal[uLen - 1] == ')') { |
375 wsSOM = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 5, | 388 wsSOM = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 5, |
376 uLen - 1 - uSharpPos - 5); | 389 uLen - 1 - uSharpPos - 5); |
377 } else { | 390 } else { |
378 wsID = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 1, | 391 wsID = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 1, |
379 uLen - uSharpPos - 1); | 392 uLen - uSharpPos - 1); |
380 } | 393 } |
381 } | 394 } |
382 } else if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && | 395 } else if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && |
383 !wsUseVal.IsEmpty()) { | 396 !wsUseVal.IsEmpty()) { |
384 if (wsUseVal[0] == '#') { | 397 if (wsUseVal[0] == '#') |
385 wsID = CFX_WideStringC(wsUseVal.c_str() + 1, wsUseVal.GetLength() - 1); | 398 wsID = CFX_WideStringC(wsUseVal.c_str() + 1, wsUseVal.GetLength() - 1); |
386 } else { | 399 else |
387 wsSOM = CFX_WideStringC(wsUseVal.c_str(), wsUseVal.GetLength()); | 400 wsSOM = CFX_WideStringC(wsUseVal.c_str(), wsUseVal.GetLength()); |
388 } | |
389 } | 401 } |
390 if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L".")) { | 402 |
| 403 if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L".")) |
391 continue; | 404 continue; |
392 } | 405 |
393 CXFA_Node* pProtoNode = nullptr; | 406 CXFA_Node* pProtoNode = nullptr; |
394 if (!wsSOM.IsEmpty()) { | 407 if (!wsSOM.IsEmpty()) { |
395 uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | | 408 uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | |
396 XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | | 409 XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | |
397 XFA_RESOLVENODE_Siblings; | 410 XFA_RESOLVENODE_Siblings; |
398 XFA_RESOLVENODE_RS resoveNodeRS; | 411 XFA_RESOLVENODE_RS resoveNodeRS; |
399 int32_t iRet = m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM, | 412 int32_t iRet = m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM, |
400 resoveNodeRS, dwFlag); | 413 resoveNodeRS, dwFlag); |
401 if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) { | 414 if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) { |
402 pProtoNode = resoveNodeRS.nodes[0]->AsNode(); | 415 pProtoNode = resoveNodeRS.nodes[0]->AsNode(); |
403 } | 416 } |
404 } else if (!wsID.IsEmpty()) { | 417 } else if (!wsID.IsEmpty()) { |
405 if (!mIDMap.Lookup(FX_HashCode_GetW(wsID, false), pProtoNode)) { | 418 if (!mIDMap.Lookup(FX_HashCode_GetW(wsID, false), pProtoNode)) { |
406 continue; | 419 continue; |
407 } | 420 } |
408 } | 421 } |
409 if (!pProtoNode) { | 422 if (!pProtoNode) |
410 continue; | 423 continue; |
411 } | 424 |
412 XFA_ProtoMerge_MergeNode(this, pUseHrefNode, pProtoNode); | 425 MergeNode(this, pUseHrefNode, pProtoNode); |
413 } | 426 } |
414 } | 427 } |
OLD | NEW |