[css-nesting-ident] Enable relaxed syntax

I2S: https://groups.google.com/a/chromium.org/g/blink-dev/c/Ods7RbPlCjI
Fixed: 1427259
Change-Id: Icf6f434f9e993aee0b32d2046e096b1e183966b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4917199
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1207558}
diff --git a/css/css-nesting/implicit-nesting-ident-recovery.html b/css/css-nesting/implicit-nesting-ident-recovery.html
new file mode 100644
index 0000000..f364832
--- /dev/null
+++ b/css/css-nesting/implicit-nesting-ident-recovery.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>CSS Nesting: Nesting, error recovery</title>
+<link rel="help" href="https://drafts.csswg.org/css-nesting-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #target1 {
+    display:block;
+    display:new-block;
+    color:green;
+  }
+  #target2 {
+    display:block;
+    display:hover {};
+    color:green;
+  }
+</style>
+<div id=target1>Green</div>
+<div id=target2>Green</div>
+<script>
+  test(() => {
+    assert_equals(getComputedStyle(target1).color, 'rgb(0, 128, 0)');
+  }, 'Unknown declaration does not consume subsequent declaration');
+</script>
+<script>
+  test(() => {
+    assert_equals(getComputedStyle(target2).color, 'rgb(0, 128, 0)');
+  }, 'Unknown declaration with blocks does not consume subsequent declaration');
+</script>
diff --git a/css/css-nesting/implicit-nesting-ident.html b/css/css-nesting/implicit-nesting-ident.html
new file mode 100644
index 0000000..d6d06b9
--- /dev/null
+++ b/css/css-nesting/implicit-nesting-ident.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>CSS Nesting: Implicit nesting (ident)</title>
+<link rel="help" href="https://drafts.csswg.org/css-nesting-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #main {
+    div {
+      color: green;
+    }
+  }
+</style>
+<div id=main>
+  <div id=target>
+    Green
+  </div>
+</main>
+<script>
+  test(() => {
+    assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
+  }, 'Nested rule starting with tag');
+</script>
diff --git a/css/css-syntax/custom-property-rule-ambiguity.html b/css/css-syntax/custom-property-rule-ambiguity.html
new file mode 100644
index 0000000..50728bc
--- /dev/null
+++ b/css/css-syntax/custom-property-rule-ambiguity.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<title>CSS Syntax: Rules that look like custom properties</title>
+<link rel="help" href="https://drafts.csswg.org/css-syntax/#consume-qualified-rule">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style id=stylesheet1>
+  .a { }
+  --x:hover { } /* Ambiguous "rule" */
+  .b { }
+</style>
+<script>
+  test(() => {
+    let rules = stylesheet1.sheet.rules;
+    assert_equals(rules.length, 2);
+    assert_equals(rules[0].selectorText, '.a');
+    assert_equals(rules[1].selectorText, '.b');
+  }, 'Rule that looks like a custom property declaration is ignored');
+</script>
+
+<!-- https://github.com/w3c/csswg-drafts/issues/9336 -->
+<style id=stylesheet2>
+  .a { }
+  --x:hover { ] } /* Ambiguous "rule" */
+  .b { }
+</style>
+<script>
+  test(() => {
+    let rules = stylesheet2.sheet.rules;
+    assert_equals(rules.length, 2);
+    assert_equals(rules[0].selectorText, '.a');
+    assert_equals(rules[1].selectorText, '.b');
+  }, 'Rule that looks like an invalid custom property declaration is ignored');
+</script>
+
+<style id=stylesheet3>
+  div {
+    .a { }
+    --x:hover { }
+    .b { }
+  }
+</style>
+<script>
+  test(() => {
+    let rules = stylesheet3.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].selectorText, 'div');
+    let div = rules[0];
+    let x = div.style.getPropertyValue('--x');
+    assert_equals(x, 'hover { }\n    .b { }');
+    let childRules = div.cssRules;
+    assert_equals(childRules.length, 1);
+    assert_equals(childRules[0].selectorText, '.a');
+  }, 'Nested rule that looks like a custom property declaration');
+</script>
+
+<!-- https://github.com/w3c/csswg-drafts/issues/9336 -->
+
+<style id=stylesheet4>
+  div {
+    .a { }
+    --x:hover { ] }
+    .b { }
+  }
+</style>
+<script>
+  test(() => {
+    let rules = stylesheet4.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].selectorText, 'div');
+    let div = rules[0];
+    // There is no valid --x declaration, because mismatched ] is not allowed
+    // in custom properties.
+    let x = div.style.getPropertyValue('--x');
+    assert_equals(x, '');
+    // We should also not have restarted parsing as a nested style rule,
+    // and instead we should have "consumed the remnants of a bad declaration",
+    // which skips to the next semicolon (or end-of-block).
+    // So in other words, there should be no nested '.b.' child rule here.
+    let childRules = div.cssRules;
+    assert_equals(childRules.length, 1);
+    assert_equals(childRules[0].selectorText, '.a');
+  }, 'Nested rule that looks like an invalid custom property declaration');
+</script>
diff --git a/css/css-syntax/trailing-braces.html b/css/css-syntax/trailing-braces.html
new file mode 100644
index 0000000..ac2e8e6
--- /dev/null
+++ b/css/css-syntax/trailing-braces.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>CSS Syntax: trailing braces</title>
+<link rel="help" href="https://drafts.csswg.org/css-syntax-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id=style>
+  #target1 {
+    color:green;
+    color:red{};
+    color:red {};
+  }
+</style>
+<div id=target1>Green</div>
+<script>
+  test(() => {
+    let rules = style.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.color, 'green');
+  }, 'Trailing braces are not valid');
+</script>
diff --git a/css/css-syntax/var-with-blocks.html b/css/css-syntax/var-with-blocks.html
new file mode 100644
index 0000000..915a246
--- /dev/null
+++ b/css/css-syntax/var-with-blocks.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<title>CSS Syntax: {}-blocks in declaration values</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9317">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<!-- Standard properties -->
+
+<style id=plain_var>
+  .a {
+    color: rgb(2, 2, 2);
+    color:var(--x); /* Valid */
+    background-color:rgb(1, 1, 1);
+  }
+</style>
+<script>
+  test(() => {
+    let rules = plain_var.sheet.rules;
+    assert_equals(rules.length, 1);
+    let declarations = rules[0].style;
+    assert_equals(declarations.color, 'var(--x)');
+    assert_equals(declarations.backgroundColor, 'rgb(1, 1, 1)');
+  }, 'Plain var()');
+</script>
+
+<style id=whole_value_block>
+  .a {
+    color: rgb(2, 2, 2);
+    color:{var(--x)}; /* Valid */
+    background-color:rgb(1, 1, 1);
+  }
+</style>
+<script>
+  test(() => {
+    let rules = whole_value_block.sheet.rules;
+    assert_equals(rules.length, 1);
+    let declarations = rules[0].style;
+    assert_equals(declarations.color, '{var(--x)}');
+    assert_equals(declarations.backgroundColor, 'rgb(1, 1, 1)');
+  }, 'Whole-value block with var()');
+</script>
+
+<style id=whole_value_block_with_space>
+  .a {
+    color: rgb(2, 2, 2);
+    color: { var(--x) }; /* Valid */
+    background-color:rgb(1, 1, 1);
+  }
+</style>
+<script>
+  test(() => {
+    let rules = whole_value_block_with_space.sheet.rules;
+    assert_equals(rules.length, 1);
+    let declarations = rules[0].style;
+    assert_equals(declarations.color, '{ var(--x) }');
+    assert_equals(declarations.backgroundColor, 'rgb(1, 1, 1)');
+  }, 'Whole-value block with var() (spaces)');
+</script>
+
+<style id=trailing_block>
+  .a {
+    color: rgb(2, 2, 2);
+    color:var(--x) { }; /* Invalid */
+    background-color:rgb(1, 1, 1);
+  }
+</style>
+<script>
+  test(() => {
+    let rules = trailing_block.sheet.rules;
+    assert_equals(rules.length, 1);
+    let declarations = rules[0].style;
+    assert_equals(declarations.color, 'rgb(2, 2, 2)');
+    assert_equals(declarations.backgroundColor, 'rgb(1, 1, 1)');
+  }, 'Trailing block, leading var()');
+</script>
+
+<style id=leading_block>
+  .a {
+    color: rgb(2, 2, 2);
+    color:{ } var(--x); /* Invalid */
+    background-color:rgb(1, 1, 1);
+  }
+</style>
+<script>
+  test(() => {
+    let rules = leading_block.sheet.rules;
+    assert_equals(rules.length, 1);
+    let declarations = rules[0].style;
+    assert_equals(declarations.color, 'rgb(2, 2, 2)');
+    assert_equals(declarations.backgroundColor, 'rgb(1, 1, 1)');
+  }, 'Leading block, trailing var()');
+</script>
+
+<style id=in_block_var_with_trailing_token>
+  .a {
+    color: rgb(2, 2, 2);
+    color:{ var(--x) } A; /* Invalid */
+    background-color:rgb(1, 1, 1);
+  }
+</style>
+<script>
+  test(() => {
+    let rules = in_block_var_with_trailing_token.sheet.rules;
+    assert_equals(rules.length, 1);
+    let declarations = rules[0].style;
+    assert_equals(declarations.color, 'rgb(2, 2, 2)');
+    assert_equals(declarations.backgroundColor, 'rgb(1, 1, 1)');
+  }, 'In-block var() with trailing token');
+</script>
+
+<style id=in_block_var_with_leading_token>
+  .a {
+    color: rgb(2, 2, 2);
+    color:A { var(--x) }; /* Invalid */
+    background-color:rgb(1, 1, 1);
+  }
+</style>
+<script>
+  test(() => {
+    let rules = in_block_var_with_leading_token.sheet.rules;
+    assert_equals(rules.length, 1);
+    let declarations = rules[0].style;
+    assert_equals(declarations.color, 'rgb(2, 2, 2)');
+    assert_equals(declarations.backgroundColor, 'rgb(1, 1, 1)');
+  }, 'In-block var() with leading token');
+</script>
+
+<!-- Custom Properties -->
+
+<style id=plain_var_custom>
+  .a {
+    --y:var(--x); /* Valid */
+  }
+</style>
+<script>
+  test(() => {
+    let rules = plain_var_custom.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.getPropertyValue('--y'), 'var(--x)');
+  }, 'Plain var() (custom property)');
+</script>
+
+<style id=whole_value_block_custom>
+  .a {
+    --y:{var(--x)}; /* Valid */
+  }
+</style>
+<script>
+  test(() => {
+    let rules = whole_value_block_custom.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.getPropertyValue('--y'), '{var(--x)}');
+  }, 'Whole-value block with var() (custom property)');
+</script>
+
+<style id=whole_value_block_with_space_custom>
+  .a {
+    --y: { var(--x) }; /* Valid */
+  }
+</style>
+<script>
+  test(() => {
+    let rules = whole_value_block_with_space_custom.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.getPropertyValue('--y'), '{ var(--x) }');
+  }, 'Whole-value block with var() (spaces, custom property)');
+</script>
+
+<style id=trailing_block_custom>
+  .a {
+    --y:var(--x) { }; /* Valid */
+  }
+</style>
+<script>
+  test(() => {
+    let rules = trailing_block_custom.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.getPropertyValue('--y'), 'var(--x) { }');
+  }, 'Trailing block, leading var() (custom property)');
+</script>
+
+<style id=leading_block_custom>
+  .a {
+    --y:{ } var(--x); /* Valid */
+  }
+</style>
+<script>
+  test(() => {
+    let rules = leading_block_custom.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.getPropertyValue('--y'), '{ } var(--x)');
+  }, 'Leading block, trailing var() (custom property)');
+</script>
+
+<style id=in_block_var_with_trailing_token_custom>
+  .a {
+    --y:{ var(--x) } A; /* Valid */
+  }
+</style>
+<script>
+  test(() => {
+    let rules = in_block_var_with_trailing_token_custom.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.getPropertyValue('--y'), '{ var(--x) } A');
+  }, 'In-block var() with trailing token (custom property)');
+</script>
+
+<style id=in_block_var_with_leading_token_custom>
+  .a {
+    --y:A { var(--x) }; /* Valid */
+  }
+</style>
+<script>
+  test(() => {
+    let rules = in_block_var_with_leading_token_custom.sheet.rules;
+    assert_equals(rules.length, 1);
+    assert_equals(rules[0].style.getPropertyValue('--y'), 'A { var(--x) }');
+  }, 'In-block var() with leading token (custom property)');
+</script>