1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
4 * All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
24
25 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
26 #include "third_party/blink/renderer/core/animation/css/css_animations.h"
27 #include "third_party/blink/renderer/core/css/css_light_dark_value_pair.h"
28 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
29 #include "third_party/blink/renderer/core/dom/node.h"
30 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
31 #include "third_party/blink/renderer/core/dom/pseudo_element.h"
32 #include "third_party/blink/renderer/core/style/computed_style.h"
33 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
34
35 namespace blink {
36
StyleResolverState(Document & document,Element & element,PseudoElement * pseudo_element,PseudoElementStyleRequest::RequestType pseudo_request_type,ElementType element_type,const ComputedStyle * parent_style,const ComputedStyle * layout_parent_style)37 StyleResolverState::StyleResolverState(
38 Document& document,
39 Element& element,
40 PseudoElement* pseudo_element,
41 PseudoElementStyleRequest::RequestType pseudo_request_type,
42 ElementType element_type,
43 const ComputedStyle* parent_style,
44 const ComputedStyle* layout_parent_style)
45 : element_context_(element),
46 document_(&document),
47 parent_style_(parent_style),
48 layout_parent_style_(layout_parent_style),
49 pseudo_request_type_(pseudo_request_type),
50 font_builder_(&document),
51 element_style_resources_(GetElement(),
52 document.DevicePixelRatio(),
53 pseudo_element),
54 pseudo_element_(pseudo_element),
55 element_type_(element_type) {
56 DCHECK(!!parent_style_ == !!layout_parent_style_);
57
58 if (!parent_style_) {
59 parent_style_ = element_context_.ParentStyle();
60 }
61
62 if (!layout_parent_style_)
63 layout_parent_style_ = element_context_.LayoutParentStyle();
64
65 if (!layout_parent_style_)
66 layout_parent_style_ = parent_style_;
67
68 DCHECK(document.IsActive());
69 }
70
StyleResolverState(Document & document,Element & element,const ComputedStyle * parent_style,const ComputedStyle * layout_parent_style)71 StyleResolverState::StyleResolverState(Document& document,
72 Element& element,
73 const ComputedStyle* parent_style,
74 const ComputedStyle* layout_parent_style)
75 : StyleResolverState(document,
76 element,
77 nullptr /* pseudo_element */,
78 PseudoElementStyleRequest::kForRenderer,
79 ElementType::kElement,
80 parent_style,
81 layout_parent_style) {}
82
StyleResolverState(Document & document,Element & element,PseudoId pseudo_id,PseudoElementStyleRequest::RequestType pseudo_request_type,const ComputedStyle * parent_style,const ComputedStyle * layout_parent_style)83 StyleResolverState::StyleResolverState(
84 Document& document,
85 Element& element,
86 PseudoId pseudo_id,
87 PseudoElementStyleRequest::RequestType pseudo_request_type,
88 const ComputedStyle* parent_style,
89 const ComputedStyle* layout_parent_style)
90 : StyleResolverState(document,
91 element,
92 element.GetPseudoElement(pseudo_id),
93 pseudo_request_type,
94 ElementType::kPseudoElement,
95 parent_style,
96 layout_parent_style) {}
97
~StyleResolverState()98 StyleResolverState::~StyleResolverState() {
99 // For performance reasons, explicitly clear HeapVectors and
100 // HeapHashMaps to avoid giving a pressure on Oilpan's GC.
101 animation_update_.Clear();
102 }
103
GetTreeScope() const104 TreeScope& StyleResolverState::GetTreeScope() const {
105 return GetElement().GetTreeScope();
106 }
107
SetStyle(scoped_refptr<ComputedStyle> style)108 void StyleResolverState::SetStyle(scoped_refptr<ComputedStyle> style) {
109 // FIXME: Improve RAII of StyleResolverState to remove this function.
110 style_ = std::move(style);
111 css_to_length_conversion_data_ = CSSToLengthConversionData(
112 style_.get(), RootElementStyle(), GetDocument().GetLayoutView(),
113 style_->EffectiveZoom());
114 }
115
TakeStyle()116 scoped_refptr<ComputedStyle> StyleResolverState::TakeStyle() {
117 return std::move(style_);
118 }
119
UnzoomedLengthConversionData(const ComputedStyle * font_style) const120 CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData(
121 const ComputedStyle* font_style) const {
122 float em = font_style->SpecifiedFontSize();
123 float rem = RootElementStyle() ? RootElementStyle()->SpecifiedFontSize() : 1;
124 CSSToLengthConversionData::FontSizes font_sizes(
125 em, rem, &font_style->GetFont(), font_style->EffectiveZoom());
126 CSSToLengthConversionData::ViewportSize viewport_size(
127 GetDocument().GetLayoutView());
128
129 return CSSToLengthConversionData(Style(), font_sizes, viewport_size, 1);
130 }
131
FontSizeConversionData() const132 CSSToLengthConversionData StyleResolverState::FontSizeConversionData() const {
133 return UnzoomedLengthConversionData(ParentStyle());
134 }
135
UnzoomedLengthConversionData() const136 CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData()
137 const {
138 return UnzoomedLengthConversionData(Style());
139 }
140
SetParentStyle(scoped_refptr<const ComputedStyle> parent_style)141 void StyleResolverState::SetParentStyle(
142 scoped_refptr<const ComputedStyle> parent_style) {
143 parent_style_ = std::move(parent_style);
144 }
145
SetLayoutParentStyle(scoped_refptr<const ComputedStyle> parent_style)146 void StyleResolverState::SetLayoutParentStyle(
147 scoped_refptr<const ComputedStyle> parent_style) {
148 layout_parent_style_ = std::move(parent_style);
149 }
150
LoadPendingResources()151 void StyleResolverState::LoadPendingResources() {
152 if (pseudo_request_type_ == PseudoElementStyleRequest::kForComputedStyle ||
153 (ParentStyle() && ParentStyle()->IsEnsuredInDisplayNone()) ||
154 StyleRef().Display() == EDisplay::kNone ||
155 StyleRef().IsEnsuredOutsideFlatTree())
156 return;
157
158 if (StyleRef().StyleType() == kPseudoIdTargetText) {
159 // Do not load any resources for ::target-text since that could leak text
160 // content to external stylesheets.
161 return;
162 }
163
164 element_style_resources_.LoadPendingResources(StyleRef());
165 }
166
ParentFontDescription() const167 const FontDescription& StyleResolverState::ParentFontDescription() const {
168 return parent_style_->GetFontDescription();
169 }
170
SetZoom(float f)171 void StyleResolverState::SetZoom(float f) {
172 float parent_effective_zoom = ParentStyle()
173 ? ParentStyle()->EffectiveZoom()
174 : ComputedStyleInitialValues::InitialZoom();
175
176 style_->SetZoom(f);
177
178 if (f != 1.f)
179 GetDocument().CountUse(WebFeature::kCascadedCSSZoomNotEqualToOne);
180
181 if (style_->SetEffectiveZoom(parent_effective_zoom * f))
182 font_builder_.DidChangeEffectiveZoom();
183 }
184
SetEffectiveZoom(float f)185 void StyleResolverState::SetEffectiveZoom(float f) {
186 if (style_->SetEffectiveZoom(f))
187 font_builder_.DidChangeEffectiveZoom();
188 }
189
SetWritingMode(WritingMode new_writing_mode)190 void StyleResolverState::SetWritingMode(WritingMode new_writing_mode) {
191 if (style_->GetWritingMode() == new_writing_mode) {
192 return;
193 }
194 style_->SetWritingMode(new_writing_mode);
195 font_builder_.DidChangeWritingMode();
196 }
197
SetTextOrientation(ETextOrientation text_orientation)198 void StyleResolverState::SetTextOrientation(ETextOrientation text_orientation) {
199 if (style_->GetTextOrientation() != text_orientation) {
200 style_->SetTextOrientation(text_orientation);
201 font_builder_.DidChangeTextOrientation();
202 }
203 }
204
GetParserMode() const205 CSSParserMode StyleResolverState::GetParserMode() const {
206 return GetDocument().InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode;
207 }
208
GetAnimatingElement() const209 Element* StyleResolverState::GetAnimatingElement() const {
210 if (element_type_ == ElementType::kElement)
211 return &GetElement();
212 DCHECK_EQ(ElementType::kPseudoElement, element_type_);
213 return pseudo_element_;
214 }
215
ResolveLightDarkPair(const CSSProperty & property,const CSSValue & value)216 const CSSValue& StyleResolverState::ResolveLightDarkPair(
217 const CSSProperty& property,
218 const CSSValue& value) {
219 if (const auto* pair = DynamicTo<CSSLightDarkValuePair>(value)) {
220 if (!property.IsInherited())
221 Style()->SetHasNonInheritedLightDarkValue();
222 if (Style()->UsedColorScheme() == mojom::blink::ColorScheme::kLight)
223 return pair->First();
224 return pair->Second();
225 }
226 return value;
227 }
228
MarkDependency(const CSSProperty & property)229 void StyleResolverState::MarkDependency(const CSSProperty& property) {
230 if (!RuntimeEnabledFeatures::CSSMatchedPropertiesCacheDependenciesEnabled())
231 return;
232 if (!HasValidDependencies())
233 return;
234
235 has_incomparable_dependency_ |= !property.IsComputedValueComparable();
236 dependencies_.insert(property.GetCSSPropertyName());
237 }
238
239 } // namespace blink
240