2010-01-22 Jeremy Orlow <jorlow@chromium.org>
authorjorlow@chromium.org <jorlow@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jan 2010 06:23:35 +0000 (06:23 +0000)
committerjorlow@chromium.org <jorlow@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jan 2010 06:23:35 +0000 (06:23 +0000)
        Reviewed by Darin Adler.

        Make storage events match the spec.
        https://bugs.webkit.org/show_bug.cgi?id=30546

        Update the storageEvent algorithm to match the change in WebCore.

        * src/StorageAreaProxy.cpp:
        (WebCore::StorageAreaProxy::storageEvent):
2010-01-22  Jeremy Orlow  <jorlow@chromium.org>

        Reviewed by Darin Adler.

        Make storage events match the spec.
        https://bugs.webkit.org/show_bug.cgi?id=30546

        This meat of the patch I just posted is very simple.  It's just making events
        asynchronous, not posting them to the frame that generated them, passing a null
        for the key when issuing a clear storage event, and making the events
        non-cancelable/non-bubbleable...all of which are clearly stated in the spec.

        The asynchronous and not posting to the frame that generated them forced me to
        re-write all the layout tests that dealt with storage events.  There's a lot of
        code there, but I tried to be fairly careful to ensure that test coverage did
        not shrink in any area.

        Tests: storage/domstorage/events/basic-body-attribute.html
               storage/domstorage/events/basic-setattribute.html
               storage/domstorage/events/basic.html
               storage/domstorage/events/case-sensitive.html
               storage/domstorage/events/documentURI.html

        * dom/Document.cpp:
        (WebCore::Document::Document):
        (WebCore::Document::enqueueStorageEvent):
        (WebCore::Document::storageEventTimerFired):
        * dom/Document.h:
        * storage/StorageEvent.cpp:
        (WebCore::StorageEvent::StorageEvent):
        * storage/StorageEvent.idl:
        * storage/StorageEventDispatcher.cpp:
        (WebCore::StorageEventDispatcher::dispatch):
2010-01-22  Jeremy Orlow  <jorlow@chromium.org>

        Reviewed by Darin Adler.

        Make storage events match the spec.
        https://bugs.webkit.org/show_bug.cgi?id=30546

        This meat of the patch I just posted is very simple.  It's just making events
        asynchronous, not posting them to the frame that generated them, passing a null
        for the key when issuing a clear storage event, and making the events
        non-cancelable/non-bubbleable...all of which are clearly stated in the spec.

        The asynchronous and not posting to the frame that generated them forced me to
        re-write all the layout tests that dealt with storage events.  There's a lot of
        code there, but I tried to be fairly careful to ensure that test coverage did
        not shrink in any area.

        * storage/domstorage/complex-values-expected.txt:
        * storage/domstorage/documentURI-expected.txt: Removed.
        * storage/domstorage/documentURI.html: Removed.
        * storage/domstorage/events: Added.
        * storage/domstorage/events/basic-body-attribute-expected.txt: Added.
        * storage/domstorage/events/basic-body-attribute.html: Added.
        * storage/domstorage/events/basic-expected.txt: Added.
        * storage/domstorage/events/basic-setattribute-expected.txt: Added.
        * storage/domstorage/events/basic-setattribute.html: Added.
        * storage/domstorage/events/basic.html: Added.
        * storage/domstorage/events/case-sensitive-expected.txt: Added.
        * storage/domstorage/events/case-sensitive.html: Added.
        * storage/domstorage/events/documentURI-expected.txt: Added.
        * storage/domstorage/events/documentURI.html: Added.
        * storage/domstorage/events/resources: Added.
        * storage/domstorage/events/resources/body-event-handler.html: Added.
        * storage/domstorage/events/resources/eventTestHarness.js: Added.
        * storage/domstorage/events/resources/setattribute-event-handler.html: Added.
        * storage/domstorage/events/script-tests: Added.
        * storage/domstorage/events/script-tests/TEMPLATE.html: Copied from LayoutTests/storage/domstorage/script-tests/TEMPLATE.html.
        * storage/domstorage/events/script-tests/basic-body-attribute.js: Added.
        * storage/domstorage/events/script-tests/basic-setattribute.js: Added.
        * storage/domstorage/events/script-tests/basic.js: Added.
        * storage/domstorage/events/script-tests/case-sensitive.js: Added.
        * storage/domstorage/events/script-tests/documentURI.js: Added.
        * storage/domstorage/localstorage/iframe-events-expected.txt: Removed.
        * storage/domstorage/localstorage/iframe-events.html: Removed.
        * storage/domstorage/localstorage/index-get-and-set-expected.txt:
        * storage/domstorage/localstorage/index-get-and-set.html:
        * storage/domstorage/localstorage/onstorage-attribute-markup-expected.txt: Removed.
        * storage/domstorage/localstorage/onstorage-attribute-markup.html: Removed.
        * storage/domstorage/localstorage/onstorage-attribute-setattribute-expected.txt: Removed.
        * storage/domstorage/localstorage/onstorage-attribute-setattribute.html: Removed.
        * storage/domstorage/localstorage/onstorage-attribute-setwindow-expected.txt: Removed.
        * storage/domstorage/localstorage/onstorage-attribute-setwindow.html: Removed.
        * storage/domstorage/localstorage/simple-events-expected.txt: Removed.
        * storage/domstorage/localstorage/simple-events.html: Removed.
        * storage/domstorage/script-tests/complex-values.js:
        * storage/domstorage/script-tests/documentURI.js: Removed.
        * storage/domstorage/sessionstorage/iframe-events-expected.txt: Removed.
        * storage/domstorage/sessionstorage/iframe-events.html: Removed.
        * storage/domstorage/sessionstorage/index-get-and-set-expected.txt:
        * storage/domstorage/sessionstorage/index-get-and-set.html:
        * storage/domstorage/sessionstorage/onstorage-attribute-markup-expected.txt: Removed.
        * storage/domstorage/sessionstorage/onstorage-attribute-markup.html: Removed.
        * storage/domstorage/sessionstorage/onstorage-attribute-setattribute-expected.txt: Removed.
        * storage/domstorage/sessionstorage/onstorage-attribute-setattribute.html: Removed.
        * storage/domstorage/sessionstorage/onstorage-attribute-setwindow-expected.txt: Removed.
        * storage/domstorage/sessionstorage/onstorage-attribute-setwindow.html: Removed.
        * storage/domstorage/sessionstorage/simple-events-expected.txt: Removed.
        * storage/domstorage/sessionstorage/simple-events.html: Removed.
        * storage/domstorage/window-attributes-exist-expected.txt:
        * storage/domstorage/window-attributes-exist.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@53840 268f45cc-cd09-0410-ab3c-d52691b4dbfc

58 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/domstorage/complex-values-expected.txt
LayoutTests/storage/domstorage/documentURI.html [deleted file]
LayoutTests/storage/domstorage/events/basic-body-attribute-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/events/basic-body-attribute.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/basic-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/events/basic-setattribute-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/events/basic-setattribute.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/basic.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/case-sensitive-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/events/case-sensitive.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/documentURI-expected.txt [moved from LayoutTests/storage/domstorage/documentURI-expected.txt with 61% similarity]
LayoutTests/storage/domstorage/events/documentURI.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/resources/body-event-handler.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/resources/eventTestHarness.js [new file with mode: 0644]
LayoutTests/storage/domstorage/events/resources/setattribute-event-handler.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/script-tests/TEMPLATE.html [new file with mode: 0644]
LayoutTests/storage/domstorage/events/script-tests/basic-body-attribute.js [new file with mode: 0644]
LayoutTests/storage/domstorage/events/script-tests/basic-setattribute.js [new file with mode: 0644]
LayoutTests/storage/domstorage/events/script-tests/basic.js [new file with mode: 0644]
LayoutTests/storage/domstorage/events/script-tests/case-sensitive.js [new file with mode: 0644]
LayoutTests/storage/domstorage/events/script-tests/documentURI.js [new file with mode: 0644]
LayoutTests/storage/domstorage/localstorage/iframe-events-expected.txt [deleted file]
LayoutTests/storage/domstorage/localstorage/iframe-events.html [deleted file]
LayoutTests/storage/domstorage/localstorage/index-get-and-set-expected.txt
LayoutTests/storage/domstorage/localstorage/index-get-and-set.html
LayoutTests/storage/domstorage/localstorage/onstorage-attribute-markup-expected.txt [deleted file]
LayoutTests/storage/domstorage/localstorage/onstorage-attribute-markup.html [deleted file]
LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setattribute-expected.txt [deleted file]
LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setattribute.html [deleted file]
LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setwindow-expected.txt [deleted file]
LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setwindow.html [deleted file]
LayoutTests/storage/domstorage/localstorage/simple-events-expected.txt [deleted file]
LayoutTests/storage/domstorage/localstorage/simple-events.html [deleted file]
LayoutTests/storage/domstorage/script-tests/complex-values.js
LayoutTests/storage/domstorage/script-tests/documentURI.js [deleted file]
LayoutTests/storage/domstorage/sessionstorage/iframe-events-expected.txt [deleted file]
LayoutTests/storage/domstorage/sessionstorage/iframe-events.html [deleted file]
LayoutTests/storage/domstorage/sessionstorage/index-get-and-set-expected.txt
LayoutTests/storage/domstorage/sessionstorage/index-get-and-set.html
LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-markup-expected.txt [deleted file]
LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-markup.html [deleted file]
LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute-expected.txt [deleted file]
LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute.html [deleted file]
LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setwindow-expected.txt [deleted file]
LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setwindow.html [deleted file]
LayoutTests/storage/domstorage/sessionstorage/simple-events-expected.txt [deleted file]
LayoutTests/storage/domstorage/sessionstorage/simple-events.html [deleted file]
LayoutTests/storage/domstorage/window-attributes-exist-expected.txt
LayoutTests/storage/domstorage/window-attributes-exist.html
WebCore/ChangeLog
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/storage/StorageEvent.cpp
WebCore/storage/StorageEvent.idl
WebCore/storage/StorageEventDispatcher.cpp
WebKit/chromium/ChangeLog
WebKit/chromium/src/StorageAreaProxy.cpp

