Bug 1123523 - Part 5: Record on a document whether it might have any nsIAnimationObservers registered. r=smaug
authorCameron McCormack <cam@mcc.id.au>
Sat, 14 Mar 2015 16:34:40 +1100
changeset 262493 25a2e255c12b196082520c11c41660a8bb61a2a6
parent 262492 f78134a84572a22477fd1be3b49ef3cd741b3c60
child 262494 fc3461fbe72ac4b6d0eb9be42becfe613cb2a7ba
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1123523
milestone39.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 1123523 - Part 5: Record on a document whether it might have any nsIAnimationObservers registered. r=smaug
dom/base/nsIDocument.h
dom/base/nsINode.cpp
dom/base/nsINode.h
dom/base/nsNodeUtils.cpp
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2193,16 +2193,26 @@ public:
     return mMayHaveDOMMutationObservers;
   }
 
   void SetMayHaveDOMMutationObservers()
   {
     mMayHaveDOMMutationObservers = true;
   }
 
+  bool MayHaveAnimationObservers()
+  {
+    return mMayHaveAnimationObservers;
+  }
+
+  void SetMayHaveAnimationObservers()
+  {
+    mMayHaveAnimationObservers = true;
+  }
+
   bool IsInSyncOperation()
   {
     return mInSyncOperationCount != 0;
   }
 
   void SetIsInSyncOperation(bool aSync)
   {
     if (aSync) {
@@ -2689,16 +2699,19 @@ protected:
   bool mNeedLayoutFlush;
 
   // True if a style flush might not be a no-op
   bool mNeedStyleFlush;
 
   // True if a DOMMutationObserver is perhaps attached to a node in the document.
   bool mMayHaveDOMMutationObservers;
 
+  // True if an nsIAnimationObserver is perhaps attached to a node in the document.
+  bool mMayHaveAnimationObservers;
+
   // True if a document has loaded Mixed Active Script (see nsMixedContentBlocker.cpp)
   bool mHasMixedActiveContentLoaded;
 
   // True if a document has blocked Mixed Active Script (see nsMixedContentBlocker.cpp)
   bool mHasMixedActiveContentBlocked;
 
   // True if a document has loaded Mixed Display/Passive Content (see nsMixedContentBlocker.cpp)
   bool mHasMixedDisplayContentLoaded;
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -99,16 +99,17 @@
 #include "HTMLLegendElement.h"
 #include "nsWrapperCacheInlines.h"
 #include "WrapperFactory.h"
 #include "DocumentType.h"
 #include <algorithm>
 #include "nsGlobalWindow.h"
 #include "nsDOMMutationObserver.h"
 #include "GeometryUtils.h"
+#include "nsIAnimationObserver.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsINode::nsSlots::~nsSlots()
 {
   if (mChildNodes) {
     mChildNodes->DropReference();
@@ -2743,8 +2744,23 @@ nsINode::HasBoxQuadsSupport(JSContext* a
          Preferences::GetBool("layout.css.getBoxQuads.enabled");
 }
 
 nsINode*
 nsINode::GetScopeChainParent() const
 {
   return nullptr;
 }
+
+void
+nsINode::AddAnimationObserver(nsIAnimationObserver* aAnimationObserver)
+{
+  AddMutationObserver(aAnimationObserver);
+  OwnerDoc()->SetMayHaveAnimationObservers();
+}
+
+void
+nsINode::AddAnimationObserverUnlessExists(
+                               nsIAnimationObserver* aAnimationObserver)
+{
+  AddMutationObserverUnlessExists(aAnimationObserver);
+  OwnerDoc()->SetMayHaveAnimationObservers();
+}
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -28,16 +28,17 @@
 #undef GetClassInfo
 #endif
 #endif
 
 class nsAttrAndChildArray;
 class nsChildContentList;
 struct nsCSSSelectorList;
 class nsDOMAttributeMap;
+class nsIAnimationObserver;
 class nsIContent;
 class nsIDocument;
 class nsIDOMElement;
 class nsIDOMNodeList;
 class nsIEditor;
 class nsIFrame;
 class nsIMutationObserver;
 class nsINodeList;
@@ -943,37 +944,57 @@ public:
    * Adds a mutation observer to be notified when this node, or any of its
    * descendants, are modified. The node will hold a weak reference to the
    * observer, which means that it is the responsibility of the observer to
    * remove itself in case it dies before the node.  If an observer is added
    * while observers are being notified, it may also be notified.  In general,
    * adding observers while inside a notification is not a good idea.  An
    * observer that is already observing the node must not be added without
    * being removed first.
+   *
+   * For mutation observers that implement nsIAnimationObserver, use
+   * AddAnimationObserver instead.
    */
   void AddMutationObserver(nsIMutationObserver* aMutationObserver)
   {
     nsSlots* s = Slots();
     NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver) ==
                  nsTArray<int>::NoIndex,
                  "Observer already in the list");
     s->mMutationObservers.AppendElement(aMutationObserver);
   }
 
   /**
    * Same as above, but only adds the observer if its not observing
    * the node already.
+   *
+   * For mutation observers that implement nsIAnimationObserver, use
+   * AddAnimationObserverUnlessExists instead.
    */
   void AddMutationObserverUnlessExists(nsIMutationObserver* aMutationObserver)
   {
     nsSlots* s = Slots();
     s->mMutationObservers.AppendElementUnlessExists(aMutationObserver);
   }
 
   /**
+   * Same as AddMutationObserver, but for nsIAnimationObservers.  This
+   * additionally records on the document that animation observers have
+   * been registered, which is used to determine whether notifications
+   * must be fired when animations are added, removed or changed.
+   */
+  void AddAnimationObserver(nsIAnimationObserver* aAnimationObserver);
+
+  /**
+   * Same as above, but only adds the observer if its not observing
+   * the node already.
+   */
+  void AddAnimationObserverUnlessExists(nsIAnimationObserver* aAnimationObserver);
+
+  /**
    * Removes a mutation observer.
    */
   void RemoveMutationObserver(nsIMutationObserver* aMutationObserver)
   {
     nsSlots* s = GetExistingSlots();
     if (s) {
       s->mMutationObservers.RemoveElement(aMutationObserver);
     }
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -452,16 +452,20 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
         olc->NotifyOwnerDocumentActivityChanged();
       }
     }
 
     if (oldDoc != newDoc && oldDoc->MayHaveDOMMutationObservers()) {
       newDoc->SetMayHaveDOMMutationObservers();
     }
 
+    if (oldDoc != newDoc && oldDoc->MayHaveAnimationObservers()) {
+      newDoc->SetMayHaveAnimationObservers();
+    }
+
     if (elem) {
       elem->RecompileScriptEventListeners();
     }
 
     if (aReparentScope) {
       JS::Rooted<JSObject*> wrapper(cx);
       if ((wrapper = aNode->GetWrapper())) {
         MOZ_ASSERT(IsDOMObject(wrapper));