From 83d9a92e64cfe1a7244152c0a4354f79028c75f6 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Thu, 1 Oct 2020 19:14:57 +0200 Subject: [PATCH] CSS: Better HTML style attribute tokenization --- components/prism-css.js | 32 +++++--- components/prism-css.min.js | 2 +- prism.js | 32 +++++--- .../languages/markup!+css/css_inclusion.test | 21 ++--- .../markup+css+wiki/table-tag_feature.test | 78 +++++++++++-------- .../languages/php!+css-extras/issue2008.test | 45 ++++++----- 6 files changed, 121 insertions(+), 89 deletions(-) diff --git a/components/prism-css.js b/components/prism-css.js index b0b56ebfc9..870b2085f9 100644 --- a/components/prism-css.js +++ b/components/prism-css.js @@ -52,19 +52,29 @@ Prism.languages.insertBefore('inside', 'attr-value', { 'style-attr': { - pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, + pattern: /(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i, + lookbehind: true, inside: { - 'attr-name': { - pattern: /^\s*style/i, - inside: markup.tag.inside - }, - 'punctuation': /^\s*=\s*['"]|['"]\s*$/, 'attr-value': { - pattern: /.+/i, - inside: Prism.languages.css - } - }, - alias: 'language-css' + pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, + inside: { + 'style': { + pattern: /(["'])[\s\S]+(?=["']$)/, + lookbehind: true, + alias: 'language-css', + inside: Prism.languages.css + }, + 'punctuation': [ + { + pattern: /^=/, + alias: 'attr-equals' + }, + /"|'/ + ] + } + }, + 'attr-name': /^style/i + } } }, markup.tag); } diff --git a/components/prism-css.min.js b/components/prism-css.min.js index f2197a3c66..eac256916b 100644 --- a/components/prism-css.min.js +++ b/components/prism-css.min.js @@ -1 +1 @@ -!function(e){var s=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+s.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+s.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+s.source+")*?(?=\\s*\\{)"),string:{pattern:s,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var t=e.languages.markup;t&&(t.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:t.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},t.tag))}(Prism); \ No newline at end of file +!function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var s=e.languages.markup;s&&(s.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i,lookbehind:!0,inside:{"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{style:{pattern:/(["'])[\s\S]+(?=["']$)/,lookbehind:!0,alias:"language-css",inside:e.languages.css},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},"attr-name":/^style/i}}},s.tag))}(Prism); \ No newline at end of file diff --git a/prism.js b/prism.js index 86886596b9..487be2bf8b 100644 --- a/prism.js +++ b/prism.js @@ -1384,19 +1384,29 @@ Prism.languages.rss = Prism.languages.xml; Prism.languages.insertBefore('inside', 'attr-value', { 'style-attr': { - pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, + pattern: /(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i, + lookbehind: true, inside: { - 'attr-name': { - pattern: /^\s*style/i, - inside: markup.tag.inside - }, - 'punctuation': /^\s*=\s*['"]|['"]\s*$/, 'attr-value': { - pattern: /.+/i, - inside: Prism.languages.css - } - }, - alias: 'language-css' + pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, + inside: { + 'style': { + pattern: /(["'])[\s\S]+(?=["']$)/, + lookbehind: true, + alias: 'language-css', + inside: Prism.languages.css + }, + 'punctuation': [ + { + pattern: /^=/, + alias: 'attr-equals' + }, + /"|'/ + ] + } + }, + 'attr-name': /^style/i + } } }, markup.tag); } diff --git a/tests/languages/markup!+css/css_inclusion.test b/tests/languages/markup!+css/css_inclusion.test index 69264dbc4e..a29a6f6dea 100644 --- a/tests/languages/markup!+css/css_inclusion.test +++ b/tests/languages/markup!+css/css_inclusion.test @@ -98,17 +98,18 @@ foo { "foo" ]], ["style-attr", [ - ["attr-name", [ - ["attr-name", ["style"]] - ]], - ["punctuation", "=\""], + ["attr-name", "style"], ["attr-value", [ - ["property", "bar"], - ["punctuation", ":"], - "baz", - ["punctuation", ";"] - ]], - ["punctuation", "\""] + ["punctuation", "="], + ["punctuation", "\""], + ["style", [ + ["property", "bar"], + ["punctuation", ":"], + "baz", + ["punctuation", ";"] + ]], + ["punctuation", "\""] + ]] ]], ["punctuation", ">"] ]] diff --git a/tests/languages/markup+css+wiki/table-tag_feature.test b/tests/languages/markup+css+wiki/table-tag_feature.test index e3965f9694..8f8f61e24b 100644 --- a/tests/languages/markup+css+wiki/table-tag_feature.test +++ b/tests/languages/markup+css+wiki/table-tag_feature.test @@ -68,15 +68,18 @@ baz ["punctuation", "!"], ["table-tag", [ ["style-attr", [ - ["attr-name", [["attr-name", ["style"]]]], - ["punctuation", "=\""], + ["attr-name", "style"], ["attr-value", [ - ["property", "text-align"], - ["punctuation", ":"], - "left", - ["punctuation", ";"] - ]], - ["punctuation", "\""] + ["punctuation", "="], + ["punctuation", "\""], + ["style", [ + ["property", "text-align"], + ["punctuation", ":"], + "left", + ["punctuation", ";"] + ]], + ["punctuation", "\""] + ]] ]], ["table-bar", "|"] ]], " Foo\r\n", @@ -92,30 +95,36 @@ baz ["punctuation", "!"], ["table-tag", [ ["style-attr", [ - ["attr-name", [["attr-name", ["style"]]]], - ["punctuation", "=\""], + ["attr-name", "style"], ["attr-value", [ - ["property", "color"], - ["punctuation", ":"], - "red", - ["punctuation", ";"] - ]], - ["punctuation", "\""] + ["punctuation", "="], + ["punctuation", "\""], + ["style", [ + ["property", "color"], + ["punctuation", ":"], + "red", + ["punctuation", ";"] + ]], + ["punctuation", "\""] + ]] ]], ["table-bar", "|"] ]], " Foo ", ["punctuation", "!!"], ["table-tag", [ ["style-attr", [ - ["attr-name", [["attr-name", ["style"]]]], - ["punctuation", "=\""], + ["attr-name", "style"], ["attr-value", [ - ["property", "color"], - ["punctuation", ":"], - "blue", - ["punctuation", ";"] - ]], - ["punctuation", "\""] + ["punctuation", "="], + ["punctuation", "\""], + ["style", [ + ["property", "color"], + ["punctuation", ":"], + "blue", + ["punctuation", ";"] + ]], + ["punctuation", "\""] + ]] ]], ["table-bar", "|"] ]], " Bar ", @@ -125,15 +134,18 @@ baz ["punctuation", "||"], ["table-tag", [ ["style-attr", [ - ["attr-name", [["attr-name", ["style"]]]], - ["punctuation", "=\""], + ["attr-name", "style"], ["attr-value", [ - ["property", "font-weight"], - ["punctuation", ":"], - "bold", - ["punctuation", ";"] - ]], - ["punctuation", "\""] + ["punctuation", "="], + ["punctuation", "\""], + ["style", [ + ["property", "font-weight"], + ["punctuation", ":"], + "bold", + ["punctuation", ";"] + ]], + ["punctuation", "\""] + ]] ]], ["table-bar", "|"] ]], " bar ", @@ -144,4 +156,4 @@ baz ---------------------------------------------------- Checks for tables and cell attributes. -Note: Markup is loaded before CSS so that inline styles are added into grammar. \ No newline at end of file +Note: Markup is loaded before CSS so that inline styles are added into grammar. diff --git a/tests/languages/php!+css-extras/issue2008.test b/tests/languages/php!+css-extras/issue2008.test index 4710e4ae46..3dc9d01e5e 100644 --- a/tests/languages/php!+css-extras/issue2008.test +++ b/tests/languages/php!+css-extras/issue2008.test @@ -9,31 +9,30 @@ "img" ]], ["style-attr", [ - ["attr-name", [ - ["attr-name", [ - "style" - ]] - ]], - ["punctuation", "=\""], + ["attr-name", "style"], ["attr-value", [ - ["property", "width"], - ["punctuation", ":"], - ["php", [ - ["delimiter", ""] + ["punctuation", "="], + ["punctuation", "\""], + ["style", [ + ["property", "width"], + ["punctuation", ":"], + ["php", [ + ["delimiter", ""] + ]], + "%" ]], - "%" - ]], - ["punctuation", "\""] + ["punctuation", "\""] + ]] ]], ["punctuation", "/>"] ]]