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 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_RESOLVER_STATE_H_
24 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_RESOLVER_STATE_H_
25 
26 #include <memory>
27 #include "base/macros.h"
28 #include "third_party/blink/renderer/core/animation/css/css_animation_update.h"
29 #include "third_party/blink/renderer/core/core_export.h"
30 #include "third_party/blink/renderer/core/css/css_pending_substitution_value.h"
31 #include "third_party/blink/renderer/core/css/css_property_names.h"
32 #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
33 #include "third_party/blink/renderer/core/css/parser/css_parser_mode.h"
34 #include "third_party/blink/renderer/core/css/resolver/css_to_style_map.h"
35 #include "third_party/blink/renderer/core/css/resolver/element_resolve_context.h"
36 #include "third_party/blink/renderer/core/css/resolver/element_style_resources.h"
37 #include "third_party/blink/renderer/core/css/resolver/font_builder.h"
38 #include "third_party/blink/renderer/core/dom/document.h"
39 #include "third_party/blink/renderer/core/dom/element.h"
40 #include "third_party/blink/renderer/core/style/cached_ua_style.h"
41 
42 namespace blink {
43 
44 class ComputedStyle;
45 class FontDescription;
46 class PseudoElement;
47 
48 // A per-element object which wraps an ElementResolveContext. It collects state
49 // throughout the process of computing the style. It also gives convenient
50 // access to other element-related information.
51 class CORE_EXPORT StyleResolverState {
52   STACK_ALLOCATED();
53 
54  public:
55   StyleResolverState(Document&,
56                      Element&,
57                      const ComputedStyle* parent_style = nullptr,
58                      const ComputedStyle* layout_parent_style = nullptr);
59   StyleResolverState(Document&,
60                      Element&,
61                      PseudoId,
62                      const ComputedStyle* parent_style,
63                      const ComputedStyle* layout_parent_style);
64   ~StyleResolverState();
65 
66   // In FontFaceSet and CanvasRenderingContext2D, we don't have an element to
67   // grab the document from.  This is why we have to store the document
68   // separately.
GetDocument()69   Document& GetDocument() const { return *document_; }
70   // These are all just pass-through methods to ElementResolveContext.
GetElement()71   Element& GetElement() const { return element_context_.GetElement(); }
72   TreeScope& GetTreeScope() const;
ParentNode()73   const ContainerNode* ParentNode() const {
74     return element_context_.ParentNode();
75   }
RootElementStyle()76   const ComputedStyle* RootElementStyle() const {
77     return element_context_.RootElementStyle();
78   }
ElementLinkState()79   EInsideLink ElementLinkState() const {
80     return element_context_.ElementLinkState();
81   }
DistributedToV0InsertionPoint()82   bool DistributedToV0InsertionPoint() const {
83     return element_context_.DistributedToV0InsertionPoint();
84   }
85 
ElementContext()86   const ElementResolveContext& ElementContext() const {
87     return element_context_;
88   }
89 
90   void SetStyle(scoped_refptr<ComputedStyle>);
Style()91   const ComputedStyle* Style() const { return style_.get(); }
Style()92   ComputedStyle* Style() { return style_.get(); }
StyleRef()93   ComputedStyle& StyleRef() {
94     DCHECK(style_);
95     return *style_;
96   }
97   scoped_refptr<ComputedStyle> TakeStyle();
98 
CssToLengthConversionData()99   const CSSToLengthConversionData& CssToLengthConversionData() const {
100     return css_to_length_conversion_data_;
101   }
102   CSSToLengthConversionData FontSizeConversionData() const;
103   CSSToLengthConversionData UnzoomedLengthConversionData() const;
104 
SetConversionFontSizes(const CSSToLengthConversionData::FontSizes & font_sizes)105   void SetConversionFontSizes(
106       const CSSToLengthConversionData::FontSizes& font_sizes) {
107     css_to_length_conversion_data_.SetFontSizes(font_sizes);
108   }
SetConversionZoom(float zoom)109   void SetConversionZoom(float zoom) {
110     css_to_length_conversion_data_.SetZoom(zoom);
111   }
112 
AnimationUpdate()113   CSSAnimationUpdate& AnimationUpdate() { return animation_update_; }
AnimationUpdate()114   const CSSAnimationUpdate& AnimationUpdate() const {
115     return animation_update_;
116   }
117 
IsAnimationInterpolationMapReady()118   bool IsAnimationInterpolationMapReady() const {
119     return is_animation_interpolation_map_ready_;
120   }
SetIsAnimationInterpolationMapReady()121   void SetIsAnimationInterpolationMapReady() {
122     is_animation_interpolation_map_ready_ = true;
123   }
124 
IsAnimatingCustomProperties()125   bool IsAnimatingCustomProperties() const {
126     return is_animating_custom_properties_;
127   }
SetIsAnimatingCustomProperties(bool value)128   void SetIsAnimatingCustomProperties(bool value) {
129     is_animating_custom_properties_ = value;
130   }
131 
132   // Normally, we apply all active animation effects on top of the style created
133   // by regular CSS declarations. However, !important declarations have a
134   // higher priority than animation effects [1]. If StyleCascade skipped
135   // application of some interpolation, it means something else in the cascade
136   // had a higher priority (i.e. it was !important). In this case, we can't
137   // use the base-computed-style optimization, since that code path is unable
138   // to skip any animation effects at all.
139   //
140   // [1] https://drafts.csswg.org/css-cascade-4/#cascade-origin
HasImportantOverrides()141   bool HasImportantOverrides() const { return has_important_overrides_; }
SetHasImportantOverrides()142   void SetHasImportantOverrides() { has_important_overrides_ = true; }
143 
144   // This flag is set when applying an animation (or transition) for a font
145   // affecting property. When such properties are animated, font-relative
146   // units (e.g. em, ex) in the base style must respond to the animation.
147   // Therefore we can't use the base computed style optimization in such cases.
HasFontAffectingAnimation()148   bool HasFontAffectingAnimation() const {
149     return has_font_affecting_animation_;
150   }
SetHasFontAffectingAnimation()151   void SetHasFontAffectingAnimation() { has_font_affecting_animation_ = true; }
152 
153   const Element* GetAnimatingElement() const;
154 
155   void SetParentStyle(scoped_refptr<const ComputedStyle>);
ParentStyle()156   const ComputedStyle* ParentStyle() const { return parent_style_.get(); }
157 
158   void SetLayoutParentStyle(scoped_refptr<const ComputedStyle>);
LayoutParentStyle()159   const ComputedStyle* LayoutParentStyle() const {
160     return layout_parent_style_.get();
161   }
162 
163   void CacheUserAgentBorderAndBackground();
164 
GetCachedUAStyle()165   const CachedUAStyle* GetCachedUAStyle() const {
166     return cached_ua_style_.get();
167   }
168 
GetElementStyleResources()169   ElementStyleResources& GetElementStyleResources() {
170     return element_style_resources_;
171   }
172 
173   void LoadPendingResources();
174 
175   // FIXME: Once styleImage can be made to not take a StyleResolverState
176   // this convenience function should be removed. As-is, without this, call
177   // sites are extremely verbose.
GetStyleImage(CSSPropertyID property_id,const CSSValue & value)178   StyleImage* GetStyleImage(CSSPropertyID property_id, const CSSValue& value) {
179     return element_style_resources_.GetStyleImage(property_id, value);
180   }
181 
GetFontBuilder()182   FontBuilder& GetFontBuilder() { return font_builder_; }
GetFontBuilder()183   const FontBuilder& GetFontBuilder() const { return font_builder_; }
184   // FIXME: These exist as a primitive way to track mutations to font-related
185   // properties on a ComputedStyle. As designed, these are very error-prone, as
186   // some callers set these directly on the ComputedStyle w/o telling us.
187   // Presumably we'll want to design a better wrapper around ComputedStyle for
188   // tracking these mutations and separate it from StyleResolverState.
189   const FontDescription& ParentFontDescription() const;
190 
191   void SetZoom(float);
192   void SetEffectiveZoom(float);
193   void SetWritingMode(WritingMode);
194   void SetTextOrientation(ETextOrientation);
195 
SetHasDirAutoAttribute(bool value)196   void SetHasDirAutoAttribute(bool value) { has_dir_auto_attribute_ = value; }
HasDirAutoAttribute()197   bool HasDirAutoAttribute() const { return has_dir_auto_attribute_; }
198 
GetCascadedColorValue()199   const CSSValue* GetCascadedColorValue() const {
200     return cascaded_color_value_;
201   }
GetCascadedVisitedColorValue()202   const CSSValue* GetCascadedVisitedColorValue() const {
203     return cascaded_visited_color_value_;
204   }
205 
SetCascadedColorValue(const CSSValue * color)206   void SetCascadedColorValue(const CSSValue* color) {
207     cascaded_color_value_ = color;
208   }
SetCascadedVisitedColorValue(const CSSValue * color)209   void SetCascadedVisitedColorValue(const CSSValue* color) {
210     cascaded_visited_color_value_ = color;
211   }
212 
213   HeapHashMap<CSSPropertyID, Member<const CSSValue>>&
214   ParsedPropertiesForPendingSubstitutionCache(
215       const cssvalue::CSSPendingSubstitutionValue&) const;
216 
217   CSSParserMode GetParserMode() const;
218 
219  private:
220   enum class AnimatingElementType { kElement, kPseudoElement };
221 
222   StyleResolverState(Document&,
223                      Element&,
224                      PseudoElement*,
225                      AnimatingElementType,
226                      const ComputedStyle* parent_style,
227                      const ComputedStyle* layout_parent_style);
228 
229   CSSToLengthConversionData UnzoomedLengthConversionData(
230       const ComputedStyle* font_style) const;
231 
232   ElementResolveContext element_context_;
233   Document* document_;
234 
235   // style_ is the primary output for each element's style resolve.
236   scoped_refptr<ComputedStyle> style_;
237 
238   CSSToLengthConversionData css_to_length_conversion_data_;
239 
240   // parent_style_ is not always just ElementResolveContext::ParentStyle(),
241   // so we keep it separate.
242   scoped_refptr<const ComputedStyle> parent_style_;
243   // This will almost-always be the same that parent_style_, except in the
244   // presence of display: contents. This is the style against which we have to
245   // do adjustment.
246   scoped_refptr<const ComputedStyle> layout_parent_style_;
247 
248   CSSAnimationUpdate animation_update_;
249   bool is_animation_interpolation_map_ready_;
250   bool is_animating_custom_properties_;
251   bool has_important_overrides_ = false;
252   bool has_font_affecting_animation_ = false;
253 
254   bool has_dir_auto_attribute_;
255 
256   const CSSValue* cascaded_color_value_;
257   const CSSValue* cascaded_visited_color_value_;
258 
259   FontBuilder font_builder_;
260 
261   std::unique_ptr<CachedUAStyle> cached_ua_style_;
262 
263   ElementStyleResources element_style_resources_;
264   Element* pseudo_element_;
265   AnimatingElementType animating_element_type_;
266 
267   mutable HeapHashMap<
268       Member<const cssvalue::CSSPendingSubstitutionValue>,
269       Member<HeapHashMap<CSSPropertyID, Member<const CSSValue>>>>
270       parsed_properties_for_pending_substitution_cache_;
271   DISALLOW_COPY_AND_ASSIGN(StyleResolverState);
272 };
273 
274 }  // namespace blink
275 
276 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_RESOLVER_STATE_H_
277