Bug 1133492 - Extract some of nsPresShell into a separate TouchManager class. r=smaug
authorMaksim Lebedev <alessarik@gmail.com>
Tue, 24 Feb 2015 22:20:00 -0500
changeset 261502 bd17cfb379b26f01bf9a7b8ce9a78cd12874f7bf
parent 261501 e99a6c34aa50dab52846ba33f9b907cab0169bbf
child 261503 20d0b5cb20711e8c4bee4e65091710c48c2d8ffd
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1133492
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 1133492 - Extract some of nsPresShell into a separate TouchManager class. r=smaug
dom/ipc/TabChild.cpp
gfx/layers/apz/util/APZEventState.cpp
gfx/layers/moz.build
layout/base/TouchManager.cpp
layout/base/TouchManager.h
layout/base/nsIPresShell.h
layout/base/nsLayoutUtils.cpp
layout/base/nsPresShell.cpp
layout/build/nsLayoutStatics.cpp
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2222,17 +2222,17 @@ TabChild::UpdateTapState(const WidgetTou
   if (aEvent.message == NS_TOUCH_START) {
     if (currentlyTrackingTouch || aEvent.touches.Length() > 1) {
       // We're tracking a possible tap for another point, or we saw a
       // touchstart for a later pointer after we canceled tracking of
       // the first point.  Ignore this one.
       return;
     }
     if (aStatus == nsEventStatus_eConsumeNoDefault ||
-        nsIPresShell::gPreventMouseEvents ||
+        TouchManager::gPreventMouseEvents ||
         aEvent.mFlags.mMultipleActionsPrevented) {
       return;
     }
 
     Touch* touch = aEvent.touches[0];
     mGestureDownPoint = LayoutDevicePoint(touch->mRefPoint.x, touch->mRefPoint.y);
     mActivePointerId = touch->mIdentifier;
     if (sClickHoldContextMenusEnabled) {
@@ -2263,17 +2263,17 @@ TabChild::UpdateTapState(const WidgetTou
   case NS_TOUCH_MOVE:
     if (std::abs(currentPoint.x - mGestureDownPoint.x) > sDragThreshold.width ||
         std::abs(currentPoint.y - mGestureDownPoint.y) > sDragThreshold.height) {
       CancelTapTracking();
     }
     return;
 
   case NS_TOUCH_END:
-    if (!nsIPresShell::gPreventMouseEvents) {
+    if (!TouchManager::gPreventMouseEvents) {
       APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, currentPoint, mWidget);
       APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, currentPoint, mWidget);
       APZCCallbackHelper::DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, currentPoint, mWidget);
     }
     // fall through
   case NS_TOUCH_CANCEL:
     CancelTapTracking();
     return;
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -8,16 +8,17 @@
 #include "ActiveElementManager.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/Preferences.h"
 #include "nsCOMPtr.h"
 #include "nsDocShell.h"
 #include "nsITimer.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsIWidget.h"
+#include "TouchManager.h"
 
 #define APZES_LOG(...)
 // #define APZES_LOG(...) printf_stderr("APZCCH: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
 
 static int32_t sActiveDurationMs = 10;
@@ -184,17 +185,17 @@ void
 APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
                                  const ScrollableLayerGuid& aGuid,
                                  uint64_t aInputBlockId)
 {
   if (aEvent.message == NS_TOUCH_START && aEvent.touches.Length() > 0) {
     mActiveElementManager->SetTargetElement(aEvent.touches[0]->GetTarget());
   }
 
-  bool isTouchPrevented = nsIPresShell::gPreventMouseEvents ||
+  bool isTouchPrevented = TouchManager::gPreventMouseEvents ||
       aEvent.mFlags.mMultipleActionsPrevented;
   switch (aEvent.message) {
   case NS_TOUCH_START: {
     mTouchEndCancelled = false;
     if (mPendingTouchPreventedResponse) {
       // We can enter here if we get two TOUCH_STARTs in a row and didn't
       // respond to the first one. Respond to it now.
       mContentReceivedInputBlockCallback->Run(mPendingTouchPreventedGuid,
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -354,16 +354,17 @@ IPDL_SOURCES = [
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/docshell/base',  # for nsDocShell.h
+    '/layout/base',    # for TouchManager.h
 ]
 
 FINAL_LIBRARY = 'xul'
 
 if CONFIG['MOZ_DEBUG']:
     DEFINES['D3D_DEBUG_INFO'] = True
 
 if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
--- a/layout/base/TouchManager.cpp
+++ b/layout/base/TouchManager.cpp
@@ -3,16 +3,34 @@
  * 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 "TouchManager.h"
 #include "nsPresShell.h"
 
+bool TouchManager::gPreventMouseEvents = false;
+nsRefPtrHashtable<nsUint32HashKey, dom::Touch>* TouchManager::gCaptureTouchList;
+
+/*static*/ void
+TouchManager::InitializeStatics()
+{
+  NS_ASSERTION(!gCaptureTouchList, "InitializeStatics called multiple times!");
+  gCaptureTouchList = new nsRefPtrHashtable<nsUint32HashKey, dom::Touch>;
+}
+
+/*static*/ void
+TouchManager::ReleaseStatics()
+{
+  NS_ASSERTION(gCaptureTouchList, "ReleaseStatics called without Initialize!");
+  delete gCaptureTouchList;
+  gCaptureTouchList = nullptr;
+}
+
 void
 TouchManager::Init(PresShell* aPresShell, nsIDocument* aDocument)
 {
   mPresShell = aPresShell;
   mDocument = aDocument;
 }
 
 void
@@ -46,19 +64,18 @@ EvictTouchPoint(nsRefPtr<dom::Touch>& aT
             widget->DispatchEvent(&event, status);
             return;
           }
         }
       }
     }
   }
   if (!node || !aLimitToDocument || node->OwnerDoc() == aLimitToDocument) {
-    // We couldn't dispatch touchend. Remove the touch from gCaptureTouchList
-    // explicitly.
-    nsIPresShell::gCaptureTouchList->Remove(aTouch->Identifier());
+    // We couldn't dispatch touchend. Remove the touch from gCaptureTouchList explicitly.
+    TouchManager::gCaptureTouchList->Remove(aTouch->Identifier());
   }
 }
 
 static PLDHashOperator
 AppendToTouchList(const uint32_t& aKey, nsRefPtr<dom::Touch>& aData, void *aTouchList)
 {
   WidgetTouchEvent::TouchArray* touches =
     static_cast<WidgetTouchEvent::TouchArray*>(aTouchList);
@@ -66,17 +83,17 @@ AppendToTouchList(const uint32_t& aKey, 
   touches->AppendElement(aData);
   return PL_DHASH_NEXT;
 }
 
 void
 TouchManager::EvictTouches()
 {
   WidgetTouchEvent::AutoTouchArray touches;
-  PresShell::gCaptureTouchList->Enumerate(&AppendToTouchList, &touches);
+  gCaptureTouchList->Enumerate(&AppendToTouchList, &touches);
   for (uint32_t i = 0; i < touches.Length(); ++i) {
     EvictTouchPoint(touches[i], mDocument);
   }
 }
 
 bool
 TouchManager::PreHandleEvent(WidgetEvent* aEvent,
                              nsEventStatus* aStatus,
@@ -88,31 +105,31 @@ TouchManager::PreHandleEvent(WidgetEvent
     case NS_TOUCH_START: {
       aIsHandlingUserInput = true;
       WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
       // if there is only one touch in this touchstart event, assume that it is
       // the start of a new touch session and evict any old touches in the
       // queue
       if (touchEvent->touches.Length() == 1) {
         WidgetTouchEvent::AutoTouchArray touches;
-        PresShell::gCaptureTouchList->Enumerate(&AppendToTouchList, (void *)&touches);
+        gCaptureTouchList->Enumerate(&AppendToTouchList, (void *)&touches);
         for (uint32_t i = 0; i < touches.Length(); ++i) {
           EvictTouchPoint(touches[i]);
         }
       }
       // Add any new touches to the queue
       for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
         dom::Touch* touch = touchEvent->touches[i];
         int32_t id = touch->Identifier();
-        if (!PresShell::gCaptureTouchList->Get(id, nullptr)) {
+        if (!gCaptureTouchList->Get(id, nullptr)) {
           // If it is not already in the queue, it is a new touch
           touch->mChanged = true;
         }
         touch->mMessage = aEvent->message;
-        PresShell::gCaptureTouchList->Put(id, touch);
+        gCaptureTouchList->Put(id, touch);
       }
       break;
     }
     case NS_TOUCH_MOVE: {
       // Check for touches that changed. Mark them add to queue
       WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
       WidgetTouchEvent::TouchArray& touches = touchEvent->touches;
       bool haveChanged = false;
@@ -120,34 +137,34 @@ TouchManager::PreHandleEvent(WidgetEvent
         --i;
         dom::Touch* touch = touches[i];
         if (!touch) {
           continue;
         }
         int32_t id = touch->Identifier();
         touch->mMessage = aEvent->message;
 
-        nsRefPtr<dom::Touch> oldTouch = PresShell::gCaptureTouchList->GetWeak(id);
+        nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList->GetWeak(id);
         if (!oldTouch) {
           touches.RemoveElementAt(i);
           continue;
         }
         if (!touch->Equals(oldTouch)) {
           touch->mChanged = true;
           haveChanged = true;
         }
 
         nsCOMPtr<dom::EventTarget> targetPtr = oldTouch->mTarget;
         if (!targetPtr) {
           touches.RemoveElementAt(i);
           continue;
         }
         touch->SetTarget(targetPtr);
 
-        PresShell::gCaptureTouchList->Put(id, touch);
+        gCaptureTouchList->Put(id, touch);
         // if we're moving from touchstart to touchmove for this touch
         // we allow preventDefault to prevent mouse events
         if (oldTouch->mMessage != touch->mMessage) {
           aTouchIsNew = true;
         }
       }
       // is nothing has changed, we should just return
       if (!haveChanged) {
@@ -160,17 +177,17 @@ TouchManager::PreHandleEvent(WidgetEvent
           // work.
           for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
             if (touchEvent->touches[i]) {
               touchEvent->touches[i]->mChanged = true;
               break;
             }
           }
         } else {
-          if (PresShell::gPreventMouseEvents) {
+          if (gPreventMouseEvents) {
             *aStatus = nsEventStatus_eConsumeNoDefault;
           }
           return false;
         }
       }
       break;
     }
     case NS_TOUCH_END:
@@ -185,27 +202,27 @@ TouchManager::PreHandleEvent(WidgetEvent
         dom::Touch* touch = touches[i];
         if (!touch) {
           continue;
         }
         touch->mMessage = aEvent->message;
         touch->mChanged = true;
 
         int32_t id = touch->Identifier();
-        nsRefPtr<dom::Touch> oldTouch = PresShell::gCaptureTouchList->GetWeak(id);
+        nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList->GetWeak(id);
         if (!oldTouch) {
           continue;
         }
         nsCOMPtr<EventTarget> targetPtr = oldTouch->mTarget;
 
         aCurrentEventContent = do_QueryInterface(targetPtr);
         touch->SetTarget(targetPtr);
-        PresShell::gCaptureTouchList->Remove(id);
+        gCaptureTouchList->Remove(id);
       }
       // add any touches left in the touch list, but ensure changed=false
-      PresShell::gCaptureTouchList->Enumerate(&AppendToTouchList, (void *)&touches);
+      gCaptureTouchList->Enumerate(&AppendToTouchList, (void *)&touches);
       break;
     }
     default:
       break;
   }
   return true;
 }
--- a/layout/base/TouchManager.h
+++ b/layout/base/TouchManager.h
@@ -12,25 +12,32 @@
 #ifndef TouchManager_h_
 #define TouchManager_h_
 
 class PresShell;
 class nsIDocument;
 
 class TouchManager {
 public:
+  // Initialize and release static variables
+  static void InitializeStatics();
+  static void ReleaseStatics();
+
   void Init(PresShell* aPresShell, nsIDocument* aDocument);
   void Destroy();
 
   bool PreHandleEvent(mozilla::WidgetEvent* aEvent,
                       nsEventStatus* aStatus,
                       bool& aTouchIsNew,
                       bool& aIsHandlingUserInput,
                       nsCOMPtr<nsIContent>& aCurrentEventContent);
 
+  static bool gPreventMouseEvents;
+  static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch>* gCaptureTouchList;
+
 private:
   void EvictTouches();
 
   nsRefPtr<PresShell>   mPresShell;
   nsCOMPtr<nsIDocument> mDocument;
 };
 
 #endif /* !defined(TouchManager_h_) */
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1237,22 +1237,18 @@ public:
   virtual nsresult SetIsActive(bool aIsActive) = 0;
 
   bool IsActive()
   {
     return mIsActive;
   }
 
   // mouse capturing
-
   static CapturingContentInfo gCaptureInfo;
 
-  static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch>* gCaptureTouchList;
-  static bool gPreventMouseEvents;
-
   struct PointerCaptureInfo
   {
     nsCOMPtr<nsIContent> mPendingContent;
     nsCOMPtr<nsIContent> mOverrideContent;
     bool                 mReleaseContent;
     bool                 mPrimaryState;
     
     explicit PointerCaptureInfo(nsIContent* aPendingContent, bool aPrimaryState) :
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -91,16 +91,17 @@
 #include "nsRefreshDriver.h"
 #include "nsIContentViewer.h"
 #include "LayersLogging.h"
 #include "mozilla/Preferences.h"
 #include "nsFrameSelection.h"
 #include "FrameLayerBuilder.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/EventDispatcher.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #endif
 
 #include "GeckoProfiler.h"
 #include "nsAnimationManager.h"
 #include "nsTransitionManager.h"
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -196,20 +196,18 @@ using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 using namespace mozilla::layout;
 
 CapturingContentInfo nsIPresShell::gCaptureInfo =
   { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
     false /* mPreventDrag */, nullptr /* mContent */ };
 nsIContent* nsIPresShell::gKeyDownTarget;
-nsRefPtrHashtable<nsUint32HashKey, dom::Touch>* nsIPresShell::gCaptureTouchList;
 nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerCaptureInfo>* nsIPresShell::gPointerCaptureList;
 nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerInfo>* nsIPresShell::gActivePointersIds;
-bool nsIPresShell::gPreventMouseEvents = false;
 
 // convert a color value to a string, in the CSS format #RRGGBB
 // *  - initially created for bugs 31816, 20760, 22963
 static void ColorToString(nscolor aColor, nsAutoString &aString);
 
 // RangePaintInfo is used to paint ranges to offscreen buffers
 struct RangePaintInfo {
   nsRefPtr<nsRange> mRange;
@@ -7477,28 +7475,28 @@ PresShell::HandleEvent(nsIFrame* aFrame,
       uint32_t flags = 0;
       if (aEvent->message == NS_TOUCH_START) {
         flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
         WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
         // if this is a continuing session, ensure that all these events are
         // in the same document by taking the target of the events already in
         // the capture list
         nsCOMPtr<nsIContent> anyTarget;
-        if (gCaptureTouchList->Count() > 0 && touchEvent->touches.Length() > 1) {
-          gCaptureTouchList->Enumerate(&FindAnyTarget, &anyTarget);
+        if (TouchManager::gCaptureTouchList->Count() > 0 && touchEvent->touches.Length() > 1) {
+          TouchManager::gCaptureTouchList->Enumerate(&FindAnyTarget, &anyTarget);
         } else {
-          gPreventMouseEvents = false;
+          TouchManager::gPreventMouseEvents = false;
         }
 
         for (int32_t i = touchEvent->touches.Length(); i; ) {
           --i;
           dom::Touch* touch = touchEvent->touches[i];
 
           int32_t id = touch->Identifier();
-          if (!gCaptureTouchList->Get(id, nullptr)) {
+          if (!TouchManager::gCaptureTouchList->Get(id, nullptr)) {
             // find the target for this touch
             eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
                                                               touch->mRefPoint,
                                                               frame);
             nsIFrame* target = FindFrameTargetedByInputEvent(aEvent,
                                                              frame,
                                                              eventPoint,
                                                              flags);
@@ -7542,17 +7540,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
               frame = target;
             }
           } else {
             // This touch is an old touch, we need to ensure that is not
             // marked as changed and set its target correctly
             touch->mChanged = false;
             int32_t id = touch->Identifier();
 
-            nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList->GetWeak(id);
+            nsRefPtr<dom::Touch> oldTouch = TouchManager::gCaptureTouchList->GetWeak(id);
             if (oldTouch) {
               touch->SetTarget(oldTouch->mTarget);
             }
           }
         }
       } else {
         eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
       }
@@ -7648,17 +7646,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
         WidgetTouchEvent::TouchArray& touches = touchEvent->touches;
         for (uint32_t i = 0; i < touches.Length(); ++i) {
           dom::Touch* touch = touches[i];
           if (!touch) {
             break;
           }
 
           nsRefPtr<dom::Touch> oldTouch =
-            gCaptureTouchList->GetWeak(touch->Identifier());
+            TouchManager::gCaptureTouchList->GetWeak(touch->Identifier());
           if (!oldTouch) {
             break;
           }
 
           nsCOMPtr<nsIContent> content =
             do_QueryInterface(oldTouch->GetTarget());
           if (!content) {
             break;
@@ -8271,20 +8269,20 @@ PresShell::DispatchTouchEventToDOM(Widge
       contentPresShell->PopCurrentEventInfo();
     }
   }
 
   // if preventDefault was called on any of the events dispatched
   // and this is touchstart, or the first touchmove, widget should consume
   // other events that would be associated with this touch session
   if (preventDefault && canPrevent) {
-    gPreventMouseEvents = true;
-  }
-
-  if (gPreventMouseEvents) {
+    TouchManager::gPreventMouseEvents = true;
+  }
+
+  if (TouchManager::gPreventMouseEvents) {
     *aStatus = nsEventStatus_eConsumeNoDefault;
   } else {
     *aStatus = nsEventStatus_eIgnore;
   }
 }
 
 // Dispatch event to content only (NOT full processing)
 // See also HandleEventWithTarget which does full event processing.
@@ -10693,27 +10691,24 @@ nsAccessibilityService*
 nsIPresShell::AccService()
 {
   return GetAccService();
 }
 #endif
 
 void nsIPresShell::InitializeStatics()
 {
-  NS_ASSERTION(!gCaptureTouchList, "InitializeStatics called multiple times!");
-  gCaptureTouchList = new nsRefPtrHashtable<nsUint32HashKey, dom::Touch>;
+  NS_ASSERTION(!gPointerCaptureList, "InitializeStatics called multiple times!");
   gPointerCaptureList = new nsClassHashtable<nsUint32HashKey, PointerCaptureInfo>;
   gActivePointersIds = new nsClassHashtable<nsUint32HashKey, PointerInfo>;
 }
 
 void nsIPresShell::ReleaseStatics()
 {
-  NS_ASSERTION(gCaptureTouchList, "ReleaseStatics called without Initialize!");
-  delete gCaptureTouchList;
-  gCaptureTouchList = nullptr;
+  NS_ASSERTION(gPointerCaptureList, "ReleaseStatics called without Initialize!");
   delete gPointerCaptureList;
   gPointerCaptureList = nullptr;
   delete gActivePointersIds;
   gActivePointersIds = nullptr;
 }
 
 // Asks our docshell whether we're active.
 void PresShell::QueryIsActive()
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -129,16 +129,17 @@ using namespace mozilla::system;
 #include "nsCookieService.h"
 #include "nsApplicationCacheService.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/IMEStateManager.h"
 #include "nsDocument.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "CameraPreferences.h"
+#include "TouchManager.h"
 
 using namespace mozilla;
 using namespace mozilla::net;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 
 nsrefcnt nsLayoutStatics::sLayoutStaticRefcnt = 0;
 
@@ -262,16 +263,17 @@ nsLayoutStatics::Initialize()
   AsyncLatencyLogger::InitializeStatics();
   CubebUtils::InitLibrary();
 
   nsContentSink::InitializeStatics();
   nsHtml5Module::InitializeStatics();
   mozilla::dom::FallbackEncoding::Initialize();
   nsLayoutUtils::Initialize();
   nsIPresShell::InitializeStatics();
+  TouchManager::InitializeStatics();
   nsRefreshDriver::InitializeStatics();
 
   nsCORSListenerProxy::Startup();
 
   NS_SealStaticAtomTable();
 
   nsWindowMemoryReporter::Init();
 
@@ -398,16 +400,18 @@ nsLayoutStatics::Shutdown()
 #ifdef MOZ_WEBSPEECH
   nsSynthVoiceRegistry::Shutdown();
 #endif
 
   nsCORSListenerProxy::Shutdown();
 
   nsIPresShell::ReleaseStatics();
 
+  TouchManager::ReleaseStatics();
+
   nsTreeSanitizer::ReleaseStatics();
 
   nsHtml5Module::ReleaseStatics();
 
   mozilla::dom::FallbackEncoding::Shutdown();
 
   nsRegion::ShutdownStatic();