index 1c8dfd5..0e8b124 100644 (file)
@@ -1,3 +1,74 @@
+2010-01-22  Jeremy Orlow  <jorlow@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Make storage events match the spec.
+        https://bugs.webkit.org/show_bug.cgi?id=30546
+
+        This meat of the patch I just posted is very simple.  It's just making events
+        asynchronous, not posting them to the frame that generated them, passing a null
+        for the key when issuing a clear storage event, and making the events
+        non-cancelable/non-bubbleable...all of which are clearly stated in the spec.
+
+        The asynchronous and not posting to the frame that generated them forced me to
+        re-write all the layout tests that dealt with storage events.  There's a lot of
+        code there, but I tried to be fairly careful to ensure that test coverage did
+        not shrink in any area.
+
+        * storage/domstorage/complex-values-expected.txt:
+        * storage/domstorage/documentURI-expected.txt: Removed.
+        * storage/domstorage/documentURI.html: Removed.
+        * storage/domstorage/events: Added.
+        * storage/domstorage/events/basic-body-attribute-expected.txt: Added.
+        * storage/domstorage/events/basic-body-attribute.html: Added.
+        * storage/domstorage/events/basic-expected.txt: Added.
+        * storage/domstorage/events/basic-setattribute-expected.txt: Added.
+        * storage/domstorage/events/basic-setattribute.html: Added.
+        * storage/domstorage/events/basic.html: Added.
+        * storage/domstorage/events/case-sensitive-expected.txt: Added.
+        * storage/domstorage/events/case-sensitive.html: Added.
+        * storage/domstorage/events/documentURI-expected.txt: Added.
+        * storage/domstorage/events/documentURI.html: Added.
+        * storage/domstorage/events/resources: Added.
+        * storage/domstorage/events/resources/body-event-handler.html: Added.
+        * storage/domstorage/events/resources/eventTestHarness.js: Added.
+        * storage/domstorage/events/resources/setattribute-event-handler.html: Added.
+        * storage/domstorage/events/script-tests: Added.
+        * storage/domstorage/events/script-tests/TEMPLATE.html: Copied from LayoutTests/storage/domstorage/script-tests/TEMPLATE.html.
+        * storage/domstorage/events/script-tests/basic-body-attribute.js: Added.
+        * storage/domstorage/events/script-tests/basic-setattribute.js: Added.
+        * storage/domstorage/events/script-tests/basic.js: Added.
+        * storage/domstorage/events/script-tests/case-sensitive.js: Added.
+        * storage/domstorage/events/script-tests/documentURI.js: Added.
+        * storage/domstorage/localstorage/iframe-events-expected.txt: Removed.
+        * storage/domstorage/localstorage/iframe-events.html: Removed.
+        * storage/domstorage/localstorage/index-get-and-set-expected.txt:
+        * storage/domstorage/localstorage/index-get-and-set.html:
+        * storage/domstorage/localstorage/onstorage-attribute-markup-expected.txt: Removed.
+        * storage/domstorage/localstorage/onstorage-attribute-markup.html: Removed.
+        * storage/domstorage/localstorage/onstorage-attribute-setattribute-expected.txt: Removed.
+        * storage/domstorage/localstorage/onstorage-attribute-setattribute.html: Removed.
+        * storage/domstorage/localstorage/onstorage-attribute-setwindow-expected.txt: Removed.
+        * storage/domstorage/localstorage/onstorage-attribute-setwindow.html: Removed.
+        * storage/domstorage/localstorage/simple-events-expected.txt: Removed.
+        * storage/domstorage/localstorage/simple-events.html: Removed.
+        * storage/domstorage/script-tests/complex-values.js:
+        * storage/domstorage/script-tests/documentURI.js: Removed.
+        * storage/domstorage/sessionstorage/iframe-events-expected.txt: Removed.
+        * storage/domstorage/sessionstorage/iframe-events.html: Removed.
+        * storage/domstorage/sessionstorage/index-get-and-set-expected.txt:
+        * storage/domstorage/sessionstorage/index-get-and-set.html:
+        * storage/domstorage/sessionstorage/onstorage-attribute-markup-expected.txt: Removed.
+        * storage/domstorage/sessionstorage/onstorage-attribute-markup.html: Removed.
+        * storage/domstorage/sessionstorage/onstorage-attribute-setattribute-expected.txt: Removed.
+        * storage/domstorage/sessionstorage/onstorage-attribute-setattribute.html: Removed.
+        * storage/domstorage/sessionstorage/onstorage-attribute-setwindow-expected.txt: Removed.
+        * storage/domstorage/sessionstorage/onstorage-attribute-setwindow.html: Removed.
+        * storage/domstorage/sessionstorage/simple-events-expected.txt: Removed.
+        * storage/domstorage/sessionstorage/simple-events.html: Removed.
+        * storage/domstorage/window-attributes-exist-expected.txt:
+        * storage/domstorage/window-attributes-exist.html:
+
 2010-01-25  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Darin Adler.
index 194b3b8..69d7644 100644 (file)
@@ -102,15 +102,6 @@ PASS storage.foo12 is "ÿ찡hello"
 PASS typeof storage.getItem('foo12') is "string"
 PASS storage.getItem('foo12') is "ÿ찡hello"
 
-Verify storage events are case sensitive
-storage.foo = 'test'
-Setting event listener
-PASS eventCounter is 0
-storage.foo = 'test'
-PASS eventCounter is 0
-storage.foo = 'TEST'
-PASS eventCounter is 1
-
 
 Testing localStorage
 storage.clear()
@@ -210,15 +201,6 @@ PASS typeof storage.foo12 is "string"
 PASS storage.foo12 is "ÿ찡hello"
 PASS typeof storage.getItem('foo12') is "string"
 PASS storage.getItem('foo12') is "ÿ찡hello"
