Clean up CSS code to match styles.

Simplify the code to what we support, remove unnecessary classes.

Change-Id: I7af79a4720e0c95c609f163ebb86cf67d643add1
Reviewed-on: https://pdfium-review.googlesource.com/2430
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Nicolás Peña <npm@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index d0946a4..aa75afc 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1144,8 +1144,6 @@
       "xfa/fde/cfx_chariter.h",
       "xfa/fde/cfx_wordbreak.cpp",
       "xfa/fde/cfx_wordbreak.h",
-      "xfa/fde/css/cfde_cssaccelerator.cpp",
-      "xfa/fde/css/cfde_cssaccelerator.h",
       "xfa/fde/css/cfde_csscolorvalue.cpp",
       "xfa/fde/css/cfde_csscolorvalue.h",
       "xfa/fde/css/cfde_csscomputedstyle.cpp",
@@ -1173,8 +1171,6 @@
       "xfa/fde/css/cfde_cssstylesheet.h",
       "xfa/fde/css/cfde_csssyntaxparser.cpp",
       "xfa/fde/css/cfde_csssyntaxparser.h",
-      "xfa/fde/css/cfde_csstagcache.cpp",
-      "xfa/fde/css/cfde_csstagcache.h",
       "xfa/fde/css/cfde_csstextbuf.cpp",
       "xfa/fde/css/cfde_csstextbuf.h",
       "xfa/fde/css/cfde_cssvalue.cpp",
diff --git a/xfa/fde/css/cfde_cssaccelerator.cpp b/xfa/fde/css/cfde_cssaccelerator.cpp
deleted file mode 100644
index 40fa13e..0000000
--- a/xfa/fde/css/cfde_cssaccelerator.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
-// 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/fde/css/cfde_cssaccelerator.h"
-
-#include "third_party/base/ptr_util.h"
-
-CFDE_CSSAccelerator::CFDE_CSSAccelerator() {}
-
-CFDE_CSSAccelerator::~CFDE_CSSAccelerator() {}
-
-void CFDE_CSSAccelerator::OnEnterTag(CXFA_CSSTagProvider* pTag) {
-  stack_.push(pdfium::MakeUnique<CFDE_CSSTagCache>(top(), pTag));
-}
-
-void CFDE_CSSAccelerator::OnLeaveTag(CXFA_CSSTagProvider* pTag) {
-  ASSERT(!stack_.empty());
-  ASSERT(stack_.top()->GetTag() == pTag);
-  stack_.pop();
-}
diff --git a/xfa/fde/css/cfde_cssaccelerator.h b/xfa/fde/css/cfde_cssaccelerator.h
deleted file mode 100644
index 4ef493d..0000000
--- a/xfa/fde/css/cfde_cssaccelerator.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
-// 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
-
-#ifndef XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_
-#define XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_
-
-#include <memory>
-#include <stack>
-
-#include "xfa/fde/css/cfde_csstagcache.h"
-
-class CXFA_CSSTagProvider;
-
-class CFDE_CSSAccelerator {
- public:
-  CFDE_CSSAccelerator();
-  ~CFDE_CSSAccelerator();
-
-  void OnEnterTag(CXFA_CSSTagProvider* pTag);
-  void OnLeaveTag(CXFA_CSSTagProvider* pTag);
-
-  void Clear() {
-    std::stack<std::unique_ptr<CFDE_CSSTagCache>> tmp;
-    stack_.swap(tmp);
-  }
-
-  CFDE_CSSTagCache* top() const {
-    if (stack_.empty())
-      return nullptr;
-    return stack_.top().get();
-  }
-
- private:
-  std::stack<std::unique_ptr<CFDE_CSSTagCache>> stack_;
-};
-
-#endif  // XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_
diff --git a/xfa/fde/css/cfde_cssrulecollection.cpp b/xfa/fde/css/cfde_cssrulecollection.cpp
index a72e1bb..e318651 100644
--- a/xfa/fde/css/cfde_cssrulecollection.cpp
+++ b/xfa/fde/css/cfde_cssrulecollection.cpp
@@ -15,7 +15,6 @@
 #include "xfa/fde/css/cfde_cssstylerule.h"
 #include "xfa/fde/css/cfde_cssstylesheet.h"
 #include "xfa/fde/css/cfde_csssyntaxparser.h"
