WebKit export: [view-transitions] Implement parsing & checking for pseudo-elements (#43301)

https://bugs.webkit.org/show_bug.cgi?id=265167
diff --git a/css/css-cascade/all-prop-initial-xml.html b/css/css-cascade/all-prop-initial-xml.html
index a04956a..c58a816 100644
--- a/css/css-cascade/all-prop-initial-xml.html
+++ b/css/css-cascade/all-prop-initial-xml.html
@@ -12,20 +12,26 @@
     // we need the empty stylesheet to avoid default XSLT views of the XML
     const style = iframe.contentDocument.createElementNS("http://www.w3.org/1999/xhtml", "style");
     root.appendChild(style);
-    const cs = iframe.contentWindow.getComputedStyle(root);
+
+    // Grab initial styles from a random element, as the root can get non-initial UA styling.
+    const div = iframe.contentDocument.createElementNS("http://www.w3.org/1999/xhtml", "div");
+    root.appendChild(div);
+    const cs = iframe.contentWindow.getComputedStyle(div);
+
     let actual_initial = Object.create(null);
     for (let i = 0; i < cs.length; i++) {
         let prop_name = cs[i];
         actual_initial[prop_name] = cs[prop_name];
     }
+    const rootCS = iframe.contentWindow.getComputedStyle(root);
     test(() => {
         style.textContent = ":root { color: blue }";
-        assert_equals(cs["color"], "rgb(0, 0, 255)");
+        assert_equals(rootCS["color"], "rgb(0, 0, 255)");
     }, "stylesheet takes effect");
     style.textContent = ":root { all: initial; direction: initial; unicode-bidi: initial; } style { display: none; }";
     for (let prop_name in actual_initial) {
         test(() => {
-            assert_equals(cs[prop_name], actual_initial[prop_name]);
+            assert_equals(rootCS[prop_name], actual_initial[prop_name]);
         }, prop_name);
     }
 });
