// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fxfa/cxfa_textparser.h"

#include <algorithm>
#include <utility>

#include "core/fxcrt/check.h"
#include "core/fxcrt/css/cfx_css.h"
#include "core/fxcrt/css/cfx_csscomputedstyle.h"
#include "core/fxcrt/css/cfx_cssdeclaration.h"
#include "core/fxcrt/css/cfx_cssstyleselector.h"
#include "core/fxcrt/css/cfx_cssstylesheet.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/notreached.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "core/fxge/fx_font.h"
#include "xfa/fgas/font/cfgas_fontmgr.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_fontmgr.h"
#include "xfa/fxfa/cxfa_textprovider.h"
#include "xfa/fxfa/cxfa_texttabstopscontext.h"
#include "xfa/fxfa/parser/cxfa_font.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_para.h"

namespace {

enum class TabStopStatus {
  Error,
  EOS,
  None,
  Alignment,
  StartLeader,
  Leader,
  Location,
};

WideString GetLowerCaseElementAttributeOrDefault(
    const CFX_XMLElement* pElement,
    const WideString& wsName,
    const WideString& wsDefaultValue) {
  WideString ws = pElement->GetAttribute(wsName);
  if (ws.IsEmpty())
    ws = wsDefaultValue;
  else
    ws.MakeLower();
  return ws;
}

}  // namespace

CXFA_TextParser::CXFA_TextParser() = default;

CXFA_TextParser::~CXFA_TextParser() = default;

void CXFA_TextParser::Reset() {
  map_xmlnode_to_parse_context_.clear();
  parsed_ = false;
}

void CXFA_TextParser::InitCSSData(CXFA_TextProvider* pTextProvider) {
  if (!pTextProvider)
    return;

  if (!selector_) {
    selector_ = std::make_unique<CFX_CSSStyleSelector>();

    CXFA_Font* font = pTextProvider->GetFontIfExists();
    selector_->SetDefaultFontSize(font ? font->GetFontSize() : 10.0f);
  }

  if (css_initialized_) {
    return;
  }

  css_initialized_ = true;
  auto uaSheet = LoadDefaultSheetStyle();
  selector_->SetUAStyleSheet(std::move(uaSheet));
  selector_->UpdateStyleIndex();
}

std::unique_ptr<CFX_CSSStyleSheet> CXFA_TextParser::LoadDefaultSheetStyle() {
  static const char kStyle[] =
      "html,body,ol,p,ul{display:block}"
      "li{display:list-item}"
      "ol,ul{padding-left:33px;margin:1.12em 0}"
      "ol{list-style-type:decimal}"
      "a{color:#0000ff;text-decoration:underline}"
      "b{font-weight:bolder}"
      "i{font-style:italic}"
      "sup{vertical-align:+15em;font-size:.66em}"
      "sub{vertical-align:-15em;font-size:.66em}";
  WideString ws = WideString::FromASCII(kStyle);
  auto sheet = std::make_unique<CFX_CSSStyleSheet>();
  if (!sheet->LoadBuffer(ws.AsStringView()))
    return nullptr;

  return sheet;
}

