Bug 1016053 - document.createElement('StorageEvent') must be supported. r=smaug
☠☠ backed out by 450ca9dc47e6 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 28 May 2014 05:36:00 -0400
changeset 204703 457400a5938c0785b53561de85c9bf2481eecafa
parent 204702 e2e81f6206aba34575fe19d30d973a6a68ceae28
child 204704 b04ecdf990bd3f0a3dc92095e12d7566133d783c
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [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
@@ -827,16 +827,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,115 @@
+/* -*- 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;
+}
+
+nsresult
+NS_NEWDOMStorageEvent(nsIDOMEvent** aDOMEvent, EventTarget* aOwner)
+{
+  nsRefPtr<StorageEvent> e = new StorageEvent(aOwner);
+
+  e->SetTrusted(e->Init(aOwner));
+  e.forget(aDOMEvent);
+
+  return NS_OK;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/events/StorageEvent.h
@@ -0,0 +1,90 @@
+/* -*- 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;
+
+namespace mozilla {
+namespace dom {
+
+// Helper for EventDispatcher.
+nsresult NS_NEWDOMStorageEvent(nsIDOMEvent** aDOMEvent, EventTarget* aOwner);
+
+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',