Bug 1212720 - Part 1: Implement Document.getAnimations(). r=heycam, r=smaug
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Wed, 06 Jan 2016 14:21:00 -0500
changeset 278917 832653b10478c1f7f755ac3d324b4562cea3fded
parent 278916 94cd77a189810c5e1ee53b1eff5f3d4a59b07b5e
child 278918 26974dc2a13d5b0f286b6084731e4e47e59d621b
push id29860
push usercbook@mozilla.com
push dateThu, 07 Jan 2016 10:51:20 +0000
treeherdermozilla-central@e0bcd16e1d4b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam, smaug
bugs1212720
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1212720 - Part 1: Implement Document.getAnimations(). r=heycam, r=smaug
dom/base/Element.cpp
dom/base/Element.h
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
dom/webidl/Document.webidl
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -3313,16 +3313,23 @@ Element::MozRequestPointerLock()
 void
 Element::GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations)
 {
   nsIDocument* doc = GetComposedDoc();
   if (doc) {
     doc->FlushPendingNotifications(Flush_Style);
   }
 
+  GetAnimationsUnsorted(aAnimations);
+  aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
+}
+
+void
+Element::GetAnimationsUnsorted(nsTArray<RefPtr<Animation>>& aAnimations)
+{
   EffectSet* effects = EffectSet::GetEffectSet(this,
                          nsCSSPseudoElements::ePseudo_NotPseudoElement);
   if (!effects) {
     return;
   }
 
   for (KeyframeEffectReadOnly* effect : *effects) {
     MOZ_ASSERT(effect && effect->GetAnimation(),
@@ -3330,18 +3337,16 @@ Element::GetAnimations(nsTArray<RefPtr<A
                "added to an element's effect set");
     Animation* animation = effect->GetAnimation();
 
     MOZ_ASSERT(animation->IsRelevant(),
                "Only relevant animations should be added to an element's "
                "effect set");
     aAnimations.AppendElement(animation);
   }
-
-  aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
 }
 
 NS_IMETHODIMP
 Element::GetInnerHTML(nsAString& aInnerHTML)
 {
   GetMarkup(false, aInnerHTML);
   return NS_OK;
 }
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -816,17 +816,19 @@ public:
   {
     return false;
   }
 
   virtual void SetUndoScope(bool aUndoScope, ErrorResult& aError)
   {
   }
 
+  // Note: GetAnimations will flush style while GetAnimationsUnsorted won't.
   void GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations);
+  void GetAnimationsUnsorted(nsTArray<RefPtr<Animation>>& aAnimations);
 
   NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
   virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
   void GetOuterHTML(nsAString& aOuterHTML);
   void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError);
   void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText,
                           ErrorResult& aError);
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -5,20 +5,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Base class for all our document implementations.
  */
 
 #include "nsDocument.h"
 
+#include "mozilla/AnimationComparator.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/BinarySearch.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/EffectSet.h"
 #include "mozilla/IntegerRange.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Likely.h"
 #include <algorithm>
 
 #include "mozilla/Logging.h"
 #include "plstr.h"
 #include "prprf.h"
@@ -3129,16 +3131,42 @@ nsDocument::Timeline()
 {
   if (!mDocumentTimeline) {
     mDocumentTimeline = new DocumentTimeline(this);
   }
 
   return mDocumentTimeline;
 }
 
+void
+nsDocument::GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations)
+{
+  FlushPendingNotifications(Flush_Style);
+
+  // Bug 1174575: Until we implement a suitable PseudoElement interface we
+  // don't have anything to return for the |target| attribute of
+  // KeyframeEffect(ReadOnly) objects that refer to pseudo-elements.
+  // Rather than return some half-baked version of these objects (e.g.
+  // we a null effect attribute) we simply don't provide access to animations
+  // whose effect refers to a pseudo-element until we can support them
+  // properly.
+  for (nsIContent* node = nsINode::GetFirstChild();
+       node;
+       node = node->GetNextNode(this)) {
+    if (!node->IsElement()) {
+      continue;
+    }
+
+    node->AsElement()->GetAnimationsUnsorted(aAnimations);
+  }
+
+  // Sort animations by priority
+  aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
+}
+
 /* Return true if the document is in the focused top-level window, and is an
  * ancestor of the focused DOMWindow. */
 NS_IMETHODIMP
 nsDocument::HasFocus(bool* aResult)
 {
   ErrorResult rv;
   *aResult = nsIDocument::HasFocus(rv);
   return rv.StealNSResult();
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -782,16 +782,18 @@ public:
   virtual void DeleteShell() override;
 
   virtual nsresult GetAllowPlugins(bool* aAllowPlugins) override;
 
   virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager() override;
 
   static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject);
   virtual mozilla::dom::DocumentTimeline* Timeline() override;
+  virtual void GetAnimations(
+      nsTArray<RefPtr<mozilla::dom::Animation>>& aAnimations) override;
 
   virtual nsresult SetSubDocumentFor(Element* aContent,
                                      nsIDocument* aSubDoc) override;
   virtual nsIDocument* GetSubDocumentFor(nsIContent* aContent) const override;
   virtual Element* FindContentForSubDocument(nsIDocument *aDocument) const override;
   virtual Element* GetRootElementInternal() const override;
 
   virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) override;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -98,16 +98,17 @@ template<typename> class OwningNonNull;
 
 namespace css {
 class Loader;
 class ImageLoader;
 class Rule;
 } // namespace css
 
 namespace dom {
+class Animation;
 class AnonymousContent;
 class Attr;
 class BoxObject;
 class CDATASection;
 class Comment;
 struct CustomElementDefinition;
 class DocumentFragment;
 class DocumentTimeline;
@@ -2151,16 +2152,19 @@ public:
    * @return the element associated with |aId|
    */
   virtual Element* LookupImageElement(const nsAString& aElementId) = 0;
 
   virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager() = 0;
 
   virtual mozilla::dom::DocumentTimeline* Timeline() = 0;
 
+  virtual void GetAnimations(
+      nsTArray<RefPtr<mozilla::dom::Animation>>& aAnimations) = 0;
+
   nsresult ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback,
                                         int32_t *aHandle);
   void CancelFrameRequestCallback(int32_t aHandle);
 
   typedef nsTArray<RefPtr<mozilla::dom::FrameRequestCallback>> FrameRequestCallbackList;
   /**
    * Put this document's frame request callbacks into the provided
    * list, and forget about them.
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -298,16 +298,18 @@ partial interface Document {
   //(Not implemented)Element?  find(DOMString selectors, optional (Element or sequence<Node>)? refNodes);
   //(Not implemented)NodeList  findAll(DOMString selectors, optional (Element or sequence<Node>)? refNodes);
 };
 
 // http://w3c.github.io/web-animations/#extensions-to-the-document-interface
 partial interface Document {
   [Func="nsDocument::IsWebAnimationsEnabled"]
   readonly attribute DocumentTimeline timeline;
+  [Func="nsDocument::IsWebAnimationsEnabled"]
+  sequence<Animation> getAnimations();
 };
 
 //  Mozilla extensions of various sorts
 partial interface Document {
   // nsIDOMDocumentXBL.  Wish we could make these [ChromeOnly], but
   // that would likely break bindings running with the page principal.
   [Func="IsChromeOrXBL"]
   NodeList? getAnonymousNodes(Element elt);