From 8e2996e5d3b65928167a0e41355d88c5c2ba5b79 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Thu, 29 Nov 2018 18:47:22 +0100 Subject: [PATCH 1/2] Added support for strings inside CSS selectors --- components/prism-css.js | 100 ++++++++++++---------- components/prism-css.min.js | 2 +- prism.js | 100 ++++++++++++---------- tests/languages/css/selector_feature.test | 15 +++- 4 files changed, 121 insertions(+), 96 deletions(-) diff --git a/components/prism-css.js b/components/prism-css.js index 38c77ca953..2f0ceba23a 100644 --- a/components/prism-css.js +++ b/components/prism-css.js @@ -1,52 +1,58 @@ -Prism.languages.css = { - 'comment': /\/\*[\s\S]*?\*\//, - 'atrule': { - pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i, - inside: { - 'rule': /@[\w-]+/ - // See rest below - } - }, - 'url': /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, - 'selector': /[^{}\s][^{};]*?(?=\s*\{)/, - 'string': { - pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, - greedy: true - }, - 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, - 'important': /!important\b/i, - 'function': /[-a-z0-9]+(?=\()/i, - 'punctuation': /[(){};:]/ -}; +(function (Prism) { -Prism.languages.css['atrule'].inside.rest = Prism.languages.css; + var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/.source; -if (Prism.languages.markup) { - Prism.languages.insertBefore('markup', 'tag', { - 'style': { - pattern: /()[\s\S]*?(?=<\/style>)/i, - lookbehind: true, - inside: Prism.languages.css, - alias: 'language-css', + Prism.languages.css = { + 'comment': /\/\*[\s\S]*?\*\//, + 'atrule': { + pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i, + inside: { + 'rule': /@[\w-]+/ + // See rest below + } + }, + 'url': RegExp('url\\((?:' + string + '|.*?)\\)', 'i'), + 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string + ')*?(?=\\s*\\{)'), + 'string': { + pattern: RegExp(string), greedy: true - } - }); + }, + 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, + 'important': /!important\b/i, + 'function': /[-a-z0-9]+(?=\()/i, + 'punctuation': /[(){};:]/ + }; - Prism.languages.insertBefore('inside', 'attr-value', { - 'style-attr': { - pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, - inside: { - 'attr-name': { - pattern: /^\s*style/i, - inside: Prism.languages.markup.tag.inside + Prism.languages.css['atrule'].inside.rest = Prism.languages.css; + + if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'style': { + pattern: /()[\s\S]*?(?=<\/style>)/i, + lookbehind: true, + inside: Prism.languages.css, + alias: 'language-css', + greedy: true + } + }); + + Prism.languages.insertBefore('inside', 'attr-value', { + 'style-attr': { + pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, + inside: { + 'attr-name': { + pattern: /^\s*style/i, + inside: Prism.languages.markup.tag.inside + }, + 'punctuation': /^\s*=\s*['"]|['"]\s*$/, + 'attr-value': { + pattern: /.+/i, + inside: Prism.languages.css + } }, - 'punctuation': /^\s*=\s*['"]|['"]\s*$/, - 'attr-value': { - pattern: /.+/i, - inside: Prism.languages.css - } - }, - alias: 'language-css' - } - }, Prism.languages.markup.tag); -} + alias: 'language-css' + } + }, Prism.languages.markup.tag); + } + +}(Prism)); diff --git a/components/prism-css.min.js b/components/prism-css.min.js index d761a5c392..06f0f2afdb 100644 --- a/components/prism-css.min.js +++ b/components/prism-css.min.js @@ -1 +1 @@ -Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.languages.css,Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css",greedy:!0}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); \ No newline at end of file +!function(s){var e=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/.source;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:RegExp("url\\((?:"+e+"|.*?)\\)","i"),selector:RegExp("[^{}\\s](?:[^{};\"']|"+e+")*?(?=\\s*\\{)"),string:{pattern:RegExp(e),greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},s.languages.css.atrule.inside.rest=s.languages.css,s.languages.markup&&(s.languages.insertBefore("markup","tag",{style:{pattern:/()[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:s.languages.css,alias:"language-css",greedy:!0}}),s.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:s.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:s.languages.css}},alias:"language-css"}},s.languages.markup.tag))}(Prism); \ No newline at end of file diff --git a/prism.js b/prism.js index 1bb30ec769..172a79fda4 100644 --- a/prism.js +++ b/prism.js @@ -632,58 +632,64 @@ Prism.languages.svg = Prism.languages.markup; Begin prism-css.js ********************************************** */ -Prism.languages.css = { - 'comment': /\/\*[\s\S]*?\*\//, - 'atrule': { - pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i, - inside: { - 'rule': /@[\w-]+/ - // See rest below - } - }, - 'url': /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, - 'selector': /[^{}\s][^{};]*?(?=\s*\{)/, - 'string': { - pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, - greedy: true - }, - 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, - 'important': /!important\b/i, - 'function': /[-a-z0-9]+(?=\()/i, - 'punctuation': /[(){};:]/ -}; +(function (Prism) { -Prism.languages.css['atrule'].inside.rest = Prism.languages.css; + var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/.source; -if (Prism.languages.markup) { - Prism.languages.insertBefore('markup', 'tag', { - 'style': { - pattern: /()[\s\S]*?(?=<\/style>)/i, - lookbehind: true, - inside: Prism.languages.css, - alias: 'language-css', + Prism.languages.css = { + 'comment': /\/\*[\s\S]*?\*\//, + 'atrule': { + pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i, + inside: { + 'rule': /@[\w-]+/ + // See rest below + } + }, + 'url': RegExp('url\\((?:' + string + '|.*?)\\)', 'i'), + 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string + ')*?(?=\\s*\\{)'), + 'string': { + pattern: RegExp(string), greedy: true - } - }); + }, + 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, + 'important': /!important\b/i, + 'function': /[-a-z0-9]+(?=\()/i, + 'punctuation': /[(){};:]/ + }; - Prism.languages.insertBefore('inside', 'attr-value', { - 'style-attr': { - pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, - inside: { - 'attr-name': { - pattern: /^\s*style/i, - inside: Prism.languages.markup.tag.inside + Prism.languages.css['atrule'].inside.rest = Prism.languages.css; + + if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'style': { + pattern: /()[\s\S]*?(?=<\/style>)/i, + lookbehind: true, + inside: Prism.languages.css, + alias: 'language-css', + greedy: true + } + }); + + Prism.languages.insertBefore('inside', 'attr-value', { + 'style-attr': { + pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, + inside: { + 'attr-name': { + pattern: /^\s*style/i, + inside: Prism.languages.markup.tag.inside + }, + 'punctuation': /^\s*=\s*['"]|['"]\s*$/, + 'attr-value': { + pattern: /.+/i, + inside: Prism.languages.css + } }, - 'punctuation': /^\s*=\s*['"]|['"]\s*$/, - 'attr-value': { - pattern: /.+/i, - inside: Prism.languages.css - } - }, - alias: 'language-css' - } - }, Prism.languages.markup.tag); -} + alias: 'language-css' + } + }, Prism.languages.markup.tag); + } + +}(Prism)); /* ********************************************** diff --git a/tests/languages/css/selector_feature.test b/tests/languages/css/selector_feature.test index 5a59720135..227ac755a6 100644 --- a/tests/languages/css/selector_feature.test +++ b/tests/languages/css/selector_feature.test @@ -1,25 +1,38 @@ foo{ + foo + bar { + foo:first-child:hover { + * { + foo, bar{ +[foo="{\"}"] { + ---------------------------------------------------- [ ["selector", "foo"], ["punctuation", "{"], + ["selector", "foo + bar"], ["punctuation", "{"], + ["selector", "foo:first-child:hover"], ["punctuation", "{"], + ["selector", "*"], ["punctuation", "{"], + ["selector", "foo,\r\nbar"], + ["punctuation", "{"], + + ["selector", "[foo=\"{\\\"}\"]"], ["punctuation", "{"] ] ---------------------------------------------------- -Checks for single-line and multi-line selectors. \ No newline at end of file +Checks for single-line and multi-line selectors. From 51383298b4989603c9a1356a778470f35f705642 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 6 Mar 2019 13:18:22 +0100 Subject: [PATCH 2/2] Minor improvement --- components/prism-css.js | 8 ++++---- components/prism-css.min.js | 2 +- prism.js | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/prism-css.js b/components/prism-css.js index 840b7ec918..7a44e1688f 100644 --- a/components/prism-css.js +++ b/components/prism-css.js @@ -1,6 +1,6 @@ (function (Prism) { - var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/.source; + var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/; Prism.languages.css = { 'comment': /\/\*[\s\S]*?\*\//, @@ -11,10 +11,10 @@ // See rest below } }, - 'url': RegExp('url\\((?:' + string + '|.*?)\\)', 'i'), - 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string + ')*?(?=\\s*\\{)'), + 'url': RegExp('url\\((?:' + string.source + '|.*?)\\)', 'i'), + 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'), 'string': { - pattern: RegExp(string), + pattern: string, greedy: true }, 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, diff --git a/components/prism-css.min.js b/components/prism-css.min.js index 97b3740d02..93fbe2db5d 100644 --- a/components/prism-css.min.js +++ b/components/prism-css.min.js @@ -1 +1 @@ -!function(s){var a="(\"|')(?:\\\\(?:\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\n])*\\1";s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?[\s\S]*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:RegExp("url\\((?:"+a+"|.*?)\\)","i"),selector:RegExp("[^{}\\s](?:[^{};\"']|"+a+")*?(?=\\s*\\{)"),string:{pattern:RegExp(a),greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var e=s.languages.markup;e&&(e.tag.addInlined("style","css"),s.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:e.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:s.languages.css}},alias:"language-css"}},e.tag))}(Prism); \ No newline at end of file +!function(s){var e=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?[\s\S]*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:RegExp("url\\((?:"+e.source+"|.*?)\\)","i"),selector:RegExp("[^{}\\s](?:[^{};\"']|"+e.source+")*?(?=\\s*\\{)"),string:{pattern:e,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var a=s.languages.markup;a&&(a.tag.addInlined("style","css"),s.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:a.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:s.languages.css}},alias:"language-css"}},a.tag))}(Prism); \ No newline at end of file diff --git a/prism.js b/prism.js index 84debb50b5..d96b24990c 100644 --- a/prism.js +++ b/prism.js @@ -670,7 +670,7 @@ Prism.languages.svg = Prism.languages.markup; (function (Prism) { - var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/.source; + var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/; Prism.languages.css = { 'comment': /\/\*[\s\S]*?\*\//, @@ -681,10 +681,10 @@ Prism.languages.svg = Prism.languages.markup; // See rest below } }, - 'url': RegExp('url\\((?:' + string + '|.*?)\\)', 'i'), - 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string + ')*?(?=\\s*\\{)'), + 'url': RegExp('url\\((?:' + string.source + '|.*?)\\)', 'i'), + 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'), 'string': { - pattern: RegExp(string), + pattern: string, greedy: true }, 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,