From 86244e3a4b749cc051fc223b85eb8308f9b91867 Mon Sep 17 00:00:00 2001
From: Neil Lalonde <neillalonde@gmail.com>
Date: Tue, 25 Mar 2014 17:29:59 -0400
Subject: [PATCH] New sub-category badges in category chooser. Normalize
 category badge rendering code.

---
 .../components/category_group_component.js    |  2 +-
 .../controllers/history_controller.js         |  4 ++--
 .../discourse/helpers/application_helpers.js  | 17 ++++++--------
 app/assets/javascripts/discourse/lib/html.js  | 22 ++++++++++---------
 .../discourse/views/category_chooser_view.js  | 10 ++++-----
 test/javascripts/lib/html_test.js             | 14 ++++++------
 6 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/app/assets/javascripts/discourse/components/category_group_component.js b/app/assets/javascripts/discourse/components/category_group_component.js
index b2cb1e96d..40ea90878 100644
--- a/app/assets/javascripts/discourse/components/category_group_component.js
+++ b/app/assets/javascripts/discourse/components/category_group_component.js
@@ -23,7 +23,7 @@ Discourse.CategoryGroupComponent = Ember.Component.extend({
       },
       template: Discourse.CategoryGroupComponent.templateFunction(),
       transformComplete: function(category) {
-        return Discourse.HTML.categoryLink(category, {allowUncategorized: true});
+        return Discourse.HTML.categoryBadge(category, {allowUncategorized: true});
       }
     });
   }
