From 26a8156f087cd694d65d877cb2bb48b4190e1f38 Mon Sep 17 00:00:00 2001
From: Robin Ward <robin.ward@gmail.com>
Date: Mon, 28 Oct 2013 12:44:10 -0400
Subject: [PATCH 1/5] Better blockquote button in Markdown editor when
 non-traditional markdown linebreaks are enabled.

---
 app/assets/javascripts/pagedown_custom.js    | 26 +++++++++++++++++++-
 vendor/assets/javascripts/Markdown.Editor.js | 22 +++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/app/assets/javascripts/pagedown_custom.js b/app/assets/javascripts/pagedown_custom.js
index e7a0c885a..d088f4267 100644
--- a/app/assets/javascripts/pagedown_custom.js
+++ b/app/assets/javascripts/pagedown_custom.js
@@ -10,5 +10,29 @@ window.PagedownCustom = {
         return Discourse.__container__.lookup('controller:composer').send('importQuote');
       }
     }
-  ]
+  ],
+
+  customActions: {
+    "doBlockquote": function(chunk, postProcessing, oldDoBlockquote) {
+
+      // When traditional linebreaks are set, use the default Pagedown implementation
+      if (Discourse.SiteSettings.traditional_markdown_linebreaks) {
+        return oldDoBlockquote.call(this, chunk, postProcessing);
+      }
+
+      // Our custom blockquote for non-traditional markdown linebreaks
+      var result = [];
+      chunk.selection.split(/\n/).forEach(function (line) {
+        var newLine = "";
+        if (line.indexOf("> ") === 0) {
+          newLine += line.substr(2);
+        } else {
+          if (/\S/.test(line)) { newLine += "> " + line; }
+        }
+        result.push(newLine)
+      })
+      chunk.selection = result.join("\n");
+
+    }
+  }
 };
diff --git a/vendor/assets/javascripts/Markdown.Editor.js b/vendor/assets/javascripts/Markdown.Editor.js
index bd2f2ac37..af4aa9097 100644
--- a/vendor/assets/javascripts/Markdown.Editor.js
+++ b/vendor/assets/javascripts/Markdown.Editor.js
@@ -18,6 +18,17 @@
 //        ]
 //      };
 //
+// To extend actions:
+//
+//      window.PagedownCustom = {
+//          customActions: {
+//             "doBlockquote": function(chunk, postProcessing, oldDoBlockquote) {
+//               console.log('custom blockquote called!');
+//               return oldDoBlockquote.call(this, chunk, postProcessing);
+//             }
+//          }
+//      };
+
 
 (function () {
 
@@ -1470,6 +1481,17 @@
         }
 
         function bindCommand(method) {
+            if (typeof PagedownCustom != "undefined" && PagedownCustom.customActions) {
+                var custom = PagedownCustom.customActions[method];
+                if (custom) {
+                    return function() {
+                        var args = Array.prototype.slice.call(arguments);
+                        args.push(commandManager[method]);
+                        return custom.apply(commandManager, args);
+                    };
+                }
+            }
+
             if (typeof method === "string")
                 method = commandManager[method];
             return function () { method.apply(commandManager, arguments); }

From 70ce07ae490f5ba5eecb8d20f5afe13bf9604608 Mon Sep 17 00:00:00 2001
From: Robin Ward <robin.ward@gmail.com>
Date: Mon, 28 Oct 2013 13:00:34 -0400
Subject: [PATCH 2/5] Oops JSHint again :( )

---
 app/assets/javascripts/pagedown_custom.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/assets/javascripts/pagedown_custom.js b/app/assets/javascripts/pagedown_custom.js
index d088f4267..eff6c090c 100644
--- a/app/assets/javascripts/pagedown_custom.js
+++ b/app/assets/javascripts/pagedown_custom.js
@@ -29,8 +29,8 @@ window.PagedownCustom = {
         } else {
           if (/\S/.test(line)) { newLine += "> " + line; }
         }
-        result.push(newLine)
-      })
+        result.push(newLine);
+      });
       chunk.selection = result.join("\n");
 
     }

From 8c882fd3924289422f0efb07d03b042ba6f1ee97 Mon Sep 17 00:00:00 2001
From: Robin Ward <robin.ward@gmail.com>
Date: Mon, 28 Oct 2013 15:34:38 -0400
Subject: [PATCH 3/5] Changed breadcrumb dropdowns

