blob: 369279853e9dcffd942d32842344b48a3363be72 [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// 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
Dan Sinclair95bec802017-01-19 10:27:58 -05007#include "xfa/fde/css/cfde_cssstylesheet.h"
Dan Sinclair1770c022016-03-14 14:14:16 -04008
Dan Sinclair95bec802017-01-19 10:27:58 -05009#include <utility>
tsepezf74ad992016-05-11 10:26:05 -070010
Dan Sinclair3b71d262017-04-19 08:58:54 -040011#include "core/fxcrt/fx_codepage.h"
tsepez7cda31a2016-12-07 12:10:20 -080012#include "third_party/base/ptr_util.h"
Dan Sinclair3285c562017-01-17 16:35:16 -050013#include "third_party/base/stl_util.h"
Dan Sinclair95bec802017-01-19 10:27:58 -050014#include "xfa/fde/css/cfde_cssdeclaration.h"
Dan Sinclair95bec802017-01-19 10:27:58 -050015#include "xfa/fde/css/cfde_cssstylerule.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040016#include "xfa/fde/css/fde_cssdatatable.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040017
Dan Sinclairb76f49b2017-01-23 13:55:39 -050018CFDE_CSSStyleSheet::CFDE_CSSStyleSheet() {}
weilieec3a362016-06-18 06:25:37 -070019
Dan Sinclair1770c022016-03-14 14:14:16 -040020CFDE_CSSStyleSheet::~CFDE_CSSStyleSheet() {
21 Reset();
22}
weilieec3a362016-06-18 06:25:37 -070023
Dan Sinclair1770c022016-03-14 14:14:16 -040024void CFDE_CSSStyleSheet::Reset() {
Dan Sinclair3285c562017-01-17 16:35:16 -050025 m_RuleArray.clear();
tsepez788ac382016-05-19 21:06:16 -070026 m_StringCache.clear();
Dan Sinclair1770c022016-03-14 14:14:16 -040027}
weilieec3a362016-06-18 06:25:37 -070028
Dan Sinclair1770c022016-03-14 14:14:16 -040029int32_t CFDE_CSSStyleSheet::CountRules() const {
Dan Sinclair3285c562017-01-17 16:35:16 -050030 return pdfium::CollectionSize<int32_t>(m_RuleArray);
Dan Sinclair1770c022016-03-14 14:14:16 -040031}
weilieec3a362016-06-18 06:25:37 -070032
Dan Sinclairb76f49b2017-01-23 13:55:39 -050033CFDE_CSSStyleRule* CFDE_CSSStyleSheet::GetRule(int32_t index) const {
Dan Sinclair3285c562017-01-17 16:35:16 -050034 return m_RuleArray[index].get();
Dan Sinclair1770c022016-03-14 14:14:16 -040035}
tsepezf74ad992016-05-11 10:26:05 -070036
Dan Sinclair812e96c2017-03-13 16:43:37 -040037bool CFDE_CSSStyleSheet::LoadBuffer(const wchar_t* pBuffer, int32_t iBufSize) {
Lei Zhangf3024c32017-06-26 15:28:15 -070038 ASSERT(pBuffer);
39 ASSERT(iBufSize > 0);
Dan Sinclaircfb856c2017-01-16 16:03:44 -050040
Lei Zhangf3024c32017-06-26 15:28:15 -070041 auto pSyntax = pdfium::MakeUnique<CFDE_CSSSyntaxParser>(pBuffer, iBufSize);
Dan Sinclair1770c022016-03-14 14:14:16 -040042 Reset();
Dan Sinclair96f482c2017-01-11 16:31:27 -050043 FDE_CSSSyntaxStatus eStatus;
Dan Sinclair1770c022016-03-14 14:14:16 -040044 do {
45 switch (eStatus = pSyntax->DoSyntaxParse()) {
Dan Sinclair96f482c2017-01-11 16:31:27 -050046 case FDE_CSSSyntaxStatus::StyleRule:
Dan Sinclair6414b272017-01-23 13:54:53 -050047 eStatus = LoadStyleRule(pSyntax.get(), &m_RuleArray);
Dan Sinclair1770c022016-03-14 14:14:16 -040048 break;
49 default:
50 break;
51 }
Dan Sinclair96f482c2017-01-11 16:31:27 -050052 } while (eStatus >= FDE_CSSSyntaxStatus::None);
Dan Sinclaira715f522017-01-17 16:03:48 -050053
tsepez788ac382016-05-19 21:06:16 -070054 m_StringCache.clear();
Dan Sinclair96f482c2017-01-11 16:31:27 -050055 return eStatus != FDE_CSSSyntaxStatus::Error;
Dan Sinclair1770c022016-03-14 14:14:16 -040056}
weilieec3a362016-06-18 06:25:37 -070057
Dan Sinclair96f482c2017-01-11 16:31:27 -050058FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule(
dsinclaire6ebf7a2016-04-28 06:34:24 -070059 CFDE_CSSSyntaxParser* pSyntax,
Dan Sinclair6414b272017-01-23 13:54:53 -050060 std::vector<std::unique_ptr<CFDE_CSSStyleRule>>* ruleArray) {
Dan Sinclaira715f522017-01-17 16:03:48 -050061 std::vector<std::unique_ptr<CFDE_CSSSelector>> selectors;
Dan Sinclair3285c562017-01-17 16:35:16 -050062
thestigcfb77cc2016-06-10 12:21:53 -070063 CFDE_CSSStyleRule* pStyleRule = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -040064 int32_t iValueLen = 0;
Dan Sinclair21e954b2017-02-08 10:05:05 -050065 const FDE_CSSPropertyTable* propertyTable = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -040066 CFX_WideString wsName;
Dan Sinclair6414b272017-01-23 13:54:53 -050067 while (1) {
Dan Sinclair1770c022016-03-14 14:14:16 -040068 switch (pSyntax->DoSyntaxParse()) {
Dan Sinclair96f482c2017-01-11 16:31:27 -050069 case FDE_CSSSyntaxStatus::Selector: {
Dan Sinclair21e954b2017-02-08 10:05:05 -050070 CFX_WideStringC strValue = pSyntax->GetCurrentString();
71 auto pSelector = CFDE_CSSSelector::FromString(strValue);
thestigcfb77cc2016-06-10 12:21:53 -070072 if (pSelector)
Dan Sinclaira715f522017-01-17 16:03:48 -050073 selectors.push_back(std::move(pSelector));
74 break;
75 }
Dan Sinclair21e954b2017-02-08 10:05:05 -050076 case FDE_CSSSyntaxStatus::PropertyName: {
77 CFX_WideStringC strValue = pSyntax->GetCurrentString();
78 propertyTable = FDE_GetCSSPropertyByName(strValue);
79 if (!propertyTable)
80 wsName = CFX_WideString(strValue);
Dan Sinclair1770c022016-03-14 14:14:16 -040081 break;
Dan Sinclair21e954b2017-02-08 10:05:05 -050082 }
83 case FDE_CSSSyntaxStatus::PropertyValue: {
84 if (propertyTable || iValueLen > 0) {
85 CFX_WideStringC strValue = pSyntax->GetCurrentString();
Lei Zhang375c2762017-03-10 14:37:14 -080086 auto* decl = pStyleRule->GetDeclaration();
Dan Sinclair21e954b2017-02-08 10:05:05 -050087 if (!strValue.IsEmpty()) {
88 if (propertyTable) {
89 decl->AddProperty(propertyTable, strValue);
90 } else {
91 decl->AddProperty(wsName, CFX_WideString(strValue));
92 }
Dan Sinclair1770c022016-03-14 14:14:16 -040093 }
94 }
95 break;
Dan Sinclair21e954b2017-02-08 10:05:05 -050096 }
97 case FDE_CSSSyntaxStatus::DeclOpen: {
Dan Sinclaira715f522017-01-17 16:03:48 -050098 if (!pStyleRule && !selectors.empty()) {
Dan Sinclair3285c562017-01-17 16:35:16 -050099 auto rule = pdfium::MakeUnique<CFDE_CSSStyleRule>();
100 pStyleRule = rule.get();
Dan Sinclaira715f522017-01-17 16:03:48 -0500101 pStyleRule->SetSelector(&selectors);
Dan Sinclair3285c562017-01-17 16:35:16 -0500102 ruleArray->push_back(std::move(rule));
Dan Sinclair1770c022016-03-14 14:14:16 -0400103 } else {
104 SkipRuleSet(pSyntax);
Dan Sinclair96f482c2017-01-11 16:31:27 -0500105 return FDE_CSSSyntaxStatus::None;
Dan Sinclair1770c022016-03-14 14:14:16 -0400106 }
107 break;
Dan Sinclair21e954b2017-02-08 10:05:05 -0500108 }
109 case FDE_CSSSyntaxStatus::DeclClose: {
Dan Sinclair09065ae2017-01-18 08:56:52 -0500110 if (pStyleRule && pStyleRule->GetDeclaration()->empty()) {
Dan Sinclair3285c562017-01-17 16:35:16 -0500111 ruleArray->pop_back();
112 pStyleRule = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400113 }
Dan Sinclair96f482c2017-01-11 16:31:27 -0500114 return FDE_CSSSyntaxStatus::None;
Dan Sinclair21e954b2017-02-08 10:05:05 -0500115 }
Dan Sinclair96f482c2017-01-11 16:31:27 -0500116 case FDE_CSSSyntaxStatus::EOS:
117 return FDE_CSSSyntaxStatus::EOS;
118 case FDE_CSSSyntaxStatus::Error:
119 default:
120 return FDE_CSSSyntaxStatus::Error;
Dan Sinclair1770c022016-03-14 14:14:16 -0400121 }
122 }
123}
weilieec3a362016-06-18 06:25:37 -0700124
Dan Sinclair6414b272017-01-23 13:54:53 -0500125void CFDE_CSSStyleSheet::SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax) {
126 while (1) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400127 switch (pSyntax->DoSyntaxParse()) {
Dan Sinclair96f482c2017-01-11 16:31:27 -0500128 case FDE_CSSSyntaxStatus::Selector:
129 case FDE_CSSSyntaxStatus::DeclOpen:
130 case FDE_CSSSyntaxStatus::PropertyName:
131 case FDE_CSSSyntaxStatus::PropertyValue:
Dan Sinclair1770c022016-03-14 14:14:16 -0400132 break;
Dan Sinclair96f482c2017-01-11 16:31:27 -0500133 case FDE_CSSSyntaxStatus::DeclClose:
Dan Sinclair96f482c2017-01-11 16:31:27 -0500134 case FDE_CSSSyntaxStatus::EOS:
Dan Sinclair96f482c2017-01-11 16:31:27 -0500135 case FDE_CSSSyntaxStatus::Error:
136 default:
Dan Sinclair6414b272017-01-23 13:54:53 -0500137 return;
Dan Sinclair1770c022016-03-14 14:14:16 -0400138 }
139 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400140}