Update web-platform-tests to revision b'468d01bbd84da2babf265c6af46947be68713440'

This commit is contained in:
WPT Sync Bot 2021-09-07 11:16:33 +00:00 committed by cybai
parent 35e95f55a1
commit 58e8ee674b
9438 changed files with 266112 additions and 106976 deletions

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,41 @@
<!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)"]) {
test(() => {
let style = getComputedStyle(target, illHighlightPseudo);
let defaultStyle = getComputedStyle(target);
assert_equals(style.backgroundColor, defaultStyle.backgroundColor, "Background color is element's default.");
assert_equals(style.color, defaultStyle.color, "Color is element's default.");
}, `getComputedStyle() for ${illHighlightPseudo} should be element's default`);
}
</script>

View file

@ -0,0 +1,21 @@
<!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(`::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>

View file

@ -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'],
});
}
);

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,8 @@
<!doctype html>
<meta charset="utf-8">
<style>
div {
color: red;
}
</style>
<body><div>abc</div>

View file

@ -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>

View file

@ -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.

View file

@ -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>

View file

@ -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>

View file

@ -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-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).">
<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>

View file

@ -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>

View file

@ -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-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).">
<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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,3 @@
<!doctype html>
<meta charset="utf-8">
<body><span>One two three…</span>

View file

@ -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-staticrange-001-ref.html">
<meta name="assert" value="StaticRanges that are invalid, collapsed or that cross only one boundary of a css-contain node should not be painted when they're in a Highlight">
<style>
::highlight(example-highlight) {
background-color: yellow;
color: blue;
}
#second {
contain: style;
}
</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}));
h.add(new StaticRange({startContainer: document.querySelector("#first").firstChild, startOffset: 1, endContainer: document.querySelector("#second").firstChild, endOffset: 2}));
h.add(new StaticRange({startContainer: document.querySelector("#second").firstChild, startOffset: 1, endContainer: document.querySelector("#third").firstChild, endOffset: 2}));
CSS.highlights.set("example-highlight", h);
</script>

View file

@ -0,0 +1,21 @@
<!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="StaticRanges crossing both boundaries of a css-contain (i.e. containing it entirely) should be painted">
<style>
::highlight(example-highlight) {
background-color: yellow;
color: blue;
}
#contained {
contain: style;
}
</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[2], endOffset: 0}));
CSS.highlights.set("example-highlight", h);
</script>

View file

@ -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>

View file

@ -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-staticrange-001-ref.html">
<meta name="assert" value="Highlight is repainted correctly after a node crossed by a StaticRange becomes a containment (so the range is not painted anymore)">
<script src="resources/run-after-layout-and-paint.js"></script>
<style>
::highlight(example-highlight) {
background-color: yellow;
color: blue;
}
#contained {
contain: style;
}
</style>
<body><span>One </span><span id="target"><span>two </span><span>three…</span></span>
<script>
let r = new StaticRange({startContainer: document.body, startOffset: 0, endContainer: document.querySelector("#target"), endOffset: 1});
CSS.highlights.set("example-highlight", new Highlight(r));
const targetSpan = document.querySelector("#target");
// Force frame paint before changing targetSpan's id.
runAfterLayoutAndPaint(()=>{
targetSpan.id = "contained";
document.documentElement.removeAttribute("class");
});
</script>
</html>

View file

@ -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 is repainted correctly after a node crossed by a StaticRange is not a containment anymore (so the range should be painted now)">
<script src="resources/run-after-layout-and-paint.js"></script>
<style>
::highlight(example-highlight) {
background-color: yellow;
color: blue;
}
#contained {
contain: style;
}
</style>
<body><span>One </span><span id="contained"><span>two </span><span>three…</span></span>
<script>
let r = new StaticRange({startContainer: document.body, startOffset: 0, endContainer: document.querySelector("#contained"), endOffset: 1});
CSS.highlights.set("example-highlight", new Highlight(r));
const targetSpan = document.querySelector("#contained");
// Force frame paint before changing targetSpan's id.
runAfterLayoutAndPaint(()=>{
targetSpan.id = "not-contained";
document.documentElement.removeAttribute("class");
});
</script>
</html>

View file

@ -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-staticrange-001-ref.html">
<meta name="assert" value="Highlight is repainted correctly after a node crossed by a StaticRange becomes a containment because of a CSSStyleSheet change (so the range should be painted now)">
<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 id="target"><span>two </span><span>three…</span></span>
<script>
let r = new StaticRange({startContainer: document.body, startOffset: 0, endContainer: document.querySelector("#target"), endOffset: 1});
CSS.highlights.set("example-highlight", new Highlight(r));
let styles = new CSSStyleSheet();
document.adoptedStyleSheets = [styles];
// Force frame paint before changing the style sheet.
runAfterLayoutAndPaint(()=>{
styles.replaceSync(`#target { contain: style; }`);
document.documentElement.removeAttribute("class");
});
</script>
</html>

View file

@ -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 is repainted correctly after a node crossed by a StaticRange is not a containment anymore because of a CSSStyleSheet change (so the range should be painted now)">
<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 id="target"><span>two </span><span>three…</span></span>
<script>
let r = new StaticRange({startContainer: document.body, startOffset: 0, endContainer: document.querySelector("#target"), endOffset: 1});
let styles = new CSSStyleSheet();
styles.replaceSync(`#target { contain: style; }`);
document.adoptedStyleSheets = [styles];
CSS.highlights.set("example-highlight", new Highlight(r));
// Force frame paint before changing the style sheet.
runAfterLayoutAndPaint(()=>{
styles.replaceSync(`#target {}`);
document.documentElement.removeAttribute("class");
});
</script>
</html>

View file

@ -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>

View file

@ -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();
});
});
}