Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Load a Prism grammar only when a blob names it

1b8675b19e70346d6d02d5fc0c10538f50bf94b2 · Keenan Nemetz · 9d ago · parent 11720250

Load a Prism grammar only when a blob names it

The worker imported prism-languages.min.js — every grammar Prism ships — on
every code page. That is 546 KB to evaluate before the first token, and a page
showing one Go file paid it for all 293 components.

Each component is now vendored as its own file, and prism-manifest.js maps a
language name to the files that define it in dependency order. The worker
starts with Prism's core and the manifest and imports a language's files the
first time a job names it, remembering what it has run so a file is never
imported twice. A Go blob loads 30 KB instead of 564 KB; a .tsx blob, the
widest common entry at 8 files, loads 49 KB.

The manifest also carries the components that register no language of their
own but change one: css-extras, js-extras, js-templates, php-extras, xml-doc.
Each is placed after the grammar it rewrites and included in the entries that
inherit it, so a language that extends javascript now gets js-extras' arrow
and maybe-class-name tokens too. The old bundle's order handed those to some
inheriting languages and not others; nothing loses a token.

scripts/vendor-prism.py writes the grammars and the manifest, and --check
compares them byte for byte with cdnjs. TestPrismLanguagesAreVendored,
TestPrismGrammarsMatchTheManifest and TestPrismWorkerLoadsGrammarsOnDemand
hold the server's extension table, the vendored set and the worker's lazy
import together.

server/web/static/prism-languages/naniscript.js +1

@@ -0,0 +1 @@
1 !function(e){var a=/\{[^\r\n\[\]{}]*\}/,n={"quoted-string":{pattern:/"(?:[^"\\]|\\.)*"/,alias:"operator"},"command-param-id":{pattern:/(\s)\w+:/,lookbehind:!0,alias:"property"},"command-param-value":[{pattern:a,alias:"selector"},{pattern:/([\t ])\S+/,lookbehind:!0,greedy:!0,alias:"operator"},{pattern:/\S(?:.*\S)?/,alias:"operator"}]};function t(e){return"string"==typeof e?e:Array.isArray(e)?e.map(t).join(""):t(e.content)}e.languages.naniscript={comment:{pattern:/^([\t ]*);.*/m,lookbehind:!0},define:{pattern:/^>.+/m,alias:"tag",inside:{value:{pattern:/(^>\w+[\t ]+)(?!\s)[^{}\r\n]+/,lookbehind:!0,alias:"operator"},key:{pattern:/(^>)\w+/,lookbehind:!0}}},label:{pattern:/^([\t ]*)#[\t ]*\w+[\t ]*$/m,lookbehind:!0,alias:"regex"},command:{pattern:/^([\t ]*)@\w+(?=[\t ]|$).*/m,lookbehind:!0,alias:"function",inside:{"command-name":/^@\w+/,expression:{pattern:a,greedy:!0,alias:"selector"},"command-params":{pattern:/\s*\S[\s\S]*/,inside:n}}},"generic-text":{pattern:/(^[ \t]*)[^#@>;\s].*/m,lookbehind:!0,alias:"punctuation",inside:{"escaped-char":/\\[{}\[\]"]/,expression:{pattern:a,greedy:!0,alias:"selector"},"inline-command":{pattern:/\[[\t ]*\w[^\r\n\[\]]*\]/,greedy:!0,alias:"function",inside:{"command-params":{pattern:/(^\[[\t ]*\w+\b)[\s\S]+(?=\]$)/,lookbehind:!0,inside:n},"command-param-name":{pattern:/^(\[[\t ]*)\w+/,lookbehind:!0,alias:"name"},"start-stop-char":/[\[\]]/}}}}},e.languages.nani=e.languages.naniscript,e.hooks.add("after-tokenize",(function(e){e.tokens.forEach((function(e){if("string"!=typeof e&&"generic-text"===e.type){var a=t(e);(function(e){for(var a=[],n=0;n<e.length;n++){var t=e[n],r="[]{}".indexOf(t);if(-1!==r)if(r%2==0)a.push(r+1);else if(a.pop()!==r)return!1}return 0===a.length})(a)||(e.type="bad-line",e.content=a)}}))}))}(Prism);