-
-Verify storage events are case sensitive
-storage.foo = 'test'
-Setting event listener
-PASS eventCounter is 0
-storage.foo = 'test'
-PASS eventCounter is 0
-storage.foo = 'TEST'
-PASS eventCounter is 1
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/storage/domstorage/documentURI.html b/LayoutTests/storage/domstorage/documentURI.html
deleted file mode 100644 (file)
index 01f6a98..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<html>
-<head>
-<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
-<script src="../../fast/js/resources/js-test-pre.js"></script>
-<script src="../../fast/js/resources/js-test-post-function.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="script-tests/documentURI.js"></script>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/events/basic-body-attribute-expected.txt b/LayoutTests/storage/domstorage/events/basic-body-attribute-expected.txt
new file mode 100644 (file)
index 0000000..273c95b
--- /dev/null
@@ -0,0 +1,102 @@
+This is a test to make sure DOM Storage mutations fire StorageEvents that are caught by the event listener specified as an attribute on the body.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+iframe.onload = step1
+iframe.src = 'resources/body-event-handler.html'
+Reset storage event list
+storageEventList = new Array()
+storage.setItem('FOO', 'BAR')
+PASS storageEventList.length is 1
+PASS storageEventList[0].key is "FOO"
+PASS storageEventList[0].oldValue is null
+PASS storageEventList[0].newValue is "BAR"
+storage.setItem('FU', 'BAR')
+storage.setItem('a', '1')
+storage.setItem('b', '2')
+storage.setItem('b', '3')
+PASS storageEventList.length is 5
+PASS storageEventList[1].key is "FU"
+PASS storageEventList[1].oldValue is null
+PASS storageEventList[1].newValue is "BAR"
+PASS storageEventList[2].key is "a"
+PASS storageEventList[2].oldValue is null
+PASS storageEventList[2].newValue is "1"
+PASS storageEventList[3].key is "b"
+PASS storageEventList[3].oldValue is null
+PASS storageEventList[3].newValue is "2"
+PASS storageEventList[4].key is "b"
+PASS storageEventList[4].oldValue is "2"
+PASS storageEventList[4].newValue is "3"
+storage.removeItem('FOO')
+PASS storageEventList.length is 6
+PASS storageEventList[5].key is "FOO"
+PASS storageEventList[5].oldValue is "BAR"
+PASS storageEventList[5].newValue is null
+storage.removeItem('FU')
+PASS storageEventList.length is 7
+PASS storageEventList[6].key is "FU"
+PASS storageEventList[6].oldValue is "BAR"
+PASS storageEventList[6].newValue is null
+storage.clear()
+PASS storageEventList.length is 8
+PASS storageEventList[7].key is null
+PASS storageEventList[7].oldValue is null
+PASS storageEventList[7].newValue is null
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+iframe.onload = step1
+iframe.src = 'resources/body-event-handler.html'
+Reset storage event list
+storageEventList = new Array()
+storage.setItem('FOO', 'BAR')
+PASS storageEventList.length is 1
+PASS storageEventList[0].key is "FOO"
+PASS storageEventList[0].oldValue is null
+PASS storageEventList[0].newValue is "BAR"
+storage.setItem('FU', 'BAR')
+storage.setItem('a', '1')
+storage.setItem('b', '2')
+storage.setItem('b', '3')
+PASS storageEventList.length is 5
+PASS storageEventList[1].key is "FU"
+PASS storageEventList[1].oldValue is null
+PASS storageEventList[1].newValue is "BAR"
+PASS storageEventList[2].key is "a"
+PASS storageEventList[2].oldValue is null
+PASS storageEventList[2].newValue is "1"
+PASS storageEventList[3].key is "b"
+PASS storageEventList[3].oldValue is null
+PASS storageEventList[3].newValue is "2"
+PASS storageEventList[4].key is "b"
+PASS storageEventList[4].oldValue is "2"
+PASS storageEventList[4].newValue is "3"
+storage.removeItem('FOO')
+PASS storageEventList.length is 6
+PASS storageEventList[5].key is "FOO"
+PASS storageEventList[5].oldValue is "BAR"
+PASS storageEventList[5].newValue is null
+storage.removeItem('FU')
+PASS storageEventList.length is 7
+PASS storageEventList[6].key is "FU"
+PASS storageEventList[6].oldValue is "BAR"
+PASS storageEventList[6].newValue is null
+storage.clear()
+PASS storageEventList.length is 8
+PASS storageEventList[7].key is null
+PASS storageEventList[7].oldValue is null
+PASS storageEventList[7].newValue is null
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
diff --git a/LayoutTests/storage/domstorage/events/basic-body-attribute.html b/LayoutTests/storage/domstorage/events/basic-body-attribute.html
new file mode 100644 (file)
index 0000000..c2778ff
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/eventTestHarness.js"></script>
+<script src="script-tests/basic-body-attribute.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/events/basic-expected.txt b/LayoutTests/storage/domstorage/events/basic-expected.txt
new file mode 100644 (file)
index 0000000..bccdb5c
--- /dev/null
@@ -0,0 +1,98 @@
+This is a test to make sure DOM Storage mutations fire StorageEvents that are caught by the event listener set via window.onstorage.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+Reset storage event list
+storageEventList = new Array()
+storage.setItem('FOO', 'BAR')
+PASS storageEventList.length is 1
+PASS storageEventList[0].key is "FOO"
+PASS storageEventList[0].oldValue is null
+PASS storageEventList[0].newValue is "BAR"
+storage.setItem('FU', 'BAR')
+storage.setItem('a', '1')
+storage.setItem('b', '2')
+storage.setItem('b', '3')
+PASS storageEventList.length is 5
+PASS storageEventList[1].key is "FU"
+PASS storageEventList[1].oldValue is null
+PASS storageEventList[1].newValue is "BAR"
+PASS storageEventList[2].key is "a"
+PASS storageEventList[2].oldValue is null
+PASS storageEventList[2].newValue is "1"
+PASS storageEventList[3].key is "b"
+PASS storageEventList[3].oldValue is null
+PASS storageEventList[3].newValue is "2"
+PASS storageEventList[4].key is "b"
+PASS storageEventList[4].oldValue is "2"
+PASS storageEventList[4].newValue is "3"
+storage.removeItem('FOO')
+PASS storageEventList.length is 6
+PASS storageEventList[5].key is "FOO"
+PASS storageEventList[5].oldValue is "BAR"
+PASS storageEventList[5].newValue is null
+storage.removeItem('FU')
+PASS storageEventList.length is 7
+PASS storageEventList[6].key is "FU"
+PASS storageEventList[6].oldValue is "BAR"
+PASS storageEventList[6].newValue is null
+storage.clear()
+PASS storageEventList.length is 8
+PASS storageEventList[7].key is null
+PASS storageEventList[7].oldValue is null
+PASS storageEventList[7].newValue is null
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+Reset storage event list
+storageEventList = new Array()
+storage.setItem('FOO', 'BAR')
+PASS storageEventList.length is 1
+PASS storageEventList[0].key is "FOO"
+PASS storageEventList[0].oldValue is null
+PASS storageEventList[0].newValue is "BAR"
+storage.setItem('FU', 'BAR')
+storage.setItem('a', '1')
+storage.setItem('b', '2')
+storage.setItem('b', '3')
+PASS storageEventList.length is 5
+PASS storageEventList[1].key is "FU"
+PASS storageEventList[1].oldValue is null
+PASS storageEventList[1].newValue is "BAR"
+PASS storageEventList[2].key is "a"
+PASS storageEventList[2].oldValue is null
+PASS storageEventList[2].newValue is "1"
+PASS storageEventList[3].key is "b"
+PASS storageEventList[3].oldValue is null
+PASS storageEventList[3].newValue is "2"
+PASS storageEventList[4].key is "b"
+PASS storageEventList[4].oldValue is "2"
+PASS storageEventList[4].newValue is "3"
+storage.removeItem('FOO')
+PASS storageEventList.length is 6
+PASS storageEventList[5].key is "FOO"
+PASS storageEventList[5].oldValue is "BAR"
+PASS storageEventList[5].newValue is null
+storage.removeItem('FU')
+PASS storageEventList.length is 7
+PASS storageEventList[6].key is "FU"
+PASS storageEventList[6].oldValue is "BAR"
+PASS storageEventList[6].newValue is null
+storage.clear()
+PASS storageEventList.length is 8
+PASS storageEventList[7].key is null
+PASS storageEventList[7].oldValue is null
+PASS storageEventList[7].newValue is null
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
diff --git a/LayoutTests/storage/domstorage/events/basic-setattribute-expected.txt b/LayoutTests/storage/domstorage/events/basic-setattribute-expected.txt
new file mode 100644 (file)
index 0000000..99c7f18
--- /dev/null
@@ -0,0 +1,102 @@
+This is a test to make sure DOM Storage mutations fire StorageEvents that are caught by the event listener attached via setattribute.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+iframe.onload = step1
+iframe.src = 'resources/setattribute-event-handler.html'
+Reset storage event list
+storageEventList = new Array()
+storage.setItem('FOO', 'BAR')
+PASS storageEventList.length is 1
+PASS storageEventList[0].key is "FOO"
+PASS storageEventList[0].oldValue is null
+PASS storageEventList[0].newValue is "BAR"
+storage.setItem('FU', 'BAR')
+storage.setItem('a', '1')
+storage.setItem('b', '2')
+storage.setItem('b', '3')
+PASS storageEventList.length is 5
+PASS storageEventList[1].key is "FU"
+PASS storageEventList[1].oldValue is null
+PASS storageEventList[1].newValue is "BAR"
+PASS storageEventList[2].key is "a"
+PASS storageEventList[2].oldValue is null
+PASS storageEventList[2].newValue is "1"
+PASS storageEventList[3].key is "b"
+PASS storageEventList[3].oldValue is null
+PASS storageEventList[3].newValue is "2"
+PASS storageEventList[4].key is "b"
+PASS storageEventList[4].oldValue is "2"
+PASS storageEventList[4].newValue is "3"
+storage.removeItem('FOO')
+PASS storageEventList.length is 6
+PASS storageEventList[5].key is "FOO"
+PASS storageEventList[5].oldValue is "BAR"
+PASS storageEventList[5].newValue is null
+storage.removeItem('FU')
+PASS storageEventList.length is 7
+PASS storageEventList[6].key is "FU"
+PASS storageEventList[6].oldValue is "BAR"
+PASS storageEventList[6].newValue is null
+storage.clear()
+PASS storageEventList.length is 8
+PASS storageEventList[7].key is null
+PASS storageEventList[7].oldValue is null
+PASS storageEventList[7].newValue is null
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+iframe.onload = step1
+iframe.src = 'resources/setattribute-event-handler.html'
+Reset storage event list
+storageEventList = new Array()
+storage.setItem('FOO', 'BAR')
+PASS storageEventList.length is 1
+PASS storageEventList[0].key is "FOO"
+PASS storageEventList[0].oldValue is null
+PASS storageEventList[0].newValue is "BAR"
+storage.setItem('FU', 'BAR')
+storage.setItem('a', '1')
+storage.setItem('b', '2')
+storage.setItem('b', '3')
+PASS storageEventList.length is 5
+PASS storageEventList[1].key is "FU"
+PASS storageEventList[1].oldValue is null
+PASS storageEventList[1].newValue is "BAR"
+PASS storageEventList[2].key is "a"
+PASS storageEventList[2].oldValue is null
+PASS storageEventList[2].newValue is "1"
+PASS storageEventList[3].key is "b"
+PASS storageEventList[3].oldValue is null
+PASS storageEventList[3].newValue is "2"
+PASS storageEventList[4].key is "b"
+PASS storageEventList[4].oldValue is "2"
+PASS storageEventList[4].newValue is "3"
+storage.removeItem('FOO')
+PASS storageEventList.length is 6
+PASS storageEventList[5].key is "FOO"
+PASS storageEventList[5].oldValue is "BAR"
+PASS storageEventList[5].newValue is null
+storage.removeItem('FU')
+PASS storageEventList.length is 7
+PASS storageEventList[6].key is "FU"
+PASS storageEventList[6].oldValue is "BAR"
+PASS storageEventList[6].newValue is null
+storage.clear()
+PASS storageEventList.length is 8
+PASS storageEventList[7].key is null
+PASS storageEventList[7].oldValue is null
+PASS storageEventList[7].newValue is null
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
diff --git a/LayoutTests/storage/domstorage/events/basic-setattribute.html b/LayoutTests/storage/domstorage/events/basic-setattribute.html
new file mode 100644 (file)
index 0000000..2b95568
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/eventTestHarness.js"></script>
+<script src="script-tests/basic-setattribute.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/events/basic.html b/LayoutTests/storage/domstorage/events/basic.html
new file mode 100644 (file)
index 0000000..4c52d07
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/eventTestHarness.js"></script>
+<script src="script-tests/basic.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/events/case-sensitive-expected.txt b/LayoutTests/storage/domstorage/events/case-sensitive-expected.txt
new file mode 100644 (file)
index 0000000..6cdf19f
--- /dev/null
@@ -0,0 +1,38 @@
+Verify that storage events fire even when only the case of the value changes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+
+Verify storage events are case sensitive
+storage.foo = 'test'
+Reset storage event list
+storageEventList = new Array()
+storage.foo = 'test'
+PASS storageEventList.length is 0
+storage.foo = 'TEST'
+PASS storageEventList.length is 1
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+
+Verify storage events are case sensitive
+storage.foo = 'test'
+Reset storage event list
+storageEventList = new Array()
+storage.foo = 'test'
+PASS storageEventList.length is 0
+storage.foo = 'TEST'
+PASS storageEventList.length is 1
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
diff --git a/LayoutTests/storage/domstorage/events/case-sensitive.html b/LayoutTests/storage/domstorage/events/case-sensitive.html
new file mode 100644 (file)
index 0000000..c8da433
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/eventTestHarness.js"></script>
+<script src="script-tests/case-sensitive.js"></script>
+</body>
+</html>
@@ -1,4 +1,4 @@
-Test that changing documentURI has no effects on storage events.
+Test that changing documentURI has no effects on the uri passed into storage events.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
@@ -6,32 +6,35 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 Testing sessionStorage
 storage.clear()
 PASS storage.length is 0
-window.onstorage = firstEvent
+Reset storage event list
+storageEventList = new Array()
 storage.foo = '123'
-First event fired
+PASS storageEventList.length is 1
 Saving URI
 document.documentURI = 'abc'
 PASS document.documentURI is "abc"
-window.onstorage = secondEvent
 storage.foo = 'xyz'
-Second event fired
+PASS storageEventList.length is 2
 PASS true is true
 
 
 Testing localStorage
 storage.clear()
 PASS storage.length is 0
-window.onstorage = firstEvent
+Reset storage event list
+storageEventList = new Array()
 storage.foo = '123'
-First event fired
+PASS storageEventList.length is 1
 Saving URI
 document.documentURI = 'abc'
 PASS document.documentURI is "abc"
