<!doctype html> <title>An+B Parsing</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style> foo { color: blue; } </style> <meta name="author" title="Tab Atkins-Bittner"> <link rel=help href="https://drafts.csswg.org/css-syntax/#the-anb-type"> <script> function roundtripANB(str) { const rule = document.styleSheets[0].cssRules[0]; rule.selectorText = "foo"; rule.selectorText = `:nth-child(${str})`; // Check for parse error. if(rule.selectorText == "foo") return "parse error"; return rule.selectorText.slice(11, -1); } function testANB(input, expected) { test(()=>{ assert_equals(roundtripANB(input), expected); }, `"${input}" becomes "${expected}"`); } /* Just going down all the syntax clauses one-by-one */ // odd | even | testANB("odd", "2n+1"); testANB("even", "2n"); // <integer> | testANB("1", "1"); testANB("+1", "1"); testANB("-1", "-1"); // // <n-dimension> | testANB("5n", "5n"); testANB("5N", "5n"); // '+'?† n | testANB("+n", "n"); testANB("n", "n"); testANB("N", "n"); testANB("+ n", "parse error"); // -n | testANB("-n", "-n"); testANB("-N", "-n"); // // <ndashdigit-dimension> | testANB("5n-5", "5n-5"); // '+'?† <ndashdigit-ident> | testANB("+n-5", "n-5"); testANB("n-5", "n-5"); testANB("+ n-5", "parse error"); // <dashndashdigit-ident> | testANB("-n-5", "-n-5"); // // <n-dimension> <signed-integer> | testANB("5n +5", "5n+5"); testANB("5n -5", "5n-5"); // '+'?† n <signed-integer> | testANB("+n +5", "n+5"); testANB("n +5", "n+5"); testANB("+n -5", "n-5"); testANB("+ n +5", "parse error"); testANB("n 5", "parse error"); // -n <signed-integer> | testANB("-n +5", "-n+5"); testANB("-n -5", "-n-5"); testANB("-n 5", "parse error"); // // <ndash-dimension> <signless-integer> | testANB("5n- 5", "5n-5"); testANB("5n- -5", "parse error"); testANB("5n- +5", "parse error"); testANB("-5n- 5", "-5n-5"); // '+'?† n- <signless-integer> | testANB("+n- 5", "n-5"); testANB("n- 5", "n-5"); testANB("+ n- 5", "parse error"); testANB("n- +5", "parse error"); testANB("n- -5", "parse error"); // -n- <signless-integer> | testANB("-n- 5", "-n-5"); testANB("-n- +5", "parse error"); testANB("-n- -5", "parse error"); // // <n-dimension> ['+' | '-'] <signless-integer> testANB("5n + 5", "5n+5"); testANB("5n - 5", "5n-5"); testANB("5n + +5", "parse error"); testANB("5n + -5", "parse error"); testANB("5n - +5", "parse error"); testANB("5n - -5", "parse error"); // '+'?† n ['+' | '-'] <signless-integer> | testANB("+n + 5", "n+5"); testANB("n + 5", "n+5"); testANB("+ n + 5", "parse error"); testANB("+n - 5", "n-5"); testANB("+n + +5", "parse error"); testANB("+n + -5", "parse error"); testANB("+n - +5", "parse error"); testANB("+n - -5", "parse error"); // -n ['+' | '-'] <signless-integer> testANB("-n + 5", "-n+5"); testANB("-n - 5", "-n-5"); testANB("-n + +5", "parse error"); testANB("-n + -5", "parse error"); testANB("-n - +5", "parse error"); testANB("-n - -5", "parse error"); /* Swapped ordering is invalid */ testANB("1 - n", "parse error"); testANB("0 - n", "parse error"); testANB("-1 + n", "parse error"); /* Odd space usage */ testANB("2 n + 2", "parse error"); testANB("- 2n", "parse error"); testANB("+ 2n", "parse error"); testANB("+2 n", "parse error"); </script>