Commit b61999d6 authored by beidson@apple.com's avatar beidson@apple.com

WebCore:

2008-04-15  Brady Eidson  <beidson@apple.com>

        Reviewed by Anders

        Hook up event dispatching for window.localStorage changes.

        Tests: storage/domstorage/localstorage/enumerate-storage.html
               storage/domstorage/localstorage/iframe-events.html
               storage/domstorage/localstorage/index-get-and-set.html
               storage/domstorage/localstorage/onstorage-attribute-markup.html
               storage/domstorage/localstorage/onstorage-attribute-setattribute.html
               storage/domstorage/localstorage/simple-events.html
               storage/domstorage/localstorage/simple-usage.html
               storage/domstorage/localstorage/window-open.html

        * storage/LocalStorage.cpp:
        (WebCore::LocalStorage::dispatchStorageEvent): Walk every Page in the PageGroup, adding
          each Frame that matches the storage area's security origin to a Vector.  Then dispatch
          the StorageEvent to each Frame in the Vector

        * storage/SessionStorage.cpp:
        (WebCore::SessionStorage::dispatchStorageEvent): Adopt the technique used in LocalStorage,
          which is to only add the Frames to the Vector if their security origin matches

LayoutTests:

2008-04-15  Brady Eidson  <beidson@apple.com>

        Reviewed by Anders

        Hook up event dispatching for window.localStorage changes.
        Now a meaningful LayoutTest suite can be landed for window.localStorage.

        * storage/domstorage/localstorage/enumerate-storage-expected.txt: Added.
        * storage/domstorage/localstorage/enumerate-storage.html: Added.
        * storage/domstorage/localstorage/iframe-events-expected.txt: Added.
        * storage/domstorage/localstorage/iframe-events.html: Added.
        * storage/domstorage/localstorage/index-get-and-set-expected.txt: Added.
        * storage/domstorage/localstorage/index-get-and-set.html: Added.
        * storage/domstorage/localstorage/onstorage-attribute-markup-expected.txt: Added.
        * storage/domstorage/localstorage/onstorage-attribute-markup.html: Added.
        * storage/domstorage/localstorage/onstorage-attribute-setattribute-expected.txt: Added.
        * storage/domstorage/localstorage/onstorage-attribute-setattribute.html: Added.
        * storage/domstorage/localstorage/resources: Added.
        * storage/domstorage/localstorage/resources/clearLocalStorage.js: Added.
        * storage/domstorage/localstorage/resources/iframe-events-second.html: Added.
        * storage/domstorage/localstorage/resources/window-open-second.html: Added.
        * storage/domstorage/localstorage/simple-events-expected.txt: Added.
        * storage/domstorage/localstorage/simple-events.html: Added.
        * storage/domstorage/localstorage/simple-usage-expected.txt: Added.
        * storage/domstorage/localstorage/simple-usage.html: Added.
        * storage/domstorage/localstorage/window-open-expected.txt: Added.
        * storage/domstorage/localstorage/window-open.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@31908 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c761d436