RetainPtr<CFX_CSSComputedStyle> CXFA_TextParser::CreateRootStyle(
    CXFA_TextProvider* pTextProvider) {
  CXFA_Para* para = pTextProvider->GetParaIfExists();
  auto pStyle = selector_->CreateComputedStyle(nullptr);
  float fLineHeight = 0;
  float fFontSize = 10;

  if (para) {
    fLineHeight = para->GetLineHeight();
    CFX_CSSLength indent;
    indent.Set(CFX_CSSLengthUnit::Point, para->GetTextIndent());
    pStyle->SetTextIndent(indent);
    CFX_CSSTextAlign hAlign = CFX_CSSTextAlign::Left;
    switch (para->GetHorizontalAlign()) {
      case XFA_AttributeValue::Center:
        hAlign = CFX_CSSTextAlign::Center;
        break;
      case XFA_AttributeValue::Right:
        hAlign = CFX_CSSTextAlign::Right;
        break;
      case XFA_AttributeValue::Justify:
        hAlign = CFX_CSSTextAlign::Justify;
        break;
      case XFA_AttributeValue::JustifyAll:
        hAlign = CFX_CSSTextAlign::JustifyAll;
        break;
      case XFA_AttributeValue::Left:
      case XFA_AttributeValue::Radix:
        break;
      default:
        NOTREACHED();
    }
    pStyle->SetTextAlign(hAlign);
    CFX_CSSRect rtMarginWidth;
    rtMarginWidth.left.Set(CFX_CSSLengthUnit::Point, para->GetMarginLeft());
    rtMarginWidth.top.Set(CFX_CSSLengthUnit::Point, para->GetSpaceAbove());
    rtMarginWidth.right.Set(CFX_CSSLengthUnit::Point, para->GetMarginRight());
    rtMarginWidth.bottom.Set(CFX_CSSLengthUnit::Point, para->GetSpaceBelow());
    pStyle->SetMarginWidth(rtMarginWidth);
  }

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  if (font) {
    pStyle->SetColor(font->GetColor());
    pStyle->SetFontStyle(font->IsItalic() ? CFX_CSSFontStyle::Italic
                                          : CFX_CSSFontStyle::Normal);
    pStyle->SetFontWeight(font->IsBold() ? pdfium::kFontWeightBold
                                         : pdfium::kFontWeightNormal);
    pStyle->SetNumberVerticalAlign(-font->GetBaselineShift());
    fFontSize = font->GetFontSize();
    CFX_CSSLength letterSpacing;
    letterSpacing.Set(CFX_CSSLengthUnit::Point, font->GetLetterSpacing());
    pStyle->SetLetterSpacing(letterSpacing);
    Mask<CFX_CSSTEXTDECORATION> dwDecoration;
    if (font->GetLineThrough() > 0)
      dwDecoration |= CFX_CSSTEXTDECORATION::kLineThrough;
    if (font->GetUnderline() > 1)
      dwDecoration |= CFX_CSSTEXTDECORATION::kDouble;
    else if (font->GetUnderline() > 0)
      dwDecoration |= CFX_CSSTEXTDECORATION::kUnderline;

    pStyle->SetTextDecoration(dwDecoration);
  }
  pStyle->SetLineHeight(fLineHeight);
  pStyle->SetFontSize(fFontSize);
  return pStyle;
}

RetainPtr<CFX_CSSComputedStyle> CXFA_TextParser::CreateStyle(
    const CFX_CSSComputedStyle* pParentStyle) {
  auto pNewStyle = selector_->CreateComputedStyle(pParentStyle);
  DCHECK(pNewStyle);
  if (!pParentStyle)
    return pNewStyle;

  Mask<CFX_CSSTEXTDECORATION> dwDecoration = pParentStyle->GetTextDecoration();
  float fBaseLine = 0;
  if (pParentStyle->GetVerticalAlign() == CFX_CSSVerticalAlign::Number)
    fBaseLine = pParentStyle->GetNumberVerticalAlign();

  pNewStyle->SetTextDecoration(dwDecoration);
  pNewStyle->SetNumberVerticalAlign(fBaseLine);

  const CFX_CSSRect* pRect = pParentStyle->GetMarginWidth();
  if (pRect)
    pNewStyle->SetMarginWidth(*pRect);
  return pNewStyle;
}

RetainPtr<CFX_CSSComputedStyle> CXFA_TextParser::ComputeStyle(
    const CFX_XMLNode* pXMLNode,
    RetainPtr<const CFX_CSSComputedStyle> pParentStyle) {
  auto it = map_xmlnode_to_parse_context_.find(pXMLNode);
  if (it == map_xmlnode_to_parse_context_.end()) {
    return nullptr;
  }

  Context* pContext = it->second.get();
  if (!pContext)
    return nullptr;

  pContext->SetParentStyle(pParentStyle);

  auto tagProvider = ParseTagInfo(pXMLNode);
  if (tagProvider->content_) {
    return nullptr;
  }

  auto pStyle = CreateStyle(pParentStyle);
  selector_->ComputeStyle(pContext->GetDecls(),
                          tagProvider->GetAttribute(L"style"),
                          tagProvider->GetAttribute(L"align"), pStyle.Get());
  return pStyle;
}