diff --git a/app/assets/javascripts/discourse/controllers/history_controller.js b/app/assets/javascripts/discourse/controllers/history_controller.js
index a732432a8..e992ee2c3 100644
--- a/app/assets/javascripts/discourse/controllers/history_controller.js
+++ b/app/assets/javascripts/discourse/controllers/history_controller.js
@@ -46,8 +46,8 @@ Discourse.HistoryController = Discourse.ObjectController.extend(Discourse.ModalF
 
     var raw = "";
     var opts = { allowUncategorized: true };
-    prevCategory = Discourse.HTML.categoryLink(prevCategory, opts);
-    curCategory = Discourse.HTML.categoryLink(curCategory, opts);
+    prevCategory = Discourse.HTML.categoryBadge(prevCategory, opts);
+    curCategory = Discourse.HTML.categoryBadge(curCategory, opts);
 
     if(viewMode === "side_by_side_markdown" || viewMode === "side_by_side") {
       raw = "<div class='span8'>" + prevCategory +  "</div> <div class='span8 offset1'>" + curCategory +  "</div>";
diff --git a/app/assets/javascripts/discourse/helpers/application_helpers.js b/app/assets/javascripts/discourse/helpers/application_helpers.js
index 1c37e8431..f3223a7d7 100644
--- a/app/assets/javascripts/discourse/helpers/application_helpers.js
+++ b/app/assets/javascripts/discourse/helpers/application_helpers.js
@@ -76,17 +76,14 @@ Handlebars.registerHelper('topicLink', function(property, options) {
 function categoryLinkHTML(category, options) {
   var categoryOptions = {};
   if (options.hash) {
-    if (options.hash.allowUncategorized) {
-      categoryOptions.allowUncategorized = true;
-    }
-    if (options.hash.showParent) {
-      categoryOptions.showParent = true;
-    }
+    if (options.hash.allowUncategorized) { categoryOptions.allowUncategorized = true; }
+    if (options.hash.showParent) { categoryOptions.showParent = true; }
+    if (options.hash.link !== undefined) { categoryOptions.link = options.hash.link; }
     if (options.hash.categories) {
       categoryOptions.categories = Em.Handlebars.get(this, options.hash.categories, options);
     }
   }
-  return new Handlebars.SafeString(Discourse.HTML.categoryLink(category, categoryOptions));
+  return new Handlebars.SafeString(Discourse.HTML.categoryBadge(category, categoryOptions));
 }
 
 /**
@@ -104,11 +101,11 @@ Handlebars.registerHelper('categoryLinkRaw', function(property, options) {
 });
 
 Handlebars.registerHelper('categoryBadge', function(property, options) {
-  var category = Em.Handlebars.get(this, property, options),
-      style = Discourse.HTML.categoryStyle(category);
-  return new Handlebars.SafeString("<span class='badge-category' style='" + style + "'>" + category.get('name') + "</span>");
+  options.hash.link = false;
+  return categoryLinkHTML(Ember.Handlebars.get(this, property, options), options);
 });
 
+
 /**
   Produces a bound link to a category
 
diff --git a/app/assets/javascripts/discourse/lib/html.js b/app/assets/javascripts/discourse/lib/html.js
index 0f5090ced..464e439ce 100644
--- a/app/assets/javascripts/discourse/lib/html.js
+++ b/app/assets/javascripts/discourse/lib/html.js
@@ -62,16 +62,17 @@ Discourse.HTML = {
   },
 
   /**
-    Create a badge-like category link
+    Create a category badge
 
-    @method categoryLink
+    @method categoryBadge
     @param {Discourse.Category} category the category whose link we want
     @param {Object} opts The options for the category link
-      @param {Boolean} opts.allowUncategorized Whether we allow rendering of the uncategorized category
-      @param {Boolean} opts.showParent Whether to visually show whether category is a sub-category
+      @param {Boolean} opts.allowUncategorized Whether we allow rendering of the uncategorized category (default false)
+      @param {Boolean} opts.showParent Whether to visually show whether category is a sub-category (default false)
+      @param {Boolean} opts.link Whether this category badge should link to the category (default true)
     @returns {String} the html category badge
   **/
-  categoryLink: function(category, opts) {
+  categoryBadge: function(category, opts) {
     opts = opts || {};
 
     if ((!category) ||
@@ -85,7 +86,8 @@ Discourse.HTML = {
         description = Em.get(category, 'description'),
         restricted = Em.get(category, 'read_restricted'),
         url = Discourse.getURL("/category/") + Discourse.Category.slugFor(category),
-        html = "<a href=\"" + url + "\" ";
+        elem = (opts.link === false ? 'span' : 'a'),
+        html = "<" + elem + " href=\"" + (opts.link === false ? '' : url) + "\" ";
 
     html += "data-drop-close=\"true\" class=\"badge-category" + (restricted ? ' restricted' : '' ) + "\" ";
 
@@ -100,15 +102,15 @@ Discourse.HTML = {
     if (restricted) {
       html += "><div><i class='fa fa-group'></i> " + name + "</div></a>";
     } else {
-      html += ">" + name + "</a>";
+      html += ">" + name + "</" + elem + ">";
     }
 
     if (opts.showParent && category.get('parent_category_id')) {
       var parent = Discourse.Category.findById(category.get('parent_category_id'));
-      html = "<span class='badge-wrapper'><a class='badge-category-parent' style=\"" + (Discourse.HTML.categoryStyle(parent)||'') +
-             "\" href=\"" + url + "\"><span class='category-name'>" +
+      html = "<span class='badge-wrapper'><" + elem + " class='badge-category-parent' style=\"" + (Discourse.HTML.categoryStyle(parent)||'') +
+             "\" href=\"" + (opts.link === false ? '' : url) + "\"><span class='category-name'>" +
              (Em.get(parent, 'read_restricted') ? "<i class='fa fa-group'></i> " : "") +
-             Em.get(parent, 'name') + "</span></a>" +
+             Em.get(parent, 'name') + "</span></" + elem + ">" +
              html + "</span>";
     }
 
diff --git a/app/assets/javascripts/discourse/views/category_chooser_view.js b/app/assets/javascripts/discourse/views/category_chooser_view.js
index 41e54a952..bcf4d4474 100644
--- a/app/assets/javascripts/discourse/views/category_chooser_view.js
+++ b/app/assets/javascripts/discourse/views/category_chooser_view.js
@@ -9,7 +9,7 @@
 Discourse.CategoryChooserView = Discourse.ComboboxView.extend({
   classNames: ['combobox category-combobox'],
   overrideWidths: true,
-  dataAttributes: ['name', 'color', 'text_color', 'description_text', 'topic_count', 'read_restricted'],
+  dataAttributes: ['id', 'description_text'],
   valueBinding: Ember.Binding.oneWay('source'),
 
   content: Em.computed.filter('categories', function(c) {
@@ -37,12 +37,12 @@ Discourse.CategoryChooserView = Discourse.ComboboxView.extend({
   }.property(),
 
   template: function(text, templateData) {
-    if (!templateData.color) return text;
+    var category = Discourse.Category.findById(parseInt(templateData.id,10));
+    if (!category) return text;
 
-    var result = "<div class='badge-category' style='background-color: #" + templateData.color + '; color: #' +
-        templateData.text_color + ";'>" + (templateData.read_restricted === 'true' ? "<i class='fa fa-group'></i> " : "") + templateData.name + "</div>";
+    var result = Discourse.HTML.categoryBadge(category, {showParent: true, link: false});
 
-    result += " <div class='topic-count'>&times; " + templateData.topic_count + "</div>";
+    result += " <div class='topic-count'>&times; " + category.get('topic_count') + "</div>";
 
     var description = templateData.description_text;
     // TODO wtf how can this be null?
diff --git a/test/javascripts/lib/html_test.js b/test/javascripts/lib/html_test.js
index f339e3dca..1ee03a3d6 100644
--- a/test/javascripts/lib/html_test.js
+++ b/test/javascripts/lib/html_test.js
@@ -2,11 +2,11 @@ module("Discourse.HTML");
 
 var html = Discourse.HTML;
 
-test("categoryLink without a category", function() {
-  blank(html.categoryLink(), "it returns no HTML");
+test("categoryBadge without a category", function() {
+  blank(html.categoryBadge(), "it returns no HTML");
 });
 
-test("Regular categoryLink", function() {
+test("Regular categoryBadge", function() {
   var category = Discourse.Category.create({
         name: 'hello',
         id: 123,
@@ -14,7 +14,7 @@ test("Regular categoryLink", function() {
         color: 'ff0',
         text_color: 'f00'
       }),
-      tag = parseHTML(html.categoryLink(category))[0];
+      tag = parseHTML(html.categoryBadge(category))[0];
 
   equal(tag.name, 'a', 'it creates an `a` tag');
   equal(tag.attributes['class'], 'badge-category', 'it has the correct class');
@@ -28,7 +28,7 @@ test("Regular categoryLink", function() {
 
 test("undefined color", function() {
   var noColor = Discourse.Category.create({ name: 'hello', id: 123 }),
-      tag = parseHTML(html.categoryLink(noColor))[0];
+      tag = parseHTML(html.categoryBadge(noColor))[0];
 
   blank(tag.attributes.style, "it has no color style because there are no colors");
 });
@@ -37,8 +37,8 @@ test("allowUncategorized", function() {
   var uncategorized = Discourse.Category.create({name: 'uncategorized', id: 345});
   this.stub(Discourse.Site, 'currentProp').withArgs('uncategorized_category_id').returns(345);
 
-  blank(html.categoryLink(uncategorized), "it doesn't return HTML for uncategorized by default");
-  present(html.categoryLink(uncategorized, {allowUncategorized: true}), "it returns HTML");
+  blank(html.categoryBadge(uncategorized), "it doesn't return HTML for uncategorized by default");
+  present(html.categoryBadge(uncategorized, {allowUncategorized: true}), "it returns HTML");
 });