-window.onstorage = secondEvent
 storage.foo = 'xyz'
-Second event fired
+PASS storageEventList.length is 2
 PASS true is true
+
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
 
+
diff --git a/LayoutTests/storage/domstorage/events/documentURI.html b/LayoutTests/storage/domstorage/events/documentURI.html
new file mode 100644 (file)
index 0000000..7721e87
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/eventTestHarness.js"></script>
+<script src="script-tests/documentURI.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/events/resources/body-event-handler.html b/LayoutTests/storage/domstorage/events/resources/body-event-handler.html
new file mode 100644 (file)
index 0000000..a1218fe
--- /dev/null
@@ -0,0 +1,8 @@
+<html><head><script>
+
+function handleStorageEvent(e) {
+    window.parent.storageEventList.push(e);
+}
+
+</script></head><body onstorage="handleStorageEvent(window.event);">
+</body></html>
diff --git a/LayoutTests/storage/domstorage/events/resources/eventTestHarness.js b/LayoutTests/storage/domstorage/events/resources/eventTestHarness.js
new file mode 100644 (file)
index 0000000..8f15c31
--- /dev/null
@@ -0,0 +1,51 @@
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+iframe = document.createElement("IFRAME");
+iframe.src = "about:blank";
+document.body.appendChild(iframe);
+iframe.contentWindow.document.body.innerText = "Nothing to see here.";
+
+storageEventList = new Array();
+iframe.contentWindow.onstorage = function (e) {
+    window.parent.storageEventList.push(e);
+}
+
+function runAfterStorageEvents(callback) {
+    var currentCount = storageEventList.length;
+    function onTimeout() {
+        if (currentCount != storageEventList.length)
+            runAfterStorageEvents(callback);
+        else
+            callback();
+    }
+    setTimeout(onTimeout, 0);
+}
+
+function testStorages(testCallback)
+{
+    // When we're done testing LocalStorage, this is run.
+    function allDone()
+    {
+        debug("");
+        debug("");
+        window.successfullyParsed = true;
+        isSuccessfullyParsed();
+        debug("");
+        if (window.layoutTestController)
+            layoutTestController.notifyDone()
+    }
+
+    // When we're done testing with SessionStorage, this is run.
+    function runLocalStorage()
+    {
+        debug("");
+        debug("");
+        testCallback("localStorage", allDone);
+    }
+
+    // First run the test with SessionStorage.
+    testCallback("sessionStorage", runLocalStorage);
+}
diff --git a/LayoutTests/storage/domstorage/events/resources/setattribute-event-handler.html b/LayoutTests/storage/domstorage/events/resources/setattribute-event-handler.html
new file mode 100644 (file)
index 0000000..a764c53
--- /dev/null
@@ -0,0 +1,11 @@
+<html><head></head><body>
+<script>
+
+function handleStorageEvent(e) {
+    window.parent.storageEventList.push(e);
+}
+
+document.body.setAttribute("onstorage", "handleStorageEvent(window.event);");
+
+</script>
+</body></html>
diff --git a/LayoutTests/storage/domstorage/events/script-tests/TEMPLATE.html b/LayoutTests/storage/domstorage/events/script-tests/TEMPLATE.html
new file mode 100644 (file)
index 0000000..d9af438
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/eventTestHarness.js"></script>
+<script src="YOUR_JS_FILE_HERE"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/events/script-tests/basic-body-attribute.js b/LayoutTests/storage/domstorage/events/script-tests/basic-body-attribute.js
new file mode 100644 (file)
index 0000000..7054069
--- /dev/null
@@ -0,0 +1,98 @@
+description("This is a test to make sure DOM Storage mutations fire StorageEvents that are caught by the event listener specified as an attribute on the body.");
+
+function test(storageString, callback)
+{
+    window.completionCallback = callback;
+    window.storage = eval(storageString);
+    if (!storage) {
+        testFailed(storageString + " DOES NOT exist");
+        return;
+    }
+
+    debug("Testing " + storageString);
+
+    evalAndLog("storage.clear()");
+    shouldBe("storage.length", "0");
+
+    evalAndLog("iframe.onload = step1");
+    evalAndLog("iframe.src = 'resources/body-event-handler.html'");
+}
+
+function step1()
+{
+    debug("Reset storage event list");
+    evalAndLog("storageEventList = new Array()");
+    evalAndLog("storage.setItem('FOO', 'BAR')");
+
+    runAfterStorageEvents(step2);
+}
+
+function step2()
+{
+    shouldBe("storageEventList.length", "1");
+    shouldBeEqualToString("storageEventList[0].key", "FOO");
+    shouldBeNull("storageEventList[0].oldValue");
+    shouldBeEqualToString("storageEventList[0].newValue", "BAR");
+    evalAndLog("storage.setItem('FU', 'BAR')");
+    evalAndLog("storage.setItem('a', '1')");
+    evalAndLog("storage.setItem('b', '2')");
+    evalAndLog("storage.setItem('b', '3')");
+
+    runAfterStorageEvents(step3);
+}
+
+function step3()
+{
+    shouldBe("storageEventList.length", "5");
+    shouldBeEqualToString("storageEventList[1].key", "FU");
+    shouldBeNull("storageEventList[1].oldValue");
+    shouldBeEqualToString("storageEventList[1].newValue", "BAR");
+    shouldBeEqualToString("storageEventList[2].key", "a");
+    shouldBeNull("storageEventList[2].oldValue");
+    shouldBeEqualToString("storageEventList[2].newValue", "1");
+    shouldBeEqualToString("storageEventList[3].key", "b");
+    shouldBeNull("storageEventList[3].oldValue");
+    shouldBeEqualToString("storageEventList[3].newValue", "2");
+    shouldBeEqualToString("storageEventList[4].key", "b");
+    shouldBeEqualToString("storageEventList[4].oldValue", "2");
+    shouldBeEqualToString("storageEventList[4].newValue", "3");
+    evalAndLog("storage.removeItem('FOO')");
+
+    runAfterStorageEvents(step4);
+}
+
+function step4()
+{
+    shouldBe("storageEventList.length", "6");
+    shouldBeEqualToString("storageEventList[5].key", "FOO");
+    shouldBeEqualToString("storageEventList[5].oldValue", "BAR");
+    shouldBeNull("storageEventList[5].newValue");
+    evalAndLog("storage.removeItem('FU')");
+
+    runAfterStorageEvents(step5);
+}
+
+function step5()
+{
+    shouldBe("storageEventList.length", "7");
+    shouldBeEqualToString("storageEventList[6].key", "FU");
+    shouldBeEqualToString("storageEventList[6].oldValue", "BAR");
+    shouldBeNull("storageEventList[6].newValue");
+    evalAndLog("storage.clear()");
+    runAfterStorageEvents(step6);
+}
+
+function step6()
+{
+    shouldBe("storageEventList.length", "8");
+    shouldBeNull("storageEventList[7].key");
+    shouldBeNull("storageEventList[7].oldValue");
+    shouldBeNull("storageEventList[7].newValue");
+    completionCallback();
+}
+
+testStorages(test);
+
+var successfullyParsed = true;
diff --git a/LayoutTests/storage/domstorage/events/script-tests/basic-setattribute.js b/LayoutTests/storage/domstorage/events/script-tests/basic-setattribute.js
new file mode 100644 (file)
index 0000000..0da34a6
--- /dev/null
@@ -0,0 +1,98 @@
+description("This is a test to make sure DOM Storage mutations fire StorageEvents that are caught by the event listener attached via setattribute.");
+
+function test(storageString, callback)
+{
+    window.completionCallback = callback;
+    window.storage = eval(storageString);
+    if (!storage) {
+        testFailed(storageString + " DOES NOT exist");
+        return;
+    }
+
+    debug("Testing " + storageString);
+
+    evalAndLog("storage.clear()");
+    shouldBe("storage.length", "0");
+
+    evalAndLog("iframe.onload = step1");
+    evalAndLog("iframe.src = 'resources/setattribute-event-handler.html'");
+}
+
+function step1()
+{
+    debug("Reset storage event list");
+    evalAndLog("storageEventList = new Array()");
+    evalAndLog("storage.setItem('FOO', 'BAR')");
+
+    runAfterStorageEvents(step2);
+}
+
+function step2()
+{
+    shouldBe("storageEventList.length", "1");
+    shouldBeEqualToString("storageEventList[0].key", "FOO");
+    shouldBeNull("storageEventList[0].oldValue");
+    shouldBeEqualToString("storageEventList[0].newValue", "BAR");
+    evalAndLog("storage.setItem('FU', 'BAR')");
+    evalAndLog("storage.setItem('a', '1')");
+    evalAndLog("storage.setItem('b', '2')");
+    evalAndLog("storage.setItem('b', '3')");
+
+    runAfterStorageEvents(step3);
+}
+
+function step3()
+{
+    shouldBe("storageEventList.length", "5");
+    shouldBeEqualToString("storageEventList[1].key", "FU");
+    shouldBeNull("storageEventList[1].oldValue");
+    shouldBeEqualToString("storageEventList[1].newValue", "BAR");
+    shouldBeEqualToString("storageEventList[2].key", "a");
+    shouldBeNull("storageEventList[2].oldValue");
+    shouldBeEqualToString("storageEventList[2].newValue", "1");
+    shouldBeEqualToString("storageEventList[3].key", "b");
+    shouldBeNull("storageEventList[3].oldValue");
+    shouldBeEqualToString("storageEventList[3].newValue", "2");
+    shouldBeEqualToString("storageEventList[4].key", "b");
+    shouldBeEqualToString("storageEventList[4].oldValue", "2");
+    shouldBeEqualToString("storageEventList[4].newValue", "3");
+    evalAndLog("storage.removeItem('FOO')");
+
+    runAfterStorageEvents(step4);
+}
+
+function step4()
+{
+    shouldBe("storageEventList.length", "6");
+    shouldBeEqualToString("storageEventList[5].key", "FOO");
+    shouldBeEqualToString("storageEventList[5].oldValue", "BAR");
+    shouldBeNull("storageEventList[5].newValue");
+    evalAndLog("storage.removeItem('FU')");
+
+    runAfterStorageEvents(step5);
+}
+
+function step5()
+{
+    shouldBe("storageEventList.length", "7");
+    shouldBeEqualToString("storageEventList[6].key", "FU");
+    shouldBeEqualToString("storageEventList[6].oldValue", "BAR");
+    shouldBeNull("storageEventList[6].newValue");
+    evalAndLog("storage.clear()");
+    runAfterStorageEvents(step6);
+}
+
+function step6()
+{
+    shouldBe("storageEventList.length", "8");
+    shouldBeNull("storageEventList[7].key");
+    shouldBeNull("storageEventList[7].oldValue");
+    shouldBeNull("storageEventList[7].newValue");
+    completionCallback();
+}
+
+testStorages(test);
+
+var successfullyParsed = true;
diff --git a/LayoutTests/storage/domstorage/events/script-tests/basic.js b/LayoutTests/storage/domstorage/events/script-tests/basic.js
new file mode 100644 (file)
index 0000000..06591b1
--- /dev/null
@@ -0,0 +1,97 @@
+description("This is a test to make sure DOM Storage mutations fire StorageEvents that are caught by the event listener set via window.onstorage.");
+
+function test(storageString, callback)
+{
+    window.completionCallback = callback;
+    window.storage = eval(storageString);
+    if (!storage) {
+        testFailed(storageString + " DOES NOT exist");
+        return;
+    }
+
+    debug("Testing " + storageString);
+
+    evalAndLog("storage.clear()");
+    shouldBe("storage.length", "0");
+
+    runAfterStorageEvents(step1);
+}
+
+function step1()
+{
+    debug("Reset storage event list");
+    evalAndLog("storageEventList = new Array()");
+    evalAndLog("storage.setItem('FOO', 'BAR')");
+
+    runAfterStorageEvents(step2);
+}
+
+function step2()
+{
+    shouldBe("storageEventList.length", "1");
+    shouldBeEqualToString("storageEventList[0].key", "FOO");
+    shouldBeNull("storageEventList[0].oldValue");
+    shouldBeEqualToString("storageEventList[0].newValue", "BAR");
+    evalAndLog("storage.setItem('FU', 'BAR')");
+    evalAndLog("storage.setItem('a', '1')");
+    evalAndLog("storage.setItem('b', '2')");
+    evalAndLog("storage.setItem('b', '3')");
+
+    runAfterStorageEvents(step3);
+}
+
+function step3()
+{
+    shouldBe("storageEventList.length", "5");
+    shouldBeEqualToString("storageEventList[1].key", "FU");
+    shouldBeNull("storageEventList[1].oldValue");
+    shouldBeEqualToString("storageEventList[1].newValue", "BAR");
+    shouldBeEqualToString("storageEventList[2].key", "a");
+    shouldBeNull("storageEventList[2].oldValue");
+    shouldBeEqualToString("storageEventList[2].newValue", "1");
+    shouldBeEqualToString("storageEventList[3].key", "b");
+    shouldBeNull("storageEventList[3].oldValue");
+    shouldBeEqualToString("storageEventList[3].newValue", "2");
+    shouldBeEqualToString("storageEventList[4].key", "b");
+    shouldBeEqualToString("storageEventList[4].oldValue", "2");
+    shouldBeEqualToString("storageEventList[4].newValue", "3");
+    evalAndLog("storage.removeItem('FOO')");
+
+    runAfterStorageEvents(step4);
+}
+
+function step4()
+{
+    shouldBe("storageEventList.length", "6");
+    shouldBeEqualToString("storageEventList[5].key", "FOO");
+    shouldBeEqualToString("storageEventList[5].oldValue", "BAR");
+    shouldBeNull("storageEventList[5].newValue");
+    evalAndLog("storage.removeItem('FU')");
+
+    runAfterStorageEvents(step5);
+}
+
+function step5()
+{
+    shouldBe("storageEventList.length", "7");
+    shouldBeEqualToString("storageEventList[6].key", "FU");
+    shouldBeEqualToString("storageEventList[6].oldValue", "BAR");
+    shouldBeNull("storageEventList[6].newValue");
+    evalAndLog("storage.clear()");
+    runAfterStorageEvents(step6);
+}
+
+function step6()
+{
+    shouldBe("storageEventList.length", "8");
+    shouldBeNull("storageEventList[7].key");
+    shouldBeNull("storageEventList[7].oldValue");
+    shouldBeNull("storageEventList[7].newValue");
+    completionCallback();
+}
+
+testStorages(test);
+
+var successfullyParsed = true;
diff --git a/LayoutTests/storage/domstorage/events/script-tests/case-sensitive.js b/LayoutTests/storage/domstorage/events/script-tests/case-sensitive.js
new file mode 100644 (file)
index 0000000..b5038a8
--- /dev/null
@@ -0,0 +1,50 @@
+description("Verify that storage events fire even when only the case of the value changes.");
+
+function test(storageString, callback)
+{
+    window.completionCallback = callback;
+    window.storage = eval(storageString);
+    if (!storage) {
+        testFailed(storageString + " DOES NOT exist");
+        return;
+    }
+
+    debug("Testing " + storageString);
+
+    evalAndLog("storage.clear()");
+    shouldBe("storage.length", "0");
+
+    debug("");
+    debug("Verify storage events are case sensitive");
+    evalAndLog("storage.foo = 'test'");
+
+    runAfterStorageEvents(step1);
+}
+
+function step1()
+{
+    debug("Reset storage event list");
+    evalAndLog("storageEventList = new Array()");
+    evalAndLog("storage.foo = 'test'");
+
+    runAfterStorageEvents(step2);
+}
+
+function step2()
+{
+    shouldBe("storageEventList.length", "0");
+    evalAndLog("storage.foo = 'TEST'");
+
+    runAfterStorageEvents(step3);
+}
+
+function step3()
+{
+    shouldBe("storageEventList.length", "1");
+
+    completionCallback();
+}
+
+testStorages(test);
+
+var successfullyParsed = true;
diff --git a/LayoutTests/storage/domstorage/events/script-tests/documentURI.js b/LayoutTests/storage/domstorage/events/script-tests/documentURI.js
new file mode 100644 (file)
index 0000000..4b4f4cb
--- /dev/null
@@ -0,0 +1,52 @@
+description("Test that changing documentURI has no effects on the uri passed into storage events.");
+
+function test(storageString, callback)
+{
+    window.completionCallback = callback;
+    window.storage = eval(storageString);
+    if (!storage) {
+        testFailed(storageString + " DOES NOT exist");
+        return;
+    }
+
+    debug("Testing " + storageString);
+
+    evalAndLog("storage.clear()");
+    shouldBe("storage.length", "0");
+
+    runAfterStorageEvents(step1);
+}
+
+function step1()
+{
+    debug("Reset storage event list");
+    evalAndLog("storageEventList = new Array()");
+    evalAndLog("storage.foo = '123'");
+
+    runAfterStorageEvents(step2);
+}
+
+function step2()
+{
+    shouldBe("storageEventList.length", "1");
+    debug("Saving URI");
+    window.lastURI = storageEventList[0].uri;
+
+    evalAndLog("document.documentURI = 'abc'");
+    shouldBeEqualToString("document.documentURI", "abc");
+    evalAndLog("storage.foo = 'xyz'");
+
+    runAfterStorageEvents(step3);
+}
+
+function step3()
+{
+    shouldBe("storageEventList.length", "2");
+    shouldBeTrue(String(window.lastURI == storageEventList[1].uri));
+
+    completionCallback();
+}
+
+testStorages(test);
+
+var successfullyParsed = true;
diff --git a/LayoutTests/storage/domstorage/localstorage/iframe-events-expected.txt b/LayoutTests/storage/domstorage/localstorage/iframe-events-expected.txt
deleted file mode 100644 (file)
index d09ff0f..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-This is the main frame of a 2-frame document. Each frame is in the same security origin and therefore shares the same localStorage object. As a result, each frame should receive a StorageEvent when either frame changes the localStorage object.
-
-Main frame about to run setItem on localStorage...
-Main Frame received StorageEvent:
-Key - Main Frame
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/iframe-events.html
-Storage Area - This window's window.localStorage
-
-Subframe received storage event:
-Key - Main Frame
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/iframe-events.html
-Storage Area - This window's window.localStorage
-
-Subframe about to change localStorage...
-Main Frame received StorageEvent:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html
-Storage Area - This window's window.localStorage
-
-Subframe received storage event:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html
-Storage Area - This window's window.localStorage
-
-Main frame about to run removeItem on localStorage...
-Main Frame received StorageEvent:
-Key - Main Frame
-New Value - null
-Old Value - SET
-URI - LayoutTests/storage/domstorage/localstorage/iframe-events.html
-Storage Area - This window's window.localStorage
-
-Subframe received storage event:
-Key - Main Frame
-New Value - null
-Old Value - SET
-URI - LayoutTests/storage/domstorage/localstorage/iframe-events.html
-Storage Area - This window's window.localStorage
-
-Subframe about to change localStorage...
-Main frame about to clear localStorage...
-Main Frame received StorageEvent:
-Key - 
-New Value - null
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/iframe-events.html
-Storage Area - This window's window.localStorage
-
-Subframe received storage event:
-Key - 
-New Value - null
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/iframe-events.html
-Storage Area - This window's window.localStorage
-
-Subframe about to change localStorage...
-Main Frame received StorageEvent:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html
-Storage Area - This window's window.localStorage
-
-Subframe received storage event:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html
-Storage Area - This window's window.localStorage
-
-
diff --git a/LayoutTests/storage/domstorage/localstorage/iframe-events.html b/LayoutTests/storage/domstorage/localstorage/iframe-events.html
deleted file mode 100644 (file)
index 9f93157..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<html>
-<head>
-<script src="resources/clearLocalStorage.js"></script>
-<script>
-
-if (window.layoutTestController) {
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
-}
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function normalizeURL(url)
-{
-    return url.substring(url.lastIndexOf("LayoutTests"));
-}
-
-function finish()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone()
-}
-
-function handleStorageEvent(e)
-{
-    log("Main Frame received StorageEvent:");
-    log("Key           - " + e.key);
-    log("New Value     - " + e.newValue);
-    log("Old Value     - " + e.oldValue);
-    log("URI           - " + normalizeURL(e.uri));
-    log("Storage Area  - " + ((e.storageArea == window.localStorage) ? "This window's window.localStorage" : "Another window's window.localStorage"));
-    log("");
-    
-    if (e.key == "Subframe")
-        finish();
-}
-
-function startTest()
-{
-    if (!window.localStorage) {
-        log("window.localStorage DOES NOT exist");
-        finish();
-        return;
-    }
-
-    window.addEventListener("storage", handleStorageEvent, false);
-    log("Main frame about to run setItem on localStorage...");
-    localStorage.setItem("Main Frame", "SET");
-    log("Main frame about to run removeItem on localStorage...");
-    localStorage.removeItem("Main Frame");
-    log("Main frame about to clear localStorage...");
-    localStorage.clear();
-}
-
-</script>
-</head>
-<body onload="startTest();">
-This is the main frame of a 2-frame document.  Each frame is in the same security origin and therefore shares the same localStorage object.
-As a result, each frame should receive a StorageEvent when either frame changes the localStorage object.<br>
-<iframe src="resources/iframe-events-second.html"></iframe><br>
-<div id="logger"></div>
-</body>
-</html>
index 0698ede..ad58023 100644 (file)
@@ -1,54 +1,29 @@
 This is a test to make sure you can get and set values in localStorage by index.
 Setting FOO using the index setter.
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
 Reading FOO:
 BAR
 BAR
 BAR
 
 Setting FOO again, using setItem.