void CXFA_TextParser::DoParse(const CFX_XMLNode* pXMLContainer,
                              CXFA_TextProvider* pTextProvider) {
  if (!pXMLContainer || !pTextProvider || parsed_) {
    return;
  }

  parsed_ = true;
  InitCSSData(pTextProvider);
  auto pRootStyle = CreateRootStyle(pTextProvider);
  ParseRichText(pXMLContainer, pRootStyle.Get());
}

void CXFA_TextParser::ParseRichText(const CFX_XMLNode* pXMLNode,
                                    const CFX_CSSComputedStyle* pParentStyle) {
  if (!pXMLNode)
    return;

  auto tagProvider = ParseTagInfo(pXMLNode);
  if (!tagProvider->tag_available_) {
    return;
  }

  RetainPtr<CFX_CSSComputedStyle> pNewStyle;
  if (!(tagProvider->GetTagName().EqualsASCII("body") &&
        tagProvider->GetTagName().EqualsASCII("html"))) {
    auto pTextContext = std::make_unique<Context>();
    CFX_CSSDisplay eDisplay = CFX_CSSDisplay::Inline;
    if (!tagProvider->content_) {
      auto declArray = selector_->MatchDeclarations(tagProvider->GetTagName());
      pNewStyle = CreateStyle(pParentStyle);
      selector_->ComputeStyle(declArray, tagProvider->GetAttribute(L"style"),
                              tagProvider->GetAttribute(L"align"),
                              pNewStyle.Get());

      if (!declArray.empty())
        pTextContext->SetDecls(std::move(declArray));

      eDisplay = pNewStyle->GetDisplay();
    }
    pTextContext->SetDisplay(eDisplay);
    map_xmlnode_to_parse_context_[pXMLNode] = std::move(pTextContext);
  }

  for (CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild(); pXMLChild;
       pXMLChild = pXMLChild->GetNextSibling()) {
    ParseRichText(pXMLChild, pNewStyle.Get());
  }
}

bool CXFA_TextParser::TagValidate(const WideString& wsName) const {
  static const uint32_t s_XFATagName[] = {
      0x61,        // a
      0x62,        // b
      0x69,        // i
      0x70,        // p
      0x0001f714,  // br
      0x00022a55,  // li
      0x000239bb,  // ol
      0x00025881,  // ul
      0x0bd37faa,  // sub
      0x0bd37fb8,  // sup
      0xa73e3af2,  // span
      0xb182eaae,  // body
      0xdb8ac455,  // html
  };
  return std::binary_search(std::begin(s_XFATagName), std::end(s_XFATagName),
                            FX_HashCode_GetLoweredW(wsName.AsStringView()));
}

// static
std::unique_ptr<CXFA_TextParser::TagProvider> CXFA_TextParser::ParseTagInfo(
    const CFX_XMLNode* pXMLNode) {
  auto tagProvider = std::make_unique<TagProvider>();
  const CFX_XMLElement* pXMLElement = ToXMLElement(pXMLNode);
  if (pXMLElement) {
    WideString wsName = pXMLElement->GetLocalTagName();
    tagProvider->SetTagName(wsName);
    tagProvider->tag_available_ = TagValidate(wsName);
    WideString wsValue = pXMLElement->GetAttribute(L"style");
    if (!wsValue.IsEmpty())
      tagProvider->SetAttribute(L"style", wsValue);

    return tagProvider;
  }
  if (pXMLNode->GetType() == CFX_XMLNode::Type::kText) {
    tagProvider->tag_available_ = true;
    tagProvider->content_ = true;
  }
  return tagProvider;
}

XFA_AttributeValue CXFA_TextParser::GetVAlign(
    CXFA_TextProvider* pTextProvider) const {
  CXFA_Para* para = pTextProvider->GetParaIfExists();
  return para ? para->GetVerticalAlign() : XFA_AttributeValue::Top;
}

