Bug 1146843 - Revert part of cset 33c30e283fa8 because the code is used in Fennec. r=snorp
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 02 Apr 2015 20:45:50 -0400
changeset 237499 19d96ad344663d9a2a91d2e1c7370fbf31dea899
parent 237498 40340099805520013267f18821fb8602c096e51b
child 237500 c236d0f0e4287471c12c147df1fb70004d57d96e
push id28536
push userryanvm@gmail.com
push dateFri, 03 Apr 2015 14:34:15 +0000
treeherdermozilla-central@6d849a62ec0d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1146843
milestone40.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 1146843 - Revert part of cset 33c30e283fa8 because the code is used in Fennec. r=snorp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsNodeUtils.cpp
dom/base/nsPIDOMWindow.h
dom/events/EventListenerManager.cpp
dom/events/EventListenerManager.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -569,17 +569,17 @@ extern uint64_t
 NextWindowID();
 }
 }
 
 nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
 : mFrameElement(nullptr), mDocShell(nullptr), mModalStateDepth(0),
   mRunningTimeout(nullptr), mMutationBits(0), mIsDocumentLoaded(false),
   mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
-  mMayHavePaintEventListener(false),
+  mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
   mMayHaveMouseEnterLeaveEventListener(false),
   mMayHavePointerEnterLeaveEventListener(false),
   mIsModalContentWindow(false),
   mIsActive(false), mIsBackground(false),
   mAudioMuted(false), mAudioVolume(1.0),
   mDesktopModeViewport(false), mInnerWindow(nullptr),
   mOuterWindow(aOuterWindow),
   // Make sure no actual window ends up with mWindowID == 0
@@ -9838,16 +9838,32 @@ void nsGlobalWindow::SetIsBackground(boo
     nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
     if (inner) {
       inner->SyncGamepadState();
     }
   }
 #endif
 }
 
