Bug 1014657 - Port DOMStorageEvent to WebIDL and remove nsIDOMStorageEvent, r=smaug, f=ms2ger
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 23 May 2014 08:33:24 +0100
changeset 184607 f2b9e7e71113855e6b6c38e0b5fa6fe0fe38e0ae
parent 184606 9c9833f16a625acc0b689e39fa56b20e7b47f502
child 184608 efde4f7c20e54bdba4d38772b8e473544abdeeae
push id26826
push usercbook@mozilla.com
push dateFri, 23 May 2014 13:41:49 +0000
treeherdermozilla-central@e3d39ffacb5e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1014657
milestone32.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 1014657 - Port DOMStorageEvent to WebIDL and remove nsIDOMStorageEvent, r=smaug, f=ms2ger
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/events/EventDispatcher.cpp
dom/events/test/test_eventctors.html
dom/interfaces/storage/moz.build
dom/interfaces/storage/nsIDOMStorageEvent.idl
dom/src/storage/DOMStorage.cpp
dom/webidl/StorageEvent.webidl
dom/webidl/moz.build
js/xpconnect/src/event_impl_gen.conf.in
xpcom/reflect/xptinfo/src/ShimInterfaceInfo.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11143,22 +11143,25 @@ nsGlobalWindow::Observe(nsISupports* aSu
   if (!nsCRT::strcmp(aTopic, "dom-storage2-changed")) {
     if (!IsInnerWindow() || !IsCurrentInnerWindow()) {
       return NS_OK;
     }
 
     nsIPrincipal *principal;
     nsresult rv;
 
-    nsCOMPtr<nsIDOMStorageEvent> event = do_QueryInterface(aSubject, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIDOMStorage> changingStorage;
-    rv = event->GetStorageArea(getter_AddRefs(changingStorage));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsRefPtr<StorageEvent> event = static_cast<StorageEvent*>(aSubject);
+    if (!event) {
+      return NS_ERROR_FAILURE;
+    }
+
+    nsCOMPtr<nsIDOMStorage> changingStorage = event->GetStorageArea();
+    if (!changingStorage) {
+      return NS_ERROR_FAILURE;
+    }
 
     bool fireMozStorageChanged = false;
     principal = GetPrincipal();
     if (!principal) {
       return NS_OK;
     }
 
     nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(changingStorage);
@@ -11216,40 +11219,40 @@ nsGlobalWindow::Observe(nsISupports* aSu
       break;
     }
     default:
       return NS_OK;
     }
 
     // Clone the storage event included in the observer notification. We want
     // to dispatch clones rather than the original event.
-    rv = CloneStorageEvent(fireMozStorageChanged ?
-                           NS_LITERAL_STRING("MozStorageChanged") :
-                           NS_LITERAL_STRING("storage"),
-                           event);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    event->SetTrusted(true);
+    nsRefPtr<StorageEvent> newEvent =
+      CloneStorageEvent(fireMozStorageChanged ?
+                          NS_LITERAL_STRING("MozStorageChanged") :
+                          NS_LITERAL_STRING("storage"),
+                        event);
+
+    newEvent->SetTrusted(true);
 
     if (fireMozStorageChanged) {
-      WidgetEvent* internalEvent = event->GetInternalNSEvent();
+      WidgetEvent* internalEvent = newEvent->GetInternalNSEvent();
       internalEvent->mFlags.mOnlyChromeDispatch = true;
     }
 
     if (IsFrozen()) {
       // This window is frozen, rather than firing the events here,
       // store the domain in which the change happened and fire the
       // events if we're ever thawed.
 
-      mPendingStorageEvents.AppendObject(event);
+      mPendingStorageEvents.AppendElement(newEvent);
       return NS_OK;
     }
 
     bool defaultActionEnabled;
-    DispatchEvent((nsIDOMStorageEvent *)event, &defaultActionEnabled);
+    DispatchEvent(newEvent, &defaultActionEnabled);
 
     return NS_OK;
   }
 
   if (!nsCRT::strcmp(aTopic, "offline-cache-update-added")) {
     if (mApplicationCache)
       return NS_OK;
 
@@ -11314,55 +11317,40 @@ nsGlobalWindow::Observe(nsISupports* aSu
     bool dummy;
     return DispatchEvent(event, &dummy);
   }
 
   NS_WARNING("unrecognized topic in nsGlobalWindow::Observe");
   return NS_ERROR_FAILURE;
 }
 
-nsresult
+already_AddRefed<StorageEvent>
 nsGlobalWindow::CloneStorageEvent(const nsAString& aType,
-                                  nsCOMPtr<nsIDOMStorageEvent>& aEvent)
-{
-  nsresult rv;
-
-  bool canBubble;
-  bool cancelable;
-  nsAutoString key;
-  nsAutoString oldValue;
-  nsAutoString newValue;
-  nsAutoString url;
-  nsCOMPtr<nsIDOMStorage> storageArea;
-
-  nsCOMPtr<nsIDOMEvent> domEvent = do_QueryInterface(aEvent, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  domEvent->GetBubbles(&canBubble);
-  domEvent->GetCancelable(&cancelable);
-
-  aEvent->GetKey(key);
-  aEvent->GetOldValue(oldValue);
-  aEvent->GetNewValue(newValue);
-  aEvent->GetUrl(url);
-  aEvent->GetStorageArea(getter_AddRefs(storageArea));
-
-  NS_NewDOMStorageEvent(getter_AddRefs(domEvent), this, nullptr, nullptr);
-  aEvent = do_QueryInterface(domEvent);
-  return aEvent->InitStorageEvent(aType, canBubble, cancelable,
-                                  key, oldValue, newValue,
-                                  url, storageArea);
+                                  const nsRefPtr<StorageEvent>& aEvent)
+{
+  StorageEventInit dict;
+
+  dict.mBubbles = aEvent->Bubbles();
+  dict.mCancelable = aEvent->Cancelable();
+  aEvent->GetKey(dict.mKey);
+  aEvent->GetOldValue(dict.mOldValue);
+  aEvent->GetNewValue(dict.mNewValue);
+  aEvent->GetUrl(dict.mUrl);
+  dict.mStorageArea = aEvent->GetStorageArea();
+
+  nsRefPtr<StorageEvent> event = StorageEvent::Constructor(this, aType, dict);
+  return event.forget();
 }
 
 nsresult
 nsGlobalWindow::FireDelayedDOMEvents()
 {
   FORWARD_TO_INNER(FireDelayedDOMEvents, (), NS_ERROR_UNEXPECTED);
 
-  for (int32_t i = 0; i < mPendingStorageEvents.Count(); ++i) {
+  for (uint32_t i = 0, len = mPendingStorageEvents.Length(); i < len; ++i) {
     Observe(mPendingStorageEvents[i], "dom-storage2-changed", nullptr);
   }
 
   if (mApplicationCache) {
     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->FirePendingEvents();
   }
 
   if (mFireOfflineStatusChangeEventOnThaw) {
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -32,17 +32,18 @@
 #include "nsIScriptObjectPrincipal.h"
 #include "nsITimer.h"
 #include "nsIDOMModalContentWindow.h"
 #include "mozilla/EventListenerManager.h"
 #include "nsIPrincipal.h"
 #include "nsSize.h"
 #include "mozFlushType.h"
 #include "prclist.h"
-#include "nsIDOMStorageEvent.h"
+#include "mozilla/dom/StorageEvent.h"
+#include "mozilla/dom/StorageEventBinding.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIInlineEventHandlers.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsIIdleObserver.h"
 #include "nsIDocument.h"
 #include "nsIDOMTouchEvent.h"
@@ -1331,18 +1332,19 @@ protected:
   static void NotifyDOMWindowThawed(nsGlobalWindow* aWindow);
 
   void ClearStatus();
 
   virtual void UpdateParentTarget();
 
   inline int32_t DOMMinTimeoutValue() const;
 
-  nsresult CloneStorageEvent(const nsAString& aType,
-                             nsCOMPtr<nsIDOMStorageEvent>& aEvent);
+  already_AddRefed<mozilla::dom::StorageEvent>
+  CloneStorageEvent(const nsAString& aType,
+                    const nsRefPtr<mozilla::dom::StorageEvent>& aEvent);
 
   // Outer windows only.
   nsDOMWindowList* GetWindowList();
 
   // Helper for getComputedStyle and getDefaultComputedStyle
   already_AddRefed<nsICSSDeclaration>
     GetComputedStyleHelper(mozilla::dom::Element& aElt,
                            const nsAString& aPseudoElt,
@@ -1517,17 +1519,17 @@ protected:
   uint32_t                      mTimeoutPublicIdCounter;
   uint32_t                      mTimeoutFiringDepth;
   nsRefPtr<nsLocation>          mLocation;
   nsRefPtr<nsHistory>           mHistory;
 
   // These member variables are used on both inner and the outer windows.
   nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
 
-  typedef nsCOMArray<nsIDOMStorageEvent> nsDOMStorageEventArray;
+  typedef nsTArray<nsRefPtr<mozilla::dom::StorageEvent>> nsDOMStorageEventArray;
   nsDOMStorageEventArray mPendingStorageEvents;
 
   uint32_t mTimeoutsSuspendDepth;
 
   // the method that was used to focus mFocusedNode
   uint32_t mFocusMethod;
 
   uint32_t mSerial;
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -827,18 +827,16 @@ EventDispatcher::CreateEvent(EventTarget
   if (aEventType.LowerCaseEqualsLiteral("hashchangeevent"))
     return NS_NewDOMHashChangeEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("customevent"))
     return NS_NewDOMCustomEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("mozsmsevent"))
     return NS_NewDOMMozSmsEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("mozmmsevent"))
     return NS_NewDOMMozMmsEvent(aDOMEvent, aOwner, aPresContext, nullptr);
-  if (aEventType.LowerCaseEqualsLiteral("storageevent")) {
-    return NS_NewDOMStorageEvent(aDOMEvent, aOwner, aPresContext, nullptr);
-  }
+
   // NEW EVENT TYPES SHOULD NOT BE ADDED HERE; THEY SHOULD USE ONLY EVENT
   // CONSTRUCTORS
 
   return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
 }
 
 } // namespace mozilla
--- a/dom/events/test/test_eventctors.html
+++ b/dom/events/test/test_eventctors.html
@@ -545,19 +545,16 @@ ok(e.bubbles, "Event should bubble!");
 ok(e.cancelable, "Event should be cancelable!");
 is(e.detail, 1, "detail should be 1");
 is(e.view, window, "view should be window");
 document.dispatchEvent(e);
 is(receivedEvent, e, "Wrong event!");
 
 // StorageEvent
 
-e = document.createEvent("StorageEvent");
-ok(e, "Should have created an event!");
-
 try {
   e = new StorageEvent();
 } catch(exp) {
   ex = true;
 }
 ok(ex, "First parameter is required!");
 ex = false;
 
--- a/dom/interfaces/storage/moz.build
+++ b/dom/interfaces/storage/moz.build
@@ -1,17 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 XPIDL_SOURCES += [
     'nsIDOMStorage.idl',
-    'nsIDOMStorageEvent.idl',
     'nsIDOMStorageManager.idl',
 ]
 
 XPIDL_MODULE = 'dom_storage'
 
 EXPORTS += [
     'nsPIDOMStorage.h',
 ]
deleted file mode 100644
--- a/dom/interfaces/storage/nsIDOMStorageEvent.idl
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- 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/. */
-
-#include "domstubs.idl"
-#include "nsIDOMEvent.idl"
-
-/**
- * Interface for a client side storage. See
- * http://dev.w3.org/html5/webstorage/#the-storage-event
- * for more information.
- *
- * Event sent to a window when a storage area changes.
- */
-
-interface nsIDOMStorage;
-
-[builtinclass, uuid(85f04275-4679-4e89-b43f-142bbbab1e89)]
-interface nsIDOMStorageEvent : nsIDOMEvent
-{
-  /**
-   * Attribute represents the key being changed. The key attribute is null
-   * when change has been invoked by the storage clear() method.
-   */
-  readonly attribute DOMString key;
-
-  /**
-   * The original value of the key. The oldValue is null when the change
-   * has been invoked by storage clear() method or the key has been newly
-   * added and therefor doesn't have any previous value.
-   */
-  readonly attribute DOMString oldValue;
-
-  /**
-   * The new value of the key. The newValue is null when the change
-   * has been invoked by storage clear() method or the key has been removed
-   * from the storage.
-   */
-  readonly attribute DOMString newValue;
-
-  /**
-   * Represents the address of the document whose key changed.
-   */
-  readonly attribute DOMString url;
-
-  /**
-   * Represents the Storage object that was affected.
-   */
-  readonly attribute nsIDOMStorage storageArea;
-
-  /**
-   * Initialize the event in a manner analogous to the similarly-named method
-   * in the DOM Events interfaces.
-   */
-  void initStorageEvent(in DOMString typeArg, 
-                        in boolean canBubbleArg, 
-                        in boolean cancelableArg, 
-                        in DOMString keyArg,
-                        in DOMString oldValueArg,
-                        in DOMString newValueArg,
-                        in DOMString urlArg,
-                        in nsIDOMStorage storageAreaArg);
-};
--- a/dom/src/storage/DOMStorage.cpp
+++ b/dom/src/storage/DOMStorage.cpp
@@ -2,17 +2,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 "DOMStorage.h"
 #include "DOMStorageCache.h"
 #include "DOMStorageManager.h"
 
-#include "nsIDOMStorageEvent.h"
+#include "mozilla/dom/StorageEvent.h"
 #include "nsIObserverService.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIPrincipal.h"
 #include "nsICookiePermission.h"
 
 #include "nsDOMClassInfoID.h"
 #include "mozilla/Services.h"
@@ -185,33 +185,29 @@ StorageNotifierRunnable::Run()
 
 } // anonymous namespace
 
 void
 DOMStorage::BroadcastChangeNotification(const nsSubstring& aKey,
                                         const nsSubstring& aOldValue,
                                         const nsSubstring& aNewValue)
 {
-  nsCOMPtr<nsIDOMEvent> domEvent;
+  StorageEventInit dict;
+  dict.mBubbles = false;
+  dict.mCancelable = false;
+  dict.mKey = aKey;
+  dict.mNewValue = aNewValue;
+  dict.mOldValue = aOldValue;
+  dict.mStorageArea = static_cast<nsIDOMStorage*>(this);
+  dict.mUrl = mDocumentURI;
+
   // Note, this DOM event should never reach JS. It is cloned later in
   // nsGlobalWindow.
-  NS_NewDOMStorageEvent(getter_AddRefs(domEvent), nullptr, nullptr, nullptr);
-
-  nsCOMPtr<nsIDOMStorageEvent> event = do_QueryInterface(domEvent);
-  nsresult rv = event->InitStorageEvent(NS_LITERAL_STRING("storage"),
-                                        false,
-                                        false,
-                                        aKey,
-                                        aOldValue,
-                                        aNewValue,
-                                        mDocumentURI,
-                                        static_cast<nsIDOMStorage*>(this));
-  if (NS_FAILED(rv)) {
-    return;
-  }
+  nsRefPtr<StorageEvent> event =
+    StorageEvent::Constructor(nullptr, NS_LITERAL_STRING("storage"), dict);
 
   nsRefPtr<StorageNotifierRunnable> r =
     new StorageNotifierRunnable(event,
                                 GetType() == LocalStorage
                                   ? MOZ_UTF16("localStorage")
                                   : MOZ_UTF16("sessionStorage"));
   NS_DispatchToMainThread(r);
 }
--- a/dom/webidl/StorageEvent.webidl
+++ b/dom/webidl/StorageEvent.webidl
@@ -6,35 +6,24 @@
  * Interface for a client side storage. See
  * http://dev.w3.org/html5/webstorage/#the-storage-event
  * for more information.
  *
  * Event sent to a window when a storage area changes.
  */
 interface Storage;
 
-[Constructor(DOMString type, optional StorageEventInit eventInitDict), HeaderFile="GeneratedEventClasses.h"]
+[Constructor(DOMString type, optional StorageEventInit eventInitDict)]
 interface StorageEvent : Event
 {
   readonly attribute DOMString? key;
   readonly attribute DOMString? oldValue;
   readonly attribute DOMString? newValue;
   readonly attribute DOMString? url;
   readonly attribute Storage? storageArea;
-
-  // initStorageEvent is a Gecko specific deprecated method.
-  [Throws]
-  void initStorageEvent(DOMString type,
-                        boolean canBubble,
-                        boolean cancelable,
-                        DOMString? key,
-                        DOMString? oldValue,
-                        DOMString? newValue,
-                        DOMString? url,
-                        Storage? storageArea);
 };
 
 dictionary StorageEventInit : EventInit
 {
   DOMString? key = null;
   DOMString? oldValue = null;
   DOMString? newValue = null;
   DOMString url = "";
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -529,17 +529,16 @@ WEBIDL_FILES += [
     'MozSettingsEvent.webidl',
     'MozSmsEvent.webidl',
     'PageTransitionEvent.webidl',
     'PopStateEvent.webidl',
     'PopupBlockedEvent.webidl',
     'ProgressEvent.webidl',
     'RecordErrorEvent.webidl',
     'SmartCardEvent.webidl',
-    'StorageEvent.webidl',
     'StyleRuleChangeEvent.webidl',
     'StyleSheetApplicableStateChangeEvent.webidl',
     'StyleSheetChangeEvent.webidl',
 ]
 
 # We only expose our prefable test interfaces in debug builds, just to be on
 # the safe side.
 if CONFIG['MOZ_DEBUG']:
@@ -636,16 +635,17 @@ GENERATED_EVENTS_WEBIDL_FILES = [
     'MozEmergencyCbModeEvent.webidl',
     'MozInterAppMessageEvent.webidl',
     'MozOtaStatusEvent.webidl',
     'MozStkCommandEvent.webidl',
     'RTCDataChannelEvent.webidl',
     'RTCPeerConnectionIceEvent.webidl',
     'RTCPeerConnectionIdentityErrorEvent.webidl',
     'RTCPeerConnectionIdentityEvent.webidl',
+    'StorageEvent.webidl',
     'TrackEvent.webidl',
     'UserProximityEvent.webidl',
     'USSDReceivedEvent.webidl',
 ]
 
 if CONFIG['MOZ_GAMEPAD']:
     GENERATED_EVENTS_WEBIDL_FILES += [
         'GamepadAxisMoveEvent.webidl',
--- a/js/xpconnect/src/event_impl_gen.conf.in
+++ b/js/xpconnect/src/event_impl_gen.conf.in
@@ -4,17 +4,16 @@
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
  The name of the event which real interface should have nsIDOM-prefix,
  and should be in nsIDOM<name>.idl file and which should have
  <name>Init dictionary for the event constructor. """
 
 simple_events = [
     'ProgressEvent',
-    'StorageEvent',
     'MozSettingsEvent',
     'CustomEvent',
     'PageTransitionEvent',
     'DOMTransactionEvent',
     'PopStateEvent',
     'HashChangeEvent',
     'CloseEvent',
     'DeviceOrientationEvent',
--- a/xpcom/reflect/xptinfo/src/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/src/ShimInterfaceInfo.cpp
@@ -147,17 +147,16 @@
 #include "nsIDOMScrollAreaEvent.h"
 #include "nsIDOMSerializer.h"
 #include "nsIDOMSimpleGestureEvent.h"
 #include "nsIDOMSmartCardEvent.h"
 #ifdef MOZ_WEBSPEECH
 #include "nsIDOMSpeechRecognitionEvent.h"
 #include "nsIDOMSpeechSynthesisEvent.h"
 #endif // MOZ_WEBSPEECH
-#include "nsIDOMStorageEvent.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsIDOMStyleSheetList.h"
 #include "nsIDOMStyleRuleChangeEvent.h"
 #include "nsIDOMStyleSheetApplicableStateChangeEvent.h"
 #include "nsIDOMStyleSheetChangeEvent.h"
 #include "nsIDOMSVGElement.h"
 #include "nsIDOMSVGLength.h"
 #include "nsIDOMText.h"
@@ -505,17 +504,16 @@ const ComponentsInterfaceShimEntry kComp
   DEFINE_SHIM(ScrollAreaEvent),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMSerializer, XMLSerializer),
   DEFINE_SHIM(SimpleGestureEvent),
   DEFINE_SHIM(SmartCardEvent),
 #ifdef MOZ_WEBSPEECH
   DEFINE_SHIM(SpeechRecognitionEvent),
   DEFINE_SHIM(SpeechSynthesisEvent),
 #endif // MOZ_WEBSPEECH
-  DEFINE_SHIM(StorageEvent),
   DEFINE_SHIM(StyleSheet),
   DEFINE_SHIM(StyleSheetList),
   DEFINE_SHIM(StyleRuleChangeEvent),
   DEFINE_SHIM(StyleSheetApplicableStateChangeEvent),
   DEFINE_SHIM(StyleSheetChangeEvent),
   DEFINE_SHIM(SVGElement),
   DEFINE_SHIM(SVGLength),
   DEFINE_SHIM(Text),