float CXFA_TextParser::GetTabInterval(
    const CFX_CSSComputedStyle* pStyle) const {
  WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(L"tab-interval", &wsValue))
    return CXFA_Measurement(wsValue.AsStringView()).ToUnit(XFA_Unit::Pt);
  return 36;
}

int32_t CXFA_TextParser::CountTabs(const CFX_CSSComputedStyle* pStyle) const {
  WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(L"xfa-tab-count", &wsValue))
    return wsValue.GetInteger();
  return 0;
}

bool CXFA_TextParser::IsSpaceRun(const CFX_CSSComputedStyle* pStyle) const {
  WideString wsValue;
  return pStyle && pStyle->GetCustomStyle(L"xfa-spacerun", &wsValue) &&
         wsValue.EqualsASCIINoCase("yes");
}

RetainPtr<CFGAS_GEFont> CXFA_TextParser::GetFont(
    CXFA_FFDoc* doc,
    CXFA_TextProvider* pTextProvider,
    const CFX_CSSComputedStyle* pStyle) const {
  WideString wsFamily = L"Courier";
  uint32_t dwStyle = 0;
  CXFA_Font* font = pTextProvider->GetFontIfExists();
  if (font) {
    wsFamily = font->GetTypeface();
    if (font->IsBold()) {
      dwStyle |= pdfium::kFontStyleForceBold;
    }
    if (font->IsItalic()) {
      dwStyle |= pdfium::kFontStyleItalic;
    }
  }

  if (pStyle) {
    std::optional<WideString> last_family = pStyle->GetLastFontFamily();
    if (last_family.has_value()) {
      wsFamily = last_family.value();
    }

    dwStyle = 0;
    if (pStyle->GetFontWeight() > pdfium::kFontWeightNormal) {
      dwStyle |= pdfium::kFontStyleForceBold;
    }
    if (pStyle->GetFontStyle() == CFX_CSSFontStyle::Italic) {
      dwStyle |= pdfium::kFontStyleItalic;
    }
  }

  CXFA_FontMgr* pFontMgr = doc->GetApp()->GetXFAFontMgr();
  return pFontMgr->GetFont(doc, wsFamily, dwStyle);
}

float CXFA_TextParser::GetFontSize(CXFA_TextProvider* pTextProvider,
                                   const CFX_CSSComputedStyle* pStyle) const {
  if (pStyle)
    return pStyle->GetFontSize();

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? font->GetFontSize() : 10;
}

int32_t CXFA_TextParser::GetHorScale(CXFA_TextProvider* pTextProvider,
                                     const CFX_CSSComputedStyle* pStyle,
                                     const CFX_XMLNode* pXMLNode) const {
  if (pStyle) {
    WideString wsValue;
    if (pStyle->GetCustomStyle(L"xfa-font-horizontal-scale", &wsValue))
      return wsValue.GetInteger();

    while (pXMLNode) {
      auto it = map_xmlnode_to_parse_context_.find(pXMLNode);
      if (it != map_xmlnode_to_parse_context_.end()) {
        Context* pContext = it->second.get();
        if (pContext && pContext->GetParentStyle() &&
            pContext->GetParentStyle()->GetCustomStyle(
                L"xfa-font-horizontal-scale", &wsValue)) {
          return wsValue.GetInteger();
        }
      }
      pXMLNode = pXMLNode->GetParent();
    }
  }

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? static_cast<int32_t>(font->GetHorizontalScale()) : 100;
}

int32_t CXFA_TextParser::GetVerScale(CXFA_TextProvider* pTextProvider,
                                     const CFX_CSSComputedStyle* pStyle) const {
  if (pStyle) {
    WideString wsValue;
    if (pStyle->GetCustomStyle(L"xfa-font-vertical-scale", &wsValue))
      return wsValue.GetInteger();
  }

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? static_cast<int32_t>(font->GetVerticalScale()) : 100;
}

