From 21aec0166a07b027218cbbe8e4fe6cbcf9fdd82b Mon Sep 17 00:00:00 2001 From: Soc Sieng Date: Sat, 30 Jul 2022 14:25:25 +1000 Subject: [PATCH 1/3] fix: Ignore emoji shorthand codes in URIs Fixes: #1823 --- src/core/render/emojify.js | 2 ++ test/integration/__snapshots__/emoji.test.js.snap | 2 ++ test/integration/emoji.test.js | 14 ++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/core/render/emojify.js b/src/core/render/emojify.js index 39d7a4ce3..553ec6420 100644 --- a/src/core/render/emojify.js +++ b/src/core/render/emojify.js @@ -35,6 +35,8 @@ export function emojify(text, useNativeEmoji) { ) // Mark colons in comments .replace(//g, m => m.replace(/:/g, '__colon__')) + // Mark colons in URIs + .replace(/[a-z]{2,}:\/\/[^\s]+/gi, m => m.replace(/:/g, '__colon__')) // Replace emoji shorthand codes .replace(/:([a-z0-9_\-+]+?):/g, (m, $1) => replaceEmojiShorthand(m, $1, useNativeEmoji) diff --git a/test/integration/__snapshots__/emoji.test.js.snap b/test/integration/__snapshots__/emoji.test.js.snap index 105cf9df2..f1945350f 100644 --- a/test/integration/__snapshots__/emoji.test.js.snap +++ b/test/integration/__snapshots__/emoji.test.js.snap @@ -2,6 +2,8 @@ exports[`Emoji Ignores all emoji shorthand codes (noEmoji:true) 1`] = `"

:smile:

:smile::smile:

:smile: :smile:

:smile::smile::smile:

:smile: :smile: :smile:

text:smile:

:smile:text

text:smile:text

"`; +exports[`Emoji Ignores emoji shorthand codes in URIs 1`] = `"

Url https://docsify.js.org/:foo:/ http://docsify.js.org/:100:/ ftp://docsify.js.org/:smile:/

