Update web-platform-tests to revision 78f764c05c229883e87ad135c7153051a66e2851

This commit is contained in:
WPT Sync Bot 2019-03-06 20:32:15 -05:00
parent 55347aa39f
commit bf84a079f9
1983 changed files with 58006 additions and 31437 deletions

View file

@ -183,7 +183,7 @@ jobs:
- template: tools/ci/azure/install_certs.yml
- template: tools/ci/azure/update_hosts.yml
- template: tools/ci/azure/update_manifest.yml
- script: python ./wpt run --no-manifest-update --no-restart-on-unexpected --no-fail-on-unexpected --install-fonts --test-types reftest testharness --this-chunk $(System.JobPositionInPhase) --total-chunks $(System.TotalJobsInPhase) --chunk-type hash --log-tbpl - --log-tbpl-level info --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report_$(System.JobPositionInPhase).json edge_webdriver
- script: python ./wpt run --no-manifest-update --no-fail-on-unexpected --install-fonts --test-types reftest testharness --this-chunk $(System.JobPositionInPhase) --total-chunks $(System.TotalJobsInPhase) --chunk-type hash --log-tbpl - --log-tbpl-level info --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report_$(System.JobPositionInPhase).json edge_webdriver
displayName: 'Run tests'
- task: PublishBuildArtifacts@1
displayName: 'Publish results'

View file

@ -89,6 +89,7 @@ tasks:
--this-chunk=${chunk[1]}
--total-chunks=${chunk[2]};
- $if: tasks_for == "github-pull-request"
# PR tasks that run the tests in various configurations
then:
# Taskcluster responds to a number of events issued by the GitHub API
# which should not trigger re-validation.
@ -166,3 +167,66 @@ tasks:
--
--channel=${browser.channel}
${operation.extra_args};
- $map:
- name: lint
description: >-
Lint for wpt-specific requirements
script: tools/ci/ci_lint.sh
conditions:
push
pull-request
each(operation):
# Note: jsone doesn't short-circuit evaluation so all parts of the conditional are evaluated
# Accessing properties using the [] notation allows them to evaluate as null in case they're undefined
# TODO: Allow running pushes on branches other than master
- $if: ("push" in operation.conditions && tasks_for == "github-push" && event['ref'] == "refs/heads/master") || ("pull-request" in operation.conditions && tasks_for == "github-pull-request" && event['action'] in ['opened', 'reopened', 'synchronize'])
then:
$let:
checkout_ref:
$if: tasks_for == "github-push"
then:
${event.ref}
else:
refs/pull/${event.number}/merge
in:
taskId: {$eval: 'as_slugid(operation.name)'}
taskGroupId: {$eval: 'as_slugid("task group")'}
created: {$fromNow: ''}
deadline: {$fromNow: '24 hours'}
provisionerId: aws-provisioner-v1
workerType:
$if: event.repository.full_name == 'web-platform-tests/wpt'
then:
wpt-docker-worker
else:
github-worker
metadata:
name: ${operation.name}
description: ${operation.description}
owner: ${event.sender.login}@users.noreply.github.com
source: ${event.repository.url}
payload:
image: harjgam/web-platform-tests:0.29
maxRunTime: 7200
artifacts:
public/results:
path: /home/test/artifacts
type: directory
# Fetch the GitHub-provided merge commit (rather than the pull
# request branch) so that the tasks simulate the behavior of the
# submitted patch after it is merged. Using the merge commit also
# simplifies detection of modified files because the first parent
# of the merge commit can consistently be used to summarize the
# changes.
command:
- /bin/bash
- --login
- -c
- set -ex;
~/start.sh
${event.repository.clone_url}
${checkout_ref}
FETCH_HEAD
none;
cd ~/web-platform-tests;
${operation.script};

View file

@ -28,11 +28,6 @@ matrix:
secure: "EljDx50oNpDLs7rzwIv+z1PxIgB5KMnx1W0OQkpNvltR0rBW9g/aQaE+Z/c8M/sPqN1bkvKPybKzGKjb6j9Dw3/EJhah4SskH78r3yMAe2DU/ngxqqjjfXcCc2t5MKxzHAILTAxqScPj2z+lG1jeK1Z+K5hTbSP9lk+AvS0D16w="
file: $WPT_MANIFEST_FILE.gz
skip_cleanup: true
- name: "lint"
# lint is run both on master and on PRs
os: linux
python: "2.7"
env: JOB=lint SCRIPT=tools/ci/ci_lint.sh
- name: "update-built-tests.sh"
if: type = pull_request
os: linux

View file

@ -198,7 +198,7 @@
("empty", "", None),
("onlyspace", " ", None),
("space", " 100", 100),
("whitespace", "\n\t\f100", 100),
("whitespace", "\r\n\t\f100", 100),
("plus", "+100", 100),
("minus", "-100", None),
("octal", "0100", 100),
@ -235,11 +235,13 @@
for name, string, exp in cases:
code = ""
code, testing, expected = gen(name, string, exp, code)
# We need to replace \r with 
 because \r\n gets converted to \n in the HTML parser.
htmlString = string.replace('\r', '
')
tests.append( {
"name": "size.attributes.parse.%s" % name,
"desc": "Parsing of non-negative integers",
"testing": testing,
"canvas": 'width="%s" height="%s"' % (string, string),
"canvas": 'width="%s" height="%s"' % (htmlString, htmlString),
"code": code,
"expected": expected
} )

View file

@ -4,101 +4,79 @@
<meta name="help" href="https://w3c.github.io/IndexedDB/#inject-key-into-value">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support.js"></script>
<script src="support-promises.js"></script>
<script>
indexeddb_test(
(t, db) => {
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store');
},
(t, db) => {
const tx = db.transaction('store', 'readwrite');
const request = tx.objectStore('store').put(
'value', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'key']);
});
const setter_called = false;
Object.defineProperty(Object.prototype, '10', {
configurable: true,
set: t.step_func((value) => { setter_called = true; }),
});
request.onerror = t.unreached_func('request should not fail');
request.onsuccess = t.step_func(() => {
const result = request.result;
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(
result.hasOwnProperty('10'),
'Result should have own-property overriding prototype setter.');
assert_equals(result[10], 'key',
'Result should have expected property.');
let setter_called = false;
Object.defineProperty(Object.prototype, '10', {
configurable: true,
set: value => { setter_called = true; },
});
t.add_cleanup(() => { delete Object.prototype['10']; });
delete Object.prototype['10'];
t.done();
});
},
'Returning keys to script should bypass prototype setters'
);
const tx = db.transaction('store', 'readwrite');
const result = await promiseForRequest(t, tx.objectStore('store').put(
'value', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'key']));
indexeddb_test(
(t, db) => {
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(result.hasOwnProperty('10'),
'Result should have own-property overriding prototype setter.');
assert_equals(result[10], 'key',
'Result should have expected property.');
}, 'Returning keys to script should bypass prototype setters');
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store', {autoIncrement: true, keyPath: 'id'});
},
(t, db) => {
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const request = tx.objectStore('store').get(1);
});
const setter_called = false;
Object.defineProperty(Object.prototype, 'id', {
configurable: true,
set: t.step_func(function(value) { setter_called = true; }),
});
request.onerror = t.unreached_func('request should not fail');
request.onsuccess = t.step_func(function() {
const result = request.result;
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(
result.hasOwnProperty('id'),
'Result should have own-property overriding prototype setter.');
assert_equals(result.id, 1,
'Own property should match primary key generator value');
let setter_called = false;
Object.defineProperty(Object.prototype, 'id', {
configurable: true,
set: value => { setter_called = true; },
});
t.add_cleanup(() => { delete Object.prototype['id']; });
delete Object.prototype['id'];
t.done();
});
},
'Returning values to script should bypass prototype setters'
);
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const result = await promiseForRequest(t, tx.objectStore('store').get(1));
indexeddb_test(
(t, db) => {
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(result.hasOwnProperty('id'),
'Result should have own-property overriding prototype setter.');
assert_equals(result.id, 1,
'Own property should match primary key generator value');
}, 'Returning values to script should bypass prototype setters');
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store', {autoIncrement: true, keyPath: 'a.b.c'});
},
(t, db) => {
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const request = tx.objectStore('store').get(1);
});
Object.prototype.a = {b: {c: 'on proto'}};
Object.prototype.a = {b: {c: 'on proto'}};
t.add_cleanup(() => { delete Object.prototype.a; });
request.onerror = t.unreached_func('request should not fail');
request.onsuccess = t.step_func(function() {
const result = request.result;
assert_true(result.hasOwnProperty('a'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.hasOwnProperty('b'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.b.hasOwnProperty('c'),
'Result should have own-properties overriding prototype.');
assert_equals(result.a.b.c, 1,
'Own property should match primary key generator value');
assert_equals(Object.prototype.a.b.c, 'on proto',
'Prototype should not be modified');
t.done();
});
},
'Returning values to script should bypass prototype chain'
);
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const result = await promiseForRequest(t, tx.objectStore('store').get(1));
assert_true(result.hasOwnProperty('a'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.hasOwnProperty('b'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.b.hasOwnProperty('c'),
'Result should have own-properties overriding prototype.');
assert_equals(result.a.b.c, 1,
'Own property should match primary key generator value');
assert_equals(Object.prototype.a.b.c, 'on proto',
'Prototype should not be modified');
}, 'Returning values to script should bypass prototype chain');
</script>