-Storage event fired:
-Key - FOO
-New Value - BAZ
-Old Value - BAR
-
 Reading FOO:
 BAZ
 BAZ
 BAZ
 
 Setting FOO again, using the index setter.
-Storage event fired:
-Key - FOO
-New Value - BAT
-Old Value - BAZ
-
 Reading FOO:
 BAT
 BAT
 BAT
 
 Setting FOO again, using property-slot syntax
-Storage event fired:
-Key - FOO
-New Value - BATMAN
-Old Value - BAT
-
 Reading FOO:
 BATMAN
 BATMAN
 BATMAN
 
 Removing FOO, then trying to read it
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BATMAN
-
 Reading FOO:
 undefined
 undefined
index b50b731..1026f51 100644 (file)
@@ -19,15 +19,6 @@ function finish()
         layoutTestController.notifyDone()
 }
 
-function handleStorageEvent(e)
-{
-    log("Storage event fired:");
-    log("Key           - " + e.key);
-    log("New Value     - " + e.newValue);
-    log("Old Value     - " + e.oldValue);
-    log("");
-}
-
 function runTest()
 {
     if (!window.localStorage) {
@@ -36,8 +27,6 @@ function runTest()
         return;
     }
     
-    window.addEventListener("storage", handleStorageEvent, false);
-    
     log("Setting FOO using the index setter.");
     localStorage["FOO"] = "BAR";
     log("Reading FOO:");
diff --git a/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-markup-expected.txt b/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-markup-expected.txt
deleted file mode 100644 (file)
index 05c347a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a test to make sure localStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage. The event listener is setup in the body element's markup.
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-
-
diff --git a/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-markup.html b/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-markup.html
deleted file mode 100644 (file)
index 91efc42..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<html>
-<head>
-<script src="resources/clearLocalStorage.js"></script>
-<script>
-
-if (window.layoutTestController)
-    layoutTestController.dumpAsText();
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function handleStorageEvent()
-{
-    if (!window.event) {
-        log("Global event not available.");
-        return;
-    }
-    
-    log("Storage event fired:");
-    log("Key           - " + event.key);
-    log("New Value     - " + event.newValue);
-    log("Old Value     - " + event.oldValue);
-    log("");
-}
-
-function runTest()
-{
-    if (!window.localStorage) {
-        log("window.localStorage DOES NOT exist");
-        return;
-    }
-    
-    window.localStorage.setItem("FOO", "BAR");
-    window.localStorage.setItem("FU", "BAR");
-    window.localStorage.removeItem("FOO");
-    window.localStorage.removeItem("FU");
-}
-
-</script>
-</head>
-<body onload="runTest();" onstorage="handleStorageEvent();">
-This is a test to make sure localStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage.  The event listener is setup in the body element's markup.<br>
-<div id="logger"></div>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setattribute-expected.txt b/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setattribute-expected.txt
deleted file mode 100644 (file)
index 837ff7b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a test to make sure LocalStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage. The event listener is setup via body.setAttribute().
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-
-
diff --git a/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setattribute.html b/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setattribute.html
deleted file mode 100644 (file)
index c55b9d7..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<html>
-<head>
-<script src="resources/clearLocalStorage.js"></script>
-<script>
-
-if (window.layoutTestController)
-    layoutTestController.dumpAsText();
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function handleStorageEvent()
-{
-    if (!window.event) {
-        log("Global event not available.");
-        return;
-    }
-    
-    log("Storage event fired:");
-    log("Key           - " + event.key);
-    log("New Value     - " + event.newValue);
-    log("Old Value     - " + event.oldValue);
-    log("");
-}
-
-function runTest()
-{
-    if (!window.localStorage) {
-        log("window.localStorage DOES NOT exist");
-        return;
-    }
-    
-    document.body.setAttribute("onstorage", "handleStorageEvent();");
-    
-    window.localStorage.setItem("FOO", "BAR");
-    window.localStorage.setItem("FU", "BAR");
-    window.localStorage.removeItem("FOO");
-    window.localStorage.removeItem("FU");
-}
-
-</script>
-</head>
-<body onload="runTest();">
-This is a test to make sure LocalStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage.  The event listener is setup via body.setAttribute().<br>
-<div id="logger"></div>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setwindow-expected.txt b/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setwindow-expected.txt
deleted file mode 100644 (file)
index e42bea7..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a test to make sure LocalStorage mutations fire StorageEvents that are caught by the event listener corresponding to window.onstorage.
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-
-
diff --git a/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setwindow.html b/LayoutTests/storage/domstorage/localstorage/onstorage-attribute-setwindow.html
deleted file mode 100644 (file)
index 65436ff..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<html>
-<head>
-<script src="resources/clearLocalStorage.js"></script>
-<script>
-
-if (window.layoutTestController)
-    layoutTestController.dumpAsText();
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function handleStorageEvent()
-{
-    if (!window.event) {
-        log("Global event not available.");
-        return;
-    }
-    
-    log("Storage event fired:");
-    log("Key           - " + event.key);
-    log("New Value     - " + event.newValue);
-    log("Old Value     - " + event.oldValue);
-    log("");
-}
-
-function runTest()
-{
-    if (!window.localStorage) {
-        log("window.localStorage DOES NOT exist");
-        return;
-    }
-
-    window.onstorage = handleStorageEvent;
-    
-    window.localStorage.setItem("FOO", "BAR");
-    window.localStorage.setItem("FU", "BAR");
-    window.localStorage.removeItem("FOO");
-    window.localStorage.removeItem("FU");
-}
-
-</script>
-</head>
-<body onload="runTest();">
-This is a test to make sure LocalStorage mutations fire StorageEvents that are caught by the event listener corresponding to window.onstorage.<br>
-<div id="logger"></div>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/simple-events-expected.txt b/LayoutTests/storage/domstorage/localstorage/simple-events-expected.txt
deleted file mode 100644 (file)
index 899a032..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-This is a test to make sure localStorage mutations fire StorageEvents
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-Event has a URI
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-Event has a URI
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-Event has a URI
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-Event has a URI
-
-
diff --git a/LayoutTests/storage/domstorage/localstorage/simple-events.html b/LayoutTests/storage/domstorage/localstorage/simple-events.html
deleted file mode 100644 (file)
index 8b0bf9e..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-<html>
-<head>
-<script src="resources/clearLocalStorage.js"></script>
-<script>
-
-if (window.layoutTestController) {
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
-}
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function finish()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone()
-}
-
-function handleStorageEvent(e)
-{
-    log("Storage event fired:");
-    log("Key           - " + e.key);
-    log("New Value     - " + e.newValue);
-    log("Old Value     - " + e.oldValue);
-    if (e.uri)
-        log("Event has a URI");
-    log("");
-}
-
-function runTest()
-{
-    if (!window.localStorage) {
-        log("window.localStorage DOES NOT exist");
-        finish();
-        return;
-    }
-    
-    window.addEventListener("storage", handleStorageEvent, false);
-
-    window.localStorage.setItem("FOO", "BAR");
-    window.localStorage.setItem("FU", "BAR");
-    window.localStorage.removeItem("FOO");
-    window.localStorage.removeItem("FU");
-    
-    finish();
-}
-
-</script>
-</head>
-<body onload="runTest();">
-This is a test to make sure localStorage mutations fire StorageEvents<br>
-<div id="logger"></div>
-</body>
-</html>
index dea9db8..8c6e29d 100644 (file)
@@ -1,10 +1,5 @@
 description("Test some corner case DOM Storage values.");
 