"`; + exports[`Emoji Ignores emoji shorthand codes in code, pre, script, and template tags 1`] = ` "
:100:
diff --git a/test/integration/emoji.test.js b/test/integration/emoji.test.js index e19ab8089..00caed26a 100644 --- a/test/integration/emoji.test.js +++ b/test/integration/emoji.test.js @@ -107,6 +107,20 @@ describe('Emoji', function () { expect(mainElm.innerHTML).toMatchSnapshot(); }); + test('Ignores emoji shorthand codes in URIs', async () => { + await docsifyInit({ + markdown: { + homepage: + 'Url https://docsify.js.org/:foo:/ http://docsify.js.org/:100:/ ftp://docsify.js.org/:smile:/', + }, + // _logHTML: true, + }); + + const mainElm = document.querySelector('#main'); + + expect(mainElm.innerHTML).toMatchSnapshot(); + }); + test('Ignores emoji shorthand codes in code, pre, script, and template tags', async () => { await docsifyInit({ markdown: { From feca1cd78f1c105a255bd93d5012b8b641b4061c Mon Sep 17 00:00:00 2001 From: Soc Sieng Date: Sun, 31 Jul 2022 09:07:30 +1000 Subject: [PATCH 2/3] test: Add test for emoji in anchor body --- test/integration/__snapshots__/emoji.test.js.snap | 2 ++ test/integration/emoji.test.js | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/test/integration/__snapshots__/emoji.test.js.snap b/test/integration/__snapshots__/emoji.test.js.snap index f1945350f..69c43f196 100644 --- a/test/integration/__snapshots__/emoji.test.js.snap +++ b/test/integration/__snapshots__/emoji.test.js.snap @@ -4,6 +4,8 @@ exports[`Emoji Ignores all emoji shorthand codes (noEmoji:true) 1`] = `"

:smil exports[`Emoji Ignores emoji shorthand codes in URIs 1`] = `"

Url https://docsify.js.org/:foo:/ http://docsify.js.org/:100:/ ftp://docsify.js.org/:smile:/

"`; +exports[`Emoji Ignores emoji shorthand codes in URIs while handling anchor content 1`] = `"

Achor tags \\"100\\"

"`; + exports[`Emoji Ignores emoji shorthand codes in code, pre, script, and template tags 1`] = ` "
:100:
diff --git a/test/integration/emoji.test.js b/test/integration/emoji.test.js index 00caed26a..288c737ad 100644 --- a/test/integration/emoji.test.js +++ b/test/integration/emoji.test.js @@ -121,6 +121,19 @@ describe('Emoji', function () { expect(mainElm.innerHTML).toMatchSnapshot(); }); + test('Ignores emoji shorthand codes in URIs while handling anchor content', async () => { + await docsifyInit({ + markdown: { + homepage: 'Achor tags [:100:](http://docsify.js.org/:100:/)', + }, + // _logHTML: true, + }); + + const mainElm = document.querySelector('#main'); + + expect(mainElm.innerHTML).toMatchSnapshot(); + }); + test('Ignores emoji shorthand codes in code, pre, script, and template tags', async () => { await docsifyInit({ markdown: { From 62069def38df9a38688ff951ab80bdd02930adfc Mon Sep 17 00:00:00 2001 From: Soc Sieng Date: Wed, 3 Aug 2022 08:46:28 +1000 Subject: [PATCH 3/3] fix: Handle support for URIs used in additional contexts Examples: - Without explicit scheme (i.e. starting with `//`) - In single and double quote strings - Within unquoted HTML tag attributes - In css `url()` values --- src/core/render/emojify.js | 4 ++- .../__snapshots__/emoji.test.js.snap | 4 +++ test/integration/emoji.test.js | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/core/render/emojify.js b/src/core/render/emojify.js index 553ec6420..52467c8f8 100644 --- a/src/core/render/emojify.js +++ b/src/core/render/emojify.js @@ -36,7 +36,9 @@ export function emojify(text, useNativeEmoji) { // Mark colons in comments .replace(//g, m => m.replace(/:/g, '__colon__')) // Mark colons in URIs - .replace(/[a-z]{2,}:\/\/[^\s]+/gi, m => m.replace(/:/g, '__colon__')) + .replace(/([a-z]{2,}:)?\/\/[^\s'">)]+/gi, m => + m.replace(/:/g, '__colon__') + ) // Replace emoji shorthand codes .replace(/:([a-z0-9_\-+]+?):/g, (m, $1) => replaceEmojiShorthand(m, $1, useNativeEmoji) diff --git a/test/integration/__snapshots__/emoji.test.js.snap b/test/integration/__snapshots__/emoji.test.js.snap index 69c43f196..1446cbd86 100644 --- a/test/integration/__snapshots__/emoji.test.js.snap +++ b/test/integration/__snapshots__/emoji.test.js.snap @@ -20,6 +20,10 @@ exports[`Emoji Ignores emoji shorthand codes in code, pre, script, and template exports[`Emoji Ignores emoji shorthand codes in comments 1`] = `"

Text

"`; +exports[`Emoji Ignores emoji shorthand codes in html attributes 1`] = `"

"`; + +exports[`Emoji Ignores emoji shorthand codes in style url() values 1`] = `""`; + exports[`Emoji Ignores unmatched emoji shorthand codes 1`] = `"

hh:mm

hh:mm:ss

Namespace::SubNameSpace

Namespace::SubNameSpace::Class

2014-12-29T16:11:20+00:00

"`; exports[`Emoji Renders GitHub emoji images (nativeEmoji:false) 1`] = `"

\\"smile\\"

\\"smile\\"\\"smile\\"

\\"smile\\" \\"smile\\"

\\"smile\\"\\"smile\\"\\"smile\\"

\\"smile\\" \\"smile\\" \\"smile\\"

text\\"smile\\"

\\"smile\\"text

text\\"smile\\"text

"`; diff --git a/test/integration/emoji.test.js b/test/integration/emoji.test.js index 288c737ad..dfd8516ac 100644 --- a/test/integration/emoji.test.js +++ b/test/integration/emoji.test.js @@ -134,6 +134,32 @@ describe('Emoji', function () { expect(mainElm.innerHTML).toMatchSnapshot(); }); + test('Ignores emoji shorthand codes in html attributes', async () => { + await docsifyInit({ + markdown: { + homepage: ` `, + }, + // _logHTML: true, + }); + + const mainElm = document.querySelector('#main'); + + expect(mainElm.innerHTML).toMatchSnapshot(); + }); + + test('Ignores emoji shorthand codes in style url() values', async () => { + await docsifyInit({ + markdown: { + homepage: ``, + }, + // _logHTML: true, + }); + + const mainElm = document.querySelector('#main'); + + expect(mainElm.innerHTML).toMatchSnapshot(); + }); + test('Ignores emoji shorthand codes in code, pre, script, and template tags', async () => { await docsifyInit({ markdown: {