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 "third_party/blink/renderer/core/animation/css/css_animation_update.h" 28 #include "third_party/blink/renderer/core/core_export.h" 29 #include "third_party/blink/renderer/core/css/css_property_name.h" 30 #include "third_party/blink/renderer/core/css/css_property_names.h" 31 #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" 32 #include "third_party/blink/renderer/core/css/parser/css_parser_mode.h" 33 #include "third_party/blink/renderer/core/css/pseudo_style_request.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 41 namespace blink { 42 43 class ComputedStyle; 44 class FontDescription; 45 class PseudoElement; 46 47 // A per-element object which wraps an ElementResolveContext. It collects state 48 // throughout the process of computing the style. It also gives convenient 49 // access to other element-related information. 50 class CORE_EXPORT StyleResolverState { 51 STACK_ALLOCATED(); 52 53 enum class ElementType { kElement, kPseudoElement }; 54 55 public: 56 StyleResolverState(Document&, 57 Element&, 58 const ComputedStyle* parent_style = nullptr, 59 const ComputedStyle* layout_parent_style = nullptr); 60 StyleResolverState(Document&, 61 Element&, 62 PseudoId, 63 PseudoElementStyleRequest::RequestType, 64 const ComputedStyle* parent_style, 65 const ComputedStyle* layout_parent_style); 66 StyleResolverState(const StyleResolverState&) = delete; 67 StyleResolverState& operator=(const StyleResolverState&) = delete; 68 ~StyleResolverState(); 69 IsForPseudoElement()70 bool IsForPseudoElement() const { 71 return element_type_ == ElementType::kPseudoElement; 72 } 73 74 // In FontFaceSet and CanvasRenderingContext2D, we don't have an element to 75 // grab the document from. This is why we have to store the document 76 // separately. GetDocument()77 Document& GetDocument() const { return *document_; } 78 // These are all just pass-through methods to ElementResolveContext. GetElement()79 Element& GetElement() const { return element_context_.GetElement(); } 80 TreeScope& GetTreeScope() const; ParentNode()81 const ContainerNode* ParentNode() const { 82 return element_context_.ParentNode(); 83 } RootElementStyle()84 const ComputedStyle* RootElementStyle() const { 85 if (const auto* root_element_style = element_context_.RootElementStyle()) 86 return root_element_style; 87 return Style(); 88 } ElementLinkState()89 EInsideLink ElementLinkState() const { 90 return element_context_.ElementLinkState(); 91 } DistributedToV0InsertionPoint()92 bool DistributedToV0InsertionPoint() const { 93 return element_context_.DistributedToV0InsertionPoint(); 94 } 95 ElementContext()96 const ElementResolveContext& ElementContext() const { 97 return element_context_; 98 } 99 100 void SetStyle(scoped_refptr<ComputedStyle>); Style()101 const ComputedStyle* Style() const { return style_.get(); } Style()102 ComputedStyle* Style() { return style_.get(); } StyleRef()103 ComputedStyle& StyleRef() { 104 DCHECK(style_); 105 return *style_; 106 } 107 scoped_refptr<ComputedStyle> TakeStyle(); 108 CssToLengthConversionData()109 const CSSToLengthConversionData& CssToLengthConversionData() const { 110 return css_to_length_conversion_data_; 111 } 112 CSSToLengthConversionData FontSizeConversionData() const; 113 CSSToLengthConversionData UnzoomedLengthConversionData() const; 114 SetConversionFontSizes(const CSSToLengthConversionData::FontSizes & font_sizes)115 void SetConversionFontSizes( 116 const CSSToLengthConversionData::FontSizes& font_sizes) { 117 css_to_length_conversion_data_.SetFontSizes(font_sizes); 118 } SetConversionZoom(float zoom)119 void SetConversionZoom(float zoom) { 120 css_to_length_conversion_data_.SetZoom(zoom); 121 } 122 AnimationUpdate()123 CSSAnimationUpdate& AnimationUpdate() { return animation_update_; } AnimationUpdate()124 const CSSAnimationUpdate& AnimationUpdate() const { 125 return animation_update_; 126 } 127 IsAnimationInterpolationMapReady()128 bool IsAnimationInterpolationMapReady() const { 129 return is_animation_interpolation_map_ready_; 130 } SetIsAnimationInterpolationMapReady()131 void SetIsAnimationInterpolationMapReady() { 132 is_animation_interpolation_map_ready_ = true; 133 } 134 135 Element* GetAnimatingElement() const; 136 137 void SetParentStyle(scoped_refptr<const ComputedStyle>); ParentStyle()138 const ComputedStyle* ParentStyle() const { return parent_style_.get(); } 139 140 void SetLayoutParentStyle(scoped_refptr<const ComputedStyle>); LayoutParentStyle()141 const ComputedStyle* LayoutParentStyle() const { 142 return layout_parent_style_.get(); 143 } 144 GetElementStyleResources()145 ElementStyleResources& GetElementStyleResources() { 146 return element_style_resources_; 147 } 148 149 void LoadPendingResources(); 150 151 // FIXME: Once styleImage can be made to not take a StyleResolverState 152 // this convenience function should be removed. As-is, without this, call 153 // sites are extremely verbose. GetStyleImage(CSSPropertyID property_id,const CSSValue & value)154 StyleImage* GetStyleImage(CSSPropertyID property_id, const CSSValue& value) { 155 return element_style_resources_.GetStyleImage(property_id, value); 156 } 157 GetFontBuilder()158 FontBuilder& GetFontBuilder() { return font_builder_; } GetFontBuilder()159 const FontBuilder& GetFontBuilder() const { return font_builder_; } 160 // FIXME: These exist as a primitive way to track mutations to font-related 161 // properties on a ComputedStyle. As designed, these are very error-prone, as 162 // some callers set these directly on the ComputedStyle w/o telling us. 163 // Presumably we'll want to design a better wrapper around ComputedStyle for 164 // tracking these mutations and separate it from StyleResolverState. 165 const FontDescription& ParentFontDescription() const; 166 167 void SetZoom(float); 168 void SetEffectiveZoom(float); 169 void SetWritingMode(WritingMode); 170 void SetTextOrientation(ETextOrientation); 171 SetHasDirAutoAttribute(bool value)172 void SetHasDirAutoAttribute(bool value) { has_dir_auto_attribute_ = value; } HasDirAutoAttribute()173 bool HasDirAutoAttribute() const { return has_dir_auto_attribute_; } 174 175 CSSParserMode GetParserMode() const; 176 177 // If the input CSSValue is a CSSLightDarkValuePair, return the light or dark 178 // CSSValue based on the UsedColorScheme. For all other values, just return a 179 // reference to the passed value. If the property is a non-inherited one, mark 180 // the ComputedStyle as having such a pair since that will make sure its not 181 // stored in the MatchedPropertiesCache. 182 const CSSValue& ResolveLightDarkPair(const CSSProperty&, const CSSValue&); 183 184 // The dependencies we track here end up in an entry in the 185 // MatchedPropertiesCache. Declarations such as "all:inherit" incurs several 186 // hundred dependencies, which is too big to cache, hence the number of 187 // dependencies we can track is limited. 188 static const size_t kMaxDependencies = 8; 189 190 // Mark the ComputedStyle as possibly dependent on the specified property. 191 // 192 // A "dependency" in this context means that one or more of the computed 193 // values held by the ComputedStyle depends on the computed value of the 194 // parent ComputedStyle. 195 // 196 // For example, a declaration such as background-color:var(--x) would incur 197 // a dependency on --x. 198 void MarkDependency(const CSSProperty&); 199 200 // Returns the set of all properties seen by MarkDependency. 201 // 202 // The caller must check if the dependencies are valid via 203 // HasValidDependencies() before calling this function. 204 // 205 // Note that this set might be larger than the actual set of dependencies, 206 // as we do some degree of over-marking to keep the implementation simple. 207 // 208 // For example, we mark all custom properties referenced as dependencies, even 209 // though the ComputedStyle itself may define a value for some or all of those 210 // custom properties. In the following example, both --x and --y will be 211 // added to this set, even though only --y is a true dependency: 212 // 213 // div { 214 // --x: 10px; 215 // margin: var(--x) (--y); 216 // } 217 // Dependencies()218 const HashSet<CSSPropertyName>& Dependencies() const { 219 DCHECK(HasValidDependencies()); 220 return dependencies_; 221 } 222 223 // True if there's a dependency without the kComputedValueComparable flag. HasIncomparableDependency()224 bool HasIncomparableDependency() const { 225 return has_incomparable_dependency_; 226 } 227 HasValidDependencies()228 bool HasValidDependencies() const { 229 return dependencies_.size() <= kMaxDependencies; 230 } 231 SetCanCacheBaseStyle(bool state)232 void SetCanCacheBaseStyle(bool state) { can_cache_base_style_ = state; } CanCacheBaseStyle()233 bool CanCacheBaseStyle() const { return can_cache_base_style_; } 234 235 private: 236 StyleResolverState(Document&, 237 Element&, 238 PseudoElement*, 239 PseudoElementStyleRequest::RequestType, 240 ElementType, 241 const ComputedStyle* parent_style, 242 const ComputedStyle* layout_parent_style); 243 244 CSSToLengthConversionData UnzoomedLengthConversionData( 245 const ComputedStyle* font_style) const; 246 247 ElementResolveContext element_context_; 248 Document* document_; 249 250 // style_ is the primary output for each element's style resolve. 251 scoped_refptr<ComputedStyle> style_; 252 253 CSSToLengthConversionData css_to_length_conversion_data_; 254 255 // parent_style_ is not always just ElementResolveContext::ParentStyle(), 256 // so we keep it separate. 257 scoped_refptr<const ComputedStyle> parent_style_; 258 // This will almost-always be the same that parent_style_, except in the 259 // presence of display: contents. This is the style against which we have to 260 // do adjustment. 261 scoped_refptr<const ComputedStyle> layout_parent_style_; 262 263 CSSAnimationUpdate animation_update_; 264 bool is_animation_interpolation_map_ready_ = false; 265 bool has_dir_auto_attribute_ = false; 266 PseudoElementStyleRequest::RequestType pseudo_request_type_; 267 268 FontBuilder font_builder_; 269 270 ElementStyleResources element_style_resources_; 271 Element* pseudo_element_; 272 ElementType element_type_; 273 274 // Properties depended on by the ComputedStyle. This is known after the 275 // cascade is applied. 276 HashSet<CSSPropertyName> dependencies_; 277 // True if there's an entry in 'dependencies_' which does not have the 278 // CSSProperty::kComputedValueComparable flag set. 279 bool has_incomparable_dependency_ = false; 280 281 // True if the base style can be cached to optimize style recalculations for 282 // animation updates or transition retargeting. 283 bool can_cache_base_style_ = false; 284 }; 285 286 } // namespace blink 287 288 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_RESOLVER_STATE_H_ 289