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