int32_t CXFA_TextParser::GetUnderline(
    CXFA_TextProvider* pTextProvider,
    const CFX_CSSComputedStyle* pStyle) const {
  CXFA_Font* font = pTextProvider->GetFontIfExists();
  if (!pStyle)
    return font ? font->GetUnderline() : 0;

  const Mask<CFX_CSSTEXTDECORATION> dwDecoration = pStyle->GetTextDecoration();
  if (dwDecoration & CFX_CSSTEXTDECORATION::kDouble)
    return 2;
  if (dwDecoration & CFX_CSSTEXTDECORATION::kUnderline)
    return 1;
  return 0;
}

XFA_AttributeValue CXFA_TextParser::GetUnderlinePeriod(
    CXFA_TextProvider* pTextProvider,
    const CFX_CSSComputedStyle* pStyle) const {
  WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(L"underlinePeriod", &wsValue)) {
    return wsValue.EqualsASCII("word") ? XFA_AttributeValue::Word
                                       : XFA_AttributeValue::All;
  }
  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? font->GetUnderlinePeriod() : XFA_AttributeValue::All;
}

int32_t CXFA_TextParser::GetLinethrough(
    CXFA_TextProvider* pTextProvider,
    const CFX_CSSComputedStyle* pStyle) const {
  if (pStyle) {
    const Mask<CFX_CSSTEXTDECORATION> dwDecoration =
        pStyle->GetTextDecoration();
    return (dwDecoration & CFX_CSSTEXTDECORATION::kLineThrough) ? 1 : 0;
  }
  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? font->GetLineThrough() : 0;
}

FX_ARGB CXFA_TextParser::GetColor(CXFA_TextProvider* pTextProvider,
                                  const CFX_CSSComputedStyle* pStyle) const {
  if (pStyle)
    return pStyle->GetColor();

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? font->GetColor() : 0xFF000000;
}

float CXFA_TextParser::GetBaseline(CXFA_TextProvider* pTextProvider,
                                   const CFX_CSSComputedStyle* pStyle) const {
  if (pStyle) {
    if (pStyle->GetVerticalAlign() == CFX_CSSVerticalAlign::Number)
      return pStyle->GetNumberVerticalAlign();
  } else {
    CXFA_Font* font = pTextProvider->GetFontIfExists();
    if (font)
      return font->GetBaselineShift();
  }
  return 0;
}

float CXFA_TextParser::GetLineHeight(CXFA_TextProvider* pTextProvider,
                                     const CFX_CSSComputedStyle* pStyle,
                                     bool bFirst,
                                     float fVerScale) const {
  float fLineHeight = 0;
  if (pStyle) {
    fLineHeight = pStyle->GetLineHeight();
  } else {
    CXFA_Para* para = pTextProvider->GetParaIfExists();
    if (para)
      fLineHeight = para->GetLineHeight();
  }

  if (bFirst) {
    float fFontSize = GetFontSize(pTextProvider, pStyle);
    if (fLineHeight < 0.1f)
      fLineHeight = fFontSize;
    else
      fLineHeight = std::min(fLineHeight, fFontSize);
  } else if (fLineHeight < 0.1f) {
    fLineHeight = GetFontSize(pTextProvider, pStyle) * 1.2f;
  }
  fLineHeight *= fVerScale;
  return fLineHeight;
}

std::optional<WideString> CXFA_TextParser::GetEmbeddedObj(
    const CXFA_TextProvider* pTextProvider,
    const CFX_XMLNode* pXMLNode) {
  if (!pXMLNode)
    return std::nullopt;

  const CFX_XMLElement* pElement = ToXMLElement(pXMLNode);
  if (!pElement)
    return std::nullopt;

  WideString wsAttr = pElement->GetAttribute(L"xfa:embed");
  if (wsAttr.IsEmpty())
    return std::nullopt;

  if (wsAttr[0] == L'#')
    wsAttr.Delete(0);

  WideString ws =
      GetLowerCaseElementAttributeOrDefault(pElement, L"xfa:embedType", L"som");
  if (!ws.EqualsASCII("uri"))
    return std::nullopt;

  ws = GetLowerCaseElementAttributeOrDefault(pElement, L"xfa:embedMode",
                                             L"formatted");
  if (!(ws.EqualsASCII("raw") || ws.EqualsASCII("formatted")))
    return std::nullopt;

  return pTextProvider->GetEmbeddedObj(wsAttr);
}

