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/fxcrt/css/cfx_cssstylesheet.h" 8 9 #include <utility> 10 11 #include "core/fxcrt/css/cfx_cssdata.h" 12 #include "core/fxcrt/css/cfx_cssdeclaration.h" 13 #include "core/fxcrt/css/cfx_cssstylerule.h" 14 #include "core/fxcrt/fx_codepage.h" 15 #include "third_party/base/ptr_util.h" 16 #include "third_party/base/stl_util.h" 17 CFX_CSSStyleSheet()18CFX_CSSStyleSheet::CFX_CSSStyleSheet() {} 19 ~CFX_CSSStyleSheet()20CFX_CSSStyleSheet::~CFX_CSSStyleSheet() { 21 Reset(); 22 } 23 Reset()24void CFX_CSSStyleSheet::Reset() { 25 m_RuleArray.clear(); 26 m_StringCache.clear(); 27 } 28 CountRules() const29int32_t CFX_CSSStyleSheet::CountRules() const { 30 return pdfium::CollectionSize<int32_t>(m_RuleArray); 31 } 32 GetRule(int32_t index) const33CFX_CSSStyleRule* CFX_CSSStyleSheet::GetRule(int32_t index) const { 34 return m_RuleArray[index].get(); 35 } 36 LoadBuffer(const wchar_t * pBuffer,int32_t iBufSize)37bool CFX_CSSStyleSheet::LoadBuffer(const wchar_t* pBuffer, int32_t iBufSize) { 38 ASSERT(pBuffer); 39 ASSERT(iBufSize > 0); 40 41 auto pSyntax = pdfium::MakeUnique<CFX_CSSSyntaxParser>(pBuffer, iBufSize); 42 Reset(); 43 CFX_CSSSyntaxStatus eStatus; 44 do { 45 switch (eStatus = pSyntax->DoSyntaxParse()) { 46 case CFX_CSSSyntaxStatus::StyleRule: 47 eStatus = LoadStyleRule(pSyntax.get(), &m_RuleArray); 48 break; 49 default: 50 break; 51 } 52 } while (eStatus >= CFX_CSSSyntaxStatus::None); 53 54 m_StringCache.clear(); 55 return eStatus != CFX_CSSSyntaxStatus::Error; 56 } 57 LoadStyleRule(CFX_CSSSyntaxParser * pSyntax,std::vector<std::unique_ptr<CFX_CSSStyleRule>> * ruleArray)58CFX_CSSSyntaxStatus CFX_CSSStyleSheet::LoadStyleRule( 59 CFX_CSSSyntaxParser* pSyntax, 60 std::vector<std::unique_ptr<CFX_CSSStyleRule>>* ruleArray) { 61 std::vector<std::unique_ptr<CFX_CSSSelector>> selectors; 62 63 CFX_CSSStyleRule* pStyleRule = nullptr; 64 int32_t iValueLen = 0; 65 const CFX_CSSData::Property* property = nullptr; 66 WideString wsName; 67 while (1) { 68 switch (pSyntax->DoSyntaxParse()) { 69 case CFX_CSSSyntaxStatus::Selector: { 70 WideStringView strValue = pSyntax->GetCurrentString(); 71 auto pSelector = CFX_CSSSelector::FromString(strValue); 72 if (pSelector) 73 selectors.push_back(std::move(pSelector)); 74 break; 75 } 76 case CFX_CSSSyntaxStatus::PropertyName: { 77 WideStringView strValue = pSyntax->GetCurrentString(); 78 property = CFX_CSSData::GetPropertyByName(strValue); 79 if (!property) 80 wsName = WideString(strValue); 81 break; 82 } 83 case CFX_CSSSyntaxStatus::PropertyValue: { 84 if (property || iValueLen > 0) { 85 WideStringView strValue = pSyntax->GetCurrentString(); 86 auto* decl = pStyleRule->GetDeclaration(); 87 if (!strValue.IsEmpty()) { 88 if (property) { 89 decl->AddProperty(property, strValue); 90 } else { 91 decl->AddProperty(wsName, WideString(strValue)); 92 } 93 } 94 } 95 break; 96 } 97 case CFX_CSSSyntaxStatus::DeclOpen: { 98 if (!pStyleRule && !selectors.empty()) { 99 auto rule = pdfium::MakeUnique<CFX_CSSStyleRule>(); 100 pStyleRule = rule.get(); 101 pStyleRule->SetSelector(&selectors); 102 ruleArray->push_back(std::move(rule)); 103 } else { 104 SkipRuleSet(pSyntax); 105 return CFX_CSSSyntaxStatus::None; 106 } 107 break; 108 } 109 case CFX_CSSSyntaxStatus::DeclClose: { 110 if (pStyleRule && pStyleRule->GetDeclaration()->empty()) { 111 ruleArray->pop_back(); 112 pStyleRule = nullptr; 113 } 114 return CFX_CSSSyntaxStatus::None; 115 } 116 case CFX_CSSSyntaxStatus::EOS: 117 return CFX_CSSSyntaxStatus::EOS; 118 case CFX_CSSSyntaxStatus::Error: 119 default: 120 return CFX_CSSSyntaxStatus::Error; 121 } 122 } 123 } 124 SkipRuleSet(CFX_CSSSyntaxParser * pSyntax)125void CFX_CSSStyleSheet::SkipRuleSet(CFX_CSSSyntaxParser* pSyntax) { 126 while (1) { 127 switch (pSyntax->DoSyntaxParse()) { 128 case CFX_CSSSyntaxStatus::Selector: 129 case CFX_CSSSyntaxStatus::DeclOpen: 130 case CFX_CSSSyntaxStatus::PropertyName: 131 case CFX_CSSSyntaxStatus::PropertyValue: 132 break; 133 case CFX_CSSSyntaxStatus::DeclClose: 134 case CFX_CSSSyntaxStatus::EOS: 135 case CFX_CSSSyntaxStatus::Error: 136 default: 137 return; 138 } 139 } 140 } 141