-#include "xfa/fde/css/cfde_csstagcache.h"
 
 CFDE_CSSRuleCollection::CFDE_CSSRuleCollection() : m_iSelectors(0) {}
 
@@ -29,8 +28,8 @@
 }
 
 const std::vector<std::unique_ptr<CFDE_CSSRuleCollection::Data>>*
-CFDE_CSSRuleCollection::GetTagRuleData(uint32_t dwTagHash) const {
-  auto it = m_TagRules.find(dwTagHash);
+CFDE_CSSRuleCollection::GetTagRuleData(const CFX_WideString& tagname) const {
+  auto it = m_TagRules.find(FX_HashCode_GetW(tagname.c_str(), true));
   return it != m_TagRules.end() ? &it->second : nullptr;
 }
 
diff --git a/xfa/fde/css/cfde_cssrulecollection.h b/xfa/fde/css/cfde_cssrulecollection.h
index d9bbeb3..5d49922 100644
--- a/xfa/fde/css/cfde_cssrulecollection.h
+++ b/xfa/fde/css/cfde_cssrulecollection.h
@@ -37,7 +37,7 @@
   int32_t CountSelectors() const { return m_iSelectors; }
 
   const std::vector<std::unique_ptr<Data>>* GetTagRuleData(
-      uint32_t dwTagHash) const;
+      const CFX_WideString& tagname) const;
 
  private:
   void AddRulesFrom(const CFDE_CSSStyleSheet* pStyleSheet,
diff --git a/xfa/fde/css/cfde_cssstyleselector.cpp b/xfa/fde/css/cfde_cssstyleselector.cpp
index e09f79c..fa17f7b 100644
--- a/xfa/fde/css/cfde_cssstyleselector.cpp
+++ b/xfa/fde/css/cfde_cssstyleselector.cpp
@@ -10,7 +10,6 @@
 #include <utility>
 
 #include "third_party/base/ptr_util.h"
-#include "xfa/fde/css/cfde_cssaccelerator.h"
 #include "xfa/fde/css/cfde_csscolorvalue.h"
 #include "xfa/fde/css/cfde_csscomputedstyle.h"
 #include "xfa/fde/css/cfde_csscustomproperty.h"
@@ -20,7 +19,6 @@
 #include "xfa/fde/css/cfde_cssselector.h"
 #include "xfa/fde/css/cfde_cssstylesheet.h"
 #include "xfa/fde/css/cfde_csssyntaxparser.h"
-#include "xfa/fde/css/cfde_csstagcache.h"
 #include "xfa/fde/css/cfde_cssvaluelist.h"
 #include "xfa/fxfa/app/cxfa_csstagprovider.h"
 
@@ -48,13 +46,6 @@
   m_fDefFontSize = fFontSize;
 }
 
-CFDE_CSSAccelerator* CFDE_CSSStyleSelector::InitAccelerator() {
-  if (!m_pAccelerator)
-    m_pAccelerator = pdfium::MakeUnique<CFDE_CSSAccelerator>();
-  m_pAccelerator->Clear();
-  return m_pAccelerator.get();
-}
-
 CFX_RetainPtr<CFDE_CSSComputedStyle> CFDE_CSSStyleSelector::CreateComputedStyle(
     CFDE_CSSComputedStyle* pParentStyle) {
   auto pStyle = pdfium::MakeRetain<CFDE_CSSComputedStyle>();
@@ -74,104 +65,59 @@
 }
 
 std::vector<const CFDE_CSSDeclaration*>