diff --git a/css/css-view-transitions/parsing/pseudo-elements-invalid.html b/css/css-view-transitions/parsing/pseudo-elements-invalid.html
new file mode 100644
index 0000000..5a2624d
--- /dev/null
+++ b/css/css-view-transitions/parsing/pseudo-elements-invalid.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Test pseudo elements parsing of invalid selectors</title>
+<link rel="author" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<script>
+const functionPseudoElements = [
+    "::view-transition-group",
+    "::view-transition-image-pair",
+    "::view-transition-old",
+    "::view-transition-new",
+];
+
+function test_invalid_selector_combinations(pseudo) {
+    test_invalid_selector(`${pseudo}.a`);
+    test_invalid_selector(`${pseudo} div`);
+    test_invalid_selector(`${pseudo}:hover`);
+    test_invalid_selector(`:not(${pseudo})`);
+    test_invalid_selector(`:has(${pseudo})`);
+}
+
+test_invalid_selector_combinations("::view-transition");
+test_invalid_selector("::view-transition(*)");
+test_invalid_selector("::view-transition(valid)");
+test_invalid_selector("::view-transition(root)");
+
+for (const fn of functionPseudoElements) {
+    for (const validArgument of ["*", "valid", "root"]) {
+        test_invalid_selector_combinations(`${fn}(${validArgument})`);
+    }
+
+    // Test function without argument.
+    test_invalid_selector(fn);
+    test_invalid_selector_combinations(fn);
+
+    // Test function with empty argument.
+    test_invalid_selector(`${fn}()`);
+    test_invalid_selector_combinations(`${fn}()`);
+
+    // Test function with keywords excluded from <custom-ident>.
+    test_invalid_selector(`${fn}(default)`);
+    test_invalid_selector_combinations(`${fn}(default)`);
+    test_invalid_selector(`${fn}(unset)`);
+    test_invalid_selector_combinations(`${fn}(unset)`);
+    test_invalid_selector(`${fn}(initial)`);
+    test_invalid_selector_combinations(`${fn}(initial)`);
+    test_invalid_selector(`${fn}(inherit)`);
+    test_invalid_selector_combinations(`${fn}(inherit)`);
+    test_invalid_selector(`${fn}(revert)`);
+    test_invalid_selector_combinations(`${fn}(revert)`);
+    test_invalid_selector(`${fn}(revert-layer)`);
+    test_invalid_selector_combinations(`${fn}(revert-layer)`);
+
+    // Test function with multiple arguments.
+    test_invalid_selector(`${fn}(foo, bar)`);
+    test_invalid_selector_combinations(`${fn}(foo, bar)`);
+    test_invalid_selector(`${fn}(foo bar)`);
+    test_invalid_selector_combinations(`${fn}(foo bar)`);
+
+    // Test function with selector arguments.
+    test_invalid_selector(`${fn}(.foo)`);
+    test_invalid_selector_combinations(`${fn}(.foo)`);
+    test_invalid_selector(`${fn}(#bar)`);
+    test_invalid_selector_combinations(`${fn}(#bar)`);
+}
+</script>
diff --git a/css/css-view-transitions/parsing/pseudo-elements-valid.html b/css/css-view-transitions/parsing/pseudo-elements-valid.html
new file mode 100644
index 0000000..1a0e5b8
--- /dev/null
+++ b/css/css-view-transitions/parsing/pseudo-elements-valid.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Test pseudo elements parsing of valid selectors</title>
+<link rel="author" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<script>
+const functionPseudoElements = [
+    "::view-transition-group",
+    "::view-transition-image-pair",
+    "::view-transition-old",
+    "::view-transition-new",
+];
+
+function test_valid_selector_combinations(pseudo) {
+    test_valid_selector(pseudo);
+    test_valid_selector(`:root${pseudo}`);
+    test_valid_selector(`.a${pseudo}`);
+    test_valid_selector(`div ${pseudo}`);
+}
+
+test_valid_selector_combinations("::view-transition");
+
+for (const functionName of functionPseudoElements) {
+    for (const validArgument of ["*", "root", "dashed-ident"]) {
+        test_valid_selector_combinations(`${functionName}(${validArgument})`);
+        test_valid_selector_combinations(`${functionName}(${validArgument}):only-child`);
+    }
+}
+</script>
diff --git a/css/css-view-transitions/parsing/view-transition-name-computed.html b/css/css-view-transitions/parsing/view-transition-name-computed.html
index 4a13ed5..5b05667 100644
--- a/css/css-view-transitions/parsing/view-transition-name-computed.html
+++ b/css/css-view-transitions/parsing/view-transition-name-computed.html
@@ -12,13 +12,16 @@
 </head>
 <body>
 <div id=target></div>
-<div id=scratch></div>
 <script>
-
 test_computed_value("view-transition-name", "none");
 test_computed_value("view-transition-name", "foo");
 test_computed_value("view-transition-name", "bar");
 test_computed_value("view-transition-name", "baz");
+test_computed_value("view-transition-name", "unset", "none");
+test_computed_value("view-transition-name", "initial", "none");
+test_computed_value("view-transition-name", "inherit", "none");
+test_computed_value("view-transition-name", "revert", "none");
+test_computed_value("view-transition-name", "revert-layer", "none");
 </script>
 </body>
 </html>
diff --git a/css/css-view-transitions/parsing/view-transition-name-invalid.html b/css/css-view-transitions/parsing/view-transition-name-invalid.html
index 7c47053..0151991 100644
--- a/css/css-view-transitions/parsing/view-transition-name-invalid.html
+++ b/css/css-view-transitions/parsing/view-transition-name-invalid.html
@@ -12,6 +12,7 @@
 </head>
 <body>
 <script>
+test_invalid_value("view-transition-name", "default"); // `default` isn't allowed by the `<custom-ident>` syntax.
 test_invalid_value("view-transition-name", "none none");
 test_invalid_value("view-transition-name", `"none"`);
 test_invalid_value("view-transition-name", `"foo"`);