diff --git a/app/assets/javascripts/discourse/lib/text.js.es6 b/app/assets/javascripts/discourse/lib/text.js.es6 index 6986700fc68..ee51cb53d10 100644 --- a/app/assets/javascripts/discourse/lib/text.js.es6 +++ b/app/assets/javascripts/discourse/lib/text.js.es6 @@ -60,17 +60,24 @@ function createPrettyText(options) { } function emojiOptions() { - const siteSettings = Discourse.__container__.lookup("site-settings:main"); - if (!siteSettings.enable_emoji) { + if (!Discourse.SiteSettings.enable_emoji) { return; } - return { getURL: Discourse.getURLWithCDN, emojiSet: siteSettings.emoji_set }; + return { + getURL: Discourse.getURLWithCDN, + emojiSet: Discourse.SiteSettings.emoji_set, + enableEmojiShortcuts: Discourse.SiteSettings.enable_emoji_shortcuts + }; } export function emojiUnescape(string, options) { - const opts = _.extend(emojiOptions(), options || {}); - return opts ? performEmojiUnescape(string, opts) : string; + const opts = emojiOptions(); + if (opts) { + return performEmojiUnescape(string, Object.assign(opts, options || {})); + } else { + return string; + } } export function emojiUrlFor(code) { diff --git a/app/assets/javascripts/pretty-text/emoji.js.es6 b/app/assets/javascripts/pretty-text/emoji.js.es6 index 49c5f15fe58..6e73be91f0e 100644 --- a/app/assets/javascripts/pretty-text/emoji.js.es6 +++ b/app/assets/javascripts/pretty-text/emoji.js.es6 @@ -44,7 +44,7 @@ export function performEmojiUnescape(string, opts) { } return string.replace(unicodeRegexp, m => { - const isEmoticon = !!translations[m]; + const isEmoticon = opts.enableEmojiShortcuts && !!translations[m]; const isUnicodeEmoticon = !!replacements[m]; let emojiVal; if (isEmoticon) { @@ -70,12 +70,12 @@ export function performEmojiUnescape(string, opts) { return string; } -export function performEmojiEscape(string) { +export function performEmojiEscape(string, opts) { return string.replace(unicodeRegexp, m => { if (!!translations[m]) { - return ":" + translations[m] + ":"; + return opts.emojiShortcuts ? `:${translations[m]}:` : m; } else if (!!replacements[m]) { - return ":" + replacements[m] + ":"; + return `:${replacements[m]}:`; } else { return m; } diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js.es6 b/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js.es6 index 9b851d2c091..e1c9a31bf08 100644 --- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js.es6 +++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js.es6 @@ -119,7 +119,8 @@ const rule = { if (options.enableEmoji) { title = performEmojiUnescape(topicInfo.title, { getURL: options.getURL, - emojiSet: options.emojiSet + emojiSet: options.emojiSet, + enableEmojiShortcuts: options.enableEmojiShortcuts }); } @@ -154,6 +155,7 @@ export function setup(helper) { helper.registerOptions((opts, siteSettings) => { opts.enableEmoji = siteSettings.enable_emoji; opts.emojiSet = siteSettings.emoji_set; + opts.enableEmojiShortcuts = siteSettings.enable_emoji_shortcuts; }); helper.registerPlugin(md => { diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index 94d5d02e772..32063ad5c4e 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -235,7 +235,12 @@ module PrettyText protect do v8.eval(<<~JS) __paths = #{paths_json}; - __performEmojiUnescape(#{title.inspect}, { getURL: __getURL, emojiSet: #{set}, customEmoji: #{custom} }); + __performEmojiUnescape(#{title.inspect}, { + getURL: __getURL, + emojiSet: #{set}, + customEmoji: #{custom}, + enableEmojiShortcuts: #{SiteSetting.enable_emoji_shortcuts} + }); JS end end @@ -243,9 +248,11 @@ module PrettyText def self.escape_emoji(title) return unless title + replace_emoji_shortcuts = SiteSetting.enable_emoji && SiteSetting.enable_emoji_shortcuts + protect do v8.eval(<<~JS) - __performEmojiEscape(#{title.inspect}); + __performEmojiEscape(#{title.inspect}, { emojiShortcuts: #{replace_emoji_shortcuts} }); JS end end diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index 929c0c4f15e..9ace739e48a 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -47,6 +47,70 @@ describe PrettyText do expect(cook("[quote=\"EvilTrout, post:2, topic:#{topic.id}\"]\nddd\n[/quote]", topic_id: 1)).to eq(n(expected)) end + context "emojis" do + let(:md) do + <<~MD + > This is a quote with a regular emoji :upside_down_face: + + > This is a quote with an emoji shortcut :) + + > This is a quote with a Unicode emoji 😎 + MD + end + + it "does not unescape emojis when emojis are disabled" do + SiteSetting.enable_emoji = false + + html = <<~HTML +
+

This is a quote with a regular emoji :upside_down_face:

+
+
+

This is a quote with an emoji shortcut :)

+
+
+

This is a quote with a Unicode emoji 😎

+
+ HTML + + expect(cook(md)).to eq(html.strip) + end + + it "does not convert emoji shortcuts when emoji shortcuts are disabled" do + SiteSetting.enable_emoji_shortcuts = false + + html = <<~HTML +
+

This is a quote with a regular emoji :upside_down_face:

+
+
+

This is a quote with an emoji shortcut :)

+
+
+

This is a quote with a Unicode emoji :sunglasses:

+
+ HTML + + expect(cook(md)).to eq(html.strip) + end + + it "unescapes all emojis" do + html = <<~HTML +
+

This is a quote with a regular emoji :upside_down_face:

+
+
+

This is a quote with an emoji shortcut :slight_smile:

+
+
+

This is a quote with a Unicode emoji :sunglasses:

+
+ HTML + + expect(cook(md)).to eq(html.strip) + end + end + it "do off topic quoting of posts from secure categories" do category = Fabricate(:category, read_restricted: true) topic = Fabricate(:topic, title: "this is topic with secret category", category: category) diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index 8b6d441b6f8..98b5fb187b2 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -292,6 +292,7 @@ describe Topic do let(:topic_script) { build_topic_with_title("Topic with script in its title") } let(:topic_emoji) { build_topic_with_title("I 💖 candy alot") } let(:topic_modifier_emoji) { build_topic_with_title("I 👨‍🌾 candy alot") } + let(:topic_shortcut_emoji) { build_topic_with_title("I love candy :)") } it "escapes script contents" do expect(topic_script.fancy_title).to eq("Topic with <script>alert(‘title’)</script> script in its title") @@ -320,6 +321,29 @@ describe Topic do expect(topic_script.fancy_title).not_to include("