diff --git a/app/assets/javascripts/pretty-text/emoji.js.es6 b/app/assets/javascripts/pretty-text/emoji.js.es6 index 6e73be91f0e..2089902c3b5 100644 --- a/app/assets/javascripts/pretty-text/emoji.js.es6 +++ b/app/assets/javascripts/pretty-text/emoji.js.es6 @@ -21,11 +21,29 @@ export function extendedEmojiList() { const emojiHash = {}; -const unicodeRegexp = new RegExp( - Object.keys(replacements) +export function buildReplacementsList(emojiReplacements) { + return Object.keys(emojiReplacements) .sort() .reverse() - .join("|") + "|\\B:[^\\s:]+(?::t\\d)?:?\\B", + .map(emoji => { + return emoji + .split("") + .map(chr => { + return ( + "\\u" + + chr + .charCodeAt(0) + .toString(16) + .padStart(4, "0") + ); + }) + .join(""); + }) + .join("|"); +} + +const unicodeRegexp = new RegExp( + buildReplacementsList(replacements) + "|\\B:[^\\s:]+(?::t\\d)?:?\\B", "g" ); diff --git a/app/models/emoji.rb b/app/models/emoji.rb index 94f58128c26..3307c46204f 100644 --- a/app/models/emoji.rb +++ b/app/models/emoji.rb @@ -133,9 +133,10 @@ class Emoji end def self.replacement_code(code) - hexes = code.split('-'.freeze).map!(&:hex) - # Don't replace digits, letters and some symbols - hexes.pack("U*".freeze) if hexes[0] > 255 + code + .split('-'.freeze) + .map!(&:hex) + .pack("U*".freeze) end def self.unicode_replacements @@ -146,6 +147,10 @@ class Emoji db['emojis'].each do |e| name = e['name'] + + # special cased as we prefer to keep these as symbols + next if name == 'registered'.freeze + next if name == 'copyright'.freeze next if name == 'tm'.freeze code = replacement_code(e['code']) diff --git a/lib/pretty_text/shims.js b/lib/pretty_text/shims.js index 44f80690720..4d77520eb27 100644 --- a/lib/pretty_text/shims.js +++ b/lib/pretty_text/shims.js @@ -1,6 +1,7 @@ __PrettyText = require("pretty-text/pretty-text").default; __buildOptions = require("pretty-text/pretty-text").buildOptions; __performEmojiUnescape = require("pretty-text/emoji").performEmojiUnescape; +__buildReplacementsList = require("pretty-text/emoji").buildReplacementsList; __performEmojiEscape = require("pretty-text/emoji").performEmojiEscape; __utils = require("discourse/lib/utilities"); @@ -8,13 +9,7 @@ __utils = require("discourse/lib/utilities"); __emojiUnicodeReplacer = null; __setUnicode = function(replacements) { - let unicodeRegexp = new RegExp( - Object.keys(replacements) - .sort() - .reverse() - .join("|"), - "g" - ); + let unicodeRegexp = new RegExp(__buildReplacementsList(replacements), "g"); __emojiUnicodeReplacer = function(text) { unicodeRegexp.lastIndex = 0; diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index 327dbf6d224..1da66531d7e 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -877,6 +877,13 @@ describe PrettyText do expect(PrettyText.cook("☺")).to match(/\:slight_smile\:/) end + it "replaces digits" do + expect(PrettyText.cook("🔢")).to match(/\:1234\:/) + expect(PrettyText.cook("1️⃣")).to match(/\:one\:/) + expect(PrettyText.cook("#️⃣")).to match(/\:hash\:/) + expect(PrettyText.cook("*️⃣")).to match(/\:asterisk\:/) + end + it "doesn't replace unicode emoji if emoji is disabled" do SiteSetting.enable_emoji = false expect(PrettyText.cook("💣")).not_to match(/\:bomb\:/) diff --git a/spec/models/emoji_spec.rb b/spec/models/emoji_spec.rb index c36f3161f99..f7f57ae26a0 100644 --- a/spec/models/emoji_spec.rb +++ b/spec/models/emoji_spec.rb @@ -12,11 +12,6 @@ describe Emoji do expect(Emoji.replacement_code('1f1e9-1f1ea').codepoints).to eq([127465, 127466]) end - it "returns nil for weird cases" do - expect(Emoji.replacement_code('32')).to be_nil - expect(Emoji.replacement_code('robin')).to be_nil - end - describe '.load_custom' do describe 'when a custom emoji has an invalid upload_id' do it 'should return the custom emoji without a URL' do