--- a/browser/components/extensions/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -1,11 +1,12 @@
[DEFAULT]
prefs =
dom.animations-api.core.enabled=true
+ dom.animations-api.timelines.enabled=true
support-files =
head.js
head_pageAction.js
head_sessions.js
head_webNavigation.js
context.html
context_frame.html
ctxmenu-image.png
--- a/browser/components/resistfingerprinting/test/mochitest/test_animation_api.html
+++ b/browser/components/resistfingerprinting/test/mochitest/test_animation_api.html
@@ -33,17 +33,17 @@ https://bugzilla.mozilla.org/show_bug.cg
expectedPrecision = ep;
resistFingerprinting = rfp;
reduceTimerPrecision = rtp;
prefName = "";
prefName += resistFingerprinting ? "privacy.resistFingerprinting " : "";
prefName += reduceTimerPrecision ? "privacy.reduceTimerPrecision " : "";
SpecialPowers.pushPrefEnv({"set":
[
- ["dom.animations-api.core.enabled", true],
+ ["dom.animations-api.timelines.enabled", true],
["privacy.resistFingerprinting", resistFingerprinting],
["privacy.reduceTimerPrecision", reduceTimerPrecision],
["privacy.resistFingerprinting.reduceTimerPrecision.microseconds", expectedPrecision]
]
}, runTest);
}
--- a/devtools/client/inspector/animation-old/test/head.js
+++ b/devtools/client/inspector/animation-old/test/head.js
@@ -38,16 +38,17 @@ registerCleanupFunction(() => {
// Some animation features are not enabled by default in release/beta channels
// yet including:
// * parts of the Web Animations API (Bug 1264101), and
// * the frames() timing function (Bug 1379582).
function enableAnimationFeatures() {
return new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["dom.animations-api.core.enabled", true],
+ ["dom.animations-api.timelines.enabled", true],
["layout.css.frames-timing.enabled", true],
]}, resolve);
});
}
/**
* Add a new test tab in the browser and load the given url.
* @param {String} url The url to be loaded in the new tab
--- a/devtools/client/inspector/animation/test/head.js
+++ b/devtools/client/inspector/animation/test/head.js
@@ -56,16 +56,17 @@ const closeAnimationInspector = async fu
* yet including:
* * parts of the Web Animations API (Bug 1264101), and
* * the frames() timing function (Bug 1379582).
*/
const enableAnimationFeatures = function() {
return new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["dom.animations-api.core.enabled", true],
+ ["dom.animations-api.timelines.enabled", true],
["layout.css.frames-timing.enabled", true],
]}, resolve);
});
};
/**
* Add a new test tab in the browser and load the given url.
*
--- a/dom/animation/test/chrome/test_animation_observers_sync.html
+++ b/dom/animation/test/chrome/test_animation_observers_sync.html
@@ -1579,16 +1579,21 @@ function runTest() {
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after animation is finished");
}, "exclude_animations_targeting_pseudo_elements");
}
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
- { set: [["dom.animations-api.core.enabled", true]] },
+ {
+ set: [
+ ["dom.animations-api.core.enabled", true],
+ ["dom.animations-api.timelines.enabled", true],
+ ],
+ },
function() {
runTest();
done();
}
);
</script>
--- a/dom/animation/test/crashtests/crashtests.list
+++ b/dom/animation/test/crashtests/crashtests.list
@@ -1,44 +1,44 @@
pref(dom.animations-api.core.enabled,true) load 1239889-1.html
load 1244595-1.html
-pref(dom.animations-api.core.enabled,true) load 1216842-1.html
-pref(dom.animations-api.core.enabled,true) load 1216842-2.html
-pref(dom.animations-api.core.enabled,true) load 1216842-3.html
-pref(dom.animations-api.core.enabled,true) load 1216842-4.html
-pref(dom.animations-api.core.enabled,true) load 1216842-5.html
-pref(dom.animations-api.core.enabled,true) load 1216842-6.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1216842-1.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1216842-2.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1216842-3.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1216842-4.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1216842-5.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1216842-6.html
load 1272475-1.html
load 1272475-2.html
load 1278485-1.html
-pref(dom.animations-api.core.enabled,true) load 1277272-1.html
+pref(dom.animations-api.timelines.enabled,true) load 1277272-1.html
load 1282691-1.html
pref(dom.animations-api.core.enabled,true) load 1291413-1.html
pref(dom.animations-api.core.enabled,true) load 1291413-2.html
pref(dom.animations-api.core.enabled,true) load 1304886-1.html
pref(dom.animations-api.core.enabled,true) load 1309198-1.html
pref(dom.animations-api.core.enabled,true) load 1322382-1.html
pref(dom.animations-api.core.enabled,true) load 1322291-1.html
pref(dom.animations-api.core.enabled,true) load 1322291-2.html
pref(dom.animations-api.core.enabled,true) load 1323114-1.html
pref(dom.animations-api.core.enabled,true) load 1323114-2.html
pref(dom.animations-api.core.enabled,true) load 1323119-1.html
pref(dom.animations-api.core.enabled,true) load 1324554-1.html
pref(dom.animations-api.core.enabled,true) load 1325193-1.html
pref(dom.animations-api.core.enabled,true) load 1330190-1.html
pref(dom.animations-api.core.enabled,true) load 1330190-2.html
pref(dom.animations-api.core.enabled,true) load 1330513-1.html
-pref(dom.animations-api.core.enabled,true) load 1333539-1.html
-pref(dom.animations-api.core.enabled,true) load 1333539-2.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1333539-1.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1333539-2.html
load 1334582-1.html
load 1334582-2.html
load 1334583-1.html
pref(dom.animations-api.core.enabled,true) load 1335998-1.html
pref(dom.animations-api.core.enabled,true) load 1343589-1.html
pref(dom.animations-api.core.enabled,true) load 1359658-1.html
pref(dom.animations-api.core.enabled,true) load 1373712-1.html
pref(dom.animations-api.core.enabled,true) load 1379606-1.html
load 1393605-1.html
load 1400022-1.html
pref(dom.animations-api.core.enabled,true) load 1401809.html
-pref(dom.animations-api.core.enabled,true) load 1411318-1.html
+pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.timelines.enabled,true) load 1411318-1.html
load 1468294-1.html
load 1467277-1.html
--- a/dom/animation/test/mochitest.ini
+++ b/dom/animation/test/mochitest.ini
@@ -1,18 +1,20 @@
[DEFAULT]
prefs =
dom.animations-api.core.enabled=true
+ dom.animations-api.timelines.enabled=true
# Support files for chrome tests that we want to load over HTTP need
# to go in here, not chrome.ini.
support-files =
chrome/file_animate_xrays.html
mozilla/xhr_doc.html
mozilla/file_deferred_start.html
mozilla/file_disable_animations_api_core.html
+ mozilla/file_disable_animations_api_timelines.html
mozilla/file_discrete_animations.html
mozilla/file_restyles.html
mozilla/file_transition_finish_on_compositor.html
../../../layout/style/test/property_database.js
testcommon.js
!/dom/events/test/event_leak_utils.js
[css-transitions/test_animation-cancel.html]
@@ -33,16 +35,17 @@ support-files =
[document-timeline/test_document-timeline.html]
skip-if = (verify && !debug && (os == 'mac'))
[document-timeline/test_request_animation_frame.html]
[mozilla/test_cascade.html]
[mozilla/test_cubic_bezier_limits.html]
[mozilla/test_deferred_start.html]
skip-if = (toolkit == 'android' && debug) || (os == 'win' && bits == 64) # Bug 1363957
[mozilla/test_disable_animations_api_core.html]
+[mozilla/test_disable_animations_api_timelines.html]
[mozilla/test_disabled_properties.html]
[mozilla/test_discrete_animations.html]
[mozilla/test_distance_of_basic_shape.html]
[mozilla/test_distance_of_filter.html]
[mozilla/test_distance_of_transform.html]
[mozilla/test_document_timeline_origin_time_range.html]
[mozilla/test_hide_and_show.html]
[mozilla/test_moz_prefixed_properties.html]
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/mozilla/file_disable_animations_api_timelines.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../testcommon.js"></script>
+<body>
+<script>
+'use strict';
+
+test(t => {
+ assert_false(
+ window.hasOwnProperty('DocumentTimeline'),
+ 'DocumentTimeline should not be exposed on the global'
+ );
+ assert_false(
+ window.hasOwnProperty('AnimationTimeline'),
+ 'AnimationTimeline should not be exposed on the global'
+ );
+ assert_false(
+ 'timeline' in document,
+ 'document should not have a timeline property'
+ );
+
+ const anim = addDiv(t).animate(null);
+ assert_false(
+ 'timeline' in anim,
+ 'Animation should not have a timeline property'
+ );
+}, 'Timeline-related interfaces and members are disabled');
+
+done();
+</script>
--- a/dom/animation/test/mozilla/test_deferred_start.html
+++ b/dom/animation/test/mozilla/test_deferred_start.html
@@ -2,13 +2,19 @@
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
- { "set": [["dom.animations-api.core.enabled", true]]},
+ {
+ set: [
+ ["dom.animations-api.core.enabled", true],
+ ["dom.animations-api.timelines.enabled", true],
+ ],
+ },
function() {
window.open("file_deferred_start.html");
- });
+ }
+);
</script>
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/mozilla/test_disable_animations_api_timelines.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+'use strict';
+
+setup({ explicit_done: true });
+SpecialPowers.pushPrefEnv(
+ { set: [['dom.animations-api.timelines.enabled', false]] },
+ function() {
+ window.open('file_disable_animations_api_timelines.html');
+ }
+);
+</script>
--- a/dom/animation/test/testcommon.js
+++ b/dom/animation/test/testcommon.js
@@ -215,17 +215,18 @@ function propertyToIDL(property) {
function waitForFrame() {
return new Promise(function(resolve, reject) {
window.requestAnimationFrame(resolve);
});
}
/**
* Waits for a requestAnimationFrame callback in the next refresh driver tick.
- * Note that 'dom.animations-api.core.enabled' pref should be true to use this
+ * Note that the 'dom.animations-api.core.enabled' and
+ * 'dom.animations-api.timelines.enabled' prefs should be true to use this
* function.
*/
function waitForNextFrame() {
const timeAtStart = document.timeline.currentTime;
return new Promise(resolve => {
window.requestAnimationFrame(() => {
if (timeAtStart === document.timeline.currentTime) {
window.requestAnimationFrame(resolve);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -3302,16 +3302,27 @@ bool
nsDocument::IsWebAnimationsEnabled(CallerType aCallerType)
{
MOZ_ASSERT(NS_IsMainThread());
return aCallerType == dom::CallerType::System ||
nsContentUtils::AnimationsAPICoreEnabled();
}
+bool
+nsDocument::AreWebAnimationsTimelinesEnabled(JSContext* aCx,
+ JSObject* /*unused*/
+)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ return nsContentUtils::IsSystemCaller(aCx) ||
+ StaticPrefs::dom_animations_api_timelines_enabled();
+}
+
DocumentTimeline*
nsIDocument::Timeline()
{
if (!mDocumentTimeline) {
mDocumentTimeline = new DocumentTimeline(this, TimeDuration(0));
}
return mDocumentTimeline;
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -155,16 +155,18 @@ public:
nsIStreamListener **aDocListener,
bool aReset = true,
nsIContentSink* aContentSink = nullptr) override = 0;
virtual void StopDocumentLoad() override;
static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject);
static bool IsWebAnimationsEnabled(mozilla::dom::CallerType aCallerType);
+ static bool AreWebAnimationsTimelinesEnabled(JSContext* aCx,
+ JSObject* aObject);
virtual void EndUpdate() override;
virtual void BeginLoad() override;
virtual void EndLoad() override;
// nsIRadioGroupContainer
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor,
--- a/dom/webidl/Animation.webidl
+++ b/dom/webidl/Animation.webidl
@@ -13,17 +13,17 @@
enum AnimationPlayState { "idle", "running", "paused", "finished" };
[Constructor (optional AnimationEffect? effect = null,
optional AnimationTimeline? timeline)]
interface Animation : EventTarget {
attribute DOMString id;
[Func="nsDocument::IsWebAnimationsEnabled", Pure]
attribute AnimationEffect? effect;
- [Func="nsDocument::IsWebAnimationsEnabled"]
+ [Func="nsDocument::AreWebAnimationsTimelinesEnabled"]
attribute AnimationTimeline? timeline;
[BinaryName="startTimeAsDouble"]
attribute double? startTime;
[SetterThrows, BinaryName="currentTimeAsDouble"]
attribute double? currentTime;
attribute double playbackRate;
[BinaryName="playStateFromJS"]
--- a/dom/webidl/AnimationTimeline.webidl
+++ b/dom/webidl/AnimationTimeline.webidl
@@ -5,13 +5,13 @@
*
* The origin of this IDL file is
* https://drafts.csswg.org/web-animations/#animationtimeline
*
* Copyright © 2015 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
-[Func="nsDocument::IsWebAnimationsEnabled"]
+[Func="nsDocument::AreWebAnimationsTimelinesEnabled"]
interface AnimationTimeline {
[BinaryName="currentTimeAsDouble"]
readonly attribute double? currentTime;
};
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -318,17 +318,17 @@ partial interface Document {
NodeList querySelectorAll(DOMString selectors);
//(Not implemented)Element? find(DOMString selectors, optional (Element or sequence<Node>)? refNodes);
//(Not implemented)NodeList findAll(DOMString selectors, optional (Element or sequence<Node>)? refNodes);
};
// https://drafts.csswg.org/web-animations/#extensions-to-the-document-interface
partial interface Document {
- [Func="nsDocument::IsWebAnimationsEnabled"]
+ [Func="nsDocument::AreWebAnimationsTimelinesEnabled"]
readonly attribute DocumentTimeline timeline;
[Func="nsDocument::IsWebAnimationsEnabled"]
sequence<Animation> getAnimations();
};
// https://svgwg.org/svg2-draft/struct.html#InterfaceDocumentExtensions
partial interface Document {
[BinaryName="SVGRootElement"]
--- a/dom/webidl/DocumentTimeline.webidl
+++ b/dom/webidl/DocumentTimeline.webidl
@@ -9,12 +9,12 @@
* Copyright © 2015 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
dictionary DocumentTimelineOptions {
DOMHighResTimeStamp originTime = 0;
};
-[Func="nsDocument::IsWebAnimationsEnabled",
+[Func="nsDocument::AreWebAnimationsTimelinesEnabled",
Constructor (optional DocumentTimelineOptions options)]
interface DocumentTimeline : AnimationTimeline {
};
--- a/dom/xslt/tests/mochitest/test_bug1135764.html
+++ b/dom/xslt/tests/mochitest/test_bug1135764.html
@@ -22,26 +22,31 @@ https://bugzilla.mozilla.org/show_bug.cg
return;
}
ok(frames[0].document.timeline.currentTime !== startTimelineValue,
"The timeline in an XSLT-transformed document should still advance");
SimpleTest.finish();
}
addLoadEvent(function() {
SpecialPowers.pushPrefEnv(
- { "set": [[ "dom.animations-api.core.enabled", true]] },
+ {
+ set: [
+ ["dom.animations-api.timelines.enabled", true],
+ ],
+ },
function() {
var ifr = document.querySelector("iframe");
ifr.onload = function() {
startTimelineValue = frames[0].document.timeline.currentTime;
frames[0].requestAnimationFrame(waitATick);
- }
+ };
ifr.src = "file_bug1135764.xml";
- })
- })
+ }
+ );
+ });
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1135764">Mozilla Bug 1135764</a>
<p id="display">
<iframe></iframe>
</p>
<div id="content" style="display: none">
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -1,11 +1,12 @@
[DEFAULT]
prefs =
dom.animations-api.core.enabled=true
+ dom.animations-api.timelines.enabled=true
support-files =
animation_utils.js
ccd-quirks.html
ccd.sjs
ccd-standards.html
chrome/bug418986-2.js
chrome/match.png
chrome/mismatch.png
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -86,16 +86,29 @@ VARCACHE_PREF(
accessibility_monoaudio_enable,
RelaxedAtomicBool, false
)
//---------------------------------------------------------------------------
// DOM prefs
//---------------------------------------------------------------------------
+// Is support for timelines from the Web Animations API enabled?
+#ifdef RELEASE_OR_BETA
+# define PREF_VALUE false
+#else
+# define PREF_VALUE true
+#endif
+VARCACHE_PREF(
+ "dom.animations-api.timelines.enabled",
+ dom_animations_api_timelines_enabled,
+ bool, PREF_VALUE
+)
+#undef PREF_VALUE
+
VARCACHE_PREF(
"dom.webcomponents.shadowdom.report_usage",
dom_webcomponents_shadowdom_report_usage,
bool, false
)
// Whether we disable triggering mutation events for changes to style
// attribute via CSSOM.
--- a/testing/web-platform/meta/css/css-animations/__dir__.ini
+++ b/testing/web-platform/meta/css/css-animations/__dir__.ini
@@ -1,1 +1,2 @@
-prefs: [dom.animations-api.core.enabled:true]
+prefs: [dom.animations-api.core.enabled:true,
+ dom.animations-api.timelines.enabled:true]
--- a/testing/web-platform/meta/css/css-transitions/__dir__.ini
+++ b/testing/web-platform/meta/css/css-transitions/__dir__.ini
@@ -1,1 +1,2 @@
-prefs: [dom.animations-api.core.enabled:true]
+prefs: [dom.animations-api.core.enabled:true,
+ dom.animations-api.timelines.enabled:true]
--- a/testing/web-platform/meta/web-animations/__dir__.ini
+++ b/testing/web-platform/meta/web-animations/__dir__.ini
@@ -1,2 +1,3 @@
prefs: [dom.animations-api.core.enabled:true,
+ dom.animations-api.timelines.enabled:true,
layout.css.frames-timing.enabled:true]
--- a/testing/web-platform/tests/css/css-animations/support/testcommon.js
+++ b/testing/web-platform/tests/css/css-animations/support/testcommon.js
@@ -98,18 +98,16 @@ function addStyle(t, rules) {
function waitForFrame() {
return new Promise(function(resolve, reject) {
window.requestAnimationFrame(resolve);
});
}
/**
* Waits for a requestAnimationFrame callback in the next refresh driver tick.
- * Note that 'dom.animations-api.core.enabled' pref should be true to use this
- * function.
*/
function waitForNextFrame() {
const timeAtStart = document.timeline.currentTime;
return new Promise(resolve => {
window.requestAnimationFrame(() => {
if (timeAtStart === document.timeline.currentTime) {
window.requestAnimationFrame(resolve);
} else {