Update web-platform-tests to revision de9a09ab7f605aed6a4b53ed96427412bab76463

This commit is contained in:
WPT Sync Bot 2018-12-01 20:48:01 -05:00
parent f3f9303fc9
commit 73a776843f
225 changed files with 5750 additions and 2858 deletions

View file

@ -61,7 +61,7 @@ tasks:
owner: ${event.pusher.email}
source: ${event.repository.url}
payload:
image: harjgam/web-platform-tests:0.22
image: hexcles/web-platform-tests:0.23
maxRunTime: 7200
artifacts:
public/results:
@ -125,7 +125,7 @@ tasks:
owner: ${event.pull_request.user.login}@users.noreply.github.com
source: ${event.repository.url}
payload:
image: harjgam/web-platform-tests:0.22
image: hexcles/web-platform-tests:0.23
maxRunTime: 7200
artifacts:
public/results:

View file

@ -0,0 +1,45 @@
// META: script=support-promises.js
/**
* This file contains a test that was separated out from the rest of the idb
* explict commit tests because it requires the flag 'allow_uncaught_exception',
* which prevents unintentionally thrown errors from failing tests.
*
* @author andreasbutler@google.com
*/
setup({allow_uncaught_exception:true});
promise_test(async testCase => {
// Register an event listener that will prevent the intentionally thrown
// error from bubbling up to the window and failing the testharness. This
// is necessary because currently allow_uncaught_exception does not behave
// as expected for promise_test.
//
// Git issue: https://github.com/web-platform-tests/wpt/issues/14041
self.addEventListener('error', (event) => { event.preventDefault(); });
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const putRequest = objectStore.put({isbn:'one', title:'title'});
txn.commit();
putRequest.onsuccess = () => {
throw new Error('This error thrown after an explicit commit should not ' +
'prevent the transaction from committing.');
}
await promiseForTransaction(testCase, txn);
// Ensure that despite the uncaught error after the put request, the explicit
// commit still causes the request to be committed.
const txn2 = db.transaction(['books'], 'readwrite');
const objectStore2 = txn2.objectStore('books');
const getRequest = objectStore2.get('one');
await promiseForTransaction(testCase, txn2);
assert_equals(getRequest.result.title, 'title');
}, 'Any errors in callbacks that run after an explicit commit will not stop '
+ 'the commit from being processed.');

View file