View file

@ -0,0 +1,25 @@
// META: global=window,worker
// META: title=Immutability of the global prototype chain
const objects = [];
setup(() => {
for (let object = self; object; object = Object.getPrototypeOf(object)) {
objects.push(object);
}
});
test(() => {
for (const object of objects) {
assert_throws(new TypeError(), () => {
Object.setPrototypeOf(object, {});
});
}
}, "Setting to a different prototype");
test(() => {
for (const object of objects) {
const expected = Object.getPrototypeOf(object);
Object.setPrototypeOf(object, expected);
assert_equals(Object.getPrototypeOf(object), expected);
}
}, "Setting to the same prototype");

0
tests/wpt/web-platform-tests/acid/acid2/reference.html Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid2/reference.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before After
Before After

0
tests/wpt/web-platform-tests/acid/acid2/test.html Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/empty.css Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/empty.html Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/empty.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 260 B

Before After
Before After

0
tests/wpt/web-platform-tests/acid/acid3/empty.txt Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/empty.xml Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/favicon.ico Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/reference.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

View file

0
tests/wpt/web-platform-tests/acid/acid3/support-a.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

0
tests/wpt/web-platform-tests/acid/acid3/support-b.png Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/svg.xml Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 386 B

Before After
Before After

0
tests/wpt/web-platform-tests/acid/acid3/xhtml.1 Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/xhtml.2 Executable file → Normal file
View file

0
tests/wpt/web-platform-tests/acid/acid3/xhtml.3 Executable file → Normal file
View file

View file

@ -48,7 +48,11 @@ async_test(t => {
animation.play();
assert_equals(data, '0.4');
waitForAsyncAnimationFrames(1).then(t.step_func_done(() => {
// wait until local times are synced back to the main thread.
waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(target).opacity != '1';
}).then(t.step_func_done(() => {
assert_equals(getComputedStyle(target).opacity, '0.5');
}));
});

View file

@ -16,7 +16,10 @@
const animation = new WorkletAnimation('constant_time', effect);
animation.play();
await waitForAsyncAnimationFrames(1);
// wait until local times are synced back to the main thread.
await waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(target).opacity != '1';
});
assert_equals(getComputedStyle(target).opacity, "0.5");
}, "Simple worklet animation should output values at specified local time");
</script>

View file

@ -29,7 +29,10 @@
const animation = new WorkletAnimation('test_animator', effect, document.timeline, options);
animation.play();
await waitForAsyncAnimationFrames(1);
// wait until local times are synced back to the main thread.
await waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(target).opacity != '1';
});
assert_equals(getComputedStyle(target).opacity, "0.5");
}, "Animator should be able to use options to update the animation");
</script>

View file