CXFA_TextParser::Context* CXFA_TextParser::GetParseContextFromMap(
    const CFX_XMLNode* pXMLNode) {
  auto it = map_xmlnode_to_parse_context_.find(pXMLNode);
  return it != map_xmlnode_to_parse_context_.end() ? it->second.get() : nullptr;
}

bool CXFA_TextParser::GetTabstops(const CFX_CSSComputedStyle* pStyle,
                                  CXFA_TextTabstopsContext* pTabstopContext) {
  if (!pStyle || !pTabstopContext)
    return false;

  WideString wsValue;
  if (!pStyle->GetCustomStyle(L"xfa-tab-stops", &wsValue) &&
      !pStyle->GetCustomStyle(L"tab-stops", &wsValue)) {
    return false;
  }

  pdfium::span<const wchar_t> spTabStops = wsValue.span();
  size_t iCur = 0;
  size_t iLast = 0;
  WideString wsAlign;
  TabStopStatus eStatus = TabStopStatus::None;
  while (iCur < spTabStops.size()) {
    wchar_t ch = spTabStops[iCur];
    switch (eStatus) {
      case TabStopStatus::None:
        if (ch <= ' ') {
          iCur++;
        } else {
          eStatus = TabStopStatus::Alignment;
          iLast = iCur;
        }
        break;
      case TabStopStatus::Alignment:
        if (ch == ' ') {
          wsAlign = WideStringView(spTabStops.subspan(iLast, iCur - iLast));
          eStatus = TabStopStatus::StartLeader;
          iCur++;
          while (iCur < spTabStops.size() && spTabStops[iCur] <= ' ')
            iCur++;
          iLast = iCur;
        } else {
          iCur++;
        }
        break;
      case TabStopStatus::StartLeader:
        if (ch != 'l') {
          eStatus = TabStopStatus::Location;
        } else {
          int32_t iCount = 0;
          while (iCur < spTabStops.size()) {
            ch = spTabStops[iCur];
            iCur++;
            if (ch == '(') {
              iCount++;
            } else if (ch == ')') {
              iCount--;
              if (iCount == 0)
                break;
            }
          }
          while (iCur < spTabStops.size() && spTabStops[iCur] <= ' ')
            iCur++;

          iLast = iCur;
          eStatus = TabStopStatus::Location;
        }
        break;
      case TabStopStatus::Location:
        if (ch == ' ') {
          uint32_t dwHashCode = FX_HashCode_GetLoweredW(wsAlign.AsStringView());
          CXFA_Measurement ms(
              WideStringView(spTabStops.subspan(iLast, iCur - iLast)));
          float fPos = ms.ToUnit(XFA_Unit::Pt);
          pTabstopContext->Append(dwHashCode, fPos);
          wsAlign.clear();
          eStatus = TabStopStatus::None;
        }
        iCur++;
        break;
      default:
        break;
    }
  }

  if (!wsAlign.IsEmpty()) {
    uint32_t dwHashCode = FX_HashCode_GetLoweredW(wsAlign.AsStringView());
    CXFA_Measurement ms(
        WideStringView(spTabStops.subspan(iLast, iCur - iLast)));
    float fPos = ms.ToUnit(XFA_Unit::Pt);
    pTabstopContext->Append(dwHashCode, fPos);
  }
  return true;
}

CXFA_TextParser::TagProvider::TagProvider() = default;

CXFA_TextParser::TagProvider::~TagProvider() = default;

CXFA_TextParser::Context::Context() = default;

CXFA_TextParser::Context::~Context() = default;

void CXFA_TextParser::Context::SetParentStyle(
    RetainPtr<const CFX_CSSComputedStyle> style) {
  parent_style_ = std::move(style);
}

void CXFA_TextParser::Context::SetDecls(
    std::vector<const CFX_CSSDeclaration*>&& decl) {
  decls_ = std::move(decl);
}