2008-04-15 Brady Eidson <beidson@apple.com>
Reviewed by Anders
Hook up event dispatching for window.localStorage changes.
Now a meaningful LayoutTest suite can be landed for window.localStorage.
* storage/domstorage/localstorage/enumerate-storage-expected.txt: Added.
* storage/domstorage/localstorage/enumerate-storage.html: Added.
* storage/domstorage/localstorage/iframe-events-expected.txt: Added.
* storage/domstorage/localstorage/iframe-events.html: Added.
* storage/domstorage/localstorage/index-get-and-set-expected.txt: Added.
* storage/domstorage/localstorage/index-get-and-set.html: Added.
* storage/domstorage/localstorage/onstorage-attribute-markup-expected.txt: Added.
* storage/domstorage/localstorage/onstorage-attribute-markup.html: Added.
* storage/domstorage/localstorage/onstorage-attribute-setattribute-expected.txt: Added.
* storage/domstorage/localstorage/onstorage-attribute-setattribute.html: Added.
* storage/domstorage/localstorage/resources: Added.
* storage/domstorage/localstorage/resources/clearLocalStorage.js: Added.
* storage/domstorage/localstorage/resources/iframe-events-second.html: Added.
* storage/domstorage/localstorage/resources/window-open-second.html: Added.
* storage/domstorage/localstorage/simple-events-expected.txt: Added.
* storage/domstorage/localstorage/simple-events.html: Added.
* storage/domstorage/localstorage/simple-usage-expected.txt: Added.
* storage/domstorage/localstorage/simple-usage.html: Added.
* storage/domstorage/localstorage/window-open-expected.txt: Added.
* storage/domstorage/localstorage/window-open.html: Added.
2008-04-14 Brady Eidson <beidson@apple.com>
Reviewed by Anders
This test checks to see that you can enumerate a Storage object and get only the keys as a result. The built-in properties of the Storage object should be ignored. The test operates on the localStorage object.
alpha
bar
batman
foo
fu
prototypeTestKey
zeta
<html>
<head>
<script src="resources/clearLocalStorage.js"></script>
<script>
if (layoutTestController)
layoutTestController.dumpAsText();
function log(a)
{
document.getElementById("logger").innerHTML += a + "<br>";
}
function finish()
{
if (layoutTestController)
layoutTestController.notifyDone()
}
function startTest()
{
if (!window.localStorage) {
log("window.localStorage DOES NOT exist");
return;
}
Storage.prototype.prototypeTestKey = "prototypeTestValue";
localStorage.foo = "bar";
localStorage.fu = "baz";
localStorage.batman = "bin suparman";
localStorage.bar = "foo";
localStorage.alpha = "beta";
localStorage.zeta = "gamma";
// Enumerate localStorage, appending each key onto an array
var enumeratedArray = new Array();
for (var n in localStorage)
enumeratedArray.push(n);
// Sort the array, since the storage order isn't guaranteed
enumeratedArray.sort();
for (var n in enumeratedArray)
log(enumeratedArray[n]);
}
</script>
</head>
<body onload="startTest();">
This test checks to see that you can enumerate a Storage object and get only the keys as a result. The built-in properties of the Storage object should be ignored. The test operates on the localStorage object.<br>
<div id="logger"></div>
</body>
</html>
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 change localStorage...
Main Frame received StorageEvent:
Key - Main Frame
New Value - SET
Old Value - null
Subframe received storage event:
Key - Main Frame
New Value - SET
Old Value - null
Subframe about to change localStorage...
Main Frame received StorageEvent:
Key - Subframe
New Value - SET
Old Value - null
Subframe received storage event:
Key - Subframe
New Value - SET
Old Value - null
<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("Main Frame received StorageEvent:");
log("Key - " + e.key);
log("New Value - " + e.newValue);
log("Old Value - " + e.oldValue);
log("");
if (e.key == "Subframe")
finish();
}
function startTest()
{
if (!window.localStorage) {
log("window.localStorage DOES NOT exist");
finish();
return;
}
document.body.addEventListener("storage", handleStorageEvent, false);
log("Main frame about to change localStorage...");
localStorage.setItem("Main Frame", "SET");
}
</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>
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
null
<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 (layoutTestController)
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) {
log("window.localStorage DOES NOT exist");
finish();
return;
}
document.body.addEventListener("storage", handleStorageEvent, false);
log("Setting FOO using the index setter.");
localStorage["FOO"] = "BAR";
log("Reading FOO:");
log(localStorage.FOO);
log(localStorage["FOO"]);
log(localStorage.getItem("FOO"));
log("");
log("Setting FOO again, using setItem.");
localStorage.setItem("FOO", "BAZ");
log("Reading FOO:");
log(localStorage.FOO);
log(localStorage["FOO"]);
log(localStorage.getItem("FOO"));
log("");
log("Setting FOO again, using the index setter.");
localStorage["FOO"] = "BAT";
log("Reading FOO:");
log(localStorage.FOO);
log(localStorage["FOO"]);
log(localStorage.getItem("FOO"));
log("");
log("Setting FOO again, using property-slot syntax");
localStorage.FOO = "BATMAN";
log("Reading FOO:");
log(localStorage.FOO);
log(localStorage["FOO"]);
log(localStorage.getItem("FOO"));
log("");
log("Removing FOO, then trying to read it");
localStorage.removeItem("FOO");
log("Reading FOO:");
log(localStorage.FOO);
log(localStorage["FOO"]);
log(localStorage.getItem("FOO"));
log("");
finish();
}
</script>
</head>
<body onload="runTest();">
This is a test to make sure you can get and set values in localStorage by index.<br>
<div id="logger"></div>
</body>
</html>
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
<html>
<head>
<script src="resources/clearLocalStorage.js"></script>
<script>
if (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>
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
<html>
<head>
<script src="resources/clearLocalStorage.js"></script>
<script>
if (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>
function clearLocalStorage()
{
var keys = new Array();
for (key in localStorage)
keys.push(key);
for (key in keys)
localStorage.removeItem(keys[key]);
}
if (window.localStorage)
clearLocalStorage();
<html>
<head>
<script>
function log(a)
{
parent.document.getElementById("logger").innerHTML += a + "<br>";
}
function handleStorageEvent(e)
{
log("Subframe received storage event:");
log("Key - " + e.key);
log("New Value - " + e.newValue);
log("Old Value - " + e.oldValue);
log("");
if (e.key != "Subframe") {
log("Subframe about to change localStorage...");
localStorage.setItem("Subframe", "SET");
}
}
</script>
</head>
<body onload="document.body.addEventListener('storage', handleStorageEvent, false);">
This is the subframe which exists to make sure that both frames of a same security origin receive the event for that origin's localStorage object mutating
</body>
</html>
<html>
<head>
<script>
var secondWindowLog = "Logging from second window:<br>";
function log(a)
{
secondWindowLog += a + "<br>";
}
function runTest()
{
if (!window.localStorage) {
log("window.localStorage DOES NOT exist");
return;
}
log("Value for FOO is " + window.localStorage.getItem("FOO"));
window.localStorage.setItem("FOO", "BAR-NEWWINDOW");
log("Value for FOO after changing my own copy is " + window.localStorage.getItem("FOO"));
log("Value for FOO in my opening window is " + window.opener.localStorage.getItem("FOO"));
window.opener.log(secondWindowLog);
if (layoutTestController)
layoutTestController.notifyDone();
}
</script>
</head>
<body onload="runTest();">
This is a new window to make sure the localStorage object for an origin is shared between multiple windows.<br>
</body>
</html>
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
Event has a source DOMWindow
Storage event fired:
Key - FU
New Value - BAR
Old Value - null
Event has a URI
Event has a source DOMWindow
Storage event fired:
Key - FOO
New Value - null
Old Value - BAR
Event has a URI
Event has a source DOMWindow
Storage event fired:
Key - FU
New Value - null
Old Value - BAR
Event has a URI
Event has a source DOMWindow
<html>
<head>
<script src="resources/clearLocalStorage.js"></script>
<script>
if (layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
function log(a)
{
document.getElementById("logger").innerHTML += a + "<br>";
}
function finish()
{
if (layoutTestController)
layoutTestController.notifyDone()
}
function handleStorageEvent(e)