-eventCounter = 0;
-function handleStorageEvent() {
-    eventCounter++;
-}
-
 function testKeyValue(key, value)
 {
     keyString = "storage['" + key + "']";
@@ -73,21 +68,6 @@ function test(storageString)
     testKeyValue("foo11", k);
     evalAndLog("storage.setItem('foo12', k)");
     testKeyValue("foo12", k);
-
-    debug("");
-    debug("Verify storage events are case sensitive");
-    evalAndLog("storage.foo = 'test'");
-    debug("Setting event listener");
-    window.addEventListener("storage", handleStorageEvent, false);
-    shouldBe("eventCounter", "0");
-    evalAndLog("storage.foo = 'test'");
-    shouldBe("eventCounter", "0");
-    evalAndLog("storage.foo = 'TEST'");
-    shouldBe("eventCounter", "1");
-
-    // Reset the counter for next tests (if any).
-    window.removeEventListener("storage", handleStorageEvent, false);
-    eventCounter = 0;
 }
 
 test("sessionStorage");
diff --git a/LayoutTests/storage/domstorage/script-tests/documentURI.js b/LayoutTests/storage/domstorage/script-tests/documentURI.js
deleted file mode 100644 (file)
index 93fb08b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-description("Test that changing documentURI has no effects on storage events.");
-
-function test(storageString)
-{
-    window.storage = eval(storageString);
-    if (!storage) {
-        testFailed(storageString + " DOES NOT exist");
-        return;
-    }
-
-    debug("Testing " + storageString);
-
-    window.onstorage = null;
-    evalAndLog("storage.clear()");
-    shouldBe("storage.length", "0");
-
-    evalAndLog("window.onstorage = firstEvent");
-    evalAndLog("storage.foo = '123'");
-}
-
-function firstEvent(e)
-{
-    debug("First event fired");
-    debug("Saving URI");
-    window.lastURI = e.uri;
-
-    evalAndLog("document.documentURI = 'abc'");
-    shouldBeEqualToString("document.documentURI", "abc");
-
-    evalAndLog("window.onstorage = secondEvent");
-    evalAndLog("storage.foo = 'xyz'");
-}
-
-function secondEvent(e)
-{
-    debug("Second event fired");
-    shouldBeTrue(String(window.lastURI == e.uri));
-
-    if (done) {
-        window.successfullyParsed = true;
-        isSuccessfullyParsed();
-    }
-}
-
-window.done = false;
-test("sessionStorage");
-debug("");
-debug("");
-window.done = true;
-test("localStorage");
diff --git a/LayoutTests/storage/domstorage/sessionstorage/iframe-events-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/iframe-events-expected.txt
deleted file mode 100644 (file)
index 73c7b9d..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-This is the main frame of a 2-frame document. Each frame is in the same security origin and therefore shares the same sessionStorage object. As a result, each frame should receive a StorageEvent when either frame changes the sessionStorage object.
-
-Main frame about to run setItem on sessionStorage...
-Main Frame received StorageEvent:
-Key - Main Frame
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/iframe-events.html
-Storage Area - This window's window.sessionStorage
-
-Subframe received storage event:
-Key - Main Frame
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/iframe-events.html
-Storage Area - This window's window.sessionStorage
-
-Subframe about to change sessionStorage...
-Main Frame received StorageEvent:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html
-Storage Area - This window's window.sessionStorage
-
-Subframe received storage event:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html
-Storage Area - This window's window.sessionStorage
-
-Main frame about to run removeItem on sessionStorage...
-Main Frame received StorageEvent:
-Key - Main Frame
-New Value - null
-Old Value - SET
-URI - LayoutTests/storage/domstorage/sessionstorage/iframe-events.html
-Storage Area - This window's window.sessionStorage
-
-Subframe received storage event:
-Key - Main Frame
-New Value - null
-Old Value - SET
-URI - LayoutTests/storage/domstorage/sessionstorage/iframe-events.html
-Storage Area - This window's window.sessionStorage
-
-Subframe about to change sessionStorage...
-Main frame about to clear sessionStorage...
-Main Frame received StorageEvent:
-Key - 
-New Value - null
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/iframe-events.html
-Storage Area - This window's window.sessionStorage
-
-Subframe received storage event:
-Key - 
-New Value - null
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/iframe-events.html
-Storage Area - This window's window.sessionStorage
-
-Subframe about to change sessionStorage...
-Main Frame received StorageEvent:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html
-Storage Area - This window's window.sessionStorage
-
-Subframe received storage event:
-Key - Subframe
-New Value - SET
-Old Value - null
-URI - LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html
-Storage Area - This window's window.sessionStorage
-
-
diff --git a/LayoutTests/storage/domstorage/sessionstorage/iframe-events.html b/LayoutTests/storage/domstorage/sessionstorage/iframe-events.html
deleted file mode 100644 (file)
index 1775e62..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<html>
-<head>
-<script src="resources/clearSessionStorage.js"></script>
-<script>
-
-if (window.layoutTestController) {
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
-}
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function normalizeURL(url)
-{
-    return url.substring(url.lastIndexOf("LayoutTests"));
-}
-
-function finish()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone()
-}
-
-function handleStorageEvent(e)
-{
-    log("Main Frame received StorageEvent:");
-    log("Key           - " + e.key);
-    log("New Value     - " + e.newValue);
-    log("Old Value     - " + e.oldValue);
-    log("URI           - " + normalizeURL(e.uri));
-    log("Storage Area  - " + ((e.storageArea == window.sessionStorage) ? "This window's window.sessionStorage" : "Another window's window.sessionStorage"));
-    log("");
-    
-    if (e.key == "Subframe")
-        finish();
-}
-
-function startTest()
-{
-    if (!window.sessionStorage) {
-        log("window.sessionStorage DOES NOT exist");
-        finish();
-        return;
-    }
-    window.addEventListener("storage", handleStorageEvent, false);
-    log("Main frame about to run setItem on sessionStorage...");
-    sessionStorage.setItem("Main Frame", "SET");
-    log("Main frame about to run removeItem on sessionStorage...");
-    sessionStorage.removeItem("Main Frame");
-    log("Main frame about to clear sessionStorage...");
-    sessionStorage.clear();
-}
-
-</script>
-</head>
-<body onload="startTest();">
-This is the main frame of a 2-frame document.  Each frame is in the same security origin and therefore shares the same sessionStorage object.
-As a result, each frame should receive a StorageEvent when either frame changes the sessionStorage object.<br>
-<iframe src="resources/iframe-events-second.html"></iframe><br>
-<div id="logger"></div>
-</body>
-</html>
index f98ed7b..ff66bdc 100644 (file)
@@ -1,54 +1,29 @@
 This is a test to make sure you can get and set values in SessionStorage by index.
 Setting FOO using the index setter.
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
 Reading FOO:
 BAR
 BAR
 BAR
 
 Setting FOO again, using setItem.
