mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 23:58:31 -05:00
Refactor: Move initialization code into separate initializers that use the API we
developed for plugins.
This commit is contained in:
parent
de78ee302a
commit
274743b877
14 changed files with 219 additions and 189 deletions
|
@ -11,9 +11,6 @@
|
|||
Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
||||
rootElement: '#main',
|
||||
|
||||
// Whether the app has focus or not
|
||||
hasFocus: true,
|
||||
|
||||
// Helps with integration tests
|
||||
URL_FIXTURES: {},
|
||||
|
||||
|
@ -69,61 +66,6 @@ Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
this.set('notifyCount', count);
|
||||
},
|
||||
|
||||
/**
|
||||
Establishes global DOM events and bindings via jQuery.
|
||||
|
||||
@method bindDOMEvents
|
||||
**/
|
||||
bindDOMEvents: function() {
|
||||
$('#main').on('click.discourse', 'a', function(e) {
|
||||
if (e.isDefaultPrevented() || e.shiftKey || e.metaKey || e.ctrlKey) { return; }
|
||||
|
||||
var $currentTarget = $(e.currentTarget),
|
||||
href = $currentTarget.attr('href');
|
||||
|
||||
if (!href ||
|
||||
href === '#' ||
|
||||
$currentTarget.attr('target') ||
|
||||
$currentTarget.data('ember-action') ||
|
||||
$currentTarget.data('auto-route') ||
|
||||
$currentTarget.hasClass('ember-view') ||
|
||||
$currentTarget.hasClass('lightbox') ||
|
||||
href.indexOf("mailto:") === 0 ||
|
||||
(href.match(/^http[s]?:\/\//i) && !href.match(new RegExp("^http:\\/\\/" + window.location.hostname, "i")))) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
Discourse.URL.routeTo(href);
|
||||
return false;
|
||||
});
|
||||
|
||||
$(window).focus(function() {
|
||||
Discourse.set('hasFocus', true);
|
||||
Discourse.set('notify', false);
|
||||
}).blur(function() {
|
||||
Discourse.set('hasFocus', false);
|
||||
});
|
||||
|
||||
// Add a CSRF token to all AJAX requests
|
||||
Discourse.csrfToken = $('meta[name=csrf-token]').attr('content');
|
||||
|
||||
$.ajaxPrefilter(function(options, originalOptions, xhr) {
|
||||
if (!options.crossDomain) {
|
||||
xhr.setRequestHeader('X-CSRF-Token', Discourse.csrfToken);
|
||||
}
|
||||
});
|
||||
|
||||
bootbox.animate(false);
|
||||
bootbox.backdrop(true); // clicking outside a bootbox modal closes it
|
||||
|
||||
Discourse.Mobile.init();
|
||||
|
||||
setInterval(function(){
|
||||
Discourse.Formatter.updateRelativeAge($('.relative-date'));
|
||||
},60 * 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
Log the current user out of Discourse
|
||||
|
||||
|
@ -153,37 +95,6 @@ Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
if(this.get('loginRequired')) { route.transitionTo('login'); }
|
||||
},
|
||||
|
||||
/**
|
||||
Subscribes the current user to receive message bus notifications
|
||||
**/
|
||||
subscribeUserToNotifications: function() {
|
||||
var user = Discourse.User.current();
|
||||
if (user) {
|
||||
var bus = Discourse.MessageBus;
|
||||
bus.callbackInterval = Discourse.SiteSettings.polling_interval;
|
||||
bus.enableLongPolling = true;
|
||||
bus.baseUrl = Discourse.getURL("/");
|
||||
|
||||
if (user.admin || user.moderator) {
|
||||
bus.subscribe("/flagged_counts", function(data) {
|
||||
user.set('site_flagged_posts_count', data.total);
|
||||
});
|
||||
}
|
||||
bus.subscribe("/notification/" + user.get('id'), (function(data) {
|
||||
user.set('unread_notifications', data.unread_notifications);
|
||||
user.set('unread_private_messages', data.unread_private_messages);
|
||||
}), user.notification_channel_position);
|
||||
|
||||
bus.subscribe("/categories", function(data){
|
||||
var site = Discourse.Site.current();
|
||||
_.each(data.categories,function(c){
|
||||
site.updateCategory(c);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Add an initializer hook for after the Discourse Application starts up.
|
||||
|
||||
|
@ -196,24 +107,16 @@ Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
},
|
||||
|
||||
/**
|
||||
Start up the Discourse application.
|
||||
Start up the Discourse application by running all the initializers we've defined.
|
||||
|
||||
@method start
|
||||
**/
|
||||
start: function() {
|
||||
Discourse.bindDOMEvents();
|
||||
Discourse.MessageBus.alwaysLongPoll = Discourse.Environment === "development";
|
||||
Discourse.MessageBus.start();
|
||||
Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus);
|
||||
|
||||
// Developer specific functions
|
||||
Discourse.Development.observeLiveChanges();
|
||||
Discourse.subscribeUserToNotifications();
|
||||
|
||||
if (Discourse.initializers) {
|
||||
var initializers = this.initializers;
|
||||
if (initializers) {
|
||||
var self = this;
|
||||
Em.run.next(function() {
|
||||
Discourse.initializers.forEach(function (init) {
|
||||
initializers.forEach(function (init) {
|
||||
init.call(self);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
Initialize the message bus to receive messages.
|
||||
**/
|
||||
Discourse.addInitializer(function() {
|
||||
Discourse.MessageBus.alwaysLongPoll = Discourse.Environment === "development";
|
||||
Discourse.MessageBus.start();
|
||||
Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus);
|
||||
});
|
11
app/assets/javascripts/discourse/initializers/bootbox.js
vendored
Normal file
11
app/assets/javascripts/discourse/initializers/bootbox.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
Default settings for bootbox
|
||||
**/
|
||||
Discourse.addInitializer(function() {
|
||||
|
||||
bootbox.animate(false);
|
||||
|
||||
// clicking outside a bootbox modal closes it
|
||||
bootbox.backdrop(true);
|
||||
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
Discourse does some server side rendering of HTML, such as the `cooked` contents of
|
||||
posts. The downside of this in an Ember app is the links will not go through the router.
|
||||
This jQuery code intercepts clicks on those links and routes them properly.
|
||||
**/
|
||||
|
||||
Discourse.addInitializer(function() {
|
||||
|
||||
$('#main').on('click.discourse', 'a', function(e) {
|
||||
if (e.isDefaultPrevented() || e.shiftKey || e.metaKey || e.ctrlKey) { return; }
|
||||
|
||||
var $currentTarget = $(e.currentTarget),
|
||||
href = $currentTarget.attr('href');
|
||||
|
||||
if (!href ||
|
||||
href === '#' ||
|
||||
$currentTarget.attr('target') ||
|
||||
$currentTarget.data('ember-action') ||
|
||||
$currentTarget.data('auto-route') ||
|
||||
$currentTarget.hasClass('ember-view') ||
|
||||
$currentTarget.hasClass('lightbox') ||
|
||||
href.indexOf("mailto:") === 0 ||
|
||||
(href.match(/^http[s]?:\/\//i) && !href.match(new RegExp("^http:\\/\\/" + window.location.hostname, "i")))) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
Discourse.URL.routeTo(href);
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
19
app/assets/javascripts/discourse/initializers/csrf_token.js
Normal file
19
app/assets/javascripts/discourse/initializers/csrf_token.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
Append our CSRF token to AJAX requests when necessary.
|
||||
**/
|
||||
|
||||
Discourse.addInitializer(function() {
|
||||
|
||||
var session = Discourse.Session;
|
||||
|
||||
// Add a CSRF token to all AJAX requests
|
||||
session.currentProp('csrfToken', $('meta[name=csrf-token]').attr('content'));
|
||||
|
||||
$.ajaxPrefilter(function(options, originalOptions, xhr) {
|
||||
if (!options.crossDomain) {
|
||||
xhr.setRequestHeader('X-CSRF-Token', session.currentProp('csrfToken'));
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
16
app/assets/javascripts/discourse/initializers/focus_event.js
Normal file
16
app/assets/javascripts/discourse/initializers/focus_event.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
Keep track of when the browser is in focus.
|
||||
**/
|
||||
Discourse.addInitializer(function() {
|
||||
|
||||
// Default to true
|
||||
this.set('hasFocus', true);
|
||||
|
||||
var self = this;
|
||||
$(window).focus(function() {
|
||||
self.setProperties({hasFocus: true, notify: false});
|
||||
}).blur(function() {
|
||||
self.set('hasFocus', false);
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
Initializes the `Discourse.Mobile` helper object.
|
||||
**/
|
||||
Discourse.addInitializer(function() {
|
||||
Discourse.Mobile.init();
|
||||
});
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
Use the message bus for live reloading of components for faster development.
|
||||
**/
|
||||
Discourse.addInitializer(function() {
|
||||
|
||||
console.log('live reloading');
|
||||
|
||||
// subscribe to any site customizations that are loaded
|
||||
$('link.custom-css').each(function() {
|
||||
var split = this.href.split("/"),
|
||||
id = split[split.length - 1].split(".css")[0],
|
||||
self = this;
|
||||
|
||||
return Discourse.MessageBus.subscribe("/file-change/" + id, function(data) {
|
||||
if (!$(self).data('orig')) {
|
||||
$(self).data('orig', self.href);
|
||||
}
|
||||
var orig = $(self).data('orig'),
|
||||
sp = orig.split(".css?");
|
||||
|
||||
self.href = sp[0] + ".css?" + data;
|
||||
});
|
||||
});
|
||||
|
||||
// Custom header changes
|
||||
$('header.custom').each(function() {
|
||||
var 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("<div></div>");
|
||||
_.each(data,function(me,idx) {
|
||||
|
||||
if (me === "refresh") {
|
||||
// Refresh if necessary
|
||||
document.location.reload(true);
|
||||
} else if (me.name.substr(-10) === "handlebars") {
|
||||
|
||||
// Reload handlebars
|
||||
var js = me.name.replace(".handlebars", "").replace("app/assets/javascripts", "/assets");
|
||||
$LAB.script(js + "?hash=" + me.hash).wait(function() {
|
||||
var templateName;
|
||||
templateName = js.replace(".js", "").replace("/assets/", "");
|
||||
return _.each(Ember.View.views, function(view) {
|
||||
if (view.get('templateName') === templateName) {
|
||||
view.set('templateName', 'empty');
|
||||
view.rerender();
|
||||
Em.run.schedule('afterRender', function() {
|
||||
view.set('templateName', templateName);
|
||||
view.rerender();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
$('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;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
Updates the relative ages of dates on the screen.
|
||||
|
||||
**/
|
||||
Discourse.addInitializer(function() {
|
||||
|
||||
setInterval(function(){
|
||||
Discourse.Formatter.updateRelativeAge($('.relative-date'));
|
||||
}, 60 * 1000);
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
Updates the relative ages of dates on the screen.
|
||||
|
||||
**/
|
||||
Discourse.addInitializer(function() {
|
||||
|
||||
var user = Discourse.User.current();
|
||||
if (user) {
|
||||
var bus = Discourse.MessageBus;
|
||||
bus.callbackInterval = Discourse.SiteSettings.polling_interval;
|
||||
bus.enableLongPolling = true;
|
||||
bus.baseUrl = Discourse.getURL("/");
|
||||
|
||||
if (user.admin || user.moderator) {
|
||||
bus.subscribe("/flagged_counts", function(data) {
|
||||
user.set('site_flagged_posts_count', data.total);
|
||||
});
|
||||
}
|
||||
bus.subscribe("/notification/" + user.get('id'), (function(data) {
|
||||
user.set('unread_notifications', data.unread_notifications);
|
||||
user.set('unread_private_messages', data.unread_private_messages);
|
||||
}), user.notification_channel_position);
|
||||
|
||||
bus.subscribe("/categories", function(data){
|
||||
var site = Discourse.Site.current();
|
||||
_.each(data.categories,function(c){
|
||||
site.updateCategory(c);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/**
|
||||
Functions to help development of Discourse, such as inserting probes
|
||||
|
||||
@class Development
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.Development = {
|
||||
|
||||
/**
|
||||
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("<div></div>");
|
||||
_.each(data,function(me,idx) {
|
||||
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 _.each(Ember.View.views, function(view) {
|
||||
if (view.get('templateName') === templateName) {
|
||||
view.set('templateName', 'empty');
|
||||
view.rerender();
|
||||
Em.run.schedule('afterRender', function() {
|
||||
view.set('templateName', templateName);
|
||||
view.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;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
};
|
|
@ -1,12 +1,10 @@
|
|||
/**
|
||||
A class that is responsible for logic related to mobile devices.
|
||||
An object that is responsible for logic related to mobile devices.
|
||||
|
||||
@class Mobile
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
@module Mobile
|
||||
**/
|
||||
Discourse.Mobile = {
|
||||
|
||||
isMobileDevice: false,
|
||||
mobileView: false,
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ Discourse.Ajax = Em.Mixin.create({
|
|||
// note: for bad CSRF we don't loop an extra request right away.
|
||||
// this allows us to eliminate the possibility of having a loop.
|
||||
if (xhr.status === 403 && xhr.responseText === "['BAD CSRF']") {
|
||||
Discourse.csrfToken = null;
|
||||
Discourse.Session.current().set('csrfToken', null);
|
||||
}
|
||||
|
||||
// If it's a parseerror, don't reject
|
||||
|
@ -79,7 +79,7 @@ Discourse.Ajax = Em.Mixin.create({
|
|||
|
||||
// For cached pages we strip out CSRF tokens, need to round trip to server prior to sending the
|
||||
// request (bypass for GET, not needed)
|
||||
if(args.type && args.type !== 'GET' && !Discourse.csrfToken){
|
||||
if(args.type && args.type !== 'GET' && !Discourse.Session.currentProp('csrfToken')){
|
||||
return Ember.Deferred.promise(function(promise){
|
||||
$.ajax(Discourse.getURL('/session/csrf'))
|
||||
.success(function(result){
|
||||
|
|
|
@ -104,7 +104,7 @@ d.write('<style>#ember-testing-container { position: absolute; background: white
|
|||
Discourse.rootElement = '#ember-testing';
|
||||
Discourse.setupForTesting();
|
||||
Discourse.injectTestHelpers();
|
||||
Discourse.bindDOMEvents();
|
||||
Discourse.runInitializers();
|
||||
|
||||
Discourse.Router.map(function() {
|
||||
Discourse.routeBuilder.call(this);
|
||||
|
|
Loading…
Reference in a new issue