Commit f701be68 authored by Oriol Brufau's avatar Oriol Brufau Committed by Commit Bot

[css-pseudo] Restrict the properties allowed in ::marker

Only the following properties apply to a ::marker pseudo-element:
  - all font properties
  - `color`
  - `text-combine-upright`, `unicode-bidi`, and `direction`
  - `content`

Spec: https://drafts.csswg.org/css-pseudo-4/#marker-pseudo

BUG=457718

TEST=external/wpt/css/css-pseudo/parsing/marker-supported-properties.html

The test has 2 failures because font-synthesis and font-variant-position
have not been implemented yet.

Change-Id: I9f82e13bdd14a06a84ee55e352cd5a2c64d6fb97
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1891310Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Commit-Queue: Oriol Brufau <obrufau@igalia.com>
Cr-Commit-Position: refs/heads/master@{#710995}
parent a9d7f4c0
...@@ -1494,6 +1494,43 @@ static inline bool IsValidFirstLetterStyleProperty(CSSPropertyID id) { ...@@ -1494,6 +1494,43 @@ static inline bool IsValidFirstLetterStyleProperty(CSSPropertyID id) {
} }
} }
static inline bool IsValidMarkerStyleProperty(CSSPropertyID id) {
switch (id) {
// Valid ::marker properties listed in spec:
// https://drafts.csswg.org/css-pseudo-4/#marker-pseudo
case CSSPropertyID::kColor:
case CSSPropertyID::kContent:
case CSSPropertyID::kDirection:
case CSSPropertyID::kFont:
case CSSPropertyID::kFontFamily:
case CSSPropertyID::kFontFeatureSettings:
case CSSPropertyID::kFontKerning:
case CSSPropertyID::kFontOpticalSizing:
case CSSPropertyID::kFontSize:
case CSSPropertyID::kFontSizeAdjust:
case CSSPropertyID::kFontStretch:
case CSSPropertyID::kFontStyle:
case CSSPropertyID::kFontVariant:
case CSSPropertyID::kFontVariantCaps:
case CSSPropertyID::kFontVariantEastAsian:
case CSSPropertyID::kFontVariantLigatures:
case CSSPropertyID::kFontVariantNumeric:
case CSSPropertyID::kFontVariationSettings:
case CSSPropertyID::kFontWeight:
case CSSPropertyID::kTextCombineUpright:
case CSSPropertyID::kUnicodeBidi:
return true;
// Not directly specified in spec, but variables should be supported nearly
// anywhere.
case CSSPropertyID::kVariable:
return true;
default:
return false;
}
}
static bool PassesPropertyFilter(ValidPropertyFilter valid_property_filter, static bool PassesPropertyFilter(ValidPropertyFilter valid_property_filter,
CSSPropertyID property, CSSPropertyID property,
const Document& document) { const Document& document) {
...@@ -1504,6 +1541,8 @@ static bool PassesPropertyFilter(ValidPropertyFilter valid_property_filter, ...@@ -1504,6 +1541,8 @@ static bool PassesPropertyFilter(ValidPropertyFilter valid_property_filter,
return IsValidFirstLetterStyleProperty(property); return IsValidFirstLetterStyleProperty(property);
case ValidPropertyFilter::kCue: case ValidPropertyFilter::kCue:
return IsValidCueStyleProperty(property); return IsValidCueStyleProperty(property);
case ValidPropertyFilter::kMarker:
return IsValidMarkerStyleProperty(property);
} }
NOTREACHED(); NOTREACHED();
return true; return true;
......
...@@ -56,6 +56,8 @@ static inline ValidPropertyFilter DetermineValidPropertyFilter( ...@@ -56,6 +56,8 @@ static inline ValidPropertyFilter DetermineValidPropertyFilter(
return ValidPropertyFilter::kCue; return ValidPropertyFilter::kCue;
if (component->GetPseudoType() == CSSSelector::kPseudoFirstLetter) if (component->GetPseudoType() == CSSSelector::kPseudoFirstLetter)
return ValidPropertyFilter::kFirstLetter; return ValidPropertyFilter::kFirstLetter;
if (component->GetPseudoType() == CSSSelector::kPseudoMarker)
return ValidPropertyFilter::kMarker;
} }
return ValidPropertyFilter::kNoFilter; return ValidPropertyFilter::kNoFilter;
} }
......
...@@ -41,17 +41,20 @@ enum AddRuleFlags { ...@@ -41,17 +41,20 @@ enum AddRuleFlags {
kRuleHasDocumentSecurityOrigin = 1, kRuleHasDocumentSecurityOrigin = 1,
}; };
// Some CSS properties do not apply to certain psuedo-elements, and need to be // Some CSS properties do not apply to certain pseudo-elements, and need to be
// ignored when resolving styles. // ignored when resolving styles.
enum class ValidPropertyFilter : unsigned { enum class ValidPropertyFilter : unsigned {
// All properties are valid. This is the common case. // All properties are valid. This is the common case.
kNoFilter, kNoFilter,
// Defined in a :cue psuedo-element scope. Only properties listed // Defined in a ::cue pseudo-element scope. Only properties listed
// in https://w3c.github.io/webvtt/#the-cue-pseudo-element are valid. // in https://w3c.github.io/webvtt/#the-cue-pseudo-element are valid.
kCue, kCue,
// Defined in a :first-letter psuedo-element scope. Only properties listed in // Defined in a ::first-letter pseudo-element scope. Only properties listed in
// https://drafts.csswg.org/css-pseudo-4/#first-letter-styling are valid. // https://drafts.csswg.org/css-pseudo-4/#first-letter-styling are valid.
kFirstLetter, kFirstLetter,
// Defined in a ::marker pseudo-element scope. Only properties listed in
// https://drafts.csswg.org/css-pseudo-4/#marker-pseudo are valid.
kMarker,
}; };
class CSSSelector; class CSSSelector;
......
This is a testharness.js-based test.
PASS Property font value 'italic small-caps 900 expanded 25px / 50px Ahem' computes to ['italic small-caps 900 expanded 25px Ahem' or 'italic small-caps 900 expanded 25px/normal Ahem'] in ::marker
PASS Property font-family value 'Ahem' computes to 'Ahem' in ::marker
PASS Property font-feature-settings value '"smcp"' computes to '"smcp"' in ::marker
PASS Property font-kerning value 'none' computes to 'none' in ::marker
PASS Property font-size value '25px' computes to '25px' in ::marker
PASS Property font-size-adjust value '1' computes to '1' in ::marker
PASS Property font-stretch value 'expanded' computes to ['expanded' or '125%'] in ::marker
PASS Property font-style value 'italic' computes to 'italic' in ::marker
FAIL Property font-synthesis value 'none' computes to 'none' in ::marker assert_true: font-synthesis doesn't seem to be supported in the computed style expected true got false
PASS Property font-variant value 'small-caps' computes to 'small-caps' in ::marker
PASS Property font-variant-caps value 'small-caps' computes to 'small-caps' in ::marker
PASS Property font-variant-east-asian value 'full-width' computes to 'full-width' in ::marker
PASS Property font-variant-ligatures value 'historical-ligatures' computes to 'historical-ligatures' in ::marker
PASS Property font-variant-numeric value 'slashed-zero' computes to 'slashed-zero' in ::marker
FAIL Property font-variant-position value 'sub' computes to 'sub' in ::marker assert_true: font-variant-position doesn't seem to be supported in the computed style expected true got false
PASS Property font-weight value '900' computes to '900' in ::marker
PASS Property color value 'rgb(0, 100, 200)' computes to 'rgb(0, 100, 200)' in ::marker
PASS Property text-combine-upright value 'none' computes to 'none' in ::marker
PASS Property unicode-bidi value 'plaintext' computes to 'plaintext' in ::marker
PASS Property direction value 'rtl' computes to 'rtl' in ::marker
PASS Property content value '"foo"' computes to '"foo"' in ::marker
PASS Property display value 'none' computes to ['block' or 'inline'] in ::marker
PASS Property position value 'absolute' computes to 'static' in ::marker
PASS Property float value 'right' computes to 'none' in ::marker
PASS Property list-style value 'inside url('foo') decimal' computes to 'outside none disc' in ::marker
PASS Property list-style-image value 'url('foo')' computes to 'none' in ::marker
PASS Property list-style-position value 'inside' computes to 'outside' in ::marker
PASS Property list-style-type value 'decimal' computes to 'disc' in ::marker
PASS Property line-height value '50px' computes to 'normal' in ::marker
Harness: the test ran to completion.
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Pseudo-Elements Test: Supported properties in ::marker</title>
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<meta name="assert" content="This test checks that only certain properties apply to ::marker pseudo-elements." />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
<div id="log"></div>
<ul>
<li id="target">target</li>
</ul>
<script>
// ::marker supports all font properties.
test_pseudo_computed_value("::marker", "font", "italic small-caps 900 expanded 25px / 50px Ahem",
["italic small-caps 900 expanded 25px Ahem", "italic small-caps 900 expanded 25px/normal Ahem"]);
test_pseudo_computed_value("::marker", "font-family", "Ahem");
test_pseudo_computed_value("::marker", "font-feature-settings", "\"smcp\"");
test_pseudo_computed_value("::marker", "font-kerning", "none");
test_pseudo_computed_value("::marker", "font-size", "25px");
test_pseudo_computed_value("::marker", "font-size-adjust", "1");
test_pseudo_computed_value("::marker", "font-stretch", "expanded", ["expanded", "125%"]);
test_pseudo_computed_value("::marker", "font-style", "italic");
test_pseudo_computed_value("::marker", "font-synthesis", "none");
test_pseudo_computed_value("::marker", "font-variant", "small-caps");
test_pseudo_computed_value("::marker", "font-variant-caps", "small-caps");
test_pseudo_computed_value("::marker", "font-variant-east-asian", "full-width");
test_pseudo_computed_value("::marker", "font-variant-ligatures", "historical-ligatures");
test_pseudo_computed_value("::marker", "font-variant-numeric", "slashed-zero");
test_pseudo_computed_value("::marker", "font-variant-position", "sub");
test_pseudo_computed_value("::marker", "font-weight", "900");
// ::marker supports `color`
test_pseudo_computed_value("::marker", "color", "rgb(0, 100, 200)");
// ::marker supports `text-combine-upright`, `unicode-bidi` and `direction`
test_pseudo_computed_value("::marker", "text-combine-upright", "none");
test_pseudo_computed_value("::marker", "unicode-bidi", "plaintext");
test_pseudo_computed_value("::marker", "direction", "rtl");
// ::marker supports `content`
test_pseudo_computed_value("::marker", "content", "\"foo\"");
// ::marker does NOT support layout properties
test_pseudo_computed_value("::marker", "display", "none", ["block", "inline"]);
test_pseudo_computed_value("::marker", "position", "absolute", "static");
test_pseudo_computed_value("::marker", "float", "right", "none");
// ::marker does NOT support list properties despite being affected by them,
// they apply to the list item instead.
test_pseudo_computed_value("::marker", "list-style", "inside url('foo') decimal", "outside none disc");
test_pseudo_computed_value("::marker", "list-style-image", "url('foo')", "none");
test_pseudo_computed_value("::marker", "list-style-position", "inside", "outside");
test_pseudo_computed_value("::marker", "list-style-type", "decimal", "disc");
// ::marker does NOT support `line-height` because, despite being a
// longhand of `font`, it's not a font property.
test_pseudo_computed_value("::marker", "line-height", "50px", "normal");
</script>
...@@ -40,3 +40,44 @@ function test_computed_value(property, specified, computed) { ...@@ -40,3 +40,44 @@ function test_computed_value(property, specified, computed) {
}, "Property " + property + " value '" + specified + "' computes to " + }, "Property " + property + " value '" + specified + "' computes to " +
computedDesc); computedDesc);
} }
function test_pseudo_computed_value(pseudo, property, specified, computed) {
if (!computed)
computed = specified;
let computedDesc = "'" + computed + "'";
if (Array.isArray(computed))
computedDesc = '[' + computed.map(e => "'" + e + "'").join(' or ') + ']';
test(() => {
assert_true(/^::\w+$/.test(pseudo), pseudo + " doesn't seem to be a pseudo-element");
const styleElement = document.createElement("style");
document.documentElement.appendChild(styleElement);
try {
const {sheet} = styleElement;
sheet.insertRule("#target" + pseudo + "{}");
const {style} = sheet.cssRules[0];
const target = document.getElementById('target');
assert_true(property in getComputedStyle(target, pseudo), property + " doesn't seem to be supported in the computed style");
assert_true(CSS.supports(property, specified), "'" + specified + "' is a supported value for " + property + ".");
style[property] = specified;
let readValue = getComputedStyle(target, pseudo)[property];
if (Array.isArray(computed)) {
assert_in_array(readValue, computed);
} else {
assert_equals(readValue, computed);
}
if (readValue !== specified) {
style[property] = '';
style[property] = readValue;
assert_equals(getComputedStyle(target, pseudo)[property], readValue,
'computed value should round-trip');
}
} finally {
document.documentElement.removeChild(styleElement);
}
}, "Property " + property + " value '" + specified + "' computes to " +
computedDesc + " in " + pseudo);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment