mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 1730134 - Add some parsing and serialization tests for @layer. r=boris
This uncovers some serialization bugs, and some missing null-checks given the statement layer doesn't have a rule list. Differential Revision: https://phabricator.services.mozilla.com/D125176
This commit is contained in:
parent
694fef2dcb
commit
b31a2c497f
@ -33,7 +33,9 @@ ServoCSSRuleList::ServoCSSRuleList(already_AddRefed<ServoCssRules> aRawRules,
|
||||
StyleSheet* aSheet,
|
||||
css::GroupRule* aParentRule)
|
||||
: mStyleSheet(aSheet), mParentRule(aParentRule), mRawRules(aRawRules) {
|
||||
Servo_CssRules_ListTypes(mRawRules, &mRules);
|
||||
if (mRawRules) {
|
||||
Servo_CssRules_ListTypes(mRawRules, &mRules);
|
||||
}
|
||||
}
|
||||
|
||||
// QueryInterface implementation for ServoCSSRuleList
|
||||
@ -166,7 +168,7 @@ nsresult ServoCSSRuleList::InsertRule(const nsACString& aRule,
|
||||
"Caller must ensure that "
|
||||
"the list is not unlinked from stylesheet");
|
||||
|
||||
if (IsReadOnly()) {
|
||||
if (!mRawRules || IsReadOnly()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -198,7 +200,7 @@ nsresult ServoCSSRuleList::InsertRule(const nsACString& aRule,
|
||||
}
|
||||
|
||||
nsresult ServoCSSRuleList::DeleteRule(uint32_t aIndex) {
|
||||
if (IsReadOnly()) {
|
||||
if (!mRawRules || IsReadOnly()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ impl ToCssWithGuard for LayerRule {
|
||||
guard: &SharedRwLockReadGuard,
|
||||
dest: &mut crate::str::CssStringWriter,
|
||||
) -> fmt::Result {
|
||||
dest.write_str("@layer ")?;
|
||||
dest.write_str("@layer")?;
|
||||
match self.kind {
|
||||
LayerRuleKind::Block {
|
||||
ref name,
|
||||
@ -242,8 +242,8 @@ impl ToCssWithGuard for LayerRule {
|
||||
ref is_anonymous,
|
||||
} => {
|
||||
if !*is_anonymous {
|
||||
name.to_css(&mut CssWriter::new(dest))?;
|
||||
dest.write_char(' ')?;
|
||||
name.to_css(&mut CssWriter::new(dest))?;
|
||||
}
|
||||
rules.read_with(guard).to_css_block(guard, dest)
|
||||
},
|
||||
@ -251,7 +251,9 @@ impl ToCssWithGuard for LayerRule {
|
||||
let mut writer = CssWriter::new(dest);
|
||||
let mut first = true;
|
||||
for name in &**names {
|
||||
if !first {
|
||||
if first {
|
||||
writer.write_char(' ')?;
|
||||
} else {
|
||||
writer.write_str(", ")?;
|
||||
}
|
||||
first = false;
|
||||
|
@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>@layer rule parsing / serialization</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="author" title="Mozilla" href="https://mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-cascade-5/#layering">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
<script>
|
||||
test_valid_rule("@layer A;");
|
||||
test_valid_rule("@layer A, B, C;");
|
||||
test_valid_rule("@layer A.A;");
|
||||
test_valid_rule("@layer A, B.C.D, C;");
|
||||
|
||||
test_invalid_rule("@layer;");
|
||||
test_invalid_rule("@layer A . A;");
|
||||
|
||||
test_valid_rule("@layer {\n}");
|
||||
test_valid_rule("@layer A {\n}");
|
||||
test_valid_rule("@layer A.B {\n}");
|
||||
test_invalid_rule("@layer A . B {\n}");
|
||||
|
||||
test_invalid_rule("@layer A, B, C {\n}");
|
||||
</script>
|
@ -95,3 +95,49 @@ function test_invalid_selector(selector) {
|
||||
stringifiedSelector + " should throw in insertRule");
|
||||
}, stringifiedSelector + " should be an invalid selector");
|
||||
}
|
||||
|
||||
// serialized can be the expected serialization of rule, or an array of
|
||||
// permitted serializations, or omitted if value should serialize as rule.
|
||||
function test_valid_rule(rule, serialized) {
|
||||
if (serialized === undefined)
|
||||
serialized = rule;
|
||||
|
||||
test(function(){
|
||||
const style = document.createElement("style");
|
||||
document.head.append(style);
|
||||
const {sheet} = style;
|
||||
document.head.removeChild(style);
|
||||
const {cssRules} = sheet;
|
||||
|
||||
assert_equals(cssRules.length, 0, "Sheet should have no rules");
|
||||
sheet.insertRule(rule);
|
||||
assert_equals(cssRules.length, 1, "Sheet should have 1 rule");
|
||||
|
||||
const serialization = cssRules[0].cssText;
|
||||
if (Array.isArray(serialized))
|
||||
assert_in_array(serialization, serialized, "serialization should be sound");
|
||||
else
|
||||
assert_equals(serialization, serialized, "serialization should be canonical");
|
||||
|
||||
sheet.deleteRule(0);
|
||||
assert_equals(cssRules.length, 0, "Sheet should have no rule");
|
||||
sheet.insertRule(serialization);
|
||||
assert_equals(cssRules.length, 1, "Sheet should have 1 rule");
|
||||
|
||||
assert_equals(cssRules[0].cssText, serialization, "serialization should round-trip");
|
||||
}, rule + " should be a valid rule");
|
||||
}
|
||||
|
||||
function test_invalid_rule(rule) {
|
||||
test(function(){
|
||||
const style = document.createElement("style");
|
||||
document.head.append(style);
|
||||
const {sheet} = style;
|
||||
document.head.removeChild(style);
|
||||
|
||||
assert_throws_dom(
|
||||
DOMException.SYNTAX_ERR,
|
||||
() => sheet.insertRule(rule),
|
||||
rule + " should throw in insertRule");
|
||||
}, rule + " should be an invalid rule");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user