<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[286555] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/286555">286555</a></dd>
<dt>Author</dt> <dd>graouts@webkit.org</dd>
<dt>Date</dt> <dd>2021-12-06 11:30:57 -0800 (Mon, 06 Dec 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Web Animations] Add a way to run scripted animations
https://bugs.webkit.org/show_bug.cgi?id=233869
rdar://85983542

Reviewed by Dean Jackson.

Source/WebCore:

Tests: webanimations/custom-effect/custom-effect.html
       webanimations/custom-effect/document-timeline-animate.html

This patch adds two new Web-exposed features to allow authors to write callback-based animations
leveraging the full power of the Web Animations model.

First, we add a new AnimationEffect subclass which wraps a callback to be executed on every tick
of the associated animation's timeline: CustomEffect. It can be constructed by providing a JS function
as its first parameter, and either a number or a dictionary to provide timing properties for the effect.
This is similar to how KeyframeEffect will accept a keyframes object and then timing data. The callback
is provided the effect progress as its sole parameter. Web authors can use this new interface as follows:

    const animation = new Animation;
    animation.effect = new CustomEffect(progress => { … }, 1000);
    animation.play();

Second, to make starting callback-based animations more straightforward and in a very similar fashion
to how keyframe animations can be initiated on an element using Element.animate(), we introduce a new
animate() method on DocumentTimeline, allowing the previous exmaple to be written as:

    const animation = document.timeline.animate(progress => { … }, 1000);

This simple approach allows Web authors to move past the simple use of requestAnimationFrame() and harness
the Web Animations timing model which will let them pause and resume animations, seek them, control their
playback rate, apply easing, respond to the "finished" promise, etc.

The code itself is very simple, CustomEffect is simply an AnimationEffect subclass that indicates that it's
always interested in scheduling updates while active using the ticksContinouslyWhileActive() method. This
means that all the scheduling logic contained in WebAnimation and AnimationEffect applies, allowing callbacks
to not be fired when the animation is paused or when the page is suspended, or fired sparingly when a steps()
timing function is specified.

* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Headers.cmake:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* animation/AnimationEffect.h:
(WebCore::AnimationEffect::isCustomEffect const):
* animation/CustomAnimationOptions.h: Added.
* animation/CustomAnimationOptions.idl: Added.
* animation/CustomEffect.cpp: Added.
(WebCore::CustomEffect::create):
(WebCore::CustomEffect::CustomEffect):
(WebCore::CustomEffect::animationDidTick):
* animation/CustomEffect.h: Added.
(WebCore::CustomEffect::~CustomEffect):
* animation/CustomEffect.idl: Added.
* animation/CustomEffectCallback.h: Added.
* animation/CustomEffectCallback.idl: Added.
* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::animate):
* animation/DocumentTimeline.h:
* animation/DocumentTimeline.idl:
* bindings/js/WebCoreBuiltinNames.h:

Source/WTF:

Add a new experimental feature for the CustomEffect interface.

* Scripts/Preferences/WebPreferencesExperimental.yaml:

LayoutTests:

Add tests for the new CustomEffect interface and the document.timeline.animate() method.
These are written using WPT libraries such that they may be upstreamed to the WPT repository
in the future if and when the CustomEffect interface is standardized.