---
 .../discourse/components/breadcrumbs_component.js    | 12 ++++++++----
 .../discourse/components/categorydrop_component.js   | 11 +++++++++++
 app/assets/javascripts/discourse/models/category.js  |  2 +-
 .../components/discourse-breadcrumbs.js.handlebars   | 10 ++++------
 .../components/discourse-categorydrop.js.handlebars  |  5 +++--
 .../discourse/templates/list.js.handlebars           |  4 +---
 app/assets/stylesheets/desktop/topic-list.scss       |  4 ++--
 app/assets/stylesheets/mobile/topic-list.scss        |  4 ++--
 config/locales/client.en.yml                         |  2 ++
 9 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/app/assets/javascripts/discourse/components/breadcrumbs_component.js b/app/assets/javascripts/discourse/components/breadcrumbs_component.js
index 1f4d90094..d1efb82ae 100644
--- a/app/assets/javascripts/discourse/components/breadcrumbs_component.js
+++ b/app/assets/javascripts/discourse/components/breadcrumbs_component.js
@@ -7,16 +7,20 @@ Discourse.DiscourseBreadcrumbsComponent = Ember.Component.extend({
     return !c.get('parentCategory');
   }),
 
-  targetCategory: function() {
-    // Note we can't use Em.computed.or here because it returns a boolean not the object
+  firstCategory: function() {
     return this.get('parentCategory') || this.get('category');
   }.property('parentCategory', 'category'),
 
+  secondCategory: function() {
+    if (this.get('parentCategory')) return this.get('category');
+    return null;
+  }.property('category', 'parentCategory'),
+
   childCategories: function() {
     var self = this;
     return this.get('categories').filter(function (c) {
-      return c.get('parentCategory') === self.get('targetCategory');
+      return c.get('parentCategory') === self.get('firstCategory');
     });
-  }.property('targetCategory')
+  }.property('firstCategory')
 
 });
