From 2d03163be0db145c3f4a41db95ce845c32651856 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?= <regis@hanol.fr>
Date: Mon, 15 Jun 2015 15:27:22 +0200
Subject: [PATCH] FEATURE: add support for emojis in title

---
 .../discourse/helpers/topic-link.js.es6            |  2 +-
 .../javascripts/discourse/lib/emoji/emoji.js.erb   |  5 ++---
 .../javascripts/discourse/models/topic.js.es6      | 14 ++++++++++++++
 .../templates/components/featured-topic.hbs        |  2 +-
 .../templates/components/header-extra-info.hbs     |  2 +-
 .../javascripts/discourse/templates/topic.hbs      |  2 +-
 test/javascripts/models/topic-test.js.es6          |  5 +++++
 7 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/app/assets/javascripts/discourse/helpers/topic-link.js.es6 b/app/assets/javascripts/discourse/helpers/topic-link.js.es6
index 4af28e7c6be..f0703c6d9ea 100644
--- a/app/assets/javascripts/discourse/helpers/topic-link.js.es6
+++ b/app/assets/javascripts/discourse/helpers/topic-link.js.es6
@@ -1,6 +1,6 @@
 import registerUnbound from 'discourse/helpers/register-unbound';
 
 registerUnbound('topic-link', function(topic) {
-  var title = topic.get('fancy_title');
+  var title = topic.get('fancyTitle');
   return new Handlebars.SafeString("<a href='" + topic.get('lastUnreadUrl') + "' class='title'>" + title + "</a>");
 });
diff --git a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb
index 582af89dfe2..1441f0cdcef 100644
--- a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb
+++ b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb
@@ -99,7 +99,7 @@ function checkPrev(prev) {
     var lastToken = prev[prev.length-1];
     if (lastToken && lastToken.charAt) {
       var lastChar = lastToken.charAt(lastToken.length-1);
-      if (lastChar !== ' ' && lastChar !== "\n") return false;
+      if (!/\s/.test(lastChar)) return false;
     }
   }
   return true;
@@ -140,10 +140,9 @@ Discourse.Dialect.registerInline(':', function(text, match, prev) {
     translationColonRegexp.lastIndex = 0;
     var m = translationColonRegexp.exec(text);
     if (m && m[0] && text.indexOf(m[0]) === 0) {
-
       // Check outer edge
       var lastChar = text.charAt(m[0].length);
-      if (lastChar && (lastChar !== ' ' && lastChar !== "\n")) return;
+      if (lastChar && !/\s/.test(lastChar)) return;
       contents = imageFor(translationsWithColon[m[0]]);
       if (contents) {
         return [m[0].length, contents];
diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6
index 9823080304b..923e8104acf 100644
--- a/app/assets/javascripts/discourse/models/topic.js.es6
+++ b/app/assets/javascripts/discourse/models/topic.js.es6
@@ -5,6 +5,20 @@ const Topic = RestModel.extend({
   errorTitle: null,
   errorLoading: false,
 
+  fancyTitle: function() {
+    let title = this.get("fancy_title");
+
+    if (this.siteSettings.enable_emoji && title.indexOf(":") >= 0) {
+      title = title.replace(/:\S+:?/, function(m) {
+        const emoji = Discourse.Emoji.translations[m] ? Discourse.Emoji.translations[m] : m.slice(1, m.length - 1),
+              url = Discourse.Emoji.urlFor(emoji);
+        return url ? "<img src='" + url + "' title='" + emoji + "' alt='" + emoji + "' class='emoji'>" : m;
+      });
+    }
+
+    return title;
+  }.property("fancy_title"),
+
   // returns createdAt if there's no bumped date
   bumpedAt: function() {
     const bumpedAt = this.get('bumped_at');
diff --git a/app/assets/javascripts/discourse/templates/components/featured-topic.hbs b/app/assets/javascripts/discourse/templates/components/featured-topic.hbs
index e0475953014..8cbb7ac5181 100644
--- a/app/assets/javascripts/discourse/templates/components/featured-topic.hbs
+++ b/app/assets/javascripts/discourse/templates/components/featured-topic.hbs
@@ -1,5 +1,5 @@
 {{topic-status topic=topic}}
-<a class='title' href="{{unbound topic.lastUnreadUrl}}">{{{unbound topic.fancy_title}}}</a>
+<a class='title' href="{{unbound topic.lastUnreadUrl}}">{{{unbound topic.fancyTitle}}}</a>
 {{topic-post-badges newPosts=topic.totalUnread unseen=topic.unseen url=topic.lastUnreadUrl}}
 
 {{#if latestTopicOnly}}
diff --git a/app/assets/javascripts/discourse/templates/components/header-extra-info.hbs b/app/assets/javascripts/discourse/templates/components/header-extra-info.hbs
index 10c176dd6f3..2f6b95c498c 100644
--- a/app/assets/javascripts/discourse/templates/components/header-extra-info.hbs
+++ b/app/assets/javascripts/discourse/templates/components/header-extra-info.hbs
@@ -8,7 +8,7 @@
 
         {{#if topic.details.loaded}}
           {{topic-status topic=topic}}
-          <a class='topic-link' href='{{unbound topic.url}}' {{action "jumpToTopPost"}}>{{{topic.fancy_title}}}</a>
+          <a class='topic-link' href='{{unbound topic.url}}' {{action "jumpToTopPost"}}>{{{topic.fancyTitle}}}</a>
         {{else}}
           {{#if topic.errorLoading}}
             <span class="error">{{topic.errorTitle}}</span>
diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs
index a5bb12e87a9..26e8bbc0178 100644
--- a/app/assets/javascripts/discourse/templates/topic.hbs
+++ b/app/assets/javascripts/discourse/templates/topic.hbs
@@ -37,7 +37,7 @@
               {{#if model.details.loaded}}
                 {{topic-status topic=model}}
                 <a href='{{unbound model.url}}' {{action "jumpTop"}} class='fancy-title'>
-                  {{{model.fancy_title}}}
+                  {{{model.fancyTitle}}}
                 </a>
               {{/if}}
 
diff --git a/test/javascripts/models/topic-test.js.es6 b/test/javascripts/models/topic-test.js.es6
index 3bd2230171e..a3f31615f99 100644
--- a/test/javascripts/models/topic-test.js.es6
+++ b/test/javascripts/models/topic-test.js.es6
@@ -71,3 +71,8 @@ test("recover", function() {
   blank(topic.get('deleted_by'), "it clears deleted_by");
   //ok(Discourse.ajax.calledOnce, "it called recover over the wire");
 });
+
+test('fancyTitle', function() {
+  var topic = Topic.create({ siteSettings: { enable_emoji: true }, fancy_title: ":smile: with all the emojis" });
+  equal(topic.get('fancyTitle'), "<img src='/images/emoji/undefined/smile.png?v=0' title='smile' alt='smile' class='emoji'> with all the emojis", "supports emojis");
+});