Highlight API: Invalidate markers' nodes in prepaint phase

Move HighlightRegistry::ValidateHighlightMarkers calls to prepaint phase
so the nodes affected by the markers added/removed are invalidated and
then repainted in the paint phase of this lifecycle.

Also make tests wait until callback is executed.

Bug: 1238845
Change-Id: I998af8632ba21c7c504c99290a3424be7537c569
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3088068
Reviewed-by: Stefan Zager <szager@chromium.org>
Reviewed-by: Dan Clark <daniec@microsoft.com>
Commit-Queue: Fernando Fiori <ffiori@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#911572}
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html
index 909779d..aef391e 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-001.html
@@ -1,9 +1,11 @@
 <!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;
@@ -17,9 +19,9 @@
   r.setEnd(document.body, 2);
 
   // Force frame paint before registering the Highlight.
-  requestAnimationFrame(()=>{
-    requestAnimationFrame(()=>{
-      CSS.highlights.set("example-highlight", new Highlight(r));
-    });
+  runAfterLayoutAndPaint(()=>{
+    CSS.highlights.set("example-highlight", new Highlight(r));
+    document.documentElement.removeAttribute("class");
   });
-</script>
\ No newline at end of file
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html
index 197b9a4..99271ff 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-002.html
@@ -1,9 +1,11 @@
 <!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;
@@ -18,9 +20,9 @@
   CSS.highlights.set("example-highlight", new Highlight(r));
 
   // Force frame paint before deleting the Highlight.
-  requestAnimationFrame(()=>{
-    requestAnimationFrame(()=>{
-      CSS.highlights.delete("example-highlight");
-    });
+  runAfterLayoutAndPaint(()=>{
+    CSS.highlights.delete("example-highlight");
+    document.documentElement.removeAttribute("class");
   });
-</script>
\ No newline at end of file
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html
index a02d050..d1f8722 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-003.html
@@ -1,9 +1,11 @@
 <!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;
@@ -16,10 +18,10 @@
   CSS.highlights.set("example-highlight", new Highlight(r));
 
   // Force frame paint before modifying the Highlight's range.
-  requestAnimationFrame(()=>{
-    requestAnimationFrame(()=>{
-      r.setStart(document.body, 0);
-      r.setEnd(document.body, 2);
-    });
+  runAfterLayoutAndPaint(()=>{
+    r.setStart(document.body, 0);
+    r.setEnd(document.body, 2);
+    document.documentElement.removeAttribute("class");
   });
-</script>
\ No newline at end of file
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html
index 2b22743..62f05a8 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-004.html
@@ -1,9 +1,11 @@
 <!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;
@@ -19,9 +21,9 @@
   CSS.highlights.set("example-highlight", h);
 
   // Force frame paint before modifying the Highlight.
-  requestAnimationFrame(()=>{
-    requestAnimationFrame(()=>{
-      h.add(r);
-    });
+  runAfterLayoutAndPaint(()=>{
+    h.add(r);
+    document.documentElement.removeAttribute("class");
   });
-</script>
\ No newline at end of file
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html
index b22b7d7..cabc4c3 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-005.html
@@ -1,9 +1,11 @@
 <!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;
@@ -27,9 +29,9 @@
   CSS.highlights.set("another-highlight", h2);
 
   // Force frame paint before modifying the Highlight.
-  requestAnimationFrame(()=>{
-    requestAnimationFrame(()=>{
-      h1.priority = 3;
-    });
+  runAfterLayoutAndPaint(()=>{
+    h1.priority = 3;
+    document.documentElement.removeAttribute("class");
   });
-</script>
\ No newline at end of file
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html
index d773a01..81c2298 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-invalidation-006.html
@@ -1,9 +1,11 @@
 <!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;
@@ -11,18 +13,18 @@
   }
 </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 ";
+<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.
-    requestAnimationFrame(()=>{
-      requestAnimationFrame(()=>{
-        document.body.insertBefore(newNode, document.body.firstChild);
-      });
-    });
-  </script>
\ No newline at end of file
+  // Force frame paint before inserting a new node.
+  runAfterLayoutAndPaint(()=>{
+    document.body.insertBefore(newNode, document.body.firstChild);
+    document.documentElement.removeAttribute("class");
+  });
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html
index fa3d7ce..14e9766 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-004.html
@@ -1,9 +1,11 @@
 <!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;
@@ -20,9 +22,9 @@
 
   const targetSpan = document.querySelector("#target");
   // Force frame paint before changing targetSpan's id.
-  requestAnimationFrame( () => {
-    requestAnimationFrame( () => {
-      targetSpan.id = "contained";
-    });
+  runAfterLayoutAndPaint(()=>{
+    targetSpan.id = "contained";
+    document.documentElement.removeAttribute("class");
   });
-</script>
\ No newline at end of file
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html
index ab486ae..b955b0f 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html
@@ -1,9 +1,11 @@
 <!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;
@@ -20,9 +22,9 @@
 
   const targetSpan = document.querySelector("#contained");
   // Force frame paint before changing targetSpan's id.
-  requestAnimationFrame( () => {
-    requestAnimationFrame( () => {
-      targetSpan.id = "not-contained";
-    });
+  runAfterLayoutAndPaint(()=>{
+    targetSpan.id = "not-contained";
+    document.documentElement.removeAttribute("class");
   });
-</script>
\ No newline at end of file
+</script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-006.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-006.html
index 52ab8c7..8436102 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-006.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-006.html
@@ -1,9 +1,11 @@
 <!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;
@@ -19,9 +21,9 @@
   document.adoptedStyleSheets = [styles];
 
   // Force frame paint before changing the style sheet.
-  requestAnimationFrame( () => {
-    requestAnimationFrame( () => {
-      styles.replaceSync(`#target { contain: style; }`);
-    });
+  runAfterLayoutAndPaint(()=>{
+    styles.replaceSync(`#target { contain: style; }`);
+    document.documentElement.removeAttribute("class");
   });
 </script>
+</html>
diff --git a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-007.html b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-007.html
index d56082a..03a7ee6 100644
--- a/css/css-highlight-api/painting/custom-highlight-painting-staticrange-007.html
+++ b/css/css-highlight-api/painting/custom-highlight-painting-staticrange-007.html
@@ -1,9 +1,11 @@
 <!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;
@@ -19,9 +21,9 @@
   CSS.highlights.set("example-highlight", new Highlight(r));
 
   // Force frame paint before changing the style sheet.
-  requestAnimationFrame( () => {
-    requestAnimationFrame( () => {
-      styles.replaceSync(`#target {}`);
-    });
+  runAfterLayoutAndPaint(()=>{
+    styles.replaceSync(`#target {}`);
+    document.documentElement.removeAttribute("class");
   });
 </script>
+</html>
\ No newline at end of file
diff --git a/css/css-highlight-api/painting/resources/run-after-layout-and-paint.js b/css/css-highlight-api/painting/resources/run-after-layout-and-paint.js
new file mode 100644
index 0000000..75d3e27
--- /dev/null
+++ b/css/css-highlight-api/painting/resources/run-after-layout-and-paint.js
@@ -0,0 +1,11 @@
+// This is inspired in runAfterLayoutAndPaint() from
+// third_party/blink/web_tests/resources/run-after-layout-and-paint.js.
+function runAfterLayoutAndPaint(callback) {
+  // See http://crrev.com/c/1395193/10/third_party/blink/web_tests/http/tests/resources/run-after-layout-and-paint.js
+  // for more discussions.
+  requestAnimationFrame(function() {
+    requestAnimationFrame(function() {
+      callback();
+    });
+  });
+}
\ No newline at end of file