-CFDE_CSSStyleSelector::MatchDeclarations(CXFA_CSSTagProvider* pTag) {
-  ASSERT(pTag);
-
-  CFDE_CSSTagCache* pCache = m_pAccelerator->top();
-  ASSERT(pCache && pCache->GetTag() == pTag);
-
+CFDE_CSSStyleSelector::MatchDeclarations(const CFX_WideString& tagname) {
   std::vector<const CFDE_CSSDeclaration*> matchedDecls;
-  if (m_UARules.CountSelectors() == 0 || !pCache->HashTag())
+  if (m_UARules.CountSelectors() == 0 || tagname.IsEmpty())
     return matchedDecls;
 
-  auto rules = m_UARules.GetTagRuleData(pCache->HashTag());
+  auto rules = m_UARules.GetTagRuleData(tagname);
   if (!rules)
     return matchedDecls;
 
   for (const auto& d : *rules) {
-    if (MatchSelector(pCache, d->pSelector))
+    if (MatchSelector(tagname, d->pSelector))
       matchedDecls.push_back(d->pDeclaration);
   }
   return matchedDecls;
 }
 
-bool CFDE_CSSStyleSelector::MatchSelector(CFDE_CSSTagCache* pCache,
+bool CFDE_CSSStyleSelector::MatchSelector(const CFX_WideString& tagname,
                                           CFDE_CSSSelector* pSel) {
-  uint32_t dwHash;
-  while (pSel && pCache) {
-    switch (pSel->GetType()) {
-      case FDE_CSSSelectorType::Descendant:
-        dwHash = pSel->GetNameHash();
-        while ((pCache = pCache->GetParent()) != nullptr) {
-          if (dwHash != pCache->HashTag())
-            continue;
-          if (MatchSelector(pCache, pSel->GetNextSelector()))
-            return true;
-        }
-        return false;
-      case FDE_CSSSelectorType::Element:
-        dwHash = pSel->GetNameHash();
-        if (dwHash != pCache->HashTag())
-          return false;
-        break;
-      default:
-        ASSERT(false);
-        break;
-    }
-    pSel = pSel->GetNextSelector();
+  // TODO(dsinclair): The code only supports a single level of selector at this
+  // point. None of the code using selectors required the complexity so lets
+  // just say we don't support them to simplify the code for now.
+  if (!pSel || pSel->GetNextSelector() ||
+      pSel->GetType() == FDE_CSSSelectorType::Descendant) {
+    return false;
   }
-  return !pSel && pCache;
+  return pSel->GetNameHash() == FX_HashCode_GetW(tagname.c_str(), true);
 }
 
 void CFDE_CSSStyleSelector::ComputeStyle(
-    CXFA_CSSTagProvider* pTag,
     const std::vector<const CFDE_CSSDeclaration*>& declArray,
-    CFDE_CSSComputedStyle* pDestStyle) {
-  ASSERT(pDestStyle);
+    const CFX_WideString& styleString,
+    const CFX_WideString& alignString,
+    CFDE_CSSComputedStyle* pDest) {
+  std::unique_ptr<CFDE_CSSDeclaration> pDecl;
+  if (!styleString.IsEmpty() || !alignString.IsEmpty()) {
+    pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>();
 
-  static const uint32_t s_dwStyleHash = FX_HashCode_GetW(L"style", true);
-  static const uint32_t s_dwAlignHash = FX_HashCode_GetW(L"align", true);
-
-  if (!pTag->empty()) {
-    std::unique_ptr<CFDE_CSSDeclaration> pDecl;
-    for (auto it : *pTag) {
-      CFX_WideString wsAttri = it.first;
-      CFX_WideString wsValue = it.second;
-      uint32_t dwAttriHash = FX_HashCode_GetW(wsAttri.AsStringC(), true);
-      if (dwAttriHash == s_dwStyleHash) {
-        if (!pDecl)
-          pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>();
-
-        AppendInlineStyle(pDecl.get(), wsValue.c_str(), wsValue.GetLength());
-      } else if (dwAttriHash == s_dwAlignHash) {
-        if (!pDecl)
-          pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>();
-
-        FDE_CSSPropertyArgs args;
-        args.pStringCache = nullptr;
-        args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign);
-        pDecl->AddProperty(&args, wsValue.c_str(), wsValue.GetLength());
-      }
-    }
-
-    if (pDecl) {
-      ApplyDeclarations(declArray, pDecl.get(), pDestStyle);
-      return;
+    if (!styleString.IsEmpty())
+      AppendInlineStyle(pDecl.get(), styleString);
+    if (!alignString.IsEmpty()) {
+      FDE_CSSPropertyArgs args;
+      args.pStringCache = nullptr;
+      args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign);
+      pDecl->AddProperty(&args, alignString.c_str(), alignString.GetLength());
     }
   }
-
-  if (declArray.empty())
-    return;
-
-  ApplyDeclarations(declArray, nullptr, pDestStyle);
+  ApplyDeclarations(declArray, pDecl.get(), pDest);
 }
 
 void CFDE_CSSStyleSelector::ApplyDeclarations(
     const std::vector<const CFDE_CSSDeclaration*>& declArray,
     const CFDE_CSSDeclaration* extraDecl,
-    CFDE_CSSComputedStyle* pDestStyle) {
-  CFDE_CSSComputedStyle* pComputedStyle = pDestStyle;
-
+    CFDE_CSSComputedStyle* pComputedStyle) {
   std::vector<const CFDE_CSSPropertyHolder*> importants;
   std::vector<const CFDE_CSSPropertyHolder*> normals;
   std::vector<const CFDE_CSSCustomProperty*> customs;
@@ -205,11 +151,11 @@
 }
 
 void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
-                                              const FX_WCHAR* psz,
-                                              int32_t iLen) {
-  ASSERT(pDecl && psz && iLen > 0);
+                                              const CFX_WideString& style) {
+  ASSERT(pDecl && !style.IsEmpty());
+
   auto pSyntax = pdfium::MakeUnique<CFDE_CSSSyntaxParser>();
-  if (!pSyntax->Init(psz, iLen, 32, true))
+  if (!pSyntax->Init(style.c_str(), style.GetLength(), 32, true))
     return;
 
   int32_t iLen2 = 0;
diff --git a/xfa/fde/css/cfde_cssstyleselector.h b/xfa/fde/css/cfde_cssstyleselector.h
index 15bce93..b4eaa68 100644
--- a/xfa/fde/css/cfde_cssstyleselector.h
+++ b/xfa/fde/css/cfde_cssstyleselector.h
@@ -15,45 +15,44 @@
 #include "xfa/fde/css/cfde_cssrulecollection.h"
 #include "xfa/fde/css/fde_css.h"
 
-class CFDE_CSSAccelerator;
 class CFDE_CSSComputedStyle;
 class CFDE_CSSCustomProperty;
 class CFDE_CSSDeclaration;
 class CFDE_CSSPropertyHolder;
 class CFDE_CSSSelector;
 class CFDE_CSSStyleSheet;
-class CFDE_CSSTagCache;
 class CFDE_CSSValue;
 class CFDE_CSSValueList;
 class CFGAS_FontMgr;
-class CXFA_CSSTagProvider;
 
 class CFDE_CSSStyleSelector {
  public:
   explicit CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr);
   ~CFDE_CSSStyleSelector();
 
-  CFDE_CSSAccelerator* InitAccelerator();
-
   void SetDefFontSize(FX_FLOAT fFontSize);
   void SetUAStyleSheet(std::unique_ptr<CFDE_CSSStyleSheet> pSheet);
   void UpdateStyleIndex();
 
   CFX_RetainPtr<CFDE_CSSComputedStyle> CreateComputedStyle(
       CFDE_CSSComputedStyle* pParentStyle);
-  void ComputeStyle(CXFA_CSSTagProvider* pTag,
-                    const std::vector<const CFDE_CSSDeclaration*>& declArray,
+
+  // Note, the dest style has to be an out param because the CXFA_TextParser
+  // adds non-inherited data from the parent style. Attempting to copy
+  // internally will fail as you'll lose the non-inherited data.
+  void ComputeStyle(const std::vector<const CFDE_CSSDeclaration*>& declArray,
+                    const CFX_WideString& styleString,
+                    const CFX_WideString& alignString,
                     CFDE_CSSComputedStyle* pDestStyle);
 
   std::vector<const CFDE_CSSDeclaration*> MatchDeclarations(
-      CXFA_CSSTagProvider* pTag);
+      const CFX_WideString& tagname);
 
  private:
-  bool MatchSelector(CFDE_CSSTagCache* pCache, CFDE_CSSSelector* pSel);
+  bool MatchSelector(const CFX_WideString& tagname, CFDE_CSSSelector* pSel);
 
   void AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
-                         const FX_WCHAR* psz,
-                         int32_t iLen);
+                         const CFX_WideString& style);
   void ApplyDeclarations(
       const std::vector<const CFDE_CSSDeclaration*>& declArray,
       const CFDE_CSSDeclaration* extraDecl,
@@ -83,7 +82,6 @@
   FX_FLOAT m_fDefFontSize;
   std::unique_ptr<CFDE_CSSStyleSheet> m_UAStyles;
   CFDE_CSSRuleCollection m_UARules;
-  std::unique_ptr<CFDE_CSSAccelerator> m_pAccelerator;
 };
 
 #endif  // XFA_FDE_CSS_CFDE_CSSSTYLESELECTOR_H_
diff --git a/xfa/fde/css/cfde_csstagcache.cpp b/xfa/fde/css/cfde_csstagcache.cpp
deleted file mode 100644
index df2c2ce..0000000
--- a/xfa/fde/css/cfde_csstagcache.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
-// 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/fde/css/cfde_csstagcache.h"
-
-#include <algorithm>
-
-#include "core/fxcrt/fx_ext.h"
-#include "xfa/fxfa/app/cxfa_csstagprovider.h"
-
-CFDE_CSSTagCache::CFDE_CSSTagCache(CFDE_CSSTagCache* parent,
-                                   CXFA_CSSTagProvider* tag)
-    : pTag(tag), pParent(parent), dwTagHash(0) {
-  dwTagHash = FX_HashCode_GetW(pTag->GetTagName().AsStringC(), true);
-}
-
-CFDE_CSSTagCache::~CFDE_CSSTagCache() {}
diff --git a/xfa/fde/css/cfde_csstagcache.h b/xfa/fde/css/cfde_csstagcache.h
deleted file mode 100644
index dae35fb..0000000
--- a/xfa/fde/css/cfde_csstagcache.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
-// 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
-
-#ifndef XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_
-#define XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_
-
-#include <vector>
-
-#include "core/fxcrt/fx_system.h"
-#include "third_party/base/stl_util.h"
-
-class CXFA_CSSTagProvider;
-
-class CFDE_CSSTagCache {
- public:
-  CFDE_CSSTagCache(CFDE_CSSTagCache* parent, CXFA_CSSTagProvider* tag);
-  ~CFDE_CSSTagCache();
-
-  CFDE_CSSTagCache* GetParent() const { return pParent; }
-  CXFA_CSSTagProvider* GetTag() const { return pTag; }
-  uint32_t HashTag() const { return dwTagHash; }
-
- private:
-  CXFA_CSSTagProvider* pTag;
-  CFDE_CSSTagCache* pParent;
-  uint32_t dwTagHash;
-};
-
-#endif  // XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_
diff --git a/xfa/fxfa/app/cxfa_csstagprovider.h b/xfa/fxfa/app/cxfa_csstagprovider.h
index 3c23784..f5db867 100644
--- a/xfa/fxfa/app/cxfa_csstagprovider.h
+++ b/xfa/fxfa/app/cxfa_csstagprovider.h
@@ -13,30 +13,27 @@
 
 class CXFA_CSSTagProvider {
  public:
-  using AttributeMap = std::map<CFX_WideString, CFX_WideString>;
-
   CXFA_CSSTagProvider();
   ~CXFA_CSSTagProvider();
 
   CFX_WideString GetTagName() { return m_wsTagName; }
 
-  AttributeMap::iterator begin() { return m_Attributes.begin(); }
-  AttributeMap::iterator end() { return m_Attributes.end(); }
-
-  bool empty() const { return m_Attributes.empty(); }
-
-  void SetTagNameObj(const CFX_WideString& wsName) { m_wsTagName = wsName; }
+  void SetTagName(const CFX_WideString& wsName) { m_wsTagName = wsName; }
   void SetAttribute(const CFX_WideString& wsAttr,
                     const CFX_WideString& wsValue) {
     m_Attributes.insert({wsAttr, wsValue});
   }
 
+  CFX_WideString GetAttribute(const CFX_WideString& wsAttr) {
+    return m_Attributes[wsAttr];
+  }
+
   bool m_bTagAvailable;
   bool m_bContent;
 
- protected:
+ private:
   CFX_WideString m_wsTagName;
-  AttributeMap m_Attributes;
+  std::map<CFX_WideString, CFX_WideString> m_Attributes;
 };
 
 #endif  // XFA_FXFA_APP_CXFA_CSSTAGPROVIDER_H_
diff --git a/xfa/fxfa/app/cxfa_textparser.cpp b/xfa/fxfa/app/cxfa_textparser.cpp
index 2a724cc..9759cb2 100644
--- a/xfa/fxfa/app/cxfa_textparser.cpp
+++ b/xfa/fxfa/app/cxfa_textparser.cpp
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "third_party/base/ptr_util.h"
-#include "xfa/fde/css/cfde_cssaccelerator.h"
 #include "xfa/fde/css/cfde_csscomputedstyle.h"
 #include "xfa/fde/css/cfde_cssstyleselector.h"
 #include "xfa/fde/css/cfde_cssstylesheet.h"
@@ -198,17 +197,14 @@
 
   pContext->m_pParentStyle.Reset(pParentStyle);
 
-  CXFA_CSSTagProvider tagProvider;
-  ParseTagInfo(pXMLNode, tagProvider);
-  if (tagProvider.m_bContent)
+  auto tagProvider = ParseTagInfo(pXMLNode);
+  if (tagProvider->m_bContent)
     return nullptr;
 
   auto pStyle = CreateStyle(pParentStyle);
-  CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
-  pCSSAccel->OnEnterTag(&tagProvider);
-
-  m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(), pStyle.Get());
-  pCSSAccel->OnLeaveTag(&tagProvider);
+  m_pSelector->ComputeStyle(pContext->GetDecls(),
+                            tagProvider->GetAttribute(L"style"),
+                            tagProvider->GetAttribute(L"align"), pStyle.Get());
   return pStyle;
 }
 
