Bug 1889496 - Part 2: Implement CSSStartingStyleRule interface. r=webidl,firefox-style-system-reviewers,layout-reviewers,emilio

Introduce CSSStartingStyleRule and add one extra parsing test for
@starting-style rule.

Differential Revision: https://phabricator.services.mozilla.com/D206564
This commit is contained in:
Boris Chiou 2024-04-05 21:03:07 +00:00
Родитель 8bc06baebe
Коммит f28ff20558
19 изменённых файлов: 199 добавлений и 46 удалений

Просмотреть файл

@ -1,5 +1,8 @@
[DEFAULT]
prefs = ["dom.svg.pathSeg.enabled=false"]
prefs = [
"dom.svg.pathSeg.enabled=false",
"layout.css.starting-style-at-rules.enabled=true",
]
support-files = [
"497633.html",
"fail.png",

Просмотреть файл

@ -328,6 +328,8 @@ let interfaceNamesInGlobalScope = [
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "CSSRuleList", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "CSSStartingStyleRule", insecureContext: true, nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "CSSStyleDeclaration", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "CSSStyleRule", insecureContext: true },

Просмотреть файл

@ -0,0 +1,12 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://drafts.csswg.org/css-transitions-2/#the-cssstartingstylerule-interface
*/
[Exposed=Window, Pref="layout.css.starting-style-at-rules.enabled"]
interface CSSStartingStyleRule : CSSGroupingRule {
};

Просмотреть файл

@ -497,6 +497,7 @@ WEBIDL_FILES = [
"CSSRule.webidl",
"CSSRuleList.webidl",
"CSSScopeRule.webidl",
"CSSStartingStyleRule.webidl",
"CSSStyleDeclaration.webidl",
"CSSStyleRule.webidl",
"CSSStyleSheet.webidl",

Просмотреть файл

@ -434,6 +434,7 @@ static uint32_t CollectAtRules(ServoCSSRuleList& aRuleList,
case StyleCssRuleType::FontFeatureValues:
case StyleCssRuleType::FontPaletteValues:
case StyleCssRuleType::Scope:
case StyleCssRuleType::StartingStyle:
break;
}

Просмотреть файл

@ -87,7 +87,8 @@ void ServoStyleRuleMap::RuleRemoved(StyleSheet& aStyleSheet,
case StyleCssRuleType::LayerBlock:
case StyleCssRuleType::Container:
case StyleCssRuleType::Document:
case StyleCssRuleType::Scope: {
case StyleCssRuleType::Scope:
case StyleCssRuleType::StartingStyle: {
// See the comment in SheetRemoved.
mTable.Clear();
break;
@ -126,7 +127,8 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) {
case StyleCssRuleType::Supports:
case StyleCssRuleType::Container:
case StyleCssRuleType::Document:
case StyleCssRuleType::Scope: {
case StyleCssRuleType::Scope:
case StyleCssRuleType::StartingStyle: {
auto& rule = static_cast<css::GroupRule&>(aRule);
FillTableFromRuleList(*rule.CssRules());
break;

Просмотреть файл

@ -0,0 +1,47 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/CSSStartingStyleRule.h"
#include "mozilla/dom/CSSStartingStyleRuleBinding.h"
#include "mozilla/ServoBindings.h"
namespace mozilla::dom {
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSStartingStyleRule,
css::GroupRule)
// QueryInterface implementation for SupportsRule
#ifdef DEBUG
void CSSStartingStyleRule::List(FILE* out, int32_t aIndent) const {
nsAutoCString str;
for (int32_t i = 0; i < aIndent; i++) {
str.AppendLiteral(" ");
}
Servo_StartingStyleRule_Debug(mRawRule, &str);
fprintf_stderr(out, "%s\n", str.get());
}
#endif
StyleCssRuleType CSSStartingStyleRule::Type() const {
return StyleCssRuleType::StartingStyle;
}
already_AddRefed<StyleLockedCssRules>
CSSStartingStyleRule::GetOrCreateRawRules() {
return Servo_StartingStyleRule_GetRules(mRawRule).Consume();
}
void CSSStartingStyleRule::GetCssText(nsACString& aCssText) const {
Servo_StartingStyleRule_GetCssText(mRawRule.get(), &aCssText);
}
JSObject* CSSStartingStyleRule::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return CSSStartingStyleRule_Binding::Wrap(aCx, this, aGivenProto);
}
} // namespace mozilla::dom

Просмотреть файл

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef CSSStaringStyleRule_h___
#define CSSStaringStyleRule_h___
#include "mozilla/css/GroupRule.h"
#include "mozilla/ServoBindingTypes.h"
namespace mozilla::dom {
class CSSStartingStyleRule final : public css::GroupRule {
public:
CSSStartingStyleRule(RefPtr<StyleStartingStyleRule> aRawRule,
StyleSheet* aSheet, css::Rule* aParentRule,
uint32_t aLine, uint32_t aColumn)
: css::GroupRule(aSheet, aParentRule, aLine, aColumn),
mRawRule(std::move(aRawRule)) {}
NS_DECL_ISUPPORTS_INHERITED
#ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
#endif
StyleStartingStyleRule* Raw() const { return mRawRule; }
void SetRawAfterClone(RefPtr<StyleStartingStyleRule> aRaw) {
mRawRule = std::move(aRaw);
css::GroupRule::DidSetRawAfterClone();
}
already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final;
// WebIDL interface
StyleCssRuleType Type() const final;
void GetCssText(nsACString& aCssText) const final;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
JSObject* WrapObject(JSContext*, JS::Handle<JSObject*>) override;
private:
~CSSStartingStyleRule() = default;
RefPtr<StyleStartingStyleRule> mRawRule;
};
} // namespace mozilla::dom
#endif

Просмотреть файл

@ -100,13 +100,15 @@ void Rule::AssertParentRuleType() {
// this->Type() here since it's virtual.
if (mParentRule) {
auto type = mParentRule->Type();
MOZ_ASSERT(
type == StyleCssRuleType::Media || type == StyleCssRuleType::Style ||
type == StyleCssRuleType::Document ||
type == StyleCssRuleType::Supports ||
type == StyleCssRuleType::Keyframes ||
type == StyleCssRuleType::LayerBlock ||
type == StyleCssRuleType::Container || type == StyleCssRuleType::Scope);
MOZ_ASSERT(type == StyleCssRuleType::Media ||
type == StyleCssRuleType::Style ||
type == StyleCssRuleType::Document ||
type == StyleCssRuleType::Supports ||
type == StyleCssRuleType::Keyframes ||
type == StyleCssRuleType::LayerBlock ||
type == StyleCssRuleType::Container ||
type == StyleCssRuleType::Scope ||
type == StyleCssRuleType::StartingStyle);
}
}
#endif

Просмотреть файл

@ -130,6 +130,7 @@ UNLOCKED_RULE_TYPE(Document)
UNLOCKED_RULE_TYPE(FontFeatureValues)
UNLOCKED_RULE_TYPE(FontPaletteValues)
UNLOCKED_RULE_TYPE(Scope)
UNLOCKED_RULE_TYPE(StartingStyle)
SERVO_ARC_TYPE(AnimationValue, mozilla::StyleAnimationValue)
SERVO_ARC_TYPE(ComputedStyle, mozilla::ComputedStyle)

Просмотреть файл

@ -88,6 +88,7 @@ BASIC_RULE_FUNCS_LOCKED(FontFace)
BASIC_RULE_FUNCS_LOCKED(CounterStyle)
GROUP_RULE_FUNCS_UNLOCKED(Container)
GROUP_RULE_FUNCS_UNLOCKED(Scope)
GROUP_RULE_FUNCS_UNLOCKED(StartingStyle)
#undef GROUP_RULE_FUNCS_LOCKED
#undef GROUP_RULE_FUNCS_UNLOCKED

Просмотреть файл

@ -22,9 +22,10 @@
#include "mozilla/dom/CSSNamespaceRule.h"
#include "mozilla/dom/CSSPageRule.h"
#include "mozilla/dom/CSSPropertyRule.h"
#include "mozilla/dom/CSSScopeRule.h"
#include "mozilla/dom/CSSStartingStyleRule.h"
#include "mozilla/dom/CSSStyleRule.h"
#include "mozilla/dom/CSSSupportsRule.h"
#include "mozilla/dom/CSSScopeRule.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/StyleSheet.h"
@ -100,15 +101,13 @@ css::Rule* ServoCSSRuleList::GetRule(uint32_t aIndex) {
CASE_RULE_UNLOCKED(LayerStatement, LayerStatement)
CASE_RULE_UNLOCKED(Container, Container)
CASE_RULE_UNLOCKED(Scope, Scope)
CASE_RULE_UNLOCKED(StartingStyle, StartingStyle)
#undef CASE_RULE_LOCKED
#undef CASE_RULE_UNLOCKED
#undef CASE_RULE_WITH_PREFIX
case StyleCssRuleType::Keyframe:
MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here");
return nullptr;
case StyleCssRuleType::StartingStyle:
// TODO: Implement this in the following patch.
return nullptr;
case StyleCssRuleType::Margin:
// Margin rules not implemented yet, see bug 1864737
return nullptr;
@ -291,9 +290,7 @@ void ServoCSSRuleList::SetRawContents(RefPtr<StyleLockedCssRules> aNewRules,
RULE_CASE_UNLOCKED(LayerStatement, LayerStatement)
RULE_CASE_UNLOCKED(Container, Container)
RULE_CASE_UNLOCKED(Scope, Scope)
case StyleCssRuleType::StartingStyle:
// TODO: Implement this in the following patch.
break;
RULE_CASE_UNLOCKED(StartingStyle, StartingStyle)
case StyleCssRuleType::Keyframe:
MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here");
break;

Просмотреть файл

@ -54,6 +54,7 @@ template struct StyleStrong<StyleLockedFontFaceRule>;
template struct StyleStrong<StyleLockedCounterStyleRule>;
template struct StyleStrong<StyleContainerRule>;
template struct StyleStrong<StyleScopeRule>;
template struct StyleStrong<StyleStartingStyleRule>;
template <typename T>
inline void StyleOwnedSlice<T>::Clear() {

Просмотреть файл

@ -43,6 +43,7 @@
#include "mozilla/dom/CSSPropertyRule.h"
#include "mozilla/dom/CSSScopeRule.h"
#include "mozilla/dom/CSSSupportsRule.h"
#include "mozilla/dom/CSSStartingStyleRule.h"
#include "mozilla/dom/FontFaceSet.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ElementInlines.h"
@ -1004,9 +1005,7 @@ void ServoStyleSet::RuleChangedInternal(StyleSheet& aSheet, css::Rule& aRule,
CASE_FOR(LayerStatement, LayerStatement)
CASE_FOR(Container, Container)
CASE_FOR(Scope, Scope)
case StyleCssRuleType::StartingStyle:
// TODO: Implement this in the following patch.
break;
CASE_FOR(StartingStyle, StartingStyle)
// @namespace can only be inserted / removed when there are only other
// @namespace and @import rules, and can't be mutated.
case StyleCssRuleType::Namespace:

Просмотреть файл

@ -145,6 +145,7 @@ EXPORTS.mozilla.dom += [
"CSSPropertyRule.h",
"CSSRuleList.h",
"CSSScopeRule.h",
"CSSStartingStyleRule.h",
"CSSStyleRule.h",
"CSSSupportsRule.h",
"CSSValue.h",
@ -197,6 +198,7 @@ UNIFIED_SOURCES += [
"CSSPropertyRule.cpp",
"CSSRuleList.cpp",
"CSSScopeRule.cpp",
"CSSStartingStyleRule.cpp",
"CSSStyleRule.cpp",
"CSSSupportsRule.cpp",
"DeclarationBlock.cpp",

Просмотреть файл

@ -16,7 +16,8 @@ use crate::stylesheets::keyframes_rule::Keyframe;
use crate::stylesheets::{
ContainerRule, CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule,
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
MediaRule, NamespaceRule, PageRule, PropertyRule, ScopeRule, StyleRule, StylesheetContents, SupportsRule,
MediaRule, NamespaceRule, PageRule, PropertyRule, ScopeRule, StartingStyleRule, StyleRule,
StylesheetContents, SupportsRule,
};
use servo_arc::Arc;
@ -174,3 +175,8 @@ impl_simple_arc_ffi!(
Servo_ScopeRule_AddRef,
Servo_ScopeRule_Release
);
impl_simple_arc_ffi!(
StartingStyleRule,
Servo_StartingStyleRule_AddRef,
Servo_StartingStyleRule_Release
);

Просмотреть файл

@ -138,7 +138,7 @@ use style::stylesheets::{
CssRules, CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule,
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
MediaRule, NamespaceRule, Origin, OriginSet, PagePseudoClassFlags, PageRule, PropertyRule,
SanitizationData, SanitizationKind, StyleRule, StylesheetContents,
SanitizationData, SanitizationKind, StartingStyleRule, StyleRule, StylesheetContents,
StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData, ScopeRule,
};
use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
@ -2499,6 +2499,14 @@ impl_group_rule_funcs! { (Scope, ScopeRule, ScopeRule),
changed: Servo_StyleSet_ScopeRuleChanged,
}
impl_group_rule_funcs! { (StartingStyle, StartingStyleRule, StartingStyleRule),
get_rules: Servo_StartingStyleRule_GetRules,
getter: Servo_CssRules_GetStartingStyleRuleAt,
debug: Servo_StartingStyleRule_Debug,
to_css: Servo_StartingStyleRule_GetCssText,
changed: Servo_StyleSet_StartingStyleRuleChanged,
}
#[no_mangle]
pub extern "C" fn Servo_StyleRule_GetStyle(
rule: &LockedStyleRule,

Просмотреть файл

@ -1,24 +0,0 @@
[idlharness-2.html]
[CSSStartingStyleRule interface: existence and properties of interface object]
expected: FAIL
[CSSStartingStyleRule interface object length]
expected: FAIL
[CSSStartingStyleRule interface object name]
expected: FAIL
[CSSStartingStyleRule interface: existence and properties of interface prototype object]
expected: FAIL
[CSSStartingStyleRule interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSStartingStyleRule interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[CSSStartingStyleRule must be primary interface of sheet.cssRules[0\]]
expected: FAIL
[Stringification of sheet.cssRules[0\]]
expected: FAIL

Просмотреть файл

@ -0,0 +1,38 @@
<!doctype html>
<title>@starting-style: parsing</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions-2/#at-ruledef-starting-style">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<main id=main></main>
<script>
function test_valid(actual, expected) {
if (expected === undefined)
expected = actual;
test(t => {
t.add_cleanup(() => main.replaceChildren());
let style = document.createElement('style');
style.textContent = `${actual}{}`;
main.append(style);
assert_equals(style.sheet.rules.length, 1);
let rule = style.sheet.rules[0];
assert_equals(rule.cssText, `${expected} {\n}`);
}, `${actual} is valid`);
}
function test_invalid(actual) {
test(t => {
t.add_cleanup(() => main.replaceChildren());
let style = document.createElement('style');
style.textContent = `${actual}{}`;
main.append(style);
assert_equals(style.sheet.rules.length, 0);
}, `${actual} is not valid`);
}
test_valid('@starting-style');
test_invalid('@starting-style div');
test_invalid('@starting-style ()');
test_invalid('@starting-style ( {}');
test_invalid('@starting-style }');
</script>