summaryrefslogtreecommitdiffstats
path: root/LayoutTests/storage/domstorage
diff options
context:
space:
mode:
Diffstat (limited to 'LayoutTests/storage/domstorage')
-rw-r--r--LayoutTests/storage/domstorage/clear-expected.txt35
-rw-r--r--LayoutTests/storage/domstorage/clear.html12
-rw-r--r--LayoutTests/storage/domstorage/complex-keys-expected.txt237
-rw-r--r--LayoutTests/storage/domstorage/complex-keys.html12
-rw-r--r--LayoutTests/storage/domstorage/complex-values-expected.txt207
-rw-r--r--LayoutTests/storage/domstorage/complex-values.html12
-rw-r--r--LayoutTests/storage/domstorage/events/basic-body-attribute-expected.txt102
-rw-r--r--LayoutTests/storage/domstorage/events/basic-body-attribute.html13
-rw-r--r--LayoutTests/storage/domstorage/events/basic-expected.txt98
-rw-r--r--LayoutTests/storage/domstorage/events/basic-setattribute-expected.txt102
-rw-r--r--LayoutTests/storage/domstorage/events/basic-setattribute.html13
-rw-r--r--LayoutTests/storage/domstorage/events/basic.html13
-rw-r--r--LayoutTests/storage/domstorage/events/case-sensitive-expected.txt38
-rw-r--r--LayoutTests/storage/domstorage/events/case-sensitive.html13
-rw-r--r--LayoutTests/storage/domstorage/events/documentURI-expected.txt40
-rw-r--r--LayoutTests/storage/domstorage/events/documentURI.html13
-rw-r--r--LayoutTests/storage/domstorage/events/resources/body-event-handler.html8
-rw-r--r--LayoutTests/storage/domstorage/events/resources/eventTestHarness.js51
-rw-r--r--LayoutTests/storage/domstorage/events/resources/setattribute-event-handler.html11
-rw-r--r--LayoutTests/storage/domstorage/events/script-tests/TEMPLATE.html13
-rw-r--r--LayoutTests/storage/domstorage/events/script-tests/basic-body-attribute.js98
-rw-r--r--LayoutTests/storage/domstorage/events/script-tests/basic-setattribute.js98
-rw-r--r--LayoutTests/storage/domstorage/events/script-tests/basic.js97
-rw-r--r--LayoutTests/storage/domstorage/events/script-tests/case-sensitive.js50
-rw-r--r--LayoutTests/storage/domstorage/events/script-tests/documentURI.js52
-rw-r--r--LayoutTests/storage/domstorage/localstorage/delete-removal-expected.txt13
-rw-r--r--LayoutTests/storage/domstorage/localstorage/delete-removal.html51
-rw-r--r--LayoutTests/storage/domstorage/localstorage/enumerate-storage-expected.txt9
-rw-r--r--LayoutTests/storage/domstorage/localstorage/enumerate-storage.html47
-rw-r--r--LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key-expected.txt8
-rw-r--r--LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key.html47
-rw-r--r--LayoutTests/storage/domstorage/localstorage/index-get-and-set-expected.txt32
-rw-r--r--LayoutTests/storage/domstorage/localstorage/index-get-and-set.html79
-rw-r--r--LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt7
-rw-r--r--LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage.html50
-rw-r--r--LayoutTests/storage/domstorage/localstorage/resources/clearLocalStorage.js12
-rw-r--r--LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html24
-rw-r--r--LayoutTests/storage/domstorage/localstorage/resources/window-open-second.html36
-rw-r--r--LayoutTests/storage/domstorage/localstorage/simple-usage-expected.txt13
-rw-r--r--LayoutTests/storage/domstorage/localstorage/simple-usage.html49
-rw-r--r--LayoutTests/storage/domstorage/localstorage/string-conversion-expected.txt15
-rw-r--r--LayoutTests/storage/domstorage/localstorage/string-conversion.html54
-rw-r--r--LayoutTests/storage/domstorage/localstorage/window-open-expected.txt8
-rw-r--r--LayoutTests/storage/domstorage/localstorage/window-open.html39
-rw-r--r--LayoutTests/storage/domstorage/quota-expected.txt32
-rw-r--r--LayoutTests/storage/domstorage/quota.html12
-rw-r--r--LayoutTests/storage/domstorage/remove-item-expected.txt65
-rw-r--r--LayoutTests/storage/domstorage/remove-item.html12
-rw-r--r--LayoutTests/storage/domstorage/script-tests/TEMPLATE.html12
-rw-r--r--LayoutTests/storage/domstorage/script-tests/clear.js34
-rw-r--r--LayoutTests/storage/domstorage/script-tests/complex-keys.js152
-rw-r--r--LayoutTests/storage/domstorage/script-tests/complex-values.js79
-rw-r--r--LayoutTests/storage/domstorage/script-tests/quota.js87
-rw-r--r--LayoutTests/storage/domstorage/script-tests/remove-item.js50
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/delete-removal-expected.txt13
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/delete-removal.html51
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/enumerate-storage-expected.txt9
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/enumerate-storage.html47
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key-expected.txt9
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key.html47
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/index-get-and-set-expected.txt32
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/index-get-and-set.html79
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage-expected.txt7
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage.html50
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/resources/clearSessionStorage.js12
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html24
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/resources/window-open-second.html36
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/simple-usage-expected.txt13
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/simple-usage.html49
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/string-conversion-expected.txt15
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/string-conversion.html54
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/window-open-expected.txt8
-rw-r--r--LayoutTests/storage/domstorage/sessionstorage/window-open.html39
-rw-r--r--LayoutTests/storage/domstorage/window-attributes-exist-expected.txt21
-rw-r--r--LayoutTests/storage/domstorage/window-attributes-exist.html59
75 files changed, 3240 insertions, 0 deletions
diff --git a/LayoutTests/storage/domstorage/clear-expected.txt b/LayoutTests/storage/domstorage/clear-expected.txt
new file mode 100644
index 0000000..30dcae1
--- /dev/null
+++ b/LayoutTests/storage/domstorage/clear-expected.txt
@@ -0,0 +1,35 @@
+Test basic dom storage .clear() functionality.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+storage['FOO'] = 'MyFOO'
+storage['BAR'] = 'MyBar'
+PASS storage.length is 2
+PASS storage['FOO'] is "MyFOO"
+PASS storage['BAR'] is "MyBar"
+storage.clear()
+PASS storage.length is 0
+PASS storage['FOO'] is undefined
+PASS storage['BAR'] is undefined
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+storage['FOO'] = 'MyFOO'
+storage['BAR'] = 'MyBar'
+PASS storage.length is 2
+PASS storage['FOO'] is "MyFOO"
+PASS storage['BAR'] is "MyBar"
+storage.clear()
+PASS storage.length is 0
+PASS storage['FOO'] is undefined
+PASS storage['BAR'] is undefined
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/clear.html b/LayoutTests/storage/domstorage/clear.html
new file mode 100644
index 0000000..8f23701
--- /dev/null
+++ b/LayoutTests/storage/domstorage/clear.html
@@ -0,0 +1,12 @@
+<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/clear.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/complex-keys-expected.txt b/LayoutTests/storage/domstorage/complex-keys-expected.txt
new file mode 100644
index 0000000..4ff0d29
--- /dev/null
+++ b/LayoutTests/storage/domstorage/complex-keys-expected.txt
@@ -0,0 +1,237 @@
+Test dom storage with many different types of keys (as opposed to values)
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+
+PASS storage.getItem('FOO') is null
+storage.setItem('FOO', 'BAR')
+PASS storage.length is 1
+PASS storage.getItem('FOO') is "BAR"
+PASS storage.getItem('foo') is null
+PASS storage.foo is undefined.
+PASS storage['foo'] is undefined.
+storage.foo = 'x'
+PASS storage.foo is "x"
+PASS storage['foo'] is "x"
+PASS storage.getItem('foo') is "x"
+storage['foo'] = 'y'
+PASS storage.foo is "y"
+PASS storage['foo'] is "y"
+PASS storage.getItem('foo') is "y"
+storage.setItem('foo', 'z')
+PASS storage.foo is "z"
+PASS storage['foo'] is "z"
+PASS storage.getItem('foo') is "z"
+PASS storage.length is 2
+
+Testing a null key
+storage.setItem(null, 'asdf')
+PASS storage.getItem('null') is "asdf"
+PASS storage.getItem(null) is "asdf"
+PASS storage['null'] is "asdf"
+PASS storage[null] is "asdf"
+PASS storage.length is 3
+storage[null] = 1
+PASS storage.getItem(null) is "1"
+storage['null'] = 2
+PASS storage.getItem(null) is "2"
+storage.setItem('null', 3)
+PASS storage.getItem(null) is "3"
+PASS storage.length is 3
+
+Testing an undefined key
+storage[undefined] = 'xyz'
+PASS storage.getItem('undefined') is "xyz"
+PASS storage.getItem(undefined) is "xyz"
+PASS storage['undefined'] is "xyz"
+PASS storage[undefined] is "xyz"
+PASS storage.length is 4
+storage['undefined'] = 4
+PASS storage.getItem(undefined) is "4"
+storage.setItem(undefined, 5)
+PASS storage.getItem(undefined) is "5"
+storage.setItem('undefined', 6)
+PASS storage.getItem(undefined) is "6"
+PASS storage.length is 4
+
+Testing a numeric key
+storage['2'] = 'ppp'
+PASS storage.getItem('2') is "ppp"
+PASS storage.getItem(2) is "ppp"
+PASS storage['2'] is "ppp"
+PASS storage[2] is "ppp"
+PASS storage.length is 5
+storage[2] = 7
+PASS storage.getItem(2) is "7"
+storage.setItem(2, 8)
+PASS storage.getItem(2) is "8"
+storage.setItem('2', 9)
+PASS storage.getItem(2) is "9"
+PASS storage.length is 5
+
+Setting a non-ascii string to foo
+storage[k] = 'hello'
+PASS storage.getItem(k) is "hello"
+PASS storage[k] is "hello"
+PASS storage.length is 6
+
+Testing case differences
+storage.foo1 = 'lower1'
+storage.FOO1 = 'UPPER1'
+storage['foo2'] = 'lower2'
+storage['FOO2'] = 'UPPER2'
+storage.setItem('foo3', 'lower3')
+storage.setItem('FOO3', 'UPPER3')
+PASS storage.foo1 is "lower1"
+PASS storage.FOO1 is "UPPER1"
+PASS storage['foo2'] is "lower2"
+PASS storage['FOO2'] is "UPPER2"
+PASS storage.getItem('foo3') is "lower3"
+PASS storage.getItem('FOO3') is "UPPER3"
+PASS storage.length is 12
+
+Testing overriding length
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage.length = 0
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage['length'] = 0
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage.setItem('length', 0)
+PASS storage.length is 13
+PASS storage['length'] is 13
+PASS storage.getItem('length') is "0"
+storage.removeItem('length')
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage.setItem('length', 0)
+PASS storage.length is 13
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+
+PASS storage.getItem('FOO') is null
+storage.setItem('FOO', 'BAR')
+PASS storage.length is 1
+PASS storage.getItem('FOO') is "BAR"
+PASS storage.getItem('foo') is null
+PASS storage.foo is undefined.
+PASS storage['foo'] is undefined.
+storage.foo = 'x'
+PASS storage.foo is "x"
+PASS storage['foo'] is "x"
+PASS storage.getItem('foo') is "x"
+storage['foo'] = 'y'
+PASS storage.foo is "y"
+PASS storage['foo'] is "y"
+PASS storage.getItem('foo') is "y"
+storage.setItem('foo', 'z')
+PASS storage.foo is "z"
+PASS storage['foo'] is "z"
+PASS storage.getItem('foo') is "z"
+PASS storage.length is 2
+
+Testing a null key
+storage.setItem(null, 'asdf')
+PASS storage.getItem('null') is "asdf"
+PASS storage.getItem(null) is "asdf"
+PASS storage['null'] is "asdf"
+PASS storage[null] is "asdf"
+PASS storage.length is 3
+storage[null] = 1
+PASS storage.getItem(null) is "1"
+storage['null'] = 2
+PASS storage.getItem(null) is "2"
+storage.setItem('null', 3)
+PASS storage.getItem(null) is "3"
+PASS storage.length is 3
+
+Testing an undefined key
+storage[undefined] = 'xyz'
+PASS storage.getItem('undefined') is "xyz"
+PASS storage.getItem(undefined) is "xyz"
+PASS storage['undefined'] is "xyz"
+PASS storage[undefined] is "xyz"
+PASS storage.length is 4
+storage['undefined'] = 4
+PASS storage.getItem(undefined) is "4"
+storage.setItem(undefined, 5)
+PASS storage.getItem(undefined) is "5"
+storage.setItem('undefined', 6)
+PASS storage.getItem(undefined) is "6"
+PASS storage.length is 4
+
+Testing a numeric key
+storage['2'] = 'ppp'
+PASS storage.getItem('2') is "ppp"
+PASS storage.getItem(2) is "ppp"
+PASS storage['2'] is "ppp"
+PASS storage[2] is "ppp"
+PASS storage.length is 5
+storage[2] = 7
+PASS storage.getItem(2) is "7"
+storage.setItem(2, 8)
+PASS storage.getItem(2) is "8"
+storage.setItem('2', 9)
+PASS storage.getItem(2) is "9"
+PASS storage.length is 5
+
+Setting a non-ascii string to foo
+storage[k] = 'hello'
+PASS storage.getItem(k) is "hello"
+PASS storage[k] is "hello"
+PASS storage.length is 6
+
+Testing case differences
+storage.foo1 = 'lower1'
+storage.FOO1 = 'UPPER1'
+storage['foo2'] = 'lower2'
+storage['FOO2'] = 'UPPER2'
+storage.setItem('foo3', 'lower3')
+storage.setItem('FOO3', 'UPPER3')
+PASS storage.foo1 is "lower1"
+PASS storage.FOO1 is "UPPER1"
+PASS storage['foo2'] is "lower2"
+PASS storage['FOO2'] is "UPPER2"
+PASS storage.getItem('foo3') is "lower3"
+PASS storage.getItem('FOO3') is "UPPER3"
+PASS storage.length is 12
+
+Testing overriding length
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage.length = 0
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage['length'] = 0
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage.setItem('length', 0)
+PASS storage.length is 13
+PASS storage['length'] is 13
+PASS storage.getItem('length') is "0"
+storage.removeItem('length')
+PASS storage.length is 12
+PASS storage['length'] is 12
+PASS storage.getItem('length') is null
+storage.setItem('length', 0)
+PASS storage.length is 13
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/complex-keys.html b/LayoutTests/storage/domstorage/complex-keys.html
new file mode 100644
index 0000000..40af774
--- /dev/null
+++ b/LayoutTests/storage/domstorage/complex-keys.html
@@ -0,0 +1,12 @@
+<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/complex-keys.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/complex-values-expected.txt b/LayoutTests/storage/domstorage/complex-values-expected.txt
new file mode 100644
index 0000000..69d7644
--- /dev/null
+++ b/LayoutTests/storage/domstorage/complex-values-expected.txt
@@ -0,0 +1,207 @@
+Test some corner case DOM Storage values.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+
+PASS typeof storage['foo'] is "undefined"
+PASS storage['foo'] is undefined.
+PASS typeof storage.foo is "undefined"
+PASS storage.foo is undefined.
+PASS typeof storage.getItem('foo') is "object"
+PASS storage.getItem('foo') is null
+
+storage.foo1 = null
+PASS typeof storage['foo1'] is "string"
+PASS storage['foo1'] is "null"
+PASS typeof storage.foo1 is "string"
+PASS storage.foo1 is "null"
+PASS typeof storage.getItem('foo1') is "string"
+PASS storage.getItem('foo1') is "null"
+storage['foo2'] = null
+PASS typeof storage['foo2'] is "string"
+PASS storage['foo2'] is "null"
+PASS typeof storage.foo2 is "string"
+PASS storage.foo2 is "null"
+PASS typeof storage.getItem('foo2') is "string"
+PASS storage.getItem('foo2') is "null"
+storage.setItem('foo3', null)
+PASS typeof storage['foo3'] is "string"
+PASS storage['foo3'] is "null"
+PASS typeof storage.foo3 is "string"
+PASS storage.foo3 is "null"
+PASS typeof storage.getItem('foo3') is "string"
+PASS storage.getItem('foo3') is "null"
+
+storage.foo4 = undefined
+PASS typeof storage['foo4'] is "string"
+PASS storage['foo4'] is "undefined"
+PASS typeof storage.foo4 is "string"
+PASS storage.foo4 is "undefined"
+PASS typeof storage.getItem('foo4') is "string"
+PASS storage.getItem('foo4') is "undefined"
+storage['foo5'] = undefined
+PASS typeof storage['foo5'] is "string"
+PASS storage['foo5'] is "undefined"
+PASS typeof storage.foo5 is "string"
+PASS storage.foo5 is "undefined"
+PASS typeof storage.getItem('foo5') is "string"
+PASS storage.getItem('foo5') is "undefined"
+storage.setItem('foo6', undefined)
+PASS typeof storage['foo6'] is "string"
+PASS storage['foo6'] is "undefined"
+PASS typeof storage.foo6 is "string"
+PASS storage.foo6 is "undefined"
+PASS typeof storage.getItem('foo6') is "string"
+PASS storage.getItem('foo6') is "undefined"
+
+storage.foo7 = 2
+PASS typeof storage['foo7'] is "string"
+PASS storage['foo7'] is "2"
+PASS typeof storage.foo7 is "string"
+PASS storage.foo7 is "2"
+PASS typeof storage.getItem('foo7') is "string"
+PASS storage.getItem('foo7') is "2"
+storage['foo8'] = 2
+PASS typeof storage['foo8'] is "string"
+PASS storage['foo8'] is "2"
+PASS typeof storage.foo8 is "string"
+PASS storage.foo8 is "2"
+PASS typeof storage.getItem('foo8') is "string"
+PASS storage.getItem('foo8') is "2"
+storage.setItem('foo9', 2)
+PASS typeof storage['foo9'] is "string"
+PASS storage['foo9'] is "2"
+PASS typeof storage.foo9 is "string"
+PASS storage.foo9 is "2"
+PASS typeof storage.getItem('foo9') is "string"
+PASS storage.getItem('foo9') is "2"
+
+storage.foo10 = k
+PASS typeof storage['foo10'] is "string"
+PASS storage['foo10'] is "ÿ찡hello"
+PASS typeof storage.foo10 is "string"
+PASS storage.foo10 is "ÿ찡hello"
+PASS typeof storage.getItem('foo10') is "string"
+PASS storage.getItem('foo10') is "ÿ찡hello"
+storage['foo11'] = k
+PASS typeof storage['foo11'] is "string"
+PASS storage['foo11'] is "ÿ찡hello"
+PASS typeof storage.foo11 is "string"
+PASS storage.foo11 is "ÿ찡hello"
+PASS typeof storage.getItem('foo11') is "string"
+PASS storage.getItem('foo11') is "ÿ찡hello"
+storage.setItem('foo12', k)
+PASS typeof storage['foo12'] is "string"
+PASS storage['foo12'] is "ÿ찡hello"
+PASS typeof storage.foo12 is "string"
+PASS storage.foo12 is "ÿ찡hello"
+PASS typeof storage.getItem('foo12') is "string"
+PASS storage.getItem('foo12') is "ÿ찡hello"
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+
+PASS typeof storage['foo'] is "undefined"
+PASS storage['foo'] is undefined.
+PASS typeof storage.foo is "undefined"
+PASS storage.foo is undefined.
+PASS typeof storage.getItem('foo') is "object"
+PASS storage.getItem('foo') is null
+
+storage.foo1 = null
+PASS typeof storage['foo1'] is "string"
+PASS storage['foo1'] is "null"
+PASS typeof storage.foo1 is "string"
+PASS storage.foo1 is "null"
+PASS typeof storage.getItem('foo1') is "string"
+PASS storage.getItem('foo1') is "null"
+storage['foo2'] = null
+PASS typeof storage['foo2'] is "string"
+PASS storage['foo2'] is "null"
+PASS typeof storage.foo2 is "string"
+PASS storage.foo2 is "null"
+PASS typeof storage.getItem('foo2') is "string"
+PASS storage.getItem('foo2') is "null"
+storage.setItem('foo3', null)
+PASS typeof storage['foo3'] is "string"
+PASS storage['foo3'] is "null"
+PASS typeof storage.foo3 is "string"
+PASS storage.foo3 is "null"
+PASS typeof storage.getItem('foo3') is "string"
+PASS storage.getItem('foo3') is "null"
+
+storage.foo4 = undefined
+PASS typeof storage['foo4'] is "string"
+PASS storage['foo4'] is "undefined"
+PASS typeof storage.foo4 is "string"
+PASS storage.foo4 is "undefined"
+PASS typeof storage.getItem('foo4') is "string"
+PASS storage.getItem('foo4') is "undefined"
+storage['foo5'] = undefined
+PASS typeof storage['foo5'] is "string"
+PASS storage['foo5'] is "undefined"
+PASS typeof storage.foo5 is "string"
+PASS storage.foo5 is "undefined"
+PASS typeof storage.getItem('foo5') is "string"
+PASS storage.getItem('foo5') is "undefined"
+storage.setItem('foo6', undefined)
+PASS typeof storage['foo6'] is "string"
+PASS storage['foo6'] is "undefined"
+PASS typeof storage.foo6 is "string"
+PASS storage.foo6 is "undefined"
+PASS typeof storage.getItem('foo6') is "string"
+PASS storage.getItem('foo6') is "undefined"
+
+storage.foo7 = 2
+PASS typeof storage['foo7'] is "string"
+PASS storage['foo7'] is "2"
+PASS typeof storage.foo7 is "string"
+PASS storage.foo7 is "2"
+PASS typeof storage.getItem('foo7') is "string"
+PASS storage.getItem('foo7') is "2"
+storage['foo8'] = 2
+PASS typeof storage['foo8'] is "string"
+PASS storage['foo8'] is "2"
+PASS typeof storage.foo8 is "string"
+PASS storage.foo8 is "2"
+PASS typeof storage.getItem('foo8') is "string"
+PASS storage.getItem('foo8') is "2"
+storage.setItem('foo9', 2)
+PASS typeof storage['foo9'] is "string"
+PASS storage['foo9'] is "2"
+PASS typeof storage.foo9 is "string"
+PASS storage.foo9 is "2"
+PASS typeof storage.getItem('foo9') is "string"
+PASS storage.getItem('foo9') is "2"
+
+storage.foo10 = k
+PASS typeof storage['foo10'] is "string"
+PASS storage['foo10'] is "ÿ찡hello"
+PASS typeof storage.foo10 is "string"
+PASS storage.foo10 is "ÿ찡hello"
+PASS typeof storage.getItem('foo10') is "string"
+PASS storage.getItem('foo10') is "ÿ찡hello"
+storage['foo11'] = k
+PASS typeof storage['foo11'] is "string"
+PASS storage['foo11'] is "ÿ찡hello"
+PASS typeof storage.foo11 is "string"
+PASS storage.foo11 is "ÿ찡hello"
+PASS typeof storage.getItem('foo11') is "string"
+PASS storage.getItem('foo11') is "ÿ찡hello"
+storage.setItem('foo12', k)
+PASS typeof storage['foo12'] is "string"
+PASS storage['foo12'] is "ÿ찡hello"
+PASS typeof storage.foo12 is "string"
+PASS storage.foo12 is "ÿ찡hello"
+PASS typeof storage.getItem('foo12') is "string"
+PASS storage.getItem('foo12') is "ÿ찡hello"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/complex-values.html b/LayoutTests/storage/domstorage/complex-values.html
new file mode 100644
index 0000000..00ad8d7
--- /dev/null
+++ b/LayoutTests/storage/domstorage/complex-values.html
@@ -0,0 +1,12 @@
+<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/complex-values.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
index 0000000..273c95b
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/basic-body-attribute-expected.txt
@@ -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
index 0000000..c2778ff
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/basic-body-attribute.html
@@ -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
index 0000000..bccdb5c
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/basic-expected.txt
@@ -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
index 0000000..99c7f18
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/basic-setattribute-expected.txt
@@ -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
index 0000000..2b95568
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/basic-setattribute.html
@@ -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
index 0000000..4c52d07
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/basic.html
@@ -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
index 0000000..6cdf19f
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/case-sensitive-expected.txt
@@ -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
index 0000000..c8da433
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/case-sensitive.html
@@ -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>
diff --git a/LayoutTests/storage/domstorage/events/documentURI-expected.txt b/LayoutTests/storage/domstorage/events/documentURI-expected.txt
new file mode 100644
index 0000000..5952523
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/documentURI-expected.txt
@@ -0,0 +1,40 @@
+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".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+Reset storage event list
+storageEventList = new Array()
+storage.foo = '123'
+PASS storageEventList.length is 1
+Saving URI
+document.documentURI = 'abc'
+PASS document.documentURI is "abc"
+storage.foo = 'xyz'
+PASS storageEventList.length is 2
+PASS true is true
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+Reset storage event list
+storageEventList = new Array()
+storage.foo = '123'
+PASS storageEventList.length is 1
+Saving URI
+document.documentURI = 'abc'
+PASS document.documentURI is "abc"
+storage.foo = 'xyz'
+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
index 0000000..7721e87
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/documentURI.html
@@ -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
index 0000000..a1218fe
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/resources/body-event-handler.html
@@ -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
index 0000000..8f15c31
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/resources/eventTestHarness.js
@@ -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
index 0000000..a764c53
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/resources/setattribute-event-handler.html
@@ -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
index 0000000..d9af438
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/script-tests/TEMPLATE.html
@@ -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
index 0000000..7054069
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/script-tests/basic-body-attribute.js
@@ -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
index 0000000..0da34a6
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/script-tests/basic-setattribute.js
@@ -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
index 0000000..06591b1
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/script-tests/basic.js
@@ -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
index 0000000..b5038a8
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/script-tests/case-sensitive.js
@@ -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
index 0000000..4b4f4cb
--- /dev/null
+++ b/LayoutTests/storage/domstorage/events/script-tests/documentURI.js
@@ -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/delete-removal-expected.txt b/LayoutTests/storage/domstorage/localstorage/delete-removal-expected.txt
new file mode 100644
index 0000000..b50b617
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/delete-removal-expected.txt
@@ -0,0 +1,13 @@
+This test makes sure that using the syntax `delete localStorage.keyName` works as an alias to `localStorage.removeItem(keyName).`
+foo (before anything) is: undefined
+foo (after a named property settter set) is: bar
+foo (after a delete) is: undefined
+foo (after an indexed setter set) is: bar
+foo (after deleting FOO (not foo)) is: bar
+foo (after a delete) is: undefined
+foo (after calling setItem) is: bar
+foo (after a delete) is: undefined
+foo (after a redundant delete) is: undefined
+foo (after an implicit settter set) is: bar
+foo (after an indexed delete) is: undefined
+
diff --git a/LayoutTests/storage/domstorage/localstorage/delete-removal.html b/LayoutTests/storage/domstorage/localstorage/delete-removal.html
new file mode 100644
index 0000000..85d1278
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/delete-removal.html
@@ -0,0 +1,51 @@
+<html>
+<head>
+<script src="resources/clearLocalStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById('logger').appendChild(document.createTextNode(a));
+ document.getElementById('logger').appendChild(document.createElement("br"));
+}
+
+function runTest()
+{
+ if (!window.localStorage) {
+ log("window.localStorage DOES NOT exist");
+ return;
+ }
+
+ log("foo (before anything) is: " + localStorage.foo);
+ localStorage.foo = "bar";
+ log("foo (after a named property settter set) is: " + localStorage.foo);
+ delete localStorage.foo;
+ log("foo (after a delete) is: " + localStorage.foo);
+ localStorage["foo"] = "bar";
+ log("foo (after an indexed setter set) is: " + localStorage.foo);
+ delete localStorage.FOO;
+ log("foo (after deleting FOO (not foo)) is: " + localStorage.foo);
+ delete localStorage.foo;
+ log("foo (after a delete) is: " + localStorage.foo);
+ localStorage.setItem("foo", "bar");
+ log("foo (after calling setItem) is: " + localStorage.foo);
+ delete localStorage.foo;
+ log("foo (after a delete) is: " + localStorage.foo);
+ delete localStorage.foo;
+ log("foo (after a redundant delete) is: " + localStorage.foo);
+ localStorage.foo = "bar";
+ log("foo (after an implicit settter set) is: " + localStorage.foo);
+ delete localStorage["foo"];
+ log("foo (after an indexed delete) is: " + localStorage.foo);
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This test makes sure that using the syntax `delete localStorage.keyName` works as an alias to `localStorage.removeItem(keyName).`<br><hr>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/enumerate-storage-expected.txt b/LayoutTests/storage/domstorage/localstorage/enumerate-storage-expected.txt
new file mode 100644
index 0000000..a9feac5
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/enumerate-storage-expected.txt
@@ -0,0 +1,9 @@
+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
+
diff --git a/LayoutTests/storage/domstorage/localstorage/enumerate-storage.html b/LayoutTests/storage/domstorage/localstorage/enumerate-storage.html
new file mode 100644
index 0000000..b45a419
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/enumerate-storage.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+<script src="resources/clearLocalStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+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>
diff --git a/LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key-expected.txt b/LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key-expected.txt
new file mode 100644
index 0000000..7b61676
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key-expected.txt
@@ -0,0 +1,8 @@
+This test attempts to enumerate all the keys in localStorage with .length + .key(). The built-in properties of the Storage object should be ignored. The test operates on the localStorage object.
+alpha
+bar
+batman
+foo
+fu
+zeta
+
diff --git a/LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key.html b/LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key.html
new file mode 100644
index 0000000..aa77dcd
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/enumerate-with-length-and-key.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+<script src="resources/clearLocalStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+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 i=0; i<localStorage.length; ++i)
+ enumeratedArray.push(localStorage.key(i));
+
+ // 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 attempts to enumerate all the keys in localStorage with .length + .key(). 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>
diff --git a/LayoutTests/storage/domstorage/localstorage/index-get-and-set-expected.txt b/LayoutTests/storage/domstorage/localstorage/index-get-and-set-expected.txt
new file mode 100644
index 0000000..ad58023
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/index-get-and-set-expected.txt
@@ -0,0 +1,32 @@
+This is a test to make sure you can get and set values in localStorage by index.
+Setting FOO using the index setter.
+Reading FOO:
+BAR
+BAR
+BAR
+
+Setting FOO again, using setItem.
+Reading FOO:
+BAZ
+BAZ
+BAZ
+
+Setting FOO again, using the index setter.
+Reading FOO:
+BAT
+BAT
+BAT
+
+Setting FOO again, using property-slot syntax
+Reading FOO:
+BATMAN
+BATMAN
+BATMAN
+
+Removing FOO, then trying to read it
+Reading FOO:
+undefined
+undefined
+null
+
+
diff --git a/LayoutTests/storage/domstorage/localstorage/index-get-and-set.html b/LayoutTests/storage/domstorage/localstorage/index-get-and-set.html
new file mode 100644
index 0000000..1026f51
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/index-get-and-set.html
@@ -0,0 +1,79 @@
+<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 runTest()
+{
+ if (!window.localStorage) {
+ log("window.localStorage DOES NOT exist");
+ finish();
+ return;
+ }
+
+ 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>
diff --git a/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt b/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt
new file mode 100644
index 0000000..6de4296
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt
@@ -0,0 +1,7 @@
+This is a test to make sure that when private browsing is on any attempt to change the localStorage area fail.
+Initial value of testItem is: InitialValue
+Caught exception trying to change item: Error: QUOTA_EXCEEDED_ERR: DOM Exception 22
+After change attempt, testItem is: InitialValue
+After remove attempt, testItem is: InitialValue
+After clear attempt, testItem is: InitialValue
+
diff --git a/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage.html b/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage.html
new file mode 100644
index 0000000..9e46bec
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage.html
@@ -0,0 +1,50 @@
+<html>
+<head>
+<script src="resources/clearLocalStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.localStorage) {
+ log("window.localStorage DOES NOT exist");
+ return;
+ }
+ if (!window.layoutTestController) {
+ log("Test only designed to be run under DumpRenderTree");
+ return;
+ }
+
+ localStorage.setItem("testItem", "InitialValue");
+ layoutTestController.setPrivateBrowsingEnabled(true);
+ log("Initial value of testItem is: " + localStorage.getItem("testItem"));
+
+ try {
+ localStorage.setItem("testItem", "ChangedValue");
+ } catch(e) {
+ log("Caught exception trying to change item: " + e);
+ }
+
+ log("After change attempt, testItem is: " + localStorage.getItem("testItem"));
+
+ localStorage.removeItem("testItem");
+ log("After remove attempt, testItem is: " + localStorage.getItem("testItem"));
+
+ localStorage.clear();
+ log("After clear attempt, testItem is: " + localStorage.getItem("testItem"));
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This is a test to make sure that when private browsing is on any attempt to change the localStorage area fail.
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/resources/clearLocalStorage.js b/LayoutTests/storage/domstorage/localstorage/resources/clearLocalStorage.js
new file mode 100644
index 0000000..418d000
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/resources/clearLocalStorage.js
@@ -0,0 +1,12 @@
+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();
diff --git a/LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html b/LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html
new file mode 100644
index 0000000..2ab8ba1
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/resources/iframe-events-second.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<script>
+function handleStorageEvent(e)
+{
+ parent.log("Subframe received storage event:");
+ parent.log("Key - " + e.key);
+ parent.log("New Value - " + e.newValue);
+ parent.log("Old Value - " + e.oldValue);
+ parent.log("URI - " + parent.normalizeURL(e.uri));
+ parent.log("Storage Area - " + ((e.storageArea == window.localStorage) ? "This window's window.localStorage" : "Another window's window.localStorage"));
+ parent.log("");
+
+ if (e.key != "Subframe") {
+ parent.log("Subframe about to change localStorage...");
+ localStorage.setItem("Subframe", "SET");
+ }
+}
+</script>
+</head>
+<body onload="window.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>
diff --git a/LayoutTests/storage/domstorage/localstorage/resources/window-open-second.html b/LayoutTests/storage/domstorage/localstorage/resources/window-open-second.html
new file mode 100644
index 0000000..f944d71
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/resources/window-open-second.html
@@ -0,0 +1,36 @@
+<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 (window.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>
diff --git a/LayoutTests/storage/domstorage/localstorage/simple-usage-expected.txt b/LayoutTests/storage/domstorage/localstorage/simple-usage-expected.txt
new file mode 100644
index 0000000..8a318c8
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/simple-usage-expected.txt
@@ -0,0 +1,13 @@
+This test tries simple operations on localStorage
+Length is 0
+Value for FOO is null
+Length is 1
+Value for FOO is BAR
+Key for index 0 is FOO
+Key for index 1 is null
+Key for index -1 is null
+Length is 1
+Value for FOO is BAZ
+Length is 0
+Value for FOO is null
+
diff --git a/LayoutTests/storage/domstorage/localstorage/simple-usage.html b/LayoutTests/storage/domstorage/localstorage/simple-usage.html
new file mode 100644
index 0000000..37592d0
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/simple-usage.html
@@ -0,0 +1,49 @@
+<html>
+<head>
+<script src="resources/clearLocalStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.localStorage) {
+ log("window.localStorage DOES NOT exist");
+ return;
+ }
+
+ log("Length is " + localStorage.length);
+ log("Value for FOO is " + localStorage.getItem("FOO"));
+
+ localStorage.setItem("FOO", "BAR");
+
+ log("Length is " + localStorage.length);
+ log("Value for FOO is " + localStorage.getItem("FOO"));
+ log("Key for index 0 is " + localStorage.key(0));
+ log("Key for index 1 is " + localStorage.key(1));
+ log("Key for index -1 is " + localStorage.key(-1));
+
+ localStorage.setItem("FOO", "BAZ");
+
+ log("Length is " + localStorage.length);
+ log("Value for FOO is " + localStorage.getItem("FOO"));
+
+ localStorage.removeItem("FOO");
+
+ log("Length is " + localStorage.length);
+ log("Value for FOO is " + localStorage.getItem("FOO"));
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This test tries simple operations on localStorage<br>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/string-conversion-expected.txt b/LayoutTests/storage/domstorage/localstorage/string-conversion-expected.txt
new file mode 100644
index 0000000..81ca1fa
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/string-conversion-expected.txt
@@ -0,0 +1,15 @@
+This test case verifies that local storage only stores strings.
+Length is 0
+Testing implicit setters
+Type/value for null is string/null
+Type/value for 0 is string/0
+Type/value for function(){} is string/function () {}
+Testing explicit setters
+Type/value for null is string/null
+Type/value for 0 is string/0
+Type/value for function(){} is string/function () {}
+Testing index setters
+Type/value for null is string/null
+Type/value for 0 is string/0
+Type/value for function(){} is string/function () {}
+
diff --git a/LayoutTests/storage/domstorage/localstorage/string-conversion.html b/LayoutTests/storage/domstorage/localstorage/string-conversion.html
new file mode 100644
index 0000000..aa8bdfd
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/string-conversion.html
@@ -0,0 +1,54 @@
+<html>
+<head>
+<script src="resources/clearLocalStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.localStorage) {
+ log("window.localStorage DOES NOT exist");
+ return;
+ }
+
+ log("Length is " + localStorage.length);
+
+ log("Testing implicit setters");
+ localStorage.a = null;
+ log("Type/value for null is " + typeof localStorage.a + "/" + localStorage.a);
+ localStorage.b = 0;
+ log("Type/value for 0 is " + typeof localStorage.b + "/" + localStorage.b);
+ localStorage.c = function(){};
+ log("Type/value for function(){} is " + typeof localStorage.c + "/" + localStorage.c);
+
+ log("Testing explicit setters");
+ localStorage.setItem('d', null);
+ log("Type/value for null is " + typeof localStorage.d + "/" + localStorage.d);
+ localStorage.setItem('e', 0);
+ log("Type/value for 0 is " + typeof localStorage.e + "/" + localStorage.e);
+ localStorage.setItem('f', function(){});
+ log("Type/value for function(){} is " + typeof localStorage.f + "/" + localStorage.f);
+
+ log("Testing index setters");
+ localStorage['g'] = null;
+ log("Type/value for null is " + typeof localStorage.g + "/" + localStorage.g);
+ localStorage['h'] = 0;
+ log("Type/value for 0 is " + typeof localStorage.h + "/" + localStorage.h);
+ localStorage['i'] = function(){};
+ log("Type/value for function(){} is " + typeof localStorage.i + "/" + localStorage.i);
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This test case verifies that local storage only stores strings.
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/localstorage/window-open-expected.txt b/LayoutTests/storage/domstorage/localstorage/window-open-expected.txt
new file mode 100644
index 0000000..9a53f26
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/window-open-expected.txt
@@ -0,0 +1,8 @@
+This is a test to make sure the localStorage object for multiple windows in the same security origin share the same global storage area.
+Value for FOO is BAR
+Logging from second window:
+Value for FOO is BAR
+Value for FOO after changing my own copy is BAR-NEWWINDOW
+Value for FOO in my opening window is BAR-NEWWINDOW
+
+
diff --git a/LayoutTests/storage/domstorage/localstorage/window-open.html b/LayoutTests/storage/domstorage/localstorage/window-open.html
new file mode 100644
index 0000000..b390881
--- /dev/null
+++ b/LayoutTests/storage/domstorage/localstorage/window-open.html
@@ -0,0 +1,39 @@
+<html>
+<head>
+<script src="resources/clearLocalStorage.js"></script>
+<script>
+
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.setCanOpenWindows();
+ layoutTestController.waitUntilDone();
+}
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.localStorage) {
+ log("window.localStorage DOES NOT exist");
+ return;
+ }
+
+ window.log = log;
+
+ window.localStorage.setItem("FOO", "BAR");
+ log("Value for FOO is " + window.localStorage.getItem("FOO"));
+ window.open("resources/window-open-second.html");
+
+
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This is a test to make sure the localStorage object for multiple windows in the same security origin share the same global storage area.<br>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/quota-expected.txt b/LayoutTests/storage/domstorage/quota-expected.txt
new file mode 100644
index 0000000..248ff79
--- /dev/null
+++ b/LayoutTests/storage/domstorage/quota-expected.txt
@@ -0,0 +1,32 @@
+Test the DOM Storage quota code.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+Creating 'data' which contains 64K of data
+PASS data.length is 65536
+Putting 'data' into 40 sessionStorage buckets.
+Putting 'data' into another bucket.h
+PASS Insertion worked.
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+Creating 'data' which contains 64K of data
+PASS data.length is 65536
+Putting 'data' into 39 localStorage buckets.
+Putting 'data' into another bucket.h
+PASS Hit exception as expected
+Verify that data was never inserted.
+PASS storage.getItem(39) is null
+Removing bucket 38.
+Adding 'Hello!' into a new bucket.
+PASS Insertion worked.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/quota.html b/LayoutTests/storage/domstorage/quota.html
new file mode 100644
index 0000000..58a891b
--- /dev/null
+++ b/LayoutTests/storage/domstorage/quota.html
@@ -0,0 +1,12 @@
+<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/quota.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/remove-item-expected.txt b/LayoutTests/storage/domstorage/remove-item-expected.txt
new file mode 100644
index 0000000..8a3b391
--- /dev/null
+++ b/LayoutTests/storage/domstorage/remove-item-expected.txt
@@ -0,0 +1,65 @@
+Test .removeItem within DOM Storage.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing sessionStorage
+storage.clear()
+PASS storage.length is 0
+
+PASS storage.foo1 is undefined.
+storage.foo1 = 'bar'
+PASS storage.foo1 is "bar"
+storage.removeItem('foo1')
+PASS storage.foo1 is undefined.
+storage.removeItem('foo1')
+PASS storage.foo1 is undefined.
+
+PASS storage['foo2'] is undefined.
+storage['foo2'] = 'bar'
+PASS storage['foo2'] is "bar"
+storage.removeItem('foo2')
+PASS storage['foo2'] is undefined.
+storage.removeItem('foo2')
+PASS storage['foo2'] is undefined.
+
+PASS storage.getItem('foo3') is null
+storage.setItem('foo3', 'bar')
+PASS storage.getItem('foo3') is "bar"
+storage.removeItem('foo3')
+PASS storage.getItem('foo3') is null
+storage.removeItem('foo3')
+PASS storage.getItem('foo3') is null
+
+
+Testing localStorage
+storage.clear()
+PASS storage.length is 0
+
+PASS storage.foo1 is undefined.
+storage.foo1 = 'bar'
+PASS storage.foo1 is "bar"
+storage.removeItem('foo1')
+PASS storage.foo1 is undefined.
+storage.removeItem('foo1')
+PASS storage.foo1 is undefined.
+
+PASS storage['foo2'] is undefined.
+storage['foo2'] = 'bar'
+PASS storage['foo2'] is "bar"
+storage.removeItem('foo2')
+PASS storage['foo2'] is undefined.
+storage.removeItem('foo2')
+PASS storage['foo2'] is undefined.
+
+PASS storage.getItem('foo3') is null
+storage.setItem('foo3', 'bar')
+PASS storage.getItem('foo3') is "bar"
+storage.removeItem('foo3')
+PASS storage.getItem('foo3') is null
+storage.removeItem('foo3')
+PASS storage.getItem('foo3') is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/domstorage/remove-item.html b/LayoutTests/storage/domstorage/remove-item.html
new file mode 100644
index 0000000..f9f6ae3
--- /dev/null
+++ b/LayoutTests/storage/domstorage/remove-item.html
@@ -0,0 +1,12 @@
+<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/remove-item.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/script-tests/TEMPLATE.html b/LayoutTests/storage/domstorage/script-tests/TEMPLATE.html
new file mode 100644
index 0000000..239a794
--- /dev/null
+++ b/LayoutTests/storage/domstorage/script-tests/TEMPLATE.html
@@ -0,0 +1,12 @@
+<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="YOUR_JS_FILE_HERE"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/script-tests/clear.js b/LayoutTests/storage/domstorage/script-tests/clear.js
new file mode 100644
index 0000000..bf6e5f3
--- /dev/null
+++ b/LayoutTests/storage/domstorage/script-tests/clear.js
@@ -0,0 +1,34 @@
+description("Test basic dom storage .clear() functionality.");
+
+function test(storageString)
+{
+ storage = eval(storageString);
+ if (!storage) {
+ testFailed(storageString + " DOES NOT exist");
+ return;
+ }
+
+ debug("Testing " + storageString);
+
+ evalAndLog("storage.clear()");
+ shouldBe("storage.length", "0");
+
+ evalAndLog("storage['FOO'] = 'MyFOO'");
+ evalAndLog("storage['BAR'] = 'MyBar'");
+ shouldBe("storage.length", "2");
+ shouldBeEqualToString("storage['FOO']", "MyFOO");
+ shouldBeEqualToString("storage['BAR']", "MyBar");
+
+ evalAndLog("storage.clear()");
+ shouldBe("storage.length", "0");
+ shouldBe("storage['FOO']", "undefined"); // FIXME: Wait...shouldn't this be null?
+ shouldBe("storage['BAR']", "undefined"); // ditto
+}
+
+test("sessionStorage");
+debug("");
+debug("");
+test("localStorage");
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
diff --git a/LayoutTests/storage/domstorage/script-tests/complex-keys.js b/LayoutTests/storage/domstorage/script-tests/complex-keys.js
new file mode 100644
index 0000000..2b6919f
--- /dev/null
+++ b/LayoutTests/storage/domstorage/script-tests/complex-keys.js
@@ -0,0 +1,152 @@
+description("Test dom storage with many different types of keys (as opposed to values)");
+
+function test(storageString)
+{
+ storage = eval(storageString);
+ if (!storage) {
+ testFailed(storageString + " DOES NOT exist");
+ return;
+ }
+
+ debug("Testing " + storageString);
+
+ evalAndLog("storage.clear()");
+ shouldBe("storage.length", "0");
+
+ debug("");
+ shouldBeNull("storage.getItem('FOO')");
+ evalAndLog("storage.setItem('FOO', 'BAR')");
+ shouldBe("storage.length", "1");
+
+ shouldBeEqualToString("storage.getItem('FOO')", "BAR");
+ shouldBeNull("storage.getItem('foo')");
+ shouldBeUndefined("storage.foo");
+ shouldBeUndefined("storage['foo']");
+
+ evalAndLog("storage.foo = 'x'");
+ shouldBeEqualToString("storage.foo", "x");
+ shouldBeEqualToString("storage['foo']", "x");
+ shouldBeEqualToString("storage.getItem('foo')", "x");
+ evalAndLog("storage['foo'] = 'y'");
+ shouldBeEqualToString("storage.foo", "y");
+ shouldBeEqualToString("storage['foo']", "y");
+ shouldBeEqualToString("storage.getItem('foo')", "y");
+ evalAndLog("storage.setItem('foo', 'z')");
+ shouldBeEqualToString("storage.foo", "z");
+ shouldBeEqualToString("storage['foo']", "z");
+ shouldBeEqualToString("storage.getItem('foo')", "z");
+ shouldBe("storage.length", "2");
+
+ debug("");
+ debug("Testing a null key");
+ evalAndLog("storage.setItem(null, 'asdf')");
+ shouldBeEqualToString("storage.getItem('null')", "asdf");
+ shouldBeEqualToString("storage.getItem(null)", "asdf");
+ shouldBeEqualToString("storage['null']", "asdf");
+ shouldBeEqualToString("storage[null]", "asdf");
+ shouldBe("storage.length", "3");
+
+ evalAndLog("storage[null] = 1");
+ shouldBeEqualToString("storage.getItem(null)", "1");
+ evalAndLog("storage['null'] = 2");
+ shouldBeEqualToString("storage.getItem(null)", "2");
+ evalAndLog("storage.setItem('null', 3)");
+ shouldBeEqualToString("storage.getItem(null)", "3");
+ shouldBe("storage.length", "3");
+
+ debug("");
+ debug("Testing an undefined key");
+ evalAndLog("storage[undefined] = 'xyz'");
+ shouldBeEqualToString("storage.getItem('undefined')", "xyz");
+ shouldBeEqualToString("storage.getItem(undefined)", "xyz");
+ shouldBeEqualToString("storage['undefined']", "xyz");
+ shouldBeEqualToString("storage[undefined]", "xyz");
+ shouldBe("storage.length", "4");
+
+ evalAndLog("storage['undefined'] = 4");
+ shouldBeEqualToString("storage.getItem(undefined)", "4");
+ evalAndLog("storage.setItem(undefined, 5)");
+ shouldBeEqualToString("storage.getItem(undefined)", "5");
+ evalAndLog("storage.setItem('undefined', 6)");
+ shouldBeEqualToString("storage.getItem(undefined)", "6");
+ shouldBe("storage.length", "4");
+
+ debug("");
+ debug("Testing a numeric key");
+ evalAndLog("storage['2'] = 'ppp'");
+ shouldBeEqualToString("storage.getItem('2')", "ppp");
+ shouldBeEqualToString("storage.getItem(2)", "ppp");
+ shouldBeEqualToString("storage['2']", "ppp");
+ shouldBeEqualToString("storage[2]", "ppp");
+ shouldBe("storage.length", "5");
+
+ evalAndLog("storage[2] = 7");
+ shouldBeEqualToString("storage.getItem(2)", "7");
+ evalAndLog("storage.setItem(2, 8)");
+ shouldBeEqualToString("storage.getItem(2)", "8");
+ evalAndLog("storage.setItem('2', 9)");
+ shouldBeEqualToString("storage.getItem(2)", "9");
+ shouldBe("storage.length", "5");
+
+ debug("");
+ debug("Setting a non-ascii string to foo");
+ k = String.fromCharCode(255425) + String.fromCharCode(255) + String.fromCharCode(2554252321) + String.fromCharCode(0) + 'hello';
+ evalAndLog("storage[k] = 'hello'");
+ shouldBeEqualToString("storage.getItem(k)", "hello");
+ shouldBeEqualToString("storage[k]", "hello");
+ shouldBe("storage.length", "6");
+
+ debug("");
+ debug("Testing case differences");
+ evalAndLog("storage.foo1 = 'lower1'");
+ evalAndLog("storage.FOO1 = 'UPPER1'");
+ evalAndLog("storage['foo2'] = 'lower2'");
+ evalAndLog("storage['FOO2'] = 'UPPER2'");
+ evalAndLog("storage.setItem('foo3', 'lower3')");
+ evalAndLog("storage.setItem('FOO3', 'UPPER3')");
+ shouldBeEqualToString("storage.foo1", "lower1");
+ shouldBeEqualToString("storage.FOO1", "UPPER1");
+ shouldBeEqualToString("storage['foo2']", "lower2");
+ shouldBeEqualToString("storage['FOO2']", "UPPER2");
+ shouldBeEqualToString("storage.getItem('foo3')", "lower3");
+ shouldBeEqualToString("storage.getItem('FOO3')", "UPPER3");
+ shouldBe("storage.length", "12");
+
+
+ debug("");
+ debug("Testing overriding length");
+ shouldBe("storage.length", "12");
+ shouldBe("storage['length']", "12");
+ shouldBeNull("storage.getItem('length')");
+
+ evalAndLog("storage.length = 0");
+ shouldBe("storage.length", "12");
+ shouldBe("storage['length']", "12");
+ shouldBeNull("storage.getItem('length')");
+
+ evalAndLog("storage['length'] = 0");
+ shouldBe("storage.length", "12");
+ shouldBe("storage['length']", "12");
+ shouldBeNull("storage.getItem('length')");
+
+ evalAndLog("storage.setItem('length', 0)");
+ shouldBe("storage.length", "13");
+ shouldBe("storage['length']", "13");
+ shouldBeEqualToString("storage.getItem('length')", "0");
+
+ evalAndLog("storage.removeItem('length')");
+ shouldBe("storage.length", "12");
+ shouldBe("storage['length']", "12");
+ shouldBeNull("storage.getItem('length')");
+
+ evalAndLog("storage.setItem('length', 0)");
+ shouldBe("storage.length", "13");
+}
+
+test("sessionStorage");
+debug("");
+debug("");
+test("localStorage");
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
diff --git a/LayoutTests/storage/domstorage/script-tests/complex-values.js b/LayoutTests/storage/domstorage/script-tests/complex-values.js
new file mode 100644
index 0000000..8c6e29d
--- /dev/null
+++ b/LayoutTests/storage/domstorage/script-tests/complex-values.js
@@ -0,0 +1,79 @@
+description("Test some corner case DOM Storage values.");
+
+function testKeyValue(key, value)
+{
+ keyString = "storage['" + key + "']";
+ shouldBeEqualToString("typeof " + keyString, "string");
+ shouldBeEqualToString(keyString, value);
+
+ keyString = "storage." + key;
+ shouldBeEqualToString("typeof " + keyString, "string");
+ shouldBeEqualToString(keyString, value);
+
+ keyString = "storage.getItem('" + key + "')";
+ shouldBeEqualToString("typeof " + keyString, "string");
+ shouldBeEqualToString(keyString, value);
+}
+
+function test(storageString)
+{
+ storage = eval(storageString);
+ if (!storage) {
+ testFailed(storageString + " DOES NOT exist");
+ return;
+ }
+
+ debug("Testing " + storageString);
+
+ evalAndLog("storage.clear()");
+ shouldBe("storage.length", "0");
+
+ debug("");
+ shouldBeEqualToString("typeof storage['foo']", "undefined");
+ shouldBeUndefined("storage['foo']");
+ shouldBeEqualToString("typeof storage.foo", "undefined");
+ shouldBeUndefined("storage.foo");
+ shouldBeEqualToString("typeof storage.getItem('foo')", "object");
+ shouldBeNull("storage.getItem('foo')");
+
+ debug("");
+ evalAndLog("storage.foo1 = null");
+ testKeyValue("foo1", "null");
+ evalAndLog("storage['foo2'] = null");
+ testKeyValue("foo2", "null");
+ evalAndLog("storage.setItem('foo3', null)");
+ testKeyValue("foo3", "null");
+
+ debug("");
+ evalAndLog("storage.foo4 = undefined");
+ testKeyValue("foo4", "undefined");
+ evalAndLog("storage['foo5'] = undefined");
+ testKeyValue("foo5", "undefined");
+ evalAndLog("storage.setItem('foo6', undefined)");
+ testKeyValue("foo6", "undefined");
+
+ debug("");
+ evalAndLog("storage.foo7 = 2");
+ testKeyValue("foo7", "2");
+ evalAndLog("storage['foo8'] = 2");
+ testKeyValue("foo8", "2");
+ evalAndLog("storage.setItem('foo9', 2)");
+ testKeyValue("foo9", "2");
+
+ debug("");
+ k = String.fromCharCode(255425) + String.fromCharCode(255) + String.fromCharCode(2554252321) + String.fromCharCode(0) + 'hello';
+ evalAndLog("storage.foo10 = k");
+ testKeyValue("foo10", k);
+ evalAndLog("storage['foo11'] = k");
+ testKeyValue("foo11", k);
+ evalAndLog("storage.setItem('foo12', k)");
+ testKeyValue("foo12", k);
+}
+
+test("sessionStorage");
+debug("");
+debug("");
+test("localStorage");
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
diff --git a/LayoutTests/storage/domstorage/script-tests/quota.js b/LayoutTests/storage/domstorage/script-tests/quota.js
new file mode 100644
index 0000000..ad9afe9
--- /dev/null
+++ b/LayoutTests/storage/domstorage/script-tests/quota.js
@@ -0,0 +1,87 @@
+description("Test the DOM Storage quota code.");
+
+function testQuota(storageString)
+{
+ storage = eval(storageString);
+ if (!storage) {
+ testFailed(storageString + " DOES NOT exist");
+ return;
+ }
+
+ debug("Testing " + storageString);
+
+ evalAndLog("storage.clear()");
+ shouldBe("storage.length", "0");
+
+ debug("Creating 'data' which contains 64K of data");
+ data = "X";
+ for (var i=0; i<16; i++)
+ data += data;
+ shouldBe("data.length", "65536");
+
+ debug("Putting 'data' into 39 " + storageString + " buckets.");
+ for (var i=0; i<39; i++)
+ storage[i] = data;
+
+ debug("Putting 'data' into another bucket.h");
+ try {
+ storage[39] = data;
+ testFailed("Did not hit quota error.");
+ } catch (e) {
+ testPassed("Hit exception as expected");
+ }
+
+ debug("Verify that data was never inserted.");
+ shouldBeNull("storage.getItem(39)");
+
+ debug("Removing bucket 38.");
+ storage.removeItem('38');
+
+ debug("Adding 'Hello!' into a new bucket.");
+ try {
+ storage['foo'] = "Hello!";
+ testPassed("Insertion worked.");
+ } catch (e) {
+ testFailed("Exception: " + e);
+ }
+}
+
+function testNoQuota(storageString)
+{
+ storage = eval(storageString);
+ if (!storage) {
+ testFailed(storageString + " DOES NOT exist");
+ return;
+ }
+
+ debug("Testing " + storageString);
+
+ evalAndLog("storage.clear()");
+ shouldBe("storage.length", "0");
+
+ debug("Creating 'data' which contains 64K of data");
+ data = "X";
+ for (var i=0; i<16; i++)
+ data += data;
+ shouldBe("data.length", "65536");
+
+ debug("Putting 'data' into 40 " + storageString + " buckets.");
+ for (var i=0; i<40; i++)
+ storage[i] = data;
+
+ debug("Putting 'data' into another bucket.h");
+ try {
+ storage[40] = data;
+ testPassed("Insertion worked.");
+ } catch (e) {
+ testFailed("Exception: " + e);
+ }
+}
+
+testNoQuota("sessionStorage");
+debug("");
+debug("");
+testQuota("localStorage");
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
diff --git a/LayoutTests/storage/domstorage/script-tests/remove-item.js b/LayoutTests/storage/domstorage/script-tests/remove-item.js
new file mode 100644
index 0000000..62731f1
--- /dev/null
+++ b/LayoutTests/storage/domstorage/script-tests/remove-item.js
@@ -0,0 +1,50 @@
+description("Test .removeItem within DOM Storage.");
+
+function test(storageString)
+{
+ storage = eval(storageString);
+ if (!storage) {
+ testFailed(storageString + " DOES NOT exist");
+ return;
+ }
+
+ debug("Testing " + storageString);
+
+ evalAndLog("storage.clear()");
+ shouldBe("storage.length", "0");
+
+ debug("");
+ shouldBeUndefined("storage.foo1");
+ evalAndLog("storage.foo1 = 'bar'");
+ shouldBeEqualToString("storage.foo1", "bar");
+ evalAndLog("storage.removeItem('foo1')");
+ shouldBeUndefined("storage.foo1");
+ evalAndLog("storage.removeItem('foo1')");
+ shouldBeUndefined("storage.foo1");
+
+ debug("");
+ shouldBeUndefined("storage['foo2']");
+ evalAndLog("storage['foo2'] = 'bar'");
+ shouldBeEqualToString("storage['foo2']", "bar");
+ evalAndLog("storage.removeItem('foo2')");
+ shouldBeUndefined("storage['foo2']");
+ evalAndLog("storage.removeItem('foo2')");
+ shouldBeUndefined("storage['foo2']");
+
+ debug("");
+ shouldBeNull("storage.getItem('foo3')");
+ evalAndLog("storage.setItem('foo3', 'bar')");
+ shouldBeEqualToString("storage.getItem('foo3')", "bar");
+ evalAndLog("storage.removeItem('foo3')");
+ shouldBeNull("storage.getItem('foo3')");
+ evalAndLog("storage.removeItem('foo3')");
+ shouldBeNull("storage.getItem('foo3')");
+}
+
+test("sessionStorage");
+debug("");
+debug("");
+test("localStorage");
+
+window.successfullyParsed = true;
+isSuccessfullyParsed();
diff --git a/LayoutTests/storage/domstorage/sessionstorage/delete-removal-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/delete-removal-expected.txt
new file mode 100644
index 0000000..ce04017
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/delete-removal-expected.txt
@@ -0,0 +1,13 @@
+This test makes sure that using the syntax `delete sessionStorage.keyName` works as an alias to `sessionStorage.removeItem(keyName).`
+foo (before anything) is: undefined
+foo (after a named property setter set) is: bar
+foo (after a delete) is: undefined
+foo (after an indexed setter set) is: bar
+foo (after deleting FOO (not foo)) is : bar
+foo (after a delete) is: undefined
+foo (after calling setItem) is: bar
+foo (after a delete) is: undefined
+foo (after a redundant delete) is: undefined
+foo (after a named property setter set) is: bar
+foo (after an indexed delete) is: undefined
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/delete-removal.html b/LayoutTests/storage/domstorage/sessionstorage/delete-removal.html
new file mode 100644
index 0000000..7a4b8d2
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/delete-removal.html
@@ -0,0 +1,51 @@
+<html>
+<head>
+<script src="resources/clearSessionStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById('logger').appendChild(document.createTextNode(a));
+ document.getElementById('logger').appendChild(document.createElement("br"));
+}
+
+function runTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+
+ log("foo (before anything) is: " + sessionStorage.foo);
+ sessionStorage.foo = "bar";
+ log("foo (after a named property setter set) is: " + sessionStorage.foo);
+ delete sessionStorage.foo;
+ log("foo (after a delete) is: " + sessionStorage.foo);
+ sessionStorage["foo"] = "bar";
+ log("foo (after an indexed setter set) is: " + sessionStorage.foo);
+ delete sessionStorage.FOO;
+ log("foo (after deleting FOO (not foo)) is : " + sessionStorage.foo);
+ delete sessionStorage.foo;
+ log("foo (after a delete) is: " + sessionStorage.foo);
+ sessionStorage.setItem("foo", "bar");
+ log("foo (after calling setItem) is: " + sessionStorage.foo);
+ delete sessionStorage.foo;
+ log("foo (after a delete) is: " + sessionStorage.foo);
+ delete sessionStorage.foo;
+ log("foo (after a redundant delete) is: " + sessionStorage.foo);
+ sessionStorage.foo = "bar";
+ log("foo (after a named property setter set) is: " + sessionStorage.foo);
+ delete sessionStorage["foo"];
+ log("foo (after an indexed delete) is: " + sessionStorage.foo);
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This test makes sure that using the syntax `delete sessionStorage.keyName` works as an alias to `sessionStorage.removeItem(keyName).`<br><hr>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/enumerate-storage-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/enumerate-storage-expected.txt
new file mode 100644
index 0000000..7c87325
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/enumerate-storage-expected.txt
@@ -0,0 +1,9 @@
+This test checks to see that you can enumber 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 SessionStorage object.
+alpha
+bar
+batman
+foo
+fu
+prototypeTestKey
+zeta
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/enumerate-storage.html b/LayoutTests/storage/domstorage/sessionstorage/enumerate-storage.html
new file mode 100644
index 0000000..7321f9a
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/enumerate-storage.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+<script src="resources/clearSessionStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function startTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+
+ Storage.prototype.prototypeTestKey = "prototypeTestValue";
+ sessionStorage.foo = "bar";
+ sessionStorage.fu = "baz";
+ sessionStorage.batman = "bin suparman";
+ sessionStorage.bar = "foo";
+ sessionStorage.alpha = "beta";
+ sessionStorage.zeta = "gamma";
+
+ // Enumerate sessionStorage, appending each key onto an array
+ var enumeratedArray = new Array();
+ for (var n in sessionStorage)
+ 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 enumber 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 SessionStorage object.<br>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key-expected.txt
new file mode 100644
index 0000000..f879759
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key-expected.txt
@@ -0,0 +1,9 @@
+This test attempts to enumerate all the keys in sessionStorage with .length + .key(). The built-in properties of the Storage object should be ignored. The test operates on the sessionStorage object.
+alpha
+bar
+batman
+foo
+fu
+prototypeTestKey
+zeta
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key.html b/LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key.html
new file mode 100644
index 0000000..27266f1
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+<script src="resources/clearSessionStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function startTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+
+ Storage.prototype.prototypeTestKey = "prototypeTestValue";
+ sessionStorage.foo = "bar";
+ sessionStorage.fu = "baz";
+ sessionStorage.batman = "bin suparman";
+ sessionStorage.bar = "foo";
+ sessionStorage.alpha = "beta";
+ sessionStorage.zeta = "gamma";
+
+ // Enumerate sessionStorage, appending each key onto an array
+ var enumeratedArray = new Array();
+ for (var n in sessionStorage)
+ 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 attempts to enumerate all the keys in sessionStorage with .length + .key(). The built-in properties of the Storage object should be ignored. The test operates on the sessionStorage object.<br>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/index-get-and-set-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/index-get-and-set-expected.txt
new file mode 100644
index 0000000..ff66bdc
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/index-get-and-set-expected.txt
@@ -0,0 +1,32 @@
+This is a test to make sure you can get and set values in SessionStorage by index.
+Setting FOO using the index setter.
+Reading FOO:
+BAR
+BAR
+BAR
+
+Setting FOO again, using setItem.
+Reading FOO:
+BAZ
+BAZ
+BAZ
+
+Setting FOO again, using the index setter.
+Reading FOO:
+BAT
+BAT
+BAT
+
+Setting FOO again, using property-slot syntax
+Reading FOO:
+BATMAN
+BATMAN
+BATMAN
+
+Removing FOO, then trying to read it
+Reading FOO:
+undefined
+undefined
+null
+
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/index-get-and-set.html b/LayoutTests/storage/domstorage/sessionstorage/index-get-and-set.html
new file mode 100644
index 0000000..7922d0b
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/index-get-and-set.html
@@ -0,0 +1,79 @@
+<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 runTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ finish();
+ return;
+ }
+
+ log("Setting FOO using the index setter.");
+ sessionStorage["FOO"] = "BAR";
+ log("Reading FOO:");
+ log(sessionStorage.FOO);
+ log(sessionStorage["FOO"]);
+ log(sessionStorage.getItem("FOO"));
+ log("");
+
+ log("Setting FOO again, using setItem.");
+ sessionStorage.setItem("FOO", "BAZ");
+ log("Reading FOO:");
+ log(sessionStorage.FOO);
+ log(sessionStorage["FOO"]);
+ log(sessionStorage.getItem("FOO"));
+ log("");
+
+ log("Setting FOO again, using the index setter.");
+ sessionStorage["FOO"] = "BAT";
+ log("Reading FOO:");
+ log(sessionStorage.FOO);
+ log(sessionStorage["FOO"]);
+ log(sessionStorage.getItem("FOO"));
+ log("");
+
+ log("Setting FOO again, using property-slot syntax");
+ sessionStorage.FOO = "BATMAN";
+ log("Reading FOO:");
+ log(sessionStorage.FOO);
+ log(sessionStorage["FOO"]);
+ log(sessionStorage.getItem("FOO"));
+ log("");
+
+ log("Removing FOO, then trying to read it");
+ sessionStorage.removeItem("FOO");
+ log("Reading FOO:");
+ log(sessionStorage.FOO);
+ log(sessionStorage["FOO"]);
+ log(sessionStorage.getItem("FOO"));
+ log("");
+
+ finish();
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This is a test to make sure you can get and set values in SessionStorage by index.<br>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage-expected.txt
new file mode 100644
index 0000000..ed2017a
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage-expected.txt
@@ -0,0 +1,7 @@
+This is a test to make sure that when private browsing is on any attempt to change the sessionStorage area fail.
+Initial value of testItem is: InitialValue
+Caught exception trying to change item: Error: QUOTA_EXCEEDED_ERR: DOM Exception 22
+After change attempt, testItem is: InitialValue
+After remove attempt, testItem is: InitialValue
+After clear attempt, testItem is: InitialValue
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage.html b/LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage.html
new file mode 100644
index 0000000..8dd7a6a
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/private-browsing-affects-storage.html
@@ -0,0 +1,50 @@
+<html>
+<head>
+<script src="resources/clearSessionStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+ if (!window.layoutTestController) {
+ log("Test only designed to be run under DumpRenderTree");
+ return;
+ }
+
+ sessionStorage.setItem("testItem", "InitialValue");
+ layoutTestController.setPrivateBrowsingEnabled(true);
+ log("Initial value of testItem is: " + sessionStorage.getItem("testItem"));
+
+ try {
+ sessionStorage.setItem("testItem", "ChangedValue");
+ } catch(e) {
+ log("Caught exception trying to change item: " + e);
+ }
+
+ log("After change attempt, testItem is: " + sessionStorage.getItem("testItem"));
+
+ sessionStorage.removeItem("testItem");
+ log("After remove attempt, testItem is: " + sessionStorage.getItem("testItem"));
+
+ sessionStorage.clear();
+ log("After clear attempt, testItem is: " + sessionStorage.getItem("testItem"));
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This is a test to make sure that when private browsing is on any attempt to change the sessionStorage area fail.
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/resources/clearSessionStorage.js b/LayoutTests/storage/domstorage/sessionstorage/resources/clearSessionStorage.js
new file mode 100644
index 0000000..489ef2a
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/resources/clearSessionStorage.js
@@ -0,0 +1,12 @@
+function clearSessionStorage()
+{
+ var keys = new Array();
+ for (key in sessionStorage)
+ keys.push(key);
+
+ for (key in keys)
+ sessionStorage.removeItem(keys[key]);
+}
+
+if (window.sessionStorage)
+ clearSessionStorage();
diff --git a/LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html b/LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html
new file mode 100644
index 0000000..2d7b004
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/resources/iframe-events-second.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<script>
+function handleStorageEvent(e)
+{
+ parent.log("Subframe received storage event:");
+ parent.log("Key - " + e.key);
+ parent.log("New Value - " + e.newValue);
+ parent.log("Old Value - " + e.oldValue);
+ parent.log("URI - " + parent.normalizeURL(e.uri));
+ parent.log("Storage Area - " + ((e.storageArea == window.sessionStorage) ? "This window's window.sessionStorage" : "Another window's window.sessionStorage"));
+ parent.log("");
+
+ if (e.key != "Subframe") {
+ parent.log("Subframe about to change sessionStorage...");
+ sessionStorage.setItem("Subframe", "SET");
+ }
+}
+</script>
+</head>
+<body onload="window.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 sessionStorage object mutating
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/resources/window-open-second.html b/LayoutTests/storage/domstorage/sessionstorage/resources/window-open-second.html
new file mode 100644
index 0000000..b8dede6
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/resources/window-open-second.html
@@ -0,0 +1,36 @@
+<html>
+<head>
+<script>
+
+var secondWindowLog = "Logging from second window:<br>";
+
+function log(a)
+{
+ secondWindowLog += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+
+ log("Value for FOO is " + window.sessionStorage.getItem("FOO"));
+ window.sessionStorage.setItem("FOO", "BAR-NEWWINDOW");
+ log("Value for FOO after changing my own copy is " + window.sessionStorage.getItem("FOO"));
+
+ log("Value for FOO in my opening window is " + window.opener.sessionStorage.getItem("FOO"));
+
+ window.opener.log(secondWindowLog);
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This is a new window to make sure there is a copy of the previous window's sessionStorage, and that they diverge after a change<br>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/simple-usage-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/simple-usage-expected.txt
new file mode 100644
index 0000000..399fd08
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/simple-usage-expected.txt
@@ -0,0 +1,13 @@
+This test trys simple operations on SessionStorage
+Length is 0
+Value for FOO is null
+Length is 1
+Value for FOO is BAR
+Key for index 0 is FOO
+Key for index 1 is null
+Key for index -1 is null
+Length is 1
+Value for FOO is BAZ
+Length is 0
+Value for FOO is null
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/simple-usage.html b/LayoutTests/storage/domstorage/sessionstorage/simple-usage.html
new file mode 100644
index 0000000..8e45521
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/simple-usage.html
@@ -0,0 +1,49 @@
+<html>
+<head>
+<script src="resources/clearSessionStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+
+ log("Length is " + window.sessionStorage.length);
+ log("Value for FOO is " + window.sessionStorage.getItem("FOO"));
+
+ window.sessionStorage.setItem("FOO", "BAR");
+
+ log("Length is " + window.sessionStorage.length);
+ log("Value for FOO is " + window.sessionStorage.getItem("FOO"));
+ log("Key for index 0 is " + window.sessionStorage.key(0));
+ log("Key for index 1 is " + window.sessionStorage.key(1));
+ log("Key for index -1 is " + window.sessionStorage.key(-1));
+
+ window.sessionStorage.setItem("FOO", "BAZ");
+
+ log("Length is " + window.sessionStorage.length);
+ log("Value for FOO is " + window.sessionStorage.getItem("FOO"));
+
+ window.sessionStorage.removeItem("FOO");
+
+ log("Length is " + window.sessionStorage.length);
+ log("Value for FOO is " + window.sessionStorage.getItem("FOO"));
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This test trys simple operations on SessionStorage<br>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/string-conversion-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/string-conversion-expected.txt
new file mode 100644
index 0000000..65dcb2c
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/string-conversion-expected.txt
@@ -0,0 +1,15 @@
+This test case verifies that session storage only stores strings.
+Length is 0
+Testing implicit setters
+Type/value for null is string/null
+Type/value for 0 is string/0
+Type/value for function(){} is string/function () {}
+Testing explicit setters
+Type/value for null is string/null
+Type/value for 0 is string/0
+Type/value for function(){} is string/function () {}
+Testing index setters
+Type/value for null is string/null
+Type/value for 0 is string/0
+Type/value for function(){} is string/function () {}
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/string-conversion.html b/LayoutTests/storage/domstorage/sessionstorage/string-conversion.html
new file mode 100644
index 0000000..64a4e14
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/string-conversion.html
@@ -0,0 +1,54 @@
+<html>
+<head>
+<script src="resources/clearSessionStorage.js"></script>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+
+ log("Length is " + sessionStorage.length);
+
+ log("Testing implicit setters");
+ sessionStorage.a = null;
+ log("Type/value for null is " + typeof sessionStorage.a + "/" + sessionStorage.a);
+ sessionStorage.b = 0;
+ log("Type/value for 0 is " + typeof sessionStorage.b + "/" + sessionStorage.b);
+ sessionStorage.c = function(){};
+ log("Type/value for function(){} is " + typeof sessionStorage.c + "/" + sessionStorage.c);
+
+ log("Testing explicit setters");
+ sessionStorage.setItem('d', null);
+ log("Type/value for null is " + typeof sessionStorage.d + "/" + sessionStorage.d);
+ sessionStorage.setItem('e', 0);
+ log("Type/value for 0 is " + typeof sessionStorage.e + "/" + sessionStorage.e);
+ sessionStorage.setItem('f', function(){});
+ log("Type/value for function(){} is " + typeof sessionStorage.f + "/" + sessionStorage.f);
+
+ log("Testing index setters");
+ sessionStorage['g'] = null;
+ log("Type/value for null is " + typeof sessionStorage.g + "/" + sessionStorage.g);
+ sessionStorage['h'] = 0;
+ log("Type/value for 0 is " + typeof sessionStorage.h + "/" + sessionStorage.h);
+ sessionStorage['i'] = function(){};
+ log("Type/value for function(){} is " + typeof sessionStorage.i + "/" + sessionStorage.i);
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This test case verifies that session storage only stores strings.
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/sessionstorage/window-open-expected.txt b/LayoutTests/storage/domstorage/sessionstorage/window-open-expected.txt
new file mode 100644
index 0000000..c613414
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/window-open-expected.txt
@@ -0,0 +1,8 @@
+This is a new window to make sure there is a copy of the previous window's sessionStorage, and that they diverge after a change
+Value for FOO is BAR
+Logging from second window:
+Value for FOO is BAR
+Value for FOO after changing my own copy is BAR-NEWWINDOW
+Value for FOO in my opening window is BAR
+
+
diff --git a/LayoutTests/storage/domstorage/sessionstorage/window-open.html b/LayoutTests/storage/domstorage/sessionstorage/window-open.html
new file mode 100644
index 0000000..34f8f39
--- /dev/null
+++ b/LayoutTests/storage/domstorage/sessionstorage/window-open.html
@@ -0,0 +1,39 @@
+<html>
+<head>
+<script src="resources/clearSessionStorage.js"></script>
+<script>
+
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.setCanOpenWindows();
+ layoutTestController.waitUntilDone();
+}
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function runTest()
+{
+ if (!window.sessionStorage) {
+ log("window.sessionStorage DOES NOT exist");
+ return;
+ }
+
+ window.log = log;
+
+ window.sessionStorage.setItem("FOO", "BAR");
+ log("Value for FOO is " + window.sessionStorage.getItem("FOO"));
+ window.open("resources/window-open-second.html");
+
+
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This is a new window to make sure there is a copy of the previous window's sessionStorage, and that they diverge after a change<br>
+<div id="logger"></div>
+</body>
+</html>
diff --git a/LayoutTests/storage/domstorage/window-attributes-exist-expected.txt b/LayoutTests/storage/domstorage/window-attributes-exist-expected.txt
new file mode 100644
index 0000000..e7668fd
--- /dev/null
+++ b/LayoutTests/storage/domstorage/window-attributes-exist-expected.txt
@@ -0,0 +1,21 @@
+This test checks to see if window.localStorage, window.sessionStorage and window.onstorage exist.
+window.sessionStorage exists
+Storage object sessionStorage has length
+Storage object sessionStorage has key
+Storage object sessionStorage has getItem
+Storage object sessionStorage has setItem
+Storage object sessionStorage has removeItem
+Storage object sessionStorage has clear
+window.sessionStorage == window.sessionStorage: true
+window.sessionStorage === window.sessionStorage: true
+window.localStorage exists
+Storage object localStorage has length
+Storage object localStorage has key
+Storage object localStorage has getItem
+Storage object localStorage has setItem
+Storage object localStorage has removeItem
+Storage object localStorage has clear
+window.localStorage == window.localStorage: true
+window.localStorage === window.localStorage: true
+window.onstorage exists
+
diff --git a/LayoutTests/storage/domstorage/window-attributes-exist.html b/LayoutTests/storage/domstorage/window-attributes-exist.html
new file mode 100644
index 0000000..d01ba7c
--- /dev/null
+++ b/LayoutTests/storage/domstorage/window-attributes-exist.html
@@ -0,0 +1,59 @@
+<html>
+<head>
+<script>
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function log(a)
+{
+ document.getElementById("logger").innerHTML += a + "<br>";
+}
+
+function testStorage(name, storage)
+{
+ if ("length" in storage)
+ log("Storage object " + name + " has length");
+ if ("key" in storage)
+ log("Storage object " + name + " has key");
+ if ("getItem" in storage)
+ log("Storage object " + name + " has getItem");
+ if ("setItem" in storage)
+ log("Storage object " + name + " has setItem");
+ if ("removeItem" in storage)
+ log("Storage object " + name + " has removeItem");
+ if ("clear" in storage)
+ log("Storage object " + name + " has clear");
+}
+
+function runTest()
+{
+ if ("sessionStorage" in window) {
+ log("window.sessionStorage exists");
+ testStorage("sessionStorage", window.sessionStorage);
+ log("window.sessionStorage == window.sessionStorage: " + (window.sessionStorage == window.sessionStorage));
+ log("window.sessionStorage === window.sessionStorage: " + (window.sessionStorage === window.sessionStorage));
+ } else
+ log("window.sessionStorage DOES NOT exist");
+
+ if ("localStorage" in window) {
+ log("window.localStorage exists");
+ testStorage("localStorage", window.localStorage);
+ log("window.localStorage == window.localStorage: " + (window.localStorage == window.localStorage));
+ log("window.localStorage === window.localStorage: " + (window.localStorage === window.localStorage));
+ } else
+ log("window.localStorage DOES NOT exist");
+
+ if ("onstorage" in window)
+ log("window.onstorage exists");
+ else
+ log("window.onstorage DOES NOT exist");
+}
+
+</script>
+</head>
+<body onload="runTest();">
+This test checks to see if window.localStorage, window.sessionStorage and window.onstorage exist.<br>
+<div id="logger"></div>
+</body>
+</html>