Bug 1290914 - support Element.animate() on AnonymousContent nodes through the AnonymousContent.setAnimationForElement() method. r?bz draft
authorMike de Boer <mdeboer@mozilla.com>
Wed, 07 Sep 2016 12:01:17 +0200
changeset 410967 1d7be95d8cbe5bf7868adf31281774adf8cc161a
parent 410966 541c9086c0f27fba60beecc9bc94543103895c86
child 410968 0d56ae5f3cdda0ad88735139c35ebdc321ebc0ae
push id28805
push usermdeboer@mozilla.com
push dateWed, 07 Sep 2016 10:05:39 +0000
reviewersbz
bugs1290914
milestone51.0a1
Bug 1290914 - support Element.animate() on AnonymousContent nodes through the AnonymousContent.setAnimationForElement() method. r?bz MozReview-Commit-ID: 3Wl5yAjHGPN
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffectReadOnly.cpp
dom/animation/TimingParams.cpp
dom/base/AnonymousContent.cpp
dom/base/AnonymousContent.h
dom/base/Element.cpp
dom/base/test/test_anonymousContent_api.html
dom/base/test/test_anonymousContent_manipulate_content.html
dom/webidl/Animatable.webidl
dom/webidl/AnonymousContent.webidl
dom/webidl/KeyframeAnimationOptions.webidl
dom/webidl/moz.build
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/KeyframeEffect.h"
 
