Update web-platform-tests to revision 7bfbc0fa30aad867faa1c6cc748884be76635a08

This commit is contained in:
WPT Sync Bot 2018-02-22 20:08:40 -05:00 committed by Josh Matthews
parent 0fa3248723
commit 65b0e306b7
87 changed files with 2402 additions and 622 deletions

File diff suppressed because it is too large Load diff

View file

@ -273,3 +273,9 @@
[SubtleCrypto interface: calling unwrapKey(KeyFormat, BufferSource, CryptoKey, AlgorithmIdentifier, AlgorithmIdentifier, boolean, [object Object\]) on crypto.subtle with too few arguments must throw TypeError] [SubtleCrypto interface: calling unwrapKey(KeyFormat, BufferSource, CryptoKey, AlgorithmIdentifier, AlgorithmIdentifier, boolean, [object Object\]) on crypto.subtle with too few arguments must throw TypeError]
expected: FAIL expected: FAIL
[CryptoKey interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[SubtleCrypto interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -164,3 +164,9 @@
[SubtleCrypto interface: calling unwrapKey(KeyFormat, BufferSource, CryptoKey, AlgorithmIdentifier, AlgorithmIdentifier, boolean, [object Object\]) on crypto.subtle with too few arguments must throw TypeError] [SubtleCrypto interface: calling unwrapKey(KeyFormat, BufferSource, CryptoKey, AlgorithmIdentifier, AlgorithmIdentifier, boolean, [object Object\]) on crypto.subtle with too few arguments must throw TypeError]
expected: FAIL expected: FAIL
[CryptoKey interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[SubtleCrypto interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -0,0 +1,2 @@
[text-indent-on-blank-line-rtl-left-align.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[vh_not_refreshing_on_chrome.html]
expected: FAIL

View file

@ -504,3 +504,6 @@
[CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type] [CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type]
expected: FAIL expected: FAIL
[CaretPosition interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -645,3 +645,9 @@
[CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "parentRule" with the proper type] [CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "parentRule" with the proper type]
expected: FAIL expected: FAIL
[CSSPageRule interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[CSSMarginRule interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -774,3 +774,93 @@
[DOMTokenList interface: document.body.classList must inherit property "supports(DOMString)" with the proper type] [DOMTokenList interface: document.body.classList must inherit property "supports(DOMString)" with the proper type]
expected: FAIL expected: FAIL
[AbortController interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[AbortSignal interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[MutationObserver interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[MutationRecord interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Document interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Unscopable handled correctly for prepend([object Object\],[object Object\]) on Document]
expected: FAIL
[Unscopable handled correctly for append([object Object\],[object Object\]) on Document]
expected: FAIL
[DocumentType interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Unscopable handled correctly for before([object Object\],[object Object\]) on DocumentType]
expected: FAIL
[Unscopable handled correctly for after([object Object\],[object Object\]) on DocumentType]
expected: FAIL
[Unscopable handled correctly for replaceWith([object Object\],[object Object\]) on DocumentType]
expected: FAIL
[Unscopable handled correctly for remove() on DocumentType]
expected: FAIL
[DocumentFragment interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Unscopable handled correctly for prepend([object Object\],[object Object\]) on DocumentFragment]
expected: FAIL
[Unscopable handled correctly for append([object Object\],[object Object\]) on DocumentFragment]
expected: FAIL
[ShadowRoot interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Element interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Unscopable handled correctly for slot property on Element]
expected: FAIL
[Unscopable handled correctly for prepend([object Object\],[object Object\]) on Element]
expected: FAIL
[Unscopable handled correctly for append([object Object\],[object Object\]) on Element]
expected: FAIL
[Unscopable handled correctly for before([object Object\],[object Object\]) on Element]
expected: FAIL
[Unscopable handled correctly for after([object Object\],[object Object\]) on Element]
expected: FAIL
[Unscopable handled correctly for replaceWith([object Object\],[object Object\]) on Element]
expected: FAIL
[Unscopable handled correctly for remove() on Element]
expected: FAIL
[CharacterData interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Unscopable handled correctly for before([object Object\],[object Object\]) on CharacterData]
expected: FAIL
[Unscopable handled correctly for after([object Object\],[object Object\]) on CharacterData]
expected: FAIL
[Unscopable handled correctly for replaceWith([object Object\],[object Object\]) on CharacterData]
expected: FAIL
[Unscopable handled correctly for remove() on CharacterData]
expected: FAIL
[CDATASection interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -36,3 +36,6 @@
[Element interface: document.createElementNS(null, "test") must inherit property "onfullscreenerror" with the proper type] [Element interface: document.createElementNS(null, "test") must inherit property "onfullscreenerror" with the proper type]
expected: FAIL expected: FAIL
[Unscopable handled correctly for fullscreen property on Document]
expected: FAIL

View file

@ -13905,3 +13905,99 @@
[OffscreenCanvas interface: operation getContext(OffscreenRenderingContextId, any)] [OffscreenCanvas interface: operation getContext(OffscreenRenderingContextId, any)]
expected: FAIL expected: FAIL
[HTMLAllCollection interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[DOMStringList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[HTMLMenuElement interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[AudioTrackList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[AudioTrack interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[VideoTrackList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[VideoTrack interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[TextTrackList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[TextTrack interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[TextTrackCueList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[TextTrackCue interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[TimeRanges interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[TrackEvent interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[HTMLSlotElement interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[TextMetrics interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[Path2D interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageBitmapRenderingContext interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[OffscreenCanvas interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[OffscreenCanvasRenderingContext2D interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[DataTransfer interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[DataTransferItemList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[DataTransferItem interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[DragEvent interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[BarProp interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ApplicationCache interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[PromiseRejectionEvent interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[ImageBitmap interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[MessageChannel interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[MessagePort interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[BroadcastChannel interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[SharedWorker interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[HTMLMarqueeElement interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -54,3 +54,6 @@
[DOMStringList interface: location.ancestorOrigins must inherit property "contains(DOMString)" with the proper type] [DOMStringList interface: location.ancestorOrigins must inherit property "contains(DOMString)" with the proper type]
expected: FAIL expected: FAIL
[DOMStringList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -24,3 +24,6 @@
[DOMStringList interface: operation contains(DOMString)] [DOMStringList interface: operation contains(DOMString)]
expected: FAIL expected: FAIL
[DOMStringList interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -345,3 +345,9 @@
[Performance interface: window.performance must inherit property "navigation" with the proper type] [Performance interface: window.performance must inherit property "navigation" with the proper type]
expected: FAIL expected: FAIL
[PerformanceNavigationTiming interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[PerformanceNavigation interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -48,3 +48,6 @@
[PerformanceNavigationTiming interface: operation toJSON()] [PerformanceNavigationTiming interface: operation toJSON()]
expected: FAIL expected: FAIL
[PerformanceNavigationTiming interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -1,5 +1,4 @@
[po-navigation.html] [po-navigation.html]
type: testharness
[navigation entry is observable] [navigation entry is observable]
expected: FAIL expected: FAIL

View file

@ -186,3 +186,9 @@
[UIEvent interface: new CompositionEvent("event") must inherit property "which" with the proper type] [UIEvent interface: new CompositionEvent("event") must inherit property "which" with the proper type]
expected: FAIL expected: FAIL
[WheelEvent interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[CompositionEvent interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -1,6 +1,5 @@
[name-property.html] [name-property.html]
type: testharness type: testharness
expected: ERROR
[Test the name property of shared and dedicated workers via the name constructor option] [Test the name property of shared and dedicated workers via the name constructor option]
expected: FAIL expected: FAIL

View file

@ -597,3 +597,12 @@
[BluetoothRemoteGATTDescriptor interface: bluetooth_descriptor must inherit property "writeValue(BufferSource)" with the proper type] [BluetoothRemoteGATTDescriptor interface: bluetooth_descriptor must inherit property "writeValue(BufferSource)" with the proper type]
expected: FAIL expected: FAIL
[ValueEvent interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[BluetoothManufacturerDataMap interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[BluetoothServiceDataMap interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL

View file

@ -0,0 +1,27 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
// TODO(https://crbug.com/672127) Use this test case to test the rest of
// characteristic functions.
'use strict';
const test_desc = 'Service is removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let characteristic, fake_peripheral, fake_service;
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
characteristic.getDescriptor(user_description.name),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,27 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
// TODO(https://crbug.com/672127) Use this test case to test the rest of
// characteristic functions.
'use strict';
const test_desc = 'Service is removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let characteristic, fake_peripheral, fake_service;
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
characteristic.getDescriptors(user_description.uuid),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,27 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
// TODO(https://crbug.com/672127) Use this test case to test the rest of
// characteristic functions.
'use strict';
const test_desc = 'Service is removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let characteristic, fake_peripheral, fake_service;
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
characteristic.getDescriptors(user_description.name),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service is removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let characteristic, fake_peripheral, fake_service;
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
characteristic.startNotifications(),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service gets removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let characteristic, fake_peripheral, fake_service;
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
characteristic.readValue(),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service gets removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let characteristic, fake_peripheral, fake_service;
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
characteristic.writeValue(new ArrayBuffer(1 /* length */)),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,25 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service gets removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let descriptor, fake_peripheral, fake_service;
bluetooth_test(() => getUserDescriptionDescriptor()
.then(_ => ({descriptor, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
descriptor.readValue(),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,25 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service gets removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let descriptor, fake_peripheral, fake_service;
bluetooth_test(() => getUserDescriptionDescriptor()
.then(_ => ({descriptor, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
descriptor.writeValue(new ArrayBuffer(1 /* length */)),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,20 @@
// TODO(https://crbug.com/672127) Use this test case to test the rest of
// characteristic functions.
'use strict';
const test_desc = 'Service is removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let characteristic, fake_peripheral, fake_service;
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
characteristic.CALLS([
getDescriptor(user_description.name)|
getDescriptors(user_description.uuid)[UUID]|
getDescriptors(user_description.name)]),
expected,
'Service got removed.')),
test_desc);

View file

@ -0,0 +1,18 @@
'use strict';
const test_desc = 'Service gets removed. Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let descriptor, fake_peripheral, fake_service;
bluetooth_test(() => getUserDescriptionDescriptor()
.then(_ => ({descriptor, fake_peripheral, fake_service} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
descriptor.CALLS([
readValue()|
writeValue(new ArrayBuffer(1 /* length */))
]),
expected,
'Service got removed.')),
test_desc);

View file

@ -0,0 +1,20 @@
'use strict';
const test_desc = 'Service is removed before FUNCTION_NAME call. ' +
'Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let service, fake_service, fake_peripheral;
bluetooth_test(() => getHealthThermometerService()
.then(_ => ({service, fake_service, fake_peripheral} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
service.CALLS([
getCharacteristic('measurement_interval')|
getCharacteristics()|
getCharacteristics('measurement_interval')[UUID]
]),
expected,
'Service got removed.')),
test_desc);

View file

@ -0,0 +1,26 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service is removed before getCharacteristic call. ' +
'Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let service, fake_service, fake_peripheral;
bluetooth_test(() => getHealthThermometerService()
.then(_ => ({service, fake_service, fake_peripheral} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
service.getCharacteristic('measurement_interval'),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,26 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service is removed before getCharacteristics call. ' +
'Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let service, fake_service, fake_peripheral;
bluetooth_test(() => getHealthThermometerService()
.then(_ => ({service, fake_service, fake_peripheral} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
service.getCharacteristics('measurement_interval'),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,26 @@
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
<!DOCTYPE html>
<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="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Service is removed before getCharacteristics call. ' +
'Reject with InvalidStateError.';
const expected = new DOMException('GATT Service no longer exists.',
'InvalidStateError');
let service, fake_service, fake_peripheral;
bluetooth_test(() => getHealthThermometerService()
.then(_ => ({service, fake_service, fake_peripheral} = _))
.then(() => fake_service.remove())
.then(() => fake_peripheral.simulateGATTServicesChanged())
.then(() => assert_promise_rejects_with_message(
service.getCharacteristics(),
expected,
'Service got removed.')),
test_desc);
</script>

View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<p>There should be a hotpink square in the bottom left corner of a larger blue square.</p>
<div style="width:200px; background:blue;">
<div style="height:100px;"></div>
<div style="width:100px; height:100px; background:hotpink;"></div>
</div>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<title>Text-indent on blank line in RTL container with text-align:left</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/text.html#propdef-text-indent" title="16.1 Indentation: the 'text-indent' property">
<link rel="match" href="text-indent-on-blank-line-rtl-left-align-ref.html">
<p>There should be a hotpink square in the bottom left corner of a larger blue square.</p>
<div style="text-align:left; direction:rtl; text-indent:300px; line-height:100px; width:200px; background:blue;">
<br>
<div style="vertical-align:bottom; display:inline-block; width:100px; height:100px; background:hotpink;"></div>
</div>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<style>
.result {
background: green;
border-radius: 2px;
margin: 10px;
width: 100px;
height: 100px;
}
</style>
<div class="result"></div>

View file

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-invalidation">
<link rel="match" href="style-map-multi-ref.html">
<meta name="assert" content="This test checks that properties are correctly given to the layout function." />
<style>
.test {
background: red;
margin: 10px;
width: 100px;
/* Properties under test. */
--foo: bar;
border-radius: 2px;
}
@supports (display: layout(test)) {
.test {
background: green;
display: layout(test);
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script id="code" type="text/worklet">
registerLayout('test', class {
static get inputProperties() {
return [ '--bar', '--foo', 'align-items', 'border-top-left-radius'];
}
*intrinsicSizes() {}
*layout(children, edges, constraints, styleMap) {
const expected = [
{property: '--bar', value: '[CSSUnparsedValue=]'},
{property: '--foo', value: '[CSSUnparsedValue= bar]'},
{property: 'align-items', value: '[CSSKeywordValue=normal]'},
{property: 'border-top-left-radius', value: '[CSSUnitValue=2px]'},
];
const actual = Array.from(styleMap.keys()).sort().map((property) => {
const valueObject = styleMap.get(property);
const value = '[' + valueObject.constructor.name + '=' + valueObject.toString() + ']';
return {property, value};
});
if (expected.length != actual.length)
return {autoBlockSize: 0};
for (let i = 0; i < expected.length; i++) {
if (expected[i].property != actual[i].property)
return {autoBlockSize: 0};
if (expected[i].value != actual[i].value)
return {autoBlockSize: 0};
}
return {autoBlockSize: 100};
}
});
</script>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
</script>
</html>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<style>
.result {
background: green;
border-radius: 2px;
margin: 10px;
width: 100px;
height: 100px;
}
</style>
<div class="result"></div>
<div class="result"></div>
<div class="result"></div>
<div class="result"></div>

View file

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-invalidation">
<link rel="match" href="style-map-ref.html">
<meta name="assert" content="This test checks that properties are correctly given to the layout function." />
<style>
.test {
background: red;
margin: 10px;
width: 100px;
/* Properties under test. */
--foo: bar;
border-radius: 2px;
}
@supports (display: layout(test)) {
.test {
background: green;
}
.test-0 { display: layout(test-0); }
.test-1 { display: layout(test-1); }
.test-2 { display: layout(test-2); }
.test-3 { display: layout(test-3); }
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test test-0"></div>
<div class="test test-1"></div>
<div class="test test-2"></div>
<div class="test test-3"></div>
<script>
const tmpl = (test, idx) => {
return `
registerLayout('test-${idx}', class {
static get inputProperties() { return ['${test.property}']; }
*intrinsicSizes() {}
*layout(children, edges, constraints, styleMap) {
const value = styleMap.get('${test.property}');
const result = '[' + value.constructor.name + '=' + value.toString() + ']';
if (result != '${test.expected}')
return {autoBlockSize: 0};
const size = Array.from(styleMap.keys()).length;
if (size != 1)
return {autoBlockSize: 0};
return {autoBlockSize: 100};
}
});
`;
}
const tests = [
{property: '--bar', expected: '[CSSUnparsedValue=]'},
{property: '--foo', expected: '[CSSUnparsedValue= bar]'},
{property: 'align-items', expected: '[CSSKeywordValue=normal]'},
{property: 'border-top-left-radius', expected: '[CSSUnitValue=2px]'},
];
const workletSource = tests.map(tmpl).join('\n');
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, workletSource);
</script>
</html>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<title>Reference for position:sticky elements should not affect the flow position of other elements</title>
<style>
.scroller {
height: 200px;
width: 100px;
overflow-y: scroll;
margin-bottom: 15px;
}
.sticky {
background-color: green;
}
.box {
height: 50px;
width: 50px;
}
.before {
background-color: fuchsia;
}
.after {
background-color: orange;
}
.padding {
height: 450px;
}
</style>
<div class="scroller">
<div class="before box"></div>
<div class="box"></div>
<div class="after box"></div>
<div class="sticky box"></div>
<div class="padding"></div>
</div>
<div>You should see a fuchsia box, a one-box gap, an orange box, and then a green box above.</div>

View file

@ -1,58 +1,46 @@
<!DOCTYPE html> <!DOCTYPE html>
<title>position:sticky elements should not affect the flow position of other elements</title> <title>position:sticky elements should not affect the flow position of other elements</title>
<link rel="match" href="position-sticky-inflow-position-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that position:sticky elements do not affect the flow position of other elements" /> <meta name="assert" content="This test checks that position:sticky elements do not affect the flow position of other elements" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style> <style>
.scroller { .scroller {
position: relative;
height: 200px; height: 200px;
width: 100px; width: 100px;
overflow: scroll; overflow-y: scroll;
margin-bottom: 15px;
} }
#sticky { .sticky {
background-color: green; background-color: green;
position: sticky; position: sticky;
top: 150px; top: 150px;
} }
#before {
background-color: fuchsia;
}
#after {
background-color: orange;
}
.box { .box {
height: 50px; height: 50px;
width: 50px; width: 50px;
} }
.before {
background-color: fuchsia;
}
.after {
background-color: orange;
}
.padding { .padding {
height: 500px; height: 500px;
} }
</style> </style>
<div class="scroller"> <div class="scroller">
<div id="before" class="box"></div> <div class="before box"></div>
<div id="sticky" class="box"></div> <div class="sticky box"></div>
<div id="after" class="box"></div> <div class="after box"></div>
<div class="padding"></div> <div class="padding"></div>
</div> </div>
<script> <div>You should see a fuchsia box, a one-box gap, an orange box, and then a green box above.</div>
test(() => {
// The sticky element is pushed to be stuck 150 pixels from the top.
assert_equals(sticky.offsetTop, 150);
// Neither 'before' or 'after' should be affected by the change in the sticky
// element's location.
assert_equals(before.offsetTop, 0);
assert_equals(after.offsetTop, before.clientHeight + sticky.clientHeight);
}, 'sticky offset should not affect the position of other elements.');
</script>

View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<title>Reference for position:sticky elements should properly interact with margins</title>
<style>
.group {
display: inline-block;
position: relative;
width: 180px;
height: 400px;
}
.scroller {
width: 150px;
height: 300px;
overflow-y: scroll;
overflow-x: hidden;
}
.indicator {
position: relative;
background-color: green;
margin: 15px;
}
.box {
width: 100px;
height: 100px;
}
.padding {
height: 385px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 0;
document.getElementById('scroller2').scrollTop = 60;
document.getElementById('scroller3').scrollTop = 120;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="indicator box" style="top: 0;"></div>
<div class="padding"></div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="indicator box" style="top: 50px;"></div>
<div class="padding"></div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="indicator box" style="top: 85px;"></div>
<div class="padding"></div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -1,49 +1,92 @@
<!DOCTYPE html> <!DOCTYPE html>
<title>position:sticky elements should properly interact with margins</title> <title>position:sticky elements should properly interact with margins</title>
<link rel="match" href="position-sticky-margins-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="position:sticky elements should ignore margins when sticking, but consider them when making sure sticky elements do not escape their containing block" /> <meta name="assert" content="position:sticky elements should ignore margins when sticking, but consider them when making sure sticky elements do not escape their containing block" />
<script src="/resources/testharness.js"></script> <style>
<script src="/resources/testharnessreport.js"></script> .group {
display: inline-block;
position: relative;
width: 180px;
height: 400px;
}
<script src="resources/sticky-util.js"></script> .scroller {
position: relative;
width: 150px;
height: 300px;
overflow-y: scroll;
overflow-x: hidden;
}
<body></body> .holder {
width: 130px;
height: 200px;
}
.sticky {
position: sticky;
background-color: green;
top: 5px;
margin: 15px;
}
.indicator {
left: 15px;
position: absolute;
background-color: red;
}
.box {
width: 100px;
height: 100px;
}
.padding {
height: 300px;
}
</style>
<script> <script>
test(() => { window.addEventListener('load', function() {
const elements = setupStickyTest('top', 50); document.getElementById('scroller1').scrollTop = 0;
elements.sticky.style.margin = '15px'; document.getElementById('scroller2').scrollTop = 60;
elements.scroller.scrollTop = 100; document.getElementById('scroller3').scrollTop = 120;
assert_equals(elements.sticky.offsetTop, });
elements.container.offsetTop + elements.filler.clientHeight + 15);
}, 'Before sticking, the margin should be obeyed.');
test(() => {
const elements = setupStickyTest('top', 50);
elements.sticky.style.margin = '15px';
elements.scroller.scrollTop = 200;
// This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but
// for clarity the calculations are left explicit.
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
const targetTopY = elements.scroller.scrollTop + 50;
const stickyOffset = targetTopY - nonStickyTopY;
assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset);
}, 'Whilst stuck, the margin is irrelevant.');
test(() => {
const elements = setupStickyTest('top', 50);
elements.sticky.style.margin = '15px';
elements.scroller.scrollTop = 300;
const maxOffsetInContainer = elements.container.offsetTop +
elements.container.clientHeight - elements.sticky.clientHeight;
assert_equals(elements.sticky.offsetTop, maxOffsetInContainer - 15);
}, 'The margin is taken into account when making sure the sticky element ' +
'does not escape its container');
</script> </script>
<!-- Before sticking, the margin should be obeyed. -->
<div class="group">
<div id="scroller1" class="scroller">
<div class="indicator box" style="top: 15px;"></div>
<div class="holder">
<div class="sticky box"></div>
</div>
<div class="padding"></div>
</div>
</div>
<!-- Whilst stuck, the margin is irrelevant. -->
<div class="group">
<div id="scroller2" class="scroller">
<div class="indicator box" style="top: 65px;"></div>
<div class="holder">
<div class="sticky box"></div>
</div>
<div class="padding"></div>
</div>
</div>
<!-- The margin does count when making sure the sticky element does not escape
its containing block. -->
<div class="group">
<div id="scroller3" class="scroller">
<div class="indicator box" style="top: 100px;"></div>
<div class="holder">
<div class="sticky box"></div>
</div>
<div class="padding"></div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -0,0 +1,69 @@
<!DOCTYPE html>
<title>Reference for position:sticky elements should respect padding on their ancestor overflow element</title>
<style>
.group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
.scroller {
padding: 20px 0;
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
.contents {
height: 500px;
}
.indicator {
background-color: green;
position: absolute;
left: 0;
}
.box {
width: 100%;
height: 100px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 50;
document.getElementById('scroller2').scrollTop = 175;
document.getElementById('scroller3').scrollTop = 220;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="contents">
<div class="indicator box" style="top: 170px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="contents">
<div class="indicator box" style="top: 195px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="contents">
<div class="indicator box" style="top: 220px;"></div>
</div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -1,54 +1,106 @@
<!DOCTYPE html> <!DOCTYPE html>
<title>position:sticky elements should respect padding on their ancestor overflow element</title> <title>position:sticky elements should respect padding on their ancestor overflow element</title>
<link rel="match" href="position-sticky-overflow-padding-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that position:sticky elements respect padding on their ancestor overflow element" /> <meta name="assert" content="This test checks that position:sticky elements respect padding on their ancestor overflow element" />
<script src="/resources/testharness.js"></script> <style>
<script src="/resources/testharnessreport.js"></script> .group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
<script src="resources/sticky-util.js"></script> .scroller {
/* The target sticky position should be offset by this padding. */
padding: 20px 0;
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
<body></body> .contents {
height: 500px;
}
.prepadding {
height: 100px;
}
.container {
height: 200px;
}
.innerpadding {
height: 50px;
}
.indicator {
background-color: red;
position: absolute;
left: 0;
}
.sticky {
background-color: green;
position: sticky;
top: 0;
}
.box {
width: 100%;
height: 100px;
}
</style>
<script> <script>
test(() => { window.addEventListener('load', function() {
const elements = setupStickyTest('top', 50); document.getElementById('scroller1').scrollTop = 50;
elements.scroller.style.padding = '20px 0'; document.getElementById('scroller2').scrollTop = 175;
document.getElementById('scroller3').scrollTop = 220;
// Before sticking; the element isn't within the padding range. });
elements.scroller.scrollTop = 150;
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
assert_equals(elements.sticky.offsetTop, nonStickyTopY);
}, 'A sticky element should not be affected by ancestor padding until it ' +
'reaches it');
test(() => {
const elements = setupStickyTest('top', 50);
elements.sticky.style.top = '0';
elements.scroller.style.padding = '20px 0';
elements.scroller.scrollTop = 200;
// This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but
// for clarity the calculations are left explicit.
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
const targetTopY = elements.scroller.scrollTop;
const stickyOffset = targetTopY - nonStickyTopY;
assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset + 20);
}, 'A sticky element should be offset by ancestor padding even when stuck');
test(() => {
const elements = setupStickyTest('top', 50);
elements.sticky.style.top = '0';
elements.scroller.style.padding = '20px 0';
elements.scroller.scrollTop = 315;
const maxOffsetInContainer = elements.container.offsetTop +
elements.container.clientHeight - elements.sticky.clientHeight;
assert_equals(elements.sticky.offsetTop, maxOffsetInContainer);
}, 'Ancestor overflow padding does not allow a sticky element to escape its ' +
'container');
</script> </script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="indicator box" style="top: 170px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="sticky box"></div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="indicator box" style="top: 195px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="sticky box"></div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="indicator box" style="top: 220px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="sticky box"></div>
</div>
</div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<title>Reference for position:sticky should operate correctly for the root scroller</title>
<style>
body {
/* Assumption: 3000px is taller than any user agents test window size. */
height: 3000px;
}
.indicator {
background-color: green;
position: absolute;
top: 750px;
}
.box {
width: 200px;
height: 200px;
}
</style>
<script>
window.addEventListener('load', function() {
window.scrollTo(0, 700);
});
</script>
<div class="indicator box"></div>
<div style="position: absolute; top: 1000px;">You should see a green box above. No red should be visible.</div>

View file

@ -1,31 +1,39 @@
<!DOCTYPE html> <!DOCTYPE html>
<title>position:sticky should operate correctly for the root scroller</title> <title>position:sticky should operate correctly for the root scroller</title>
<link rel="match" href="position-sticky-root-scroller-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that position:sticky elements work when using the root (document) scroller" /> <meta name="assert" content="This test checks that position:sticky elements work when using the root (document) scroller" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style> <style>
body { body {
/* Assumption: 3000px is taller than any user agents test window size. */ /* Assumption: 3000px is taller than any user agents test window size. */
height: 3000px; height: 3000px;
} }
#sticky { .indicator {
background-color: red;
position: absolute;
}
.sticky {
background-color: green;
position: sticky; position: sticky;
top: 50px; top: 50px;
}
.box {
width: 200px; width: 200px;
height: 200px; height: 200px;
background-color: green;
} }
</style> </style>
<div id="sticky"></div>
<script> <script>
test(() => { window.addEventListener('load', function() {
window.scrollTo(0, 700); window.scrollTo(0, 700);
assert_equals(sticky.offsetTop, 700 + 50); });
}, 'Sticky elements work with the root (document) scroller');
</script> </script>
<div class="indicator box" style="top: 750px;"></div>
<div class="sticky box"></div>
<div style="position: absolute; top: 1000px;">You should see a green box above. No red should be visible.</div>

View file

@ -0,0 +1,81 @@
<!DOCTYPE html>
<title>Reference for transforms on position:sticky elements should apply after sticking</title>
<style>
.group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
.scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
.contents {
height: 500px;
}
.indicator {
background-color: green;
position: relative;
}
.box {
width: 100%;
height: 50px;
}
.rotated {
transform: rotateX(60deg);
height: 100px;
width: 100%;
}
.perspective {
transform: perspective(3px) translateZ(1px);
height: 50px;
width: 50px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 50;
document.getElementById('scroller2').scrollTop = 50;
document.getElementById('scroller3').scrollTop = 50;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="contents">
<div class="indicator box" style="height: 100px; top: 75px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="contents">
<div class="rotated indicator" style="top: 100px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<!-- Required for blending. -->
<div class="perspective" style="position: absolute; background: red; top: 100px;"></div>
<div class="contents">
<div class="perspective indicator" style="top: 100px;"></div>
</div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -0,0 +1,67 @@
<!DOCTYPE html>
<title>Reference for translations on position:sticky elements should apply after sticking</title>
<style>
.group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
.scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
.contents {
height: 500px;
}
.indicator {
background-color: green;
position: relative;
}
.box {
width: 100%;
height: 50px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 50;
document.getElementById('scroller2').scrollTop = 70;
document.getElementById('scroller3').scrollTop = 50;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="contents">
<div class="indicator box" style="top: 50px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="contents">
<div class="indicator box" style="top: 50px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="contents">
<div class="indicator box" style="top: 200px;"></div>
</div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -1,45 +1,92 @@
<!DOCTYPE html> <!DOCTYPE html>
<title>translations on position:sticky elements should apply after sticking</title> <title>translations on position:sticky elements should apply after sticking</title>
<link rel="match" href="position-sticky-transforms-translate-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that translations on position:sticky elements are carried out on their stuck position" /> <meta name="assert" content="This test checks that translations on position:sticky elements are carried out on their stuck position" />
<script src="/resources/testharness.js"></script> <style>
<script src="/resources/testharnessreport.js"></script> .group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
<script src="resources/sticky-util.js"></script> .scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
<body style="margin: 0;"></body> .contents {
height: 500px;
}
.container {
height: 150px;
}
.indicator {
background-color: red;
position: absolute;
left: 0;
}
.sticky {
background-color: green;
position: sticky;
top: 50px;
}
.box {
width: 100%;
height: 50px;
}
</style>
<script> <script>
test(() => { window.addEventListener('load', function() {
const elements = setupStickyTest('top', 50); document.getElementById('scroller1').scrollTop = 50;
elements.sticky.style.transform = 'translateY(-100%)'; document.getElementById('scroller2').scrollTop = 70;
elements.scroller.scrollTop = 100; document.getElementById('scroller3').scrollTop = 50;
// Transforms don't affect offsetTop, so use getBoundingClientRect. });
assert_equals(elements.sticky.getBoundingClientRect().y,
elements.scroller.getBoundingClientRect().y);
}, 'Translation transform can move sticky element past sticking point');
test(() => {
const elements = setupStickyTest('top', 50);
elements.sticky.style.transform = 'translateY(50%)';
elements.scroller.scrollTop = 200;
// Transforms don't affect offsetTop, so use getBoundingClientRect.
const stickyElementOffset = elements.sticky.getBoundingClientRect().y -
elements.scroller.getBoundingClientRect().y;
assert_equals(stickyElementOffset, 100);
}, 'Stuck elements can still be moved via translations');
test(() => {
const elements = setupStickyTest('top', 50);
elements.container.style.transform = 'translateY(100px)';
elements.scroller.scrollTop = 200;
// Transforms don't affect offsetTop, so use getBoundingClientRect.
// Here the sticky element will originally have stuck at 50px from the top,
// but is then 'pulled' downwards by the 100px container transform.
const stickyElementOffset = elements.sticky.getBoundingClientRect().y -
elements.scroller.getBoundingClientRect().y;
assert_equals(stickyElementOffset, 150);
}, 'The sticky element should stick before the container is offset by a ' +
'translation');
</script> </script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="indicator box" style="top: 50px;"></div>
<div class="contents">
<div class="container">
<div class="sticky box" style="transform: translateY(-100%);"></div>
</div>
</div>
</div>
</div>
<!-- The pre-transform sticky is not allowed to escape its containing block. -->
<div class="group">
<div id="scroller2" class="scroller">
<div class="indicator box" style="top: 50px;"></div>
<div class="contents">
<div class="container">
<div class="sticky box" style="transform: translateY(-100%);"></div>
</div>
</div>
</div>
</div>
<!-- The sticky element should stick before the container is transformed. -->
<div class="group">
<div id="scroller3" class="scroller">
<div class="indicator box" style="top: 200px;"></div>
<div class="contents">
<div class="container" style="transform: translateY(100px);">
<div class="sticky box"></div>
</div>
</div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -1,49 +1,101 @@
<!DOCTYPE html> <!DOCTYPE html>
<title>transforms on position:sticky elements should apply after sticking</title> <title>transforms on position:sticky elements should apply after sticking</title>
<link rel="match" href="position-sticky-transforms-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" /> <link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that transforms on position:sticky elements are carried out on their stuck position" /> <meta name="assert" content="This test checks that transforms on position:sticky elements are carried out on their stuck position" />
<script src="/resources/testharness.js"></script> <style>
<script src="/resources/testharnessreport.js"></script> .group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
<script src="resources/sticky-util.js"></script> .scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
<body style="margin: 0;"></body> .contents {
height: 500px;
}
.container {
height: 150px;
}
.indicator {
background-color: red;
position: absolute;
}
.sticky {
background-color: green;
position: sticky;
top: 50px;
}
.box {
width: 100%;
height: 50px;
}
.rotated {
transform: rotateX(60deg);
width: 100%;
height: 100px;
}
.perspective {
transform: perspective(3px) translateZ(1px);
height: 50px;
width: 50px;
}
</style>
<script> <script>
test(() => { window.addEventListener('load', function() {
const elements = setupStickyTest('top', 50); document.getElementById('scroller1').scrollTop = 50;
elements.sticky.style.transform = 'scale(2)'; document.getElementById('scroller2').scrollTop = 50;
elements.scroller.scrollTop = 200; document.getElementById('scroller3').scrollTop = 50;
});
// Transforms don't affect offsetTop, so use getBoundingClientRect.
// Scaling the sticky element by 2 means its top-y moves (1/2 * height)
// upwards, in this case placing it at the top of the viewport.
const boundingRect = elements.sticky.getBoundingClientRect();
assert_equals(boundingRect.y, elements.scroller.getBoundingClientRect().y);
}, 'Scale transforms are carried out on the stuck element position');
test(() => {
const elements = setupStickyTest('top', 50);
elements.sticky.style.transform = 'rotateX(60deg)';
elements.scroller.scrollTop = 200;
// Transforms don't affect offsetTop, so use getBoundingClientRect.
// Rotating around the x-axis essentially 'squashes' it (from the camera's
// viewpoint), in this case shifting the offset to 75 rather than 50.
const stickyElementOffset = elements.sticky.getBoundingClientRect().y -
elements.scroller.getBoundingClientRect().y;
assert_equals(stickyElementOffset, 75);
}, 'Rotate transforms are carried out on the stuck element position');
test(() => {
const elements = setupStickyTest('top', 50);
elements.sticky.style.transform = 'perspective(3px) translateZ(1px)';
elements.scroller.scrollTop = 200;
// Transforms don't affect offsetTop, so use getBoundingClientRect.
const stickyElementOffset = elements.sticky.getBoundingClientRect().y -
elements.scroller.getBoundingClientRect().y;
assert_equals(stickyElementOffset, 25);
}, 'Perspective transforms are carried out on the stuck element position');
</script> </script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="indicator box" style="height: 100px; top: 75px;"></div>
<div class="contents">
<div class="container">
<div class="sticky box" style="transform: scale(2);"></div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="rotated indicator" style="top: 100px;"></div>
<div class="contents">
<div class="container" style="height: 250px;">
<div class="rotated sticky"></div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="perspective indicator" style="top: 100px;"></div>
<div class="contents">
<div class="container">
<div class="perspective sticky"></div>
</div>
</div>
</div>
</div>
<div>You should see three green boxes above. No red should be visible.</div>

View file

@ -9,7 +9,7 @@
<script> <script>
'use strict'; 'use strict';
const gTestUrl = '../resources/1x1-green.png'; const gTestUrl = '/media/1x1-green.png';
const gBadTestUrl = document.location.href; const gBadTestUrl = document.location.href;
async_test(t => { async_test(t => {

View file

@ -11,7 +11,7 @@
<script> <script>
'use strict'; 'use strict';
const gTestUrl = '../resources/1x1-green.png'; const gTestUrl = '/media/1x1-green.png';
const gBase64TestUrl = 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA='; const gBase64TestUrl = 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=';
const gBadTestUrl = document.location.href; const gBadTestUrl = document.location.href;

View file

@ -20,6 +20,16 @@ test(() => {
'Fallback member should be null'); 'Fallback member should be null');
}, 'CSSVariableReferenceValue can be constructed with no fallback'); }, 'CSSVariableReferenceValue can be constructed with no fallback');
test(() => {
const result = new CSSVariableReferenceValue('--foo', null);
assert_not_equals(result, null,
'A CSSVariableReferenceValue should be created');
assert_equals(result.variable, '--foo',
'Variable member should be same as passed in the constructor');
assert_equals(result.fallback, null, 'Fallback member should be null');
}, 'CSSVariableReferenceValue can be constructed with null fallback');
test(() => { test(() => {
const result = new CSSVariableReferenceValue('--foo', const result = new CSSVariableReferenceValue('--foo',
new CSSUnparsedValue(['lemon'])); new CSSUnparsedValue(['lemon']));
@ -32,7 +42,7 @@ test(() => {
'Fallback member should not be null'); 'Fallback member should not be null');
assert_style_value_equals(result.fallback, new CSSUnparsedValue(['lemon']), assert_style_value_equals(result.fallback, new CSSUnparsedValue(['lemon']),
'Fallback member should be as same as passed in the constructor'); 'Fallback member should be as same as passed in the constructor');
}, 'CSSVariableReferenceValue can be constructed with fallback'); }, 'CSSVariableReferenceValue can be constructed with valid fallback');
test(() => { test(() => {
let result = new CSSVariableReferenceValue('--foo'); let result = new CSSVariableReferenceValue('--foo');

View file

@ -24,7 +24,7 @@ test(t => {
test(t => { test(t => {
const styleMap = createComputedStyleMap(t, 'width: 10px; transition-duration: 1s, 2s; height: 20px'); const styleMap = createComputedStyleMap(t, 'width: 10px; transition-duration: 1s, 2s; height: 20px');
assert_style_value_equals(findInStyleMap(styleMap, 'width'), CSS.px(10)); assert_style_value_array_equals(findInStyleMap(styleMap, 'width'), [CSS.px(10)]);
}, 'StylePropertyMap iterator returns CSS properties with the correct CSSStyleValue'); }, 'StylePropertyMap iterator returns CSS properties with the correct CSSStyleValue');
test(t => { test(t => {
@ -34,9 +34,9 @@ test(t => {
test(t => { test(t => {
const styleMap = createComputedStyleMap(t, '--A: A; --C: C; color: red; --B: B;'); const styleMap = createComputedStyleMap(t, '--A: A; --C: C; color: red; --B: B;');
assert_style_value_equals(findInStyleMap(styleMap, '--A'), new CSSUnparsedValue([' A'])); assert_style_value_array_equals(findInStyleMap(styleMap, '--A'), [new CSSUnparsedValue([' A'])]);
assert_style_value_equals(findInStyleMap(styleMap, '--B'), new CSSUnparsedValue([' B'])); assert_style_value_array_equals(findInStyleMap(styleMap, '--B'), [new CSSUnparsedValue([' B'])]);
assert_style_value_equals(findInStyleMap(styleMap, '--C'), new CSSUnparsedValue([' C'])); assert_style_value_array_equals(findInStyleMap(styleMap, '--C'), [new CSSUnparsedValue([' C'])]);
}, 'StylePropertyMap iterator returns custom properties with the correct CSSStyleValue'); }, 'StylePropertyMap iterator returns custom properties with the correct CSSStyleValue');
</script> </script>

View file

@ -25,7 +25,8 @@ test(t => {
const keys = [...styleMap.keys()], values = [...styleMap.values()]; const keys = [...styleMap.keys()], values = [...styleMap.values()];
assert_array_equals(keys, ['height', 'width']); assert_array_equals(keys, ['height', 'width']);
assert_style_value_array_equals(values, [CSS.px(5), CSS.px(10)]); assert_style_value_array_equals(values[0], [CSS.px(5)]);
assert_style_value_array_equals(values[1], [CSS.px(10)]);
}, 'StylePropertyMap iterator returns CSS properties with the correct CSSStyleValue'); }, 'StylePropertyMap iterator returns CSS properties with the correct CSSStyleValue');
test(t => { test(t => {
@ -41,11 +42,9 @@ test(t => {
const keys = [...styleMap.keys()], values = [...styleMap.values()]; const keys = [...styleMap.keys()], values = [...styleMap.values()];
assert_array_equals(keys, ['--A', '--B', '--C']); assert_array_equals(keys, ['--A', '--B', '--C']);
assert_style_value_array_equals(values, [ assert_style_value_array_equals(values[0], [new CSSUnparsedValue([' A'])]);
new CSSUnparsedValue([' A']), assert_style_value_array_equals(values[1], [new CSSUnparsedValue([' B'])]);
new CSSUnparsedValue([' B']), assert_style_value_array_equals(values[2], [new CSSUnparsedValue([' C'])]);
new CSSUnparsedValue([' C']),
])
}, 'StylePropertyMap iterator returns custom properties with the correct CSSStyleValue'); }, 'StylePropertyMap iterator returns custom properties with the correct CSSStyleValue');
</script> </script>

View file

@ -25,7 +25,8 @@ test(t => {
const keys = [...styleMap.keys()], values = [...styleMap.values()]; const keys = [...styleMap.keys()], values = [...styleMap.values()];
assert_array_equals(keys, ['height', 'width']); assert_array_equals(keys, ['height', 'width']);
assert_style_value_array_equals(values, [CSS.px(5), CSS.px(10)]); assert_style_value_array_equals(values[0], [CSS.px(5)]);
assert_style_value_array_equals(values[1], [CSS.px(10)]);
}, 'StylePropertyMap iterator returns CSS properties with the correct CSSStyleValue'); }, 'StylePropertyMap iterator returns CSS properties with the correct CSSStyleValue');
test(t => { test(t => {
@ -41,11 +42,9 @@ test(t => {
const keys = [...styleMap.keys()], values = [...styleMap.values()]; const keys = [...styleMap.keys()], values = [...styleMap.values()];
assert_array_equals(keys, ['--A', '--B', '--C']); assert_array_equals(keys, ['--A', '--B', '--C']);
assert_style_value_array_equals(values, [ assert_style_value_array_equals(values[0], [new CSSUnparsedValue([' A'])]);
new CSSUnparsedValue([' A']), assert_style_value_array_equals(values[1], [new CSSUnparsedValue([' B'])]);
new CSSUnparsedValue([' B']), assert_style_value_array_equals(values[2], [new CSSUnparsedValue([' C'])]);
new CSSUnparsedValue([' C']),
])
}, 'StylePropertyMap iterator returns custom properties with the correct CSSStyleValue'); }, 'StylePropertyMap iterator returns custom properties with the correct CSSStyleValue');
</script> </script>

View file

@ -0,0 +1,34 @@
<!doctype html>
<meta charset="utf-8">
<title>'opacity' property</title>
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-get">
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#property-stle-value-normalization">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../resources/testhelper.js"></script>
<script src="resources/testsuite.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';
function assert_is_equal_with_clamping(input, result) {
const number = input.to('number');
if (number.value < 0)
assert_style_value_equals(result, new CSSUnitValue(0, 'number'));
else if (number.value > 1)
assert_style_value_equals(result, new CSSUnitValue(1, 'number'));
else
assert_style_value_equals(result, input);
}
runPropertyTests('opacity', [
{
syntax: '<number>',
computed: assert_is_equal_with_clamping
},
]);
</script>

View file

@ -111,6 +111,31 @@ const gTestSyntaxExamples = {
} }
], ],
}, },
'<number>': {
description: 'a number',
examples: [
{
description: 'the number zero',
input: new CSSUnitValue(0, 'number')
},
{
description: 'a negative number',
input: new CSSUnitValue(-3.14, 'number')
},
{
description: 'a positive number',
input: new CSSUnitValue(3.14, 'number')
},
{
description: "a calc number",
input: new CSSMathSum(new CSSUnitValue(2, 'number'), new CSSUnitValue(3, 'number')),
defaultSpecified: (_, result) => assert_is_calc_sum(result),
defaultComputed: (_, result) => {
assert_style_value_equals(result, new CSSUnitValue(5, 'number'));
}
}
],
},
'<position>': { '<position>': {
description: 'a position', description: 'a position',
examples: [ examples: [

View file

@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100" height="50">
<style>use:not(:target) { display: none; }</style>
<defs>
<rect id="green-box" fill="#00ff00" width="100" height="50"/>
<rect id="red-box" fill="#ff0000" width="100" height="50"/>
</defs>
<use id="green" xlink:href="#green-box"/>
<use id="red" xlink:href="#red-box"/>
</svg>

After

Width:  |  Height:  |  Size: 411 B

View file

@ -7,37 +7,31 @@ interface CSSStyleValue {
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)] [Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
interface StylePropertyMapReadOnly { interface StylePropertyMapReadOnly {
readonly maplike<DOMString, sequence<CSSStyleValue>>; iterable<DOMString, sequence<CSSStyleValue>>;
any get(DOMString property); any get(DOMString property);
/* 'any' means (undefined or CSSStyleValue) here, /* 'any' means (undefined or CSSStyleValue) here,
see https://github.com/heycam/webidl/issues/60 */ see https://github.com/heycam/webidl/issues/60 */
sequence<CSSStyleValue> getAll(DOMString property); sequence<CSSStyleValue> getAll(DOMString property);
boolean has(DOMString property); boolean has(DOMString property);
stringifier; readonly attribute long size;
}; };
callback UpdateFunction = CSSStyleValue (CSSStyleValue oldValue);
[Exposed=Window] [Exposed=Window]
interface StylePropertyMap : StylePropertyMapReadOnly { interface StylePropertyMap : StylePropertyMapReadOnly {
maplike<DOMString, sequence<CSSStyleValue>>; void set(DOMString property, (CSSStyleValue or DOMString)... values);
void append(DOMString property, (CSSStyleValue or DOMString)... values); void append(DOMString property, (CSSStyleValue or DOMString)... values);
void delete(DOMString property); void delete(DOMString property);
void set(DOMString property, (CSSStyleValue or DOMString)... values);
void clear(); void clear();
}; };
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
partial interface Element { partial interface Element {
StylePropertyMapReadOnly computedStyleMap(); StylePropertyMapReadOnly computedStyleMap();
}; };
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
partial interface CSSStyleRule { partial interface CSSStyleRule {
[SameObject] readonly attribute StylePropertyMap styleMap; [SameObject] readonly attribute StylePropertyMap styleMap;
}; };
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
partial interface ElementCSSInlineStyle { partial interface ElementCSSInlineStyle {
[SameObject] readonly attribute StylePropertyMap attributeStyleMap; [SameObject] readonly attribute StylePropertyMap attributeStyleMap;
}; };
@ -54,7 +48,7 @@ interface CSSUnparsedValue : CSSStyleValue {
typedef (DOMString or CSSVariableReferenceValue) CSSUnparsedSegment; typedef (DOMString or CSSVariableReferenceValue) CSSUnparsedSegment;
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet), [Exposed=(Window, Worker, PaintWorklet, LayoutWorklet),
Constructor(DOMString variable, optional CSSUnparsedValue fallback)] Constructor(DOMString variable, optional CSSUnparsedValue? fallback = null)]
interface CSSVariableReferenceValue { interface CSSVariableReferenceValue {
attribute DOMString variable; attribute DOMString variable;
readonly attribute CSSUnparsedValue? fallback; readonly attribute CSSUnparsedValue? fallback;
@ -66,8 +60,6 @@ interface CSSKeywordValue : CSSStyleValue {
attribute DOMString value; attribute DOMString value;
}; };
typedef (DOMString or CSSKeywordValue) CSSKeywordish;
typedef (double or CSSNumericValue) CSSNumberish; typedef (double or CSSNumericValue) CSSNumberish;
enum CSSNumericBaseType { enum CSSNumericBaseType {
@ -306,7 +298,7 @@ interface CSSMatrixComponent : CSSTransformComponent {
}; };
dictionary CSSMatrixComponentOptions { dictionary CSSMatrixComponentOptions {
boolean is2D = false; boolean is2D;
}; };
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet), [Exposed=(Window, Worker, PaintWorklet, LayoutWorklet),

View file

@ -340,7 +340,7 @@ interface Element : Node {
attribute DOMString id; attribute DOMString id;
attribute DOMString className; attribute DOMString className;
[SameObject, PutForwards=value] readonly attribute DOMTokenList classList; [SameObject, PutForwards=value] readonly attribute DOMTokenList classList;
attribute DOMString slot; [Unscopable] attribute DOMString slot;
boolean hasAttributes(); boolean hasAttributes();
[SameObject] readonly attribute NamedNodeMap attributes; [SameObject] readonly attribute NamedNodeMap attributes;

View file

Before

Width:  |  Height:  |  Size: 135 B

After

Width:  |  Height:  |  Size: 135 B

Before After
Before After

View file

@ -3,7 +3,6 @@
<title>PerformanceObservers: navigation</title> <title>PerformanceObservers: navigation</title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="performanceobservers.js"></script>
<h1>PerformanceObservers: navigation</h1> <h1>PerformanceObservers: navigation</h1>
<p> <p>
Navigation will <a href="https://w3c.github.io/performance-timeline/#dfn-queue-a-performanceentry">queue a PerformanceEntry</a>. Navigation will <a href="https://w3c.github.io/performance-timeline/#dfn-queue-a-performanceentry">queue a PerformanceEntry</a>.
@ -11,14 +10,16 @@ Navigation will <a href="https://w3c.github.io/performance-timeline/#dfn-queue-a
<div id="log"></div> <div id="log"></div>
<script> <script>
async_test(function (t) { async_test(function (t) {
function checkEntry(pes) {
assert_equals(pes.length, 1, "Only one navigation timing entry");
assert_equals(pes[0].entryType, "navigation", "entryType is \"navigation\"");
assert_equals(pes[0].name, window.location.toString(), "name is the address of the document");
}
var observer = new PerformanceObserver( var observer = new PerformanceObserver(
t.step_func(function (entryList, obs) { t.step_func(function (entryList, obs) {
checkEntries(entryList.getEntries(), checkEntry(entryList.getEntries());
[{ entryType: "navigation", name: "document"}]); checkEntry(entryList.getEntriesByType("navigation"));
checkEntries(entryList.getEntriesByType("navigation"), checkEntry(entryList.getEntriesByName(window.location.toString()));
[{ entryType: "navigation", name: "document"}]);
checkEntries(entryList.getEntriesByName("document"),
[{ entryType: "navigation", name: "document"}]);
observer.disconnect(); observer.disconnect();
t.done(); t.done();
}) })

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<link rel="help" href="https://github.com/w3c/preload/issues/120">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/preload/resources/preload_helper.js"></script>
<script>
var t = async_test('Makes sure that Link headers preload images with (experimental) srcset/imgsizes attributes.');
</script>
<body>
<script src="resources/dummy.js?pipe=trickle(d3)&link-header-preload-srcset"></script>
<script>
window.addEventListener("load", t.step_func(function() {
verifyPreloadAndRTSupport();
verifyNumberOfDownloads('resources/square.png?1x', 1);
verifyNumberOfDownloads('resources/square.png?2x', 0);
verifyNumberOfDownloads('resources/square.png?3x', 0);
verifyNumberOfDownloads('resources/square.png?base', 0);
verifyNumberOfDownloads('resources/square.png?200', 0);
verifyNumberOfDownloads('resources/square.png?400', 1);
verifyNumberOfDownloads('resources/square.png?800', 0);
verifyNumberOfDownloads('resources/square.png?150', 0);
verifyNumberOfDownloads('resources/square.png?300', 1);
verifyNumberOfDownloads('resources/square.png?600', 0);
t.done();
}));
</script>
</body>

View file

@ -0,0 +1,3 @@
Link: <resources/square.png?1x>; rel=preload; as=image; srcset="resources/square.png?2x 2x, resources/square.png?3x 3x"
Link: <resources/square.png?base>; rel=preload; as=image; srcset="resources/square.png?200 200w, resources/square.png?400 400w, resources/square.png?800 800w"; imgsizes=400px
Link: <resources/square.png?base>; rel=preload; as=image; srcset="resources/square.png?150 150w, resources/square.png?300 300w, resources/square.png?600 600w"; imgsizes="(min-width: 300px) 300px, 150px"

View file

@ -1007,6 +1007,13 @@ IdlInterface.prototype.has_constants = function()
}; };
//@} //@}
IdlInterface.prototype.get_unscopables = function()
{
return this.members.filter(function(member) {
return member.isUnscopable;
});
};
IdlInterface.prototype.is_global = function() IdlInterface.prototype.is_global = function()
//@{ //@{
{ {
@ -1552,6 +1559,69 @@ IdlInterface.prototype.test_self = function()
assert_equals(self[this.name].prototype.constructor, self[this.name], assert_equals(self[this.name].prototype.constructor, self[this.name],
this.name + '.prototype.constructor is not the same object as ' + this.name); this.name + '.prototype.constructor is not the same object as ' + this.name);
}.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property'); }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property');
test(function()
{
if (this.is_callback() && !this.has_constants()) {
return;
}
assert_own_property(self, this.name,
"self does not have own property " + format_value(this.name));
if (this.is_callback()) {
assert_false("prototype" in self[this.name],
this.name + ' should not have a "prototype" property');
return;
}
assert_own_property(self[this.name], "prototype",
'interface "' + this.name + '" does not have own property "prototype"');
// If the interface has any member declared with the [Unscopable] extended
// attribute, then there must be a property on the interface prototype object
// whose name is the @@unscopables symbol, which has the attributes
// { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true },
// and whose value is an object created as follows...
var unscopables = this.get_unscopables().map(m => m.name);
var proto = self[this.name].prototype;
if (unscopables.length != 0) {
assert_own_property(
proto, Symbol.unscopables,
this.name + '.prototype should have an @@unscopables property');
var desc = Object.getOwnPropertyDescriptor(proto, Symbol.unscopables);
assert_false("get" in desc,
this.name + ".prototype[Symbol.unscopables] should not have a getter");
assert_false("set" in desc, this.name + ".prototype[Symbol.unscopables] should not have a setter");
assert_false(desc.writable, this.name + ".prototype[Symbol.unscopables] should not be writable");
assert_false(desc.enumerable, this.name + ".prototype[Symbol.unscopables] should not be enumerable");
assert_true(desc.configurable, this.name + ".prototype[Symbol.unscopables] should be configurable");
assert_equals(desc.value, proto[Symbol.unscopables],
this.name + '.prototype[Symbol.unscopables] should be in the descriptor');
assert_equals(typeof desc.value, "object",
this.name + '.prototype[Symbol.unscopables] should be an object');
assert_equals(Object.getPrototypeOf(desc.value), null,
this.name + '.prototype[Symbol.unscopables] should have a null prototype');
assert_equals(Object.getOwnPropertySymbols(desc.value).length,
0,
this.name + '.prototype[Symbol.unscopables] should have the right number of symbol-named properties');
// Check that we do not have _extra_ unscopables. Checking that we
// have all the ones we should will happen in the per-member tests.
var observed = Object.getOwnPropertyNames(desc.value);
for (var prop of observed) {
assert_not_equals(unscopables.indexOf(prop),
-1,
this.name + '.prototype[Symbol.unscopables] has unexpected property "' + prop + '"');
}
} else {
assert_equals(Object.getOwnPropertyDescriptor(self[this.name].prototype, Symbol.unscopables),
undefined,
this.name + '.prototype should not have @@unscopables');
}
}.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s @@unscopables property');
}; };
//@} //@}
@ -1805,6 +1875,10 @@ IdlInterface.prototype.test_member_attribute = function(member)
} }
}.bind(this)); }.bind(this));
test(function () {
this.do_member_unscopable_asserts(member);
}.bind(this), 'Unscopable handled correctly for ' + member.name + ' property on ' + this.name);
}; };
//@} //@}
@ -1869,6 +1943,41 @@ IdlInterface.prototype.test_member_operation = function(member)
} }
this.do_member_operation_asserts(memberHolderObject, member, a_test); this.do_member_operation_asserts(memberHolderObject, member, a_test);
}.bind(this)); }.bind(this));
test(function () {
this.do_member_unscopable_asserts(member);
}.bind(this),
'Unscopable handled correctly for ' + member.name + "(" +
member.arguments.map(
function(m) {return m.idlType.idlType; } ).join(", ")
+ ")" + ' on ' + this.name);
};
IdlInterface.prototype.do_member_unscopable_asserts = function(member)
{
// Check that if the member is unscopable then it's in the
// @@unscopables object properly.
if (!member.isUnscopable) {
return;
}
var unscopables = self[this.name].prototype[Symbol.unscopables];
var prop = member.name;
var propDesc = Object.getOwnPropertyDescriptor(unscopables, prop);
assert_equals(typeof propDesc, "object",
this.name + '.prototype[Symbol.unscopables].' + prop + ' must exist')
assert_false("get" in propDesc,
this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no getter');
assert_false("set" in propDesc,
this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no setter');
assert_true(propDesc.writable,
this.name + '.prototype[Symbol.unscopables].' + prop + ' must be writable');
assert_true(propDesc.enumerable,
this.name + '.prototype[Symbol.unscopables].' + prop + ' must be enumerable');
assert_true(propDesc.configurable,
this.name + '.prototype[Symbol.unscopables].' + prop + ' must be configurable');
assert_equals(propDesc.value, true,
this.name + '.prototype[Symbol.unscopables].' + prop + ' must have the value `true`');
}; };
//@} //@}
@ -2552,6 +2661,7 @@ function IdlInterfaceMember(obj)
} }
this.isUnforgeable = this.has_extended_attribute("Unforgeable"); this.isUnforgeable = this.has_extended_attribute("Unforgeable");
this.isUnscopable = this.has_extended_attribute("Unscopable");
} }
//@} //@}

View file

@ -82,6 +82,13 @@ idlArray.test();
"message": null, "message": null,
"stack": null "stack": null
}, },
{
"name": "Foo interface: existence and properties of interface prototype object's @@unscopables property",
"status_string": "PASS",
"properties": {},
"message": null,
"stack": null
},
{ {
"name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError", "name": "Foo interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError",
"status_string": "FAIL", "status_string": "FAIL",
@ -222,6 +229,13 @@ idlArray.test();
"message": null, "message": null,
"stack": null "stack": null
}, },
{
"name": "Window interface: existence and properties of interface prototype object's @@unscopables property",
"status_string": "PASS",
"properties": {},
"message": null,
"stack": null
},
{ {
"name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError", "name": "Window interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError",
"status_string": "PASS", "status_string": "PASS",

View file

@ -89,6 +89,13 @@ idlArray.test();
"message": null, "message": null,
"stack": null "stack": null
}, },
{
"name": "Foo interface: existence and properties of interface prototype object's @@unscopables property",
"status_string": "PASS",
"properties": {},
"message": null,
"stack": null
},
{ {
"name": "Foo must be primary interface of new Foo()", "name": "Foo must be primary interface of new Foo()",
"status_string": "PASS", "status_string": "PASS",

View file

@ -18,6 +18,6 @@ def main(request, response):
headers.append(('Access-Control-Allow-Origin', '*')) headers.append(('Access-Control-Allow-Origin', '*'))
image_path = os.path.join(request.doc_root, 'images') image_path = os.path.join(request.doc_root, 'images')
body = create_part(os.path.join(image_path, 'green-1x1.png')) body = create_part(os.path.join(image_path, 'red.png'))
body = body + create_part(os.path.join(image_path, 'red-16x16.png')) body = body + create_part(os.path.join(image_path, 'red-16x16.png'))
return headers, body return headers, body

View file

@ -0,0 +1,3 @@
addEventListener('fetch', evt => {
evt.respondWith(fetch(evt.request));
});

View file

@ -0,0 +1,3 @@
<!DOCTYPE html>
<meta charset="utf-8">
<img src="/images/green.svg">

View file

@ -0,0 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Green svg box reference file</title>
<p>Pass if you see a green box below.</p>
<iframe src="svg-target-reftest-001-frame.html">

View file

@ -0,0 +1,2 @@
<!DOCTYPE html>
<img src="/images/colors.svg#green">

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset="utf-8">
<title>Service worker interception does not break SVG fragment targets</title>
<meta name="assert" content="SVG with link fragment should render correctly when intercepted by a service worker.">
<script src="resources/test-helpers.sub.js"></script>
<link rel="match" href="resources/svg-target-reftest-001.html">
<p>Pass if you see a green box below.</p>
<script>
// We want to use utility functions designed for testharness.js where
// there is a test object. We don't have a test object in reftests
// so fake one for now.
const fake_test = { step_func: f => f };
async function runTest() {
const script = './resources/pass-through-worker.js';
const scope = './resources/svg-target-reftest-frame.html';
let reg = await navigator.serviceWorker.register(script, { scope });
await wait_for_state(fake_test, reg.installing, 'activated');
let f = await with_iframe(scope);
document.documentElement.classList.remove('reftest-wait');
await reg.unregister();
// Note, we cannot remove the frame explicitly because we can't
// tell when the reftest completes.
}
runTest();
</script>
</html>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>Should not crash on circular filter reference containing a foreignObject.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>test(()=>{})</script>
<svg id="svg" filter="url(#filter)">
<foreignObject overflow="hidden"></foreignObject>
</svg>
<svg>
<filter id="filter">
<feImage xlink:href="#svg"></feImage>
</filter>
</svg>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>Should not crash on circular filter reference containing an svg under svg.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>test(()=>{})</script>
<svg id="svg" filter="url(#filter)">
<filter id="filter">
<feImage xlink:href="#svg"></feImage>
</filter>
<svg overflow="hidden" width="20" height="20">
<rect fill="black" width="20" height="20"></rect>
</svg>
</svg>

View file

@ -1,6 +1,5 @@
@AutomatedTester @AutomatedTester
@andreastt @andreastt
@lukeis
@mjzffr @mjzffr
@shs96c @shs96c
@whimboo @whimboo

View file

@ -1,6 +1,11 @@
import pytest import pytest
from tests.support.asserts import assert_error, assert_same_element, assert_success from tests.support.asserts import (
assert_element_has_focus,
assert_error,
assert_same_element,
assert_success,
)
from tests.support.inline import inline from tests.support.inline import inline
@ -17,7 +22,7 @@ def add_event_listeners(element):
element.session.execute_script(""" element.session.execute_script("""
let [target] = arguments; let [target] = arguments;
window.events = []; window.events = [];
for (let expected of ["focus", "blur", "change", "keypress", "keydown", "keyup", "input"]) { for (let expected of ["focus", "change", "keypress", "keydown", "keyup", "input"]) {
target.addEventListener(expected, ({type}) => window.events.push(type)); target.addEventListener(expected, ({type}) => window.events.push(type));
} }
""", args=(element,)) """, args=(element,))
@ -34,6 +39,7 @@ def test_input(session):
element_send_keys(session, element, "foo") element_send_keys(session, element, "foo")
assert element.property("value") == "foo" assert element.property("value") == "foo"
assert_element_has_focus(element)
def test_textarea(session): def test_textarea(session):
@ -43,6 +49,7 @@ def test_textarea(session):
element_send_keys(session, element, "foo") element_send_keys(session, element, "foo")
assert element.property("value") == "foo" assert element.property("value") == "foo"
assert_element_has_focus(element)
def test_input_append(session): def test_input_append(session):
@ -89,6 +96,13 @@ def test_events(session, tag):
"keydown", "keydown",
"keypress", "keypress",
"input", "input",
"keyup", "keyup"]
"change",
"blur"]
@pytest.mark.parametrize("tag", ["input", "textarea"])
def test_not_blurred(session, tag):
session.url = inline("<%s>" % tag)
element = session.find.css(tag, all=False)
element_send_keys(session, element, "")
assert_element_has_focus(element)

View file

@ -1,4 +1,4 @@
from tests.support.asserts import assert_error, assert_same_element, assert_success from tests.support.asserts import assert_error, assert_success
from tests.support.inline import iframe, inline from tests.support.inline import iframe, inline
@ -13,8 +13,8 @@ def send_keys_to_element(session, element, text):
def test_body_is_interactable(session): def test_body_is_interactable(session):
session.url = inline(""" session.url = inline("""
<body onkeypress="document.getElementById('result').value += event.key"> <body onkeypress="document.querySelector('input').value += event.key">
<input type="text" id="result"/> <input>
</body> </body>
""") """)
@ -22,18 +22,18 @@ def test_body_is_interactable(session):
result = session.find.css("input", all=False) result = session.find.css("input", all=False)
# By default body is the active element # By default body is the active element
assert_same_element(session, element, session.active_element) assert session.active_element is element
response = send_keys_to_element(session, element, "foo") response = send_keys_to_element(session, element, "foo")
assert_success(response) assert_success(response)
assert_same_element(session, element, session.active_element) assert session.active_element is element
assert result.property("value") == "foo" assert result.property("value") == "foo"
def test_document_element_is_interactable(session): def test_document_element_is_interactable(session):
session.url = inline(""" session.url = inline("""
<html onkeypress="document.getElementById('result').value += event.key"> <html onkeypress="document.querySelector('input').value += event.key">
<input type="text" id="result"/> <input>
</html> </html>
""") """)
@ -42,18 +42,18 @@ def test_document_element_is_interactable(session):
result = session.find.css("input", all=False) result = session.find.css("input", all=False)
# By default body is the active element # By default body is the active element
assert_same_element(session, body, session.active_element) assert session.active_element is body
response = send_keys_to_element(session, element, "foo") response = send_keys_to_element(session, element, "foo")
assert_success(response) assert_success(response)
assert_same_element(session, body, session.active_element) assert session.active_element is element
assert result.property("value") == "foo" assert result.property("value") == "foo"
def test_iframe_is_interactable(session): def test_iframe_is_interactable(session):
session.url = inline(iframe(""" session.url = inline(iframe("""
<body onkeypress="document.getElementById('result').value += event.key"> <body onkeypress="document.querySelector('input').value += event.key">
<input type="text" id="result"/> <input>
</body> </body>
""")) """))
@ -61,11 +61,11 @@ def test_iframe_is_interactable(session):
frame = session.find.css("iframe", all=False) frame = session.find.css("iframe", all=False)
# By default the body has the focus # By default the body has the focus
assert_same_element(session, body, session.active_element) assert session.active_element is body
response = send_keys_to_element(session, frame, "foo") response = send_keys_to_element(session, frame, "foo")
assert_success(response) assert_success(response)
assert_same_element(session, body, session.active_element) assert session.active_element is frame
# Any key events are immediately routed to the nested # Any key events are immediately routed to the nested
# browsing context's active document. # browsing context's active document.
@ -75,7 +75,7 @@ def test_iframe_is_interactable(session):
def test_transparent_element(session): def test_transparent_element(session):
session.url = inline("<input style=\"opacity: 0;\">") session.url = inline("""<input style="opacity: 0">""")
element = session.find.css("input", all=False) element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo") response = send_keys_to_element(session, element, "foo")
@ -94,8 +94,8 @@ def test_readonly_element(session):
def test_obscured_element(session): def test_obscured_element(session):
session.url = inline(""" session.url = inline("""
<input type="text" /> <input>
<div style="position: relative; top: -3em; height: 5em; background-color: blue"></div> <div style="position: relative; top: -3em; height: 5em; background: blue;"></div>
""") """)
element = session.find.css("input", all=False) element = session.find.css("input", all=False)
@ -113,7 +113,7 @@ def test_not_a_focusable_element(session):
def test_not_displayed_element(session): def test_not_displayed_element(session):
session.url = inline("<input style=\"display: none\">") session.url = inline("""<input style="display: none">""")
element = session.find.css("input", all=False) element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo") response = send_keys_to_element(session, element, "foo")
@ -121,7 +121,7 @@ def test_not_displayed_element(session):
def test_hidden_element(session): def test_hidden_element(session):
session.url = inline("<input style=\"visibility: hidden\">") session.url = inline("""<input style="visibility: hidden">""")
element = session.find.css("input", all=False) element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo") response = send_keys_to_element(session, element, "foo")
@ -129,7 +129,7 @@ def test_hidden_element(session):
def test_disabled_element(session): def test_disabled_element(session):
session.url = inline("<input disabled=\"false\">") session.url = inline("""<input disabled>""")
element = session.find.css("input", all=False) element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo") response = send_keys_to_element(session, element, "foo")

View file

@ -161,9 +161,8 @@ def test_element(session):
session.url = inline("<input type=checkbox>") session.url = inline("<input type=checkbox>")
element = session.find.css("input", all=False) element = session.find.css("input", all=False)
element.click() element.click()
assert None == session.execute_script("return arguments[0].hasAttribute('checked')", assert session.execute_script("return arguments[0].hasAttribute('checked')", args=(element,)) is False
args=[element]) result = session.transport.send("GET", "session/{session_id}/element/{element_id}/property/checked"
result = session.transport.send("GET", "session/{session_id}/element/{element_id}/property/id"
.format(session_id=session.session_id, .format(session_id=session.session_id,
element_id=element.id)) element_id=element.id))
assert_success(result, True) assert_success(result, True)

View file

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html class="reftest-wait">
<script src="/common/reftest-wait.js"></script>
<style>
.container {
position: relative;
display: inline-block;
width: 320px;
height: 240px;
}
.cue {
position: absolute;
top: 0;
left: 0;
right: 0;
overflow: hidden;
}
.cue.center {
text-align: center;
}
.cue > span {
font-family: sans-serif;
background: green;
color: green;
font-size: 50px;
padding: 2px;
}
</style>
<div class="container">
<video width="320" height="240" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
<source src="/media/white.webm" type="video/webm">
<source src="/media/white.mp4" type="video/mp4">
</video>
<div class="cue center"><span>&#x5d0;&#x5d1;&#x5d2;</span></div>
</div>
</html>

View file

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html class="reftest-wait">
<script src="/common/reftest-wait.js"></script>
<link rel="match" href="track-cue-rendering-position-align-rtl-center-ref.html">
<script>
function addTrackWithRtlCueData(video, cueData) {
var track = video.addTextTrack('subtitles');
var cue = new VTTCue(0, 10, '\u05d0\u05d1\u05d2');
for (var prop in cueData)
cue[prop] = cueData[prop];
track.addCue(cue);
track.mode = 'showing';
}
</script>
<style>
video::cue {
font-size: 50px;
color: green;
background-color: green;
}
</style>
<video width="320" height="240" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
<source src="/media/white.webm" type="video/webm">
<source src="/media/white.mp4" type="video/mp4">
<script>
var video = document.currentScript.parentNode;
addTrackWithRtlCueData(video, { position: 50, positionAlign: 'center', align: 'center', size: 50, line: 0 });
</script>
</video>
</html>

View file

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html class="reftest-wait">
<script src="/common/reftest-wait.js"></script>
<style>
.container {
position: relative;
display: inline-block;
width: 320px;
height: 240px;
}
.cue {
position: absolute;
top: 0;
left: 0;
right: 0;
overflow: hidden;
}
.cue.start {
text-align: end;
}
.cue > span {
font-family: sans-serif;
background: green;
color: green;
font-size: 50px;
padding: 2px;
}
</style>
<div class="container">
<video width="320" height="240" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
<source src="/media/white.webm" type="video/webm">
<source src="/media/white.mp4" type="video/mp4">
</video>
<div class="cue start"><span>&#x5d0;&#x5d1;&#x5d2;</span></div>
</div>
</html>

View file

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html class="reftest-wait">
<script src="/common/reftest-wait.js"></script>
<link rel="match" href="track-cue-rendering-position-align-rtl-line-left-ref.html">
<script>
function addTrackWithRtlCueData(video, cueData) {
var track = video.addTextTrack('subtitles');
var cue = new VTTCue(0, 10, '\u05d0\u05d1\u05d2');
for (var prop in cueData)
cue[prop] = cueData[prop];
track.addCue(cue);
track.mode = 'showing';
}
</script>
<style>
video::cue {
font-size: 50px;
color: green;
background-color: green;
}
</style>
<video width="320" height="240" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
<source src="/media/white.webm" type="video/webm">
<source src="/media/white.mp4" type="video/mp4">
<script>
var video = document.currentScript.parentNode;
addTrackWithRtlCueData(video, { position: 50, positionAlign: 'line-left', align: 'start', size: 50, line: 0 });
</script>
</video>
</html>

View file

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html class="reftest-wait">
<script src="/common/reftest-wait.js"></script>
<style>
.container {
position: relative;
display: inline-block;
width: 320px;
height: 240px;
}
.cue {
position: absolute;
top: 0;
left: 0;
right: 0;
overflow: hidden;
}
.cue.end {
text-align: start;
}
.cue > span {
font-family: sans-serif;
background: green;
color: green;
font-size: 50px;
padding: 2px;
}
</style>
<div class="container">
<video width="320" height="240" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
<source src="/media/white.webm" type="video/webm">
<source src="/media/white.mp4" type="video/mp4">
</video>
<div class="cue end"><span>&#x5d0;&#x5d1;&#x5d2;</span></div>
</div>
</html>

View file

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html class="reftest-wait">
<script src="/common/reftest-wait.js"></script>
<link rel="match" href="track-cue-rendering-position-align-rtl-line-right-ref.html">
<script>
function addTrackWithRtlCueData(video, cueData) {
var track = video.addTextTrack('subtitles');
var cue = new VTTCue(0, 10, '\u05d0\u05d1\u05d2');
for (var prop in cueData)
cue[prop] = cueData[prop];
track.addCue(cue);
track.mode = 'showing';
}
</script>
<style>
video::cue {
font-size: 50px;
color: green;
background-color: green;
}
</style>
<video width="320" height="240" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
<source src="/media/white.webm" type="video/webm">
<source src="/media/white.mp4" type="video/mp4">
<script>
var video = document.currentScript.parentNode;
addTrackWithRtlCueData(video, { position: 50, positionAlign: 'line-right', align: 'end', size: 50, line: 0 });
</script>
</video>
</html>

View file

@ -1,8 +1,9 @@
"use strict"; "use strict";
importScripts("/resources/testharness.js");
var name = "something else"; var name = "something else";
// This just makes the test name not "Untitled" // This just makes the test name not "Untitled"
test(() => { }, "Declaring name as an accidental global must not cause a harness error"); test(() => { }, `Declaring name as an accidental global must not cause a harness error for ${self.constructor.name}`);
done(); done();