Bug 1016053 - document.createElement('StorageEvent') must be supported, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 29 May 2014 14:33:00 +0100
changeset 185567 498162161226626fd168d1ea4a9c70bd3bc0c5b3
parent 185566 3ee661e747bdb222da2d46b58cb9d8a303a1999c
child 185568 1c823c4af27808514e8c4287795698db4212dd68
push id44120
push useramarchesini@mozilla.com
push dateThu, 29 May 2014 13:33:17 +0000
treeherdermozilla-inbound@498162161226 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1016053
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 1016053 - document.createElement('StorageEvent') must be supported, r=smaug
dom/events/EventDispatcher.cpp
dom/events/StorageEvent.cpp
dom/events/StorageEvent.h
dom/events/moz.build
dom/events/test/mochitest.ini
dom/events/test/test_dom_storage_event.html
dom/events/test/test_eventctors.html
dom/webidl/StorageEvent.webidl
dom/webidl/moz.build
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -11,16 +11,17 @@
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsINode.h"
 #include "nsPIDOMWindow.h"
 #include "GeckoProfiler.h"
 #include "GeneratedEvents.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/EventTarget.h"
+#include "mozilla/dom/StorageEvent.h"
 #include "mozilla/dom/TouchEvent.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
@@ -827,16 +828,20 @@ 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);
+  }
+
 
   // NEW EVENT TYPES SHOULD NOT BE ADDED HERE; THEY SHOULD USE ONLY EVENT
   // CONSTRUCTORS
 
   return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
 }
 
 } // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/events/StorageEvent.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 "mozilla/dom/StorageEvent.h"