@@ -228,25 +224,23 @@
   if (!pXMLNode)
     return;
 
-  CXFA_CSSTagProvider tagProvider;
-  ParseTagInfo(pXMLNode, tagProvider);
-  if (!tagProvider.m_bTagAvailable)
+  auto tagProvider = ParseTagInfo(pXMLNode);
+  if (!tagProvider->m_bTagAvailable)
     return;
 
   CFX_RetainPtr<CFDE_CSSComputedStyle> pNewStyle;
-  if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) ||
-      (tagProvider.GetTagName() != FX_WSTRC(L"html"))) {
+  if ((tagProvider->GetTagName() != L"body") ||
+      (tagProvider->GetTagName() != L"html")) {
     CXFA_TextParseContext* pTextContext = new CXFA_TextParseContext;
     FDE_CSSDisplay eDisplay = FDE_CSSDisplay::Inline;
-    if (!tagProvider.m_bContent) {
+    if (!tagProvider->m_bContent) {
+      auto declArray =
+          m_pSelector->MatchDeclarations(tagProvider->GetTagName());
       pNewStyle = CreateStyle(pParentStyle);
-      CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
-      pCSSAccel->OnEnterTag(&tagProvider);
+      m_pSelector->ComputeStyle(declArray, tagProvider->GetAttribute(L"style"),
+                                tagProvider->GetAttribute(L"align"),
+                                pNewStyle.Get());
 
-      auto declArray = m_pSelector->MatchDeclarations(&tagProvider);
-      m_pSelector->ComputeStyle(&tagProvider, declArray, pNewStyle.Get());
-
-      pCSSAccel->OnLeaveTag(&tagProvider);
       if (!declArray.empty())
         pTextContext->SetDecls(std::move(declArray));
 
@@ -286,23 +280,26 @@
                             FX_HashCode_GetW(wsName.AsStringC(), true));
 }
 
-void CXFA_TextParser::ParseTagInfo(CFDE_XMLNode* pXMLNode,
-                                   CXFA_CSSTagProvider& tagProvider) {
+std::unique_ptr<CXFA_CSSTagProvider> CXFA_TextParser::ParseTagInfo(
+    CFDE_XMLNode* pXMLNode) {
+  auto tagProvider = pdfium::MakeUnique<CXFA_CSSTagProvider>();
+
   CFX_WideString wsName;
   if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
     CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
     pXMLElement->GetLocalTagName(wsName);
-    tagProvider.SetTagNameObj(wsName);
-    tagProvider.m_bTagAvailable = TagValidate(wsName);
+    tagProvider->SetTagName(wsName);
+    tagProvider->m_bTagAvailable = TagValidate(wsName);
 
     CFX_WideString wsValue;
     pXMLElement->GetString(L"style", wsValue);
     if (!wsValue.IsEmpty())
-      tagProvider.SetAttribute(L"style", wsValue);
+      tagProvider->SetAttribute(L"style", wsValue);
   } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
-    tagProvider.m_bTagAvailable = true;
-    tagProvider.m_bContent = true;
+    tagProvider->m_bTagAvailable = true;
+    tagProvider->m_bContent = true;
   }
+  return tagProvider;
 }
 
 int32_t CXFA_TextParser::GetVAlign(CXFA_TextProvider* pTextProvider) const {
@@ -312,23 +309,23 @@
 
 FX_FLOAT CXFA_TextParser::GetTabInterval(CFDE_CSSComputedStyle* pStyle) const {
   CFX_WideString wsValue;
-  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue))
+  if (pStyle && pStyle->GetCustomStyle(L"tab-interval", wsValue))
     return CXFA_Measurement(wsValue.AsStringC()).ToUnit(XFA_UNIT_Pt);
   return 36;
 }
 
 int32_t CXFA_TextParser::CountTabs(CFDE_CSSComputedStyle* pStyle) const {
   CFX_WideString wsValue;
-  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-count"), wsValue))
+  if (pStyle && pStyle->GetCustomStyle(L"xfa-tab-count", wsValue))
     return wsValue.GetInteger();
   return 0;
 }
 
 bool CXFA_TextParser::IsSpaceRun(CFDE_CSSComputedStyle* pStyle) const {
   CFX_WideString wsValue;
-  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-spacerun"), wsValue)) {
+  if (pStyle && pStyle->GetCustomStyle(L"xfa-spacerun", wsValue)) {
     wsValue.MakeLower();
-    return wsValue == FX_WSTRC(L"yes");
+    return wsValue == L"yes";
   }
   return false;
 }
