mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Update web-platform-tests to revision 0b22439430b6d8d9a6d43a0908e86c0366f207c0
This commit is contained in:
parent
39ec04a065
commit
c8e806d0ef
93 changed files with 2118 additions and 597 deletions
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<title>Worklet Animation's animator name should be accessible via animatorName property</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="common.js"></script>
|
||||
|
||||
<script id="test_animator" type="text/worklet">
|
||||
class NoopAnimator {
|
||||
animate(currentTime, effect) {}
|
||||
}
|
||||
registerAnimator('Tokyo', NoopAnimator);
|
||||
registerAnimator('دزفول', NoopAnimator);
|
||||
</script>
|
||||
|
||||
<body></body>
|
||||
|
||||
<script>
|
||||
promise_test(async t => {
|
||||
await runInAnimationWorklet(document.getElementById('test_animator').textContent);
|
||||
|
||||
// An ascii name and a non-ascii one.
|
||||
for (let name of ['Tokyo', 'دزفول']) {
|
||||
const animation = new WorkletAnimation(name, new KeyframeEffect(document.body, {}));
|
||||
assert_equals(name, animation.animatorName);
|
||||
}
|
||||
}, 'Verify that animatorName matches passed name');
|
||||
</script>
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Animations: column-rule-color animations respond to style changes</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#crc">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
.paused {
|
||||
animation-duration: 4s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: -2s;
|
||||
animation-play-state: paused;
|
||||
}
|
||||
#container {
|
||||
color: rgb(80, 0, 0);
|
||||
}
|
||||
#first {
|
||||
animation-name: first-anim;
|
||||
color: rgb(60, 0, 0);
|
||||
}
|
||||
#second {
|
||||
animation-name: second-anim;
|
||||
}
|
||||
@keyframes first-anim {
|
||||
from { column-rule-color: currentColor; }
|
||||
to { column-rule-color: rgb(0, 60, 0); }
|
||||
}
|
||||
@keyframes second-anim {
|
||||
from { column-rule-color: inherit; }
|
||||
to { column-rule-color: rgb(0, 0, 80); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="first" class="paused"></div>
|
||||
<div id="second" class="paused"></div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var container = document.getElementById('container');
|
||||
|
||||
test(() => {
|
||||
const first = document.getElementById('first');
|
||||
assert_equals(getComputedStyle(first).columnRuleColor, 'rgb(30, 30, 0)');
|
||||
first.style.color = 'rgb(0, 0, 60)';
|
||||
assert_equals(getComputedStyle(first).columnRuleColor, 'rgb(0, 30, 30)');
|
||||
}, 'column-rule-color responds to currentColor changes');
|
||||
|
||||
test(() => {
|
||||
const container = document.getElementById('container');
|
||||
const second = document.getElementById('second');
|
||||
assert_equals(getComputedStyle(second).columnRuleColor, 'rgb(40, 0, 40)');
|
||||
container.style.columnRuleColor = 'rgb(0, 80, 0)';
|
||||
assert_equals(getComputedStyle(second).columnRuleColor, 'rgb(0, 40, 40)');
|
||||
}, 'column-rule-color responds to inherited changes');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Animations: column-width animations respond to style changes</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#cw">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
.paused {
|
||||
animation-duration: 4s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: -2s;
|
||||
animation-play-state: paused;
|
||||
}
|
||||
#container {
|
||||
column-width: 40px;
|
||||
font-size: 10px;
|
||||
}
|
||||
#first {
|
||||
animation-name: first-anim;
|
||||
}
|
||||
#second {
|
||||
animation-name: second-anim;
|
||||
}
|
||||
#third {
|
||||
animation-name: third-anim;
|
||||
}
|
||||
@keyframes first-anim {
|
||||
from { column-width: 3em; }
|
||||
to { column-width: 5em; }
|
||||
}
|
||||
@keyframes second-anim {
|
||||
from { column-width: 40px; }
|
||||
to { column-width: calc(40px - 2em); }
|
||||
}
|
||||
@keyframes third-anim {
|
||||
from { column-width: 20px; }
|
||||
to { column-width: inherit; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="first" class="paused"></div>
|
||||
<div id="second" class="paused"></div>
|
||||
<div id="third" class="paused"></div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var container = document.getElementById('container');
|
||||
|
||||
test(() => {
|
||||
const first = document.getElementById('first');
|
||||
assert_equals(getComputedStyle(first).columnWidth, '40px');
|
||||
first.style.fontSize = '20px';
|
||||
assert_equals(getComputedStyle(first).columnWidth, '80px');
|
||||
}, 'column-width responds to font-size changes');
|
||||
|
||||
test(() => {
|
||||
const second = document.getElementById('second');
|
||||
assert_equals(getComputedStyle(second).columnWidth, '30px');
|
||||
second.style.fontSize = '90px';
|
||||
assert_equals(getComputedStyle(second).columnWidth, '0px');
|
||||
}, 'column-width clamps to 0px');
|
||||
|
||||
test(() => {
|
||||
const container = document.getElementById('container');
|
||||
const third = document.getElementById('third');
|
||||
assert_equals(getComputedStyle(third).columnWidth, '30px');
|
||||
container.style.columnWidth = 'auto';
|
||||
assert_equals(getComputedStyle(third).columnWidth, 'auto');
|
||||
}, 'column-width responds to inherited changes');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Masking Module Level 1: parsing mask-position with invalid values</title>
|
||||
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-position">
|
||||
<meta name="assert" content="mask-position supports only the '<position>#' grammar.">
|
||||
<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("mask-position", "auto");
|
||||
test_invalid_value("mask-position", "1px 2px 3px");
|
||||
test_invalid_value("mask-position", "left right");
|
||||
test_invalid_value("mask-position", "bottom 10%");
|
||||
test_invalid_value("mask-position", "bottom 10% top 20%");
|
||||
|
||||
test_invalid_value("mask-position", "center left 1px");
|
||||
test_invalid_value("mask-position", "center top 2px");
|
||||
test_invalid_value("mask-position", "right 3% center");
|
||||
test_invalid_value("mask-position", "left 4px top");
|
||||
test_invalid_value("mask-position", "right top 5px");
|
||||
test_invalid_value("mask-position", "bottom 6% center");
|
||||
test_invalid_value("mask-position", "bottom 7% left");
|
||||
test_invalid_value("mask-position", "bottom right 8%");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Masking Module Level 1: parsing mask-position with valid values</title>
|
||||
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-position">
|
||||
<meta name="assert" content="mask-position supports the full '<position>#' grammar.">
|
||||
<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("mask-position", "10%", "10% center");
|
||||
test_valid_value("mask-position", "right 30% top 60px");
|
||||
test_valid_value("mask-position", "-20% -30px");
|
||||
test_valid_value("mask-position", "30px center");
|
||||
test_valid_value("mask-position", "40px top");
|
||||
test_valid_value("mask-position", "bottom 10% right 20%", "right 20% bottom 10%");
|
||||
test_valid_value("mask-position", "bottom right", "right bottom");
|
||||
test_valid_value("mask-position", "center 50px");
|
||||
test_valid_value("mask-position", "center bottom");
|
||||
test_valid_value("mask-position", "center left", "left center");
|
||||
test_valid_value("mask-position", "left", "left center");
|
||||
test_valid_value("mask-position", "left bottom");
|
||||
test_valid_value("mask-position", "right 40%");
|
||||
test_valid_value("mask-position", "top", "center top");
|
||||
test_valid_value("mask-position", "top center", "center top");
|
||||
test_valid_value("mask-position", "center", "center center");
|
||||
|
||||
test_valid_value("mask-position", "bottom left, right 20%", "left bottom, right 20%");
|
||||
test_valid_value("mask-position", "top, center, left", "center top, center center, left center");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<canvas id ="canvas" width="540" height="550"></canvas>
|
||||
<script>
|
||||
var canvas = document.getElementById('canvas');
|
||||
canvas.style.width = (canvas.width / devicePixelRatio) + 'px';
|
||||
canvas.style.height = (canvas.height / devicePixelRatio) + 'px';
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.scale(devicePixelRatio, devicePixelRatio);
|
||||
var fillW = 250;
|
||||
var fillH = 50;
|
||||
ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 100);
|
||||
ctx.beginPath();
|
||||
ctx.rect(0, 0, fillW, fillH);
|
||||
ctx.closePath();
|
||||
ctx.clip();
|
||||
ctx.fillStyle = 'green';
|
||||
ctx.fillRect(0, 0, fillW, fillH);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-paint-api/#dom-css-paintworklet">
|
||||
<link rel="match" href="canvas-transform-ref.html">
|
||||
<style>
|
||||
.container {
|
||||
width: 270px;
|
||||
height: 275px;
|
||||
}
|
||||
|
||||
#canvas-geometry {
|
||||
background-image: paint(geometry);
|
||||
}
|
||||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="/common/worklet-reftest.js"></script>
|
||||
<body>
|
||||
<div id="canvas-geometry" class="container"></div>
|
||||
|
||||
<script id="code" type="text/worklet">
|
||||
// Regression test for crbug.com/970783. The canvas transform matrix should
|
||||
// account for the devicePixelRatio, such that the clip bounds can be
|
||||
// properly computed when applying clips.
|
||||
registerPaint('geometry', class {
|
||||
paint(ctx, geom) {
|
||||
var fillW = 250;
|
||||
var fillH = 50;
|
||||
ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 100);
|
||||
ctx.beginPath();
|
||||
ctx.rect(0, 0, fillW, fillH);
|
||||
ctx.closePath();
|
||||
ctx.clip();
|
||||
ctx.fillStyle = 'green';
|
||||
ctx.fillRect(0, 0, fillW, fillH);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
<p style="color: blue">Blue <span style="color: green">This text should be green.</span> Blue</p>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo">
|
||||
<link rel="match" href="first-line-change-inline-color-nested-ref.html">
|
||||
<style>
|
||||
#block { color: green; }
|
||||
#block::first-line { color: blue; }
|
||||
.green { color: green; }
|
||||
</style>
|
||||
<div id="block">
|
||||
<div>
|
||||
<p>Blue <span id="target"><span>This text should be green.</span></span> Blue</p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
target.className = 'green';
|
||||
document.documentElement.removeAttribute('class');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
<p style="color: blue">Blue <span style="color: green">This text should be green.</span> Blue</p>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo">
|
||||
<link rel="match" href="first-line-change-inline-color-ref.html">
|
||||
<style>
|
||||
#block { color: green; }
|
||||
#block::first-line { color: blue; }
|
||||
.green { color: green; }
|
||||
</style>
|
||||
<div id="block">
|
||||
<div>
|
||||
<p>Blue <span id="target">This text should be green.</span> Blue</p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
target.className = 'green';
|
||||
document.documentElement.removeAttribute('class');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<div>
|
||||
<span style="color: green">This text should be green.</span><br>
|
||||
<span style="color: blue">This text should be blue.</span>
|
||||
</div>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo">
|
||||
<link rel="match" href="first-line-on-ancestor-block-ref.html">
|
||||
<style>
|
||||
#block::first-line { color: green; }
|
||||
</style>
|
||||
<div id="block">
|
||||
<div>
|
||||
<div style="color: blue">
|
||||
<div>
|
||||
<span><span>This text should be green.</span></span><br>
|
||||
This text should be blue.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<div>
|
||||
<span style="color: green">This text should be green.</span><br>
|
||||
<span style="color: blue">This text should be blue.</span>
|
||||
</div>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo">
|
||||
<link rel="match" href="first-line-with-out-of-flow-ref.html">
|
||||
<style>
|
||||
#block::first-line { color: green; }
|
||||
</style>
|
||||
<div id="block">
|
||||
<div style="position: absolute"><br></div>
|
||||
<div style="float: right"><br></div>
|
||||
<div>
|
||||
<div style="position: absolute"><br></div>
|
||||
<div style="float: right"><br></div>
|
||||
<div style="color: blue">
|
||||
<div>
|
||||
<span><span>This text should be green.</span></span><br>
|
||||
This text should be blue.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS test Reference</title>
|
||||
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
|
||||
|
||||
<style>
|
||||
div {
|
||||
font: 25px/1 Ahem;
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if there is a green square and no red.
|
||||
|
||||
<div>XX<br>XX</div>
|
|
@ -0,0 +1,21 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS Text test: hanging trailing spaces with white-space:pre-wrap</title>
|
||||
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
|
||||
<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
|
||||
<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-004-ref.html">
|
||||
<meta name="assert" content="Preserved white space at the end of the line is hanged when white-space is pre-wrap.">
|
||||
<style>
|
||||
div {
|
||||
font: 25px/1 Ahem;
|
||||
color: green;
|
||||
background: red;
|
||||
|
||||
width: 2ch;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if there is a green square and no red.
|
||||
<div>XX<span> </span>XX</div>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS Text test: hanging trailing spaces with white-space:pre-wrap</title>
|
||||
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
|
||||
<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
|
||||
<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-004-ref.html">
|
||||
<meta name="assert" content="Preserved white space at the end of the line is hanged when white-space is pre-wrap.">
|
||||
<style>
|
||||
div {
|
||||
font: 10px/1 Ahem;
|
||||
}
|
||||
.ref {
|
||||
position: absolute;
|
||||
color: red;
|
||||
z-index: -1;
|
||||
}
|
||||
.ref span { color: green; }
|
||||
.test {
|
||||
color: green;
|
||||
|
||||
width: 5ch;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if there is a green square and no red.
|
||||
<div class="ref">XX<span>XXX</span><br>X<span>XX</span>X<span>X</span><br><span>XXXXX</span><br><span>XXXXX</span><br><span>XXXXX</span></div>
|
||||
<div class="test">XX<span> </span><span>X X </span></div>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS Text test: hanging trailing spaces with white-space:pre-wrap</title>
|
||||
<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
|
||||
<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
|
||||
<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-004-ref.html">
|
||||
<meta name="assert" content="Preserved white space at the end of the line is hanged when white-space is pre-wrap and any overflowing space is removed.">
|
||||
<style>
|
||||
div {
|
||||
font: 25px/1 Ahem;
|
||||
}
|
||||
.ref {
|
||||
position: absolute;
|
||||
color: red;
|
||||
z-index: -1;
|
||||
}
|
||||
.test span { background: red; }
|
||||
.test {
|
||||
color: green;
|
||||
width: 2ch;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.test span { background: green; }
|
||||
</style>
|
||||
|
||||
<p>This test passes if there is a green square and no red.
|
||||
<div class="ref">X<span>X</span><br>XX</div>
|
||||
<div class="test">X<span>  </span><span> XX</span></div>
|
||||
|
|
@ -16,9 +16,11 @@ test_valid_value("scale", "none");
|
|||
|
||||
test_valid_value("scale", "1");
|
||||
|
||||
test_valid_value("scale", "100");
|
||||
test_valid_value("scale", "100 100", "100");
|
||||
test_valid_value("scale", "100 200");
|
||||
test_valid_value("scale", "100 100 1");
|
||||
|
||||
test_valid_value("scale", "100 200");
|
||||
test_valid_value("scale", "100 200 1");
|
||||
test_valid_value("scale", "100 200 300");
|
||||
</script>
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSSOM View - scrollIntoView considers direction:rtl</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#scroll-an-element">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
float: left;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#scroller {
|
||||
direction: rtl;
|
||||
overflow-x: scroll;
|
||||
width: 300px;
|
||||
height: 215px;
|
||||
}
|
||||
#container{
|
||||
width: 600px;
|
||||
height: 200px;
|
||||
}
|
||||
#target {
|
||||
background-color: #ff0;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="scroller">
|
||||
<div id="container">
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box" id="target"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// This page is direction: rtl and scroller is direction: rtl.
|
||||
// So the the overflow direction is leftward, downward. The beginning edges are the top and right edges.
|
||||
// And the ending edges are the bottom and left edges.
|
||||
// Acording to the spec, x is min(0, max(x, element padding edge width - element scrolling area width)).
|
||||
// So x is nonpositive and decreases leftward.
|
||||
|
||||
var target = document.getElementById("target");
|
||||
var scroller = document.getElementById("scroller");
|
||||
var box_width = target.offsetWidth;
|
||||
var scroller_width = scroller.offsetWidth;
|
||||
|
||||
var leftEdge = -2*box_width + scroller_width;
|
||||
var center = -(3*box_width - scroller_width)/2;
|
||||
var rightEdge = - box_width;
|
||||
|
||||
test(() => {
|
||||
scroller.scrollTo(0, 0);
|
||||
target.scrollIntoView({inline: "start"});
|
||||
assert_approx_equals(scroller.scrollLeft, rightEdge, 0.5, "start should be the right edge");
|
||||
}, `scrollIntoView({inline: "start"}), direction: rtl`);
|
||||
|
||||
test(() => {
|
||||
scroller.scrollTo(0, 0);
|
||||
target.scrollIntoView({inline: "center"});
|
||||
assert_approx_equals(scroller.scrollLeft, center, 0.5, "should center the target");
|
||||
}, `scrollIntoView({inline: "center"}), direction: rtl`);
|
||||
|
||||
test(() => {
|
||||
scroller.scrollTo(0, 0);
|
||||
target.scrollIntoView({inline: "end"});
|
||||
assert_approx_equals(scroller.scrollLeft, leftEdge, 0.5, "end should be the left edge");
|
||||
}, `scrollIntoView({inline: "end"}), direction: rtl`);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,111 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSSOM View - scrollIntoView considers horizontal-tb and rtl direction</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#scroll-an-element">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
float: left;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#scroller {
|
||||
direction: rtl;
|
||||
overflow: scroll;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
#container{
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
}
|
||||
#target {
|
||||
background-color: #ff0;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="scroller">
|
||||
<div id="container">
|
||||
<!-- ROW-1 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-2 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box" id="target"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-3 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// In horizontal-tb mode and rtl direction, X corresponds to the inline axis
|
||||
// and is oriented leftward. Y corresponds to the block axis and is oriented
|
||||
// downward. So the beginning edges are the top and right edges and the ending
|
||||
// edges are the bottom and left edges.
|
||||
|
||||
// According to the spec, x is min(0, max(x, element padding edge width - element scrolling area width)).
|
||||
// So x is nonpositive and decreases leftward.
|
||||
|
||||
// This assumes that the horizontal scrollbar is on the bottom side
|
||||
// and the vertical scrollbar is on the left side.
|
||||
|
||||
var target = document.getElementById("target");
|
||||
var scroller = document.getElementById("scroller");
|
||||
var scrollbar_width = scroller.offsetWidth - scroller.clientWidth;
|
||||
|
||||
var scroller_width = scroller.offsetWidth;
|
||||
var scroller_height = scroller.offsetHeight;
|
||||
var box_width = target.offsetWidth;
|
||||
var box_height = target.offsetHeight;
|
||||
|
||||
var expectedX = {
|
||||
inlineStart: -box_width,
|
||||
inlineCenter: -((3*box_width - scroller_width)/2) - scrollbar_width/2,
|
||||
inlineEnd: -(2*box_width - scroller_width) - scrollbar_width,
|
||||
};
|
||||
|
||||
var expectedY = {
|
||||
blockStart: box_height,
|
||||
blockCenter: (3*box_height - scroller_height)/2 + scrollbar_width/2,
|
||||
blockEnd: 2*box_height - scroller_height + scrollbar_width,
|
||||
};
|
||||
|
||||
[
|
||||
[{block: "start", inline: "start"}, expectedX.inlineStart, expectedY.blockStart],
|
||||
[{block: "start", inline: "center"}, expectedX.inlineCenter, expectedY.blockStart],
|
||||
[{block: "start", inline: "end"}, expectedX.inlineEnd, expectedY.blockStart],
|
||||
[{block: "center", inline: "start"}, expectedX.inlineStart, expectedY.blockCenter],
|
||||
[{block: "center", inline: "center"}, expectedX.inlineCenter, expectedY.blockCenter],
|
||||
[{block: "center", inline: "end"}, expectedX.inlineEnd, expectedY.blockCenter],
|
||||
[{block: "end", inline: "start"}, expectedX.inlineStart, expectedY.blockEnd],
|
||||
[{block: "end", inline: "center"}, expectedX.inlineCenter, expectedY.blockEnd],
|
||||
[{block: "end", inline: "end"}, expectedX.inlineEnd, expectedY.blockEnd],
|
||||
].forEach(([input, expectedX, expectedY]) => {
|
||||
test(() => {
|
||||
scroller.scrollTo(0, 0);
|
||||
target.scrollIntoView(input);
|
||||
assert_approx_equals(scroller.scrollLeft, expectedX, 0.5, "scrollX");
|
||||
assert_approx_equals(scroller.scrollTop, expectedY, 0.5, "scrollY");
|
||||
}, `scrollIntoView(${JSON.stringify(input)})`);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,106 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSSOM View - scrollIntoView considers horizontal-tb writing mode</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
float: left;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
#container{
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
}
|
||||
#target {
|
||||
background-color: #ff0;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="scroller">
|
||||
<div id="container">
|
||||
<!-- ROW-1 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-2 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box" id="target"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-3 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// In horizontal-tb mode, X corresponds to the inline axis and is oriented
|
||||
// rightward. Y corresponds to the block axis and is oriented downward.
|
||||
// So the beginning edges are the top and left edges and the ending
|
||||
// edges are the bottom and right edges.
|
||||
|
||||
// This assumes that the horizontal scrollbar is on the bottom side and
|
||||
// the vertical scrollbar is on the right side.
|
||||
|
||||
var target = document.getElementById("target");
|
||||
var scroller = document.getElementById("scroller");
|
||||
var scrollbar_width = scroller.offsetWidth - scroller.clientWidth;
|
||||
|
||||
var scroller_width = scroller.offsetWidth;
|
||||
var scroller_height = scroller.offsetHeight;
|
||||
var box_width = target.offsetWidth;
|
||||
var box_height = target.offsetHeight;
|
||||
|
||||
var expectedX = {
|
||||
inlineStart: box_width,
|
||||
inlineCenter: (3*box_width - scroller_width)/2 + scrollbar_width/2,
|
||||
inlineEnd: 2*box_width - scroller_width + scrollbar_width,
|
||||
};
|
||||
|
||||
var expectedY = {
|
||||
blockStart: box_height,
|
||||
blockCenter: (3*box_height - scroller_height)/2 + scrollbar_width/2,
|
||||
blockEnd: 2*box_height - scroller_height + scrollbar_width,
|
||||
};
|
||||
|
||||
[
|
||||
[{block: "start", inline: "start"}, expectedX.inlineStart, expectedY.blockStart],
|
||||
[{block: "start", inline: "center"}, expectedX.inlineCenter, expectedY.blockStart],
|
||||
[{block: "start", inline: "end"}, expectedX.inlineEnd, expectedY.blockStart],
|
||||
[{block: "center", inline: "start"}, expectedX.inlineStart, expectedY.blockCenter],
|
||||
[{block: "center", inline: "center"}, expectedX.inlineCenter, expectedY.blockCenter],
|
||||
[{block: "center", inline: "end"}, expectedX.inlineEnd, expectedY.blockCenter],
|
||||
[{block: "end", inline: "start"}, expectedX.inlineStart, expectedY.blockEnd],
|
||||
[{block: "end", inline: "center"}, expectedX.inlineCenter, expectedY.blockEnd],
|
||||
[{block: "end", inline: "end"}, expectedX.inlineEnd, expectedY.blockEnd],
|
||||
].forEach(([input, expectedX, expectedY]) => {
|
||||
test(() => {
|
||||
scroller.scrollTo(0, 0);
|
||||
target.scrollIntoView(input);
|
||||
assert_approx_equals(scroller.scrollLeft, expectedX, 0.5, "scrollX");
|
||||
assert_approx_equals(scroller.scrollTop, expectedY, 0.5, "scrollY");
|
||||
}, `scrollIntoView(${JSON.stringify(input)})`);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,112 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSSOM View - scrollIntoView considers vertical-lr and rtl direction</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#scroll-an-element">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
float: left;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#scroller {
|
||||
writing-mode: vertical-lr;
|
||||
direction: rtl;
|
||||
overflow: scroll;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
#container{
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
}
|
||||
#target {
|
||||
background-color: #ff0;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="scroller">
|
||||
<div id="container">
|
||||
<!-- ROW-1 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-2 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box" id="target"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-3 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// In vertical-lr mode and rtl direction, X corresponds to the block axis
|
||||
// and is oriented rightward. Y corresponds to the inline axis and is oriented
|
||||
// upward. So the beginning edges are the bottom and left edges and the ending
|
||||
// edges are the top and right edges.
|
||||
|
||||
// According to the spec, y be min(0, max(y, element padding edge height - element scrolling area height)).
|
||||
// So y is nonpositive and decreases upward.
|
||||
|
||||
// This assumes that the horizontal scrollbar
|
||||
// is on the bottom side and the vertical scrollbar is on the right side.
|
||||
|
||||
var target = document.getElementById("target");
|
||||
var scroller = document.getElementById("scroller");
|
||||
var scrollbar_width = scroller.offsetWidth - scroller.clientWidth;
|
||||
|
||||
var scroller_width = scroller.offsetWidth;
|
||||
var scroller_height = scroller.offsetHeight;
|
||||
var box_width = target.offsetWidth;
|
||||
var box_height = target.offsetHeight;
|
||||
|
||||
var expectedX = {
|
||||
blockStart: box_width,
|
||||
blockCenter: (3*box_width - scroller_width)/2 + scrollbar_width/2,
|
||||
blockEnd: 2*box_width - scroller_width + scrollbar_width,
|
||||
};
|
||||
|
||||
var expectedY = {
|
||||
inlineStart: -box_height,
|
||||
inlineCenter: -((3*box_height - scroller_height)/2) - scrollbar_width/2,
|
||||
inlineEnd: -(2*box_height - scroller_height) - scrollbar_width,
|
||||
};
|
||||
|
||||
[
|
||||
[{block: "start", inline: "start"}, expectedX.blockStart, expectedY.inlineStart],
|
||||
[{block: "start", inline: "center"}, expectedX.blockStart, expectedY.inlineCenter],
|
||||
[{block: "start", inline: "end"}, expectedX.blockStart, expectedY.inlineEnd],
|
||||
[{block: "center", inline: "start"}, expectedX.blockCenter, expectedY.inlineStart],
|
||||
[{block: "center", inline: "center"}, expectedX.blockCenter, expectedY.inlineCenter],
|
||||
[{block: "center", inline: "end"}, expectedX.blockCenter, expectedY.inlineEnd],
|
||||
[{block: "end", inline: "start"}, expectedX.blockEnd, expectedY.inlineStart],
|
||||
[{block: "end", inline: "center"}, expectedX.blockEnd, expectedY.inlineCenter],
|
||||
[{block: "end", inline: "end"}, expectedX.blockEnd, expectedY.inlineEnd],
|
||||
].forEach(([input, expectedX, expectedY]) => {
|
||||
test(() => {
|
||||
scroller.scrollTo(0, 0);
|
||||
target.scrollIntoView(input);
|
||||
assert_approx_equals(scroller.scrollLeft, expectedX, 0.5, "scrollX");
|
||||
assert_approx_equals(scroller.scrollTop, expectedY, 0.5, "scrollY");
|
||||
}, `scrollIntoView(${JSON.stringify(input)})`);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,107 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSSOM View - scrollIntoView considers vertical-lr writing mode</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
float: left;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#scroller {
|
||||
writing-mode: vertical-lr;
|
||||
overflow: scroll;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
#container{
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
}
|
||||
#target {
|
||||
background-color: #ff0;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="scroller">
|
||||
<div id="container">
|
||||
<!-- ROW-1 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-2 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box" id="target"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
|
||||
<!-- ROW-3 -->
|
||||
<div class="row">
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// In vertical-lr mode, X corresponds to the block axis and is oriented
|
||||
// rightward. Y corresponds to the inline axis and is oriented downward.
|
||||
// So the beginning edges are the top and left edges and the ending
|
||||
// edges are the bottom and right edges.
|
||||
|
||||
// This assumes that the horizontal scrollbar is on the bottom side and
|
||||
// the vertical scrollbar is on the right side.
|
||||
|
||||
var target = document.getElementById("target");
|
||||
var scroller = document.getElementById("scroller");
|
||||
var scrollbar_width = scroller.offsetWidth - scroller.clientWidth;
|
||||
|
||||
var scroller_width = scroller.offsetWidth;
|
||||
var scroller_height = scroller.offsetHeight;
|
||||
var box_width = target.offsetWidth;
|
||||
var box_height = target.offsetHeight;
|
||||
|
||||
var expectedX = {
|
||||
blockStart: box_width,
|
||||
blockCenter: (3*box_width - scroller_width)/2 + (scrollbar_width/2),
|
||||
blockEnd: (2*box_width) - scroller_width + scrollbar_width,
|
||||
};
|
||||
|
||||
var expectedY = {
|
||||
inlineStart: box_height,
|
||||
inlineCenter: ((3*box_height - scroller_height)/2) + (scrollbar_width/2),
|
||||
inlineEnd: ((2*box_height) - scroller_height) + scrollbar_width,
|
||||
};
|
||||
|
||||
[
|
||||
[{block: "start", inline: "start"}, expectedX.blockStart, expectedY.inlineStart],
|
||||
[{block: "start", inline: "center"}, expectedX.blockStart, expectedY.inlineCenter],
|
||||
[{block: "start", inline: "end"}, expectedX.blockStart, expectedY.inlineEnd],
|
||||
[{block: "center", inline: "start"}, expectedX.blockCenter, expectedY.inlineStart],
|
||||
[{block: "center", inline: "center"}, expectedX.blockCenter, expectedY.inlineCenter],
|
||||
[{block: "center", inline: "end"}, expectedX.blockCenter, expectedY.inlineEnd],
|
||||
[{block: "end", inline: "start"}, expectedX.blockEnd, expectedY.inlineStart],
|
||||
[{block: "end", inline: "center"}, expectedX.blockEnd, expectedY.inlineCenter],
|
||||
[{block: "end", inline: "end"}, expectedX.blockEnd, expectedY.inlineEnd],
|
||||
].forEach(([input, expectedX, expectedY]) => {
|
||||
test(() => {
|
||||
scroller.scrollTo(0, 0);
|
||||
target.scrollIntoView(input);
|
||||
assert_approx_equals(scroller.scrollLeft, expectedX, 0.5, "scrollX");
|
||||
assert_approx_equals(scroller.scrollTop, expectedY, 0.5, "scrollY");
|
||||
}, `scrollIntoView(${JSON.stringify(input)})`);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -55,7 +55,11 @@
|
|||
<script>
|
||||
// In vertical-rl mode, X corresponds to the block axis and is oriented
|
||||
// leftward. Y corresponds to the inline axis and is oriented downward.
|
||||
// So the beginning edges are the top and right edges and the ending
|
||||
// edges are the bottom and left edges.
|
||||
|
||||
// This assumes that the horizontal scrollbar is on the bottom side.
|
||||
|
||||
var target = document.getElementById("target");
|
||||
var scroller = document.getElementById("scroller");
|
||||
var scrollbar_width = scroller.offsetWidth - scroller.clientWidth;
|
||||
|
@ -102,17 +106,6 @@ if(scroller.scrollLeft === 0) {
|
|||
};
|
||||
}
|
||||
|
||||
// This formats dict as a string suitable as test name.
|
||||
// format_value() is provided by testharness.js,
|
||||
// which also preserves sign for -0.
|
||||
function format_dict(dict) {
|
||||
const props = [];
|
||||
for (let prop in dict) {
|
||||
props.push(`${prop}: ${format_value(dict[prop])}`);
|
||||
}
|
||||
return `{${props.join(", ")}}`;
|
||||
}
|
||||
|
||||
[
|
||||
[{block: "start", inline: "start"}, expectedX.blockStart, expectedY.inlineStart],
|
||||
[{block: "start", inline: "center"}, expectedX.blockStart, expectedY.inlineCenter],
|
||||
|
@ -129,7 +122,7 @@ function format_dict(dict) {
|
|||
target.scrollIntoView(input);
|
||||
assert_approx_equals(scroller.scrollLeft, expectedX, 0.5, "scrollX");
|
||||
assert_approx_equals(scroller.scrollTop, expectedY, 0.5, "scrollY");
|
||||
}, `scrollIntoView(${format_dict(input)})`);
|
||||
}, `scrollIntoView(${JSON.stringify(input)})`);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
<script>
|
||||
/*
|
||||
In this test, a slow image is added to the frame to delay onload. The entry
|
||||
for the other image should be available before onload, and thus delivered to
|
||||
the performance timeline.
|
||||
is available from the observer with the buffered flag set to true.
|
||||
*/
|
||||
async_test(function(t) {
|
||||
if (!window.PerformanceElementTiming) {
|
||||
|
@ -23,18 +22,26 @@
|
|||
img.setAttribute('elementtiming', 'my_image');
|
||||
img.setAttribute('id', 'my_id');
|
||||
document.body.appendChild(img);
|
||||
window.onload = t.step_func_done( () => {
|
||||
const entries = performance.getEntriesByType('element');
|
||||
assert_greater_than_equal(entries.length, 1);
|
||||
assert_equals(performance.getEntries().filter(e => e.identifier === 'my_image').length, 1);
|
||||
const entry = entries[0];
|
||||
const index = window.location.href.lastIndexOf('/');
|
||||
const pathname = window.location.href.substring(0, index) +
|
||||
'/resources/square20.jpg';
|
||||
checkElement(entry, pathname, 'my_image', 'my_id', beforeRender, img);
|
||||
checkNaturalSize(entry, 20, 20);
|
||||
|
||||
// this PerformanceObserver should be notified about the previously
|
||||
// buffered element entry
|
||||
new PerformanceObserver(function (entryList, observer) {
|
||||
assert_equals(entryList.getEntries().length, 1);
|
||||
entryList.getEntries().forEach(function(entry) {
|
||||
assert_equals(entry.entryType, "element");
|
||||
const index = window.location.href.lastIndexOf('/');
|
||||
const pathname = window.location.href.substring(0, index) +
|
||||
'/resources/square20.jpg';
|
||||
checkElement(entry, pathname, 'my_image', 'my_id', beforeRender, img);
|
||||
checkNaturalSize(entry, 20, 20);
|
||||
observer.disconnect();
|
||||
t.done();
|
||||
});
|
||||
}).observe({
|
||||
type: "element",
|
||||
buffered: true
|
||||
});
|
||||
}, "Element Timing: image loads before onload.");
|
||||
}, "Element Timing: image loads before onload available from buffered flag.");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -27,9 +27,7 @@
|
|||
firstClickEnd = performance.now();
|
||||
}
|
||||
|
||||
function validateEntries() {
|
||||
const entries = performance.getEntriesByName('mousedown', 'event');
|
||||
|
||||
function validateEntries(entries) {
|
||||
const entriesBeforeOnload = entries.filter(
|
||||
e => e.startTime < onloadStart);
|
||||
assert_equals(entriesBeforeOnload.length, 1,
|
||||
|
@ -48,8 +46,8 @@
|
|||
|
||||
const entriesAfterOnload = entries.filter(
|
||||
e => e.startTime >= onloadStart);
|
||||
assert_equals(entriesAfterOnload.length, 0,
|
||||
"Events after onload shouldn't be buffered.");
|
||||
assert_equals(entriesAfterOnload.length, 1,
|
||||
"Events after onload should still be buffered.");
|
||||
}
|
||||
|
||||
/* Timeline:
|
||||
|
@ -66,24 +64,31 @@
|
|||
async_test(function(t) {
|
||||
clickTimeMin = performance.now();
|
||||
clickAndBlockMain('button');
|
||||
// Use a dummy observer to know when both clicks have been dispatched.
|
||||
const observerPromise = new Promise((resolve, reject) => {
|
||||
let entryCount = 0;
|
||||
new PerformanceObserver(entryList => {
|
||||
entryCount += entryList.getEntries().filter(
|
||||
entry => entry.name === 'mousedown').length;
|
||||
if (entryCount >= 2)
|
||||
resolve();
|
||||
}).observe({ entryTypes: ['event'] });
|
||||
});
|
||||
// Event handlers will be dispatched asynchronously, so this will be called
|
||||
// before processing begins.
|
||||
processingStartMin = performance.now();
|
||||
const bufferedEntries = [];
|
||||
on_event(window, 'load', e => {
|
||||
onloadStart = performance.now();
|
||||
const clickPromise = clickAndBlockMain('button');
|
||||
Promise.all([observerPromise, clickPromise]).then(
|
||||
t.step_func_done(validateEntries));
|
||||
// Register the observer after the page has been loaded
|
||||
const observer = new PerformanceObserver(function (entryList, observer) {
|
||||
entryList.getEntries().forEach(function(entry) {
|
||||
assert_equals(entry.entryType, "event");
|
||||
if (entry.name === 'mousedown') {
|
||||
bufferedEntries.push(entry);
|
||||
}
|
||||
if (bufferedEntries.length == 2) {
|
||||
validateEntries(bufferedEntries)
|
||||
observer.disconnect();
|
||||
t.done();
|
||||
}
|
||||
});
|
||||
})
|
||||
observer.observe({
|
||||
type: "event",
|
||||
buffered: true
|
||||
});
|
||||
clickAndBlockMain('button');
|
||||
});
|
||||
}, "Event Timing: click, onload.");
|
||||
|
||||
|
|
|
@ -20,19 +20,6 @@
|
|||
let onloadStart;
|
||||
let observedEntries = [];
|
||||
|
||||
function verifyBuffer(bufferedEntries) {
|
||||
assert_equals(bufferedEntries.length, 1,
|
||||
"Only events before onload should be buffered.");
|
||||
const entry = bufferedEntries[0];
|
||||
assert_greater_than(onloadStart, entry.startTime,
|
||||
"Onload should be later than entry's start time.");
|
||||
assert_greater_than(entry.processingStart, timeBeforeFirstClick,
|
||||
"The entry's processing start should be after timeBeforeFirstClick");
|
||||
assert_less_than(entry.processingStart, timeAfterFirstClick,
|
||||
"The entry's processing start should be before timeAfterFirstClick.");
|
||||
verifyClickEvent(entry, true);
|
||||
}
|
||||
|
||||
function verifyObserverEntries(observedEntries) {
|
||||
const entriesAfterFirstClick = observedEntries.filter(
|
||||
e => e.startTime > timeAfterFirstClick);
|
||||
|
@ -60,6 +47,9 @@
|
|||
"entry2's processing start should be berfore timeAfterFirstClick.");
|
||||
assert_greater_than(timeAfterFirstClick, entry2.startTime,
|
||||
"timeAfterFirstClick should be later than entry2's start time.");
|
||||
// This should happen before onLoad
|
||||
assert_greater_than(onloadStart, entry2.startTime,
|
||||
"Onload should be later than entry's start time.");
|
||||
}
|
||||
|
||||
/* Timeline:
|
||||
|
@ -82,7 +72,7 @@
|
|||
entry => entry.name === 'mousedown'));
|
||||
if (observedEntries.length < 2) return;
|
||||
resolve(observedEntries);
|
||||
}).observe({ entryTypes: ['event'] });
|
||||
}).observe({ type: 'event' , buffered: true});
|
||||
});
|
||||
timeBeforeFirstClick = performance.now();
|
||||
clickAndBlockMain('button').then( () => {
|
||||
|
@ -95,7 +85,6 @@
|
|||
Promise.all([observerPromise, bufferPromise]).then((results) => {
|
||||
timeAfterSecondClick = performance.now();
|
||||
t.step(verifyObserverEntries.bind(null, results[0]));
|
||||
t.step(verifyBuffer.bind(null, performance.getEntriesByName('mousedown', 'event')));
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,30 +23,38 @@
|
|||
async_test(function(t) {
|
||||
let numFirstInputObserved = 0;
|
||||
let numEventsObserved = 0;
|
||||
new PerformanceObserver(t.step_func((entryList, obs) => {
|
||||
const observedEntries = entryList.getEntries().filter(
|
||||
entry => entry.name === 'mousedown');
|
||||
numEventsObserved += observedEntries.filter(entry =>
|
||||
entry.entryType == 'event').length;
|
||||
numFirstInputObserved += observedEntries.filter(entry =>
|
||||
entry.entryType == 'firstInput').length;
|
||||
let observedEventEntries = [];
|
||||
|
||||
const event_observer_promise = new Promise((resolve, reject) => {
|
||||
new PerformanceObserver(function(entryList) {
|
||||
observedEventEntries = entryList.getEntries().filter(
|
||||
entry => entry.name === 'mousedown');
|
||||
numEventsObserved += observedEventEntries.length;
|
||||
if (numEventsObserved >= 2) {
|
||||
assert_equals(performance.getEntriesByType('event').length, 0,
|
||||
"There should be no buffered event entries.");
|
||||
assert_equals(performance.getEntriesByType('firstInput').length, 1,
|
||||
"There should be a buffered firstInput entry.");
|
||||
// There should be 2 event entries and one firstInput entry.
|
||||
// There should be 2 event entries.
|
||||
assert_equals(numEventsObserved, 2,
|
||||
"There should be 2 observed event entries.");
|
||||
assert_equals(numFirstInputObserved, 1,
|
||||
"There should be only 1 observed firstInput entry.");
|
||||
t.done();
|
||||
resolve();
|
||||
}
|
||||
})).observe({ entryTypes: ['event', 'firstInput'] });
|
||||
on_event(window, 'load', () => {
|
||||
clickAndBlockMain('button').then(() => {
|
||||
}).observe({ type: 'event' , buffered: true});
|
||||
});
|
||||
|
||||
const first_input_observer_promise = new Promise((resolve, reject) => {
|
||||
new PerformanceObserver(function(entryList) {
|
||||
assert_equals(entryList.getEntries().length, 1);
|
||||
resolve();
|
||||
}).observe({ type: 'firstInput' , buffered: true});
|
||||
});
|
||||
|
||||
on_event(window, 'load', function(e) {
|
||||
const click_promise = clickAndBlockMain('button').then(() => {
|
||||
clickAndBlockMain('button');
|
||||
});
|
||||
Promise.all(
|
||||
[event_observer_promise, first_input_observer_promise, click_promise]
|
||||
).then(() => {
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
},
|
||||
"Event Timing: check firstInput after onload, observer, click, click."
|
||||
|
|
|
@ -17,16 +17,9 @@ registration are lost
|
|||
let observerStart;
|
||||
let processingStartMin;
|
||||
|
||||
function verifyBufferAndObserverEntries(observedEntries) {
|
||||
// Verify buffer entries
|
||||
const bufferedEntries = performance.getEntriesByName('mousedown', 'event');
|
||||
const bufferedEntriesBeforeObserver = bufferedEntries.filter(e => e.startTime <
|
||||
observerStart);
|
||||
assert_equals(bufferedEntries.length, 0,
|
||||
"Long latency events after onload should not be buffered."
|
||||
);
|
||||
|
||||
// Verify observer entries
|
||||
function verifyObserverEntries(observedEntries) {
|
||||
// Verify observer entries. Should not include first click since we didn't
|
||||
// buffered to true.
|
||||
assert_equals(observedEntries.length, 1, "Long latency task after observer start should be observed.");
|
||||
const entry = observedEntries[0];
|
||||
verifyClickEvent(entry);
|
||||
|
@ -45,8 +38,8 @@ registration are lost
|
|||
callbackTime = performance.now();
|
||||
const observedEntries = entryList.getEntries().filter(
|
||||
entry => entry.name === 'mousedown');
|
||||
verifyBufferAndObserverEntries(observedEntries);
|
||||
})).observe({ entryTypes: ['event'] });
|
||||
verifyObserverEntries(observedEntries);
|
||||
})).observe({ type: 'event'});
|
||||
observerStart = performance.now();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<html>
|
||||
<script src=event-timing-test-utils.js></script>
|
||||
<button id='button_child_frame'>Generate a 'click' event</button>
|
||||
<img src=slow-image.py>
|
||||
<script>
|
||||
const clickTimeMin = performance.now();
|
||||
clickAndBlockMain('button_child_frame');
|
||||
|
@ -10,7 +9,7 @@
|
|||
const observerPromise = new Promise((resolve, reject) => {
|
||||
new PerformanceObserver((entryList) => {
|
||||
resolve(entryList.getEntries().filter(entry => entry.name === 'mousedown'));
|
||||
}).observe({ entryTypes: ['event'] });
|
||||
}).observe({ type:'event', buffered: true });
|
||||
});
|
||||
window.addEventListener('load', e => {
|
||||
observerPromise.then((observedEntries) => {
|
||||
|
|
|
@ -58,6 +58,7 @@ protected_mime_types = [
|
|||
"application/x-protobuf",
|
||||
"application/x-www-form-urlencoded",
|
||||
"application/zip",
|
||||
"multipart/byteranges",
|
||||
"text/event-stream",
|
||||
// TODO(lukasza): https://crbug.com/944162: Add application/pdf and
|
||||
// text/csv to the list of content types tested here (after
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<title>iframe with scrolling attr equals yes</title>
|
||||
<link rel="author" title="Jinfeng Ma" href="mailto:majinfeng1@xiaomi.org">
|
||||
|
||||
<p>Test passes if you can see the scrollbars of the iframe displayed below.</p>
|
||||
<iframe src="support/iframe-which-content-height-equals-400px.html" scrolling="yes" width="200px" height="100px">
|
||||
</iframe>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<title>modify iframe scrolling attr to yes</title>
|
||||
<link rel="author" title="Jinfeng Ma" href="mailto:majinfeng1@xiaomi.org">
|
||||
<link rel="help" href="https://www.w3.org/TR/html401/present/frames.html#adef-scrolling">
|
||||
<link rel="match" href="iframe-modify-scrolling-attr-to-yes-ref.html">
|
||||
|
||||
<p>Test passes if you can see the scrollbars of the iframe displayed below.</p>
|
||||
<iframe src="support/iframe-which-content-height-equals-400px.html" scrolling="no" width="200px" height="100px">
|
||||
</iframe>
|
||||
|
||||
<script>
|
||||
let iframe = document.querySelector("iframe");
|
||||
iframe.onload = function () {
|
||||
iframe.scrolling = 'yes';
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<body style="width: 200px; height: 400px">
|
||||
iframe content
|
||||
</body>
|
|
@ -1,8 +0,0 @@
|
|||
[actionsWithKeyPressed.html]
|
||||
expected:
|
||||
if product == "safari": ERROR
|
||||
|
||||
[TestDriver actions: actions with key pressed]
|
||||
expected:
|
||||
if product == "firefox": FAIL
|
||||
if os == "mac" and product == "chrome": FAIL
|
|
@ -1,67 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>TestDriver actions: actions with key pressed</title>
|
||||
<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>
|
||||
|
||||
<style>
|
||||
div#test1, div#test2 {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
div#test2 {
|
||||
position: fixed;
|
||||
top: 100px;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="test1">
|
||||
</div>
|
||||
|
||||
<div id="test2">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let keys = [];
|
||||
|
||||
async_test(t => {
|
||||
let test1 = document.getElementById("test1");
|
||||
let test2 = document.getElementById("test2");
|
||||
document.getElementById("test1").addEventListener("click",
|
||||
e => {keys.push(e.getModifierState("Control"))});
|
||||
document.getElementById("test2").addEventListener("click",
|
||||
e => {keys.push(e.getModifierState("Control"))});
|
||||
|
||||
let actions = new test_driver.Actions()
|
||||
.keyDown("\uE009")
|
||||
.addTick()
|
||||
.pointerMove(0, 0, {origin: test1})
|
||||
.pointerDown()
|
||||
.pointerUp()
|
||||
.pointerMove(0, 0, {origin: test2})
|
||||
.pointerDown()
|
||||
.pointerUp()
|
||||
.addTick()
|
||||
.keyUp("\uE009")
|
||||
.addTick()
|
||||
.pointerMove(0, 0, {origin: test1})
|
||||
.pointerDown()
|
||||
.pointerUp();
|
||||
|
||||
actions.send()
|
||||
.then(t.step_func_done(() => assert_array_equals(keys, [true, true, false])))
|
||||
.catch(e => t.step_func(() => assert_unreached("Actions sequence failed " + e)));
|
||||
});
|
||||
</script>
|
|
@ -10,7 +10,8 @@ typedef (Int8Array or Int16Array or Int32Array or
|
|||
typedef (ArrayBufferView or ArrayBuffer) BufferSource;
|
||||
[
|
||||
Exposed=(Window,Worker),
|
||||
Constructor(optional DOMString message = "", optional DOMString name = "Error")
|
||||
Constructor(optional DOMString message = "", optional DOMString name = "Error"),
|
||||
Serializable
|
||||
]
|
||||
interface DOMException { // but see below note about ECMAScript binding
|
||||
readonly attribute DOMString name;
|
||||
|
|
|
@ -10,7 +10,7 @@ partial interface Navigator {
|
|||
[SecureContext, Exposed=Window] interface XR : EventTarget {
|
||||
// Methods
|
||||
Promise<void> supportsSession(XRSessionMode mode);
|
||||
Promise<XRSession> requestSession(XRSessionMode mode);
|
||||
Promise<XRSession> requestSession(XRSessionMode mode, optional XRSessionInit options);
|
||||
|
||||
// Events
|
||||
attribute EventHandler ondevicechange;
|
||||
|
@ -22,6 +22,11 @@ enum XRSessionMode {
|
|||
"immersive-ar"
|
||||
};
|
||||
|
||||
dictionary XRSessionInit {
|
||||
sequence<DOMString> requiredFeatures;
|
||||
sequence<DOMString> optionalFeatures;
|
||||
};
|
||||
|
||||
enum XREnvironmentBlendMode {
|
||||
"opaque",
|
||||
"additive",
|
||||
|
@ -239,13 +244,11 @@ dictionary XRSessionEventInit : EventInit {
|
|||
interface XRInputSourceEvent : Event {
|
||||
[SameObject] readonly attribute XRFrame frame;
|
||||
[SameObject] readonly attribute XRInputSource inputSource;
|
||||
[SameObject] readonly attribute long? buttonIndex;
|
||||
};
|
||||
|
||||
dictionary XRInputSourceEventInit : EventInit {
|
||||
required XRFrame frame;
|
||||
required XRInputSource inputSource;
|
||||
long? buttonIndex = null;
|
||||
};
|
||||
|
||||
[SecureContext, Exposed=Window, Constructor(DOMString type, XRInputSourcesChangeEventInit eventInitDict)]
|
||||
|
|
|
@ -30,8 +30,11 @@
|
|||
assert_greater_than_equal(entry.startTime, startTime)
|
||||
assert_less_than_equal(entry.startTime, endTime)
|
||||
assert_equals(entry.duration, 0.0);
|
||||
// The layout shift value should be: 300 * (100 + 60) / viewport size.
|
||||
assert_equals(entry.value, 300 * (100 + 60) /
|
||||
const maxDimension = Math.max(document.documentElement.clientWidth,
|
||||
document.documentElement.clientHeight);
|
||||
// The layout shift value should be:
|
||||
// 300 * (100 + 60) * (60 / maxDimension) / viewport size.
|
||||
assert_equals(entry.value, 300 * (100 + 60) * (60 / maxDimension) /
|
||||
(document.documentElement.clientWidth * document.documentElement.clientHeight));
|
||||
t.done();
|
||||
}
|
||||
|
|
|
@ -51,8 +51,11 @@
|
|||
assert_greater_than_equal(entry.startTime, startTime)
|
||||
assert_less_than_equal(entry.startTime, endTime)
|
||||
assert_equals(entry.duration, 0.0);
|
||||
// The layout shift value should be: 300 * (100 + 60) / viewport size.
|
||||
assert_equals(entry.value, 300 * (100 + 60) /
|
||||
const maxDimension = Math.max(document.documentElement.clientWidth,
|
||||
document.documentElement.clientHeight);
|
||||
// The layout shift value should be:
|
||||
// 300 * (100 + 60) * (60 / maxDimension) / viewport size.
|
||||
assert_equals(entry.value, 300 * (100 + 60) * (60 / maxDimension) /
|
||||
(document.documentElement.clientWidth * document.documentElement.clientHeight));
|
||||
})
|
||||
);
|
||||
|
@ -75,8 +78,11 @@
|
|||
assert_greater_than_equal(entry.startTime, startTime)
|
||||
assert_less_than_equal(entry.startTime, endTime)
|
||||
assert_equals(entry.duration, 0.0);
|
||||
// The layout shift value should be: 300 * (100 + 60) / viewport size.
|
||||
assert_equals(entry.value, 300 * (100 + 60) /
|
||||
const maxDimension = Math.max(document.documentElement.clientWidth,
|
||||
document.documentElement.clientHeight);
|
||||
// The layout shift value should be:
|
||||
// 300 * (100 + 60) * (60 / maxDimension) / viewport size.
|
||||
assert_equals(entry.value, 300 * (100 + 60) * (60 / maxDimension) /
|
||||
(document.documentElement.clientWidth * document.documentElement.clientHeight));
|
||||
// We should see that there was a click input entry
|
||||
assert_equals(entry.hadRecentInput, true);
|
||||
|
|
|
@ -3,39 +3,74 @@ promise_test(async t => cleanupSandboxedFileSystem(),
|
|||
'Cleanup to setup test environment');
|
||||
|
||||
promise_test(async t => {
|
||||
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const handle = await createFileWithContents(t, 'file-to-remove', '12345', dir);
|
||||
await createFileWithContents(t, 'file-to-keep', 'abc');
|
||||
await handle.remove();
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const handle = await createFileWithContents(t, 'file-to-remove', '12345', root);
|
||||
await createFileWithContents(t, 'file-to-keep', 'abc', root);
|
||||
await root.removeEntry('file-to-remove');
|
||||
|
||||
assert_array_equals(await getSortedDirectoryEntries(dir), ['file-to-keep']);
|
||||
assert_array_equals(await getSortedDirectoryEntries(root), ['file-to-keep']);
|
||||
await promise_rejects(t, 'NotFoundError', getFileContents(handle));
|
||||
}, 'remove() to remove a file');
|
||||
}, 'removeEntry() to remove a file');
|
||||
|
||||
promise_test(async t => {
|
||||
const handle = await createFileWithContents(t, 'file-to-remove', '12345');
|
||||
await handle.remove();
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const handle = await createFileWithContents(t, 'file-to-remove', '12345', root);
|
||||
await root.removeEntry('file-to-remove');
|
||||
|
||||
await promise_rejects(t, 'NotFoundError', handle.remove());
|
||||
}, 'remove() on an already removed file should fail');
|
||||
await promise_rejects(t, 'NotFoundError', root.removeEntry('file-to-remove'));
|
||||
}, 'removeEntry() on an already removed file should fail');
|
||||
|
||||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const dir = await root.getDirectory('dir-to-remove', { create: true });
|
||||
await createFileWithContents(t, 'file-to-keep', 'abc');
|
||||
await dir.remove();
|
||||
await createFileWithContents(t, 'file-to-keep', 'abc', root);
|
||||
await root.removeEntry('dir-to-remove');
|
||||
|
||||
assert_array_equals(await getSortedDirectoryEntries(root), ['file-to-keep']);
|
||||
await promise_rejects(t, 'NotFoundError', getSortedDirectoryEntries(dir));
|
||||
}, 'remove() to remove an empty directory');
|
||||
}, 'removeEntry() to remove an empty directory');
|
||||
|
||||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const dir = await root.getDirectory('dir-to-remove', { create: true });
|
||||
t.add_cleanup(() => dir.removeRecursively());
|
||||
t.add_cleanup(() => root.removeEntry('dir-to-remove', { recursive: true }));
|
||||
await createEmptyFile(t, 'file-in-dir', dir);
|
||||
|
||||
await promise_rejects(t, 'InvalidModificationError', dir.remove());
|
||||
await promise_rejects(t, 'InvalidModificationError', root.removeEntry('dir-to-remove'));
|
||||
assert_array_equals(await getSortedDirectoryEntries(root), ['dir-to-remove/']);
|
||||
assert_array_equals(await getSortedDirectoryEntries(dir), ['file-in-dir']);
|
||||
}, 'remove() on a non-empty directory should fail');
|
||||
}, 'removeEntry() on a non-empty directory should fail');
|
||||
|
||||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const dir = await createDirectory(t, 'dir', root);
|
||||
await promise_rejects(t, 'NotFoundError', dir.removeEntry(""));
|
||||
}, 'removeEntry() with empty name should fail');
|
||||
|
||||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const dir = await createDirectory(t, 'dir', root);
|
||||
await promise_rejects(t, 'SecurityError', dir.removeEntry(kCurrentDirectory));
|
||||
}, `removeEntry() with "${kCurrentDirectory}" name should fail`);
|
||||
|
||||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const dir = await createDirectory(t, 'dir', root);
|
||||
await promise_rejects(t, 'SecurityError', dir.removeEntry(kParentDirectory));
|
||||
}, `removeEntry() with "${kParentDirectory}" name should fail`);
|
||||
|
||||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
|
||||
const dir_name = 'dir-name';
|
||||
const dir = await createDirectory(t, dir_name, root);
|
||||
|
||||
const file_name = 'file-name';
|
||||
await createEmptyFile(t, file_name, dir);
|
||||
|
||||
for (let i = 0; i < kPathSeparators.length; ++i) {
|
||||
const path_with_separator = `${dir_name}${kPathSeparators[i]}${file_name}`;
|
||||
await promise_rejects(t, 'SecurityError', root.removeEntry(path_with_separator),
|
||||
`removeEntry() must reject names containing "${kPathSeparators[i]}"`);
|
||||
}
|
||||
}, 'removeEntry() with a path separator should fail.');
|
||||
|
|
|
@ -10,7 +10,7 @@ promise_test(async t => {
|
|||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const handle = await root.getDirectory('non-existing-dir', { create: true });
|
||||
t.add_cleanup(() => handle.removeRecursively());
|
||||
t.add_cleanup(() => root.removeEntry('non-existing-dir', { recursive: true }));
|
||||
|
||||
assert_false(handle.isFile);
|
||||
assert_true(handle.isDirectory);
|
||||
|
@ -22,7 +22,7 @@ promise_test(async t => {
|
|||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const existing_handle = await root.getDirectory('dir-with-contents', { create: true });
|
||||
t.add_cleanup(() => existing_handle.removeRecursively());
|
||||
t.add_cleanup(() => root.removeEntry('dir-with-contents', { recursive: true }));
|
||||
const file_handle = await createEmptyFile(t, 'test-file', existing_handle);
|
||||
|
||||
const handle = await root.getDirectory('dir-with-contents', { create: false });
|
||||
|
@ -36,7 +36,7 @@ promise_test(async t => {
|
|||
promise_test(async t => {
|
||||
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const existing_handle = await root.getDirectory('dir-with-contents', { create: true });
|
||||
t.add_cleanup(() => existing_handle.removeRecursively());
|
||||
t.add_cleanup(() => root.removeEntry('dir-with-contents', { recursive: true }));
|
||||
const file_handle = await existing_handle.getFile('test-file', { create: true });
|
||||
|
||||
const handle = await root.getDirectory('dir-with-contents', { create: true });
|
||||
|
|
|
@ -10,7 +10,7 @@ promise_test(async t => {
|
|||
promise_test(async t => {
|
||||
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const handle = await dir.getFile('non-existing-file', { create: true });
|
||||
t.add_cleanup(() => handle.remove());
|
||||
t.add_cleanup(() => dir.removeEntry('non-existing-file'));
|
||||
|
||||
assert_true(handle.isFile);
|
||||
assert_false(handle.isDirectory);
|
||||
|
@ -48,7 +48,7 @@ promise_test(async t => {
|
|||
promise_test(async t => {
|
||||
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const dir_handle = await dir.getDirectory('dir-name', { create: true });
|
||||
t.add_cleanup(() => dir_handle.removeRecursively());
|
||||
t.add_cleanup(() => dir.removeEntry('dir-name', { recursive: true }));
|
||||
|
||||
await promise_rejects(t, 'TypeMismatchError', dir.getFile('dir-name'));
|
||||
}, 'getFile(create=false) when a directory already exists with the same name');
|
||||
|
@ -56,7 +56,7 @@ promise_test(async t => {
|
|||
promise_test(async t => {
|
||||
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
const dir_handle = await dir.getDirectory('dir-name', { create: true });
|
||||
t.add_cleanup(() => dir_handle.removeRecursively());
|
||||
t.add_cleanup(() => dir.removeEntry('dir-name', { recursive: true }));
|
||||
|
||||
await promise_rejects(t, 'TypeMismatchError', dir.getFile('dir-name', { create: true }));
|
||||
}, 'getFile(create=true) when a directory already exists with the same name');
|
||||
|
|
|
@ -15,12 +15,8 @@ if (navigator.userAgent.includes("Windows NT")) {
|
|||
|
||||
async function cleanupSandboxedFileSystem() {
|
||||
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
|
||||
for await (let entry of dir.getEntries()) {
|
||||
if (entry.isDirectory)
|
||||
await entry.removeRecursively();
|
||||
else
|
||||
await entry.remove();
|
||||
}
|
||||
for await (let entry of dir.getEntries())
|
||||
dir.removeEntry(entry.name, { recursive: entry.isDirectory });
|
||||
}
|
||||
|
||||
async function getFileSize(handle) {
|
||||
|
@ -60,7 +56,7 @@ async function createDirectory(test, name, parent) {
|
|||
const new_dir_handle = await parent_dir_handle.getDirectory(name, { create: true });
|
||||
test.add_cleanup(async () => {
|
||||
try {
|
||||
await new_dir_handle.removeRecursively();
|
||||
await parent_dir_handle.removeEntry(name, { recursive: true });
|
||||
} catch (e) {
|
||||
// Ignore any errors when removing directories, as tests might
|
||||
// have already removed the directory.
|
||||
|
@ -74,7 +70,7 @@ async function createEmptyFile(test, name, parent) {
|
|||
const handle = await dir.getFile(name, { create: true });
|
||||
test.add_cleanup(async () => {
|
||||
try {
|
||||
await handle.remove();
|
||||
await dir.removeEntry(name);
|
||||
} catch (e) {
|
||||
// Ignore any errors when removing files, as tests might already remove the file.
|
||||
}
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/resources/testdriver-actions.js"></script>
|
||||
<style>
|
||||
iframe {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
background: green;
|
||||
}
|
||||
#outerFrame {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background: blue;
|
||||
}
|
||||
</style>
|
||||
<body id="outerFrame body" onload="run()">
|
||||
<div id='outerFrame'>
|
||||
<iframe id='innerFrameElement' src="resources/pointerevent_mouse_pointercapture-iframe.html"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
var receivedEventList = [];
|
||||
function handleEvent(event) {
|
||||
receivedEventList.push(event.target.id + ' received ' + event.type);
|
||||
|
||||
if (event.type == 'pointerdown') {
|
||||
if (document.setPointerCaptureOnPointerDown) {
|
||||
event.target.setPointerCapture(event.pointerId);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.type == "pointermove") {
|
||||
if (document.releasePointerCaptureOnFirstMove && event.target.hasPointerCapture(event.pointerId))
|
||||
event.target.releasePointerCapture(event.pointerId);
|
||||
}
|
||||
};
|
||||
|
||||
document.testEventList = ['pointerup', 'pointerdown', 'pointermove', 'gotpointercapture', 'lostpointercapture'];
|
||||
document.testEventList.forEach(function(eventName) {
|
||||
document.getElementById('outerFrame').addEventListener(eventName, handleEvent);
|
||||
});
|
||||
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
document.releasePointerCaptureOnFirstMove = false;
|
||||
|
||||
function run() {
|
||||
promise_test (async() => {
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
receivedEventList = [];
|
||||
expectedEventList = ["innerFrame received pointermove",
|
||||
"innerFrame received pointerdown",
|
||||
"innerFrame received gotpointercapture",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received pointerup",
|
||||
"innerFrame received lostpointercapture"];
|
||||
await new test_driver.Actions()
|
||||
.pointerMove(200, 200)
|
||||
.pointerDown()
|
||||
.pointerMove(150, 150)
|
||||
.pointerMove(50, 50)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test pointer capture event route across the same-origin frame: Mouse down at inner frame and set pointer capture.");
|
||||
|
||||
|
||||
promise_test (async() => {
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
receivedEventList = [];
|
||||
expectedEventList = ["outerFrame received pointermove",
|
||||
"outerFrame received pointerdown",
|
||||
"outerFrame received gotpointercapture",
|
||||
"outerFrame received pointermove",
|
||||
"outerFrame received pointerup",
|
||||
"outerFrame received lostpointercapture"];
|
||||
await new test_driver.Actions()
|
||||
.pointerMove(25, 25)
|
||||
.pointerDown()
|
||||
.pointerMove(200, 200)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test pointer capture event route across the same-origin frame: Mouse down at outer frame body and set pointer capture.");
|
||||
|
||||
|
||||
promise_test (async() => {
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
document.releasePointerCaptureOnFirstMove = true;
|
||||
receivedEventList = [];
|
||||
expectedEventList = ["innerFrame received pointermove",
|
||||
"innerFrame received pointerdown",
|
||||
"innerFrame received gotpointercapture",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received lostpointercapture",
|
||||
"innerFrameDocument received pointermove",
|
||||
"innerFrameDocument received pointerup",];
|
||||
await new test_driver.Actions()
|
||||
.pointerMove(200, 200)
|
||||
.pointerDown()
|
||||
.pointerMove(150, 150)
|
||||
.pointerMove(50, 50)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.releasePointerCaptureOnFirstMove = false;
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test pointer capture event route across the same-origin frame: Mouse down with set capture at inner frame, then release on next mouse move.");
|
||||
|
||||
|
||||
promise_test (async() => {
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
document.releasePointerCaptureOnFirstMove = true;
|
||||
receivedEventList = [];
|
||||
expectedEventList = ["outerFrame received pointermove",
|
||||
"outerFrame received pointerdown",
|
||||
"outerFrame received gotpointercapture",
|
||||
"outerFrame received pointermove",
|
||||
"outerFrame received lostpointercapture",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received pointerup"];
|
||||
await new test_driver.Actions()
|
||||
.pointerMove(50, 50)
|
||||
.pointerDown()
|
||||
.pointerMove(200, 200)
|
||||
.pointerMove(250, 250)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.releasePointerCaptureOnFirstMove = false;
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test pointercapture event route across the same-origin frame: Mouse down with set capture at outer frame, then release on next mouse move.");
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/resources/testdriver-actions.js"></script>
|
||||
<script type="text/javascript" src="pointerevent_support.js"></script>
|
||||
<style>
|
||||
iframe {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
background: green;
|
||||
}
|
||||
#outerFrame {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background: blue;
|
||||
}
|
||||
body {
|
||||
touch-action:none;
|
||||
}
|
||||
</style>
|
||||
<body id="outerFrame body" onload="run()">
|
||||
<div id='outerFrame'>
|
||||
<iframe id='innerFrameElement' src="resources/pointerevent_pointercapture-iframe.html"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
var receivedEventList = [];
|
||||
var start_logging = false;
|
||||
function handleEvent(event) {
|
||||
if (event.type == 'pointerdown') {
|
||||
start_logging = true;
|
||||
if (document.setPointerCaptureOnPointerDown) {
|
||||
event.target.setPointerCapture(event.pointerId);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.type == "pointermove") {
|
||||
if (document.releasePointerCaptureOnFirstMove && event.target.hasPointerCapture(event.pointerId))
|
||||
event.target.releasePointerCapture(event.pointerId);
|
||||
}
|
||||
if (start_logging)
|
||||
receivedEventList.push(event.target.id + ' received ' + event.type);
|
||||
};
|
||||
|
||||
document.testEventList = ['pointerup', 'pointerdown', 'pointermove', 'gotpointercapture', 'lostpointercapture'];
|
||||
document.testEventList.forEach(function(eventName) {
|
||||
document.getElementById('outerFrame').addEventListener(eventName, handleEvent);
|
||||
});
|
||||
|
||||
function Reset() {
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
document.releasePointerCaptureOnFirstMove = false;
|
||||
receivedEventList = [];
|
||||
start_logging = false;
|
||||
}
|
||||
|
||||
function run() {
|
||||
ALL_POINTERS.forEach(function(pointerType) {
|
||||
promise_test (async() => {
|
||||
Reset();
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
expectedEventList = ["innerFrame received pointerdown",
|
||||
"innerFrame received gotpointercapture",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received pointerup",
|
||||
"innerFrame received lostpointercapture"];
|
||||
var pointerId = pointerType + "Pointer1";
|
||||
await new test_driver.Actions()
|
||||
.addPointer(pointerId, pointerType)
|
||||
.pointerMove(200, 200)
|
||||
.pointerDown()
|
||||
.pointerMove(150, 150)
|
||||
.pointerMove(50, 50)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test " + pointerType + "pointer capture in same-origin frame: Pointer down at inner frame and set pointer capture.");
|
||||
|
||||
promise_test (async() => {
|
||||
Reset();
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
expectedEventList = ["outerFrame received pointerdown",
|
||||
"outerFrame received gotpointercapture",
|
||||
"outerFrame received pointermove",
|
||||
"outerFrame received pointerup",
|
||||
"outerFrame received lostpointercapture"];
|
||||
var pointerId = pointerType + "Pointer1";
|
||||
await new test_driver.Actions()
|
||||
.addPointer(pointerId, pointerType)
|
||||
.pointerMove(25, 25)
|
||||
.pointerDown()
|
||||
.pointerMove(200, 200)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test " + pointerType + "pointer capture in same-origin frame: Pointer down at outer frame body and set pointer capture.");
|
||||
|
||||
|
||||
promise_test (async() => {
|
||||
Reset();
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
document.releasePointerCaptureOnFirstMove = true;
|
||||
// Mouse event has the frame capture, so after pointer capture released, events are
|
||||
// dispatched to innerFrameDocument.
|
||||
expectedEventList = ["innerFrame received pointerdown",
|
||||
"innerFrame received gotpointercapture",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received lostpointercapture",
|
||||
(pointerType == "touch" ? "outerFrame": "innerFrameDocument") + " received pointermove",
|
||||
(pointerType == "touch" ? "outerFrame": "innerFrameDocument") + " received pointerup",];
|
||||
var pointerId = pointerType + "Pointer1";
|
||||
await new test_driver.Actions()
|
||||
.addPointer(pointerId, pointerType)
|
||||
.pointerMove(200, 200)
|
||||
.pointerDown()
|
||||
.pointerMove(150, 150)
|
||||
.pointerMove(50, 50)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.releasePointerCaptureOnFirstMove = false;
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test " + pointerType + "pointer capture in same-origin frame: Pointerdown with set capture at inner frame, then release on next pointermove.");
|
||||
|
||||
|
||||
promise_test (async() => {
|
||||
Reset();
|
||||
document.setPointerCaptureOnPointerDown = true;
|
||||
document.releasePointerCaptureOnFirstMove = true;
|
||||
expectedEventList = ["outerFrame received pointerdown",
|
||||
"outerFrame received gotpointercapture",
|
||||
"outerFrame received pointermove",
|
||||
"outerFrame received lostpointercapture",
|
||||
"innerFrame received pointermove",
|
||||
"innerFrame received pointerup"];
|
||||
var pointerId = pointerType + "Pointer1";
|
||||
await new test_driver.Actions()
|
||||
.addPointer(pointerId, pointerType)
|
||||
.pointerMove(50, 50)
|
||||
.pointerDown()
|
||||
.pointerMove(200, 200)
|
||||
.pointerMove(250, 250)
|
||||
.pointerUp()
|
||||
.send();
|
||||
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
|
||||
document.releasePointerCaptureOnFirstMove = false;
|
||||
document.setPointerCaptureOnPointerDown = false;
|
||||
}, "Test " + pointerType + "pointer capture in same-origin frame: Pointerdown with set capture at outer frame, then release on next pointermove.");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,4 +1,9 @@
|
|||
<html id='innerFrameDocument'>
|
||||
<style>
|
||||
body {
|
||||
touch-action:none;
|
||||
}
|
||||
</style>
|
||||
<body id='innerFrame' style='height:500px; width: 500px; padding: 0; margin: 0;'>
|
||||
<script>
|
||||
top.document.testEventList.forEach(function(eventName) {
|
||||
|
@ -6,4 +11,4 @@
|
|||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
|
@ -27,6 +27,12 @@
|
|||
sha384: 'sha384-wDAWxH4tOWBwAwHfBn9B7XuNmFxHTMeigAMwn0iVQ0zq3FtmYMLxihcGnU64CwcX',
|
||||
sha512: 'sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w=='
|
||||
},
|
||||
{
|
||||
destination: 'image', ext: '.png', supports_sri: false,
|
||||
sha256: 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=',
|
||||
sha384: 'sha384-OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb',
|
||||
sha512: 'sha512-z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg=='
|
||||
},
|
||||
// TODO(domfarolino): Add more destinations.
|
||||
];
|
||||
|
||||
|
|
|
@ -34,6 +34,13 @@ SRIScriptTest.prototype.execute = function() {
|
|||
document.body.appendChild(e);
|
||||
};
|
||||
|
||||
function set_extra_attributes(element, attrs) {
|
||||
// Apply the rest of the attributes, if any.
|
||||
for (const [attr_name, attr_val] of Object.entries(attrs)) {
|
||||
element[attr_name] = attr_val;
|
||||
}
|
||||
}
|
||||
|
||||
function buildElementFromDestination(resource_url, destination, attrs) {
|
||||
// Assert: |destination| is a valid destination.
|
||||
let element;
|
||||
|
@ -45,26 +52,24 @@ function buildElementFromDestination(resource_url, destination, attrs) {
|
|||
switch (destination) {
|
||||
case "script":
|
||||
element = document.createElement(destination);
|
||||
set_extra_attributes(element, attrs);
|
||||
element.src = resource_url;
|
||||
break;
|
||||
case "style":
|
||||
element = document.createElement('link');
|
||||
set_extra_attributes(element, attrs);
|
||||
element.rel = 'stylesheet';
|
||||
element.href = resource_url;
|
||||
break;
|
||||
case "image":
|
||||
element = document.createElement('img');
|
||||
set_extra_attributes(element, attrs);
|
||||
element.src = resource_url;
|
||||
break;
|
||||
default:
|
||||
assert_unreached("INVALID DESTINATION");
|
||||
}
|
||||
|
||||
// Apply the rest of the attributes, if any.
|
||||
for (const [attr_name, attr_val] of Object.entries(attrs)) {
|
||||
element[attr_name] = attr_val;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
|
|
BIN
tests/wpt/web-platform-tests/subresource-integrity/image.png
Normal file
BIN
tests/wpt/web-platform-tests/subresource-integrity/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -132,7 +132,7 @@ promise_test(t => {
|
|||
const promises = [];
|
||||
invalid_signals.forEach(invalid_signal => {
|
||||
promises.push(
|
||||
promise_rejects(t, 'TypeError', writer.push(test_text_data, { signal: invalid_signal })));
|
||||
promise_rejects(t, new TypeError(), writer.push(test_text_data, { signal: invalid_signal })));
|
||||
});
|
||||
return Promise.all(promises);
|
||||
}, "NFCWriter.push should fail if signal is not an AbortSignal.");
|
||||
|
|
|
@ -547,15 +547,17 @@ function validateMediaStreamTrackStats(statsReport, stats) {
|
|||
assert_optional_unsigned_int_field(stats, 'partialFramesLost');
|
||||
assert_optional_unsigned_int_field(stats, 'fullFramesLost');
|
||||
} else {
|
||||
assert_number_field(stats, 'audioLevel');
|
||||
assert_optional_number_field(stats, 'totalAudioEnergy');
|
||||
if (stats['remoteSource']) {
|
||||
assert_number_field(stats, 'audioLevel');
|
||||
assert_optional_number_field(stats, 'totalAudioEnergy');
|
||||
assert_optional_number_field(stats, 'totalSamplesDuration');
|
||||
}
|
||||
assert_optional_boolean_field(stats, 'voiceActivityFlag');
|
||||
assert_optional_number_field(stats, 'echoReturnLoss');
|
||||
assert_optional_number_field(stats, 'echoReturnLossEnhancement');
|
||||
|
||||
assert_optional_unsigned_int_field(stats, 'totalSamplesSent');
|
||||
assert_optional_unsigned_int_field(stats, 'totalSamplesReceived');
|
||||
assert_optional_number_field(stats, 'totalSamplesDuration');
|
||||
assert_optional_unsigned_int_field(stats, 'concealedSamples');
|
||||
assert_optional_unsigned_int_field(stats, 'concealmentEvents');
|
||||
assert_optional_number_field(stats, 'jitterBufferDelay');
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!doctype html>
|
||||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
async_test((t) => {
|
||||
let onloadIsCalled = false;
|
||||
window.addEventListener('load', () => {
|
||||
onloadIsCalled = true;
|
||||
}, {once: true});
|
||||
document.addEventListener('readystatechange', t.step_func(() => {
|
||||
if (document.readyState !== 'complete') {
|
||||
return;
|
||||
}
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', 'resources/pass.txt', false /* async */);
|
||||
xhr.send();
|
||||
assert_false(onloadIsCalled);
|
||||
// The load event eventually arrives.
|
||||
window.addEventListener('load', t.step_func_done(() => {
|
||||
}), {once: 'true'});
|
||||
}));
|
||||
}, 'sync XHR should not fire window.onload synchronously');
|
||||
</script>
|
||||
</body>
|
Loading…
Add table
Add a link
Reference in a new issue