@ -0,0 +1,181 @@
// META: script=support-promises.js
/**
* This file contains the webplatform tests for the explicit commit() method
* of the IndexedDB transaction API.
*
* @author andreasbutler@google.com
*/
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
objectStore.put({isbn: 'one', title: 'title1'});
objectStore.put({isbn: 'two', title: 'title2'});
objectStore.put({isbn: 'three', title: 'title3'});
txn.commit();
await promiseForTransaction(testCase, txn);
const txn2 = db.transaction(['books'], 'readonly');
const objectStore2 = txn2.objectStore('books');
const getRequestitle1 = objectStore2.get('one');
const getRequestitle2 = objectStore2.get('two');
const getRequestitle3 = objectStore2.get('three');
txn2.commit();
await promiseForTransaction(testCase, txn2);
assert_array_equals(
[getRequestitle1.result.title,
getRequestitle2.result.title,
getRequestitle3.result.title],
['title1', 'title2', 'title3'],
'All three retrieved titles should match those that were put.');
db.close();
}, 'Explicitly committed data can be read back out.');
promise_test(async testCase => {
let db = await createDatabase(testCase, () => {});
assert_equals(1, db.version, 'A database should be created as version 1');
db.close();
// Upgrade the versionDB database and explicitly commit its versionchange
// transaction.
db = await migrateDatabase(testCase, 2, async (db, txn) => {
txn.commit();
});
assert_equals(2, db.version,
'The database version should have been incremented regardless of '
+ 'whether the versionchange transaction was explicitly or implicitly '
+ 'committed.');
db.close();
}, 'commit() on a version change transaction does not cause errors.');
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
txn.commit();
assert_throws('TransactionInactiveError',
() => { objectStore.put({isbn: 'one', title: 'title1'}); },
'After commit is called, the transaction should be inactive.');
db.close();
}, 'A committed transaction becomes inactive immediately.');
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const putRequest = objectStore.put({isbn: 'one', title: 'title1'});
putRequest.onsuccess = testCase.step_func(() => {
assert_throws('TransactionInactiveError',
() => { objectStore.put({isbn:'two', title:'title2'}); },
'The transaction should not be active in the callback of a request after '
+ 'commit() is called.');
});
txn.commit();
await promiseForTransaction(testCase, txn);
db.close();
}, 'A committed transaction is inactive in future request callbacks.');
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
txn.commit();
assert_throws('TransactionInactiveError',
() => { objectStore.put({isbn:'one', title:'title1'}); },
'After commit is called, the transaction should be inactive.');
const txn2 = db.transaction(['books'], 'readonly');
const objectStore2 = txn2.objectStore('books');
const getRequest = objectStore2.get('one');
await promiseForTransaction(testCase, txn2);
assert_equals(getRequest.result, undefined);
db.close();
}, 'Puts issued after commit are not fulfilled.');
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
txn.abort();
assert_throws('InvalidStateError',
() => { txn.commit(); },
'The transaction should have been aborted.');
db.close();
}, 'Calling commit on an aborted transaction throws.');
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
txn.commit();
assert_throws('InvalidStateError',
() => { txn.commit(); },
'The transaction should have already committed.');
db.close();
}, 'Calling commit on a committed transaction throws.');
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const putRequest = objectStore.put({isbn:'one', title:'title1'});
txn.commit();
assert_throws('InvalidStateError',
() => { txn.abort(); },
'The transaction should already have committed.');
const txn2 = db.transaction(['books'], 'readwrite');
const objectStore2 = txn2.objectStore('books');
const getRequest = objectStore2.get('one');
await promiseForTransaction(testCase, txn2);
assert_equals(
getRequest.result.title,
'title1',
'Explicitly committed data should be gettable.');
db.close();
}, 'Calling abort on a committed transaction throws and does not prevent '
+ 'persisting the data.');
promise_test(async testCase => {
const db = await createDatabase(testCase, async db => {
await createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const releaseTxnFunction = keepAlive(testCase, txn, 'books');
// Break up the scope of execution to force the transaction into an inactive
// state.
await timeoutPromise(0);
assert_throws('InvalidStateError',
() => { txn.commit(); },
'The transaction should be inactive so calling commit should throw.');
releaseTxnFunction();
db.close();
}, 'Calling txn.commit() when txn is inactive should throw.');

View file

@ -312,3 +312,32 @@ async function deleteAllDatabases(testCase) {
await eventWatcher.wait_for('success');
}
}
// Keeps the passed transaction alive indefinitely (by making requests
// against the named store). Returns a function that asserts that the
// transaction has not already completed and then ends the request loop so that
// the transaction may autocommit and complete.
function keepAlive(testCase, transaction, storeName) {
let completed = false;
transaction.addEventListener('complete', () => { completed = true; });
let keepSpinning = true;
function spin() {
if (!keepSpinning)
return;
transaction.objectStore(storeName).get(0).onsuccess = spin;
}
spin();
return testCase.step_func(() => {
assert_false(completed, 'Transaction completed while kept alive');
keepSpinning = false;
});
}
// Return a promise that resolves after a setTimeout finishes to break up the
// scope of a function's execution.
function timeoutPromise(ms) {
return new Promise(resolve => { setTimeout(resolve, ms); });
}

View file

@ -1,6 +1,3 @@
var databaseName = "database";
var databaseVersion = 1;
/* Delete created databases
*
* Go through each finished test, see if it has an associated database. Close
@ -170,18 +167,18 @@ function is_transaction_active(tx, store_name) {
}
}
// Keep the passed transaction alive indefinitely (by making requests
// against the named store). Returns a function to to let the
// transaction finish, and asserts that the transaction is not yet
// finished.
// Keeps the passed transaction alive indefinitely (by making requests
// against the named store). Returns a function that asserts that the
// transaction has not already completed and then ends the request loop so that
// the transaction may autocommit and complete.
function keep_alive(tx, store_name) {
let completed = false;
tx.addEventListener('complete', () => { completed = true; });
let pin = true;
let keepSpinning = true;
function spin() {
if (!pin)
if (!keepSpinning)
return;
tx.objectStore(store_name).get(0).onsuccess = spin;
}
@ -189,6 +186,6 @@ function keep_alive(tx, store_name) {
return () => {
assert_false(completed, 'Transaction completed while kept alive');
pin = false;
keepSpinning = false;
};
}

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Security-Policy" content="img-src 'self'">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
var t1 = async_test("First image should be blocked");
var t2 = async_test("Second image should be blocked");
window.onmessage = t1.step_func_done(function(e) {
if (e.data == "img blocked") {
frames[0].frames[0].frameElement.srcdoc =
`<script>
window.addEventListener('securitypolicyviolation', function(e) {
if (e.violatedDirective == 'img-src') {
top.postMessage('img blocked', '*');
}
})
</scr` + `ipt>
<img src='/content-security-policy/support/fail.png'
onload='top.postMessage("img loaded", "*")'/>`;
window.onmessage = t2.step_func_done(function(e) {
if (e.data != "img blocked")
assert_true(false, "The second image should have been blocked");
});
} else {
assert_true(false, "The first image should have been blocked");
}
});
</script>
<iframe src="support/srcdoc-child-frame.html"></iframe>
</body>
</html>

View file

@ -0,0 +1,19 @@
<head>
<meta http-equiv="Content-Security-Policy" content="img-src 'none'">
</head>
<body>
<script>
var i = document.createElement('iframe');
i.srcdoc=`<script>
window.addEventListener('securitypolicyviolation', function(e) {
if (e.violatedDirective == 'img-src') {
top.postMessage('img blocked', '*');
}
})
</scr` + `ipt>
<img src='/content-security-policy/support/fail.png'
onload='top.postMessage("img loaded", "*")'/>`;
i.id = "srcdoc-frame";
document.body.appendChild(i);
</script>
</body>

View file

@ -0,0 +1,2 @@
<meta http-equiv="Content-Security-Policy" content="{{GET[csp]}}">
CHILD FRAME

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<iframe src="support/frame-with-csp.sub.html?csp=script-src%20%27self%27"></iframe>
<div onclick="frames[0].location.href = 'javascript:parent.postMessage(\'executed\', \'*\')'" id="special_div"></div>
<script>
var t = async_test("Should have executed the javascript url");
window.onmessage = t.step_func(function(e) {
if (e.data == "executed")
t.done();
});
window.addEventListener('securitypolicyviolation', t.unreached_func("Should not have raised a violation event"));
document.getElementById('special_div').click();
</script>
</body>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<head>
<meta http-equiv="content-security-policy" content="script-src 'self' 'nonce-abc'">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<iframe src="support/frame-with-csp.sub.html"></iframe>
<div onclick="frames[0].location.href = 'javascript:parent.postMessage(\'executed\', \'*\')'" id="special_div"></div>
<script nonce='abc'>
var t = async_test("Should not have executed the javascript url");
window.onmessage = t.step_func(function(e) {
if (e.data == "executed")
assert_true(false, "Javascript url executed");
});
window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
assert_equals(e.blockedURI, 'inline');
assert_equals(e.violatedDirective, 'script-src-attr');
}));
document.getElementById('special_div').click();
</script>
</body>

View file

@ -0,0 +1,75 @@
<!doctype html>
<meta charset="utf-8">
<title>Test for the page-break-* legacy shorthands.</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://drafts.csswg.org/css-cascade-4/#legacy-shorthand">
<link rel="help" href="https://drafts.csswg.org/css-break/#page-break-properties">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div></div>
<script>
const NEW_VALUES = ["page", "column"].filter(v => CSS.supports("break-before", v));
const LEGACY_VALUES = ["always", "auto", "left", "right", "avoid"];
const LEGACY_MAPPING = { "always": "page" };
const REVERSE_LEGACY_MAPPING = { "page": "always" };
const div = document.querySelector("div");
const cs = getComputedStyle(div);
test(function() {
for (const property of ["break-before", "break-after"]) {
for (const val of LEGACY_VALUES) {
const mapped_value = LEGACY_MAPPING[val] || val;
div.style["page-" + property] = val;
assert_equals(div.style["page-" + property], val);
assert_equals(div.style[property], mapped_value);
assert_equals(cs.getPropertyValue("page-" + property), val);
assert_equals(cs.getPropertyValue(property), mapped_value);
assert_not_equals(div.style.cssText.indexOf(property + ": " + mapped_value + ";"), -1);
assert_equals(div.style.cssText.indexOf("page-" + property), -1,
"Legacy shorthands don't appear in cssText");
}
}
}, "Legacy values of the shorthands work as expected")
test(function() {
for (const property of ["break-before", "break-after"]) {
for (const val of NEW_VALUES) {
const mapped_value = REVERSE_LEGACY_MAPPING[val] || "";
div.style[property] = val;
assert_equals(div.style[property], val);
assert_equals(div.style["page-" + property], mapped_value);
assert_equals(cs.getPropertyValue("page-" + property), mapped_value);
assert_equals(cs.getPropertyValue(property), val);
}
}
}, "New values work on the new longhands, but serialize to the empty string in the legacy shorthands");
test(function() {
for (const property of ["break-before", "break-after"]) {
for (const val of NEW_VALUES) {
div.style["page-" + property] = "";
div.style["page-" + property] = val;
assert_equals(div.style["page-" + property], "");
assert_equals(div.style[property], "");
assert_equals(cs.getPropertyValue("page-" + property), "auto");
assert_equals(cs.getPropertyValue(property), "auto");
}
}
}, "New values of the break longhands don't work on legacy shorthands");
// See https://github.com/w3c/csswg-drafts/issues/3332
test(function() {
for (const property of ["break-before", "break-after"]) {
div.style["page-" + property] = "var(--a)";
assert_equals(div.style["page-" + property], "var(--a)");
assert_equals(div.style[property], "");
assert_equals(div.style.cssText.indexOf("page-" + property), -1);
}
}, "Legacy shorthands really never appear on cssText, even when there are variable references");
</script>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test Reference: column-span:all should act like column-span:none in different block formatting context</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
#column {
column-count: 3;
column-rule: 6px solid;
width: 600px;
outline: 1px solid black;
}
h3 {
column-span: none;
outline: 1px solid blue;
}
</style>
<body onload="runTest();">
<article id="column">
<div>block1</div>
<div style="display: inline-block;">
<h3>non-spanner</h3>
</div>
<div style="overflow: hidden;">
<h3>non-spanner</h3>
</div>
<div style="column-span: all; outline: 1px solid green;">
Spanner
<h3>non-spanner in a spanner</h3>
</div>
<div>block2</div>
</article>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test: column-span:all should act like column-span:none in different block formatting context</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
<link rel="match" href="multicol-span-all-004-ref.html">
<meta name="assert" content="This test checks a column-span:all element should act like column-span: none if it's under different block formatting context.">
<style>
#column {
column-count: 3;
column-rule: 6px solid;
width: 600px;
outline: 1px solid black;
}
h3 {
column-span: all;
outline: 1px solid blue;
}
</style>
<body onload="runTest();">
<article id="column">
<div>block1</div>
<div style="display: inline-block;">
<h3>non-spanner</h3>
</div>
<div style="overflow: hidden;">
<h3>non-spanner</h3>
</div>
<div style="column-span: all; outline: 1px solid green;">
Spanner
<h3>non-spanner in a spanner</h3>
</div>
<div>block2</div>
</article>
</body>
</html>

View file

@ -42,7 +42,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield inside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield inside region");
test1.step(function () {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeydown = test1.step_func(function (evt) {

View file

@ -43,7 +43,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield outside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield outside region");
test1.step( function() {
var testTarget = document.getElementById("outside-region");
testTarget.onkeydown = test1.step_func(function (evt) {

View file

@ -44,7 +44,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeypress event fired in textfield inside region", {timeout: testTimeout});
var test1 = async_test("onkeypress event fired in textfield inside region");
test1.step( function() {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeypress = test1.step_func(function (evt) {
@ -59,7 +59,7 @@
keyDown("textfield-inside");
});
var test2 = async_test("onkeypress event fired in textfield outside region", {timeout: testTimeout});
var test2 = async_test("onkeypress event fired in textfield outside region");
test2.step( function() {
var testTarget = document.getElementById("outside-region");
testTarget.onkeypress = test2.step_func(function (evt) {

View file

@ -45,7 +45,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield inside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield inside region");
test1.step(function () {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeydown = test1.step_func(function (evt) {
@ -59,7 +59,7 @@
});
});
var test2 = async_test("onkeyup event fired in textfield inside region", {timeout: testTimeout});
var test2 = async_test("onkeyup event fired in textfield inside region");
test2.step(function () {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeyup = test2.step_func(function (evt) {
@ -74,7 +74,7 @@
keyDown("textfield-inside");
});
var test3 = async_test("onkeydown event fired in textfield outside region", {timeout: testTimeout});
var test3 = async_test("onkeydown event fired in textfield outside region");
test3.step( function() {
var testTarget = document.getElementById("outside-region");
testTarget.onkeydown = test3.step_func(function (evt) {
@ -88,7 +88,7 @@
});
});
var test4 = async_test("onkeyup event fired in textfield outside region", {timeout: testTimeout});
var test4 = async_test("onkeyup event fired in textfield outside region");
test4.step( function() {
var testTarget = document.getElementById("outside-region");
testTarget.onkeyup = test4.step_func(function (evt) {

View file

@ -47,7 +47,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield outside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield outside region");
test1.step( function() {
var testTarget = document.getElementById("textfield-outside");
testTarget.onkeydown = test1.step_func(function (evt) {
@ -66,7 +66,7 @@
});
});
var test2 = async_test("onkeyup event fired in textarea outside region", {timeout: testTimeout});
var test2 = async_test("onkeyup event fired in textarea outside region");
test2.step(function () {
var testTarget = document.getElementById("textarea-outside");
testTarget.onkeyup = test2.step_func(function (evt) {
@ -80,7 +80,7 @@
});
});
var test3 = async_test("onkeydown event fired in textarea outside region", {timeout: testTimeout});
var test3 = async_test("onkeydown event fired in textarea outside region");
test3.step( function() {
var testTarget = document.getElementById("textarea-outside");
testTarget.onkeydown = test3.step_func( function(evt) {

View file

@ -49,7 +49,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield inside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield inside region");
test1.step(function () {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeydown = test1.step_func(function (evt) {
@ -63,7 +63,7 @@
});
});
var test2 = async_test("onkeyup event fired in textfield inside region", {timeout: testTimeout});
var test2 = async_test("onkeyup event fired in textfield inside region");
test2.step(function () {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeyup = test2.step_func(function (evt) {
@ -78,7 +78,7 @@
pressDeleteKey("textfield-inside");
});
var test3 = async_test("onkeydown event fired in textfield outside region", {timeout: testTimeout});
var test3 = async_test("onkeydown event fired in textfield outside region");
test3.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.onkeydown = test3.step_func(function (evt) {
@ -92,7 +92,7 @@
});
});
var test4 = async_test("onkeyup event fired in textfield outside region", {timeout: testTimeout});
var test4 = async_test("onkeyup event fired in textfield outside region");
test4.step( function() {
var testTarget = document.getElementById("outside-region");
testTarget.onkeyup = test4.step_func(function (evt) {

View file

@ -47,7 +47,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield1 inside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield1 inside region");
test1.step(function () {
var testTarget = document.getElementById("textfield-inside1");
testTarget.onkeydown = test1.step_func(function (evt) {
@ -66,7 +66,7 @@
});
});
var test2 = async_test("onkeyup event fired in textfield2 inside region", {timeout: testTimeout});
var test2 = async_test("onkeyup event fired in textfield2 inside region");
test2.step(function () {
var testTarget = document.getElementById("textfield-inside2");
testTarget.onkeyup = test2.step_func(function (evt) {
@ -77,7 +77,7 @@
});
});
var test3 = async_test("onkeydown event fired in textfield2 inside region", {timeout: testTimeout});
var test3 = async_test("onkeydown event fired in textfield2 inside region");
test3.step( function() {
var testTarget = document.getElementById("textfield-inside2");
testTarget.onkeydown = test3.step_func(function (evt) {
@ -96,7 +96,7 @@
});
});
var test4 = async_test("onkeyup event fired in textarea inside region", {timeout: testTimeout});
var test4 = async_test("onkeyup event fired in textarea inside region");
test4.step( function() {
var testTarget = document.getElementById("textarea-inside");
testTarget.onkeyup = test4.step_func(function (evt) {
@ -110,7 +110,7 @@
});
});
var test5 = async_test("onkeydown event fired in textarea inside region", {timeout: testTimeout});
var test5 = async_test("onkeydown event fired in textarea inside region");
test5.step( function() {
var testTarget = document.getElementById("textarea-inside");
testTarget.onkeydown = test5.step_func(function (evt) {

View file

@ -44,7 +44,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield inside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield inside region");
test1.step(function () {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeydown = test1.step_func(function (evt) {
@ -63,7 +63,7 @@
});
});
var test2 = async_test("onkeydown event fired in textfield outside region", {timeout: testTimeout});
var test2 = async_test("onkeydown event fired in textfield outside region");
test2.step(function () {
var testTarget = document.getElementById("textfield-outside");
testTarget.onkeydown = test2.step_func(function (evt) {
@ -77,7 +77,7 @@
});
});
var test3 = async_test("onkeyup event fired in textfield outside region", {timeout: testTimeout});
var test3 = async_test("onkeyup event fired in textfield outside region");
test3.step(function () {
var testTarget = document.getElementById("textfield-outside");
testTarget.onkeyup = test3.step_func(function (evt) {

View file

@ -44,7 +44,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield outside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield outside region");
test1.step(function () {
var testTarget = document.getElementById("textfield-outside");
testTarget.onkeydown = test1.step_func(function (evt) {
@ -63,7 +63,7 @@
});
});
var test2 = async_test("onkeyup event fired in textfield outside region", {timeout: testTimeout});
var test2 = async_test("onkeyup event fired in textfield outside region");
test2.step(function () {
var testTarget = document.getElementById("textfield-outside");
testTarget.onkeyup = test2.step_func(function (evt) {
@ -75,7 +75,7 @@
});
});
var test3 = async_test("onkeydown event fired in textarea outside region", {timeout: testTimeout});
var test3 = async_test("onkeydown event fired in textarea outside region");
test3.step(function () {
var testTarget = document.getElementById("textarea-outside");
testTarget.onkeydown = test3.step_func(function (evt) {
@ -89,7 +89,7 @@
});
});
var test4 = async_test("onkeyup event fired in textarea outside region", {timeout: testTimeout});
var test4 = async_test("onkeyup event fired in textarea outside region");
test4.step( function() {
var testTarget = document.getElementById("textarea-outside");
testTarget.onkeyup = test4.step_func(function (evt) {

View file

@ -44,7 +44,7 @@
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onkeydown event fired in textfield inside region", {timeout: testTimeout});
var test1 = async_test("onkeydown event fired in textfield inside region");
test1.step(function () {
var testTarget = document.getElementById("textfield-inside");
testTarget.onkeydown = test1.step_func(function (evt) {
@ -63,7 +63,7 @@
});
});
var test2 = async_test("onkeyup event fired in textarea inside region", {timeout: testTimeout});
var test2 = async_test("onkeyup event fired in textarea inside region");
test2.step(function () {
var testTarget = document.getElementById("textarea-inside");
testTarget.onkeyup = test2.step_func(function (evt) {
@ -77,7 +77,7 @@
});
});
var test3 = async_test("onkeydown event fired in textarea inside region", {timeout: testTimeout});
var test3 = async_test("onkeydown event fired in textarea inside region");
test3.step( function() {
var testTarget = document.getElementById("textarea-inside");
testTarget.onkeydown = test3.step_func(function (evt) {

View file

@ -31,7 +31,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onclick event fired inside region", {timeout: testTimeout});
var test1 = async_test("onclick event fired inside region");
test1.step(function () {
var testTarget = document.getElementById("target-block");
testTarget.onclick = test1.step_func(function (evt) {
@ -46,7 +46,7 @@
mouseClick("target-block");
});
var test2 = async_test("onclick event fired outside region", {timeout: testTimeout});
var test2 = async_test("onclick event fired outside region");
test2.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.onclick = test2.step_func(function (evt) {

View file

@ -30,7 +30,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onmousedown event fired inside region", {timeout: testTimeout});
var test1 = async_test("onmousedown event fired inside region");
test1.step(function () {
var testTarget = document.getElementById("target-block");
testTarget.onmousedown = test1.step_func(function (evt) {

View file

@ -31,7 +31,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onmousedown event fired outside region", {timeout: testTimeout});
var test1 = async_test("onmousedown event fired outside region");
test1.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.onmousedown = test1.step_func(function (evt) {

View file

@ -30,7 +30,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onmouseup event fired inside region", {timeout: testTimeout});
var test1 = async_test("onmouseup event fired inside region");
test1.step(function () {
var testTarget = document.getElementById("target-block");
testTarget.onmouseup = test1.step_func(function (evt) {

View file

@ -31,7 +31,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onmouseup event fired outside region", {timeout: testTimeout});
var test1 = async_test("onmouseup event fired outside region");
test1.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.onmouseup = test1.step_func(function (evt) {

View file

@ -31,7 +31,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("ondblclick event fired inside region", {timeout: testTimeout});
var test1 = async_test("ondblclick event fired inside region");
test1.step(function () {
var testTarget = document.getElementById("target-block");
testTarget.ondblclick = test1.step_func(function (evt) {
@ -46,7 +46,7 @@
mouseDblClick("target-block");
});
var test2 = async_test("ondblclick event fired outside region", {timeout: testTimeout});
var test2 = async_test("ondblclick event fired outside region");
test2.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.ondblclick = test2.step_func( function(evt) {

View file

@ -31,7 +31,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onmousemove event fired inside region", {timeout: testTimeout});
var test1 = async_test("onmousemove event fired inside region");
test1.step(function () {
var testTarget = document.getElementById("target-block");
testTarget.onmousemove = test1.step_func(function (evt) {
@ -46,7 +46,7 @@
mouseMove("target-block");
});
var test2 = async_test("onmousemove event fired outside region", {timeout: testTimeout});
var test2 = async_test("onmousemove event fired outside region");
test2.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.onmousemove = test2.step_func(function (evt) {

View file

@ -31,7 +31,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onmouseover event fired inside region", {timeout: testTimeout});
var test1 = async_test("onmouseover event fired inside region");
test1.step(function () {
var testTarget = document.getElementById("target-block");
testTarget.onmouseover = test1.step_func(function (evt) {
@ -46,7 +46,7 @@
mouseOver("target-block");
});
var test2 = async_test("onmouseout event fired inside region", {timeout: testTimeout});
var test2 = async_test("onmouseout event fired inside region");
test2.step(function () {
var testTarget = document.getElementById("target-block");
testTarget.onmouseout = test2.step_func(function (evt) {

View file

@ -31,7 +31,7 @@
<script type="text/javascript">
if(getLeftPosition("target-block") !== 0) {
var test1 = async_test("onmouseover event fired outside region", {timeout: testTimeout});
var test1 = async_test("onmouseover event fired outside region");
test1.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.onmouseover = test1.step_func(function (evt) {
@ -46,7 +46,7 @@
mouseOver("outside-region");
});
var test2 = async_test("onmouseout event fired outside region", {timeout: testTimeout});
var test2 = async_test("onmouseout event fired outside region");
test2.step(function () {
var testTarget = document.getElementById("outside-region");
testTarget.onmouseout = test2.step_func(function (evt) {

View file

@ -21,7 +21,7 @@ function runSelectionTest(inSelectionTests, useMouse)
if( isRegionsEnabled() )
{
var selectionTest = async_test("Text was selected", {timeout: testTimeout});
var selectionTest = async_test("Text was selected");
selectionTest.step( function()
{
var endSelect = document.getElementById("end-select");

View file

@ -0,0 +1,179 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Ruby Reference: ruby content w. layout-internal 'display' values</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<style>
html,body {
color:black; background-color:white; font:14px/1 monospace; padding:0; margin:0;
}
input {
width: 20px;
-webkit-appearance: none;
border: 1px solid black;
background: white;
}
.thg { display: table-header-group; }
.trg { display: table-row-group; }
.tfg { display: table-footer-group; }
.tr { display: table-row; }
.tc { display: table-cell; }
.tcg { display: table-column-group; }
.tco { display: table-column; }
.tca { display: table-caption; }
.t { display: table; }
.rb { display: ruby-base; }
.rt { display: ruby-text; }
.rbc { display: ruby-base-container; }
.rtc { display: ruby-text-container; }
.x { background: red}
</style>
</head>
<body>
<ruby><rb><span>a<span><input class="thg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="thg"><input class="thg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="thg">b</div><input class="thg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="thg">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="trg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="trg"><input class="trg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="trg">b</div><input class="trg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="trg">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="tfg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="tfg"><input class="tfg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tfg">b</div><input class="tfg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tfg">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="tr"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="tr"><input class="tr"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tr">b</div><input class="tr"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tr">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="tc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="tc"><input class="tc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tc">b</div><input class="tc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tc">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="tcg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="tcg"><input class="tcg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tcg">b</div><input class="tcg"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tcg">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="tco"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="tco"><input class="tco"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tco">b</div><input class="tco"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tco">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="tca"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="tca"><input class="tca"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tca">b</div><input class="tca"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="tca">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="t"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="t"><input class="t"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="t">b</div><input class="t"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="t">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="rb"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="rb"><input class="rb"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rb">b</div><input class="rb"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rb">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="rt"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="rt"><input class="rt"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rt">b</div><input class="rt"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rt">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="rbc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="rbc"><input class="rbc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rbc">b</div><input class="rbc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rbc">b</div></span>c</span></rb></ruby>
<ruby><rb><span>a<span><input class="rtc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><input class="rtc"><input class="rtc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rtc">b</div><input class="rtc"></span>b</span></rb></ruby>
<ruby><rb><span>a<span><div class="rtc">b</div></span>c</span></rb></ruby>
<br><hr>
<!-- -->
<ruby><rb><span><input class="thg"></span>b</rb></ruby>
<ruby><rb><span><input class="thg"><input class="thg"></span>b</rb></ruby>
<ruby><rb><span><div class="thg">b</div><input class="thg"></span>b</rb></ruby>
<ruby><rb><span><div class="thg">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="trg"></span>b</rb></ruby>
<ruby><rb><span><input class="trg"><input class="trg"></span>b</rb></ruby>
<ruby><rb><span><div class="trg">b</div><input class="trg"></span>b</rb></ruby>
<ruby><rb><span><div class="trg">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="tfg"></span>b</rb></ruby>
<ruby><rb><span><input class="tfg"><input class="tfg"></span>b</rb></ruby>
<ruby><rb><span><div class="tfg">b</div><input class="tfg"></span>b</rb></ruby>
<ruby><rb><span><div class="tfg">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="tr"></span>b</rb></ruby>
<ruby><rb><span><input class="tr"><input class="tr"></span>b</rb></ruby>
<ruby><rb><span><div class="tr">b</div><input class="tr"></span>b</rb></ruby>
<ruby><rb><span><div class="tr">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="tc"></span>b</rb></ruby>
<ruby><rb><span><input class="tc"><input class="tc"></span>b</rb></ruby>
<ruby><rb><span><div class="tc">b</div><input class="tc"></span>b</rb></ruby>
<ruby><rb><span><div class="tc">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="tcg"></span>b</rb></ruby>
<ruby><rb><span><input class="tcg"><input class="tcg"></span>b</rb></ruby>
<ruby><rb><span><div class="tcg">b</div><input class="tcg"></span>b</rb></ruby>
<ruby><rb><span><div class="tcg">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="tco"></span>b</rb></ruby>
<ruby><rb><span><input class="tco"><input class="tco"></span>b</rb></ruby>
<ruby><rb><span><div class="tco">b</div><input class="tco"></span>b</rb></ruby>
<ruby><rb><span><div class="tco">b</div></span>c</rb></ruby>
<!-- bug NNNNNN
<ruby><rb><span><input class="tca"></span>b</rb></ruby>
<ruby><rb><span><input class="tca"><input class="tca"></span>b</rb></ruby>
<ruby><rb><span><div class="tca">b</div><input class="tca"></span>b</rb></ruby>
<ruby><rb><span><div class="tca">b</div></span>c</rb></ruby>
-->
<ruby><rb><span><input class="t"></span>b</rb></ruby>
<ruby><rb><span><input class="t"><input class="t"></span>b</rb></ruby>
<ruby><rb><span><div class="t">b</div><input class="t"></span>b</rb></ruby>
<ruby><rb><span><div class="t">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="rb"></span>b</rb></ruby>
<ruby><rb><span><input class="rb"><input class="rb"></span>b</rb></ruby>
<ruby><rb><span><div class="rb">b</div><input class="rb"></span>b</rb></ruby>
<ruby><rb><span><div class="rb">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="rt"></span>b</rb></ruby>
<ruby><rb><span><input class="rt"><input class="rt"></span>b</rb></ruby>
<ruby><rb><span><div class="rt">b</div><input class="rt"></span>b</rb></ruby>
<ruby><rb><span><div class="rt">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="rbc"></span>b</rb></ruby>
<ruby><rb><span><input class="rbc"><input class="rbc"></span>b</rb></ruby>
<ruby><rb><span><div class="rbc">b</div><input class="rbc"></span>b</rb></ruby>
<ruby><rb><span><div class="rbc">b</div></span>c</rb></ruby>
<ruby><rb><span><input class="rtc"></span>b</rb></ruby>
<ruby><rb><span><input class="rtc"><input class="rtc"></span>b</rb></ruby>
<ruby><rb><span><div class="rtc">b</div><input class="rtc"></span>b</rb></ruby>
<ruby><rb><span><div class="rtc">b</div></span>c</rb></ruby>
</body>
</html>

View file

@ -0,0 +1,181 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Ruby Test: ruby content w. layout-internal 'display' values</title>
<link rel="help" href="https://drafts.csswg.org/css-ruby-1/#box-fixup">
<link rel="help" href="https://drafts.csswg.org/css-display-3/#inlinify">
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<link rel="match" href="ruby-layout-internal-boxes-ref.html">
<style>
html,body {
color:black; background-color:white; font:14px/1 monospace; padding:0; margin:0;
}
input {
width: 20px;
-webkit-appearance: none;
border: 1px solid black;
background: white;
}
.thg { display: table-header-group; }
.trg { display: table-row-group; }
.tfg { display: table-footer-group; }
.tr { display: table-row; }
.tc { display: table-cell; }
.tcg { display: table-column-group; }
.tco { display: table-column; }
.tca { display: table-caption; }
.t { display: table; }
.rb { display: ruby-base; }
.rt { display: ruby-text; }
.rbc { display: ruby-base-container; }
.rtc { display: ruby-text-container; }
</style>
</head>
<body>
<ruby><rb><span>a<input class="thg">b</span></rb></ruby>
<ruby><rb><span>a<input class="thg"><input class="thg">b</span></rb></ruby>
<ruby><rb><span>a<div class="thg">b</div><input class="thg">b</span></rb></ruby>
<ruby><rb><span>a<div class="thg">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="trg">b</span></rb></ruby>
<ruby><rb><span>a<input class="trg"><input class="trg">b</span></rb></ruby>
<ruby><rb><span>a<div class="trg">b</div><input class="trg">b</span></rb></ruby>
<ruby><rb><span>a<div class="trg">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="tfg">b</span></rb></ruby>
<ruby><rb><span>a<input class="tfg"><input class="tfg">b</span></rb></ruby>
<ruby><rb><span>a<div class="tfg">b</div><input class="tfg">b</span></rb></ruby>
<ruby><rb><span>a<div class="tfg">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="tr">b</span></rb></ruby>
<ruby><rb><span>a<input class="tr"><input class="tr">b</span></rb></ruby>
<ruby><rb><span>a<div class="tr">b</div><input class="tr">b</span></rb></ruby>
<ruby><rb><span>a<div class="tr">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="tc">b</span></rb></ruby>
<ruby><rb><span>a<input class="tc"><input class="tc">b</span></rb></ruby>
<ruby><rb><span>a<div class="tc">b</div><input class="tc">b</span></rb></ruby>
<ruby><rb><span>a<div class="tc">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="tcg">b</span></rb></ruby>
<ruby><rb><span>a<input class="tcg"><input class="tcg">b</span></rb></ruby>
<ruby><rb><span>a<div class="tcg">b</div><input class="tcg">b</span></rb></ruby>
<ruby><rb><span>a<div class="tcg">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="tco">b</span></rb></ruby>
<ruby><rb><span>a<input class="tco"><input class="tco">b</span></rb></ruby>
<ruby><rb><span>a<div class="tco">b</div><input class="tco">b</span></rb></ruby>
<ruby><rb><span>a<div class="tco">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="tca">b</span></rb></ruby>
<ruby><rb><span>a<input class="tca"><input class="tca">b</span></rb></ruby>
<ruby><rb><span>a<div class="tca">b</div><input class="tca">b</span></rb></ruby>
<ruby><rb><span>a<div class="tca">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="t">b</span></rb></ruby>
<ruby><rb><span>a<input class="t"><input class="t">b</span></rb></ruby>
<ruby><rb><span>a<div class="t">b</div><input class="t">b</span></rb></ruby>
<ruby><rb><span>a<div class="t">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="rb">b</span></rb></ruby>
<ruby><rb><span>a<input class="rb"><input class="rb">b</span></rb></ruby>
<ruby><rb><span>a<div class="rb">b</div><input class="rb">b</span></rb></ruby>
<ruby><rb><span>a<div class="rb">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="rt">b</span></rb></ruby>
<ruby><rb><span>a<input class="rt"><input class="rt">b</span></rb></ruby>
<ruby><rb><span>a<div class="rt">b</div><input class="rt">b</span></rb></ruby>
<ruby><rb><span>a<div class="rt">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="rbc">b</span></rb></ruby>
<ruby><rb><span>a<input class="rbc"><input class="rbc">b</span></rb></ruby>
<ruby><rb><span>a<div class="rbc">b</div><input class="rbc">b</span></rb></ruby>
<ruby><rb><span>a<div class="rbc">b</div>c</span></rb></ruby>
<ruby><rb><span>a<input class="rtc">b</span></rb></ruby>
<ruby><rb><span>a<input class="rtc"><input class="rtc">b</span></rb></ruby>
<ruby><rb><span>a<div class="rtc">b</div><input class="rtc">b</span></rb></ruby>
<ruby><rb><span>a<div class="rtc">b</div>c</span></rb></ruby>
<br><hr>
<!-- same as above but without the SPAN wrapper -->
<ruby><rb><input class="thg">b</rb></ruby>
<ruby><rb><input class="thg"><input class="thg">b</rb></ruby>
<ruby><rb><div class="thg">b</div><input class="thg">b</rb></ruby>
<ruby><rb><div class="thg">b</div>c</rb></ruby>
<ruby><rb><input class="trg">b</rb></ruby>
<ruby><rb><input class="trg"><input class="trg">b</rb></ruby>
<ruby><rb><div class="trg">b</div><input class="trg">b</rb></ruby>
<ruby><rb><div class="trg">b</div>c</rb></ruby>
<ruby><rb><input class="tfg">b</rb></ruby>
<ruby><rb><input class="tfg"><input class="tfg">b</rb></ruby>
<ruby><rb><div class="tfg">b</div><input class="tfg">b</rb></ruby>
<ruby><rb><div class="tfg">b</div>c</rb></ruby>
<ruby><rb><input class="tr">b</rb></ruby>
<ruby><rb><input class="tr"><input class="tr">b</rb></ruby>
<ruby><rb><div class="tr">b</div><input class="tr">b</rb></ruby>
<ruby><rb><div class="tr">b</div>c</rb></ruby>
<ruby><rb><input class="tc">b</rb></ruby>
<ruby><rb><input class="tc"><input class="tc">b</rb></ruby>
<ruby><rb><div class="tc">b</div><input class="tc">b</rb></ruby>
<ruby><rb><div class="tc">b</div>c</rb></ruby>
<ruby><rb><input class="tcg">b</rb></ruby>
<ruby><rb><input class="tcg"><input class="tcg">b</rb></ruby>
<ruby><rb><div class="tcg">b</div><input class="tcg">b</rb></ruby>
<ruby><rb><div class="tcg">b</div>c</rb></ruby>
<ruby><rb><input class="tco">b</rb></ruby>
<ruby><rb><input class="tco"><input class="tco">b</rb></ruby>
<ruby><rb><div class="tco">b</div><input class="tco">b</rb></ruby>
<ruby><rb><div class="tco">b</div>c</rb></ruby>
<!-- FIXME after https://bugzilla.mozilla.org/show_bug.cgi?id=1510299
<ruby><rb><input class="tca">b</rb></ruby>
<ruby><rb><input class="tca"><input class="tca">b</rb></ruby>
<ruby><rb><div class="tca">b</div><input class="tca">b</rb></ruby>
<ruby><rb><div class="tca">b</div>c</rb></ruby>
-->
<ruby><rb><input class="t">b</rb></ruby>
<ruby><rb><input class="t"><input class="t">b</rb></ruby>
<ruby><rb><div class="t">b</div><input class="t">b</rb></ruby>
<ruby><rb><div class="t">b</div>c</rb></ruby>
<ruby><rb><input class="rb">b</rb></ruby>
<ruby><rb><input class="rb"><input class="rb">b</rb></ruby>
<ruby><rb><div class="rb">b</div><input class="rb">b</rb></ruby>
<ruby><rb><div class="rb">b</div>c</rb></ruby>
<ruby><rb><input class="rt">b</rb></ruby>
<ruby><rb><input class="rt"><input class="rt">b</rb></ruby>
<ruby><rb><div class="rt">b</div><input class="rt">b</rb></ruby>
<ruby><rb><div class="rt">b</div>c</rb></ruby>
<ruby><rb><input class="rbc">b</rb></ruby>
<ruby><rb><input class="rbc"><input class="rbc">b</rb></ruby>
<ruby><rb><div class="rbc">b</div><input class="rbc">b</rb></ruby>
<ruby><rb><div class="rbc">b</div>c</rb></ruby>
<ruby><rb><input class="rtc">b</rb></ruby>
<ruby><rb><input class="rtc"><input class="rtc">b</rb></ruby>
<ruby><rb><div class="rtc">b</div><input class="rtc">b</rb></ruby>
<ruby><rb><div class="rtc">b</div>c</rb></ruby>
</body>
</html>

View file

@ -20,15 +20,15 @@
<custom-element id="c-e-1"></custom-element>
The following text should be green:
<custom-element id="c-e-2"></custom-element>
<script type="text/javascript">
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e-1", "part"]);
const el = getElementByShadowIds(document, ["c-e-1", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "::part with host selector styles in first host");
test(function() {
var el = getElementByShadowIds(document, ["c-e-2", "part"]);
const el = getElementByShadowIds(document, ["c-e-2", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "::part with host selector styles in second host");
</script>

View file

@ -26,11 +26,11 @@
<custom-element-inner id="c-e-inner" part="c-e-part"></custom-element-inner>
</template>
<custom-element-outer id="c-e-outer"></custom-element-outer>
<script type="text/javascript">
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]);
const el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "::part cannot be chained to reach elements in the inner host");
test(function() {

View file

@ -18,11 +18,11 @@
</template>
The following text should be green:
<div><custom-element id="c-e"></custom-element></div>
<script type="text/javascript">
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e", "part"]);
const el = getElementByShadowIds(document, ["c-e", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Complex selector for host works");
</script>

View file

@ -18,11 +18,11 @@
</template>
The following text should be green:
<pre><custom-element id="c-e"></custom-element></pre>
<script type="text/javascript">
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e", "part"]);
const el = getElementByShadowIds(document, ["c-e", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Non-matching complex selector for host does not style");
</script>

View file

@ -18,11 +18,11 @@
</template>
The following text should be green:
<custom-element id="c-e"></custom-element>
<script type="text/javascript">
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e", "part"]);
const el = getElementByShadowIds(document, ["c-e", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Part is not styled when host is not selected");
</script>

View file

@ -20,11 +20,11 @@
</template>
The following text should be green:
<custom-element id="c-e"></custom-element>
<script type="text/javascript">
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e", "part"]);
const el = getElementByShadowIds(document, ["c-e", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Part in selected host is not styled by ::part in a stylesheet inside the host");
</script>

View file

@ -25,16 +25,16 @@
</template>
The following text should be green:
<custom-element-outer id="c-e-outer"></custom-element-outer>
<script type="text/javascript">
<script>
"use strict";
const colorBlue = "rgb(0, 0, 255)";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e-outer", "green_part"]);
const el = getElementByShadowIds(document, ["c-e-outer", "green_part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Part in outer host is styled by document style sheet");
test(function() {
var el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "blue_part"]);
const el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "blue_part"]);
assert_equals(window.getComputedStyle(el).color, colorBlue);
}, "Part in inner host is not styled by document style sheet");
</script>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>CSS Shadow Parts - Invalidation Change Part Name IDL DOMTokenList</title>
<meta href="mailto:fergal@chromium.org" rel="author" title="Fergal Daly">
<link href="http://www.google.com/" rel="author" title="Google">
<link href="https://drafts.csswg.org/css-shadow-parts/" rel="help">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/shadow-helper.js"></script>
</head>
<body>
<style>#c-e::part(partp) { color: red; }</style>
<style>#c-e::part(new-partp) { color: green; }</style>
<script>installCustomElement("custom-element", "custom-element-template");</script>
<template id="custom-element-template">
<style>span { color: blue; }</style>
<span id="part" part="partp">This text</span>
</template>
The following text should be green:
<div><custom-element id="c-e"></custom-element></div>
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
const el = getElementByShadowIds(document, ["c-e", "part"]);
el.part.remove("partp");
el.part.add("new-partp");
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Part in selected host changed color via part IDL DOMTokenList attribute.");
</script>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>CSS Shadow Parts - Invalidation Change Part Name IDL Setter</title>
<meta href="mailto:fergal@chromium.org" rel="author" title="Fergal Daly">
<link href="http://www.google.com/" rel="author" title="Google">
<link href="https://drafts.csswg.org/css-shadow-parts/" rel="help">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/shadow-helper.js"></script>
</head>
<body>
<style>#c-e::part(partp) { color: red; }</style>
<script>installCustomElement("custom-element", "custom-element-template");</script>
<template id="custom-element-template">
<style>span { color: green; }</style>
<span id="part" part="partp">This text</span>
</template>
The following text should be green:
<div><custom-element id="c-e"></custom-element></div>
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
const el = getElementByShadowIds(document, ["c-e", "part"]);
el.part = "new-partp"
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Part in selected host changed color via part IDL attribute setter.");
</script>
</body>
</html>

View file

@ -18,13 +18,13 @@
</template>
The following text should be green:
<div><custom-element id="c-e"></custom-element></div>
<script type="text/javascript">
<script>
"use strict";
test(function() {
var part = getElementByShadowIds(document, ["c-e", "part"]);
var before = window.getComputedStyle(part).color;
const part = getElementByShadowIds(document, ["c-e", "part"]);
const before = window.getComputedStyle(part).color;
part.setAttribute("part", "new-partp");
var after = window.getComputedStyle(part).color;
const after = window.getComputedStyle(part).color;
assert_not_equals(before, after);
}, "Part in selected host changed color");
</script>

View file

@ -18,13 +18,13 @@
</template>
The following text should be green:
<div id="elem"><custom-element id="c-e"></custom-element></div>
<script type="text/javascript">
<script>
"use strict";
test(function() {
var part = getElementByShadowIds(document, ["c-e", "part"]);
var before = window.getComputedStyle(part).color;
const part = getElementByShadowIds(document, ["c-e", "part"]);
const before = window.getComputedStyle(part).color;
document.getElementById("elem").setAttribute("id", "new-elem");
var after = window.getComputedStyle(part).color;
const after = window.getComputedStyle(part).color;
assert_not_equals(before, after);
}, "Part in selected host changed color");
</script>

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<title>CSS Shadow Parts - Part Name IDL</title>
<meta href="mailto:fergal@chromium.org" rel="author" title="Fergal Daly">
<link href="http://www.google.com/" rel="author" title="Google">
<link href="https://drafts.csswg.org/css-shadow-parts/" rel="help">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/shadow-helper.js"></script>
</head>
<body>
<span id="s_no_part"></span>
<span id="s_part" part="part1"></span>
<span id="s_2_parts" part="part1 part2"></span>
<script>
"use strict";
test(function() {
const parts = s_no_part.part;
assert_equals(parts.length, 0);
assert_equals(parts.value, "");
}, "Access to .part returns an empty DOMTokenList.");
test(function() {
const parts = s_2_parts.part;
assert_equals(parts.length, 2);
assert_equals(parts[0], "part1");
assert_equals(parts[1], "part2");
assert_equals(parts.value, "part1 part2");
}, "Multiple names give a DOMTokenList with multiple entries.");
test(function() {
const parts = s_no_part.part;
assert_equals(parts.length, 0);
assert_equals(parts.value, "");
parts.add("part1");
assert_equals(parts.length, 1);
assert_equals(parts.value, "part1");
}, "DOMTokenList created by access is persisted.");
test(function() {
const parts = s_part.part;
assert_equals(parts.length, 1);
assert_equals(parts.value, "part1");
parts.add("part2");
assert_equals(parts.length, 2);
assert_equals(parts.value, "part1 part2");
assert_equals(s_part.getAttribute("part"), parts.value);
parts.remove("part1");
assert_equals(parts.length, 1);
assert_equals(parts.value, "part2");
assert_equals(s_part.getAttribute("part"), parts.value);
}, "Changes in DOMTokenList are refected in attribute.");
</script>
</body>
</html>

View file

@ -18,11 +18,11 @@
</template>
The following text should be green:
<custom-element id="c-e"></custom-element>
<script type="text/javascript">
<script>
"use strict";
const colorGreen = "rgb(0, 128, 0)";
test(function() {
var el = getElementByShadowIds(document, ["c-e", "part"]);
const el = getElementByShadowIds(document, ["c-e", "part"]);
assert_equals(window.getComputedStyle(el).color, colorGreen);
}, "Part in selected host is styled");
</script>

View file

@ -2,7 +2,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: white-space-collapsing - discard - basic cases Reftest Reference</title>
<title>CSS Test: text-space-collapse - discard - basic cases Reftest Reference</title>
<link rel="author" title="Satoshi Umehara" href="mailto:umehara@est.co.jp" />
<style type="text/css">
<![CDATA[

View file

@ -2,7 +2,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: white-space-collapsing - preserve-breaks - basic cases Reftest Reference</title>
<title>CSS Test: text-space-collapse - preserve-breaks - basic cases Reftest Reference</title>
<link rel="author" title="Satoshi Umehara" href="mailto:umehara@est.co.jp" />
<style type="text/css">
<![CDATA[

View file

@ -2,7 +2,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: white-space-collapsing - trim-inner - basic cases Reftest Reference</title>
<title>CSS Test: text-space-trim - trim-inner - basic cases Reftest Reference</title>
<link rel="author" title="Satoshi Umehara" href="mailto:umehara@est.co.jp" />
<style type="text/css">
<![CDATA[
@ -17,20 +17,20 @@
Test passes if each text positions in the first line match the corresponding positions in the second line.
</p>
<div>
<span>1 2</span>
<span>  3  4  </span>
<span>5 6</span>
<span>7
[<span>1 2</span>]
[<span>  3  4  </span>]
[<span>5 6</span>]
[<span>7
8</span>
8</span>]
</div>
<div>
<span>1 2</span>
<span>  3  4  </span>
<span>5 6</span>
<span>7
[<span>1 2</span>]
[<span>  3  4  </span>]
[<span>5 6</span>]
[<span>7
8</span>
8</span>]
</div>
</body>
</html>

View file

@ -2,16 +2,16 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: white-space-collapsing - discard - basic cases</title>
<title>CSS Test: text-space-collapse - discard - basic cases</title>
<link rel="author" title="Satoshi Umehara" href="mailto:umehara@est.co.jp" />
<link rel="help" title="CSS Text Level 3: 4.1. White Space Collapsing: the white-space-collapsing property" href="http://www.w3.org/TR/css-text-3/#white-space-collapsing" />
<link rel="match" href="reference/white-space-collapsing-discard-001-ref.xht"/>
<link rel="help" title="CSS Text Level 4: 3.1. White Space Collapsing: the text-space-collapse property" href="https://drafts.csswg.org/css-text-4/#white-space-collapsing" />
<link rel="match" href="reference/text-space-collapse-discard-001-ref.xht"/>
<meta name="flags" content="" />
<meta name="assert" content="The UA should discard all white space in the element when white-space-collapsing is set to discard." />
<meta name="assert" content="The UA should discard all white space in the element when text-space-collapse is set to discard." />
<style type="text/css">
<![CDATA[
.test span {
white-space-collapsing: discard;
text-space-collapse: discard;
}
/* the CSS below is not part of the test */
span {

View file

@ -2,16 +2,16 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: white-space-collapsing - preserve-breaks - basic cases</title>
<title>CSS Test: text-space-collapse - preserve-breaks - basic cases</title>
<link rel="author" title="Satoshi Umehara" href="mailto:umehara@est.co.jp" />
<link rel="help" title="CSS Text Level 3: 4.1. White Space Collapsing: the white-space-collapsing property" href="http://www.w3.org/TR/css-text-3/#white-space-collapsing" />
<link rel="match" href="reference/white-space-collapsing-preserve-breaks-001-ref.xht"/>
<link rel="help" title="CSS Text Level 4: 3.1. White Space Collapsing: the text-space-collapse property" href="https://drafts.csswg.org/css-text-4/#white-space-collapsing" />
<link rel="match" href="reference/text-space-collapse-preserve-breaks-001-ref.xht"/>
<meta name="flags" content="" />
<meta name="assert" content="The UA should collapse sequences of white space into a single character when white-space-collapsing is set to preserve." />
<meta name="assert" content="The UA should collapse sequences of white space into a single character but preserve segment breaks as forced line breaks when text-space-collapse is set to preserve-breaks." />
<style type="text/css">
<![CDATA[
.test span {
white-space-collapsing: preserve-breaks;
text-space-collapse: preserve-breaks;
}
/* the CSS below is not part of the test */
span {

View file

@ -2,16 +2,16 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: white-space-collapsing - trim-inner - basic cases</title>
<title>CSS Test: text-space-trim - trim-inner - basic cases</title>
<link rel="author" title="Satoshi Umehara" href="mailto:umehara@est.co.jp" />
<link rel="help" title="CSS Text Level 3: 4.1. White Space Collapsing: the white-space-collapsing property" href="http://www.w3.org/TR/css-text-3/#white-space-collapsing" />
<link rel="match" href="reference/white-space-collapsing-trim-inner-001-ref.xht"/>
<link rel="help" title="CSS Text Level 4: 3.2. White Space Trimming: the text-space-trim property" href="https://drafts.csswg.org/css-text-4/#white-space-trim" />
<link rel="match" href="reference/text-space-trim-trim-inner-001-ref.xht"/>
<meta name="flags" content="" />
<meta name="assert" content="The UA should discard all white space at the beginning of a block and all white space at the end of a block when white-space-collapsing is set to trim-inner." />
<meta name="assert" content="The UA should discard all white space at the beginning of a block and all white space at the end of a block when text-space-trim is set to trim-inner." />
<style type="text/css">
<![CDATA[
.test span {
white-space-collapsing: trim-inner;
text-space-trim: trim-inner;
}
/* the CSS below is not part of the test */
div {
@ -26,24 +26,24 @@
</p>
<div>
<div class="test">
<span> 1 2 </span>
<span>  3  4  </span>
<span> 5 6 </span>
<span>
[<span> 1 2 </span>]
[<span>  3  4  </span>]
[<span> 5 6 </span>]
[<span>
7
8
</span>
</span>]
</div>
<div>
<span>1 2</span>
<span>  3  4  </span>
<span>5 6</span>
<span>7
[<span>1 2</span>]
[<span>  3  4  </span>]
[<span>5 6</span>]
[<span>7
8</span>
8</span>]
</div>
</div>
</body>

View file

@ -75,8 +75,6 @@
testsPerSlice: 1,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -76,8 +76,6 @@
testsPerSlice: 1,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -86,8 +86,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -69,8 +69,6 @@
testsPerSlice: 1,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -65,8 +65,6 @@
testsPerSlice: 1,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -67,8 +67,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -70,8 +70,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -71,8 +71,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -70,8 +70,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
var styles = {

View file

@ -70,8 +70,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
// as we're dealing with em-based lengths, we need to define a font-size

View file

@ -70,8 +70,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
// clone and overwrite initial styles to be

View file

@ -71,8 +71,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
// clone and overwrite initial styles to be

View file

@ -71,8 +71,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
// have parent transition the font-size only

View file

@ -93,8 +93,6 @@
testsPerSlice: 50,
// milliseconds to wait before calling teardown and ending test
duration: parseFloat(duration) * 1000,
// the global suite timeout
timeout: timeout,
// prepare individual test
setup: function(data, options) {
generalParallelTest.setup(data, options);

View file

@ -81,7 +81,7 @@ root.runParallelAsyncHarness = function(options) {
options.tests.forEach(function(data, index) {
data.cases = {};
cases.forEach(function(name) {
data.cases[name] = async_test(data.name + " / " + name, {timeout: options.timeout || 60000});
data.cases[name] = async_test(data.name + " / " + name);
});
});

View file

@ -0,0 +1,83 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>Reference: text-overflow:ellipsis and ruby</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<style>
html,body {
color:black; background-color:white; font:14px/1 monospace; padding:0; margin:0;
}
.clip {
overflow: hidden;
width: 40px;
text-overflow: ellipsis;
}
input { width: 40px; -webkit-appearance: none; border: 1px solid black; }
span { white-space: pre; }
.thg { display: inline-table; }
.tc { display: inline-table; }
.t { display: inline-table; }
</style>
</head>
<body>
<div style="float:left; width:300px">
<div class="clip">
<span><span><span>aa<input class="thg">bb</span></span></span>
<br>
<span><span><span>aa<div class="thg">bbbbbb</div>cc</span></span></span>
<br>
<span><span><span>aa<span>bbbbbb</span>cc</span></span></span>
<br>
<span><span><span>aa<input class="tc">bb</span></span></span>
<br>
<span><span><span>aa<div class="tc">bbbbbb</div>cc</span></span></span>
<br>
<span><span><span>aa<input class="t">bb</span></span></span>
<br>
<span><span><span>aa<div class="t">bbbbbb</div>cc</span></span></span>
<br>
<span><span><span><input class="thg">bb</span></span></span>
<br>
<span><span><span><div class="thg">bbbbbb</div>cc</span></span></span>
<br>
<span><span><span><span>bbbbbb</span>cc</span></span></span>
<br>
<span><span><span><input class="tc">bb</span></span></span>
<br>
<span><span><span><div class="tc">bbbbbb</div>cc</span></span></span>
<br>
<span><span><span><input class="t">bb</span></span></span>
<br>
<span><span><span><div class="t">bbbbbb</div>cc</span></span></span>
</div>
</div>
<div style="float:left; width:300px">
<div class="clip">
<span><span><input class="thg">bb</span></span>
<br>
<span><span><div class="thg">bbbbbb</div>cc</span></span>
<br>
<span><span>bbbbbbcc</span></span>
<br>
<span><span><input class="tc">bb</span></span>
<br>
<span><span><div class="tc">bbbbbb</div>cc</span></span>
<br>
<span><span><input class="t">bb</span></span>
<br>
<span><span><div class="t">bbbbbb</div>cc</span></span>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,85 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Basic User Interface Test: text-overflow:ellipsis and ruby</title>
<link rel="help" href="http://www.w3.org/TR/css3-ui/#text-overflow">
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<link rel="match" href="text-overflow-ruby-ref.html">
<style>
html,body {
color:black; background-color:white; font:14px/1 monospace; padding:0; margin:0;
}
.clip {
overflow: hidden;
width: 40px;
text-overflow: ellipsis;
}
input { width: 40px; -webkit-appearance: none; border: 1px solid black; }
.thg { display: table-header-group; }
.tc { display: table-cell; }
.t { display: table; }
</style>
</head>
<body>
<div style="float:left; width:300px">
<div class="clip">
<ruby><rb><span>aa<input class="thg">bb</span></rb></ruby>
<br>
<ruby><rb><span>aa<div class="thg">bbbbbb</div>cc</span></rb></ruby>
<br>
<ruby><rb><span>aa<span>bbbbbb</span>cc</span></rb></ruby>
<br>
<ruby><rb><span>aa<input class="tc">bb</span></rb></ruby>
<br>
<ruby><rb><span>aa<div class="tc">bbbbbb</div>cc</span></rb></ruby>
<br>
<ruby><rb><span>aa<input class="t">bb</span></rb></ruby>
<br>
<ruby><rb><span>aa<div class="t">bbbbbb</div>cc</span></rb></ruby>
<br>
<ruby><rb><span><input class="thg">bb</span></rb></ruby>
<br>
<ruby><rb><span><div class="thg">bbbbbb</div>cc</span></rb></ruby>
<br>
<ruby><rb><span><span>bbbbbb</span>cc</span></rb></ruby>
<br>
<ruby><rb><span><input class="tc">bb</span></rb></ruby>
<br>
<ruby><rb><span><div class="tc">bbbbbb</div>cc</span></rb></ruby>
<br>
<ruby><rb><span><input class="t">bb</span></rb></ruby>
<br>
<ruby><rb><span><div class="t">bbbbbb</div>cc</span></rb></ruby>
</div>
</div>
<div style="float:left; width:300px">
<div class="clip">
<ruby><rb><input class="thg">bb</rb></ruby>
<br>
<ruby><rb><div class="thg">bbbbbb</div>cc</rb></ruby>
<br>
<ruby><rb>bbbbbbcc</rb></ruby>
<br>
<ruby><rb><input class="tc">bb</rb></ruby>
<br>
<ruby><rb><div class="tc">bbbbbb</div>cc</rb></ruby>
<br>
<ruby><rb><input class="t">bb</rb></ruby>
<br>
<ruby><rb><div class="t">bbbbbb</div>cc</rb></ruby>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!doctype html>
<title>CSS Variables Test: Exponential blowup doesn't crash</title>
<meta charset="UTF-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="author" href="https://mozilla.org" title="Mozilla">
<link rel="help" href="https://drafts.csswg.org/css-variables/">
<script>
let css = `
--v0: "Something really really really long";
`;
for (let i = 0; i < 30; ++i)
css += `--v${i + 1}: var(--v${i}), var(--v${i});`;
let s = document.createElement("style");
s.innerHTML = `
:root { ${css}; }
:root::before { content: var(--v31); }
`;
document.head.appendChild(s);
</script>
PASS if doesn't crash
<script>
test(function() {
getComputedStyle(document.documentElement, "::before").content;
assert_true(true, "Didn't crash");
});
</script>

View file

@ -6,12 +6,11 @@
<div>
<p>Expected: A green box and an overlapping black box, with a magenta<br>
overlapping region.</p>
<p>Expected: Just a single green box.</p>
</div>
<div class="colorbox"></div>
<div class="box2outside"></div>
<div class="box2inside"></div>
<style>
.colorbox {
@ -22,21 +21,5 @@
left: 10px;
top: 100px;
}
.box2outside {
background: black;
position: absolute;
width: 100px;
height: 100px;
left: 60px;
top: 150px;
}
.box2inside {
background: #ff7fff;
position: absolute;
width: 50px;
height: 50px;
left: 60px;
top: 150px;
}
</style>

View file

@ -6,8 +6,7 @@
<link rel="match" href="backdrop-filter-basic-opacity-ref.html">
<div>
<p>Expected: A green box and an overlapping black box, with a magenta<br>
overlapping region.</p>
<p>Expected: Just a single green box.</p>
</div>
<div class="colorbox">
<div class="filterbox"></div>
@ -29,7 +28,7 @@
left: 50px;
top: 50px;
backdrop-filter: invert(1);
opacity: 0.5;
opacity: 0;
}
</style>

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>backdrop-filter: Should not filter outside of clip/scroll.</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<div style="width:600px;">
<p>Expected: A green box, overlapping red box, and a small, inset cyan box. The<br>
cyan should not extend to the bottom/right edges of the red box.</p>
</div>
<div id="A">
<div id="B">
<div id="F"></div>
<div id="T"></div>
</div>
</div>
<style>
div {
position:absolute;
width: 200px;
height: 200px;
}
#A {
overflow:hidden;
top: 110px;
left: 10px;
}
#B {
background:green;
}
#F {
position:fixed;
background:#f008;
top:150px;
left:50px;
}
#T {
background:#c0e3ff;
top:90px;
left:90px;
width: 110px;
height: 110px;
}
</style>

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>backdrop-filter: Should not filter outside of clip/scroll.</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
<link rel="match" href="backdrop-filter-fixed-clip-ref.html">
<div style="width:600px;">
<p>Expected: A green box, overlapping red box, and a small, inset cyan box. The<br>
cyan should not extend to the bottom/right edges of the red box.</p>
</div>
<div id="A">
<div id="B">
<div id="F"></div>
<div id="T"></div>
</div>
</div>
<style>
div {
position:absolute;
width: 200px;
height: 200px;
}
#A {
overflow:hidden;
top: 110px;
left: 10px;
}
#B {
opacity: 0.99999;
background:green;
}
#F {
position:fixed;
background:#f008;
top:150px;
left:50px;
}
#T {
background:#fff8;
top:90px;
left:90px;
backdrop-filter:invert(1);
}
</style>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>backdrop-filter: Should not filter outside parent stacking context.</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
<link rel="match" href="backdrop-filter-isolation-ref.html">
<div class="outside">
<div class="stacking-context">
<div class="filter">
</div>
</div>
</div>
<style>
div {
position: absolute;
width: 100px;
height: 100px;
background: green;
}
.outside {
top: 10px;
left: 10px;
}
.stacking-context {
position: fixed;
top: 10px;
left: 130px;
}
.filter {
width: 160px;
height: 160px;
top: 30px;
left: -90px;
opacity: 0.3;
backdrop-filter: invert(1);
background: yellow;
}
</style>

View file

@ -37,6 +37,12 @@
checkDOMMatrix(matrix, initialMatrix());
},"test scale() doesn't mutate");
test(function() {
var matrix = initialMatrix();
matrix.scaleNonUniform(1,5);
checkDOMMatrix(matrix, initialMatrix());
},"test scaleNonUniform() doesn't mutate");
test(function() {
var matrix = initialMatrix();
matrix.scale3d(3,2,1,1);

View file

@ -139,6 +139,27 @@
checkDOMMatrix(result, expected);
},"test scale() with offsets");
test(function() {
var result = initialDOMMatrix().scaleNonUniform();
var expected = initialDOMMatrix()
.scale(1, 1, 1, 0, 0, 0);
checkDOMMatrix(result, expected);
},"test scaleNonUniform()");
test(function() {
var result = initialDOMMatrix().scaleNonUniform(6);
var expected = initialDOMMatrix()
.scale(6, 1, 1, 0, 0, 0);
checkDOMMatrix(result, expected);
},"test scaleNonUniform() with sx");
test(function() {
var result = initialDOMMatrix().scaleNonUniform(5, 7);
var expected = initialDOMMatrix()
.scale(5, 7, 1, 0, 0, 0);
checkDOMMatrix(result, expected);
},"test scaleNonUniform() with sx, sy");
test(function() {
var result = initialDOMMatrix().scale3d(7, 5, 2, 3);
var expected = initialDOMMatrix()

View file

@ -7,7 +7,6 @@
// Removed members
[
// https://github.com/w3c/fxtf-drafts/commit/99e3212469026b2f2f50926a41912d110a1741b7
['DOMMatrixReadOnly', 'scaleNonUniform'],
['DOMMatrix', 'scaleNonUniformSelf'],
// https://github.com/w3c/fxtf-drafts/commit/86da3dc961d442f9d8dc7ab59065a9804e109286
['DOMMatrix', 'multiplyBy'],

View file

@ -0,0 +1,143 @@
<!DOCTYPE html>
<html>
<head>
<title>Custom Elements: create an element for a token must perform a microtask checkpoint</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="When the HTML parser creates an element for a token, it must perform a microtask checkpoint before invoking the constructor">
<meta name="help" content="https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token">
<meta name="help" content="https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint">
<meta name="help" content="https://html.spec.whatwg.org/multipage/parsing.html#adoption-agency-algorithm">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/custom-elements-helpers.js"></script>
</head>
<body>
<div id="log"></div>
<script>
async function construct_custom_element_in_parser(test, markup)
{
const window = await create_window_in_test(test, `
<!DOCTYPE html>
<html>
<body><script>
class SomeElement extends HTMLElement {
constructor() {
super();
window.recordsListInConstructor = recordsList.map((records) => records.slice(0));
}
}
customElements.define('some-element', SomeElement);
const recordsList = [];
const observer = new MutationObserver((records) => {
recordsList.push(records);
});
observer.observe(document.body, {childList: true, subtree: true});
window.onload = () => {
window.recordsListInDOMContentLoaded = recordsList.map((records) => records.slice(0));
}
</scr` + `ipt>${markup}</body></html>`);
return window;
}
promise_test(async function () {
const contentWindow = await construct_custom_element_in_parser(this, '<b><some-element></b>');
const contentDocument = contentWindow.document;
let recordsList = contentWindow.recordsListInConstructor;
assert_true(Array.isArray(recordsList));
assert_equals(recordsList.length, 1);
assert_true(Array.isArray(recordsList[0]));
assert_equals(recordsList[0].length, 1);
let record = recordsList[0][0];
assert_equals(record.type, 'childList');
assert_equals(record.target, contentDocument.body);
assert_equals(record.previousSibling, contentDocument.querySelector('script'));
assert_equals(record.nextSibling, null);
assert_equals(record.removedNodes.length, 0);
assert_equals(record.addedNodes.length, 1);
assert_equals(record.addedNodes[0], contentDocument.querySelector('b'));
recordsList = contentWindow.recordsListInDOMContentLoaded;
assert_true(Array.isArray(recordsList));
assert_equals(recordsList.length, 2);
assert_true(Array.isArray(recordsList[1]));
assert_equals(recordsList[1].length, 1);
record = recordsList[1][0];
assert_equals(record.type, 'childList');
assert_equals(record.target, contentDocument.querySelector('b'));
assert_equals(record.previousSibling, null);
assert_equals(record.nextSibling, null);
assert_equals(record.removedNodes.length, 0);
assert_equals(record.addedNodes.length, 1);
assert_equals(record.addedNodes[0], contentDocument.querySelector('some-element'));
}, 'HTML parser must perform a microtask checkpoint before constructing a custom element');
promise_test(async function () {
const contentWindow = await construct_custom_element_in_parser(this, '<b><i>hello</b><some-element>');
const contentDocument = contentWindow.document;
let recordsList = contentWindow.recordsListInConstructor;
assert_true(Array.isArray(recordsList));
assert_equals(recordsList.length, 1);
assert_true(Array.isArray(recordsList[0]));
assert_equals(recordsList[0].length, 4);
let record = recordsList[0][0];
assert_equals(record.type, 'childList');
assert_equals(record.target, contentDocument.body);
assert_equals(record.previousSibling, contentDocument.querySelector('script'));
assert_equals(record.nextSibling, null);
assert_equals(record.removedNodes.length, 0);
assert_equals(record.addedNodes.length, 1);
assert_equals(record.addedNodes[0], contentDocument.querySelector('b'));
record = recordsList[0][1];
assert_equals(record.type, 'childList');
assert_equals(record.target, contentDocument.querySelector('b'));
assert_equals(record.previousSibling, null);
assert_equals(record.nextSibling, null);
assert_equals(record.removedNodes.length, 0);
assert_equals(record.addedNodes.length, 1);
assert_equals(record.addedNodes[0], contentDocument.querySelector('i'));
record = recordsList[0][2];
assert_equals(record.type, 'childList');
assert_equals(record.target, contentDocument.querySelector('i'));
assert_equals(record.previousSibling, null);
assert_equals(record.nextSibling, null);
assert_equals(record.removedNodes.length, 0);
assert_equals(record.addedNodes.length, 1);
assert_equals(record.addedNodes[0].nodeType, Node.TEXT_NODE);
assert_equals(record.addedNodes[0].data, "hello");
record = recordsList[0][3];
assert_equals(record.type, 'childList');
assert_equals(record.target, contentDocument.body);
assert_equals(record.previousSibling, contentDocument.querySelector('b'));
assert_equals(record.nextSibling, null);
assert_equals(record.removedNodes.length, 0);
assert_equals(record.addedNodes.length, 1);
assert_equals(record.addedNodes[0], contentDocument.querySelectorAll('i')[1]);
recordsList = contentWindow.recordsListInDOMContentLoaded;
assert_true(Array.isArray(recordsList));
assert_equals(recordsList.length, 2);
assert_true(Array.isArray(recordsList[1]));
assert_equals(recordsList[1].length, 1);
record = recordsList[1][0];
assert_equals(record.type, 'childList');
assert_equals(record.target, contentDocument.querySelectorAll('i')[1]);
assert_equals(record.previousSibling, null);
assert_equals(record.nextSibling, null);
assert_equals(record.removedNodes.length, 0);
assert_equals(record.addedNodes.length, 1);
assert_equals(record.addedNodes[0], contentDocument.querySelector('some-element'));
}, 'HTML parser must perform a microtask checkpoint before constructing a custom element during the adoption agency algorithm');
</script>
</body>
</html>

View file

@ -8,7 +8,7 @@
<meta name="help" content="https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/custom-elements-helpers.js"></script>
<script src="./resources/custom-elements-helpers.js"></script>
</head>
<body>
<div id="log"></div>

View file

@ -8,7 +8,7 @@
<meta name="help" content="https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/custom-elements-helpers.js"></script>
<script src="./resources/custom-elements-helpers.js"></script>
</head>
<body>
<div id="log"></div>

View file

@ -26,6 +26,41 @@ This function causes a sequence of actions to be sent to the browser. It is base
The action can be a keyboard action, a pointer action or a pause. It returns a `Promise` that
resolves after the actions have been sent or rejects if an error was thrown.
Test authors are encouraged to use the builder API to generate the sequence of actions. The builder
API can be accessed via the `new test_driver.Actions()` object.
Example:
```js
let text_box = document.getElementById("text");
let actions = new test_driver.Actions()
.pointerMove(0, 0, {origin: text_box})
.pointerDown()
.pointerUp()
.addTick()
.keyDown("p")
.keyUp("p");
actions.send();
```
Calling into `send()` is going to dispatch the action sequence (via `test_driver.action_sequence`) and also returns a `Promise` which should be handled however is appropriate in the test. The other functions in the `Actions()` object are going to modify the state of the object by adding a new action in the sequence and return the same object. So the functions can be easily chained as shown in the example above. Here is a list of helper functions in the `Actions` class:
```
pointerDown: Create a pointerDown event for the current default pointer source
pointerUp: Create a pointerUp event for the current default pointer source
pointerMove: Create a move event for the current default pointer source
keyDown: Create a keyDown event for the current default key source
keyUp: Create a keyUp event for the current default key source
pause: Add a pause to the current tick
addTick: Insert a new actions tick
setPointer: Set the current default pointer source (By detault the pointerType is mouse)
addPointer: Add a new pointer input source with the given name
setKeyboard: Set the current default key source
addKeyboard: Add a new key input source with the given name
```
### bless
Usage: `test_driver.bless(intent, action)`

View file

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8 />
<title>Event Timing: buffer long-latency events before onload</title>
<button id='button' onclick='clickDelay()'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<img src=resources/slow-image.py>
<script>
let clickTimeMin;
let processingStartMin;
let onloadStart;
let firstClickStart = 0;
let firstClickEnd = 0;
function clickDelay() {
const onclickStart = performance.now();
if (firstClickStart === 0)
firstClickStart = onclickStart;
while(performance.now() < onclickStart + 60) {}
if (firstClickEnd === 0)
firstClickEnd = performance.now();
}
function validateEntries() {
const entries = performance.getEntriesByName('click', 'event');
const entriesBeforeOnload = entries.filter(
e => e.startTime < onloadStart);
assert_equals(entriesBeforeOnload.length, 1,
"Long latency events before onload should be buffered.");
const entry = entriesBeforeOnload[0];
verifyClickEvent(entry, true);
assert_greater_than_equal(entry.startTime, clickTimeMin,
"The entry's start time should be later than clickTimeMin.");
assert_greater_than_equal(entry.processingStart, processingStartMin,
"The entry should be processed later than processingStartMin.");
assert_less_than_equal(entry.processingStart, firstClickStart,
"The processingStart must be before firstClickStart.")
assert_greater_than_equal(entry.processingEnd, firstClickEnd,
"The processingEnd must be after firstClickEnd.");
const entriesAfterOnload = entries.filter(
e => e.startTime >= onloadStart);
assert_equals(entriesAfterOnload.length, 0,
"Events after onload shouldn't be buffered.");
}
/* Timeline:
Begin Busy Loop
Click 1 arrives
End Busy Loop
(Dispatch and Process Click 1 - buffered)
Onload Event Fires
Begin Busy Loop
Click 2 arrives
End Busy Loop
(Dispatch and Process Click 2 - not buffered)
*/
async_test(function(t) {
clickTimeMin = performance.now();
clickAndBlockMain('button');
// Event handlers will be dispatched asynchronously, so this will be called
// before processing begins.
processingStartMin = performance.now();
on_event(window, 'load', e => {
onloadStart = performance.now();
clickAndBlockMain('button').then(wait).then(
t.step_func_done(validateEntries));
});
}, "Event Timing: click, onload.");
</script>
</html>

View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Event Timing: entries should be observable by its own frame.</title>
</head>
<body>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<img src=./resources/slow-image.py>
<iframe src=resources/event-timing-crossiframe-childframe.html></iframe>
<script>
let clickTimeMin;
let processingStartMin;
let onloadStart;
function validateEntries() {
const entries = performance.getEntriesByName('click', 'event');
assert_equals(entries.length, 1,
"Observer of main frames should only capture main-frame event-timing entries."
);
const entry = entries[0];
verifyClickEvent(entry, true);
assert_greater_than(entry.processingStart, processingStartMin,
"The entry's processing start should be later than processingStartMin.");
assert_greater_than(onloadStart, entry.processingStart,
"onload should occur later than the entry's procesisng start.");
assert_greater_than(entry.startTime, clickTimeMin,
"The entry's start time should be later than clickTimeMin.");
assert_greater_than(onloadStart, entry.startTime,
"onload should occur later than the entry's start time.");
}
function validateChildFrameEntries(childFrameData) {
assert_equals(childFrameData.bufferedEntries.length, 1,
"Event Timing of child frames should only capture child-frame event-timing entries."
);
const entry = entries[0];
verifyClickEvent(entry);
assert_greater_than(entry.processingStart, childFrameData.processingStartMin,
"The entry's processing start should be later than the child frame's processingStartMin.");
assert_greater_than(childFrameData.onloadStart, entry.processingStart,
"Child frame's onload should occur later than the entry's processing \
start.");
assert_greater_than(entry.startTime, childFrameData.clickTimeMin,
"The entry's start time should be later than the child frame's \
clickTimeMin.");
assert_greater_than(childFrameData.onloadStart, entry.startTime,
"Child frame's onload should be later than the entry's start time.");
assert_array_equals(childFrameData.observedEntries,
childFrameData.bufferedEntries,
"The child frame's observed entries should be buffered as well.");
}
async_test(function(t) {
clickTimeMin = performance.now();
clickAndBlockMain('button');
processingStartMin = performance.now();
const childFrameEntriesPromise = new Promise((resolve, reject) => {
window.addEventListener("message", (event) => {
resolve(event.data);
}, false);
});
on_event(window, 'load', e => {
onloadStart = performance.now();
childFrameEntriesPromise.then((entries) => {
t.step(() => {
validateChildFrameEntries(entries);
validateEntries();
});
t.done();
});
});
}, "Event Timing: entries should only be observable by its own frame.");
</script>
</body>
</html>

View file

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Event Timing: entries should be observable by its own frame.
</title>
<script src=./resources/event-timing-support.js></script>
</head>
<body>
<h2>Description:</h2>
<p>
<div>
The goal of this manual test is to verify that observers that have
registered "event" entry type can observe the long-latency input events,
and verify the same behavior within iframe and in cross-frame scenario.
</div>
</p>
<h2>Manual test steps:</h2>
<p>
<div>
Step 1: Click the "make busy" button to make main-thread busy for 2 seconds.</span>
</div>
<div>
Step 2: do several clicks on "click while busy" while busy to generate long-latency inputs.
</div>
<div>
Step 3: observe in the "timeline" section that the long-latency clicks are captured by the observer.
</div>
<div>
Step 4: do step 1 to step 3 for the iframe. Observe that the observers only observe input events within its frame.
</div>
</p>
<div>
<h2>Actions:</h2>
<button id='busy_button' onclick='onMakeBusy()'>make busy</button>
<button id='click_input_button' onclick='1'> click while busy </button>
</div>
<h2>iframe:</h2>
<div>
<iframe name='childframe' width="100%" height="30%" src=./resources/event-timing-observer-manual-childframe.html></iframe>
</div>
<h2>Timeline:</h2>
<p id='timeline'></p>
</body>
<script>
function log(message) {
const timestamp = performance.now();
const elem = document.createElement('div');
elem.innerHTML = `${timestamp.toFixed(1)}: ${message}`;
const timeline = document.getElementById('timeline');
timeline.appendChild(elem);
}
function onMakeBusy() {
log("busy start");
step_timeout(()=>{
mainThreadBusy(2000);
log("busy end");
}, 0);
}
document.body.onload = () => {
new PerformanceObserver((entryList) => {
entryList.getEntries().forEach(e => {
log(`entry observed: ${JSON.stringify(e)}`);
});
}).observe({ entryTypes: ['event'] });
log("observer registered");
};
window.onmessage = (msg) => {
log("received msg: " + msg.data);
if (msg.data === 'CHILD_FRAME_IS_READY') {
// TODO(crbug/831729): automate clicks on iframe when testdriver support
// clicking in iframe.
}
};
</script>
</html>

View file

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8 />
<title>Event Timing: Performance observers can observe long-latency events
</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<img src=resources/slow-image.py>
<script>
let timeBeforeFirstClick;
let timeAfterFirstClick;
let timeAfterSecondClick;
let onloadStart;
let observedEntries = [];
function verifyBuffer(bufferedEntries) {
assert_equals(bufferedEntries.length, 1,
"Only events before onload should be buffered.");
const entry = bufferedEntries[0];
assert_greater_than(onloadStart, entry.startTime,
"Onload should be later than entry's start time.");
assert_greater_than(entry.processingStart, timeBeforeFirstClick,
"The entry's processing start should be after timeBeforeFirstClick");
assert_less_than(entry.processingStart, timeAfterFirstClick,
"The entry's processing start should be before timeAfterFirstClick.");
verifyClickEvent(entry, true);
}
function verifyObserverEntries(observedEntries) {
const entriesAfterFirstClick = observedEntries.filter(
e => e.startTime > timeAfterFirstClick);
assert_equals(entriesAfterFirstClick.length, 1,
'There should be one event after timeAfterFirstClick.');
const entry1 = entriesAfterFirstClick[0];
verifyClickEvent(entry1);
assert_greater_than(entry1.processingStart, timeAfterFirstClick,
"entry1's processing start should be after timeAfterFirstClick");
assert_less_than(entry1.processingStart, timeAfterSecondClick,
"entry1's processing start should be before timeAfterSecondClick.");
assert_greater_than(entry1.startTime, onloadStart,
"entry1's start time should be later than onloadStart.");
const entriesBeforeFirstClick =
observedEntries.filter(e => e.startTime < timeAfterFirstClick);
assert_equals(entriesBeforeFirstClick.length, 1,
'There should be one event before timeAfterFirstClick.'
);
const entry2 = entriesBeforeFirstClick[0];
verifyClickEvent(entry2);
assert_greater_than(entry2.processingStart, timeBeforeFirstClick,
"entry2's processing start should be after timeBeforeFirstClick");
assert_less_than(entry2.processingStart, timeAfterFirstClick,
"entry2's processing start should be berfore timeAfterFirstClick.");
assert_greater_than(timeAfterFirstClick, entry2.startTime,
"timeAfterFirstClick should be later than entry2's start time.");
}
/* Timeline:
Observer starts
Begin Busy Loop
Click 1 arrives
End Busy Loop
(Dispatch and Process Click 1 (buffered, observed))
Onload Event Fires
Begin Busy Loop
Click 2 arrives
End Busy Loop
(Dispatch and Process Click 2 (buffered, observed))
observer callback start
*/
async_test(function(t) {
const observerPromise = new Promise((resolve, reject) => {
new PerformanceObserver(function(entryList) {
observedEntries = observedEntries.concat(entryList.getEntries());
if (observedEntries.length < 2) return;
resolve(observedEntries);
}).observe({ entryTypes: ['event'] });
});
timeBeforeFirstClick = performance.now();
clickAndBlockMain('button').then( () => {
timeAfterFirstClick = performance.now();
});
on_event(window, 'load', function(e) {
onloadStart = performance.now();
// After onload start and before registering observer.
const bufferPromise = clickAndBlockMain('button').then(wait);
Promise.all([observerPromise, bufferPromise]).then((results) => {
timeAfterSecondClick = performance.now();
t.step(verifyObserverEntries.bind(null, results[0]));
t.step(verifyBuffer.bind(null, performance.getEntriesByName('click', 'event')));
t.done();
});
});
}, "Event Timing: click, observer, onload, click.");
</script>
</html>

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8 />
<title>Event Timing: buffer long-latency events before onload</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<script>
/* Timeline:
Onload
PerformanceObserver is registered
Click 1
Click 2
PerformanceObserver should observe only one firstInput entry.
(Dispatch and Process Click 2 - not buffered)
*/
async_test(function(t) {
let numFirstInputObserved = 0;
let numEventsObserved = 0;
new PerformanceObserver(t.step_func((entryList, obs) => {
const observedEntries = entryList.getEntries();
numEventsObserved += observedEntries.filter(entry =>
entry.entryType == 'event').length;
numFirstInputObserved += observedEntries.filter(entry =>
entry.entryType == 'firstInput').length;
if (numEventsObserved >= 2) {
assert_equals(performance.getEntriesByType('event').length, 0,
"There should be no buffered event entries.");
assert_equals(performance.getEntriesByType('firstInput').length, 0,
"There should be no buffered firstInput entries.");
// There should be 2 event entries and one firstInput entry.
assert_equals(numEventsObserved, 2,
"There should be 2 observed event entries.");
assert_equals(numFirstInputObserved, 1,
"There should be only 1 observed firstInput entry.");
t.done();
}
})).observe({ entryTypes: ['event', 'firstInput'] });
on_event(window, 'load', () => {
clickAndBlockMain('button').then(wait).then(() => {
clickAndBlockMain('button').then(wait);
});
});
},
"Event Timing: check firstInput after onload, observer, click, click."
);
</script>
</html>

View file

@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8 />
<title>Event Timing: long-latency events after onload and before observer
registration are lost
</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<script>
let callbackTime;
let observerStart;
let processingStartMin;
function verifyBufferAndObserverEntries(observedEntries) {
// Verify buffer entries
const bufferedEntries = performance.getEntriesByName('click', 'event');
const bufferedEntriesBeforeObserver = bufferedEntries.filter(e => e.startTime <
observerStart);
assert_equals(bufferedEntries.length, 0,
"Long latency events after onload should not be buffered."
);
// Verify observer entries
assert_equals(observedEntries.length, 1, "Long latency task after observer start should be observed.");
const entry = observedEntries[0];
verifyClickEvent(entry);
assert_greater_than(entry.processingStart, processingStartMin,
"The entry's processing start should be later than processingStartMin.");
assert_greater_than(callbackTime, entry.processingStart,
"The callback time should be later than the entry's processing start.");
assert_greater_than(entry.startTime, observerStart,
"The entry's start time should be later than observer start.");
assert_greater_than(callbackTime, entry.startTime,
"The callback time should be later than entry's start time.");
}
function startObserver(t) {
new PerformanceObserver(t.step_func_done((entryList, obs) => {
callbackTime = performance.now();
const observedEntries = entryList.getEntries();
verifyBufferAndObserverEntries(observedEntries);
})).observe({ entryTypes: ['event'] });
observerStart = performance.now();
}
/* Timeline:
Onload Event fires
Begin Busy Loop
Click 1 arrives
End Busy Loop
(Dispatch and Process Click 1 (not buffered, not observed))
Observer start
Begin Busy Loop
Click 2 arrives
End Busy Loop
(Dispatch and Process Click 2 (not buffered, observed))
*/
async_test(function(t) {
on_event(window, 'load', () => {
clickAndBlockMain('button').then(() => {
startObserver(t);
clickAndBlockMain('button').then(wait);
processingStartMin = performance.now();
});
});
},
"Event Timing: onload, click, observer, click."
);
</script>
</html>

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8 />
<title>Event Timing: only observe the first input</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<script>
/* Test:
PerformanceObserver for firstInput is registered
Click 1
Click 2
Wait
Expected result:
PerformanceObserver should observe one and only one entry.
*/
async_test(function(t) {
let hasObservedFirstInput = false;
new PerformanceObserver(t.step_func((entryList) => {
assert_false(hasObservedFirstInput);
hasObservedFirstInput = true;
const observedEntries = entryList.getEntries();
assert_equals(observedEntries.length, 1);
assert_equals(observedEntries[0].entryType, 'firstInput');
assert_equals(observedEntries[0].name, 'click');
})).observe({ entryTypes: ['firstInput'] });
on_event(window, 'load', () => {
clickAndBlockMain('button').then(() => {
clickAndBlockMain('button').then(wait).then( () => {
// After some wait, the PerformanceObserver should have processed both clicks.
// One and only one firstInput entry should have been dispatched, so
// |hasObservedFirstInput| should be true.
t.step_timeout( () => {
assert_true(hasObservedFirstInput);
t.done();
}, 10);
});
});
});
},
"Event Timing: check firstInput for a PerformanceObserver observing only firstInput."
);
</script>
</html>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8>
<title>Event Timing: make sure event-timing entries are retrievable by existing perf APIs.</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<img src=resources/slow-image.py>
<script>
function validateEntries() {
const entriesByName = performance.getEntriesByName('click', 'event');
const entriesByType = performance.getEntriesByType('event');
const allEntries = performance.getEntries();
assert_equals(entriesByName.length, 1, 'event-timing entry should be retrievable by getEntriesByName');
const e = entriesByName[0];
assert_true(entriesByType.includes(e), 'event-timing entry should be retrievable by getEntries');
assert_true(allEntries.includes(e), 'event-timing entry should be retrievable by getEntriesByType');
}
/* Timeline:
Begin Busy Loop
Click 1 arrives
End Busy Loop
(Dispatch and Process Click 1 - buffered)
Onload Event Fires
Validate entries
*/
async_test(function(t) {
clickAndBlockMain('button');
on_event(window, 'load', e => {
validateEntries();
t.done();
});
}, "Event Timing: make sure event-timing entries are retrievable by existing perf APIs.");
</script>
</html>

View file

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8 />
<title>Event Timing only times certain types of trusted event.
</title>
<button id='button' onclick='mainThreadBusy(60)'
onfocus='mainThreadBusy(60)'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=resources/event-timing-support.js></script>
<script>
let trustedClickStart;
function trustedClickAndBlockMain(id) {
return new Promise((resolve, reject) => {
trustedClickStart = performance.now();
clickOnElement(id, resolve);
});
}
function untrustedClickAndBlockMain(id) {
const target = document.getElementById(id);
// Block mainthread in the callback, as dispatchEvent() is a sync call.
target.dispatchEvent(new MouseEvent('click'));
}
function trustedFocusAndBlockMain(id) {
const target = document.getElementById(id);
trustedFocusStart = performance.now();
// Block mainthread in the callback, as focus() is a sync call.
target.focus();
}
async_test(function(t) {
new PerformanceObserver(t.step_func_done(entryList => {
const observerCallbackTime = performance.now();
const entries = entryList.getEntries();
assert_equals(entries.length, 1,
"Should only observe one entry: " +
JSON.stringify(entries) + ".");
assert_equals(entries[0].name, 'click',
"The observed entry should be a click");
assert_less_than(entries[0].startTime, observerCallbackTime,
"The startTime should be before observerCallbackTime");
assert_greater_than(entries[0].startTime, trustedClickStart,
"The startTime should be after trustedClickStart");
})).observe({ entryTypes: ['event'] });
// Untrusted event of a type event timing cares about.
untrustedClickAndBlockMain('button');
// Trusted event of a type event timing doesn't cares about.
trustedFocusAndBlockMain('button');
// Trusted event of a type event timing cares about.
trustedClickAndBlockMain('button').then(wait);
}, "Event Timing only times certain types of trusted event.");
</script>
</html>

View file

@ -0,0 +1,29 @@
<!DOCType html>
<html>
<script src=event-timing-support.js></script>
<button id='button_child_frame' onclick='2'>Generate a 'click' event</button>
<img src=slow-image.py>
<script>
const clickTimeMin = performance.now();
clickAndBlockMain('button_child_frame');
const processingStartMin = performance.now();
const observerPromise = new Promise((resolve, reject) => {
new PerformanceObserver((entryList) => {
resolve(entryList.getEntries());
}).observe({ entryTypes: ['event'] });
});
window.addEventListener('load', e => {
observerPromise.then((observedEntries) => {
const onloadStart = performance.now();
const bufferedEntries = performance.getEntriesByType('event');
top.postMessage({
"bufferedEntries" : bufferedEntries,
"observedEntries": observedEntries,
"clickTimeMin": clickTimeMin,
"processingStartMin" : processingStartMin,
"onloadStart" : onloadStart,
}, '*');
});
});
</script>
</html>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
</head>
<script src=./event-timing-support.js></script>
<script>
function log(message) {
const timestamp = performance.now();
const elem = document.createElement('div');
elem.innerHTML = `${timestamp.toFixed(1)}: ${message}`;
const timeline = document.getElementById('timeline');
timeline.appendChild(elem);
}
function run() {
new PerformanceObserver((entryList) => {
entryList.getEntries().forEach(e => {
log(`entry observed: ${JSON.stringify(e)}`);
});
}).observe({ entryTypes: ['event'] });
log("observer registered");
top.postMessage('CHILD_FRAME_IS_READY', "*");
}
function onMakeBusy() {
log("busy start");
step_timeout(()=>{
mainThreadBusy(2000);
log("busy end");
}, 0);
}
</script>
<body onload='run()'>
<h3>Actions:</h3>
<p>
<button id='busy_button' onclick='onMakeBusy()'>Make busy</button>
<button id='click_input_button' onclick='1'> click while busy </button>
</p>
<h3>Timeline:</h3>
<p id='timeline'></p>
</body>
</html>

View file

@ -0,0 +1,66 @@
// Clicks on the element with the given ID. It adds an event handler to the element
// which ensures that the events have a long duration and reported by EventTiming
// where appropriate. Calls |callback| during event handler.
function clickOnElement(id, callback) {
const element = document.getElementById(id);
const rect = element.getBoundingClientRect();
const xCenter = rect.x + rect.width / 2;
const yCenter = rect.y + rect.height / 2;
const leftButton = 0;
const clickHandler = () => {
mainThreadBusy(60);
if (callback)
callback();
element.removeEventListener("click", clickHandler);
};
element.addEventListener("click", clickHandler);
test_driver.click(element);
}
function mainThreadBusy(duration) {
const now = performance.now();
while (performance.now() < now + duration);
}
// This method should receive an entry of type 'event'. |is_first| is true only
// when the event also happens to correspond to the first event. In this case,
// the timings of the 'firstInput' entry should be equal to those of this entry.
function verifyClickEvent(entry, is_first=false) {
assert_true(entry.cancelable);
assert_equals(entry.name, 'click');
assert_equals(entry.entryType, 'event');
assert_greater_than(entry.duration, 50,
"The entry's duration should be greater than 50ms.");
assert_greater_than(entry.processingStart, entry.startTime,
"The entry's processingStart should be greater than startTime.");
assert_greater_than_equal(entry.processingEnd, entry.processingStart,
"The entry's processingEnd must be at least as large as processingStart.");
assert_greater_than_equal(entry.duration, entry.processingEnd - entry.startTime,
"The entry's duration must be at least as large as processingEnd - startTime.");
if (is_first) {
let firstInputs = performance.getEntriesByType('firstInput');
assert_equals(firstInputs.length, 1, 'There should be a single firstInput entry');
let firstInput = firstInputs[0];
assert_equals(firstInput.name, entry.name);
assert_equals(firstInput.entryType, 'firstInput');
assert_equals(firstInput.startTime, entry.startTime);
assert_equals(firstInput.duration, entry.duration);
assert_equals(firstInput.processingStart, entry.processingStart);
assert_equals(firstInput.processingEnd, entry.processingEnd);
assert_equals(firstInput.cancelable, entry.cancelable);
}
}
function wait() {
return new Promise((resolve, reject) => {
step_timeout(() => {
resolve();
}, 0);
});
}
function clickAndBlockMain(id) {
return new Promise((resolve, reject) => {
clickOnElement(id, resolve);
});
}

View file

@ -0,0 +1,7 @@
import time
def main(request, response):
# Sleep for 500ms to delay onload.
time.sleep(0.5)
response.headers.set("Cache-Control", "no-cache, must-revalidate");
response.headers.set("Location", "data:image/gif;base64,R0lGODlhAQABAJAAAMjIyAAAACwAAAAAAQABAAACAgQBADs%3D");

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<title>Fetch destination test for prefetching</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/media.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script>
let frame;
// Set up the service worker and the frame.
promise_test(t => {
const kScope = 'resources/empty.https.html';
const kScript = 'resources/fetch-destination-worker.js';
return service_worker_unregister_and_register(t, kScript, kScope)
.then(registration => {
add_completion_callback(() => {
registration.unregister();
});
return wait_for_state(t, registration.installing, 'activated');
})
.then(() => {
return with_iframe(kScope);
})
.then(f => {
frame = f;
add_completion_callback(() => { f.remove(); });
});
}, 'Initialize global state');
// HTMLLinkElement with rel=prefetch - empty string destination
promise_test(async t => {
await new Promise((resolve, reject) => {
let node = frame.contentWindow.document.createElement("link");
node.rel = "prefetch";
node.onload = resolve;
node.onerror = reject;
node.href = "dummy?dest=";
frame.contentWindow.document.body.appendChild(node);
}).catch(() => {
assert_unreached("Fetch errored.");
});
}, 'HTMLLinkElement with rel=prefetch fetches with an empty string Request.destination');
</script>

View file

@ -425,18 +425,4 @@ promise_test(async t => {
});
}, 'HTMLLinkElement with rel=preload and as=manifest fetches with a "manifest" Request.destination');
// HTMLLinkElement with rel=prefetch - empty string destination
promise_test(async t => {
await new Promise((resolve, reject) => {
let node = frame.contentWindow.document.createElement("link");
node.rel = "prefetch";
node.onload = resolve;
node.onerror = reject;
node.href = "dummy?dest=";
frame.contentWindow.document.body.appendChild(node);
}).catch(() => {
assert_unreached("Fetch errored.");
});
}, 'HTMLLinkElement with rel=prefetch fetches with an empty string Request.destination');
</script>

Some files were not shown because too many files have changed in this diff Show more