+#include "nsIDOMStorage.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(StorageEvent)
+
+NS_IMPL_ADDREF_INHERITED(StorageEvent, Event)
+NS_IMPL_RELEASE_INHERITED(StorageEvent, Event)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(StorageEvent, Event)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStorageArea)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(StorageEvent, Event)
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(StorageEvent, Event)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mStorageArea)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(StorageEvent)
+NS_INTERFACE_MAP_END_INHERITING(Event)
+
+StorageEvent::StorageEvent(EventTarget* aOwner)
+  : Event(aOwner, nullptr, nullptr)
+{
+}
+
+StorageEvent::~StorageEvent()
+{
+}
+
+StorageEvent*
+StorageEvent::AsStorageEvent()
+{
+  return this;
+}
+
+JSObject*
+StorageEvent::WrapObject(JSContext* aCx)
+{
+  return StorageEventBinding::Wrap(aCx, this);
+}
+
+already_AddRefed<StorageEvent>
+StorageEvent::Constructor(EventTarget* aOwner,
+                          const nsAString& aType,
+                          const StorageEventInit& aEventInitDict)
+{
+  nsRefPtr<StorageEvent> e = new StorageEvent(aOwner);
+
+  bool trusted = e->Init(aOwner);
+  e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
+  e->mKey = aEventInitDict.mKey;
+  e->mOldValue = aEventInitDict.mOldValue;
+  e->mNewValue = aEventInitDict.mNewValue;
+  e->mUrl = aEventInitDict.mUrl;
+  e->mStorageArea = aEventInitDict.mStorageArea;
+  e->SetTrusted(trusted);
+
+  return e.forget();
+}
+
+already_AddRefed<StorageEvent>
+StorageEvent::Constructor(const GlobalObject& aGlobal,
+                          const nsAString& aType,
+                          const StorageEventInit& aEventInitDict,
+                          ErrorResult& aRv)
+{
+  nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
+  return Constructor(owner, aType, aEventInitDict);
+}
+
+void
+StorageEvent::InitStorageEvent(const nsAString& aType, bool aCanBubble,
+                               bool aCancelable, const nsAString& aKey,
+                               const nsAString& aOldValue,
+                               const nsAString& aNewValue,
+                               const nsAString& aURL,
+                               nsIDOMStorage* aStorageArea,
+                               ErrorResult& aRv)
+{
+  aRv = InitEvent(aType, aCanBubble, aCancelable);
+  if (aRv.Failed()) {
+    return;
+  }
+
+  mKey = aKey;
+  mOldValue = aOldValue;
+  mNewValue = aNewValue;
+  mUrl = aURL;
+  mStorageArea = aStorageArea;
+}
+
+} // namespace dom
+} // namespace mozilla
+
+nsresult
+NS_NewDOMStorageEvent(nsIDOMEvent** aDOMEvent,
+                      mozilla::dom::EventTarget* aOwner)
+{
+  nsRefPtr<mozilla::dom::StorageEvent> e =
+    new mozilla::dom::StorageEvent(aOwner);
+
+  e->SetTrusted(e->Init(aOwner));
+  e.forget(aDOMEvent);
+
+  return NS_OK;
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/events/StorageEvent.h
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_StorageEvent_h
+#define mozilla_dom_StorageEvent_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/Event.h"
+#include "mozilla/dom/StorageEventBinding.h"
+
+class nsIDOMStorage;
+
+// Helper for EventDispatcher.
+nsresult NS_NewDOMStorageEvent(nsIDOMEvent** aDOMEvent,
+                               mozilla::dom::EventTarget* aOwner);
+
+namespace mozilla {
+namespace dom {
+
+class StorageEvent : public Event
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(StorageEvent, Event)
+
+  StorageEvent(EventTarget* aOwner);
+  virtual ~StorageEvent();
+
+protected:
+  nsString mKey;
+  nsString mOldValue;
+  nsString mNewValue;
+  nsString mUrl;
+  nsCOMPtr<nsIDOMStorage> mStorageArea;
+
+public:
+  virtual StorageEvent* AsStorageEvent();
+
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  static already_AddRefed<StorageEvent>
+  Constructor(EventTarget* aOwner, const nsAString& aType,
+              const StorageEventInit& aEventInitDict);
+
+  static already_AddRefed<StorageEvent>
+  Constructor(const GlobalObject& aGlobal, const nsAString& aType,
+              const StorageEventInit& aEventInitDict, ErrorResult& aRv);
+
+  void InitStorageEvent(const nsAString& aType, bool aCanBubble,
+                        bool aCancelable, const nsAString& aKey,
+                        const nsAString& aOldValue,
+                        const nsAString& aNewValue,
+                        const nsAString& aURL,
+                        nsIDOMStorage* aStorageArea,
+                        ErrorResult& aRv);
+
+  void GetKey(nsString& aRetVal) const
+  {
+    aRetVal = mKey;
+  }
+
+  void GetOldValue(nsString& aRetVal) const
+  {
+    aRetVal = mOldValue;
+  }
+
+  void GetNewValue(nsString& aRetVal) const
+  {
+    aRetVal = mNewValue;
+  }
+
+  void GetUrl(nsString& aRetVal) const
+  {
+    aRetVal = mUrl;
+  }
+
+  nsIDOMStorage* GetStorageArea() const
+  {
+    return mStorageArea;
+  }
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_StorageEvent_h
--- a/dom/events/moz.build
+++ b/dom/events/moz.build
@@ -49,16 +49,17 @@ EXPORTS.mozilla.dom += [
     'MouseEvent.h',
     'MouseScrollEvent.h',
     'MutationEvent.h',
     'NotifyPaintEvent.h',
     'PaintRequest.h',
     'PointerEvent.h',
     'ScrollAreaEvent.h',
     'SimpleGestureEvent.h',
+    'StorageEvent.h',
     'Touch.h',
     'TouchEvent.h',
     'TransitionEvent.h',
     'UIEvent.h',
     'WheelEvent.h',
     'XULCommandEvent.h',
 ]
 
@@ -93,16 +94,17 @@ UNIFIED_SOURCES += [
     'MouseEvent.cpp',
     'MouseScrollEvent.cpp',
     'MutationEvent.cpp',
     'NotifyPaintEvent.cpp',
     'PaintRequest.cpp',
     'PointerEvent.cpp',
     'ScrollAreaEvent.cpp',
     'SimpleGestureEvent.cpp',
+    'StorageEvent.cpp',
     'TextComposition.cpp',
     'Touch.cpp',
     'TouchEvent.cpp',
     'TransitionEvent.cpp',
     'UIEvent.cpp',
     'WheelEvent.cpp',
     'WheelHandlingHelper.cpp',
     'XULCommandEvent.cpp',
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -150,8 +150,9 @@ skip-if = toolkit == 'android' #TIMED_OU
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_focus_disabled.html]
 [test_messageEvent.html]
 [test_moz_mouse_pixel_scroll_event.html]
 [test_onerror_handler_args.html]
 [test_wheel_default_action.html]
 skip-if = buildapp == 'b2g' || e10s
 [test_bug985988.html]
+[test_dom_storage_event.html]
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_dom_storage_event.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for DOM StorageEvent</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+const kTests = [
+  { createEventArg: "StorageEvent",
+    type: "aaa", bubbles: true, cancelable: true,
+    key: null, oldValue: 'a', newValue: 'b', url: 'c', storageArea: null },
+
+  { createEventArg: "storageevent",
+    type: "bbb", bubbles: false, cancelable: true,
+    key: 'key', oldValue: null, newValue: 'b', url: 'c', storageArea: null },
+
+  { createEventArg: "Storageevent",
+    type: "ccc", bubbles: true, cancelable: false,
+    key: 'key', oldValue: 'a', newValue: null, url: 'c', storageArea: null },
+
+  { createEventArg: "storageEvent",
+    type: "ddd", bubbles: false, cancelable: false,
+    key: 'key', oldValue: 'a', newValue: 'b', url: null, storageArea: null },
+
+  { createEventArg: "StorageEvent",
+    type: "eee", bubbles: true, cancelable: true,
+    key: 'key', oldValue: 'a', newValue: 'b', url: 'c', storageArea: null },
+
+  { createEventArg: "storageevent",
+    type: "fff", bubbles: false, cancelable: true,
+    key: null, oldValue: null, newValue: null, url: null, storageArea: null },
+  ];
+
+for (var i = 0; i < kTests.length; i++) {
+  var description = "test, Index: " + i + ", ";
+  const kTest = kTests[i];
+  var e = document.createEvent(kTest.createEventArg);
+  e.initStorageEvent(kTest.type, kTest.bubbles, kTest.cancelable,
+                     kTest.key, kTest.oldValue, kTest.newValue, kTest.url,
+                     kTest.storageArea);
+
+  for (var attr in kTest) {
+    if (attr == 'createEventArg')
+      continue;
+
+    is(e[attr], kTest[attr], description + attr + " returns wrong value");
+  }
+  is(e.isTrusted, false, description + "isTrusted returns wrong value");
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/events/test/test_eventctors.html
+++ b/dom/events/test/test_eventctors.html
@@ -554,16 +554,19 @@ 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/webidl/StorageEvent.webidl
+++ b/dom/webidl/StorageEvent.webidl
@@ -14,16 +14,27 @@ interface Storage;
 [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;
+
+  // Bug 1016053 - This is not spec compliant.
+  [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
@@ -309,16 +309,17 @@ WEBIDL_FILES = [
     'ServiceWorkerGlobalScope.webidl',
     'SettingsManager.webidl',
     'ShadowRoot.webidl',
     'SharedWorker.webidl',
     'SharedWorkerGlobalScope.webidl',
     'SimpleGestureEvent.webidl',
     'SourceBuffer.webidl',
     'SourceBufferList.webidl',
+    'StorageEvent.webidl',
     'StorageType.webidl',
     'StyleSheet.webidl',
     'StyleSheetList.webidl',
     'SubtleCrypto.webidl',
     'SVGAElement.webidl',
     'SVGAltGlyphElement.webidl',
     'SVGAngle.webidl',
     'SVGAnimatedAngle.webidl',
@@ -635,17 +636,16 @@ 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',