From 0167f6bb57e4c7eb68e734a4cb2ac4ff0e53813e Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Wed, 2 Mar 2016 14:31:32 -0500 Subject: [PATCH] FIX: Don't substitute emojis within code blocks --- .../discourse/lib/emoji/emoji.js.erb | 22 +++++++++++++++++++ app/models/emoji.rb | 8 ++----- lib/pretty_text.rb | 7 +++++- spec/components/pretty_text_spec.rb | 8 +++++++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb index 67313d67fbc..057404585e2 100644 --- a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb +++ b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb @@ -12,6 +12,15 @@ Discourse.Dialect.registerEmoji = function(code, url) { extendedEmoji[code] = url; }; +var _unicodeReplacements; +var _unicodeRegexp; +Discourse.Dialect.setUnicodeReplacements = function(replacements) { + _unicodeReplacements = replacements; + if (replacements) { + _unicodeRegexp = new RegExp(Object.keys(replacements).join("|"), "g"); + } +} + // This method is used by PrettyText to reset custom emojis in multisites Discourse.Dialect.resetEmojis = function() { extendedEmoji = {}; @@ -151,6 +160,19 @@ Object.keys(translations).forEach(function (t) { } }); +Discourse.Dialect.addPreProcessor(function(text) { + if (_unicodeReplacements) { + _unicodeRegexp.lastIndex = 0; + + var m; + while ((m = _unicodeRegexp.exec(text)) !== null) { + text = text.replace(m[0], ":" + _unicodeReplacements[m[0]] + ":"); + } + } + + return text; +}); + function escapeRegExp(s) { return s.replace(/[-/\\^$*+?.()|[\]{}]/gi, '\\$&'); } diff --git a/app/models/emoji.rb b/app/models/emoji.rb index e65b91e0d7a..986a7288a5f 100644 --- a/app/models/emoji.rb +++ b/app/models/emoji.rb @@ -131,12 +131,8 @@ class Emoji @unicode_replacements end - def self.unicode_regexp - @unicode_regexp ||= Regexp.union(unicode_replacements.keys) - end - - def self.sub_unicode!(text) - text.gsub!(unicode_regexp) {|m| ":#{unicode_replacements[m]}:"} + def self.unicode_replacements_json + @unicode_replacements_json ||= unicode_replacements.to_json end end diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index e41a8ad413e..6dacab922d9 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -201,6 +201,12 @@ module PrettyText end end + if SiteSetting.enable_emoji? + context.eval("Discourse.Dialect.setUnicodeReplacements(#{Emoji.unicode_replacements_json})"); + else + context.eval("Discourse.Dialect.setUnicodeReplacements(null)"); + end + # reset emojis (v8 context is shared amongst multisites) context.eval("Discourse.Dialect.resetEmojis();") # custom emojis @@ -259,7 +265,6 @@ module PrettyText options[:topicId] = opts[:topic_id] working_text = text.dup - Emoji.sub_unicode!(working_text) if SiteSetting.enable_emoji? sanitized = markdown(working_text, options) doc = Nokogiri::HTML.fragment(sanitized) diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index a098509f65d..44a7c5dde12 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -395,6 +395,14 @@ HTML expect(PrettyText.cook("šŸ’£")).to match(/\:bomb\:/) end + it "doesn't replace emoji in inline code blocks with our emoji sets if emoji is enabled" do + expect(PrettyText.cook("`šŸ’£`")).not_to match(/\:bomb\:/) + end + + it "doesn't replace emoji in code blocks with our emoji sets if emoji is enabled" do + expect(PrettyText.cook("```\nšŸ’£`\n```\n")).not_to match(/\:bomb\:/) + end + it "replaces some glyphs that are not in the emoji range" do expect(PrettyText.cook("ā˜ŗ")).to match(/\:slightly_smiling\:/) end