blob: 4a8efd2aadf164b33b99c3293f72fca4a3154686 [file] [log] [blame]
/*
* (C) 1999-2003 Lars Knoll (knoll@kde.org)
* (C) 2002-2003 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2002, 2006, 2008, 2012, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_H_
#include <limits>
#include "base/bits.h"
#include "base/memory/scoped_refptr.h"
#include "base/types/pass_key.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/container_query.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_selector_list.h"
#include "third_party/blink/renderer/core/css/css_syntax_definition.h"
#include "third_party/blink/renderer/core/css/css_variable_data.h"
#include "third_party/blink/renderer/core/css/media_list.h"
#include "third_party/blink/renderer/core/css/parser/css_at_rule_id.h"
#include "third_party/blink/renderer/core/css/parser/css_nesting_type.h"
#include "third_party/blink/renderer/core/css/style_scope.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class CascadeLayer;
class CSSRule;
class CSSStyleSheet;
class ExecutionContext;
class StyleSheetContents;
class CORE_EXPORT StyleRuleBase : public GarbageCollected<StyleRuleBase> {
public:
enum RuleType {
kCharset,
kStyle,
kImport,
kMedia,
kFontFace,
kFontPaletteValues,
kFontFeatureValues,
kFontFeature,
kPage,
kPageMargin,
kProperty,
kKeyframes,
kKeyframe,
kLayerBlock,
kLayerStatement,
kNamespace,
kContainer,
kCounterStyle,
kScope,
kSupports,
kStartingStyle,
kViewTransition,
kFunction,
kPositionTry,
};
// Name of a cascade layer as given by an @layer rule, split at '.' into a
// vector. Note that this may not be the full layer name if the rule is nested
// in another @layer rule or in a layered @import.
using LayerName = Vector<AtomicString, 1>;
static String LayerNameAsString(const LayerName&);
RuleType GetType() const { return static_cast<RuleType>(type_); }
bool IsCharsetRule() const { return GetType() == kCharset; }
bool IsContainerRule() const { return GetType() == kContainer; }
bool IsCounterStyleRule() const { return GetType() == kCounterStyle; }
bool IsFontFaceRule() const { return GetType() == kFontFace; }
bool IsFontPaletteValuesRule() const {
return GetType() == kFontPaletteValues;
}
bool IsFontFeatureValuesRule() const {
return GetType() == kFontFeatureValues;
}
bool IsFontFeatureRule() const { return GetType() == kFontFeature; }
bool IsKeyframesRule() const { return GetType() == kKeyframes; }
bool IsKeyframeRule() const { return GetType() == kKeyframe; }
bool IsLayerBlockRule() const { return GetType() == kLayerBlock; }
bool IsLayerStatementRule() const { return GetType() == kLayerStatement; }
bool IsNamespaceRule() const { return GetType() == kNamespace; }
bool IsMediaRule() const { return GetType() == kMedia; }
bool IsPageRule() const { return GetType() == kPage; }
bool IsPageRuleMargin() const { return GetType() == kPageMargin; }
bool IsPropertyRule() const { return GetType() == kProperty; }
bool IsStyleRule() const { return GetType() == kStyle; }
bool IsScopeRule() const { return GetType() == kScope; }
bool IsSupportsRule() const { return GetType() == kSupports; }
bool IsImportRule() const { return GetType() == kImport; }
bool IsStartingStyleRule() const { return GetType() == kStartingStyle; }
bool IsViewTransitionRule() const { return GetType() == kViewTransition; }
bool IsConditionRule() const {
return GetType() == kContainer || GetType() == kMedia ||
GetType() == kSupports || GetType() == kStartingStyle;
}
bool IsFunctionRule() const { return GetType() == kFunction; }
bool IsPositionTryRule() const { return GetType() == kPositionTry; }
StyleRuleBase* Copy() const;
// FIXME: There shouldn't be any need for the null parent version.
CSSRule* CreateCSSOMWrapper(
wtf_size_t position_hint = std::numeric_limits<wtf_size_t>::max(),
CSSStyleSheet* parent_sheet = nullptr,
bool trigger_use_counters = false) const;
CSSRule* CreateCSSOMWrapper(wtf_size_t position_hint,
CSSRule* parent_rule,
bool trigger_use_counters = false) const;
// Move this rule from being a child of old_parent (which is only given for
// sake of DCHECK) to being a child of new_parent, updating parent pointers
// in the selector. This happens only when we need to reallocate a StyleRule
// because its selector changed.
void Reparent(StyleRule* old_parent, StyleRule* new_parent);
void Trace(Visitor*) const;
void TraceAfterDispatch(blink::Visitor* visitor) const {}
void FinalizeGarbageCollectedObject();
// See CSSSelector::IsInvisible.
bool IsInvisible() const;
// See CSSSelector::Signal.
bool IsSignaling() const;
bool HasSignalingChildRule() const { return has_signaling_child_rule_; }
// This class mimics the API of HeapVector<Member<StyleRuleBase>>,
// except that any invisible rule added to the vector isn't visible
// through any member function except `RawChildRules`.
//
// TODO(crbug.com/1517290): Remove this when we're done use-counting.
class CORE_EXPORT ChildRuleVector : public GarbageCollected<ChildRuleVector> {
public:
ChildRuleVector() = default;
// An iterator which skips invisible rules.
class CORE_EXPORT Iterator {
STACK_ALLOCATED();
public:
Iterator(const Member<StyleRuleBase>* position,
const Member<StyleRuleBase>* end)
: position_(position), end_(end) {
CHECK_LE(position, end);
}
void operator++();
Member<StyleRuleBase> operator*() const { return *position_; }
bool operator==(const Iterator& o) const {
return position_ == o.position_ && end_ == o.end_;
}
bool operator!=(const Iterator& o) const { return !(*this == o); }
private:
const Member<StyleRuleBase>* position_;
const Member<StyleRuleBase>* end_;
};
ChildRuleVector* Copy() const;
Iterator begin() const {
// The AdjustedIndex call ensures that we skip leading invisible rules.
return Iterator(rules_.begin() + AdjustedIndex(0), rules_.end());
}
Iterator end() const { return Iterator(rules_.end(), rules_.end()); }
const Member<StyleRuleBase>& operator[](wtf_size_t i) const {
return rules_.at(AdjustedIndex(i));
}
Member<StyleRuleBase>& operator[](wtf_size_t i) {
return rules_.at(AdjustedIndex(i));
}
wtf_size_t size() const { return rules_.size() - num_invisible_rules_; }
void AddChildRule(StyleRuleBase* rule);
void WrapperInsertRule(unsigned index, StyleRuleBase*);
void WrapperRemoveRule(unsigned index);
const HeapVector<Member<StyleRuleBase>>& RawChildRules() const {
return rules_;
}
void Trace(blink::Visitor* visitor) const { visitor->Trace(rules_); }
private:
// Finds the real index of the Nth non-invisible child rule.
// The provided `index` must be in the range [0, size()].
wtf_size_t AdjustedIndex(wtf_size_t index) const;
HeapVector<Member<StyleRuleBase>> rules_;
wtf_size_t num_invisible_rules_ = 0;
};
protected:
explicit StyleRuleBase(RuleType type)
: type_(type), has_signaling_child_rule_(false) {}
StyleRuleBase(const StyleRuleBase& rule)
: type_(rule.type_),
has_signaling_child_rule_(rule.has_signaling_child_rule_) {}
void SetHasSignalingChildRule(bool has_signaling_child_rule) {
has_signaling_child_rule_ = has_signaling_child_rule;
}
private:
CSSRule* CreateCSSOMWrapper(wtf_size_t position_hint,
CSSStyleSheet* parent_sheet,
CSSRule* parent_rule,
bool trigger_use_counters) const;
const uint8_t type_;
// See CSSSelector::Signal.
bool has_signaling_child_rule_;
};
// A single rule from a stylesheet. Contains a selector list (one or more
// complex selectors) and a collection of style properties to be applied where
// those selectors match. These are output by CSSParserImpl.
//
// Note that since this we generate so many StyleRule objects, and all of them
// have at least one selector, the selector list is not allocated separately as
// on a CSSSelectorList. Instead, we put the CSSSelectors immediately after the
// StyleRule object. This both saves memory (since we don't need the pointer,
// or any of the extra allocation overhead), and makes it likely that the
// CSSSelectors are on the same cache line as the StyleRule. (On the flip side,
// it makes it unlikely that the CSSSelector's RareData is on the same cache
// line as the CSSSelector itself, but it is still overall a good tradeoff
// for us.) StyleRule provides an API that is a subset of CSSSelectorList,
// partially implemented using its static member functions.
class CORE_EXPORT StyleRule : public StyleRuleBase {
static AdditionalBytes AdditionalBytesForSelectors(size_t flattened_size) {
constexpr size_t padding_bytes =
base::bits::AlignUp(sizeof(StyleRule), alignof(CSSSelector)) -
sizeof(StyleRule);
return AdditionalBytes{(sizeof(CSSSelector) * flattened_size) +
padding_bytes};
}
public:
// Use these to allocate the right amount of memory for the StyleRule.
static StyleRule* Create(base::span<CSSSelector> selectors,
CSSPropertyValueSet* properties) {
return MakeGarbageCollected<StyleRule>(
AdditionalBytesForSelectors(selectors.size()),
base::PassKey<StyleRule>(), selectors, properties);
}
static StyleRule* Create(base::span<CSSSelector> selectors,
CSSLazyPropertyParser* lazy_property_parser) {
return MakeGarbageCollected<StyleRule>(
AdditionalBytesForSelectors(selectors.size()),
base::PassKey<StyleRule>(), selectors, lazy_property_parser);
}
// See comment on the corresponding constructor.
static StyleRule* Create(base::span<CSSSelector> selectors) {
return MakeGarbageCollected<StyleRule>(
AdditionalBytesForSelectors(selectors.size()),
base::PassKey<StyleRule>(), selectors);
}
// Creates a StyleRule with the selectors changed (used by setSelectorText()).
static StyleRule* Create(base::span<CSSSelector> selectors,
StyleRule&& other) {
return MakeGarbageCollected<StyleRule>(
AdditionalBytesForSelectors(selectors.size()),
base::PassKey<StyleRule>(), selectors, std::move(other));
}
// Constructors. Note that these expect that the StyleRule has been
// allocated on the Oilpan heap, with <flattened_size> * sizeof(CSSSelector)
// additional bytes after the StyleRule (flattened_size is the number of
// selectors). Do not call them directly; they are public only so that
// MakeGarbageCollected() can call them. Instead, use Create() above or
// Copy() below, as appropriate.
StyleRule(base::PassKey<StyleRule>,
base::span<CSSSelector> selector_vector,
CSSPropertyValueSet*);
StyleRule(base::PassKey<StyleRule>,
base::span<CSSSelector> selector_vector,
CSSLazyPropertyParser*);
// If you use this constructor, the object will not be fully constructed until
// you call SetProperties().
StyleRule(base::PassKey<StyleRule>, base::span<CSSSelector> selector_vector);
StyleRule(base::PassKey<StyleRule>,
base::span<CSSSelector> selector_vector,
StyleRule&&);
StyleRule(const StyleRule&, size_t flattened_size);
StyleRule(const StyleRule&) = delete;
~StyleRule();
void SetProperties(CSSPropertyValueSet* properties) {
DCHECK_EQ(properties_.Get(), nullptr);
properties_ = properties;
}
// Partial subset of the CSSSelector API.
const CSSSelector* FirstSelector() const { return SelectorArray(); }
const CSSSelector& SelectorAt(wtf_size_t index) const {
return SelectorArray()[index];
}
CSSSelector& MutableSelectorAt(wtf_size_t index) {
return SelectorArray()[index];
}
wtf_size_t SelectorIndex(const CSSSelector& selector) const {
return static_cast<wtf_size_t>(&selector - FirstSelector());
}
wtf_size_t IndexOfNextSelectorAfter(wtf_size_t index) const {
const CSSSelector& current = SelectorAt(index);
const CSSSelector* next = CSSSelectorList::Next(current);
if (!next) {
return kNotFound;
}
return SelectorIndex(*next);
}
String SelectorsText() const {
return CSSSelectorList::SelectorsText(FirstSelector());
}
const CSSPropertyValueSet& Properties() const;
MutableCSSPropertyValueSet& MutableProperties();
StyleRule* Copy() const {
const CSSSelector* selector_array = SelectorArray();
size_t flattened_size = 1;
while (!selector_array[flattened_size - 1].IsLastInSelectorList()) {
++flattened_size;
}
return MakeGarbageCollected<StyleRule>(
AdditionalBytesForSelectors(flattened_size), *this, flattened_size);
}
static unsigned AverageSizeInBytes();
// Helper function to avoid parsing lazy properties when not needed.
bool PropertiesHaveFailedOrCanceledSubresources() const;
void TraceAfterDispatch(blink::Visitor*) const;
const ChildRuleVector* ChildRules() const { return child_rule_vector_.Get(); }
void EnsureChildRules() {
// Allocate the child rule vector only when we need it,
// since most rules won't have children (almost by definition).
if (child_rule_vector_ == nullptr) {
child_rule_vector_ = MakeGarbageCollected<ChildRuleVector>();
}
}
// Note that if `child` is invisible (see CSSSelector::IsInvisible),
// then the added child rule won't be visible through `ChildRules`.
void AddChildRule(StyleRuleBase*);
void WrapperInsertRule(unsigned index, StyleRuleBase* rule) {
EnsureChildRules();
child_rule_vector_->WrapperInsertRule(index, rule);
}
void WrapperRemoveRule(unsigned index) {
child_rule_vector_->WrapperRemoveRule(index);
}
private:
friend class StyleRuleBase;
friend class CSSLazyParsingTest;
bool HasParsedProperties() const;
CSSSelector* SelectorArray() {
return reinterpret_cast<CSSSelector*>(base::bits::AlignUp(
reinterpret_cast<uint8_t*>(this + 1), alignof(CSSSelector)));
}
const CSSSelector* SelectorArray() const {
return const_cast<StyleRule*>(this)->SelectorArray();
}
mutable Member<CSSPropertyValueSet> properties_;
mutable Member<CSSLazyPropertyParser> lazy_property_parser_;
Member<ChildRuleVector> child_rule_vector_;
};
class CORE_EXPORT StyleRuleFontFace : public StyleRuleBase {
public:
explicit StyleRuleFontFace(CSSPropertyValueSet*);
StyleRuleFontFace(const StyleRuleFontFace&);
const CSSPropertyValueSet& Properties() const { return *properties_; }
MutableCSSPropertyValueSet& MutableProperties();
StyleRuleFontFace* Copy() const {
return MakeGarbageCollected<StyleRuleFontFace>(*this);
}
void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
const CascadeLayer* GetCascadeLayer() const { return layer_.Get(); }
void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSPropertyValueSet> properties_; // Cannot be null.
Member<const CascadeLayer> layer_;
};
class CORE_EXPORT StyleRuleProperty : public StyleRuleBase {
public:
StyleRuleProperty(const String& name, CSSPropertyValueSet*);
StyleRuleProperty(const StyleRuleProperty&);
const CSSPropertyValueSet& Properties() const { return *properties_; }
MutableCSSPropertyValueSet& MutableProperties();
const String& GetName() const { return name_; }
const CSSValue* GetSyntax() const;
const CSSValue* Inherits() const;
const CSSValue* GetInitialValue() const;
bool SetNameText(const ExecutionContext* execution_context,
const String& name_text);
void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
const CascadeLayer* GetCascadeLayer() const { return layer_.Get(); }
StyleRuleProperty* Copy() const {
return MakeGarbageCollected<StyleRuleProperty>(*this);
}
void TraceAfterDispatch(blink::Visitor*) const;
private:
String name_;
Member<CSSPropertyValueSet> properties_;
Member<const CascadeLayer> layer_;
};
class CORE_EXPORT StyleRuleGroup : public StyleRuleBase {
public:
const ChildRuleVector& ChildRules() const { return *child_rule_vector_; }
ChildRuleVector& ChildRules() { return *child_rule_vector_; }
void WrapperInsertRule(CSSStyleSheet*, unsigned, StyleRuleBase*);
void WrapperRemoveRule(CSSStyleSheet*, unsigned);
void TraceAfterDispatch(blink::Visitor*) const;
protected:
StyleRuleGroup(RuleType, HeapVector<Member<StyleRuleBase>> rules);
StyleRuleGroup(const StyleRuleGroup&);
private:
Member<ChildRuleVector> child_rule_vector_;
};
class CORE_EXPORT StyleRuleScope : public StyleRuleGroup {
public:
StyleRuleScope(const StyleScope&, HeapVector<Member<StyleRuleBase>> rules);
StyleRuleScope(const StyleRuleScope&);
StyleRuleScope* Copy() const {
return MakeGarbageCollected<StyleRuleScope>(*this);
}
void TraceAfterDispatch(blink::Visitor*) const;
const StyleScope& GetStyleScope() const { return *style_scope_; }
void SetPreludeText(const ExecutionContext*,
String,
CSSNestingType,
StyleRule* parent_rule_for_nesting,
bool is_within_scope,
StyleSheetContents* style_sheet);
private:
Member<const StyleScope> style_scope_;
};
// https://www.w3.org/TR/css-cascade-5/#layer-block
class CORE_EXPORT StyleRuleLayerBlock : public StyleRuleGroup {
public:
StyleRuleLayerBlock(LayerName&& name,
HeapVector<Member<StyleRuleBase>> rules);
StyleRuleLayerBlock(const StyleRuleLayerBlock&);
const LayerName& GetName() const { return name_; }
String GetNameAsString() const;
StyleRuleLayerBlock* Copy() const {
return MakeGarbageCollected<StyleRuleLayerBlock>(*this);
}
void TraceAfterDispatch(blink::Visitor*) const;
private:
LayerName name_;
};
// https://www.w3.org/TR/css-cascade-5/#layer-empty
class CORE_EXPORT StyleRuleLayerStatement : public StyleRuleBase {
public:
explicit StyleRuleLayerStatement(Vector<LayerName>&& names);
StyleRuleLayerStatement(const StyleRuleLayerStatement& other);
const Vector<LayerName>& GetNames() const { return names_; }
Vector<String> GetNamesAsStrings() const;
StyleRuleLayerStatement* Copy() const {
return MakeGarbageCollected<StyleRuleLayerStatement>(*this);
}
void TraceAfterDispatch(blink::Visitor*) const;
private:
Vector<LayerName> names_;
};
// TODO(sesse): When we get CSSOM support for page margin rules, consider
// whether this should be a StyleRuleGroup or not. (The page margin rules
// are not strictly selectors, though.)
class StyleRulePage : public StyleRuleBase {
public:
StyleRulePage(CSSSelectorList* selector_list,
CSSPropertyValueSet* properties,
HeapVector<Member<StyleRuleBase>> child_rules);
StyleRulePage(const StyleRulePage&);
const CSSSelector* Selector() const { return selector_list_->First(); }
const CSSPropertyValueSet& Properties() const { return *properties_; }
MutableCSSPropertyValueSet& MutableProperties();
void WrapperAdoptSelectorList(CSSSelectorList* selectors) {
selector_list_ = selectors;
}
StyleRulePage* Copy() const {
return MakeGarbageCollected<StyleRulePage>(*this);
}
void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
const CascadeLayer* GetCascadeLayer() const { return layer_.Get(); }
const HeapVector<Member<StyleRuleBase>, 4>& ChildRules() const {
return child_rules_;
}
HeapVector<Member<StyleRuleBase>, 4>& ChildRules() { return child_rules_; }
void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSPropertyValueSet> properties_; // Cannot be null.
Member<const CascadeLayer> layer_;
Member<CSSSelectorList> selector_list_;
// Page margin rules (e.g. @top-left).
HeapVector<Member<StyleRuleBase>, 4> child_rules_;
};
class StyleRulePageMargin : public StyleRuleBase {
public:
StyleRulePageMargin(CSSAtRuleID id, CSSPropertyValueSet* properties);
StyleRulePageMargin(const StyleRulePageMargin&);
const CSSPropertyValueSet& Properties() const { return *properties_; }
MutableCSSPropertyValueSet& MutableProperties();
CSSAtRuleID ID() const { return id_; }
StyleRulePageMargin* Copy() const {
return MakeGarbageCollected<StyleRulePageMargin>(*this);
}
void TraceAfterDispatch(blink::Visitor*) const;
private:
CSSAtRuleID id_; // What margin, e.g. @top-right.
Member<CSSPropertyValueSet> properties_; // Cannot be null.
};
// If you add new children of this class, remember to update IsConditionRule()
// above.
class CORE_EXPORT StyleRuleCondition : public StyleRuleGroup {
public:
String ConditionText() const { return condition_text_; }
void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleGroup::TraceAfterDispatch(visitor);
}
protected:
StyleRuleCondition(RuleType, HeapVector<Member<StyleRuleBase>> rules);
StyleRuleCondition(RuleType,
const String& condition_text,
HeapVector<Member<StyleRuleBase>> rules);
StyleRuleCondition(const StyleRuleCondition&);
String condition_text_;
};
class CORE_EXPORT StyleRuleMedia : public StyleRuleCondition {
public:
StyleRuleMedia(const MediaQuerySet*, HeapVector<Member<StyleRuleBase>> rules);
StyleRuleMedia(const StyleRuleMedia&) = default;
const MediaQuerySet* MediaQueries() const { return media_queries_.Get(); }
void SetMediaQueries(const MediaQuerySet* media_queries) {
media_queries_ = media_queries;
}
StyleRuleMedia* Copy() const {
return MakeGarbageCollected<StyleRuleMedia>(*this);
}
void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<const MediaQuerySet> media_queries_;
};
class CORE_EXPORT StyleRuleSupports : public StyleRuleCondition {
public:
StyleRuleSupports(const String& condition_text,
bool condition_is_supported,
HeapVector<Member<StyleRuleBase>> rules);
StyleRuleSupports(const StyleRuleSupports&);
bool ConditionIsSupported() const { return condition_is_supported_; }
StyleRuleSupports* Copy() const {
return MakeGarbageCollected<StyleRuleSupports>(*this);
}
void SetConditionText(const ExecutionContext*, String);
void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleCondition::TraceAfterDispatch(visitor);
}
private:
bool condition_is_supported_;
};
class CORE_EXPORT StyleRuleContainer : public StyleRuleCondition {
public:
StyleRuleContainer(ContainerQuery&, HeapVector<Member<StyleRuleBase>> rules);
StyleRuleContainer(const StyleRuleContainer&);
ContainerQuery& GetContainerQuery() const { return *container_query_; }
StyleRuleContainer* Copy() const {
return MakeGarbageCollected<StyleRuleContainer>(*this);
}
void SetConditionText(const ExecutionContext*, String);
void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<ContainerQuery> container_query_;
};
class StyleRuleStartingStyle : public StyleRuleGroup {
public:
explicit StyleRuleStartingStyle(HeapVector<Member<StyleRuleBase>> rules);
StyleRuleStartingStyle(const StyleRuleStartingStyle&) = default;
StyleRuleStartingStyle* Copy() const {
return MakeGarbageCollected<StyleRuleStartingStyle>(*this);
}
void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleGroup::TraceAfterDispatch(visitor);
}
};
// This should only be used within the CSS Parser
class StyleRuleCharset : public StyleRuleBase {
public:
StyleRuleCharset() : StyleRuleBase(kCharset) {}
void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleBase::TraceAfterDispatch(visitor);
}
private:
};
// An @function rule, representing a CSS function.
class CORE_EXPORT StyleRuleFunction : public StyleRuleBase {
public:
struct Type {
CSSSyntaxDefinition syntax;
// Whether this is a numeric type, that would be accepted by calc()
// (see https://drafts.csswg.org/css-values/#calc-func). This is used
// to allow the user to not have to write calc() around every single
// expression, so that one could do e.g. --foo(2 + 2) instead of
// --foo(calc(2 + 2)). Since writing calc() around an expression of
// such a type will never change its meaning, and nested calc is allowed,
// this is always safe even when not needed.
bool should_add_implicit_calc;
};
struct Parameter {
String name;
Type type;
};
StyleRuleFunction(AtomicString name,
Vector<Parameter> parameters,
scoped_refptr<CSSVariableData> function_body,
Type return_type);
StyleRuleFunction(const StyleRuleFunction&) = delete;
const AtomicString& GetName() const { return name_; }
const Vector<Parameter>& GetParameters() const { return parameters_; }
CSSVariableData& GetFunctionBody() const { return *function_body_; }
const Type& GetReturnType() const { return return_type_; }
void TraceAfterDispatch(blink::Visitor*) const;
private:
AtomicString name_;
Vector<Parameter> parameters_;
scoped_refptr<CSSVariableData> function_body_;
Type return_type_;
};
template <>
struct DowncastTraits<StyleRule> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsStyleRule();
}
};
template <>
struct DowncastTraits<StyleRuleFontFace> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsFontFaceRule();
}
};
template <>
struct DowncastTraits<StyleRulePage> {
static bool AllowFrom(const StyleRuleBase& rule) { return rule.IsPageRule(); }
};
template <>
struct DowncastTraits<StyleRulePageMargin> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsPageRuleMargin();
}
};
template <>
struct DowncastTraits<StyleRuleProperty> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsPropertyRule();
}
};
template <>
struct DowncastTraits<StyleRuleScope> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsScopeRule();
}
};
template <>
struct DowncastTraits<StyleRuleGroup> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsMediaRule() || rule.IsSupportsRule() ||
rule.IsContainerRule() || rule.IsLayerBlockRule() ||
rule.IsScopeRule() || rule.IsStartingStyleRule();
}
};
template <>
struct DowncastTraits<StyleRuleLayerBlock> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsLayerBlockRule();
}
};
template <>
struct DowncastTraits<StyleRuleLayerStatement> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsLayerStatementRule();
}
};
template <>
struct DowncastTraits<StyleRuleMedia> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsMediaRule();
}
};
template <>
struct DowncastTraits<StyleRuleSupports> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsSupportsRule();
}
};
template <>
struct DowncastTraits<StyleRuleContainer> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsContainerRule();
}
};
template <>
struct DowncastTraits<StyleRuleCharset> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsCharsetRule();
}
};
template <>
struct DowncastTraits<StyleRuleStartingStyle> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsStartingStyleRule();
}
};
template <>
struct DowncastTraits<StyleRuleFunction> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsFunctionRule();
}
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_H_