From 69851bc6cf1e77f78f9edfd4f4f27c4a4a1dc024 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 12 Mar 2015 12:12:23 -0400 Subject: [PATCH] Deprecates global use of `Discourse.MessageBus` We can use DI for this, which makes it easier for plugins to subscribe to the message bus. --- .../admin/routes/admin-backups.js.es6 | 8 +-- .../discourse/controllers/topic.js.es6 | 4 +- .../initializers/asset-version.js.es6 | 13 +++-- .../discourse/initializers/banner.js.es6 | 11 ++-- .../initializers/inject-objects.js.es6 | 50 +++++++++---------- .../initializers/live-development.js.es6 | 9 ++-- .../discourse/initializers/logout.js.es6 | 15 +++--- .../discourse/initializers/message-bus.js.es6 | 23 ++++++--- .../discourse/initializers/read-only.js.es6 | 13 +++-- .../subscribe-user-notifications.js.es6 | 19 +++---- .../javascripts/discourse/lib/message_bus.js | 1 - .../models/topic-tracking-state.js.es6 | 19 ++++--- .../javascripts/discourse/routes/user.js.es6 | 4 +- test/javascripts/test_helper.js | 2 +- 14 files changed, 98 insertions(+), 93 deletions(-) delete mode 100644 app/assets/javascripts/discourse/lib/message_bus.js diff --git a/app/assets/javascripts/admin/routes/admin-backups.js.es6 b/app/assets/javascripts/admin/routes/admin-backups.js.es6 index 8234048c2..64b8984ed 100644 --- a/app/assets/javascripts/admin/routes/admin-backups.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-backups.js.es6 @@ -1,11 +1,11 @@ import showModal from 'discourse/lib/show-modal'; +const LOG_CHANNEL = "/admin/backups/logs"; + export default Discourse.Route.extend({ - LOG_CHANNEL: "/admin/backups/logs", - activate() { - Discourse.MessageBus.subscribe(this.LOG_CHANNEL, this._processLogMessage.bind(this)); + this.messageBus.subscribe(LOG_CHANNEL, this._processLogMessage.bind(this)); }, _processLogMessage(log) { @@ -40,7 +40,7 @@ export default Discourse.Route.extend({ }, deactivate() { - Discourse.MessageBus.unsubscribe(this.LOG_CHANNEL); + this.messageBus.unsubscribe(LOG_CHANNEL); }, actions: { diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index a55954dbe..3b3850b67 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -563,7 +563,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon this.unsubscribe(); const self = this; - Discourse.MessageBus.subscribe("/topic/" + this.get('id'), function(data) { + this.messageBus.subscribe("/topic/" + this.get('id'), function(data) { const topic = self.get('model'); if (data.notification_level_change) { @@ -605,7 +605,7 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedCon if (!topicId) return; // there is a condition where the view never calls unsubscribe, navigate to a topic from a topic - Discourse.MessageBus.unsubscribe('/topic/*'); + this.messageBus.unsubscribe('/topic/*'); }, // Topic related diff --git a/app/assets/javascripts/discourse/initializers/asset-version.js.es6 b/app/assets/javascripts/discourse/initializers/asset-version.js.es6 index 0e03ce13a..6f3b3686d 100644 --- a/app/assets/javascripts/discourse/initializers/asset-version.js.es6 +++ b/app/assets/javascripts/discourse/initializers/asset-version.js.es6 @@ -1,15 +1,14 @@ -/** - Subscribe to "asset-version" change events via the Message Bus -**/ +// Subscribe to "asset-version" change events via the Message Bus export default { name: "asset-version", after: "message-bus", - initialize: function () { - var timeoutIsSet = false; - if (!Discourse.MessageBus) { return; } + initialize(container) { + let timeoutIsSet = false; + const messageBus = container.lookup('message-bus:main'); + if (!messageBus) { return; } - Discourse.MessageBus.subscribe("/global/asset-version", function (version) { + messageBus.subscribe("/global/asset-version", function (version) { Discourse.set("assetVersion", version); if (!timeoutIsSet && Discourse.get("requiresRefresh")) { diff --git a/app/assets/javascripts/discourse/initializers/banner.js.es6 b/app/assets/javascripts/discourse/initializers/banner.js.es6 index 718a253a5..d4a1cb6f7 100644 --- a/app/assets/javascripts/discourse/initializers/banner.js.es6 +++ b/app/assets/javascripts/discourse/initializers/banner.js.es6 @@ -2,15 +2,16 @@ export default { name: "banner", after: "message-bus", - initialize: function (container) { - var banner = Em.Object.create(PreloadStore.get("banner")), - site = container.lookup('site:main'); + initialize(container) { + const banner = Em.Object.create(PreloadStore.get("banner")), + site = container.lookup('site:main'); site.set("banner", banner); - if (!Discourse.MessageBus) { return; } + const messageBus = container.lookup('message-bus:main'); + if (!messageBus) { return; } - Discourse.MessageBus.subscribe("/site/banner", function (banner) { + messageBus.subscribe("/site/banner", function (banner) { site.set("banner", Em.Object.create(banner)); }); } diff --git a/app/assets/javascripts/discourse/initializers/inject-objects.js.es6 b/app/assets/javascripts/discourse/initializers/inject-objects.js.es6 index 7950eb467..be33aed10 100644 --- a/app/assets/javascripts/discourse/initializers/inject-objects.js.es6 +++ b/app/assets/javascripts/discourse/initializers/inject-objects.js.es6 @@ -2,53 +2,49 @@ import Session from 'discourse/models/session'; import AppEvents from 'discourse/lib/app-events'; import Store from 'discourse/models/store'; +function inject() { + const app = arguments[0], + name = arguments[1], + singletonName = Ember.String.underscore(name).replace(/_/, '-') + ':main'; + + Array.prototype.slice.call(arguments, 2).forEach(function(dest) { + app.inject(dest, name, singletonName); + }); +} + +function injectAll(app, name) { + inject(app, name, 'controller', 'component', 'route', 'view', 'model'); +} + export default { name: "inject-objects", initialize(container, app) { - // Inject appEvents everywhere const appEvents = AppEvents.create(); app.register('app-events:main', appEvents, { instantiate: false }); - - app.inject('controller', 'appEvents', 'app-events:main'); - app.inject('component', 'appEvents', 'app-events:main'); - app.inject('route', 'appEvents', 'app-events:main'); - app.inject('view', 'appEvents', 'app-events:main'); - app.inject('model', 'appEvents', 'app-events:main'); + injectAll(app, 'appEvents'); Discourse.URL.appEvents = appEvents; // Inject Discourse.Site to avoid using Discourse.Site.current() const site = Discourse.Site.current(); app.register('site:main', site, { instantiate: false }); - app.inject('controller', 'site', 'site:main'); - app.inject('component', 'site', 'site:main'); - app.inject('route', 'site', 'site:main'); - app.inject('view', 'site', 'site:main'); - app.inject('model', 'site', 'site:main'); + injectAll(app, 'site'); // Inject Discourse.SiteSettings to avoid using Discourse.SiteSettings globals app.register('site-settings:main', Discourse.SiteSettings, { instantiate: false }); - app.inject('controller', 'siteSettings', 'site-settings:main'); - app.inject('component', 'siteSettings', 'site-settings:main'); - app.inject('route', 'siteSettings', 'site-settings:main'); - app.inject('view', 'siteSettings', 'site-settings:main'); - app.inject('model', 'siteSettings', 'site-settings:main'); + injectAll(app, 'siteSettings'); // Inject Session for transient data app.register('session:main', Session.current(), { instantiate: false }); - app.inject('controller', 'session', 'session:main'); - app.inject('component', 'session', 'session:main'); - app.inject('route', 'session', 'session:main'); - app.inject('view', 'session', 'session:main'); - app.inject('model', 'session', 'session:main'); + injectAll(app, 'session'); app.register('current-user:main', Discourse.User.current(), { instantiate: false }); - app.inject('component', 'currentUser', 'current-user:main'); - app.inject('route', 'currentUser', 'current-user:main'); - app.inject('controller', 'currentUser', 'current-user:main'); + inject(app, 'currentUser', 'component', 'route', 'controller'); + + app.register('message-bus:main', window.MessageBus, { instantiate: false }); + inject(app, 'messageBus', 'route', 'controller'); app.register('store:main', Store); - app.inject('route', 'store', 'store:main'); - app.inject('controller', 'store', 'store:main'); + inject(app, 'store', 'route', 'controller'); } }; diff --git a/app/assets/javascripts/discourse/initializers/live-development.js.es6 b/app/assets/javascripts/discourse/initializers/live-development.js.es6 index d3a75461e..817b9e058 100644 --- a/app/assets/javascripts/discourse/initializers/live-development.js.es6 +++ b/app/assets/javascripts/discourse/initializers/live-development.js.es6 @@ -3,7 +3,8 @@ import loadScript from 'discourse/lib/load-script'; // Use the message bus for live reloading of components for faster development. export default { name: "live-development", - initialize() { + initialize(container) { + const messageBus = container.lookup('message-bus:main'); // subscribe to any site customizations that are loaded $('link.custom-css').each(function() { @@ -11,7 +12,7 @@ export default { id = split[split.length - 1].split(".css")[0], self = this; - return Discourse.MessageBus.subscribe("/file-change/" + id, function(data) { + return messageBus.subscribe("/file-change/" + id, function(data) { if (!$(self).data('orig')) { $(self).data('orig', self.href); } @@ -24,13 +25,13 @@ export default { // Custom header changes $('header.custom').each(function() { const header = $(this); - return Discourse.MessageBus.subscribe("/header-change/" + $(this).data('key'), function(data) { + return messageBus.subscribe("/header-change/" + $(this).data('key'), function(data) { return header.html(data); }); }); // Observe file changes - Discourse.MessageBus.subscribe("/file-change", function(data) { + messageBus.subscribe("/file-change", function(data) { Ember.TEMPLATES.empty = Handlebars.compile("
"); _.each(data,function(me) { diff --git a/app/assets/javascripts/discourse/initializers/logout.js.es6 b/app/assets/javascripts/discourse/initializers/logout.js.es6 index 926ae3beb..7fdf60ae1 100644 --- a/app/assets/javascripts/discourse/initializers/logout.js.es6 +++ b/app/assets/javascripts/discourse/initializers/logout.js.es6 @@ -1,16 +1,17 @@ -/** - Subscribe to "logout" change events via the Message Bus -**/ +// Subscribe to "logout" change events via the Message Bus export default { name: "logout", after: "message-bus", - initialize: function () { - if (!Discourse.MessageBus) { return; } + initialize: function (container) { + const messageBus = container.lookup('message-bus:main'), + siteSettings = container.lookup('site-settings:main'); - Discourse.MessageBus.subscribe("/logout", function () { + if (!messageBus) { return; } + + messageBus.subscribe("/logout", function () { var refresher = function() { - var redirect = Discourse.SiteSettings.logout_redirect; + var redirect = siteSettings.logout_redirect; if(redirect.length === 0){ window.location.pathname = Discourse.getURL('/'); } else { diff --git a/app/assets/javascripts/discourse/initializers/message-bus.js.es6 b/app/assets/javascripts/discourse/initializers/message-bus.js.es6 index bbc6716bf..452dd0239 100644 --- a/app/assets/javascripts/discourse/initializers/message-bus.js.es6 +++ b/app/assets/javascripts/discourse/initializers/message-bus.js.es6 @@ -1,17 +1,24 @@ -/** - Initialize the message bus to receive messages. -**/ +// Initialize the message bus to receive messages. export default { name: "message-bus", after: 'inject-objects', - initialize: function() { - + initialize(container) { // We don't use the message bus in testing if (Discourse.testing) { return; } - Discourse.MessageBus.alwaysLongPoll = Discourse.Environment === "development"; - Discourse.MessageBus.start(); - Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus); + const messageBus = container.lookup('message-bus:main'); + + const deprecatedBus = {}; + deprecatedBus.prototype = messageBus; + deprecatedBus.subscribe = function() { + Ember.warn("Discourse.MessageBus is deprecated. Use `this.messageBus` instead"); + messageBus.subscribe.apply(messageBus, Array.prototype.slice(arguments)); + }; + Discourse.MessageBus = deprecatedBus; + + messageBus.alwaysLongPoll = Discourse.Environment === "development"; + messageBus.start(); + Discourse.KeyValueStore.init("discourse_", messageBus); } }; diff --git a/app/assets/javascripts/discourse/initializers/read-only.js.es6 b/app/assets/javascripts/discourse/initializers/read-only.js.es6 index a6822bab3..a270f951f 100644 --- a/app/assets/javascripts/discourse/initializers/read-only.js.es6 +++ b/app/assets/javascripts/discourse/initializers/read-only.js.es6 @@ -1,15 +1,14 @@ -/** - Subscribe to "read-only" status change events via the Message Bus -**/ +// Subscribe to "read-only" status change events via the Message Bus export default { name: "read-only", after: "message-bus", - initialize: function (container) { - if (!Discourse.MessageBus) { return; } + initialize(container) { + const messageBus = container.lookup('message-bus:main'); + if (!messageBus) { return; } - var site = container.lookup('site:main'); - Discourse.MessageBus.subscribe("/site/read-only", function (enabled) { + const site = container.lookup('site:main'); + messageBus.subscribe("/site/read-only", function (enabled) { site.set('isReadOnly', enabled); }); } diff --git a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 index fe79cb98e..9689614dd 100644 --- a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 +++ b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 @@ -1,16 +1,13 @@ -/** - Subscribes to user events on the message bus -**/ +// Subscribes to user events on the message bus export default { name: 'subscribe-user-notifications', after: 'message-bus', - initialize: function(container) { - var user = Discourse.User.current(); + initialize(container) { + const user = container.lookup('current-user:main'), + site = container.lookup('site:main'), + siteSettings = container.lookup('site-settings:main'), + bus = container.lookup('message-bus:main'); - var site = container.lookup('site:main'), - siteSettings = container.lookup('site-settings:main'); - - var bus = Discourse.MessageBus; bus.callbackInterval = siteSettings.anon_polling_interval; bus.backgroundCallbackInterval = siteSettings.background_polling_interval; bus.baseUrl = siteSettings.long_polling_base_url; @@ -36,8 +33,8 @@ export default { }); } bus.subscribe("/notification/" + user.get('id'), (function(data) { - var oldUnread = user.get('unread_notifications'); - var oldPM = user.get('unread_private_messages'); + const oldUnread = user.get('unread_notifications'); + const oldPM = user.get('unread_private_messages'); user.set('unread_notifications', data.unread_notifications); user.set('unread_private_messages', data.unread_private_messages); diff --git a/app/assets/javascripts/discourse/lib/message_bus.js b/app/assets/javascripts/discourse/lib/message_bus.js deleted file mode 100644 index ed18f383e..000000000 --- a/app/assets/javascripts/discourse/lib/message_bus.js +++ /dev/null @@ -1 +0,0 @@ -Discourse.MessageBus = window.MessageBus; diff --git a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 index 947f0ba18..036fac5a6 100644 --- a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 +++ b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 @@ -52,11 +52,10 @@ const TopicTrackingState = Discourse.Model.extend({ } }; - Discourse.MessageBus.subscribe("/new", process); - Discourse.MessageBus.subscribe("/latest", process); - const currentUser = Discourse.User.current(); - if(currentUser) { - Discourse.MessageBus.subscribe("/unread/" + currentUser.id, process); + this.messageBus.subscribe("/new", process); + this.messageBus.subscribe("/latest", process); + if (this.currentUser) { + this.messageBus.subscribe("/unread/" + this.currentUser.get('id'), process); } }, @@ -293,8 +292,14 @@ const TopicTrackingState = Discourse.Model.extend({ TopicTrackingState.reopenClass({ - createFromStates(data){ - const instance = Discourse.TopicTrackingState.create(); + createFromStates(data) { + + // TODO: This should be a model that does injection automatically + const container = Discourse.__container__, + messageBus = container.lookup('message-bus:main'), + currentUser = container.lookup('current-user:main'), + instance = Discourse.TopicTrackingState.create({ messageBus, currentUser }); + instance.loadStates(data); instance.establishChannels(); return instance; diff --git a/app/assets/javascripts/discourse/routes/user.js.es6 b/app/assets/javascripts/discourse/routes/user.js.es6 index 0ab1271fd..6e206c82e 100644 --- a/app/assets/javascripts/discourse/routes/user.js.es6 +++ b/app/assets/javascripts/discourse/routes/user.js.es6 @@ -69,14 +69,14 @@ export default Discourse.Route.extend({ activate: function() { this._super(); var user = this.modelFor('user'); - Discourse.MessageBus.subscribe("/users/" + user.get('username_lower'), function(data) { + this.messageBus.subscribe("/users/" + user.get('username_lower'), function(data) { user.loadUserAction(data); }); }, deactivate: function() { this._super(); - Discourse.MessageBus.unsubscribe("/users/" + this.modelFor('user').get('username_lower')); + this.messageBus.unsubscribe("/users/" + this.modelFor('user').get('username_lower')); // Remove the search context this.controllerFor('search').set('searchContext', null); diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js index a9bd9b664..38c3eb2a9 100644 --- a/test/javascripts/test_helper.js +++ b/test/javascripts/test_helper.js @@ -62,7 +62,7 @@ sinon.config = { window.assetPath = function() { return null; }; // Stop the message bus so we don't get ajax calls -Discourse.MessageBus.stop(); +window.MessageBus.stop(); // Trick JSHint into allow document.write var d = document;