-#include "mozilla/dom/AnimatableBinding.h"
+#include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
   // For UnrestrictedDoubleOrKeyframeAnimationOptions
 #include "mozilla/dom/AnimationEffectTiming.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/KeyframeUtils.h"
 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
 #include "nsIScriptError.h"
 
 namespace mozilla {
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/KeyframeEffectReadOnly.h"
 
-#include "mozilla/dom/AnimatableBinding.h"
+#include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
   // For UnrestrictedDoubleOrKeyframeAnimationOptions;
 #include "mozilla/dom/CSSPseudoElement.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/FloatingPoint.h" // For IsFinite
 #include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt
 #include "mozilla/KeyframeUtils.h"
--- a/dom/animation/TimingParams.cpp
+++ b/dom/animation/TimingParams.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/TimingParams.h"
 
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/dom/AnimatableBinding.h"
+#include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "nsCSSParser.h" // For nsCSSParser
 #include "nsIDocument.h"
 #include "nsRuleNode.h"
 
 namespace mozilla {
 
 template <class OptionsType>
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -132,16 +132,33 @@ AnonymousContent::GetCanvasContext(const
   nsCOMPtr<nsISupports> context;
 
   HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(element);
   canvas->GetContext(aContextId, getter_AddRefs(context));
 
   return context.forget();
 }
 
+already_AddRefed<Animation>
+AnonymousContent::SetAnimationForElement(JSContext* aContext,
+                                         const nsAString& aElementId,
+                                         JS::Handle<JSObject*> aKeyframes,
+                                         const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
+                                         ErrorResult& aRv)
+{
+  Element* element = GetElementById(aElementId);
+
+  if (!element) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return nullptr;
+  }
+
+  return element->Animate(aContext, aKeyframes, aOptions, aRv);
+}
+
 Element*
 AnonymousContent::GetElementById(const nsAString& aElementId)
 {
   // This can be made faster in the future if needed.
   nsCOMPtr<nsIAtom> elementId = NS_Atomize(aElementId);
   for (nsIContent* kid = mContentNode->GetFirstChild(); kid;
        kid = kid->GetNextNode(mContentNode)) {
     if (!kid->IsElement()) {
--- a/dom/base/AnonymousContent.h
+++ b/dom/base/AnonymousContent.h
@@ -11,16 +11,17 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsICSSDeclaration.h"
 #include "nsIDocument.h"
 
 namespace mozilla {
 namespace dom {
 
 class Element;
+class UnrestrictedDoubleOrAnonymousKeyframeAnimationOptions;
 
 class AnonymousContent final
 {
 public:
   // Ref counting and cycle collection
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnonymousContent)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnonymousContent)
 
@@ -52,16 +53,22 @@ public:
   void RemoveAttributeForElement(const nsAString& aElementId,
                                  const nsAString& aName,
                                  ErrorResult& aRv);
 
   already_AddRefed<nsISupports> GetCanvasContext(const nsAString& aElementId,
                                                  const nsAString& aContextId,
                                                  ErrorResult& aRv);
 
+  already_AddRefed<Animation> SetAnimationForElement(JSContext* aContext,
+                                                     const nsAString& aElementId,
+                                                     JS::Handle<JSObject*> aKeyframes,
+                                                     const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
+                                                     ErrorResult& aError);
+
 private:
   ~AnonymousContent();
   nsCOMPtr<Element> mContentNode;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -48,16 +48,17 @@
 #include "nsVariant.h"
 #include "nsDOMTokenList.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsError.h"
 #include "nsDOMString.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIDOMMutationEvent.h"
 #include "mozilla/dom/AnimatableBinding.h"
+#include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
 #include "mozilla/AnimationComparator.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
--- a/dom/base/test/test_anonymousContent_api.html
+++ b/dom/base/test/test_anonymousContent_api.html
@@ -40,16 +40,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   // Testing the API of the returned object
   let div = document.createElement("div");
   div.textContent = "this is a test element";
   let anonymousContent = chromeDocument.insertAnonymousContent(div);
   ok(anonymousContent, "AnonymousContent object returned");
 
   let members = ["getTextContentForElement", "setTextContentForElement",
                  "getAttributeForElement", "setAttributeForElement",
-                 "removeAttributeForElement", "getCanvasContext"];
+                 "removeAttributeForElement", "getCanvasContext",
+                 "setAnimationForElement"];
   for (let member of members) {
     ok(member in anonymousContent, "AnonymousContent object defines " + member);
   }
   chromeDocument.removeAnonymousContent(anonymousContent);
   </script>
 </body>
 </html>
--- a/dom/base/test/test_anonymousContent_manipulate_content.html
+++ b/dom/base/test/test_anonymousContent_manipulate_content.html
@@ -55,12 +55,20 @@ https://bugzilla.mozilla.org/show_bug.cg
     "Class attribute for the test element is correct after update");
   ok(testElement.getAttribute("class") !== "updated-test-class",
     "Class attribute change on the inserted node does not change the original DOM node");
 
   anonymousContent.removeAttributeForElement("test-element", "class");
   is(anonymousContent.getAttributeForElement("test-element", "class"), null,
     "Class attribute for the test element was removed");
 
+  let anim = anonymousContent.setAnimationForElement("test-element", [
+    { transform: 'translateY(0px)' },
+    { transform: 'translateY(-300px)' }
+  ], 2000);
+  is(anim.playState, "pending", "Animation should be running");
+  anim.cancel();
+  is(anim.playState, "idle", "Animation should have stopped immediately");
+
   chromeDocument.removeAnonymousContent(anonymousContent);
   </script>
 </body>
 </html>
--- a/dom/webidl/Animatable.webidl
+++ b/dom/webidl/Animatable.webidl
@@ -17,13 +17,12 @@ dictionary KeyframeAnimationOptions : Ke
 dictionary AnimationFilter {
   boolean subtree = false;
 };
 
 [NoInterfaceObject]
 interface Animatable {
   [Func="nsDocument::IsElementAnimateEnabled", Throws]
   Animation animate(object? keyframes,
-                    optional (unrestricted double or KeyframeAnimationOptions)
-                      options);
+                    optional UnrestrictedDoubleOrKeyframeAnimationOptions options);
   [Func="nsDocument::IsWebAnimationsEnabled"]
   sequence<Animation> getAnimations(optional AnimationFilter filter);
 };
--- a/dom/webidl/AnonymousContent.webidl
+++ b/dom/webidl/AnonymousContent.webidl
@@ -56,9 +56,15 @@ interface AnonymousContent {
 
   /**
    * Get the canvas' context for the element specified if it's a <canvas>
    * node, `null` otherwise.
    */
   [Throws]
   nsISupports? getCanvasContext(DOMString elementId,
                                 DOMString contextId);
+
+  [Func="nsDocument::IsElementAnimateEnabled", Throws]
+  Animation setAnimationForElement(DOMString elementId,
+                                   object? keyframes,
+                                   optional UnrestrictedDoubleOrKeyframeAnimationOptions
+                                     options);
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/KeyframeAnimationOptions.webidl
@@ -0,0 +1,14 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://dev.w3.org/fxtf/web-animations/#the-animatable-interface
+ *
+ * Copyright © 2014 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+// This typedef is off in its own file, because of bug 995352.
+typedef (unrestricted double or KeyframeAnimationOptions) UnrestrictedDoubleOrKeyframeAnimationOptions;
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -286,16 +286,17 @@ WEBIDL_FILES = [
     'InputMethod.webidl',
     'InputPort.webidl',
     'InputPortManager.webidl',
     'InspectorUtils.webidl',
     'IterableIterator.webidl',
     'KeyAlgorithm.webidl',
     'KeyboardEvent.webidl',
     'KeyEvent.webidl',
+    'KeyframeAnimationOptions.webidl',
     'KeyframeEffect.webidl',
     'LegacyQueryInterface.webidl',
     'LinkStyle.webidl',
     'ListBoxObject.webidl',
     'LocalMediaStream.webidl',
     'Location.webidl',
     'MediaDeviceInfo.webidl',
     'MediaDevices.webidl',