[css-pseudo] Support animations and transitions in ::marker

As resolved in https://github.com/w3c/csswg-drafts/issues/4814, allow
::marker to have animations or transitions. But only for the properties
that apply to ::marker.

TEST=external/wpt/css/css-animations/Document-getAnimations.tentative.html
TEST=external/wpt/css/css-animations/animationevent-marker-pseudoelement.html
TEST=external/wpt/css/css-animations/event-order.tentative.html
TEST=external/wpt/css/css-pseudo/parsing/marker-supported-properties.html
TEST=external/wpt/css/css-pseudo/parsing/marker-supported-properties-in-animation.html
TEST=external/wpt/css/css-transitions/Document-getAnimations.tentative.html
TEST=external/wpt/css/css-transitions/non-rendered-element-004.tentative.html

BUG=1054509

Change-Id: Ie86aeb42d4d311264fd5810c1ad89c0fa7b93ab0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2119518
Commit-Queue: Oriol Brufau <obrufau@igalia.com>
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#753752}
diff --git a/css/css-pseudo/parsing/marker-supported-properties-in-animation.html b/css/css-pseudo/parsing/marker-supported-properties-in-animation.html
new file mode 100644
index 0000000..faf7c90
--- /dev/null
+++ b/css/css-pseudo/parsing/marker-supported-properties-in-animation.html
@@ -0,0 +1,292 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Pseudo-Elements Test: Supported properties in ::marker animations</title>
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
+<link rel="help" href="https://drafts.csswg.org/css-animations-1/#keyframes">
+<link rel="help" href="https://drafts.csswg.org/css-transitions-1/#transitions">
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<meta name="assert" content="This test checks ::marker supports animations and transitions, but only for the properties that apply to ::marker." />
+<style id="style"></style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<ul>
+  <li id="target">target</li>
+</ul>
+<script>
+const interpolationTests = [
+  // ::marker supports all font properties.
+  {
+    property: "font",
+    from: "oblique normal 100 ultra-condensed 5px / 20px serif",
+    to: "italic small-caps 900 ultra-expanded 25px / 50px Ahem",
+    midPoint: ["italic small-caps 500 expanded 15px Ahem", "italic small-caps 500 expanded 15px/normal Ahem"],
+  },
+  {
+    property: "font-family",
+    from: "serif",
+    to: "Ahem",
+    midPoint: "Ahem",
+  },
+  {
+    property: "font-feature-settings",
+    from: "'c2sc'",
+    to: "'smcp'",
+    midPoint: "\"smcp\"",
+  },
+  {
+    property: "font-kerning",
+    from: "normal",
+    to: "none",
+    midPoint: "none",
+  },
+  {
+    property: "font-size",
+    from: "5px",
+    to: "25px",
+    midPoint: "15px",
+  },
+  {
+    property: "font-size-adjust",
+    from: "1",
+    to: "3",
+    midPoint: "2",
+  },
+  {
+    property: "font-stretch",
+    from: "ultra-condensed",
+    to: "ultra-expanded",
+    midPoint: ["expanded", "125%"],
+  },
+  {
+    property: "font-style",
+    from: "oblique",
+    to: "italic",
+    midPoint: "italic",
+  },
+  {
+    property: "font-synthesis",
+    from: "weight",
+    to: "none",
+    midPoint: "none",
+  },
+  {
+    property: "font-variant",
+    from: "unicase",
+    to: "small-caps",
+    midPoint: "small-caps",
+  },
+  {
+    property: "font-variant-caps",
+    from: "unicase",
+    to: "small-caps",
+    midPoint: "small-caps",
+  },
+  {
+    property: "font-variant-east-asian",
+    from: "proportional-width",
+    to: "full-width",
+    midPoint: "full-width",
+  },
+  {
+    property: "font-variant-ligatures",
+    from: "no-historical-ligatures",
+    to: "historical-ligatures",
+    midPoint: "historical-ligatures",
+  },
+  {
+    property: "font-variant-numeric",
+    from: "ordinal",
+    to: "slashed-zero",
+    midPoint: "slashed-zero",
+  },
+  {
+    property: "font-variant-position",
+    from: "super",
+    to: "sub",
+    midPoint: "sub",
+  },
+  {
+    property: "font-weight",
+    from: "100",
+    to: "900",
+    midPoint: "500",
+  },
+
+  // ::marker supports `white-space`
+  {
+    property: "white-space",
+    from: "pre-line",
+    to: "nowrap",
+    midPoint: "nowrap",
+  },
+
+  // ::marker supports `color`
+  {
+    property: "color",
+    from: "rgb(0, 100, 200)",
+    to: "rgb(100, 200, 0)",
+    midPoint: "rgb(50, 150, 100)",
+  },
+
+  // ::marker supports `text-combine-upright`, `unicode-bidi` and `direction`,
+  // but they are not animatable.
+  {
+    property: "text-combine-upright",
+    from: "all",
+    to: "all",
+    midPoint: null,
+  },
+  {
+    property: "unicode-bidi",
+    from: "embed",
+    to: "plaintext",
+    midPoint: null,
+  },
+  {
+    property: "direction",
+    from: "rtl",
+    to: "rtl",
+    midPoint: null,
+  },
+
+  // ::marker supports `content`
+  {
+    property: "content",
+    from: "'foo'",
+    to: "'bar'",
+    midPoint: "\"bar\"",
+  },
+
+  // ::marker does NOT support layout properties
+  {
+    property: "display",
+    from: "flex",
+    to: "none",
+    midPoint: ["block", "inline", "inline-block"],
+  },
+  {
+    property: "position",
+    from: "fixed",
+    to: "absolute",
+    midPoint: "static",
+  },
+  {
+    property: "float",
+    from: "left",
+    to: "right",
+    midPoint: "none",
+  },
+
+  // ::marker does NOT support list properties despite being affected by them,
+  // they apply to the list item instead.
+  {
+    property: "list-style",
+    from: "inside url('foo') square",
+    to: "inside url('bar') decimal",
+    midPoint: "outside none disc",
+  },
+  {
+    property: "list-style-image",
+    from: "url('foo')",
+    to: "url('bar')",
+    midPoint: "none",
+  },
+  {
+    property: "list-style-position",
+    from: "inside",
+    to: "inside",
+    midPoint: "outside",
+  },
+  {
+    property: "list-style-type",
+    from: "square",
+    to: "decimal",
+    midPoint: "disc",
+  },
+
+  // ::marker does NOT support `line-height` because, despite being a
+  // longhand of `font`, it's not a font property.
+  {
+    property: "line-height",
+    from: "20px",
+    to: "50px",
+    midPoint: "normal",
+  },
+];
+
+const target = document.getElementById("target");
+const styleElement = document.getElementById("style");
+const markerStyle = getComputedStyle(target, "::marker");
+
+function check({property, from, to, midPoint}) {
+  assert_true(property in markerStyle, property + " doesn't seem to be supported in the computed style");
+  assert_true(CSS.supports(property, from), `'${from}' is a supported value for ${property}.`);
+  assert_true(CSS.supports(property, to), `'${to}' is a supported value for ${property}.`);
+  const computed = markerStyle.getPropertyValue(property);
+  if (Array.isArray(midPoint)) {
+    assert_in_array(computed, midPoint);
+  } else {
+    assert_equals(computed, midPoint);
+  }
+}
+
+function testAnimations(interpolationTests) {
+  styleElement.textContent = `
+    ::marker {
+      animation: anim 2s -1s paused linear;
+    }
+    @keyframes anim {
+      from {}
+      to {}
+    }
+  `;
+  const keyframes = styleElement.sheet.cssRules[1];
+  const fromStyle = keyframes.cssRules[0].style;
+  const toStyle = keyframes.cssRules[1].style;
+  for (let {property, from, to, midPoint} of interpolationTests) {
+    fromStyle.cssText = "";
+    toStyle.cssText = "";
+    if (midPoint == null) {
+      midPoint = markerStyle.getPropertyValue(property);
+    }
+    fromStyle.setProperty(property, from);
+    toStyle.setProperty(property, to);
+    test(() => {
+      check({property, from, to, midPoint});
+    }, `Animation of ${property} in ::marker`);
+  }
+}
+
+function testTransitions(interpolationTests) {
+  styleElement.textContent = `
+    .transition::marker {
+      transition: all 2s -1s linear;
+    }
+    .from::marker {}
+    .to::marker {}
+  `;
+  const fromStyle = styleElement.sheet.cssRules[1].style;
+  const toStyle = styleElement.sheet.cssRules[2].style;
+  for (let {property, from, to, midPoint} of interpolationTests) {
+    fromStyle.cssText = "";
+    toStyle.cssText = "";
+    if (midPoint == null) {
+      midPoint = to;
+    }
+    fromStyle.setProperty(property, from);
+    toStyle.setProperty(property, to);
+    target.className = "from";
+    markerStyle.width;
+    target.classList.add("transition");
+    markerStyle.width;
+    target.classList.add("to");
+    test(() => {
+      check({property, from, to, midPoint});
+    }, `Transition of ${property} in ::marker`);
+  }
+}
+
+testAnimations(interpolationTests);
+testTransitions(interpolationTests);
+</script>
diff --git a/css/css-pseudo/parsing/marker-supported-properties.html b/css/css-pseudo/parsing/marker-supported-properties.html
index 7f8eacb..e27decc 100644
--- a/css/css-pseudo/parsing/marker-supported-properties.html
+++ b/css/css-pseudo/parsing/marker-supported-properties.html
@@ -45,6 +45,24 @@
 // ::marker supports `content`
 test_pseudo_computed_value("::marker", "content", "\"foo\"");
 