-Storage event fired:
-Key - FOO
-New Value - BAZ
-Old Value - BAR
-
 Reading FOO:
 BAZ
 BAZ
 BAZ
 
 Setting FOO again, using the index setter.
-Storage event fired:
-Key - FOO
-New Value - BAT
-Old Value - BAZ
-
 Reading FOO:
 BAT
 BAT
 BAT
 
 Setting FOO again, using property-slot syntax
-Storage event fired:
-Key - FOO
-New Value - BATMAN
-Old Value - BAT
-
 Reading FOO:
 BATMAN
 BATMAN
 BATMAN
 
 Removing FOO, then trying to read it
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BATMAN
-
 Reading FOO:
 undefined
 undefined
index 16945cd..7922d0b 100644 (file)
@@ -19,15 +19,6 @@ function finish()
         layoutTestController.notifyDone()
 }
 
-function handleStorageEvent(e)
-{
-    log("Storage event fired:");
-    log("Key           - " + e.key);
-    log("New Value     - " + e.newValue);
-    log("Old Value     - " + e.oldValue);
-    log("");
-}
-
 function runTest()
 {
     if (!window.sessionStorage) {
@@ -36,8 +27,6 @@ function runTest()
         return;
     }
     
-    window.addEventListener("storage", handleStorageEvent, false);
-    
     log("Setting FOO using the index setter.");
     sessionStorage["FOO"] = "BAR";
     log("Reading FOO:");
diff --git a/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-markup-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-markup-expected.txt
deleted file mode 100644 (file)
index 732e66c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a test to make sure SessionStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage. The event listener is setup in the body element's markup.
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-
-
diff --git a/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-markup.html b/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-markup.html
deleted file mode 100644 (file)
index 8969047..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<html>
-<head>
-<script src="resources/clearSessionStorage.js"></script>
-<script>
-
-if (window.layoutTestController)
-    layoutTestController.dumpAsText();
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function handleStorageEvent()
-{
-    if (!window.event) {
-        log("Global event not available.");
-        return;
-    }
-    
-    log("Storage event fired:");
-    log("Key           - " + event.key);
-    log("New Value     - " + event.newValue);
-    log("Old Value     - " + event.oldValue);
-    log("");
-}
-
-function runTest()
-{
-    if (!window.sessionStorage) {
-        log("window.sessionStorage DOES NOT exist");
-        return;
-    }
-    
-    window.sessionStorage.setItem("FOO", "BAR");
-    window.sessionStorage.setItem("FU", "BAR");
-    window.sessionStorage.removeItem("FOO");
-    window.sessionStorage.removeItem("FU");
-}
-
-</script>
-</head>
-<body onload="runTest();" onstorage="handleStorageEvent();">
-This is a test to make sure SessionStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage.  The event listener is setup in the body element's markup.<br>
-<div id="logger"></div>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute-expected.txt
deleted file mode 100644 (file)
index 48da701..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a test to make sure SessionStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage. The event listener is setup via body.setAttribute().
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-
-
diff --git a/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute.html b/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute.html
deleted file mode 100644 (file)
index a7ecd46..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<html>
-<head>
-<script src="resources/clearSessionStorage.js"></script>
-<script>
-
-if (window.layoutTestController)
-    layoutTestController.dumpAsText();
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function handleStorageEvent()
-{
-    if (!window.event) {
-        log("Global event not available.");
-        return;
-    }
-    
-    log("Storage event fired:");
-    log("Key           - " + event.key);
-    log("New Value     - " + event.newValue);
-    log("Old Value     - " + event.oldValue);
-    log("");
-}
-
-function runTest()
-{
-    if (!window.sessionStorage) {
-        log("window.sessionStorage DOES NOT exist");
-        return;
-    }
-    
-    document.body.setAttribute("onstorage", "handleStorageEvent();");
-    
-    window.sessionStorage.setItem("FOO", "BAR");
-    window.sessionStorage.setItem("FU", "BAR");
-    window.sessionStorage.removeItem("FOO");
-    window.sessionStorage.removeItem("FU");
-}
-
-</script>
-</head>
-<body onload="runTest();">
-This is a test to make sure SessionStorage mutations fire StorageEvents that are caught by the event listener corresponding to body.onstorage.  The event listener is setup via body.setAttribute().<br>
-<div id="logger"></div>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setwindow-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setwindow-expected.txt
deleted file mode 100644 (file)
index 257dc52..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a test to make sure SessionStorage mutations fire StorageEvents that are caught by the event listener corresponding to window.onstorage.
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-
-
diff --git a/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setwindow.html b/LayoutTests/storage/domstorage/sessionstorage/onstorage-attribute-setwindow.html
deleted file mode 100644 (file)
index 3fd8225..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<html>
-<head>
-<script src="resources/clearSessionStorage.js"></script>
-<script>
-
-if (window.layoutTestController)
-    layoutTestController.dumpAsText();
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function handleStorageEvent()
-{
-    if (!window.event) {
-        log("Global event not available.");
-        return;
-    }
-    
-    log("Storage event fired:");
-    log("Key           - " + event.key);
-    log("New Value     - " + event.newValue);
-    log("Old Value     - " + event.oldValue);
-    log("");
-}
-
-function runTest()
-{
-    if (!window.sessionStorage) {
-        log("window.sessionStorage DOES NOT exist");
-        return;
-    }
-
-    window.onstorage = handleStorageEvent;
-    
-    window.sessionStorage.setItem("FOO", "BAR");
-    window.sessionStorage.setItem("FU", "BAR");
-    window.sessionStorage.removeItem("FOO");
-    window.sessionStorage.removeItem("FU");
-}
-
-</script>
-</head>
-<body onload="runTest();">
-This is a test to make sure SessionStorage mutations fire StorageEvents that are caught by the event listener corresponding to window.onstorage.<br>
-<div id="logger"></div>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/simple-events-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/simple-events-expected.txt
deleted file mode 100644 (file)
index c9133c0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-This is a test to make sure SessionStorage mutations fire StorageEvents
-Storage event fired:
-Key - FOO
-New Value - BAR
-Old Value - null
-Event has a URI
-
-Storage event fired:
-Key - FU
-New Value - BAR
-Old Value - null
-Event has a URI
-
-Storage event fired:
-Key - FOO
-New Value - null
-Old Value - BAR
-Event has a URI
-
-Storage event fired:
-Key - FU
-New Value - null
-Old Value - BAR
-Event has a URI
-
-
diff --git a/LayoutTests/storage/domstorage/sessionstorage/simple-events.html b/LayoutTests/storage/domstorage/sessionstorage/simple-events.html
deleted file mode 100644 (file)
index 0b0b11f..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-<html>
-<head>
-<script src="resources/clearSessionStorage.js"></script>
-<script>
-
-if (window.layoutTestController) {
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
-}
-
-function log(a)
-{
-    document.getElementById("logger").innerHTML += a + "<br>";
-}
-
-function finish()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone()
-}
-
-function handleStorageEvent(e)
-{
-    log("Storage event fired:");
-    log("Key           - " + e.key);
-    log("New Value     - " + e.newValue);
-    log("Old Value     - " + e.oldValue);
-    if (e.uri)
-        log("Event has a URI");
-    log("");
-}
-
-function runTest()
-{
-    if (!window.sessionStorage) {
-        log("window.sessionStorage DOES NOT exist");
-        finish();
-        return;
-    }
-    
-    window.addEventListener("storage", handleStorageEvent, false);
-
-    window.sessionStorage.setItem("FOO", "BAR");
-    window.sessionStorage.setItem("FU", "BAR");
-    window.sessionStorage.removeItem("FOO");
-    window.sessionStorage.removeItem("FU");
-    
-    finish();
-}
-
-</script>
-</head>
-<body onload="runTest();">
-This is a test to make sure SessionStorage mutations fire StorageEvents<br>
-<div id="logger"></div>
-</body>
-</html>
index 09b47c5..e7668fd 100644 (file)
@@ -18,5 +18,4 @@ Storage object localStorage has clear
 window.localStorage == window.localStorage: true
 window.localStorage === window.localStorage: true
 window.onstorage exists
