summaryrefslogtreecommitdiffstats
path: root/LayoutTests
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2010-11-04 12:00:17 -0700
committerJohn Reck <jreck@google.com>2010-11-09 11:35:04 -0800
commite14391e94c850b8bd03680c23b38978db68687a8 (patch)
tree3fed87e6620fecaf3edc7259ae58a11662bedcb2 /LayoutTests
parent1bd705833a68f07850cf7e204b26f8d328d16951 (diff)
downloadexternal_webkit-e14391e94c850b8bd03680c23b38978db68687a8.zip
external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.gz
external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.bz2
Merge Webkit at r70949: Initial merge by git.
Change-Id: I77b8645c083b5d0da8dba73ed01d4014aab9848e
Diffstat (limited to 'LayoutTests')
-rw-r--r--LayoutTests/fast/js/resources/js-test-pre.js18
-rw-r--r--LayoutTests/storage/indexeddb/constants-expected.txt2
-rw-r--r--LayoutTests/storage/indexeddb/constants.html2
-rw-r--r--LayoutTests/storage/indexeddb/database-quota-expected.txt1032
-rw-r--r--LayoutTests/storage/indexeddb/database-quota.html10
-rw-r--r--LayoutTests/storage/indexeddb/duplicates-expected.txt541
-rw-r--r--LayoutTests/storage/indexeddb/duplicates.html213
-rw-r--r--LayoutTests/storage/indexeddb/index-basics-expected.txt4
-rw-r--r--LayoutTests/storage/indexeddb/index-basics.html15
-rw-r--r--LayoutTests/storage/indexeddb/index-cursor-expected.txt38
-rw-r--r--LayoutTests/storage/indexeddb/index-cursor.html34
-rw-r--r--LayoutTests/storage/indexeddb/keyrange-expected.txt12
-rw-r--r--LayoutTests/storage/indexeddb/keyrange.html47
-rw-r--r--LayoutTests/storage/indexeddb/objectstore-basics-expected.txt11
-rw-r--r--LayoutTests/storage/indexeddb/objectstore-basics.html36
-rw-r--r--LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt20
-rw-r--r--LayoutTests/storage/indexeddb/objectstore-cursor.html37
-rw-r--r--LayoutTests/storage/indexeddb/open-cursor-expected.txt3
-rw-r--r--LayoutTests/storage/indexeddb/open-cursor.html8
-rw-r--r--LayoutTests/storage/indexeddb/tutorial-expected.txt2
-rw-r--r--LayoutTests/storage/indexeddb/tutorial.html433
21 files changed, 1474 insertions, 1044 deletions
diff --git a/LayoutTests/fast/js/resources/js-test-pre.js b/LayoutTests/fast/js/resources/js-test-pre.js
index 3536a89..c14d513 100644
--- a/LayoutTests/fast/js/resources/js-test-pre.js
+++ b/LayoutTests/fast/js/resources/js-test-pre.js
@@ -219,6 +219,24 @@ function shouldBeUndefined(_a)
testFailed(_a + " should be undefined. Was " + _av);
}
+function shouldBeDefined(_a)
+{
+ var exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ exception = e;
+ }
+
+ if (exception)
+ testFailed(_a + " should be defined. Threw exception " + exception);
+ else if (_av !== undefined)
+ testPassed(_a + " is defined.");
+ else
+ testFailed(_a + " should be defined. Was " + _av);
+}
+
function shouldBeGreaterThanOrEqual(_a, _b) {
if (typeof _a != "string" || typeof _b != "string")
debug("WARN: shouldBeGreaterThanOrEqual expects string arguments");
diff --git a/LayoutTests/storage/indexeddb/constants-expected.txt b/LayoutTests/storage/indexeddb/constants-expected.txt
index 15a2df7..8f53b56 100644
--- a/LayoutTests/storage/indexeddb/constants-expected.txt
+++ b/LayoutTests/storage/indexeddb/constants-expected.txt
@@ -8,7 +8,7 @@ PASS webkitIDBKeyRange.LEFT_OPEN is 1
PASS webkitIDBKeyRange.RIGHT_OPEN is 2
PASS webkitIDBKeyRange.LEFT_BOUND is 4
PASS webkitIDBKeyRange.RIGHT_BOUND is 8
-PASS webkitIDBDatabaseException.UNKNOWN_ERR is 0
+PASS webkitIDBDatabaseException.UNKNOWN_ERR is 1
PASS webkitIDBDatabaseException.NON_TRANSIENT_ERR is 1
PASS webkitIDBDatabaseException.NOT_FOUND_ERR is 2
PASS webkitIDBDatabaseException.CONSTRAINT_ERR is 3
diff --git a/LayoutTests/storage/indexeddb/constants.html b/LayoutTests/storage/indexeddb/constants.html
index 813fe7a..9cdf4c4 100644
--- a/LayoutTests/storage/indexeddb/constants.html
+++ b/LayoutTests/storage/indexeddb/constants.html
@@ -22,7 +22,7 @@ function test()
shouldBe("webkitIDBKeyRange.LEFT_BOUND", "4");
shouldBe("webkitIDBKeyRange.RIGHT_BOUND", "8");
- shouldBe("webkitIDBDatabaseException.UNKNOWN_ERR", "0");
+ shouldBe("webkitIDBDatabaseException.UNKNOWN_ERR", "1");
shouldBe("webkitIDBDatabaseException.NON_TRANSIENT_ERR", "1");
shouldBe("webkitIDBDatabaseException.NOT_FOUND_ERR", "2");
shouldBe("webkitIDBDatabaseException.CONSTRAINT_ERR", "3");
diff --git a/LayoutTests/storage/indexeddb/database-quota-expected.txt b/LayoutTests/storage/indexeddb/database-quota-expected.txt
index b6ea505..91d3ac7 100644
--- a/LayoutTests/storage/indexeddb/database-quota-expected.txt
+++ b/LayoutTests/storage/indexeddb/database-quota-expected.txt
@@ -68,1035 +68,7 @@ trans = db.transaction()
Creating 'data' which contains 64K of data
PASS data.length is 65536
store = trans.objectStore('test123')
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Success event fired:
-PASS 'result' in event is true
-PASS 'code' in event is false
-PASS 'message' in event is false
-PASS 'source' in event is true
-PASS event.source != null is true
-PASS 'onsuccess' in event.target is true
-PASS 'onerror' in event.target is true
-PASS 'readyState' in event.target is true
-PASS event.target.readyState is event.target.DONE
-
-store = event.source
-store.add({x: data}, dataAdded)
-Error function called: (0) Error writing data to stable storage.
+Error function called: (1) Error writing data to stable storage.
Error event fired:
PASS 'result' in event is false
PASS 'code' in event is true
@@ -1108,7 +80,7 @@ PASS 'onerror' in event.target is true
PASS 'readyState' in event.target is true
PASS event.target.readyState is event.target.DONE
-PASS Adding data failed due to quota error. Data added was: 5120 KB
+PASS Adding data failed due to quota error. Data added was about 5 MB
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/database-quota.html b/LayoutTests/storage/indexeddb/database-quota.html
index 45ce709..aefe6b1 100644
--- a/LayoutTests/storage/indexeddb/database-quota.html
+++ b/LayoutTests/storage/indexeddb/database-quota.html
@@ -90,17 +90,15 @@ function checkQuotaEnforcing()
function addData()
{
if (dataAdded < 5 * 1024 * 1024) {
- if (dataAdded > 0) {
- verifySuccessEvent(event);
- store = evalAndLog("store = event.source");
- }
+ if (dataAdded > 0)
+ store = event.source;
} else {
testFailed("added more than quota");
done();
return;
}
dataAdded += 65536;
- result = evalAndLog("store.add({x: data}, dataAdded)");
+ result = store.add({x: data}, dataAdded);
result.onsuccess = addData;
result.onerror = logError;
}
@@ -113,7 +111,7 @@ function logError()
function testComplete()
{
- testPassed("Adding data failed due to quota error. Data added was: " + dataAdded / 1024 + " KB");
+ testPassed("Adding data failed due to quota error. Data added was about " + Math.round(dataAdded / 1024 / 1024) + " MB");
done();
}
diff --git a/LayoutTests/storage/indexeddb/duplicates-expected.txt b/LayoutTests/storage/indexeddb/duplicates-expected.txt
new file mode 100644
index 0000000..2ea8c36
--- /dev/null
+++ b/LayoutTests/storage/indexeddb/duplicates-expected.txt
@@ -0,0 +1,541 @@
+Verify that you can put the same data in 2 different databases without uniqueness constraints firing.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+webkitIndexedDB.open('name', 'description')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+db = event.result
+db.setVersion('new version')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+setVersionSuccess():
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+trans = event.result
+PASS trans !== null is true
+Deleted all object stores.
+db.createObjectStore('storeName', null)
+store.createIndex('indexName', 'x')
+store.add({x: 'value', y: 'zzz'}, 'key')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+event.source.add({x: 'value2', y: 'zzz2'}, 'key2')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+indexObject.getKey('value')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result is "key"
+indexObject.get('value')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result.x is "value"
+PASS event.result.y is "zzz"
+indexObject.getKey('does not exist')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Error event fired:
+PASS 'result' in event is false
+PASS 'code' in event is true
+PASS 'message' in event is true
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.code is webkitIDBDatabaseException.NOT_FOUND_ERR
+indexObject.get('does not exist')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Error event fired:
+PASS 'result' in event is false
+PASS 'code' in event is true
+PASS 'message' in event is true
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.code is webkitIDBDatabaseException.NOT_FOUND_ERR
+indexObject.openKeyCursor()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value"
+PASS event.result.value is "key"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value2"
+PASS event.result.value is "key2"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is true
+indexObject.openCursor()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value"
+PASS event.result.value.x is "value"
+PASS event.result.value.y is "zzz"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value2"
+PASS event.result.value.x is "value2"
+PASS event.result.value.y is "zzz2"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is true
+webkitIndexedDB.open('name2', 'description2')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+db = event.result
+db.setVersion('new version')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+setVersionSuccess():
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+trans = event.result
+PASS trans !== null is true
+Deleted all object stores.
+db.createObjectStore('storeName', null)
+store.createIndex('indexName', 'x')
+store.add({x: 'value', y: 'zzz'}, 'key')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+event.source.add({x: 'value2', y: 'zzz2'}, 'key2')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+indexObject.getKey('value')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result is "key"
+indexObject.get('value')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result.x is "value"
+PASS event.result.y is "zzz"
+indexObject.getKey('does not exist')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Error event fired:
+PASS 'result' in event is false
+PASS 'code' in event is true
+PASS 'message' in event is true
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.code is webkitIDBDatabaseException.NOT_FOUND_ERR
+indexObject.get('does not exist')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Error event fired:
+PASS 'result' in event is false
+PASS 'code' in event is true
+PASS 'message' in event is true
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.code is webkitIDBDatabaseException.NOT_FOUND_ERR
+indexObject.openKeyCursor()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value"
+PASS event.result.value is "key"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value2"
+PASS event.result.value is "key2"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is true
+indexObject.openCursor()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value"
+PASS event.result.value.x is "value"
+PASS event.result.value.y is "zzz"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is false
+PASS event.result.key is "value2"
+PASS event.result.value.x is "value2"
+PASS event.result.value.y is "zzz2"
+event.result.continue()
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result === null is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/indexeddb/duplicates.html b/LayoutTests/storage/indexeddb/duplicates.html
new file mode 100644
index 0000000..70cf8c4
--- /dev/null
+++ b/LayoutTests/storage/indexeddb/duplicates.html
@@ -0,0 +1,213 @@
+<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>
+<script src="resources/shared.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("Verify that you can put the same data in 2 different databases without uniqueness constraints firing.");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+testCount = 0;
+function test()
+{
+ if (testCount++ == 0)
+ result = evalAndLog("webkitIndexedDB.open('name', 'description')");
+ else
+ result = evalAndLog("webkitIndexedDB.open('name2', 'description2')");
+ verifyResult(result);
+ result.onsuccess = setVersion;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function setVersion()
+{
+ verifySuccessEvent(event);
+ db = evalAndLog("db = event.result");
+
+ result = evalAndLog("db.setVersion('new version')");
+ verifyResult(result);
+ result.onsuccess = deleteExisting;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function deleteExisting()
+{
+ debug("setVersionSuccess():");
+ verifySuccessEvent(event);
+ window.trans = evalAndLog("trans = event.result");
+ shouldBeTrue("trans !== null");
+ trans.onabort = unexpectedAbortCallback;
+
+ deleteAllObjectStores(db, createIndex);
+}
+
+function createIndex()
+{
+ window.store = evalAndLog("db.createObjectStore('storeName', null)");
+ window.indexObject = evalAndLog("store.createIndex('indexName', 'x')");
+ addData();
+}
+
+function addData()
+{
+ result = evalAndLog("store.add({x: 'value', y: 'zzz'}, 'key')");
+ verifyResult(result);
+ result.onsuccess = addMore;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function addMore()
+{
+ verifySuccessEvent(event);
+
+ result = evalAndLog("event.source.add({x: 'value2', y: 'zzz2'}, 'key2')");
+ verifyResult(result);
+ result.onsuccess = getData;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function getData()
+{
+ verifySuccessEvent(event);
+
+ result = evalAndLog("indexObject.getKey('value')");
+ verifyResult(result);
+ result.onsuccess = getObjectData;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function getObjectData()
+{
+ verifySuccessEvent(event);
+ shouldBeEqualToString("event.result", "key");
+
+ result = evalAndLog("indexObject.get('value')");
+ verifyResult(result);
+ result.onsuccess = getDataFail;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function getDataFail()
+{
+ verifySuccessEvent(event);
+ shouldBeEqualToString("event.result.x", "value");
+ shouldBeEqualToString("event.result.y", "zzz");
+
+ result = evalAndLog("indexObject.getKey('does not exist')");
+ verifyResult(result);
+ result.onsuccess = unexpectedSuccessCallback;
+ result.onerror = getObjectDataFail;
+}
+
+function getObjectDataFail()
+{
+ verifyErrorEvent(event);
+ shouldBe("event.code", "webkitIDBDatabaseException.NOT_FOUND_ERR");
+
+ result = evalAndLog("indexObject.get('does not exist')");
+ verifyResult(result);
+ result.onsuccess = unexpectedSuccessCallback;
+ result.onerror = openKeyCursor;
+}
+
+function openKeyCursor()
+{
+ verifyErrorEvent(event);
+ shouldBe("event.code", "webkitIDBDatabaseException.NOT_FOUND_ERR");
+
+ window.result = evalAndLog("indexObject.openKeyCursor()");
+ verifyResult(result);
+ result.onsuccess = cursor1Continue;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function cursor1Continue()
+{
+ verifySuccessEvent(event);
+ shouldBeFalse("event.result === null");
+ shouldBeEqualToString("event.result.key", "value");
+ shouldBeEqualToString("event.result.value", "key");
+
+ // We re-use the last result object.
+ evalAndLog("event.result.continue()");
+ verifyResult(window.result);
+ window.result.onsuccess = cursor1Continue2;
+}
+
+function cursor1Continue2()
+{
+ verifySuccessEvent(event);
+ shouldBeFalse("event.result === null");
+ shouldBeEqualToString("event.result.key", "value2");
+ shouldBeEqualToString("event.result.value", "key2");
+
+ // We re-use the last result object.
+ evalAndLog("event.result.continue()");
+ verifyResult(window.result);
+ window.result.onsuccess = openObjectCursor;
+}
+
+function openObjectCursor()
+{
+ verifySuccessEvent(event);
+ shouldBeTrue("event.result === null");
+
+ window.result = evalAndLog("indexObject.openCursor()");
+ verifyResult(result);
+ result.onsuccess = cursor2Continue;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function cursor2Continue()
+{
+ verifySuccessEvent(event);
+ shouldBeFalse("event.result === null");
+ shouldBeEqualToString("event.result.key", "value");
+ shouldBeEqualToString("event.result.value.x", "value");
+ shouldBeEqualToString("event.result.value.y", "zzz");
+
+ // We re-use the last result object.
+ evalAndLog("event.result.continue()");
+ verifyResult(window.result);
+ window.result.onsuccess = cursor2Continue2;
+}
+
+function cursor2Continue2()
+{
+ verifySuccessEvent(event);
+ shouldBeFalse("event.result === null");
+ shouldBeEqualToString("event.result.key", "value2");
+ shouldBeEqualToString("event.result.value.x", "value2");
+ shouldBeEqualToString("event.result.value.y", "zzz2");
+
+ // We re-use the last result object.
+ evalAndLog("event.result.continue()");
+ verifyResult(window.result);
+ window.result.onsuccess = last;
+}
+
+function last()
+{
+ verifySuccessEvent(event);
+ shouldBeTrue("event.result === null");
+
+ if (testCount == 1)
+ test();
+ else
+ done();
+}
+
+test();
+
+var successfullyParsed = true;
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/storage/indexeddb/index-basics-expected.txt b/LayoutTests/storage/indexeddb/index-basics-expected.txt
index 0869d95..f886a19 100644
--- a/LayoutTests/storage/indexeddb/index-basics-expected.txt
+++ b/LayoutTests/storage/indexeddb/index-basics-expected.txt
@@ -300,6 +300,10 @@ PASS 'readyState' in event.target is true
PASS event.target.readyState is event.target.DONE
PASS event.result === null is true
+Passing an invalid key into indexObject.get().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into indexObject.getKey().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/index-basics.html b/LayoutTests/storage/indexeddb/index-basics.html
index f7257f1..7a16c3a 100644
--- a/LayoutTests/storage/indexeddb/index-basics.html
+++ b/LayoutTests/storage/indexeddb/index-basics.html
@@ -219,6 +219,21 @@ function last()
verifySuccessEvent(event);
shouldBeTrue("event.result === null");
+ try {
+ debug("Passing an invalid key into indexObject.get().");
+ indexObject.get([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into indexObject.getKey().");
+ indexObject.getKey([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
done();
}
diff --git a/LayoutTests/storage/indexeddb/index-cursor-expected.txt b/LayoutTests/storage/indexeddb/index-cursor-expected.txt
index 88b96ff..bc01070 100644
--- a/LayoutTests/storage/indexeddb/index-cursor-expected.txt
+++ b/LayoutTests/storage/indexeddb/index-cursor-expected.txt
@@ -2058,6 +2058,44 @@ PASS event.result.key is testData[7]
PASS event.result.value is expectedIndex
PASS event.result.key is testData[6]
PASS event.result is null
+
+Next test: null key path sorted ascending.
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[0]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[1]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[2]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[3]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[4]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[5]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[6]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[7]
+PASS event.result is null
+
+Next test: null key path sorted descending.
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[7]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[6]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[5]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[4]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[3]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[2]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[1]
+PASS event.result.value is expectedIndex
+PASS event.result.key is testData[0]
+PASS event.result is null
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/index-cursor.html b/LayoutTests/storage/indexeddb/index-cursor.html
index 5aab4f8..6a9d1ac 100644
--- a/LayoutTests/storage/indexeddb/index-cursor.html
+++ b/LayoutTests/storage/indexeddb/index-cursor.html
@@ -107,7 +107,7 @@ function scheduleTests()
function runNextTest()
{
if (!scheduledTests.length) {
- done();
+ testNullKeyRange();
return;
}
@@ -226,6 +226,38 @@ function cursorIteration()
event.result.continue();
}
+window.nullKeyRangeStep = 0;
+function testNullKeyRange()
+{
+ window.lower = 0;
+ window.lowerIsOpen = false;
+ window.upper = testData.length-1;
+ window.upperIsOpen = false;
+
+ str = "Next test: null key path ";
+ if (window.nullKeyRangeStep == 0) {
+ str += "sorted ascending.";
+ window.ascending = true;
+ window.expectedIndex = lower;
+ window.nullKeyRangeStep = 1;
+ } else if (window.nullKeyRangeStep == 1) {
+ str += "sorted descending.";
+ window.ascending = false;
+ window.expectedIndex = upper;
+ window.nullKeyRangeStep = 2;
+ } else {
+ done();
+ return;
+ }
+
+ debug("");
+ debug(str);
+
+ var request = indexObject.openKeyCursor(null, ascending ? webkitIDBCursor.NEXT : webkitIDBCursor.PREV);
+ request.onsuccess = cursorIteration;
+ request.onerror = unexpectedErrorCallback;
+}
+
openDatabase(); // The first step.
var successfullyParsed = true;
diff --git a/LayoutTests/storage/indexeddb/keyrange-expected.txt b/LayoutTests/storage/indexeddb/keyrange-expected.txt
index 8d6bf86..1a7dfff 100644
--- a/LayoutTests/storage/indexeddb/keyrange-expected.txt
+++ b/LayoutTests/storage/indexeddb/keyrange-expected.txt
@@ -141,6 +141,18 @@ PASS keyRange.left is 'aaf'
PASS keyRange.right is 'abf'
PASS leftFlags is keyRange.LEFT_OPEN | keyRange.LEFT_BOUND
PASS rightFlags is keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND
+Passing an invalid key into only([])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into rightBound([])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into leftBound([])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into bound(null, [])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into bound([],null)
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into bound([], [])
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/keyrange.html b/LayoutTests/storage/indexeddb/keyrange.html
index c3885fc..48708d9 100644
--- a/LayoutTests/storage/indexeddb/keyrange.html
+++ b/LayoutTests/storage/indexeddb/keyrange.html
@@ -112,6 +112,53 @@ function test()
checkBoundKeyRange("'aae'", "'abe'", true, false);
checkBoundKeyRange("'aaf'", "'abf'", true, true);
+ try {
+ debug("Passing an invalid key into only([])");
+ webkitIDBKeyRange.only([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into rightBound([])");
+ webkitIDBKeyRange.rightBound([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into leftBound([])");
+ webkitIDBKeyRange.leftBound([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into bound(null, [])");
+ webkitIDBKeyRange.bound(null, []);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into bound([],null)");
+ webkitIDBKeyRange.bound([], null);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into bound([], [])");
+ webkitIDBKeyRange.bound([], []);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
}
test();
diff --git a/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt b/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
index d22e6f0..e0c9770 100644
--- a/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
+++ b/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
@@ -43,7 +43,7 @@ PASS event.target.readyState is event.target.DONE
trans = event.result
PASS trans !== null is true
Deleted all object stores.
-creatObjectStore():
+createObjectStore():
store = db.createObjectStore('storeName', null)
storeNames = db.objectStores
PASS store.name is "storeName"
@@ -176,6 +176,15 @@ PASS 'readyState' in event.target is true
PASS event.target.readyState is event.target.DONE
PASS event.result is null
+store = event.source
+Passing an invalid key into store.get().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into store.remove().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into store.add().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+Passing an invalid key into store.put().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/objectstore-basics.html b/LayoutTests/storage/indexeddb/objectstore-basics.html
index 9730db8..005247e 100644
--- a/LayoutTests/storage/indexeddb/objectstore-basics.html
+++ b/LayoutTests/storage/indexeddb/objectstore-basics.html
@@ -47,7 +47,7 @@ function setVersionSuccess()
function createObjectStore()
{
- debug("creatObjectStore():");
+ debug("createObjectStore():");
window.store = evalAndLog("store = db.createObjectStore('storeName', null)");
var storeNames = evalAndLog("storeNames = db.objectStores");
@@ -195,6 +195,40 @@ function removeSuccess()
debug("removeSuccess():");
verifySuccessEvent(event);
shouldBeNull("event.result");
+ var store = evalAndLog("store = event.source");
+
+ try {
+ debug("Passing an invalid key into store.get().");
+ store.get([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into store.remove().");
+ store.remove([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into store.add().");
+ store.add(null, []);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
+ try {
+ debug("Passing an invalid key into store.put().");
+ store.put(null, []);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+
done();
}
diff --git a/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt b/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt
index 881fe92..1493a80 100644
--- a/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt
+++ b/LayoutTests/storage/indexeddb/objectstore-cursor-expected.txt
@@ -854,6 +854,26 @@ PASS event.result is null
Next test: lower bound is 6; upper bound is 6; sorted descending.
PASS event.result.key is testData[6]
PASS event.result is null
+
+Next test: null key path sorted ascending.
+PASS event.result.key is testData[0]
+PASS event.result.key is testData[1]
+PASS event.result.key is testData[2]
+PASS event.result.key is testData[3]
+PASS event.result.key is testData[4]
+PASS event.result.key is testData[5]
+PASS event.result.key is testData[6]
+PASS event.result is null
+
+Next test: null key path sorted descending.
+PASS event.result.key is testData[6]
+PASS event.result.key is testData[5]
+PASS event.result.key is testData[4]
+PASS event.result.key is testData[3]
+PASS event.result.key is testData[2]
+PASS event.result.key is testData[1]
+PASS event.result.key is testData[0]
+PASS event.result is null
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/storage/indexeddb/objectstore-cursor.html b/LayoutTests/storage/indexeddb/objectstore-cursor.html
index d9ad805..d0d786b 100644
--- a/LayoutTests/storage/indexeddb/objectstore-cursor.html
+++ b/LayoutTests/storage/indexeddb/objectstore-cursor.html
@@ -105,7 +105,7 @@ function scheduleTests()
function runNextTest()
{
if (!scheduledTests.length) {
- done();
+ testNullKeyRange();
return;
}
@@ -164,8 +164,7 @@ function runNextTest()
else
keyRange = webkitIDBKeyRange.rightBound(testData[upper], upperIsOpen);
- // FIXME: Should be webkitIDBCursor.NEXT : webkitIDBCursor.PREV, but we can't do that yet.
- var request = objectStore.openCursor(keyRange, ascending ? 0 : 2);
+ var request = objectStore.openCursor(keyRange, ascending ? webkitIDBCursor.NEXT : webkitIDBCursor.PREV);
request.onsuccess = cursorIteration;
request.onerror = unexpectedErrorCallback;
}
@@ -204,6 +203,38 @@ function cursorIteration()
event.result.continue();
}
+window.nullKeyRangeStep = 0;
+function testNullKeyRange()
+{
+ window.lower = 0;
+ window.lowerIsOpen = false;
+ window.upper = testData.length-1;
+ window.upperIsOpen = false;
+
+ str = "Next test: null key path ";
+ if (window.nullKeyRangeStep == 0) {
+ str += "sorted ascending.";
+ window.ascending = true;
+ window.expectedIndex = lower;
+ window.nullKeyRangeStep = 1;
+ } else if (window.nullKeyRangeStep == 1) {
+ str += "sorted descending.";
+ window.ascending = false;
+ window.expectedIndex = upper;
+ window.nullKeyRangeStep = 2;
+ } else {
+ done();
+ return;
+ }
+
+ debug("");
+ debug(str);
+
+ var request = objectStore.openCursor(null, ascending ? webkitIDBCursor.NEXT : webkitIDBCursor.PREV);
+ request.onsuccess = cursorIteration;
+ request.onerror = unexpectedErrorCallback;
+}
+
openDatabase(); // The first step.
var successfullyParsed = true;
diff --git a/LayoutTests/storage/indexeddb/open-cursor-expected.txt b/LayoutTests/storage/indexeddb/open-cursor-expected.txt
index 1bca527..c3c1a8d 100644
--- a/LayoutTests/storage/indexeddb/open-cursor-expected.txt
+++ b/LayoutTests/storage/indexeddb/open-cursor-expected.txt
@@ -72,6 +72,9 @@ PASS event.result.direction is 0
PASS event.result.key is 'myKey'
PASS event.result.value is 'myValue'
+Passing an invalid key into .continue().
+PASS Caught exception: Error: TYPE_MISMATCH_ERR: DOM Exception 17
+
Opening an empty cursor.
objectStore.openCursor(keyRange)
PASS 'onsuccess' in result is true
diff --git a/LayoutTests/storage/indexeddb/open-cursor.html b/LayoutTests/storage/indexeddb/open-cursor.html
index ec62f2c..815c01b 100644
--- a/LayoutTests/storage/indexeddb/open-cursor.html
+++ b/LayoutTests/storage/indexeddb/open-cursor.html
@@ -41,6 +41,14 @@ function cursorSuccess()
shouldBe("event.result.key", "'myKey'");
shouldBe("event.result.value", "'myValue'");
debug("");
+ try {
+ debug("Passing an invalid key into .continue().");
+ event.result.continue([]);
+ testFailed("No exception thrown");
+ } catch (e) {
+ testPassed("Caught exception: " + e.toString());
+ }
+ debug("");
openEmptyCursor();
}
diff --git a/LayoutTests/storage/indexeddb/tutorial-expected.txt b/LayoutTests/storage/indexeddb/tutorial-expected.txt
new file mode 100644
index 0000000..1e424ef
--- /dev/null
+++ b/LayoutTests/storage/indexeddb/tutorial-expected.txt
@@ -0,0 +1,2 @@
+All done!
+
diff --git a/LayoutTests/storage/indexeddb/tutorial.html b/LayoutTests/storage/indexeddb/tutorial.html
new file mode 100644
index 0000000..2e7e41f
--- /dev/null
+++ b/LayoutTests/storage/indexeddb/tutorial.html
@@ -0,0 +1,433 @@
+<html><title>IndexedDB Tutorial</title>
+<script>
+
+// This is a tutorial that highlights many of the features of IndexedDB along witha number of
+// caveats that currently exist in Chromium/WebKit but which will hopefully be improved upon
+// over time.
+//
+// The latest version of the spec can be found here:
+// http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html but note that there are quite a
+// few bugs currently opened against it and some major unresolved issues (like whether dynamic
+// transactions should be in for v1). Many of the bugs are filed here:
+// http://www.w3.org/Bugs/Public/buglist.cgi?query_format=advanced&short_desc_type=allwordssubstr&short_desc=&component=Indexed+Database+API&longdesc_type=allwordssubstr&longdesc=&bug_file_loc_type=allwordssubstr&bug_file_loc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=allwords&keywords=&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&emailtype1=substring&email1=&emailtype2=substring&email2=&bug_id_type=anyexact&bug_id=&votes=&chfieldfrom=&chfieldto=Now&chfieldvalue=&cmdtype=doit&order=Reuse+same+sort+as+last+time&known_name=IndexedDB&query_based_on=IndexedDB&field0-0-0=noop&type0-0-0=noop&value0-0-0=
+// Discussion happens on public-webapps@w3.org
+//
+// Although not user friendly, additional capabilities and example code can be found in the
+// tests for IndexedDB which are here:
+// http://trac.webkit.org/browser/trunk/LayoutTests/storage/indexeddb
+//
+// This document is currently maintained by Jeremy Orlow <jorlow@chromium.org>
+
+
+// This is not an ideal layout test since it doesn't verify things as thoroughly as it could,
+// but adding such content would make it much more cluttered and thus wouldn't serve its primary
+// goal of teaching people IndexedDB. That said, it does have a good amount of coverage and
+// serves as a living document describing what's expected to work and how within WebKit so it
+// seems well worth having checked in.
+if (window.layoutTestController)
+ layoutTestController.dumpAsText(true);
+
+
+function setup()
+{
+ // As this API is still experimental, it's being shipped behind vendor specific prefixes.
+ if ('webkitIndexedDB' in window) {
+ indexedDB = webkitIndexedDB;
+ IDBCursor = webkitIDBCursor;
+ IDBKeyRange = webkitIDBKeyRange;
+ IDBTransaction = webkitIDBTransaction;
+ }
+
+ // This tutorial assumes that Mozilla and WebKit match each other which isn't true at the
+ // moment, but we can hope it'll become true over time.
+ if ('moz_indexedDB' in window) {
+ indexedDB = moz_indexedDB;
+ // Not implemented by them yet. I'm just guessing what they'll be.
+ IDBCursor = moz_IDBCursor;
+ IDBKeyRange = moz_IDBKeyRange;
+ IDBTransaction = moz_IDBTransaction;
+ }
+}
+
+function log(txt)
+{
+ document.write(txt + "<br>");
+}
+
+function logError(txt)
+{
+ log("<font color=red>" + txt + "</font>");
+}
+
+function start()
+{
+ setup();
+
+ // This is an example of one of the many asynchronous commands in IndexedDB's async interface.
+ // Each returns an IDBRequest object which has "success" and "error" event handlers. You can use
+ // "addEventListener" if you'd like, but I'm using the simpler = syntax. Only one or the other
+ // will fire. You're guaranteed that they won't fire until control is returned from JavaScript
+ // execution.
+ var request = indexedDB.open("myDB", "This is a description of the database."); // Chromium/WebKit doesn't yet require the description, but it will soon.
+ request.onsuccess = onOpen;
+ request.onerror = unexpectedError;
+}
+
+function unexpectedError()
+{
+ // If an asynchronous call results in an error, an "error" event will fire on the IDBRequest
+ // object that was returned and the event's code and message attributes will be populated with
+ // the correct values.
+ logError("Error " + event.code + ": " + event.message);
+
+ // Unfortunately, Chromium/WebKit do not implicitly abort a transaction when an error occurs
+ // within one of its async operations. In the future, when an error occurs and the event is
+ // not canceled, the transaction will be aborted.
+ if (currentTransaction)
+ currentTransaction.abort();
+}
+
+function onOpen()
+{
+ // If an asynchronous call results in success, a "success" event will fire on the IDBRequest
+ // object that was returned and the call's result will be placed in the event's "result"
+ // attribute. In some cases, the expected result will be null.
+ window.db = event.result;
+
+ // The IDBDatabase object has a "version" attribute. This can only be set by calling
+ // "setVersion" on the database and supplying a new version. This also starts a new
+ // transaction which is very special. There are many details and gotchas surrounding
+ // setVersion which we'll get into later.
+ if (db.version == "1.0") {
+ // We could skip setting up the object stores and indexes if this were a real application
+ // that wasn't going to change things without changing the version number. But since this
+ // is both a tutorial and a living document, we'll go on and set things up every time we run.
+ }
+ var request = db.setVersion("1.0");
+ request.onsuccess = onSetVersion;
+ request.onerror = unexpectedError;
+}
+
+function onSetVersion()
+{
+ // We are now in a setVersion transaction. Such a transaction is the only place where one
+ // can add or remove indexes and objectStores. The result (property of event) is an
+ // IDBTransaction object that has "complete", "abort", and "timeout" event handlers which tell
+ // us when the transaction has committed, aborted, or timed out.
+ window.currentTransaction = event.result;
+ currentTransaction.oncomplete = onSetVersionComplete;
+ currentTransaction.onabort = unexpectedAbort;
+
+ // Delete existing object stores.
+ while (db.objectStores.length)
+ db.removeObjectStore(db.objectStores[0]);
+
+ // Now that we have a blank slate, let's create an objectStore. An objectStore is simply an
+ // ordered mapping of keys to values. We can iterate through ranges of keys or do individual
+ // lookups. ObjectStores don't have any schema.
+ //
+ // Keys can be integers, strings, or null. (The spec also defines dates and there's talk of
+ // handling arrays, but these are not implemented yet in Chromium/WebKit.) Values can be
+ // anything supported by the structured clone algorithm
+ // (http://dev.w3.org/html5/spec/Overview.html#internal-structured-cloning-algorithm) which
+ // is a superset of what can be expressed in JSON. (Note that Chromium/WebKit does not fully
+ // implement the structured clone algorithm yet, but it definitely handles anything JSON
+ // serializable.)
+ //
+ // There are two types of objectStores: ones where the path is supplied manually every time a
+ // value is inserted and those with a "key path". A keyPath is essentially a JavaScript
+ // expression that is evaluated on every value to extract a key. For example, if you pass in
+ // the value of "{fname: 'john', lname: 'doe', address: {street: 'Buckingham Palace", number:
+ // 76}, siblings: ["Nancy", "Marcus"], id: 22}" and an objectStore has a keyPath of "id" then
+ // 22 will be the key for this value. In objectStores, each key must be unique.
+ //
+ // Note that the exact syntax allowed for keyPaths is not yet well specified, but
+ // Chromium/WebKit currently allows paths that are multiple levels deep within an object and
+ // allows that to be intermixed with array dereferences. So, for example, a key path of
+ // "address.number" or "siblings[0]" would be legal (provided every entry had an address with
+ // a number attribute and at least one sibling). You can even go wild and say
+ // "foo[0][2].bar[0].baz.test[1][2][3]". It's possible this will change in the future though.
+ //
+ // If you set autoIncrement (the third optional parameter), IndexedDB will generate a key
+ // for your entry automatically. And if you have a keyPath set, it'll set the value at
+ // the location of the keyPath _in the database_ (i.e. it will not modify the value you pass
+ // in to put/add). Unfortunately autoIncrement is not yet implemented in Chromium/WebKit.
+ //
+ // Let's now create an objectStore for people. We'll supply a key path in this case.
+ var objectStore = db.createObjectStore("people", "id");
+
+ // Notice that it returned synchronously. The rule of thumb is that any call that touches (in
+ // any way) keys or values is asynchronous and any other call (besides setVersion and open) are
+ // asynchronous.
+ //
+ // Now let's create some indexes. Indexes allow you to create other keys via key paths which
+ // will also point to a particular value in an objectStore. In this example, we'll create
+ // indexes for a persons first and last name. Indexes can optionally be specified to not be
+ // unique, which is good in the case of names. The first parameter is the name of the index.
+ // Second is the key path. The third specifies uniqueness.
+ var fname = objectStore.createIndex("fname", "fname", false);
+ var lname = objectStore.createIndex("lname", "lname", false);
+
+ // Note that if you wanted to delete these indexes, you can either call objectStore.removeIndex
+ // or simply delete the objectStores that own the indexes. (Note that removeObjectStore and
+ // removeIndex may be changed to deleteObjectStore and deleteIndex in the future.)
+ //
+ // If we wanted to, we could populate the objectStore with some data here or do anything else
+ // allowed in a normal (i.e. non-setVersion) transaction. This is useful so that data migrations
+ // can be atomic with changes to the objectStores/indexes.
+ //
+ // Because we haven't actually made any new asynchronous requests, this transaction will
+ // start committing as soon as we leave this function. This will cause oncomplete event handler
+ // for the transaction will fire shortly after. IndexedDB transactions commit whenever control is
+ // returned from JavaScript with no further work being queued up against the transaction. This
+ // means one cannot call setTimeout, do an XHR, or anything like that and expect my transaction
+ // to still be around when that completes.
+
+}
+
+function unexpectedAbort()
+{
+ logError("A transaction aborted unexpectedly!");
+}
+
+function onSetVersionComplete()
+{
+ // Lets create a new transaction and then not schedule any work on it to watch it abort itself.
+ // Transactions (besides those created with setVersion) are created synchronously. All three
+ // parameters are optional for transaction.
+ //
+ // The first specifies which object stores to lock. The spec specifies "dynamic transactions"
+ // which don't require this and which have finer grained locks, but no one yet supports this and
+ // it may even be dropped from the first version of the spec, so I don't suggest you rely on it.
+ // Chromium/WebKit also does not yet support anything finer grained than database level locking,
+ // so in this tutorial we'll just pass in the empty array which means "lock the world".
+ //
+ // The second parameter specifies the locking mode. The default is READ_ONLY (i.e. a shared lock).
+ // That's fine for this case, but later we'll ask for IDBTransaction.READ_WRITE. At the moment,
+ // Chromium/WebKit pretends every transaction is READ_WRITE, which is kind of bad. (Note that
+ // SNAPSHOT_READ will soon be removed from the spec.)
+ //
+ // The last parameter is the timeout length. At the moment, Chromium/WebKit defaults to 0 which
+ // means never, but it's possible we'll change this in the future, so set it if you really care.
+ window.currentTransaction = db.transaction([], IDBTransaction.READ_WRITE, 0);
+ currentTransaction.oncomplete = unexpectedComplete;
+ currentTransaction.onabort = onTransactionAborted;
+
+ // Verify that "people" is the only object store in existance. The objectStores attribute is
+ // a DOMStringList which is somewhat like an array.
+ var objectStoreList = db.objectStores;
+ if (objectStoreList.length != 1
+ || !objectStoreList.contains("people")
+ || objectStoreList.item(0) != "people"
+ || objectStoreList[0] != "people") {
+ logError("Something went wrong.");
+ }
+
+ // Let's grab a handle to the objectStore. This handle is tied to the transaction that creates
+ // it and thus becomes invalid once this transaction completes.
+ var objectStore = currentTransaction.objectStore("people");
+ if (!objectStore)
+ logError("Something went wrong.");
+
+ // If we try to grab an objectStore that doesn't exist, IndexedDB throws an exception.
+ try {
+ currentTransaction.objectStore("x");
+ logError("Something went wrong.");
+ } catch (e) {
+ // Note that the error messages in exceptions are mostly lies at the moment. The reason is
+ // that the spec re-uses exception codes for existing exceptions and there's no way we can
+ // disambiguate between the two. The best work-around at the moment is to look at
+ // http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#the-idbdatabaseexception-interface
+ // to figure out what the number corresponds to. We will try to resolve this soon in spec-land.
+ }
+
+ // Verify that fname and lname are the only indexes in existance.
+ if (objectStore.indexNames.length != 2)
+ logError("Something went wrong.");
+
+ // Note that no async actions were ever queued up agianst our transaction, so it'll abort once
+ // we leave this context.
+}
+
+function unexpectedComplete()
+{
+ logError("A transaction committed unexpectedly!");
+}
+
+function onTransactionAborted()
+{
+ // Now let's make a real transaction and a person to our objectStore.
+ window.currentTransaction = db.transaction(["people"], IDBTransaction.READ_WRITE, 0);
+ currentTransaction.onabort = unexpectedAbort;
+
+ var people = currentTransaction.objectStore("people");
+ var request = people.put({fname: 'John', lname: 'Doe', id: 1}); // If our objectStore didn't have a key path, the second parameter would have been the key.
+ request.onsuccess = onPutSuccess;
+ request.onerror = unexpectedError;
+
+ // While we're at it, why not add a few more? Multiple queued up async commands will be executed
+ // sequentially (though there is talk of prioritizing cursor.continue--see discussion below). Since
+ // we don't care about the individual commands' successes, we'll only bother with on error handlers.
+ //
+ // Remember that our implementation of unexpectedError should abort the "currentTransaction" in the
+ // case of an error. (Though no error should occur in this case.)
+ people.put({fname: 'Jane', lname: 'Doe', id: 2}).onerror = unexpectedError;
+ people.put({fname: 'Philip', lname: 'Fry', id: 3}).onerror = unexpectedError;
+
+ // Not shown here are the .remove method (which is soon to be renamed .delete) and .add (which is
+ // like .put except that it fires an onerror if the element already exists).
+}
+
+function onPutSuccess()
+{
+ // Result is the key used for the put.
+ if (event.result !== 1)
+ logError("Something went wrong.");
+
+ // We should be able to request the transaction via event.transaction from within any event handler
+ // (like this one) but this is not yet implemented in Chromium/WebKit. As a work-around, we use the
+ // global "currentTransaction" variable we set above.
+ currentTransaction.oncomplete = onPutTransactionComplete;
+}
+
+function onPutTransactionComplete()
+{
+ // OK, now let's query the people objectStore in a couple different ways. First up, let's try get.
+ // It simply takes in a key and returns a request whose result will be the value.
+ window.currentTransaction = db.transaction(["people"], IDBTransaction.READ_WRITE, 0);
+ currentTransaction.onabort = unexpectedAbort;
+
+ var people = currentTransaction.objectStore("people");
+ var request = people.get(1);
+ request.onsuccess = onGetSuccess;
+ request.onerror = unexpectedError;
+
+ // Note that multiple objectStore (or index) method calls will return different objects (that still
+ // refer to the same objectStore/index on disk).
+ people.someProperty = true;
+ if (currentTransaction.objectStore("people").someProperty)
+ logError("Something went wrong.");
+}
+
+function onGetSuccess()
+{
+ if (event.result.fname !== "John")
+ logError("Something went wrong.");
+
+ // Events have a .source attribute which is the object that fired the event. In this case, it's our
+ // "people" objectStore object.
+ var people = event.source;
+
+ // Now let's try opening a cursor from id 1 (exclusive/open) to id 3 (inclusive/closed). This means
+ // we'll get the objects for ids 2 and 3. You can also create cursors that are only right or only
+ // left bounded or ommit the bound in order to grab all objects. You can also specify a direction
+ // which can be IDBCursor.NEXT (default) for the cursor to move forward, NEXT_NO_DUPLICATE to only
+ // return unique entires (only applies to indexes with unique set to false), PREV to move backwards,
+ // and PREV_NO_DUPLICATE.
+ var keyRange = IDBKeyRange.bound(1, 3, true, false);
+ var request = people.openCursor(keyRange, IDBCursor.NEXT);
+ request.onsuccess = onObjectStoreCursor;
+ request.onerror = unexpectedError;
+}
+
+function onObjectStoreCursor()
+{
+ // The result of openCursor is an IDBCursor object or null if there are no (more--see below)
+ // records left.
+ var cursor = event.result;
+ if (cursor === null) {
+ cursorComplete(event.source); // The soruce is still an objectStore.
+ return;
+ }
+
+ // We could use these values if we wanted to.
+ var key = cursor.key;
+ var value = cursor.value;
+
+ // cursor.count is probably going to be removed.
+ // cursor.update and .remove are not yet implemented in Chromium/WebKit.
+
+ // cursor.continue will reuse the same request object as what openCursor returned. In the future,
+ // we MAY prioritize .continue() calls ahead of all other async operations queued up. This will
+ // introduce a level of non-determinism but should speed things up. Mozilla has already implemented
+ // this non-standard behavior, from what I've head.
+ event.result.continue();
+}
+
+function cursorComplete(objectStore)
+{
+ // While still in the same transaction, let's now do a lookup on the lname index.
+ var lname = objectStore.index("lname");
+
+ // Note that the spec has not been updated yet, but instead of get and getObject, we now
+ // have getKey and get. The former returns the objectStore's key that corresponds to the key
+ // in the index. get returns the objectStore's value that corresponds to the key in the
+ // index.
+ var request = lname.getKey("Doe");
+ request.onsuccess = onIndexGetSuccess;
+ request.onerror = unexpectedError;
+}
+
+function onIndexGetSuccess()
+{
+ // Because we did "getKey" the result is the objectStore's key.
+ if (event.result !== 1)
+ logError("Something went wrong.");
+
+ // Similarly, indexes have openCursor and openKeyCursor. We'll try a few of them with various
+ // different IDBKeyRanges just to demonstrate how to use them, but we won't bother to handle
+ // the onsuccess conditions.
+ var lname = event.source;
+ lname.openCursor(IDBKeyRange.leftBound("Doe", false), IDBCursor.NEXT_NO_DUPLICATE);
+ lname.openCursor(null, IDBCursor.PREV_NO_DUPLICATE);
+ lname.openCursor(IDBKeyRange.rightBound("ZZZZ"));
+ lname.openCursor(IDBKeyRange.only("Doe"), IDBCursor.PREV);
+ lname.openCursor();
+ lname.openKeyCursor();
+
+ // We should be able to request the transaction via event.transaction from within any event handler
+ // (like this one) but this is not yet implemented in Chromium/WebKit. As a work-around, we use the
+ // global "currentTransaction" variable we set above.
+ currentTransaction.oncomplete = onAllDone;
+}
+
+function onAllDone()
+{
+ log("Everything worked!");
+}
+
+// The way setVersion is supposed to work:
+// To keep things simple to begin with, objectStores and indexes can only be created in a setVersion
+// transaction and one can only run if no other connections are open to the database. This is designed
+// to save app developers from having an older verison of a web page that expects a certain set of
+// objectStores and indexes from breaking in odd ways when things get changed out from underneith it.
+// In the future, we'll probably add a more advanced mechanism, but this is it for now.
+// Because a setVersion transaction could stall out nearly forever until the user closes windows,
+// we've added a "blocked" event to the request object returned by setVersion. This will fire if the
+// setVersion transaction can't begin because other windows have an open connection. The app can then
+// either pop something up telling the user to close windows or it can tell the other windows to call
+// .close() on their database handle. .close() halts any new transactions from starting and waits for
+// the existing ones to finish. It then closes the connection and any indexedDB calls afterwards are
+// invalid (they'll probably throw, but this isn't specified yet). We may specify .close() to return
+// an IDBRequest object so that we can fire the onsuccess when the close completes.
+// Once inside a setVersion transaction, you can do anything you'd like. The one connection which
+// was allowed to stay open to complete the setVersion transaction will stay alive. Multiple
+// setVersion transactions can be queued up at once and will fire in the order queued (though
+// this obviously only works if they're queued in the same page).
+//
+// The current status of setVersion in Chromium/WebKit:
+// In Chromium/WebKit we currently don't enforce the "all connections must be closed before a
+// setVersion transaction starts" rule. We also don't implement database.close() or have a blocked
+// event on the request .setVersion() returns.
+//
+// The current status of workers:
+// Chromium/WebKit do not yet support workers using IndexedDB. Support for the async interface
+// will likely come before the sync interface. For now, a work-around is using postMessage to tell
+// the page what to do on the worker's behalf in an ad-hoc manner. Anything that can be serialized
+// to disk can be serialized for postMessage.
+
+</script>
+<body onload="start()">
+Please view source for more information on what this is doing and why...<br><br>
+</body>
+</html>