blob: 466a6f3a1d5c761c7a07c6164fb1c6b11bd7b311 [file] [log] [blame]
/*
* (C) 1999-2003 Lars Knoll (knoll@kde.org)
* (C) 2002-2003 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2002, 2005, 2006, 2008, 2012 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.
*/
#include "third_party/blink/renderer/core/css/style_rule.h"
#include "third_party/blink/renderer/core/css/css_font_face_rule.h"
#include "third_party/blink/renderer/core/css/css_font_feature_values_rule.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_import_rule.h"
#include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
#include "third_party/blink/renderer/core/css/css_media_rule.h"
#include "third_party/blink/renderer/core/css/css_namespace_rule.h"
#include "third_party/blink/renderer/core/css/css_page_rule.h"
#include "third_party/blink/renderer/core/css/css_style_rule.h"
#include "third_party/blink/renderer/core/css/css_supports_rule.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/css_viewport_rule.h"
#include "third_party/blink/renderer/core/css/style_rule_import.h"
#include "third_party/blink/renderer/core/css/style_rule_keyframe.h"
#include "third_party/blink/renderer/core/css/style_rule_namespace.h"
namespace blink {
struct SameSizeAsStyleRuleBase
: public GarbageCollectedFinalized<SameSizeAsStyleRuleBase> {
unsigned bitfields;
};
static_assert(sizeof(StyleRuleBase) <= sizeof(SameSizeAsStyleRuleBase),
"StyleRuleBase should stay small");
CSSRule* StyleRuleBase::CreateCSSOMWrapper(CSSStyleSheet* parent_sheet) const {
return CreateCSSOMWrapper(parent_sheet, nullptr);
}
CSSRule* StyleRuleBase::CreateCSSOMWrapper(CSSRule* parent_rule) const {
return CreateCSSOMWrapper(nullptr, parent_rule);
}
void StyleRuleBase::Trace(blink::Visitor* visitor) {
switch (GetType()) {
case kCharset:
To<StyleRuleCharset>(this)->TraceAfterDispatch(visitor);
return;
case kStyle:
To<StyleRule>(this)->TraceAfterDispatch(visitor);
return;
case kPage:
To<StyleRulePage>(this)->TraceAfterDispatch(visitor);
return;
case kFontFace:
To<StyleRuleFontFace>(this)->TraceAfterDispatch(visitor);
return;
case kMedia:
To<StyleRuleMedia>(this)->TraceAfterDispatch(visitor);
return;
case kSupports:
To<StyleRuleSupports>(this)->TraceAfterDispatch(visitor);
return;
case kImport:
To<StyleRuleImport>(this)->TraceAfterDispatch(visitor);
return;
case kKeyframes:
To<StyleRuleKeyframes>(this)->TraceAfterDispatch(visitor);
return;
case kKeyframe:
To<StyleRuleKeyframe>(this)->TraceAfterDispatch(visitor);
return;
case kNamespace:
To<StyleRuleNamespace>(this)->TraceAfterDispatch(visitor);
return;
case kViewport:
To<StyleRuleViewport>(this)->TraceAfterDispatch(visitor);
return;
case kFontFeatureValues:
To<StyleRuleFontFeatureValues>(this)->TraceAfterDispatch(visitor);
return;
}
NOTREACHED();
}
void StyleRuleBase::FinalizeGarbageCollectedObject() {
switch (GetType()) {
case kCharset:
To<StyleRuleCharset>(this)->~StyleRuleCharset();
return;
case kStyle:
To<StyleRule>(this)->~StyleRule();
return;
case kPage:
To<StyleRulePage>(this)->~StyleRulePage();
return;
case kFontFace:
To<StyleRuleFontFace>(this)->~StyleRuleFontFace();
return;
case kMedia:
To<StyleRuleMedia>(this)->~StyleRuleMedia();
return;
case kSupports:
To<StyleRuleSupports>(this)->~StyleRuleSupports();
return;
case kImport:
To<StyleRuleImport>(this)->~StyleRuleImport();
return;
case kKeyframes:
To<StyleRuleKeyframes>(this)->~StyleRuleKeyframes();
return;
case kKeyframe:
To<StyleRuleKeyframe>(this)->~StyleRuleKeyframe();
return;
case kNamespace:
To<StyleRuleNamespace>(this)->~StyleRuleNamespace();
return;
case kViewport:
To<StyleRuleViewport>(this)->~StyleRuleViewport();
return;
case kFontFeatureValues:
To<StyleRuleFontFeatureValues>(this)->~StyleRuleFontFeatureValues();
return;
}
NOTREACHED();
}
StyleRuleBase* StyleRuleBase::Copy() const {
switch (GetType()) {
case kStyle:
return To<StyleRule>(this)->Copy();
case kPage:
return To<StyleRulePage>(this)->Copy();
case kFontFace:
return To<StyleRuleFontFace>(this)->Copy();
case kMedia:
return To<StyleRuleMedia>(this)->Copy();
case kSupports:
return To<StyleRuleSupports>(this)->Copy();
case kImport:
// FIXME: Copy import rules.
NOTREACHED();
return nullptr;
case kKeyframes:
return To<StyleRuleKeyframes>(this)->Copy();
case kViewport:
return To<StyleRuleViewport>(this)->Copy();
case kNamespace:
return To<StyleRuleNamespace>(this)->Copy();
case kFontFeatureValues:
return To<StyleRuleFontFeatureValues>(this)->Copy();
case kCharset:
case kKeyframe:
NOTREACHED();
return nullptr;
}
NOTREACHED();
return nullptr;
}
CSSRule* StyleRuleBase::CreateCSSOMWrapper(CSSStyleSheet* parent_sheet,
CSSRule* parent_rule) const {
CSSRule* rule = nullptr;
StyleRuleBase* self = const_cast<StyleRuleBase*>(this);
switch (GetType()) {
case kStyle:
rule =
MakeGarbageCollected<CSSStyleRule>(To<StyleRule>(self), parent_sheet);
break;
case kPage:
rule = MakeGarbageCollected<CSSPageRule>(To<StyleRulePage>(self),
parent_sheet);
break;
case kFontFace:
rule = MakeGarbageCollected<CSSFontFaceRule>(To<StyleRuleFontFace>(self),
parent_sheet);
break;
case kMedia:
rule = MakeGarbageCollected<CSSMediaRule>(To<StyleRuleMedia>(self),
parent_sheet);
break;
case kSupports:
rule = MakeGarbageCollected<CSSSupportsRule>(To<StyleRuleSupports>(self),
parent_sheet);
break;
case kImport:
rule = MakeGarbageCollected<CSSImportRule>(To<StyleRuleImport>(self),
parent_sheet);
break;
case kKeyframes:
rule = MakeGarbageCollected<CSSKeyframesRule>(
To<StyleRuleKeyframes>(self), parent_sheet);
break;
case kNamespace:
rule = MakeGarbageCollected<CSSNamespaceRule>(
To<StyleRuleNamespace>(self), parent_sheet);
break;
case kViewport:
rule = MakeGarbageCollected<CSSViewportRule>(To<StyleRuleViewport>(self),
parent_sheet);
break;
case kFontFeatureValues:
rule = MakeGarbageCollected<CSSFontFeatureValuesRule>(
To<StyleRuleFontFeatureValues>(self), parent_sheet);
break;
case kKeyframe:
case kCharset:
NOTREACHED();
return nullptr;
}
if (parent_rule)
rule->SetParentRule(parent_rule);
return rule;
}
unsigned StyleRule::AverageSizeInBytes() {
return sizeof(StyleRule) + sizeof(CSSSelector) +
CSSPropertyValueSet::AverageSizeInBytes();
}
StyleRule::StyleRule(CSSSelectorList selector_list,
CSSPropertyValueSet* properties)
: StyleRuleBase(kStyle),
should_consider_for_matching_rules_(kConsiderIfNonEmpty),
selector_list_(std::move(selector_list)),
properties_(properties) {}
StyleRule::StyleRule(CSSSelectorList selector_list,
CSSLazyPropertyParser* lazy_property_parser)
: StyleRuleBase(kStyle),
should_consider_for_matching_rules_(kAlwaysConsider),
selector_list_(std::move(selector_list)),
lazy_property_parser_(lazy_property_parser) {}
const CSSPropertyValueSet& StyleRule::Properties() const {
if (!properties_) {
properties_ = lazy_property_parser_->ParseProperties();
lazy_property_parser_.Clear();
}
return *properties_;
}
StyleRule::StyleRule(const StyleRule& o)
: StyleRuleBase(o),
should_consider_for_matching_rules_(kConsiderIfNonEmpty),
selector_list_(o.selector_list_.Copy()),
properties_(o.Properties().MutableCopy()) {}
StyleRule::~StyleRule() = default;
MutableCSSPropertyValueSet& StyleRule::MutableProperties() {
// Ensure properties_ is initialized.
if (!Properties().IsMutable())
properties_ = properties_->MutableCopy();
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
bool StyleRule::PropertiesHaveFailedOrCanceledSubresources() const {
return properties_ && properties_->HasFailedOrCanceledSubresources();
}
bool StyleRule::ShouldConsiderForMatchingRules(bool include_empty_rules) const {
DCHECK(should_consider_for_matching_rules_ == kAlwaysConsider || properties_);
return include_empty_rules ||
should_consider_for_matching_rules_ == kAlwaysConsider ||
!properties_->IsEmpty();
}
bool StyleRule::HasParsedProperties() const {
// StyleRule should only have one of {lazy_property_parser_, properties_} set.
DCHECK(lazy_property_parser_ || properties_);
DCHECK(!lazy_property_parser_ || !properties_);
return !lazy_property_parser_;
}
void StyleRule::TraceAfterDispatch(blink::Visitor* visitor) {
visitor->Trace(properties_);
visitor->Trace(lazy_property_parser_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
StyleRulePage::StyleRulePage(CSSSelectorList selector_list,
CSSPropertyValueSet* properties)
: StyleRuleBase(kPage),
properties_(properties),
selector_list_(std::move(selector_list)) {}
StyleRulePage::StyleRulePage(const StyleRulePage& page_rule)
: StyleRuleBase(page_rule),
properties_(page_rule.properties_->MutableCopy()),
selector_list_(page_rule.selector_list_.Copy()) {}
StyleRulePage::~StyleRulePage() = default;
MutableCSSPropertyValueSet& StyleRulePage::MutableProperties() {
if (!properties_->IsMutable())
properties_ = properties_->MutableCopy();
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
void StyleRulePage::TraceAfterDispatch(blink::Visitor* visitor) {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
StyleRuleFontFace::StyleRuleFontFace(CSSPropertyValueSet* properties)
: StyleRuleBase(kFontFace), properties_(properties) {}
StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& font_face_rule)
: StyleRuleBase(font_face_rule),
properties_(font_face_rule.properties_->MutableCopy()) {}
StyleRuleFontFace::~StyleRuleFontFace() = default;
MutableCSSPropertyValueSet& StyleRuleFontFace::MutableProperties() {
if (!properties_->IsMutable())
properties_ = properties_->MutableCopy();
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
void StyleRuleFontFace::TraceAfterDispatch(blink::Visitor* visitor) {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
StyleRuleGroup::StyleRuleGroup(RuleType type,
HeapVector<Member<StyleRuleBase>>& adopt_rule)
: StyleRuleBase(type) {
child_rules_.swap(adopt_rule);
}
StyleRuleGroup::StyleRuleGroup(const StyleRuleGroup& group_rule)
: StyleRuleBase(group_rule), child_rules_(group_rule.child_rules_.size()) {
for (unsigned i = 0; i < child_rules_.size(); ++i)
child_rules_[i] = group_rule.child_rules_[i]->Copy();
}
void StyleRuleGroup::WrapperInsertRule(unsigned index, StyleRuleBase* rule) {
child_rules_.insert(index, rule);
}
void StyleRuleGroup::WrapperRemoveRule(unsigned index) {
child_rules_.EraseAt(index);
}
void StyleRuleGroup::TraceAfterDispatch(blink::Visitor* visitor) {
visitor->Trace(child_rules_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
StyleRuleCondition::StyleRuleCondition(
RuleType type,
HeapVector<Member<StyleRuleBase>>& adopt_rules)
: StyleRuleGroup(type, adopt_rules) {}
StyleRuleCondition::StyleRuleCondition(
RuleType type,
const String& condition_text,
HeapVector<Member<StyleRuleBase>>& adopt_rules)
: StyleRuleGroup(type, adopt_rules), condition_text_(condition_text) {}
StyleRuleCondition::StyleRuleCondition(
const StyleRuleCondition& condition_rule) = default;
StyleRuleMedia::StyleRuleMedia(scoped_refptr<MediaQuerySet> media,
HeapVector<Member<StyleRuleBase>>& adopt_rules)
: StyleRuleCondition(kMedia, adopt_rules), media_queries_(media) {}
StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& media_rule)
: StyleRuleCondition(media_rule) {
if (media_rule.media_queries_)
media_queries_ = media_rule.media_queries_->Copy();
}
StyleRuleSupports::StyleRuleSupports(
const String& condition_text,
bool condition_is_supported,
HeapVector<Member<StyleRuleBase>>& adopt_rules)
: StyleRuleCondition(kSupports, condition_text, adopt_rules),
condition_is_supported_(condition_is_supported) {}
void StyleRuleMedia::TraceAfterDispatch(blink::Visitor* visitor) {
StyleRuleCondition::TraceAfterDispatch(visitor);
}
StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& supports_rule)
: StyleRuleCondition(supports_rule),
condition_is_supported_(supports_rule.condition_is_supported_) {}
StyleRuleViewport::StyleRuleViewport(CSSPropertyValueSet* properties)
: StyleRuleBase(kViewport), properties_(properties) {}
StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& viewport_rule)
: StyleRuleBase(viewport_rule),
properties_(viewport_rule.properties_->MutableCopy()) {}
StyleRuleViewport::~StyleRuleViewport() = default;
MutableCSSPropertyValueSet& StyleRuleViewport::MutableProperties() {
if (!properties_->IsMutable())
properties_ = properties_->MutableCopy();
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
void StyleRuleViewport::TraceAfterDispatch(blink::Visitor* visitor) {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
StyleRuleFontFeatureValues::StyleRuleFontFeatureValues(
const CSSValueList* font_family,
const CSSIdentifierValue* font_display)
: StyleRuleBase(kFontFeatureValues),
font_family_(font_family),
font_display_(font_display) {}
void StyleRuleFontFeatureValues::TraceAfterDispatch(blink::Visitor* visitor) {
visitor->Trace(font_family_);
visitor->Trace(font_display_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
} // namespace blink