diff --git a/app/assets/javascripts/pretty-text/engines/markdown-it/emoji.js.es6 b/app/assets/javascripts/pretty-text/engines/markdown-it/emoji.js.es6 index 7056cc5a765..dd85d24f34a 100644 --- a/app/assets/javascripts/pretty-text/engines/markdown-it/emoji.js.es6 +++ b/app/assets/javascripts/pretty-text/engines/markdown-it/emoji.js.es6 @@ -171,13 +171,17 @@ function getEmojiTokenByTranslation(content, pos, state) { } } -function applyEmoji(content, state) { +function applyEmoji(content, state, emojiUnicodeReplacer) { let i; let result = null; let contentToken = null; let start = 0; + if (emojiUnicodeReplacer) { + content = emojiUnicodeReplacer(content); + } + let endToken = content.length; for (i=0; i{ - md.core.ruler.push('emoji', state => textReplace(state, applyEmoji)); + md.core.ruler.push('emoji', state => textReplace( + state, (c,s)=>applyEmoji(c,s,md.options.discourse.emojiUnicodeReplacer)) + ); }); } diff --git a/app/assets/javascripts/pretty-text/pretty-text.js.es6 b/app/assets/javascripts/pretty-text/pretty-text.js.es6 index 6f8803b9b03..f2c4633d20c 100644 --- a/app/assets/javascripts/pretty-text/pretty-text.js.es6 +++ b/app/assets/javascripts/pretty-text/pretty-text.js.es6 @@ -21,7 +21,8 @@ export function buildOptions(state) { userId, getCurrentUser, currentUser, - lookupAvatarByPostNumber + lookupAvatarByPostNumber, + emojiUnicodeReplacer } = state; if (!siteSettings.enable_experimental_markdown_it) { @@ -53,6 +54,7 @@ export function buildOptions(state) { currentUser, lookupAvatarByPostNumber, mentionLookup: state.mentionLookup, + emojiUnicodeReplacer, allowedHrefSchemes: siteSettings.allowed_href_schemes ? siteSettings.allowed_href_schemes.split('|') : null, markdownIt: siteSettings.enable_experimental_markdown_it }; diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index 5394ca14aa5..3231301f53a 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -149,6 +149,7 @@ module PrettyText end if SiteSetting.enable_experimental_markdown_it + # defer load markdown it unless context.eval("window.markdownit") ctx_load_manifest(context, "markdown-it-bundle.js") end @@ -168,6 +169,7 @@ module PrettyText __optInput.categoryHashtagLookup = __categoryLookup; __optInput.mentionLookup = __mentionLookup; __optInput.customEmoji = #{custom_emoji.to_json}; + __optInput.emojiUnicodeReplacer = __emojiUnicodeReplacer; JS if opts[:topicId] diff --git a/lib/pretty_text/shims.js b/lib/pretty_text/shims.js index c156fdb0cd7..afb1a199a37 100644 --- a/lib/pretty_text/shims.js +++ b/lib/pretty_text/shims.js @@ -3,7 +3,28 @@ __buildOptions = require('pretty-text/pretty-text').buildOptions; __performEmojiUnescape = require('pretty-text/emoji').performEmojiUnescape; __utils = require('discourse/lib/utilities'); -__setUnicode = require('pretty-text/engines/discourse-markdown/emoji').setUnicodeReplacements; + +__emojiUnicodeReplacer = null; + +__setUnicode = function(replacements) { + require('pretty-text/engines/discourse-markdown/emoji').setUnicodeReplacements(replacements); + + let unicodeRegexp = new RegExp(Object.keys(replacements).sort().reverse().join("|"), "g"); + + __emojiUnicodeReplacer = function(text) { + unicodeRegexp.lastIndex = 0; + let m; + while ((m = unicodeRegexp.exec(text)) !== null) { + let replacement = ":" + replacements[m[0]] + ":"; + const before = text.charAt(m.index-1); + if (!/\B/.test(before)) { + replacement = "\u200b" + replacement; + } + text = text.replace(m[0], replacement); + } + return text; + }; +}; __paths = {}; diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index eddfecf94f2..94ac2971ee4 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -503,13 +503,13 @@ HTML SiteSetting.enable_experimental_markdown_it = true end - # it "replaces skin toned emoji" do - # expect(PrettyText.cook("hello 👱🏿‍♀️")).to eq("

hello \":blonde_woman:t6:\"

") - # expect(PrettyText.cook("hello 👩‍🎤")).to eq("

hello \":woman_singer:\"

") - # expect(PrettyText.cook("hello 👩🏾‍🎓")).to eq("

hello \":woman_student:t5:\"

") - # expect(PrettyText.cook("hello 🤷‍♀️")).to eq("

hello \":woman_shrugging:\"

") - # end - # + it "replaces skin toned emoji" do + expect(PrettyText.cook("hello 👱🏿‍♀️")).to eq("

hello \":blonde_woman:t6:\"

") + expect(PrettyText.cook("hello 👩‍🎤")).to eq("

hello \":woman_singer:\"

") + expect(PrettyText.cook("hello 👩🏾‍🎓")).to eq("

hello \":woman_student:t5:\"

") + expect(PrettyText.cook("hello 🤷‍♀️")).to eq("

hello \":woman_shrugging:\"

") + end + it "supports href schemes" do SiteSetting.allowed_href_schemes = "macappstore|steam"