@ -16,6 +16,19 @@ function registerConstantLocalTimeAnimator(localTime) {
`);
}
// TODO(majidvp): This is used to sidestep a bug where we currently animate
// with currentTime=NaN when scroll timeline is not active. Remove once we fix
// http://crbug.com/937456
function registerPassthroughExceptNaNAnimator() {
return runInAnimationWorklet(`
registerAnimator('passthrough_except_nan', class {
animate(currentTime, effect) {
if (Number.isNaN(currentTime)) return;
effect.localTime = currentTime;
}
});
`);
}
function runInAnimationWorklet(code) {
return CSS.animationWorklet.addModule(

View file

@ -33,7 +33,11 @@ runInAnimationWorklet(
const effect = new KeyframeEffect(target, [{ opacity: 0 }], { duration: 1000 });
const animation = new WorkletAnimation('iframe_animator', effect);
animation.play();
waitForAnimationFrames(2).then(_ => {
// wait until local times are synced back to the main thread.
waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(target).opacity != '1';
}).then(_ => {
window.parent.postMessage(getComputedStyle(target).opacity, '*');
});
});

View file

@ -57,14 +57,15 @@ function createAndPlayTestAnimation(elements, timeline_orientation) {
timeRange: 1000,
orientation: timeline_orientation
});
const animation = new WorkletAnimation('passthrough', effect, timeline);
const animation = new WorkletAnimation('passthrough_except_nan', effect, timeline);
animation.play();
return animation;
}
setup(setupAndRegisterTests, {explicit_done: true});
function setupAndRegisterTests() {
registerPassthroughAnimator().then(() => {
registerPassthroughExceptNaNAnimator().then(() => {
// Note that block horizontal-tb is tested implicitly in the basic
// ScrollTimeline tests (as it is the default).
async_test(
@ -90,14 +91,14 @@ function setupAndRegisterTests() {
function block_vertical_lr(t) {
const elements = createTestDOM(true, 'vertical-lr', 'ltr');
createAndPlayTestAnimation(elements, 'block');
const animation = createAndPlayTestAnimation(elements, 'block');
// Move the scroller to the 25% point.
const maxScroll =
elements.scroller.scrollWidth - elements.scroller.clientWidth;
elements.scroller.scrollLeft = 0.25 * maxScroll;
waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
assert_equals(
getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
}));
@ -105,7 +106,7 @@ function block_vertical_lr(t) {
function block_vertical_rl(t) {
const elements = createTestDOM(true, 'vertical-rl', 'ltr');
createAndPlayTestAnimation(elements, 'block');
const animation = createAndPlayTestAnimation(elements, 'block');
// Move the scroller to the 75% point. Since it is vertical-rl, this is
// equivalent to the 25% point for the ScrollTimeline.
@ -113,7 +114,7 @@ function block_vertical_rl(t) {
elements.scroller.scrollWidth - elements.scroller.clientWidth;
elements.scroller.scrollLeft = 0.75 * maxScroll;
waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
assert_equals(
getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
}));
@ -121,7 +122,7 @@ function block_vertical_rl(t) {
function inline_horizontal_tb_rtl(t) {
const elements = createTestDOM(true, 'horizontal-tb', 'rtl');
createAndPlayTestAnimation(elements, 'inline');
const animation = createAndPlayTestAnimation(elements, 'inline');
// Move the scroller to the 75% point. Since it is direction: rtl, this is
// equivalent to the 25% point for the ScrollTimeline.
@ -129,7 +130,7 @@ function inline_horizontal_tb_rtl(t) {
elements.scroller.scrollWidth - elements.scroller.clientWidth;
elements.scroller.scrollLeft = 0.75 * maxScroll;
waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
assert_equals(
getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
}));
@ -137,14 +138,14 @@ function inline_horizontal_tb_rtl(t) {
function inline_vertical_writing_mode_ltr(t) {
const elements = createTestDOM(false, 'vertical-lr', 'ltr');
createAndPlayTestAnimation(elements, 'inline');
const animation = createAndPlayTestAnimation(elements, 'inline');
// Move the scroller to the 25% point.
const maxScroll =
elements.scroller.scrollHeight - elements.scroller.clientHeight;
elements.scroller.scrollTop = 0.25 * maxScroll;
waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
assert_equals(
getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
}));
@ -152,7 +153,7 @@ function inline_vertical_writing_mode_ltr(t) {
function inline_vertical_writing_mode_rtl(t) {
const elements = createTestDOM(false, 'vertical-lr', 'rtl');
createAndPlayTestAnimation(elements, 'inline');
const animation = createAndPlayTestAnimation(elements, 'inline');
// Move the scroller to the 75% point. Since this is a vertical writing mode
// and direction: rtl, this is 25% of the ScrollTimeline currentTime.
@ -160,7 +161,7 @@ function inline_vertical_writing_mode_rtl(t) {
elements.scroller.scrollHeight - elements.scroller.clientHeight;
elements.scroller.scrollTop = 0.75 * maxScroll;
waitForAsyncAnimationFrames(2).then(t.step_func_done(() => {
waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
assert_equals(
getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
}));

View file

@ -0,0 +1,74 @@
<html class="reftest-wait">
<title>Scroll timeline with WorkletAnimation and transition from display:none to display:block</title>
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
<meta name="assert" content="Scroll timeline should properly handle going from display:none to display:block">
<link rel="match" href="worklet-animation-with-scroll-timeline-ref.html">
<script src="/web-animations/testcommon.js"></script>
<script src="/common/reftest-wait.js"></script>
<script src="common.js"></script>
<style>
#box {
width: 100px;
height: 100px;
background-color: green;
}
#covered {
width: 100px;
height: 100px;
background-color: red;
}
#scroller {
overflow: auto;
height: 100px;
width: 100px;
}
.removed {
display: none;
}
#contents {
height: 1000px;
width: 100%;
}
</style>
<div id="box"></div>
<div id="covered"></div>
<div id="scroller">
<div id="contents"></div>
</div>
<script>
registerPassthroughAnimator().then(()=>{
const box = document.getElementById('box');
const effect = new KeyframeEffect(box,
[
{ transform: 'translateY(0)', opacity: 1 },
{ transform: 'translateY(200px)', opacity: 0 }
], {
duration: 1000,
}
);
const scroller = document.getElementById('scroller');
scroller.classList.add('removed');
const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
const animation = new WorkletAnimation('passthrough', effect, timeline);
animation.play();
waitForAsyncAnimationFrames(1).then(_ => {
scroller.classList.remove('removed');
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
waitForAsyncAnimationFrames(1).then(_ => {
takeScreenshot();
});
});
});
</script>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<title>Scroll timeline with WorkletAnimation using a scroller with overflow hidden</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: green;
transform: translate(0, 100px);
opacity: 0.5;
}
#covered {
width: 100px;
height: 100px;
background-color: red;
}
#scroller {
overflow: hidden;
height: 100px;
width: 100px;
}
#contents {
height: 1000px;
width: 100%;
}
</style>
<div id="box"></div>
<div id="covered"></div>
<div id="scroller">
<div id="contents"></div>
</div>
<script>
window.addEventListener('load', function() {
// Move the scroller to halfway.
const scroller = document.getElementById("scroller");
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
});
</script>

View file

@ -0,0 +1,68 @@
<html class="reftest-wait">
<title>Scroll timeline with WorkletAnimation using a scroller with overflow hidden</title>
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
<meta name="assert" content="Worklet animation correctly updates values when using a overflow: hidden on the scroller being used as the source for the ScrollTimeline">
<link rel="match" href="worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html">
<script src="/web-animations/testcommon.js"></script>
<script src="/common/reftest-wait.js"></script>
<script src="common.js"></script>
<style>
#box {
width: 100px;
height: 100px;
background-color: green;
}
#covered {
width: 100px;
height: 100px;
background-color: red;
}
#scroller {
overflow: hidden;
height: 100px;
width: 100px;
}
#contents {
height: 1000px;
width: 100%;
}
</style>
<div id="box"></div>
<div id="covered"></div>
<div id="scroller">
<div id="contents"></div>
</div>
<script>
registerPassthroughAnimator().then(_ => {
const box = document.getElementById('box');
const effect = new KeyframeEffect(box,
[
{transform: 'translateY(0)', opacity: 1},
{transform: 'translateY(200px)', opacity: 0}
], {
duration: 1000,
}
);
const scroller = document.getElementById('scroller');
const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
const animation = new WorkletAnimation('passthrough', effect, timeline);
animation.play();
// Move the scroller to the halfway point.
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(box).transform != 'matrix(1, 0, 0, 1, 0, 0)';
}).then(_ => {
takeScreenshot();
});
});
</script>

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<title>Reference for Animation Worklet with scroll timeline tests</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: green;
transform: translate(0, 100px);
opacity: 0.5;
}
#covered {
width: 100px;
height: 100px;
background-color: red;
}
#scroller {
overflow: auto;
height: 100px;
width: 100px;
/* TODO(yigu): Rewrite the test to not rely on compositing. */
will-change: transform;
}
#contents {
height: 1000px;
width: 100%;
}
</style>
<div id="box"></div>
<div id="covered"></div>
<div id="scroller">
<div id="contents"></div>
</div>
<script>
window.addEventListener('load', function() {
// Move the scroller to halfway.
const scroller = document.getElementById("scroller");
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
});
</script>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<title>Reference for Scroll timeline with WorkletAnimation using the root scroller</title>
<style>
html {
min-height: 100%;
min-width: 100%;
padding-bottom: 100px;
padding-right: 100px;
}
#box {
width: 100px;
height: 100px;
background-color: green;
transform: translate(0, 100px);
opacity: 0.5;
}
#covered {
width: 100px;
height: 100px;
background-color: red;
}
</style>
<div id="box"></div>
<div id="covered"></div>
<script>
window.addEventListener('load', function() {
// Move the scroller to halfway.
const scroller = document.scrollingElement;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
});
</script>

View file

@ -0,0 +1,62 @@
<html class="reftest-wait">
<title>Scroll timeline with WorkletAnimation using the root scroller</title>
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
<meta name="assert" content="Worklet animation correctly updates values when using the root scroller as the source for the ScrollTimeline">
<link rel="match" href="worklet-animation-with-scroll-timeline-root-scroller-ref.html">
<script src="/web-animations/testcommon.js"></script>
<script src="/common/reftest-wait.js"></script>
<script src="common.js"></script>
<style>
html {
min-height: 100%;
min-width: 100%;
padding-bottom: 100px;
padding-right: 100px;
}
#box {
width: 100px;
height: 100px;
background-color: green;
}
#covered {
width: 100px;
height: 100px;
background-color: red;
}
</style>
<div id="box"></div>
<div id="covered"></div>
<script>
registerPassthroughAnimator().then(()=>{
const box = document.getElementById('box');
const effect = new KeyframeEffect(box,
[
{transform: 'translateY(0)', opacity: 1},
{transform: 'translateY(200px)', opacity: 0}
], {
duration: 1000,
}
);
const scroller = document.scrollingElement;
const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
const animation = new WorkletAnimation('passthrough', effect, timeline);
animation.play();
// Move the scroller to the halfway point.
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(box).transform != 'matrix(1, 0, 0, 1, 0, 0)';
}).then(_ => {
takeScreenshot();
});
});
</script>

View file

@ -0,0 +1,67 @@
<html class="reftest-wait">
<title>Basic use of scroll timeline with WorkletAnimation</title>
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
<meta name="assert" content="Should be able to use the scroll timeline to drive the worklet animation timing">
<link rel="match" href="worklet-animation-with-scroll-timeline-ref.html">
<script src="/web-animations/testcommon.js"></script>
<script src="/common/reftest-wait.js"></script>
<script src="common.js"></script>
<style>
#box {
width: 100px;
height: 100px;
background-color: green;
}
#covered {
width: 100px;
height: 100px;
background-color: red;
}
#scroller {
overflow: auto;
height: 100px;
width: 100px;
}
#contents {
height: 1000px;
width: 100%;
}
</style>
<div id="box"></div>
<div id="covered"></div>
<div id="scroller">
<div id="contents"></div>
</div>
<script>
registerPassthroughAnimator().then(() => {
const box = document.getElementById('box');
const effect = new KeyframeEffect(box,
[
{ transform: 'translateY(0)', opacity: 1},
{ transform: 'translateY(200px)', opacity: 0}
], {
duration: 1000,
}
);
const scroller = document.getElementById('scroller');
const timeline = new ScrollTimeline({ scrollSource: scroller, timeRange: 1000, orientation: 'block' });
const animation = new WorkletAnimation('passthrough', effect, timeline);
animation.play();
// Move the scroller to the halfway point.
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
waitForAsyncAnimationFrames(1).then(_ => {
takeScreenshot();
});
});
</script>

View file

@ -1,44 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>Test setSinkId behavior </title>
<div id='log'></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
"use strict";
const audio = new Audio();
promise_test(t => audio.setSinkId(""), "setSinkId on default audio output should always work");
promise_test(t => promise_rejects(t, "NotFoundError", audio.setSinkId("nonexistent_device_id")),
"setSinkId fails with NotFoundError on made up deviceid");
promise_test(async t => {
const list = await navigator.mediaDevices.enumerateDevices();
const outputDevicesList = list.filter(({kind}) => kind == "audiooutput");
assert_not_equals(outputDevicesList.length, 0,
"media device list includes at least one audio output device");
let acceptedDevices = 0;
for (const {deviceId} of outputDevicesList) {
const {deviceId} = outputDevicesList[0];
const p1 = audio.setSinkId(deviceId);
assert_equals(audio.sinkId, "", "before it resolves, setSinkId is unchanged");
try {
let r = await p1;
assert_equals(acceptedDevices, 0, "only the default sink device can be set");
acceptedDevices++;
assert_equals(r, undefined, "setSinkId resolves with undefined");
assert_equals(audio.sinkId, deviceId, "when it resolves, setSinkId updates sinkId to the requested deviceId");
r = await audio.setSinkId(deviceId);
assert_equals(r, undefined, "resetting sinkid on same current value should always work");
r = await audio.setSinkId("");
assert_equals(r, undefined, "resetting sinkid on default audio output should always work");
} catch (e) {
assert_equals(e.name, "NotAllowedError", "Non-default devices are failing with NotAllowed error");
}
}
}, "List device, setSinkId should be allowed on the default, the rest of the devices will get a NotAllowedError");
</script>

View file

@ -1,5 +1,6 @@
<html>
<title>Accept-CH-Lifetime test with same-origin iframe</title>
<meta name="timeout" content="long">
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View file

@ -1,5 +1,6 @@
<html>
<title>Accept-CH-Lifetime test with subresource</title>
<meta name="timeout" content="long">
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View file

@ -18,3 +18,5 @@ def main(request, response):
response.headers.set("downlink-received", request.headers.get("downlink"))
if "ect" in request.headers:
response.headers.set("ect-received", request.headers.get("ect"))
if "Sec-CH-Lang" in request.headers:
response.headers.set("lang-received", request.headers.get("Sec-CH-Lang"))

View file

@ -1,5 +1,5 @@
<html>
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect">
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang">
<title>Accept-CH http-equiv insecure transport test</title>
<body>
<script src="/resources/testharness.js"></script>
@ -27,6 +27,7 @@ promise_test(t => {
assert_false(r.headers.has("rtt-received"), "rtt-received");
assert_false(r.headers.has("downlink-received"), "downlink-received");
assert_false(r.headers.has("ect-received"), "ect-received");
assert_false(r.headers.has("lang-received"), "lang-received");
});
}, "Accept-CH http-equiv test over insecure transport");

View file

@ -1,5 +1,5 @@
<html>
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect">
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang">
<title>Accept-CH http-equiv cross-navigation test</title>
<body>
<script src="/resources/testharness.js"></script>
@ -39,9 +39,9 @@ promise_test(t => {
// not persisted for the origin.
window.open("resources/do_not_expect_client_hints_headers.html");
async_test(t => {
window.addEventListener('message', function(event) {
t.done();
})
window.addEventListener('message', t.step_func_done(e => {
assert_equals(e.data, 'PASS');
}));
}, "Loading of resources/do_not_expect_client_hints_headers.html did not finish.");
</script>

View file

@ -1,5 +1,5 @@
<html>
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect">
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect, lang">
<title>Accept-CH http-equiv same-origin and cross-origin test</title>
<body>
<script src="/resources/testharness.js"></script>
@ -38,6 +38,8 @@ promise_test(t => {
assert_in_array(r.headers.get("ect-received"), ["slow-2g", "2g",
"3g", "4g"], 'ect-received is unexpected');
assert_true(r.headers.has("lang-received"), "lang-received");
});
}, "Same origin Accept-CH http-equiv test");
@ -52,6 +54,7 @@ promise_test(t => {
assert_false(r.headers.has("rtt-received"), "rtt-received");
assert_false(r.headers.has("downlink-received"), "downlink-received");
assert_false(r.headers.has("ect-received"), "ect-received");
assert_false(r.headers.has("lang-received"), "lang-received");
});
}, "Cross-Origin Accept-CH http-equiv test");

View file

@ -1,5 +1,6 @@
<html>
<title>Accept-CH-Lifetime test with same-origin iframe</title>
<meta name="timeout" content="long">
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View file

@ -1,5 +1,6 @@
<html>
<title>Accept-CH-Lifetime test with subresource</title>
<meta name="timeout" content="long">
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View file

@ -5,6 +5,14 @@
"html-aria/combobox-autocomplete-list/div-haswarn.html": "The \u201ctextbox\u201d role is unnecessary for an \u201cinput\u201d element that has no \u201clist\u201d attribute and whose type is \u201ctext\u201d.",
"html-aria/host-language/implicit-semantics-checkbox-disparity-haswarn.html": "The \u201ccheckbox\u201d role is unnecessary for element \u201cinput\u201d whose type is \u201ccheckbox\u201d.",
"html-aria/host-language/implicit-semantics-checkbox-role-haswarn.html": "The \u201ccheckbox\u201d role is unnecessary for element \u201cinput\u201d whose type is \u201ccheckbox\u201d.",
"html-aria/live-events/test-case-live-event-1-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-aria/name-computation-general/597-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-aria/name-computation-general/598-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-aria/name-computation-general/599-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-aria/name-computation-img/557-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-aria/name-computation-img/565-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-aria/name-computation-img/566-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-aria/properties-global-norole/properties-global-norole-aria-label-Test-string-value-haswarn.html": "Possible misuse of \u201caria-label\u201d. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)",
"html-rdfa/0019-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cdiv\u201d at this point.",
"html-rdfa/0035-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cimg\u201d at this point.",
"html-rdfa/0037-novalid.html": "Attribute \u201chref\u201d not allowed on element \u201cimg\u201d at this point.",

View file

@ -15,6 +15,36 @@
t2.done();
}));
}, "Event is fired");
async_test(function(t3) {
var observer = new ReportingObserver(function(reports, observer) {
t3.step(function() {
assert_equals(reports.length, 1);
// Ensure that the contents of the report are valid.
var base_url = "{{location[scheme]}}://{{location[host]}}/content-security-policy/"
var document_url = base_url + "reporting-api/reporting-api-sends-reports-on-violation.https.sub.html";
assert_equals(reports[0].type, "csp-violation");
assert_equals(reports[0].url, document_url);
assert_equals(reports[0].body.documentURL, document_url);
assert_equals(reports[0].body.referrer, null);
assert_equals(reports[0].body.blockedURL,
base_url + "support/fail.png");
assert_equals(reports[0].body.effectiveDirective, "img-src");
assert_equals(reports[0].body.originalPolicy,
"script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-group");
assert_equals(reports[0].body.sourceFile, document_url);
assert_equals(reports[0].body.sample, null);
assert_equals(reports[0].body.disposition, "enforce");
assert_equals(reports[0].body.statusCode, 0);
assert_equals(reports[0].body.lineNumber, 53);
assert_equals(reports[0].body.columnNumber, 0);
});
t3.done();
});
observer.observe();
}, "Report is observable to ReportingObserver");
</script>
<img src='/content-security-policy/support/fail.png'
onload='t1.unreached_func("The image should not have loaded");'

View file

@ -38,7 +38,7 @@
span
{
background-color: yellow;
font-size: large;
font-size: larger;
}
</style>

View file

@ -374,12 +374,12 @@ test(t => {
assert_equals(animations[1].effect.target.type, '::before',
'The animation targeting the ::before pseudo-element ' +
'should be returned second');
assert_equals(animations[1].effect.target.parentElement, parent,
assert_equals(animations[1].effect.target.element, parent,
'This ::before element should be child of parent element');
assert_equals(animations[2].effect.target.type, '::after',
'The animation targeting the ::after pesudo-element ' +
'should be returned third');
assert_equals(animations[2].effect.target.parentElement, parent,
assert_equals(animations[2].effect.target.element, parent,
'This ::after element should be child of parent element');
assert_equals(animations[3].effect.target, child,
@ -388,12 +388,12 @@ test(t => {
assert_equals(animations[4].effect.target.type, '::before',
'The animation targeting the ::before pseudo-element ' +
'should be returned fifth');
assert_equals(animations[4].effect.target.parentElement, child,
assert_equals(animations[4].effect.target.element, child,
'This ::before element should be child of child element');
assert_equals(animations[5].effect.target.type, '::after',
'The animation targeting the ::after pesudo-element ' +
'should be returned last');
assert_equals(animations[5].effect.target.parentElement, child,
assert_equals(animations[5].effect.target.element, child,
'This ::after element should be child of child element');
}, '{ subtree: true } on an element with a child returns animations from the'
+ ' element, its pseudo-elements, its child and its child pseudo-elements');

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Flexbox Test: Indefinite % flex-basis should cause height to be ignored</title>
<link rel="author" title="Google LLC" href="https://www.google.com">
<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#flex-basis-property">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
#container {
background-color: red;
display: flex;
width: 100px;
flex-direction: column;
}
#item {
flex: 0 0 0%;
height: 500px;
background-color: red;
}
#child {
height: 100px;
background-color: green;
}
</style>
<body>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="container">
<div id="item">
<div id="child"></div>
</div>
</div>
</body>

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<title>CSS Flexbox: min-height: auto with nested flexboxes</title>
<link rel="author" title="Google LLC" href="https://www.google.com/" />
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#min-size-auto" />
<link rel="issue" href="https://bugs.chromium.org/p/chromium/issues/detail?id=933931" />
<link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
<style>
.outer {
display: flex;
flex-direction: column;
height: 20px;
width: 100px;
background: red;
}
.middle {
display: flex;
flex-direction: column;
background: green;
}
.inner {
display: flex;
flex-direction: column;
}
.tall {
width: 50px;
height: 100px;
background: green;
}
</style>
<body>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="outer">
<div class="middle">
<div class="inner">
<div class="tall"></div>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<link rel="author" title="Google LLC" href="http://www.google.com" />
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#cross-sizing" />
<title>css-flexbox: Tests that we size items in a wrapping column flexbox as fit-content</title>
<link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
<meta name="assert" content="The flexbox here should have one flex line, 100px by 100px. The flex items overflow but are transparent." />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<!-- This makes sure that we only see green if the flex items are sized correctly -->
<div style="position: absolute; width: 100px; height: 100px; background: green;"></div>
<div style="display: flex; flex-direction: column; flex-wrap: wrap; width: 200px; height: 100px; line-height: 20px; align-content: flex-start;">
<div style="background-color: red; height: 100px; max-width: 50%; align-self: center;">
<!-- These zero-height divs give the flex item a min-content width of
50px and a max-content width of 250px -->
<div style="width: 50px; display: inline-block;"></div>
<div style="width: 50px; display: inline-block;"></div>
<div style="width: 50px; display: inline-block;"></div>
<div style="width: 50px; display: inline-block;"></div>
<div style="width: 50px; display: inline-block;"></div>
</div>
</div>

View file

@ -1,9 +0,0 @@
<title>In quirks mode a flex item should resolve its percentage height against its first ancestor with a defined height.</title>
<link rel="help" href="https://quirks.spec.whatwg.org/#the-percentage-height-calculation-quirk">
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<p style="margin-top: 1em;">Test passes if there is a filled green square.</p>
<div style="width: 200px; height: 200px;">
<div style="display: flex;">
<div style="width: 50%; height: 50%; background: green;"></div>
</div>
</div>

View file

@ -0,0 +1,17 @@
<!-- quirks mode -->
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#the-height-property">
<meta name="assert" content="The percentage height resolution quirk isn't applied to flexboxes.">
<p>There should be a green square to the left of a blue square, and no red.</p>
<div id="container" style="width:200px; height:456px;">
<div style="display:flex; background:blue;" data-expected-height="100">
<img style="width:100px; height: 50%;" src="support/1x1-green.png" data-expected-height="100">
<div style="width: 50px; height: 100%; background: red;" data-expected-height="0"></div>
</div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
checkLayout("#container");
</script>

View file

@ -0,0 +1,23 @@
<!doctype html>
<title>Testing font-style angle's unit type consideration</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-style-prop" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
font-style: oblique 0.785398165rad;
}
</style>
<script>
var test_description = "font-style angle's unit type must be considered";
promise_test(
t => {
return new Promise(test => addEventListener('load', () => test()))
.then(test => assert_equals(getComputedStyle(document.querySelector("body"))['font-style'], "oblique 45deg", "Invalid gCS($(\"body\"))['font-style'];"))
},
test_description
);
</script>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: minimum contribution with baseline-alignment shim</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid/#algo-content" title="11.5. Resolve Intrinsic Track Sizes">
<meta name="assert" content="Checks that the minimum contribution takes the baseline-alignment shim into account when calculating the outer size that grid items would have if their preferred size were their minimum size. Also checks that the shim is used again when clamping the automatic minimum size to less than or equal to the stretch fit into the grid area.">
<style>
.grid {
display: grid;
position: relative;
font-size: 0;
height: 0;
width: 0;
margin-bottom: 125px;
grid-template-rows: 50px 50px;
justify-items: baseline;
}
.item1, .item2 {
writing-mode: vertical-lr;
}
.item1 {
padding-left: 25px;
background: yellow;
}
.item2 {
padding-right: 25px;
background: magenta;
}
.item1::before, .item2::before {
content: '';
display: inline-block;
width: 25px;
height: 25px;
vertical-align: top;
}
.item2::before {
vertical-align: bottom;
}
.area {
position: absolute;
z-index: -1;
left: 0;
right: 0;
top: 0;
bottom: 0;
grid-column: 1 / 2;
grid-row: 1 / 3;
background: cyan;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<div id="log"></div>
<div class="grid" style="grid-template-columns: minmax(auto, 0px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="75" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 75px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="75" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 88px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="88" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 100px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 150px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, auto);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<script>
checkLayout(".grid");
</script>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: minimum contribution with baseline-alignment shim</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid/#algo-content" title="11.5. Resolve Intrinsic Track Sizes">
<meta name="assert" content="Checks that the minimum contribution takes the baseline-alignment shim into account when calculating the outer size that grid items would have if their preferred size were their minimum size. Also checks that the shim is used again when clamping the automatic minimum size to less than or equal to the stretch fit into the grid area.">
<style>
.grid {
display: grid;
position: relative;
font-size: 0;
height: 0;
width: 0;
margin-bottom: 125px;
grid-template-rows: 50px 50px;
justify-items: baseline;
}
.item1, .item2 {
writing-mode: vertical-rl;
}
.item1 {
padding-left: 25px;
background: yellow;
}
.item2 {
padding-right: 25px;
background: magenta;
}
.item1::before, .item2::before {
content: '';
display: inline-block;
width: 25px;
height: 25px;
vertical-align: top;
}
.item2::before {
vertical-align: bottom;
}
.area {
position: absolute;
z-index: -1;
left: 0;
right: 0;
top: 0;
bottom: 0;
grid-column: 1 / 2;
grid-row: 1 / 3;
background: cyan;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<div id="log"></div>
<div class="grid" style="grid-template-columns: minmax(auto, 0px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="75" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 75px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="75" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 88px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="88" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 100px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, 150px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-columns: minmax(auto, auto);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<script>
checkLayout(".grid");
</script>

View file

@ -0,0 +1,93 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: minimum contribution with baseline-alignment shim</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid/#algo-content" title="11.5. Resolve Intrinsic Track Sizes">
<meta name="assert" content="Checks that the minimum contribution takes the baseline-alignment shim into account when calculating the outer size that grid items would have if their preferred size were their minimum size. Also checks that the shim is used again when clamping the automatic minimum size to less than or equal to the stretch fit into the grid area.">
<style>
.grid {
display: grid;
position: relative;
font-size: 0;
height: 0;
width: 0;
margin-bottom: 125px;
grid-template-columns: 50px 50px;
align-items: baseline;
}
.item1 {
padding-top: 25px;
background: yellow;
}
.item2 {
padding-bottom: 25px;
background: magenta;
}
.item1::before, .item2::before {
content: '';
display: inline-block;
width: 25px;
height: 25px;
vertical-align: bottom;
}
.item2::before {
vertical-align: top;
}
.area {
position: absolute;
z-index: -1;
left: 0;
right: 0;
top: 0;
bottom: 0;
grid-column: 1 / 3;
grid-row: 1 / 2;
background: cyan;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<div id="log"></div>
<div class="grid" style="grid-template-rows: minmax(auto, 0px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="75"></div>
</div>
<div class="grid" style="grid-template-rows: minmax(auto, 75px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="75"></div>
</div>
<div class="grid" style="grid-template-rows: minmax(auto, 88px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="88"></div>
</div>
<div class="grid" style="grid-template-rows: minmax(auto, 100px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-rows: minmax(auto, 150px);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<div class="grid" style="grid-template-rows: minmax(auto, auto);">
<div class="item1" data-offset-x="0" data-offset-y="0"></div>
<div class="item2" data-offset-x="50" data-offset-y="50"></div>
<div class="area" data-expected-width="100" data-expected-height="100"></div>
</div>
<script>
checkLayout(".grid");
</script>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<title>Hit-test of clip-path objectBoundingBox &lt;clipPath> with additional transform</title>
<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
.box {
width: 100px;
height: 100px;
background-color: blue;
margin: 100px;
clip-path: url(#clip);
}
</style>
<div class="box"></div>
<svg height="0">
<clipPath id="clip" clipPathUnits="objectBoundingBox" transform="scale(0.01, 0.01)">
<polygon points="50,0 100,50 50,100 0,50"/>
</clipPath>
</svg>
<script>
function assert_element_at(element, pointlist) {
for (let point of pointlist) {
let result = document.elementFromPoint(point[0], point[1]);
assert_equals(result, element, point.join(','));
}
}
test(function() {
let div = document.querySelector('.box');
// Points inside clip-path.
assert_element_at(div, [[150, 150], [150, 125], [150, 175], [125, 150], [175, 150]]);
// Points outside clip-path.
assert_element_at(document.body, [[120, 120], [180, 120], [120, 180], [180, 180]]);
});
</script>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<title>Hit-test of clip-path nested objectBoundingBox &lt;clipPath></title>
<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
.box {
width: 200px;
height: 200px;
background-color: blue;
margin: 100px;
clip-path: url(#clip);
}
</style>
<div class="box"></div>
<svg height="0">
<clipPath id="nested" clipPathUnits="objectBoundingBox">
<circle cx="0.25" cy="0.25" r="0.25"/>
</clipPath>
<clipPath id="clip" clipPathUnits="objectBoundingBox" clip-path="url(#nested)">
<rect width="0.5" height="0.5"/>
</clipPath>
</svg>
<script>
function assert_element_at(element, pointlist) {
for (let point of pointlist) {
let result = document.elementFromPoint(point[0], point[1]);
assert_equals(result, element, point.join(','));
}
}
test(function() {
let div = document.querySelector('.box');
// Points inside clip-path.
assert_element_at(div, [[150, 150], [150, 125], [150, 175], [125, 150], [175, 150]]);
// Points outside clip-path.
assert_element_at(document.body, [[110, 110], [190, 110], [110, 190], [190, 190]]);
});
</script>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<title>Hit-test of clip-path userSpaceOnUse &lt;clipPath></title>
<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
.box {
width: 100px;
height: 100px;
background-color: blue;
margin: 100px;
clip-path: url(#clip);
}
</style>
<div class="box"></div>
<svg height="0">
<clipPath id="clip" clipPathUnits="userSpaceOnUse">
<polygon points="50,0 100,50 50,100 0,50"/>
</clipPath>
</svg>
<script>
function assert_element_at(element, pointlist) {
for (let point of pointlist) {
let result = document.elementFromPoint(point[0], point[1]);
assert_equals(result, element, point.join(','));
}
}
test(function() {
let div = document.querySelector('.box');
// Points inside clip-path.
assert_element_at(div, [[150, 150], [150, 125], [150, 175], [125, 150], [175, 150]]);
// Points outside clip-path.
assert_element_at(document.body, [[120, 120], [180, 120], [120, 180], [180, 180]]);
});
</script>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<title>Hit-test of clip-path polygon combined with box-shadow</title>
<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
.box {
width: 100px;
height: 100px;
background-color: blue;
box-shadow: -100px 0px red;
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
</style>
<div class="box"></div>
<script>
function assert_element_at(element, pointlist) {
for (let point of pointlist) {
let result = document.elementFromPoint(point[0], point[1]);
assert_equals(result, element, point.join(','));
}
}
test(function() {
let div = document.querySelector('.box');
// Points inside clip-path.
assert_element_at(div, [[50, 50], [50, 25], [50, 75], [25, 50], [75, 50]]);
// Points outside clip-path.
assert_element_at(document.body, [[20, 20], [80, 20], [20, 80], [80, 80]]);
});
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<style>
#test {
width: 100px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
border: solid thin grey;
font: 20px 'Ahem';
line-height: 40px;
}
</style>
<p>This tests the -webkit-line-clamp property with line-height applied.</p>
<div id="test">
XXXX XXX
</div>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<link rel="match" href="webkit-line-clamp-with-line-height-ref.html">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2847#issuecomment-468084957">
<meta name="assert" content="This test checks that -webkit-line-clamp calculates respects line-height when calculating its block-size.">
<style>
#test {
width: 100px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
border: solid thin grey;
font: 20px 'Ahem';
line-height: 40px;
}
</style>
<p>This tests the -webkit-line-clamp property with line-height applied.</p>
<div id="test">
XXXX XXX
</div>

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<title>CSS Position Absolute: dynamic changes to containing block height</title>
<link rel="author" href="mailto:atotic@google.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=933054">
<meta name="assert" content="Chrome regression: abspos descendant responds to containing block size change through line items">
<style>
#container {
position: relative;
}
#intermediate {
overflow: hidden;
width:200px;
height:200px;
background:red;
}
#block {
height:200px;
background:green;
}
#target {
position: absolute;
width: 200px;
height: 100px;
background:green;
}
</style>
<!-- Test for crbug.com/933054
Relayout optimizations cause OOF descendant not to be
repositioned
-->
<div id="container">
<div id="intermediate">
<div id="block"></div>
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
test(() => {
document.getElementById("block").style.height = "100px";
assert_equals(document.querySelector("#target").offsetTop, 100);
}, '#target static position responded to parent relayout');
</script>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<title>CSS Position Absolute: Chrome chrash</title>
<link rel="author" href="mailto:atotic@google.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=938224">
<meta name="assert" content="absolute position in LI container does not crash">
<style>
#container {
position: absolute;
top: 0px;
left: 0px;
}
#abs {
position: absolute;
top: 0px;
left: 0px;
}
</style>
<li id="container">
<ul>
<li>
<div id="abs">abs</div>
</li>
</ul>
</li>
<script>
test(() => {
}, 'test passes if it does not crash');
</script>

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<div style="height: 100vh"></div>
<div style="background: green; height: 100px"></div>
<script>
window.scrollTo(0, 100);
</script>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>z-index, will-change, mix-blend-mode on overlapping layers</title>
<link rel="match" href="z-index-blend-will-change-overlapping-layers-ref.html">
<link rel="help" href="https://www.w3.org/TR/CSS2/visuren.html#propdef-z-index">
<link rel="help" href="https://drafts.csswg.org/css-will-change/#will-change">
<link rel="help" href="https://www.w3.org/TR/compositing-1/#mix-blend-mode">
<meta name="assert" content="Tests z-index, will-change and mix-blend-mode on overlapping layers.
Passes if there is a green bar when the page is scrolled to the bottom.">
<script src="/common/reftest-wait.js"></script>
<div style="z-index: 1; position: relative; height: 100vh">
<div style="mix-blend-mode: multiply"></div>
<div style="will-change: transform; position: absolute; bottom: -100px; width: 100px; height: 100px; background: red">
</div>
</div>
<div style="z-index: 1; position: relative; background: green; height: 100px"></div>
<script>
requestAnimationFrame(()=>{
requestAnimationFrame(()=>{
window.scrollBy(0, 100);
takeScreenshot();
});
});
</script>
</html>

View file

@ -1,4 +1,5 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" />
<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#supported-syntax-strings" />
<script src="/resources/testharness.js"></script>
@ -29,9 +30,11 @@ assert_valid(" <number>", "5");
assert_valid("<percentage> ", "10%");
assert_valid("<color>+", "red");
assert_valid(" <length>+ | <percentage>", "2px 8px");
assert_valid(" <length>+ | <color>#", "red, blue");
assert_valid("<length>|<percentage>|<length-percentage>", "2px"); // Valid but silly
assert_valid("<color> | <image> | <url> | <integer> | <angle>", "red");
assert_valid("<time> | <resolution> | <transform-list> | <custom-ident>", "red");
assert_valid("\t<color>\n| foo", "foo");
assert_valid("*", ":> hello");
assert_valid("*", "([ brackets ]) { yay (??)}");
@ -86,6 +89,7 @@ assert_valid("banana", "banana");
assert_valid("bAnAnA", "bAnAnA");
assert_valid("ba-na-nya", "ba-na-nya");
assert_valid("banana", "banan\\61");
assert_valid("banan\\61", "banana");
assert_valid("<custom-ident>", "banan\\61");
assert_valid("big | bigger | BIGGER", "bigger");
assert_valid("foo+|bar", "foo foo foo");
@ -99,9 +103,14 @@ assert_valid(null, "null");
assert_valid(undefined, "undefined");
assert_valid(["array"], "array");
assert_valid("\\1F914", "🤔");
assert_valid("hmm\\1F914", "hmm🤔");
assert_valid("\\1F914hmm", "🤔hmm");
assert_valid("\\1F914 hmm", "🤔hmm");
assert_valid("\\1F914\\1F914", "🤔🤔");
// Invalid syntax
assert_invalid("banana,nya", "banana");
assert_invalid("banan\\61", "banana");
assert_invalid("<\\6c ength>", "10px");
assert_invalid("<banana>", "banana");
assert_invalid("<Number>", "10");
@ -110,11 +119,20 @@ assert_invalid("<LENGTH>", "10px");
assert_invalid("< length>", "10px");
assert_invalid("<length >", "10px");
assert_invalid("<length> +", "10px");
assert_invalid("<transform-list>+", "scale(2)");
assert_invalid("<transform-list>#", "scale(2)");
assert_invalid("<length>++", "10px");
assert_invalid("<length>##", "10px");
assert_invalid("<length>+#", "10px");
assert_invalid("<length>#+", "10px");
assert_invalid("<length> | *", "10px");
assert_invalid("*|banana", "banana");
assert_invalid("|banana", "banana");
assert_invalid("*+", "banana");
assert_invalid("|", "banana");
assert_invalid(" |", "banana");
assert_invalid("||", "banana");
assert_invalid("initial", "initial");
assert_invalid("inherit", "inherit");

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Scroll Anchoring: getComputedValue().overflowAnchor</title>
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#propdef-overflow-anchor">
<meta name="assert" content="overflow-anchor computed value is as specified.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
</head>
<body>
<div id="target"></div>
<script>
test_computed_value("overflow-anchor", "auto");
test_computed_value("overflow-anchor", "none");
</script>
</body>
</html>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Scroll Anchoring: parsing overflow-anchor with invalid values</title>
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#propdef-overflow-anchor">
<meta name="assert" content="overflow-anchor supports only the grammar 'auto | none'.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_invalid_value("overflow-anchor", "all");
test_invalid_value("overflow-anchor", "auto none");
</script>
</body>
</html>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Scroll Anchoring: parsing overflow-anchor with valid values</title>
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#propdef-overflow-anchor">
<meta name="assert" content="overflow-anchor supports the full grammar 'auto | none'.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_valid_value("overflow-anchor", "auto");
test_valid_value("overflow-anchor", "none");
</script>
</body>
</html>

View file

@ -42,7 +42,7 @@ div {
}
</style>
<div class="scroller-x" id="one-target">
<div id="space"></div>
<div class="space"></div>
<div class="large-x target" id="single" style="left: 200px;"></div>
</div>
@ -150,4 +150,4 @@ test(() => {
}, "Snap to current scroll position on x as the area is covering x axis." +
"However, we snap to the specified snap position on y as the area is not " +
"covering y axis.");
</script>
</script>

View file

@ -38,7 +38,7 @@ var height = scroller.clientHeight;
[
["horizontal-tb", 300, 500 - height],
["vertical-lr", 500 - width, 300],
["vertical-rl", 300, 300]
["vertical-rl", width - 700, 300]
].forEach(([writing_mode, left, top]) => {
test(() => {
scroller.style.writingMode = writing_mode;
@ -50,4 +50,4 @@ var height = scroller.clientHeight;
}, "Snaps correctly for " + writing_mode +
" writing mode with 'inline' and 'block' alignments");
})
</script>
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html class=reftest-wait>
<meta name="assert" content="Checks that an absolute positioned element is positioned correctly, when the available size of its parent changes due to document resize." />
<link rel="help" href="https://crbug.com/928672">
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<script src="/common/reftest-wait.js"></script>
<p>Test passes if there is a filled green square.</p>
<iframe id="target" height="100" width="200" src="support/dynamic-available-size-iframe.html" style="border: none;"></iframe>
<script>
onload = () => {
requestAnimationFrame(() => requestAnimationFrame(() => {
target.width = '100';
takeScreenshot();
}));
};
</script>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<style>
body { margin: 0; }
.parent {
position: relative;
display: flex;
width: 100%;
height: 100px;
background: red;
}
.content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 100px;
height: 100px;
background: green;
}
svg {
width: 50px;
height: 50px;
}
</style>
<div class="parent">
<div class="content">
<svg xmlns="http://www.w3.org/2000/svg"></svg>
</div>
</div>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>
Individual transform properties' animations create stacking context in delay phase
</title>
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
<link rel="match" href="stacking-context-ref.html">
<meta name="assert" content="Individual transform properties' animations
should create stacking context even in delay
phase."/>
<style>
#back {
height: 100px;
width: 100px;
position: fixed;
background: green;
margin-top: 50px;
}
@keyframes scale {
from, to { scale: 1; }
}
#test {
width: 100px;
height: 100px;
background: blue;
animation: scale 100s 100s;
}
</style>
</head>
<body>
<div id="back"></div>
<div id="test"></div>
</body>
<script>
requestAnimationFrame(() => {
document.documentElement.classList.remove('reftest-wait');
});
</script>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<title>
Reference: Individual transform properties' animations create stacking context in delay phase
</title>
<style>
#back {
height: 100px;
width: 100px;
position: fixed;
background: green;
margin-top: 50px;
}
#test {
width: 100px;
height: 100px;
background: blue;
will-change: transform;
}
</style>
</head>
<body>
<div id="back"></div>
<div id="test"></div>
</body>
</html>

View file

@ -24,7 +24,7 @@ runListValuedPropertyTests('animation-timing-function', [
]);
runUnsupportedPropertyTests('animation-timing-function', [
'cubic-bezier(0.1, 0.7, 1.0, 0.1)', 'steps(4, end)', 'frames(10)'
'cubic-bezier(0.1, 0.7, 1.0, 0.1)', 'steps(4, end)'
]);
</script>

View file

@ -24,7 +24,7 @@ runListValuedPropertyTests('transition-timing-function', [
]);
runUnsupportedPropertyTests('transition-timing-function', [
'cubic-bezier(0.1, 0.7, 1.0, 0.1)', 'steps(4, end)', 'frames(10)'
'cubic-bezier(0.1, 0.7, 1.0, 0.1)', 'steps(4, end)'
]);
</script>

View file

@ -2,5 +2,5 @@ Template-Python==0.1.post1
html5lib==1.0.1
lxml==4.1.1
mercurial==4.5
six==1.11.0
six==1.12.0
webencodings==0.5.1

View file

@ -15,7 +15,7 @@
#too-wide {
display: inline-block;
height: 20px;
height: 21px;
width: 250px;
background: blue;
}
@ -24,11 +24,31 @@
width: 100px;
height: 100px;
float: left;
/* We use a gradient, which is part of the CSS 'image' type.
* We set it up to create a hard diagonal edge from the bottom left to the
* top right of #shape, which slices through each pixel along the diagonal.
* Theoretically, this should place #too-wide at position 50,50 within
* #shape's 100x100 region, but on some devices, the gradient rasterization
* may leave pixel 50,49 unshaded enough that #too-wide is placed there
* instead. To account for that possible off-by-one rounding scenario,
* we set things up as follows:
* - We make #too-wide 1px taller than the corresponding content in the
* reference case.
* - We clip the outermost div using a 'clip-path' that only paints
* the region where the corresponding content is in the reference case.
* - If the testcase renders properly, then #too-wide will have 1px of
* content clipped off of its top or bottom (depending on how the
* linear-gradient rasterization and rounding works out). Either way,
* it'll match the reference case.
*/
shape-outside: linear-gradient(135deg, black, black 50%, transparent 50%);
}
.clip {
clip-path: inset(50px 0 30px 0px);
}
</style>
<div style="width: 300px; height: 100px;">
<div style="width: 300px; height: 100px;" class="clip">
<div id="shape"></div>
<span id="too-wide"></span>
<div>

View file

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Test for retrying floats and pushing them partway down the float area</title>
<title>Reference for retrying floats and pushing them partway down the float area</title>
<link rel="author" title="Brad Werth" href="mailto:bwerth@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>

View file

@ -105,7 +105,6 @@
# Tests of shape-outside layout behavior with too-wide inline elements
== float-retry-push-circle.html float-retry-push-ref.html
# The next test offsets a 250px wide element up to one pixel due to small offsets in gradient generation.
== float-retry-push-image.html float-retry-push-ref.html
== float-retry-push-inset.html float-retry-push-ref.html
== float-retry-push-polygon.html float-retry-push-ref.html

View file

@ -328,7 +328,9 @@ test(function () {
});
customElements.define('element-with-attribute-changed-callback', proxy);
assert_array_equals(prototypeCalls, [1, 'connectedCallback', 2, 'disconnectedCallback', 3, 'adoptedCallback', 4, 'attributeChangedCallback']);
assert_array_equals(constructorCalls, [0, 'prototype', 5, 'observedAttributes']);
assert_array_equals(constructorCalls, [0, 'prototype',
5, 'observedAttributes',
6, 'disabledFeatures']);
}, 'customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present');
test(function () {
@ -388,6 +390,53 @@ test(function () {
customElements.define('element-without-callback-with-invalid-observed-attributes', constructor);
}, 'customElements.define must not throw even if "observedAttributes" fails to convert if "attributeChangedCallback" is not defined');
test(function () {
var constructor = function () {}
var calls = [];
var proxy = new Proxy(constructor, {
get: function (target, name) {
calls.push(name);
if (name == 'disabledFeatures')
throw {name: 'expectedError'};
return target[name];
}
});
assert_throws({'name': 'expectedError'}, () => customElements.define('element-with-throwing-disabled-features', proxy));
assert_array_equals(calls, ['prototype', 'disabledFeatures'],
'customElements.define must get "prototype" and "disabledFeatures" on the constructor');
}, 'customElements.define must rethrow an exception thrown while getting disabledFeatures on the constructor prototype');
test(function () {
var constructor = function () {}
var calls = [];
var proxy = new Proxy(constructor, {
get: function (target, name) {
calls.push(name);
if (name == 'disabledFeatures')
return 1;
return target[name];
}
});
assert_throws({'name': 'TypeError'}, () => customElements.define('element-with-invalid-disabled-features', proxy));
assert_array_equals(calls, ['prototype', 'disabledFeatures'],
'customElements.define must get "prototype" and "disabledFeatures" on the constructor');
}, 'customElements.define must rethrow an exception thrown while converting the value of disabledFeatures to sequence<DOMString>');
test(function () {
var constructor = function () {}
constructor.disabledFeatures = {[Symbol.iterator]: function *() {
yield 'foo';
throw {name: 'SomeError'};
}};
assert_throws({'name': 'SomeError'}, () => customElements.define('element-with-generator-disabled-features', constructor));
}, 'customElements.define must rethrow an exception thrown while iterating over disabledFeatures to sequence<DOMString>');
test(function () {
var constructor = function () {}
constructor.disabledFeatures = {[Symbol.iterator]: 1};
assert_throws({'name': 'TypeError'}, () => customElements.define('element-with-disabled-features-with-uncallable-iterator', constructor));
}, 'customElements.define must rethrow an exception thrown while retrieving Symbol.iterator on disabledFeatures');
test(function () {
class MyCustomElement extends HTMLElement {};
customElements.define('my-custom-element', MyCustomElement);

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLLIElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert"
content="value of HTMLLIElement interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#the-li-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<body>
<script>
function getParentElement(parentElementName) {
let parentElement = document.createElement(parentElementName);
document.body.appendChild(parentElement);
return parentElement;
}
testReflectAttributeWithParentNode(
'value', 'value', '3',
'5', 'value on HTMLLIElement in ol', 'li',
() => getParentElement('ol'), HTMLLIElement
);
testReflectAttributeWithParentNode(
'value', 'value', '3',
'5', 'value on HTMLLIElement in ul', 'li',
() => getParentElement('ul'), HTMLLIElement
);
testReflectAttributeWithParentNode(
'value', 'value', '3',
'5', 'value on HTMLLIElement in menu', 'li',
() => getParentElement('menu'), HTMLLIElement
);
</script>
</body>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLLabelElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert"
content="htmlFor of HTMLLabelElement interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#the-label-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<form id="form">
<input type="radio" name="gender" id="male" value="male">
<input type="radio" name="gender" id="female" value="female">
</form>
<script>
function getParentElement() {
let parentElement = document.getElementById("form");
return parentElement;
}
testReflectAttributeWithParentNode(
'htmlFor', 'for', 'male',
'female', 'htmlFor on HTMLLabelElement', 'label',
getParentElement, HTMLLabelElement
);
</script>

View file

@ -0,0 +1,107 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLMediaElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert" content="src, crossOrigin, preload, autoplay, loop,
controls, defaultMuted of HTMLMediaElement interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#media-elements">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<body>
<script>
function getParentElement() {
return document.body;
}
function setAttributes(instance, value) {
instance.setAttribute('src', value);
}
testReflectAttribute(
'src', 'src', '/media/sound_0.mp3',
'/media/sound_5.mp3', 'src on HTMLMediaElement in audio', 'audio',
HTMLAudioElement
);
testReflectAttributeWithDependentAttributes(
'crossOrigin', 'crossorigin', 'use-credentials',
'anonymous', 'crossOrigin on HTMLMediaElement in audio', 'audio',
getParentElement, instance => setAttributes(instance, '/media/sound_5.mp3'),
HTMLAudioElement
);
testReflectAttributeWithDependentAttributes(
'preload', 'preload', 'auto',
'none', 'preload on HTMLMediaElement in audio', 'audio',
getParentElement, instance => setAttributes(instance, '/media/sound_5.mp3'),
HTMLAudioElement
);
testReflectBooleanAttributeWithDependentAttributes(
'autoplay', 'autoplay', 'autoplay on HTMLMediaElement in audio',
'audio', getParentElement,
instance => setAttributes(instance, '/media/sound_5.mp3'),
HTMLAudioElement
);
testReflectBooleanAttributeWithDependentAttributes(
'loop', 'loop', 'loop on HTMLMediaElement in audio',
'audio', getParentElement,
instance => setAttributes(instance, '/media/sound_5.mp3'), HTMLAudioElement
);
testReflectBooleanAttributeWithDependentAttributes(
'controls', 'controls', 'controls on HTMLMediaElement in audio',
'audio', getParentElement,
instance => setAttributes(instance, '/media/sound_5.mp3'),
HTMLAudioElement
);
testReflectBooleanAttributeWithDependentAttributes(
'defaultMuted', 'muted', 'defaultMuted on HTMLMediaElement in audio',
'audio', getParentElement,
instance => setAttributes(instance, '/media/sound_5.mp3'),
HTMLAudioElement
);
testReflectAttribute(
'src', 'src', '/media/video.ogv',
'/media/movie_5.mp4', 'src on HTMLMediaElement in video', 'video',
HTMLVideoElement
);
testReflectAttributeWithDependentAttributes(
'crossOrigin', 'crossorigin', 'use-credentials',
'anonymous', 'crossOrigin on HTMLMediaElement in video', 'video',
getParentElement, instance => setAttributes(instance, '/media/movie_5.mp4'),
HTMLVideoElement
);
testReflectAttributeWithDependentAttributes(
'preload', 'preload', 'auto',
'none', 'preload on HTMLMediaElement in video', 'video',
getParentElement, instance => setAttributes(instance, '/media/movie_5.mp4'),
HTMLVideoElement
);
testReflectBooleanAttributeWithDependentAttributes(
'autoplay', 'autoplay', 'autoplay on HTMLMediaElement in video',
'video', getParentElement,
instance => setAttributes(instance, '/media/movie_5.mp4'),
HTMLVideoElement
);
testReflectBooleanAttributeWithDependentAttributes(
'loop', 'loop', 'loop on HTMLMediaElement in video',
'video', getParentElement,
instance => setAttributes(instance, '/media/movie_5.mp4'),
HTMLVideoElement
);
testReflectBooleanAttributeWithDependentAttributes(
'controls', 'controls', 'controls on HTMLMediaElement in video',
'video', getParentElement,
instance => setAttributes(instance, '/media/movie_5.mp4'),
HTMLVideoElement
);
testReflectBooleanAttributeWithDependentAttributes(
'defaultMuted', 'muted', 'defaultMuted on HTMLMediaElement in video',
'video', getParentElement,
instance => setAttributes(instance, '/media/movie_5.mp4'),
HTMLVideoElement
);
</script>
</body>

View file

@ -0,0 +1,77 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLMetaElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert" content="name, httpEquiv, content of
HTMLMetaElement interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#the-meta-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<script>
function getParentElement() {
return document.head;
}
function setAttributes(instance, attribute, value) {
instance.setAttribute(attribute, value);
}
testReflectAttributeWithDependentAttributes(
'name', 'name', 'description',
'keywords', 'name on HTMLMetaElement', 'meta',
getParentElement,
instance => setAttributes(instance, 'content', 'HTMLMetaElement'),
HTMLMetaElement
);
testReflectAttributeWithDependentAttributes(
'content', 'content', 'name1',
'name2', 'content on HTMLMetaElement', 'meta',
getParentElement, instance => setAttributes(instance, 'name', 'author'),
HTMLMetaElement
);
test(() => {
let element = define_build_in_custom_element(
['http-equiv'], HTMLMetaElement, 'meta'
);
let instance = document.createElement('meta', { is: element.name });
assert_array_equals(element.takeLog().types(), ['constructed']);
document.head.appendChild(instance);
assert_array_equals(element.takeLog().types(), ['connected']);
instance['content'] = '300';
instance['httpEquiv'] = 'refresh';
let logEntries = element.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {
name: 'http-equiv', oldValue: null, newValue: 'refresh', namespace: null
});
}, 'httpEquiv on HTMLMetaElement must enqueue an attributeChanged'
+ ' reaction when adding a new attribute');
test(() => {
let element = define_build_in_custom_element(
['http-equiv'], HTMLMetaElement, 'meta'
);
let instance = document.createElement('meta', { is: element.name });
document.head.appendChild(instance);
assert_array_equals(element.takeLog().types(), ['constructed', 'connected']);
instance['content'] = 'text/html; charset=UTF-8';
instance['httpEquiv'] = 'content-type';
assert_array_equals(element.takeLog().types(), ['attributeChanged']);
instance['content'] = '300';
instance['httpEquiv'] = 'refresh';
let logEntries = element.takeLog();
assert_array_equals(logEntries.types(), ['attributeChanged']);
assert_attribute_log_entry(logEntries.last(), {
name: 'http-equiv', oldValue: 'content-type',
newValue: 'refresh', namespace: null
});
}, 'httpEquiv on HTMLMetaElement must enqueue an attributeChanged'
+ ' reaction when replacing an existing attribute');
</script>

View file

@ -0,0 +1,20 @@
test(t => {
const hostParent = document.createElement("section"),
host = hostParent.appendChild(document.createElement("div")),
shadowRoot = host.attachShadow({ mode: "closed" }),
targetParent = shadowRoot.appendChild(document.createElement("p")),
target = targetParent.appendChild(document.createElement("span")),
path = [hostParent, host, shadowRoot, targetParent, target],
expected = [],
result = [];
path.forEach((node, index) => {
expected.splice(index, 0, "capturing " + node.nodeName);
expected.splice(index + 1, 0, "bubbling " + node.nodeName);
});
path.forEach(node => {
node.addEventListener("test", () => { result.push("bubbling " + node.nodeName) });
node.addEventListener("test", () => { result.push("capturing " + node.nodeName) }, true);
});
target.dispatchEvent(new CustomEvent('test', { detail: {}, bubbles: true, composed: true }));
assert_array_equals(result, expected);
});

View file

@ -0,0 +1,11 @@
test(function() {
var desc1 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
assert_not_equals(desc1, undefined);
assert_equals(typeof desc1.get, "function");
var desc2 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
assert_not_equals(desc2, undefined);
assert_equals(typeof desc2.get, "function");
assert_equals(desc1.get, desc2.get);
});

View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<title>Default passive document level touchmove event listener test</title>
<link rel="help" href="https://github.com/WICG/interventions/issues/35">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<body onload=runTest()>
<div id="touchDiv">
</div>
</body>
<style>
#touchDiv {
width: 100px;
height: 100px;
}
</style>
<script>
var touch_div = document.getElementById("touchDiv");
var cancelable = true;
var touch_move_arrived = false;
document.addEventListener("touchmove", function (event) {
cancelable = event.cancelable;
touch_move_arrived = true;
event.preventDefault();
});
function waitFor(condition) {
const MAX_FRAME = 500;
return new Promise((resolve, reject) => {
function tick(frames) {
// We requestAnimationFrame either for 500 frames or until condition is
// met.
if (frames >= MAX_FRAME)
reject("Condition did not become true after 500 frames");
else if (condition())
resolve();
else
requestAnimationFrame(tick.bind(this, frames + 1));
}
tick(0);
});
}
function waitForCompositorCommit() {
return new Promise((resolve) => {
// rAF twice.
window.requestAnimationFrame(() => {
window.requestAnimationFrame(resolve);
});
});
}
function injectInput() {
new test_driver.Actions()
.addPointer("touch_pointer", "touch")
.pointerMove(0, 0, {origin: touch_div})
.pointerDown()
.pointerMove(30, 30)
.pointerUp()
.send();
}
function runTest() {
promise_test (async () => {
await waitForCompositorCommit();
injectInput();
await waitFor(()=> { return touch_move_arrived; });
assert_false(cancelable);
}, "Touchmove events are non-cancelable since the event listener is treated as passive.");
}
</script>

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