+// ::marker supports animation properties.
+test_pseudo_computed_value("::marker", "animation", "1s linear 2s infinite alternate forwards paused anim");
+test_pseudo_computed_value("::marker", "animation-delay", "1s");
+test_pseudo_computed_value("::marker", "animation-direction", "alternate");
+test_pseudo_computed_value("::marker", "animation-duration", "2s");
+test_pseudo_computed_value("::marker", "animation-fill-mode", "forwards");
+test_pseudo_computed_value("::marker", "animation-iteration-count", "infinite");
+test_pseudo_computed_value("::marker", "animation-name", "anim");
+test_pseudo_computed_value("::marker", "animation-play-state", "paused");
+test_pseudo_computed_value("::marker", "animation-timing-function", "linear");
+
+// ::marker supports transition properties.
+test_pseudo_computed_value("::marker", "transition", "display 1s linear 2s");
+test_pseudo_computed_value("::marker", "transition-delay", "1s");
+test_pseudo_computed_value("::marker", "transition-duration", "2s");
+test_pseudo_computed_value("::marker", "transition-property", "display");
+test_pseudo_computed_value("::marker", "transition-timing-function", "linear");
+
 // ::marker does NOT support layout properties
 test_pseudo_computed_value("::marker", "display", "none", ["block", "inline", "inline-block"]);
 test_pseudo_computed_value("::marker", "position", "absolute", "static");