diff --git a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb index 12cb1711ba8..e662df804e6 100644 --- a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb +++ b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb @@ -30,16 +30,19 @@ for (var name in aliases) { } Discourse.Emoji.unescape = function(string) { + //this can be further improved by supporting matches of emoticons that don't begin with a colon if (Discourse.SiteSettings.enable_emoji && string.indexOf(":") >= 0) { - string = string.replace(/:[^\s:]+:?/g, function(m) { - var emoji = Discourse.Emoji.translations[m] ? Discourse.Emoji.translations[m] : m.slice(1, m.length - 1), + string = string.replace(/\B:[^\s:]+:?\B/g, function(m) { + var isEmoticon = !!Discourse.Emoji.translations[m], + emoji = isEmoticon ? Discourse.Emoji.translations[m] : m.slice(1, m.length - 1), + hasEndingColon = m.lastIndexOf(":") === m.length - 1, url = Discourse.Emoji.urlFor(emoji); - return url ? "" + emoji + "" : m; + return url && (isEmoticon || hasEndingColon) ? "" + emoji + "" : m; }); } return string; -} +}; Discourse.Emoji.urlFor = urlFor = function(code) { var url, set = Discourse.SiteSettings.emoji_set; @@ -63,12 +66,12 @@ Discourse.Emoji.urlFor = urlFor = function(code) { } return url; -} +}; Discourse.Emoji.exists = function(code){ code = code.toLowerCase(); return !!(extendedEmoji.hasOwnProperty(code) || emojiHash.hasOwnProperty(code)); -} +}; function imageFor(code) { code = code.toLowerCase(); @@ -204,6 +207,6 @@ Discourse.Emoji.search = function(term, options) { } return results; -} +}; Discourse.Markdown.whiteListTag('img', 'class', 'emoji'); diff --git a/test/javascripts/helpers/site-settings.js b/test/javascripts/helpers/site-settings.js index 7782c2e4d49..7adde6c8845 100644 --- a/test/javascripts/helpers/site-settings.js +++ b/test/javascripts/helpers/site-settings.js @@ -91,6 +91,7 @@ Discourse.SiteSettingsOriginal = { "show_create_topics_notice":true, "available_locales":"cs|da|de|en|es|fr|he|id|it|ja|ko|nb_NO|nl|pl_PL|pt|pt_BR|ru|sv|uk|zh_CN|zh_TW", "highlighted_languages":"apache|bash|cs|cpp|css|coffeescript|diff|xml|http|ini|json|java|javascript|makefile|markdown|nginx|objectivec|ruby|perl|php|python|sql|handlebars", - "enable_emoji":true + "enable_emoji":true, + "emoji_set":"emoji_one" }; Discourse.SiteSettings = jQuery.extend(true, {}, Discourse.SiteSettingsOriginal); diff --git a/test/javascripts/lib/bbcode-test.js.es6 b/test/javascripts/lib/bbcode-test.js.es6 index 84d9b93b8c3..575ad7e7558 100644 --- a/test/javascripts/lib/bbcode-test.js.es6 +++ b/test/javascripts/lib/bbcode-test.js.es6 @@ -52,7 +52,7 @@ test('spoiler', function() { format("[spoiler]it's a sled[/spoiler]", "it's a sled", "supports spoiler tags on text"); format("[spoiler][/spoiler]", "", "supports spoiler tags on images"); - format("[spoiler] This is the **bold** :smiley: [/spoiler]", " This is the bold \"smiley\" ", "supports spoiler tags on emojis"); + format("[spoiler] This is the **bold** :smiley: [/spoiler]", " This is the bold \"smiley\" ", "supports spoiler tags on emojis"); format("[spoiler] Why not both ?[/spoiler]", " Why not both ?", "supports images and text"); format("In a p tag a spoiler [spoiler] [/spoiler] can work.", "In a p tag a spoiler can work.", "supports images and text in a p tag"); }); diff --git a/test/javascripts/lib/emoji-test.js.es6 b/test/javascripts/lib/emoji-test.js.es6 index e96941fc03c..fcf2c92eea8 100644 --- a/test/javascripts/lib/emoji-test.js.es6 +++ b/test/javascripts/lib/emoji-test.js.es6 @@ -1,10 +1,29 @@ module('emoji'); +var testUnescape = function(input, expected, description) { + var unescaped = Discourse.Emoji.unescape(input); + equal(unescaped, expected, description); +}; + +test("Emoji.unescape", function(){ + + testUnescape("Not emoji :O) :frog) :smile)", "Not emoji :O) :frog) :smile)", "title without emoji"); + testUnescape("Not emoji :frog :smile", "Not emoji :frog :smile", "end colon is not optional"); + testUnescape("emoticons :)", "emoticons smile", "emoticons are still supported"); + testUnescape("With emoji :O: :frog: :smile:", + "With emoji O frog smile", + "title with emoji"); + testUnescape("a:smile:a", "a:smile:a", "word characters not allowed next to emoji"); + testUnescape("(:frog:) :)", "(frog) smile", "non-word characters allowed next to emoji"); + testUnescape(":smile: hi", "smile hi", "start of line"); + testUnescape("hi :smile:", "hi smile", "end of line"); + +}); + test("Emoji.search", function(){ // able to find an alias equal(Discourse.Emoji.search("coll").length, 1); }); - diff --git a/test/javascripts/models/topic-test.js.es6 b/test/javascripts/models/topic-test.js.es6 index a1f7d159e20..3aab0b4159b 100644 --- a/test/javascripts/models/topic-test.js.es6 +++ b/test/javascripts/models/topic-test.js.es6 @@ -76,6 +76,6 @@ test("recover", function() { test('fancyTitle', function() { var topic = Topic.create({ fancy_title: ":smile: with all :) the emojis :pear::peach:" }); equal(topic.get('fancyTitle'), - "smile with all smile the emojis pearpeach", + "smile with all smile the emojis pearpeach", "supports emojis"); });