* platform/win/TestExpectations:
* webanimations/custom-effect/custom-effect-expected.txt: Added.
* webanimations/custom-effect/custom-effect.html: Added.
* webanimations/custom-effect/document-timeline-animate-expected.txt: Added.
* webanimations/custom-effect/document-timeline-animate.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformwinTestExpectations">trunk/LayoutTests/platform/win/TestExpectations</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFScriptsPreferencesWebPreferencesExperimentalyaml">trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesinputxcfilelist">trunk/Source/WebCore/DerivedSources-input.xcfilelist</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesoutputxcfilelist">trunk/Source/WebCore/DerivedSources-output.xcfilelist</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesmake">trunk/Source/WebCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebCoreHeaderscmake">trunk/Source/WebCore/Headers.cmake</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreanimationAnimationEffecth">trunk/Source/WebCore/animation/AnimationEffect.h</a></li>
<li><a href="#trunkSourceWebCoreanimationDocumentTimelinecpp">trunk/Source/WebCore/animation/DocumentTimeline.cpp</a></li>
<li><a href="#trunkSourceWebCoreanimationDocumentTimelineh">trunk/Source/WebCore/animation/DocumentTimeline.h</a></li>
<li><a href="#trunkSourceWebCoreanimationDocumentTimelineidl">trunk/Source/WebCore/animation/DocumentTimeline.idl</a></li>
<li><a href="#trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh">trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/webanimations/custom-effect/</li>
<li><a href="#trunkLayoutTestswebanimationscustomeffectcustomeffectexpectedtxt">trunk/LayoutTests/webanimations/custom-effect/custom-effect-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebanimationscustomeffectcustomeffecthtml">trunk/LayoutTests/webanimations/custom-effect/custom-effect.html</a></li>
<li><a href="#trunkLayoutTestswebanimationscustomeffectdocumenttimelineanimateexpectedtxt">trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebanimationscustomeffectdocumenttimelineanimatehtml">trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate.html</a></li>
<li><a href="#trunkSourceWebCoreanimationCustomAnimationOptionsh">trunk/Source/WebCore/animation/CustomAnimationOptions.h</a></li>
<li><a href="#trunkSourceWebCoreanimationCustomAnimationOptionsidl">trunk/Source/WebCore/animation/CustomAnimationOptions.idl</a></li>
<li><a href="#trunkSourceWebCoreanimationCustomEffectcpp">trunk/Source/WebCore/animation/CustomEffect.cpp</a></li>
<li><a href="#trunkSourceWebCoreanimationCustomEffecth">trunk/Source/WebCore/animation/CustomEffect.h</a></li>
<li><a href="#trunkSourceWebCoreanimationCustomEffectidl">trunk/Source/WebCore/animation/CustomEffect.idl</a></li>
<li><a href="#trunkSourceWebCoreanimationCustomEffectCallbackh">trunk/Source/WebCore/animation/CustomEffectCallback.h</a></li>
<li><a href="#trunkSourceWebCoreanimationCustomEffectCallbackidl">trunk/Source/WebCore/animation/CustomEffectCallback.idl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/LayoutTests/ChangeLog 2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2021-12-06  Antoine Quint  <graouts@webkit.org>
+
+        [Web Animations] Add a way to run scripted animations
+        https://bugs.webkit.org/show_bug.cgi?id=233869
+        rdar://85983542
+
+        Reviewed by Dean Jackson.
+
+        Add tests for the new CustomEffect interface and the document.timeline.animate() method.
+        These are written using WPT libraries such that they may be upstreamed to the WPT repository
+        in the future if and when the CustomEffect interface is standardized.
+
+        * platform/win/TestExpectations:
+        * webanimations/custom-effect/custom-effect-expected.txt: Added.
+        * webanimations/custom-effect/custom-effect.html: Added.
+        * webanimations/custom-effect/document-timeline-animate-expected.txt: Added.
+        * webanimations/custom-effect/document-timeline-animate.html: Added.
+
</ins><span class="cx"> 2021-12-06  Rob Buis  <rbuis@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         Null check in shouldUseBreakElement
</span></span></pre></div>
<a id="trunkLayoutTestsplatformwinTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/win/TestExpectations (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/win/TestExpectations  2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/LayoutTests/platform/win/TestExpectations     2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -4760,3 +4760,5 @@
</span><span class="cx"> webkit.org/b/232321 imported/mozilla/svg/viewBox-and-pattern-03.svg [ Pass Crash ]
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/232703 webanimations/no-style-updates-for-animated-sibling-elements-accelerated.html [ Failure ]
</span><ins>+
+webkit.org/b/233887 webanimations/custom-effect [ Failure ]
</ins></span></pre></div>
<a id="trunkLayoutTestswebanimationscustomeffectcustomeffectexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webanimations/custom-effect/custom-effect-expected.txt (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webanimations/custom-effect/custom-effect-expected.txt                         (rev 0)
+++ trunk/LayoutTests/webanimations/custom-effect/custom-effect-expected.txt    2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+
+PASS Custom effects with no fill do not fire with progress = 1.
+PASS Forward-filling custom effects fire once with progress = 1.
+PASS Backward-filling custom effects fire only once with progress = 0 during the before phase.
+PASS Custom effects are called when the associated animatoun is paused and seeked.
+PASS Custom effects fire callbacks with no other reason to update the page rendering.
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebanimationscustomeffectcustomeffecthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webanimations/custom-effect/custom-effect.html (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webanimations/custom-effect/custom-effect.html                         (rev 0)
+++ trunk/LayoutTests/webanimations/custom-effect/custom-effect.html    2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+<!doctype html>
+<meta charset=utf-8>
+<title>CustomEffect</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../imported/w3c/web-platform-tests/web-animations/testcommon.js"></script>
+<body>
+<script>
+'use strict';
+
+promise_test(async t => {
+    let numberOfCalls = 0;
+    let customEffectProgress = null;
+
+    const animation = document.timeline.animate(progress => {
+        customEffectProgress = progress;
+        numberOfCalls++;
+    }, { duration: 1 });
+
+    assert_equals(customEffectProgress, null, "Callback does not fire upon creation.");
+
+    await waitForAnimationFrames(1);
+    assert_equals(customEffectProgress, 0, "Callback is first fired with progress = 0.");
+
+    await animation.finished;
+    const numberOfCallsAfterEffectEnded = numberOfCalls;
+
+    await waitForAnimationFrames(1);
+    assert_equals(numberOfCallsAfterEffectEnded, numberOfCalls, "Callback is no longer fired after custom effect entered the after phase.");
+    assert_not_equals(customEffectProgress, 1, "Callback is first fired with progress = 1.");
+}, "Custom effects with no fill do not fire with progress = 1.");
+
+promise_test(async t => {
+    let numberOfCalls = 0;
+    let customEffectProgress = null;
+
+    const animation = document.timeline.animate(progress => {
+        customEffectProgress = progress;
+        numberOfCalls++;
+    }, { fill: "forwards", duration: 1});
+
+    assert_equals(customEffectProgress, null, "Callback does not fire upon creation.");
+
+    await animation.finished;
+    assert_equals(customEffectProgress, 1, "Callback is finally fired with progress = 1.");
+
+    const numberOfCallsAfterEffectEnded = numberOfCalls;
+
+    await waitForAnimationFrames(1);
+    assert_equals(numberOfCallsAfterEffectEnded, numberOfCalls, "Callback is no longer fired after custom effect entered the after phase.");
+}, "Forward-filling custom effects fire once with progress = 1.");
+
+promise_test(async t => {
+    let numberOfCalls = 0;
+    let customEffectProgress = null;
+
+    // Create an animation that won't start until long into the future.
+    const animation = new Animation;
+    animation.startTime = document.timeline.currentTime + (100 * 1000);
+    animation.effect = new CustomEffect(progress => {
+        customEffectProgress = progress;
+        numberOfCalls++;
+    }, { fill: "backwards", duration: 1});
+
+    assert_equals(customEffectProgress, null, "Callback does not fire upon creation.");
+
+    await waitForAnimationFrames(1);
+    assert_equals(customEffectProgress, 0, "Callback is first fired with progress = 0.");
+
+    await waitForAnimationFrames(1);
+    assert_equals(numberOfCalls, 1, "Callback is not fired after the first frame as it's still in the before phase and its progress hasn't changed.");
+}, "Backward-filling custom effects fire only once with progress = 0 during the before phase.");
+
+promise_test(async t => {
+    let numberOfCalls = 0;
+    let customEffectProgress = null;
+
+    const duration = 1000;
+    const animation = document.timeline.animate(progress => {
+        customEffectProgress = progress;
+        numberOfCalls++;
+    }, duration);
+
+    animation.pause();
+    assert_equals(customEffectProgress, null, "Callback does not fire upon creation.");
+
+    await waitForAnimationFrames(1);
+    assert_equals(customEffectProgress, 0, "Callback is first fired with progress = 0.");
+
+    await waitForAnimationFrames(1);
+    assert_equals(numberOfCalls, 1, "Callback is not called while animation is paused.");
+
+    animation.currentTime = animation.startTime + (duration * 0.2);
+    animation.currentTime = animation.startTime + (duration * 0.1);
+
+    await waitForAnimationFrames(1);
+    assert_equals(numberOfCalls, 2, "Callback is only called once if changing the current time several times between frames.");
+    assert_equals(customEffectProgress, 0.1, "Callback is called with the update progress when seeking the animation.");
+}, "Custom effects are called when the associated animatoun is paused and seeked.");
+
+promise_test(async t => {
+    await new Promise(resolve => {
+        document.timeline.animate(progress => resolve(), 100 * 1000);
+    });
+}, "Custom effects fire callbacks with no other reason to update the page rendering.");
+
+</script>
+</body>
</ins></span></pre></div>
<a id="trunkLayoutTestswebanimationscustomeffectdocumenttimelineanimateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate-expected.txt (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate-expected.txt                             (rev 0)
+++ trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate-expected.txt        2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+
+PASS document.timeline.animate() allows to set the animation's id.
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebanimationscustomeffectdocumenttimelineanimatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate.html (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate.html                             (rev 0)
+++ trunk/LayoutTests/webanimations/custom-effect/document-timeline-animate.html        2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+<!doctype html>
+<meta charset=utf-8>
+<title>CustomEffect</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<body>
+<script>
+'use strict';
+
+test(t => {
+    const id = "custom-animation-id";
+    const animation = document.timeline.animate(progress => { }, { duration: 1, id });
+    assert_equals(animation.id, id);
+}, "document.timeline.animate() allows to set the animation's id.");
+
+</script>
+</body>
</ins></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog       2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WTF/ChangeLog  2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2021-12-06  Antoine Quint  <graouts@webkit.org>
+
+        [Web Animations] Add a way to run scripted animations
+        https://bugs.webkit.org/show_bug.cgi?id=233869
+        rdar://85983542
+
+        Reviewed by Dean Jackson.
+
+        Add a new experimental feature for the CustomEffect interface.
+
+        * Scripts/Preferences/WebPreferencesExperimental.yaml:
+
</ins><span class="cx"> 2021-12-06  Jon Lee  <jonlee@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Update GPU Process feature flags
</span></span></pre></div>
<a id="trunkSourceWTFScriptsPreferencesWebPreferencesExperimentalyaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml     2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml        2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -1471,6 +1471,19 @@
</span><span class="cx">     WebCore:
</span><span class="cx">       default: false
</span><span class="cx"> 
</span><ins>+WebAnimationsCustomEffectsEnabled:
+  type: bool
+  humanReadableName: "Web Animations custom effects"
+  humanReadableDescription: "Support for the CustomEffect interface"
+  defaultValue:
+    WebKitLegacy:
+      default: false
+    WebKit:
+      "ENABLE(EXPERIMENTAL_FEATURES)" : true
+      default: false
+    WebCore:
+      default: false
+
</ins><span class="cx"> # FIXME: This is enabled when ENABLE(EXPERIMENTAL_FEATURES) is true in WebKit2. Perhaps we should consider using that for WebKitLegacy as well.
</span><span class="cx"> WebAnimationsMutableTimelinesEnabled:
</span><span class="cx">   type: bool
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt      2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/CMakeLists.txt 2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -679,7 +679,6 @@
</span><span class="cx">     animation/Animatable.idl
</span><span class="cx">     animation/AnimationEffect.idl
</span><span class="cx">     animation/AnimationFrameProvider.idl
</span><del>-    animation/EffectTiming.idl
</del><span class="cx">     animation/AnimationPlaybackEvent.idl
</span><span class="cx">     animation/AnimationPlaybackEventInit.idl
</span><span class="cx">     animation/AnimationTimeline.idl
</span><span class="lines">@@ -688,10 +687,14 @@
</span><span class="cx">     animation/CompositeOperation.idl
</span><span class="cx">     animation/CompositeOperationOrAuto.idl
</span><span class="cx">     animation/ComputedEffectTiming.idl
</span><ins>+    animation/CustomAnimationOptions.idl
+    animation/CustomEffect.idl
+    animation/CustomEffectCallback.idl
</ins><span class="cx">     animation/Document+WebAnimations.idl
</span><span class="cx">     animation/DocumentOrShadowRoot+WebAnimations.idl
</span><span class="cx">     animation/DocumentTimeline.idl
</span><span class="cx">     animation/DocumentTimelineOptions.idl
</span><ins>+    animation/EffectTiming.idl
</ins><span class="cx">     animation/FillMode.idl
</span><span class="cx">     animation/GetAnimationsOptions.idl
</span><span class="cx">     animation/GlobalEventHandlers+CSSAnimations.idl
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/ChangeLog      2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -1,3 +1,69 @@
</span><ins>+2021-12-06  Antoine Quint  <graouts@webkit.org>
+
+        [Web Animations] Add a way to run scripted animations
+        https://bugs.webkit.org/show_bug.cgi?id=233869
+        rdar://85983542
+
+        Reviewed by Dean Jackson.
+
+        Tests: webanimations/custom-effect/custom-effect.html
+               webanimations/custom-effect/document-timeline-animate.html
+
+        This patch adds two new Web-exposed features to allow authors to write callback-based animations
+        leveraging the full power of the Web Animations model.
+
+        First, we add a new AnimationEffect subclass which wraps a callback to be executed on every tick
+        of the associated animation's timeline: CustomEffect. It can be constructed by providing a JS function
+        as its first parameter, and either a number or a dictionary to provide timing properties for the effect.
+        This is similar to how KeyframeEffect will accept a keyframes object and then timing data. The callback
+        is provided the effect progress as its sole parameter. Web authors can use this new interface as follows:
+
+            const animation = new Animation;
+            animation.effect = new CustomEffect(progress => { … }, 1000);
+            animation.play();
+
+        Second, to make starting callback-based animations more straightforward and in a very similar fashion
+        to how keyframe animations can be initiated on an element using Element.animate(), we introduce a new
+        animate() method on DocumentTimeline, allowing the previous exmaple to be written as:
+
+            const animation = document.timeline.animate(progress => { … }, 1000);
+
+        This simple approach allows Web authors to move past the simple use of requestAnimationFrame() and harness
+        the Web Animations timing model which will let them pause and resume animations, seek them, control their
+        playback rate, apply easing, respond to the "finished" promise, etc.
+
+        The code itself is very simple, CustomEffect is simply an AnimationEffect subclass that indicates that it's
+        always interested in scheduling updates while active using the ticksContinouslyWhileActive() method. This
+        means that all the scheduling logic contained in WebAnimation and AnimationEffect applies, allowing callbacks
+        to not be fired when the animation is paused or when the page is suspended, or fired sparingly when a steps()
+        timing function is specified.
+
+        * CMakeLists.txt:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * Headers.cmake:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * animation/AnimationEffect.h:
+        (WebCore::AnimationEffect::isCustomEffect const):
+        * animation/CustomAnimationOptions.h: Added.
+        * animation/CustomAnimationOptions.idl: Added.
+        * animation/CustomEffect.cpp: Added.
+        (WebCore::CustomEffect::create):
+        (WebCore::CustomEffect::CustomEffect):
+        (WebCore::CustomEffect::animationDidTick):
+        * animation/CustomEffect.h: Added.
+        (WebCore::CustomEffect::~CustomEffect):
+        * animation/CustomEffect.idl: Added.
+        * animation/CustomEffectCallback.h: Added.
+        * animation/CustomEffectCallback.idl: Added.
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::animate):
+        * animation/DocumentTimeline.h:
+        * animation/DocumentTimeline.idl:
+        * bindings/js/WebCoreBuiltinNames.h:
+
</ins><span class="cx"> 2021-12-06  Rob Buis  <rbuis@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         Null check in shouldUseBreakElement
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesinputxcfilelist"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources-input.xcfilelist (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources-input.xcfilelist     2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/DerivedSources-input.xcfilelist        2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -814,6 +814,9 @@
</span><span class="cx"> $(PROJECT_DIR)/animation/CompositeOperation.idl
</span><span class="cx"> $(PROJECT_DIR)/animation/CompositeOperationOrAuto.idl
</span><span class="cx"> $(PROJECT_DIR)/animation/ComputedEffectTiming.idl
</span><ins>+$(PROJECT_DIR)/animation/CustomAnimationOptions.idl
+$(PROJECT_DIR)/animation/CustomEffect.idl
+$(PROJECT_DIR)/animation/CustomEffectCallback.idl
</ins><span class="cx"> $(PROJECT_DIR)/animation/Document+WebAnimations.idl
</span><span class="cx"> $(PROJECT_DIR)/animation/DocumentOrShadowRoot+WebAnimations.idl
</span><span class="cx"> $(PROJECT_DIR)/animation/DocumentTimeline.idl
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesoutputxcfilelist"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources-output.xcfilelist (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources-output.xcfilelist    2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/DerivedSources-output.xcfilelist       2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -530,6 +530,12 @@
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCryptoRsaHashedKeyAlgorithm.h
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCryptoRsaKeyAlgorithm.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCryptoRsaKeyAlgorithm.h
</span><ins>+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomAnimationOptions.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomAnimationOptions.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomEffect.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomEffect.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomEffectCallback.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomEffectCallback.h
</ins><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomElementRegistry.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomElementRegistry.h
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCustomEvent.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources.make (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources.make 2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/DerivedSources.make    2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -703,6 +703,9 @@
</span><span class="cx">     $(WebCore)/animation/CompositeOperation.idl \
</span><span class="cx">     $(WebCore)/animation/CompositeOperationOrAuto.idl \
</span><span class="cx">     $(WebCore)/animation/ComputedEffectTiming.idl \
</span><ins>+    $(WebCore)/animation/CustomAnimationOptions.idl \
+    $(WebCore)/animation/CustomEffect.idl \
+    $(WebCore)/animation/CustomEffectCallback.idl \
</ins><span class="cx">     $(WebCore)/animation/Document+WebAnimations.idl \
</span><span class="cx">     $(WebCore)/animation/DocumentOrShadowRoot+WebAnimations.idl \
</span><span class="cx">     $(WebCore)/animation/DocumentTimeline.idl \
</span></span></pre></div>
<a id="trunkSourceWebCoreHeaderscmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Headers.cmake (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Headers.cmake       2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/Headers.cmake  2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -384,6 +384,7 @@
</span><span class="cx">     accessibility/isolatedtree/AXIsolatedTree.h
</span><span class="cx"> 
</span><span class="cx">     animation/CSSPropertyBlendingClient.h
</span><ins>+    animation/CustomAnimationOptions.h
</ins><span class="cx">     animation/CompositeOperation.h
</span><span class="cx">     animation/DocumentTimelinesController.h
</span><span class="cx">     animation/EffectTiming.h
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/Sources.txt    2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -469,6 +469,7 @@
</span><span class="cx"> animation/CSSAnimation.cpp
</span><span class="cx"> animation/CSSPropertyAnimation.cpp
</span><span class="cx"> animation/CSSTransition.cpp
</span><ins>+animation/CustomEffect.cpp
</ins><span class="cx"> animation/DeclarativeAnimation.cpp
</span><span class="cx"> animation/DocumentTimeline.cpp
</span><span class="cx"> animation/DocumentTimelinesController.cpp
</span><span class="lines">@@ -3005,6 +3006,9 @@
</span><span class="cx"> JSCryptoKeyUsage.cpp
</span><span class="cx"> JSCryptoRsaHashedKeyAlgorithm.cpp
</span><span class="cx"> JSCryptoRsaKeyAlgorithm.cpp
</span><ins>+JSCustomAnimationOptions.cpp
+JSCustomEffect.cpp
+JSCustomEffectCallback.cpp
</ins><span class="cx"> JSCustomElementRegistry.cpp
</span><span class="cx"> JSCustomEvent.cpp
</span><span class="cx"> JSDOMApplicationCache.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -2279,6 +2279,9 @@
</span><span class="cx">          715AD7212050513F00D592DC /* CSSTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 7123C186204739BA00789392 /* CSSTransition.h */; };
</span><span class="cx">          71729F7B20F3BA4900801CE6 /* DocumentTimelineOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 71729F7A20F3BA3A00801CE6 /* DocumentTimelineOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          71729F7E20F3BB4700801CE6 /* JSDocumentTimelineOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 71729F7C20F3BAB900801CE6 /* JSDocumentTimelineOptions.h */; };
</span><ins>+               7173694A275E0B5E003ADA9B /* CustomEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A74B082759293600DE80BA /* CustomEffect.h */; };
+               7173694B275E0B6A003ADA9B /* CustomEffectCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A74B0A27592B3500DE80BA /* CustomEffectCallback.h */; };
+               7173694C275E0BAB003ADA9B /* CustomAnimationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 71736947275E0B4B003ADA9B /* CustomAnimationOptions.h */; };
</ins><span class="cx">           7177AD57274295D1002F103B /* HTMLModelElementCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 7177AD5627429590002F103B /* HTMLModelElementCamera.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          7181A16C244F0F40007D8A24 /* DocumentTimelinesController.h in Headers */ = {isa = PBXBuildFile; fileRef = 7181A169244F0F2C007D8A24 /* DocumentTimelinesController.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          71A1B6081DEE5AD70073BCFB /* modern-media-controls-localized-strings.js in Resources */ = {isa = PBXBuildFile; fileRef = 71A1B6061DEE5A820073BCFB /* modern-media-controls-localized-strings.js */; };
</span><span class="lines">@@ -11076,6 +11079,8 @@
</span><span class="cx">          71729F7A20F3BA3A00801CE6 /* DocumentTimelineOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentTimelineOptions.h; sourceTree = "<group>"; };
</span><span class="cx">          71729F7C20F3BAB900801CE6 /* JSDocumentTimelineOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDocumentTimelineOptions.h; sourceTree = "<group>"; };
</span><span class="cx">          71729F7D20F3BABA00801CE6 /* JSDocumentTimelineOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDocumentTimelineOptions.cpp; sourceTree = "<group>"; };
</span><ins>+               71736947275E0B4B003ADA9B /* CustomAnimationOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomAnimationOptions.h; sourceTree = "<group>"; };
+               71736949275E0B4C003ADA9B /* CustomAnimationOptions.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CustomAnimationOptions.idl; sourceTree = "<group>"; };
</ins><span class="cx">           7173DEBD2614DF040097DF32 /* Styleable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Styleable.cpp; sourceTree = "<group>"; };
</span><span class="cx">          7177AD542742952F002F103B /* HTMLModelElementCamera.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLModelElementCamera.idl; sourceTree = "<group>"; };
</span><span class="cx">          7177AD5627429590002F103B /* HTMLModelElementCamera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLModelElementCamera.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -11112,6 +11117,11 @@
</span><span class="cx">          71A57DF0154BE25C0009D120 /* SVGPathUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathUtilities.h; sourceTree = "<group>"; };
</span><span class="cx">          71A58193236F466400D81A24 /* KeyframeEffectStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyframeEffectStack.h; sourceTree = "<group>"; };
</span><span class="cx">          71A58195236F466500D81A24 /* KeyframeEffectStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyframeEffectStack.cpp; sourceTree = "<group>"; };
</span><ins>+               71A74B052759293600DE80BA /* CustomEffect.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CustomEffect.idl; sourceTree = "<group>"; };
+               71A74B072759293600DE80BA /* CustomEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomEffect.cpp; sourceTree = "<group>"; };
+               71A74B082759293600DE80BA /* CustomEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomEffect.h; sourceTree = "<group>"; };
+               71A74B0927592A5300DE80BA /* CustomEffectCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CustomEffectCallback.idl; sourceTree = "<group>"; };
+               71A74B0A27592B3500DE80BA /* CustomEffectCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomEffectCallback.h; sourceTree = "<group>"; };
</ins><span class="cx">           71AEE4EB21B5A49C00DDB036 /* TouchAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TouchAction.h; sourceTree = "<group>"; };
</span><span class="cx">          71B0460A1DD3C2EE00EE19CF /* status-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "status-support.js"; sourceTree = "<group>"; };
</span><span class="cx">          71B28424203CEC0B0036AA5D /* JSCSSAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCSSAnimation.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -24257,6 +24267,13 @@
</span><span class="cx">                          7123C187204739BB00789392 /* CSSTransition.cpp */,
</span><span class="cx">                          7123C186204739BA00789392 /* CSSTransition.h */,
</span><span class="cx">                          7123C185204739B900789392 /* CSSTransition.idl */,
</span><ins>+                               71736947275E0B4B003ADA9B /* CustomAnimationOptions.h */,
+                               71736949275E0B4C003ADA9B /* CustomAnimationOptions.idl */,
+                               71A74B072759293600DE80BA /* CustomEffect.cpp */,
+                               71A74B082759293600DE80BA /* CustomEffect.h */,
+                               71A74B052759293600DE80BA /* CustomEffect.idl */,
+                               71A74B0A27592B3500DE80BA /* CustomEffectCallback.h */,
+                               71A74B0927592A5300DE80BA /* CustomEffectCallback.idl */,
</ins><span class="cx">                           715AD71F2050512400D592DC /* DeclarativeAnimation.cpp */,
</span><span class="cx">                          715AD71D2050512400D592DC /* DeclarativeAnimation.h */,
</span><span class="cx">                          7C3A8AC02509A602008C477F /* Document+WebAnimations.idl */,
</span><span class="lines">@@ -33808,6 +33825,9 @@
</span><span class="cx">                          93F1992F08245E59001E9ABC /* Cursor.h in Headers */,
</span><span class="cx">                          BC2272A20E82E87C00E7F975 /* CursorData.h in Headers */,
</span><span class="cx">                          BC2272AD0E82E8F300E7F975 /* CursorList.h in Headers */,
</span><ins>+                               7173694C275E0BAB003ADA9B /* CustomAnimationOptions.h in Headers */,
+                               7173694A275E0B5E003ADA9B /* CustomEffect.h in Headers */,
+                               7173694B275E0B6A003ADA9B /* CustomEffectCallback.h in Headers */,
</ins><span class="cx">                           93D437A01D57B19A00AB85EA /* CustomElementReactionQueue.h in Headers */,
</span><span class="cx">                          9BD4E91B1C462CFC005065BC /* CustomElementRegistry.h in Headers */,
</span><span class="cx">                          62CD325A1157E57C0063B0A7 /* CustomEvent.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCoreanimationAnimationEffecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/animation/AnimationEffect.h (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/AnimationEffect.h 2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/animation/AnimationEffect.h    2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual ~AnimationEffect();
</span><span class="cx"> 
</span><ins>+    virtual bool isCustomEffect() const { return false; }
</ins><span class="cx">     virtual bool isKeyframeEffect() const { return false; }
</span><span class="cx"> 
</span><span class="cx">     EffectTiming getBindingsTiming() const;
</span></span></pre></div>
<a id="trunkSourceWebCoreanimationCustomAnimationOptionshfromrev286554trunkSourceWebCoreanimationDocumentTimelineidl"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/animation/CustomAnimationOptions.h (from rev 286554, trunk/Source/WebCore/animation/DocumentTimeline.idl) (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/CustomAnimationOptions.h                          (rev 0)
+++ trunk/Source/WebCore/animation/CustomAnimationOptions.h     2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "EffectTiming.h"
+
+namespace WebCore {
+
+struct CustomAnimationOptions : EffectTiming {
+    String id;
+};
+
+} // namespace WebCore
+
</ins></span></pre></div>
<a id="trunkSourceWebCoreanimationCustomAnimationOptionsidlfromrev286554trunkSourceWebCoreanimationDocumentTimelineidl"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/animation/CustomAnimationOptions.idl (from rev 286554, trunk/Source/WebCore/animation/DocumentTimeline.idl) (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/CustomAnimationOptions.idl                                (rev 0)
+++ trunk/Source/WebCore/animation/CustomAnimationOptions.idl   2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+dictionary CustomAnimationOptions : EffectTiming {
+    DOMString id = "";
+};
+
</ins></span></pre></div>
<a id="trunkSourceWebCoreanimationCustomEffectcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/animation/CustomEffect.cpp (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/CustomEffect.cpp                          (rev 0)
+++ trunk/Source/WebCore/animation/CustomEffect.cpp     2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CustomEffect.h"
+
+#include "CustomEffectCallback.h"
+#include <JavaScriptCore/Exception.h>
+
+namespace WebCore {
+using namespace JSC;
+
+ExceptionOr<Ref<CustomEffect>> CustomEffect::create(Ref<CustomEffectCallback>&& callback, std::optional<std::variant<double, EffectTiming>>&& options)
+{
+    auto customEffect = adoptRef(*new CustomEffect(WTFMove(callback)));
+
+    if (options) {
+        OptionalEffectTiming timing;
+        auto optionsValue = options.value();
+        if (std::holds_alternative<double>(optionsValue)) {
+            std::variant<double, String> duration = std::get<double>(optionsValue);
+            timing.duration = duration;
+        } else {
+            auto effectTimingOptions = std::get<EffectTiming>(optionsValue);
+
+            timing = {
+                effectTimingOptions.duration,
+                effectTimingOptions.iterations,
+                effectTimingOptions.delay,
+                effectTimingOptions.endDelay,
+                effectTimingOptions.iterationStart,
+                effectTimingOptions.easing,
+                effectTimingOptions.fill,
+                effectTimingOptions.direction
+            };
+        }
+        auto updateTimingResult = customEffect->updateTiming(timing);
+        if (updateTimingResult.hasException())
+            return updateTimingResult.releaseException();
+    }
+
+    return customEffect;
+}
+
+CustomEffect::CustomEffect(Ref<CustomEffectCallback>&& callback)
+    : m_callback(WTFMove(callback))
+{
+}
+
+void CustomEffect::animationDidTick()
+{
+    auto computedTiming = getComputedTiming();
+    if (!computedTiming.progress)
+        return;
+
+    m_callback->handleEvent(*computedTiming.progress);
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreanimationCustomEffecthfromrev286554trunkSourceWebCoreanimationDocumentTimelineidl"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/animation/CustomEffect.h (from rev 286554, trunk/Source/WebCore/animation/DocumentTimeline.idl) (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/CustomEffect.h                            (rev 0)
+++ trunk/Source/WebCore/animation/CustomEffect.h       2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "AnimationEffect.h"
+#include "CustomEffectCallback.h"
+#include "EffectTiming.h"
+#include <wtf/Ref.h>
+
+namespace WebCore {
+
+class CustomEffect : public AnimationEffect {
+public:
+    static ExceptionOr<Ref<CustomEffect>> create(Ref<CustomEffectCallback>&&, std::optional<std::variant<double, EffectTiming>>&&);
+    ~CustomEffect() { }
+
+private:
+    CustomEffect(Ref<CustomEffectCallback>&&);
+
+    // AnimationEffect
+    bool isCustomEffect() const final { return true; }
+    void animationDidTick() final;
+    bool ticksContinouslyWhileActive() const final { return true; }
+
+    Ref<CustomEffectCallback> m_callback;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_ANIMATION_EFFECT(CustomEffect, isCustomEffect());
</ins></span></pre></div>
<a id="trunkSourceWebCoreanimationCustomEffectidlfromrev286554trunkSourceWebCoreanimationDocumentTimelineidl"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/animation/CustomEffect.idl (from rev 286554, trunk/Source/WebCore/animation/DocumentTimeline.idl) (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/CustomEffect.idl                          (rev 0)
+++ trunk/Source/WebCore/animation/CustomEffect.idl     2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    EnabledBySetting=WebAnimationsCustomEffectsEnabled,
+    Exposed=Window,
+    JSGenerateToNativeObject,
+] interface CustomEffect : AnimationEffect {
+    constructor(CustomEffectCallback callback, optional (unrestricted double or EffectTiming) options);
+};
</ins></span></pre></div>
<a id="trunkSourceWebCoreanimationCustomEffectCallbackhfromrev286554trunkSourceWebCoreanimationDocumentTimelineidl"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/animation/CustomEffectCallback.h (from rev 286554, trunk/Source/WebCore/animation/DocumentTimeline.idl) (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/CustomEffectCallback.h                            (rev 0)
+++ trunk/Source/WebCore/animation/CustomEffectCallback.h       2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ActiveDOMCallback.h"
+#include "CallbackResult.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Seconds.h>
+
+namespace WebCore {
+
+class CustomEffectCallback : public RefCounted<CustomEffectCallback>, public ActiveDOMCallback {
+public:
+    using ActiveDOMCallback::ActiveDOMCallback;
+
+    virtual CallbackResult<void> handleEvent(double progress) = 0;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreanimationCustomEffectCallbackidlfromrev286554trunkSourceWebCoreanimationDocumentTimelineidl"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/animation/CustomEffectCallback.idl (from rev 286554, trunk/Source/WebCore/animation/DocumentTimeline.idl) (0 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/CustomEffectCallback.idl                          (rev 0)
+++ trunk/Source/WebCore/animation/CustomEffectCallback.idl     2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+callback CustomEffectCallback = undefined (double progress);
</ins></span></pre></div>
<a id="trunkSourceWebCoreanimationDocumentTimelinecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/DocumentTimeline.cpp      2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp 2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -28,6 +28,9 @@
</span><span class="cx"> 
</span><span class="cx"> #include "AnimationEventBase.h"
</span><span class="cx"> #include "CSSTransition.h"
</span><ins>+#include "CustomAnimationOptions.h"
+#include "CustomEffect.h"
+#include "CustomEffectCallback.h"
</ins><span class="cx"> #include "DeclarativeAnimation.h"
</span><span class="cx"> #include "Document.h"
</span><span class="cx"> #include "DocumentTimelinesController.h"
</span><span class="lines">@@ -494,4 +497,37 @@
</span><span class="cx">     return m_numberOfAnimationTimelineInvalidationsForTesting;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ExceptionOr<Ref<WebAnimation>> DocumentTimeline::animate(Ref<CustomEffectCallback>&& callback, std::optional<std::variant<double, CustomAnimationOptions>>&& options)
+{
+    ASSERT(m_document);
+
+    String id = "";
+    std::optional<std::variant<double, EffectTiming>> customEffectOptions;
+
+    if (options) {
+        std::variant<double, EffectTiming> customEffectOptionsVariant;
+        if (std::holds_alternative<double>(*options))
+            customEffectOptionsVariant = std::get<double>(*options);
+        else {
+            auto customEffectOptions = std::get<CustomAnimationOptions>(*options);
+            id = customEffectOptions.id;
+            customEffectOptionsVariant = WTFMove(customEffectOptions);
+        }
+        customEffectOptions = customEffectOptionsVariant;
+    }
+
+    auto customEffectResult = CustomEffect::create(WTFMove(callback), WTFMove(customEffectOptions));
+    if (customEffectResult.hasException())
+        return customEffectResult.releaseException();
+
+    auto animation = WebAnimation::create(*document(), &customEffectResult.returnValue().get());
+    animation->setId(id);
+
+    auto animationPlayResult = animation->play();
+    if (animationPlayResult.hasException())
+        return animationPlayResult.releaseException();
+
+    return animation;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreanimationDocumentTimelineh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/DocumentTimeline.h        2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h   2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -34,10 +34,13 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class AnimationEventBase;
</span><ins>+class CustomEffectCallback;
</ins><span class="cx"> class DocumentTimelinesController;
</span><span class="cx"> class RenderBoxModelObject;
</span><span class="cx"> class RenderElement;
</span><span class="cx"> 
</span><ins>+struct CustomAnimationOptions;
+
</ins><span class="cx"> class DocumentTimeline final : public AnimationTimeline
</span><span class="cx"> {
</span><span class="cx"> public:
</span><span class="lines">@@ -50,6 +53,7 @@
</span><span class="cx">     Document* document() const { return m_document.get(); }
</span><span class="cx"> 
</span><span class="cx">     std::optional<Seconds> currentTime() override;
</span><ins>+    ExceptionOr<Ref<WebAnimation>> animate(Ref<CustomEffectCallback>&&, std::optional<std::variant<double, CustomAnimationOptions>>&&);
</ins><span class="cx"> 
</span><span class="cx">     void animationTimingDidChange(WebAnimation&) override;
</span><span class="cx">     void removeAnimation(WebAnimation&) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreanimationDocumentTimelineidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/animation/DocumentTimeline.idl (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/DocumentTimeline.idl      2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/animation/DocumentTimeline.idl 2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -27,4 +27,5 @@
</span><span class="cx">     Exposed=Window
</span><span class="cx"> ] interface DocumentTimeline : AnimationTimeline {
</span><span class="cx">     [CallWith=Document] constructor(optional DocumentTimelineOptions options);
</span><ins>+    [EnabledBySetting=WebAnimationsCustomEffectsEnabled] WebAnimation animate(CustomEffectCallback callback, optional (unrestricted double or CustomAnimationOptions) options);
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (286554 => 286555)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h   2021-12-06 19:22:54 UTC (rev 286554)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h      2021-12-06 19:30:57 UTC (rev 286555)
</span><span class="lines">@@ -106,6 +106,7 @@
</span><span class="cx">     macro(CSSUnparsedValue) \
</span><span class="cx">     macro(CSSVariableReferenceValue) \
</span><span class="cx">     macro(CustomElementRegistry) \
</span><ins>+    macro(CustomEffect) \
</ins><span class="cx">     macro(Database) \
</span><span class="cx">     macro(DataTransferItem) \
</span><span class="cx">     macro(DataTransferItemList) \
</span></span></pre>
</div>
</div>

</body>
</html>