CXFA_Node* XFA_DataDescription_MaybeCreateDataNode(
    CXFA_Document* pDocument,
    CXFA_Node* pDataParent,
    XFA_Element eNodeType,
    const CFX_WideString& wsName) {
  if (!pDataParent) {
    return nullptr;
  }
  CXFA_Node* pParentDDNode = pDataParent->GetDataDescriptionNode();
  if (!pParentDDNode) {
    CXFA_Node* pDataNode =
        pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
    ASSERT(pDataNode);
    pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
    pDataNode->CreateXMLMappingNode();
    pDataParent->InsertChild(pDataNode);
    pDataNode->SetFlag(XFA_NodeFlag_Initialized, false);
    return pDataNode;
  } else {
    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup>
        sIterator(pParentDDNode);
    for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
         pDDGroupNode = sIterator.MoveToNext()) {
      if (pDDGroupNode != pParentDDNode) {
        if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup) {
          continue;
        }
        CFX_WideString wsNamespace;
        if (!pDDGroupNode->TryNamespace(wsNamespace) ||
            wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
          continue;
        }
      }
      CXFA_Node* pDDNode =
          pDDGroupNode->GetFirstChildByName(wsName.AsStringC());
      if (!pDDNode) {
        continue;
      }
      if (pDDNode->GetElementType() != eNodeType) {
        break;
      }
      CXFA_Node* pDataNode =
          pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
      ASSERT(pDataNode);
      pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
      pDataNode->CreateXMLMappingNode();
      if (eNodeType == XFA_Element::DataValue &&
          pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) ==
              XFA_ATTRIBUTEENUM_MetaData) {
        pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData);
      }
      pDataParent->InsertChild(pDataNode);
      pDataNode->SetDataDescriptionNode(pDDNode);
      pDataNode->SetFlag(XFA_NodeFlag_Initialized, false);
      return pDataNode;
    }
    return nullptr;
  }
}
Beispiel #2
0
void CJX_Field::defaultValue(CFXJSE_Value* pValue,
                             bool bSetting,
                             XFA_Attribute eAttribute) {
  CXFA_Node* xfaNode = GetXFANode();
  if (!xfaNode->IsWidgetReady())
    return;

  if (bSetting) {
    if (pValue) {
      xfaNode->SetPreNull(xfaNode->IsNull());
      xfaNode->SetIsNull(pValue->IsNull());
    }

    WideString wsNewText;
    if (pValue && !(pValue->IsNull() || pValue->IsUndefined()))
      wsNewText = pValue->ToWideString();
    if (xfaNode->GetUIChildNode()->GetElementType() == XFA_Element::NumericEdit)
      wsNewText = xfaNode->NumericLimit(wsNewText);

    CXFA_Node* pContainerNode = xfaNode->GetContainerNode();
    WideString wsFormatText(wsNewText);
    if (pContainerNode)
      wsFormatText = pContainerNode->GetFormatDataValue(wsNewText);

    SetContent(wsNewText, wsFormatText, true, true, true);
    return;
  }

  WideString content = GetContent(true);
  if (content.IsEmpty()) {
    pValue->SetNull();
    return;
  }

  CXFA_Node* formValue = xfaNode->GetFormValueIfExists();
  CXFA_Node* pNode = formValue ? formValue->GetFirstChild() : nullptr;
  if (pNode && pNode->GetElementType() == XFA_Element::Decimal) {
    if (xfaNode->GetUIChildNode()->GetElementType() ==
            XFA_Element::NumericEdit &&
        (pNode->JSObject()->GetInteger(XFA_Attribute::FracDigits) == -1)) {
      pValue->SetString(content.ToUTF8().AsStringView());
    } else {
      CFX_Decimal decimal(content.AsStringView());
      pValue->SetFloat((float)(double)decimal);
    }
  } else if (pNode && pNode->GetElementType() == XFA_Element::Integer) {
    pValue->SetInteger(FXSYS_wtoi(content.c_str()));
  } else if (pNode && pNode->GetElementType() == XFA_Element::Boolean) {
    pValue->SetBoolean(FXSYS_wtoi(content.c_str()) == 0 ? false : true);
  } else if (pNode && pNode->GetElementType() == XFA_Element::Float) {
    CFX_Decimal decimal(content.AsStringView());
    pValue->SetFloat((float)(double)decimal);
  } else {
    pValue->SetString(content.ToUTF8().AsStringView());
  }
}
Beispiel #3
0
int32_t CXFA_NodeHelper::CountSiblings(CXFA_Node* pNode,
                                       XFA_LOGIC_TYPE eLogicType,
                                       CXFA_NodeArray* pSiblings,
                                       FX_BOOL bIsClassName) {
  if (!pNode)
    return 0;
  CXFA_Node* parent = ResolveNodes_GetParent(pNode, XFA_LOGIC_NoTransparent);
  if (!parent)
    return 0;
  const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
      parent->GetElementType(), pNode->GetElementType(), XFA_XDPPACKET_UNKNOWN);
  if (!pProperty && eLogicType == XFA_LOGIC_Transparent) {
    parent = ResolveNodes_GetParent(pNode, XFA_LOGIC_Transparent);
    if (!parent) {
      return 0;
    }
  }
  if (bIsClassName) {
    return NodeAcc_TraverseSiblings(parent, pNode->GetClassHashCode(),
                                    pSiblings, eLogicType, bIsClassName);
  } else {
    return NodeAcc_TraverseSiblings(parent, pNode->GetNameHash(), pSiblings,
                                    eLogicType, bIsClassName);
  }
}
Beispiel #4
0
FX_BOOL CXFA_NodeHelper::NodeIsProperty(CXFA_Node* refNode) {
  CXFA_Node* parent = ResolveNodes_GetParent(refNode, XFA_LOGIC_NoTransparent);
  return parent && refNode &&
         XFA_GetPropertyOfElement(parent->GetElementType(),
                                  refNode->GetElementType(),
                                  XFA_XDPPACKET_UNKNOWN);
}
Beispiel #5
0
void CXFA_FFDocView::ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc) {
  m_bLayoutEvent = TRUE;
  FX_BOOL bChanged = FALSE;
  CXFA_Node* pFormNode = nullptr;
  if (pWidgetAcc) {
    bChanged = ResetSingleWidgetAccData(pWidgetAcc);
    pFormNode = pWidgetAcc->GetNode();
  } else {
    pFormNode = GetRootSubform();
  }
  if (!pFormNode) {
    return;
  }
  if (pFormNode->GetElementType() != XFA_Element::Field &&
      pFormNode->GetElementType() != XFA_Element::ExclGroup) {
    CXFA_WidgetAccIterator Iterator(this, pFormNode);
    while (CXFA_WidgetAcc* pAcc = Iterator.MoveToNext()) {
      bChanged |= ResetSingleWidgetAccData(pAcc);
      if (pAcc->GetNode()->GetElementType() == XFA_Element::ExclGroup) {
        Iterator.SkipTree();
      }
    }
  }
  if (bChanged) {
    m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc);
  }
}
FX_BOOL CXFA_ScriptContext::RunVariablesScript(CXFA_Node* pScriptNode) {
  if (!pScriptNode)
    return FALSE;

  if (pScriptNode->GetElementType() != XFA_Element::Script)
    return TRUE;

  CXFA_Node* pParent = pScriptNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (!pParent || pParent->GetElementType() != XFA_Element::Variables)
    return FALSE;

  if (m_mapVariableToContext.GetValueAt(pScriptNode))
    return TRUE;

  CXFA_Node* pTextNode = pScriptNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  if (!pTextNode)
    return FALSE;

  CFX_WideStringC wsScript;
  if (!pTextNode->TryCData(XFA_ATTRIBUTE_Value, wsScript))
    return FALSE;

  CFX_ByteString btScript =
      FX_UTF8Encode(wsScript.c_str(), wsScript.GetLength());
  std::unique_ptr<CFXJSE_Value> hRetValue(new CFXJSE_Value(m_pIsolate));
  CXFA_Node* pThisObject = pParent->GetNodeItem(XFA_NODEITEM_Parent);
  CFXJSE_Context* pVariablesContext =
      CreateVariablesContext(pScriptNode, pThisObject);
  CXFA_Object* pOriginalObject = m_pThisObject;
  m_pThisObject = pThisObject;
  FX_BOOL bRet =
      pVariablesContext->ExecuteScript(btScript.c_str(), hRetValue.get());
  m_pThisObject = pOriginalObject;
  return bRet;
}
uint32_t CXFA_FFField::UpdateUIProperty() {
  CXFA_Node* pUiNode = m_pDataAcc->GetUIChild();
  uint32_t dwStyle = 0;
  if (pUiNode && pUiNode->GetElementType() == XFA_Element::DefaultUi) {
    dwStyle = FWL_STYLEEXT_EDT_ReadOnly;
  }
  return dwStyle;
}
Beispiel #8
0
XFA_Element CXFA_Fill::GetFillType() {
    CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    while (pChild) {
        XFA_Element eType = pChild->GetElementType();
        if (eType != XFA_Element::Color && eType != XFA_Element::Extras)
            return eType;

        pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    return XFA_Element::Solid;
}
Beispiel #9
0
FX_BOOL CXFA_FFDocView::ResetSingleWidgetAccData(CXFA_WidgetAcc* pWidgetAcc) {
  CXFA_Node* pNode = pWidgetAcc->GetNode();
  XFA_Element eType = pNode->GetElementType();
  if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup) {
    return FALSE;
  }
  pWidgetAcc->ResetData();
  pWidgetAcc->UpdateUIDisplay();
  if (CXFA_Validate validate = pWidgetAcc->GetValidate()) {
    AddValidateWidget(pWidgetAcc);
    validate.GetNode()->SetFlag(XFA_NodeFlag_NeedsInitApp, false);
  }
  return TRUE;
}
void CXFA_ScriptContext::NormalPropertySetter(CFXJSE_Value* pOriginalValue,
                                              const CFX_ByteStringC& szPropName,
                                              CFXJSE_Value* pReturnValue) {
  CXFA_Object* pOriginalObject = ToObject(pOriginalValue, nullptr);
  if (!pOriginalObject)
    return;

  CXFA_ScriptContext* lpScriptContext =
      pOriginalObject->GetDocument()->GetScriptContext();
  CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOriginalObject);
  CFX_WideString wsPropName = CFX_WideString::FromUTF8(szPropName);
  const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo = XFA_GetScriptAttributeByName(
      pObject->GetElementType(), wsPropName.AsStringC());
  if (lpAttributeInfo) {
    (pObject->*(lpAttributeInfo->lpfnCallback))(
        pReturnValue, TRUE, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
  } else {
    if (pObject->IsNode()) {
      if (wsPropName.GetAt(0) == '#') {
        wsPropName = wsPropName.Right(wsPropName.GetLength() - 1);
      }
      CXFA_Node* pNode = ToNode(pObject);
      CXFA_Node* pPropOrChild = nullptr;
      XFA_Element eType = XFA_GetElementTypeForName(wsPropName.AsStringC());
      if (eType != XFA_Element::Unknown)
        pPropOrChild = pNode->GetProperty(0, eType);
      else
        pPropOrChild = pNode->GetFirstChildByName(wsPropName.AsStringC());

      if (pPropOrChild) {
        CFX_WideString wsDefaultName(L"{default}");
        const XFA_SCRIPTATTRIBUTEINFO* lpAttrInfo =
            XFA_GetScriptAttributeByName(pPropOrChild->GetElementType(),
                                         wsDefaultName.AsStringC());
        if (lpAttrInfo) {
          (pPropOrChild->*(lpAttrInfo->lpfnCallback))(
              pReturnValue, TRUE, (XFA_ATTRIBUTE)lpAttrInfo->eAttribute);
          return;
        }
      }
    }
    CXFA_Object* pScriptObject =
        lpScriptContext->GetVariablesThis(pOriginalObject, TRUE);
    if (pScriptObject) {
      lpScriptContext->QueryVariableValue(ToNode(pScriptObject), szPropName,
                                          pReturnValue, FALSE);
    }
  }
}
void XFA_DataDescription_UpdateDataRelation(CXFA_Node* pDataNode,
                                            CXFA_Node* pDataDescriptionNode) {
  ASSERT(pDataDescriptionNode);
  for (CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
       pDataChild;
       pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    uint32_t dwNameHash = pDataChild->GetNameHash();
    if (!dwNameHash)
      continue;

    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup>
        sIterator(pDataDescriptionNode);
    for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
         pDDGroupNode = sIterator.MoveToNext()) {
      if (pDDGroupNode != pDataDescriptionNode) {
        if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup)
          continue;

        CFX_WideString wsNamespace;
        if (!pDDGroupNode->TryNamespace(wsNamespace) ||
            wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
          continue;
        }
      }
      CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash);
      if (!pDDNode)
        continue;
      if (pDDNode->GetElementType() != pDataChild->GetElementType())
        break;

      pDataChild->SetDataDescriptionNode(pDDNode);
      XFA_DataDescription_UpdateDataRelation(pDataChild, pDDNode);
      break;
    }
  }
}
Beispiel #12
0
int32_t CXFA_FFDocView::ExecEventActivityByDeepFirst(CXFA_Node* pFormNode,
                                                     XFA_EVENTTYPE eEventType,
                                                     FX_BOOL bIsFormReady,
                                                     FX_BOOL bRecursive,
                                                     CXFA_Node* pExclude) {
  int32_t iRet = XFA_EVENTERROR_NotExist;
  if (pFormNode == pExclude) {
    return iRet;
  }
  XFA_Element elementType = pFormNode->GetElementType();
  if (elementType == XFA_Element::Field) {
    if (eEventType == XFA_EVENT_IndexChange) {
      return iRet;
    }
    CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
    if (!pWidgetAcc) {
      return iRet;
    }
    CXFA_EventParam eParam;
    eParam.m_eType = eEventType;
    eParam.m_pTarget = pWidgetAcc;
    eParam.m_bIsFormReady = bIsFormReady;
    return XFA_ProcessEvent(this, pWidgetAcc, &eParam);
  }
  if (bRecursive) {
    for (CXFA_Node* pNode = pFormNode->GetNodeItem(
             XFA_NODEITEM_FirstChild, XFA_ObjectType::ContainerNode);
         pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling,
                                           XFA_ObjectType::ContainerNode)) {
      elementType = pNode->GetElementType();
      if (elementType != XFA_Element::Variables &&
          elementType != XFA_Element::Draw) {
        iRet |= ExecEventActivityByDeepFirst(pNode, eEventType, bIsFormReady,
                                             bRecursive, pExclude);
      }
    }
  }
  CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
  if (!pWidgetAcc) {
    return iRet;
  }
  CXFA_EventParam eParam;
  eParam.m_eType = eEventType;
  eParam.m_pTarget = pWidgetAcc;
  eParam.m_bIsFormReady = bIsFormReady;
  iRet |= XFA_ProcessEvent(this, pWidgetAcc, &eParam);
  return iRet;
}
Beispiel #13
0
CXFA_Node* CXFA_NodeHelper::ResolveNodes_GetParent(CXFA_Node* pNode,
                                                   XFA_LOGIC_TYPE eLogicType) {
  if (!pNode) {
    return nullptr;
  }
  if (eLogicType == XFA_LOGIC_NoTransparent) {
    return pNode->GetNodeItem(XFA_NODEITEM_Parent);
  }
  CXFA_Node* parent;
  CXFA_Node* node = pNode;
  while (TRUE) {
    parent = ResolveNodes_GetParent(node);
    if (!parent) {
      break;
    }
    XFA_Element parentType = parent->GetElementType();
    if ((!parent->IsUnnamed() && parentType != XFA_Element::SubformSet) ||
        parentType == XFA_Element::Variables) {
      break;
    }
    node = parent;
  }
  return parent;
}
FX_BOOL CXFA_ScriptContext::QueryVariableValue(
    CXFA_Node* pScriptNode,
    const CFX_ByteStringC& szPropName,
    CFXJSE_Value* pValue,
    FX_BOOL bGetter) {
  if (!pScriptNode || pScriptNode->GetElementType() != XFA_Element::Script)
    return FALSE;

  CXFA_Node* variablesNode = pScriptNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (!variablesNode ||
      variablesNode->GetElementType() != XFA_Element::Variables)
    return FALSE;

  void* lpVariables = m_mapVariableToContext.GetValueAt(pScriptNode);
  if (!lpVariables)
    return FALSE;

  FX_BOOL bRes = FALSE;
  CFXJSE_Context* pVariableContext = static_cast<CFXJSE_Context*>(lpVariables);
  std::unique_ptr<CFXJSE_Value> pObject = pVariableContext->GetGlobalObject();
  std::unique_ptr<CFXJSE_Value> hVariableValue(new CFXJSE_Value(m_pIsolate));
  if (!bGetter) {
    pObject->SetObjectOwnProperty(szPropName, pValue);
    bRes = TRUE;
  } else if (pObject->HasObjectOwnProperty(szPropName, FALSE)) {
    pObject->GetObjectProperty(szPropName, hVariableValue.get());
    if (hVariableValue->IsFunction())
      pValue->SetFunctionBind(hVariableValue.get(), pObject.get());
    else if (bGetter)
      pValue->Assign(hVariableValue.get());
    else
      hVariableValue.get()->Assign(pValue);
    bRes = TRUE;
  }
  return bRes;
}
Beispiel #15
0
int32_t CXFA_NodeHelper::NodeAcc_TraverseSiblings(CXFA_Node* parent,
                                                  uint32_t dNameHash,
                                                  CXFA_NodeArray* pSiblings,
                                                  XFA_LOGIC_TYPE eLogicType,
                                                  FX_BOOL bIsClassName,
                                                  FX_BOOL bIsFindProperty) {
  if (!parent || !pSiblings) {
    return 0;
  }
  int32_t nCount = 0;
  int32_t i = 0;
  if (bIsFindProperty) {
    CXFA_NodeArray properties;
    parent->GetNodeList(properties, XFA_NODEFILTER_Properties);
    int32_t nProperties = properties.GetSize();
    for (i = 0; i < nProperties; ++i) {
      CXFA_Node* child = properties[i];
      if (bIsClassName) {
        if (child->GetClassHashCode() == dNameHash) {
          pSiblings->Add(child);
          nCount++;
        }
      } else {
        if (child->GetNameHash() == dNameHash) {
          if (child->GetElementType() != XFA_Element::PageSet &&
              child->GetElementType() != XFA_Element::Extras &&
              child->GetElementType() != XFA_Element::Items) {
            pSiblings->Add(child);
            nCount++;
          }
        }
      }
      if (child->IsUnnamed() &&
          child->GetElementType() == XFA_Element::PageSet) {
        nCount += NodeAcc_TraverseSiblings(child, dNameHash, pSiblings,
                                           eLogicType, bIsClassName, FALSE);
      }
    }
    if (nCount > 0) {
      return nCount;
    }
  }
  CXFA_NodeArray children;
  parent->GetNodeList(children, XFA_NODEFILTER_Children);
  int32_t nChildren = children.GetSize();
  for (i = 0; i < nChildren; i++) {
    CXFA_Node* child = children[i];
    if (child->GetElementType() == XFA_Element::Variables) {
      continue;
    }
    if (bIsClassName) {
      if (child->GetClassHashCode() == dNameHash) {
        if (pSiblings) {
          pSiblings->Add(child);
        }
        nCount++;
      }
    } else {
      if (child->GetNameHash() == dNameHash) {
        if (pSiblings) {
          pSiblings->Add(child);
        }
        nCount++;
      }
    }
    if (eLogicType == XFA_LOGIC_NoTransparent) {
      continue;
    }
    if (NodeIsTransparent(child) &&
        child->GetElementType() != XFA_Element::PageSet) {
      nCount += NodeAcc_TraverseSiblings(child, dNameHash, pSiblings,
                                         eLogicType, bIsClassName, FALSE);
    }
  }
  return nCount;
}
Beispiel #16
0
CXFA_Node* CXFA_TextProvider::GetTextNode(bool& bRichText) {
  bRichText = false;

  if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
    CXFA_Value* pValueNode =
        m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
    if (!pValueNode)
      return nullptr;

    CXFA_Node* pChildNode = pValueNode->GetFirstChild();
    if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) {
      Optional<WideString> contentType = pChildNode->JSObject()->TryAttribute(
          XFA_Attribute::ContentType, false);
      if (contentType.has_value() &&
          contentType.value().EqualsASCII("text/html")) {
        bRichText = true;
      }
    }
    return pChildNode;
  }

  if (m_eType == XFA_TEXTPROVIDERTYPE_Datasets) {
    CXFA_Node* pBind = m_pNode->GetBindData();
    CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
    for (CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild(); pXMLChild;
         pXMLChild = pXMLChild->GetNextSibling()) {
      CFX_XMLElement* pElement = ToXMLElement(pXMLChild);
      if (pElement && XFA_RecognizeRichText(pElement)) {
        bRichText = true;
        break;
      }
    }
    return pBind;
  }

  if (m_eType == XFA_TEXTPROVIDERTYPE_Caption) {
    CXFA_Caption* pCaptionNode =
        m_pNode->GetChild<CXFA_Caption>(0, XFA_Element::Caption, false);
    if (!pCaptionNode)
      return nullptr;

    CXFA_Value* pValueNode =
        pCaptionNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
    if (!pValueNode)
      return nullptr;

    CXFA_Node* pChildNode = pValueNode->GetFirstChild();
    if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) {
      Optional<WideString> contentType = pChildNode->JSObject()->TryAttribute(
          XFA_Attribute::ContentType, false);
      if (contentType.has_value() &&
          contentType.value().EqualsASCII("text/html")) {
        bRichText = true;
      }
    }
    return pChildNode;
  }

  CXFA_Items* pItemNode =
      m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
  if (!pItemNode)
    return nullptr;

  CXFA_Node* pNode = pItemNode->GetFirstChild();
  while (pNode) {
    WideString wsName = pNode->JSObject()->GetCData(XFA_Attribute::Name);
    if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover &&
        wsName.EqualsASCII("rollover")) {
      return pNode;
    }
    if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName.EqualsASCII("down"))
      return pNode;

    pNode = pNode->GetNextSibling();
  }
  return nullptr;
}