-The onstorage property works when a storage event is fired.
 
index 3e3be04..d01ba7c 100644 (file)
@@ -26,16 +26,6 @@ function testStorage(name, storage)
         log("Storage object " + name + " has clear");
 }
 
-function testOnstorage()
-{
-    window.onstorage = function(event)
-    {
-        log("The onstorage property works when a storage event is fired.");
-    }
-    
-    window.localStorage["test"] = "test";
-}
-
 function runTest()
 {
     if ("sessionStorage" in window) {
@@ -54,10 +44,9 @@ function runTest()
     } else
         log("window.localStorage DOES NOT exist");
 
-    if ("onstorage" in window) {
+    if ("onstorage" in window)
         log("window.onstorage exists");
-        testOnstorage();
-    } else
+    else
         log("window.onstorage DOES NOT exist");
 }
 
index c059568..296453d 100644 (file)
@@ -1,3 +1,37 @@
+2010-01-22  Jeremy Orlow  <jorlow@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Make storage events match the spec.
+        https://bugs.webkit.org/show_bug.cgi?id=30546
+
+        This meat of the patch I just posted is very simple.  It's just making events
+        asynchronous, not posting them to the frame that generated them, passing a null
+        for the key when issuing a clear storage event, and making the events
+        non-cancelable/non-bubbleable...all of which are clearly stated in the spec.
+
+        The asynchronous and not posting to the frame that generated them forced me to
+        re-write all the layout tests that dealt with storage events.  There's a lot of
+        code there, but I tried to be fairly careful to ensure that test coverage did
+        not shrink in any area.
+
+        Tests: storage/domstorage/events/basic-body-attribute.html
+               storage/domstorage/events/basic-setattribute.html
+               storage/domstorage/events/basic.html
+               storage/domstorage/events/case-sensitive.html
+               storage/domstorage/events/documentURI.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::enqueueStorageEvent):
+        (WebCore::Document::storageEventTimerFired):
+        * dom/Document.h:
+        * storage/StorageEvent.cpp:
+        (WebCore::StorageEvent::StorageEvent):
+        * storage/StorageEvent.idl:
+        * storage/StorageEventDispatcher.cpp:
+        (WebCore::StorageEventDispatcher::dispatch):
+
 2010-01-25  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Darin Adler.
index 066b698..af456b4 100644 (file)
@@ -388,6 +388,7 @@ Document::Document(Frame* frame, bool isXHTML, bool isHTML)
     , m_normalWorldWrapperCache(0)
 #endif
     , m_usingGeolocation(false)
+    , m_storageEventTimer(this, &Document::storageEventTimerFired)
 #if ENABLE(WML)
     , m_containsWMLContent(false)
 #endif
@@ -2993,6 +2994,25 @@ void Document::dispatchWindowLoadEvent()
     domWindow->dispatchLoadEvent();
 }
 
+void Document::enqueueStorageEvent(PassRefPtr<Event> storageEvent)
+{
+    m_storageEventQueue.append(storageEvent);
+    if (!m_storageEventTimer.isActive())
+        m_storageEventTimer.startOneShot(0);
+}
+
+void Document::storageEventTimerFired(Timer<Document>*)
+{
+    ASSERT(!m_storageEventTimer.isActive());
+    Vector<RefPtr<Event> > storageEventQueue;
+    storageEventQueue.swap(m_storageEventQueue);
+
+    typedef Vector<RefPtr<Event> >::const_iterator Iterator;
+    Iterator end = storageEventQueue.end();
+    for (Iterator it = storageEventQueue.begin(); it != end; ++it)
+        dispatchWindowEvent(*it);
+}
+
 PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec)
 {
     RefPtr<Event> event;
index 94429e4..265b351 100644 (file)
@@ -618,6 +618,9 @@ public:
     void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0);
     void dispatchWindowLoadEvent();
 
+    void enqueueStorageEvent(PassRefPtr<Event>);
+    void storageEventTimerFired(Timer<Document>*);
+
     PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);
 
     // keep track of what types of event listeners are registered, so we don't
@@ -1183,6 +1186,9 @@ private:
 
     bool m_usingGeolocation;
 
+    Timer<Document> m_storageEventTimer;
+    Vector<RefPtr<Event> > m_storageEventQueue;
+
 #if ENABLE(WML)
     bool m_containsWMLContent;
 #endif
index 13ccfe9..126aca0 100644 (file)
@@ -47,7 +47,7 @@ PassRefPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const St
 }
 
 StorageEvent::StorageEvent(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& uri, Storage* storageArea)
-    : Event(type, false, true)
+    : Event(type, false, false)
     , m_key(key)
     , m_oldValue(oldValue)
     , m_newValue(newValue)
index 4f642e4..3e77eda 100644 (file)
@@ -28,7 +28,7 @@ module storage {
     interface [
         Conditional=DOM_STORAGE
     ] StorageEvent : Event {
-        readonly attribute DOMString key;
+        readonly attribute [ConvertNullStringTo=Null] DOMString key;
         readonly attribute [ConvertNullStringTo=Null] DOMString oldValue;
         readonly attribute [ConvertNullStringTo=Null] DOMString newValue;
         readonly attribute DOMString uri;
index 9763e07..dc0295b 100644 (file)
@@ -50,25 +50,25 @@ void StorageEventDispatcher::dispatch(const String& key, const String& oldValue,
     if (storageType == SessionStorage) {
         // Send events only to our page.
         for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
-            if (frame->document()->securityOrigin()->equal(securityOrigin))
+            if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
                 frames.append(frame);
         }
 
         for (unsigned i = 0; i < frames.size(); ++i)
-            frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
+            frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
     } else {
         // Send events to every page.
         const HashSet<Page*>& pages = page->group().pages();
         HashSet<Page*>::const_iterator end = pages.end();
         for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
             for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
-                if (frame->document()->securityOrigin()->equal(securityOrigin))
+                if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
                     frames.append(frame);
             }
         }
 
         for (unsigned i = 0; i < frames.size(); ++i)
-            frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage()));
+            frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage()));
     }
 }
 
index 0a26af3..cdf2127 100644 (file)
@@ -1,3 +1,15 @@
+2010-01-22  Jeremy Orlow  <jorlow@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Make storage events match the spec.
+        https://bugs.webkit.org/show_bug.cgi?id=30546
+
+        Update the storageEvent algorithm to match the change in WebCore.
+
+        * src/StorageAreaProxy.cpp:
+        (WebCore::StorageAreaProxy::storageEvent):
+
 2010-01-22  Elliot Glaysher  <erg@chromium.org>
 
         Reviewed by David Levin.
index 5381850..c9185fe 100644 (file)
@@ -119,25 +119,25 @@ void StorageAreaProxy::storageEvent(const String& key, const String& oldValue, c
     if (storageType == SessionStorage) {
         // Send events only to our page.
         for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
-            if (frame->document()->securityOrigin()->equal(securityOrigin))
+            if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
                 frames.append(frame);
         }
 
         for (unsigned i = 0; i < frames.size(); ++i)
-            frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
+            frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
     } else {
         // Send events to every page.
         const HashSet<Page*>& pages = page->group().pages();
         HashSet<Page*>::const_iterator end = pages.end();
         for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
             for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
-                if (frame->document()->securityOrigin()->equal(securityOrigin))
+                if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
                     frames.append(frame);
             }
         }
 
         for (unsigned i = 0; i < frames.size(); ++i)
-            frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage()));
+            frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage()));
     }
 }