diff --git a/app/assets/javascripts/discourse/components/categorydrop_component.js b/app/assets/javascripts/discourse/components/categorydrop_component.js
index 0eb45d099..cc1ef418a 100644
--- a/app/assets/javascripts/discourse/components/categorydrop_component.js
+++ b/app/assets/javascripts/discourse/components/categorydrop_component.js
@@ -7,6 +7,17 @@ Discourse.DiscourseCategorydropComponent = Ember.Component.extend({
     return "icon icon-caret-right";
   }.property('expanded'),
 
+  allCategoriesUrl: function() {
+    return this.get('category.parentCategory.url') || "/";
+  }.property('category'),
+
+  allCategoriesLabel: function() {
+    if (this.get('subCategory')) {
+      return I18n.t('categories.all_subcategories');
+    }
+    return I18n.t('categories.all');
+  }.property('category'),
+
   badgeStyle: function() {
     var category = this.get('category');
     if (category) {
diff --git a/app/assets/javascripts/discourse/models/category.js b/app/assets/javascripts/discourse/models/category.js
index dc75876c5..afd286cf8 100644
--- a/app/assets/javascripts/discourse/models/category.js
+++ b/app/assets/javascripts/discourse/models/category.js
@@ -31,7 +31,7 @@ Discourse.Category = Discourse.Model.extend({
   }.property('id'),
 
   url: function() {
-    return Discourse.getURL("/category/") + (this.get('slug'));
+    return Discourse.getURL("/category/") + Discourse.Category.slugFor(this);
   }.property('name'),
 
   unreadUrl: function() {
diff --git a/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars b/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars
index a67132bf2..a25f303fc 100644
--- a/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars
@@ -1,12 +1,10 @@
 <li>
-{{discourse-categorydrop parentCategory=category categories=parentCategories}}
+{{discourse-categorydrop category=firstCategory categories=parentCategories}}
 </li>
-<li>
-  {{discourse-categorydrop parentCategory=category category=targetCategory categories=childCategories}}
-</li>
-{{#if parentCategory}}
+
+{{#if childCategories}}
   <li>
-    {{boundCategoryLink category}}
+    {{discourse-categorydrop category=secondCategory categories=childCategories subCategory="true"}}
   </li>
 {{/if}}
 
diff --git a/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars b/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars
index c74315390..c3b09e9cc 100644
--- a/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars
@@ -1,12 +1,13 @@
 {{#if category}}
-  {{boundCategoryLink category allowUncategorized=true}}
+  <a href="#" {{action expand}} class="badge-category" {{bindAttr style="badgeStyle"}}>{{category.name}}</a>
 {{else}}
-  <a href='/' class='badge-category home' {{bindAttr style="badgeStyle"}}><i class='icon icon-home'></i></a>
+  <a href='#' {{action expand}} class='badge-category home' {{bindAttr style="badgeStyle"}}>{{allCategoriesLabel}}</i></a>
 {{/if}}
 
 {{#if categories}}
   <a href='#' {{action expand}} class='badge-category category-dropdown-button' {{bindAttr style="badgeStyle"}}><i {{bindAttr class="iconClass"}}></i></a>
   <section {{bindAttr class="expanded::hidden :category-dropdown-menu"}} class='chooser'>
+    <div class='cat'><a {{bindAttr href=allCategoriesUrl}} class='badge-category home'>{{allCategoriesLabel}}</a></div>
     {{#each categories}}<div class='cat'>{{categoryLink this allowUncategorized=true}}</div>{{/each}}
   </section>
 {{/if}}
diff --git a/app/assets/javascripts/discourse/templates/list.js.handlebars b/app/assets/javascripts/discourse/templates/list.js.handlebars
index ab0c79b24..929844a99 100644
--- a/app/assets/javascripts/discourse/templates/list.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/list.js.handlebars
@@ -1,9 +1,7 @@
 <div class='list-controls'>
   <div class="container">
 
-    {{#if category}}
-      {{discourse-breadcrumbs category=category categories=categories}}
-    {{/if}}
+    {{discourse-breadcrumbs category=category categories=categories}}
 
     <ul class="nav nav-pills" id='category-filter'>
       {{each availableNavItems itemViewClass="Discourse.NavItemView"}}
diff --git a/app/assets/stylesheets/desktop/topic-list.scss b/app/assets/stylesheets/desktop/topic-list.scss
index 7c61af262..aecf0526e 100644
--- a/app/assets/stylesheets/desktop/topic-list.scss
+++ b/app/assets/stylesheets/desktop/topic-list.scss
@@ -351,8 +351,8 @@
 
 .list-controls {
   .home {
-    font-size: 20px;
-    font-weight: normal;
+    background-color: #eee;
+    color: #333;
   }
 
   .badge-category {
diff --git a/app/assets/stylesheets/mobile/topic-list.scss b/app/assets/stylesheets/mobile/topic-list.scss
index 591499c24..8877ef4ea 100644
--- a/app/assets/stylesheets/mobile/topic-list.scss
+++ b/app/assets/stylesheets/mobile/topic-list.scss
@@ -241,8 +241,8 @@
 
 .list-controls {
   .home {
-    font-size: 20px;
-    font-weight: normal;
+    color: #333;
+    background-color: #eee;
   }
 
   .badge-category {
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 944550edb..0be59d5f8 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -184,6 +184,8 @@ en:
       "13": "Inbox"
 
     categories:
+      all: "all categories"
+      all_subcategories: "all subcategories"
       category: "Category"
       posts: "Posts"
       topics: "Topics"

From 8ea1a1069ef0967dd3eaa173912be4822acce055 Mon Sep 17 00:00:00 2001
From: Neil Lalonde <neillalonde@gmail.com>
Date: Mon, 28 Oct 2013 16:15:45 -0400
Subject: [PATCH 4/5] Use the debounce parameter instead of hard-coding 100

---
 app/assets/javascripts/discourse/mixins/scrolling.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/assets/javascripts/discourse/mixins/scrolling.js b/app/assets/javascripts/discourse/mixins/scrolling.js
index d42b67c38..b106836ea 100644
--- a/app/assets/javascripts/discourse/mixins/scrolling.js
+++ b/app/assets/javascripts/discourse/mixins/scrolling.js
@@ -24,7 +24,7 @@ Discourse.Scrolling = Em.Mixin.create({
     if (opts.debounce) {
       onScrollMethod = Discourse.debounce(function() {
         return scrollingMixin.scrolled();
-      }, 100);
+      }, opts.debounce);
     } else {
       onScrollMethod = function() {
         return scrollingMixin.scrolled();

From e52f6e0f6d012ba3086b206d25a8f3c9f773d677 Mon Sep 17 00:00:00 2001
From: Neil Lalonde <neillalonde@gmail.com>
Date: Mon, 28 Oct 2013 16:16:48 -0400
Subject: [PATCH 5/5] FIX: weird scroll position on visiting a topic page for
 the first time (chrome OS X, maybe mobile safari too)

---
 app/assets/javascripts/discourse/models/post_stream.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/assets/javascripts/discourse/models/post_stream.js b/app/assets/javascripts/discourse/models/post_stream.js
index c4c0217d5..43819f614 100644
--- a/app/assets/javascripts/discourse/models/post_stream.js
+++ b/app/assets/javascripts/discourse/models/post_stream.js
@@ -253,6 +253,8 @@ Discourse.PostStream = Em.Object.extend({
 
       if (opts.nearPost) {
         Discourse.TopicView.jumpToPost(topic.get('id'), opts.nearPost);
+      } else {
+        Discourse.TopicView.jumpToPost(topic.get('id'), 1);
       }
 
       Discourse.URL.set('queryParams', postStream.get('streamFilters'));