DEV: Upgrade Markdown.it to v13.0.1 (#17099)

Updates markdown-it to v13.0.1

Noteworthy changes:
* `markdownit()` is now available on `globalThis` instead of `window`.

* The `text_collapse` rule was renamed to `fragments_join` which affected the `bbcode-inline` implementation.

* The `linkify` rule was added to the `inline` chain which affected the handling of the `[url]` BBCode. If available, our implementation reuses `link_open` and `link_close` tokens created by linkify in order to prevent duplicate links.

* The rendered HTML for code changed slightly. There's now a linebreak before the `</code>` tag. The tests were adjusted accordingly.
This commit is contained in:
Gerhard Schlager 2022-06-20 15:25:13 +02:00 committed by GitHub
parent 051167c98a
commit 1c6f8f8a36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 8321 additions and 7971 deletions

View File

@ -21,6 +21,7 @@
"fillIn": "off", "fillIn": "off",
"find": "off", "find": "off",
"getSettledState": "off", "getSettledState": "off",
"globalThis": "readonly",
"hasModule": "off", "hasModule": "off",
"invisible": "off", "invisible": "off",
"jQuery": "off", "jQuery": "off",

View File

@ -877,7 +877,7 @@ eviltrout</p>
assert.cooked( assert.cooked(
" ```\n hello\n ```", " ```\n hello\n ```",
"<pre><code>```\nhello\n```</code></pre>", "<pre><code>```\nhello\n```\n</code></pre>",
"only detect ``` at the beginning of lines" "only detect ``` at the beginning of lines"
); );
@ -925,13 +925,13 @@ eviltrout</p>
assert.cooked( assert.cooked(
" <pre>test</pre>", " <pre>test</pre>",
"<pre><code>&lt;pre&gt;test&lt;/pre&gt;</code></pre>", "<pre><code>&lt;pre&gt;test&lt;/pre&gt;\n</code></pre>",
"it does not parse other block types in markdown code blocks" "it does not parse other block types in markdown code blocks"
); );
assert.cooked( assert.cooked(
" [quote]test[/quote]", " [quote]test[/quote]",
"<pre><code>[quote]test[/quote]</code></pre>", "<pre><code>[quote]test[/quote]\n</code></pre>",
"it does not parse other block types in markdown code blocks" "it does not parse other block types in markdown code blocks"
); );

View File

@ -344,9 +344,9 @@ function buildCustomMarkdownCookFunction(engineOpts, defaultEngineOpts) {
function createMarkdownItEngineWithOpts(markdownitOpts, ruleOverrides) { function createMarkdownItEngineWithOpts(markdownitOpts, ruleOverrides) {
if (ruleOverrides !== undefined) { if (ruleOverrides !== undefined) {
// Preset for "zero", https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js // Preset for "zero", https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js
return window.markdownit("zero", markdownitOpts).enable(ruleOverrides); return globalThis.markdownit("zero", markdownitOpts).enable(ruleOverrides);
} }
return window.markdownit(markdownitOpts); return globalThis.markdownit(markdownitOpts);
} }
function overrideMarkdownFeatures(features, featureOverrides) { function overrideMarkdownFeatures(features, featureOverrides) {

View File

@ -85,7 +85,6 @@ function processBBCode(state, silent) {
let i, let i,
startDelim, startDelim,
endDelim, endDelim,
token,
tagInfo, tagInfo,
delimiters = state.delimiters, delimiters = state.delimiters,
max = delimiters.length; max = delimiters.length;
@ -108,9 +107,11 @@ function processBBCode(state, silent) {
endDelim = delimiters[startDelim.end]; endDelim = delimiters[startDelim.end];
token = state.tokens[startDelim.token];
let tag, className; let tag, className;
const startToken = state.tokens[startDelim.token];
const endToken = state.tokens[endDelim.token];
if (typeof tagInfo.rule.wrap === "function") { if (typeof tagInfo.rule.wrap === "function") {
let content = ""; let content = "";
for (let j = startDelim.token + 1; j < endDelim.token; j++) { for (let j = startDelim.token + 1; j < endDelim.token; j++) {
@ -119,7 +120,7 @@ function processBBCode(state, silent) {
content += inner.content; content += inner.content;
} }
} }
tagInfo.rule.wrap(token, state.tokens[endDelim.token], tagInfo, content); tagInfo.rule.wrap(startToken, endToken, tagInfo, content, state);
continue; continue;
} else { } else {
let split = tagInfo.rule.wrap.split("."); let split = tagInfo.rule.wrap.split(".");
@ -127,21 +128,20 @@ function processBBCode(state, silent) {
className = split.slice(1).join(" "); className = split.slice(1).join(" ");
} }
token.type = "bbcode_" + tagInfo.tag + "_open"; startToken.type = "bbcode_" + tagInfo.tag + "_open";
token.tag = tag; startToken.tag = tag;
if (className) { if (className) {
token.attrs = [["class", className]]; startToken.attrs = [["class", className]];
} }
token.nesting = 1; startToken.nesting = 1;
token.markup = token.content; startToken.markup = startToken.content;
token.content = ""; startToken.content = "";
token = state.tokens[endDelim.token]; endToken.type = "bbcode_" + tagInfo.tag + "_close";
token.type = "bbcode_" + tagInfo.tag + "_close"; endToken.tag = tag;
token.tag = tag; endToken.nesting = -1;
token.nesting = -1; endToken.markup = startToken.content;
token.markup = token.content; endToken.content = "";
token.content = "";
} }
return false; return false;
} }
@ -164,7 +164,7 @@ export function setup(helper) {
md.inline.ruler.push("bbcode-inline", (state, silent) => md.inline.ruler.push("bbcode-inline", (state, silent) =>
tokenizeBBCode(state, silent, ruler) tokenizeBBCode(state, silent, ruler)
); );
md.inline.ruler2.before("text_collapse", "bbcode-inline", processBBCode); md.inline.ruler2.before("fragments_join", "bbcode-inline", processBBCode);
ruler.push("code", { ruler.push("code", {
tag: "code", tag: "code",
@ -176,13 +176,35 @@ export function setup(helper) {
}, },
}); });
const simpleUrlRegex = /^http[s]?:\/\//; const simpleUrlRegex = /^https?:\/\//;
ruler.push("url", { ruler.push("url", {
tag: "url", tag: "url",
wrap(startToken, endToken, tagInfo, content) { wrap(startToken, endToken, tagInfo, content, state) {
const url = (tagInfo.attrs["_default"] || content).trim(); const url = (tagInfo.attrs["_default"] || content).trim();
let linkifyFound = false;
if (simpleUrlRegex.test(url)) { if (state.md.options.linkify) {
const tokens = state.tokens;
const startIndex = tokens.indexOf(startToken);
const endIndex = tokens.indexOf(endToken);
// reuse existing tokens from linkify if they exist
for (let index = startIndex + 1; index < endIndex; index++) {
const token = tokens[index];
if (
token.markup === "linkify" &&
token.info === "auto" &&
token.type === "link_open"
) {
linkifyFound = true;
token.attrs.push(["data-bbcode", "true"]);
break;
}
}
}
if (!linkifyFound && simpleUrlRegex.test(url)) {
startToken.type = "link_open"; startToken.type = "link_open";
startToken.tag = "a"; startToken.tag = "a";
startToken.attrs = [ startToken.attrs = [
@ -214,7 +236,7 @@ export function setup(helper) {
tag: "email", tag: "email",
replace(state, tagInfo, content) { replace(state, tagInfo, content) {
let token; let token;
let email = tagInfo.attrs["_default"] || content; const email = tagInfo.attrs["_default"] || content;
token = state.push("link_open", "a", 1); token = state.push("link_open", "a", 1);
token.attrs = [ token.attrs = [

View File

@ -7,11 +7,10 @@
"license": "GPL-2.0-only", "license": "GPL-2.0-only",
"dependencies": { "dependencies": {
"@discourse/itsatrap": "^2.0.10", "@discourse/itsatrap": "^2.0.10",
"@fortawesome/fontawesome-free": "5.15.4",
"@discourse/moment-timezone-names-translations": "^1.0.0", "@discourse/moment-timezone-names-translations": "^1.0.0",
"@fortawesome/fontawesome-free": "5.15.4",
"@highlightjs/cdn-assets": "^10.7.0", "@highlightjs/cdn-assets": "^10.7.0",
"@json-editor/json-editor": "^2.6.1", "@json-editor/json-editor": "^2.6.1",
"tippy.js": "^6.3.7",
"@popperjs/core": "v2.10.2", "@popperjs/core": "v2.10.2",
"@uppy/aws-s3": "^2.0.8", "@uppy/aws-s3": "^2.0.8",
"@uppy/aws-s3-multipart": "^2.2.1", "@uppy/aws-s3-multipart": "^2.2.1",
@ -29,10 +28,11 @@
"handlebars": "^4.7.7", "handlebars": "^4.7.7",
"jquery": "3.5.1", "jquery": "3.5.1",
"magnific-popup": "1.1.0", "magnific-popup": "1.1.0",
"markdown-it": "10.0.0", "markdown-it": "13.0.1",
"moment": "2.29.2", "moment": "2.29.2",
"moment-timezone": "0.5.31", "moment-timezone": "0.5.31",
"pikaday": "1.8.0", "pikaday": "1.8.0",
"tippy.js": "^6.3.7",
"workbox-cacheable-response": "^4.3.1", "workbox-cacheable-response": "^4.3.1",
"workbox-core": "^4.3.1", "workbox-core": "^4.3.1",
"workbox-expiration": "^4.3.1", "workbox-expiration": "^4.3.1",

File diff suppressed because one or more lines are too long

View File

@ -437,6 +437,11 @@ argparse@^1.0.7:
dependencies: dependencies:
sprintf-js "~1.0.2" sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
arr-diff@^4.0.0: arr-diff@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@ -1375,10 +1380,10 @@ ensure-posix-path@^1.0.0:
resolved "https://registry.yarnpkg.com/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz#3c62bdb19fa4681544289edb2b382adc029179ce" resolved "https://registry.yarnpkg.com/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz#3c62bdb19fa4681544289edb2b382adc029179ce"
integrity sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw== integrity sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==
entities@~2.0.0: entities@~3.0.1:
version "2.0.3" version "3.0.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2:
version "1.18.3" version "1.18.3"
@ -2585,10 +2590,10 @@ lighthouse-logger@^1.0.0:
debug "^2.6.8" debug "^2.6.8"
marky "^1.2.0" marky "^1.2.0"
linkify-it@^2.0.0: linkify-it@^4.0.1:
version "2.2.0" version "4.0.1"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec"
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==
dependencies: dependencies:
uc.micro "^1.0.1" uc.micro "^1.0.1"
@ -2669,14 +2674,14 @@ map-visit@^1.0.0:
dependencies: dependencies:
object-visit "^1.0.0" object-visit "^1.0.0"
markdown-it@10.0.0: markdown-it@13.0.1:
version "10.0.0" version "13.0.1"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430"
integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg== integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==
dependencies: dependencies:
argparse "^1.0.7" argparse "^2.0.1"
entities "~2.0.0" entities "~3.0.1"
linkify-it "^2.0.0" linkify-it "^4.0.1"
mdurl "^1.0.1" mdurl "^1.0.1"
uc.micro "^1.0.5" uc.micro "^1.0.5"