diff --git a/app/assets/javascripts/admin/routes/admin_routes.js b/app/assets/javascripts/admin/routes/admin_routes.js index bb583fdc95d..f3a2a09a47b 100644 --- a/app/assets/javascripts/admin/routes/admin_routes.js +++ b/app/assets/javascripts/admin/routes/admin_routes.js @@ -4,7 +4,7 @@ @method buildRoutes @for Discourse.AdminRoute **/ -Discourse.buildRoutes(function() { +Discourse.Route.buildRoutes(function() { this.resource('admin', { path: '/admin' }, function() { this.route('dashboard', { path: '/' }); this.route('site_settings', { path: '/site_settings' }); diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js index 70932d6799b..4607c6a740a 100644 --- a/app/assets/javascripts/discourse.js +++ b/app/assets/javascripts/discourse.js @@ -1,31 +1,28 @@ /*global Modernizr:true*/ /*global assetPath:true*/ -var csrf_token; +/** + The main Discourse Application + @class Discourse + @extends Ember.Application +**/ Discourse = Ember.Application.createWithMixins({ rootElement: '#main', // Data we want to remember for a short period transient: Em.Object.create(), + // Whether the app has focus or not hasFocus: true, + + // Are we currently scrolling? scrolling: false, // The highest seen post number by topic highestSeenByTopic: {}, - logoSmall: (function() { - var logo; - logo = Discourse.SiteSettings.logo_small_url; - if (logo && logo.length > 1) { - return ""; - } else { - return ""; - } - }).property(), - - titleChanged: (function() { + titleChanged: function() { var title; title = ""; if (this.get('title')) { @@ -37,51 +34,45 @@ Discourse = Ember.Application.createWithMixins({ title = "(*) " + title; } // chrome bug workaround see: http://stackoverflow.com/questions/2952384/changing-the-window-title-when-focussing-the-window-doesnt-work-in-chrome - window.setTimeout((function() { + window.setTimeout(function() { document.title = "."; document.title = title; - }), 200); - }).observes('title', 'hasFocus', 'notify'), + }, 200); + }.observes('title', 'hasFocus', 'notify'), - currentUserChanged: (function() { - var bus, user; - bus = Discourse.MessageBus; + currentUserChanged: function() { // We don't want to receive any previous user notifications + var bus = Discourse.MessageBus; bus.unsubscribe("/notification/*"); bus.callbackInterval = Discourse.SiteSettings.anon_polling_interval; bus.enableLongPolling = false; - user = this.get('currentUser'); + + var user = this.get('currentUser'); if (user) { bus.callbackInterval = Discourse.SiteSettings.polling_interval; bus.enableLongPolling = true; if (user.admin) { bus.subscribe("/flagged_counts", function(data) { - return user.set('site_flagged_posts_count', data.total); + user.set('site_flagged_posts_count', data.total); }); } - return bus.subscribe("/notification/" + user.id, (function(data) { + bus.subscribe("/notification/" + user.id, (function(data) { user.set('unread_notifications', data.unread_notifications); - return user.set('unread_private_messages', data.unread_private_messages); + user.set('unread_private_messages', data.unread_private_messages); }), user.notification_channel_position); } - }).observes('currentUser'), - notifyTitle: function() { - return this.set('notify', true); - }, + }.observes('currentUser'), - // Browser aware replaceState - replaceState: function(path) { - if (window.history && - window.history.pushState && - window.history.replaceState && - !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)) { - if (window.location.pathname !== path) { - return history.replaceState({ - path: path - }, null, path); - } - } + // The classes of buttons to show on a post + postButtons: function() { + return Discourse.SiteSettings.post_menu.split("|").map(function(i) { + return (i.replace(/\+/, '').capitalize()); + }); + }.property('Discourse.SiteSettings.post_menu'), + + notifyTitle: function() { + this.set('notify', true); }, openComposer: function(opts) { @@ -90,291 +81,108 @@ Discourse = Ember.Application.createWithMixins({ if (composer) composer.open(opts); }, - // Like router.route, but allow full urls rather than relative one - // HERE BE HACKS - uses the ember container for now until we can do this nicer. - routeTo: function(path) { - var newMatches, newTopicId, oldMatches, oldTopicId, opts, router, topicController, topicRegexp; - path = path.replace(/https?\:\/\/[^\/]+/, ''); - - // If we're in the same topic, don't push the state - topicRegexp = /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/; - newMatches = topicRegexp.exec(path); - newTopicId = newMatches ? newMatches[2] : null; - if (newTopicId) { - oldMatches = topicRegexp.exec(window.location.pathname); - if ((oldTopicId = oldMatches ? oldMatches[2] : void 0) && (oldTopicId === newTopicId)) { - Discourse.replaceState(path); - topicController = Discourse.__container__.lookup('controller:topic'); - opts = { - trackVisit: false - }; - if (newMatches[3]) { - opts.nearPost = newMatches[3]; - } - topicController.get('content').loadPosts(opts); - return; - } - } - // Be wary of looking up the router. In this case, we have links in our - // HTML, say form compiled markdown posts, that need to be routed. - router = Discourse.__container__.lookup('router:main'); - router.router.updateURL(path); - return router.handleURL(path); - }, - - // The classes of buttons to show on a post - postButtons: (function() { - return Discourse.SiteSettings.post_menu.split("|").map(function(i) { - return "" + (i.replace(/\+/, '').capitalize()); - }); - }).property('Discourse.SiteSettings.post_menu'), + /** + Establishes global DOM events and bindings via jQuery. + @method bindDOMEvents + **/ bindDOMEvents: function() { - var $html, hasTouch, - _this = this; - $html = $('html'); + var $html, hasTouch; - /* Add the discourse touch event */ + $html = $('html'); hasTouch = false; + if ($html.hasClass('touch')) { hasTouch = true; } + if (Modernizr.prefixed("MaxTouchPoints", navigator) > 1) { hasTouch = true; } + if (hasTouch) { $html.addClass('discourse-touch'); this.touch = true; this.hasTouch = true; - } else { $html.addClass('discourse-no-touch'); this.touch = false; } + $('#main').on('click.discourse', '[data-not-implemented=true]', function(e) { e.preventDefault(); alert(Em.String.i18n('not_implemented')); return false; }); + $('#main').on('click.discourse', 'a', function(e) { - var $currentTarget, href; - if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) { - return; - } - $currentTarget = $(e.currentTarget); - href = $currentTarget.attr('href'); - if (href === void 0) { - return; - } - if (href === '#') { - return; - } - if ($currentTarget.attr('target')) { - return; - } - if ($currentTarget.data('auto-route')) { - return; - } - if ($currentTarget.hasClass('lightbox')) { - return; - } - if (href.indexOf("mailto:") === 0) { - return; - } - if (href.match(/^http[s]?:\/\//i) && !href.match(new RegExp("^http:\\/\\/" + window.location.hostname, "i"))) { - return; - } + if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) return; + + var $currentTarget = $(e.currentTarget); + var href = $currentTarget.attr('href'); + if (!href) return; + if (href === '#') return; + if ($currentTarget.attr('target')) return; + if ($currentTarget.data('auto-route')) return; + if ($currentTarget.hasClass('lightbox')) return; + if (href.indexOf("mailto:") === 0) return; + if (href.match(/^http[s]?:\/\//i) && !href.match(new RegExp("^http:\\/\\/" + window.location.hostname, "i"))) return; + e.preventDefault(); - _this.routeTo(href); + Discourse.URL.routeTo(href); return false; }); - return $(window).focus(function() { - _this.set('hasFocus', true); - return _this.set('notify', false); + + $(window).focus(function() { + Discourse.set('hasFocus', true); + Discourse.set('notify', false); }).blur(function() { - return _this.set('hasFocus', false); + Discourse.set('hasFocus', false); }); - }, - logout: function() { - var username, - _this = this; - username = this.get('currentUser.username'); - Discourse.KeyValueStore.abandonLocal(); - return jQuery.ajax("/session/" + username, { - type: 'DELETE', - success: function(result) { - /* To keep lots of our variables unbound, we can handle a redirect on logging out. - */ - return window.location.reload(); + + // Add a CSRF token to all AJAX requests + var csrfToken = $('meta[name=csrf-token]').attr('content'); + jQuery.ajaxPrefilter(function(options, originalOptions, xhr) { + if (!options.crossDomain) { + xhr.setRequestHeader('X-CSRF-Token', csrfToken); } }); }, - /* fancy probes in ember - */ - insertProbes: function() { - var topLevel; - if (typeof console === "undefined" || console === null) { - return; - } - topLevel = function(fn, name) { - return window.probes.measure(fn, { - name: name, - before: function(data, owner, args) { - if (owner) { - return window.probes.clear(); - } - }, - after: function(data, owner, args) { - var ary, f, n, v, _ref; - if (owner && data.time > 10) { - f = function(name, data) { - if (data && data.count) { - return "" + name + " - " + data.count + " calls " + ((data.time + 0.0).toFixed(2)) + "ms"; - } - }; - if (console && console.group) { - console.group(f(name, data)); - } else { - console.log(""); - console.log(f(name, data)); - } - ary = []; - _ref = window.probes; - for (n in _ref) { - v = _ref[n]; - if (n === name || v.time < 1) { - continue; - } - ary.push({ - k: n, - v: v - }); - } - ary.sortBy(function(item) { - if (item.v && item.v.time) { - return -item.v.time; - } else { - return 0; - } - }).each(function(item) { - var output = f("" + item.k, item.v); - if (output) { - return console.log(output); - } - }); - if (typeof console !== "undefined" && console !== null) { - if (typeof console.groupEnd === "function") { - console.groupEnd(); - } - } - return window.probes.clear(); - } - } - }); - }; - Ember.View.prototype.renderToBuffer = window.probes.measure(Ember.View.prototype.renderToBuffer, "renderToBuffer"); - Discourse.routeTo = topLevel(Discourse.routeTo, "Discourse.routeTo"); - Ember.run.end = topLevel(Ember.run.end, "Ember.run.end"); + /** + Log the current user out of Discourse + + @method logout + **/ + logout: function() { + Discourse.KeyValueStore.abandonLocal(); + return jQuery.ajax("/session/" + this.get('currentUser.username'), { + type: 'DELETE', + success: function(result) { + // To keep lots of our variables unbound, we can handle a redirect on logging out. + window.location.reload(); + } + }); }, + authenticationComplete: function(options) { // TODO, how to dispatch this to the view without the container? var loginView; loginView = Discourse.__container__.lookup('controller:modal').get('currentView'); return loginView.authenticationComplete(options); }, - buildRoutes: function(builder) { - var oldBuilder; - oldBuilder = Discourse.routeBuilder; - Discourse.routeBuilder = function() { - if (oldBuilder) { - oldBuilder.call(this); - } - return builder.call(this); - }; - }, + start: function() { - this.bindDOMEvents(); + Discourse.bindDOMEvents(); Discourse.SiteSettings = PreloadStore.getStatic('siteSettings'); Discourse.MessageBus.start(); Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus); - Discourse.insertProbes(); - // subscribe to any site customizations that are loaded - $('link.custom-css').each(function() { - var id, split, stylesheet, - _this = this; - split = this.href.split("/"); - id = split[split.length - 1].split(".css")[0]; - stylesheet = this; - return Discourse.MessageBus.subscribe("/file-change/" + id, function(data) { - var orig, sp; - if (!$(stylesheet).data('orig')) { - $(stylesheet).data('orig', stylesheet.href); - } - orig = $(stylesheet).data('orig'); - sp = orig.split(".css?"); - stylesheet.href = sp[0] + ".css?" + data; - }); - }); - $('header.custom').each(function() { - var header; - header = $(this); - return Discourse.MessageBus.subscribe("/header-change/" + ($(this).data('key')), function(data) { - return header.html(data); - }); - }); - - // possibly move this to dev only - return Discourse.MessageBus.subscribe("/file-change", function(data) { - Ember.TEMPLATES.empty = Handlebars.compile("
"); - return data.each(function(me) { - var js; - if (me === "refresh") { - return document.location.reload(true); - } else if (me.name.substr(-10) === "handlebars") { - js = me.name.replace(".handlebars", "").replace("app/assets/javascripts", "/assets"); - return $LAB.script(js + "?hash=" + me.hash).wait(function() { - var templateName; - templateName = js.replace(".js", "").replace("/assets/", ""); - return jQuery.each(Ember.View.views, function() { - var _this = this; - if (this.get('templateName') === templateName) { - this.set('templateName', 'empty'); - this.rerender(); - return Em.run.next(function() { - _this.set('templateName', templateName); - return _this.rerender(); - }); - } - }); - }); - } else { - return $('link').each(function() { - if (this.href.match(me.name) && me.hash) { - if (!$(this).data('orig')) { - $(this).data('orig', this.href); - } - this.href = $(this).data('orig') + "&hash=" + me.hash; - } - }); - } - }); - }); + // Developer specific functions + Discourse.Development.setupProbes(); + Discourse.Development.observeLiveChanges(); } + }); -Discourse.Router = Discourse.Router.reopen({ - location: 'discourse_location' -}); - -// since we have no jquery-rails these days, hook up csrf token -csrf_token = $('meta[name=csrf-token]').attr('content'); - -jQuery.ajaxPrefilter(function(options, originalOptions, xhr) { - if (!options.crossDomain) { - xhr.setRequestHeader('X-CSRF-Token', csrf_token); - } -}); - - +Discourse.Router = Discourse.Router.reopen({ location: 'discourse_location' }); \ No newline at end of file diff --git a/app/assets/javascripts/discourse/components/click_track.js b/app/assets/javascripts/discourse/components/click_track.js index 7f2e66cdf07..df9b68943f8 100644 --- a/app/assets/javascripts/discourse/components/click_track.js +++ b/app/assets/javascripts/discourse/components/click_track.js @@ -88,7 +88,7 @@ Discourse.ClickTrack = { topic_id: topicId, redirect: false }); - Discourse.routeTo(href); + Discourse.URL.routeTo(href); return false; } diff --git a/app/assets/javascripts/discourse/components/development.js b/app/assets/javascripts/discourse/components/development.js new file mode 100644 index 00000000000..7e1d314fa87 --- /dev/null +++ b/app/assets/javascripts/discourse/components/development.js @@ -0,0 +1,158 @@ +/** + Functions to help development of Discourse, such as inserting probes + + @class Development + @namespace Discourse + @module Discourse +**/ +Discourse.Development = { + + + /** + Set up probes for performance measurements. + + @method setupProbes + **/ + setupProbes: function() { + + // Don't probe if we don't have a console + if (typeof console === "undefined" || console === null) return; + + var topLevel = function(fn, name) { + return window.probes.measure(fn, { + name: name, + + before: function(data, owner, args) { + if (owner) { + return window.probes.clear(); + } + }, + + after: function(data, owner, args) { + var ary, f, n, v, _ref; + if (owner && data.time > 10) { + + f = function(name, data) { + if (data && data.count) return name + " - " + data.count + " calls " + ((data.time + 0.0).toFixed(2)) + "ms"; + }; + + if (console && console.group) { + console.group(f(name, data)); + } else { + console.log(""); + console.log(f(name, data)); + } + + ary = []; + _ref = window.probes; + for (n in _ref) { + v = _ref[n]; + if (n === name || v.time < 1) { + continue; + } + ary.push({ + k: n, + v: v + }); + } + ary.sortBy(function(item) { + if (item.v && item.v.time) { + return -item.v.time; + } else { + return 0; + } + }).each(function(item) { + var output = f("" + item.k, item.v); + if (output) { + return console.log(output); + } + }); + if (typeof console !== "undefined" && console !== null) { + if (typeof console.groupEnd === "function") { + console.groupEnd(); + } + } + return window.probes.clear(); + } + } + }); + }; + + Ember.View.prototype.renderToBuffer = window.probes.measure(Ember.View.prototype.renderToBuffer, "renderToBuffer"); + Discourse.URL.routeTo = topLevel(Discourse.URL.routeTo, "Discourse.URL.routeTo"); + Ember.run.end = topLevel(Ember.run.end, "Ember.run.end"); + }, + + /** + Use the message bus for live reloading of components for faster development. + + @method observeLiveChanges + **/ + observeLiveChanges: function() { + + // subscribe to any site customizations that are loaded + $('link.custom-css').each(function() { + var id, split, stylesheet, + _this = this; + split = this.href.split("/"); + id = split[split.length - 1].split(".css")[0]; + stylesheet = this; + return Discourse.MessageBus.subscribe("/file-change/" + id, function(data) { + var orig, sp; + if (!$(stylesheet).data('orig')) { + $(stylesheet).data('orig', stylesheet.href); + } + orig = $(stylesheet).data('orig'); + sp = orig.split(".css?"); + stylesheet.href = sp[0] + ".css?" + data; + }); + }); + + // Custom header changes + $('header.custom').each(function() { + var header; + header = $(this); + return Discourse.MessageBus.subscribe("/header-change/" + ($(this).data('key')), function(data) { + return header.html(data); + }); + }); + + // Observe file changes + return Discourse.MessageBus.subscribe("/file-change", function(data) { + Ember.TEMPLATES.empty = Handlebars.compile("
"); + return data.each(function(me) { + var js; + if (me === "refresh") { + return document.location.reload(true); + } else if (me.name.substr(-10) === "handlebars") { + js = me.name.replace(".handlebars", "").replace("app/assets/javascripts", "/assets"); + return $LAB.script(js + "?hash=" + me.hash).wait(function() { + var templateName; + templateName = js.replace(".js", "").replace("/assets/", ""); + return jQuery.each(Ember.View.views, function() { + var _this = this; + if (this.get('templateName') === templateName) { + this.set('templateName', 'empty'); + this.rerender(); + return Em.run.next(function() { + _this.set('templateName', templateName); + return _this.rerender(); + }); + } + }); + }); + } else { + return $('link').each(function() { + if (this.href.match(me.name) && me.hash) { + if (!$(this).data('orig')) { + $(this).data('orig', this.href); + } + this.href = $(this).data('orig') + "&hash=" + me.hash; + } + }); + } + }); + }); + } + +}; \ No newline at end of file diff --git a/app/assets/javascripts/discourse/components/url.js b/app/assets/javascripts/discourse/components/url.js new file mode 100644 index 00000000000..b4ff5b4e6cf --- /dev/null +++ b/app/assets/javascripts/discourse/components/url.js @@ -0,0 +1,69 @@ +/** + URL related functions. + + @class URL + @namespace Discourse + @module Discourse +**/ +Discourse.URL = { + + /** + Browser aware replaceState. Will only be invoked if the browser supports it. + + @method replaceState + @param {String} path The path we are replacing our history state with. + **/ + replaceState: function(path) { + if (window.history && + window.history.pushState && + window.history.replaceState && + !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/) && + (window.location.pathname !== path)) { + return history.replaceState({ path: path }, null, path); + } + }, + + /** + Our custom routeTo method is used to intelligently overwrite default routing + behavior. + + It contains the logic necessary to route within a topic using replaceState to + keep the history intact. + + Note that currently it uses `__container__` which is not advised + but there is no other way to access the router. + + @method routeTo + @param {String} path The path we are routing to. + **/ + routeTo: function(path) { + var newMatches, newTopicId, oldMatches, oldTopicId, opts, router, topicController, topicRegexp; + path = path.replace(/https?\:\/\/[^\/]+/, ''); + + console.log("route to: " + path); + + // If we're in the same topic, don't push the state + topicRegexp = /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/; + newMatches = topicRegexp.exec(path); + newTopicId = newMatches ? newMatches[2] : null; + if (newTopicId) { + oldMatches = topicRegexp.exec(window.location.pathname); + if ((oldTopicId = oldMatches ? oldMatches[2] : void 0) && (oldTopicId === newTopicId)) { + Discourse.URL.replaceState(path); + topicController = Discourse.__container__.lookup('controller:topic'); + opts = { trackVisit: false }; + if (newMatches[3]) { + opts.nearPost = newMatches[3]; + } + topicController.get('content').loadPosts(opts); + return; + } + } + // Be wary of looking up the router. In this case, we have links in our + // HTML, say form compiled markdown posts, that need to be routed. + router = Discourse.__container__.lookup('router:main'); + router.router.updateURL(path); + return router.handleURL(path); + } + +}; \ No newline at end of file diff --git a/app/assets/javascripts/discourse/controllers/composer_controller.js b/app/assets/javascripts/discourse/controllers/composer_controller.js index d19b946a855..7666505be5b 100644 --- a/app/assets/javascripts/discourse/controllers/composer_controller.js +++ b/app/assets/javascripts/discourse/controllers/composer_controller.js @@ -42,7 +42,7 @@ Discourse.ComposerController = Discourse.Controller.extend({ } else { Discourse.set('currentUser.reply_count', Discourse.get('currentUser.reply_count') + 1); } - Discourse.routeTo(opts.post.get('url')); + Discourse.URL.routeTo(opts.post.get('url')); }, function(error) { composer.set('disableDrafts', false); bootbox.alert(error); @@ -159,7 +159,7 @@ Discourse.ComposerController = Discourse.Controller.extend({ // View a new reply we've made viewNewReply: function() { - Discourse.routeTo(this.get('createdPost.url')); + Discourse.URL.routeTo(this.get('createdPost.url')); this.close(); return false; }, diff --git a/app/assets/javascripts/discourse/controllers/header_controller.js b/app/assets/javascripts/discourse/controllers/header_controller.js index 716282bebe7..6d60c8437db 100644 --- a/app/assets/javascripts/discourse/controllers/header_controller.js +++ b/app/assets/javascripts/discourse/controllers/header_controller.js @@ -1,21 +1,21 @@ /** This controller supports actions on the site header - @class HeaderController + @class HeaderController @extends Discourse.Controller @namespace Discourse @module Discourse -**/ +**/ Discourse.HeaderController = Discourse.Controller.extend({ topic: null, - showExtraInfo: false, + showExtraInfo: null, toggleStar: function() { var topic = this.get('topic'); if (topic) topic.toggleStar(); return false; } - + }); diff --git a/app/assets/javascripts/discourse/controllers/topic_controller.js b/app/assets/javascripts/discourse/controllers/topic_controller.js index 50c7caa6669..f1c503b0d85 100644 --- a/app/assets/javascripts/discourse/controllers/topic_controller.js +++ b/app/assets/javascripts/discourse/controllers/topic_controller.js @@ -10,7 +10,6 @@ Discourse.TopicController = Discourse.ObjectController.extend({ userFilters: new Em.Set(), multiSelect: false, bestOf: false, - showExtraHeaderInfo: false, needs: ['header', 'modal', 'composer', 'quoteButton'], filter: (function() { @@ -42,10 +41,6 @@ Discourse.TopicController = Discourse.ObjectController.extend({ return this.get('canDeleteSelected'); }).property('canDeleteSelected'), - showExtraHeaderInfoChanged: (function() { - this.set('controllers.header.showExtraInfo', this.get('showExtraHeaderInfo')); - }).observes('showExtraHeaderInfo'), - canDeleteSelected: (function() { var canDelete, selectedPosts; selectedPosts = this.get('selectedPosts'); @@ -109,11 +104,11 @@ Discourse.TopicController = Discourse.ObjectController.extend({ }, jumpTop: function() { - Discourse.routeTo(this.get('content.url')); + Discourse.URL.routeTo(this.get('content.url')); }, jumpBottom: function() { - Discourse.routeTo(this.get('content.lastPostUrl')); + Discourse.URL.routeTo(this.get('content.lastPostUrl')); }, cancelFilter: function() { diff --git a/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js b/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js index 608bc2b54fc..eea4d849bcc 100644 --- a/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js +++ b/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js @@ -9,7 +9,7 @@ Discourse.UserPrivateMessagesController = Discourse.ObjectController.extend({ editPreferences: function() { - return Discourse.routeTo("/users/" + (this.get('content.username_lower')) + "/preferences"); + return Discourse.URL.routeTo("/users/" + (this.get('content.username_lower')) + "/preferences"); }, composePrivateMessage: function() { diff --git a/app/assets/javascripts/discourse/models/topic_list.js b/app/assets/javascripts/discourse/models/topic_list.js index c5781bac165..32f40ebc629 100644 --- a/app/assets/javascripts/discourse/models/topic_list.js +++ b/app/assets/javascripts/discourse/models/topic_list.js @@ -14,7 +14,7 @@ Discourse.TopicList = Discourse.Model.extend({ _this = this; promise = new RSVP.Promise(); if (moreUrl = this.get('more_topics_url')) { - Discourse.replaceState("/" + (this.get('filter')) + "/more"); + Discourse.URL.replaceState("/" + (this.get('filter')) + "/more"); jQuery.ajax(moreUrl, { success: function(result) { var newTopics, topicIds, topics; diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js index 744d89af7bb..a491962d1d6 100644 --- a/app/assets/javascripts/discourse/routes/application_routes.js +++ b/app/assets/javascripts/discourse/routes/application_routes.js @@ -4,7 +4,7 @@ @method buildRoutes @for Discourse.ApplicationRoute **/ -Discourse.buildRoutes(function() { +Discourse.Route.buildRoutes(function() { var router = this; // Topic routes diff --git a/app/assets/javascripts/discourse/routes/discourse_route.js b/app/assets/javascripts/discourse/routes/discourse_route.js index c76fc682f89..7489189465f 100644 --- a/app/assets/javascripts/discourse/routes/discourse_route.js +++ b/app/assets/javascripts/discourse/routes/discourse_route.js @@ -28,3 +28,14 @@ Discourse.Route = Em.Route.extend({ }); +Discourse.Route.reopenClass({ + + buildRoutes: function(builder) { + var oldBuilder = Discourse.routeBuilder; + Discourse.routeBuilder = function() { + if (oldBuilder) oldBuilder.call(this); + return builder.call(this); + }; + } + +}); diff --git a/app/assets/javascripts/discourse/routes/topic_route.js b/app/assets/javascripts/discourse/routes/topic_route.js index 5145062bcb4..9c7e7436d0c 100644 --- a/app/assets/javascripts/discourse/routes/topic_route.js +++ b/app/assets/javascripts/discourse/routes/topic_route.js @@ -34,10 +34,7 @@ Discourse.TopicRoute = Discourse.Route.extend({ }, setupController: function(controller, model) { - var headerController; - controller.set('showExtraHeaderInfo', false); - headerController = this.controllerFor('header'); - headerController.set('topic', model); + this.controllerFor('header').set('topic', model); } }); diff --git a/app/assets/javascripts/discourse/templates/header.js.handlebars b/app/assets/javascripts/discourse/templates/header.js.handlebars index ab13bc0f1a4..98488b61568 100644 --- a/app/assets/javascripts/discourse/templates/header.js.handlebars +++ b/app/assets/javascripts/discourse/templates/header.js.handlebars @@ -1,17 +1,7 @@
-
- {{#if controller.showExtraInfo}} - - {{#linkTo list.popular}}{{{Discourse.logoSmall}}}{{/linkTo}} - - {{else}} - - {{#linkTo list.popular}}{{/linkTo}} - - {{/if}} -
+ {{view.logoHTML}} {{view Discourse.TopicExtraInfoView}}
@@ -24,7 +14,7 @@ {{/if}}
{{/unless}} -