diff --git a/components/prism-css-extras.js b/components/prism-css-extras.js index 6000210d59..0ffad78c3b 100644 --- a/components/prism-css-extras.js +++ b/components/prism-css-extras.js @@ -2,7 +2,7 @@ Prism.languages.css.selector = { pattern: Prism.languages.css.selector, inside: { 'pseudo-element': /:(?:after|before|first-letter|first-line|selection)|::[-\w]+/, - 'pseudo-class': /:[-\w]+(?:\(.*\))?/, + 'pseudo-class': /:[-\w]+/, 'class': /\.[-:.\w]+/, 'id': /#[-:.\w]+/, 'attribute': { @@ -35,7 +35,16 @@ Prism.languages.css.selector = { ], 'operator': /[|~*^$]?=/ } - } + }, + 'n-th': { + pattern: /(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/, + lookbehind: true, + inside: { + 'number': /[\dn]+/, + 'operator': /[+-]/ + } + }, + 'punctuation': /[()]/ } }; diff --git a/components/prism-css-extras.min.js b/components/prism-css-extras.min.js index e51f261c17..d1cf1ee5f1 100644 --- a/components/prism-css-extras.min.js +++ b/components/prism-css-extras.min.js @@ -1 +1 @@ -Prism.languages.css.selector={pattern:Prism.languages.css.selector,inside:{"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+(?:\(.*\))?/,class:/\.[-:.\w]+/,id:/#[-:.\w]+/,attribute:{pattern:/\[(?:[^[\]"']|("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1)*\]/,greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)[-*\w\xA0-\uFFFF]*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},attribute:{pattern:/^(\s*)[-\w\xA0-\uFFFF]+/,lookbehind:!0},value:[/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,{pattern:/(=\s*)[-\w\xA0-\uFFFF]+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}}}},Prism.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*/i,lookbehind:!0}}),Prism.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:/#[\da-f]{3,8}/i,entity:/\\[\da-f]{1,8}/i,unit:{pattern:/(\d)(?:%|[a-z]+)/,lookbehind:!0},number:/-?[\d.]+/}); \ No newline at end of file +Prism.languages.css.selector={pattern:Prism.languages.css.selector,inside:{"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-:.\w]+/,id:/#[-:.\w]+/,attribute:{pattern:/\[(?:[^[\]"']|("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1)*\]/,greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)[-*\w\xA0-\uFFFF]*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},attribute:{pattern:/^(\s*)[-\w\xA0-\uFFFF]+/,lookbehind:!0},value:[/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,{pattern:/(=\s*)[-\w\xA0-\uFFFF]+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},punctuation:/[()]/}},Prism.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*/i,lookbehind:!0}}),Prism.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:/#[\da-f]{3,8}/i,entity:/\\[\da-f]{1,8}/i,unit:{pattern:/(\d)(?:%|[a-z]+)/,lookbehind:!0},number:/-?[\d.]+/}); \ No newline at end of file diff --git a/tests/languages/css!+css-extras/selector_feature.test b/tests/languages/css!+css-extras/selector_feature.test index 475ed1b7c4..d42ec7faa6 100644 --- a/tests/languages/css!+css-extras/selector_feature.test +++ b/tests/languages/css!+css-extras/selector_feature.test @@ -1,13 +1,11 @@ foo:after { foo::first-letter { -foo:nth-child(2n+1) { - foo.bar { foo#bar { -#foo > .bar:not(baz):after { +#foo > .bar:hover:after { ---------------------------------------------------- @@ -22,11 +20,6 @@ foo#bar { ["pseudo-element", "::first-letter"] ]], ["punctuation", "{"], - ["selector", [ - "foo", - ["pseudo-class", ":nth-child(2n+1)"] - ]], ["punctuation", "{"], - ["selector", [ "foo", ["class", ".bar"] @@ -41,11 +34,11 @@ foo#bar { ["id", "#foo"], " > ", ["class", ".bar"], - ["pseudo-class", ":not(baz)"], + ["pseudo-class", ":hover"], ["pseudo-element", ":after"] ]], ["punctuation", "{"] ] ---------------------------------------------------- -Checks for pseudo-elements, pseudo-classes, classes and ids inside selectors. \ No newline at end of file +Checks for pseudo-elements, pseudo-classes, classes and ids inside selectors. diff --git a/tests/languages/css!+css-extras/selector_n-th_feature.test b/tests/languages/css!+css-extras/selector_n-th_feature.test new file mode 100644 index 0000000000..0e9dc7b6c2 --- /dev/null +++ b/tests/languages/css!+css-extras/selector_n-th_feature.test @@ -0,0 +1,62 @@ +:nth-child(2n+1) {} +:nth-child(+2n - 1) {} +:nth-child(2n) {} +:nth-child(+5) {} + +---------------------------------------------------- + +[ + ["selector", [ + ["pseudo-class", ":nth-child"], + ["punctuation", "("], + ["n-th", [ + ["number", "2n"], + ["operator", "+"], + ["number", "1"] + ]], + ["punctuation", ")"] + ]], + ["punctuation", "{"], + ["punctuation", "}"], + + ["selector", [ + ["pseudo-class", ":nth-child"], + ["punctuation", "("], + ["n-th", [ + ["operator", "+"], + ["number", "2n"], + ["operator", "-"], + ["number", "1"] + ]], + ["punctuation", ")"] + ]], + ["punctuation", "{"], + ["punctuation", "}"], + + ["selector", [ + ["pseudo-class", ":nth-child"], + ["punctuation", "("], + ["n-th", [ + ["number", "2n"] + ]], + ["punctuation", ")"] + ]], + ["punctuation", "{"], + ["punctuation", "}"], + + ["selector", [ + ["pseudo-class", ":nth-child"], + ["punctuation", "("], + ["n-th", [ + ["operator", "+"], + ["number", "5"] + ]], + ["punctuation", ")"] + ]], + ["punctuation", "{"], + ["punctuation", "}"] +] + +---------------------------------------------------- + +Checks for n-th expressions. diff --git a/tests/languages/css!+css-extras/selector_pseudo-class_feature.test b/tests/languages/css!+css-extras/selector_pseudo-class_feature.test new file mode 100644 index 0000000000..e4dfe15183 --- /dev/null +++ b/tests/languages/css!+css-extras/selector_pseudo-class_feature.test @@ -0,0 +1,59 @@ +foo:hover {} + +:lang(en) {} + +.bar:not(baz:hover):not(.foo) {} + +:where(p:not(.class)) {} + +---------------------------------------------------- + +[ + ["selector", [ + "foo", + ["pseudo-class", ":hover"] + ]], + ["punctuation", "{"], + ["punctuation", "}"], + + ["selector", [ + ["pseudo-class", ":lang"], + ["punctuation", "("], + "en", + ["punctuation", ")"] + ]], + ["punctuation", "{"], + ["punctuation", "}"], + + ["selector", [ + ["class", ".bar"], + ["pseudo-class", ":not"], + ["punctuation", "("], + "baz", + ["pseudo-class", ":hover"], + ["punctuation", ")"], + ["pseudo-class", ":not"], + ["punctuation", "("], + ["class", ".foo"], + ["punctuation", ")"] + ]], + ["punctuation", "{"], + ["punctuation", "}"], + + ["selector", [ + ["pseudo-class", ":where"], + ["punctuation", "("], + "p", + ["pseudo-class", ":not"], + ["punctuation", "("], + ["class", ".class"], + ["punctuation", ")"], + ["punctuation", ")"] + ]], + ["punctuation", "{"], + ["punctuation", "}"] +] + +---------------------------------------------------- + +Checks for pseudo-classes inside selectors.