mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Don't serialize shorthand with non-uniform CSS-wide keywords
This commit is contained in:
parent
3c6b8d5a2c
commit
f8f4da3b90
Notes:
github-actions[bot]
2025-06-16 11:39:06 +00:00
Author: https://github.com/Calme1709
Commit: f8f4da3b90
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5066
Reviewed-by: https://github.com/AtkinsSJ ✅
5 changed files with 253 additions and 9 deletions
|
@ -61,8 +61,12 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (all_same_keyword && built_in_keyword.has_value())
|
if (built_in_keyword.has_value()) {
|
||||||
return MUST(String::from_utf8(string_from_keyword(built_in_keyword.value())));
|
if (all_same_keyword)
|
||||||
|
return MUST(String::from_utf8(string_from_keyword(built_in_keyword.value())));
|
||||||
|
|
||||||
|
return ""_string;
|
||||||
|
}
|
||||||
|
|
||||||
auto default_to_string = [&]() {
|
auto default_to_string = [&]() {
|
||||||
auto all_properties_same_value = true;
|
auto all_properties_same_value = true;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 11 tests
|
||||||
|
|
||||||
|
5 Pass
|
||||||
|
6 Fail
|
||||||
|
Fail All properties can serialize 'initial'
|
||||||
|
Fail All properties (except 'all') can serialize their initial value (computed)
|
||||||
|
Fail All properties (except 'all') can serialize their initial value (specified)
|
||||||
|
Fail All shorthands can serialize their longhands set to 'initial'
|
||||||
|
Fail All shorthands (except 'all') can serialize their longhands set to their initial value
|
||||||
|
Pass All aliases can serialize target property set to 'initial'
|
||||||
|
Pass All aliases can serialize target property set to its initial value
|
||||||
|
Fail Can't serialize shorthand when longhands are set to different css-wide keywords
|
||||||
|
Pass Can't serialize shorthand when longhands have different priority
|
||||||
|
Pass Can't serialize shorthand set to 'initial' when some longhand is missing
|
||||||
|
Pass Can't serialize shorthand set to initial value when some longhand is missing
|
|
@ -2,10 +2,10 @@ Harness status: OK
|
||||||
|
|
||||||
Found 5 tests
|
Found 5 tests
|
||||||
|
|
||||||
2 Pass
|
4 Pass
|
||||||
3 Fail
|
1 Fail
|
||||||
Pass Single value flex with CSS-wide keyword should serialize correctly.
|
Pass Single value flex with CSS-wide keyword should serialize correctly.
|
||||||
Fail Single value flex with non-CSS-wide value should serialize correctly.
|
Fail Single value flex with non-CSS-wide value should serialize correctly.
|
||||||
Pass Multiple values flex with CSS-wide keyword should serialize correctly.
|
Pass Multiple values flex with CSS-wide keyword should serialize correctly.
|
||||||
Fail Multiple values flex with CSS-wide keywords and non-CSS-wide value should serialize correctly.
|
Pass Multiple values flex with CSS-wide keywords and non-CSS-wide value should serialize correctly.
|
||||||
Fail Multiple values flex with CSS-wide and two non-CSS-wide-keyword values should serialize correctly.
|
Pass Multiple values flex with CSS-wide and two non-CSS-wide-keyword values should serialize correctly.
|
|
@ -2,12 +2,12 @@ Harness status: OK
|
||||||
|
|
||||||
Found 7 tests
|
Found 7 tests
|
||||||
|
|
||||||
5 Pass
|
6 Pass
|
||||||
2 Fail
|
1 Fail
|
||||||
Pass font-variant: normal serialization
|
Pass font-variant: normal serialization
|
||||||
Pass font-variant: none serialization
|
Pass font-variant: none serialization
|
||||||
Pass font-variant-ligatures: none serialization with non-default value for another longhand
|
Pass font-variant-ligatures: none serialization with non-default value for another longhand
|
||||||
Pass font-variant: normal with non-default longhands
|
Pass font-variant: normal with non-default longhands
|
||||||
Fail CSS-wide keyword in one longhand
|
Pass CSS-wide keyword in one longhand
|
||||||
Pass CSS-wide keyword in shorthand
|
Pass CSS-wide keyword in shorthand
|
||||||
Fail font: menu serialization
|
Fail font: menu serialization
|
|
@ -0,0 +1,223 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Common serialization checks for all properties</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue">
|
||||||
|
|
||||||
|
<div id="element"></div>
|
||||||
|
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
const element = document.getElementById("element");
|
||||||
|
const { style } = element;
|
||||||
|
const computedStyle = getComputedStyle(element);
|
||||||
|
const cssProperties = new Set();
|
||||||
|
const cssShorthands = new Map();
|
||||||
|
const cssShorthandsForLonghand = new Map();
|
||||||
|
const cssLonghands = new Set();
|
||||||
|
const cssAliases = new Map();
|
||||||
|
const initialValues = new Map();
|
||||||
|
|
||||||
|
setup(function() {
|
||||||
|
for (let obj = style; obj; obj = Reflect.getPrototypeOf(obj)) {
|
||||||
|
for (let name of Object.getOwnPropertyNames(obj)) {
|
||||||
|
const property = name.replace(/[A-Z]/g, c => "-" + c.toLowerCase());
|
||||||
|
if (CSS.supports(property, "initial")) {
|
||||||
|
cssProperties.add(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let property of cssProperties) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(property, "initial");
|
||||||
|
if (style.length > 1) {
|
||||||
|
cssShorthands.set(property, [...style]);
|
||||||
|
for (let longhand of style) {
|
||||||
|
if (cssShorthandsForLonghand.has(longhand)) {
|
||||||
|
cssShorthandsForLonghand.get(longhand).add(property);
|
||||||
|
} else {
|
||||||
|
cssShorthandsForLonghand.set(longhand, new Set([property]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (style.length === 1) {
|
||||||
|
if (property === style[0]) {
|
||||||
|
cssLonghands.add(property);
|
||||||
|
} else {
|
||||||
|
cssAliases.set(property, style[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let property of cssProperties) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(property, "initial");
|
||||||
|
const result = style.getPropertyValue(property);
|
||||||
|
if (result !== "initial") {
|
||||||
|
bad.push([property, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "All properties can serialize 'initial'");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
for (let longhand of cssLonghands) {
|
||||||
|
element.style.setProperty(longhand, "initial");
|
||||||
|
}
|
||||||
|
const bad = [];
|
||||||
|
for (let property of cssProperties) {
|
||||||
|
const result = computedStyle.getPropertyValue(property);
|
||||||
|
if (CSS.supports(property, result)) {
|
||||||
|
initialValues.set(property, result);
|
||||||
|
} else if (property !== "all") {
|
||||||
|
bad.push([property, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "All properties (except 'all') can serialize their initial value (computed)");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [property, value] of initialValues) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(property, value);
|
||||||
|
const result = style.getPropertyValue(property);
|
||||||
|
if (!CSS.supports(property, result) && property !== "all") {
|
||||||
|
bad.push([property, value, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "All properties (except 'all') can serialize their initial value (specified)");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [shorthand, longhands] of cssShorthands) {
|
||||||
|
style.cssText = "";
|
||||||
|
for (let longhand of longhands) {
|
||||||
|
style.setProperty(longhand, "initial");
|
||||||
|
}
|
||||||
|
const result = style.getPropertyValue(shorthand);
|
||||||
|
if (result !== "initial") {
|
||||||
|
bad.push([shorthand, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "All shorthands can serialize their longhands set to 'initial'");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
outerloop:
|
||||||
|
for (let [shorthand, longhands] of cssShorthands) {
|
||||||
|
style.cssText = "";
|
||||||
|
for (let longhand of longhands) {
|
||||||
|
if (!initialValues.has(longhand)) {
|
||||||
|
continue outerloop;
|
||||||
|
}
|
||||||
|
style.setProperty(longhand, initialValues.get(longhand));
|
||||||
|
}
|
||||||
|
const result = style.getPropertyValue(shorthand);
|
||||||
|
if (!CSS.supports(shorthand, result) && shorthand !== "all") {
|
||||||
|
bad.push([shorthand, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "All shorthands (except 'all') can serialize their longhands set to their initial value");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [alias, target] of cssAliases) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(target, "initial");
|
||||||
|
const result = style.getPropertyValue(alias);
|
||||||
|
if (result !== "initial") {
|
||||||
|
bad.push([alias, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "All aliases can serialize target property set to 'initial'");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [alias, target] of cssAliases) {
|
||||||
|
if (!initialValues.has(target)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(target, initialValues.get(target));
|
||||||
|
const result = style.getPropertyValue(alias);
|
||||||
|
if (!CSS.supports(alias, result)) {
|
||||||
|
bad.push([alias, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "All aliases can serialize target property set to its initial value");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [shorthand, longhands] of cssShorthands) {
|
||||||
|
for (let longhand of longhands) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(shorthand, "initial");
|
||||||
|
style.setProperty(longhand, "inherit");
|
||||||
|
const result = style.getPropertyValue(shorthand);
|
||||||
|
if (result !== "") {
|
||||||
|
bad.push([shorthand, longhand, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "Can't serialize shorthand when longhands are set to different css-wide keywords");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [shorthand, longhands] of cssShorthands) {
|
||||||
|
for (let longhand of longhands) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(shorthand, "initial");
|
||||||
|
style.setProperty(longhand, "initial", "important");
|
||||||
|
const result = style.getPropertyValue(shorthand);
|
||||||
|
if (result !== "") {
|
||||||
|
bad.push([shorthand, longhand, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "Can't serialize shorthand when longhands have different priority");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [shorthand, longhands] of cssShorthands) {
|
||||||
|
for (let longhand of longhands) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(shorthand, "initial");
|
||||||
|
style.removeProperty(longhand);
|
||||||
|
const result = style.getPropertyValue(shorthand);
|
||||||
|
if (result !== "") {
|
||||||
|
bad.push([shorthand, longhand, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "Can't serialize shorthand set to 'initial' when some longhand is missing");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const bad = [];
|
||||||
|
for (let [shorthand, longhands] of cssShorthands) {
|
||||||
|
if (initialValues.has(shorthand)) {
|
||||||
|
for (let longhand of longhands) {
|
||||||
|
style.cssText = "";
|
||||||
|
style.setProperty(shorthand, initialValues.get(shorthand));
|
||||||
|
style.removeProperty(longhand);
|
||||||
|
const result = style.getPropertyValue(shorthand);
|
||||||
|
if (result !== "") {
|
||||||
|
bad.push([shorthand, longhand, result]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_array_equals(bad, []);
|
||||||
|
}, "Can't serialize shorthand set to initial value when some longhand is missing");
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue