diff --git a/IndexedDB/idbdatabase_deleteObjectStore.any.js b/IndexedDB/idbdatabase_deleteObjectStore.any.js new file mode 100644 index 00000000000000..5288891bd75fdb --- /dev/null +++ b/IndexedDB/idbdatabase_deleteObjectStore.any.js @@ -0,0 +1,89 @@ +// META: global=window,worker +// META: title=IDBDatabase.deleteObjectStore() +// META: script=resources/support.js +// @author Microsoft +// @author Odin Hørthe Omdal + +'use_strict'; + +async_test(t => { + let db; + let add_success = false; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + + const objStore = db.createObjectStore("store", { autoIncrement: true }); + assert_equals(db.objectStoreNames[0], "store", "objectStoreNames"); + + const rq_add = objStore.add(1); + rq_add.onsuccess = function() { add_success = true; }; + rq_add.onerror = fail(t, 'rq_add.error'); + + objStore.createIndex("idx", "a"); + db.deleteObjectStore("store"); + assert_equals(db.objectStoreNames.length, 0, "objectStoreNames.length after delete"); + assert_false(db.objectStoreNames.contains("store")); + + const exc = "InvalidStateError"; + assert_throws_dom(exc, function() { objStore.add(2); }); + assert_throws_dom(exc, function() { objStore.put(3); }); + assert_throws_dom(exc, function() { objStore.get(1); }); + assert_throws_dom(exc, function() { objStore.clear(); }); + assert_throws_dom(exc, function() { objStore.count(); }); + assert_throws_dom(exc, function() { objStore.delete(1); }); + assert_throws_dom(exc, function() { objStore.openCursor(); }); + assert_throws_dom(exc, function() { objStore.index("idx"); }); + assert_throws_dom(exc, function() { objStore.deleteIndex("idx"); }); + assert_throws_dom(exc, function() { objStore.createIndex("idx2", "a"); + }); + }; + + open_rq.onsuccess = function() { + assert_true(add_success, "First add was successful"); + t.done(); + } +}, 'Deleted object store\'s name should be removed from database\'s list. Attempting to use a \ +deleted IDBObjectStore should throw an InvalidStateError'); + +async_test(t => { + const open_rq = createdb(t); + + open_rq.onupgradeneeded = function(e) { + const db = e.target.result; + assert_throws_dom('NotFoundError', function() { db.deleteObjectStore('whatever'); }); + t.done(); + }; +}, 'Attempting to remove an object store that does not exist should throw a NotFoundError'); + +async_test(t => { + const keys = []; + const open_rq = createdb(t); + + open_rq.onupgradeneeded = function(e) { + const db = e.target.result; + + const objStore = db.createObjectStore("resurrected", { autoIncrement: true, keyPath: "k" }); + objStore.add({ k: 5 }).onsuccess = function(e) { keys.push(e.target.result); }; + objStore.add({}).onsuccess = function(e) { keys.push(e.target.result); }; + objStore.createIndex("idx", "i"); + assert_true(objStore.indexNames.contains("idx")); + assert_equals(objStore.keyPath, "k", "keyPath"); + + db.deleteObjectStore("resurrected"); + + const objStore2 = db.createObjectStore("resurrected", { autoIncrement: true }); + objStore2.add("Unicorns'R'us").onsuccess = function(e) { keys.push(e.target.result); }; + assert_false(objStore2.indexNames.contains("idx"), "index exist on new objstore"); + assert_equals(objStore2.keyPath, null, "keyPath"); + + assert_throws_dom("NotFoundError", function() { objStore2.index("idx"); }); + }; + + open_rq.onsuccess = function(e) { + assert_array_equals(keys, [5, 6, 1], "keys"); + t.done(); + }; +}, 'Attempting to access an index that was deleted as part of object store deletion and then \ +recreated using the same object store name should throw a NotFoundError'); diff --git a/IndexedDB/idbdatabase_deleteObjectStore.htm b/IndexedDB/idbdatabase_deleteObjectStore.htm deleted file mode 100644 index e3f6a775c56d9d..00000000000000 --- a/IndexedDB/idbdatabase_deleteObjectStore.htm +++ /dev/null @@ -1,25 +0,0 @@ - -IDBDatabase.deleteObjectStore() - object store's name is removed from database's list - - - - - - - -
diff --git a/IndexedDB/idbdatabase_deleteObjectStore3.htm b/IndexedDB/idbdatabase_deleteObjectStore3.htm deleted file mode 100644 index 3ddbe8ec62b42f..00000000000000 --- a/IndexedDB/idbdatabase_deleteObjectStore3.htm +++ /dev/null @@ -1,23 +0,0 @@ - -IDBDatabase.deleteObjectStore() - attempt to remove an object store that does not exist - - - - - - - -
diff --git a/IndexedDB/idbdatabase_deleteObjectStore4-not_reused.htm b/IndexedDB/idbdatabase_deleteObjectStore4-not_reused.htm deleted file mode 100644 index 0a5e1b83cf1676..00000000000000 --- a/IndexedDB/idbdatabase_deleteObjectStore4-not_reused.htm +++ /dev/null @@ -1,42 +0,0 @@ - - -IDBDatabase.deleteObjectStore() - the object store is not reused - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_delete.any.js b/IndexedDB/idbobjectstore_delete.any.js new file mode 100644 index 00000000000000..0b731f391d0302 --- /dev/null +++ b/IndexedDB/idbobjectstore_delete.any.js @@ -0,0 +1,207 @@ +// META: global=window,worker +// META: title=IDBObjectStore.delete() +// META: script=resources/support.js +// @author Microsoft + +'use_strict'; + +async_test(t => { + let db; + const record = { key: 1, property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + + const objStore = db.createObjectStore("test", { keyPath: "key" }); + objStore.add(record); + }; + + open_rq.onsuccess = function(e) { + const delete_rq = db.transaction("test", "readwrite", + { durability: 'relaxed' }) + .objectStore("test") + .delete(record.key); + + delete_rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, undefined); + + e.target.transaction.oncomplete = t.step_func(VerifyRecordRemoved); + }); + }; + + function VerifyRecordRemoved() { + const rq = db.transaction("test", "readonly", + { durability: 'relaxed' }) + .objectStore("test") + .get(record.key); + + rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, undefined); + t.done(); + }); + } +}, 'delete() removes record (inline keys)'); + +async_test(t => { + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + const db = e.target.result; + + const delete_rq = db.createObjectStore("test") + .delete(1); + + delete_rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, undefined); + t.done(); + }); + }; +}, 'delete() key doesn\'t match any records'); + +async_test(t => { + let db; + const record = { test: { obj: { key: 1 } }, property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + + const objStore = db.createObjectStore("test", + { keyPath: "test.obj.key" }); + objStore.add(record); + }; + + open_rq.onsuccess = function(e) { + const delete_rq = db.transaction("test", "readwrite", + { durability: 'relaxed' }) + .objectStore("test") + .delete(record.test.obj.key); + + delete_rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, undefined); + + e.target.transaction.oncomplete = t.step_func(VerifyRecordRemoved); + }); + }; + + function VerifyRecordRemoved() { + const rq = db.transaction("test", "readonly", + { durability: 'relaxed' }) + .objectStore("test") + .get(record.test.obj.key); + + rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, undefined); + t.done(); + }); + } +}, 'Object store\'s key path is an object attribute'); + +async_test(t => { + let db; + const key = 1; + const record = { property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + + const objStore = db.createObjectStore("test"); + objStore.add(record, key); + }; + + open_rq.onsuccess = function(e) { + const delete_rq = db.transaction("test", "readwrite", + { durability: 'relaxed' }) + .objectStore("test") + .delete(key); + + delete_rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, undefined); + + e.target.transaction.oncomplete = t.step_func(VerifyRecordRemoved); + }); + }; + + function VerifyRecordRemoved() { + const rq = db.transaction("test", "readonly", + { durability: 'relaxed' }) + .objectStore("test") + .get(key); + + rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, undefined); + t.done(); + }); + } +}, 'delete() removes record (out-of-line keys)'); + +async_test(t => { + let db; + const open_rq = createdb(t); + + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const os = db.createObjectStore("store"); + + for(let i = 0; i < 10; i++) + os.add("data" + i, i); + }; + + open_rq.onsuccess = function (e) { + const os = db.transaction("store", "readwrite", + { durability: 'relaxed' }) + .objectStore("store"); + + os.delete(IDBKeyRange.bound(3, 6)); + os.count().onsuccess = t.step_func(function(e) { + assert_equals(e.target.result, 6, "Count after deleting \ + 3-6 from 10"); + t.done(); + }); + }; +}, 'delete() removes all of the records in the range'); + +async_test(function(t) { + let db; + const records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }]; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(event) { + db = event.target.result; + const objStore = db.createObjectStore("store", { keyPath: "pKey" }); + for (let i = 0; i < records.length; i++) { + objStore.add(records[i]); + } + }; + + open_rq.onsuccess = function(event) { + const txn = db.transaction("store", "readonly", + { durability: 'relaxed' }); + const ostore = txn.objectStore("store"); + t.step(function() { + assert_throws_dom("ReadOnlyError", function() { + ostore.delete("primaryKey_0"); + }); + }); + t.done(); + }; +}, 'If the transaction this IDBObjectStore belongs to has its mode set to \ +readonly, throw ReadOnlyError'); + +async_test(t => { + let ostore; + const records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }]; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(event) { + const db = event.target.result; + ostore = db.createObjectStore("store", { keyPath: "pKey" }); + db.deleteObjectStore("store"); + assert_throws_dom("InvalidStateError", function() { + ostore.delete("primaryKey_0"); + }); + t.done(); + }; +}, 'If the object store has been deleted, the implementation must throw a \ +DOMException of type InvalidStateError'); diff --git a/IndexedDB/idbobjectstore_delete.htm b/IndexedDB/idbobjectstore_delete.htm deleted file mode 100644 index 880309d01a09b0..00000000000000 --- a/IndexedDB/idbobjectstore_delete.htm +++ /dev/null @@ -1,46 +0,0 @@ - - -IDBObjectStore.delete() - delete removes record (inline keys) - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_delete2.htm b/IndexedDB/idbobjectstore_delete2.htm deleted file mode 100644 index eb711699057913..00000000000000 --- a/IndexedDB/idbobjectstore_delete2.htm +++ /dev/null @@ -1,27 +0,0 @@ - - -IDBObjectStore.delete() - key doesn't match any records - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_delete3.htm b/IndexedDB/idbobjectstore_delete3.htm deleted file mode 100644 index 1ea9dd9958202e..00000000000000 --- a/IndexedDB/idbobjectstore_delete3.htm +++ /dev/null @@ -1,47 +0,0 @@ - - -IDBObjectStore.delete() - object store's key path is an object attribute - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_delete4.htm b/IndexedDB/idbobjectstore_delete4.htm deleted file mode 100644 index 9d074bff85cdc7..00000000000000 --- a/IndexedDB/idbobjectstore_delete4.htm +++ /dev/null @@ -1,48 +0,0 @@ - - -IDBObjectStore.delete() - delete removes record (out-of-line keys) - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_delete5.htm b/IndexedDB/idbobjectstore_delete5.htm deleted file mode 100644 index f7696e6efa151c..00000000000000 --- a/IndexedDB/idbobjectstore_delete5.htm +++ /dev/null @@ -1,32 +0,0 @@ - -IDBObjectStore.delete() - removes all of the records in the range - - - - - - -
diff --git a/IndexedDB/idbobjectstore_delete6.htm b/IndexedDB/idbobjectstore_delete6.htm deleted file mode 100644 index 70d8af32fe852b..00000000000000 --- a/IndexedDB/idbobjectstore_delete6.htm +++ /dev/null @@ -1,36 +0,0 @@ - - -IDBObjectStore.delete() - If the transaction this IDBObjectStore belongs to has its mode set to readonly, throw ReadOnlyError - - - - - -
- - diff --git a/IndexedDB/idbobjectstore_delete7.htm b/IndexedDB/idbobjectstore_delete7.htm deleted file mode 100644 index a65885cc2b43bd..00000000000000 --- a/IndexedDB/idbobjectstore_delete7.htm +++ /dev/null @@ -1,27 +0,0 @@ - - -IDBObjectStore.delete() - If the object store has been deleted, the implementation must throw a DOMException of type InvalidStateError - - - - - -
- diff --git a/IndexedDB/idbobjectstore_deleteIndex.any.js b/IndexedDB/idbobjectstore_deleteIndex.any.js new file mode 100644 index 00000000000000..ed0246e0e79f52 --- /dev/null +++ b/IndexedDB/idbobjectstore_deleteIndex.any.js @@ -0,0 +1,42 @@ +// META: global=window,worker +// META: title=IDBObjectStore.deleteIndex() +// META: script=resources/support.js +// @author Microsoft + +'use_strict'; + +async_test(t => { + let db; + const key = 1; + const record = { property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("test"); + objStore.createIndex("index", "indexedProperty"); + }; + + open_rq.onsuccess = function(e) { + db.close(); + const new_version = createdb(t, db.name, 2); + new_version.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = e.target.transaction.objectStore("test"); + objStore.deleteIndex("index"); + }; + + new_version.onsuccess = function(e) { + let index; + const objStore = db.transaction("test", "readonly", + { durability: 'relaxed' }) + .objectStore("test"); + + assert_throws_dom('NotFoundError', function() + { index = objStore.index("index"); }); + assert_equals(index, undefined); + db.close(); + t.done(); + }; + }; +}, 'IDBObjectStore.deleteIndex() removes the index'); diff --git a/IndexedDB/idbobjectstore_deleteIndex.htm b/IndexedDB/idbobjectstore_deleteIndex.htm deleted file mode 100644 index f12af6fc53760b..00000000000000 --- a/IndexedDB/idbobjectstore_deleteIndex.htm +++ /dev/null @@ -1,44 +0,0 @@ - - -IDBObjectStore.deleteIndex() - removes the index - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_deleted.htm b/IndexedDB/idbobjectstore_deleted.htm deleted file mode 100644 index 5ccc8fdb1b6838..00000000000000 --- a/IndexedDB/idbobjectstore_deleted.htm +++ /dev/null @@ -1,50 +0,0 @@ - - -Attempting to use deleted IDBObjectStore - - - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put.any.js b/IndexedDB/idbobjectstore_put.any.js new file mode 100644 index 00000000000000..89303291e9d692 --- /dev/null +++ b/IndexedDB/idbobjectstore_put.any.js @@ -0,0 +1,427 @@ +// META: global=window,worker +// META: title=IDBObjectStore.put() +// META: script=resources/support.js +// @author Microsoft +// @author Intel + +'use strict'; + +async_test(t => { + let db; + const record = { key: 1, property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("store", { keyPath: "key" }); + + objStore.put(record); + }; + + open_rq.onsuccess = function(e) { + const rq = db.transaction("store", "readonly", + { durability: 'relaxed' }) + .objectStore("store") + .get(record.key); + + rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result.property, record.property); + assert_equals(e.target.result.key, record.key); + t.done(); + }); + }; +}, 'put() with an inline key'); + +async_test(t => { + let db; + const key = 1; + const record = { property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("store"); + + objStore.put(record, key); + }; + + open_rq.onsuccess = function(e) { + const rq = db.transaction("store", "readonly", {durability: 'relaxed'}) + .objectStore("store") + .get(key); + + rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result.property, record.property); + + t.done(); + }); + }; +},'put() with an out-of-line key'); + +async_test(t => { + let db; + let success_event; + const record = { key: 1, property: "data" }; + const record_put = { key: 1, property: "changed", more: ["stuff", 2] }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("store", { keyPath: "key" }); + objStore.put(record); + + const rq = objStore.put(record_put); + rq.onerror = fail(t, "error on put"); + + rq.onsuccess = t.step_func(function(e) { + success_event = true; + }); + }; + + open_rq.onsuccess = function(e) { + assert_true(success_event); + + const rq = db.transaction("store", "readonly", + { durability: 'relaxed' }) + .objectStore("store") + .get(1); + + rq.onsuccess = t.step_func(function(e) { + const rec = e.target.result; + + assert_equals(rec.key, record_put.key); + assert_equals(rec.property, record_put.property); + assert_array_equals(rec.more, record_put.more); + + t.done(); + }); + }; +}, 'put() record with key already exists'); + +async_test(t => { + const record = { key: 1, property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + let db = e.target.result; + const objStore = db.createObjectStore("store", { + autoIncrement: true }); + objStore.createIndex("i1", "property", { unique: true }); + objStore.put(record); + + const rq = objStore.put(record); + rq.onsuccess = fail(t, "success on putting duplicate indexed record"); + + rq.onerror = t.step_func(function(e) { + assert_equals(rq.error.name, "ConstraintError"); + assert_equals(e.target.error.name, "ConstraintError"); + + assert_equals(e.type, "error"); + + e.preventDefault(); + e.stopPropagation(); + }); + }; + + // Defer done, giving a spurious rq.onsuccess a chance to run + open_rq.onsuccess = function(e) { + t.done(); + }; +}, 'put() where an index has unique:true specified'); + +async_test(t => { + let db; + const record = { test: { obj: { key: 1 } }, property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("store", + { keyPath: "test.obj.key" }); + objStore.put(record); + }; + + open_rq.onsuccess = function(e) { + const rq = db.transaction("store", "readonly", + { durability: 'relaxed' }) + .objectStore("store") + .get(record.test.obj.key); + + rq.onsuccess = t.step_func(function(e) { + assert_equals(e.target.result.property, record.property); + + t.done(); + }); + }; +}, 'Object store\'s key path is an object attribute'); + +async_test(t => { + let db; + const record = { property: "data" }; + const expected_keys = [1, 2, 3, 4]; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("store", { keyPath: "key", + autoIncrement: true }); + + objStore.put(record); + objStore.put(record); + objStore.put(record); + objStore.put(record); + }; + + open_rq.onsuccess = function(e) { + let actual_keys = []; + const rq = db.transaction("store", "readonly", { durability: 'relaxed' }) + .objectStore("store") + .openCursor(); + + rq.onsuccess = t.step_func(function(e) { + const cursor = e.target.result; + + if (cursor) { + actual_keys.push(cursor.value.key); + cursor.continue(); + } else { + assert_array_equals(actual_keys, expected_keys); + t.done(); + } + }); + }; + }, 'autoIncrement and inline keys'); + +async_test(t => { + let db; + const record = { property: "data" }; + const expected_keys = [1, 2, 3, 4]; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("store", { keyPath: "key", + autoIncrement: true }); + + objStore.put(record); + objStore.put(record); + objStore.put(record); + objStore.put(record); + }; + + open_rq.onsuccess = function(e) { + const actual_keys = []; + const rq = db.transaction("store", "readonly", + { durability: 'relaxed' }) + .objectStore("store") + .openCursor(); + + rq.onsuccess = t.step_func(function(e) { + const cursor = e.target.result; + + if(cursor) { + actual_keys.push(cursor.value.key); + cursor.continue(); + } else { + assert_array_equals(actual_keys, expected_keys); + t.done(); + } + }); + }; +}, 'autoIncrement and out-of-line keys'); + +async_test(t => { + let db; + const record = { property: "data" }; + const expected_keys = [1, 2, 3, 4]; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + db = e.target.result; + const objStore = db.createObjectStore("store", + { keyPath: "test.obj.key", autoIncrement: true }); + + objStore.put(record); + objStore.put(record); + objStore.put(record); + objStore.put(record); + }; + + open_rq.onsuccess = function(e) { + const actual_keys = []; + const rq = db.transaction("store", "readonly", + { durability: 'relaxed' }) + .objectStore("store") + .openCursor(); + + rq.onsuccess = t.step_func(function(e) { + const cursor = e.target.result; + + if (cursor) { + actual_keys.push(cursor.value.test.obj.key); + cursor.continue(); + } else { + assert_array_equals(actual_keys, expected_keys); + t.done(); + } + }); + }; +}, 'Object store has autoIncrement:true and the key path is an object \ +attribute'); + +async_test(t => { + const record = { key: 1, property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + let rq; + const db = e.target.result; + const objStore = db.createObjectStore("store", { keyPath: "key" }); + + assert_throws_dom("DataError", function() { + rq = objStore.put(record, 1); + }); + + assert_equals(rq, undefined); + t.done(); + }; +}, 'Attempt to put() a record that does not meet the constraints of an object \ +store\'s inline key requirements'); + +async_test(t => { + const record = { property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + let db = e.target.result; + + let rq; + const objStore = db.createObjectStore("store", { keyPath: "key" }); + + assert_throws_dom("DataError", function() { + rq = objStore.put(record); + }); + + assert_equals(rq, undefined); + t.done(); + }; +}, 'Attempt to call put() without an key parameter when the object store uses \ +out-of-line keys'); + +async_test(t => { + const record = { key: { value: 1 }, property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + const db = e.target.result; + + let rq; + const objStore = db.createObjectStore("store", { keyPath: "key" }); + + assert_throws_dom("DataError", function() { + rq = objStore.put(record); + }); + + assert_equals(rq, undefined); + t.done(); + }; +}, 'Attempt to put() a record where the record\'s key does not meet the \ +constraints of a valid key'); + +async_test(t => { + const record = { property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + const db = e.target.result; + + let rq; + const objStore = db.createObjectStore("store", { keyPath: "key" }); + + assert_throws_dom("DataError", function() { + rq = objStore.put(record); + }); + + assert_equals(rq, undefined); + t.done(); + }; +}, 'Attempt to put() a record where the record\'s in-line key is not defined'); + +async_test(t => { + const record = { property: "data" }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + const db = e.target.result; + + let rq; + const objStore = db.createObjectStore("store"); + + assert_throws_dom("DataError", function() { + rq = objStore.put(record, { value: 1 }); + }); + + assert_equals(rq, undefined); + t.done(); + }; +}, 'Attempt to put() a record where the out of line key provided does not \ +meet the constraints of a valid key'); + +async_test(t => { + const record = { key: 1, indexedProperty: { property: "data" } }; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(e) { + const db = e.target.result; + + let rq; + const objStore = db.createObjectStore("store", { keyPath: "key" }); + + objStore.createIndex("index", "indexedProperty"); + + rq = objStore.put(record); + + assert_true(rq instanceof IDBRequest); + rq.onsuccess = function() { + t.done(); + }; + }; +}, 'put() a record where a value being indexed does not meet the constraints \ +of a valid key'); + +async_test(t => { + let db; + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(event) { + db = event.target.result; + db.createObjectStore("store", { keyPath: "pKey" }); + }; + + open_rq.onsuccess = function(event) { + const txn = db.transaction("store", "readonly", + { durability: 'relaxed' }); + const ostore = txn.objectStore("store"); + t.step(function() { + assert_throws_dom("ReadOnlyError", function() { + ostore.put({ pKey: "primaryKey_0" }); + }); + }); + t.done(); + }; +}, 'If the transaction this IDBObjectStore belongs to has its mode set to \ +readonly, throw ReadOnlyError'); + +async_test(t => { + let ostore; + const open_rq = createdb(t); + open_rq.onupgradeneeded = function(event) { + const db = event.target.result; + ostore = db.createObjectStore("store", { keyPath: "pKey" }); + db.deleteObjectStore("store"); + assert_throws_dom("InvalidStateError", function() { + ostore.put({ pKey: "primaryKey_0" }); + }); + t.done(); + }; +}, 'If the object store has been deleted, the implementation must throw a \ +DOMException of type InvalidStateError'); diff --git a/IndexedDB/idbobjectstore_put.htm b/IndexedDB/idbobjectstore_put.htm deleted file mode 100644 index e277ce54a2022a..00000000000000 --- a/IndexedDB/idbobjectstore_put.htm +++ /dev/null @@ -1,35 +0,0 @@ - - -IDBObjectStore.put() - put with an inline key - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put10.htm b/IndexedDB/idbobjectstore_put10.htm deleted file mode 100644 index 6882e8e4b5c5bc..00000000000000 --- a/IndexedDB/idbobjectstore_put10.htm +++ /dev/null @@ -1,29 +0,0 @@ - - -IDBObjectStore.put() - Attempt to call 'put' without an key parameter when the object store uses out-of-line keys - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put11.htm b/IndexedDB/idbobjectstore_put11.htm deleted file mode 100644 index a5ed2db357b56f..00000000000000 --- a/IndexedDB/idbobjectstore_put11.htm +++ /dev/null @@ -1,29 +0,0 @@ - - -IDBObjectStore.put() - Attempt to put a record where the record's key does not meet the constraints of a valid key - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put12.htm b/IndexedDB/idbobjectstore_put12.htm deleted file mode 100644 index 0693980277dd66..00000000000000 --- a/IndexedDB/idbobjectstore_put12.htm +++ /dev/null @@ -1,29 +0,0 @@ - - -IDBObjectStore.put() - Attempt to put a record where the record's in-line key is not defined - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put13.htm b/IndexedDB/idbobjectstore_put13.htm deleted file mode 100644 index 8ae6561fc5c617..00000000000000 --- a/IndexedDB/idbobjectstore_put13.htm +++ /dev/null @@ -1,29 +0,0 @@ - - -IDBObjectStore.put() - Attempt to put a record where the out of line key provided does not meet the constraints of a valid key - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put14.htm b/IndexedDB/idbobjectstore_put14.htm deleted file mode 100644 index bc5647f4c11a87..00000000000000 --- a/IndexedDB/idbobjectstore_put14.htm +++ /dev/null @@ -1,32 +0,0 @@ - - -IDBObjectStore.put() - Put a record where a value being indexed does not meet the constraints of a valid key - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put15.htm b/IndexedDB/idbobjectstore_put15.htm deleted file mode 100644 index e7affaddd444f4..00000000000000 --- a/IndexedDB/idbobjectstore_put15.htm +++ /dev/null @@ -1,31 +0,0 @@ - - -IDBObjectStore.put() - If the transaction this IDBObjectStore belongs to has its mode set to readonly, throw ReadOnlyError - - - - - -
- - diff --git a/IndexedDB/idbobjectstore_put16.htm b/IndexedDB/idbobjectstore_put16.htm deleted file mode 100644 index e298ba88493f32..00000000000000 --- a/IndexedDB/idbobjectstore_put16.htm +++ /dev/null @@ -1,25 +0,0 @@ - - -IDBObjectStore.put() - If the object store has been deleted, the implementation must throw a DOMException of type InvalidStateError - - - - - -
- diff --git a/IndexedDB/idbobjectstore_put2.htm b/IndexedDB/idbobjectstore_put2.htm deleted file mode 100644 index 733e2cb1549fc6..00000000000000 --- a/IndexedDB/idbobjectstore_put2.htm +++ /dev/null @@ -1,36 +0,0 @@ - - -IDBObjectStore.put() - put with an out-of-line key - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put3.htm b/IndexedDB/idbobjectstore_put3.htm deleted file mode 100644 index b7792bdaf1d848..00000000000000 --- a/IndexedDB/idbobjectstore_put3.htm +++ /dev/null @@ -1,48 +0,0 @@ - - -IDBObjectStore.put() - record with same key already exists - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put4.htm b/IndexedDB/idbobjectstore_put4.htm deleted file mode 100644 index 4a59836eb6313e..00000000000000 --- a/IndexedDB/idbobjectstore_put4.htm +++ /dev/null @@ -1,40 +0,0 @@ - - -IDBObjectStore.put() - put where an index has unique:true specified - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put5.htm b/IndexedDB/idbobjectstore_put5.htm deleted file mode 100644 index 6e945e27d2a187..00000000000000 --- a/IndexedDB/idbobjectstore_put5.htm +++ /dev/null @@ -1,34 +0,0 @@ - - -IDBObjectStore.put() - object store's key path is an object attribute - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put6.htm b/IndexedDB/idbobjectstore_put6.htm deleted file mode 100644 index f0b6f0b98dca08..00000000000000 --- a/IndexedDB/idbobjectstore_put6.htm +++ /dev/null @@ -1,47 +0,0 @@ - - -IDBObjectStore.put() - autoIncrement and inline keys - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put7.htm b/IndexedDB/idbobjectstore_put7.htm deleted file mode 100644 index e41959f21102dc..00000000000000 --- a/IndexedDB/idbobjectstore_put7.htm +++ /dev/null @@ -1,47 +0,0 @@ - - -IDBObjectStore.put() - autoIncrement and out-of-line keys - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put8.htm b/IndexedDB/idbobjectstore_put8.htm deleted file mode 100644 index 2bec639d322d67..00000000000000 --- a/IndexedDB/idbobjectstore_put8.htm +++ /dev/null @@ -1,47 +0,0 @@ - - -IDBObjectStore.put() - object store has autoIncrement:true and the key path is an object attribute - - - - - - - -
diff --git a/IndexedDB/idbobjectstore_put9.htm b/IndexedDB/idbobjectstore_put9.htm deleted file mode 100644 index dff9415d691c43..00000000000000 --- a/IndexedDB/idbobjectstore_put9.htm +++ /dev/null @@ -1,27 +0,0 @@ - - -IDBObjectStore.put() - Attempt to put a record that does not meet the constraints of an object store's inline key requirements - - - - - - - -
diff --git a/IndexedDB/ready-state-destroyed-execution-context.html b/IndexedDB/ready-state-destroyed-execution-context.html index 8194052391a779..6b2677fae799bf 100644 --- a/IndexedDB/ready-state-destroyed-execution-context.html +++ b/IndexedDB/ready-state-destroyed-execution-context.html @@ -21,6 +21,10 @@ const openRequest = iframe.contentWindow.indexedDB.open(dbname); assert_equals(openRequest.readyState, 'pending'); iframe.remove(); + await new Promise(resolve => { + openRequest.onerror = resolve; + openRequest.onsuccess = resolve; + }); assert_equals(openRequest.readyState, 'done'); }, 'readyState accessor is valid after execution context is destroyed'); diff --git a/WebCryptoAPI/sign_verify/eddsa.js b/WebCryptoAPI/sign_verify/eddsa.js index 7817b78cff6293..4952df502d83ce 100644 --- a/WebCryptoAPI/sign_verify/eddsa.js +++ b/WebCryptoAPI/sign_verify/eddsa.js @@ -1,363 +1,214 @@ function run_test() { - setup({explicit_done: true}); - var subtle = self.crypto.subtle; // Change to test prefixed implementations - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; - // Source file [algorithm_name]_vectors.js provides the getTestVectors method // for the algorithm that drives these tests. var testVectors = getTestVectors(); - // Test verification first, because signing tests rely on that working testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.data) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); - }); - - return operation; - }, vector.name + " verification"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification"); - }); - - all_promises.push(promise); - }); + var algorithm = {name: vector.algorithmName}; - // Test verification with an altered buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { + // Test verification first, because signing tests rely on that working + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) + } catch (err) { + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }; + assert_true(isVerified, "Signature verified"); + }, vector.name + " verification"); + + // Test verification with an altered buffer after call + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); var signature = copyBuffer(vector.signature); - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.data) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); - }); - - signature[0] = 255 - signature[0]; - return operation; - }, vector.name + " verification with altered signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature after call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if data is altered after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { + [isVerified] = await Promise.all([ + subtle.verify(algorithm, key, signature, vector.data), + signature[0] = 255 - signature[0] + ]); + } catch (err) { + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }; + assert_true(isVerified, "Signature verified"); + }, vector.name + " verification with altered signature after call"); + + // Check for successful verification even if data is altered after call. + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); var data = copyBuffer(vector.data); - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, data) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); - }); - - data[0] = 255 - data[0]; - return operation; - }, vector.name + " with altered data after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered data after call"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to using privateKey to verify. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { - return subtle.verify(algorithm, vector.privateKey, vector.signature, vector.data) - .then(function(data) { - assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name + ": " + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " using privateKey to verify"); - - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " using privateKey to verify"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to using publicKey to sign. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { - return subtle.sign(algorithm, vector.publicKey, vector.data) - .then(function(signature) { - assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name + ": " + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " using publicKey to sign"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " using publicKey to sign"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to no "verify" usage. - testVectors.forEach(function(originalVector) { - var vector = Object.assign({}, originalVector); - - var promise = importVectorKeys(vector, [], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { - return subtle.verify(algorithm, vector.publicKey, vector.signature, vector.data) - .then(function(data) { - assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": " + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " no verify usage"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " no verify usage"); - }); - - all_promises.push(promise); - }); - - // Check for successful signing and verification. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { - return subtle.sign(algorithm, vector.privateKey, vector.data) - .then(function(signature) { - assert_true(equalBuffers(signature, vector.signature), "Signing did not give the expected output"); - // Can we verify the signature? - return subtle.verify(algorithm, vector.publicKey, signature, vector.data) - .then(function(is_verified) { - assert_true(is_verified, "Round trip verification works"); - return signature; - }, function(err) { - assert_unreached("verify error for test " + vector.name + ": " + err.message + "'"); - }); - }, function(err) { - assert_unreached("sign error for test " + vector.name + ": '" + err.message + "'"); - }); - }, vector.name + " round trip"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested signing or verifying - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " round trip"); - }); - - all_promises.push(promise); - }); - - // Test signing with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - var algorithm = {name: vector.algorithmName}; - return importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var operation = subtle.sign(algorithm, wrongKey, vector.data) - .then(function(signature) { - assert_unreached("Signing should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " signing with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " signing with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Test verification with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - return importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; - promise_test(function(test) { - var operation = subtle.verify(algorithm, wrongKey, vector.signature, vector.data) - .then(function(signature) { - assert_unreached("Verifying should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verifying with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verifying with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " verifying with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with wrong signature - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; + [isVerified] = await Promise.all([ + subtle.verify(algorithm, key, vector.signature, data), + data[0] = 255 - data[0] + ]); + } catch (err) { + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }; + assert_true(isVerified, "Signature verified"); + }, vector.name + " with altered data after call"); + + // Check for failures due to using privateKey to verify. + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]); + isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) + assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name); + } catch (err) { + if (err instanceof AssertionError) + throw err; + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); + }; + assert_false(isVerified, "Signature verified"); + }, vector.name + " using privateKey to verify"); + + // Check for failures due to using publicKey to sign. + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + let signature = await subtle.sign(algorithm, key, vector.data); + assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name); + } catch (err) { + if (err instanceof AssertionError) + throw err; + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); + }; + }, vector.name + " using publicKey to sign"); + + // Check for failures due to no "verify" usage. + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, []); + isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) + assert_unreached("Should have thrown error for no verify usage in " + vector.name); + } catch (err) { + if (err instanceof AssertionError) + throw err; + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); + }; + assert_false(isVerified, "Signature verified"); + }, vector.name + " no verify usage"); + + // Check for successful signing and verification. + var algorithm = {name: vector.algorithmName}; + promise_test(async() => { + let isVerified = false; + let privateKey, publicKey; + let signature; + try { + privateKey = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]); + publicKey = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + signature = await subtle.sign(algorithm, privateKey, vector.data); + isVerified = await subtle.verify(algorithm, publicKey, vector.signature, vector.data) + } catch (err) { + assert_false(publicKey === undefined || privateKey === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_false(signature === undefined, "sign error for test " + vector.name + ": '" + err.message + "'"); + assert_unreached("verify error for test " + vector.name + ": " + err.message + "'"); + }; + assert_true(isVerified, "Round trip verification works"); + }, vector.name + " round trip"); + + // Test signing with the wrong algorithm + var algorithm = {name: vector.algorithmName}; + promise_test(async() => { + let wrongKey; + try { + wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) + let signature = await subtle.sign(algorithm, wrongKey, vector.data); + assert_unreached("Signing should not have succeeded for " + vector.name); + } catch (err) { + if (err instanceof AssertionError) + throw err; + assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }; + }, vector.name + " signing with wrong algorithm name"); + + // Test verification with the wrong algorithm + var algorithm = {name: vector.algorithmName}; + promise_test(async() => { + let wrongKey; + try { + wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) + let isVerified = await subtle.verify(algorithm, wrongKey, vector.signature, vector.data) + assert_unreached("Verifying should not have succeeded for " + vector.name); + } catch (err) { + if (err instanceof AssertionError) + throw err; + assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }; + }, vector.name + " verifying with wrong algorithm name"); + + // Test verification fails with wrong signature + var algorithm = {name: vector.algorithmName}; + promise_test(async() => { + let key; + let isVerified = true; var signature = copyBuffer(vector.signature); signature[0] = 255 - signature[0]; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.data) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to altered signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to altered signature"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with short (odd length) signature - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + isVerified = await subtle.verify(algorithm, key, signature, vector.data) + } catch (err) { + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }; + assert_false(isVerified, "Signature verified"); + }, vector.name + " verification failure due to altered signature"); + + // Test verification fails with short (odd length) signature + promise_test(async() => { + let key; + let isVerified = true; var signature = vector.signature.slice(1); // Skip the first byte - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.data) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to shortened signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to shortened signature"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with wrong data - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName}; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + isVerified = await subtle.verify(algorithm, key, signature, vector.data) + } catch (err) { + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }; + assert_false(isVerified, "Signature verified"); + }, vector.name + " verification failure due to shortened signature"); + + // Test verification fails with wrong data + promise_test(async() => { + let key; + let isVerified = true; var data = copyBuffer(vector.data); data[0] = 255 - data[0]; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, data) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to altered data"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to altered data"); - }); - - all_promises.push(promise); - }); - - - promise_test(function() { - return Promise.all(all_promises) - .then(function() {done();}) - .catch(function() {done();}) - }, "setup"); - - // Test that generated keys are valid for signing and verifying. - testVectors.forEach(function(vector) { - var algorithm = {name: vector.algorithmName}; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + isVerified = await subtle.verify(algorithm, key, vector.signature, data) + } catch (err) { + assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }; + assert_false(isVerified, "Signature verified"); + }, vector.name + " verification failure due to altered data"); + + // Test that generated keys are valid for signing and verifying. promise_test(async() => { let key = await subtle.generateKey(algorithm, false, ["sign", "verify"]); let signature = await subtle.sign(algorithm, key.privateKey, vector.data); @@ -371,17 +222,14 @@ function run_test() { Object.keys(kSmallOrderTestCases).forEach(function (algorithmName) { var algorithm = {name: algorithmName}; kSmallOrderTestCases[algorithmName].forEach(function(test) { - // Test low-order public keys promise_test(async() => { let isVerified = true; let publicKey; try { - publicKey = await subtle.importKey("raw", test.keyData, - algorithm, - false, ["verify"]) - isVerified = await subtle.verify(algorithmName, publicKey, test.signature, test.message); + publicKey = await subtle.importKey("raw", test.keyData, algorithm, false, ["verify"]) + isVerified = await subtle.verify(algorithm, publicKey, test.signature, test.message); } catch (err) { - assert_equals(isVerified, test.verified, "Signature verification result."); + assert_false(publicKey === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); assert_unreached("The operation shouldn't fail, but it thown this error: " + err.name + ": " + err.message + "."); } assert_false(isVerified, "Signature verification result."); @@ -389,41 +237,6 @@ function run_test() { }); }); - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. - // - // Returns a Promise that yields an updated vector on success. - function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) { - var publicPromise, privatePromise; - - if (vector.publicKey !== null) { - publicPromise = new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithmName}, false, publicKeyUsages) - .then(function(key) { - vector.publicKey = key; - return vector; - }); // Returns a copy of the sourceBuffer it is sent. - } - - if (vector.privateKey !== null) { - privatePromise = new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithmName}, false, privateKeyUsages) - .then(function(key) { - vector.privateKey = key; - return vector; - }); - } - - return Promise.all([publicPromise, privatePromise]); - } - // Returns a copy of the sourceBuffer it is sent. function copyBuffer(sourceBuffer) { var source = new Uint8Array(sourceBuffer); diff --git a/accname/name/comp_label.html b/accname/name/comp_label.html index 8b569ba6fff7b0..3eda2a5367b857 100644 --- a/accname/name/comp_label.html +++ b/accname/name/comp_label.html @@ -186,6 +186,12 @@

Name computation precedence tests

x + + + + x label diff --git a/accname/name/comp_name_from_content.html b/accname/name/comp_name_from_content.html index deae6699c6e985..3504658ea46156 100644 --- a/accname/name/comp_name_from_content.html +++ b/accname/name/comp_name_from_content.html @@ -49,6 +49,12 @@ content: " after "; /* [sic] leading and trailing space */ content: " after " / " alt-after "; /* Override the previous line for engines that support the Alternative Text syntax. */ } + .fallback-before-empty::before { + content: "before" / ""; + } + .fallback-before-image-empty::before { + content: "before " url(/images/blue.png) / ""; + } .fallback-before-mixed::before { content: " before "; /* [sic] leading and trailing space */ content: " before " / " start " attr(data-alt-text-before) " end "; /* Override the previous line for engines that support the Alternative Text syntax. */ @@ -145,6 +151,10 @@

label

+

Empty alternative text for CSS content in pseudo-elements when applied to primitive appearance form controls

+

+

+

simple w/ for each child


one two three

diff --git a/compute-pressure/compute_pressure_basic.tentative.https.any.js b/compute-pressure/compute_pressure_basic.https.any.js similarity index 91% rename from compute-pressure/compute_pressure_basic.tentative.https.any.js rename to compute-pressure/compute_pressure_basic.https.any.js index 28322ced729af6..15d572bd8eed7d 100644 --- a/compute-pressure/compute_pressure_basic.tentative.https.any.js +++ b/compute-pressure/compute_pressure_basic.https.any.js @@ -21,7 +21,7 @@ pressure_test(async (t, mockPressureService) => { t.add_cleanup(() => observer.disconnect()); observer.observe('cpu'); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_true(changes.length === 1); assert_equals(changes[0].state, 'critical'); @@ -37,7 +37,7 @@ pressure_test((t, mockPressureService) => { const promise = observer.observe('cpu'); observer.unobserve('cpu'); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); return promise_rejects_dom(t, 'AbortError', promise); }, 'Removing observer before observe() resolves works'); @@ -57,7 +57,7 @@ pressure_test(async (t, mockPressureService) => { await Promise.all(observePromises); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); return Promise.all(callbackPromises); }, 'Calling observe() multiple times works'); @@ -72,7 +72,7 @@ pressure_test(async (t, mockPressureService) => { t.add_cleanup(() => observer1.disconnect()); observer1.observe('cpu'); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_true(observer1_changes.length === 1); assert_equals(observer1_changes[0][0].source, 'cpu'); diff --git a/compute-pressure/compute_pressure_detached_iframe.tentative.https.html b/compute-pressure/compute_pressure_detached_iframe.https.html similarity index 95% rename from compute-pressure/compute_pressure_detached_iframe.tentative.https.html rename to compute-pressure/compute_pressure_detached_iframe.https.html index 5511a147048d61..6123521248cb7f 100644 --- a/compute-pressure/compute_pressure_detached_iframe.tentative.https.html +++ b/compute-pressure/compute_pressure_detached_iframe.https.html @@ -69,7 +69,7 @@ t.add_cleanup(() => observer.disconnect()); observer.observe('cpu').catch(reject); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_equals(changes[0].state, 'critical'); }, 'Detaching frame while PressureObserver.observe() settles'); @@ -84,7 +84,7 @@ await observer.observe('cpu'); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); iframe.remove(); diff --git a/compute-pressure/compute_pressure_disconnect.tentative.https.any.js b/compute-pressure/compute_pressure_disconnect.https.any.js similarity index 95% rename from compute-pressure/compute_pressure_disconnect.tentative.https.any.js rename to compute-pressure/compute_pressure_disconnect.https.any.js index 1d188fad8b8e1c..f8bc3fb357811a 100644 --- a/compute-pressure/compute_pressure_disconnect.tentative.https.any.js +++ b/compute-pressure/compute_pressure_disconnect.https.any.js @@ -31,7 +31,7 @@ pressure_test(async (t, mockPressureService) => { t.add_cleanup(() => observer2.disconnect()); observer2.observe('cpu').catch(reject); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_equals( diff --git a/compute-pressure/compute_pressure_disconnect_idempotent.tentative.https.any.js b/compute-pressure/compute_pressure_disconnect_idempotent.https.any.js similarity index 94% rename from compute-pressure/compute_pressure_disconnect_idempotent.tentative.https.any.js rename to compute-pressure/compute_pressure_disconnect_idempotent.https.any.js index 74d37bd6e5cc75..3c9a6688a42fb8 100644 --- a/compute-pressure/compute_pressure_disconnect_idempotent.tentative.https.any.js +++ b/compute-pressure/compute_pressure_disconnect_idempotent.https.any.js @@ -25,7 +25,7 @@ pressure_test(async (t, mockPressureService) => { t.add_cleanup(() => observer2.disconnect()); observer2.observe('cpu').catch(reject); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_equals( diff --git a/compute-pressure/compute_pressure_disconnect_immediately.tentative.https.any.js b/compute-pressure/compute_pressure_disconnect_immediately.https.any.js similarity index 93% rename from compute-pressure/compute_pressure_disconnect_immediately.tentative.https.any.js rename to compute-pressure/compute_pressure_disconnect_immediately.https.any.js index 9b545fbe1c33bc..86963e242aba38 100644 --- a/compute-pressure/compute_pressure_disconnect_immediately.tentative.https.any.js +++ b/compute-pressure/compute_pressure_disconnect_immediately.https.any.js @@ -24,7 +24,7 @@ pressure_test(async (t, mockPressureService) => { t.add_cleanup(() => observer2.disconnect()); observer2.observe('cpu').catch(reject); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_equals( @@ -55,7 +55,7 @@ pressure_test(async (t, mockPressureService) => { observer1.disconnect(); await promise_rejects_dom(t, 'AbortError', promise); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_equals( diff --git a/compute-pressure/compute_pressure_duplicate_updates.tentative.https.any.js b/compute-pressure/compute_pressure_duplicate_updates.https.any.js similarity index 92% rename from compute-pressure/compute_pressure_duplicate_updates.tentative.https.any.js rename to compute-pressure/compute_pressure_duplicate_updates.https.any.js index dde92932dd14e7..04c5df5e5767c1 100644 --- a/compute-pressure/compute_pressure_duplicate_updates.tentative.https.any.js +++ b/compute-pressure/compute_pressure_duplicate_updates.https.any.js @@ -12,11 +12,11 @@ pressure_test(async (t, mockPressureService) => { observer_changes.push(changes); if (++n === 2) resolve(observer_changes); - }, {sampleRate: 5.0}); + }, {sampleInterval: 200}); observer.observe('cpu'); const updatesDelivered = mockPressureService.updatesDelivered(); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval*/ 200); // Deliver 2 updates. await t.step_wait( () => mockPressureService.updatesDelivered() >= (updatesDelivered + 2), diff --git a/compute-pressure/compute_pressure_multiple.tentative.https.any.js b/compute-pressure/compute_pressure_multiple.https.any.js similarity index 94% rename from compute-pressure/compute_pressure_multiple.tentative.https.any.js rename to compute-pressure/compute_pressure_multiple.https.any.js index c8cef5beca0cba..8c50cc4b3df27e 100644 --- a/compute-pressure/compute_pressure_multiple.tentative.https.any.js +++ b/compute-pressure/compute_pressure_multiple.https.any.js @@ -24,7 +24,7 @@ pressure_test(async (t, mockPressureService) => { }); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); const [changes1, changes2, changes3] = await Promise.all([changes1_promise, changes2_promise, changes3_promise]); diff --git a/compute-pressure/compute_pressure_observe_idempotent.tentative.https.any.js b/compute-pressure/compute_pressure_observe_idempotent.https.any.js similarity index 90% rename from compute-pressure/compute_pressure_observe_idempotent.tentative.https.any.js rename to compute-pressure/compute_pressure_observe_idempotent.https.any.js index 5dc3804b2f7ea2..9fcbb49814b6c0 100644 --- a/compute-pressure/compute_pressure_observe_idempotent.tentative.https.any.js +++ b/compute-pressure/compute_pressure_observe_idempotent.https.any.js @@ -12,7 +12,7 @@ pressure_test(async (t, mockPressureService) => { observer.observe('cpu').catch(reject); observer.observe('cpu').catch(reject); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_equals(update[0].state, 'critical'); diff --git a/compute-pressure/compute_pressure_observe_unobserve_failure.tentative.https.any.js b/compute-pressure/compute_pressure_observe_unobserve_failure.https.any.js similarity index 100% rename from compute-pressure/compute_pressure_observe_unobserve_failure.tentative.https.any.js rename to compute-pressure/compute_pressure_observe_unobserve_failure.https.any.js diff --git a/compute-pressure/compute_pressure_options.https.any.js b/compute-pressure/compute_pressure_options.https.any.js new file mode 100644 index 00000000000000..d0760ef6224db7 --- /dev/null +++ b/compute-pressure/compute_pressure_options.https.any.js @@ -0,0 +1,26 @@ +// META: global=window,dedicatedworker,sharedworker + +'use strict'; + +test(t => { + const observer = new PressureObserver(() => {}, {sampleInterval: 0}); + assert_equals(typeof observer, 'object'); +}, 'PressureObserver constructor doesnt throw error for sampleInterval value 0'); + + +test(t => { + assert_throws_js(TypeError, () => { + new PressureObserver(() => {}, {sampleInterval: -2}); + }); +}, 'PressureObserver constructor requires a positive sampleInterval'); + +test(t => { + assert_throws_js(TypeError, () => { + new PressureObserver(() => {}, {sampleInterval: 2 ** 32}); + }); +}, 'PressureObserver constructor requires a sampleInterval in unsigned long range'); + +test(t => { + const observer = new PressureObserver(() => {}, {}); + assert_equals(typeof observer, 'object'); +}, 'PressureObserver constructor succeeds on empty sampleInterval'); diff --git a/compute-pressure/compute_pressure_options.tentative.https.any.js b/compute-pressure/compute_pressure_options.tentative.https.any.js deleted file mode 100644 index 69999819d962fb..00000000000000 --- a/compute-pressure/compute_pressure_options.tentative.https.any.js +++ /dev/null @@ -1,25 +0,0 @@ -// META: global=window,dedicatedworker,sharedworker - -'use strict'; - -test(t => { - assert_throws_js(RangeError, () => { - new PressureObserver(() => {}, {sampleRate: 0}); - }); -}, 'PressureObserver constructor requires a non-zero sampleRate'); - -test(t => { - assert_throws_js(RangeError, () => { - new PressureObserver(() => {}, {sampleRate: -2}); - }); -}, 'PressureObserver constructor requires a positive sampleRate'); - -test(t => { - const observer = new PressureObserver(() => {}, {sampleRate: 0.5}); - assert_equals(typeof observer, 'object'); -}, 'PressureObserver constructor doesnt throw error on positive sampleRate'); - -test(t => { - const observer = new PressureObserver(() => {}, {}); - assert_equals(typeof observer, 'object'); -}, 'PressureObserver constructor succeeds on empty sampleRate'); diff --git a/compute-pressure/compute_pressure_rate_obfuscation_mitigation_not_triggered.tentative.https.window.js b/compute-pressure/compute_pressure_rate_obfuscation_mitigation_not_triggered.https.window.js similarity index 93% rename from compute-pressure/compute_pressure_rate_obfuscation_mitigation_not_triggered.tentative.https.window.js rename to compute-pressure/compute_pressure_rate_obfuscation_mitigation_not_triggered.https.window.js index cb1aa432ce6124..e348a8ea08886b 100644 --- a/compute-pressure/compute_pressure_rate_obfuscation_mitigation_not_triggered.tentative.https.window.js +++ b/compute-pressure/compute_pressure_rate_obfuscation_mitigation_not_triggered.https.window.js @@ -6,7 +6,7 @@ 'use strict'; pressure_test(async (t, mockPressureService) => { - const sampleRateInHz = 10; + const sampleIntervalInMs = 100; const readings = ['nominal', 'fair', 'serious', 'critical']; // Normative values for rate obfuscation parameters. // https://w3c.github.io/compute-pressure/#rate-obfuscation-normative-parameters. @@ -17,10 +17,10 @@ pressure_test(async (t, mockPressureService) => { const observerChanges = []; const observer = new PressureObserver(changes => { observerChanges.push(changes); - }, {sampleRate: sampleRateInHz}); + }, {sampleInterval: sampleIntervalInMs}); observer.observe('cpu'); - mockPressureService.startPlatformCollector(sampleRateInHz); + mockPressureService.startPlatformCollector(sampleIntervalInMs); let i = 0; // mockPressureService.updatesDelivered() does not necessarily match // pressureChanges.length, as system load and browser optimizations can diff --git a/compute-pressure/compute_pressure_rate_obfuscation_mitigation_triggered.tentative.https.window.js b/compute-pressure/compute_pressure_rate_obfuscation_mitigation_triggered.https.window.js similarity index 93% rename from compute-pressure/compute_pressure_rate_obfuscation_mitigation_triggered.tentative.https.window.js rename to compute-pressure/compute_pressure_rate_obfuscation_mitigation_triggered.https.window.js index 11dcc3c70aa151..ebe33bc8bf712d 100644 --- a/compute-pressure/compute_pressure_rate_obfuscation_mitigation_triggered.tentative.https.window.js +++ b/compute-pressure/compute_pressure_rate_obfuscation_mitigation_triggered.https.window.js @@ -6,7 +6,7 @@ 'use strict'; pressure_test(async (t, mockPressureService) => { - const sampleRateInHz = 25; + const sampleIntervalInMs = 40; const readings = ['nominal', 'fair', 'serious', 'critical']; // Normative values for rate obfuscation parameters. // https://w3c.github.io/compute-pressure/#rate-obfuscation-normative-parameters. @@ -31,10 +31,10 @@ pressure_test(async (t, mockPressureService) => { } } observerChanges.push(changes); - }, {sampleRate: sampleRateInHz}); + }, {sampleInterval: sampleIntervalInMs}); observer.observe('cpu'); - mockPressureService.startPlatformCollector(sampleRateInHz); + mockPressureService.startPlatformCollector(sampleIntervalInMs); let i = 0; // mockPressureService.updatesDelivered() does not necessarily match // pressureChanges.length, as system load and browser optimizations can diff --git a/compute-pressure/compute_pressure_supported_sources.tentative.https.any.js b/compute-pressure/compute_pressure_supported_sources.https.any.js similarity index 100% rename from compute-pressure/compute_pressure_supported_sources.tentative.https.any.js rename to compute-pressure/compute_pressure_supported_sources.https.any.js diff --git a/compute-pressure/compute_pressure_take_records.tentative.https.any.js b/compute-pressure/compute_pressure_take_records.https.any.js similarity index 92% rename from compute-pressure/compute_pressure_take_records.tentative.https.any.js rename to compute-pressure/compute_pressure_take_records.https.any.js index d93c9b5c886f9d..55660b228be224 100644 --- a/compute-pressure/compute_pressure_take_records.tentative.https.any.js +++ b/compute-pressure/compute_pressure_take_records.https.any.js @@ -20,7 +20,7 @@ pressure_test(async (t, mockPressureService) => { observer.observe('cpu'); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_equals(changes[0].state, 'critical'); diff --git a/compute-pressure/compute_pressure_timestamp.tentative.https.any.js b/compute-pressure/compute_pressure_timestamp.https.any.js similarity index 78% rename from compute-pressure/compute_pressure_timestamp.tentative.https.any.js rename to compute-pressure/compute_pressure_timestamp.https.any.js index f283caa6baebbe..09caeb34789df2 100644 --- a/compute-pressure/compute_pressure_timestamp.tentative.https.any.js +++ b/compute-pressure/compute_pressure_timestamp.https.any.js @@ -7,15 +7,15 @@ pressure_test(async (t, mockPressureService) => { const readings = ['nominal', 'fair', 'serious', 'critical']; - const sampleRate = 4.0; + const sampleInterval = 250; const pressureChanges = await new Promise(async resolve => { const observerChanges = []; const observer = new PressureObserver(changes => { observerChanges.push(changes); - }, {sampleRate}); + }, {sampleInterval}); observer.observe('cpu'); - mockPressureService.startPlatformCollector(sampleRate * 2); + mockPressureService.startPlatformCollector(sampleInterval / 2); let i = 0; // mockPressureService.updatesDelivered() does not necessarily match // pressureChanges.length, as system load and browser optimizations can @@ -34,27 +34,24 @@ pressure_test(async (t, mockPressureService) => { assert_equals(pressureChanges.length, 4); assert_greater_than_equal( - pressureChanges[1][0].time - pressureChanges[0][0].time, - (1 / sampleRate * 1000)); + pressureChanges[1][0].time - pressureChanges[0][0].time, sampleInterval); assert_greater_than_equal( - pressureChanges[2][0].time - pressureChanges[1][0].time, - (1 / sampleRate * 1000)); + pressureChanges[2][0].time - pressureChanges[1][0].time, sampleInterval); assert_greater_than_equal( - pressureChanges[3][0].time - pressureChanges[2][0].time, - (1 / sampleRate * 1000)); + pressureChanges[3][0].time - pressureChanges[2][0].time, sampleInterval); }, 'Faster collector: Timestamp difference between two changes should be higher or equal to the observer sample rate'); pressure_test(async (t, mockPressureService) => { const pressureChanges = []; - const sampleRate = 1.0; + const sampleInterval = 1000; const observer = new PressureObserver(changes => { pressureChanges.push(changes); - }, {sampleRate}); + }, {sampleInterval}); await new Promise(async resolve => { observer.observe('cpu'); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(sampleRate); + mockPressureService.startPlatformCollector(sampleInterval); await t.step_wait(() => pressureChanges.length == 1); observer.disconnect(); resolve(); @@ -63,7 +60,7 @@ pressure_test(async (t, mockPressureService) => { await new Promise(async resolve => { observer.observe('cpu'); mockPressureService.setPressureUpdate('cpu', 'serious'); - mockPressureService.startPlatformCollector(sampleRate * 4); + mockPressureService.startPlatformCollector(sampleInterval / 4); await t.step_wait(() => pressureChanges.length == 2); observer.disconnect(); resolve(); @@ -74,6 +71,5 @@ pressure_test(async (t, mockPressureService) => { // should be deleted. So the second PressureRecord is not discarded even // though the time interval does not meet the requirement. assert_less_than( - pressureChanges[1][0].time - pressureChanges[0][0].time, - (1 / sampleRate * 1000)); + pressureChanges[1][0].time - pressureChanges[0][0].time, sampleInterval); }, 'disconnect() should update [[LastRecordMap]]'); diff --git a/compute-pressure/compute_pressure_update_toJSON.tentative.https.any.js b/compute-pressure/compute_pressure_update_toJSON.https.any.js similarity index 89% rename from compute-pressure/compute_pressure_update_toJSON.tentative.https.any.js rename to compute-pressure/compute_pressure_update_toJSON.https.any.js index 0024d697549061..7f726698d61dd3 100644 --- a/compute-pressure/compute_pressure_update_toJSON.tentative.https.any.js +++ b/compute-pressure/compute_pressure_update_toJSON.https.any.js @@ -7,7 +7,7 @@ pressure_test(async (t, mockPressureService) => { const observer = new PressureObserver(resolve); observer.observe('cpu'); mockPressureService.setPressureUpdate('cpu', 'critical'); - mockPressureService.startPlatformCollector(/*sampleRate=*/ 5.0); + mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200); }); assert_true(changes.length === 1); const json = changes[0].toJSON(); diff --git a/compute-pressure/idlharness.https.any.js b/compute-pressure/idlharness.https.any.js index e8289962324eee..48ab5615b03fbe 100644 --- a/compute-pressure/idlharness.https.any.js +++ b/compute-pressure/idlharness.https.any.js @@ -11,5 +11,5 @@ idl_test(['compute-pressure'], ['dom', 'html'], async idl_array => { PressureObserver: ['observer'], }); - self.observer = new PressureObserver(() => {}, {sampleRate: 1.0}); + self.observer = new PressureObserver(() => {}, {sampleInterval: 1000}); }); diff --git a/console/console-countReset-logging-manual.html b/console/console-countReset-logging-manual.html index 7fe01f50edbfa1..f0a9358fba5d74 100644 --- a/console/console-countReset-logging-manual.html +++ b/console/console-countReset-logging-manual.html @@ -24,21 +24,25 @@ console.count(); console.countReset(); console.count(); +console.countReset(); console.count(undefined); console.countReset(undefined); console.count(undefined); +console.countReset(undefined); console.count("default"); console.countReset("default"); console.count("default"); +console.countReset("default"); console.count({toString() {return "default"}}); console.countReset({toString() {return "default"}}); console.count({toString() {return "default"}}); +console.countReset({toString() {return "default"}}); console.count("a label"); -console.countReset(); +console.countReset("a label"); console.count("a label"); console.countReset("b"); // should produce a warning diff --git a/credential-management/digital-identity.https.html b/credential-management/digital-identity.https.html new file mode 100644 index 00000000000000..bfbe76baf80a6e --- /dev/null +++ b/credential-management/digital-identity.https.html @@ -0,0 +1,138 @@ + +Digital Identity Credential tests. + + + + + + + + + diff --git a/credential-management/fedcm-authz/fedcm-continue-on-disallowed.https.html b/credential-management/fedcm-authz/fedcm-continue-on-disallowed.https.html new file mode 100644 index 00000000000000..fcda3a3dd591c6 --- /dev/null +++ b/credential-management/fedcm-authz/fedcm-continue-on-disallowed.https.html @@ -0,0 +1,31 @@ + +Federated Credential Management API network request tests. + + + + + + + + + diff --git a/credential-management/fedcm-authz/fedcm-continue-on-with-account.https.html b/credential-management/fedcm-authz/fedcm-continue-on-with-account.https.html new file mode 100644 index 00000000000000..5bd8ef34fe83e5 --- /dev/null +++ b/credential-management/fedcm-authz/fedcm-continue-on-with-account.https.html @@ -0,0 +1,37 @@ + +Federated Credential Management API network request tests. + + + + + + + + + diff --git a/credential-management/fedcm-authz/fedcm-continue-on.https.html b/credential-management/fedcm-authz/fedcm-continue-on.https.html index 3ce1f51e370535..c7da5384af43ef 100644 --- a/credential-management/fedcm-authz/fedcm-continue-on.https.html +++ b/credential-management/fedcm-authz/fedcm-continue-on.https.html @@ -18,7 +18,7 @@ const options = request_options_with_mediation_required('manifest_with_continue_on.json'); await select_manifest(t, options); const cred = await fedcm_get_and_select_first_account(t, options); - assert_equals(cred.token, "resolved token"); + assert_equals(cred.token, "account=1234"); }, "continue_on and IdentityProvider.resolve work correctly."); diff --git a/credential-management/fedcm-authz/fedcm-userinfo-after-resolve.https.html b/credential-management/fedcm-authz/fedcm-userinfo-after-resolve.https.html index ef53ed4ffca54f..0521f4a2ab5d82 100644 --- a/credential-management/fedcm-authz/fedcm-userinfo-after-resolve.https.html +++ b/credential-management/fedcm-authz/fedcm-userinfo-after-resolve.https.html @@ -29,7 +29,7 @@ const options = alt_request_options_with_mediation_required('manifest_with_continue_on.json'); await select_manifest(t, options); const cred = await fedcm_get_and_select_first_account(t, options); - assert_equals(cred.token, "resolved token"); + assert_equals(cred.token, "account=1234"); const iframe_in_idp_scope = `${alt_manifest_origin}/\ credential-management/support/fedcm/userinfo-iframe.html`; diff --git a/credential-management/fedcm-button-and-other-account/fedcm-button-mode-basics.tentative.https.html b/credential-management/fedcm-button-and-other-account/fedcm-button-mode-basics.tentative.https.html new file mode 100644 index 00000000000000..a71e2621352492 --- /dev/null +++ b/credential-management/fedcm-button-and-other-account/fedcm-button-mode-basics.tentative.https.html @@ -0,0 +1,34 @@ + +Federated Credential Management API Button Mode basic tests. + + + + + + + diff --git a/credential-management/fedcm-button-mode-basics.https.html b/credential-management/fedcm-button-and-other-account/fedcm-button-mode-priority.tentative.https.html similarity index 77% rename from credential-management/fedcm-button-mode-basics.https.html rename to credential-management/fedcm-button-and-other-account/fedcm-button-mode-priority.tentative.https.html index abf46ee7db0511..b71e84db47e458 100644 --- a/credential-management/fedcm-button-mode-basics.https.html +++ b/credential-management/fedcm-button-and-other-account/fedcm-button-mode-priority.tentative.https.html @@ -1,5 +1,5 @@ -Federated Credential Management API auto selected flag tests. +Federated Credential Management API Button Mode priority tests. @@ -9,28 +9,22 @@ diff --git a/credential-management/fedcm-context.https.html b/credential-management/fedcm-context.https.html index bc1f96eafa03c7..7b3e1032af98b4 100644 --- a/credential-management/fedcm-context.https.html +++ b/credential-management/fedcm-context.https.html @@ -16,32 +16,32 @@ fedcm_test(async t => { let p = navigator.credentials.get(request_options_with_mediation_required()); - const title = await fedcm_get_title_promise(t); - assert_true(title.toLowerCase().includes('sign in')); + const result = await fedcm_get_title_promise(t); + assert_true(result.title.toLowerCase().includes('sign in')); window.test_driver.select_fedcm_account(0); return p; }, "FedCM call defaults to 'signin' context."); fedcm_test(async t => { let p = navigator.credentials.get(request_options_with_context("manifest.py", "signup")); - const title = await fedcm_get_title_promise(t); - assert_true(title.toLowerCase().includes('sign up')); + const result = await fedcm_get_title_promise(t); + assert_true(result.title.toLowerCase().includes('sign up')); window.test_driver.select_fedcm_account(0); return p; }, "FedCM with 'signup' context."); fedcm_test(async t => { let p = navigator.credentials.get(request_options_with_context("manifest.py", "use")); - const title = await fedcm_get_title_promise(t); - assert_true(title.toLowerCase().includes('use')); + const result = await fedcm_get_title_promise(t); + assert_true(result.title.toLowerCase().includes('use')); window.test_driver.select_fedcm_account(0); return p; }, "FedCM with 'use' context."); fedcm_test(async t => { let p = navigator.credentials.get(request_options_with_context("manifest.py", "continue")); - const title = await fedcm_get_title_promise(t); - assert_true(title.toLowerCase().includes('continue')); + const result = await fedcm_get_title_promise(t); + assert_true(result.title.toLowerCase().includes('continue')); window.test_driver.select_fedcm_account(0); return p; }, "FedCM with 'continue' context."); diff --git a/credential-management/fedcm-domainhint.https.html b/credential-management/fedcm-domainhint.https.html index 3e07491d48d2f6..20b4569a05e67d 100644 --- a/credential-management/fedcm-domainhint.https.html +++ b/credential-management/fedcm-domainhint.https.html @@ -22,7 +22,7 @@ let options = request_options_with_domain_hint('manifest.py', 'nomatch'); - const cred = fedcm_get_and_select_first_account(t, options); + const cred = navigator.credentials.get(options); // We expect a mismatch dialog. const type = await fedcm_get_dialog_type_promise(t); assert_equals(type, 'ConfirmIdpLogin'); diff --git a/credential-management/fedcm-endpoint-redirects.https.html b/credential-management/fedcm-endpoint-redirects.https.html index cff5036f393231..36a4de7900c1f8 100644 --- a/credential-management/fedcm-endpoint-redirects.https.html +++ b/credential-management/fedcm-endpoint-redirects.https.html @@ -20,7 +20,7 @@ let test_options = request_options_with_mediation_required("manifest_redirect_accounts.json"); await select_manifest(t, test_options); - const cred = fedcm_get_and_select_first_account(t, test_options); + const cred = navigator.credentials.get(test_options); // We expect a mismatch dialog. const type = await fedcm_get_dialog_type_promise(t); assert_equals(type, 'ConfirmIdpLogin'); diff --git a/credential-management/fedcm-loginhint.https.html b/credential-management/fedcm-loginhint.https.html index edae955a761756..fe35007a87dc06 100644 --- a/credential-management/fedcm-loginhint.https.html +++ b/credential-management/fedcm-loginhint.https.html @@ -19,7 +19,7 @@ await mark_signed_in(); let options = request_options_with_login_hint('manifest.py', 'nomatch'); - const cred = fedcm_get_and_select_first_account(t, options); + const cred = navigator.credentials.get(options); // We expect a mismatch dialog. const type = await fedcm_get_dialog_type_promise(t); assert_equals(type, 'ConfirmIdpLogin'); diff --git a/credential-management/fedcm-same-site-none/fedcm-same-site-none.https.html b/credential-management/fedcm-same-site-none/fedcm-same-site-none.https.html new file mode 100644 index 00000000000000..77ecdaff9fe36e --- /dev/null +++ b/credential-management/fedcm-same-site-none/fedcm-same-site-none.https.html @@ -0,0 +1,25 @@ + +Federated Credential Management API SameSite=None tests. + + + + + + + + + diff --git a/credential-management/support/digital-identity-helper.js b/credential-management/support/digital-identity-helper.js new file mode 100644 index 00000000000000..687a751745c510 --- /dev/null +++ b/credential-management/support/digital-identity-helper.js @@ -0,0 +1,23 @@ +// Builds valid digital identity request for navigator.identity.get() API. +export function buildValidNavigatorIdentityRequest() { + return { + digital: { + providers: [{ + protocol: "protocol", + selector: { + format: ['mdoc'], + doctype: 'org.iso.18013.5.1.mDL', + fields: [ + 'org.iso.18013.5.1.family_name', + 'org.iso.18013.5.1.portrait', + ] + }, + params: { + nonce: '1234', + readerPublicKey: 'test_reader_public_key', + extraParamAsNeededByDigitalCredentials: true, + }, + }], + }, + }; +} diff --git a/credential-management/support/digital-identity-iframe.html b/credential-management/support/digital-identity-iframe.html new file mode 100644 index 00000000000000..8e193ff09f90fb --- /dev/null +++ b/credential-management/support/digital-identity-iframe.html @@ -0,0 +1,27 @@ + + + + diff --git a/credential-management/support/fedcm-helper.sub.js b/credential-management/support/fedcm-helper.sub.js index 765b3cc48a9019..18c9aa486dce23 100644 --- a/credential-management/support/fedcm-helper.sub.js +++ b/credential-management/support/fedcm-helper.sub.js @@ -8,7 +8,9 @@ export function open_and_wait_for_popup(origin, path) { // We rely on the popup page to send us a message when done. const popup_message_handler = (event) => { - if (event.origin == origin) { + // We use new URL() to ensure the two origins are normalized the same + // way (especially so that default ports are handled identically). + if (new URL(event.origin).toString() == new URL(origin).toString()) { popup_window.close(); window.removeEventListener('message', popup_message_handler); resolve(); @@ -22,7 +24,7 @@ export function open_and_wait_for_popup(origin, path) { // Set the identity provider cookie. export function set_fedcm_cookie(host) { if (host == undefined) { - document.cookie = 'cookie=1; SameSite=Strict; Path=/credential-management/support; Secure'; + document.cookie = 'cookie=1; SameSite=None; Path=/credential-management/support; Secure'; return Promise.resolve(); } else { return open_and_wait_for_popup(host, '/credential-management/support/set_cookie'); diff --git a/credential-management/support/fedcm/accounts_check_same_site_strict.py b/credential-management/support/fedcm/accounts_check_same_site_strict.py new file mode 100644 index 00000000000000..a6f385feac1ccf --- /dev/null +++ b/credential-management/support/fedcm/accounts_check_same_site_strict.py @@ -0,0 +1,28 @@ +import importlib +error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check") + +def main(request, response): + request_error = error_checker.accountsCheck(request) + if (request_error): + return request_error + if request.cookies.get(b"same_site_strict") == b"1": + return (546, [], "Should not send SameSite=Strict cookies") + if request.headers.get(b"Sec-Fetch-Site") != b"cross-site": + return (538, [], "Wrong Sec-Fetch-Site header") + + response.headers.set(b"Content-Type", b"application/json") + + return """ +{ + "accounts": [{ + "id": "1234", + "given_name": "John", + "name": "John Doe", + "email": "john_doe@idp.example", + "picture": "https://idp.example/profile/123", + "approved_clients": ["123", "456", "789"], + "login_hints": ["john_doe"], + "domain_hints": ["idp.example", "example"] + }] +} +""" diff --git a/credential-management/support/fedcm/accounts_no_approved_clients.py b/credential-management/support/fedcm/accounts_no_approved_clients.py new file mode 100644 index 00000000000000..faea06edc36306 --- /dev/null +++ b/credential-management/support/fedcm/accounts_no_approved_clients.py @@ -0,0 +1,30 @@ +import importlib +error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check") + +def main(request, response): + request_error = error_checker.accountsCheck(request) + if (request_error): + return request_error + + response.headers.set(b"Content-Type", b"application/json") + + return """ +{ + "accounts": [{ + "id": "1234", + "given_name": "John", + "name": "John Doe", + "email": "john_doe@idp.example", + "picture": "https://idp.example/profile/123", + "login_hints": ["john_doe"], + "domain_hints": ["idp.example", "example"] + }, + { + "id": "jane_doe", + "given_name": "Jane", + "name": "Jane Doe", + "email": "jane_doe@idp.example", + "picture": "https://idp.example/profile/5678" + }] +} +""" diff --git a/credential-management/support/fedcm/continue_on.py b/credential-management/support/fedcm/continue_on.py index 42b4f3f8fdcbf6..1b4831b51de7ee 100644 --- a/credential-management/support/fedcm/continue_on.py +++ b/credential-management/support/fedcm/continue_on.py @@ -8,5 +8,7 @@ def main(request, response): response.headers.set(b"Content-Type", b"application/json") - return "{\"continue_on\": \"resolve.html\"}" + account = request.POST.get(b"account_id").decode("utf-8") + nonce = request.POST.get(b"nonce").decode("utf-8") + return "{\"continue_on\": \"resolve.html?selected=%s&%s\"}" % (account, nonce) diff --git a/credential-management/support/fedcm/manifest_check_same_site_strict.json b/credential-management/support/fedcm/manifest_check_same_site_strict.json new file mode 100644 index 00000000000000..d7304159834804 --- /dev/null +++ b/credential-management/support/fedcm/manifest_check_same_site_strict.json @@ -0,0 +1,7 @@ +{ + "accounts_endpoint": "accounts_check_same_site_strict.py", + "client_metadata_endpoint": "client_metadata.py", + "id_assertion_endpoint": "token_check_same_site_strict.py", + "login_url": "login.html" +} + diff --git a/credential-management/support/fedcm/manifest_with_continue_on.json b/credential-management/support/fedcm/manifest_with_continue_on.json index 3f5a954b875475..d7673c7e1b13e6 100644 --- a/credential-management/support/fedcm/manifest_with_continue_on.json +++ b/credential-management/support/fedcm/manifest_with_continue_on.json @@ -1,5 +1,5 @@ { - "accounts_endpoint": "accounts.py", + "accounts_endpoint": "accounts_no_approved_clients.py", "client_metadata_endpoint": "client_metadata.py", "id_assertion_endpoint": "continue_on.py", "disconnect_endpoint": "disconnect.py", diff --git a/credential-management/support/fedcm/request-params-check.py b/credential-management/support/fedcm/request-params-check.py index b774496d5dab3e..6c610e6e201dd1 100644 --- a/credential-management/support/fedcm/request-params-check.py +++ b/credential-management/support/fedcm/request-params-check.py @@ -17,8 +17,6 @@ def commonUncredentialedRequestCheck(request): def commonCredentialedRequestCheck(request): if request.cookies.get(b"cookie") != b"1": return (537, [], "Missing cookie") - if request.headers.get(b"Sec-Fetch-Site") != b"none": - return (538, [], "Wrong Sec-Fetch-Site header") def commonPostCheck(request): if not request.headers.get(b"Origin"): diff --git a/credential-management/support/fedcm/resolve.html b/credential-management/support/fedcm/resolve.html index 87f5112cfd1358..dbdc28c3247a38 100644 --- a/credential-management/support/fedcm/resolve.html +++ b/credential-management/support/fedcm/resolve.html @@ -1,7 +1,16 @@ diff --git a/credential-management/support/fedcm/set_accounts_cookie.py b/credential-management/support/fedcm/set_accounts_cookie.py index ab349922104c00..15adf11324ee6b 100644 --- a/credential-management/support/fedcm/set_accounts_cookie.py +++ b/credential-management/support/fedcm/set_accounts_cookie.py @@ -15,6 +15,7 @@ def main(request, response): // If this page was opened as a popup, notify the opener. if (window.opener) { window.opener.postMessage("done_loading", "*"); + window.close(); } Sent header value: {}".format(header_value) diff --git a/credential-management/support/fedcm/token_check_same_site_strict.py b/credential-management/support/fedcm/token_check_same_site_strict.py new file mode 100644 index 00000000000000..8a4b3a234bdb99 --- /dev/null +++ b/credential-management/support/fedcm/token_check_same_site_strict.py @@ -0,0 +1,15 @@ +import importlib +error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check") + +def main(request, response): + request_error = error_checker.tokenCheck(request) + if (request_error): + return request_error + if request.cookies.get(b"same_site_strict") == b"1": + return (546, [], "Should not send SameSite=Strict cookies") + + response.headers.set(b"Content-Type", b"application/json") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"Origin")) + response.headers.set(b"Access-Control-Allow-Credentials", "true") + + return "{\"token\": \"token\"}" diff --git a/credential-management/support/fencedframe-mark-signedin.html b/credential-management/support/fencedframe-mark-signedin.html index 532db7047a8a09..681fcd67875256 100644 --- a/credential-management/support/fencedframe-mark-signedin.html +++ b/credential-management/support/fencedframe-mark-signedin.html @@ -3,13 +3,17 @@ diff --git a/credential-management/support/set_cookie b/credential-management/support/set_cookie index 1080b366e4680f..2c3196058a9e52 100644 --- a/credential-management/support/set_cookie +++ b/credential-management/support/set_cookie @@ -6,6 +6,7 @@ // If this page was opened as a popup, notify the opener. if (window.opener) { window.opener.postMessage("done_loading", "*"); + window.close(); } diff --git a/credential-management/support/set_cookie.headers b/credential-management/support/set_cookie.headers index b19ff933a6f585..4226ff4c9975cc 100644 --- a/credential-management/support/set_cookie.headers +++ b/credential-management/support/set_cookie.headers @@ -1,2 +1,3 @@ Content-Type: text/html Set-Cookie: cookie=1; SameSite=None; Secure +Set-Cookie: same_site_strict=1; SameSite=Strict; Secure diff --git a/css/CSS2/linebox/vertical-align-122-ref.xht b/css/CSS2/linebox/vertical-align-122-ref.xht new file mode 100644 index 00000000000000..86b4856266285a --- /dev/null +++ b/css/CSS2/linebox/vertical-align-122-ref.xht @@ -0,0 +1,87 @@ + + + + CSS Reftest Reference + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/css/CSS2/linebox/vertical-align-122.xht b/css/CSS2/linebox/vertical-align-122.xht new file mode 100644 index 00000000000000..1d7c180f197b92 --- /dev/null +++ b/css/CSS2/linebox/vertical-align-122.xht @@ -0,0 +1,62 @@ + + + + CSS Test: vertical-align on inline-block + + + + + + + + + + + +
+ X
X +
+
+ X
X +
+
+ X
X +
+
+ X
X +
+
+
+ +
+
+ +
+
+ +
+
+ +
+ + diff --git a/css/CSS2/tables/reference/no_red_3x3_monospace_table-ref.xht b/css/CSS2/tables/reference/no_red_3x3_monospace_table-ref.xht index 821ddc77b00912..5425f5b17501d5 100644 --- a/css/CSS2/tables/reference/no_red_3x3_monospace_table-ref.xht +++ b/css/CSS2/tables/reference/no_red_3x3_monospace_table-ref.xht @@ -17,6 +17,7 @@ position: absolute; top: 1px; left: 1px; + right: 1px; } td { padding: 0; diff --git a/css/CSS2/tables/table-anonymous-objects-212-ref.xht b/css/CSS2/tables/table-anonymous-objects-212-ref.xht new file mode 100644 index 00000000000000..4781f3c52702c9 --- /dev/null +++ b/css/CSS2/tables/table-anonymous-objects-212-ref.xht @@ -0,0 +1,11 @@ + + + + CSS Reftest Reference + + + + above
+ below + + diff --git a/css/CSS2/tables/table-anonymous-objects-212.xht b/css/CSS2/tables/table-anonymous-objects-212.xht new file mode 100644 index 00000000000000..e6bdfd5dd9bc30 --- /dev/null +++ b/css/CSS2/tables/table-anonymous-objects-212.xht @@ -0,0 +1,16 @@ + + + + CSS Test: Anonymous table objects + + + + + + + + above + below + + diff --git a/css/CSS2/tables/table-anonymous-objects-213-ref.xht b/css/CSS2/tables/table-anonymous-objects-213-ref.xht new file mode 100644 index 00000000000000..9c2f98a29d8fc7 --- /dev/null +++ b/css/CSS2/tables/table-anonymous-objects-213-ref.xht @@ -0,0 +1,10 @@ + + + + CSS Reftest Reference + + + + left right + + diff --git a/css/CSS2/tables/table-anonymous-objects-213.xht b/css/CSS2/tables/table-anonymous-objects-213.xht new file mode 100644 index 00000000000000..e701a82bf06305 --- /dev/null +++ b/css/CSS2/tables/table-anonymous-objects-213.xht @@ -0,0 +1,19 @@ + + + + CSS Test: Anonymous table objects + + + + + + + + + left + right + + + diff --git a/css/CSS2/tables/table-vertical-align-baseline-008.xht b/css/CSS2/tables/table-vertical-align-baseline-008.xht new file mode 100644 index 00000000000000..1200ac1ae87c79 --- /dev/null +++ b/css/CSS2/tables/table-vertical-align-baseline-008.xht @@ -0,0 +1,25 @@ + + + + CSS Test: Test for baseline alignment of table cells + + + + + + + + +

Test passes if there is a filled green square and no red.

+
+
+ + +
+
+ + diff --git a/css/CSS2/tables/table-vertical-align-baseline-009.xht b/css/CSS2/tables/table-vertical-align-baseline-009.xht new file mode 100644 index 00000000000000..4620848ddc1966 --- /dev/null +++ b/css/CSS2/tables/table-vertical-align-baseline-009.xht @@ -0,0 +1,29 @@ + + + + CSS Test: Test for baseline alignment of table cells + + + + + + + + + +

Test passes if there is a filled green square and no red.

+
+ X + X + + X + X + +
+ + diff --git a/css/CSS2/text/text-align-justify-with-overflow-ref.html b/css/CSS2/text/text-align-justify-with-overflow-ref.html new file mode 100644 index 00000000000000..be2ac9dae17306 --- /dev/null +++ b/css/CSS2/text/text-align-justify-with-overflow-ref.html @@ -0,0 +1,26 @@ + + + + + CSS Test: Overflowing content with text-align: justify + + + + + + + + + + +
lorem ipsum lastline
+
lorem ipsum lastline
+ + diff --git a/css/CSS2/text/text-align-justify-with-overflow.html b/css/CSS2/text/text-align-justify-with-overflow.html new file mode 100644 index 00000000000000..927e9afd5add40 --- /dev/null +++ b/css/CSS2/text/text-align-justify-with-overflow.html @@ -0,0 +1,29 @@ + + + + + CSS Test: Overflowing content with text-align: justify + + + + + + + + + + + +
lorem ipsum lastline
+
lorem ipsum lastline
+ + + diff --git a/css/CSS2/text/text-indent-wrap-002-ref.html b/css/CSS2/text/text-indent-wrap-002-ref.html new file mode 100644 index 00000000000000..9750ce4c8994bb --- /dev/null +++ b/css/CSS2/text/text-indent-wrap-002-ref.html @@ -0,0 +1,23 @@ + + + + + CSS Test: text-indent test (multiple-lines and text-align: justify) + + + + + + + +

This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines.

+ + diff --git a/css/CSS2/text/text-indent-wrap-002.html b/css/CSS2/text/text-indent-wrap-002.html new file mode 100644 index 00000000000000..128cba3f1221d8 --- /dev/null +++ b/css/CSS2/text/text-indent-wrap-002.html @@ -0,0 +1,22 @@ + + + + + CSS Test: text-indent test (multiple-lines and text-align: justify) + + + + + + + + +

This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines. This is a long piece of text that will wrap to multiple lines.

+ + diff --git a/css/css-align/gaps/gap-parsing-002.html b/css/css-align/gaps/gap-parsing-002.html new file mode 100644 index 00000000000000..f84abccf3cf796 --- /dev/null +++ b/css/css-align/gaps/gap-parsing-002.html @@ -0,0 +1,67 @@ + + + +CSS Align Gap Values: longhand and shorthand gap parsing for style attribute + + + + + + + + + + diff --git a/css/css-anchor-position/anchor-center-htb-htb.html b/css/css-anchor-position/anchor-center-htb-htb.html index 7012208044af1c..20abb2ed096c93 100644 --- a/css/css-anchor-position/anchor-center-htb-htb.html +++ b/css/css-anchor-position/anchor-center-htb-htb.html @@ -21,7 +21,7 @@ } .target { - anchor-default: --anchor; + position-anchor: --anchor; position: absolute; background: cyan; justify-self: anchor-center; diff --git a/css/css-anchor-position/anchor-center-htb-vrl.html b/css/css-anchor-position/anchor-center-htb-vrl.html index 584424d306fb54..099d9cd15b43ae 100644 --- a/css/css-anchor-position/anchor-center-htb-vrl.html +++ b/css/css-anchor-position/anchor-center-htb-vrl.html @@ -22,7 +22,7 @@ .target { writing-mode: vertical-rl; - anchor-default: --anchor; + position-anchor: --anchor; position: absolute; background: cyan; align-self: anchor-center; diff --git a/css/css-anchor-position/anchor-center-vrl-htb.html b/css/css-anchor-position/anchor-center-vrl-htb.html index c7ee2302626eb8..3e4f485cec3d73 100644 --- a/css/css-anchor-position/anchor-center-vrl-htb.html +++ b/css/css-anchor-position/anchor-center-vrl-htb.html @@ -23,7 +23,7 @@ .target { writing-mode: horizontal-tb; - anchor-default: --anchor; + position-anchor: --anchor; position: absolute; background: cyan; align-self: anchor-center; diff --git a/css/css-anchor-position/anchor-center-vrl-vrl.html b/css/css-anchor-position/anchor-center-vrl-vrl.html index d314dc7f2fc696..fe40c731419c42 100644 --- a/css/css-anchor-position/anchor-center-vrl-vrl.html +++ b/css/css-anchor-position/anchor-center-vrl-vrl.html @@ -22,7 +22,7 @@ } .target { - anchor-default: --anchor; + position-anchor: --anchor; position: absolute; background: cyan; justify-self: anchor-center; diff --git a/css/css-anchor-position/anchor-getComputedStyle-002.html b/css/css-anchor-position/anchor-getComputedStyle-002.html index ae697fcc749891..a3e00d50485a35 100644 --- a/css/css-anchor-position/anchor-getComputedStyle-002.html +++ b/css/css-anchor-position/anchor-getComputedStyle-002.html @@ -13,7 +13,7 @@ margin: 0; } -.cb { +.rel { position: relative; background: lightgray; } @@ -36,7 +36,7 @@
-
+
@@ -51,7 +51,7 @@ height: 100px; } -#test1 .cb { +#test1 .rel{ width: 100px; height: 300px; } @@ -79,19 +79,23 @@
- Lorem - - ipsum dolor sit - - - amet.
+
+ Lorem + + ipsum dolor sit + + + amet. +
- Lorem - - ipsum dolor sit - - - amet.
+
+ Lorem + + ipsum dolor sit + + + amet. +
- - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- diff --git a/css/css-anchor-position/anchor-name-style-contained.html b/css/css-anchor-position/anchor-name-style-contained.html deleted file mode 100644 index a5295758891e4e..00000000000000 --- a/css/css-anchor-position/anchor-name-style-contained.html +++ /dev/null @@ -1,60 +0,0 @@ - -CSS Anchor Positioning: anchor-name is style contained - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/css/css-anchor-position/anchor-position-circular.html b/css/css-anchor-position/anchor-position-circular.html index 8efbeb09e20304..85fca57421cb13 100644 --- a/css/css-anchor-position/anchor-position-circular.html +++ b/css/css-anchor-position/anchor-position-circular.html @@ -15,7 +15,7 @@ #anchored1 { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: orange; @@ -24,7 +24,7 @@ #anchored2 { position: absolute; - anchor-default: --a2; + position-anchor: --a2; left: anchor(--a2 left); top: anchor(--a2 bottom); background: green; diff --git a/css/css-anchor-position/anchor-position-dynamic-004.html b/css/css-anchor-position/anchor-position-dynamic-004.html index 146703e628b7f5..b7944652a0b21d 100644 --- a/css/css-anchor-position/anchor-position-dynamic-004.html +++ b/css/css-anchor-position/anchor-position-dynamic-004.html @@ -30,7 +30,7 @@
-
+
diff --git a/css/css-anchor-position/anchor-position-top-layer-001.html b/css/css-anchor-position/anchor-position-top-layer-001.html index 055459551b8c94..a8513bb74ca029 100644 --- a/css/css-anchor-position/anchor-position-top-layer-001.html +++ b/css/css-anchor-position/anchor-position-top-layer-001.html @@ -21,7 +21,7 @@ width: 100px; height: 100px; background: lime; - anchor-default: --a; + position-anchor: --a; outline: none; } diff --git a/css/css-anchor-position/anchor-position-top-layer-002.html b/css/css-anchor-position/anchor-position-top-layer-002.html index a87a9d7eedd899..9ce0b8e5f9fe50 100644 --- a/css/css-anchor-position/anchor-position-top-layer-002.html +++ b/css/css-anchor-position/anchor-position-top-layer-002.html @@ -21,7 +21,7 @@ width: 100px; height: 100px; background: lime; - anchor-default: --a; + position-anchor: --a; outline: none; } diff --git a/css/css-anchor-position/anchor-position-top-layer-003.html b/css/css-anchor-position/anchor-position-top-layer-003.html index 96d5219c5ce550..3bc815af0cab70 100644 --- a/css/css-anchor-position/anchor-position-top-layer-003.html +++ b/css/css-anchor-position/anchor-position-top-layer-003.html @@ -21,7 +21,7 @@ width: 100px; height: 100px; background: lime; - anchor-default: --a; + position-anchor: --a; outline: none; } diff --git a/css/css-anchor-position/anchor-position-top-layer-004.html b/css/css-anchor-position/anchor-position-top-layer-004.html index c986e3f98d3c71..ad0a7b8b32f278 100644 --- a/css/css-anchor-position/anchor-position-top-layer-004.html +++ b/css/css-anchor-position/anchor-position-top-layer-004.html @@ -21,7 +21,7 @@ width: 100px; height: 100px; background: lime; - anchor-default: --a; + position-anchor: --a; outline: none; } diff --git a/css/css-anchor-position/anchor-position-top-layer-005.html b/css/css-anchor-position/anchor-position-top-layer-005.html index cf39c77736738d..51aa482aee52eb 100644 --- a/css/css-anchor-position/anchor-position-top-layer-005.html +++ b/css/css-anchor-position/anchor-position-top-layer-005.html @@ -22,7 +22,7 @@ width: 100px; height: 100px; background: lime; - anchor-default: --a; + position-anchor: --a; } body { diff --git a/css/css-anchor-position/anchor-position-top-layer-006.html b/css/css-anchor-position/anchor-position-top-layer-006.html index c13284b854843f..a3b9e63c06b59b 100644 --- a/css/css-anchor-position/anchor-position-top-layer-006.html +++ b/css/css-anchor-position/anchor-position-top-layer-006.html @@ -22,7 +22,7 @@ width: 100px; height: 100px; background: lime; - anchor-default: --a; + position-anchor: --a; } body { diff --git a/css/css-anchor-position/anchor-scroll-001.html b/css/css-anchor-position/anchor-scroll-001.html index 8609795c8a6d02..b9dfc56e2effe4 100644 --- a/css/css-anchor-position/anchor-scroll-001.html +++ b/css/css-anchor-position/anchor-scroll-001.html @@ -40,7 +40,7 @@ position: absolute; left: anchor(--anchor left); bottom: anchor(--anchor top); - anchor-default: --anchor; + position-anchor: --anchor; } #outer-anchored { @@ -48,7 +48,7 @@ position: absolute; left: anchor(--anchor left); top: anchor(--anchor bottom); - anchor-default: --anchor; + position-anchor: --anchor; } diff --git a/css/css-anchor-position/anchor-scroll-002.html b/css/css-anchor-position/anchor-scroll-002.html index 8ef6f500a1f2fb..2c51e6a1a3ab74 100644 --- a/css/css-anchor-position/anchor-scroll-002.html +++ b/css/css-anchor-position/anchor-scroll-002.html @@ -45,7 +45,7 @@ height: 50px; top: anchor(--a1 top); left: anchor(--a1 right); - anchor-default: --a1; + position-anchor: --a1; } diff --git a/css/css-anchor-position/anchor-scroll-003.html b/css/css-anchor-position/anchor-scroll-003.html index c1b31c0becf286..6c0dd08355c471 100644 --- a/css/css-anchor-position/anchor-scroll-003.html +++ b/css/css-anchor-position/anchor-scroll-003.html @@ -47,7 +47,7 @@ position: absolute; left: anchor(--a left); bottom: anchor(--a top); - anchor-default: --a; + position-anchor: --a; width: 50px; height: 50px; background: lime; diff --git a/css/css-anchor-position/anchor-scroll-004.html b/css/css-anchor-position/anchor-scroll-004.html index d08279118d9e9c..c0e0afb23f143e 100644 --- a/css/css-anchor-position/anchor-scroll-004.html +++ b/css/css-anchor-position/anchor-scroll-004.html @@ -32,7 +32,7 @@ .target { position: absolute; - anchor-default: --a; + position-anchor: --a; top: anchor(--a bottom); left: anchor(--a left); color: lime; diff --git a/css/css-anchor-position/anchor-scroll-005.html b/css/css-anchor-position/anchor-scroll-005.html index a9a7d24d2b9ccd..f8f26b719f07c2 100644 --- a/css/css-anchor-position/anchor-scroll-005.html +++ b/css/css-anchor-position/anchor-scroll-005.html @@ -33,7 +33,7 @@ width: 100px; height: 100px; bottom: anchor(--a top); - anchor-default: --a; + position-anchor: --a; background: lime; } diff --git a/css/css-anchor-position/anchor-scroll-006.html b/css/css-anchor-position/anchor-scroll-006.html index 2ffd026b55296f..9c8a8c0ac2fe3c 100644 --- a/css/css-anchor-position/anchor-scroll-006.html +++ b/css/css-anchor-position/anchor-scroll-006.html @@ -50,21 +50,21 @@ /* Needs scroll adjustment in x axis only */ #target1 { - anchor-default: --a1; + position-anchor: --a1; left: anchor(left); top: anchor(--scroller1 bottom); } /* Needs scroll adjustment in y axis only */ #target2 { - anchor-default: --a2; + position-anchor: --a2; top: anchor(top); left: anchor(--scroller2 right); } /* No scroll adjustment needed */ #target3 { - anchor-default: --a3; + position-anchor: --a3; top: anchor(--scroller3 bottom); left: anchor(--scroller3 right); } diff --git a/css/css-anchor-position/anchor-scroll-007.html b/css/css-anchor-position/anchor-scroll-007.html index ec519106190c7c..7e288d713f6b6f 100644 --- a/css/css-anchor-position/anchor-scroll-007.html +++ b/css/css-anchor-position/anchor-scroll-007.html @@ -56,7 +56,7 @@ height: 50px; left: anchor(--a3 left); top: anchor(--a1 top); - anchor-default: --a2; + position-anchor: --a2; background: lime; } diff --git a/css/css-anchor-position/anchor-scroll-chained-001.tentative.html b/css/css-anchor-position/anchor-scroll-chained-001.tentative.html index 60ad128022640e..1235f8fad4388c 100644 --- a/css/css-anchor-position/anchor-scroll-chained-001.tentative.html +++ b/css/css-anchor-position/anchor-scroll-chained-001.tentative.html @@ -25,7 +25,7 @@ #anchored1 { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; @@ -34,7 +34,7 @@ #anchored2 { position: absolute; - anchor-default: --a2; + position-anchor: --a2; left: anchor(--a2 left); top: anchor(--a2 bottom); background: lime; diff --git a/css/css-anchor-position/anchor-scroll-chained-002.tentative.html b/css/css-anchor-position/anchor-scroll-chained-002.tentative.html index e180c5646826b2..9c60799e0bb40f 100644 --- a/css/css-anchor-position/anchor-scroll-chained-002.tentative.html +++ b/css/css-anchor-position/anchor-scroll-chained-002.tentative.html @@ -31,7 +31,7 @@ #anchored1 { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; @@ -40,7 +40,7 @@ #anchored2 { position: absolute; - anchor-default: --a2; + position-anchor: --a2; left: anchor(--a2 left); top: anchor(--a2 bottom); background: lime; diff --git a/css/css-anchor-position/anchor-scroll-chained-003.tentative.html b/css/css-anchor-position/anchor-scroll-chained-003.tentative.html index 8912fcb6994035..b441c92bf15f4f 100644 --- a/css/css-anchor-position/anchor-scroll-chained-003.tentative.html +++ b/css/css-anchor-position/anchor-scroll-chained-003.tentative.html @@ -31,7 +31,7 @@ #anchored1 { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; @@ -41,7 +41,7 @@ #anchored2 { position: absolute; - anchor-default: --a2; + position-anchor: --a2; left: anchor(--a2 left); top: anchor(--a2 bottom); background: lime; diff --git a/css/css-anchor-position/anchor-scroll-chained-004.tentative.html b/css/css-anchor-position/anchor-scroll-chained-004.tentative.html index 5834eb1f4cb2df..f1765a9870f37e 100644 --- a/css/css-anchor-position/anchor-scroll-chained-004.tentative.html +++ b/css/css-anchor-position/anchor-scroll-chained-004.tentative.html @@ -37,7 +37,7 @@ #anchored1 { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; @@ -45,7 +45,7 @@ #anchored2 { position: absolute; - anchor-default: --a2; + position-anchor: --a2; left: anchor(--a2 left); top: anchor(--a2 bottom); background: lime; diff --git a/css/css-anchor-position/anchor-scroll-chained-fallback.tentative.html b/css/css-anchor-position/anchor-scroll-chained-fallback.tentative.html index bc7e231e7ce7de..d2300da818291f 100644 --- a/css/css-anchor-position/anchor-scroll-chained-fallback.tentative.html +++ b/css/css-anchor-position/anchor-scroll-chained-fallback.tentative.html @@ -27,29 +27,26 @@ #anchored1 { position: absolute; - anchor-default: --a1; + position-anchor: --a1; background: green; - position-fallback: --fallback; + position-try-options: --fallback; anchor-name: --a2; + left: anchor(--a1 left); + bottom: anchor(--a1 top); } #anchored2 { position: absolute; - anchor-default: --a2; + position-anchor: --a2; left: anchor(--a2 left); top: anchor(--a2 bottom); background: lime; } -@position-fallback --fallback { - @try { - left: anchor(--a1 left); - bottom: anchor(--a1 top); - } - @try { - left: anchor(--a1 right); - top: anchor(--a1 top); - } +@position-try --fallback { + left: anchor(--a1 right); + top: anchor(--a1 top); + bottom: auto; } diff --git a/css/css-anchor-position/anchor-scroll-composited-scrolling-001-crash.html b/css/css-anchor-position/anchor-scroll-composited-scrolling-001-crash.html index 005a27393a23b8..4dd9bad60eae27 100644 --- a/css/css-anchor-position/anchor-scroll-composited-scrolling-001-crash.html +++ b/css/css-anchor-position/anchor-scroll-composited-scrolling-001-crash.html @@ -23,7 +23,7 @@ #anchored { position: absolute; - anchor-default: --a; + position-anchor: --a; left: anchor(--a left); bottom: anchor(--a top); width: 100px; diff --git a/css/css-anchor-position/anchor-scroll-composited-scrolling-002-crash.html b/css/css-anchor-position/anchor-scroll-composited-scrolling-002-crash.html index 83ce1468252532..80dabbb6661e56 100644 --- a/css/css-anchor-position/anchor-scroll-composited-scrolling-002-crash.html +++ b/css/css-anchor-position/anchor-scroll-composited-scrolling-002-crash.html @@ -23,7 +23,7 @@ position: fixed; top: anchor(--a bottom); left: anchor(--a left); - anchor-default: --a; + position-anchor: --a; } diff --git a/css/css-anchor-position/anchor-scroll-composited-scrolling-003-crash.html b/css/css-anchor-position/anchor-scroll-composited-scrolling-003-crash.html index 594c844bfb5c7e..f46d902ffee7ce 100644 --- a/css/css-anchor-position/anchor-scroll-composited-scrolling-003-crash.html +++ b/css/css-anchor-position/anchor-scroll-composited-scrolling-003-crash.html @@ -23,7 +23,7 @@ position: fixed; top: anchor(--a bottom); left: anchor(--a left); - anchor-default: --a; + position-anchor: --a; } diff --git a/css/css-anchor-position/anchor-scroll-composited-scrolling-004-crash.html b/css/css-anchor-position/anchor-scroll-composited-scrolling-004-crash.html index 226a1b099c3b12..ee5ad2f41ae3a7 100644 --- a/css/css-anchor-position/anchor-scroll-composited-scrolling-004-crash.html +++ b/css/css-anchor-position/anchor-scroll-composited-scrolling-004-crash.html @@ -23,7 +23,7 @@ position: fixed; top: anchor(--a bottom); left: anchor(--a left); - anchor-default: --a; + position-anchor: --a; } diff --git a/css/css-anchor-position/anchor-scroll-composited-scrolling-005-crash.html b/css/css-anchor-position/anchor-scroll-composited-scrolling-005-crash.html index 639e2e064a79bf..c5e44a79e79731 100644 --- a/css/css-anchor-position/anchor-scroll-composited-scrolling-005-crash.html +++ b/css/css-anchor-position/anchor-scroll-composited-scrolling-005-crash.html @@ -23,7 +23,7 @@ position: fixed; top: anchor(--a bottom); left: anchor(--a left); - anchor-default: --a; + position-anchor: --a; } diff --git a/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html b/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html index 6e57accc457f9f..49c6dc780c785f 100644 --- a/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html +++ b/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html @@ -29,7 +29,7 @@ background: red; left: 0; bottom: anchor(--a top); - anchor-default: --a; + position-anchor: --a; } #overlap { position: absolute; diff --git a/css/css-anchor-position/anchor-scroll-fixedpos-002.html b/css/css-anchor-position/anchor-scroll-fixedpos-002.html index 5b2aa2dd50ba52..1a05d8b93a1049 100644 --- a/css/css-anchor-position/anchor-scroll-fixedpos-002.html +++ b/css/css-anchor-position/anchor-scroll-fixedpos-002.html @@ -23,7 +23,7 @@ #anchored { position: fixed; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 right); top: anchor(--a1 top); background: green; diff --git a/css/css-anchor-position/anchor-scroll-fixedpos.html b/css/css-anchor-position/anchor-scroll-fixedpos.html index a32ef3f7c497a6..7923ed789de055 100644 --- a/css/css-anchor-position/anchor-scroll-fixedpos.html +++ b/css/css-anchor-position/anchor-scroll-fixedpos.html @@ -22,7 +22,7 @@ #anchored { position: fixed; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 right); top: anchor(--a1 top); background: green; diff --git a/css/css-anchor-position/anchor-scroll-js-expose.html b/css/css-anchor-position/anchor-scroll-js-expose.html index 1ef44d03c2202d..3b3f1a06086ae8 100644 --- a/css/css-anchor-position/anchor-scroll-js-expose.html +++ b/css/css-anchor-position/anchor-scroll-js-expose.html @@ -35,7 +35,7 @@ bottom: anchor(--anchor top); width: 100px; height: 100px; - anchor-default: --anchor; + position-anchor: --anchor; background-color: green; } diff --git a/css/css-anchor-position/anchor-scroll-nested.html b/css/css-anchor-position/anchor-scroll-nested.html index 557f748c02988b..291fe0d7103fa3 100644 --- a/css/css-anchor-position/anchor-scroll-nested.html +++ b/css/css-anchor-position/anchor-scroll-nested.html @@ -41,7 +41,7 @@ width: 50px; height: 50px; left: anchor(--anchor left); - anchor-default: --anchor; + position-anchor: --anchor; } .above { diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-001.html b/css/css-anchor-position/anchor-scroll-position-try-001.html similarity index 84% rename from css/css-anchor-position/anchor-scroll-fallback-position-001.html rename to css/css-anchor-position/anchor-scroll-position-try-001.html index 04518e5019349f..3130018e73d921 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-001.html +++ b/css/css-anchor-position/anchor-scroll-position-try-001.html @@ -35,30 +35,29 @@ #anchored { position: absolute; background: green; - anchor-default: --a; - position-fallback: --fallback; + position-anchor: --a; + position-try-options: --f1, --f2; + width: 100px; height: 100px; + /* Above the anchor */ + left: anchor(--a left); + bottom: anchor(--a top); } -@position-fallback --fallback { - /* Above the anchor */ - @try { - width: 100px; height: 100px; - left: anchor(--a left); - bottom: anchor(--a top); - } +@position-try --f1 { /* Left of the anchor */ - @try { - width: 100px; height: 100px; - right: anchor(--a left); - top: anchor(--a top); - } + right: anchor(--a left); + top: anchor(--a top); + bottom: auto; + left: auto; +} + +@position-try --f2 { /* Right of the anchor */ - @try { - width: 100px; height: 100px; - left: anchor(--a right); - top: anchor(--a top); - } + left: anchor(--a right); + top: anchor(--a top); + bottom: auto; } +
diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-002.html b/css/css-anchor-position/anchor-scroll-position-try-002.html similarity index 89% rename from css/css-anchor-position/anchor-scroll-fallback-position-002.html rename to css/css-anchor-position/anchor-scroll-position-try-002.html index f30c35d390da93..52bbcd62fc1931 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-002.html +++ b/css/css-anchor-position/anchor-scroll-position-try-002.html @@ -31,14 +31,15 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; + position-anchor: --a; top: anchor(--a top); - position-fallback: --pf; + left: anchor(--a right); + position-try-options: --pf; } -@position-fallback --pf { - @try { left: anchor(--a right); } - @try { right: anchor(--a left); } +@position-try --pf { + left: auto; + right: anchor(--a left); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-003.html b/css/css-anchor-position/anchor-scroll-position-try-003.html similarity index 91% rename from css/css-anchor-position/anchor-scroll-fallback-position-003.html rename to css/css-anchor-position/anchor-scroll-position-try-003.html index 60bc9b919af0cf..b89a574d768edf 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-003.html +++ b/css/css-anchor-position/anchor-scroll-position-try-003.html @@ -35,16 +35,17 @@ #anchored { position: absolute; + top: anchor(--a bottom); width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try-options: --pf; } -@position-fallback --pf { - @try { top: anchor(--a bottom); } - @try { bottom: anchor(--a top); } +@position-try --pf { + top: auto; + bottom: anchor(--a top); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-004.html b/css/css-anchor-position/anchor-scroll-position-try-004.html similarity index 86% rename from css/css-anchor-position/anchor-scroll-fallback-position-004.html rename to css/css-anchor-position/anchor-scroll-position-try-004.html index 99e4f9c30d1dd6..bf0bee972deadd 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-004.html +++ b/css/css-anchor-position/anchor-scroll-position-try-004.html @@ -33,17 +33,24 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try-options: --pf1, --pf2; + /* Top of the anchor */ + bottom: anchor(--a top); + left: anchor(--a left); } -@position-fallback --pf { - /* Top of the anchor */ - @try { bottom: anchor(--a top); left: anchor(--a left); } +@position-try --pf1 { /* Bottom of the anchor */ - @try { top: anchor(--a bottom); left: anchor(--a left); } + top: anchor(--a bottom); + bottom: auto; +} +@position-try --pf2 { /* Left of the anchor */ - @try { top: anchor(--a top); right: anchor(--a left); } + top: anchor(--a top); + right: anchor(--a left); + bottom: auto; + left: auto; } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-005.html b/css/css-anchor-position/anchor-scroll-position-try-005.html similarity index 90% rename from css/css-anchor-position/anchor-scroll-fallback-position-005.html rename to css/css-anchor-position/anchor-scroll-position-try-005.html index 0adfe0834d850c..197a9e4f79c2a8 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-005.html +++ b/css/css-anchor-position/anchor-scroll-position-try-005.html @@ -32,14 +32,15 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; + position-anchor: --a; top: anchor(--a top); - position-fallback: --pf; + left: anchor(--a right); + position-try-options: --pf; } -@position-fallback --pf { - @try { left: anchor(--a right); } - @try { right: anchor(--a left); } +@position-try --pf { + left: auto; + right: anchor(--a left); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-006.html b/css/css-anchor-position/anchor-scroll-position-try-006.html similarity index 82% rename from css/css-anchor-position/anchor-scroll-fallback-position-006.html rename to css/css-anchor-position/anchor-scroll-position-try-006.html index b4a1a24de69f7d..132c45c89c75d6 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-006.html +++ b/css/css-anchor-position/anchor-scroll-position-try-006.html @@ -28,27 +28,26 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try: --pf1, --pf2, --pf3; + inset-block-start: anchor(--a end); + inset-inline-start: anchor(--a end); } -@position-fallback --pf { - @try { - inset-block-start: anchor(--a end); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-start: anchor(--a end); - inset-inline-end: anchor(--a start); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-end: anchor(--a start); - } +@position-try --pf1 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-start: anchor(--a end); +} +@position-try --pf2 { + inset: auto; + inset-block-start: anchor(--a end); + inset-inline-end: anchor(--a start); +} +@position-try --pf3 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-end: anchor(--a start); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-007.html b/css/css-anchor-position/anchor-scroll-position-try-007.html similarity index 82% rename from css/css-anchor-position/anchor-scroll-fallback-position-007.html rename to css/css-anchor-position/anchor-scroll-position-try-007.html index baa283ba944540..a02bd35a669a92 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-007.html +++ b/css/css-anchor-position/anchor-scroll-position-try-007.html @@ -32,27 +32,26 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try-options: --pf1, --pf2, --pf3; + inset-block-start: anchor(--a end); + inset-inline-start: anchor(--a end); } -@position-fallback --pf { - @try { - inset-block-start: anchor(--a end); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-start: anchor(--a end); - inset-inline-end: anchor(--a start); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-end: anchor(--a start); - } +@position-try --pf1 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-start: anchor(--a end); +} +@position-try --pf2 { + inset: auto; + inset-block-start: anchor(--a end); + inset-inline-end: anchor(--a start); +} +@position-try --pf3 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-end: anchor(--a start); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-008.html b/css/css-anchor-position/anchor-scroll-position-try-008.html similarity index 82% rename from css/css-anchor-position/anchor-scroll-fallback-position-008.html rename to css/css-anchor-position/anchor-scroll-position-try-008.html index ae625d5823982e..2deddd587ef2a5 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-008.html +++ b/css/css-anchor-position/anchor-scroll-position-try-008.html @@ -33,27 +33,26 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try-options: --pf1, --pf2, --pf3; + inset-block-start: anchor(--a end); + inset-inline-start: anchor(--a end); } -@position-fallback --pf { - @try { - inset-block-start: anchor(--a end); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-start: anchor(--a end); - inset-inline-end: anchor(--a start); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-end: anchor(--a start); - } +@position-try --pf1 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-start: anchor(--a end); +} +@position-try --pf2 { + inset: auto; + inset-block-start: anchor(--a end); + inset-inline-end: anchor(--a start); +} +@position-try --pf3 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-end: anchor(--a start); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-009.html b/css/css-anchor-position/anchor-scroll-position-try-009.html similarity index 82% rename from css/css-anchor-position/anchor-scroll-fallback-position-009.html rename to css/css-anchor-position/anchor-scroll-position-try-009.html index b355d476e6b7f6..0d7d6b077fc734 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-009.html +++ b/css/css-anchor-position/anchor-scroll-position-try-009.html @@ -32,27 +32,26 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try-options: --pf1, --pf2, --pf3; + inset-block-start: anchor(--a end); + inset-inline-start: anchor(--a end); } -@position-fallback --pf { - @try { - inset-block-start: anchor(--a end); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-start: anchor(--a end); - inset-inline-end: anchor(--a start); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-end: anchor(--a start); - } +@position-try --pf1 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-start: anchor(--a end); +} +@position-try --pf2 { + inset: auto; + inset-block-start: anchor(--a end); + inset-inline-end: anchor(--a start); +} +@position-try --pf3 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-end: anchor(--a start); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-010.html b/css/css-anchor-position/anchor-scroll-position-try-010.html similarity index 82% rename from css/css-anchor-position/anchor-scroll-fallback-position-010.html rename to css/css-anchor-position/anchor-scroll-position-try-010.html index a0dd599b3b66ef..21f32ad068e64d 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-010.html +++ b/css/css-anchor-position/anchor-scroll-position-try-010.html @@ -33,27 +33,26 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try-options: --pf1, --pf2, --pf3; + inset-block-start: anchor(--a end); + inset-inline-start: anchor(--a end); } -@position-fallback --pf { - @try { - inset-block-start: anchor(--a end); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-start: anchor(--a end); - } - @try { - inset-block-start: anchor(--a end); - inset-inline-end: anchor(--a start); - } - @try { - inset-block-end: anchor(--a start); - inset-inline-end: anchor(--a start); - } +@position-try --pf1 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-start: anchor(--a end); +} +@position-try --pf2 { + inset: auto; + inset-block-start: anchor(--a end); + inset-inline-end: anchor(--a start); +} +@position-try --pf3 { + inset: auto; + inset-block-end: anchor(--a start); + inset-inline-end: anchor(--a start); } diff --git a/css/css-anchor-position/anchor-scroll-fallback-position-011.html b/css/css-anchor-position/anchor-scroll-position-try-011.html similarity index 87% rename from css/css-anchor-position/anchor-scroll-fallback-position-011.html rename to css/css-anchor-position/anchor-scroll-position-try-011.html index 98fa4b5f86cd52..5de84610105129 100644 --- a/css/css-anchor-position/anchor-scroll-fallback-position-011.html +++ b/css/css-anchor-position/anchor-scroll-position-try-011.html @@ -45,27 +45,26 @@ width: 100px; height: 100px; background: green; - anchor-default: --a; - position-fallback: --pf; + position-anchor: --a; + position-try-options: --pf1, --pf2, --pf3; + bottom: anchor(--a top); + left: anchor(--a right); } -@position-fallback --pf { - @try { - bottom: anchor(--a top); - left: anchor(--a right); - } - @try { - top: anchor(--a bottom); - left: anchor(--a right); - } - @try { - bottom: anchor(--a top); - right: anchor(--a left); - } - @try { - top: anchor(--a bottom); - right: anchor(--a left); - } +@position-try --pf1 { + inset: auto; + top: anchor(--a bottom); + left: anchor(--a right); +} +@position-try --pf2 { + inset: auto; + bottom: anchor(--a top); + right: anchor(--a left); +} +@position-try --pf3 { + inset: auto; + top: anchor(--a bottom); + right: anchor(--a left); } diff --git a/css/css-anchor-position/anchor-scroll-to-sticky-001.html b/css/css-anchor-position/anchor-scroll-to-sticky-001.html index abab944751ed2d..a6c3b0572533a2 100644 --- a/css/css-anchor-position/anchor-scroll-to-sticky-001.html +++ b/css/css-anchor-position/anchor-scroll-to-sticky-001.html @@ -27,7 +27,7 @@ #anchored { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; diff --git a/css/css-anchor-position/anchor-scroll-to-sticky-002.html b/css/css-anchor-position/anchor-scroll-to-sticky-002.html index 357421ecf1b361..e2d91fe4dd6966 100644 --- a/css/css-anchor-position/anchor-scroll-to-sticky-002.html +++ b/css/css-anchor-position/anchor-scroll-to-sticky-002.html @@ -28,7 +28,7 @@ #anchored { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; diff --git a/css/css-anchor-position/anchor-scroll-to-sticky-003.html b/css/css-anchor-position/anchor-scroll-to-sticky-003.html index 0e770044913669..b40f5cc8d519f0 100644 --- a/css/css-anchor-position/anchor-scroll-to-sticky-003.html +++ b/css/css-anchor-position/anchor-scroll-to-sticky-003.html @@ -27,7 +27,7 @@ #anchored { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; diff --git a/css/css-anchor-position/anchor-scroll-to-sticky-004.html b/css/css-anchor-position/anchor-scroll-to-sticky-004.html index f7878ae8df8d19..30325ce1e0fa14 100644 --- a/css/css-anchor-position/anchor-scroll-to-sticky-004.html +++ b/css/css-anchor-position/anchor-scroll-to-sticky-004.html @@ -30,7 +30,7 @@ #anchored { position: absolute; - anchor-default: --a1; + position-anchor: --a1; left: anchor(--a1 left); top: anchor(--a1 bottom); background: green; diff --git a/css/css-anchor-position/anchor-scroll-update-001.html b/css/css-anchor-position/anchor-scroll-update-001.html index f11797edadb669..aa49fbcc6db54a 100644 --- a/css/css-anchor-position/anchor-scroll-update-001.html +++ b/css/css-anchor-position/anchor-scroll-update-001.html @@ -41,7 +41,7 @@ position: absolute; left: anchor(--anchor left); bottom: anchor(--anchor top); - anchor-default: --anchor; + position-anchor: --anchor; } #outer-anchored { @@ -49,7 +49,7 @@ position: absolute; left: anchor(--anchor left); top: anchor(--anchor bottom); - anchor-default: --anchor; + position-anchor: --anchor; } diff --git a/css/css-anchor-position/anchor-scroll-update-002.html b/css/css-anchor-position/anchor-scroll-update-002.html index 19447952b0be25..5695db2a1cded6 100644 --- a/css/css-anchor-position/anchor-scroll-update-002.html +++ b/css/css-anchor-position/anchor-scroll-update-002.html @@ -1,6 +1,6 @@ -Anchored elements should update location on `anchor-default` property changes +Anchored elements should update location on `position-anchor` property changes @@ -75,8 +75,8 @@ async function runTest() { await raf(); await raf(); - document.getElementById('inner-anchored').style.anchorDefault = '--anchor'; - document.getElementById('outer-anchored').style.anchorDefault = '--anchor'; + document.getElementById('inner-anchored').style.positionAnchor = '--anchor'; + document.getElementById('outer-anchored').style.positionAnchor = '--anchor'; document.documentElement.classList.remove('reftest-wait'); } runTest(); diff --git a/css/css-anchor-position/anchor-scroll-update-003.html b/css/css-anchor-position/anchor-scroll-update-003.html index 57a524c483fd2f..2e1532badfac69 100644 --- a/css/css-anchor-position/anchor-scroll-update-003.html +++ b/css/css-anchor-position/anchor-scroll-update-003.html @@ -37,7 +37,7 @@ position: absolute; left: anchor(--anchor left); bottom: anchor(--anchor top); - anchor-default: --anchor; + position-anchor: --anchor; } #outer-anchored { @@ -45,7 +45,7 @@ position: absolute; left: anchor(--anchor left); top: anchor(--anchor bottom); - anchor-default: --anchor; + position-anchor: --anchor; } diff --git a/css/css-anchor-position/anchor-scroll-update-004.html b/css/css-anchor-position/anchor-scroll-update-004.html index d20a7b660a6942..87138fb2d92a8d 100644 --- a/css/css-anchor-position/anchor-scroll-update-004.html +++ b/css/css-anchor-position/anchor-scroll-update-004.html @@ -49,7 +49,7 @@ position: absolute; left: anchor(--anchor left); bottom: anchor(--anchor top); - anchor-default: --anchor; + position-anchor: --anchor; } #outer-anchored { @@ -57,7 +57,7 @@ position: absolute; left: anchor(--anchor left); top: anchor(--anchor bottom); - anchor-default: --anchor; + position-anchor: --anchor; } diff --git a/css/css-anchor-position/anchor-scroll-update-005.html b/css/css-anchor-position/anchor-scroll-update-005.html index c2e7248c80c5ed..37874bba5528a1 100644 --- a/css/css-anchor-position/anchor-scroll-update-005.html +++ b/css/css-anchor-position/anchor-scroll-update-005.html @@ -24,7 +24,7 @@ background-color: green; top: anchor(--a top); left: 0; - anchor-default: --a; + position-anchor: --a; }
diff --git a/css/css-anchor-position/anchor-scroll-update-006.html b/css/css-anchor-position/anchor-scroll-update-006.html index 2535c68f78738b..81defee7cf4c3d 100644 --- a/css/css-anchor-position/anchor-scroll-update-006.html +++ b/css/css-anchor-position/anchor-scroll-update-006.html @@ -24,7 +24,7 @@ background-color: green; top: anchor(--a top); left: 0; - anchor-default: --a; + position-anchor: --a; }
diff --git a/css/css-anchor-position/anchor-scroll-update-007.html b/css/css-anchor-position/anchor-scroll-update-007.html index 4859f01d66084e..33050348c4d290 100644 --- a/css/css-anchor-position/anchor-scroll-update-007.html +++ b/css/css-anchor-position/anchor-scroll-update-007.html @@ -37,7 +37,7 @@ position: absolute; left: anchor(--anchor left); bottom: anchor(--anchor top); - anchor-default: --anchor; + position-anchor: --anchor; } #outer-anchored { @@ -45,7 +45,7 @@ position: fixed; left: anchor(--anchor left); top: anchor(--anchor bottom); - anchor-default: --anchor; + position-anchor: --anchor; } diff --git a/css/css-anchor-position/anchor-scroll-vlr.html b/css/css-anchor-position/anchor-scroll-vlr.html index 00406c825e924b..76186f9cad7daa 100644 --- a/css/css-anchor-position/anchor-scroll-vlr.html +++ b/css/css-anchor-position/anchor-scroll-vlr.html @@ -50,7 +50,7 @@ position: absolute; top: anchor(--anchor top); left: anchor(--anchor right); - anchor-default: --anchor; + position-anchor: --anchor; } #outer-anchored { @@ -58,7 +58,7 @@ position: absolute; top: anchor(--anchor top); right: anchor(--anchor left); - anchor-default: --anchor; + position-anchor: --anchor; } diff --git a/css/css-anchor-position/anchor-scroll-vrl.html b/css/css-anchor-position/anchor-scroll-vrl.html index 2432d72899343f..13ea8b37abdd70 100644 --- a/css/css-anchor-position/anchor-scroll-vrl.html +++ b/css/css-anchor-position/anchor-scroll-vrl.html @@ -50,7 +50,7 @@ position: absolute; top: anchor(--anchor top); left: anchor(--anchor right); - anchor-default: --anchor; + position-anchor: --anchor; } #outer-anchored { @@ -58,7 +58,7 @@ position: absolute; top: anchor(--anchor top); right: anchor(--anchor left); - anchor-default: --anchor; + position-anchor: --anchor; } diff --git a/css/css-anchor-position/at-fallback-position-parse.html b/css/css-anchor-position/at-fallback-position-parse.html deleted file mode 100644 index 942d9a2984595b..00000000000000 --- a/css/css-anchor-position/at-fallback-position-parse.html +++ /dev/null @@ -1,39 +0,0 @@ - -Tests parsing of @fallback-position rule - - - - - - diff --git a/css/css-anchor-position/at-position-fallback-cssom.html b/css/css-anchor-position/at-position-fallback-cssom.html deleted file mode 100644 index df295bf2d0adc7..00000000000000 --- a/css/css-anchor-position/at-position-fallback-cssom.html +++ /dev/null @@ -1,81 +0,0 @@ - -Tests the CSSOM interfaces of @position-fallback and @try rules - - - - - -
-
-
- - diff --git a/css/css-anchor-position/at-fallback-position-allowed-declarations.html b/css/css-anchor-position/at-position-try-allowed-declarations.html similarity index 70% rename from css/css-anchor-position/at-fallback-position-allowed-declarations.html rename to css/css-anchor-position/at-position-try-allowed-declarations.html index cca222ac6d7803..f6dac753d2bcf2 100644 --- a/css/css-anchor-position/at-fallback-position-allowed-declarations.html +++ b/css/css-anchor-position/at-position-try-allowed-declarations.html @@ -1,5 +1,5 @@ -Tests which properties are allowed in @fallback-position +Tests which properties are allowed in @position-try @@ -15,21 +15,21 @@ test(t => { t.add_cleanup(cleanup); const serialization = `${property}: ${value}`; - const rule = `@position-fallback --foo { @try { ${property}: ${value}; } }`; + const rule = `@position-try --foo { ${property}: ${value}; }`; const index = style.sheet.insertRule(rule); - const parsed = style.sheet.cssRules[index].cssRules[0]; - assert_equals(parsed.cssText, `@try { ${serialization}; }`); - }, `${property}: ${value} is allowed in @fallback-position`); + const parsed = style.sheet.cssRules[index]; + assert_equals(parsed.cssText, `@position-try --foo { ${serialization}; }`); + }, `${property}: ${value} is allowed in @position-try`); } function test_disallowed_declaration(property, value = '1px') { test(t => { t.add_cleanup(cleanup); - const rule = `@position-fallback --foo { @try { ${property}: ${value}; } }`; + const rule = `@position-try --foo { ${property}: ${value}; }`; const index = style.sheet.insertRule(rule); - const parsed = style.sheet.cssRules[index].cssRules[0]; - assert_equals(parsed.cssText, `@try { }`); - }, `${property}: ${value} is disallowed in @fallback-position`); + const parsed = style.sheet.cssRules[index]; + assert_equals(parsed.cssText, `@position-try --foo { }`); + }, `${property}: ${value} is disallowed in @position-try`); } // Inset properties are allowed @@ -44,7 +44,7 @@ test_allowed_declaration('inset-block'); test_allowed_declaration('inset-inline'); test_allowed_declaration('inset'); -test_allowed_declaration('inset-area', 'all'); +test_allowed_declaration('inset-area', 'span-all'); // Margin properties are allowed test_allowed_declaration('margin-top'); @@ -74,12 +74,12 @@ test_allowed_declaration('max-inline-size'); // Box alignment properties are allowed -test_allowed_declaration('justify-content', 'normal'); -test_allowed_declaration('align-content', 'normal'); -test_allowed_declaration('justify-items', 'normal'); -test_allowed_declaration('align-items', 'normal'); test_allowed_declaration('justify-self', 'normal'); test_allowed_declaration('align-self', 'normal'); +test_allowed_declaration('place-self', 'normal'); + +// The 'position-anchor' property is allowed +test_allowed_declaration('position-anchor', '--anchor'); // Custom properties are disallowed test_disallowed_declaration('--custom'); @@ -91,12 +91,16 @@ test_disallowed_declaration('display'); test_disallowed_declaration('position'); test_disallowed_declaration('float'); +test_disallowed_declaration('justify-content', 'normal'); +test_disallowed_declaration('align-content', 'normal'); +test_disallowed_declaration('justify-items', 'normal'); +test_disallowed_declaration('align-items', 'normal'); -// 'revert' and 'revert-layer' are disallowed -test_disallowed_declaration('top', 'revert'); -test_disallowed_declaration('top', 'revert-layer'); -test_disallowed_declaration('inset', 'revert'); -test_disallowed_declaration('inset', 'revert-layer'); +// 'revert' and 'revert-layer' are allowed +test_allowed_declaration('top', 'revert'); +test_allowed_declaration('top', 'revert-layer'); +test_allowed_declaration('inset', 'revert'); +test_allowed_declaration('inset', 'revert-layer'); // !important is disallowed test_disallowed_declaration('top', '1px !important'); diff --git a/css/css-anchor-position/at-position-try-cssom.html b/css/css-anchor-position/at-position-try-cssom.html new file mode 100644 index 00000000000000..91172c51853131 --- /dev/null +++ b/css/css-anchor-position/at-position-try-cssom.html @@ -0,0 +1,66 @@ + +Tests the CSSOM interfaces of @position-try rules + + + + + +
+
+
+ + diff --git a/css/css-anchor-position/at-position-fallback-invalidation-shadow-dom.html b/css/css-anchor-position/at-position-try-invalidation-shadow-dom.html similarity index 61% rename from css/css-anchor-position/at-position-fallback-invalidation-shadow-dom.html rename to css/css-anchor-position/at-position-try-invalidation-shadow-dom.html index 066cba1dac72d8..50e67de1aef6d9 100644 --- a/css/css-anchor-position/at-position-fallback-invalidation-shadow-dom.html +++ b/css/css-anchor-position/at-position-try-invalidation-shadow-dom.html @@ -1,18 +1,20 @@ -CSS Anchor Positioning Test: Dynamically change @position-fallback rules in Shadow DOM +CSS Anchor Positioning Test: Dynamically change @position-try rules in Shadow DOM