@@ -406,7 +403,7 @@
                                      CFDE_CSSComputedStyle* pStyle) const {
   if (pStyle) {
     CFX_WideString wsValue;
-    if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-vertical-scale"), wsValue))
+    if (pStyle->GetCustomStyle(L"xfa-font-vertical-scale", wsValue))
       return wsValue.GetInteger();
   }
 
@@ -437,8 +434,8 @@
     iUnderline = 1;
 
   CFX_WideString wsValue;
-  if (pStyle->GetCustomStyle(FX_WSTRC(L"underlinePeriod"), wsValue)) {
-    if (wsValue == FX_WSTRC(L"word"))
+  if (pStyle->GetCustomStyle(L"underlinePeriod", wsValue)) {
+    if (wsValue == L"word")
       iPeriod = XFA_ATTRIBUTEENUM_Word;
   } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
     iPeriod = font.GetUnderlinePeriod();
@@ -527,8 +524,8 @@
     else
       ws.MakeLower();
 
-    bool bURI = (ws == FX_WSTRC(L"uri"));
-    if (!bURI && ws != FX_WSTRC(L"som"))
+    bool bURI = (ws == L"uri");
+    if (!bURI && ws != L"som")
       return false;
 
     ws.clear();
@@ -538,8 +535,8 @@
     else
       ws.MakeLower();
 
-    bool bRaw = (ws == FX_WSTRC(L"raw"));
-    if (!bRaw && ws != FX_WSTRC(L"formatted"))
+    bool bRaw = (ws == L"raw");
+    if (!bRaw && ws != L"formatted")
       return false;
 
     bRet = pTextProvider->GetEmbbedObj(bURI, bRaw, wsAttr, wsValue);
@@ -559,8 +556,8 @@
     return false;
 
   CFX_WideString wsValue;
-  if (!pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-stops"), wsValue) &&
-      !pStyle->GetCustomStyle(FX_WSTRC(L"tab-stops"), wsValue)) {
+  if (!pStyle->GetCustomStyle(L"xfa-tab-stops", wsValue) &&
+      !pStyle->GetCustomStyle(L"tab-stops", wsValue)) {
     return false;
   }
 
diff --git a/xfa/fxfa/app/cxfa_textparser.h b/xfa/fxfa/app/cxfa_textparser.h
index 9332dfc..86da502 100644
--- a/xfa/fxfa/app/cxfa_textparser.h
+++ b/xfa/fxfa/app/cxfa_textparser.h
@@ -89,7 +89,7 @@
   void InitCSSData(CXFA_TextProvider* pTextProvider);
   void ParseRichText(CFDE_XMLNode* pXMLNode,
                      CFDE_CSSComputedStyle* pParentStyle);
-  void ParseTagInfo(CFDE_XMLNode* pXMLNode, CXFA_CSSTagProvider& tagProvider);
+  std::unique_ptr<CXFA_CSSTagProvider> ParseTagInfo(CFDE_XMLNode* pXMLNode);
   std::unique_ptr<CFDE_CSSStyleSheet> LoadDefaultSheetStyle();
   CFX_RetainPtr<CFDE_CSSComputedStyle> CreateStyle(
       CFDE_CSSComputedStyle* pParentStyle);