| <!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> |