Home | History | Annotate | Download | only in fxfa
      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 "xfa/fxfa/cxfa_textprovider.h"
      8 
      9 #include <algorithm>
     10 #include <memory>
     11 #include <vector>
     12 
     13 #include "core/fxcrt/xml/cfx_xmlelement.h"
     14 #include "core/fxcrt/xml/cfx_xmlnode.h"
     15 #include "fxjs/cfxjse_engine.h"
     16 #include "fxjs/cfxjse_value.h"
     17 #include "fxjs/xfa/cjx_object.h"
     18 #include "third_party/base/ptr_util.h"
     19 #include "third_party/base/stl_util.h"
     20 #include "xfa/fde/cfde_textout.h"
     21 #include "xfa/fxfa/cxfa_eventparam.h"
     22 #include "xfa/fxfa/cxfa_ffapp.h"
     23 #include "xfa/fxfa/cxfa_ffcheckbutton.h"
     24 #include "xfa/fxfa/cxfa_ffdoc.h"
     25 #include "xfa/fxfa/cxfa_ffdocview.h"
     26 #include "xfa/fxfa/cxfa_fffield.h"
     27 #include "xfa/fxfa/cxfa_ffpageview.h"
     28 #include "xfa/fxfa/cxfa_ffwidget.h"
     29 #include "xfa/fxfa/cxfa_fontmgr.h"
     30 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
     31 #include "xfa/fxfa/parser/cxfa_caption.h"
     32 #include "xfa/fxfa/parser/cxfa_font.h"
     33 #include "xfa/fxfa/parser/cxfa_items.h"
     34 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
     35 #include "xfa/fxfa/parser/cxfa_localevalue.h"
     36 #include "xfa/fxfa/parser/cxfa_node.h"
     37 #include "xfa/fxfa/parser/cxfa_para.h"
     38 #include "xfa/fxfa/parser/cxfa_value.h"
     39 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
     40 #include "xfa/fxfa/parser/xfa_utils.h"
     41 
     42 CXFA_Node* CXFA_TextProvider::GetTextNode(bool& bRichText) {
     43   bRichText = false;
     44 
     45   if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
     46     CXFA_Node* pElementNode = m_pWidgetAcc->GetNode();
     47     CXFA_Value* pValueNode =
     48         pElementNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
     49     if (!pValueNode)
     50       return nullptr;
     51 
     52     CXFA_Node* pChildNode = pValueNode->GetFirstChild();
     53     if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) {
     54       Optional<WideString> contentType = pChildNode->JSObject()->TryAttribute(
     55           XFA_Attribute::ContentType, false);
     56       if (contentType && *contentType == L"text/html")
     57         bRichText = true;
     58     }
     59     return pChildNode;
     60   }
     61 
     62   if (m_eType == XFA_TEXTPROVIDERTYPE_Datasets) {
     63     CXFA_Node* pBind = m_pWidgetAcc->GetNode()->GetBindData();
     64     CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
     65     ASSERT(pXMLNode);
     66     for (CFX_XMLNode* pXMLChild =
     67              pXMLNode->GetNodeItem(CFX_XMLNode::FirstChild);
     68          pXMLChild;
     69          pXMLChild = pXMLChild->GetNodeItem(CFX_XMLNode::NextSibling)) {
     70       if (pXMLChild->GetType() == FX_XMLNODE_Element) {
     71         CFX_XMLElement* pElement = static_cast<CFX_XMLElement*>(pXMLChild);
     72         if (XFA_RecognizeRichText(pElement))
     73           bRichText = true;
     74       }
     75     }
     76     return pBind;
     77   }
     78 
     79   if (m_eType == XFA_TEXTPROVIDERTYPE_Caption) {
     80     CXFA_Caption* pCaptionNode =
     81         m_pWidgetAcc->GetNode()->GetChild<CXFA_Caption>(0, XFA_Element::Caption,
     82                                                         false);
     83     if (!pCaptionNode)
     84       return nullptr;
     85 
     86     CXFA_Value* pValueNode =
     87         pCaptionNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
     88     if (!pValueNode)
     89       return nullptr;
     90 
     91     CXFA_Node* pChildNode = pValueNode->GetFirstChild();
     92     if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) {
     93       Optional<WideString> contentType = pChildNode->JSObject()->TryAttribute(
     94           XFA_Attribute::ContentType, false);
     95       if (contentType && *contentType == L"text/html")
     96         bRichText = true;
     97     }
     98     return pChildNode;
     99   }
    100 
    101   CXFA_Items* pItemNode = m_pWidgetAcc->GetNode()->GetChild<CXFA_Items>(
    102       0, XFA_Element::Items, false);
    103   if (!pItemNode)
    104     return nullptr;
    105 
    106   CXFA_Node* pNode = pItemNode->GetFirstChild();
    107   while (pNode) {
    108     WideString wsName = pNode->JSObject()->GetCData(XFA_Attribute::Name);
    109     if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover && wsName == L"rollover")
    110       return pNode;
    111     if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == L"down")
    112       return pNode;
    113 
    114     pNode = pNode->GetNextSibling();
    115   }
    116   return nullptr;
    117 }
    118 
    119 CXFA_Para* CXFA_TextProvider::GetParaIfExists() {
    120   if (m_eType == XFA_TEXTPROVIDERTYPE_Text)
    121     return m_pWidgetAcc->GetNode()->GetParaIfExists();
    122 
    123   CXFA_Caption* pNode = m_pWidgetAcc->GetNode()->GetChild<CXFA_Caption>(
    124       0, XFA_Element::Caption, false);
    125   return pNode->GetChild<CXFA_Para>(0, XFA_Element::Para, false);
    126 }
    127 
    128 CXFA_Font* CXFA_TextProvider::GetFontIfExists() {
    129   if (m_eType == XFA_TEXTPROVIDERTYPE_Text)
    130     return m_pWidgetAcc->GetNode()->GetFontIfExists();
    131 
    132   CXFA_Caption* pNode = m_pWidgetAcc->GetNode()->GetChild<CXFA_Caption>(
    133       0, XFA_Element::Caption, false);
    134   CXFA_Font* font = pNode->GetChild<CXFA_Font>(0, XFA_Element::Font, false);
    135   return font ? font : m_pWidgetAcc->GetNode()->GetFontIfExists();
    136 }
    137 
    138 bool CXFA_TextProvider::IsCheckButtonAndAutoWidth() {
    139   XFA_Element eType = m_pWidgetAcc->GetUIType();
    140   if (eType != XFA_Element::CheckButton)
    141     return false;
    142   return !m_pWidgetAcc->GetNode()->TryWidth();
    143 }
    144 
    145 bool CXFA_TextProvider::GetEmbbedObj(bool bURI,
    146                                      bool bRaw,
    147                                      const WideString& wsAttr,
    148                                      WideString& wsValue) {
    149   if (m_eType != XFA_TEXTPROVIDERTYPE_Text)
    150     return false;
    151 
    152   if (!bURI)
    153     return false;
    154 
    155   CXFA_Node* pWidgetNode = m_pWidgetAcc->GetNode();
    156   CXFA_Node* pParent = pWidgetNode->GetParent();
    157   CXFA_Document* pDocument = pWidgetNode->GetDocument();
    158   CXFA_Node* pIDNode = nullptr;
    159   CXFA_WidgetAcc* pEmbAcc = nullptr;
    160   if (pParent)
    161     pIDNode = pDocument->GetNodeByID(pParent, wsAttr.AsStringView());
    162 
    163   if (!pIDNode) {
    164     pIDNode = pDocument->GetNodeByID(
    165         ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Form)),
    166         wsAttr.AsStringView());
    167   }
    168   if (pIDNode)
    169     pEmbAcc = pIDNode->GetWidgetAcc();
    170 
    171   if (!pEmbAcc)
    172     return false;
    173 
    174   wsValue = pEmbAcc->GetValue(XFA_VALUEPICTURE_Display);
    175   return true;
    176 }
    177