new file mode 100644
--- /dev/null
+++ b/dom/animation/test/mozilla/file_discrete-animations.html
@@ -0,0 +1,170 @@
+<!doctype html>
+<head>
+<meta charset=utf-8>
+<title>Test Mozilla-specific discrete animatable properties</title>
+<script type="application/javascript" src="../testcommon.js"></script>
+</head>
+<body>
+<script>
+"use strict";
+
+const gMozillaSpecificProperties = {
+ "-moz-appearance": {
+ // https://drafts.csswg.org/css-align/#propdef-align-content
+ from: "button",
+ to: "none"
+ },
+ "-moz-border-bottom-colors": {
+ from: "rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0)",
+ to: "rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0)"
+ },
+ "-moz-border-left-colors": {
+ from: "rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0)",
+ to: "rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0)"
+ },
+ "-moz-border-right-colors": {
+ from: "rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0)",
+ to: "rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0)"
+ },
+ "-moz-border-top-colors": {
+ from: "rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0) rgb(255, 0, 0)",
+ to: "rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0) rgb(0, 255, 0)"
+ },
+ "-moz-box-align": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/box-align
+ from: "center",
+ to: "stretch"
+ },
+ "-moz-box-direction": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/box-direction
+ from: "reverse",
+ to: "normal"
+ },
+ "-moz-box-ordinal-group": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/box-ordinal-group
+ from: "1",
+ to: "5"
+ },
+ "-moz-box-orient": {
+ // https://www.w3.org/TR/css-flexbox-1/
+ from: "horizontal",
+ to: "vertical"
+ },
+ "-moz-box-pack": {
+ // https://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#propdef-box-pack
+ from: "center",
+ to: "end"
+ },
+ "-moz-float-edge": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/-moz-float-edge
+ from: "margin-box",
+ to: "content-box"
+ },
+ "-moz-force-broken-image-icon": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/-moz-force-broken-image-icon
+ from: "1",
+ to: "5"
+ },
+ "image-rendering": {
+ // https://drafts.csswg.org/css-images-3/#propdef-image-rendering
+ from: "-moz-crisp-edges",
+ to: "auto"
+ },
+ "-moz-stack-sizing": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/-moz-stack-sizing
+ from: "ignore",
+ to: "stretch-to-fit"
+ },
+ "-moz-tab-size": {
+ // https://drafts.csswg.org/css-text-3/#propdef-tab-size
+ from: "1",
+ to: "5"
+ },
+ "-moz-text-size-adjust": {
+ // https://drafts.csswg.org/css-size-adjust/#propdef-text-size-adjust
+ from: "none",
+ to: "auto"
+ },
+ "-webkit-text-stroke-width": {
+ // https://compat.spec.whatwg.org/#propdef--webkit-text-stroke-width
+ from: "10px",
+ to: "50px"
+ }
+}
+
+for (let property in gMozillaSpecificProperties) {
+ const testData = gMozillaSpecificProperties[property];
+ const from = testData.from;
+ const to = testData.to;
+ const idlName = propertyToIDL(property);
+ const keyframes = {};
+ keyframes[idlName] = [from, to];
+
+ test(t => {
+ const div = addDiv(t);
+ const animation = div.animate(keyframes,
+ { duration: 1000, fill: "both" });
+ testAnimationSamples(animation, idlName,
+ [{ time: 0, expected: from.toLowerCase() },
+ { time: 499, expected: from.toLowerCase() },
+ { time: 500, expected: to.toLowerCase() },
+ { time: 1000, expected: to.toLowerCase() }]);
+ }, property + " should animate between '"
+ + from + "' and '" + to + "' with linear easing");
+
+ test(function(t) {
+ // Easing: http://cubic-bezier.com/#.68,0,1,.01
+ // With this curve, we don't reach the 50% point until about 95% of
+ // the time has expired.
+ const div = addDiv(t);
+ const animation = div.animate(keyframes,
+ { duration: 1000, fill: "both",
+ easing: "cubic-bezier(0.68,0,1,0.01)" });
+ testAnimationSamples(animation, idlName,
+ [{ time: 0, expected: from.toLowerCase() },
+ { time: 940, expected: from.toLowerCase() },
+ { time: 960, expected: to.toLowerCase() }]);
+ }, property + " should animate between '"
+ + from + "' and '" + to + "' with effect easing");
+
+ test(function(t) {
+ // Easing: http://cubic-bezier.com/#.68,0,1,.01
+ // With this curve, we don't reach the 50% point until about 95% of
+ // the time has expired.
+ keyframes.easing = "cubic-bezier(0.68,0,1,0.01)";
+ const div = addDiv(t);
+ const animation = div.animate(keyframes,
+ { duration: 1000, fill: "both" });
+ testAnimationSamples(animation, idlName,
+ [{ time: 0, expected: from.toLowerCase() },
+ { time: 940, expected: from.toLowerCase() },
+ { time: 960, expected: to.toLowerCase() }]);
+ }, property + " should animate between '"
+ + from + "' and '" + to + "' with keyframe easing");
+}
+
+function propertyToIDL(property) {
+ var prefixMatch = property.match(/^-(\w+)-/);
+ if (prefixMatch) {
+ var prefix = prefixMatch[1] === "moz" ? "Moz" : prefixMatch[1];
+ property = prefix + property.substring(prefixMatch[0].length - 1);
+ }
+ // https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
+ return property.replace(/-([a-z])/gi, function(str, group) {
+ return group.toUpperCase();
+ });
+}
+
+function testAnimationSamples(animation, idlName, testSamples) {
+ const target = animation.effect.target;
+ testSamples.forEach(testSample => {
+ animation.currentTime = testSample.time;
+ assert_equals(getComputedStyle(target)[idlName], testSample.expected,
+ "The value should be " + testSample.expected +
+ " at " + testSample.time + "ms");
+ });
+}
+
+done();
+</script>
+</body>
--- a/testing/web-platform/tests/web-animations/animation-model/animation-types/type-per-property.html
+++ b/testing/web-platform/tests/web-animations/animation-model/animation-types/type-per-property.html
@@ -29,40 +29,227 @@ var gCSSProperties = {
]
},
"align-self": {
// https://drafts.csswg.org/css-align/#propdef-align-self
tests: [
discrete("flex-start", "flex-end")
]
},
+ "backface-visibility": {
+ // https://drafts.csswg.org/css-transforms/#propdef-backface-visibility
+ "tests": [
+ discrete("visible", "hidden")
+ ]
+ },
+ "background-attachment": {
+ // https://drafts.csswg.org/css-backgrounds-3/#background-attachment
+ "tests": [
+ discrete("fixed", "local")
+ ]
+ },
+ "background-blend-mode": {
+ // https://drafts.fxtf.org/compositing-1/#propdef-background-blend-mode
+ "tests": [
+ discrete("multiply", "screen")
+ ]
+ },
+ "background-clip": {
+ // https://drafts.csswg.org/css-backgrounds-3/#background-clip
+ "tests": [
+ discrete("padding-box", "content-box")
+ ]
+ },
+ "background-image": {
+ // https://drafts.csswg.org/css-backgrounds-3/#background-image
+ "tests": [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "background-origin": {
+ // https://drafts.csswg.org/css-backgrounds-3/#background-origin
+ "tests": [
+ discrete("padding-box", "content-box")
+ ]
+ },
+ "background-repeat": {
+ // https://drafts.csswg.org/css-backgrounds-3/#background-repeat
+ "tests": [
+ discrete("space", "round")
+ ]
+ },
+ "border-bottom-style": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-bottom-style
+ "tests": [
+ discrete("dotted", "solid")
+ ]
+ },
+ "border-collapse": {
+ // https://drafts.csswg.org/css-tables/#propdef-border-collapse
+ "tests": [
+ discrete("collapse", "separate")
+ ]
+ },
+ "border-image-outset": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-image-outset
+ "tests": [
+ discrete("1 1 1 1", "5 5 5 5")
+ ]
+ },
+ "border-image-repeat": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-image-repeat
+ "tests": [
+ discrete("stretch stretch", "repeat repeat")
+ ]
+ },
+ "border-image-slice": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-image-slice
+ "tests": [
+ discrete("1 1 1 1", "5 5 5 5")
+ ]
+ },
+ "border-image-source": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-image-source
+ "tests": [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "border-image-width": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-image-width
+ "tests": [
+ discrete("1 1 1 1", "5 5 5 5")
+ ]
+ },
+ "border-left-style": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-left-style
+ "tests": [
+ discrete("dotted", "solid")
+ ]
+ },
+ "border-right-style": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-right-style
+ "tests": [
+ discrete("dotted", "solid")
+ ]
+ },
+ "border-top-style": {
+ // https://drafts.csswg.org/css-backgrounds-3/#border-top-style
+ "tests": [
+ discrete("dotted", "solid")
+ ]
+ },
+ "box-decoration-break": {
+ // https://drafts.csswg.org/css-break/#propdef-box-decoration-break
+ "tests": [
+ discrete("slice", "clone")
+ ]
+ },
+ "box-sizing": {
+ // https://drafts.csswg.org/css-ui-4/#box-sizing
+ "tests": [
+ discrete("content-box", "border-box")
+ ]
+ },
+ "caption-side": {
+ // https://drafts.csswg.org/css-tables/#propdef-caption-side
+ "tests": [
+ discrete("top", "bottom")
+ ]
+ },
+ "clear": {
+ // https://drafts.csswg.org/css-page-floats/#propdef-clear
+ "tests": [
+ discrete("inline-start", "inline-end")
+ ]
+ },
"clip-rule": {
// https://drafts.fxtf.org/css-masking-1/#propdef-clip-rule
tests: [
discrete("evenodd", "nonzero")
]
},
+ "color-adjust": {
+ // https://drafts.csswg.org/css-color-4/#color-adjust
+ tests: [
+ discrete("economy", "exact")
+ ]
+ },
"color-interpolation": {
// https://svgwg.org/svg2-draft/painting.html#ColorInterpolationProperty
tests: [
discrete("linearRGB", "auto")
]
},
"color-interpolation-filters": {
// https://drafts.fxtf.org/filters-1/#propdef-color-interpolation-filters
tests: [
discrete("sRGB", "linearRGB")
]
},
+ "column-fill": {
+ // https://drafts.csswg.org/css-multicol/#propdef-column-fill
+ tests: [
+ discrete("auto", "balance")
+ ]
+ },
+ "column-rule-style": {
+ // https://drafts.csswg.org/css-multicol/#propdef-column-rule-style
+ tests: [
+ discrete("none", "dotted")
+ ]
+ },
+ "contain": {
+ // https://drafts.csswg.org/css-containment/#propdef-contain
+ tests: [
+ discrete("strict", "none")
+ ]
+ },
+ "content": {
+ // https://drafts.csswg.org/css-content-3/#propdef-content
+ tests: [
+ discrete("\"a\"", "\"b\"")
+ ],
+ tagName: "::before"
+ },
+ "counter-increment": {
+ // https://drafts.csswg.org/css-lists-3/#propdef-counter-increment
+ tests: [
+ discrete("ident-1 1", "ident-2 2")
+ ]
+ },
+ "counter-reset": {
+ // https://drafts.csswg.org/css-lists-3/#propdef-counter-reset
+ tests: [
+ discrete("ident-1 1", "ident-2 2")
+ ]
+ },
+ "cursor": {
+ // https://drafts.csswg.org/css2/ui.html#propdef-cursor
+ tests: [
+ discrete("pointer", "wait")
+ ]
+ },
+ "direction": {
+ // https://drafts.csswg.org/css-writing-modes-3/#propdef-direction
+ tests: [
+ discrete("ltr", "rtl")
+ ]
+ },
"dominant-baseline": {
// https://drafts.csswg.org/css-inline/#propdef-dominant-baseline
tests: [
discrete("ideographic", "alphabetic")
]
},
+ "empty-cells": {
+ // https://drafts.csswg.org/css-tables/#propdef-empty-cells
+ tests: [
+ discrete("show", "hide")
+ ]
+ },
"fill-rule": {
// https://svgwg.org/svg2-draft/painting.html#FillRuleProperty
tests: [
discrete("evenodd", "nonzero")
]
},
"flex-basis": {
// https://drafts.csswg.org/css-flexbox/#propdef-flex-basis
@@ -96,20 +283,182 @@ var gCSSProperties = {
]
},
"font-style": {
// https://drafts.csswg.org/css-fonts/#propdef-font-style
tests: [
discrete("italic", "oblique")
]
},
- "image-rendering": {
- // https://drafts.csswg.org/css-images/#propdef-image-rendering
+ "float": {
+ // https://drafts.csswg.org/css-page-floats/#propdef-float
+ tests: [
+ discrete("left", "right")
+ ]
+ },
+ "font-family": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-family
+ tests: [
+ discrete("helvetica", "verdana")
+ ]
+ },
+ "font-feature-settings": {
+ // https://drafts.csswg.org/css-fonts/#descdef-font-feature-settings
+ tests: [
+ discrete("\"liga\" 5", "normal")
+ ]
+ },
+ "font-kerning": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-kerning
+ tests: [
+ discrete("auto", "normal")
+ ]
+ },
+ "font-language-override": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override
+ tests: [
+ discrete("\"eng\"", "normal")
+ ]
+ },
+ "font-style": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-style
+ tests: [
+ discrete("italic", "oblique")
+ ]
+ },
+ "font-synthesis": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-synthesis
+ tests: [
+ discrete("none", "weight style")
+ ]
+ },
+ "font-variant-alternates": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-variant-alternates
+ tests: [
+ discrete("swash(unknown)", "stylistic(unknown)")
+ ]
+ },
+ "font-variant-caps": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-variant-caps
+ tests: [
+ discrete("small-caps", "unicase")
+ ]
+ },
+ "font-variant-east-asian": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-variant-east-asian
+ tests: [
+ discrete("full-width", "proportional-width")
+ ]
+ },
+ "font-variant-ligatures": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-variant-ligatures
+ tests: [
+ discrete("common-ligatures", "no-common-ligatures")
+ ]
+ },
+ "font-variant-numeric": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-variant-numeric
+ tests: [
+ discrete("lining-nums", "oldstyle-nums")
+ ]
+ },
+ "font-variant-position": {
+ // https://drafts.csswg.org/css-fonts-3/#propdef-font-variant-position
+ tests: [
+ discrete("sub", "super")
+ ]
+ },
+ "grid-auto-columns": {
+ // https://drafts.csswg.org/css-grid/#propdef-grid-auto-columns
tests: [
- discrete("optimizeQuality", "pixelated")
+ discrete("1px", "5px")
+ ]
+ },
+ "grid-auto-flow": {
+ // https://drafts.csswg.org/css-grid/#propdef-grid-auto-flow
+ tests: [
+ discrete("row", "column")
+ ]
+ },
+ "grid-auto-rows": {
+ // https://drafts.csswg.org/css-grid/#propdef-grid-auto-rows
+ tests: [
+ discrete("1px", "5px")
+ ]
+ },
+ "grid-column-end": {
+ // https://drafts.csswg.org/css-grid/#propdef-grid-column-end
+ tests: [
+ discrete("1", "5")
+ ]
+ },
+ "grid-column-start": {
+ // https://drafts.csswg.org/css-grid/#propdef-grid-column-start
+ tests: [
+ discrete("1", "5")
+ ]
+ },
+ "grid-row-end": {
+ // https://drafts.csswg.org/css-grid/#propdef-grid-row-end
+ tests: [
+ discrete("1", "5")
+ ]
+ },
+ "grid-row-start": {
+ // https://drafts.csswg.org/css-grid/#propdef-grid-row-start
+ tests: [
+ discrete("1", "5")
+ ]
+ },
+ "grid-template-areas": {
+ // https://drafts.csswg.org/css-template/#grid-template-areas
+ tests: [
+ discrete("\". . a b\" \". .a b\"", "none")
+ ]
+ },
+ "grid-template-columns": {
+ // https://drafts.csswg.org/css-template/#grid-template-columns
+ tests: [
+ discrete("1px", "5px")
+ ]
+ },
+ "grid-template-rows": {
+ // https://drafts.csswg.org/css-template/#grid-template-rows
+ tests: [
+ discrete("1px", "5px")
+ ]
+ },
+ "hyphens": {
+ // https://drafts.csswg.org/css-text-3/#propdef-hyphens
+ tests: [
+ discrete("manual", "auto")
+ ]
+ },
+ "image-orientation": {
+ // https://drafts.csswg.org/css-images-3/#propdef-image-orientation
+ tests: [
+ discrete("0deg", "90deg")
+ ]
+ },
+ "ime-mode": {
+ // https://drafts.csswg.org/css-ui/#input-method-editor
+ tests: [
+ discrete("disabled", "auto")
+ ]
+ },
+ "initial-letter": {
+ // https://drafts.csswg.org/css-inline/#propdef-initial-letter
+ tests: [
+ discrete("1 2", "3 4")
+ ]
+ },
+ "isolation": {
+ // https://drafts.fxtf.org/compositing-1/#propdef-isolation
+ tests: [
+ discrete("auto", "isolate")
]
},
"justify-content": {
// https://drafts.csswg.org/css-align/#propdef-justify-content
tests: [
discrete("baseline", "last baseline")
]
},
@@ -120,47 +469,233 @@ var gCSSProperties = {
]
},
"justify-self": {
// https://drafts.csswg.org/css-align/#propdef-justify-self
tests: [
discrete("baseline", "last baseline")
]
},
+ "list-style-image": {
+ // https://drafts.csswg.org/css-lists-3/#propdef-list-style-image
+ tests: [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "list-style-position": {
+ // https://drafts.csswg.org/css-lists-3/#propdef-list-style-position
+ tests: [
+ discrete("inside", "outside")
+ ]
+ },
+ "list-style-type": {
+ // https://drafts.csswg.org/css-lists-3/#propdef-list-style-type
+ tests: [
+ discrete("circle", "square")
+ ]
+ },
+ "marker-end": {
+ // https://svgwg.org/specs/markers/#MarkerEndProperty
+ tests: [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "marker-mid": {
+ // https://svgwg.org/specs/markers/#MarkerMidProperty
+ tests: [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "marker-start": {
+ // https://svgwg.org/specs/markers/#MarkerStartProperty
+ tests: [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "mask": {
+ // https://drafts.fxtf.org/css-masking-1/#the-mask
+ tests: [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "mask-clip": {
+ // https://drafts.fxtf.org/css-masking-1/#propdef-mask-clip
+ tests: [
+ discrete("content-box", "border-box")
+ ]
+ },
+ "mask-composite": {
+ // https://drafts.fxtf.org/css-masking-1/#propdef-mask-composite
+ tests: [
+ discrete("add", "subtract")
+ ]
+ },
+ "mask-image": {
+ // https://drafts.fxtf.org/css-masking-1/#propdef-mask-image
+ tests: [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
+ "mask-mode": {
+ // https://drafts.fxtf.org/css-masking-1/#propdef-mask-mode
+ tests: [
+ discrete("alpha", "luminance")
+ ]
+ },
+ "mask-origin": {
+ // https://drafts.fxtf.org/css-masking-1/#propdef-mask-origin
+ tests: [
+ discrete("content-box", "border-box")
+ ]
+ },
+ "mask-repeat": {
+ // https://drafts.fxtf.org/css-masking-1/#propdef-mask-repeat
+ tests: [
+ discrete("space", "round")
+ ]
+ },
"mask-type": {
// https://drafts.fxtf.org/css-masking-1/#propdef-mask-type
tests: [
discrete("alpha", "luminance")
]
},
+ "mix-blend-mode": {
+ // https://drafts.fxtf.org/compositing-1/#propdef-mix-blend-mode
+ tests: [
+ discrete("multiply", "screen")
+ ]
+ },
+ "object-fit": {
+ // https://drafts.csswg.org/css-images-3/#propdef-object-fit
+ tests: [
+ discrete("fill", "contain")
+ ]
+ },
"order": {
// https://drafts.csswg.org/css-flexbox/#propdef-order
tests: [
integer()
]
},
+ "outline-style": {
+ // https://drafts.csswg.org/css-ui/#propdef-outline-style
+ tests: [
+ discrete("none", "dotted")
+ ]
+ },
+ "overflow-clip-box": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/overflow-clip-box
+ tests: [
+ discrete("padding-box", "content-box")
+ ]
+ },
+ "overflow-wrap": {
+ // https://drafts.csswg.org/css-text-3/#propdef-overflow-wrap
+ tests: [
+ discrete("normal", "break-word")
+ ]
+ },
+ "overflow-x": {
+ // https://drafts.csswg.org/css-overflow-3/#propdef-overflow-x
+ tests: [
+ discrete("visible", "hidden")
+ ]
+ },
+ "overflow-y": {
+ // https://drafts.csswg.org/css-overflow-3/#propdef-overflow-y
+ tests: [
+ discrete("visible", "hidden")
+ ]
+ },
+ "page-break-after": {
+ // https://drafts.csswg.org/css-break-3/#propdef-break-after
+ tests: [
+ discrete("always", "auto")
+ ]
+ },
+ "page-break-before": {
+ // https://drafts.csswg.org/css-break-3/#propdef-break-before
+ tests: [
+ discrete("always", "auto")
+ ]
+ },
+ "page-break-inside": {
+ // https://drafts.csswg.org/css-break-3/#propdef-break-inside
+ tests: [
+ discrete("auto", "avoid")
+ ]
+ },
+ "paint-order": {
+ // https://svgwg.org/svg2-draft/painting.html#PaintOrderProperty
+ tests: [
+ discrete("fill", "stroke")
+ ]
+ },
"pointer-events": {
// https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty
tests: [
discrete("fill", "none")
]
},
+ "position": {
+ // https://drafts.csswg.org/css-position/#propdef-position
+ tests: [
+ discrete("absolute", "fixed")
+ ]
+ },
+ "quotes": {
+ // https://drafts.csswg.org/css-content-3/#propdef-quotes
+ tests: [
+ discrete("\"“\" \"”\" \"‘\" \"’\"", "\"‘\" \"’\" \"“\" \"”\"")
+ ]
+ },
+ "resize": {
+ // https://drafts.csswg.org/css-ui/#propdef-resize
+ tests: [
+ discrete("both", "horizontal")
+ ]
+ },
"ruby-align": {
// https://drafts.csswg.org/css-ruby-1/#propdef-ruby-align
tests: [
discrete("start", "center")
]
},
"ruby-position": {
// https://drafts.csswg.org/css-ruby-1/#propdef-ruby-position
tests: [
discrete("under", "over")
],
tagName: "ruby"
},
+ "scroll-behavior": {
+ // https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior
+ tests: [
+ discrete("auto", "smooth")
+ ]
+ },
+ "scroll-snap-type-x": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/scroll-snap-type-x
+ tests: [
+ discrete("mandatory", "proximity")
+ ]
+ },
+ "scroll-snap-type-y": {
+ // https://developer.mozilla.org/en/docs/Web/CSS/scroll-snap-type-y
+ tests: [
+ discrete("mandatory", "proximity")
+ ]
+ },
+ "shape-outside": {
+ // http://dev.w3.org/csswg/css-shapes/#propdef-shape-outside
+ tests: [
+ discrete("url(\"http://localhost/test-1\")", "url(\"http://localhost/test-2\")")
+ ]
+ },
"shape-rendering": {
// https://svgwg.org/svg2-draft/painting.html#ShapeRenderingProperty
tests: [
discrete("optimizeSpeed", "crispEdges")
]
},
"stroke-linecap": {
// https://svgwg.org/svg2-draft/painting.html#StrokeLinecapProperty
@@ -170,64 +705,148 @@ var gCSSProperties = {
},
"stroke-linejoin": {
// https://svgwg.org/svg2-draft/painting.html#StrokeLinejoinProperty
tests: [
discrete("round", "miter")
],
tagName: "rect"
},
+ "table-layout": {
+ // https://drafts.csswg.org/css-tables/#propdef-table-layout
+ tests: [
+ discrete("auto", "fixed")
+ ]
+ },
+ "text-align": {
+ // https://drafts.csswg.org/css-text-3/#propdef-text-align
+ tests: [
+ discrete("start", "end")
+ ]
+ },
+ "text-align-last": {
+ // https://drafts.csswg.org/css-text-3/#propdef-text-align-last
+ tests: [
+ discrete("start", "end")
+ ]
+ },
"text-anchor": {
// https://svgwg.org/svg2-draft/text.html#TextAnchorProperty
tests: [
discrete("middle", "end")
]
},
"text-combine-upright": {
// https://drafts.csswg.org/css-writing-modes-3/#propdef-text-combine-upright
tests: [
- discrete("all", "digits")
+ discrete("all", "none")
]
},
"text-decoration-line": {
// https://drafts.csswg.org/css-text-decor-3/#propdef-text-decoration-line
tests: [
discrete("underline", "overline")
]
},
+ "text-decoration-style": {
+ // http://dev.w3.org/csswg/css-text-decor-3/#propdef-text-decoration-style
+ tests: [
+ discrete("solid", "dotted")
+ ]
+ },
+ "text-emphasis-position": {
+ // http://dev.w3.org/csswg/css-text-decor-3/#propdef-text-emphasis-position
+ tests: [
+ discrete("over right", "under left")
+ ]
+ },
+ "text-emphasis-style": {
+ // http://dev.w3.org/csswg/css-text-decor-3/#propdef-text-emphasis-style
+ tests: [
+ discrete("filled circle", "open dot")
+ ]
+ },
"text-orientation": {
// https://drafts.csswg.org/css-writing-modes-3/#propdef-text-orientation
tests: [
discrete("upright", "sideways")
]
},
+ "text-overflow": {
+ // https://drafts.csswg.org/css-ui/#propdef-text-overflow
+ tests: [
+ discrete("clip", "ellipsis")
+ ]
+ },
"text-rendering": {
// https://svgwg.org/svg2-draft/painting.html#TextRenderingProperty
tests: [
discrete("optimizeSpeed", "optimizeLegibility")
]
},
+ "text-transform": {
+ // https://drafts.csswg.org/css-text-3/#propdef-text-transform
+ tests: [
+ discrete("capitalize", "uppercase")
+ ]
+ },
+ "touch-action": {
+ // https://w3c.github.io/pointerevents/#the-touch-action-css-property
+ tests: [
+ discrete("auto", "none")
+ ]
+ },
+ "transform-box": {
+ // https://drafts.csswg.org/css-transforms/#propdef-transform-box
+ tests: [
+ discrete("fill-box", "border-box")
+ ]
+ },
+ "transform-style": {
+ // https://drafts.csswg.org/css-transforms/#propdef-transform-style
+ tests: [
+ discrete("flat", "preserve-3d")
+ ]
+ },
+ "unicode-bidi": {
+ // https://drafts.csswg.org/css-writing-modes-3/#propdef-unicode-bidi
+ tests: [
+ discrete("embed", "bidi-override")
+ ]
+ },
"vector-effect": {
// https://svgwg.org/svg2-draft/coords.html#VectorEffectProperty
tests: [
discrete("none", "non-scaling-stroke")
]
},
"visibility": {
// https://drafts.csswg.org/css2/visufx.html#propdef-visibility
tests: [
visibility()
]
},
+ "white-space": {
+ // https://drafts.csswg.org/css-text-4/#propdef-white-space
+ tests: [
+ discrete("pre", "nowrap")
+ ]
+ },
"word-break": {
// https://drafts.csswg.org/css-text-3/#propdef-word-break
tests: [
discrete("keep-all", "break-all")
]
},
+ "will-change": {
+ // http://dev.w3.org/csswg/css-will-change/#propdef-will-change
+ tests: [
+ discrete("scroll-position", "contents")
+ ]
+ },
"writing-mode": {
// https://drafts.csswg.org/css-writing-modes-3/#propdef-writing-mode
tests: [
discrete("vertical-rl", "sideways-rl")
]
},
}
@@ -242,17 +861,17 @@ for (var property in gCSSProperties) {
}
function discrete(from, to) {
return function(property, options) {
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = [from, to];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: from.toLowerCase() },
{ time: 499, expected: from.toLowerCase() },
{ time: 500, expected: to.toLowerCase() },
{ time: 1000, expected: to.toLowerCase() }]);
}, property + " uses discrete animation when animating between '"
@@ -260,17 +879,17 @@ function discrete(from, to) {
test(function(t) {
// Easing: http://cubic-bezier.com/#.68,0,1,.01
// With this curve, we don't reach the 50% point until about 95% of
// the time has expired.
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = [from, to];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both",
easing: "cubic-bezier(0.68,0,1,0.01)" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: from.toLowerCase() },
{ time: 940, expected: from.toLowerCase() },
{ time: 960, expected: to.toLowerCase() }]);
}, property + " uses discrete animation when animating between '"
@@ -279,17 +898,17 @@ function discrete(from, to) {
test(function(t) {
// Easing: http://cubic-bezier.com/#.68,0,1,.01
// With this curve, we don't reach the 50% point until about 95% of
// the time has expired.
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = [from, to];
keyframes.easing = "cubic-bezier(0.68,0,1,0.01)";
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: from.toLowerCase() },
{ time: 940, expected: from.toLowerCase() },
{ time: 960, expected: to.toLowerCase() }]);
}, property + " uses discrete animation when animating between '"
+ from + "' and '" + to + "' with keyframe easing");
@@ -297,81 +916,81 @@ function discrete(from, to) {
}
function length() {
return function(property, options) {
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["10px", "50px"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "10px" },
{ time: 500, expected: "30px" },
{ time: 1000, expected: "50px" }]);
}, property + " supports animating as a length");
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["1rem", "5rem"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "10px" },
{ time: 500, expected: "30px" },
{ time: 1000, expected: "50px" }]);
}, property + " supports animating as a length of rem");
}
}
function percentage() {
return function(property, options) {
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["10%", "50%"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "10%" },
{ time: 500, expected: "30%" },
{ time: 1000, expected: "50%" }]);
}, property + " supports animating as a percentage");
}
}
function integer() {
return function(property, options) {
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = [-2, 2];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "-2" },
{ time: 500, expected: "0" },
{ time: 1000, expected: "2" }]);
}, property + " supports animating as an integer");
}
}
function positiveNumber() {
return function(property, options) {
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = [1.1, 1.5];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "1.1" },
{ time: 500, expected: "1.3" },
{ time: 1000, expected: "1.5" }]);
}, property + " supports animating as a positive number");
}
@@ -381,69 +1000,69 @@ function lengthPercentageOrCalc() {
return function(property, options) {
length()(property, options);
percentage()(property, options);
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["10px", "20%"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "10px" },
{ time: 500, expected: "calc(5px + 10%)" },
{ time: 1000, expected: "20%" }]);
}, property + " supports animating as combination units 'px' and '%'");
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["10%", "2em"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "10%" },
{ time: 500, expected: "calc(10px + 5%)" },
{ time: 1000, expected: "20px" }]);
}, property + " supports animating as combination units '%' and 'em'");
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["1em", "2rem"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "10px" },
{ time: 500, expected: "15px" },
{ time: 1000, expected: "20px" }]);
}, property + " supports animating as combination units 'em' and 'rem'");
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["10px", "calc(1em + 20%)"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "10px" },
{ time: 500, expected: "calc(10px + 10%)" },
{ time: 1000, expected: "calc(10px + 20%)" }]);
}, property + " supports animating as combination units 'px' and 'calc'");
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["calc(10px + 10%)", "calc(1em + 1rem + 20%)"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0,
expected: "calc(10px + 10%)" },
{ time: 500,
expected: "calc(15px + 15%)" },
{ time: 1000,
@@ -453,45 +1072,45 @@ function lengthPercentageOrCalc() {
}
function visibility() {
return function(property, options) {
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["visible", "hidden"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "visible" },
{ time: 999, expected: "visible" },
{ time: 1000, expected: "hidden" }]);
}, property + " uses visibility animation when animating "
+ "from 'visible' to 'hidden'");
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["hidden", "visible"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "hidden" },
{ time: 1, expected: "visible" },
{ time: 1000, expected: "visible" }]);
}, property + " uses visibility animation when animating "
+ "from 'hidden' to 'visible'");
test(function(t) {
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["hidden", "collapse"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation = target.animate(keyframes,
{ duration: 1000, fill: "both" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "hidden" },
{ time: 499, expected: "hidden" },
{ time: 500, expected: "collapse" },
{ time: 1000, expected: "collapse" }]);
}, property + " uses visibility animation when animating "
@@ -499,17 +1118,17 @@ function visibility() {
test(function(t) {
// Easing: http://cubic-bezier.com/#.68,-.55,.26,1.55
// With this curve, the value is less than 0 till about 34%
// also more than 1 since about 63%
var idlName = propertyToIDL(property);
var keyframes = {};
keyframes[idlName] = ["visible", "hidden"];
- var target = createElement(t, options.tagName);
+ var target = createTestElement(t, options.tagName);
var animation =
target.animate(keyframes,
{ duration: 1000, fill: "both",
easing: "cubic-bezier(0.68, -0.55, 0.26, 1.55)" });
testAnimationSamples(animation, idlName,
[{ time: 0, expected: "visible" },
{ time: 1, expected: "visible" },
{ time: 330, expected: "visible" },
@@ -518,25 +1137,35 @@ function visibility() {
{ time: 630, expected: "hidden" },
{ time: 1000, expected: "hidden" }]);
}, property + " uses visibility animation when animating "
+ "from 'visible' to 'hidden' with easeInOutBack easing");
}
}
function testAnimationSamples(animation, idlName, testSamples) {
- var target = animation.effect.target;
+ var type = animation.effect.target.type;
+ var target = type
+ ? animation.effect.target.parentElement
+ : animation.effect.target;
testSamples.forEach(function(testSample) {
animation.currentTime = testSample.time;
- assert_equals(getComputedStyle(target)[idlName], testSample.expected,
+ assert_equals(getComputedStyle(target, type)[idlName],
+ testSample.expected,
"The value should be " + testSample.expected +
" at " + testSample.time + "ms");
});
}
+function createTestElement(t, tagName) {
+ return tagName && tagName.startsWith("::")
+ ? createPseudo(t, tagName.substring(2))
+ : createElement(t, tagName);
+}
+
function isSupported(property) {
var testKeyframe = new TestKeyframe(propertyToIDL(property));
try {
// Since TestKeyframe returns 'undefined' for |property|,
// the KeyframeEffect constructor will throw
// if the string "undefined" is not a valid value for the property.
new KeyframeEffect(null, testKeyframe);
} catch(e) {}