Highlight API: Implement painting behavior

- Add painting code and HighlightMarker.
- Add visual update when a Range, registered Highlight or
HighlightRegistry is modified.
- Add StaticRange validation when validating HighlightMarkers.
- Move CheckForDifferentRootContainer() to
AbstractRange::HasDifferentRootContainer().
- Add correct ordering of HighlightMarkers for painting (includes
Highlight prioritization).

Bug: 1185234, 1185946
Change-Id: I6959b4cc444233c1aafbeea5f9ff011ace637555
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2857439
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: Sanket Joshi <sajos@microsoft.com>
Reviewed-by: Mason Freed <masonf@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Fernando Fiori <ffiori@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#893033}
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-001-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-001-ref.html
new file mode 100644
index 0000000..b058789
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-001-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+    .highlighted {
+      background-color: yellow;
+      color: blue;
+    }
+</style>
+<body><span class="highlighted">One two </span><span>three…</span>
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-001.html b/css/css-highlight-api/painting/custom-highlight-painting-001.html
new file mode 100644
index 0000000..ede3383
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-001.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="::highlight overlay is painted">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 2);
+
+  CSS.highlights.add(new Highlight("example-highlight", r));
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-002-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-002-ref.html
new file mode 100644
index 0000000..d063bbd
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-002-ref.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+  div {
+    color: red;
+  }
+</style>
+<body><div>abc</div>
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-002.html b/css/css-highlight-api/painting/custom-highlight-painting-002.html
new file mode 100644
index 0000000..0926c35
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-002.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-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);
+  CSS.highlights.add(new Highlight('foo', r));
+  CSS.highlights.add(new Highlight('bar', r));
+</script>
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-003-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-003-ref.html
new file mode 100644
index 0000000..b2dccfa
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-003-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+  span { background-color: rgba(0, 0, 255, 0.3); }
+</style>
+<body>L<span>orem I</span>psum.
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-003.html b/css/css-highlight-api/painting/custom-highlight-painting-003.html
new file mode 100644
index 0000000..972a0e6
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-003.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-003-ref.html">
+<meta name="assert" value="Intersections of overlapping ranges contained in the same Highlight are painted only once">
+<style>
+  ::highlight(sample) { background-color: rgba(0, 0, 255, 0.3); }
+</style>
+<body>Lorem Ipsum.
+<script>
+  let textNode = document.body.firstChild;
+
+  let r1 = new Range();
+  r1.setStart(textNode, 1);
+  r1.setEnd(textNode, 5);
+
+  let r2 = new Range();
+  r2.setStart(textNode, 3);
+  r2.setEnd(textNode, 7);
+
+  CSS.highlights.add(new Highlight("sample", r1, r2));
+</script>
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-004-2-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-004-2-ref.html
new file mode 100644
index 0000000..4ad1de6
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-004-2-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+  .foo {
+    color:blue;
+    background-color:yellow;
+  }
+  .bar {
+    color:orange;
+  }
+  .bar-over-foo {
+    color:orange;
+    background-color:yellow;
+  }
+</style>
+<body><span class="foo">Som</span><span class="bar-over-foo">e t</span><span class="bar">ext</span>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-004-2.html b/css/css-highlight-api/painting/custom-highlight-painting-004-2.html
new file mode 100644
index 0000000..accbd8b
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-004-2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-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("foo", r1);
+  let h2 = new Highlight("bar", r2);
+
+  CSS.highlights.add(h1);
+  CSS.highlights.add(h2);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-004-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-004-ref.html
new file mode 100644
index 0000000..8cb5b69
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-004-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+  .foo {
+    color:blue;
+    background-color:yellow;
+  }
+  .bar {
+    background-color:orange;
+  }
+  .bar-over-foo {
+    color:blue;
+    background-color:orange;
+  }
+</style>
+<body><span class="foo">Som</span><span class="bar-over-foo">e t</span><span class="bar">ext</span>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-004.html b/css/css-highlight-api/painting/custom-highlight-painting-004.html
new file mode 100644
index 0000000..4ca7979
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-004.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-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("foo", r1);
+  let h2 = new Highlight("bar", r2);
+
+  CSS.highlights.add(h1);
+  CSS.highlights.add(h2);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-005.html b/css/css-highlight-api/painting/custom-highlight-painting-005.html
new file mode 100644
index 0000000..9209d94
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-005.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after modifying (setEnd()) a Range contained in it">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 1);
+  CSS.highlights.add(new Highlight("example-highlight", r));
+  r.setEnd(document.body, 2);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-006.html b/css/css-highlight-api/painting/custom-highlight-painting-006.html
new file mode 100644
index 0000000..4a9e88b
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-006.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after modifying (setStart()) a Range contained in it">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 1);
+  r.setEnd(document.body, 2);
+  CSS.highlights.add(new Highlight("example-highlight", r));
+  r.setStart(document.body, 0);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-007.html b/css/css-highlight-api/painting/custom-highlight-painting-007.html
new file mode 100644
index 0000000..0e58131
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-007.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after adding a Range to it after registering it in the HighlightRegistry">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r1 = new Range();
+  r1.setStart(document.body, 0);
+  r1.setEnd(document.body, 1);
+  let h = new Highlight("example-highlight", r1);
+  let r2 = new Range();
+  r2.setStart(document.body, 1);
+  r2.setEnd(document.body, 2);
+  CSS.highlights.add(h);
+  h.add(r2);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-008.html b/css/css-highlight-api/painting/custom-highlight-painting-008.html
new file mode 100644
index 0000000..68b4b8c
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-008.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted after deleting a Range from it after registering it in the HighlightRegistry">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r1 = new Range();
+  r1.setStart(document.body, 0);
+  r1.setEnd(document.body, 2);
+  let r2 = new Range();
+  r2.setStart(document.body, 1);
+  r2.setEnd(document.body, 3);
+  let h = new Highlight("example-highlight", r1, r2);
+  CSS.highlights.add(h);
+  h.delete(r2);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-009.html b/css/css-highlight-api/painting/custom-highlight-painting-009.html
new file mode 100644
index 0000000..9214c16
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-009.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly when collapsing a Range after registering a Highlight that contains it in the HighlightRegistry">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+  ::highlight(another-highlight) {
+    background-color: red;
+    color: orange;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r1 = new Range();
+  r1.setStart(document.body, 0);
+  r1.setEnd(document.body, 2);
+  let r2 = new Range();
+  r2.setStart(document.body, 1);
+  r2.setEnd(document.body, 3);
+  let h1 = new Highlight("example-highlight", r1);
+  let h2 = new Highlight("another-highlight", r2);
+  CSS.highlights.add(h1);
+  CSS.highlights.add(h2);
+  r2.collapse();
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-010.html b/css/css-highlight-api/painting/custom-highlight-painting-010.html
new file mode 100644
index 0000000..ca5755d
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-010.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after inserting a node in the middle of a Range contained in it">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>two </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 1);
+  CSS.highlights.add(new Highlight("example-highlight", r));
+  let newNode = document.createElement("span");
+  newNode.innerText = "One ";
+  document.body.insertBefore(newNode, document.body.firstChild);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-011.html b/css/css-highlight-api/painting/custom-highlight-painting-011.html
new file mode 100644
index 0000000..f37680e
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-011.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after removing a node included in a Range contained in it">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>One </span><span>two </span><span>two-point-five </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 3);
+  CSS.highlights.add(new Highlight("example-highlight", r));
+  document.body.removeChild(document.body.children[2]);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-012.html b/css/css-highlight-api/painting/custom-highlight-painting-012.html
new file mode 100644
index 0000000..eb3cbea
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-012.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after modifying the inner text of a node included in a Range contained in it">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>Zero </span><span>two </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 2);
+  CSS.highlights.add(new Highlight("example-highlight", r));
+  document.body.firstChild.innerText = "One ";
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-013.html b/css/css-highlight-api/painting/custom-highlight-painting-013.html
new file mode 100644
index 0000000..6bb21bf
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-013.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after modifying text content of a node included in a Range contained in it">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span id="first">One </span><span id="second">two-point-five </span><span id="third">three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.querySelector("#first").firstChild, 0);
+  r.setEnd(document.querySelector("#third").firstChild, 0);
+  CSS.highlights.add(new Highlight("example-highlight", r));
+  document.querySelector("#second").firstChild.textContent = "two ";
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-below-grammar-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-below-grammar-ref.html
new file mode 100644
index 0000000..d660daf
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-below-grammar-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+  ::grammar-error {
+    background-color: lime;
+    color: green;
+  }
+</style>
+<span>Many thing can happen.</span>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html b/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html
new file mode 100644
index 0000000..f6b4839
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-below-grammar-ref.html">
+<meta name="assert" value="Highlight overlay is painted below all other pseudo overlays (comparing only to grammar suffices since it's the one immediately above ::highlight, assuming ::grammar-error is painted in the correct order)">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+  ::grammar-error {
+    background-color: lime;
+    color: green;
+  }
+</style>
+<!--
+  The grammar mistakes in the text below are intentional and part of this test.
+
+  https://html.spec.whatwg.org/multipage/interaction.html#spelling-and-grammar-checking
+  • contenteditable makes the text “checkable for the purposes of [spelling and grammar checking]”
+  • spellcheck tries to enable spelling and grammar checking (subject to user preferences)
+  • lang tries to guide the UA towards checking the text in English (but the UA may ignore this)
+-->
+<span contenteditable="true" spellcheck="true" lang="en">Many thing can happen.</div>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 1);
+  CSS.highlights.add(new Highlight("example-highlight", r));
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-below-target-text-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-below-target-text-ref.html
new file mode 100644
index 0000000..70d6926
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-below-target-text-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<style>
+  #highlight {
+    background-color: yellow;
+    color: limegreen;
+  }
+  #highlight-and-target-text {
+    background-color: orange;
+    color: limegreen;
+  }
+  #target-text {
+    background-color: orange;
+  }
+</style>
+<span id="highlight">Some </span><span id="highlight-and-target-text">te</span><span id="target-text">xt</span>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html b/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html
new file mode 100644
index 0000000..99e7af7
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-below-target-text-ref.html">
+<meta name="assert" value="Style properties defined in a ::highlight shouldn't be overriden by default values if there's another pseudo overlay painted on top of it (::target-text in this case) which doesn't specify a value for that property (color in this case)">
+<style>
+  ::highlight(foo) {
+    color:limegreen;
+    background-color:yellow;
+  }
+  ::target-text {
+    background-color:orange;
+  }
+</style>
+<body>Some text
+<script>
+  let r = new Range();
+  r.setStart(document.body.firstChild, 0);
+  r.setEnd(document.body.firstChild, 7);
+  CSS.highlights.add(new Highlight("foo", r));
+  window.location.href = `custom-highlight-painting-below-target-text.html#:~:text=text`;
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-prioritization-001.html b/css/css-highlight-api/painting/custom-highlight-painting-prioritization-001.html
new file mode 100644
index 0000000..88c7716
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-prioritization-001.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlights are prioritized correctly by changing their .priority (higher priority is painted on top no matter the order of insertion into the HighlightRegistry)">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+  ::highlight(another-highlight) {
+    background-color: red;
+    color: orange;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 2);
+  let h1 = new Highlight("example-highlight", r);
+  let h2 = new Highlight("another-highlight", r);
+  h1.priority = 2;
+  h2.priority = 1;
+  CSS.highlights.add(h1);
+  CSS.highlights.add(h2);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-prioritization-002.html b/css/css-highlight-api/painting/custom-highlight-painting-prioritization-002.html
new file mode 100644
index 0000000..9c9b05c
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-prioritization-002.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlights are repainted correctly when changing their priority after adding them to the HighlightRegistry">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+  ::highlight(another-highlight) {
+    background-color: red;
+    color: orange;
+  }
+</style>
+<body><span>One </span><span>two </span><span>three…</span>
+<script>
+  let r = new Range();
+  r.setStart(document.body, 0);
+  r.setEnd(document.body, 2);
+  let h1 = new Highlight("example-highlight", r);
+  let h2 = new Highlight("another-highlight", r);
+  CSS.highlights.add(h1);
+  CSS.highlights.add(h2);
+  h1.priority = 1;
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001-ref.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001-ref.html
new file mode 100644
index 0000000..a89d86d
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<meta charset="utf-8">
+<body><span>One two three…</span>
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001.html
new file mode 100644
index 0000000..1d0a6f9
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-001.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-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("example-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.add(h);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-002.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-002.html
new file mode 100644
index 0000000..ed280f7
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-002.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </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("example-highlight");
+  h.add(new StaticRange({startContainer: document.body.firstChild.childNodes[0], startOffset: 0, endContainer: document.body.firstChild.childNodes[2], endOffset: 0}));
+  CSS.highlights.add(h);
+</script>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-003.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-003.html
new file mode 100644
index 0000000..e621ca3
--- /dev/null
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-003.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Highlight API Test: </title>
+<link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/">
+<link rel="match" href="custom-highlight-painting-001-ref.html">
+<meta name="assert" value="Highlight is repainted correctly after removing a node included in a StaticRange contained in it (StaticRange not modified)">
+<style>
+  ::highlight(example-highlight) {
+    background-color: yellow;
+    color: blue;
+  }
+</style>
+<body><span>One </span><span>one-point-five </span><span>two </span><span>three…</span>
+<script>
+  let r = new StaticRange({startContainer: document.body, startOffset: 0, endContainer: document.body, endOffset: 2});
+  CSS.highlights.add(new Highlight("example-highlight", r));
+  document.body.removeChild(document.body.children[1]);
+</script>
\ No newline at end of file