Update web-platform-tests to revision 2dda7b8c10c7566fa6167a32b09c85d51baf2a85
|
@ -8,8 +8,8 @@
|
|||
promise_test(async test => {
|
||||
// 6.3.1.9.2: If |registration|’s active worker is null, then reject promise
|
||||
// with a TypeError and abort these steps.
|
||||
const script = 'resources/sw.js';
|
||||
const scope = 'resources/scope' + location.pathname;
|
||||
const script = 'service_workers/sw.js';
|
||||
const scope = 'service_workers/' + location.pathname;
|
||||
|
||||
const serviceWorkerRegistration =
|
||||
await service_worker_unregister_and_register(test, script, scope);
|
||||
|
@ -21,7 +21,7 @@ promise_test(async test => {
|
|||
await promise_rejects(
|
||||
test, new TypeError(),
|
||||
serviceWorkerRegistration.backgroundFetch.fetch(
|
||||
uniqueId(), ['resources/sw.js']),
|
||||
uniqueId(), ['resources/feature-name.txt']),
|
||||
'fetch() must reject on pending and installing workers');
|
||||
|
||||
}, 'Background Fetch requires an activated Service Worker');
|
||||
|
@ -44,7 +44,9 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
// 6.3.1.7.2: If |internalRequest|’s mode is "no-cors", then return a
|
||||
// promise rejected with a TypeError.
|
||||
{
|
||||
const request = new Request('resources/sw.js', {mode: 'no-cors'});
|
||||
const request =
|
||||
new Request('resources/feature-name.txt', {mode: 'no-cors'});
|
||||
|
||||
await promise_rejects(
|
||||
test, new TypeError(), backgroundFetch.fetch(uniqueId(), request),
|
||||
'Requests must not be in no-cors mode');
|
||||
|
@ -56,8 +58,8 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
// 6.3.1.9.2: If |bgFetchMap[id]| exists, reject |promise| with a TypeError
|
||||
// and abort these steps.
|
||||
return promise_rejects(test, new TypeError(), Promise.all([
|
||||
backgroundFetch.fetch('my-id', 'resources/sw.js'),
|
||||
backgroundFetch.fetch('my-id', 'resources/feature-name.txt')
|
||||
backgroundFetch.fetch('my-id', 'resources/feature-name.txt?1'),
|
||||
backgroundFetch.fetch('my-id', 'resources/feature-name.txt?2')
|
||||
]));
|
||||
|
||||
}, 'IDs must be unique among active Background Fetch registrations');
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
// https://wicg.github.io/background-fetch/#background-fetch-manager-getIds
|
||||
|
||||
promise_test(async test => {
|
||||
const script = 'resources/sw.js';
|
||||
const scope = 'resources/scope' + location.pathname;
|
||||
const script = 'service_workers/sw.js';
|
||||
const scope = 'service_workers/' + location.pathname;
|
||||
|
||||
const serviceWorkerRegistration =
|
||||
await service_worker_unregister_and_register(test, script, scope);
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
// https://wicg.github.io/background-fetch/#background-fetch-manager-get
|
||||
|
||||
promise_test(async test => {
|
||||
const script = 'resources/sw.js';
|
||||
const scope = 'resources/scope' + location.pathname;
|
||||
const script = 'service_workers/sw.js';
|
||||
const scope = 'service_workers/' + location.pathname;
|
||||
|
||||
const serviceWorkerRegistration =
|
||||
await service_worker_unregister_and_register(test, script, scope);
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
spec: https://wicg.github.io/budget-api/
|
||||
suggested_reviewers:
|
||||
- beverloo
|
|
@ -1,24 +0,0 @@
|
|||
// META: script=/resources/WebIDLParser.js
|
||||
// META: script=/resources/idlharness.js
|
||||
|
||||
'use strict';
|
||||
|
||||
// See https://wicg.github.io/budget-api/
|
||||
|
||||
idl_test(
|
||||
['budget-api'],
|
||||
['html'],
|
||||
async idl_array => {
|
||||
idl_array.add_objects({ BudgetService: ['navigator.budget'] });
|
||||
if (self.Window) {
|
||||
idl_array.add_objects({ Navigator: ['navigator'] });
|
||||
} else {
|
||||
idl_array.add_objects({ WorkerNavigator: ['navigator'] });
|
||||
}
|
||||
const budgetStates = await navigator.budget.getBudget();
|
||||
if (budgetStates.length) {
|
||||
self.budgetState = budgetStates[0];
|
||||
idl_array.add_objects({ BudgetState: ['budgetState'] });
|
||||
}
|
||||
}
|
||||
);
|
|
@ -229,9 +229,9 @@ test(t => {
|
|||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
color: "rgb(0, 0, 0)", composite: null },
|
||||
color: "rgb(0, 0, 0)", composite: "auto" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
color: "rgb(255, 255, 255)", composite: null },
|
||||
color: "rgb(255, 255, 255)", composite: "auto" },
|
||||
];
|
||||
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
|
@ -299,10 +299,10 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
marginBottom: "8px", marginLeft: "8px",
|
||||
marginRight: "8px", marginTop: "8px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
marginBottom: "16px", marginLeft: "16px",
|
||||
marginRight: "16px", marginTop: "16px" },
|
||||
];
|
||||
|
@ -323,9 +323,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)" },
|
||||
];
|
||||
|
||||
|
@ -345,9 +345,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 0, 255)" },
|
||||
];
|
||||
|
||||
|
@ -367,11 +367,11 @@ test(t => {
|
|||
assert_equals(frames.length, 3, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)" },
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: null,
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)" },
|
||||
];
|
||||
|
||||
|
@ -391,9 +391,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
marginTop: '50px', marginBottom: '100px' },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
marginTop: '250px', marginBottom: '200px' },
|
||||
];
|
||||
|
||||
|
@ -413,13 +413,13 @@ test(t => {
|
|||
assert_equals(frames.length, 4, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 0, 0)", marginTop: "8px" },
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "ease", composite: null,
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: null,
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: "auto",
|
||||
marginTop: "12px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)", marginTop: "16px" },
|
||||
];
|
||||
|
||||
|
@ -439,13 +439,13 @@ test(t => {
|
|||
assert_equals(frames.length, 4, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "linear", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
|
||||
color: "rgb(0, 0, 0)", marginTop: "8px" },
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)", composite: null,
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)", composite: "auto",
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in", composite: null,
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in", composite: "auto",
|
||||
marginTop: "12px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)", marginTop: "16px" },
|
||||
];
|
||||
|
||||
|
@ -465,9 +465,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 0, 0)", marginTop: "8px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)", marginTop: "16px" },
|
||||
];
|
||||
|
||||
|
@ -487,11 +487,11 @@ test(t => {
|
|||
assert_equals(frames.length, 3, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
|
||||
color: "rgb(0, 0, 0)", fontSize: "16px" },
|
||||
{ offset: 0, computedOffset: 0, easing: "linear", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
|
||||
marginTop: "8px", paddingLeft: "2px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
|
||||
paddingLeft: "4px" },
|
||||
];
|
||||
|
@ -512,11 +512,11 @@ test(t => {
|
|||
assert_equals(frames.length, 3, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
|
||||
marginTop: "0px", marginRight: "0px", marginBottom: "0px" },
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)", composite: null,
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)", composite: "auto",
|
||||
marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
|
||||
];
|
||||
|
||||
|
@ -536,17 +536,17 @@ test(t => {
|
|||
assert_equals(frames.length, 6, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
paddingTop: "30px" },
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: null,
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
|
||||
paddingTop: "20px" },
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: null,
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: "auto",
|
||||
paddingTop: "20px" },
|
||||
{ offset: 0.85, computedOffset: 0.85, easing: "ease", composite: null,
|
||||
{ offset: 0.85, computedOffset: 0.85, easing: "ease", composite: "auto",
|
||||
paddingTop: "30px" },
|
||||
{ offset: 0.851, computedOffset: 0.851, easing: "ease", composite: null,
|
||||
{ offset: 0.851, computedOffset: 0.851, easing: "ease", composite: "auto",
|
||||
paddingTop: "60px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
paddingTop: "70px" },
|
||||
];
|
||||
|
||||
|
@ -568,9 +568,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
filter: "none" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
filter: "blur(5px) sepia(60%) saturate(30%)" },
|
||||
];
|
||||
|
||||
|
@ -589,9 +589,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
filter: "drop-shadow(rgb(0, 255, 0) 10px 10px 10px)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
filter: "drop-shadow(rgb(255, 0, 0) 50px 30px 10px)" },
|
||||
];
|
||||
|
||||
|
@ -617,11 +617,11 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
textShadow: "rgb(0, 0, 0) 1px 1px 2px,"
|
||||
+ " rgb(0, 0, 255) 0px 0px 16px,"
|
||||
+ " rgb(0, 0, 255) 0px 0px 3.2px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
textShadow: "none" },
|
||||
];
|
||||
|
||||
|
@ -644,9 +644,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
backgroundSize: "auto auto" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
backgroundSize: "50% auto, 6px auto, contain" },
|
||||
];
|
||||
|
||||
|
@ -676,9 +676,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
transform: "none" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
transform: "translate(100px, 0px)" },
|
||||
];
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
|
@ -696,12 +696,12 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
marginBottom: "0px",
|
||||
marginLeft: "0px",
|
||||
marginRight: "0px",
|
||||
marginTop: "0px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
marginBottom: "100px",
|
||||
marginLeft: "100px",
|
||||
marginRight: "100px",
|
||||
|
@ -722,9 +722,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 0, 0)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
color: "rgb(0, 255, 0)" },
|
||||
];
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
|
@ -742,9 +742,9 @@ test(t => {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
transform: "translate(100px, 0px)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
transform: "none" },
|
||||
];
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid Layout Test: Content Distribution and the track sizing algorithm</title>
|
||||
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-grid/#grid-align">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-align/#content-distribution">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-align/#valdef-align-content-space-around">
|
||||
<link rel="stylesheet" href="../../support/alignment.css">
|
||||
<meta name="flags" content="ahem">
|
||||
<meta name="assert" content="Content Distribution offset doesn't account for tracks with non-spanning items.">
|
||||
<style>
|
||||
.grid {
|
||||
display: inline-grid;
|
||||
background: grey;
|
||||
grid-template-columns: 100px;
|
||||
font: 20px/1 Ahem;
|
||||
width: 200px;
|
||||
}
|
||||
.item1 {
|
||||
background: green;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
.item2 {
|
||||
background: blue;
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
}
|
||||
</style>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/check-layout-th.js"></script>
|
||||
|
||||
<body onload="checkLayout('.grid')">
|
||||
<div class="grid justifyContentSpaceAround" data-expected-width="200" data-expected-height="60">
|
||||
<div class="item1" data-expected-width="100" data-expected-height="40">XXXX XXX</div>
|
||||
<div class="item2" data-expected-width="100" data-expected-height="20">XXX</div>
|
||||
</div>
|
||||
</body>
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid Layout Test: Content Distribution and the track sizing algorithm</title>
|
||||
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-grid/#grid-align">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-align/#content-distribution">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-align/#valdef-align-content-space-between">
|
||||
<link rel="stylesheet" href="../../support/alignment.css">
|
||||
<meta name="flags" content="ahem">
|
||||
<meta name="assert" content="Content Distribution offset doesn't account for relative sized tracks with non-spanning items.">
|
||||
<style>
|
||||
.grid {
|
||||
display: inline-grid;
|
||||
background: grey;
|
||||
grid-template-columns: 50%;
|
||||
font: 20px/1 Ahem;
|
||||
}
|
||||
|
||||
.item1 {
|
||||
background: green;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
.item2 {
|
||||
background: blue;
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
}
|
||||
</style>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/check-layout-th.js"></script>
|
||||
|
||||
<body onload="checkLayout('.grid')">
|
||||
<div class="grid justifyContentSpaceBetween" data-expected-width="220" data-expected-height="40">
|
||||
<div class="item1" data-expected-width="110" data-expected-height="40">XXXX XXX</div>
|
||||
<div class="item2" data-expected-width="60" data-expected-height="40">XXX</div>
|
||||
</div>
|
||||
</body>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: counter-* properties with a calc() expression</title>
|
||||
<link rel="author" title="Ondřej Žára" href="https://ondras.zarovi.cz/"/>
|
||||
<style type="text/css">
|
||||
body {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>The following two lines should be the same:</p>
|
||||
|
||||
<div id="test">
|
||||
<span id="a">8</span>
|
||||
<span id="b">10</span>
|
||||
</div>
|
||||
|
||||
<div id="reference">
|
||||
<span>8</span>
|
||||
<span>10</span>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: counter-* properties with a calc() expression</title>
|
||||
<link rel="author" title="Ondřej Žára" href="https://ondras.zarovi.cz/"/>
|
||||
|
||||
<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#counters"/>
|
||||
<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#propdef-content"/>
|
||||
<link rel="help" href="https://www.w3.org/TR/CSS21/syndata.html#counter"/>
|
||||
<link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-notation"/>
|
||||
<link rel="help" href="https://www.w3.org/TR/css-lists-3/#counter-properties"/>
|
||||
<link rel="match" href="calc-in-counter-001-ref.xhtml"/>
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#a { counter-reset: a calc(3 + 5); }
|
||||
#a::before { content: counter(a); }
|
||||
|
||||
#b { counter-reset: b 0; counter-increment: b calc(4 + 6); }
|
||||
#b::before { content: counter(b); }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>The following two lines should be the same:</p>
|
||||
|
||||
<div id="test">
|
||||
<span id="a"></span>
|
||||
<span id="b"></span>
|
||||
</div>
|
||||
|
||||
<div id="reference">
|
||||
<span>8</span>
|
||||
<span>10</span>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -138,5 +138,33 @@
|
|||
<div class="b" style="margin-top: 30px"><div class="fixedSizeChild"/></div>
|
||||
<div class="c" style="margin-top: 30px"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: 160px"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: 120px"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -147,5 +147,33 @@
|
|||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -148,5 +148,33 @@
|
|||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -141,5 +141,33 @@
|
|||
<div class="b" style="margin-left: 30px"><div class="fixedSizeChild"/></div>
|
||||
<div class="c" style="margin-left: 30px"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-left: 160px"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-left: 120px"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -147,5 +147,33 @@
|
|||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -148,5 +148,33 @@
|
|||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<style>
|
||||
div.flexbox {
|
||||
width: 200px;
|
||||
margin-bottom: 2px;
|
||||
background: lightgray;
|
||||
height: 20px;
|
||||
clear: all;
|
||||
}
|
||||
div.a {
|
||||
width: 10px;
|
||||
height: 20px;
|
||||
background: lightgreen;
|
||||
float: left;
|
||||
}
|
||||
div.b {
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
background: pink;
|
||||
float: left;
|
||||
}
|
||||
div.c {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
background: orange;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* Inside of 'b': */
|
||||
div.fixedSizeChild {
|
||||
width: 30px;
|
||||
height: 10px;
|
||||
background: purple;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (stretch) -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b" style="margin-left:80px; width:110px"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b" style="margin-left: 40px; width: 70px"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 160px"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 120px"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 80px"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 60px"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b" style="margin-left: 160px"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b" style="margin-left: 60px"><div class="fixedSizeChild"/></div>
|
||||
<div class="c" style="margin-left: 60px"/>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 40px"/>
|
||||
<div class="b" style="margin-left: 80px"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 20px"/>
|
||||
<div class="b" style="margin-left: 40px"><div class="fixedSizeChild"/></div>
|
||||
<div class="c" style="margin-left: 40px"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: calc(160px / 3)"/>
|
||||
<div class="b" style="margin-left: calc(160px / 3)"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 30px"/>
|
||||
<div class="b" style="margin-left: 30px"><div class="fixedSizeChild"/></div>
|
||||
<div class="c" style="margin-left: 30px"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-left: 190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-left: 160px"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-left: 120px"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="a"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,179 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- Testcase with a series of horizontal flex containers, with 1-3 flex lines,
|
||||
testing each possible value of the 'align-content' property. -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: Testing 'align-content' in a vertical writing-mode flex container</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#align-content-property"/>
|
||||
<link rel="match" href="flexbox-align-content-wmvert-001-ref.xhtml"/>
|
||||
<style>
|
||||
div.flexbox {
|
||||
width: 200px;
|
||||
height: 20px; /* Short, to force us to wrap */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 2px;
|
||||
background: lightgray;
|
||||
writing-mode: vertical-lr;
|
||||
}
|
||||
div.a {
|
||||
width: 10px;
|
||||
height: 20px;
|
||||
flex: none;
|
||||
background: lightgreen;
|
||||
}
|
||||
div.b {
|
||||
width: auto;
|
||||
height: 20px; /* height comes from contents */
|
||||
flex: none;
|
||||
background: pink;
|
||||
}
|
||||
div.c {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
flex: none;
|
||||
background: orange;
|
||||
}
|
||||
|
||||
/* Inside of 'b': */
|
||||
div.fixedSizeChild {
|
||||
width: 30px;
|
||||
height: 10px;
|
||||
background: purple;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (stretch) -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox" style="align-content: flex-start">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: flex-start">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: flex-start">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox" style="align-content: flex-end">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: flex-end">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: flex-end">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="flexbox" style="align-content: center">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: center">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: center">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox" style="align-content: space-between">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: space-between">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: space-between">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<div class="flexbox" style="align-content: space-around">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: space-around">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: space-around">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<div class="flexbox" style="align-content: space-evenly">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: space-evenly">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: space-evenly">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- start -->
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- end -->
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
</div>
|
||||
<div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
|
||||
<div class="a"/>
|
||||
<div class="b"><div class="fixedSizeChild"/></div>
|
||||
<div class="c"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
.flexbox > div { float: left }
|
||||
.flex-start, .flex-end, .center, .baseline, .stretch,
|
||||
.auto, .unspecified, .initial, .inherit {
|
||||
.auto, .unspecified, .initial, .inherit, .self-start, .self-end {
|
||||
width: 40px;
|
||||
margin: 1px 2px 3px 4px;
|
||||
border-width: 2px 3px 4px 5px;
|
||||
|
@ -53,6 +53,16 @@
|
|||
.stretch {
|
||||
background: pink;
|
||||
}
|
||||
.self-start {
|
||||
background: yellow;
|
||||
}
|
||||
.self-end {
|
||||
background: purple;
|
||||
}
|
||||
.wmvertrev {
|
||||
writing-mode: vertical-lr;
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -81,5 +91,12 @@
|
|||
<div class="stretch" style="height: 182px">stretch</div>
|
||||
<div class="stretch big">a b c d e f</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="flexbox">
|
||||
<div class="self-start">self-start</div>
|
||||
<div class="self-start big">a b c d e f</div>
|
||||
<div class="self-end wmvertrev">self-end</div>
|
||||
<div class="self-end wmvertrev big">a b c d e f</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -57,6 +57,18 @@
|
|||
background: pink;
|
||||
align-self: stretch;
|
||||
}
|
||||
.self-start {
|
||||
background: yellow;
|
||||
align-self: self-start;
|
||||
}
|
||||
.self-end {
|
||||
background: purple;
|
||||
align-self: self-end;
|
||||
}
|
||||
.wmvertrev {
|
||||
writing-mode: vertical-lr;
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -75,5 +87,12 @@
|
|||
<div class="stretch">stretch</div>
|
||||
<div class="stretch big">a b c d e f</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="flexbox">
|
||||
<div class="self-start">self-start</div>
|
||||
<div class="self-start big">a b c d e f</div>
|
||||
<div class="self-end wmvertrev">self-end</div>
|
||||
<div class="self-end wmvertrev big">a b c d e f</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
font-size: 10px;
|
||||
}
|
||||
|
||||
.flex-start, .flex-end, .center, .baseline, .stretch {
|
||||
.flex-start, .flex-end, .center, .baseline, .stretch,
|
||||
.self-start, .self-end {
|
||||
clear: both;
|
||||
margin: 1px 2px 3px 4px;
|
||||
border-width: 2px 3px 4px 5px;
|
||||
|
@ -58,6 +59,16 @@
|
|||
.stretch {
|
||||
background: pink;
|
||||
}
|
||||
.self-start {
|
||||
background: yellow;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
.self-end {
|
||||
background: purple;
|
||||
float: left;
|
||||
text-align: right;
|
||||
}
|
||||
.clearFloats { clear: both }
|
||||
</style>
|
||||
</head>
|
||||
|
@ -86,5 +97,11 @@
|
|||
we use floats or inline-blocks, whose margins don't collapse. -->
|
||||
<div class="stretch big" style="margin-top: 4px">a b c d e f</div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="self-start">self-start</div>
|
||||
<div class="self-start big">a b c d e f</div>
|
||||
<div class="self-end">self-end</div>
|
||||
<div class="self-end big">a b c d e f</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -56,6 +56,17 @@
|
|||
background: pink;
|
||||
align-self: stretch;
|
||||
}
|
||||
.self-start {
|
||||
background: yellow;
|
||||
align-self: self-start;
|
||||
}
|
||||
.self-end {
|
||||
background: purple;
|
||||
align-self: self-end;
|
||||
}
|
||||
.dirrtl {
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -73,5 +84,11 @@
|
|||
<div class="stretch">stretch</div>
|
||||
<div class="stretch big">a b c d e f</div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="self-start dirrtl">self-start</div>
|
||||
<div class="self-start dirrtl big">a b c d e f</div>
|
||||
<div class="self-end dirrtl">self-end</div>
|
||||
<div class="self-end dirrtl big">a b c d e f</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- Reference case for align-items / align-self behavior, using blocks in
|
||||
place of flex items and using float and width keywords to emulate the
|
||||
align-items / align-self properties. -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<style>
|
||||
.flexbox {
|
||||
border: 1px dashed blue;
|
||||
width: 200px;
|
||||
float: left;
|
||||
font-size: 10px;
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.flex-start, .flex-end, .center, .baseline, .stretch, .self-start, .self-end {
|
||||
clear: both;
|
||||
margin: 1px 2px 3px 4px;
|
||||
border-width: 2px 3px 4px 5px;
|
||||
padding: 3px 4px 5px 6px;
|
||||
border-style: dotted;
|
||||
}
|
||||
|
||||
div.big {
|
||||
font-size: 20px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
/* Classes for each of the various align-self values */
|
||||
.flex-start {
|
||||
background: lime;
|
||||
float: right;
|
||||
}
|
||||
.flex-end {
|
||||
background: orange;
|
||||
float: left;
|
||||
}
|
||||
<!-- We center shrinkwrapped text by putting it into an inline-block, and
|
||||
then wrapping that inline-block in a helper-div that has
|
||||
"text-align:center" set. -->
|
||||
.centerParent {
|
||||
text-align: center;
|
||||
}
|
||||
.center {
|
||||
background: lightblue;
|
||||
display: inline-block;
|
||||
text-align: right; /* Keep parent's centering from tweaking my text */
|
||||
}
|
||||
.baseline {
|
||||
background: teal;
|
||||
float: right;
|
||||
}
|
||||
.stretch {
|
||||
background: pink;
|
||||
}
|
||||
.self-start {
|
||||
background: yellow;
|
||||
float: right;
|
||||
}
|
||||
.self-end {
|
||||
background: purple;
|
||||
float: left;
|
||||
}
|
||||
.clearFloats { clear: both }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexbox">
|
||||
<div class="flex-start">start</div>
|
||||
<div class="flex-start big">a b c d e f</div>
|
||||
<div class="flex-end">end</div>
|
||||
<div class="flex-end big">a b c d e f</div>
|
||||
<div class="clearFloats"></div>
|
||||
<div class="centerParent">
|
||||
<div class="center">center</div>
|
||||
</div>
|
||||
<div class="centerParent">
|
||||
<div class="center big">a b c d e f</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="baseline">base</div>
|
||||
<div class="baseline big">abc</div>
|
||||
<div class="clearFloats"></div>
|
||||
<div class="stretch">stretch</div>
|
||||
<!-- Force a 3px + 1px = 4px margin between this and the previous div
|
||||
(to thwart the effects of margin-collapsing). This is the only
|
||||
place we need this hack, because everywhere else in this test
|
||||
we use floats or inline-blocks, whose margins don't collapse. -->
|
||||
<div class="stretch big" style="margin-top: 4px">a b c d e f</div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="self-start">self-start</div>
|
||||
<div class="self-start big">a b c d e f</div>
|
||||
<div class="self-end">self-end</div>
|
||||
<div class="self-end big">a b c d e f</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- Testcase for align-items / align-self behavior, with all the possible
|
||||
values included on different items within a flex container, and with
|
||||
margin/border/padding values on each item. -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: Testing the behavior of 'align-self' with a vertical flex container, with margin/padding/border on the items and with 'direction:rtl'</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#align-items-property"/>
|
||||
<link rel="match" href="flexbox-align-self-vert-rtl-005-ref.xhtml"/>
|
||||
<style>
|
||||
.flexbox {
|
||||
border: 1px dashed blue;
|
||||
width: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
float: left;
|
||||
font-size: 10px;
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.flexbox > div {
|
||||
margin: 1px 2px 3px 4px;
|
||||
border-width: 2px 3px 4px 5px;
|
||||
padding: 3px 4px 5px 6px;
|
||||
|
||||
border-style: dotted;
|
||||
}
|
||||
|
||||
div.big {
|
||||
font-size: 20px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
/* Classes for each of the various align-self values */
|
||||
.flex-start {
|
||||
background: lime;
|
||||
align-self: flex-start;
|
||||
}
|
||||
.flex-end {
|
||||
background: orange;
|
||||
align-self: flex-end;
|
||||
}
|
||||
.center {
|
||||
background: lightblue;
|
||||
align-self: center;
|
||||
}
|
||||
.baseline {
|
||||
background: teal;
|
||||
align-self: baseline;
|
||||
}
|
||||
.stretch {
|
||||
background: pink;
|
||||
align-self: stretch;
|
||||
}
|
||||
.self-start {
|
||||
background: yellow;
|
||||
align-self: self-start;
|
||||
}
|
||||
.self-end {
|
||||
background: purple;
|
||||
align-self: self-end;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexbox">
|
||||
<div class="flex-start">start</div>
|
||||
<div class="flex-start big">a b c d e f</div>
|
||||
<div class="flex-end">end</div>
|
||||
<div class="flex-end big">a b c d e f</div>
|
||||
<div class="center">center</div>
|
||||
<div class="center big">a b c d e f</div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="baseline">base</div>
|
||||
<div class="baseline big">abc</div>
|
||||
<div class="stretch">stretch</div>
|
||||
<div class="stretch big">a b c d e f</div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="self-start dirrtl">self-start</div>
|
||||
<div class="self-start dirrtl big">a b c d e f</div>
|
||||
<div class="self-end dirrtl">self-end</div>
|
||||
<div class="self-end dirrtl big nowidth">a b c d e f</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,192 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<style>
|
||||
body { line-height: 0; }
|
||||
|
||||
div.flexbox {
|
||||
width: 200px;
|
||||
margin-bottom: 2px;
|
||||
direction: rtl;
|
||||
}
|
||||
div.flexbox > * {
|
||||
display: inline-block;
|
||||
}
|
||||
div.a {
|
||||
height: 20px;
|
||||
width: 10px;
|
||||
background: lightgreen;
|
||||
}
|
||||
div.b {
|
||||
height: 20px;
|
||||
width: 50px;
|
||||
background: pink;
|
||||
}
|
||||
div.c {
|
||||
height: 20px;
|
||||
width: 100px;
|
||||
background: orange;
|
||||
}
|
||||
.centerParent {
|
||||
text-align: center;
|
||||
}
|
||||
.center {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (start) -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox" style="text-align: left">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="text-align: left;">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="text-align: left;">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="centerParent">
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="centerParent">
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="centerParent">
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b" style="float: left"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a" style="display:block; float: right"/>
|
||||
<div class="c" style="float:left"/>
|
||||
<!-- Use fixed-size margins to subtract space for "a" and "c", and then
|
||||
use auto margins to center 'b' within the remaining space -->
|
||||
<div style="display: block; margin-right: 10px; margin-left: 100px">
|
||||
<div class="b" style="margin: auto"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<!-- Center "a" here just as we did above in the "center" case. -->
|
||||
<div class="centerParent">
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- For the rest, we'll use a flex container with invisible flexible items
|
||||
instead of packing space. That's simpler than trying to hack up
|
||||
a width-independent reference case for "justify-content: space-around".
|
||||
(There are other reftests to ensure that basic flex container
|
||||
behavior is correct, so it's safe to rely on it here.) -->
|
||||
<div class="flexbox" style="display: flex">
|
||||
<div style="flex: 0.5"/>
|
||||
<div class="a"/>
|
||||
<div style="flex: 1"/>
|
||||
<div class="b"/>
|
||||
<div style="flex: 0.5"/>
|
||||
</div>
|
||||
<div class="flexbox" style="display: flex">
|
||||
<div style="flex: 0.5"/>
|
||||
<div class="a"/>
|
||||
<div style="flex: 1"/>
|
||||
<div class="b"/>
|
||||
<div style="flex: 1"/>
|
||||
<div class="c"/>
|
||||
<div style="flex: 0.5"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<!-- Center "a" here just as we did above in the "center" case. -->
|
||||
<div class="centerParent">
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- As above with space-around, we'll use a flex container with invisible
|
||||
flexible items instead of packing space. -->
|
||||
<div class="flexbox" style="display: flex">
|
||||
<div style="flex: 1"/>
|
||||
<div class="a"/>
|
||||
<div style="flex: 1"/>
|
||||
<div class="b"/>
|
||||
<div style="flex: 1"/>
|
||||
</div>
|
||||
<div class="flexbox" style="display: flex">
|
||||
<div style="flex: 1"/>
|
||||
<div class="a"/>
|
||||
<div style="flex: 1"/>
|
||||
<div class="b"/>
|
||||
<div style="flex: 1"/>
|
||||
<div class="c"/>
|
||||
<div style="flex: 1"/>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- left -->
|
||||
<div class="flexbox" style="text-align:left">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="text-align:left">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="text-align:left">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- right -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- Testcase to exercise each possible value of the 'justify-content'
|
||||
property, in an auto-sized horizontal flex container. -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: Testing 'justify-content' in an auto-sized reversed horizontal flex container</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#justify-content-property"/>
|
||||
<link rel="match" href="flexbox-justify-content-horiz-006-ref.xhtml"/>
|
||||
<style>
|
||||
div.flexbox {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
width: 200px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
div.a {
|
||||
height: 20px;
|
||||
flex: 0 10px;
|
||||
background: lightgreen;
|
||||
}
|
||||
div.b {
|
||||
height: 20px;
|
||||
flex: 0 50px;
|
||||
background: pink;
|
||||
}
|
||||
div.c {
|
||||
height: 20px;
|
||||
flex: 0 100px;
|
||||
background: orange;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (start) -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- left -->
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- right -->
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<style>
|
||||
div.flexbox {
|
||||
height: 200px;
|
||||
margin-right: 2px;
|
||||
float: left;
|
||||
}
|
||||
div.a {
|
||||
width: 20px;
|
||||
height: 10px;
|
||||
background: lightgreen;
|
||||
}
|
||||
div.b {
|
||||
width: 20px;
|
||||
height: 50px;
|
||||
background: pink;
|
||||
}
|
||||
div.c {
|
||||
width: 20px;
|
||||
height: 100px;
|
||||
background: orange;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (start) -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top:190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top:140px"/><div class="a"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top:190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top:140px"/><div class="a"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: 70px"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: 20px"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top:190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"/><div class="a" style="margin-top: 140px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"
|
||||
/><div class="b" style="margin-top: 20px"
|
||||
/><div class="a" style="margin-top: 20px"/>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: 35px"
|
||||
/><div class="a" style="margin-top: 70px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: calc(40px / 6)"
|
||||
/><div class="b" style="margin-top: calc(40px / 3)"
|
||||
/><div class="a" style="margin-top: calc(40px / 3)"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: calc(140px / 3)"
|
||||
/><div class="a" style="margin-top: calc(140px / 3)"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: 10px"
|
||||
/><div class="b" style="margin-top: 10px"
|
||||
/><div class="a" style="margin-top: 10px"/>
|
||||
</div>
|
||||
|
||||
<!-- left -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- right -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- Testcase with a series of vertical flex containers, testing each
|
||||
possible value of the 'justify-content' property. -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: Testing 'justify-content' in a vertical flex container</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#justify-content-property"/>
|
||||
<link rel="match" href="flexbox-justify-content-vert-006-ref.xhtml"/>
|
||||
<style>
|
||||
div.flexbox {
|
||||
height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
margin-right: 2px;
|
||||
float: left;
|
||||
}
|
||||
div.a {
|
||||
width: 20px;
|
||||
flex: 0 10px;
|
||||
background: lightgreen;
|
||||
}
|
||||
div.b {
|
||||
width: 20px;
|
||||
flex: 0 50px;
|
||||
background: pink;
|
||||
}
|
||||
div.c {
|
||||
width: 20px;
|
||||
flex: 0 100px;
|
||||
background: orange;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (start) -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- left -->
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- right -->
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<style>
|
||||
div.flexbox {
|
||||
height: 200px;
|
||||
margin-right: 2px;
|
||||
float: left;
|
||||
}
|
||||
div.a {
|
||||
width: 20px;
|
||||
height: 10px;
|
||||
background: lightgreen;
|
||||
}
|
||||
div.b {
|
||||
width: 20px;
|
||||
height: 50px;
|
||||
background: pink;
|
||||
}
|
||||
div.c {
|
||||
width: 20px;
|
||||
height: 100px;
|
||||
background: orange;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (start) -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top:190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top:140px"/><div class="a"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top:190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top:140px"/><div class="a"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top:40px"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: 70px"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: 20px"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top:190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"/><div class="a" style="margin-top: 140px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"
|
||||
/><div class="b" style="margin-top: 20px"
|
||||
/><div class="a" style="margin-top: 20px"/>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: 35px"
|
||||
/><div class="a" style="margin-top: 70px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: calc(40px / 6)"
|
||||
/><div class="b" style="margin-top: calc(40px / 3)"
|
||||
/><div class="a" style="margin-top: calc(40px / 3)"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 95px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: calc(140px / 3)"
|
||||
/><div class="a" style="margin-top: calc(140px / 3)"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: 10px"
|
||||
/><div class="b" style="margin-top: 10px"
|
||||
/><div class="a" style="margin-top: 10px"/>
|
||||
</div>
|
||||
|
||||
<!-- left -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
<!-- right -->
|
||||
<div class="flexbox">
|
||||
<div class="a" style="margin-top: 190px"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="b" style="margin-top: 140px"/><div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="c" style="margin-top: 40px"/><div class="b"/><div class="a"/>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,142 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- Testcase with a series of vertical flex containers, testing each
|
||||
possible value of the 'justify-content' property. -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: Testing 'justify-content' in a vertical writing mode flex container</title>
|
||||
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#justify-content-property"/>
|
||||
<link rel="match" href="flexbox-justify-content-wmvert-001-ref.xhtml"/>
|
||||
<style>
|
||||
div.flexbox {
|
||||
height: 200px;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
margin-right: 2px;
|
||||
float: left;
|
||||
writing-mode: vertical-lr;
|
||||
}
|
||||
div.a {
|
||||
width: 20px;
|
||||
flex: 0 10px;
|
||||
background: lightgreen;
|
||||
}
|
||||
div.b {
|
||||
width: 20px;
|
||||
flex: 0 50px;
|
||||
background: pink;
|
||||
}
|
||||
div.c {
|
||||
width: 20px;
|
||||
flex: 0 100px;
|
||||
background: orange;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- default (start) -->
|
||||
<div class="flexbox">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"></div>
|
||||
</div>
|
||||
<div class="flexbox">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-start -->
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-start">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- flex-end -->
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: flex-end">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- center -->
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: center">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-between -->
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-between">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-around -->
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-around">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- space-evenly -->
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: space-evenly">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- left -->
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: left">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
<!-- right -->
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/><div class="b"/>
|
||||
</div>
|
||||
<div class="flexbox" style="justify-content: right">
|
||||
<div class="a"/><div class="b"/><div class="c"/>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -11,6 +11,7 @@
|
|||
== flexbox-align-content-horiz-001b.xhtml flexbox-align-content-horiz-001-ref.xhtml
|
||||
== flexbox-align-content-vert-001a.xhtml flexbox-align-content-vert-001-ref.xhtml
|
||||
== flexbox-align-content-vert-001b.xhtml flexbox-align-content-vert-001-ref.xhtml
|
||||
== flexbox-align-content-wmvert-001.xhtml flexbox-align-content-wmvert-001-ref.xhtml
|
||||
|
||||
# Tests for cross-axis alignment (align-self / align-items properties)
|
||||
== flexbox-align-self-baseline-horiz-001a.xhtml flexbox-align-self-baseline-horiz-001-ref.xhtml
|
||||
|
@ -39,6 +40,7 @@
|
|||
== flexbox-align-self-vert-rtl-002.xhtml flexbox-align-self-vert-rtl-002-ref.xhtml
|
||||
== flexbox-align-self-vert-rtl-003.xhtml flexbox-align-self-vert-rtl-003-ref.xhtml
|
||||
== flexbox-align-self-vert-rtl-004.xhtml flexbox-align-self-vert-rtl-004-ref.xhtml
|
||||
== flexbox-align-self-vert-rtl-005.xhtml flexbox-align-self-vert-rtl-005-ref.xhtml
|
||||
|
||||
== flexbox-align-items-center-nested-001.html flexbox-align-items-center-nested-001-ref.html
|
||||
|
||||
|
@ -158,12 +160,15 @@
|
|||
== flexbox-justify-content-horiz-003.xhtml flexbox-justify-content-horiz-003-ref.xhtml
|
||||
== flexbox-justify-content-horiz-004.xhtml flexbox-justify-content-horiz-004-ref.xhtml
|
||||
== flexbox-justify-content-horiz-005.xhtml flexbox-justify-content-horiz-005-ref.xhtml
|
||||
== flexbox-justify-content-horiz-006.xhtml flexbox-justify-content-horiz-006-ref.xhtml
|
||||
== flexbox-justify-content-vert-001a.xhtml flexbox-justify-content-vert-001-ref.xhtml
|
||||
== flexbox-justify-content-vert-001b.xhtml flexbox-justify-content-vert-001-ref.xhtml
|
||||
== flexbox-justify-content-vert-002.xhtml flexbox-justify-content-vert-002-ref.xhtml
|
||||
== flexbox-justify-content-vert-003.xhtml flexbox-justify-content-vert-003-ref.xhtml
|
||||
== flexbox-justify-content-vert-004.xhtml flexbox-justify-content-vert-004-ref.xhtml
|
||||
== flexbox-justify-content-vert-005.xhtml flexbox-justify-content-vert-005-ref.xhtml
|
||||
== flexbox-justify-content-vert-006.xhtml flexbox-justify-content-vert-006-ref.xhtml
|
||||
== flexbox-justify-content-wmvert-001.xhtml flexbox-justify-content-wmvert-001-ref.xhtml
|
||||
|
||||
# Tests for flexbox with margin, border, and/or padding on flex items
|
||||
== flexbox-margin-auto-horiz-001.xhtml flexbox-margin-auto-horiz-001-ref.xhtml
|
||||
|
|
|
@ -18,6 +18,32 @@ the global scope.
|
|||
NB: presently, testdriver.js only works in the top-level test browsing
|
||||
context (and not therefore in any frame or window opened from it).
|
||||
|
||||
### `test_driver.bless(intent, action)`
|
||||
#### `intent: a string describing the motivation for this invocation`
|
||||
#### `action: an optional function`
|
||||
|
||||
This function simulates [activation][activation], allowing tests to
|
||||
perform privileged operations that require user interaction. For
|
||||
example, sandboxed iframes with the
|
||||
`allow-top-navigation-by-user-activation` may only navigate their
|
||||
parent's browsing context under these circumstances. The `intent`
|
||||
string is presented to human operators when the test is not run in
|
||||
automation.
|
||||
|
||||
This method returns a promise which is resolved with the result of
|
||||
invoking the `action` function. If no such function is provided, the
|
||||
promise is resolved with the value `undefined`.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
var mediaElement = document.createElement('video');
|
||||
|
||||
test_driver.bless('initiate media playback', function () {
|
||||
mediaElement.play();
|
||||
});
|
||||
```
|
||||
|
||||
### `test_driver.click(element)`
|
||||
#### `element: a DOM Element object`
|
||||
|
||||
|
@ -48,4 +74,5 @@ between the function being called and the promise settling.
|
|||
To send special keys, one must send the respective key's codepoint. Since this uses the WebDriver protocol, you can find a [list for code points to special keys in the spec](https://w3c.github.io/webdriver/webdriver-spec.html#keyboard-actions).
|
||||
For example, to send the tab key you would send "\uE004".
|
||||
|
||||
[activation]: https://html.spec.whatwg.org/multipage/interaction.html#activation
|
||||
[testharness]: {{ site.baseurl }}{% link _writing-tests/testharness.md %}
|
||||
|
|
|
@ -56,16 +56,16 @@ test(t => {
|
|||
assert_equals(counter++, 3);
|
||||
}));
|
||||
child.addEventListener("hi", t.step_func(e => {
|
||||
assert_equals(window.event, e);
|
||||
assert_equals(window.event, undefined);
|
||||
assert_equals(counter++, 2);
|
||||
}));
|
||||
furtherChild.addEventListener("hi", t.step_func(e => {
|
||||
host.appendChild(child);
|
||||
assert_equals(window.event, e);
|
||||
assert_equals(window.event, undefined);
|
||||
assert_equals(counter++, 0);
|
||||
}));
|
||||
furtherChild.addEventListener("hi", t.step_func(e => {
|
||||
assert_equals(window.event, e);
|
||||
assert_equals(window.event, undefined);
|
||||
assert_equals(counter++, 1);
|
||||
}));
|
||||
furtherChild.dispatchEvent(new Event("hi", { composed: true, bubbles: true }));
|
||||
|
@ -75,7 +75,7 @@ test(t => {
|
|||
async_test(t => {
|
||||
const frame = document.body.appendChild(document.createElement("iframe"));
|
||||
frame.src = "resources/event-global-extra-frame.html";
|
||||
frame.onload = t.step_func_done(() => {
|
||||
frame.onload = t.step_func_done((load_event) => {
|
||||
const event = new Event("hi");
|
||||
document.addEventListener("hi", frame.contentWindow.listener); // listener intentionally not wrapped in t.step_func
|
||||
document.addEventListener("hi", t.step_func(e => {
|
||||
|
@ -85,6 +85,6 @@ async_test(t => {
|
|||
document.dispatchEvent(event);
|
||||
assert_equals(frameState.event, event);
|
||||
assert_equals(frameState.windowEvent, event);
|
||||
assert_equals(frameState.parentEvent, undefined);
|
||||
assert_equals(frameState.parentEvent, load_event);
|
||||
});
|
||||
}, "Listener from a different global");
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// META: script=/common/utils.js
|
||||
// META: script=../resources/utils.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=resources/corspreflight.js
|
||||
|
||||
const corsURL = get_host_info().HTTP_REMOTE_ORIGIN + dirname(location.pathname) + RESOURCES_DIR + "preflight.py";
|
||||
|
||||
promise_test(() => fetch("resources/not-cors-safelisted.json").then(res => res.json().then(runTests)), "Loading data…");
|
||||
|
||||
function runTests(testArray) {
|
||||
testArray.forEach(testItem => {
|
||||
const [headerName, headerValue] = testItem;
|
||||
corsPreflight("Need CORS-preflight for " + headerName + "/" + headerValue + " header",
|
||||
corsURL,
|
||||
"GET",
|
||||
true,
|
||||
[[headerName, headerValue]]);
|
||||
});
|
||||
}
|
|
@ -1,65 +1,7 @@
|
|||
// META: script=/common/utils.js
|
||||
// META: script=../resources/utils.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
|
||||
function headerNames(headers)
|
||||
{
|
||||
let names = [];
|
||||
for (let header of headers)
|
||||
names.push(header[0].toLowerCase());
|
||||
return names
|
||||
}
|
||||
|
||||
/*
|
||||
Check preflight is done
|
||||
Control if server allows method and headers and check accordingly
|
||||
Check control access headers added by UA (for method and headers)
|
||||
*/
|
||||
function corsPreflight(desc, corsUrl, method, allowed, headers, safeHeaders) {
|
||||
return promise_test(function(test) {
|
||||
var uuid_token = token();
|
||||
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(response) {
|
||||
var url = corsUrl + (corsUrl.indexOf("?") === -1 ? "?" : "&");
|
||||
var urlParameters = "token=" + uuid_token + "&max_age=0";
|
||||
var requestInit = {"mode": "cors", "method": method};
|
||||
var requestHeaders = [];
|
||||
if (headers)
|
||||
requestHeaders.push.apply(requestHeaders, headers);
|
||||
if (safeHeaders)
|
||||
requestHeaders.push.apply(requestHeaders, safeHeaders);
|
||||
requestInit["headers"] = requestHeaders;
|
||||
|
||||
if (allowed) {
|
||||
urlParameters += "&allow_methods=" + method + "&control_request_headers";
|
||||
if (headers) {
|
||||
//Make the server allow the headers
|
||||
urlParameters += "&allow_headers=" + headerNames(headers).join("%20%2C");
|
||||
}
|
||||
return fetch(url + urlParameters, requestInit).then(function(resp) {
|
||||
assert_equals(resp.status, 200, "Response's status is 200");
|
||||
assert_equals(resp.headers.get("x-did-preflight"), "1", "Preflight request has been made");
|
||||
if (headers) {
|
||||
var actualHeaders = resp.headers.get("x-control-request-headers").toLowerCase().split(",");
|
||||
for (var i in actualHeaders)
|
||||
actualHeaders[i] = actualHeaders[i].trim();
|
||||
for (var header of headers)
|
||||
assert_in_array(header[0].toLowerCase(), actualHeaders, "Preflight asked permission for header: " + header);
|
||||
|
||||
let accessControlAllowHeaders = headerNames(headers).sort().join(",");
|
||||
assert_equals(resp.headers.get("x-control-request-headers"), accessControlAllowHeaders, "Access-Control-Allow-Headers value");
|
||||
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
|
||||
} else {
|
||||
assert_equals(resp.headers.get("x-control-request-headers"), null, "Access-Control-Request-Headers should be omitted")
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)).then(function(){
|
||||
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, desc);
|
||||
}
|
||||
// META: script=resources/corspreflight.js
|
||||
|
||||
var corsUrl = get_host_info().HTTP_REMOTE_ORIGIN + dirname(location.pathname) + RESOURCES_DIR + "preflight.py";
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
function headerNames(headers) {
|
||||
let names = [];
|
||||
for (let header of headers) {
|
||||
names.push(header[0].toLowerCase());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/*
|
||||
Check preflight is done
|
||||
Control if server allows method and headers and check accordingly
|
||||
Check control access headers added by UA (for method and headers)
|
||||
*/
|
||||
function corsPreflight(desc, corsUrl, method, allowed, headers, safeHeaders) {
|
||||
return promise_test(function(test) {
|
||||
var uuid_token = token();
|
||||
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(response) {
|
||||
var url = corsUrl + (corsUrl.indexOf("?") === -1 ? "?" : "&");
|
||||
var urlParameters = "token=" + uuid_token + "&max_age=0";
|
||||
var requestInit = {"mode": "cors", "method": method};
|
||||
var requestHeaders = [];
|
||||
if (headers)
|
||||
requestHeaders.push.apply(requestHeaders, headers);
|
||||
if (safeHeaders)
|
||||
requestHeaders.push.apply(requestHeaders, safeHeaders);
|
||||
requestInit["headers"] = requestHeaders;
|
||||
|
||||
if (allowed) {
|
||||
urlParameters += "&allow_methods=" + method + "&control_request_headers";
|
||||
if (headers) {
|
||||
//Make the server allow the headers
|
||||
urlParameters += "&allow_headers=" + headerNames(headers).join("%20%2C");
|
||||
}
|
||||
return fetch(url + urlParameters, requestInit).then(function(resp) {
|
||||
assert_equals(resp.status, 200, "Response's status is 200");
|
||||
assert_equals(resp.headers.get("x-did-preflight"), "1", "Preflight request has been made");
|
||||
if (headers) {
|
||||
var actualHeaders = resp.headers.get("x-control-request-headers").toLowerCase().split(",");
|
||||
for (var i in actualHeaders)
|
||||
actualHeaders[i] = actualHeaders[i].trim();
|
||||
for (var header of headers)
|
||||
assert_in_array(header[0].toLowerCase(), actualHeaders, "Preflight asked permission for header: " + header);
|
||||
|
||||
let accessControlAllowHeaders = headerNames(headers).sort().join(",");
|
||||
assert_equals(resp.headers.get("x-control-request-headers"), accessControlAllowHeaders, "Access-Control-Allow-Headers value");
|
||||
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
|
||||
} else {
|
||||
assert_equals(resp.headers.get("x-control-request-headers"), null, "Access-Control-Request-Headers should be omitted")
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)).then(function(){
|
||||
return fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, desc);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
["accept", "\""],
|
||||
["accept", "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678"],
|
||||
["accept-language", "\u0001"],
|
||||
["accept-language", "@"],
|
||||
["content-language", "\u0001"],
|
||||
["content-language", "@"],
|
||||
["content-type", "text/html"],
|
||||
["content-type", "text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901"],
|
||||
["test", "hi"]
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
promise_test(() => fetch("../cors/resources/not-cors-safelisted.json").then(res => res.json().then(runTests)), "Loading data…");
|
||||
|
||||
function runTests(testArray) {
|
||||
testArray = testArray.concat([
|
||||
["dpr", "2"],
|
||||
["downlink", "1"], // https://wicg.github.io/netinfo/
|
||||
["save-data", "on"],
|
||||
["viewport-width", "100"],
|
||||
["width", "100"]
|
||||
]);
|
||||
testArray.forEach(testItem => {
|
||||
const [headerName, headerValue] = testItem;
|
||||
test(() => {
|
||||
const noCorsHeaders = new Request("about:blank", { mode: "no-cors" }).headers;
|
||||
noCorsHeaders.append(headerName, headerValue);
|
||||
assert_false(noCorsHeaders.has(headerName));
|
||||
}, "\"no-cors\" Headers object cannot have " + headerName + "/" + headerValue + " as header");
|
||||
});
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<script>
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let key = "embed-same-origin";
|
||||
|
||||
let e = document.createElement('embed');
|
||||
e.src = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
|
||||
e.onload = e => {
|
||||
let expected = {"destination":"embed", "site":"same-origin"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
|
||||
document.body.appendChild(e);
|
||||
})
|
||||
}, "Same-Origin embed");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let key = "embed-same-site";
|
||||
|
||||
let e = document.createElement('embed');
|
||||
e.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
|
||||
e.onload = e => {
|
||||
let expected = {"destination":"embed", "site":"same-site"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
|
||||
document.body.appendChild(e);
|
||||
})
|
||||
}, "Same-Site embed");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let key = "embed-cross-site";
|
||||
|
||||
let e = document.createElement('embed');
|
||||
e.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
|
||||
e.onload = e => {
|
||||
let expected = {"destination":"embed", "site":"cross-site"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
|
||||
document.body.appendChild(e);
|
||||
})
|
||||
}, "Cross-Site embed");
|
||||
</script>
|
|
@ -10,7 +10,6 @@
|
|||
assert_header_equals(j.header, {
|
||||
"cause": undefined,
|
||||
"destination": "",
|
||||
"target": "subresource",
|
||||
"site": "same-origin"
|
||||
});
|
||||
});
|
||||
|
@ -23,7 +22,6 @@
|
|||
assert_header_equals(j.header, {
|
||||
"cause": undefined,
|
||||
"destination": "",
|
||||
"target": "subresource",
|
||||
"site": "same-site"
|
||||
});
|
||||
});
|
||||
|
@ -36,7 +34,6 @@
|
|||
assert_header_equals(j.header, {
|
||||
"cause": undefined,
|
||||
"destination": "",
|
||||
"target": "subresource",
|
||||
"site": "cross-site"
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<div id="test1">1</div>
|
||||
<div id="test2">2</div>
|
||||
<div id="test3">3</div>
|
||||
<!-- Same-Origin request -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: myFirstFont;
|
||||
src: url(https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=font-same-origin);
|
||||
}
|
||||
#test1 {
|
||||
font-family: myFirstFont;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Same-Site request -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: mySecondFont;
|
||||
src: url(https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=font-same-site);
|
||||
}
|
||||
#test2 {
|
||||
font-family: mySecondFont;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Cross-Site request -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: myThirdFont;
|
||||
src: url(https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=font-cross-site);
|
||||
}
|
||||
#test3 {
|
||||
font-family: myThirdFont;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
<script>
|
||||
document.fonts.ready.then(function () {
|
||||
test_same_origin();
|
||||
test_same_site();
|
||||
test_cross_site();
|
||||
});
|
||||
|
||||
function test_same_origin(){
|
||||
var same_origin_test = async_test("Same-Origin font");
|
||||
same_origin_test.step(function () {
|
||||
key = "font-same-origin";
|
||||
expected_same_origin = {"destination":"font", "site":"same-origin"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_origin_xhr = new XMLHttpRequest();
|
||||
same_origin_xhr.open("PUT", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
|
||||
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
|
||||
});
|
||||
same_origin_xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function test_same_site(){
|
||||
var same_site_test = async_test("Same-Site font");
|
||||
same_site_test.step(function () {
|
||||
key = "font-same-site";
|
||||
expected_same_site = {"destination":"font", "site":"same-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_site_xhr = new XMLHttpRequest();
|
||||
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
|
||||
verify_response(same_site_xhr, same_site_test, expected_same_site)
|
||||
});
|
||||
same_site_xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function test_cross_site(){
|
||||
var cross_site_test = async_test("Cross-Site font");
|
||||
cross_site_test.step(function () {
|
||||
key = "font-cross-site";
|
||||
expected_cross_site = {"destination":"font", "site":"cross-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
cross_site_xhr = new XMLHttpRequest();
|
||||
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
|
||||
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
|
||||
});
|
||||
cross_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -13,8 +13,7 @@
|
|||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "nested",
|
||||
"destination": "nested-document",
|
||||
"site": "same-origin"
|
||||
});
|
||||
t.done();
|
||||
|
@ -32,8 +31,7 @@
|
|||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "nested",
|
||||
"destination": "nested-document",
|
||||
"site": "same-site"
|
||||
});
|
||||
t.done();
|
||||
|
@ -51,8 +49,7 @@
|
|||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "nested",
|
||||
"destination": "nested-document",
|
||||
"site": "cross-site"
|
||||
});
|
||||
t.done();
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
|
||||
"cause": undefined,
|
||||
"destination": "image",
|
||||
"target": "subresource",
|
||||
"site": "same-origin"
|
||||
});
|
||||
}),
|
||||
|
@ -29,7 +28,6 @@
|
|||
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
|
||||
"cause": undefined,
|
||||
"destination": "image",
|
||||
"target": "subresource",
|
||||
"site": "same-site"
|
||||
});
|
||||
}),
|
||||
|
@ -44,7 +42,6 @@
|
|||
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
|
||||
"cause": undefined,
|
||||
"destination": "image",
|
||||
"target": "subresource",
|
||||
"site": "cross-site"
|
||||
});
|
||||
}),
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<script>
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let key = "object-same-origin";
|
||||
|
||||
let e = document.createElement('object');
|
||||
e.data = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
|
||||
e.onload = e => {
|
||||
let expected = {"destination":"object", "site":"same-origin"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
|
||||
document.body.appendChild(e);
|
||||
})
|
||||
}, "Same-Origin object");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let key = "object-same-site";
|
||||
|
||||
let e = document.createElement('object');
|
||||
e.data = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
|
||||
e.onload = e => {
|
||||
let expected = {"destination":"object", "site":"same-site"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
|
||||
document.body.appendChild(e);
|
||||
})
|
||||
}, "Same-Site object");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let key = "object-cross-site";
|
||||
|
||||
let e = document.createElement('object');
|
||||
e.data = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
|
||||
e.onload = e => {
|
||||
let expected = {"destination":"object", "site":"cross-site"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
|
||||
document.body.appendChild(e);
|
||||
})
|
||||
}, "Cross-Site object");
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<!-- redirect Cross-Site -> Cross-Site -->
|
||||
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-cross-site"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_cross_site(){
|
||||
var cross_site_test = async_test("Cross-Site -> Cross-Site redirect");
|
||||
cross_site_test.step(function () {
|
||||
filename = "redirect-cross-site-cross-site";
|
||||
expected_cross_site = {"destination":"image", "site":"cross-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
cross_site_xhr = new XMLHttpRequest();
|
||||
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
|
||||
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
|
||||
});
|
||||
cross_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
|
||||
<!-- redirect Cross-Site -> Same-Origin -->
|
||||
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-same-origin"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_same_origin(){
|
||||
var same_origin_test = async_test("Cross-Site -> Same-Origin redirect");
|
||||
same_origin_test.step(function () {
|
||||
filename = "redirect-cross-site-same-origin";
|
||||
expected_same_origin = {"destination":"image", "site":"cross-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_origin_xhr = new XMLHttpRequest();
|
||||
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
|
||||
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
|
||||
});
|
||||
same_origin_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<!-- redirect Cross-Site -> Same-Site -->
|
||||
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-same-site"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_same_site(){
|
||||
var same_site_test = async_test("Cross-Site -> Same-Site redirect");
|
||||
same_site_test.step(function () {
|
||||
filename = "redirect-cross-site-same-site";
|
||||
expected_same_site = {"destination":"image", "site":"cross-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_site_xhr = new XMLHttpRequest();
|
||||
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
|
||||
verify_response(same_site_xhr, same_site_test, expected_same_site)
|
||||
});
|
||||
same_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<!-- redirect Same-Origin -> Cross-Site -->
|
||||
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-cross-site"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_cross_site(){
|
||||
var cross_site_test = async_test("Same-Origin -> Cross-Site redirect");
|
||||
cross_site_test.step(function () {
|
||||
filename = "redirect-same-origin-cross-site";
|
||||
expected_cross_site = {"destination":"image", "site":"same-origin"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
cross_site_xhr = new XMLHttpRequest();
|
||||
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
|
||||
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
|
||||
});
|
||||
cross_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
|
||||
<!-- redirect Same-Origin -> Same-Origin -->
|
||||
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-same-origin"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_same_origin(){
|
||||
var same_origin_test = async_test("Same-Origin -> Same-Origin redirect");
|
||||
same_origin_test.step(function () {
|
||||
filename = "redirect-same-origin-same-origin";
|
||||
expected_same_origin = {"destination":"image", "site":"same-origin"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_origin_xhr = new XMLHttpRequest();
|
||||
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
|
||||
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
|
||||
});
|
||||
same_origin_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
|
||||
<!-- redirect Same-Origin -> Same-Site -->
|
||||
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-same-site"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_same_site(){
|
||||
var same_site_test = async_test("Same-Origin -> Same-Site redirect");
|
||||
same_site_test.step(function () {
|
||||
filename = "redirect-same-origin-same-site";
|
||||
expected_same_site = {"destination":"image", "site":"same-origin"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_site_xhr = new XMLHttpRequest();
|
||||
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
|
||||
verify_response(same_site_xhr, same_site_test, expected_same_site)
|
||||
});
|
||||
same_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
|
||||
<!-- redirect Same-Site -> Cross-Site -->
|
||||
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-cross-site"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_cross_site(){
|
||||
var cross_site_test = async_test("Same-Site -> Cross-Site redirect");
|
||||
cross_site_test.step(function () {
|
||||
key = "redirect-same-site-cross-site";
|
||||
expected_cross_site = {"destination":"image", "site":"same-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
cross_site_xhr = new XMLHttpRequest();
|
||||
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
|
||||
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
|
||||
});
|
||||
cross_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
|
||||
<!-- redirect Same-Site -> Same-Origin -->
|
||||
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-same-origin"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_same_origin(){
|
||||
var same_origin_test = async_test("Same-Site -> Same-Origin redirect");
|
||||
same_origin_test.step(function () {
|
||||
key = "redirect-same-site-same-origin";
|
||||
expected_same_origin = {"destination":"image", "site":"same-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_origin_xhr = new XMLHttpRequest();
|
||||
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
|
||||
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
|
||||
});
|
||||
same_origin_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
|
||||
<!-- redirect Same-Site -> Same-Site -->
|
||||
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-same-site"></img>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_same_site(){
|
||||
var same_site_test = async_test("Same-Site -> Same-Site redirect");
|
||||
same_site_test.step(function () {
|
||||
key = "redirect-same-site-same-site";
|
||||
expected_same_site = {"destination":"image", "site":"same-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_site_xhr = new XMLHttpRequest();
|
||||
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
|
||||
verify_response(same_site_xhr, same_site_test, expected_same_site)
|
||||
});
|
||||
same_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<link id="style" href="https://foo.bar" rel="stylesheet">
|
||||
<body></body>
|
||||
<script>
|
||||
let counter = 0;
|
||||
document.addEventListener("securitypolicyviolation", (e) => {
|
||||
counter++;
|
||||
if (counter == 3) {
|
||||
promise_test(t => {
|
||||
expected = {"destination":"report", "site":"same-origin"};
|
||||
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=report-same-origin")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected));
|
||||
}, "Same-Origin report");
|
||||
|
||||
promise_test(t => {
|
||||
expected = {"destination":"report", "site":"same-site"};
|
||||
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=report-same-site")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected));
|
||||
}, "Same-site report");
|
||||
|
||||
promise_test(t => {
|
||||
expected = {"destination":"report", "site":"cross-site"};
|
||||
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=report-cross-site")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected));
|
||||
}, "Cross-site report");
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,3 @@
|
|||
Content-Security-Policy: style-src 'self' 'unsafe-inline'; report-uri /fetch/sec-metadata/resources/record-header.py?file=report-same-origin
|
||||
Content-Security-Policy: style-src 'self' 'unsafe-inline'; report-uri https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=report-same-site
|
||||
Content-Security-Policy: style-src 'self' 'unsafe-inline'; report-uri https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=report-cross-site
|
|
@ -0,0 +1 @@
|
|||
self.postMessage("Loaded");
|
|
@ -8,5 +8,5 @@ def main(request, response):
|
|||
headers.append(("Access-Control-Allow-Origin", request.headers["origin"]))
|
||||
|
||||
|
||||
body = json.dumps({ "header": request.headers["sec-metadata"] })
|
||||
body = json.dumps({ "header": request.headers.get("sec-metadata", "") })
|
||||
return headers, body
|
||||
|
|
|
@ -3,6 +3,6 @@ import json
|
|||
def main(request, response):
|
||||
headers = [("Content-Type", "text/javascript")]
|
||||
|
||||
body = "var header = %s;" % json.dumps(request.headers["sec-metadata"]);
|
||||
body = "var header = %s;" % json.dumps(request.headers.get("sec-metadata", ""));
|
||||
|
||||
return headers, body
|
||||
|
|
|
@ -9,9 +9,18 @@ function parse_metadata(value) {
|
|||
}
|
||||
|
||||
function assert_header_equals(value, expected) {
|
||||
// check that the returned value is an object, not a String
|
||||
assert_not_equals(value, "", "Empty Sec-Metadata header.");
|
||||
let result = parse_metadata(value);
|
||||
assert_equals(result.cause, expected.cause, "cause");
|
||||
assert_equals(result.destination, expected.destination, "destination");
|
||||
assert_equals(result.target, expected.target, "target");
|
||||
assert_equals(result.site, expected.site, "site");
|
||||
}
|
||||
|
||||
function verify_response(xhr, test, expected){
|
||||
if (xhr.readyState === 4) {
|
||||
assert_header_equals(xhr.responseText, expected);
|
||||
test.done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
import os
|
||||
import uuid
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
resourcePath = os.getcwd() + "/fetch/sec-metadata/resources/"
|
||||
|
||||
def main(request, response):
|
||||
|
||||
## Get the query parameter (key) from URL ##
|
||||
## Tests will record POST requests (CSP Report) and GET (rest) ##
|
||||
if request.GET:
|
||||
key = request.GET['file']
|
||||
elif request.POST:
|
||||
key = request.POST['file']
|
||||
|
||||
## Convert the key from String to UUID valid String ##
|
||||
testId = hashlib.md5(key).hexdigest()
|
||||
|
||||
## Handle the header retrieval request ##
|
||||
if 'retrieve' in request.GET:
|
||||
response.writer.write_status(200)
|
||||
response.writer.end_headers()
|
||||
header_value = request.server.stash.take(testId)
|
||||
if header_value != None:
|
||||
response.writer.write(header_value)
|
||||
|
||||
response.close_connection = True
|
||||
|
||||
## Record incoming Sec-Metadata header value
|
||||
else:
|
||||
## Return empty string as a default value ##
|
||||
header = request.headers.get("Sec-Metadata", "")
|
||||
try:
|
||||
request.server.stash.put(testId, header)
|
||||
except KeyError:
|
||||
## The header is already recorded
|
||||
pass
|
||||
|
||||
## Prevent the browser from caching returned responses and allow CORS ##
|
||||
response.headers.set("Access-Control-Allow-Origin", "*")
|
||||
response.headers.set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
response.headers.set("Pragma", "no-cache")
|
||||
response.headers.set("Expires", "0")
|
||||
|
||||
## Add a valid ServiceWorker Content-Type ##
|
||||
if key.startswith("serviceworker"):
|
||||
response.headers.set("Content-Type", "application/javascript")
|
||||
|
||||
## Return a valid .vtt content for the <track> tag ##
|
||||
if key.startswith("track"):
|
||||
return "WEBVTT"
|
||||
|
||||
## Return a valid SharedWorker ##
|
||||
if key.startswith("sharedworker"):
|
||||
response.headers.set("Content-Type", "application/javascript")
|
||||
file = open(resourcePath + "sharedWorker.js", "r")
|
||||
shared_worker = file.read()
|
||||
file.close()
|
||||
return shared_worker
|
||||
|
||||
## Return a valid font content and Content-Type ##
|
||||
if key.startswith("font"):
|
||||
file = open("fonts/Ahem.ttf", "r")
|
||||
font = file.read()
|
||||
file.close()
|
||||
return font
|
||||
|
||||
## Return a valid audio content and Content-Type ##
|
||||
if key.startswith("audio"):
|
||||
response.headers.set("Content-Type", "audio/mpeg")
|
||||
file = open("media/sound_5.mp3", "r")
|
||||
audio = file.read()
|
||||
file.close()
|
||||
return audio
|
||||
|
||||
## Return a valid video content and Content-Type ##
|
||||
if key.startswith("video"):
|
||||
response.headers.set("Content-Type", "video/mp4")
|
||||
file = open("media/A4.mp4", "r")
|
||||
video = file.read()
|
||||
file.close()
|
||||
return video
|
||||
|
||||
## Return a valid style content and Content-Type ##
|
||||
if key.startswith("style") or key.startswith("embed") or key.startswith("object"):
|
||||
response.headers.set("Content-Type", "text/html")
|
||||
return "<html>EMBED!</html>"
|
||||
|
||||
## Return a valid image content and Content-Type for redirect requests ##
|
||||
if key.startswith("redirect"):
|
||||
response.headers.set("Content-Type", "image/jpeg")
|
||||
file = open("media/1x1-green.png", "r")
|
||||
image = file.read()
|
||||
file.close()
|
||||
return image
|
||||
|
||||
## Return a valid dedicated worker
|
||||
if key.startswith("worker"):
|
||||
response.headers.set("Content-Type", "application/javascript")
|
||||
return "self.postMessage('loaded');"
|
||||
|
||||
## Return a valid XSLT
|
||||
if key.startswith("xslt"):
|
||||
response.headers.set("Content-Type", "text/xsl")
|
||||
return """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:template match="@*|node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*|node()"/>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>"""
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
onconnect = function(e) {
|
||||
var port = e.ports[0];
|
||||
|
||||
port.addEventListener('message', function(e) {
|
||||
port.postMessage("Ready");
|
||||
});
|
||||
|
||||
port.start();
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet href="https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=xslt-same-origin" type="text/xsl" ?>
|
||||
<?xml-stylesheet href="https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=xslt-same-site" type="text/xsl" ?>
|
||||
<?xml-stylesheet href="https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=xslt-cross-site" type="text/xsl" ?>
|
||||
|
||||
<!-- postMessage parent back when the resources are loaded -->
|
||||
<script xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
|
||||
setTimeout(function(){
|
||||
if (window.opener)
|
||||
window.opener.postMessage("", "*");
|
||||
if (window.top != window)
|
||||
window.top.postMessage("", "*");}, 100);
|
||||
]]></script>
|
|
@ -12,7 +12,6 @@
|
|||
assert_header_equals(header, {
|
||||
"cause": undefined,
|
||||
"destination": "script",
|
||||
"target": "subresource",
|
||||
"site": "same-origin"
|
||||
});
|
||||
}, "Same-origin script");
|
||||
|
@ -27,7 +26,6 @@
|
|||
assert_header_equals(header, {
|
||||
"cause": undefined,
|
||||
"destination": "script",
|
||||
"target": "subresource",
|
||||
"site": "same-site"
|
||||
});
|
||||
}, "Same-site script");
|
||||
|
@ -42,7 +40,6 @@
|
|||
assert_header_equals(header, {
|
||||
"cause": undefined,
|
||||
"destination": "script",
|
||||
"target": "subresource",
|
||||
"site": "cross-site"
|
||||
});
|
||||
}, "Cross-site script");
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
navigator.serviceWorker.register('/fetch/sec-metadata/resources/record-header.py?file=serviceworker-same-origin').then(function(registration) {
|
||||
test_same_origin();
|
||||
|
||||
// uninstall the serviceworker after the test
|
||||
navigator.serviceWorker.getRegistrations().then(function(registrations) {
|
||||
for(let registration of registrations) {
|
||||
registration.unregister()
|
||||
}
|
||||
})
|
||||
}, function(err) {
|
||||
// registration failed
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
test(function () {
|
||||
done();
|
||||
}, "Browser does not support serviceworker");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_same_origin(){
|
||||
var same_origin_test = async_test("Same-Origin serviceworker");
|
||||
same_origin_test.step(function () {
|
||||
key = "serviceworker-same-origin";
|
||||
expected_same_origin = {"destination":"serviceworker", "site":"same-origin"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_origin_xhr = new XMLHttpRequest();
|
||||
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
|
||||
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
|
||||
});
|
||||
same_origin_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<script>
|
||||
|
||||
// TESTS //
|
||||
if (window.Worker) {
|
||||
|
||||
// Same-Origin test
|
||||
var sharedWorker = new SharedWorker('/fetch/sec-metadata/resources/record-header.py?file=sharedworker-same-origin');
|
||||
sharedWorker.port.start();
|
||||
|
||||
sharedWorker.onerror = function(){
|
||||
test_same_origin();
|
||||
}
|
||||
sharedWorker.port.onmessage = function(e) {
|
||||
test_same_origin();
|
||||
}
|
||||
sharedWorker.port.postMessage("Ready");
|
||||
}
|
||||
|
||||
function test_same_origin(){
|
||||
var same_origin_test = async_test("Same-Origin sharedworker");
|
||||
same_origin_test.step(function () {
|
||||
key = "sharedworker-same-origin";
|
||||
expected_same_origin = {"destination":"sharedworker", "site":"same-origin"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_origin_xhr = new XMLHttpRequest();
|
||||
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
|
||||
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
|
||||
});
|
||||
same_origin_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<body></body>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<script>
|
||||
function test_same_origin() {
|
||||
var same_origin_test = async_test("Same-Origin style");
|
||||
same_origin_test.step(function () {
|
||||
key = "style-same-origin";
|
||||
expected_same_origin = {"destination":"style", "site":"same-origin"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_origin_xhr = new XMLHttpRequest();
|
||||
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
|
||||
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
|
||||
});
|
||||
same_origin_xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function test_same_site() {
|
||||
var same_site_test = async_test("Same-Site style");
|
||||
same_site_test.step(function () {
|
||||
key = "style-same-site";
|
||||
expected_same_site = {"destination":"style", "site":"same-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
same_site_xhr = new XMLHttpRequest();
|
||||
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
|
||||
verify_response(same_site_xhr, same_site_test, expected_same_site)
|
||||
});
|
||||
same_site_xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function test_cross_site() {
|
||||
var cross_site_test = async_test("Cross-Site style");
|
||||
cross_site_test.step(function () {
|
||||
key = "style-cross-site";
|
||||
expected_cross_site = {"destination":"style", "site":"cross-site"};
|
||||
|
||||
// Requests from the server the saved value of the Sec-Metadata header
|
||||
cross_site_xhr = new XMLHttpRequest();
|
||||
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
|
||||
|
||||
// Async test step triggered when the response is loaded
|
||||
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
|
||||
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
|
||||
});
|
||||
cross_site_xhr.send();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<body>
|
||||
<!-- Same-Origin request -->
|
||||
<link href="https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-same-origin"
|
||||
rel="stylesheet" onload="test_same_origin()" onerror="test_same_origin()">
|
||||
|
||||
<!-- Same-Site request -->
|
||||
<link href="https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-same-site"
|
||||
rel="stylesheet" onload="test_same_site()" onerror="test_same_site()">
|
||||
|
||||
<!-- Cross-Site request -->
|
||||
<link href="https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-cross-site"
|
||||
rel="stylesheet" onload="test_cross_site()" onerror="test_cross_site()">
|
||||
</body>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
function createVideoElement() {
|
||||
let el = document.createElement('video');
|
||||
el.src = "/media/movie_5.mp4";
|
||||
el.setAttribute("controls", "");
|
||||
el.setAttribute("crossorigin", "");
|
||||
return el;
|
||||
}
|
||||
|
||||
function createTrack() {
|
||||
let el = document.createElement("track");
|
||||
el.setAttribute("default", "");
|
||||
el.setAttribute("kind", "captions");
|
||||
el.setAttribute("srclang", "en");
|
||||
return el;
|
||||
}
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let video = createVideoElement();
|
||||
let el = createTrack();
|
||||
el.src = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=track-same-origin";
|
||||
el.onload = t.step_func(_ => {
|
||||
expected = {"destination":"track", "site":"same-origin"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=track-same-origin")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve());
|
||||
});
|
||||
video.appendChild(el);
|
||||
document.body.appendChild(video);
|
||||
});
|
||||
}, "Same-Origin track");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let video = createVideoElement();
|
||||
let el = createTrack();
|
||||
el.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=track-same-site";
|
||||
el.onload = t.step_func(_ => {
|
||||
expected = {"destination":"track", "site":"same-site"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=track-same-site")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
|
||||
});
|
||||
video.appendChild(el);
|
||||
document.body.appendChild(video);
|
||||
});
|
||||
}, "Same-Site track");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let video = createVideoElement();
|
||||
let el = createTrack();
|
||||
el.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=track-cross-site";
|
||||
el.onload = t.step_func(_ => {
|
||||
expected = {"destination":"track", "site":"cross-site"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=track-cross-site")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
video.appendChild(el);
|
||||
document.body.appendChild(video);
|
||||
});
|
||||
}, "Cross-Site track");
|
||||
</script>
|
|
@ -17,7 +17,6 @@
|
|||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-origin"
|
||||
});
|
||||
t.done();
|
||||
|
@ -34,7 +33,6 @@
|
|||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-site"
|
||||
});
|
||||
t.done();
|
||||
|
@ -51,7 +49,6 @@
|
|||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "cross-site"
|
||||
});
|
||||
t.done();
|
||||
|
@ -71,7 +68,6 @@
|
|||
assert_header_equals(e.data, {
|
||||
"cause": "user-activated",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-origin"
|
||||
});
|
||||
t.done();
|
||||
|
@ -93,7 +89,6 @@
|
|||
assert_header_equals(e.data, {
|
||||
"cause": "user-activated",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-site"
|
||||
});
|
||||
t.done();
|
||||
|
@ -115,7 +110,6 @@
|
|||
assert_header_equals(e.data, {
|
||||
"cause": "user-activated",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "cross-site"
|
||||
});
|
||||
t.done();
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<script>
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let key = "worker-same-origin";
|
||||
let w = new Worker("/fetch/sec-metadata/resources/record-header.py?file=" + key);
|
||||
w.onmessage = e => {
|
||||
let expected = {"destination":"worker", "site":"same-origin"};
|
||||
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected))
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
});
|
||||
}, "Same-Origin worker");
|
||||
</script>
|
||||
<body></body>
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<script>
|
||||
// Open a window with XML document which loads resources via <?xml-stylesheet/> tag
|
||||
let w = window.open("resources/xslt-test.sub.xml");
|
||||
window.addEventListener('message', function(e) {
|
||||
if (e.source != w)
|
||||
return;
|
||||
|
||||
promise_test(t => {
|
||||
let expected = {"destination":"xslt", "site":"same-origin"};
|
||||
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=xslt-same-origin")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected));
|
||||
}, "Same-Origin xslt");
|
||||
|
||||
promise_test(t => {
|
||||
let expected = {"destination":"xslt", "site":"same-site"};
|
||||
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=xslt-same-site")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected));
|
||||
}, "Same-site xslt");
|
||||
|
||||
promise_test(t => {
|
||||
let expected = {"destination":"xslt", "site":"cross-site"};
|
||||
return fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=xslt-cross-site")
|
||||
.then(response => response.text())
|
||||
.then(text => assert_header_equals(text, expected));
|
||||
}, "Cross-site xslt");
|
||||
|
||||
w.close();
|
||||
});
|
||||
|
||||
</script>
|
|
@ -1,32 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set">
|
||||
<link ref="help" href="https://xhr.spec.whatwg.org/#dom-formdata">
|
||||
<link rel="help" href="https://fetch.spec.whatwg.org/#concept-bodyinit-extract">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<iframe name="frame1"></iframe>
|
||||
<form accept-charset="iso-8859-1" target="frame1" action="/common/blank.html">
|
||||
<input type="hidden" name="_charset_">
|
||||
<iframe name="frame1" id="frame1"></iframe>
|
||||
<form accept-charset="iso-8859-1" target="frame1" action="/common/blank.html" id="form1">
|
||||
<input type="hidden" name="_charset_">
|
||||
</form>
|
||||
|
||||
<iframe name="frame2" id="frame2"></iframe>
|
||||
<form target="frame2" action="/common/blank.html" id="form2">
|
||||
<input type="text" name="foo">
|
||||
<button type="close" name="close" value="true">close</button>
|
||||
<button type="button" name="button" value="true">button</button>
|
||||
<button type="reset" name="reset" value="true">reset</button>
|
||||
<button type="submit" name="submit" value="true">submit</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
|
||||
const form1 = document.getElementById('form1'),
|
||||
form2 = document.getElementById('form2'),
|
||||
frame1 = document.getElementById('frame1'),
|
||||
frame2 = document.getElementById('frame2');
|
||||
|
||||
test(() => {
|
||||
let formData = new FormData(document.querySelector('form'));
|
||||
const formData = new FormData(form1);
|
||||
assert_equals(formData.get('_charset_'), 'UTF-8');
|
||||
}, 'FormData constructor always produces UTF-8 _charset_ value.');
|
||||
|
||||
let t = async_test('_charset_ control sets the expected encoding name.');
|
||||
t.step(() => {
|
||||
let iframe = document.querySelector('iframe');
|
||||
iframe.onload = t.step_func_done(() => {
|
||||
assert_not_equals(iframe.contentDocument.URL.indexOf('_charset_=windows-1252'), -1);
|
||||
async_test(t => {
|
||||
frame1.onload = t.step_func_done(() => {
|
||||
assert_not_equals(frame1.contentDocument.URL.indexOf('_charset_=windows-1252'), -1);
|
||||
});
|
||||
document.querySelector('form').submit();
|
||||
});
|
||||
form1.submit();
|
||||
}, '_charset_ control sets the expected encoding name.');
|
||||
|
||||
async_test(t => {
|
||||
frame2.onload = t.step_func_done(() => {
|
||||
assert_equals(frame2.contentDocument.URL.split("?")[1], 'foo=&submit=true');
|
||||
});
|
||||
form2.submit.click();
|
||||
}, 'The button cannot be setted if it is not a submitter.');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -1,15 +1,60 @@
|
|||
for (const ev of ["unload", "beforeunload", "pagehide"]) {
|
||||
for (const [ev, target] of [
|
||||
["beforeunload", iframe => iframe.contentWindow],
|
||||
["pagehide", iframe => iframe.contentWindow],
|
||||
["unload", iframe => iframe.contentWindow],
|
||||
["visibilitychange", iframe => iframe.contentDocument],
|
||||
]) {
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
iframe.src = "/common/blank.html";
|
||||
iframe.onload = t.step_func(() => {
|
||||
iframe.contentWindow.addEventListener(ev, t.step_func_done(() => {
|
||||
target(iframe).addEventListener(ev, t.step_func_done(() => {
|
||||
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
|
||||
assert_equals(iframe.contentDocument.open(), iframe.contentDocument);
|
||||
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
|
||||
}));
|
||||
iframe.src = "about:blank";
|
||||
});
|
||||
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event`);
|
||||
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (in top-level browsing context)`);
|
||||
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
iframe.src = "/common/blank.html?1";
|
||||
iframe.onload = t.step_func(() => {
|
||||
const doc = iframe.contentDocument;
|
||||
const innerIframe = doc.body.appendChild(doc.createElement("iframe"));
|
||||
innerIframe.src = "/common/blank.html?2";
|
||||
innerIframe.onload = t.step_func(() => {
|
||||
// Navigate the parent, listen on the child, and open() the parent.
|
||||
target(innerIframe).addEventListener(ev, t.step_func_done(() => {
|
||||
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
|
||||
iframe.contentDocument.open();
|
||||
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
|
||||
}));
|
||||
iframe.src = "about:blank";
|
||||
});
|
||||
});
|
||||
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (open(parent) while unloading parent and child)`);
|
||||
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
iframe.src = "/common/blank.html?1";
|
||||
iframe.onload = t.step_func(() => {
|
||||
const doc = iframe.contentDocument;
|
||||
const innerIframe = doc.body.appendChild(doc.createElement("iframe"));
|
||||
innerIframe.src = "/common/blank.html?2";
|
||||
innerIframe.onload = t.step_func(() => {
|
||||
// Navigate the child, listen on the child, and open() the parent.
|
||||
target(innerIframe).addEventListener(ev, t.step_func_done(() => {
|
||||
assert_not_equals(iframe.contentDocument.childNodes.length, 0);
|
||||
iframe.contentDocument.open();
|
||||
assert_equals(iframe.contentDocument.childNodes.length, 0);
|
||||
}));
|
||||
innerIframe.src = "about:blank";
|
||||
});
|
||||
});
|
||||
}, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (open(parent) while unloading child only)`);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TestDriver bless method</title>
|
||||
<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>
|
||||
promise_test(() => {
|
||||
return test_driver.bless('empty', () => {});
|
||||
}, 'functions in the absence of a `body` element');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
// At the time of this writing, the only standard requirement for user
|
||||
// activation concerns the interaction between iframe elements and their parent
|
||||
// browsing contexts [1]. Because testdriver.js currently cannot operate within
|
||||
// an iframe, the standard requirement cannot be used to verify the correctness
|
||||
// of the `bless` method. Instead, rely on the non-standard restriction on
|
||||
// unattended media playback. Browsers which do not implement such a
|
||||
// restriction will pass this test spuriously.
|
||||
//
|
||||
// [1] https://html.spec.whatwg.org/multipage/origin.html#attr-iframe-sandbox-allow-top-navigation-by-user-activation
|
||||
promise_test(() => {
|
||||
const video = document.createElement('video');
|
||||
video.setAttribute('src', '/media/counting.ogv');
|
||||
document.body.appendChild(video);
|
||||
return test_driver.bless('start video playback', () => video.play())
|
||||
}, 'user activation');
|
||||
|
||||
promise_test(() => {
|
||||
return test_driver.bless('demonstrates return value without action')
|
||||
.then((value) => {
|
||||
assert_equals(value, undefined);
|
||||
});
|
||||
}, 'no action function provided');
|
||||
|
||||
promise_test(() => {
|
||||
const expectedValue = {};
|
||||
|
||||
return test_driver.bless('demonstrate a synchronous return value', () => {
|
||||
return expectedValue;
|
||||
}).then((actualValue) => {
|
||||
assert_equals(
|
||||
actualValue,
|
||||
expectedValue,
|
||||
'the promise should be fulfilled with the returned value'
|
||||
);
|
||||
});
|
||||
|
||||
}, 'synchronous return value');
|
||||
|
||||
promise_test(() => {
|
||||
const expectedError = new Error();
|
||||
|
||||
return test_driver.bless('demonstrates a synchronous error', () => {
|
||||
throw expectedError;
|
||||
})
|
||||
.then(() => {
|
||||
assert_unreached('the promise should be rejected');
|
||||
}, (actualError) => {
|
||||
assert_equals(
|
||||
actualError,
|
||||
expectedError,
|
||||
'the promise should be rejected with the thrown value'
|
||||
);
|
||||
});
|
||||
}, 'synchronous error');
|
||||
|
||||
promise_test(() => {
|
||||
const expectedValue = {};
|
||||
|
||||
return test_driver.bless('demonstrate an asynchronous return value', () => {
|
||||
return Promise.resolve(expectedValue);
|
||||
}).then((actualValue) => {
|
||||
assert_equals(
|
||||
actualValue,
|
||||
expectedValue,
|
||||
'the promise should be fulfilled with the fulfillment value'
|
||||
);
|
||||
});
|
||||
|
||||
}, 'asynchronous return value');
|
||||
|
||||
promise_test(() => {
|
||||
const expectedError = new Error();
|
||||
|
||||
return test_driver.bless('demonstrates an asynchronous error', () => {
|
||||
return Promise.reject(expectedError);
|
||||
})
|
||||
.then(() => {
|
||||
assert_unreached('the promise should be rejected');
|
||||
}, (actualError) => {
|
||||
assert_equals(
|
||||
actualError,
|
||||
expectedError,
|
||||
'the promise should be rejected with the rejected value'
|
||||
);
|
||||
});
|
||||
}, 'asynchronous error');
|
||||
</script>
|
||||
</body>
|
|
@ -1,32 +0,0 @@
|
|||
// GENERATED CONTENT - DO NOT EDIT
|
||||
// Content was automatically extracted by Reffy into reffy-reports
|
||||
// (https://github.com/tidoust/reffy-reports)
|
||||
// Source: Web Budget API (https://wicg.github.io/budget-api/)
|
||||
|
||||
[Exposed=Window]
|
||||
partial interface Navigator {
|
||||
[SameObject] readonly attribute BudgetService budget;
|
||||
};
|
||||
|
||||
[Exposed=Worker]
|
||||
partial interface WorkerNavigator {
|
||||
[SameObject] readonly attribute BudgetService budget;
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface BudgetService {
|
||||
Promise<double> getCost(OperationType operation);
|
||||
Promise<sequence<BudgetState>> getBudget();
|
||||
|
||||
Promise<boolean> reserve(OperationType operation);
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
interface BudgetState {
|
||||
readonly attribute double budgetAt;
|
||||
readonly attribute DOMTimeStamp time;
|
||||
};
|
||||
|
||||
enum OperationType {
|
||||
"silent-push"
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
// GENERATED CONTENT - DO NOT EDIT
|
||||
// Content was automatically extracted by Reffy into reffy-reports
|
||||
// (https://github.com/tidoust/reffy-reports)
|
||||
// Source: MediaStreamTrack Content Hints (https://w3c.github.io/mst-content-hint/)
|
||||
|
||||
partial interface MediaStreamTrack {
|
||||
attribute DOMString contentHint;
|
||||
};
|
3
tests/wpt/web-platform-tests/mst-content-hint/META.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
spec: https://w3c.github.io/mst-content-hint/
|
||||
suggested_reviewers:
|
||||
- alvestrand
|
|
@ -0,0 +1,111 @@
|
|||
<!DOCTYPE HTML>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<canvas id="canvas">
|
||||
</canvas>
|
||||
<script>
|
||||
|
||||
function createAudioTrack() {
|
||||
ac = new AudioContext();
|
||||
var osc = ac.createOscillator();
|
||||
var dest = ac.createMediaStreamDestination();
|
||||
osc.connect(dest);
|
||||
audio_track = dest.stream.getAudioTracks()[0];
|
||||
|
||||
assert_equals(audio_track.kind, "audio");
|
||||
return audio_track;
|
||||
}
|
||||
|
||||
function createVideoTrack() {
|
||||
canvas = document.getElementById("canvas");
|
||||
video_track = canvas.captureStream().getVideoTracks()[0];
|
||||
|
||||
assert_equals(video_track.kind, "video");
|
||||
return video_track;
|
||||
}
|
||||
|
||||
test(t => {
|
||||
audio_track = createAudioTrack();
|
||||
assert_equals("", audio_track.contentHint);
|
||||
|
||||
video_track = createVideoTrack();
|
||||
assert_equals("", video_track.contentHint);
|
||||
}, "Tracks have empty default content hint");
|
||||
|
||||
test(t => {
|
||||
audio_track = createAudioTrack();
|
||||
audio_track.contentHint = "speech";
|
||||
assert_equals(audio_track.contentHint, "speech");
|
||||
audio_track.contentHint = "music";
|
||||
assert_equals(audio_track.contentHint, "music");
|
||||
audio_track.contentHint = "";
|
||||
assert_equals(audio_track.contentHint, "");
|
||||
}, "Accepts valid audio contentHints");
|
||||
|
||||
test(t => {
|
||||
audio_track = createAudioTrack();
|
||||
audio_track.contentHint = "speech";
|
||||
assert_equals(audio_track.contentHint, "speech");
|
||||
audio_track.contentHint = "motion";
|
||||
assert_equals(audio_track.contentHint, "speech",
|
||||
"Audio tracks should ignore video-only contentHints.");
|
||||
audio_track.contentHint = "bogus";
|
||||
assert_equals(audio_track.contentHint, "speech",
|
||||
"Audio tracks should ignore garbage contentHints");
|
||||
}, "Audio tracks ignore invalid/video contentHints");
|
||||
|
||||
test(t => {
|
||||
video_track = createVideoTrack();
|
||||
video_track.contentHint = "motion";
|
||||
assert_equals(video_track.contentHint, "motion");
|
||||
video_track.contentHint = "detail";
|
||||
assert_equals(video_track.contentHint, "detail");
|
||||
video_track.contentHint = "text";
|
||||
assert_equals(video_track.contentHint, "text");
|
||||
video_track.contentHint = "";
|
||||
assert_equals(video_track.contentHint, "");
|
||||
}, "Accepts valid video contentHints");
|
||||
|
||||
test(t => {
|
||||
video_track = createVideoTrack();
|
||||
video_track.contentHint = "motion";
|
||||
assert_equals(video_track.contentHint, "motion");
|
||||
video_track.contentHint = "speech";
|
||||
assert_equals(video_track.contentHint, "motion",
|
||||
"Video tracks should ignore audio-only contentHints.");
|
||||
video_track.contentHint = "bogus";
|
||||
assert_equals(video_track.contentHint, "motion",
|
||||
"Video tracks should ignore garbage contentHints");
|
||||
}, "Video tracks ignore invalid/audio contentHints");
|
||||
|
||||
test(t => {
|
||||
video_track = createVideoTrack();
|
||||
video_track.contentHint = "motion";
|
||||
assert_equals(video_track.contentHint, "motion");
|
||||
|
||||
// Cloning a track should preserve contentHint.
|
||||
video_track_clone = video_track.clone();
|
||||
assert_equals(video_track_clone.contentHint, "motion");
|
||||
|
||||
// Changing a cloned track's contentHint should not change the original.
|
||||
video_track_clone.contentHint = "detail";
|
||||
assert_equals(video_track_clone.contentHint, "detail");
|
||||
assert_equals(video_track.contentHint, "motion");
|
||||
}, "Cloned video tracks have separate contentHints");
|
||||
|
||||
test(t => {
|
||||
audio_track = createAudioTrack();
|
||||
audio_track.contentHint = "speech";
|
||||
assert_equals(audio_track.contentHint, "speech");
|
||||
|
||||
// Cloning a track should preserve contentHint.
|
||||
audio_track_clone = audio_track.clone();
|
||||
assert_equals(audio_track_clone.contentHint, "speech");
|
||||
|
||||
// Changing a cloned track's contentHint should not change the original.
|
||||
audio_track_clone.contentHint = "music";
|
||||
assert_equals(audio_track_clone.contentHint, "music");
|
||||
assert_equals(audio_track.contentHint, "speech");
|
||||
}, "Cloned audio tracks have separate contentHints");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
// META: script=/resources/WebIDLParser.js
|
||||
// META: script=/resources/idlharness.js
|
||||
// META: script=/webrtc/RTCPeerConnection-helper.js
|
||||
|
||||
'use strict';
|
||||
|
||||
idl_test(
|
||||
['mst-content-hint'],
|
||||
['mediacapture-streams', 'dom'],
|
||||
async idl_array => {
|
||||
idl_array.add_objects({
|
||||
MediaStreamTrack: ['audioTrack', 'videoTrack'],
|
||||
});
|
||||
|
||||
const stream = await getNoiseStream({ audio: true, video: true });
|
||||
self.audioTrack = stream.getAudioTracks()[0];
|
||||
self.videoTrack = stream.getVideoTracks()[0];
|
||||
}
|
||||
);
|
|
@ -1,273 +0,0 @@
|
|||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var mojomId = 'device/usb/public/mojom/chooser_service.mojom';
|
||||
if (mojo.internal.isMojomLoaded(mojomId)) {
|
||||
console.warn('The following mojom is loaded multiple times: ' + mojomId);
|
||||
return;
|
||||
}
|
||||
mojo.internal.markMojomLoaded(mojomId);
|
||||
var bindings = mojo;
|
||||
var associatedBindings = mojo;
|
||||
var codec = mojo.internal;
|
||||
var validator = mojo.internal;
|
||||
|
||||
var exports = mojo.internal.exposeNamespace('device.mojom');
|
||||
var device$ =
|
||||
mojo.internal.exposeNamespace('device.mojom');
|
||||
if (mojo.config.autoLoadMojomDeps) {
|
||||
mojo.internal.loadMojomIfNecessary(
|
||||
'device/usb/public/mojom/device.mojom', 'device.mojom.js');
|
||||
}
|
||||
var device_manager$ =
|
||||
mojo.internal.exposeNamespace('device.mojom');
|
||||
if (mojo.config.autoLoadMojomDeps) {
|
||||
mojo.internal.loadMojomIfNecessary(
|
||||
'device/usb/public/mojom/device_manager.mojom', 'device_manager.mojom.js');
|
||||
}
|
||||
|
||||
|
||||
|
||||
function UsbChooserService_GetPermission_Params(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
}
|
||||
|
||||
|
||||
UsbChooserService_GetPermission_Params.prototype.initDefaults_ = function() {
|
||||
this.deviceFilters = null;
|
||||
};
|
||||
UsbChooserService_GetPermission_Params.prototype.initFields_ = function(fields) {
|
||||
for(var field in fields) {
|
||||
if (this.hasOwnProperty(field))
|
||||
this[field] = fields[field];
|
||||
}
|
||||
};
|
||||
|
||||
UsbChooserService_GetPermission_Params.validate = function(messageValidator, offset) {
|
||||
var err;
|
||||
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
var kVersionSizes = [
|
||||
{version: 0, numBytes: 16}
|
||||
];
|
||||
err = messageValidator.validateStructVersion(offset, kVersionSizes);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
|
||||
// validate UsbChooserService_GetPermission_Params.deviceFilters
|
||||
err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(device_manager$.UsbDeviceFilter), false, [0], 0);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
return validator.validationError.NONE;
|
||||
};
|
||||
|
||||
UsbChooserService_GetPermission_Params.encodedSize = codec.kStructHeaderSize + 8;
|
||||
|
||||
UsbChooserService_GetPermission_Params.decode = function(decoder) {
|
||||
var packed;
|
||||
var val = new UsbChooserService_GetPermission_Params();
|
||||
var numberOfBytes = decoder.readUint32();
|
||||
var version = decoder.readUint32();
|
||||
val.deviceFilters = decoder.decodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter));
|
||||
return val;
|
||||
};
|
||||
|
||||
UsbChooserService_GetPermission_Params.encode = function(encoder, val) {
|
||||
var packed;
|
||||
encoder.writeUint32(UsbChooserService_GetPermission_Params.encodedSize);
|
||||
encoder.writeUint32(0);
|
||||
encoder.encodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter), val.deviceFilters);
|
||||
};
|
||||
function UsbChooserService_GetPermission_ResponseParams(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
}
|
||||
|
||||
|
||||
UsbChooserService_GetPermission_ResponseParams.prototype.initDefaults_ = function() {
|
||||
this.result = null;
|
||||
};
|
||||
UsbChooserService_GetPermission_ResponseParams.prototype.initFields_ = function(fields) {
|
||||
for(var field in fields) {
|
||||
if (this.hasOwnProperty(field))
|
||||
this[field] = fields[field];
|
||||
}
|
||||
};
|
||||
|
||||
UsbChooserService_GetPermission_ResponseParams.validate = function(messageValidator, offset) {
|
||||
var err;
|
||||
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
var kVersionSizes = [
|
||||
{version: 0, numBytes: 16}
|
||||
];
|
||||
err = messageValidator.validateStructVersion(offset, kVersionSizes);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
|
||||
// validate UsbChooserService_GetPermission_ResponseParams.result
|
||||
err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, device$.UsbDeviceInfo, true);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
return validator.validationError.NONE;
|
||||
};
|
||||
|
||||
UsbChooserService_GetPermission_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
|
||||
|
||||
UsbChooserService_GetPermission_ResponseParams.decode = function(decoder) {
|
||||
var packed;
|
||||
var val = new UsbChooserService_GetPermission_ResponseParams();
|
||||
var numberOfBytes = decoder.readUint32();
|
||||
var version = decoder.readUint32();
|
||||
val.result = decoder.decodeStructPointer(device$.UsbDeviceInfo);
|
||||
return val;
|
||||
};
|
||||
|
||||
UsbChooserService_GetPermission_ResponseParams.encode = function(encoder, val) {
|
||||
var packed;
|
||||
encoder.writeUint32(UsbChooserService_GetPermission_ResponseParams.encodedSize);
|
||||
encoder.writeUint32(0);
|
||||
encoder.encodeStructPointer(device$.UsbDeviceInfo, val.result);
|
||||
};
|
||||
var kUsbChooserService_GetPermission_Name = 0;
|
||||
|
||||
function UsbChooserServicePtr(handleOrPtrInfo) {
|
||||
this.ptr = new bindings.InterfacePtrController(UsbChooserService,
|
||||
handleOrPtrInfo);
|
||||
}
|
||||
|
||||
function UsbChooserServiceAssociatedPtr(associatedInterfacePtrInfo) {
|
||||
this.ptr = new associatedBindings.AssociatedInterfacePtrController(
|
||||
UsbChooserService, associatedInterfacePtrInfo);
|
||||
}
|
||||
|
||||
UsbChooserServiceAssociatedPtr.prototype =
|
||||
Object.create(UsbChooserServicePtr.prototype);
|
||||
UsbChooserServiceAssociatedPtr.prototype.constructor =
|
||||
UsbChooserServiceAssociatedPtr;
|
||||
|
||||
function UsbChooserServiceProxy(receiver) {
|
||||
this.receiver_ = receiver;
|
||||
}
|
||||
UsbChooserServicePtr.prototype.getPermission = function() {
|
||||
return UsbChooserServiceProxy.prototype.getPermission
|
||||
.apply(this.ptr.getProxy(), arguments);
|
||||
};
|
||||
|
||||
UsbChooserServiceProxy.prototype.getPermission = function(deviceFilters) {
|
||||
var params = new UsbChooserService_GetPermission_Params();
|
||||
params.deviceFilters = deviceFilters;
|
||||
return new Promise(function(resolve, reject) {
|
||||
var builder = new codec.MessageV1Builder(
|
||||
kUsbChooserService_GetPermission_Name,
|
||||
codec.align(UsbChooserService_GetPermission_Params.encodedSize),
|
||||
codec.kMessageExpectsResponse, 0);
|
||||
builder.encodeStruct(UsbChooserService_GetPermission_Params, params);
|
||||
var message = builder.finish();
|
||||
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
|
||||
var reader = new codec.MessageReader(message);
|
||||
var responseParams =
|
||||
reader.decodeStruct(UsbChooserService_GetPermission_ResponseParams);
|
||||
resolve(responseParams);
|
||||
}).catch(function(result) {
|
||||
reject(Error("Connection error: " + result));
|
||||
});
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
function UsbChooserServiceStub(delegate) {
|
||||
this.delegate_ = delegate;
|
||||
}
|
||||
UsbChooserServiceStub.prototype.getPermission = function(deviceFilters) {
|
||||
return this.delegate_ && this.delegate_.getPermission && this.delegate_.getPermission(deviceFilters);
|
||||
}
|
||||
|
||||
UsbChooserServiceStub.prototype.accept = function(message) {
|
||||
var reader = new codec.MessageReader(message);
|
||||
switch (reader.messageName) {
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
UsbChooserServiceStub.prototype.acceptWithResponder =
|
||||
function(message, responder) {
|
||||
var reader = new codec.MessageReader(message);
|
||||
switch (reader.messageName) {
|
||||
case kUsbChooserService_GetPermission_Name:
|
||||
var params = reader.decodeStruct(UsbChooserService_GetPermission_Params);
|
||||
this.getPermission(params.deviceFilters).then(function(response) {
|
||||
var responseParams =
|
||||
new UsbChooserService_GetPermission_ResponseParams();
|
||||
responseParams.result = response.result;
|
||||
var builder = new codec.MessageV1Builder(
|
||||
kUsbChooserService_GetPermission_Name,
|
||||
codec.align(UsbChooserService_GetPermission_ResponseParams.encodedSize),
|
||||
codec.kMessageIsResponse, reader.requestID);
|
||||
builder.encodeStruct(UsbChooserService_GetPermission_ResponseParams,
|
||||
responseParams);
|
||||
var message = builder.finish();
|
||||
responder.accept(message);
|
||||
});
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function validateUsbChooserServiceRequest(messageValidator) {
|
||||
var message = messageValidator.message;
|
||||
var paramsClass = null;
|
||||
switch (message.getName()) {
|
||||
case kUsbChooserService_GetPermission_Name:
|
||||
if (message.expectsResponse())
|
||||
paramsClass = UsbChooserService_GetPermission_Params;
|
||||
break;
|
||||
}
|
||||
if (paramsClass === null)
|
||||
return validator.validationError.NONE;
|
||||
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
|
||||
}
|
||||
|
||||
function validateUsbChooserServiceResponse(messageValidator) {
|
||||
var message = messageValidator.message;
|
||||
var paramsClass = null;
|
||||
switch (message.getName()) {
|
||||
case kUsbChooserService_GetPermission_Name:
|
||||
if (message.isResponse())
|
||||
paramsClass = UsbChooserService_GetPermission_ResponseParams;
|
||||
break;
|
||||
}
|
||||
if (paramsClass === null)
|
||||
return validator.validationError.NONE;
|
||||
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
|
||||
}
|
||||
|
||||
var UsbChooserService = {
|
||||
name: 'device.mojom.UsbChooserService',
|
||||
kVersion: 0,
|
||||
ptrClass: UsbChooserServicePtr,
|
||||
proxyClass: UsbChooserServiceProxy,
|
||||
stubClass: UsbChooserServiceStub,
|
||||
validateRequest: validateUsbChooserServiceRequest,
|
||||
validateResponse: validateUsbChooserServiceResponse,
|
||||
};
|
||||
UsbChooserServiceStub.prototype.validator = validateUsbChooserServiceRequest;
|
||||
UsbChooserServiceProxy.prototype.validator = validateUsbChooserServiceResponse;
|
||||
exports.UsbChooserService = UsbChooserService;
|
||||
exports.UsbChooserServicePtr = UsbChooserServicePtr;
|
||||
exports.UsbChooserServiceAssociatedPtr = UsbChooserServiceAssociatedPtr;
|
||||
})();
|
|
@ -1 +0,0 @@
|
|||
Content-Type: text/javascript; charset=utf-8
|
|
@ -282,6 +282,166 @@
|
|||
encoder.skip(1);
|
||||
encoder.skip(1);
|
||||
};
|
||||
function WebUsbService_GetPermission_Params(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
}
|
||||
|
||||
|
||||
WebUsbService_GetPermission_Params.prototype.initDefaults_ = function() {
|
||||
this.deviceFilters = null;
|
||||
};
|
||||
WebUsbService_GetPermission_Params.prototype.initFields_ = function(fields) {
|
||||
for(var field in fields) {
|
||||
if (this.hasOwnProperty(field))
|
||||
this[field] = fields[field];
|
||||
}
|
||||
};
|
||||
WebUsbService_GetPermission_Params.generate = function(generator_) {
|
||||
var generated = new WebUsbService_GetPermission_Params;
|
||||
generated.deviceFilters = generator_.generateArray(function() {
|
||||
return generator_.generateStruct(device.mojom.UsbDeviceFilter, false);
|
||||
});
|
||||
return generated;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_Params.prototype.mutate = function(mutator_) {
|
||||
if (mutator_.chooseMutateField()) {
|
||||
this.deviceFilters = mutator_.mutateArray(this.deviceFilters, function(val) {
|
||||
return mutator_.mutateStruct(val, device.mojom.UsbDeviceFilter, false);
|
||||
});
|
||||
}
|
||||
return this;
|
||||
};
|
||||
WebUsbService_GetPermission_Params.prototype.getHandleDeps = function() {
|
||||
var handles = [];
|
||||
return handles;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_Params.prototype.setHandles = function() {
|
||||
this.setHandlesInternal_(arguments, 0);
|
||||
};
|
||||
WebUsbService_GetPermission_Params.prototype.setHandlesInternal_ = function(handles, idx) {
|
||||
return idx;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_Params.validate = function(messageValidator, offset) {
|
||||
var err;
|
||||
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
var kVersionSizes = [
|
||||
{version: 0, numBytes: 16}
|
||||
];
|
||||
err = messageValidator.validateStructVersion(offset, kVersionSizes);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
|
||||
// validate WebUsbService_GetPermission_Params.deviceFilters
|
||||
err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(device_manager$.UsbDeviceFilter), false, [0], 0);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
return validator.validationError.NONE;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_Params.encodedSize = codec.kStructHeaderSize + 8;
|
||||
|
||||
WebUsbService_GetPermission_Params.decode = function(decoder) {
|
||||
var packed;
|
||||
var val = new WebUsbService_GetPermission_Params();
|
||||
var numberOfBytes = decoder.readUint32();
|
||||
var version = decoder.readUint32();
|
||||
val.deviceFilters = decoder.decodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter));
|
||||
return val;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_Params.encode = function(encoder, val) {
|
||||
var packed;
|
||||
encoder.writeUint32(WebUsbService_GetPermission_Params.encodedSize);
|
||||
encoder.writeUint32(0);
|
||||
encoder.encodeArrayPointer(new codec.PointerTo(device_manager$.UsbDeviceFilter), val.deviceFilters);
|
||||
};
|
||||
function WebUsbService_GetPermission_ResponseParams(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
}
|
||||
|
||||
|
||||
WebUsbService_GetPermission_ResponseParams.prototype.initDefaults_ = function() {
|
||||
this.result = null;
|
||||
};
|
||||
WebUsbService_GetPermission_ResponseParams.prototype.initFields_ = function(fields) {
|
||||
for(var field in fields) {
|
||||
if (this.hasOwnProperty(field))
|
||||
this[field] = fields[field];
|
||||
}
|
||||
};
|
||||
WebUsbService_GetPermission_ResponseParams.generate = function(generator_) {
|
||||
var generated = new WebUsbService_GetPermission_ResponseParams;
|
||||
generated.result = generator_.generateStruct(device.mojom.UsbDeviceInfo, true);
|
||||
return generated;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_ResponseParams.prototype.mutate = function(mutator_) {
|
||||
if (mutator_.chooseMutateField()) {
|
||||
this.result = mutator_.mutateStruct(this.result, device.mojom.UsbDeviceInfo, true);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
WebUsbService_GetPermission_ResponseParams.prototype.getHandleDeps = function() {
|
||||
var handles = [];
|
||||
return handles;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_ResponseParams.prototype.setHandles = function() {
|
||||
this.setHandlesInternal_(arguments, 0);
|
||||
};
|
||||
WebUsbService_GetPermission_ResponseParams.prototype.setHandlesInternal_ = function(handles, idx) {
|
||||
return idx;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_ResponseParams.validate = function(messageValidator, offset) {
|
||||
var err;
|
||||
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
var kVersionSizes = [
|
||||
{version: 0, numBytes: 16}
|
||||
];
|
||||
err = messageValidator.validateStructVersion(offset, kVersionSizes);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
|
||||
// validate WebUsbService_GetPermission_ResponseParams.result
|
||||
err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, device$.UsbDeviceInfo, true);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
return validator.validationError.NONE;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
|
||||
|
||||
WebUsbService_GetPermission_ResponseParams.decode = function(decoder) {
|
||||
var packed;
|
||||
var val = new WebUsbService_GetPermission_ResponseParams();
|
||||
var numberOfBytes = decoder.readUint32();
|
||||
var version = decoder.readUint32();
|
||||
val.result = decoder.decodeStructPointer(device$.UsbDeviceInfo);
|
||||
return val;
|
||||
};
|
||||
|
||||
WebUsbService_GetPermission_ResponseParams.encode = function(encoder, val) {
|
||||
var packed;
|
||||
encoder.writeUint32(WebUsbService_GetPermission_ResponseParams.encodedSize);
|
||||
encoder.writeUint32(0);
|
||||
encoder.encodeStructPointer(device$.UsbDeviceInfo, val.result);
|
||||
};
|
||||
function WebUsbService_SetClient_Params(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
|
@ -366,7 +526,8 @@
|
|||
};
|
||||
var kWebUsbService_GetDevices_Name = 0;
|
||||
var kWebUsbService_GetDevice_Name = 1;
|
||||
var kWebUsbService_SetClient_Name = 2;
|
||||
var kWebUsbService_GetPermission_Name = 2;
|
||||
var kWebUsbService_SetClient_Name = 3;
|
||||
|
||||
function WebUsbServicePtr(handleOrPtrInfo) {
|
||||
this.ptr = new bindings.InterfacePtrController(WebUsbService,
|
||||
|
@ -426,6 +587,31 @@
|
|||
var message = builder.finish();
|
||||
this.receiver_.accept(message);
|
||||
};
|
||||
WebUsbServicePtr.prototype.getPermission = function() {
|
||||
return WebUsbServiceProxy.prototype.getPermission
|
||||
.apply(this.ptr.getProxy(), arguments);
|
||||
};
|
||||
|
||||
WebUsbServiceProxy.prototype.getPermission = function(deviceFilters) {
|
||||
var params_ = new WebUsbService_GetPermission_Params();
|
||||
params_.deviceFilters = deviceFilters;
|
||||
return new Promise(function(resolve, reject) {
|
||||
var builder = new codec.MessageV1Builder(
|
||||
kWebUsbService_GetPermission_Name,
|
||||
codec.align(WebUsbService_GetPermission_Params.encodedSize),
|
||||
codec.kMessageExpectsResponse, 0);
|
||||
builder.encodeStruct(WebUsbService_GetPermission_Params, params_);
|
||||
var message = builder.finish();
|
||||
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
|
||||
var reader = new codec.MessageReader(message);
|
||||
var responseParams =
|
||||
reader.decodeStruct(WebUsbService_GetPermission_ResponseParams);
|
||||
resolve(responseParams);
|
||||
}).catch(function(result) {
|
||||
reject(Error("Connection error: " + result));
|
||||
});
|
||||
}.bind(this));
|
||||
};
|
||||
WebUsbServicePtr.prototype.setClient = function() {
|
||||
return WebUsbServiceProxy.prototype.setClient
|
||||
.apply(this.ptr.getProxy(), arguments);
|
||||
|
@ -451,6 +637,9 @@
|
|||
WebUsbServiceStub.prototype.getDevice = function(guid, deviceRequestd) {
|
||||
return this.delegate_ && this.delegate_.getDevice && this.delegate_.getDevice(guid, deviceRequestd);
|
||||
}
|
||||
WebUsbServiceStub.prototype.getPermission = function(deviceFilters) {
|
||||
return this.delegate_ && this.delegate_.getPermission && this.delegate_.getPermission(deviceFilters);
|
||||
}
|
||||
WebUsbServiceStub.prototype.setClient = function(client) {
|
||||
return this.delegate_ && this.delegate_.setClient && this.delegate_.setClient(client);
|
||||
}
|
||||
|
@ -491,6 +680,22 @@
|
|||
responder.accept(message);
|
||||
});
|
||||
return true;
|
||||
case kWebUsbService_GetPermission_Name:
|
||||
var params = reader.decodeStruct(WebUsbService_GetPermission_Params);
|
||||
this.getPermission(params.deviceFilters).then(function(response) {
|
||||
var responseParams =
|
||||
new WebUsbService_GetPermission_ResponseParams();
|
||||
responseParams.result = response.result;
|
||||
var builder = new codec.MessageV1Builder(
|
||||
kWebUsbService_GetPermission_Name,
|
||||
codec.align(WebUsbService_GetPermission_ResponseParams.encodedSize),
|
||||
codec.kMessageIsResponse, reader.requestID);
|
||||
builder.encodeStruct(WebUsbService_GetPermission_ResponseParams,
|
||||
responseParams);
|
||||
var message = builder.finish();
|
||||
responder.accept(message);
|
||||
});
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -508,6 +713,10 @@
|
|||
if (!message.expectsResponse() && !message.isResponse())
|
||||
paramsClass = WebUsbService_GetDevice_Params;
|
||||
break;
|
||||
case kWebUsbService_GetPermission_Name:
|
||||
if (message.expectsResponse())
|
||||
paramsClass = WebUsbService_GetPermission_Params;
|
||||
break;
|
||||
case kWebUsbService_SetClient_Name:
|
||||
if (!message.expectsResponse() && !message.isResponse())
|
||||
paramsClass = WebUsbService_SetClient_Params;
|
||||
|
@ -526,6 +735,10 @@
|
|||
if (message.isResponse())
|
||||
paramsClass = WebUsbService_GetDevices_ResponseParams;
|
||||
break;
|
||||
case kWebUsbService_GetPermission_Name:
|
||||
if (message.isResponse())
|
||||
paramsClass = WebUsbService_GetPermission_ResponseParams;
|
||||
break;
|
||||
}
|
||||
if (paramsClass === null)
|
||||
return validator.validationError.NONE;
|
||||
|
@ -548,6 +761,9 @@
|
|||
getDevice: {
|
||||
params: WebUsbService_GetDevice_Params,
|
||||
},
|
||||
getPermission: {
|
||||
params: WebUsbService_GetPermission_Params,
|
||||
},
|
||||
setClient: {
|
||||
params: WebUsbService_SetClient_Params,
|
||||
},
|
||||
|
|
|
@ -13,10 +13,6 @@ let internal = {
|
|||
webUsbService: null,
|
||||
webUsbServiceInterceptor: null,
|
||||
webUsbServiceCrossFrameProxy: null,
|
||||
|
||||
chooser: null,
|
||||
chooserInterceptor: null,
|
||||
chooserCrossFrameProxy: null,
|
||||
};
|
||||
|
||||
// Converts an ECMAScript String object to an instance of
|
||||
|
@ -376,6 +372,17 @@ class FakeWebUsbService {
|
|||
}
|
||||
}
|
||||
|
||||
getPermission(deviceFilters) {
|
||||
return new Promise(resolve => {
|
||||
if (navigator.usb.test.onrequestdevice) {
|
||||
navigator.usb.test.onrequestdevice(
|
||||
new USBDeviceRequestEvent(deviceFilters, resolve));
|
||||
} else {
|
||||
resolve({ result: null });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setClient(client) {
|
||||
this.client_ = client;
|
||||
}
|
||||
|
@ -403,27 +410,6 @@ class USBDeviceRequestEvent {
|
|||
}
|
||||
}
|
||||
|
||||
class FakeChooserService {
|
||||
constructor() {
|
||||
this.bindingSet_ = new mojo.BindingSet(device.mojom.UsbChooserService);
|
||||
}
|
||||
|
||||
addBinding(handle) {
|
||||
this.bindingSet_.addBinding(this, handle);
|
||||
}
|
||||
|
||||
getPermission(deviceFilters) {
|
||||
return new Promise(resolve => {
|
||||
if (navigator.usb.test.onrequestdevice) {
|
||||
navigator.usb.test.onrequestdevice(
|
||||
new USBDeviceRequestEvent(deviceFilters, resolve));
|
||||
} else {
|
||||
resolve({ result: null });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Unlike FakeDevice this class is exported to callers of USBTest.addFakeDevice.
|
||||
class FakeUSBDevice {
|
||||
constructor() {
|
||||
|
@ -472,15 +458,6 @@ class USBTest {
|
|||
internal.webUsbServiceCrossFrameProxy = new CrossFrameHandleProxy(
|
||||
handle => internal.webUsbService.addBinding(handle));
|
||||
|
||||
internal.chooser = new FakeChooserService();
|
||||
internal.chooserInterceptor =
|
||||
new MojoInterfaceInterceptor(device.mojom.UsbChooserService.name);
|
||||
internal.chooserInterceptor.oninterfacerequest =
|
||||
e => internal.chooser.addBinding(e.handle);
|
||||
internal.chooserInterceptor.start();
|
||||
internal.chooserCrossFrameProxy = new CrossFrameHandleProxy(
|
||||
handle => internal.chooser.addBinding(handle));
|
||||
|
||||
// Wait for a call to GetDevices() to pass between the renderer and the
|
||||
// mock in order to establish that everything is set up.
|
||||
await navigator.usb.getDevices();
|
||||
|
@ -498,13 +475,6 @@ class USBTest {
|
|||
e => internal.webUsbServiceCrossFrameProxy.forwardHandle(e.handle);
|
||||
otherWindow.webUsbServiceInterceptor.start();
|
||||
|
||||
otherWindow.chooserInterceptor =
|
||||
new otherWindow.MojoInterfaceInterceptor(
|
||||
device.mojom.UsbChooserService.name);
|
||||
otherWindow.chooserInterceptor.oninterfacerequest =
|
||||
e => internal.chooserCrossFrameProxy.forwardHandle(e.handle);
|
||||
otherWindow.chooserInterceptor.start();
|
||||
|
||||
// Wait for a call to GetDevices() to pass between the renderer and the
|
||||
// mock in order to establish that everything is set up.
|
||||
await otherWindow.navigator.usb.getDevices();
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
def main(request, response):
|
||||
if "clear-vary-value-override-cookie" in request.GET:
|
||||
response.unset_cookie("vary-value-override")
|
||||
return "vary cookie cleared"
|
||||
|
||||
set_cookie_vary = request.GET.first("set-vary-value-override-cookie",
|
||||
default="")
|
||||
if set_cookie_vary:
|
||||
response.set_cookie("vary-value-override", set_cookie_vary)
|
||||
return "vary cookie set"
|
||||
|
||||
# If there is a vary-value-override cookie set, then use its value
|
||||
# for the VARY header no matter what the query string is set to. This
|
||||
# override is necessary to test the case when two URLs are identical
|
||||
# (including query), but differ by VARY header.
|
||||
cookie_vary = request.cookies.get("vary-value-override");
|
||||
if cookie_vary:
|
||||
response.headers.set("vary", cookie_vary)
|
||||
else:
|
||||
# If there is no cookie, then use the query string value, if present.
|
||||
query_vary = request.GET.first("vary", default="")
|
||||
if query_vary:
|
||||
response.headers.set("vary", query_vary)
|
||||
|
||||
return "vary response"
|
|
@ -267,84 +267,4 @@ cache_test(function(cache, test) {
|
|||
'twice.');
|
||||
}, 'Cache.addAll called with the same Request object specified twice');
|
||||
|
||||
cache_test(async function(cache, test) {
|
||||
const url = '../resources/vary.py?vary=x-shape';
|
||||
let requests = [
|
||||
new Request(url, { headers: { 'x-shape': 'circle' }}),
|
||||
new Request(url, { headers: { 'x-shape': 'square' }}),
|
||||
];
|
||||
let result = await cache.addAll(requests);
|
||||
assert_equals(result, undefined, 'Cache.addAll() should succeed');
|
||||
}, 'Cache.addAll should succeed when entries differ by vary header');
|
||||
|
||||
cache_test(async function(cache, test) {
|
||||
const url = '../resources/vary.py?vary=x-shape';
|
||||
let requests = [
|
||||
new Request(url, { headers: { 'x-shape': 'circle' }}),
|
||||
new Request(url, { headers: { 'x-shape': 'circle' }}),
|
||||
];
|
||||
await promise_rejects(
|
||||
test,
|
||||
'InvalidStateError',
|
||||
cache.addAll(requests),
|
||||
'Cache.addAll() should reject when entries are duplicate by vary header');
|
||||
}, 'Cache.addAll should reject when entries are duplicate by vary header');
|
||||
|
||||
// VARY header matching is asymmetric. Determining if two entries are duplicate
|
||||
// depends on which entry's response is used in the comparison. The target
|
||||
// response's VARY header determines what request headers are examined. This
|
||||
// test verifies that Cache.addAll() duplicate checking handles this asymmetric
|
||||
// behavior correctly.
|
||||
cache_test(async function(cache, test) {
|
||||
const base_url = '../resources/vary.py';
|
||||
|
||||
// Define a request URL that sets a VARY header in the
|
||||
// query string to be echoed back by the server.
|
||||
const url = base_url + '?vary=x-size';
|
||||
|
||||
// Set a cookie to override the VARY header of the response
|
||||
// when the request is made with credentials. This will
|
||||
// take precedence over the query string vary param. This
|
||||
// is a bit confusing, but it's necessary to construct a test
|
||||
// where the URL is the same, but the VARY headers differ.
|
||||
//
|
||||
// Note, the test could also pass this information in additional
|
||||
// request headers. If the cookie approach becomes too unwieldy
|
||||
// this test could be rewritten to use that technique.
|
||||
await fetch(base_url + '?set-vary-value-override-cookie=x-shape');
|
||||
test.add_cleanup(_ => fetch(base_url + '?clear-vary-value-override-cookie'));
|
||||
|
||||
let requests = [
|
||||
// This request will result in a Response with a "Vary: x-shape"
|
||||
// header. This *will not* result in a duplicate match with the
|
||||
// other entry.
|
||||
new Request(url, { headers: { 'x-shape': 'circle',
|
||||
'x-size': 'big' },
|
||||
credentials: 'same-origin' }),
|
||||
|
||||
// This request will result in a Response with a "Vary: x-size"
|
||||
// header. This *will* result in a duplicate match with the other
|
||||
// entry.
|
||||
new Request(url, { headers: { 'x-shape': 'square',
|
||||
'x-size': 'big' },
|
||||
credentials: 'omit' }),
|
||||
];
|
||||
await promise_rejects(
|
||||
test,
|
||||
'InvalidStateError',
|
||||
cache.addAll(requests),
|
||||
'Cache.addAll() should reject when one entry has a vary header ' +
|
||||
'matching an earlier entry.');
|
||||
|
||||
// Test the reverse order now.
|
||||
await promise_rejects(
|
||||
test,
|
||||
'InvalidStateError',
|
||||
cache.addAll(requests.reverse()),
|
||||
'Cache.addAll() should reject when one entry has a vary header ' +
|
||||
'matching a later entry.');
|
||||
|
||||
}, 'Cache.addAll should reject when one entry has a vary header ' +
|
||||
'matching another entry');
|
||||
|
||||
done();
|
||||
|
|
|
@ -1,19 +1,37 @@
|
|||
async function wait_for_performance_entries(url) {
|
||||
let entries = performance.getEntriesByName(url);
|
||||
if (entries.length > 0) {
|
||||
return entries;
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
new PerformanceObserver((list) => {
|
||||
const entries = list.getEntriesByName(url);
|
||||
if (entries.length > 0) {
|
||||
resolve(entries);
|
||||
}
|
||||
}).observe({ entryTypes: ['resource'] });
|
||||
});
|
||||
}
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(self.registration.navigationPreload.enable());
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
let headers;
|
||||
event.respondWith(
|
||||
event.preloadResponse
|
||||
.then(response => {
|
||||
var headers = response.headers;
|
||||
return response.text().then(text =>
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
decodedBodySize: headers.get('X-Decoded-Body-Size'),
|
||||
encodedBodySize: headers.get('X-Encoded-Body-Size'),
|
||||
timingEntries: performance.getEntriesByName(event.request.url)
|
||||
}),
|
||||
{headers: {'Content-Type': 'text/html'}}));
|
||||
}));
|
||||
headers = response.headers;
|
||||
return response.text()
|
||||
})
|
||||
.then(_ => wait_for_performance_entries(event.request.url))
|
||||
.then(entries =>
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
decodedBodySize: headers.get('X-Decoded-Body-Size'),
|
||||
encodedBodySize: headers.get('X-Encoded-Body-Size'),
|
||||
timingEntries: entries
|
||||
}),
|
||||
{headers: {'Content-Type': 'text/html'}})));
|
||||
});
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 001</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<circle id="Circle1" cx="120" cy="180" r="100"/>
|
||||
<circle id="Circle2" cx="360" cy="240" r="100"/>
|
||||
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<circle id="Circle1x" cx="120" cy="180" r="80"/>
|
||||
<circle id="Circle2x" cx="360" cy="240" r="80"/>
|
||||
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
|
||||
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
|
||||
</defs>
|
||||
|
||||
<g style="fill:none;stroke:lightblue">
|
||||
<use xlink:href="#Rect1" />
|
||||
<use xlink:href="#Rect2" />
|
||||
<use xlink:href="#Circle1" />
|
||||
<use xlink:href="#Circle2" />
|
||||
</g>
|
||||
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
|
||||
<use xlink:href="#Rect1x" />
|
||||
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
|
||||
<use xlink:href="#Circle1x" />
|
||||
<use xlink:href="#Circle2x" />
|
||||
</g>
|
||||
|
||||
<g id="test-body-reference" style="font-size:16px">
|
||||
<text style="text-anchor:middle">
|
||||
<tspan x="74.1" y="157.3">Lorem</tspan>
|
||||
<tspan x="71" y="177.3">ipsum</tspan>
|
||||
<tspan x="120" y="197.3">dolor sit amet,</tspan>
|
||||
<tspan x="120" y="217.3">consectetur</tspan>
|
||||
<tspan x="360" y="197.2">adipisicing elit,</tspan>
|
||||
<tspan x="360" y="217.2">sed do eiusmod</tspan>
|
||||
<tspan x="401.3" y="237.2">tempor </tspan>
|
||||
</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
69
tests/wpt/web-platform-tests/svg/text/reftests/text-complex-001.svg
Executable file
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 001</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<html:link rel="match" href="text-complex-001-ref.svg" />
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<circle id="Circle1" cx="120" cy="180" r="100"/>
|
||||
<circle id="Circle2" cx="360" cy="240" r="100"/>
|
||||
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<circle id="Circle1x" cx="120" cy="180" r="80"/>
|
||||
<circle id="Circle2x" cx="360" cy="240" r="80"/>
|
||||
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
|
||||
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
|
||||
</defs>
|
||||
|
||||
<g style="fill:none;stroke:lightblue">
|
||||
<use xlink:href="#Rect1" />
|
||||
<use xlink:href="#Rect2" />
|
||||
<use xlink:href="#Circle1" />
|
||||
<use xlink:href="#Circle2" />
|
||||
</g>
|
||||
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
|
||||
<use xlink:href="#Rect1x" />
|
||||
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
|
||||
<use xlink:href="#Circle1x" />
|
||||
<use xlink:href="#Circle2x" />
|
||||
</g>
|
||||
|
||||
<g id="test-body-content" style="font-size:16px;line-spacing:1.25">
|
||||
<text style="shape-inside:url(#Circle1) url(#Circle2);
|
||||
shape-subtract:url(#Rect1) url(#Rect2);
|
||||
shape-padding:20px;
|
||||
text-align: center;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 002</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<circle id="Circle1" cx="360" cy="180" r="100"/>
|
||||
<circle id="Circle2" cx="120" cy="240" r="100"/>
|
||||
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<circle id="Circle1x" cx="360" cy="180" r="80"/>
|
||||
<circle id="Circle2x" cx="120" cy="240" r="80"/>
|
||||
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
|
||||
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
|
||||
</defs>
|
||||
|
||||
<g style="fill:none;stroke:lightblue">
|
||||
<use xlink:href="#Rect1" />
|
||||
<use xlink:href="#Rect2" />
|
||||
<use xlink:href="#Circle1" />
|
||||
<use xlink:href="#Circle2" />
|
||||
</g>
|
||||
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
|
||||
<use xlink:href="#Rect1x" />
|
||||
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
|
||||
<use xlink:href="#Circle1x" />
|
||||
<use xlink:href="#Circle2x" />
|
||||
</g>
|
||||
|
||||
<g id="test-body-reference" style="font-size:16px;direction:rtl">
|
||||
<text style="text-anchor:middle">
|
||||
<tspan x="398.9" y="137.9">لكن</tspan>
|
||||
<tspan x="406.1" y="158.5">لا بد أن</tspan>
|
||||
<tspan x="408.9" y="179.2">أوضح لك</tspan>
|
||||
<tspan x="360.0" y="199.8">أن كل هذه الأفكار</tspan>
|
||||
<tspan x="360" y="220.5">المغلوطة حول</tspan>
|
||||
<tspan x="120" y="197.8">استنكار النشوة</tspan>
|
||||
<tspan x="120" y="218.5">وتمجيد الألم نشأت</tspan>
|
||||
<tspan x="76.0" y="239.1">بالفعل،</tspan>
|
||||
</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 002</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<html:link rel="match" href="text-complex-002-ref.svg" />
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<circle id="Circle1" cx="360" cy="180" r="100"/>
|
||||
<circle id="Circle2" cx="120" cy="240" r="100"/>
|
||||
<rect id="Rect1" x="120" y="80" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<rect id="Rect2" x="120" y="260" width="240" height="80" style="shape-margin: 20px;"/>
|
||||
<circle id="Circle1x" cx="360" cy="180" r="80"/>
|
||||
<circle id="Circle2x" cx="120" cy="240" r="80"/>
|
||||
<rect id="Rect1x" x="100" y="60" width="280" height="120"/>
|
||||
<rect id="Rect2x" x="100" y="240" width="280" height="120"/>
|
||||
</defs>
|
||||
|
||||
<g style="fill:none;stroke:lightblue">
|
||||
<use xlink:href="#Rect1" />
|
||||
<use xlink:href="#Rect2" />
|
||||
<use xlink:href="#Circle1" />
|
||||
<use xlink:href="#Circle2" />
|
||||
</g>
|
||||
<g style="fill:none;stroke:lightblue;stroke-dasharray:5 5">
|
||||
<use xlink:href="#Rect1x" />
|
||||
<use xlink:href="#Rect2x" style="shape-margin: 20px;" />
|
||||
<use xlink:href="#Circle1x" />
|
||||
<use xlink:href="#Circle2x" />
|
||||
</g>
|
||||
|
||||
<g id="test-body-content" style="font-size:16px;line-spacing:1.25;direction:rtl ">
|
||||
<text style="shape-inside:url(#Circle1) url(#Circle2);
|
||||
shape-subtract:url(#Rect1) url(#Rect2);
|
||||
shape-padding:20px;
|
||||
text-align: center;">لكن لا بد أن أوضح لك أن كل هذه الأفكار المغلوطة حول استنكار النشوة وتمجيد الألم نشأت بالفعل، وسأعرض لك التفاصيل</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
77
tests/wpt/web-platform-tests/svg/text/reftests/text-shape-inside-001-ref.svg
Executable file
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 001</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<rect id="TestRect" x="90" y="100" width="300" height="40"/>
|
||||
</defs>
|
||||
|
||||
<g id="test-body-reference" style="font-size:16px">
|
||||
<g transform="translate(0,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text>
|
||||
<tspan x="90" y="114.8">Lorem ipsum dolor sit amet, consectetur</tspan>
|
||||
<tspan x="90" y="134.8">adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g transform="translate(0,60)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="text-anchor:middle">
|
||||
<tspan x="240" y="114.8">Lorem ipsum dolor sit amet, consectetur</tspan>
|
||||
<tspan x="240" y="134.8">adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g transform="translate(0,120)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="text-anchor:end">
|
||||
<tspan x="390" y="114.8">Lorem ipsum dolor sit amet, consectetur</tspan>
|
||||
<tspan x="390" y="134.8">adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g transform="translate(0,180)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text>
|
||||
<tspan x="90" y="114.8">Lorem</tspan>
|
||||
<tspan x="142.9">ipsum</tspan>
|
||||
<tspan x="193.4">dolor</tspan>
|
||||
<tspan x="236.8">sit</tspan>
|
||||
<tspan x="261.2">amet,</tspan>
|
||||
<tspan x="308.9">consectetur</tspan>
|
||||
<tspan x="90" y="134.8">adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
61
tests/wpt/web-platform-tests/svg/text/reftests/text-shape-inside-001.svg
Executable file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 001</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<html:link rel="match" href="text-shape-inside-001-ref.svg" />
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<rect id="TestRect" x="90" y="100" width="300" height="40"/>
|
||||
</defs>
|
||||
|
||||
<g id="test-body-content" style="font-size:16px;line-spacing:1.25">
|
||||
<g transform="translate(0,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect)">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
<g transform="translate(0,60)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect);text-align:center">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
<g transform="translate(0,120)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect);text-align:right">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
<g transform="translate(0,180)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect);text-align:justify">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
76
tests/wpt/web-platform-tests/svg/text/reftests/text-shape-inside-002-ref.svg
Executable file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 002</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<rect id="TestRect" x="90" y="100" width="60" height="200"/>
|
||||
</defs>
|
||||
|
||||
<g id="test-body-reference" style="font-size:16px">
|
||||
<g transform="translate(0,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text transform="translate(250,10) rotate(90)">
|
||||
<tspan x="90" y="114.8">Lorem ipsum dolor sit amet,</tspan>
|
||||
<tspan x="90" y="134.8">consectetur adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g transform="translate(80,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text transform="translate(250,-40) rotate(90)" style="text-anchor:middle">
|
||||
<tspan x="240" y="114.8">Lorem ipsum dolor sit amet,</tspan>
|
||||
<tspan x="240" y="134.8">consectetur adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g transform="translate(160,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text transform="translate(250,-90) rotate(90)" style="text-anchor:end">
|
||||
<tspan x="390" y="114.8">Lorem ipsum dolor sit amet,</tspan>
|
||||
<tspan x="390" y="134.8">consectetur adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g transform="translate(240,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text transform="translate(250,-150) rotate(90)">
|
||||
<tspan x="250" y="114.8">Lorem</tspan>
|
||||
<tspan x="300.3">ipsum</tspan>
|
||||
<tspan x="348.2">dolor</tspan>
|
||||
<tspan x="389">sit</tspan>
|
||||
<tspan x="410.9">amet,</tspan>
|
||||
<tspan x="250" y="134.8">consectetur adipisicing elit,</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
61
tests/wpt/web-platform-tests/svg/text/reftests/text-shape-inside-002.svg
Executable file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="svg-root"
|
||||
width="100%" height="100%" viewBox="0 0 480 360"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<g id="testmeta">
|
||||
<title>Text in Shape — 002</title>
|
||||
<html:link rel="author"
|
||||
title="Tavmjong Bah"
|
||||
href="mailto:tavmjong@free.fr"/>
|
||||
<html:link rel="reviewer"
|
||||
title="NAME_OF_REVIEWER"
|
||||
href="mailto:EMAIL OR http://CONTACT_PAGE" />
|
||||
<!-- YYYY-MM-DD -->
|
||||
<html:link rel="help"
|
||||
href="https://svgwg.org/svg2-draft/text.html#TextShapeInside"/>
|
||||
<html:link rel="match" href="text-shape-inside-002-ref.svg" />
|
||||
<metadata class="flags">TOKENS</metadata>
|
||||
<desc class="assert">TEST ASSERTION</desc>
|
||||
</g>
|
||||
|
||||
<style id="test-font" type="text/css">
|
||||
/* Standard Font (if needed). */
|
||||
@font-face {
|
||||
font-family: FreeSans;
|
||||
src: url("fonts/FreeSans.woff") format("woff"),
|
||||
local("FreeSans");
|
||||
}
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<style id="test-style" type="text/css">
|
||||
/* Style that is being tested (if needed). */
|
||||
text { font-family: FreeSans, sans-serif }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<rect id="TestRect" x="90" y="100" width="60" height="200"/>
|
||||
</defs>
|
||||
|
||||
<g id="test-body-content" style="font-size:16px;line-spacing:1.25;writing-mode:tb-rl">
|
||||
<g transform="translate(0,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect)">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
<g transform="translate(80,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect);text-align:center">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
<g transform="translate(160,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect);text-align:right">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
<g transform="translate(240,0)">
|
||||
<use xlink:href="#TestRect" style="fill:none;stroke:lightblue"/>
|
||||
<text style="shape-inside:url(#TestRect);text-align:justify">Lorem ipsum dolor sit amet, consectetur adipisicing elit,</text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
|
@ -301,6 +301,8 @@ def get_parser():
|
|||
help="Include files in the worktree that are not in version control")
|
||||
parser.add_argument("--show-type", action="store_true",
|
||||
help="Print the test type along with each affected test")
|
||||
parser.add_argument("--null", action="store_true",
|
||||
help="Separate items with a null byte")
|
||||
return parser
|
||||
|
||||
|
||||
|
@ -326,8 +328,11 @@ def run_changed_files(**kwargs):
|
|||
changed, _ = files_changed(revish, kwargs["ignore_rules"],
|
||||
include_uncommitted=kwargs["modified"],
|
||||
include_new=kwargs["new"])
|
||||
|
||||
separator = "\0" if kwargs["null"] else "\n"
|
||||
|
||||
for item in sorted(changed):
|
||||
print(os.path.relpath(item, wpt_root))
|
||||
sys.stdout.write(os.path.relpath(item, wpt_root) + separator)
|
||||
|
||||
|
||||
def run_tests_affected(**kwargs):
|
||||
|
@ -346,6 +351,9 @@ def run_tests_affected(**kwargs):
|
|||
if kwargs["show_type"]:
|
||||
wpt_manifest = load_manifest(manifest_path)
|
||||
message = "{path}\t{item_type}"
|
||||
|
||||
message += "\0" if kwargs["null"] else "\n"
|
||||
|
||||
for item in sorted(tests_changed | dependents):
|
||||
results = {
|
||||
"path": os.path.relpath(item, wpt_root)
|
||||
|
@ -355,4 +363,4 @@ def run_tests_affected(**kwargs):
|
|||
if len(item_types) != 1:
|
||||
item_types = [" ".join(item_types)]
|
||||
results["item_type"] = item_types.pop()
|
||||
print(message.format(**results))
|
||||
sys.stdout.write(message.format(**results))
|
||||
|
|
|
@ -270,6 +270,25 @@ html/browsers/offline/appcache/workers/resources/appcache-worker.py
|
|||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.xfail(sys.platform == "win32",
|
||||
reason="Tests currently don't work on Windows for path reasons")
|
||||
def test_files_changed_null(capsys):
|
||||
commit = "9047ac1d9f51b1e9faa4f9fad9c47d109609ab09"
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
wpt.main(argv=["files-changed", "--null", "%s~..%s" % (commit, commit)])
|
||||
assert excinfo.value.code == 0
|
||||
out, err = capsys.readouterr()
|
||||
assert out == "\0".join(["html/browsers/offline/appcache/workers/appcache-worker.html",
|
||||
"html/browsers/offline/appcache/workers/resources/appcache-dedicated-worker-not-in-cache.js",
|
||||
"html/browsers/offline/appcache/workers/resources/appcache-shared-worker-not-in-cache.js",
|
||||
"html/browsers/offline/appcache/workers/resources/appcache-worker-data.py",
|
||||
"html/browsers/offline/appcache/workers/resources/appcache-worker-import.py",
|
||||
"html/browsers/offline/appcache/workers/resources/appcache-worker.manifest",
|
||||
"html/browsers/offline/appcache/workers/resources/appcache-worker.py",
|
||||
""])
|
||||
assert err == ""
|
||||
|
||||
|
||||
def test_files_changed_ignore():
|
||||
from tools.wpt.testfiles import exclude_ignored
|
||||
files = ["resources/testharness.js", "resources/webidl2/index.js", "test/test.js"]
|
||||
|
@ -304,6 +323,25 @@ def test_tests_affected(capsys, manifest_dir):
|
|||
assert "infrastructure/reftest-wait.html" in out
|
||||
|
||||
|
||||
@pytest.mark.slow # this updates the manifest
|
||||
@pytest.mark.xfail(sys.platform == "win32",
|
||||
reason="Tests currently don't work on Windows for path reasons")
|
||||
def test_tests_affected_null(capsys, manifest_dir):
|
||||
# This doesn't really work properly for random commits because we test the files in
|
||||
# the current working directory for references to the changed files, not the ones at
|
||||
# that specific commit. But we can at least test it returns something sensible.
|
||||
# The test will fail if the file we assert is renamed, so we choose a stable one.
|
||||
commit = "9bf1daa3d8b4425f2354c3ca92c4cf0398d329dd"
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
wpt.main(argv=["tests-affected", "--null", "--metadata", manifest_dir, "%s~..%s" % (commit, commit)])
|
||||
assert excinfo.value.code == 0
|
||||
out, err = capsys.readouterr()
|
||||
|
||||
tests = out.split("\0")
|
||||
assert "dom/interfaces.html" in tests
|
||||
assert "html/dom/interfaces.https.html" in tests
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.xfail(sys.platform == "win32",
|
||||
reason="Tests currently don't work on Windows for path reasons")
|
||||
|
|
|
@ -817,11 +817,12 @@ class InternalRefTestImplementation(object):
|
|||
|
||||
def run_test(self, test):
|
||||
references = self.get_references(test)
|
||||
timeout = (test.timeout * 1000) * self.timeout_multiplier
|
||||
rv = self.executor.protocol.marionette._send_message("reftest:run",
|
||||
{"test": self.executor.test_url(test),
|
||||
"references": references,
|
||||
"expected": test.expected(),
|
||||
"timeout": test.timeout * 1000})["value"]
|
||||
"timeout": timeout})["value"]
|
||||
return rv
|
||||
|
||||
def get_references(self, node):
|
||||
|
|
|
@ -64,25 +64,23 @@ class TestInputFile(TestUsingServer):
|
|||
finally:
|
||||
InputFile.max_buffer_size = old_max_buf
|
||||
|
||||
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
|
||||
def test_iter(self):
|
||||
@wptserve.handlers.handler
|
||||
def handler(request, response):
|
||||
f = request.raw_input
|
||||
return " ".join(line for line in f)
|
||||
return b" ".join(line for line in f)
|
||||
|
||||
route = ("POST", "/test/test_iter", handler)
|
||||
self.server.router.register(*route)
|
||||
resp = self.request(route[1], method="POST", body="12345\nabcdef\r\nzyxwv")
|
||||
resp = self.request(route[1], method="POST", body=b"12345\nabcdef\r\nzyxwv")
|
||||
self.assertEqual(200, resp.getcode())
|
||||
self.assertEqual(["12345\n", "abcdef\r\n", "zyxwv"], resp.read().split(" "))
|
||||
self.assertEqual([b"12345\n", b"abcdef\r\n", b"zyxwv"], resp.read().split(b" "))
|
||||
|
||||
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
|
||||
def test_iter_input_longer_than_buffer(self):
|
||||
@wptserve.handlers.handler
|
||||
def handler(request, response):
|
||||
f = request.raw_input
|
||||
return " ".join(line for line in f)
|
||||
return b" ".join(line for line in f)
|
||||
|
||||
route = ("POST", "/test/test_iter", handler)
|
||||
self.server.router.register(*route)
|
||||
|
@ -90,15 +88,14 @@ class TestInputFile(TestUsingServer):
|
|||
old_max_buf = InputFile.max_buffer_size
|
||||
InputFile.max_buffer_size = 10
|
||||
try:
|
||||
resp = self.request(route[1], method="POST", body="12345\nabcdef\r\nzyxwv")
|
||||
resp = self.request(route[1], method="POST", body=b"12345\nabcdef\r\nzyxwv")
|
||||
self.assertEqual(200, resp.getcode())
|
||||
self.assertEqual(["12345\n", "abcdef\r\n", "zyxwv"], resp.read().split(" "))
|
||||
self.assertEqual([b"12345\n", b"abcdef\r\n", b"zyxwv"], resp.read().split(b" "))
|
||||
finally:
|
||||
InputFile.max_buffer_size = old_max_buf
|
||||
|
||||
|
||||
class TestRequest(TestUsingServer):
|
||||
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
|
||||
def test_body(self):
|
||||
@wptserve.handlers.handler
|
||||
def handler(request, response):
|
||||
|
@ -107,10 +104,9 @@ class TestRequest(TestUsingServer):
|
|||
|
||||
route = ("POST", "/test/test_body", handler)
|
||||
self.server.router.register(*route)
|
||||
resp = self.request(route[1], method="POST", body="12345ab\ncdef")
|
||||
self.assertEqual("12345ab\ncdef", resp.read())
|
||||
resp = self.request(route[1], method="POST", body=b"12345ab\ncdef")
|
||||
self.assertEqual(b"12345ab\ncdef", resp.read())
|
||||
|
||||
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
|
||||
def test_route_match(self):
|
||||
@wptserve.handlers.handler
|
||||
def handler(request, response):
|
||||
|
@ -119,7 +115,7 @@ class TestRequest(TestUsingServer):
|
|||
route = ("GET", "/test/{match}_*", handler)
|
||||
self.server.router.register(*route)
|
||||
resp = self.request("/test/some_route")
|
||||
self.assertEqual("some route", resp.read())
|
||||
self.assertEqual(b"some route", resp.read())
|
||||
|
||||
|
||||
class TestAuth(TestUsingServer):
|
||||
|
|
|
@ -29,8 +29,8 @@ test(t => {
|
|||
|
||||
anim.effect.composite = 'add';
|
||||
const keyframes = anim.effect.getKeyframes();
|
||||
assert_equals(keyframes[0].composite, null,
|
||||
'unspecified keyframe composite value should be null even ' +
|
||||
assert_equals(keyframes[0].composite, 'auto',
|
||||
'unspecified keyframe composite value should be auto even ' +
|
||||
'if effect composite is set');
|
||||
}, 'Unspecified keyframe composite value when setting effect composite');
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ test(t => {
|
|||
const effect = new KeyframeEffect(target, {
|
||||
left: ['10px', '20px']
|
||||
}, { composite });
|
||||
assert_equals(effect.getKeyframes()[0].composite, null,
|
||||
assert_equals(effect.getKeyframes()[0].composite, 'auto',
|
||||
`resulting composite for '${composite}'`);
|
||||
}
|
||||
for (const composite of gBadOptionsCompositeValueTests) {
|
||||
|
@ -98,7 +98,7 @@ test(t => {
|
|||
}, { composite: composite });
|
||||
});
|
||||
}
|
||||
}, 'composite value is null if the composite operation specified on the ' +
|
||||
}, 'composite value is auto if the composite operation specified on the ' +
|
||||
'keyframe effect is being used');
|
||||
|
||||
for (const subtest of gKeyframesTests) {
|
||||
|
|
|
@ -193,21 +193,21 @@ test(() => {
|
|||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
left: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0.5,
|
||||
easing: 'linear',
|
||||
left: '300px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
left: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, 'Keyframes are read from a custom iterator');
|
||||
|
@ -228,21 +228,21 @@ test(() => {
|
|||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
left: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0.5,
|
||||
easing: 'linear',
|
||||
left: '300px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
left: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, '\'easing\' and \'offset\' are ignored on iterable objects');
|
||||
|
@ -261,14 +261,14 @@ test(() => {
|
|||
easing: 'linear',
|
||||
left: '100px',
|
||||
top: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0.5,
|
||||
easing: 'linear',
|
||||
left: '300px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
|
@ -276,7 +276,7 @@ test(() => {
|
|||
easing: 'linear',
|
||||
left: '200px',
|
||||
top: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, 'Keyframes are read from a custom iterator with multiple properties'
|
||||
|
@ -295,21 +295,21 @@ test(() => {
|
|||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
left: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: 0.75,
|
||||
computedOffset: 0.75,
|
||||
easing: 'linear',
|
||||
left: '250px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
left: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, 'Keyframes are read from a custom iterator with where an offset is'
|
||||
|
@ -349,9 +349,9 @@ test(() => {
|
|||
{ done: true },
|
||||
]));
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: null },
|
||||
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: null },
|
||||
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: null },
|
||||
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: 'auto' },
|
||||
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: 'auto' },
|
||||
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: 'auto' },
|
||||
]);
|
||||
}, 'An undefined keyframe returned from a custom iterator should be treated as a'
|
||||
+ ' default keyframe');
|
||||
|
@ -364,9 +364,9 @@ test(() => {
|
|||
{ done: true },
|
||||
]));
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: null },
|
||||
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: null },
|
||||
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: null },
|
||||
{ left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: 'auto' },
|
||||
{ offset: null, computedOffset: 0.5, easing: 'linear', composite: 'auto' },
|
||||
{ left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: 'auto' },
|
||||
]);
|
||||
}, 'A null keyframe returned from a custom iterator should be treated as a'
|
||||
+ ' default keyframe');
|
||||
|
@ -377,7 +377,7 @@ test(() => {
|
|||
{ done: true },
|
||||
]));
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', composite: null }
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', composite: 'auto' }
|
||||
]);
|
||||
}, 'A list of values returned from a custom iterator should be ignored');
|
||||
|
||||
|
@ -437,14 +437,14 @@ test(() => {
|
|||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
height: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
height: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, 'Only enumerable properties on keyframes are read');
|
||||
|
@ -468,14 +468,14 @@ test(() => {
|
|||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
top: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
top: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, 'Only properties defined directly on keyframes are read');
|
||||
|
@ -496,14 +496,14 @@ test(() => {
|
|||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
height: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
height: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, 'Only enumerable properties on property-indexed keyframes are read');
|
||||
|
@ -527,14 +527,14 @@ test(() => {
|
|||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
top: '100px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
top: '200px',
|
||||
composite: null,
|
||||
composite: 'auto',
|
||||
},
|
||||
]);
|
||||
}, 'Only properties defined directly on property-indexed keyframes are read');
|
||||
|
|