summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-highlight-api
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/css/css-highlight-api
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-highlight-api')
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/Highlight-iteration-with-modifications.html91
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/Highlight-iteration.html201
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/Highlight-multiple-type-attribute.html47
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/Highlight-setlike-tampered-Set-prototype.html55
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/Highlight-setlike.html106
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/Highlight-type-attribute.tentative.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration-with-modifications.html109
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration.html186
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike-tampered-Map-prototype.html61
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike.html75
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting-ref.html23
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting.html65
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/highlight-priority.html77
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-computed.html40
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-from-font-computed.html59
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-parsing.html22
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/idlharness.window.js17
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001-ref.html12
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001.html22
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001.html26
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001.html31
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002-ref.html25
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002.html39
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003-ref.html19
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003.html40
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004-ref.html25
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004.html41
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-005.html39
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-006.html37
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001-ref.html13
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001.html32
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-002.html50
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-003.html48
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-004.html47
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-font-metrics-001.html47
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-logical-metrics-001.html39
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001-ref.html22
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001.html42
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002-ref.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html45
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003-ref.html18
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003.html42
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004-ref.html18
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004.html38
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005-ref.html19
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005.html49
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001-ref.html19
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001.html32
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002.html33
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001-ref.html9
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002-ref.html8
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002.html24
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003-ref.html6
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003.html23
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2.html34
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004.html34
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-005.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-006.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-007.html24
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-008.html24
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-009.html30
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-010.html22
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-011.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-012.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-013.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-014.html26
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-015.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-016.html21
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-017.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-018.html22
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar-ref.html9
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html31
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency-ref.html13
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency.html22
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection.html24
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html23
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001.html12
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-002.html33
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003-ref.html24
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003.html46
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004.html45
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005-ref.html18
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005.html45
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006-ref.html10
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006.html50
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001-ref.html10
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-002.html21
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003-ref.html10
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003.html23
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html28
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html29
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html37
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html30
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007-ref.html10
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007.html34
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001.html43
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002-ref.html17
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002.html53
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-001.html28
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-002.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003.html36
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001-ref.html3
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001.html22
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-002.html21
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-003.html18
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004-ref.html10
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html20
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html28
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001-ref.html29
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001.html36
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001.html27
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-shadow.tentative.html21
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001.html25
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001.html36
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-code.html13
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-container.html16
-rw-r--r--testing/web-platform/tests/css/css-highlight-api/painting/resources/run-after-layout-and-paint.js11
135 files changed, 4258 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-highlight-api/Highlight-iteration-with-modifications.html b/testing/web-platform/tests/css/css-highlight-api/Highlight-iteration-with-modifications.html
new file mode 100644
index 0000000000..b1f0fb10ee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/Highlight-iteration-with-modifications.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<title>Highlight iteration with insertions and deletions inbetween</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id='testDiv'>abc</div>
+<script>
+ 'use strict';
+ let container = document.getElementById('testDiv');
+ let range1 = new StaticRange({startContainer: container, startOffset: 0, endContainer: container, endOffset: 1});
+ let range2 = new Range();
+
+ // Test insertions using .add
+ test(() => {
+ let customHighlight = new Highlight();
+ let iterator = customHighlight[Symbol.iterator]();
+ customHighlight.add(range1);
+ let element = iterator.next();
+ assert_true(element.done, 'The iteration ends although we added a new range after starting the iteration');
+ assert_equals(element.value, undefined, 'A range added after starting the iteration is not found during the current iteration');
+ }, 'Highlight iteration is not modified when a new range is added after starting the iteration');
+
+ test(() => {
+ let customHighlight = new Highlight(range1);
+ let iterator = customHighlight[Symbol.iterator]();
+ customHighlight.add(range2);
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end although there was a second range added to the Highlight after starting the iteration');
+ assert_equals(element.value, range1, 'The range that was pointed to by the iterator is returned although a second range was added after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the ranges that were in the Highlight when the iteration started although there was a range addition after starting the iteration');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'Highlight iteration is not modified when a new range is added after starting the iteration with one range in the Highlight');
+
+ // Test deletions using .delete
+ test(() => {
+ let customHighlight = new Highlight(range1);
+ let iterator = customHighlight[Symbol.iterator]();
+ customHighlight.delete(range1);
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end although the range that was pointed to by the iterator was deleted');
+ assert_equals(element.value, range1, 'The range that was pointed to by the iterator is returned although it was deleted after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the ranges although the range that was pointed to by the iterator was deleted after starting the iteration');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'Highlight iteration is not modified when the range that was pointed to by the iterator was deleted after starting the iteration');
+
+ test(() => {
+ let customHighlight = new Highlight(range1, range2);
+ let iterator = customHighlight[Symbol.iterator]();
+ customHighlight.delete(range2);
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end when the range following to the one that was pointed to by the iterator was deleted');
+ assert_equals(element.value, range1, 'The range that was pointed to by the iterator is returned as it should although the next range was deleted immediately after starting the iteration');
+ element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end when you call .next twice since the beginning of the iteration although the second range was deleted');
+ assert_equals(element.value, range2, 'The range that was pointed to by the iterator is returned as it should although the next range was deleted immediately after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the ranges although the second range was deleted immediately after starting the iteration');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'Highlight iteration is not modified when the range that was immediately after the one pointed to by the iterator was deleted after starting the iteration');
+
+ test(() => {
+ let customHighlight = new Highlight(range1, range2);
+ let iterator = customHighlight[Symbol.iterator]();
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end when there are still two ranges to visit');
+ assert_equals(element.value, range1, 'The range that was pointed to by the iterator is returned as it should');
+ customHighlight.delete(range1);
+ element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end when the range previously visited is deleted and there is still a range to visit');
+ assert_equals(element.value, range2, 'The range that was pointed to by the iterator is returned as it should although the previous range was deleted after calling .next');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the ranges although the first range was deleted after the first call to .next');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'Highlight iteration is not modified when a range that was already visited is deleted and there are still ranges to visit');
+
+ // Test deletions using .clear
+ test(() => {
+ let customHighlight = new Highlight(range1);
+ let iterator = customHighlight[Symbol.iterator]();
+ customHighlight.clear();
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end although the range that was pointed to by the iterator was deleted using .clear()');
+ assert_equals(element.value, range1, 'The range that was pointed to by the iterator is returned although it was deleted using .clear() after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the ranges although the range that was pointed to by the iterator was deleted using .clear() after starting the iteration');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'Highlight iteration is not modified when the range that was pointed to by the iterator was deleted using .clear() after starting the iteration');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/Highlight-iteration.html b/testing/web-platform/tests/css/css-highlight-api/Highlight-iteration.html
new file mode 100644
index 0000000000..f3268b49cd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/Highlight-iteration.html
@@ -0,0 +1,201 @@
+<!doctype html>
+<title>Highlight iteration</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id='testDiv'>abc</div>
+<script>
+ 'use strict';
+ let range1 = new Range();
+ let container = document.getElementById('testDiv');
+ let range2 = new StaticRange({startContainer: container, startOffset: 0, endContainer: container, endOffset: 0});
+
+ let rangeAdditionModeCollection = ["constructor", "add function"];
+ let iterationInitializationCollection = ["customHighlight[Symbol.iterator]()", "customHighlight.values()", "customHighlight.keys()"];
+
+ function getIterator(customHighlight, iterationInitialization){
+ var iterator;
+ if(iterationInitialization === "customHighlight[Symbol.iterator]()"){
+ iterator = customHighlight[Symbol.iterator]();
+ }
+ else if(iterationInitialization === "customHighlight.values()"){
+ iterator = customHighlight.values();
+ }
+ else if(iterationInitialization === "customHighlight.keys()"){
+ iterator = customHighlight.keys();
+ }
+ return iterator;
+ }
+
+ // Test .keys, .values, [Symbol.iterator]
+
+ for(let iterationInitialization of iterationInitializationCollection){
+ test(() => {
+ let customHighlight = new Highlight();
+ let iterator = getIterator(customHighlight, iterationInitialization);
+ let element = iterator.next();
+ assert_true(element.done, 'Highlight is iterable and .next() returns an element with .done===true when there are no more ranges to iterate');
+ assert_equals(element.value, undefined, 'Highlight is iterable and .next() returns an element with .value undefined when there are no more ranges to iterate.');
+ }, 'Highlight can be iterated when it\'s empty initializing the iterator with ' + iterationInitialization);
+ }
+
+ for(let rangeAdditionMode of rangeAdditionModeCollection){
+ for(let iterationInitialization of iterationInitializationCollection){
+ test(() => {
+ var customHighlight;
+ if(rangeAdditionMode === "constructor"){
+ customHighlight = new Highlight(range1);
+ }
+ else if(rangeAdditionMode === "add function"){
+ customHighlight = new Highlight();
+ customHighlight.add(range1);
+ }
+
+ let iterator = getIterator(customHighlight, iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'Highlight is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last range');
+ assert_equals(element.value, range1, '.next() returns an element with .value corresponding to the first range added to the Highlight');
+ element = iterator.next();
+ assert_true(element.done, 'Highlight is iterable and .next() returns an element with .done===true when there are no more ranges to iterate');
+ assert_equals(element.value, undefined, 'Highlight is iterable and .next() returns an element with .value undefined when there are no more ranges to iterate.');
+ }, 'Highlight can be iterated over all of its ranges initializing the iterator with ' + iterationInitialization + ' and adding a range by passing it to the ' + rangeAdditionMode);
+
+ test(() => {
+ var customHighlight;
+ if(rangeAdditionMode === "constructor"){
+ customHighlight = new Highlight(range1, range2);
+ }
+ else if(rangeAdditionMode === "add function"){
+ customHighlight = new Highlight();
+ customHighlight.add(range1);
+ customHighlight.add(range2);
+ }
+
+ let iterator = getIterator(customHighlight, iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'Highlight is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last range');
+ assert_equals(element.value, range1, '.next() returns an element with .value corresponding to the first range added to the Highlight');
+ element = iterator.next();
+ assert_false(element.done, 'Highlight is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last range');
+ assert_equals(element.value, range2, '.next() returns an element with .value corresponding to the second range added to the Highlight');
+ element = iterator.next();
+ assert_true(element.done, 'Highlight is iterable and .next() returns an element with .done===true when there are no more ranges to iterate');
+ assert_equals(element.value, undefined, 'Highlight is iterable and .next() returns an element with .value undefined when there are no more ranges to iterate.');
+ }, 'Highlight can be iterated over all of its ranges initializing the iterator with ' + iterationInitialization + ' and adding two ranges by passing them to the ' + rangeAdditionMode);
+ }
+ }
+
+ // Test .entries()
+
+ test(() => {
+ let customHighlight = new Highlight();
+ let iterator = customHighlight.entries();
+ let element = iterator.next();
+ assert_true(element.done, 'Highlight is iterable and .next() returns an element with .done===true when there are no more ranges to iterate');
+ assert_equals(element.value, undefined, 'Highlight is iterable and .next() returns an element with .value undefined when there are no more ranges to iterate.');
+ }, 'Highlight can be iterated when it\'s empty initializing the iterator with .entries()');
+
+ for(let rangeAdditionMode of rangeAdditionModeCollection){
+ test(() => {
+ var customHighlight;
+ if(rangeAdditionMode === "constructor"){
+ customHighlight = new Highlight(range1);
+ }
+ else if(rangeAdditionMode === "add function"){
+ customHighlight = new Highlight();
+ customHighlight.add(range1);
+ }
+
+ let iterator = customHighlight.entries();
+ let element = iterator.next();
+ assert_false(element.done, 'Highlight is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last range');
+ assert_equals(element.value[0], range1, '.next() returns an element with .value[0] corresponding to the first range added to the Highlight');
+ assert_equals(element.value[1], range1, '.next() returns an element with .value[1] corresponding to the first range added to the Highlight');
+ element = iterator.next();
+ assert_true(element.done, 'Highlight is iterable and .next() returns an element with .done===true when there are no more ranges to iterate');
+ assert_equals(element.value, undefined, 'Highlight is iterable and .next() returns an element with .value undefined when there are no more ranges to iterate.');
+ }, 'Highlight can be iterated over all of its ranges initializing the iterator with .entries() and adding a range by passing it to the ' + rangeAdditionMode);
+
+ test(() => {
+ var customHighlight;
+ if(rangeAdditionMode === "constructor"){
+ customHighlight = new Highlight(range1, range2);
+ }
+ else if(rangeAdditionMode === "add function"){
+ customHighlight = new Highlight();
+ customHighlight.add(range1);
+ customHighlight.add(range2);
+ }
+
+ let iterator = customHighlight.entries();
+ let element = iterator.next();
+ assert_false(element.done, 'Highlight is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value[0], range1, '.next() returns an element with .value[0] corresponding to the first range added to the Highlight');
+ assert_equals(element.value[1], range1, '.next() returns an element with .value[1] corresponding to the first range added to the Highlight');
+ element = iterator.next();
+ assert_false(element.done, 'Highlight is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value[0], range2, '.next() returns an element with .value[0] corresponding to the second range added to the Highlight');
+ assert_equals(element.value[1], range2, '.next() returns an element with .value[1] corresponding to the second range added to the Highlight');
+ element = iterator.next();
+ assert_true(element.done, 'Highlight is iterable and .next() returns an element with .done===true when there are no more ranges to iterate');
+ assert_equals(element.value, undefined, 'Highlight is iterable and .next() returns an element with .value undefined when there are no more ranges to iterate.');
+ }, 'Highlight can be iterated over all of its ranges initializing the iterator with .entries() and adding two ranges by passing them to the ' + rangeAdditionMode);
+ }
+
+ // Test .forEach
+
+ function compareArrays(array1, array2){
+ if(array1.length != array2.length){
+ return false;
+ }
+ for(let index=0; index<array1.length; ++index){
+ if(array1[index] != array2[index])
+ return false;
+ }
+ return true;
+ }
+
+ test(() => {
+ let customHighlight = new Highlight();
+ let expectedResult = [];
+ let actualResult = [];
+ customHighlight.forEach((range) => {actualResult.push(range);});
+ assert_true(compareArrays(actualResult, expectedResult), 'The ranges seen match the ranges added');
+ }, 'Highlight can be iterated through when it\'s empty using forEach.');
+
+ for(let rangeAdditionMode of rangeAdditionModeCollection){
+ test(() => {
+ var customHighlight;
+ if(rangeAdditionMode === "constructor"){
+ customHighlight = new Highlight(range1);
+ }
+ else if(rangeAdditionMode === "add function"){
+ customHighlight = new Highlight();
+ customHighlight.add(range1);
+ }
+
+ let expectedResult = [range1];
+ let actualResult = [];
+ customHighlight.forEach((range) => {actualResult.push(range);});
+ assert_true(compareArrays(actualResult, expectedResult), 'The ranges seen match the ranges added');
+ }, 'Highlight can be iterated through using forEach when it has one range that was added by passing it to the ' + rangeAdditionMode);
+
+ test(() => {
+ var customHighlight;
+ if(rangeAdditionMode === "constructor"){
+ customHighlight = new Highlight(range1, range2);
+ }
+ else if(rangeAdditionMode === "add function"){
+ customHighlight = new Highlight();
+ customHighlight.add(range1);
+ customHighlight.add(range2);
+ }
+
+ let expectedResult = [range1, range2];
+ let actualResult = [];
+ customHighlight.forEach((range) => {actualResult.push(range);});
+ assert_true(compareArrays(actualResult, expectedResult), 'The ranges seen match the ranges added');
+ }, 'Highlight can be iterated through using forEach when it has two ranges that were added by passing them to the ' + rangeAdditionMode);
+ }
+
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/Highlight-multiple-type-attribute.html b/testing/web-platform/tests/css/css-highlight-api/Highlight-multiple-type-attribute.html
new file mode 100644
index 0000000000..dc8b330455
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/Highlight-multiple-type-attribute.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Highlight type has a limited set of types</title>
+ <link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ #one::highlight(yellow-highlight) {
+ background-color: yellow;
+ }
+ #two::highlight(green-highlight) {
+ background-color: green;
+ }
+ </style>
+</head>
+<body>
+ <span id="one">One </span><span id="two">two </span>
+ <script>
+ test(() => {
+ let highlightYellow = new Highlight(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2}));
+ let highlightGreen = new Highlight(new StaticRange({startContainer: document.body, startOffset: 2, endContainer: document.body, endOffset: 3}));
+
+ CSS.highlights.set("yellow-highlight", highlightYellow);
+ CSS.highlights.set("green-highlight", highlightGreen);
+
+ assert_equals(highlightYellow.type, "highlight");
+ assert_equals(highlightGreen.type, "highlight");
+
+ highlightGreen.type = "grammar-error";
+
+ assert_equals(highlightYellow.type, "highlight");
+ assert_equals(highlightGreen.type, "grammar-error");
+
+ highlightGreen.type = "Spelling-error";
+
+ assert_equals(highlightYellow.type, "highlight");
+ assert_equals(highlightGreen.type, "grammar-error");
+
+ highlightYellow.type = "ergeoirgjgeerror";
+
+ assert_equals(highlightYellow.type, "highlight");
+ assert_equals(highlightGreen.type, "grammar-error");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/Highlight-setlike-tampered-Set-prototype.html b/testing/web-platform/tests/css/css-highlight-api/Highlight-setlike-tampered-Set-prototype.html
new file mode 100644
index 0000000000..4c23f4850c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/Highlight-setlike-tampered-Set-prototype.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<title>Highlight is a setlike interface that works as expected even if Set.prototype is tampered</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script>
+"use strict";
+
+function tamperSetPrototype() {
+ delete Set.prototype.size;
+
+ Set.prototype.entries = null;
+ Set.prototype.forEach = undefined;
+ Set.prototype.has = "foo";
+ Set.prototype.keys = 0;
+ Set.prototype.values = Symbol();
+ Set.prototype[Symbol.iterator] = 1;
+ Set.prototype.add = true;
+ Set.prototype.clear = "";
+ Set.prototype.delete = -1.5;
+
+ Object.freeze(Set.prototype);
+}
+
+test(() => {
+ tamperSetPrototype();
+
+ const staticRange = new StaticRange({startContainer: document.body, endContainer: document.body, startOffset: 0, endOffset: 0});
+ const highlight = new Highlight(staticRange);
+
+ assert_equals(highlight.size, 1);
+ assert_true(highlight.has(staticRange));
+ assert_equals([...highlight.entries()][0][0], staticRange);
+
+ highlight.clear();
+ assert_equals(highlight.size, 0);
+
+ highlight.add(staticRange);
+ assert_equals(highlight.size, 1);
+
+ highlight.delete(staticRange);
+ assert_equals(highlight.size, 0);
+ assert_false(highlight.has(staticRange));
+
+ highlight.add(staticRange);
+ assert_equals([...highlight.keys()][0], staticRange);
+ assert_equals([...highlight.values()][0], staticRange);
+
+ let callbackCalled = false;
+ highlight.forEach(() => { callbackCalled = true; });
+ assert_true(callbackCalled);
+}, "Highlight is a setlike interface that works as expected even if Set.prototype is tampered.");
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/Highlight-setlike.html b/testing/web-platform/tests/css/css-highlight-api/Highlight-setlike.html
new file mode 100644
index 0000000000..0093f9be23
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/Highlight-setlike.html
@@ -0,0 +1,106 @@
+<!doctype html>
+<title> Highlight has a setlike interface </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id='testDiv'>abc</div>
+<script>
+ 'use strict';
+ let priority = 123;
+
+ test(() => {
+ let customHighlight = new Highlight();
+ assert_equals(customHighlight.priority, 0, 'Highlight uses 0 as priority by default.');
+
+ customHighlight.priority = priority;
+ assert_equals(customHighlight.priority, priority, 'Highlight sets priority correctly.');
+
+ assert_equals(customHighlight.size, 0, 'Highlight starts empty');
+ }, 'Highlight initializes empty (if no ranges are provided) and with priority 0.');
+
+ let range0 = new Range();
+ let range1 = new Range();
+ let range2 = new Range();
+
+ let container = document.getElementById('testDiv');
+ let staticRange0 = new StaticRange({startContainer: container, startOffset: 0, endContainer: container, endOffset: 0});
+ let staticRange1 = new StaticRange({startContainer: container, startOffset: 0, endContainer: container, endOffset: 0});
+ let staticRange2 = new StaticRange({startContainer: container, startOffset: 0, endContainer: container, endOffset: 0});
+
+ let rangeCollections = [[range0,range1,range2], [staticRange0,staticRange1,staticRange2], [range0,staticRange1,range2], [staticRange0,range1,staticRange2]]
+
+ var i;
+ for(i=0; i<rangeCollections.length; i++){
+ let rangesCombinationDescription = " (using the following combination of ranges [";
+ var j;
+ for(j=0; j<rangeCollections[i].length; j++){
+ if(j!=0) rangesCombinationDescription += ", ";
+ rangesCombinationDescription = rangesCombinationDescription + Object.prototype.toString.call(rangeCollections[i][j]);
+ }
+ rangesCombinationDescription += "])";
+
+ test(() => {
+ let customHighlight = new Highlight();
+ assert_false(customHighlight.has(rangeCollections[i][0]), 'Highlight.has returns false when it doesn\'t contain the range which is passed as the argument');
+ assert_false(customHighlight.has(rangeCollections[i][1]), 'Highlight.has returns false when it doesn\'t contain the range which is passed as the argument');
+ assert_false(customHighlight.has(rangeCollections[i][2]), 'Highlight.has returns false when it doesn\'t contain the range which is passed as the argument');
+ customHighlight.add(rangeCollections[i][0]);
+ assert_true(customHighlight.has(rangeCollections[i][0]), 'Highlight.has returns true when it contains the range which is passed as the argument');
+ assert_false(customHighlight.has(rangeCollections[i][1]), 'Highlight.has returns false when it doesn\'t contain the range which is passed as the argument');
+ assert_false(customHighlight.has(rangeCollections[i][2]), 'Highlight.has returns false when it doesn\'t contain the range which is passed as the argument');
+
+ assert_equals(customHighlight.size, 1, 'Highlight.size is 1 after only adding 1 range');
+ customHighlight.add(rangeCollections[i][0]);
+ assert_equals(customHighlight.size, 1, 'Highlight.size is 1 after only adding same range twice');
+
+ customHighlight.add(rangeCollections[i][1]);
+ assert_true(customHighlight.has(rangeCollections[i][0]), 'Highlight.has returns true when it contains the range which is passed as the argument');
+ assert_true(customHighlight.has(rangeCollections[i][1]), 'Highlight.has returns true when it contains the range which is passed as the argument');
+ assert_false(customHighlight.has(rangeCollections[i][2]), 'Highlight.has returns false when it doesn\'t contain the range which is passed as the argument');
+
+ assert_equals(customHighlight.size, 2, 'Highlight.size is 2 after only adding two different ranges');
+ }, 'Highlight add and has methods work as expected' + rangesCombinationDescription);
+
+ test(() => {
+ let customHighlight = new Highlight(rangeCollections[i][0], rangeCollections[i][1]);
+ assert_false(customHighlight.delete(rangeCollections[i][2]), 'Highlight.delete returns false when trying to delete a range that is not in the highlight');
+ assert_true(customHighlight.delete(rangeCollections[i][1]), 'Highlight.delete returns true when trying to delete a range that is in the highlight');
+ assert_false(customHighlight.delete(rangeCollections[i][1]), 'Highlight.delete returns false when trying to delete a range that was in the highlight before but it\'s not there anymore');
+ assert_true(customHighlight.delete(rangeCollections[i][0]), 'Highlight.delete returns true when trying to delete a range that is in the highlight');
+ assert_false(customHighlight.delete(rangeCollections[i][0]), 'Highlight.delete returns false when trying to delete a range that was in the highlight before but it\'s not there anymore');
+ }, 'Highlight delete method works as expected' + rangesCombinationDescription);
+
+ test(() => {
+ let customHighlight = new Highlight(rangeCollections[i][0], rangeCollections[i][0]);
+ assert_true(customHighlight.has(rangeCollections[i][0]), 'Highlight.has returns true when it is called with the range used twice in the constructor');
+ assert_equals(customHighlight.size, 1, 'Highlight behaves like a set when constructing it with two equal ranges.');
+
+ customHighlight = new Highlight(rangeCollections[i][0], rangeCollections[i][1], rangeCollections[i][0], rangeCollections[i][1]);
+ assert_true(customHighlight.has(rangeCollections[i][0]), 'Highlight.has returns true when it is called with one of the ranges used twice in the constructor');
+ assert_true(customHighlight.has(rangeCollections[i][1]), 'Highlight.has returns true when it is called with the other range used twice in the constructor');
+ assert_equals(customHighlight.size, 2, 'Highlight behaves like a set when constructing it with two pairs of equal ranges.');
+ }, 'Highlight constructor behaves like a set when using equal ranges' + rangesCombinationDescription);
+
+ test(() => {
+ let customHighlight = new Highlight(rangeCollections[i][0]);
+ assert_true(customHighlight.has(rangeCollections[i][0]), 'Highlight.has returns true when it is called with the range used in its constructor');
+ assert_equals(customHighlight.size, 1, 'Highlight.size is 1 after constructing it with one range');
+ }, 'Highlight constructor works as expected when called with one range' + rangesCombinationDescription);
+
+ test(() => {
+ let customHighlight = new Highlight(rangeCollections[i][0], rangeCollections[i][1]);
+ assert_true(customHighlight.has(rangeCollections[i][0]), 'Highlight.has returns true when it is called with the first range used in its constructor');
+ assert_true(customHighlight.has(rangeCollections[i][1]), 'Highlight.has returns true when it is called with the second range used in its constructor');
+ assert_equals(customHighlight.size, 2, 'Highlight.size is 2 after constructing it with two ranges');
+ }, 'Highlight constructor works as expected when called with two ranges' + rangesCombinationDescription);
+
+ test(() => {
+ let customHighlight = new Highlight(rangeCollections[i][0], rangeCollections[i][1]);
+ assert_equals(customHighlight.size, 2, 'Highlight has size 2 after constructing it with two ranges');
+ customHighlight.clear();
+ assert_equals(customHighlight.size, 0, 'Highlight becomes empty after executing clear()');
+ customHighlight.clear();
+ assert_equals(customHighlight.size, 0, 'Highlight is still empty after executing clear() twice');
+ }, 'Highlight clear method works as expected' + rangesCombinationDescription);
+ }
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/Highlight-type-attribute.tentative.html b/testing/web-platform/tests/css/css-highlight-api/Highlight-type-attribute.tentative.html
new file mode 100644
index 0000000000..97e3aaa3ca
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/Highlight-type-attribute.tentative.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title> Highlight type attribute tests </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ test(() => {
+ let customHighlight = new Highlight();
+ assert_equals(customHighlight.type, "highlight", 'Highlight uses \"highlight\" as default type.');
+
+ customHighlight.type = "type-not-listed-in-HighlightType-enum";
+ assert_equals(customHighlight.type, "highlight", 'Highlight type doesn\'t change after assigning an invalid value.');
+
+ customHighlight.type = "spelling-error";
+ assert_equals(customHighlight.type, "spelling-error", 'Highlight type changes to the assigned value if it\'s part of the HighlightType enum (\"spelling-error\"").');
+
+ customHighlight.type = "grammar-error";
+ assert_equals(customHighlight.type, "grammar-error", 'Highlight type changes to the assigned value if it\'s part of the HighlightType enum (\"grammar-error\").');
+ }, 'Highlight has a mutable \'type\' attribute that is a HighlightType enum.');
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration-with-modifications.html b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration-with-modifications.html
new file mode 100644
index 0000000000..7e1a0c08f3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration-with-modifications.html
@@ -0,0 +1,109 @@
+<!doctype html>
+<title>HighlightRegistry iteration with insertions and deletions inbetween</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ 'use strict';
+ let customHighlight1 = new Highlight();
+ let customHighlight2 = new Highlight();
+ let highlightName1 = "example1";
+ let highlightName2 = "example2";
+
+ // Test insertions using .add
+ test(() => {
+ let iterator = CSS.highlights[Symbol.iterator]();
+ CSS.highlights.set(highlightName1, customHighlight1);
+ let element = iterator.next();
+ assert_true(element.done, 'The iteration ends although we added a new Highlight after starting the iteration');
+ assert_equals(element.value, undefined, 'A Highlight added after starting the iteration is not found during the current iteration');
+ }, 'HighlightRegistry iteration is not modified when a new Highlight is added after starting the iteration');
+
+ CSS.highlights.clear();
+
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ let iterator = CSS.highlights[Symbol.iterator]();
+ CSS.highlights.set(highlightName2, customHighlight2);
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end although there was a second Highlight added to the HighlightRegistry after starting the iteration');
+ assert_equals(element.value[0], highlightName1, 'The highlight name that was pointed to by the iterator is returned although a second Highlight was added after starting the iteration');
+ assert_equals(element.value[1], customHighlight1, 'The Highlight that was pointed to by the iterator is returned although a second Highlight was added after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the Highlights that were in the HighlightRegistry when the iteration started although there was a Highlight addition after starting the iteration');
+ assert_equals(element.value, undefined, 'A Highlight added after starting the iteration is not found during the current iteration');
+ }, 'HighlightRegistry iteration is not modified when a new Highlight is added after starting the iteration with one Highlight in the HighlightRegistry');
+
+ CSS.highlights.clear();
+
+ // Test deletions using .delete
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ let iterator = CSS.highlights[Symbol.iterator]();
+ CSS.highlights.delete(highlightName1);
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end although the Highlight that was pointed to by the iterator was deleted');
+ assert_equals(element.value[0], highlightName1, 'The highlight name that was pointed to by the iterator is returned although it was deleted after starting the iteration');
+ assert_equals(element.value[1], customHighlight1, 'The Highlight that was pointed to by the iterator is returned although it was deleted after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the highlights although the Highlight that was pointed to by the iterator was deleted after starting the iteration');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'HighlightRegistry iteration is not modified when the Highlight that was pointed to by the iterator was deleted after starting the iteration');
+
+ CSS.highlights.clear();
+
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ CSS.highlights.set(highlightName2, customHighlight2);
+ let iterator = CSS.highlights[Symbol.iterator]();
+ CSS.highlights.delete(highlightName2);
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end although the Highlight following to the one that was pointed to by the iterator was deleted');
+ assert_equals(element.value[0], highlightName1, 'The highlight name that was pointed to by the iterator is returned as it should although the next Highlight was deleted immediately after starting the iteration');
+ assert_equals(element.value[1], customHighlight1, 'The Highlight that was pointed to by the iterator is returned as it should although the next Highlight was deleted immediately after starting the iteration');
+ element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end when you call .next twice since the beginning of the iteration although the second Highlight was deleted');
+ assert_equals(element.value[0], highlightName2, 'The highlight name that was pointed to by the iterator is returned as it should although the next Highlight was deleted immediately after starting the iteration');
+ assert_equals(element.value[1], customHighlight2, 'The Highlight that was pointed to by the iterator is returned as it should although the next Highlight was deleted immediately after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the highlights although the second Highlight was deleted immediately after starting the iteration');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'HighlightRegistry iteration is not modified when the Highlight that was immediately after the one pointed to by the iterator was deleted after starting the iteration');
+
+ CSS.highlights.clear();
+
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ CSS.highlights.set(highlightName2, customHighlight2);
+ let iterator = CSS.highlights[Symbol.iterator]();
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end when there are still two Highlights to visit');
+ assert_equals(element.value[0], highlightName1, 'The highlight name that was pointed to by the iterator is returned as it should');
+ assert_equals(element.value[1], customHighlight1, 'The Highlight that was pointed to by the iterator is returned as it should');
+ CSS.highlights.delete(highlightName1);
+ element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end when the Highlight previously visited is deleted and there is still a Highlight to visit');
+ assert_equals(element.value[0], highlightName2, 'The highlight name that was pointed to by the iterator is returned as it should although the previous Highlight was deleted after calling .next');
+ assert_equals(element.value[1], customHighlight2, 'The Highlight that was pointed to by the iterator is returned as it should although the previous Highlight was deleted after calling .next');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the highlights although the first Highlight was deleted after the first call to .next');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'HighlightRegistry iteration is not modified when a Highlight that was already visited is deleted and there are still Highlights to visit');
+
+ CSS.highlights.clear();
+
+ // Test deletions using .clear
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ let iterator = CSS.highlights[Symbol.iterator]();
+ CSS.highlights.clear();
+ let element = iterator.next();
+ assert_false(element.done, 'The iteration doesn\'t end although the Highlight that was pointed to by the iterator was deleted using .clear()');
+ assert_equals(element.value[0], highlightName1, 'The highlight name that was pointed to by the iterator is returned although it was deleted using .clear() after starting the iteration');
+ assert_equals(element.value[1], customHighlight1, 'The Highlight that was pointed to by the iterator is returned although it was deleted using .clear() after starting the iteration');
+ element = iterator.next();
+ assert_true(element.done, 'The iteration ends after going through all the highlights although the Highlight that was pointed to by the iterator was deleted using .clear() after starting the iteration');
+ assert_equals(element.value, undefined, '.next() returns undefined when the iteration ends');
+ }, 'HighlightRegistry iteration is not modified when the Highlight that was pointed to by the iterator was deleted using .clear() after starting the iteration');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration.html b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration.html
new file mode 100644
index 0000000000..b1bc1afecb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-iteration.html
@@ -0,0 +1,186 @@
+<!doctype html>
+<title>HighlightRegistry iteration</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ 'use strict';
+ let customHighlight1 = new Highlight();
+ let customHighlight2 = new Highlight();
+ let highlightName1 = "example1";
+ let highlightName2 = "example2";
+
+ function getIterator(iterationInitialization){
+ var iterator;
+ if(iterationInitialization === "CSS.highlights[Symbol.iterator]()"){
+ iterator = CSS.highlights[Symbol.iterator]();
+ }
+ else if(iterationInitialization === "CSS.highlights.entries()"){
+ iterator = CSS.highlights.entries();
+ }
+ else if(iterationInitialization === "CSS.highlights.values()"){
+ iterator = CSS.highlights.values();
+ }
+ else if(iterationInitialization === "CSS.highlights.keys()"){
+ iterator = CSS.highlights.keys();
+ }
+ return iterator;
+ }
+
+
+ // Test .keys()
+
+ let iterationInitialization = "CSS.highlights.keys()";
+ test(() => {
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlight names to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlight names to iterate.');
+ }, 'HighlightRegistry can be iterated when it\'s empty initializing the iterator with ' + iterationInitialization);
+
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight name');
+ assert_equals(element.value, highlightName1, '.next() returns an element with .value corresponding to the first highlight name added to the HighlightRegistry');
+ element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlight names to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlight names to iterate.');
+ }, 'HighlightRegistry can be iterated over all of its highlight names after adding one of them initializing the iterator with ' + iterationInitialization);
+
+ test(() => {
+ CSS.highlights.set(highlightName2, customHighlight2);
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value, highlightName1, '.next() returns an element with .value corresponding to the first highlight name added to the HighlightRegistry');
+ element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value, highlightName2, '.next() returns an element with .value corresponding to the second highlight name added to the HighlightRegistry');
+ element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlight names to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlight names to iterate.');
+ }, 'HighlightRegistry can be iterated over all of its highlight names after adding two of them initializing the iterator with ' + iterationInitialization);
+
+ CSS.highlights.clear();
+
+
+ // Test .values()
+
+ iterationInitialization = "CSS.highlights.values()";
+ test(() => {
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlights to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlights to iterate.');
+ }, 'HighlightRegistry can be iterated when it\'s empty initializing the iterator with ' + iterationInitialization);
+
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value, customHighlight1, '.next() returns an element with .value corresponding to the first Highlight added to the HighlightRegistry');
+ element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlights to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlights to iterate.');
+ }, 'HighlightRegistry can be iterated over all of its Highlights after adding one of them initializing the iterator with ' + iterationInitialization);
+
+ test(() => {
+ CSS.highlights.set(highlightName2, customHighlight2);
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value, customHighlight1, '.next() returns an element with .value corresponding to the first Highlight added to the HighlightRegistry');
+ element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value, customHighlight2, '.next() returns an element with .value corresponding to the second Highlight added to the HighlightRegistry');
+ element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlights to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlights to iterate.');
+ }, 'HighlightRegistry can be iterated over all of its Highlights after adding two of them initializing the iterator with ' + iterationInitialization);
+
+ CSS.highlights.clear();
+
+
+ // Test [Symbol.iterator]() and .entries()
+
+ let iterationInitializationCollection = ["CSS.highlights[Symbol.iterator]()", "CSS.highlights.entries()"];
+ for(let iterationInitialization of iterationInitializationCollection){
+ test(() => {
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlights to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlights to iterate.');
+ }, 'HighlightRegistry can be iterated when it\'s empty initializing the iterator with ' + iterationInitialization);
+
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value[0], highlightName1, '.next() returns an element with .value[0] corresponding to the first Highlight name added to the HighlightRegistry');
+ assert_equals(element.value[1], customHighlight1, '.next() returns an element with .value[1] corresponding to the first Highlight added to the HighlightRegistry');
+ element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlights to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlights to iterate.');
+ }, 'HighlightRegistry can be iterated over all of its Highlights after adding one of them initializing the iterator with ' + iterationInitialization);
+
+ test(() => {
+ CSS.highlights.set(highlightName2, customHighlight2);
+ let iterator = getIterator(iterationInitialization);
+ let element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value[0], highlightName1, '.next() returns an element with .value[0] corresponding to the first Highlight name added to the HighlightRegistry');
+ assert_equals(element.value[1], customHighlight1, '.next() returns an element with .value[1] corresponding to the first Highlight added to the HighlightRegistry');
+ element = iterator.next();
+ assert_false(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===false when the iteration didn\'t go past the last highlight');
+ assert_equals(element.value[0], highlightName2, '.next() returns an element with .value[0] corresponding to the second Highlight name added to the HighlightRegistry');
+ assert_equals(element.value[1], customHighlight2, '.next() returns an element with .value[1] corresponding to the second Highlight added to the HighlightRegistry');
+ element = iterator.next();
+ assert_true(element.done, 'HighlightRegistry is iterable and .next() returns an element with .done===true when there are no more highlights to iterate');
+ assert_equals(element.value, undefined, 'HighlightRegistry is iterable and .next() returns an element with .value undefined when there are no more highlights to iterate.');
+ }, 'HighlightRegistry can be iterated over all of its Highlights after adding two of them initializing the iterator with ' + iterationInitialization);
+
+ CSS.highlights.clear();
+ }
+
+
+ // Test .forEach
+
+ function compareArrays(array1, array2){
+ if(array1.length != array2.length){
+ return false;
+ }
+ for(let index=0; index<array1.length; ++index){
+ if(array1[index] != array2[index])
+ return false;
+ }
+ return true;
+ }
+
+ let expectedResult = [];
+
+ test(() => {
+ let actualResult = [];
+ CSS.highlights.forEach((highlight) => {actualResult.push(highlight);});
+ assert_true(compareArrays(actualResult, expectedResult), 'The highlights seen match the highlights added');
+ }, 'HighlightRegistry can be iterated through when it\'s empty using forEach.');
+
+ test(() => {
+ CSS.highlights.set(highlightName1, customHighlight1);
+ expectedResult.push(customHighlight1);
+ let actualResult = [];
+ CSS.highlights.forEach((highlight) => {actualResult.push(highlight);});
+ assert_true(compareArrays(actualResult, expectedResult), 'The highlights seen match the highlights added');
+ }, 'HighlightRegistry can be iterated through when it has one Highlight using forEach.');
+
+ test(() => {
+ CSS.highlights.set(highlightName2, customHighlight2);
+ expectedResult.push(customHighlight2);
+ let actualResult = [];
+ CSS.highlights.forEach((highlight) => {actualResult.push(highlight);});
+ assert_true(compareArrays(actualResult, expectedResult), 'The highlights seen match the highlights added');
+ }, 'HighlightRegistry can be iterated through when it has two Highlights using forEach.');
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike-tampered-Map-prototype.html b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike-tampered-Map-prototype.html
new file mode 100644
index 0000000000..3b38bd8f16
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike-tampered-Map-prototype.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<title>HighlightRegistry is a maplike interface that works as expected even if Map.prototype is tampered</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script>
+"use strict";
+
+function tamperMapPrototype() {
+ delete Map.prototype.size;
+
+ Map.prototype.entries = null;
+ Map.prototype.forEach = undefined;
+ Map.prototype.get = "foo";
+ Map.prototype.has = 0;
+ Map.prototype.keys = Symbol();
+ Map.prototype.values = 1;
+ Map.prototype[Symbol.iterator] = true;
+ Map.prototype.clear = false;
+ Map.prototype.delete = "";
+ Map.prototype.set = 3.14;
+
+ Object.freeze(Map.prototype);
+}
+
+test(() => {
+ tamperMapPrototype();
+
+ const highlight = new Highlight(new StaticRange({startContainer: document.body, endContainer: document.body, startOffset: 0, endOffset: 0}));
+ const highlightRegister = new HighlightRegister();
+
+ assert_equals(highlightRegister.size, 0);
+ highlightRegister.set("foo", highlight);
+ assert_equals(highlightRegister.size, 1);
+
+ assert_true(highlightRegister.has("foo"));
+ assert_equals([...highlightRegister.entries()][0][0], "foo");
+
+ highlightRegister.clear();
+ assert_equals(highlightRegister.size, 0);
+ assert_equals(highlightRegister.get("foo"), undefined);
+
+ highlightRegister.set("bar", highlight);
+ assert_equals(highlightRegister.get("bar"), highlight);
+ assert_equals([...highlightRegister][0][1], highlight);
+
+ highlightRegister.delete("bar");
+ assert_equals(highlightRegister.size, 0);
+ assert_false(highlightRegister.has("bar"));
+
+ highlightRegister.set("baz", highlight);
+ assert_equals([...highlightRegister.keys()][0], "baz");
+ assert_equals([...highlightRegister.values()][0], highlight);
+
+ let callbackCalled = false;
+ highlightRegister.forEach(() => { callbackCalled = true; });
+ assert_true(callbackCalled);
+}, "HighlightRegistry is a maplike interface that works as expected even if Map.prototype is tampered.");
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike.html b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike.html
new file mode 100644
index 0000000000..d8bbe4731f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/HighlightRegistry-maplike.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<title>HighlightRegistry has a maplike interface</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ 'use strict';
+
+ test(() => {
+ assert_not_equals(window.HighlightRegistry, undefined, 'HighlightRegistry is in window');
+ assert_equals(typeof HighlightRegistry, 'function', 'HighlightRegistry is a function');
+ assert_throws_js(TypeError, function () { var x = new HighlightRegistry(); },
+ 'HighlightRegistry constructor throws');
+
+ assert_not_equals(CSS.highlights, undefined, 'CSS.highlights exists');
+ assert_equals(CSS.highlights.__proto__, window.HighlightRegistry.prototype,
+ 'CSS.highlights and window.HighlightRegistry have same prototype');
+
+ assert_equals(CSS.highlights.size, 0, 'HighlightRegistry starts empty');
+ }, 'HighlightRegistry initializes as it should.');
+
+ test(() => {
+ let name1 = "example1";
+ let name2 = "example2";
+ let h1 = new Highlight();
+ let h2 = new Highlight();
+
+ assert_false(CSS.highlights.has(name1), 'HighlightRegistry.has returns false when it doesn\'t have the key which is called with as argument.');
+ CSS.highlights.set(name1, h1);
+ assert_true(CSS.highlights.has(name1), 'HighlightRegistry.has returns true when it has the key which is called with as argument.');
+ assert_equals(CSS.highlights.size, 1, 'HighlightRegistry.size is 1 after only inserting 1 key.');
+
+ assert_false(CSS.highlights.delete(name2), 'HighlightRegistry.delete returns false when trying to delete an key that is not in the map.');
+ assert_equals(CSS.highlights.size, 1, 'HighlightRegistry.size stays the same after trying to delete a non-existing key.');
+
+ CSS.highlights.set(name2, h2);
+ assert_true(CSS.highlights.has(name1), 'HighlightRegistry.has returns true when it is called with the key inserted first');
+ assert_true(CSS.highlights.has(name2), 'HighlightRegistry.has returns true when it is called with the key inserted second');
+ assert_equals(CSS.highlights.get(name1), h1, 'HighlightRegistry.get returns the first Highlight when it is called with the key inserted first');
+ assert_equals(CSS.highlights.get(name2), h2, 'HighlightRegistry.get returns the second Highlight when it is called with the key inserted second');
+ assert_equals(CSS.highlights.size, 2, 'HighlightRegistry.size is 2 after only inserting two different keys.');
+
+ assert_true(CSS.highlights.delete(name2), 'HighlightRegistry.delete returns true when trying to delete a key that is in the group.');
+ assert_true(CSS.highlights.has(name1), 'HighlightRegistry.has returns true when it is called with the key inserted first');
+ assert_false(CSS.highlights.has(name2), 'HighlightRegistry.has returns true when it is called with the key that was deleted');
+ assert_equals(CSS.highlights.get(name1), h1, 'HighlightRegistry.get still returns the first Highlight when it is called with the key inserted first');
+ assert_equals(CSS.highlights.get(name2), undefined, 'HighlightRegistry.get returns undefined when it is called with a key that was deleted');
+ assert_equals(CSS.highlights.size, 1, 'HighlightRegistry.size decreases in 1 after deleting an existing key.');
+
+ assert_false(CSS.highlights.delete(name2), 'HighlightRegistry.delete returns false when trying to delete a key that was already deleted.');
+ assert_true(CSS.highlights.has(name1), 'HighlightRegistry.has returns true when it is called with the key inserted first');
+ assert_false(CSS.highlights.has(name2), 'HighlightRegistry.has returns false when it is called with a key that was deleted twice');
+ assert_equals(CSS.highlights.get(name1), h1, 'HighlightRegistry.get still returns the first Highlight when it is called with the key inserted first');
+ assert_equals(CSS.highlights.get(name2), undefined, 'HighlightRegistry.get still returns undefined when it is called with a key that was deleted');
+ assert_equals(CSS.highlights.size, 1, 'HighlightRegistry.size stays the same after trying to delete the same key for a second time.');
+
+ assert_true(CSS.highlights.delete(name1), 'HighlightRegistry.delete returns true when trying to delete the remaining key');
+ assert_false(CSS.highlights.has(name1), 'HighlightRegistry.has returns false when it is called with the key inserted first and then deleted');
+ assert_false(CSS.highlights.has(name2), 'HighlightRegistry.has returns false when it is called with the key inserted second and then deleted');
+ assert_equals(CSS.highlights.get(name1), undefined, 'HighlightRegistry.get returns undefined when it is called with a key that was deleted');
+ assert_equals(CSS.highlights.get(name2), undefined, 'HighlightRegistry.get returns undefined when it is called with a key that was deleted');
+ assert_equals(CSS.highlights.size, 0, 'HighlightRegistry.size decreases in 1 after deleting an existing key.');
+
+ CSS.highlights.set(name1, h1);
+ CSS.highlights.set(name1, h2);
+ assert_equals(CSS.highlights.size, 1, 'HighlightRegistry.size keeps the same after an insertion of a Highlight with an existing name');
+ assert_equals(CSS.highlights.get(name1), h2, 'The Highlight inserted with the same name as an existing one was effectively inserted into the registry');
+
+ CSS.highlights.clear();
+ assert_equals(CSS.highlights.size, 0, 'HighlightRegistry.clear empties the map.');
+ CSS.highlights.clear();
+ assert_equals(CSS.highlights.size, 0, 'HighlightRegistry.clear called with an empty registry keeps it empty.');
+ }, 'HighlightRegistry has a maplike interface.');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting-ref.html b/testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting-ref.html
new file mode 100644
index 0000000000..1865f1e104
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Highlight priority attribute painting</title>
+ <style>
+ #green-highlight {
+ background-color: green;
+ }
+ .yellow-highlight {
+ background-color: yellow;
+ }
+ .blue-highlight {
+ background-color: blue;
+ }
+ </style>
+</head>
+<body>
+ <span id="green-highlight">Green</span>
+ <span class="yellow-highlight">Yellow</span>
+ <span class="blue-highlight">Blue</span>
+ <span class="yellow-highlight">Yellow</span><span class="blue-highlight">-Blue</span>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting.html b/testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting.html
new file mode 100644
index 0000000000..89ae873592
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/highlight-priority-painting.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Highlight priority attribute painting correctness</title>
+ <link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/#priorities">
+ <link rel="match" href="highlight-priority-painting-ref.html">
+ <style>
+ ::highlight(yellow-highlight) {
+ background-color: yellow;
+ }
+ ::highlight(green-highlight) {
+ background-color: green;
+ }
+ ::highlight(blue-highlight) {
+ background-color: blue;
+ }
+ </style>
+</head>
+<body>
+ <span id="green-highlight">Green</span>
+ <span id="yellow-highlight">Yellow</span>
+ <span id="blue-highlight">Blue</span>
+ <span id="yellow-blue-highlight">Yellow-Blue</span>
+
+ <script>
+ let yellowBlue = document.getElementById("yellow-blue-highlight");
+ let green = document.getElementById("green-highlight");
+ let highlightGreen = new Highlight(new StaticRange({
+ startContainer: green.childNodes[0],
+ startOffset: 0,
+ endContainer: green.childNodes[0],
+ endOffset: 5
+ }));
+ let yellow = document.getElementById("yellow-highlight");
+ let highlightYellow = new Highlight(new StaticRange({
+ startContainer: yellow.childNodes[0],
+ startOffset: 0,
+ endContainer: yellow.childNodes[0],
+ endOffset: 6
+ }), new StaticRange({
+ startContainer: yellowBlue.childNodes[0],
+ startOffset: 0,
+ endContainer: yellowBlue.childNodes[0],
+ endOffset: 6
+ }));
+ let blue = document.getElementById("blue-highlight");
+ let highlightBlue = new Highlight(new StaticRange({
+ startContainer: blue.childNodes[0],
+ startOffset: 0,
+ endContainer: blue.childNodes[0],
+ endOffset: 4
+ }), new StaticRange({
+ startContainer: yellowBlue.childNodes[0],
+ startOffset: 0,
+ endContainer: yellowBlue.childNodes[0],
+ endOffset: 11
+ }));
+ CSS.highlights.set("yellow-highlight", highlightYellow);
+ CSS.highlights.set("green-highlight", highlightGreen);
+ CSS.highlights.set("blue-highlight", highlightBlue);
+ highlightYellow.priority = 10;
+ highlightBlue.priority = -1;
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/highlight-priority.html b/testing/web-platform/tests/css/css-highlight-api/highlight-priority.html
new file mode 100644
index 0000000000..ac0ef8a6cd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/highlight-priority.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Highlight priority attribute is mutable</title>
+ <link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/#priorities">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ ::highlight(yellow-highlight) {
+ background-color: yellow;
+ }
+ ::highlight(green-highlight) {
+ background-color: green;
+ }
+ ::highlight(blue-highlight) {
+ background-color: blue;
+ }
+ </style>
+</head>
+<body>
+ <span id="green-highlight">Green</span>
+ <span id="yellow-highlight">Yellow</span>
+ <span id="blue-highlight">Blue</span>
+ <span id="yellow-blue-highlight">Yellow-Blue</span>
+
+ <script>
+ test(() => {
+ let yellowBlue = document.getElementById("yellow-blue-highlight");
+
+ let green = document.getElementById("green-highlight");
+ let highlightGreen = new Highlight(new StaticRange({
+ startContainer: green.childNodes[0],
+ startOffset: 0,
+ endContainer: green.childNodes[0],
+ endOffset: 6
+ }));
+
+ let yellow = document.getElementById("yellow-highlight");
+ let highlightYellow = new Highlight(new StaticRange({
+ startContainer: yellow.childNodes[0],
+ startOffset: 0,
+ endContainer: yellow.childNodes[0],
+ endOffset: 6
+ }), new StaticRange({
+ startContainer: yellowBlue.childNodes[0],
+ startOffset: 0,
+ endContainer: yellowBlue.childNodes[0],
+ endOffset: 6
+ }));
+
+ let blue = document.getElementById("blue-highlight");
+ let highlightBlue = new Highlight(new StaticRange({
+ startContainer: blue.childNodes[0],
+ startOffset: 0,
+ endContainer: blue.childNodes[0],
+ endOffset: 4
+ }), new StaticRange({
+ startContainer: yellowBlue.childNodes[0],
+ startOffset: 0,
+ endContainer: yellowBlue.childNodes[0],
+ endOffset: 11
+ }));
+
+ CSS.highlights.set("yellow-highlight", highlightYellow);
+ CSS.highlights.set("green-highlight", highlightGreen);
+ CSS.highlights.set("blue-highlight", highlightBlue);
+
+ highlightYellow.priority = 10;
+ highlightBlue.priority = -1;
+
+ assert_equals(highlightYellow.priority, 10);
+ assert_equals(highlightGreen.priority, 0);
+ assert_equals(highlightBlue.priority, -1);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-computed.html b/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-computed.html
new file mode 100644
index 0000000000..99212abc3e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-computed.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS ::highlight Pseudo-Element Test: ::highlight selector getComputedStyle</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #target::highlight(foo) {
+ background-color: green;
+ color: lime;
+ }
+
+ #target::highlight(bar) {
+ background-color: cyan;
+ color: fuchsia;
+ }
+</style>
+<div id="target"></div>
+<script>
+ let highlightPseudo = "::highlight(foo)";
+ test(() => {
+ let style = getComputedStyle(target, highlightPseudo);
+ assert_equals(style.backgroundColor, "rgb(0, 128, 0)", "Background color is green.");
+ assert_equals(style.color, "rgb(0, 255, 0)", "Color is lime.");
+ }, `getComputedStyle() for ${highlightPseudo}`);
+
+ highlightPseudo = "::highlight(bar)";
+ test(() => {
+ let style = getComputedStyle(target, highlightPseudo);
+ assert_equals(style.backgroundColor, "rgb(0, 255, 255)", "Background color is cyan.");
+ assert_equals(style.color, "rgb(255, 0, 255)", "Color is fuchsia.");
+ }, `Different getComputedStyle() for ${highlightPseudo} and same element`);
+
+ for (const illHighlightPseudo of ["::highlight(foo):", "::highlight(foo))", "::highlight(foo)(", "::highlight", "::highlight(foo)(foo)", "::highlight(foo)()", ":::highlight(foo)", "::highlight(foo).", "::highlight(foo,bar)", "::highlight(foo bar)"]) {
+ test(() => {
+ let style = getComputedStyle(target, illHighlightPseudo);
+ assert_equals(style.length, 0, "Invalid pseudo identifiers should not return a style.");
+ }, `getComputedStyle() for ${illHighlightPseudo} should not return a style.`);
+ }
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-from-font-computed.html b/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-from-font-computed.html
new file mode 100644
index 0000000000..7c436d95d1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-from-font-computed.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS ::highlight Pseudo-Element Test: ::highlight selector getComputedStyle</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<meta name="assert" value="Font relative units are correctly reported in getComputedStyle">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ :root {
+ font-size: 16px;
+ }
+ div {
+ margin: 40px;
+ font-size: 20px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ #h2::highlight(highlight1) {
+ text-underline-offset: 1.0em;
+ text-decoration-line: underline;
+ text-decoration-color: blue;
+ text-decoration-thickness: 0.125rem;
+ }
+</style>
+<div id="h1">A green 10px offset underline 4px thick</div>
+<div id="h2">A blue 20px offset underline 2px thick</div>
+<script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+
+ let highlightPseudo = "::highlight(highlight1)";
+ test(() => {
+ let style = getComputedStyle(document.documentElement, highlightPseudo);
+ assert_equals(style.textUnderlineOffset, "8px", "Text underline offset is 8px.");
+ assert_equals(style.textDecorationThickness, "4px", "Text decoration thickness is 4px.");
+ }, `getComputedStyle() for root element`);
+
+ test(() => {
+ let style = getComputedStyle(h1, highlightPseudo);
+ assert_equals(style.textUnderlineOffset, "10px", "Text underline offset is 10px.");
+ assert_equals(style.textDecorationThickness, "4px", "Text decoration thickness is 4px.");
+ }, `getComputedStyle() for root highlight applied to div`);
+
+ test(() => {
+ let style = getComputedStyle(h2, highlightPseudo);
+ assert_equals(style.textUnderlineOffset, "20px", "Text underline offset is 20px.");
+ assert_equals(style.textDecorationThickness, "2px", "Text decoration thickness is 2px.");
+ }, `getComputedStyle() for div specific highlight`);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-parsing.html b/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-parsing.html
new file mode 100644
index 0000000000..1c7de5bd28
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/highlight-pseudo-parsing.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS ::highlight Pseudo-Element Test: ::highlight selector parsing</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<script>
+ const pseudo = "::highlight(foo)";
+ test_valid_selector(pseudo);
+ test_valid_selector(`.a${pseudo}`);
+ test_valid_selector(`div ${pseudo}`);
+ test_valid_selector(`::part(my-part)${pseudo}`);
+
+ test_invalid_selector("::highlight");
+ test_invalid_selector(`::before${pseudo}`);
+ test_invalid_selector(`${pseudo}.a`);
+ test_invalid_selector(`${pseudo} div`);
+ test_invalid_selector(`${pseudo}::after`);
+ test_invalid_selector(`${pseudo}:hover`);
+ test_invalid_selector(`:not(${pseudo})`);
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/idlharness.window.js b/testing/web-platform/tests/css/css-highlight-api/idlharness.window.js
new file mode 100644
index 0000000000..7e9f3c4404
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/idlharness.window.js
@@ -0,0 +1,17 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+
+// https://drafts.csswg.org/css-highlight-api-1/
+
+'use strict';
+
+idl_test(
+ ['css-highlight-api'],
+ ['cssom'],
+ idl_array => {
+ idl_array.add_objects({
+ Highlight: ['new Highlight(new Range())'],
+ HighlightRegistry: ['CSS.highlights'],
+ });
+ }
+);
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001-ref.html
new file mode 100644
index 0000000000..3d01bccf55
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::highlight with text-underline-offset, reference</title>
+<style>
+ #target {
+ text-decoration: wavy underline green 5px;
+ text-underline-offset: 20px;
+ }
+</style>
+<p id="target">The underline should be offset.</p>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001.html
new file mode 100644
index 0000000000..534438089c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/css-highlight-painting-underline-offset-001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::highlight with text-underline-offset</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="css-highlight-painting-underline-offset-001-ref.html">
+<meta name="assert" content="Verify that text-underline-offset works in a ::highlight pseudo-element.">
+<meta name="fuzzy" content="0-56;0-10">
+<style>
+ ::highlight(example) {
+ text-decoration: wavy underline green 5px;
+ text-underline-offset: 20px;
+ }
+</style>
+<p id="target">The underline should be offset.</p>
+<script>
+ let range = new Range();
+ range.setStart(target, 0);
+ range.setEnd(target, 1);
+ CSS.highlights.set(`example`, new Highlight(range));
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001-ref.html
new file mode 100644
index 0000000000..5e9ef64579
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::target-text text-decoration - reference</title>
+<style>
+ #target-text {
+ text-decoration: wavy underline overline green 5px;
+ text-underline-offset: 20px;
+ }
+ div {
+ border: solid 1px black;
+ padding: 50px;
+ }
+</style>
+<div id="upper">The word <span id="target-text">remain</span> has under/over lines.</div>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001.html
new file mode 100644
index 0000000000..fa76c0bc4e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/css-target-text-decoration-001.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::target-text text-decoration</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="css-target-text-decoration-001-ref.html">
+<meta name="assert" content="This test checks that text-decorations of target text are fully rendered.">
+<meta name="fuzzy" content="0-60;0-32">
+<script src="/common/reftest-wait.js"></script>
+<style>
+ ::target-text {
+ text-decoration: wavy underline overline green 5px;
+ text-underline-offset: 20px;
+ background-color: transparent;
+ }
+ div {
+ border: solid 1px black;
+ padding: 50px;
+ }
+</style>
+<div id="upper">The word remain has under/over lines.</div>
+<script>
+ window.location.href = `css-target-text-decoration-001.html#:~:text=remain`;
+ requestAnimationFrame(() => takeScreenshot());
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001-ref.html
new file mode 100644
index 0000000000..92751144a2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test Reference</title>
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 100px;
+ }
+ #h1 {
+ text-underline-offset: 1svw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 2svh;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">With container size</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001.html
new file mode 100644
index 0000000000..1e22dcc992
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-001.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-001-ref.html">
+<meta name="assert" value="lengths depending on containers take the correct values in a universal highlight with no container">
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 100px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 1cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 2cqh;
+ }
+</style>
+</head>
+<body>
+ <div id="h1">With container size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1));
+ </script>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002-ref.html
new file mode 100644
index 0000000000..98ccfa5b11
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test Reference</title>
+<head>
+ <style>
+ .wrapper {
+ width: 200px;
+ height: 100px;
+ text-underline-offset: 4px;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ #h2 {
+ text-underline-offset: 2svw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4svh;
+ }
+ </style>
+</head>
+<body>
+ <div class="wrapper">With container size</div>
+ <div id="h2">Without container size</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002.html
new file mode 100644
index 0000000000..0a805cf7ea
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-002-ref.html">
+<meta name="assert" value="lengths depending on containers take the correct values inside and outside a container">
+<meta name="fuzzy" content="0-60;0-25">
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 200px;
+ height: 100px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+</style>
+</head>
+<body>
+ <div class="wrapper">
+ <div id="h1">With container size</div>
+ </div>
+ <div id="h2">Without container size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003-ref.html
new file mode 100644
index 0000000000..d3d75333f8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test Reference</title>
+<head>
+ <style>
+ .wrapper {
+ width: 200px;
+ height: 100px;
+ text-underline-offset: 4px;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ </style>
+</head>
+<body>
+ <div class="wrapper">With container size</div>
+ <div>Should be no highlight</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003.html
new file mode 100644
index 0000000000..189db49bd3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-003.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-003-ref.html">
+<meta name="assert" value="lengths depending on containers take the correct values and a highlight defined inside the container renders only within the container">
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 200px;
+ height: 100px;
+ }
+ @container (width > 100px) {
+ ::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+ }
+ </style>
+</head>
+<body>
+ <div class="wrapper">
+ <div id="h1">With container size</div>
+ </div>
+ <div id="h2">Should be no highlight</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004-ref.html
new file mode 100644
index 0000000000..98ccfa5b11
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test Reference</title>
+<head>
+ <style>
+ .wrapper {
+ width: 200px;
+ height: 100px;
+ text-underline-offset: 4px;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ #h2 {
+ text-underline-offset: 2svw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4svh;
+ }
+ </style>
+</head>
+<body>
+ <div class="wrapper">With container size</div>
+ <div id="h2">Without container size</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004.html
new file mode 100644
index 0000000000..158f4ee12c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-004.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-004-ref.html">
+<meta name="assert" value="lengths depending on containers take the correct values inside and outside a container">
+<meta name="fuzzy" content="0-60;0-25">
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 200px;
+ height: 100px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+</style>
+</head>
+<body>
+ <div class="wrapper">
+ <div>
+ <div id="h1">With container size</div>
+ </div>
+ </div>
+ <div id="h2">Without container size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-005.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-005.html
new file mode 100644
index 0000000000..d7be78d1fd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-005.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-003-ref.html">
+<meta name="assert" value="a highlight on a container itself renders at the correct size">
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 200px;
+ height: 100px;
+ }
+ @container (width > 100px) {
+ .wrapper::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+ }
+ </style>
+</head>
+<body>
+ <div id="h1" class="wrapper">With container size</div>
+ <div id="h2">Should be no highlight</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-006.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-006.html
new file mode 100644
index 0000000000..4bcae073b5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-container-metrics-006.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-002-ref.html">
+<meta name="assert" value="lengths depending on containers take the correct values inside and outside a container">
+<meta name="fuzzy" content="0-60;0-25">
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 200px;
+ height: 100px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+</style>
+</head>
+<body>
+ <div id="h1" class="wrapper">With container size</div>
+ <div id="h2">Without container size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001-ref.html
new file mode 100644
index 0000000000..8c9732f1dd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Reference</title>
+<head>
+ <style>
+ iframe {
+ width: 400px;
+ height: 200px;
+ }
+</style>
+</head>
+<iframe id="iframe" src="resources/iframe-container.html"></iframe>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001.html
new file mode 100644
index 0000000000..2c28f7d132
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-001.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes update on container changes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-dynamic-container-metrics-001-ref.html">
+<meta name="assert" value="lengths depending on containers take the correct values in a universal highlight with no container when the container size changes">
+<script src="/common/reftest-wait.js"></script>
+<head>
+ <style>
+ iframe {
+ width: 200px;
+ height: 100px;
+ }
+
+ iframe.resize {
+ width: 400px;
+ height: 200px;
+ }
+</style>
+</head>
+<iframe id="iframe" src="resources/iframe-container.html"></iframe>
+<script>
+ function runtest() {
+ iframe.classList.add('resize');
+ requestAnimationFrame(() => takeScreenshot());
+ }
+ iframe.onload = runtest;
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-002.html
new file mode 100644
index 0000000000..1a0cbe87a5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-002.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using dynamic container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-002-ref.html">
+<meta name="assert" value="lengths depending on containers take the correct values when the container size chnages">
+<meta name="fuzzy" content="0-60;0-25">
+<script src="/common/reftest-wait.js"></script>
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 400px;
+ height: 200px;
+ }
+ .resize {
+ width: 200px;
+ height: 100px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+</style>
+</head>
+<body>
+ <div id="container" class="wrapper">
+ <div id="h1">With container size</div>
+ </div>
+ <div id="h2">Without container size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ requestAnimationFrame(() => {
+ container.classList.add('resize');
+ requestAnimationFrame(() => takeScreenshot());
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-003.html
new file mode 100644
index 0000000000..38246a15af
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-003.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using dynamic container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-003-ref.html">
+<meta name="assert" value="lengths depending on containers update correctly for a highlight defined only inside a container query">
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 400px;
+ height: 200px;
+ }
+ .resize {
+ width: 200px;
+ height: 100px;
+ }
+ @container (width < 300px) {
+ ::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+ }
+ </style>
+</head>
+<body>
+ <div id="container" class="wrapper">
+ <div id="h1">With container size</div>
+ </div>
+ <div id="h2">Should be no highlight</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ requestAnimationFrame(() => {
+ container.classList.add('resize');
+ requestAnimationFrame(() => takeScreenshot());
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-004.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-004.html
new file mode 100644
index 0000000000..fbdbea32ef
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-container-metrics-004.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Highlights using container sizes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
+<link rel="match" href="custom-highlight-container-metrics-003-ref.html">
+<meta name="assert" value="a highlight on a container itself renders at the correct size when the container changes">
+<head>
+ <style>
+ .wrapper {
+ container: wrapper / size;
+ width: 400px;
+ height: 200px;
+ }
+ .resize {
+ width: 200px;
+ height: 100px;
+ }
+ @container (width < 300px) {
+ .wrapper::highlight(highlight1) {
+ text-underline-offset: 2cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4cqh;
+ }
+ }
+ </style>
+</head>
+<body>
+ <div id="h1" class="wrapper">With container size</div>
+ <div id="h2">Should be no highlight</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ requestAnimationFrame(() => {
+ h1.classList.add('resize');
+ requestAnimationFrame(() => takeScreenshot());
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-font-metrics-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-font-metrics-001.html
new file mode 100644
index 0000000000..4bddbc02a1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-font-metrics-001.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-font-metrics-001-ref.html">
+<meta name="assert" value="fonts relative units take the correct values, with correct cascade">
+<meta name="fuzzy" content="0-80;0-4">
+<head>
+ <style>
+ :root {
+ font-size: 8px;
+ }
+ div {
+ margin: 50px;
+ font-size: 10px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">Font relative units with 40px font</div>
+ <div id="h2">Font relative units with 20px font</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ h1.style.fontSize = '40px';
+ h2.style.fontSize = '20px';
+ document.documentElement.style.fontSize = '16px';
+ requestAnimationFrame(() => takeScreenshot());
+ });
+ });
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-logical-metrics-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-logical-metrics-001.html
new file mode 100644
index 0000000000..ff52aed6ab
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-dynamic-logical-metrics-001.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Length relative to a changing logical direction</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-logical-metrics-002-ref.html">
+<meta name="assert" value="lengths depending on viewports and logical direction when the direction changes">
+<meta name="fuzzy" content="0-30;0-10">
+<head>
+ <style>
+ div {
+ width: 100px;
+ height: 200px;
+ line-height: 3em;
+ }
+ .vertical {
+ writing-mode: vertical-lr;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 1svb;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 1svi;
+ }
+</style>
+</head>
+<body>
+ <div id="h1">With viewport size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1));
+ requestAnimationFrame(() => {
+ h1.classList.add('vertical');
+ requestAnimationFrame(() => takeScreenshot());
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001-ref.html
new file mode 100644
index 0000000000..76b7317caa
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<head>
+ <style>
+ div {
+ margin: 50px;
+ font-size: 40px;
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ #h2 {
+ font-size: 20px;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">Font relative units with 40px font</div>
+ <div id="h2">Font relative units with 20px font</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001.html
new file mode 100644
index 0000000000..755409c6b1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-001.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-font-metrics-001-ref.html">
+<meta name="assert" value="lengths depending on fonts take the correct values in a universal highlight">
+<meta name="fuzzy" content="0-80;0-4">
+<head>
+ <style>
+ :root {
+ font-size: 16px;
+ }
+ div {
+ margin: 50px;
+ font-size: 40px;
+ }
+ #h2 {
+ font-size: 20px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">Font relative units with 40px font</div>
+ <div id="h2">Font relative units with 20px font</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002-ref.html
new file mode 100644
index 0000000000..13b38d8bbf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<head>
+ <style>
+ div {
+ margin: 40px;
+ font-size: 20px;
+ }
+ #h1 {
+ text-underline-offset: 10px;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ #h2 {
+ text-underline-offset: 20px;
+ text-decoration-line: underline;
+ text-decoration-color: blue;
+ text-decoration-thickness: 2px;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">A green 10px offset underline 4px thick</div>
+ <div id="h2">A blue 20px offset underline 2px thick</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html
new file mode 100644
index 0000000000..58b2db5ce4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-font-metrics-002-ref.html">
+<meta name="assert" value="fonts relative units take the correct values, with correct cascade">
+<meta name="fuzzy" content="0-128;0-8">
+<head>
+ <style>
+ :root {
+ font-size: 16px;
+ }
+ div {
+ margin: 40px;
+ font-size: 20px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ #h2::highlight(highlight1) {
+ text-underline-offset: 1.0em;
+ text-decoration-line: underline;
+ text-decoration-color: blue;
+ text-decoration-thickness: 0.125rem;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">A green 10px offset underline 4px thick</div>
+ <div id="h2">A blue 20px offset underline 2px thick</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003-ref.html
new file mode 100644
index 0000000000..c1a04b0803
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<head>
+ <style>
+ div {
+ margin: 40px;
+ font-size: 20px;
+ text-underline-offset: 10px;
+ text-decoration-line: underline overline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">A green 10px offset underline 4px thick and green overline 4px thick</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003.html
new file mode 100644
index 0000000000..d1035ed130
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-003.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-font-metrics-003-ref.html">
+<meta name="assert" value="combining a font relative highlight with another highlight">
+<meta name="fuzzy" content="0-120;0-8">
+<head>
+ <style>
+ :root {
+ font-size: 16px;
+ }
+ div {
+ margin: 40px;
+ font-size: 20px;
+ }
+ ::selection {
+ background-color: transparent;
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ ::highlight(highlight1) {
+ text-decoration-line: overline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">A green 10px offset underline 4px thick and green overline 4px thick</div>
+ <script>
+ getSelection().selectAllChildren(h1);
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1));
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004-ref.html
new file mode 100644
index 0000000000..c1a04b0803
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<head>
+ <style>
+ div {
+ margin: 40px;
+ font-size: 20px;
+ text-underline-offset: 10px;
+ text-decoration-line: underline overline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">A green 10px offset underline 4px thick and green overline 4px thick</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004.html
new file mode 100644
index 0000000000..fec70e97d3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-004.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-font-metrics-003-ref.html">
+<meta name="assert" value="combining a font relative highlight with another highlight">
+<meta name="fuzzy" content="0-120;0-8">
+<head>
+ <style>
+ div {
+ margin: 40px;
+ font-size: 20px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ ::highlight(highlight2) {
+ text-decoration-line: overline;
+ text-decoration-color: green;
+ text-decoration-thickness: 4px;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">A green 10px offset underline 4px thick and green overline 4px thick</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1));
+ CSS.highlights.set("highlight2", new Highlight(r1));
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005-ref.html
new file mode 100644
index 0000000000..bbfc952116
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<head>
+ <style>
+ div {
+ margin: 50px;
+ font-size: 20px;
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">Font relative units with 20px font</div>
+ <div id="h2">Font relative units with 20px font</div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005.html
new file mode 100644
index 0000000000..5b2eb65773
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-005.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-font-metrics-005-ref.html">
+<meta name="assert" value="dynmamic font size changes with highlights and font relative metrics">
+<meta name="fuzzy" content="0-80;0-10">
+<script src="/common/reftest-wait.js"></script>
+<head>
+ <style>
+ :root {
+ font-size: 16px;
+ }
+ div {
+ margin: 50px;
+ font-size: 40px;
+ }
+ #h2 {
+ font-size: 20px;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 0.5em;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 0.25rem;
+ }
+ </style>
+</head>
+<body>
+ <div id="h1">Font relative units with 20px font</div>
+ <div id="h2">Font relative units with 20px font</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ let r2 = new Range();
+ r2.setStart(h2, 0);
+ r2.setEnd(h2, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1, r2));
+
+ requestAnimationFrame(() => {
+ h1.style.fontSize = "20px";
+ requestAnimationFrame(() => { takeScreenshot() }
+ )});
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001-ref.html
new file mode 100644
index 0000000000..09bc7fac5e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test Reference</title>
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 100px;
+ line-height: 3em;
+ text-underline-offset: 1svb;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 1svi;
+ }
+</style>
+</head>
+<body>
+ <div>With viewport size</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001.html
new file mode 100644
index 0000000000..0bca0ea639
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-001.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Length relative to the logical direction</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-logical-metrics-001-ref.html">
+<meta name="assert" value="lengths depending on viewports take the correct values with vertical text">
+<meta name="fuzzy" content="0-30;0-10">
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 100px;
+ line-height: 3em;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 1svb;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 1svi;
+ }
+</style>
+</head>
+<body>
+ <div id="h1">With viewport size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1));
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002-ref.html
new file mode 100644
index 0000000000..eaed1580f9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test Reference</title>
+<head>
+ <style>
+ div {
+ width: 100px;
+ height: 200px;
+ writing-mode: vertical-lr;
+ line-height: 3em;
+ text-underline-offset: 1svb;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 1svi;
+ }
+</style>
+</head>
+<body>
+ <div id="h1">With viewport size</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002.html
new file mode 100644
index 0000000000..9e8acc054d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-logical-metrics-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Length relative to the logical direction</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="custom-highlight-logical-metrics-002-ref.html">
+<meta name="assert" value="lengths depending on viewports and logical direction with vertical text">
+<meta name="fuzzy" content="0-30;0-10">
+<head>
+ <style>
+ div {
+ width: 100px;
+ height: 200px;
+ writing-mode: vertical-lr;
+ line-height: 3em;
+ }
+ ::highlight(highlight1) {
+ text-underline-offset: 1svb;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 1svi;
+ }
+</style>
+</head>
+<body>
+ <div id="h1">With viewport size</div>
+ <script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1));
+ </script>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001-ref.html
new file mode 100644
index 0000000000..b058789f6d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+ .highlighted {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span class="highlighted">One two </span><span>three…</span>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001.html
new file mode 100644
index 0000000000..82b61ec6de
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-001.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay is painted">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+
+ CSS.highlights.set("example-highlight", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002-ref.html
new file mode 100644
index 0000000000..d063bbd497
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002-ref.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+ div {
+ color: red;
+ }
+</style>
+<body><div>abc</div>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002.html
new file mode 100644
index 0000000000..04b7dadbf8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-002.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-002-ref.html">
+<meta name="assert" value="Latest Highlight added to CSS.highlights has higher priority than the previous ones if there were no priorities explicitly set">
+<style>
+ div::highlight(bar) {
+ color: red;
+ }
+ div::highlight(foo) {
+ color: green;
+ }
+</style>
+<body><div>abc</div>
+<script>
+ let div = document.body.firstChild;
+ let r = new Range();
+ r.setStart(div, 0);
+ r.setEnd(div, 1);
+ let h = new Highlight(r);
+ CSS.highlights.set('foo', h);
+ CSS.highlights.set('bar', h);
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003-ref.html
new file mode 100644
index 0000000000..b2dccfa59f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+ span { background-color: rgba(0, 0, 255, 0.3); }
+</style>
+<body>L<span>orem I</span>psum. \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003.html
new file mode 100644
index 0000000000..210f1a230f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-003.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-003-ref.html">
+<meta name="assert" value="Intersections of overlapping ranges contained in the same Highlight are painted only once">
+<style>
+ ::highlight(sample) { background-color: rgba(0, 0, 255, 0.3); }
+</style>
+<body>Lorem Ipsum.
+<script>
+ let textNode = document.body.firstChild;
+
+ let r1 = new Range();
+ r1.setStart(textNode, 1);
+ r1.setEnd(textNode, 5);
+
+ let r2 = new Range();
+ r2.setStart(textNode, 3);
+ r2.setEnd(textNode, 7);
+
+ CSS.highlights.set("sample", new Highlight(r1, r2));
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2-ref.html
new file mode 100644
index 0000000000..4ad1de63df
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+ .foo {
+ color:blue;
+ background-color:yellow;
+ }
+ .bar {
+ color:orange;
+ }
+ .bar-over-foo {
+ color:orange;
+ background-color:yellow;
+ }
+</style>
+<body><span class="foo">Som</span><span class="bar-over-foo">e t</span><span class="bar">ext</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2.html
new file mode 100644
index 0000000000..0a612d66d1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-004-2-ref.html">
+<meta name="assert" value="When painting overlapping highlights with the same .priority, the one added last should be painted on top; and style properties not defined by the one on top (background-color in this case) should follow the rules of the next Highlight from top to bottom until there's one that overwrites default (or use default value otherwise).">
+<meta name="fuzzy" content="0-88;0-1">
+<style>
+ ::highlight(foo) {
+ color:blue;
+ background-color:yellow;
+ }
+ ::highlight(bar) {
+ color:orange;
+ }
+</style>
+<body>Some text
+<script>
+ let textNode = document.body.firstChild;
+
+ let r1 = new Range();
+ r1.setStart(textNode, 0);
+ r1.setEnd(textNode, 6);
+
+ let r2 = new Range();
+ r2.setStart(textNode, 3);
+ r2.setEnd(textNode, 9);
+
+ let h1 = new Highlight(r1);
+ let h2 = new Highlight(r2);
+
+ CSS.highlights.set("foo", h1);
+ CSS.highlights.set("bar", h2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-ref.html
new file mode 100644
index 0000000000..8cb5b69d98
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+ .foo {
+ color:blue;
+ background-color:yellow;
+ }
+ .bar {
+ background-color:orange;
+ }
+ .bar-over-foo {
+ color:blue;
+ background-color:orange;
+ }
+</style>
+<body><span class="foo">Som</span><span class="bar-over-foo">e t</span><span class="bar">ext</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004.html
new file mode 100644
index 0000000000..320617f8d1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-004.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-004-ref.html">
+<meta name="assert" value="When painting overlapping highlights with the same .priority, the one added last should be painted on top; and style properties not defined by the one on top (color in this case) should follow the rules of the next Highlight from top to bottom until there's one that overwrites default (or use default value otherwise).">
+<meta name="fuzzy" content="0-255;0-110">
+<style>
+ ::highlight(foo) {
+ color:blue;
+ background-color:yellow;
+ }
+ ::highlight(bar) {
+ background-color:orange;
+ }
+</style>
+<body>Some text
+<script>
+ let textNode = document.body.firstChild;
+
+ let r1 = new Range();
+ r1.setStart(textNode, 0);
+ r1.setEnd(textNode, 6);
+
+ let r2 = new Range();
+ r2.setStart(textNode, 3);
+ r2.setEnd(textNode, 9);
+
+ let h1 = new Highlight(r1);
+ let h2 = new Highlight(r2);
+
+ CSS.highlights.set("foo", h1);
+ CSS.highlights.set("bar", h2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-005.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-005.html
new file mode 100644
index 0000000000..f9b728c9c5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-005.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after modifying (setEnd()) a Range contained in it">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 1);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ r.setEnd(document.body, 2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-006.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-006.html
new file mode 100644
index 0000000000..b4369dcacc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-006.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after modifying (setStart()) a Range contained in it">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 1);
+ r.setEnd(document.body, 2);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ r.setStart(document.body, 0);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-007.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-007.html
new file mode 100644
index 0000000000..6cfdac2c7e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-007.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after adding a Range to it after registering it in the HighlightRegistry">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r1 = new Range();
+ r1.setStart(document.body, 0);
+ r1.setEnd(document.body, 1);
+ let h = new Highlight(r1);
+ let r2 = new Range();
+ r2.setStart(document.body, 1);
+ r2.setEnd(document.body, 2);
+ CSS.highlights.set("example-highlight", h);
+ h.add(r2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-008.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-008.html
new file mode 100644
index 0000000000..3da1d82ce3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-008.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after deleting a Range from it after registering it in the HighlightRegistry">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r1 = new Range();
+ r1.setStart(document.body, 0);
+ r1.setEnd(document.body, 2);
+ let r2 = new Range();
+ r2.setStart(document.body, 1);
+ r2.setEnd(document.body, 3);
+ let h = new Highlight(r1, r2);
+ CSS.highlights.set("example-highlight", h);
+ h.delete(r2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-009.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-009.html
new file mode 100644
index 0000000000..cee2394d62
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-009.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly when collapsing a Range after registering a Highlight that contains it in the HighlightRegistry">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+ ::highlight(another-highlight) {
+ background-color: red;
+ color: orange;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r1 = new Range();
+ r1.setStart(document.body, 0);
+ r1.setEnd(document.body, 2);
+ let r2 = new Range();
+ r2.setStart(document.body, 1);
+ r2.setEnd(document.body, 3);
+ let h1 = new Highlight(r1);
+ let h2 = new Highlight(r2);
+ CSS.highlights.set("example-highlight", h1);
+ CSS.highlights.set("another-highlight", h2);
+ r2.collapse();
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-010.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-010.html
new file mode 100644
index 0000000000..cdd2daf85c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-010.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after inserting a node in the middle of a Range contained in it">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 1);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ let newNode = document.createElement("span");
+ newNode.innerText = "One ";
+ document.body.insertBefore(newNode, document.body.firstChild);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-011.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-011.html
new file mode 100644
index 0000000000..5eef8508b6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-011.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after removing a node included in a Range contained in it">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>two-point-five </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 3);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ document.body.removeChild(document.body.children[2]);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-012.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-012.html
new file mode 100644
index 0000000000..cc8bb62e1e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-012.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after modifying the inner text of a node included in a Range contained in it">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>Zero </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ document.body.firstChild.innerText = "One ";
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-013.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-013.html
new file mode 100644
index 0000000000..021f1cb19f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-013.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after modifying text content of a node included in a Range contained in it">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span id="first">One </span><span id="second">two-point-five </span><span id="third">three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.querySelector("#first").firstChild, 0);
+ r.setEnd(document.querySelector("#third").firstChild, 0);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ document.querySelector("#second").firstChild.textContent = "two ";
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-014.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-014.html
new file mode 100644
index 0000000000..5313fe0954
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-014.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Registering the same Highlight under different names and again with a used name works as it should.">
+<style>
+ ::highlight(foo) {
+ color: blue;
+ }
+ ::highlight(bar) {
+ background-color: yellow;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+
+ let h = new Highlight(r);
+
+ CSS.highlights.set("foo", h);
+ CSS.highlights.set("bar", h);
+ CSS.highlights.set("foo", h);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-015.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-015.html
new file mode 100644
index 0000000000..62ce114dfa
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-015.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Unregistering only once a Highlight that was registered under different names works as it should and is still being painted.">
+<style>
+ ::highlight(foo) {
+ color: red;
+ }
+ ::highlight(bar) {
+ color: blue;
+ background-color: yellow;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+
+ let h = new Highlight(r);
+
+ CSS.highlights.set("foo", h);
+ CSS.highlights.set("bar", h);
+ CSS.highlights.delete("foo");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-016.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-016.html
new file mode 100644
index 0000000000..58b580e6b7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-016.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Painting</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlighted elements must be correctly painted and there should be no caching that doesn't take highlight names into account">
+<style>
+ #affected::highlight(foo) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span></span><span id="affected">One </span><span id="affected">two </span><span>three…</span>
+<script>
+ // The first <span> style resolution shouldn't cause caching an empty set of matched properties that could be used with the spans that should be highlighted later.
+ const node = document.body;
+ let r = new Range();
+ r.setStart(node, 1);
+ r.setEnd(node, 3);
+ CSS.highlights.set("foo", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-017.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-017.html
new file mode 100644
index 0000000000..c3184a986a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-017.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>CSS Highlight API Test: ::highlight color with transparent originating color</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/#custom-highlight-pseudo">
+<link rel="help" href="https://crbug.com/1273943">
+<meta name="assert" content="This test checks that ::highlight pseudo-element uses the specified color even when the originating element text color was trasnparent.">
+<link rel="match" href="/css/reference/pass_if_pass_below.html">
+<style>
+ div {
+ color: transparent;
+ }
+ ::highlight(example-highlight) {
+ color: black;
+ }
+</style>
+
+<p>Test passes if there is the word "PASS" below.</p>
+<div id="target">PASS</div>
+
+<script>
+ let r = new Range();
+ r.setStart(target, 0);
+ r.setEnd(target, 1);
+
+ CSS.highlights.set("example-highlight", new Highlight(r));
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-018.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-018.html
new file mode 100644
index 0000000000..95bef09bbe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-018.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Range across contain boundary is painted</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight should be painted even though a Range that crosses a css-contain boundary is a part of it">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+ #target {
+ contain: paint;
+ }
+</style>
+<body><span>One </span><span id="target"><span>two </span><span>three…</span></span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.querySelector("#target"), 1);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar-ref.html
new file mode 100644
index 0000000000..d660daf7c7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ ::grammar-error {
+ background-color: lime;
+ color: green;
+ }
+</style>
+<span>Many thing can happen.</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html
new file mode 100644
index 0000000000..93d2560040
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-below-grammar-ref.html">
+<meta name="assert" value="Highlight overlay is painted below all other pseudo overlays (comparing only to grammar suffices since it's the one immediately above ::highlight, assuming ::grammar-error is painted in the correct order)">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+ ::grammar-error {
+ background-color: lime;
+ color: green;
+ }
+</style>
+<!--
+ The grammar mistakes in the text below are intentional and part of this test.
+
+ https://html.spec.whatwg.org/multipage/interaction.html#spelling-and-grammar-checking
+ • contenteditable makes the text “checkable for the purposes of [spelling and grammar checking]”
+ • spellcheck tries to enable spelling and grammar checking (subject to user preferences)
+ • lang tries to guide the UA towards checking the text in English (but the UA may ignore this)
+-->
+<span contenteditable="true" spellcheck="true" lang="en">Many thing can happen.</div>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 1);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-ref.html
new file mode 100644
index 0000000000..5c7bd9361b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ #highlighted {
+ background: cyan;
+ color: blue;
+ }
+ ::selection {
+ background: blue;
+ color: cyan;
+ }
+</style>
+<body><span id="highlighted">Text should be blue over cyan here and <span id="selected">cyan over blue here</span>.</span>
+<script>
+ getSelection().setBaseAndExtent(selected, 0, selected, 1);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency-ref.html
new file mode 100644
index 0000000000..2f45cdcd75
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ #highlighted {
+ background: yellow;
+ }
+</style>
+
+<body><span id="highlighted">This should be yellow, <span id="selected">this should mix with the
+ selection,</span></span> this should have no background.
+ <script>
+ getSelection().setBaseAndExtent(selected, 0, selected, 1);
+ </script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency.html
new file mode 100644
index 0000000000..886fa28f53
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection-transparency.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-below-selection-transparency-ref.html">
+<meta name="assert"
+ value="Highlight overlay is painted below selection overlay. If selection uses transparency, colors are combined.">
+<style>
+ ::highlight(foo) {
+ background: yellow;
+ }
+</style>
+
+<body><span id="highlighted">This should be yellow, <span id="selected">this should mix with the
+ selection,</span></span> this should have no background.
+ <script>
+ let highlightRange = new Range();
+ highlightRange.setStart(document.body.firstChild, 0);
+ highlightRange.setEnd(document.body.firstChild, 2);
+ CSS.highlights.set("foo", new Highlight(highlightRange));
+ getSelection().setBaseAndExtent(selected, 0, selected, 1);
+ </script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection.html
new file mode 100644
index 0000000000..cd5ad36a69
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-selection.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-below-selection-ref.html">
+<meta name="assert" value="Highlight overlay is painted below selection overlay">
+<style>
+ ::highlight(foo) {
+ background: cyan;
+ color: blue;
+ }
+ ::selection {
+ background: blue;
+ color: cyan;
+ }
+</style>
+<body>Text should be blue over cyan here and <span id="selected">cyan over blue here</span>.
+<script>
+ let highlightRange = new Range();
+ highlightRange.setStart(document.body.firstChild, 0);
+ highlightRange.setEnd(document.body.lastChild, 0);
+ CSS.highlights.set("foo", new Highlight(highlightRange));
+ getSelection().setBaseAndExtent(selected, 0, selected, 1);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text-ref.html
new file mode 100644
index 0000000000..70d6926364
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ #highlight {
+ background-color: yellow;
+ color: limegreen;
+ }
+ #highlight-and-target-text {
+ background-color: orange;
+ color: limegreen;
+ }
+ #target-text {
+ background-color: orange;
+ }
+</style>
+<span id="highlight">Some </span><span id="highlight-and-target-text">te</span><span id="target-text">xt</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html
new file mode 100644
index 0000000000..e55ce783de
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-below-target-text-ref.html">
+<meta name="assert" value="Style properties defined in a ::highlight shouldn't be overriden by default values if there's another pseudo overlay painted on top of it (::target-text in this case) which doesn't specify a value for that property (color in this case)">
+<style>
+ ::highlight(foo) {
+ color:limegreen;
+ background-color:yellow;
+ }
+ ::target-text {
+ background-color:orange;
+ }
+</style>
+<body>Some text
+<script>
+ let r = new Range();
+ r.setStart(document.body.firstChild, 0);
+ r.setEnd(document.body.firstChild, 7);
+ CSS.highlights.set("foo", new Highlight(r));
+ window.location.href = `custom-highlight-painting-below-target-text.html#:~:text=text`;
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001-ref.html
new file mode 100644
index 0000000000..aa8915c1d7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<body>
+<iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ span {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001.html
new file mode 100644
index 0000000000..240c112c5d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-001.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-iframe-001-ref.html">
+<meta name="assert" value="Registered Highlights inside an iframe are correctly painted.">
+<body>
+<iframe
+ id="iframe"
+ src="resources/iframe-code.html"
+ >
+</iframe> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-002.html
new file mode 100644
index 0000000000..388457f9cb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-iframe-001-ref.html">
+<meta name="assert" value="Creating a Highlight in the root Document and registering it in an iframe's CSS.highlights is painted correctly.">
+<body>
+ <iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ ::highlight(foo) {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe>
+<script>
+ let iframe = document.querySelector("#iframe");
+ iframe.onload = () => {
+ let spanIframe = iframe.contentDocument.querySelector("#span-iframe");
+ let rangeIframe = new Range();
+ rangeIframe.setStart(spanIframe, 0);
+ rangeIframe.setEnd(spanIframe, 1);
+
+ let h = new Highlight();
+ h.add(rangeIframe);
+ iframe.contentWindow.CSS.highlights.set("foo", h);
+ }
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003-ref.html
new file mode 100644
index 0000000000..9d80a9f005
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ #span-doc {
+ color: green;
+ background-color: greenyellow;
+ }
+</style>
+<body>
+<iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ span {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003.html
new file mode 100644
index 0000000000..8614d35ed6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-003.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-iframe-003-ref.html">
+<meta name="assert" value="Creating a Highlight in the root Document with a Range in the root document and another one in an iframe is correctly painted when added to both CSS.highlights (root document's and iframe's).">
+<style>
+ ::highlight(foo) {
+ color: green;
+ background-color: greenyellow;
+ }
+</style>
+<body>
+ <iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ ::highlight(foo) {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span>
+<script>
+ let spanDoc = document.querySelector("#span-doc");
+ let rangeDoc = new Range();
+ rangeDoc.setStart(spanDoc, 0);
+ rangeDoc.setEnd(spanDoc, 1);
+
+ let iframe = document.querySelector("#iframe");
+ iframe.onload = () => {
+ let spanIframe = iframe.contentDocument.querySelector("#span-iframe");
+ let rangeIframe = new Range();
+ rangeIframe.setStart(spanIframe, 0);
+ rangeIframe.setEnd(spanIframe, 1);
+
+ let h = new Highlight(rangeDoc, rangeIframe);
+ iframe.contentWindow.CSS.highlights.set("foo", h);
+ CSS.highlights.set("foo", h);
+ }
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004-ref.html
new file mode 100644
index 0000000000..622ea40c80
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ #span-doc {
+ color: green;
+ background-color: greenyellow;
+ }
+</style>
+<body>
+<iframe
+ id="iframe"
+ srcdoc="<span id='span-iframe'>abc</span>"
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004.html
new file mode 100644
index 0000000000..d13d75a561
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-004.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-iframe-004-ref.html">
+<meta name="assert" value="Creating a Highlight in the root Document with a Range in the root document and another one in an iframe is correctly painted when added to the root document's CSS.highlights (only root document's range is painted).">
+<style>
+ ::highlight(foo) {
+ color: green;
+ background-color: greenyellow;
+ }
+</style>
+<body>
+ <iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ ::highlight(foo) {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span>
+<script>
+ let spanDoc = document.querySelector("#span-doc");
+ let rangeDoc = new Range();
+ rangeDoc.setStart(spanDoc, 0);
+ rangeDoc.setEnd(spanDoc, 1);
+
+ let iframe = document.querySelector("#iframe");
+ iframe.onload = () => {
+ let spanIframe = iframe.contentDocument.querySelector("#span-iframe");
+ let rangeIframe = new Range();
+ rangeIframe.setStart(spanIframe, 0);
+ rangeIframe.setEnd(spanIframe, 1);
+
+ let h = new Highlight(rangeDoc, rangeIframe);
+ CSS.highlights.set("foo", h);
+ }
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005-ref.html
new file mode 100644
index 0000000000..7a492e32c0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<body>
+<iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ span {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005.html
new file mode 100644
index 0000000000..d31590c639
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-005.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-iframe-005-ref.html">
+<meta name="assert" value="Creating a Highlight in the root Document with a Range in the root document and another one in an iframe is correctly painted when added to the iframe's CSS.highlights (only the iframe's range is painted).">
+<style>
+ ::highlight(foo) {
+ color: green;
+ background-color: greenyellow;
+ }
+</style>
+<body>
+ <iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ ::highlight(foo) {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span>
+<script>
+ let spanDoc = document.querySelector("#span-doc");
+ let rangeDoc = new Range();
+ rangeDoc.setStart(spanDoc, 0);
+ rangeDoc.setEnd(spanDoc, 1);
+
+ let iframe = document.querySelector("#iframe");
+ iframe.onload = () => {
+ let spanIframe = iframe.contentDocument.querySelector("#span-iframe");
+ let rangeIframe = new Range();
+ rangeIframe.setStart(spanIframe, 0);
+ rangeIframe.setEnd(spanIframe, 1);
+
+ let h = new Highlight(rangeDoc, rangeIframe);
+ iframe.contentWindow.CSS.highlights.set("foo", h);
+ }
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006-ref.html
new file mode 100644
index 0000000000..f5a871d0fe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<body>
+<iframe
+ id="iframe"
+ srcdoc="<span id='span-iframe'>abc</span>"
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006.html
new file mode 100644
index 0000000000..2b1e88e659
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-iframe-006.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-iframe-006-ref.html">
+<meta name="assert" value="Ranges contained in a registered Highlight that are moved to another document different than the owner of the HighlightRegistry where the Highlight has been registered should not be painted anymore.">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ ::highlight(foo) {
+ color: green;
+ background-color: greenyellow;
+ }
+</style>
+<body>
+ <iframe
+ id="iframe"
+ srcdoc="
+ <style>
+ ::highlight(foo) {
+ color: blue;
+ background-color: cyan;
+ }
+ </style>
+ <span id='span-iframe'>abc</span>
+ "
+ >
+</iframe>
+<br>
+<span id="span-doc">abc</span>
+<script>
+ let spanDoc = document.querySelector("#span-doc");
+ let r = new Range();
+ r.setStart(spanDoc, 0);
+ r.setEnd(spanDoc, 1);
+
+ let h = new Highlight(r);
+ CSS.highlights.set("foo", h);
+
+ let iframe = document.querySelector("#iframe");
+ iframe.onload = () => {
+ let spanIframe = iframe.contentDocument.querySelector("#span-iframe");
+ runAfterLayoutAndPaint(()=>{
+ r.setStart(spanIframe, 0);
+ r.setEnd(spanIframe, 1);
+ document.documentElement.removeAttribute("class");
+ });
+ }
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001-ref.html
new file mode 100644
index 0000000000..0d5385287c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ span {
+ background-color: green;
+ }
+</style>
+<body>
+<div>There should be only one green rectangle below from [ to ]:</div>
+<div>[<span>&nbsp;&nbsp;&nbsp;<strong>&nbsp;&nbsp;&nbsp;</strong>&nbsp;&nbsp;&nbsp;</span>]</div> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001.html
new file mode 100644
index 0000000000..eb5e5e1181
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-001.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Inheritance</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-inheritance-001-ref.html">
+<meta name="assert" value="Highlighted elements inherit style properties from their parent if they're not set">
+<style>
+ div::highlight(div-highlight) {
+ background-color: green;
+ color: red;
+ }
+ span::highlight(span-highlight) {
+ color: blue;
+ }
+</style>
+<body>
+<div>There should be only one green rectangle below from [ to ]:</div>
+<div id="target">[<span>&nbsp;&nbsp;&nbsp;<strong>&nbsp;&nbsp;&nbsp;</strong>&nbsp;&nbsp;&nbsp;</span>]</div>
+<script>
+ let r = new Range();
+ const node = document.getElementById("target");
+ r.setStart(node, 1);
+ r.setEnd(node, 2);
+
+ CSS.highlights.set("div-highlight", new Highlight(r));
+ CSS.highlights.set("span-highlight", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-002.html
new file mode 100644
index 0000000000..fbed69392c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-002.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Inheritance</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-inheritance-001-ref.html">
+<meta name="assert" value="Highlighted elements inherit style properties from their parent even if there's not a ::highlight selector directly applying to them or their parent.">
+<style>
+ div::highlight(div-highlight) {
+ background-color: green;
+ }
+</style>
+<body>
+<div>There should be only one green rectangle below from [ to ]:</div>
+<div id="target">[<span>&nbsp;&nbsp;&nbsp;<strong>&nbsp;&nbsp;&nbsp;</strong>&nbsp;&nbsp;&nbsp;</span>]</div>
+<script>
+ const node = document.getElementById("target");
+ let r = new Range();
+ r.setStart(node, 1);
+ r.setEnd(node, 2);
+ CSS.highlights.set("div-highlight", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003-ref.html
new file mode 100644
index 0000000000..cdab7615e4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ div {
+ color: #00000080;
+ }
+</style>
+<body>
+<div>foobar</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003.html
new file mode 100644
index 0000000000..e449ebf334
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-inheritance-003.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Inheritance</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-inheritance-003-ref.html">
+<meta name="assert" value="Unstyled highlights should not be visible">
+<style>
+ div {
+ color: #00000080;
+ background-color: red;
+ width: 0;
+ }
+</style>
+<body>
+<div id="target">foobar</div>
+<script>
+ const node = document.getElementById("target");
+ let r = new Range();
+ r.setStart(node.firstChild, 0);
+ r.setEnd(node.firstChild, 3);
+ CSS.highlights.set("div-highlight", new Highlight(r));
+</script>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html
new file mode 100644
index 0000000000..aef391ec0f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay is correctly invalidated and repainted">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+
+ // Force frame paint before registering the Highlight.
+ runAfterLayoutAndPaint(()=>{
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ document.documentElement.removeAttribute("class");
+ });
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html
new file mode 100644
index 0000000000..99271ff7a0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-staticrange-001-ref.html">
+<meta name="assert" value="::highlight overlay is correctly invalidated and repainted after deletion">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+
+ // Force frame paint before deleting the Highlight.
+ runAfterLayoutAndPaint(()=>{
+ CSS.highlights.delete("example-highlight");
+ document.documentElement.removeAttribute("class");
+ });
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html
new file mode 100644
index 0000000000..d1f8722388
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay is correctly invalidated and repainted after modifying its range">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ CSS.highlights.set("example-highlight", new Highlight(r));
+
+ // Force frame paint before modifying the Highlight's range.
+ runAfterLayoutAndPaint(()=>{
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+ document.documentElement.removeAttribute("class");
+ });
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html
new file mode 100644
index 0000000000..62f05a84ab
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay is correctly invalidated and repainted after adding a range to it">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+ let h = new Highlight();
+ CSS.highlights.set("example-highlight", h);
+
+ // Force frame paint before modifying the Highlight.
+ runAfterLayoutAndPaint(()=>{
+ h.add(r);
+ document.documentElement.removeAttribute("class");
+ });
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html
new file mode 100644
index 0000000000..cabc4c3b9c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay is correctly invalidated and repainted after modifying its priority">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+ ::highlight(another-highlight) {
+ background-color: red;
+ color: orange;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+ let h1 = new Highlight(r);
+ let h2 = new Highlight(r);
+ h1.priority = 1;
+ h2.priority = 2;
+ CSS.highlights.set("example-highlight", h1);
+ CSS.highlights.set("another-highlight", h2);
+
+ // Force frame paint before modifying the Highlight.
+ runAfterLayoutAndPaint(()=>{
+ h1.priority = 3;
+ document.documentElement.removeAttribute("class");
+ });
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html
new file mode 100644
index 0000000000..81c2298e13
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay is correctly invalidated and repainted after inserting a new node inside one of its ranges">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 1);
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ let newNode = document.createElement("span");
+ newNode.innerText = "One ";
+
+ // Force frame paint before inserting a new node.
+ runAfterLayoutAndPaint(()=>{
+ document.body.insertBefore(newNode, document.body.firstChild);
+ document.documentElement.removeAttribute("class");
+ });
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007-ref.html
new file mode 100644
index 0000000000..88f3d0f3d6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007-ref.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+ .highlighted {
+ background: blue;
+ }
+</style>
+<body>
+ <span class="highlighted">Hello</span>
+</body>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007.html
new file mode 100644
index 0000000000..f23a869728
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-invalidation-007.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: CSS Rule change</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-invalidation-007-ref.html">
+<meta name="assert" value="::highlight overlay is correctly invalidated and repainted after CSS rule is changed">
+<script src="resources/run-after-layout-and-paint.js"></script>
+<style>
+ span::highlight(example-highlight) {
+ background: yellow;
+ }
+
+ .blue::highlight(example-highlight) {
+ background: blue;
+ }
+</style>
+<body>
+ <span>Hello</span>
+<script>
+ const range = new Range();
+ const span = document.querySelector("span");
+ range.setStart(span, 0);
+ range.setEnd(span, 1);
+ CSS.highlights.set("example-highlight", new Highlight(range));
+
+ // Force frame paint before changing style
+ runAfterLayoutAndPaint(() => {
+ span.className = "blue";
+ document.documentElement.removeAttribute("class");
+ });
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001-ref.html
new file mode 100644
index 0000000000..3c08ad55ae
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ body {
+ font-size: 3em;
+ font-weight: bolder;
+
+ }
+ #affected1 {
+ color: red;
+ }
+ #affected2 {
+ color: green;
+ }
+</style>
+<body><span id="affected1">This should have 'highlight1' style (red).</span><span id="affected2">This should have 'highlight2' style (green).</span> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001.html
new file mode 100644
index 0000000000..0b380574bc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-001.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Overlapping Highlights</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-overlapping-highlights-001-ref.html">
+<meta name="assert" value="UAs must not define any styles for custom highlight pseudo-elements in the default UA stylesheet.">
+<style>
+ body {
+ font-size: 3em;
+ font-weight: bolder;
+ }
+ #affected1::highlight(highlight1) {
+ color: red;
+ }
+ #affected2::highlight(highlight2) {
+ color: green;
+ }
+</style>
+<body><span id="affected1">This should have 'highlight1' style (red).</span><span id="affected2">This should have 'highlight2' style (green).</span>
+<script>
+ /*
+ This test is meant to verify that:
+ - UAs must not define any styles for custom highlight pseudo-elements in
+ the default UA stylesheet.
+ - UAs do not paint unstyled custom highlights.
+
+ In this test, highlight2 has higher priority because it was registered
+ later, so it is painted over highlight1. This includes painting for
+ span#affected1, where there is no CSS rule for highlight2. But since unstyled
+ custom highlights are not painted, span#affected1 is still painted with the
+ styles for highlight1.
+
+ See https://drafts.csswg.org/css-highlight-api-1/#default-styles
+ */
+
+ const node = document.body;
+ let r = new Range();
+ r.setStart(node, 0);
+ r.setEnd(node, 2);
+
+ CSS.highlights.set("highlight1", new Highlight(r));
+ CSS.highlights.set("highlight2", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002-ref.html
new file mode 100644
index 0000000000..2907681b75
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+ div {
+ font-size: 3em;
+ font-weight: bolder;
+ }
+ #affected1 {
+ color: green;
+ background-color: rgb(0, 255, 0, 0.5);
+ }
+ #affected2 {
+ color: red;
+ background-color: rgba(100, 0, 100, 0.5);
+ }
+</style>
+<body><div><span id="affected1">Green on lime.</span><span id="affected2">Red on maroon.</span></div> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002.html
new file mode 100644
index 0000000000..2dda273abf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-overlapping-highlights-002.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Overlapping Highlights</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-overlapping-highlights-002-ref.html">
+<meta name="assert" value="UAs must not define any styles for custom highlight pseudo-elements in the default UA stylesheet.">
+<style>
+ div {
+ font-size: 3em;
+ font-weight: bolder;
+ }
+ #affected1::highlight(highlight1) {
+ color: green;
+ background-color: rgb(0, 255, 0, 0.5);
+ }
+ #affected2::highlight(highlight2) {
+ color: red;
+ background-color: rgba(100, 0, 100, 0.5);
+ }
+</style>
+<body><div><span id="affected1">Green on lime.</span><span id="affected2">Red on maroon.</span></div>
+<script>
+ /*
+ This test is meant to verify that:
+ - UAs must not define any styles for custom highlight pseudo-elements in
+ the default UA stylesheet.
+ - UAs do not paint unstyled custom highlights.
+
+ In this test, highlight1 has higher priority, so it is painted over
+ highlight2. This includes painting for span#affected2, where there is no CSS
+ rule for highlight1. But since unstyled custom highlights are not painted,
+ span#affected2 is still painted with the styles for highlight2.
+
+ See https://drafts.csswg.org/css-highlight-api-1/#default-styles
+ */
+
+ const div = document.querySelector("div");
+
+ let r = new Range();
+ r.setStart(div, 0);
+ r.setEnd(div, 2);
+ let r2 = new Range();
+ r2.setStart(div, 0);
+ r2.setEnd(div, 2);
+
+ let h = new Highlight(r);
+ h.priority = 3;
+ let h2 = new Highlight(r2);
+ h2.priority = 2;
+
+ CSS.highlights.set("highlight1", h);
+ CSS.highlights.set("highlight2", h2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-001.html
new file mode 100644
index 0000000000..cc2a53be54
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-001.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlights are prioritized correctly by changing their .priority (higher priority is painted on top no matter the order of insertion into the HighlightRegistry)">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+ ::highlight(another-highlight) {
+ background-color: red;
+ color: orange;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+ let h1 = new Highlight(r);
+ let h2 = new Highlight(r);
+ h1.priority = 2;
+ h2.priority = 1;
+ CSS.highlights.set("example-highlight", h1);
+ CSS.highlights.set("another-highlight", h2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-002.html
new file mode 100644
index 0000000000..756368a8e6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-002.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlights are repainted correctly when changing their priority after adding them to the HighlightRegistry">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+ ::highlight(another-highlight) {
+ background-color: red;
+ color: orange;
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+ let h1 = new Highlight(r);
+ let h2 = new Highlight(r);
+ CSS.highlights.set("example-highlight", h1);
+ CSS.highlights.set("another-highlight", h2);
+ h1.priority = 1;
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003-ref.html
new file mode 100644
index 0000000000..9d3e3b00b0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Non-conflicting attributes</title>
+<style>
+ #blue {
+ background-color: blue;
+ color: white;
+ }
+ #yellow {
+ background-color: yellow;
+ }
+</style>
+<body>
+ <p>This <span id="blue">is an</span><span id="yellow"> example</span> of two overlapping highlights</p>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003.html
new file mode 100644
index 0000000000..1c7abf4749
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-prioritization-003.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Non-conflicting attributes</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/#priorities">
+<link rel="match" href="custom-highlight-painting-prioritization-003-ref.html">
+<meta name="assert" value="Non-conflicting attributes for highlights will be painted even if lower priority">
+<style>
+ ::highlight(highlight-1) {
+ background-color: blue;
+ color: white;
+ }
+ ::highlight(highlight-2) {
+ background-color: yellow;
+ }
+</style>
+<body>
+ <p>This is an example of two overlapping highlights</p>
+</body>
+<script>
+ const text = document.querySelector("p").firstChild;
+
+ // Create two overlapping highlights
+ const range1 = new Range();
+ range1.setStart(text, 5);
+ range1.setEnd(text, 10);
+
+ const range2 = new Range();
+ range2.setStart(text, 10);
+ range2.setEnd(text, 18);
+
+ const highlight1 = new Highlight(range1);
+ const highlight2 = new Highlight(range2);
+
+ CSS.highlights.set("highlight-1", highlight1);
+ CSS.highlights.set("highlight-2", highlight2);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001-ref.html
new file mode 100644
index 0000000000..a89d86dc81
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<meta charset="utf-8">
+<body><span>One two three…</span>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001.html
new file mode 100644
index 0000000000..ee81bb89d7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Invalid StaticRanges are not painted</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-staticrange-001-ref.html">
+<meta name="assert" value="StaticRanges that are invalid or collapsed should not be painted when they're in a Highlight">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span id="first">One </span><span id="second">two </span><span id="third">three…</span>
+<script>
+ let h = new Highlight();
+ h.add(new StaticRange({startContainer: document.body, startOffset: 0, endContainer: document.body, endOffset: 0}));
+ h.add(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 0}));
+ h.add(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 100}));
+ h.add(new StaticRange({startContainer: document, startOffset: 0, endContainer: document, endOffset: 1}));
+ h.add(new StaticRange({startContainer: document.querySelector("#third").firstChild, startOffset: 1, endContainer: document.querySelector("#first").firstChild, endOffset: 2}));
+ CSS.highlights.set("example-highlight", h);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-002.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-002.html
new file mode 100644
index 0000000000..43a0b06c35
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-002.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: StaticRange across contain boundary is painted</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="A StaticRange crossing a contain boundary should be painted">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+ #contained {
+ contain: paint;
+ }
+</style>
+<body><span>One <span id="contained">two </span>three…</span>
+<script>
+ let h = new Highlight();
+ h.add(new StaticRange({startContainer: document.body.firstChild.childNodes[0], startOffset: 0, endContainer: document.body.firstChild.childNodes[1], endOffset: 1}));
+ CSS.highlights.set("example-highlight", h);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-003.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-003.html
new file mode 100644
index 0000000000..11de279fd6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-003.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after removing a node included in a StaticRange contained in it (StaticRange not modified)">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>one-point-five </span><span>two </span><span>three…</span>
+<script>
+ let r = new StaticRange({startContainer: document.body, startOffset: 0, endContainer: document.body, endOffset: 2});
+ CSS.highlights.set("example-highlight", new Highlight(r));
+ document.body.removeChild(document.body.children[1]);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004-ref.html
new file mode 100644
index 0000000000..41e66ccc1d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<style>
+ span {
+ background-color: rgba(0, 128, 0, 0.5);
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>two </span><span>one-point-five </span><span>three…</span>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html
new file mode 100644
index 0000000000..c79943c4d9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-staticrange-004-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after re-arranging nodes in StaticRange such that highlights go from overlapping to not">
+<style>
+ ::highlight(example-highlight) {
+ background-color: rgba(0, 128, 0, 0.5);
+ color: blue;
+ }
+</style>
+<body><span>One </span><span>one-point-five </span><span>two </span><span>three…</span>
+<script>
+ let r1 = new StaticRange({startContainer: document.body.children[0], startOffset: 0, endContainer: document.body.children[2], endOffset: 1});
+ let r2 = new StaticRange({startContainer: document.body.children[1], startOffset: 0, endContainer: document.body.children[3], endOffset: 1});
+ CSS.highlights.set("example-highlight", new Highlight(r1,r2));
+ document.body.appendChild(document.body.children[1]);
+ document.body.appendChild(document.body.children[2]);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html
new file mode 100644
index 0000000000..9ffe2cf26b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: StaticRange is repainted correctly after deleting and re-adding it.</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="A StaticRange is repainted correctly after deleting and re-adding it.">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body><span>One two three…</span>
+<script>
+ let h = new Highlight();
+ const range = new StaticRange({
+ startContainer: document.body.firstChild.childNodes[0],
+ startOffset: 0,
+ endContainer: document.body.firstChild.childNodes[0],
+ endOffset: 8
+ })
+ h.add(range);
+ CSS.highlights.set("example-highlight", h);
+ document.body.onload = () => {
+ h.delete(range);
+ h.add(range);
+ };
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001-ref.html
new file mode 100644
index 0000000000..568e5f9321
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Highlight API Test: Reference ::highlight painting text-decoration</title>
+<style>
+ div {
+ float: left;
+ margin: 0.5em;
+ /* Setting transparent color is a workaround to avoid hitting the following Chromium bug: https://crbug.com/1179938.
+ This could be removed once that bug is fixed. */
+ color: transparent;
+ }
+</style>
+<p>The test passes if it matches the reference file.</p>
+<script>
+ let textDecorationStyles = [
+ "solid green underline", "double green underline", "dotted green underline", "dashed green underline", "wavy green underline",
+ "solid blue overline", "double blue overline", "dotted blue overline", "dashed blue overline", "wavy blue overline",
+ "solid magenta line-through", "double magenta line-through", "dotted magenta line-through", "dashed magenta line-through", "wavy magenta line-through",
+ "solid brown underline overline line-through", "double brown underline overline line-through", "dotted brown underline overline line-through", "dashed brown underline overline line-through", "wavy brown underline overline line-through",
+ ];
+
+ textDecorationStyles.forEach((textDecorationStyle, index) => {
+ document.styleSheets[0].insertRule(`#id${index} { text-decoration: ${textDecorationStyle}; }`);
+ let element = document.createElement("div");
+ element.id = `id${index}`;
+ element.innerHTML = textDecorationStyle;
+ document.body.appendChild(element);
+ });
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001.html
new file mode 100644
index 0000000000..72201e6e78
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-001.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::highlight painting text-decoration</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-text-decoration-001-ref.html">
+<meta name="assert" content="This test checks that ::highlight pseudo-element paints text-decorations defined by it.">
+<meta name="fuzzy" content="0-255;0-27">
+<style>
+ div {
+ float: left;
+ margin: 0.5em;
+ /* Setting transparent color is a workaround to avoid hitting the following Chromium bug: https://crbug.com/1179938.
+ This could be removed once that bug is fixed. */
+ color: transparent;
+ }
+</style>
+<p>The test passes if it matches the reference file.</p>
+<script>
+ let textDecorationStyles = [
+ "solid green underline", "double green underline", "dotted green underline", "dashed green underline", "wavy green underline",
+ "solid blue overline", "double blue overline", "dotted blue overline", "dashed blue overline", "wavy blue overline",
+ "solid magenta line-through", "double magenta line-through", "dotted magenta line-through", "dashed magenta line-through", "wavy magenta line-through",
+ "solid brown underline overline line-through", "double brown underline overline line-through", "dotted brown underline overline line-through", "dashed brown underline overline line-through", "wavy brown underline overline line-through",
+ ];
+
+ textDecorationStyles.forEach((textDecorationStyle, index) => {
+ document.styleSheets[0].insertRule(`::highlight(h${index}) { text-decoration: ${textDecorationStyle}; }`);
+ let element = document.createElement("div");
+ element.innerHTML = textDecorationStyle;
+ document.body.appendChild(element);
+ let range = new Range();
+ range.setStart(element, 0);
+ range.setEnd(element, 1);
+ CSS.highlights.set(`h${index}`, new Highlight(range));
+ });
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001-ref.html
new file mode 100644
index 0000000000..3a713aa844
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Highlight API Test: Reference ::highlight dynamic change text-decoration</title>
+<style>
+ ::highlight(example) {
+ text-decoration: solid underline green;
+ }
+</style>
+<p>The test passes if it line below has a green underline.</p>
+<div id="target">target</div>
+<script>
+ let range = new Range();
+ range.setStart(target, 0);
+ range.setEnd(target, 1);
+ CSS.highlights.set(`example`, new Highlight(range));
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001.html
new file mode 100644
index 0000000000..050c7c77ce
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-decoration-dynamic-001.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::highlight dynamic change text-decoration</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-text-decoration-dynamic-001-ref.html">
+<meta name="assert" content="This test checks that it's possible to modify dynamically the text-decoration of a custom highlight through ::highlight pseudo-element.">
+<script src="/common/reftest-wait.js"></script>
+<style>
+ ::highlight(example) {
+ text-decoration: solid underline red;
+ }
+</style>
+<p>The test passes if it line below has a green underline.</p>
+<div id="target">target</div>
+<script>
+ let range = new Range();
+ range.setStart(target, 0);
+ range.setEnd(target, 1);
+ CSS.highlights.set(`example`, new Highlight(range));
+
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ document.styleSheets[0].cssRules[0].style.textDecorationColor = "green";
+ takeScreenshot();
+ }));
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-shadow.tentative.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-shadow.tentative.html
new file mode 100644
index 0000000000..b0952dfb9b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-text-shadow.tentative.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: text-decoration</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay does not paint text-shadow">
+<style>
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ text-shadow: 1px 2px rgba(255, 0, 0, 0.5);
+ }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+ let r = new Range();
+ r.setStart(document.body, 0);
+ r.setEnd(document.body, 2);
+
+ CSS.highlights.set("example-highlight", new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001-ref.html
new file mode 100644
index 0000000000..b46c679c9f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001-ref.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<link rel="stylesheet" href="../../css-pseudo/support/highlights.css">
+<meta charset="utf-8">
+<style>
+ :root {
+ writing-mode: vertical-rl;
+ }
+
+ .highlighted {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body>
+<div class="highlight_reftest"><span class="highlighted">One two </span><span>three…</span></div>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001.html
new file mode 100644
index 0000000000..9fe2bdcd5f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/custom-highlight-painting-vertical-writing-mode-001.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: Vertical Writing Mode</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-vertical-writing-mode-001-ref.html">
+<link rel="stylesheet" href="../../css-pseudo/support/highlights.css">
+<meta name="assert" value="::highlight overlay is painted correctly when the highlighted text is in a vertical writing mode">
+<style>
+ :root {
+ writing-mode: vertical-rl;
+ }
+ ::highlight(example-highlight) {
+ background-color: yellow;
+ color: blue;
+ }
+</style>
+<body>
+<div class="highlight_reftest"><span>One </span><span>two </span><span>three…</span></div>
+<script>
+ let r = new Range();
+ r.setStart(document.querySelector("div"), 0);
+ r.setEnd(document.querySelector("div"), 2);
+
+ CSS.highlights.set("example-highlight", new Highlight(r));
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001-ref.html b/testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001-ref.html
new file mode 100644
index 0000000000..a5ec6a59ae
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::highlight dynamic remove text decoration - reference</title>
+<style>
+ #upper {
+ text-decoration: wavy underline overline green 5px;
+ text-underline-offset: 20px;
+ }
+ div {
+ border: solid 1px black;
+ padding: 50px;
+ }
+</style>
+<div id="upper">This line starts with under/over lines that remain.</div>
+<div id="lower">This line starts with under/over lines that are removed.</div>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001.html b/testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001.html
new file mode 100644
index 0000000000..d885424765
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>CSS Highlight API Test: ::highlight dynamic change text-decoration</title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="css-highlight-invalidation-001-ref.html">
+<meta name="assert" content="This test checks that it's possible to modify dynamically the text-decoration of a custom highlight through ::highlight pseudo-element.">
+<meta name="fuzzy" content="0-56;0-10">
+<script src="/common/reftest-wait.js"></script>
+<style>
+ ::highlight(example) {
+ text-decoration: wavy underline overline green 5px;
+ text-underline-offset: 20px;
+ }
+ div {
+ border: solid 1px black;
+ padding: 50px;
+ }
+</style>
+<div id="upper">This line starts with under/over lines that remain.</div>
+<div id="lower">This line starts with under/over lines that are removed.</div>
+<script>
+ let range_upper = new Range();
+ range_upper.setStart(upper, 0);
+ range_upper.setEnd(upper, 1);
+ let range_lower = new Range();
+ range_lower.setStart(lower, 0);
+ range_lower.setEnd(lower, 1);
+ CSS.highlights.set(`example`, new Highlight(range_lower));
+
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ CSS.highlights.set(`example`, new Highlight(range_upper));
+ requestAnimationFrame(() => takeScreenshot());
+ }));
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-code.html b/testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-code.html
new file mode 100644
index 0000000000..a4a1829be2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-code.html
@@ -0,0 +1,13 @@
+<style>
+ ::highlight(foo) {
+ color: blue;
+ background-color: cyan;
+ }
+</style>
+<span id='span-iframe'>abc</span>
+<script>
+ let r = new Range();
+ r.setStart(document.querySelector('#span-iframe'), 0);
+ r.setEnd(document.querySelector('#span-iframe'), 1);
+ CSS.highlights.set('foo', new Highlight(r));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-container.html b/testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-container.html
new file mode 100644
index 0000000000..c89680e28c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/resources/iframe-container.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>
+ ::highlight(highlight1) {
+ text-underline-offset: 1cqw;
+ text-decoration-line: underline;
+ text-decoration-color: green;
+ text-decoration-thickness: 2cqh;
+ }
+</style>
+<div id="h1">With container size</div>
+<script>
+ let r1 = new Range();
+ r1.setStart(h1, 0);
+ r1.setEnd(h1, 1);
+ CSS.highlights.set("highlight1", new Highlight(r1));
+</script>
diff --git a/testing/web-platform/tests/css/css-highlight-api/painting/resources/run-after-layout-and-paint.js b/testing/web-platform/tests/css/css-highlight-api/painting/resources/run-after-layout-and-paint.js
new file mode 100644
index 0000000000..75d3e279a4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-highlight-api/painting/resources/run-after-layout-and-paint.js
@@ -0,0 +1,11 @@
+// This is inspired in runAfterLayoutAndPaint() from
+// third_party/blink/web_tests/resources/run-after-layout-and-paint.js.
+function runAfterLayoutAndPaint(callback) {
+ // See http://crrev.com/c/1395193/10/third_party/blink/web_tests/http/tests/resources/run-after-layout-and-paint.js
+ // for more discussions.
+ requestAnimationFrame(function() {
+ requestAnimationFrame(function() {
+ callback();
+ });
+ });
+} \ No newline at end of file