summaryrefslogtreecommitdiffstats
path: root/layout/reftests/css-animations
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /layout/reftests/css-animations
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--layout/reftests/css-animations/animate-display-table-opacity-ref.html9
-rw-r--r--layout/reftests/css-animations/animate-display-table-opacity.html14
-rw-r--r--layout/reftests/css-animations/animate-opacity-ref.html18
-rw-r--r--layout/reftests/css-animations/animate-opacity.html23
-rw-r--r--layout/reftests/css-animations/animate-preserves3d-ref.html30
-rw-r--r--layout/reftests/css-animations/animate-preserves3d.html38
-rw-r--r--layout/reftests/css-animations/animation-initially-out-of-view-with-delay-ref.html14
-rw-r--r--layout/reftests/css-animations/animation-initially-out-of-view-with-delay.html29
-rw-r--r--layout/reftests/css-animations/animation-on-empty-height-frame.html33
-rw-r--r--layout/reftests/css-animations/background-color-on-html-ref.html8
-rw-r--r--layout/reftests/css-animations/background-color-on-html.html20
-rw-r--r--layout/reftests/css-animations/background-color-ref.html9
-rw-r--r--layout/reftests/css-animations/background-color.html23
-rw-r--r--layout/reftests/css-animations/background-position-after-finish.html24
-rw-r--r--layout/reftests/css-animations/background-position-important.html17
-rw-r--r--layout/reftests/css-animations/background-position-in-delay.html16
-rw-r--r--layout/reftests/css-animations/background-position-ref.html12
-rw-r--r--layout/reftests/css-animations/background-position-running.html16
-rw-r--r--layout/reftests/css-animations/change-animation-name-in-rule-ref.html10
-rw-r--r--layout/reftests/css-animations/change-animation-name-to-non-existent-in-rule.html25
-rw-r--r--layout/reftests/css-animations/change-animation-name-to-none-in-rule.html25
-rw-r--r--layout/reftests/css-animations/change-animation-name-to-other-in-rule.html29
-rw-r--r--layout/reftests/css-animations/containing-block-on-visibility-hidden-ref.html26
-rw-r--r--layout/reftests/css-animations/containing-block-on-visibility-hidden.html34
-rw-r--r--layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html13
-rw-r--r--layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html18
-rw-r--r--layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html18
-rw-r--r--layout/reftests/css-animations/content-on-pseudo-element-at-beginning.html14
-rw-r--r--layout/reftests/css-animations/content-on-pseudo-element-at-half.html14
-rw-r--r--layout/reftests/css-animations/content-on-pseudo-element-ref.html9
-rw-r--r--layout/reftests/css-animations/continuation-opacity-ref.html15
-rw-r--r--layout/reftests/css-animations/continuation-opacity.html26
-rw-r--r--layout/reftests/css-animations/ib-split-sibling-opacity-ref.html3
-rw-r--r--layout/reftests/css-animations/ib-split-sibling-opacity.html20
-rw-r--r--layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html20
-rw-r--r--layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html39
-rw-r--r--layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element-ref.html18
-rw-r--r--layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element.html37
-rw-r--r--layout/reftests/css-animations/in-visibility-hidden-animation-ref.html16
-rw-r--r--layout/reftests/css-animations/in-visibility-hidden-animation.html36
-rw-r--r--layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html17
-rw-r--r--layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html33
-rw-r--r--layout/reftests/css-animations/mask-anim-ref.html12
-rw-r--r--layout/reftests/css-animations/mask-position-after-finish-1a.html26
-rw-r--r--layout/reftests/css-animations/mask-position-after-finish-1b.html35
-rw-r--r--layout/reftests/css-animations/mask-position-in-delay-1a.html17
-rw-r--r--layout/reftests/css-animations/mask-position-in-delay-1b.html26
-rw-r--r--layout/reftests/css-animations/mask-size-after-finish-1a.html26
-rw-r--r--layout/reftests/css-animations/mask-size-after-finish-1b.html35
-rw-r--r--layout/reftests/css-animations/mask-size-in-delay-1a.html19
-rw-r--r--layout/reftests/css-animations/mask-size-in-delay-1b.html29
-rw-r--r--layout/reftests/css-animations/no-stacking-context-animation-ref.html20
-rw-r--r--layout/reftests/css-animations/no-stacking-context-offset-distance-animation-with-offset-path-none.html24
-rw-r--r--layout/reftests/css-animations/no-stacking-context-opacity-removing-animation-in-delay.html47
-rw-r--r--layout/reftests/css-animations/no-stacking-context-transform-removing-animation-in-delay.html46
-rw-r--r--layout/reftests/css-animations/no-style-sharing-with-animations-ref.html11
-rw-r--r--layout/reftests/css-animations/no-style-sharing-with-animations.html26
-rw-r--r--layout/reftests/css-animations/opacity-animation-in-delay.html22
-rw-r--r--layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent-ref.html31
-rw-r--r--layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent.html39
-rw-r--r--layout/reftests/css-animations/partially-out-of-view-animation-ref.html15
-rw-r--r--layout/reftests/css-animations/partially-out-of-view-animation.html35
-rw-r--r--layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time-ref.html13
-rw-r--r--layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time.html29
-rw-r--r--layout/reftests/css-animations/reftest.list87
-rw-r--r--layout/reftests/css-animations/replace-with-new-positive-delay-animation-ref.html12
-rw-r--r--layout/reftests/css-animations/replace-with-new-positive-delay-animation.html42
-rw-r--r--layout/reftests/css-animations/screen-animations-notref.html11
-rw-r--r--layout/reftests/css-animations/screen-animations-ref.html11
-rw-r--r--layout/reftests/css-animations/screen-animations.html16
-rw-r--r--layout/reftests/css-animations/scroll-timeline-in-delay-omta-ref.html20
-rw-r--r--layout/reftests/css-animations/scroll-timeline-in-delay-omta.html71
-rw-r--r--layout/reftests/css-animations/stacking-context-animation-ref.html19
-rw-r--r--layout/reftests/css-animations/stacking-context-lose-opacity-1.html25
-rw-r--r--layout/reftests/css-animations/stacking-context-lose-transform-none.html25
-rw-r--r--layout/reftests/css-animations/stacking-context-offset-path-none-animation.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-offset-path-none-in-delay.html23
-rw-r--r--layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-backwards.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-forwards.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-1-animation.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-1-in-delay.html23
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-1-on-table.html25
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-1-with-fill-backwards.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-1-with-fill-forwards.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-removing-important-in-delay.html43
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-win-in-delay-on-main-thread.html31
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-win-in-delay.html27
-rw-r--r--layout/reftests/css-animations/stacking-context-opacity-wins-over-transition.html39
-rw-r--r--layout/reftests/css-animations/stacking-context-paused-on-opacity-1.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-paused-on-transform-none.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-none-animation-on-svg.html22
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-none-animation-with-backface-visibility.html26
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-none-animation-with-preserve-3d.html26
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-none-animation.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-none-in-delay.html23
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-none-with-fill-backwards.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-none-with-fill-forwards.html24
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-removing-important-in-delay.html44
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-win-in-delay-on-main-thread.html31
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-win-in-delay.html27
-rw-r--r--layout/reftests/css-animations/stacking-context-transform-wins-over-transition.html39
-rw-r--r--layout/reftests/css-animations/stop-animation-on-discarded-pseudo-element.html36
-rw-r--r--layout/reftests/css-animations/transform-animation-in-delay-ref.html13
-rw-r--r--layout/reftests/css-animations/transform-animation-in-delay.html22
-rw-r--r--layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html15
-rw-r--r--layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html42
-rw-r--r--layout/reftests/css-animations/updating-animation-on-pseudo-element-ref.html11
-rw-r--r--layout/reftests/css-animations/updating-animation-on-pseudo-element.html38
108 files changed, 2680 insertions, 0 deletions
diff --git a/layout/reftests/css-animations/animate-display-table-opacity-ref.html b/layout/reftests/css-animations/animate-display-table-opacity-ref.html
new file mode 100644
index 0000000000..958c8c3f63
--- /dev/null
+++ b/layout/reftests/css-animations/animate-display-table-opacity-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Testcase for bug 1245075</title>
+<style>
+#test {
+ width: 100px; height: 100px;
+ background: rgb(102, 102, 255);
+}
+</style>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/animate-display-table-opacity.html b/layout/reftests/css-animations/animate-display-table-opacity.html
new file mode 100644
index 0000000000..0d03054938
--- /dev/null
+++ b/layout/reftests/css-animations/animate-display-table-opacity.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Testcase for bug 1245075</title>
+<style>
+@keyframes HoldOpacity {
+ from, to { opacity: 0.6 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ display: table;
+ animation: HoldOpacity 100s linear infinite;
+}
+</style>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/animate-opacity-ref.html b/layout/reftests/css-animations/animate-opacity-ref.html
new file mode 100644
index 0000000000..d0b3bff4ae
--- /dev/null
+++ b/layout/reftests/css-animations/animate-opacity-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<title>Reftest, bug 1156456</title>
+<style>
+
+body {
+ background: #2a4;
+}
+
+div {
+ width: 200px; height: 200px;
+ background: #c37;
+ opacity: 0.6;
+ will-change: opacity;
+}
+
+</style>
+<div></div>
diff --git a/layout/reftests/css-animations/animate-opacity.html b/layout/reftests/css-animations/animate-opacity.html
new file mode 100644
index 0000000000..ff09fe514b
--- /dev/null
+++ b/layout/reftests/css-animations/animate-opacity.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<title>Reftest, bug 1156456</title>
+<style>
+
+body {
+ background: #2a4;
+}
+
+@keyframes HoldOpacity {
+ from, to {
+ opacity: 0.6;
+ }
+}
+
+div {
+ width: 200px; height: 200px;
+ background: #c37;
+ animation: 10s HoldOpacity infinite;
+}
+
+</style>
+<div></div>
diff --git a/layout/reftests/css-animations/animate-preserves3d-ref.html b/layout/reftests/css-animations/animate-preserves3d-ref.html
new file mode 100644
index 0000000000..d85a9772a5
--- /dev/null
+++ b/layout/reftests/css-animations/animate-preserves3d-ref.html
@@ -0,0 +1,30 @@
+<html>
+ <head>
+ <style type="text/css">
+ .pad {
+ display: block;
+ height: 20px;
+ }
+ .out {
+ display: block;
+ position: absolute;
+ transform-origin: 0 0;
+ width: 100px;
+ height: 50px;
+ overflow: hidden;
+ left: 108px;
+ }
+ .rect {
+ width: 100px;
+ height: 50px;
+ background-color: grey;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="pad"></div>
+ <div class="out">
+ <div class="rect"></div>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/css-animations/animate-preserves3d.html b/layout/reftests/css-animations/animate-preserves3d.html
new file mode 100644
index 0000000000..cf390513b7
--- /dev/null
+++ b/layout/reftests/css-animations/animate-preserves3d.html
@@ -0,0 +1,38 @@
+<html>
+ <head>
+ <style type="text/css">
+ .pad {
+ display: block;
+ height: 20px;
+ }
+ .out {
+ display: block;
+ position: absolute;
+ transform-origin: 0 0;
+ width: 100px;
+ height: 50px;
+ overflow: hidden;
+ }
+ .rect {
+ width: 100px;
+ height: 50px;
+ background-color: grey;
+ }
+
+ .ani {
+ animation: rot 200s linear infinite;
+ animation-timing-function: steps(2, start);
+ transform-origin: 50px 50px;
+ }
+ @keyframes rot {
+ to { transform: translate(200px, 0px); }
+ }
+ </style>
+ </head>
+ <body>
+ <div class="pad"></div>
+ <div class="out ani">
+ <div class="rect"></div>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/css-animations/animation-initially-out-of-view-with-delay-ref.html b/layout/reftests/css-animations/animation-initially-out-of-view-with-delay-ref.html
new file mode 100644
index 0000000000..4cccbc4861
--- /dev/null
+++ b/layout/reftests/css-animations/animation-initially-out-of-view-with-delay-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<title>Bug 1383239</title>
+<style>
+div {
+ position: absolute;
+ background: orange;
+ width: 20px;
+ height: 20px;
+ left: 0px;
+}
+</style>
+<div></div>
+</html>
diff --git a/layout/reftests/css-animations/animation-initially-out-of-view-with-delay.html b/layout/reftests/css-animations/animation-initially-out-of-view-with-delay.html
new file mode 100644
index 0000000000..39db15a38c
--- /dev/null
+++ b/layout/reftests/css-animations/animation-initially-out-of-view-with-delay.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<title>Bug 1383239</title>
+<style>
+div {
+ position: absolute;
+ left: -9999px;
+ background: orange;
+ width: 20px;
+ height: 20px;
+ animation: anim 100s 0.1s infinite;
+}
+
+@keyframes anim {
+ 0% {
+ left: 0px;
+ }
+ 100% {
+ left: 0px;
+ }
+}
+</style>
+<div></div>
+<script>
+document.querySelector('div').addEventListener('animationstart', ()=> {
+ document.documentElement.classList.remove('reftest-wait');
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/animation-on-empty-height-frame.html b/layout/reftests/css-animations/animation-on-empty-height-frame.html
new file mode 100644
index 0000000000..8e91c50c53
--- /dev/null
+++ b/layout/reftests/css-animations/animation-on-empty-height-frame.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<style>
+@keyframes anim {
+ from { background-color: white; }
+ to { background-color: red; }
+}
+</style>
+<body>
+</body>
+<script>
+window.addEventListener('load', () => {
+ const body = document.querySelector('body');
+ body.style.animation = 'anim 100s step-end reverse';
+ body.addEventListener('animationstart', () => {
+ // This MozAfterPaint event corresponds to the white background paint.
+ // (The animation will initially paint the background red since it is playing
+ // a step-end animation in reverse.)
+ window.addEventListener('MozAfterPaint', () => {
+ // FIXME: Bug 1341294. We need to wait for one more frame in the case
+ // the MozAfterPaint we received is not the one what we were waiting for.
+ // Note that we can't just wait for one more MozAfterPaint since in the
+ // case where everything works correctly, we won't get another
+ // MozAfterPaint for a long time due to the step-end timing function
+ // applied to the animation.
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ }, {once: true});
+ });
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/background-color-on-html-ref.html b/layout/reftests/css-animations/background-color-on-html-ref.html
new file mode 100644
index 0000000000..46119151eb
--- /dev/null
+++ b/layout/reftests/css-animations/background-color-on-html-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<html>
+<style>
+html {
+ background-color: green;
+}
+</style>
+</html>
diff --git a/layout/reftests/css-animations/background-color-on-html.html b/layout/reftests/css-animations/background-color-on-html.html
new file mode 100644
index 0000000000..a08de3a1f3
--- /dev/null
+++ b/layout/reftests/css-animations/background-color-on-html.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait reftest-no-flush">
+<style>
+@keyframes anim {
+ from { background-color: green; }
+ to { background-color: red; }
+}
+html {
+ background-color: black;
+}
+</style>
+<script>
+document.addEventListener("MozReftestInvalidate", () => {
+ document.documentElement.style.animation = "anim 100s step-end reverse";
+ document.documentElement.addEventListener("animationstart", () => {
+ document.documentElement.classList.remove("reftest-wait");
+ });
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/background-color-ref.html b/layout/reftests/css-animations/background-color-ref.html
new file mode 100644
index 0000000000..61538ea34d
--- /dev/null
+++ b/layout/reftests/css-animations/background-color-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<style>
+#target {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+</style>
+<div id="target"></div>
diff --git a/layout/reftests/css-animations/background-color.html b/layout/reftests/css-animations/background-color.html
new file mode 100644
index 0000000000..6a990524a2
--- /dev/null
+++ b/layout/reftests/css-animations/background-color.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait reftest-no-flush">
+<style>
+@keyframes anim {
+ from { background-color: green; }
+ to { background-color: red; }
+}
+#target {
+ width: 100px;
+ height: 100px;
+ background-color: black;
+}
+</style>
+<div id="target"></div>
+<script>
+document.addEventListener("MozReftestInvalidate", () => {
+ target.style.animation = "anim 100s step-end reverse";
+ target.addEventListener("animationstart", () => {
+ document.documentElement.classList.remove("reftest-wait");
+ });
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/background-position-after-finish.html b/layout/reftests/css-animations/background-position-after-finish.html
new file mode 100644
index 0000000000..ac9bdfbd46
--- /dev/null
+++ b/layout/reftests/css-animations/background-position-after-finish.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>background-position-x animation after finish</title>
+<style>
+@keyframes holdBackgroundPosition {
+ from,to { background-position-x: 100%; }
+}
+#test {
+ height: 100px;
+ width: 100px;
+ background-repeat: no-repeat;
+ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF/wAAAAAAQaMSAwAAABJJREFUeNpiYBgFo2AwAIAAAwACigABtnCV2AAAAABJRU5ErkJggg==); /* a 25x25 px red box */
+ animation: holdBackgroundPosition 0.01s;
+ background-position-x: 50%;
+}
+</style>
+<div id="test" class="reftest-opaque-layer"></div>
+<script>
+document.getElementById("test").addEventListener("animationend", () => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove("reftest-wait");
+ })
+});
+</script>
diff --git a/layout/reftests/css-animations/background-position-important.html b/layout/reftests/css-animations/background-position-important.html
new file mode 100644
index 0000000000..2b6536cbf1
--- /dev/null
+++ b/layout/reftests/css-animations/background-position-important.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<title>background-position-x animation overridden by important style</title>
+<style>
+@keyframes holdBackgroundPosition {
+ from,to { background-position-x: 50%; }
+}
+#test {
+ height: 100px;
+ width: 100px;
+ background-repeat: no-repeat;
+ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF/wAAAAAAQaMSAwAAABJJREFUeNpiYBgFo2AwAIAAAwACigABtnCV2AAAAABJRU5ErkJggg==); /* a 25x25 px red box */
+ background-position-x: 50% !important;
+ animation: holdBackgroundPosition 100s infinite;
+}
+</style>
+<div id="test" class="reftest-opaque-layer"></div>
diff --git a/layout/reftests/css-animations/background-position-in-delay.html b/layout/reftests/css-animations/background-position-in-delay.html
new file mode 100644
index 0000000000..0ddc220b2e
--- /dev/null
+++ b/layout/reftests/css-animations/background-position-in-delay.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>background-position-x animation in delay phase</title>
+<style>
+@keyframes holdBackgroundPosition {
+ from,to { background-position-x: 100%; }
+}
+#test {
+ height: 100px;
+ width: 100px;
+ background-repeat: no-repeat;
+ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF/wAAAAAAQaMSAwAAABJJREFUeNpiYBgFo2AwAIAAAwACigABtnCV2AAAAABJRU5ErkJggg==); /* a 25x25 px red box */
+ animation: holdBackgroundPosition 100s 100s infinite;
+ background-position-x: 50%;
+}
+</style>
+<div id="test" class="reftest-opaque-layer"></div>
diff --git a/layout/reftests/css-animations/background-position-ref.html b/layout/reftests/css-animations/background-position-ref.html
new file mode 100644
index 0000000000..d479820469
--- /dev/null
+++ b/layout/reftests/css-animations/background-position-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>Reference of testcases for background-position-x animations</title>
+<style>
+#test {
+ height: 100px;
+ width: 100px;
+ background-repeat: no-repeat;
+ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF/wAAAAAAQaMSAwAAABJJREFUeNpiYBgFo2AwAIAAAwACigABtnCV2AAAAABJRU5ErkJggg==); /* a 25x25 px red box */
+ background-position-x: 50%;
+}
+</style>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/background-position-running.html b/layout/reftests/css-animations/background-position-running.html
new file mode 100644
index 0000000000..73e811d599
--- /dev/null
+++ b/layout/reftests/css-animations/background-position-running.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>background-position-x animation while running</title>
+<style>
+@keyframes holdBackgroundPosition {
+ from,to { background-position-x: 50%; }
+}
+#test {
+ height: 100px;
+ width: 100px;
+ background-repeat: no-repeat;
+ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF/wAAAAAAQaMSAwAAABJJREFUeNpiYBgFo2AwAIAAAwACigABtnCV2AAAAABJRU5ErkJggg==); /* a 25x25 px red box */
+ background-position-x: 0px;
+ animation: holdBackgroundPosition 100s infinite;
+}
+</style>
+<div id="test" class="reftest-opaque-layer"></div>
diff --git a/layout/reftests/css-animations/change-animation-name-in-rule-ref.html b/layout/reftests/css-animations/change-animation-name-in-rule-ref.html
new file mode 100644
index 0000000000..5fa2d6873f
--- /dev/null
+++ b/layout/reftests/css-animations/change-animation-name-in-rule-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<style>
+div {
+ background-color: green;
+ width: 100px;
+ height: 100px;
+}
+</style>
+<div></div>
diff --git a/layout/reftests/css-animations/change-animation-name-to-non-existent-in-rule.html b/layout/reftests/css-animations/change-animation-name-to-non-existent-in-rule.html
new file mode 100644
index 0000000000..6ec117896a
--- /dev/null
+++ b/layout/reftests/css-animations/change-animation-name-to-non-existent-in-rule.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+#target {
+ animation: red 100s;
+}
+@keyframes red {
+ 0% { background-color: red; }
+ 100% { background-color: red; }
+}
+div {
+ background-color: green;
+ width: 100px;
+ height: 100px;
+}
+</style>
+<div id="target"></div>
+<script>
+document.addEventListener('MozReftestInvalidate', () => {
+ requestAnimationFrame(() => {
+ document.styleSheets[0].cssRules[0].style.animationName = 'non-existent';
+ document.documentElement.classList.remove('reftest-wait');
+ });
+}, false);
+</script>
diff --git a/layout/reftests/css-animations/change-animation-name-to-none-in-rule.html b/layout/reftests/css-animations/change-animation-name-to-none-in-rule.html
new file mode 100644
index 0000000000..7f64d2e525
--- /dev/null
+++ b/layout/reftests/css-animations/change-animation-name-to-none-in-rule.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+#target {
+ animation: red 100s;
+}
+@keyframes red {
+ 0% { background-color: red; }
+ 100% { background-color: red; }
+}
+div {
+ background-color: green;
+ width: 100px;
+ height: 100px;
+}
+</style>
+<div id="target"></div>
+<script>
+document.addEventListener('MozReftestInvalidate', () => {
+ requestAnimationFrame(() => {
+ document.styleSheets[0].cssRules[0].style.animationName = 'none';
+ document.documentElement.classList.remove('reftest-wait');
+ });
+}, false);
+</script>
diff --git a/layout/reftests/css-animations/change-animation-name-to-other-in-rule.html b/layout/reftests/css-animations/change-animation-name-to-other-in-rule.html
new file mode 100644
index 0000000000..b0107c6369
--- /dev/null
+++ b/layout/reftests/css-animations/change-animation-name-to-other-in-rule.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+#target {
+ animation: red 100s;
+}
+@keyframes red {
+ 0% { background-color: red; }
+ 100% { background-color: red; }
+}
+@keyframes green {
+ 0% { background-color: green; }
+ 100% { background-color: green; }
+}
+div {
+ background-color: green;
+ width: 100px;
+ height: 100px;
+}
+</style>
+<div id="target"></div>
+<script>
+document.addEventListener('MozReftestInvalidate', () => {
+ requestAnimationFrame(() => {
+ document.styleSheets[0].cssRules[0].style.animationName = 'green';
+ document.documentElement.classList.remove('reftest-wait');
+ });
+}, false);
+</script>
diff --git a/layout/reftests/css-animations/containing-block-on-visibility-hidden-ref.html b/layout/reftests/css-animations/containing-block-on-visibility-hidden-ref.html
new file mode 100644
index 0000000000..73bf27705b
--- /dev/null
+++ b/layout/reftests/css-animations/containing-block-on-visibility-hidden-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style>
+#parent {
+ visibility: hidden;
+ will-change: transform;
+}
+
+#fixed {
+ position: fixed;
+ background-color: green;
+ height: 100px;
+ width: 100px;
+}
+
+#scroll {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ height: 80px;
+ width: 100px;
+}
+</style>
+<div id="scroll">
+ <div id="parent">
+ <div id="fixed"></div>
+ </div>
+</div>
diff --git a/layout/reftests/css-animations/containing-block-on-visibility-hidden.html b/layout/reftests/css-animations/containing-block-on-visibility-hidden.html
new file mode 100644
index 0000000000..fff3d91e7d
--- /dev/null
+++ b/layout/reftests/css-animations/containing-block-on-visibility-hidden.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>
+Transform animation generates a containing block for fixed-pos descendants
+even if the animation value is 'transform:none'
+</title>
+<style>
+#parent {
+ visibility: hidden;
+ animation: anim 100s step-end;
+}
+
+#fixed {
+ position: fixed;
+ background-color: green;
+ height: 100px;
+ width: 100px;
+}
+
+#scroll {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ height: 80px;
+ width: 100px;
+}
+@keyframes anim {
+ 0% { transform: none; }
+ 100% { transform: translateX(0px); }
+}
+</style>
+<div id="scroll">
+ <div id="parent">
+ <div id="fixed"></div>
+ </div>
+</div>
diff --git a/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html
new file mode 100644
index 0000000000..fb4a55510a
--- /dev/null
+++ b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ <style>
+ #target::marker {
+ content: 'content';
+ }
+ #target {
+ display: list-item;
+ margin-left: 200px;
+ }
+ </style>
+ <div id='target'></div>
+</html>
diff --git a/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html
new file mode 100644
index 0000000000..76155708df
--- /dev/null
+++ b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <style>
+ @keyframes anim {
+ from { content: 'content'; }
+ to { content: ''; }
+ }
+ #target::marker {
+ content: 'initial';
+ animation: anim 100s paused;
+ }
+ #target {
+ display: list-item;
+ margin-left: 200px;
+ }
+ </style>
+ <div id='target'></div>
+</html>
diff --git a/layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html
new file mode 100644
index 0000000000..0eaffcc6cb
--- /dev/null
+++ b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <style>
+ @keyframes anim {
+ from { content: ''; }
+ to { content: 'content'; }
+ }
+ #target::marker {
+ content: 'initial';
+ animation: anim 100s linear -50s paused;
+ }
+ #target {
+ display: list-item;
+ margin-left: 200px;
+ }
+ </style>
+ <div id='target'></div>
+</html>
diff --git a/layout/reftests/css-animations/content-on-pseudo-element-at-beginning.html b/layout/reftests/css-animations/content-on-pseudo-element-at-beginning.html
new file mode 100644
index 0000000000..0d4f05890b
--- /dev/null
+++ b/layout/reftests/css-animations/content-on-pseudo-element-at-beginning.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <style>
+ @keyframes anim {
+ from { content: 'content'; }
+ to { content: ''; }
+ }
+ #target::before {
+ content: 'initial';
+ animation: anim 100s paused;
+ }
+ </style>
+ <div id='target'></div>
+</html>
diff --git a/layout/reftests/css-animations/content-on-pseudo-element-at-half.html b/layout/reftests/css-animations/content-on-pseudo-element-at-half.html
new file mode 100644
index 0000000000..57ef251dbc
--- /dev/null
+++ b/layout/reftests/css-animations/content-on-pseudo-element-at-half.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <style>
+ @keyframes anim {
+ from { content: ''; }
+ to { content: 'content'; }
+ }
+ #target::before {
+ content: 'initial';
+ animation: anim 100s linear -50s paused;
+ }
+ </style>
+ <div id='target'></div>
+</html>
diff --git a/layout/reftests/css-animations/content-on-pseudo-element-ref.html b/layout/reftests/css-animations/content-on-pseudo-element-ref.html
new file mode 100644
index 0000000000..af5303402f
--- /dev/null
+++ b/layout/reftests/css-animations/content-on-pseudo-element-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <style>
+ #target::before {
+ content: 'content';
+ }
+ </style>
+ <div id='target'></div>
+</html>
diff --git a/layout/reftests/css-animations/continuation-opacity-ref.html b/layout/reftests/css-animations/continuation-opacity-ref.html
new file mode 100644
index 0000000000..6073cf3152
--- /dev/null
+++ b/layout/reftests/css-animations/continuation-opacity-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<title>Multiline inline animated opacity test</title>
+<style>
+blink {
+ opacity: 0;
+}
+
+p {
+ max-width: 15em;
+}
+</style>
+<p>
+ <blink>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</blink>
+</p>
diff --git a/layout/reftests/css-animations/continuation-opacity.html b/layout/reftests/css-animations/continuation-opacity.html
new file mode 100644
index 0000000000..25aa9a7493
--- /dev/null
+++ b/layout/reftests/css-animations/continuation-opacity.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<title>Multiline inline animated opacity test</title>
+<style>
+@keyframes blink {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+p {
+ max-width: 15em;
+}
+</style>
+<p>
+ <blink id="target">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</blink>
+</p>
+<script>
+document.addEventListener('MozReftestInvalidate', () => {
+ target.style.animation = "blink 100s step-end reverse";
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+}, false);
+</script>
diff --git a/layout/reftests/css-animations/ib-split-sibling-opacity-ref.html b/layout/reftests/css-animations/ib-split-sibling-opacity-ref.html
new file mode 100644
index 0000000000..e29f1b6f28
--- /dev/null
+++ b/layout/reftests/css-animations/ib-split-sibling-opacity-ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<title>Opacity animation on ib-split-sibling</title>
+<span style="visibility:hidden;">A <span style="display:block;visibility:visible">B</span> C</span>
diff --git a/layout/reftests/css-animations/ib-split-sibling-opacity.html b/layout/reftests/css-animations/ib-split-sibling-opacity.html
new file mode 100644
index 0000000000..acb25883b6
--- /dev/null
+++ b/layout/reftests/css-animations/ib-split-sibling-opacity.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<title>Opacity animation on ib-split-sibling</title>
+<style>
+@keyframes anim {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+</style>
+<span id="animating">A <span style="display:block"></span> C</span>
+<script>
+window.addEventListener("load", () => {
+ animating.style.animation = 'anim 100s step-end reverse';
+ window.addEventListener("MozAfterPaint", () => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ }, {once: true});
+});
+</script>
diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html
new file mode 100644
index 0000000000..4d08b92e49
--- /dev/null
+++ b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<title>In visibility hidden color animation on pseudo element</title>
+<style>
+
+div::marker {
+ visibility: visible;
+ color: blue;
+ content: "Color Animation";
+}
+
+div {
+ color: black;
+ visibility: hidden;
+ display: list-item;
+ list-style-position: inside;
+}
+
+</style>
+<div>color animation on visible psuedo element attached to invisible element</div>
diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html
new file mode 100644
index 0000000000..8a61cdcaa4
--- /dev/null
+++ b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<title>In visibility hidden color animation on pseudo element</title>
+<style>
+
+@keyframes color {
+ 0% { color: black }
+ 1% { color: blue }
+ 100% { color: blue }
+}
+
+div::marker {
+ visibility: visible;
+ content: "Color Animation";
+ animation: color 0.1s 1 forwards;
+}
+
+div {
+ color: black;
+ visibility: hidden;
+ display: list-item;
+ list-style-position: inside;
+}
+
+</style>
+<div id="target">color animation on visible pseudo element attached to invisible element</div>
+<script>
+
+document.getElementById("target").addEventListener("animationend", AnimationEndListener);
+
+function AnimationEndListener(event) {
+ setTimeout(RemoveReftestWait, 0);
+}
+
+function RemoveReftestWait() {
+ document.documentElement.classList.remove("reftest-wait");
+}
+
+</script>
diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element-ref.html b/layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element-ref.html
new file mode 100644
index 0000000000..b94f18dd4b
--- /dev/null
+++ b/layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<title>In visibility hidden color animation on pseudo element</title>
+<style>
+
+div:before {
+ visibility: visible;
+ color: blue;
+ content: "Color Animation";
+}
+
+div {
+ color: black;
+ visibility: hidden;
+}
+
+</style>
+<div>color animation on visible psuedo element attached to invisible element</div>
diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element.html b/layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element.html
new file mode 100644
index 0000000000..cbdc4e11b3
--- /dev/null
+++ b/layout/reftests/css-animations/in-visibility-hidden-animation-pseudo-element.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<title>In visibility hidden color animation on pseudo element</title>
+<style>
+
+@keyframes color {
+ 0% { color: black }
+ 1% { color: blue }
+ 100% { color: blue }
+}
+
+div:before {
+ visibility: visible;
+ content: "Color Animation";
+ animation: color 0.1s 1 forwards;
+}
+
+div {
+ color: black;
+ visibility: hidden;
+}
+
+</style>
+<div id="target">color animation on visible pseudo element attached to invisible element</div>
+<script>
+
+document.getElementById("target").addEventListener("animationend", AnimationEndListener);
+
+function AnimationEndListener(event) {
+ setTimeout(RemoveReftestWait, 0);
+}
+
+function RemoveReftestWait() {
+ document.documentElement.classList.remove("reftest-wait");
+}
+
+</script>
diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation-ref.html b/layout/reftests/css-animations/in-visibility-hidden-animation-ref.html
new file mode 100644
index 0000000000..09997ef486
--- /dev/null
+++ b/layout/reftests/css-animations/in-visibility-hidden-animation-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<title>In visibility hidden color animation</title>
+<style>
+
+p {
+ color: blue;
+ visibility: visible;
+}
+
+div {
+ visibility: hidden;
+}
+
+</style>
+<div><p>color animation on visible element in invisible parent element</p></div>
diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation.html b/layout/reftests/css-animations/in-visibility-hidden-animation.html
new file mode 100644
index 0000000000..7488344e0e
--- /dev/null
+++ b/layout/reftests/css-animations/in-visibility-hidden-animation.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<title>in visibility hidden color animation</title>
+<style>
+
+@keyframes color {
+ 0% { color: black }
+ 1% { color: blue }
+ 100% { color: blue }
+}
+
+p {
+ visibility: visible;
+}
+
+div {
+ color: black;
+ animation: color 0.1s 1 forwards;
+ visibility: hidden;
+}
+
+</style>
+<div id="parent"><p>color animation on visible element in invisible parent element</p></div>
+<script>
+
+document.getElementById("parent").addEventListener("animationend", AnimationEndListener);
+
+function AnimationEndListener(event) {
+ setTimeout(RemoveReftestWait, 0);
+}
+
+function RemoveReftestWait() {
+ document.documentElement.classList.remove("reftest-wait");
+}
+
+</script>
diff --git a/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html
new file mode 100644
index 0000000000..a71f9e85d2
--- /dev/null
+++ b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<style>
+#target::marker {
+ content: '';
+ background-color: rgb(255, 255, 255);
+ height: 100px;
+ width: 100px;
+ position: absolute;
+}
+#target {
+ display: list-item;
+ list-style-position: inside;
+}
+</style>
+<div id="target"></div>
+</html>
diff --git a/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html
new file mode 100644
index 0000000000..42b9ca543d
--- /dev/null
+++ b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+@keyframes anim {
+ from { background-color: rgb(255, 255, 255); }
+ to { background-color: rgb(255, 255, 255); }
+}
+#target::marker {
+ content: 'initial';
+ background-color: rgb(0, 0, 0);
+ height: 100px;
+ width: 100px;
+ position: absolute;
+}
+#target.hover::marker{
+ content: '';
+ animation: anim 100s steps(1, start);
+}
+#target {
+ display: list-item;
+ list-style-position: inside;
+}
+</style>
+<div id="target"></div>
+<script>
+window.addEventListener("load", () => {
+ target.className = 'hover';
+ target.addEventListener('animationstart', () => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/mask-anim-ref.html b/layout/reftests/css-animations/mask-anim-ref.html
new file mode 100644
index 0000000000..e6da65775b
--- /dev/null
+++ b/layout/reftests/css-animations/mask-anim-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>Reference of testcases for mssk-position and mask-size animations</title>
+<style>
+#test {
+ height: 100px;
+ width: 100px;
+ background-repeat: no-repeat;
+ background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"><rect x="0" y="0" width="25" height="25" fill="blue"/></svg>');
+ background-position: 50% 50%;
+}
+</style>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/mask-position-after-finish-1a.html b/layout/reftests/css-animations/mask-position-after-finish-1a.html
new file mode 100644
index 0000000000..c777e028a3
--- /dev/null
+++ b/layout/reftests/css-animations/mask-position-after-finish-1a.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>mask-position animation after finish</title>
+<style>
+ @keyframes changeMaskPosition {
+ from { mask-position: 0% 0%; }
+ to { mask-position: center center; }
+ }
+ #test {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ mask-repeat: no-repeat;
+ mask-position: 0% 0%;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"><rect x="0" y="0" width="25" height="25" fill="blue"/></svg>');
+ animation: changeMaskPosition 0.01s forwards;
+ }
+</style>
+<div id="test"></div>
+<script>
+document.getElementById("test").addEventListener("animationend", () => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove("reftest-wait");
+ })
+});
+</script>
diff --git a/layout/reftests/css-animations/mask-position-after-finish-1b.html b/layout/reftests/css-animations/mask-position-after-finish-1b.html
new file mode 100644
index 0000000000..26a89ac1be
--- /dev/null
+++ b/layout/reftests/css-animations/mask-position-after-finish-1b.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>mask-position animation after finish</title>
+<style>
+ @keyframes changeMaskPosition {
+ from { mask-position: 0% 0%; }
+ to { mask-position: center center; }
+ }
+ #test {
+ height: 100px;
+ width: 100px;
+ mask-repeat: no-repeat;
+ mask-position: 0% 0%;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"><rect x="0" y="0" width="25" height="25" fill="blue"/></svg>');
+ animation: changeMaskPosition 0.01s forwards;
+ }
+
+ #inner {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ box-sizing: border-box;
+ /* Apply will-change property to force paint mask on mask layer */
+ border: 1px solid transparent;
+ will-change: transform;
+ }
+</style>
+<div id="test"><div id="inner"></div></div>
+<script>
+document.getElementById("test").addEventListener("animationend", () => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove("reftest-wait");
+ })
+});
+</script>
diff --git a/layout/reftests/css-animations/mask-position-in-delay-1a.html b/layout/reftests/css-animations/mask-position-in-delay-1a.html
new file mode 100644
index 0000000000..a1989482f9
--- /dev/null
+++ b/layout/reftests/css-animations/mask-position-in-delay-1a.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>mask-position animation in delay phase</title>
+<style>
+@keyframes holdMaskPosition {
+ from,to { mask-position: left top; }
+}
+#test {
+ background-color: blue;
+ height: 100px;
+ width: 100px;
+ mask-repeat: no-repeat;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"><rect x="0" y="0" width="25" height="25" fill="blue"/></svg>');
+ animation: holdMaskPosition 100s 100s infinite;
+ mask-position: center center;
+}
+</style>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/mask-position-in-delay-1b.html b/layout/reftests/css-animations/mask-position-in-delay-1b.html
new file mode 100644
index 0000000000..90e8243aed
--- /dev/null
+++ b/layout/reftests/css-animations/mask-position-in-delay-1b.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>mask-position animation in delay phase</title>
+<style>
+ @keyframes holdMaskPosition {
+ from,to { mask-position: left top; }
+ }
+ #test {
+ height: 100px;
+ width: 100px;
+ mask-repeat: no-repeat;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"><rect x="0" y="0" width="25" height="25" fill="blue"/></svg>');
+ animation: holdMaskPosition 100s 100s infinite;
+ mask-position: center center;
+ }
+
+ #inner {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ box-sizing: border-box;
+ /* Apply will-change property to force paint mask on mask layer */
+ border: 1px solid transparent;
+ will-change: transform;
+ }
+</style>
+<div id="test"><div id="inner"></div></div>
diff --git a/layout/reftests/css-animations/mask-size-after-finish-1a.html b/layout/reftests/css-animations/mask-size-after-finish-1a.html
new file mode 100644
index 0000000000..4b6b990b2c
--- /dev/null
+++ b/layout/reftests/css-animations/mask-size-after-finish-1a.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>mask-size animation after finish</title>
+<style>
+ @keyframes changeMaskSize {
+ from { mask-size: 50px 50px; }
+ to { mask-size: 25px 25px; }
+ }
+ #test {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ mask-repeat: no-repeat;
+ mask-position: center center;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"><rect x="0" y="0" width="50" height="50" fill="blue"/></svg>');
+ animation: changeMaskSize 0.01s forwards;
+ }
+</style>
+<div id="test"></div>
+<script>
+document.getElementById("test").addEventListener("animationend", () => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove("reftest-wait");
+ })
+});
+</script>
diff --git a/layout/reftests/css-animations/mask-size-after-finish-1b.html b/layout/reftests/css-animations/mask-size-after-finish-1b.html
new file mode 100644
index 0000000000..d0b15bb0f8
--- /dev/null
+++ b/layout/reftests/css-animations/mask-size-after-finish-1b.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>mask-size animation after finish</title>
+<style>
+ @keyframes changeMaskSize {
+ from { mask-size: 50px 50px; }
+ to { mask-size: 25px 25px; }
+ }
+ #test {
+ height: 100px;
+ width: 100px;
+ mask-repeat: no-repeat;
+ mask-position: center center;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"><rect x="0" y="0" width="50" height="50" fill="blue"/></svg>');
+ animation: changeMaskSize 0.01s forwards;
+ }
+
+ #inner {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ box-sizing: border-box;
+ /* Apply will-change property to force paint mask on mask layer */
+ border: 1px solid transparent;
+ will-change: transform;
+ }
+</style>
+<div id="test"><div id="inner"></div></div>
+<script>
+document.getElementById("test").addEventListener("animationend", () => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove("reftest-wait");
+ })
+});
+</script>
diff --git a/layout/reftests/css-animations/mask-size-in-delay-1a.html b/layout/reftests/css-animations/mask-size-in-delay-1a.html
new file mode 100644
index 0000000000..7adaf00bbd
--- /dev/null
+++ b/layout/reftests/css-animations/mask-size-in-delay-1a.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>mask-size animation in delay phase</title>
+<style>
+ @keyframes changeMaskSize {
+ from { mask-size: 50px 50px; }
+ to { mask-size: 50px 50px; }
+ }
+
+ #test {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ mask-repeat: no-repeat;
+ mask-position: center center;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"><rect x="0" y="0" width="25" height="25" fill="blue"/></svg>');
+ animation: changeMaskSize 100s 100s infinite;
+ }
+</style>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/mask-size-in-delay-1b.html b/layout/reftests/css-animations/mask-size-in-delay-1b.html
new file mode 100644
index 0000000000..c2c987ee7a
--- /dev/null
+++ b/layout/reftests/css-animations/mask-size-in-delay-1b.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>mask-size animation in delay phase</title>
+<style>
+@keyframes changeMaskSize {
+ from { mask-size: 50px 50px; }
+ to { mask-size: 50px 50px; }
+}
+
+#test {
+ height: 100px;
+ width: 100px;
+ mask-repeat: no-repeat;
+ mask-position: center center;
+ mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"><rect x="0" y="0" width="25" height="25" fill="blue"/></svg>');
+ animation: changeMaskSize 100s 100s infinite;
+}
+
+#inner {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ box-sizing: border-box;
+ /* Apply will-change property to force paint mask on mask layer */
+ border: 1px solid transparent;
+ will-change: transform;
+}
+
+</style>
+<div id="test"><div id="inner"></div></div>
diff --git a/layout/reftests/css-animations/no-stacking-context-animation-ref.html b/layout/reftests/css-animations/no-stacking-context-animation-ref.html
new file mode 100644
index 0000000000..efc029d03e
--- /dev/null
+++ b/layout/reftests/css-animations/no-stacking-context-animation-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>
+Reference of testcases which don't create a stacking context for bug 1278136
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ background: green;
+ position: fixed;
+ top: 50px;
+}
+#test {
+ height: 100px;
+ width: 100px;
+ background: blue;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/no-stacking-context-offset-distance-animation-with-offset-path-none.html b/layout/reftests/css-animations/no-stacking-context-offset-distance-animation-with-offset-path-none.html
new file mode 100644
index 0000000000..c8dd698148
--- /dev/null
+++ b/layout/reftests/css-animations/no-stacking-context-offset-distance-animation-with-offset-path-none.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+offset-distance animation doesn't create a stacking context if
+offset-path is none
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes distance {
+ from, to { offset-distance: 0% }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: distance 100s infinite;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/no-stacking-context-opacity-removing-animation-in-delay.html b/layout/reftests/css-animations/no-stacking-context-opacity-removing-animation-in-delay.html
new file mode 100644
index 0000000000..806e82f9b0
--- /dev/null
+++ b/layout/reftests/css-animations/no-stacking-context-opacity-removing-animation-in-delay.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>
+Removing CSS animation in delay phase destroys a stacking context
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opacity0 {
+ from, to { opacity: 0 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ opacity: 1 ! important;
+}
+</style>
+<span></span>
+<div id="test"></div>
+<script>
+window.addEventListener("load", () => {
+ var target = document.getElementById("test");
+ target.style.animation = "Opacity0 100s 100s";
+
+ // We need to wait for MozAfterPaint instead of requestAnimationFrame to
+ // ensure the stacking context has been updated on the compositor.
+ window.addEventListener("MozAfterPaint", function() {
+ // Here we have CSS animation on 100% opacity style element, so
+ // there should be a stacking context.
+
+ target.style.animation = "";
+
+ // This time we don't need to wait for MozAfterPaint because reftest tool
+ // will be received MozAferPaint event.
+ requestAnimationFrame(() => {
+ // Now we have only 100% opacity style, so we should not create any
+ // stacking context.
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ }, {once: true});
+});
+</script>
diff --git a/layout/reftests/css-animations/no-stacking-context-transform-removing-animation-in-delay.html b/layout/reftests/css-animations/no-stacking-context-transform-removing-animation-in-delay.html
new file mode 100644
index 0000000000..2e4cd9abe2
--- /dev/null
+++ b/layout/reftests/css-animations/no-stacking-context-transform-removing-animation-in-delay.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>
+Removing CSS animation in delay phase destroys stacking context
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ transform: none ! important;
+}
+</style>
+<span></span>
+<div id="test"></div>
+<script>
+window.addEventListener("load", () => {
+ var target = document.getElementById("test");
+ target.style.animation = "TransformNone 100s 100s";
+
+ // We need to wait for MozAfterPaint instead of requestAnimationFrame to
+ // ensure the stacking context has been updated on the compositor.
+ window.addEventListener("MozAfterPaint", function() {
+ // Here we have CSS animation on transform:none style element, so
+ // there should be a stacking context.
+
+ target.style.animation = "";
+ // This time we don't need to wait for MozAfterPaint because reftest tool
+ // will be received MozAferPaint event.
+ requestAnimationFrame(() => {
+ // Now we have only transform:none style, so we should not create any
+ // stacking context.
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ }, {once: true});
+});
+</script>
diff --git a/layout/reftests/css-animations/no-style-sharing-with-animations-ref.html b/layout/reftests/css-animations/no-style-sharing-with-animations-ref.html
new file mode 100644
index 0000000000..0218b02f8a
--- /dev/null
+++ b/layout/reftests/css-animations/no-style-sharing-with-animations-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<style>
+div {
+ background-color: green;
+ width: 100px;
+ height: 100px;
+}
+</style>
+<div></div>
+<div></div>
diff --git a/layout/reftests/css-animations/no-style-sharing-with-animations.html b/layout/reftests/css-animations/no-style-sharing-with-animations.html
new file mode 100644
index 0000000000..02dc960ca2
--- /dev/null
+++ b/layout/reftests/css-animations/no-style-sharing-with-animations.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+.animation {
+ animation: anim 100s forwards;
+}
+@keyframes anim {
+ 0% { background-color: red; }
+ 100% { background-color: red; }
+}
+div {
+ background-color: green;
+ width: 100px;
+ height: 100px;
+}
+</style>
+<div class="animation"></div>
+<div class="animation"></div>
+<script>
+document.addEventListener('MozReftestInvalidate', () => {
+ requestAnimationFrame(() => {
+ document.styleSheets[0].cssRules[0].style.animationName = 'none';
+ document.documentElement.classList.remove('reftest-wait');
+ });
+}, false);
+</script>
diff --git a/layout/reftests/css-animations/opacity-animation-in-delay.html b/layout/reftests/css-animations/opacity-animation-in-delay.html
new file mode 100644
index 0000000000..cafa34881f
--- /dev/null
+++ b/layout/reftests/css-animations/opacity-animation-in-delay.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<style>
+@keyframes anim {
+ from { opacity: 0.5; }
+ to { opacity: 0.5; }
+}
+div {
+ background: green;
+ width: 100px;
+ height: 100px;
+ animation: anim 100s 100s;
+ opacity: 0;
+}
+</style>
+<div></div>
+<script>
+requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent-ref.html b/layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent-ref.html
new file mode 100644
index 0000000000..ff69f708eb
--- /dev/null
+++ b/layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <title>Testcase, bug 1395151</title>
+ <style type="text/css">
+.ok {
+ background : #0f0;
+ height : 40px;
+ width : 40px;
+}
+.error {
+ opacity : .001;
+ height : 100%;
+ width : 100%;
+}
+.error > span {
+ background : #f00;
+ content : "";
+ display : block;
+ height : 100%;
+ width : 100%;
+}
+ </style>
+</head>
+<body>
+<div class="ok">
+ <div class="error"><span></span></div>
+</div>
+</body>
+</html>
diff --git a/layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent.html b/layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent.html
new file mode 100644
index 0000000000..aa90445711
--- /dev/null
+++ b/layout/reftests/css-animations/opacity-animation-in-fixed-opacity-parent.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <title>Testcase, bug 1395151</title>
+ <style type="text/css">
+@keyframes test-anim {
+ from { opacity : 1 }
+ to { opacity : 1 }
+}
+
+.ok {
+ background : #0f0;
+ height : 40px;
+ width : 40px;
+}
+
+.error {
+ opacity : .001;
+ height : 100%;
+ width : 100%;
+}
+
+.error > span {
+ animation : test-anim 1s linear infinite;
+ background : #f00;
+ content : "";
+ display : block;
+ height : 100%;
+ width : 100%;
+}
+ </style>
+</head>
+<body>
+<div class="ok">
+ <div class="error"><span></span></div>
+</div>
+</body>
+</html>
diff --git a/layout/reftests/css-animations/partially-out-of-view-animation-ref.html b/layout/reftests/css-animations/partially-out-of-view-animation-ref.html
new file mode 100644
index 0000000000..fafb98b2dc
--- /dev/null
+++ b/layout/reftests/css-animations/partially-out-of-view-animation-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<title>Animation on element which is partially out of the view</title>
+<style>
+
+div {
+ position: absolute;
+ width: 200px;
+ height: 200px;
+ background-color: blue;
+ top: -100px;
+}
+
+</style>
+<div></div>
diff --git a/layout/reftests/css-animations/partially-out-of-view-animation.html b/layout/reftests/css-animations/partially-out-of-view-animation.html
new file mode 100644
index 0000000000..2bc2af6c69
--- /dev/null
+++ b/layout/reftests/css-animations/partially-out-of-view-animation.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<title>Animation on element which is partially out of the view</title>
+<style>
+
+@keyframes background-color {
+ 0% { background-color: black }
+ 1% { background-color: blue }
+ 100% { background-color: blue }
+}
+
+div {
+ position: absolute;
+ width: 200px;
+ height: 200px;
+ background-color: black;
+ animation: background-color 0.1s 1 forwards;
+ top: -100px;
+}
+
+</style>
+<div id="target"></div>
+<script>
+
+document.getElementById("target").addEventListener("animationend", AnimationEndListener);
+
+function AnimationEndListener(event) {
+ setTimeout(RemoveReftestWait, 0);
+}
+
+function RemoveReftestWait() {
+ document.documentElement.classList.remove("reftest-wait");
+}
+
+</script>
diff --git a/layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time-ref.html b/layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time-ref.html
new file mode 100644
index 0000000000..65387b5998
--- /dev/null
+++ b/layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<style>
+#target::before {
+ content: '';
+ background-color: rgb(255, 255, 255);
+ height: 100px;
+ width: 100px;
+ position: absolute;
+}
+</style>
+<div id="target"></div>
+</html>
diff --git a/layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time.html b/layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time.html
new file mode 100644
index 0000000000..325236b2a7
--- /dev/null
+++ b/layout/reftests/css-animations/reframe-and-animation-starts-at-the-same-time.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+@keyframes anim {
+ from { background-color: rgb(255, 255, 255); }
+ to { background-color: rgb(255, 255, 255); }
+}
+#target::before {
+ content: 'initial';
+ background-color: rgb(0, 0, 0);
+ height: 100px;
+ width: 100px;
+ position: absolute;
+}
+#target.hover::before{
+ content: '';
+ animation: anim 100s steps(1, start);
+}
+</style>
+<div id="target"></div>
+<script>
+window.addEventListener("load", () => {
+ target.className = 'hover';
+ target.addEventListener('animationstart', () => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/reftest.list b/layout/reftests/css-animations/reftest.list
new file mode 100644
index 0000000000..07cd6898dd
--- /dev/null
+++ b/layout/reftests/css-animations/reftest.list
@@ -0,0 +1,87 @@
+== screen-animations.html screen-animations-ref.html
+!= screen-animations.html screen-animations-notref.html
+== animate-opacity.html animate-opacity-ref.html
+== animate-preserves3d.html animate-preserves3d-ref.html
+== animation-initially-out-of-view-with-delay.html animation-initially-out-of-view-with-delay-ref.html
+== animation-on-empty-height-frame.html about:blank
+== in-visibility-hidden-animation.html in-visibility-hidden-animation-ref.html
+== in-visibility-hidden-animation-pseudo-element.html in-visibility-hidden-animation-pseudo-element-ref.html
+pref(layout.css.marker.restricted,false) == in-visibility-hidden-animation-marker-pseudo-element.html in-visibility-hidden-animation-marker-pseudo-element-ref.html
+== partially-out-of-view-animation.html partially-out-of-view-animation-ref.html
+fails-if(useDrawSnapshot) == animate-display-table-opacity.html animate-display-table-opacity-ref.html
+# We need to run 100% opacity test case when OMTA is disabled to check that the animation creates a stacking context even if the animation is not running on the compositor
+test-pref(layers.offmainthreadcomposition.async-animations,false) == stacking-context-opacity-1-animation.html stacking-context-animation-ref.html
+# We need to run transform:none test case when OMTA is disabled to check that the animation creates a stacking context even if the animation is not running on the compositor
+test-pref(layers.offmainthreadcomposition.async-animations,false) == stacking-context-transform-none-animation.html stacking-context-animation-ref.html
+== no-stacking-context-opacity-removing-animation-in-delay.html no-stacking-context-animation-ref.html
+== no-stacking-context-transform-removing-animation-in-delay.html no-stacking-context-animation-ref.html
+== stacking-context-lose-opacity-1.html stacking-context-animation-ref.html
+== stacking-context-lose-transform-none.html stacking-context-animation-ref.html
+== stacking-context-opacity-win-in-delay.html stacking-context-animation-ref.html
+== stacking-context-opacity-win-in-delay-on-main-thread.html stacking-context-animation-ref.html
+== stacking-context-opacity-wins-over-transition.html stacking-context-animation-ref.html
+== stacking-context-transform-win-in-delay.html stacking-context-animation-ref.html
+== stacking-context-transform-win-in-delay-on-main-thread.html stacking-context-animation-ref.html
+== stacking-context-transform-wins-over-transition.html stacking-context-animation-ref.html
+== stacking-context-opacity-1-animation.html stacking-context-animation-ref.html
+== stacking-context-opacity-1-on-table.html stacking-context-animation-ref.html
+== stacking-context-opacity-1-with-fill-backwards.html stacking-context-animation-ref.html
+== stacking-context-opacity-1-with-fill-forwards.html stacking-context-animation-ref.html
+== stacking-context-paused-on-opacity-1.html stacking-context-animation-ref.html
+== stacking-context-paused-on-transform-none.html stacking-context-animation-ref.html
+== stacking-context-transform-none-animation.html stacking-context-animation-ref.html
+== stacking-context-transform-none-animation-on-svg.html stacking-context-animation-ref.html
+== stacking-context-transform-none-animation-with-backface-visibility.html stacking-context-animation-ref.html
+== stacking-context-transform-none-animation-with-preserve-3d.html stacking-context-animation-ref.html
+== stacking-context-transform-none-with-fill-backwards.html stacking-context-animation-ref.html
+== stacking-context-transform-none-with-fill-forwards.html stacking-context-animation-ref.html
+== stacking-context-opacity-1-in-delay.html stacking-context-animation-ref.html
+== stacking-context-opacity-removing-important-in-delay.html stacking-context-animation-ref.html
+== stacking-context-transform-none-in-delay.html stacking-context-animation-ref.html
+== stacking-context-transform-removing-important-in-delay.html stacking-context-animation-ref.html
+pref(layout.css.motion-path.enabled,true) == no-stacking-context-offset-distance-animation-with-offset-path-none.html no-stacking-context-animation-ref.html
+pref(layout.css.motion-path.enabled,true) == stacking-context-offset-path-none-animation.html stacking-context-animation-ref.html
+pref(layout.css.motion-path.enabled,true) == stacking-context-offset-path-none-in-delay.html stacking-context-animation-ref.html
+pref(layout.css.motion-path.enabled,true) == stacking-context-offset-path-none-with-fill-backwards.html stacking-context-animation-ref.html
+pref(layout.css.motion-path.enabled,true) == stacking-context-offset-path-none-with-fill-forwards.html stacking-context-animation-ref.html
+== background-position-in-delay.html background-position-ref.html # This test fails the reftest-opaque-layer check since animating background-position currently creates an active layer from its delay phse, and reftest-opaque-layer only handles items assigned to PaintedLayers.
+== background-position-after-finish.html background-position-ref.html
+random-if(useDrawSnapshot) == background-position-running.html background-position-ref.html # This test fails the reftest-opaque-layer check since animating background-position currently creates an active layer, and reftest-opaque-layer only handles items assigned to PaintedLayers.
+== background-position-important.html background-position-ref.html # This test fails the reftest-opaque-layer check since animating background-position overridden by a non-animated !important style also creates an active layer, and reftest-opaque-layer only handles items that are assigned to PaintedLayers.
+
+== mask-position-after-finish-1a.html mask-anim-ref.html
+== mask-position-after-finish-1b.html mask-anim-ref.html
+== mask-position-in-delay-1a.html mask-anim-ref.html
+== mask-position-in-delay-1b.html mask-anim-ref.html
+== mask-size-after-finish-1a.html mask-anim-ref.html
+== mask-size-after-finish-1b.html mask-anim-ref.html
+== mask-size-in-delay-1a.html mask-anim-ref.html
+== mask-size-in-delay-1b.html mask-anim-ref.html
+
+== stop-animation-on-discarded-pseudo-element.html about:blank
+
+== updating-animation-on-pseudo-element.html updating-animation-on-pseudo-element-ref.html
+pref(layout.css.marker.restricted,false) == updating-animation-on-marker-pseudo-element.html updating-animation-on-marker-pseudo-element-ref.html
+== content-on-pseudo-element-at-beginning.html content-on-pseudo-element-ref.html
+== content-on-pseudo-element-at-half.html content-on-pseudo-element-ref.html
+pref(layout.css.marker.restricted,false) == content-on-marker-pseudo-element-at-beginning.html content-on-marker-pseudo-element-at-beginning-ref.html
+pref(layout.css.marker.restricted,false) == content-on-marker-pseudo-element-at-half.html content-on-marker-pseudo-element-at-beginning-ref.html
+== reframe-and-animation-starts-at-the-same-time.html reframe-and-animation-starts-at-the-same-time-ref.html
+pref(layout.css.marker.restricted,false) == marker-reframe-and-animation-starts-at-the-same-time.html marker-reframe-and-animation-starts-at-the-same-time-ref.html
+== change-animation-name-to-none-in-rule.html change-animation-name-in-rule-ref.html
+== change-animation-name-to-other-in-rule.html change-animation-name-in-rule-ref.html
+== change-animation-name-to-non-existent-in-rule.html change-animation-name-in-rule-ref.html
+== no-style-sharing-with-animations.html no-style-sharing-with-animations-ref.html
+
+== continuation-opacity.html continuation-opacity-ref.html
+== ib-split-sibling-opacity.html about:blank
+
+== opacity-animation-in-fixed-opacity-parent.html opacity-animation-in-fixed-opacity-parent-ref.html
+== opacity-animation-in-delay.html about:blank
+== transform-animation-in-delay.html transform-animation-in-delay-ref.html
+== containing-block-on-visibility-hidden.html containing-block-on-visibility-hidden-ref.html
+== background-color.html background-color-ref.html
+== background-color-on-html.html background-color-on-html-ref.html
+skip-if(Android) == replace-with-new-positive-delay-animation.html replace-with-new-positive-delay-animation-ref.html # bug 1787682 for Android
+
+pref(layout.css.scroll-driven-animations.enabled,true) skip-if(!asyncPan) == scroll-timeline-in-delay-omta.html scroll-timeline-in-delay-omta-ref.html
diff --git a/layout/reftests/css-animations/replace-with-new-positive-delay-animation-ref.html b/layout/reftests/css-animations/replace-with-new-positive-delay-animation-ref.html
new file mode 100644
index 0000000000..3c822f514a
--- /dev/null
+++ b/layout/reftests/css-animations/replace-with-new-positive-delay-animation-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<style>
+#target {
+ width: 100px;
+ height: 100px;
+ opacity: 1;
+ background-color: green;
+}
+</style>
+<div id="target"></div>
+</html>
diff --git a/layout/reftests/css-animations/replace-with-new-positive-delay-animation.html b/layout/reftests/css-animations/replace-with-new-positive-delay-animation.html
new file mode 100644
index 0000000000..fbafd2cca8
--- /dev/null
+++ b/layout/reftests/css-animations/replace-with-new-positive-delay-animation.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<style>
+@keyframes first {
+ 0% { opacity: 0; }
+ 100% { opacity: 0; }
+}
+@keyframes second {
+ 0% { opacity: 0.5; }
+ 100% { opacity: 0.5; }
+}
+#target {
+ width: 100px;
+ height: 100px;
+ opacity: 1;
+ background-color: green;
+}
+</style>
+<div id="target"></div>
+<script>
+document.addEventListener("MozReftestInvalidate", async () => {
+ target.style.animation = "first 100s";
+ await new Promise(resolve => {
+ target.addEventListener("animationstart", resolve);
+ });
+
+ // Wait two frames to make sure the animation is composited.
+ await new Promise(resolve => { requestAnimationFrame(resolve); });
+ await new Promise(resolve => { requestAnimationFrame(resolve); });
+
+ target.style.animation = "second 100s 100s";
+
+ // To take a snapshot in the delay phase, wait two frames instead of
+ // wait for the animationstart event.
+ await new Promise(resolve => { requestAnimationFrame(resolve); });
+ await new Promise(resolve => { requestAnimationFrame(resolve); });
+
+ document.documentElement.classList.remove("reftest-wait");
+}, { once: true });
+</script>
+</html>
diff --git a/layout/reftests/css-animations/screen-animations-notref.html b/layout/reftests/css-animations/screen-animations-notref.html
new file mode 100644
index 0000000000..73a026f603
--- /dev/null
+++ b/layout/reftests/css-animations/screen-animations-notref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+<title>Static CSS animation</title>
+<style>
+
+p {
+ color: olive;
+}
+
+</style>
+<p>blue with animation support; olive without</p>
diff --git a/layout/reftests/css-animations/screen-animations-ref.html b/layout/reftests/css-animations/screen-animations-ref.html
new file mode 100644
index 0000000000..8830913084
--- /dev/null
+++ b/layout/reftests/css-animations/screen-animations-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+<title>Static CSS animation</title>
+<style>
+
+p {
+ color: blue;
+}
+
+</style>
+<p>blue with animation support; olive without</p>
diff --git a/layout/reftests/css-animations/screen-animations.html b/layout/reftests/css-animations/screen-animations.html
new file mode 100644
index 0000000000..ba1a0aa14e
--- /dev/null
+++ b/layout/reftests/css-animations/screen-animations.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<title>Static CSS animation</title>
+<style>
+
+@keyframes a {
+ from, to { color: blue }
+}
+
+p {
+ color: olive;
+ animation: a 1s infinite;
+}
+
+</style>
+<p>blue with animation support; olive without</p>
diff --git a/layout/reftests/css-animations/scroll-timeline-in-delay-omta-ref.html b/layout/reftests/css-animations/scroll-timeline-in-delay-omta-ref.html
new file mode 100644
index 0000000000..c6caf3029f
--- /dev/null
+++ b/layout/reftests/css-animations/scroll-timeline-in-delay-omta-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ }
+ #target {
+ width: 100px;
+ height: 100px;
+ background: green;
+ rotate: 45deg;
+ translate: 50px;
+ }
+</style>
+<body>
+ <div id="scroller"></div>
+ <div id="target"></div>
+</body>
+</html>
diff --git a/layout/reftests/css-animations/scroll-timeline-in-delay-omta.html b/layout/reftests/css-animations/scroll-timeline-in-delay-omta.html
new file mode 100644
index 0000000000..4dea5b7854
--- /dev/null
+++ b/layout/reftests/css-animations/scroll-timeline-in-delay-omta.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<head>
+<title>Scroll the scroll-driven animation from the active phase to delay</title>
+<style>
+ @keyframes anim {
+ from { translate: 100px; }
+ to { translate: 200px; }
+ }
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ scrollbar-width: none;
+ scroll-timeline: scroll_timeline;
+ }
+ #target {
+ width: 100px;
+ height: 100px;
+ background: green;
+ rotate: 45deg;
+ translate: 50px;
+ animation-name: anim;
+ animation-duration: 5s;
+ animation-timing-function: linear;
+ animation-delay: 5s;
+ animation-timeline: scroll_timeline;
+ }
+</style>
+<script>
+window.addEventListener("MozReftestInvalidate", async () => {
+ const scroller = document.getElementById("scroller");
+ scroller.scrollTop = 75;
+
+ // Wait for the MozAfterPaint to make the view id of |scroller| gets ready.
+ window.addEventListener('MozAfterPaint', async () => {
+ let utils = SpecialPowers.wrap(window).windowUtils;
+ utils.setAsyncScrollOffset(scroller, 0, -50);
+
+ await new Promise(function(resolve, reject) {
+ let repaintDone = function() {
+ SpecialPowers.Services.obs.removeObserver(
+ repaintDone,
+ "apz-repaints-flushed"
+ );
+ resolve();
+ };
+ SpecialPowers.Services.obs.addObserver(repaintDone,
+ "apz-repaints-flushed");
+ if (!utils.flushApzRepaints()) {
+ repaintDone();
+ }
+ });
+
+ // Wait for composition and then take the snapshot.
+ await new Promise(resolve => { requestAnimationFrame(resolve); });
+ await new Promise(resolve => { requestAnimationFrame(resolve); });
+
+ document.documentElement.classList.remove('reftest-wait');
+ }, {once: true});
+});
+
+</script>
+</head>
+<body>
+ <div id="scroller">
+ <div style="height: 100px; padding-bottom: 100px;"></div>
+ </div>
+ <div id="target"></div>
+</body>
+</html>
diff --git a/layout/reftests/css-animations/stacking-context-animation-ref.html b/layout/reftests/css-animations/stacking-context-animation-ref.html
new file mode 100644
index 0000000000..817056c1ce
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-animation-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Reference of testcases for bug 1273042</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ background: green;
+ position: fixed;
+ top: 50px;
+ z-index: -1;
+}
+#test {
+ height: 100px;
+ width: 100px;
+ background: blue;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-lose-opacity-1.html b/layout/reftests/css-animations/stacking-context-lose-opacity-1.html
new file mode 100644
index 0000000000..80ce2ea725
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-lose-opacity-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>
+Opacity animation creates a stacking context even if the opacity property
+is overridden by an !important rule
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opaque {
+ from, to { opacity: 1 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opaque 100s;
+ opacity: 1 !important;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-lose-transform-none.html b/layout/reftests/css-animations/stacking-context-lose-transform-none.html
new file mode 100644
index 0000000000..f08ec41bee
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-lose-transform-none.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>
+Transform animation creates a stacking context even if the transform property
+is overridden by an !important rule
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none; }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: TransformNone 100s infinite;
+ transform: none !important;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-offset-path-none-animation.html b/layout/reftests/css-animations/stacking-context-offset-path-none-animation.html
new file mode 100644
index 0000000000..53bbf4bf82
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-offset-path-none-animation.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+offset-path animation creates a stacking context even though it has only
+'offset-path:none' keyframes
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes OffsetPathNone {
+ from, to { offset-path: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: OffsetPathNone 100s infinite;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-offset-path-none-in-delay.html b/layout/reftests/css-animations/stacking-context-offset-path-none-in-delay.html
new file mode 100644
index 0000000000..568e8ea25a
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-offset-path-none-in-delay.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>
+offset-path animation creates stacking context in delay phase
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes offsetPathNone {
+ from, to { offset-path: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: offsetPathNone 100s 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-backwards.html b/layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-backwards.html
new file mode 100644
index 0000000000..50143d36bc
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-backwards.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+offset-path animation does not destroy stacking context when the animation
+has finished but has fill:backwards
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes OffsetPathNone {
+ from, to { offset-path: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: OffsetPathNone 100s 100s backwards;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-forwards.html b/layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-forwards.html
new file mode 100644
index 0000000000..1fc8700fee
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-offset-path-none-with-fill-forwards.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+offset-path animation does not destroy stacking context when the animation
+has finished but has fill:forwards
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes OffsetPathNone {
+ from, to { offset-path: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: OffsetPathNone 0s forwards;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-1-animation.html b/layout/reftests/css-animations/stacking-context-opacity-1-animation.html
new file mode 100644
index 0000000000..3a4fe7bf45
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-1-animation.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Opacity animation creates a stacking context even if it has only 100% opacity
+in its keyframes
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opaque {
+ from, to { opacity: 1; }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opaque 100s infinite;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-1-in-delay.html b/layout/reftests/css-animations/stacking-context-opacity-1-in-delay.html
new file mode 100644
index 0000000000..4e441397c8
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-1-in-delay.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>
+Opacity animation creates stacking context in delay phase
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opaque {
+ from, to { opacity: 1 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opaque 100s 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-1-on-table.html b/layout/reftests/css-animations/stacking-context-opacity-1-on-table.html
new file mode 100644
index 0000000000..f3da311909
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-1-on-table.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>
+Opacity animation on display:table element creates a stacking context even if it
+has only 100% opacity in its keyframes
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opaque {
+ from, to { opacity: 1; }
+}
+#test {
+ display: table;
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opaque 100s infinite;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-1-with-fill-backwards.html b/layout/reftests/css-animations/stacking-context-opacity-1-with-fill-backwards.html
new file mode 100644
index 0000000000..484da2979d
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-1-with-fill-backwards.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Opacity animation does not destroy stacking context when the animation
+has finished but has fill:backwards
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opaque {
+ from, to { opacity: 1 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opaque 100s 100s backwards;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-1-with-fill-forwards.html b/layout/reftests/css-animations/stacking-context-opacity-1-with-fill-forwards.html
new file mode 100644
index 0000000000..5fdda4f9dd
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-1-with-fill-forwards.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Opacity animation does not destroy stacking context when the animation
+has finished but has fill:forwards
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opaque {
+ from, to { opacity: 1 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opaque 0s forwards;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-removing-important-in-delay.html b/layout/reftests/css-animations/stacking-context-opacity-removing-important-in-delay.html
new file mode 100644
index 0000000000..f89240d230
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-removing-important-in-delay.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>
+Removing !important rule during delay phase of animation creates
+a stack context for correct style
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opacity0 {
+ from, to { opacity: 0 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opacity0 100s 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
+<script>
+window.addEventListener("load", () => {
+ var target = document.getElementById("test");
+ target.style.setProperty("opacity", "0.1", "important");
+
+ requestAnimationFrame(() => {
+ // Now the target opacity style should be 0.1 because of !important rule.
+
+ // Apply 100% opacity without important directive.
+ target.style.setProperty("opacity", "1", "");
+ requestAnimationFrame(() => {
+ // The CSS animation is no longer overridden but it's still in delay
+ // phase, so we should create a stacking context for 100% opacity style.
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ });
+});
+</script>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-win-in-delay-on-main-thread.html b/layout/reftests/css-animations/stacking-context-opacity-win-in-delay-on-main-thread.html
new file mode 100644
index 0000000000..8d35bf6225
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-win-in-delay-on-main-thread.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>
+Opacity animation winning over another opacity animation in delay phase
+on the main-thread creates a stacking context
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opacity1 {
+ from, to { opacity: 1; }
+}
+@keyframes Opacity0 {
+ from, to { opacity: 0; }
+}
+// For preventing running on the compositor.
+@keyframes Width {
+ from, to { width: 100px; }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opacity0 100s 100s, Opacity1 100s, Width 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-win-in-delay.html b/layout/reftests/css-animations/stacking-context-opacity-win-in-delay.html
new file mode 100644
index 0000000000..c60177d08f
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-win-in-delay.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>
+Opacity animation winning over another opacity animation in delay phase
+creates a stacking context
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opacity1 {
+ from, to { opacity: 1; }
+}
+@keyframes Opacity0 {
+ from, to { opacity: 0; }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opacity0 100s 100s, Opacity1 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-opacity-wins-over-transition.html b/layout/reftests/css-animations/stacking-context-opacity-wins-over-transition.html
new file mode 100644
index 0000000000..38993a8dd4
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-opacity-wins-over-transition.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>
+Opacity animation winning over opacity transition creates a stacking context
+for correct style.
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opacity1 {
+ from, to { opacity: 1; }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ opacity: 1;
+ transition: opacity 100s steps(1, start);
+ animation: Opacity1 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
+<script>
+window.addEventListener("load", () => {
+ var target = document.getElementById("test");
+ getComputedStyle(target).opacity;
+
+ // CSS animation wins over transitions, so transition won't be visible during
+ // the CSS animation.
+ target.style.opacity = 0;
+ getComputedStyle(target).opacity;
+ document.documentElement.classList.remove("reftest-wait");
+});
+</script>
diff --git a/layout/reftests/css-animations/stacking-context-paused-on-opacity-1.html b/layout/reftests/css-animations/stacking-context-paused-on-opacity-1.html
new file mode 100644
index 0000000000..b27985a6ca
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-paused-on-opacity-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Transform animation creates a stacking context even though it's paused on
+a 100% opacity keyframe
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Opaque {
+ from, to { opacity: 1 }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Opaque 100s paused;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-paused-on-transform-none.html b/layout/reftests/css-animations/stacking-context-paused-on-transform-none.html
new file mode 100644
index 0000000000..cd02908498
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-paused-on-transform-none.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Transform animation creates a stacking context even though it's paused on
+a 'transform:none' keyframe
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: TransformNone 100s paused;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-none-animation-on-svg.html b/layout/reftests/css-animations/stacking-context-transform-none-animation-on-svg.html
new file mode 100644
index 0000000000..6192d58b70
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-none-animation-on-svg.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Transform animation creates a stacking context even though it has only
+'transform:none' keyframes on an svg element</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ animation: TransformNone 100s infinite;
+}
+</style>
+<span></span>
+<svg id="test" width="100px" height="100px">
+ <rect x="0" y="0" width="100%" height="100%" fill="blue"/>
+</svg>
diff --git a/layout/reftests/css-animations/stacking-context-transform-none-animation-with-backface-visibility.html b/layout/reftests/css-animations/stacking-context-transform-none-animation-with-backface-visibility.html
new file mode 100644
index 0000000000..c96be7d4cc
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-none-animation-with-backface-visibility.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>
+Transform animation creates a stacking context even though it has only
+'transform:none' keyframes and with a style which prevents performning
+the animation on the compositor.
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ backface-visibility: hidden;
+ animation: TransformNone 100s infinite;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-none-animation-with-preserve-3d.html b/layout/reftests/css-animations/stacking-context-transform-none-animation-with-preserve-3d.html
new file mode 100644
index 0000000000..37b3f85167
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-none-animation-with-preserve-3d.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>
+Transform animation creates a stacking context even though it has only
+'transform:none' keyframes and with a style which prevents performning
+the animation on the compositor.
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ transform-style: preserve-3d;
+ animation: TransformNone 100s infinite;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-none-animation.html b/layout/reftests/css-animations/stacking-context-transform-none-animation.html
new file mode 100644
index 0000000000..53213b452d
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-none-animation.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Transform animation creates a stacking context even though it has only
+'transform:none' keyframes
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: TransformNone 100s infinite;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-none-in-delay.html b/layout/reftests/css-animations/stacking-context-transform-none-in-delay.html
new file mode 100644
index 0000000000..c52e8825d3
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-none-in-delay.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>
+Transform animation creates stacking context in delay phase
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: TransformNone 100s 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-none-with-fill-backwards.html b/layout/reftests/css-animations/stacking-context-transform-none-with-fill-backwards.html
new file mode 100644
index 0000000000..d0515c2945
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-none-with-fill-backwards.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Transform animation does not destroy stacking context when the animation
+has finished but has fill:backwards
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: TransformNone 100s 100s backwards;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-none-with-fill-forwards.html b/layout/reftests/css-animations/stacking-context-transform-none-with-fill-forwards.html
new file mode 100644
index 0000000000..2d9610232c
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-none-with-fill-forwards.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+Transform animation does not destroy stacking context when the animation
+has finished but has fill:forwards
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: TransformNone 0s forwards;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-removing-important-in-delay.html b/layout/reftests/css-animations/stacking-context-transform-removing-important-in-delay.html
new file mode 100644
index 0000000000..0b39dd4d4e
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-removing-important-in-delay.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>
+Removing !important rule during delay phase of animation creates
+a stack context for correct style
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes Transform100px {
+ from, to { transform: translate(100px) }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Transform100px 100s 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
+<script>
+window.addEventListener("load", () => {
+ var target = document.getElementById("test");
+ target.style.setProperty("transform", "translateX(200px)", "important");
+
+ requestAnimationFrame(() => {
+ // Now the target transform style should be translateX(200px) because of
+ // !important rule.
+
+ // Apply transform:none without important directive.
+ target.style.setProperty("transform", "none", "");
+ requestAnimationFrame(() => {
+ // The CSS animation is no longer overridden but it's still in delay
+ // phase, so we should create a stacking context for transform:none style.
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ });
+});
+</script>
diff --git a/layout/reftests/css-animations/stacking-context-transform-win-in-delay-on-main-thread.html b/layout/reftests/css-animations/stacking-context-transform-win-in-delay-on-main-thread.html
new file mode 100644
index 0000000000..2f61168946
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-win-in-delay-on-main-thread.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>
+Transform animation winning over another transform animation in delay phase
+on the main-thread creates a stacking context
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none; }
+}
+@keyframes Transform100px {
+ from, to { transform: translateX(100px); }
+}
+// For preventing running on the compositor.
+@keyframes Width {
+ from, to { width: 100px; }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Transform100px 100s 100s, TransformNone 100s, Width 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-win-in-delay.html b/layout/reftests/css-animations/stacking-context-transform-win-in-delay.html
new file mode 100644
index 0000000000..5a864faf47
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-win-in-delay.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>
+Transform animation winning over another transform animation in delay phase
+creates a stacking context
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none; }
+}
+@keyframes Transform100px {
+ from, to { transform: translateX(100px); }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ animation: Transform100px 100s 100s, TransformNone 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
diff --git a/layout/reftests/css-animations/stacking-context-transform-wins-over-transition.html b/layout/reftests/css-animations/stacking-context-transform-wins-over-transition.html
new file mode 100644
index 0000000000..8d1de575e0
--- /dev/null
+++ b/layout/reftests/css-animations/stacking-context-transform-wins-over-transition.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>
+Transform animation winning over transition creates a stacking context
+for correct style
+</title>
+<style>
+span {
+ height: 100px;
+ width: 100px;
+ position: fixed;
+ background: green;
+ top: 50px;
+}
+@keyframes TransformNone {
+ from, to { transform: none; }
+}
+#test {
+ width: 100px; height: 100px;
+ background: blue;
+ transform: translateX(200px);
+ transition: transform 100s steps(1, start);
+ animation: TransformNone 100s;
+}
+</style>
+<span></span>
+<div id="test"></div>
+<script>
+window.addEventListener("load", () => {
+ var target = document.getElementById("test");
+ getComputedStyle(target).transform;
+
+ // CSS animation wins over transition, so transition won't be visible during
+ // the CSS animation.
+ target.style.transform = "translateX(100px)";
+ getComputedStyle(target).transform;
+ document.documentElement.classList.remove("reftest-wait");
+});
+</script>
diff --git a/layout/reftests/css-animations/stop-animation-on-discarded-pseudo-element.html b/layout/reftests/css-animations/stop-animation-on-discarded-pseudo-element.html
new file mode 100644
index 0000000000..fccfade1cc
--- /dev/null
+++ b/layout/reftests/css-animations/stop-animation-on-discarded-pseudo-element.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+@keyframes anim {
+ 0% { background-color: red; }
+ 100% { background-color: red; }
+}
+#target.x::before,
+#target.y::before {
+ content: "";
+ position: absolute;
+ width: 100px;
+ height: 100px;
+}
+#target.x::before {
+ animation: anim 100s infinite;
+}
+</style>
+<div id="target"></div>
+<script>
+var target = document.getElementById('target');
+requestAnimationFrame(() => {
+ // Create ::before, start animation
+ target.className = 'x';
+ requestAnimationFrame(() => {
+ // Remove ::before, stop animation
+ target.className = '';
+
+ requestAnimationFrame(() => {
+ // Create ::before, should not be animating
+ target.className = 'y';
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+});
+</script>
diff --git a/layout/reftests/css-animations/transform-animation-in-delay-ref.html b/layout/reftests/css-animations/transform-animation-in-delay-ref.html
new file mode 100644
index 0000000000..9c161fe047
--- /dev/null
+++ b/layout/reftests/css-animations/transform-animation-in-delay-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<style>
+div {
+ background: green;
+ width: 100px;
+ height: 100px;
+ animation: anim 100s 100s;
+ transform: translateX(100px);
+}
+</style>
+<div></div>
+</html>
diff --git a/layout/reftests/css-animations/transform-animation-in-delay.html b/layout/reftests/css-animations/transform-animation-in-delay.html
new file mode 100644
index 0000000000..0ed13934f4
--- /dev/null
+++ b/layout/reftests/css-animations/transform-animation-in-delay.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait reftest-no-flush">
+<style>
+@keyframes anim {
+ from { transform: scale(2); }
+ to { transform: scale(2); }
+}
+div {
+ background: green;
+ width: 100px;
+ height: 100px;
+ animation: anim 100s 100s;
+ transform: translateX(100px);
+}
+</style>
+<div></div>
+<script>
+requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html
new file mode 100644
index 0000000000..9eab1517b7
--- /dev/null
+++ b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<style>
+#target::marker {
+ content: 'marker';
+ margin-left: 10em;
+ font-size: 20px;
+}
+#target {
+ display: list-item;
+ margin-left: 200px;
+}
+</style>
+<div id="target"></div>
+</html>
diff --git a/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html
new file mode 100644
index 0000000000..fc1d29cd38
--- /dev/null
+++ b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+@keyframes anim {
+ from { margin-left: 10em; }
+ to { margin-left: 10em; }
+}
+#target::marker {
+ content: 'marker';
+}
+#target.anim::marker {
+ animation: anim 100s infinite;
+ font-size: 10px;
+}
+#target.bigger-font::marker {
+ font-size: 20px;
+}
+#target {
+ display: list-item;
+ margin-left: 200px;
+}
+</style>
+<div id="target"></div>
+<script>
+addEventListener('DOMContentLoaded', () => {
+ var target = document.getElementById('target');
+
+ // Start an animation on pseudo element.
+ target.classList.add('anim');
+
+ requestAnimationFrame(() => {
+ // The animation on pseudo element should be updated
+ // when the target element classes are modified.
+ target.classList.add('bigger-font');
+
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+});
+</script>
+</html>
diff --git a/layout/reftests/css-animations/updating-animation-on-pseudo-element-ref.html b/layout/reftests/css-animations/updating-animation-on-pseudo-element-ref.html
new file mode 100644
index 0000000000..7196f11503
--- /dev/null
+++ b/layout/reftests/css-animations/updating-animation-on-pseudo-element-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<style>
+#target::before {
+ content: 'before';
+ margin-left: 10em;
+ font-size: 20px;
+}
+</style>
+<div id="target"></div>
+</html>
diff --git a/layout/reftests/css-animations/updating-animation-on-pseudo-element.html b/layout/reftests/css-animations/updating-animation-on-pseudo-element.html
new file mode 100644
index 0000000000..cae7d2723c
--- /dev/null
+++ b/layout/reftests/css-animations/updating-animation-on-pseudo-element.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<style>
+@keyframes anim {
+ from { margin-left: 10em; }
+ to { margin-left: 10em; }
+}
+#target::before {
+ content: 'before';
+}
+#target.anim::before {
+ animation: anim 100s infinite;
+ font-size: 10px;
+}
+#target.bigger-font::before {
+ font-size: 20px;
+}
+</style>
+<div id="target"></div>
+<script>
+addEventListener('DOMContentLoaded', () => {
+ var target = document.getElementById('target');
+
+ // Start an animation on pseudo element.
+ target.classList.add('anim');
+
+ requestAnimationFrame(() => {
+ // The animation on pseudo element should be updated
+ // when the target element classes are modified.
+ target.classList.add('bigger-font');
+
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+});
+</script>
+</html>