+void nsGlobalWindow::MaybeUpdateTouchState()
+{
+  FORWARD_TO_INNER_VOID(MaybeUpdateTouchState, ());
+
+  if (mMayHaveTouchEventListener) {
+    nsCOMPtr<nsIObserverService> observerService =
+      services::GetObserverService();
+
+    if (observerService) {
+      observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
+                                       DOM_TOUCH_LISTENER_ADDED,
+                                       nullptr);
+    }
+  }
+}
+
 void
 nsGlobalWindow::EnableGamepadUpdates()
 {
   MOZ_ASSERT(IsInnerWindow());
 
   if (mHasGamepad) {
 #ifdef MOZ_GAMEPAD
     nsRefPtr<GamepadService> gamepadsvc(GamepadService::GetService());
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -463,16 +463,18 @@ public:
 
   virtual void EnterModalState() override;
   virtual void LeaveModalState() override;
 
   // Outer windows only.
   virtual bool CanClose() override;
   virtual void ForceClose() override;
 
+  virtual void MaybeUpdateTouchState() override;
+
   // Outer windows only.
   virtual bool DispatchCustomEvent(const nsAString& aEventName) override;
   bool DispatchResizeEvent(const mozilla::CSSIntSize& aSize);
 
   // Inner windows only.
   virtual void RefreshCompartmentPrincipal() override;
 
   // Outer windows only.
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -514,16 +514,19 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       nsPIDOMWindow* window = newDoc->GetInnerWindow();
       if (window) {
         EventListenerManager* elm = aNode->GetExistingListenerManager();
         if (elm) {
           window->SetMutationListeners(elm->MutationListenerBits());
           if (elm->MayHavePaintEventListener()) {
             window->SetHasPaintEventListeners();
           }
+          if (elm->MayHaveTouchEventListener()) {
+            window->SetHasTouchEventListeners();
+          }
           if (elm->MayHaveMouseEnterLeaveEventListener()) {
             window->SetHasMouseEnterLeaveEventListeners();
           }
           if (elm->MayHavePointerEnterLeaveEventListener()) {
             window->SetHasPointerEnterLeaveEventListeners();
           }
         }
       }
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -58,18 +58,18 @@ enum PopupControlState {
 enum UIStateChangeType
 {
   UIStateChangeType_NoChange,
   UIStateChangeType_Set,
   UIStateChangeType_Clear
 };
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x4178bd68, 0xa3f7, 0x4ff7, \
-  { 0xa6, 0x27, 0x4a, 0x99, 0xa1, 0xe0, 0x42, 0x37 } }
+{ 0x2485d4d7, 0xf7cb, 0x481e, \
+  { 0x9c, 0x89, 0xb2, 0xa8, 0x12, 0x67, 0x7f, 0x97 } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -155,16 +155,18 @@ public:
       NS_ERROR("HasMutationListeners() called on orphan inner window!");
 
       return;
     }
 
     mMutationBits |= aType;
   }
 
+  virtual void MaybeUpdateTouchState() {}
+
   nsIDocument* GetExtantDoc() const
   {
     return mDoc;
   }
   nsIURI* GetDocumentURI() const;
   nsIURI* GetDocBaseURI() const;
 
   nsIDocument* GetDoc()
@@ -444,16 +446,28 @@ public:
    * or content in that document) has a paint event listener.
    */
   bool HasPaintEventListeners()
   {
     return mMayHavePaintEventListener;
   }
   
   /**
+   * Call this to indicate that some node (this window, its document,
+   * or content in that document) has a touch event listener.
+   */
+  void SetHasTouchEventListeners()
+  {
+    if (!mMayHaveTouchEventListener) {
+      mMayHaveTouchEventListener = true;
+      MaybeUpdateTouchState();
+    }
+  }
+
+  /**
    * Moves the top-level window into fullscreen mode if aIsFullScreen is true,
    * otherwise exits fullscreen. If aRequireTrust is true, this method only
    * changes window state in a context trusted for write.
    *
    * If aHMD is not null, the window is made full screen on the given VR HMD
    * device instead of its currrent display.
    *
    * Outer windows only.
@@ -763,16 +777,17 @@ protected:
   nsTimeout             *mRunningTimeout;
 
   uint32_t               mMutationBits;
 
   bool                   mIsDocumentLoaded;
   bool                   mIsHandlingResizeEvent;
   bool                   mIsInnerWindow;
   bool                   mMayHavePaintEventListener;
+  bool                   mMayHaveTouchEventListener;
   bool                   mMayHaveMouseEnterLeaveEventListener;
   bool                   mMayHavePointerEnterLeaveEventListener;
 
   // This variable is used on both inner and outer windows (and they
   // should match).
   bool                   mIsModalContentWindow;
 
   // Tracks activation state that's used for :-moz-window-inactive.
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -92,16 +92,17 @@ MutationBitForEventType(uint32_t aEventT
 
 uint32_t EventListenerManager::sMainThreadCreatedCount = 0;
 
 EventListenerManager::EventListenerManager(EventTarget* aTarget)
   : mMayHavePaintEventListener(false)
   , mMayHaveMutationListeners(false)
   , mMayHaveCapturingListeners(false)
   , mMayHaveSystemGroupListeners(false)
+  , mMayHaveTouchEventListener(false)
   , mMayHaveMouseEnterLeaveEventListener(false)
   , mMayHavePointerEnterLeaveEventListener(false)
   , mClearingListeners(false)
   , mIsMainThreadELM(NS_IsMainThread())
   , mNoListenerForEvent(0)
   , mTarget(aTarget)
 {
   NS_ASSERTION(aTarget, "unexpected null pointer");
@@ -322,16 +323,27 @@ EventListenerManager::AddEventListenerIn
       window->EnableNetworkEvent(NS_NETWORK_UPLOAD_EVENT);
     }
   } else if (aTypeAtom == nsGkAtoms::onmoznetworkdownload) {
     nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
     if (window) {
       window->EnableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
     }
 #endif // MOZ_B2G
+  } else if (aTypeAtom == nsGkAtoms::ontouchstart ||
+             aTypeAtom == nsGkAtoms::ontouchend ||
+             aTypeAtom == nsGkAtoms::ontouchmove ||
+             aTypeAtom == nsGkAtoms::ontouchcancel) {
+    mMayHaveTouchEventListener = true;
+    nsPIDOMWindow* window = GetInnerWindowForTarget();
+    // we don't want touchevent listeners added by scrollbars to flip this flag
+    // so we ignore listeners created with system event flag
+    if (window && !aFlags.mInSystemGroup) {
+      window->SetHasTouchEventListeners();
+    }
   } else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) {
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (aTypeAtom == nsGkAtoms::onpointerenter ||
         aTypeAtom == nsGkAtoms::onpointerleave) {
       mMayHavePointerEnterLeaveEventListener = true;
       if (window) {
 #ifdef DEBUG
         nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -383,16 +383,22 @@ public:
   static void Shutdown();
 
   /**
    * Returns true if there may be a paint event listener registered,
    * false if there definitely isn't.
    */
   bool MayHavePaintEventListener() { return mMayHavePaintEventListener; }
 
+  /**
+   * Returns true if there may be a touch event listener registered,
+   * false if there definitely isn't.
+   */
+  bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; }
+
   bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
   bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
 
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
 
   uint32_t ListenerCount() const
   {
     return mListeners.Length();
@@ -532,16 +538,17 @@ protected:
 
   already_AddRefed<nsIScriptGlobalObject>
   GetScriptGlobalAndDocument(nsIDocument** aDoc);
 
   uint32_t mMayHavePaintEventListener : 1;
   uint32_t mMayHaveMutationListeners : 1;
   uint32_t mMayHaveCapturingListeners : 1;
   uint32_t mMayHaveSystemGroupListeners : 1;
+  uint32_t mMayHaveTouchEventListener : 1;
   uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
   uint32_t mMayHavePointerEnterLeaveEventListener : 1;
   uint32_t mClearingListeners : 1;
   uint32_t mIsMainThreadELM : 1;
   uint32_t mNoListenerForEvent : 23;
 
   nsAutoTObserverArray<Listener, 2> mListeners;
   dom::EventTarget* MOZ_NON_OWNING_REF mTarget;