diff --git a/.gitignore b/.gitignore
index e07bc7a8ff..ba4e20a0b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,6 +60,7 @@ CHANGELOG.md
config.js
/core/client/config.js
+!/core/client/app/services/config.js
# Built asset files
/core/built
diff --git a/core/client/app/components/gh-alert.js b/core/client/app/components/gh-alert.js
index b8e35b7d7c..1ac91e4b39 100644
--- a/core/client/app/components/gh-alert.js
+++ b/core/client/app/components/gh-alert.js
@@ -1,10 +1,12 @@
import Ember from 'ember';
-var AlertComponent = Ember.Component.extend({
+export default Ember.Component.extend({
tagName: 'article',
classNames: ['gh-alert', 'gh-alert-blue'],
classNameBindings: ['typeClass'],
+ notifications: Ember.inject.service(),
+
typeClass: Ember.computed(function () {
var classes = '',
message = this.get('message'),
@@ -31,10 +33,7 @@ var AlertComponent = Ember.Component.extend({
actions: {
closeNotification: function () {
- var self = this;
- self.notifications.closeNotification(self.get('message'));
+ this.get('notifications').closeNotification(this.get('message'));
}
}
});
-
-export default AlertComponent;
diff --git a/core/client/app/components/gh-blog-url.js b/core/client/app/components/gh-blog-url.js
index 381911e341..21df2de71c 100644
--- a/core/client/app/components/gh-blog-url.js
+++ b/core/client/app/components/gh-blog-url.js
@@ -1,7 +1,8 @@
import Ember from 'ember';
var blogUrl = Ember.Component.extend({
- tagName: ''
+ tagName: '',
+ config: Ember.inject.service()
});
export default blogUrl;
diff --git a/core/client/app/components/gh-dropdown-button.js b/core/client/app/components/gh-dropdown-button.js
index 8d47b17d4a..d0f982e099 100644
--- a/core/client/app/components/gh-dropdown-button.js
+++ b/core/client/app/components/gh-dropdown-button.js
@@ -1,7 +1,7 @@
import Ember from 'ember';
import DropdownMixin from 'ghost/mixins/dropdown-mixin';
-var DropdownButton = Ember.Component.extend(DropdownMixin, {
+export default Ember.Component.extend(DropdownMixin, {
tagName: 'button',
attributeBindings: 'role',
role: 'button',
@@ -9,11 +9,11 @@ var DropdownButton = Ember.Component.extend(DropdownMixin, {
// matches with the dropdown this button toggles
dropdownName: null,
+ dropdown: Ember.inject.service(),
+
// Notify dropdown service this dropdown should be toggled
click: function (event) {
this._super(event);
this.get('dropdown').toggleDropdown(this.get('dropdownName'), this);
}
});
-
-export default DropdownButton;
diff --git a/core/client/app/components/gh-dropdown.js b/core/client/app/components/gh-dropdown.js
index 707bad0b9a..810eca5883 100644
--- a/core/client/app/components/gh-dropdown.js
+++ b/core/client/app/components/gh-dropdown.js
@@ -1,8 +1,10 @@
import Ember from 'ember';
import DropdownMixin from 'ghost/mixins/dropdown-mixin';
-var GhostDropdown = Ember.Component.extend(DropdownMixin, {
+export default Ember.Component.extend(DropdownMixin, {
classNames: 'ghost-dropdown',
+ classNameBindings: ['fadeIn:fade-in-scale:fade-out', 'isOpen:open:closed'],
+
name: null,
closeOnClick: false,
@@ -17,7 +19,7 @@ var GhostDropdown = Ember.Component.extend(DropdownMixin, {
return this.get('isOpen') && !this.get('closing');
}),
- classNameBindings: ['fadeIn:fade-in-scale:fade-out', 'isOpen:open:closed'],
+ dropdown: Ember.inject.service(),
open: function () {
this.set('isOpen', true);
@@ -88,5 +90,3 @@ var GhostDropdown = Ember.Component.extend(DropdownMixin, {
dropdownService.off('toggle', this, this.toggle);
}
});
-
-export default GhostDropdown;
diff --git a/core/client/app/components/gh-ed-preview.js b/core/client/app/components/gh-ed-preview.js
index def2ab1f07..437806e18e 100644
--- a/core/client/app/components/gh-ed-preview.js
+++ b/core/client/app/components/gh-ed-preview.js
@@ -2,6 +2,8 @@ import Ember from 'ember';
import uploader from 'ghost/assets/lib/uploader';
var Preview = Ember.Component.extend({
+ config: Ember.inject.service(),
+
didInsertElement: function () {
this.set('scrollWrapper', this.$().closest('.entry-preview-content'));
Ember.run.scheduleOnce('afterRender', this, this.dropzoneHandler);
diff --git a/core/client/app/components/gh-nav-menu.js b/core/client/app/components/gh-nav-menu.js
index b9dd569880..666ea88e08 100644
--- a/core/client/app/components/gh-nav-menu.js
+++ b/core/client/app/components/gh-nav-menu.js
@@ -5,6 +5,8 @@ export default Ember.Component.extend({
classNames: ['gh-nav'],
classNameBindings: ['open'],
+ config: Ember.inject.service(),
+
open: false,
autoNav: null,
diff --git a/core/client/app/components/gh-notification.js b/core/client/app/components/gh-notification.js
index 3e69ceca99..60f67744e9 100644
--- a/core/client/app/components/gh-notification.js
+++ b/core/client/app/components/gh-notification.js
@@ -1,10 +1,14 @@
import Ember from 'ember';
-var NotificationComponent = Ember.Component.extend({
+export default Ember.Component.extend({
tagName: 'article',
classNames: ['gh-notification', 'gh-notification-green'],
classNameBindings: ['typeClass'],
+ message: null,
+
+ notifications: Ember.inject.service(),
+
typeClass: Ember.computed(function () {
var classes = '',
message = this.get('message'),
@@ -34,17 +38,14 @@ var NotificationComponent = Ember.Component.extend({
self.$().on('animationend webkitAnimationEnd oanimationend MSAnimationEnd', function (event) {
if (event.originalEvent.animationName === 'fade-out') {
- self.notifications.removeObject(self.get('message'));
+ self.get('notifications').removeObject(self.get('message'));
}
});
},
actions: {
closeNotification: function () {
- var self = this;
- self.notifications.closeNotification(self.get('message'));
+ this.get('notifications').closeNotification(this.get('message'));
}
}
});
-
-export default NotificationComponent;
diff --git a/core/client/app/components/gh-notifications.js b/core/client/app/components/gh-notifications.js
index ec124fa8e3..03ce6e859f 100644
--- a/core/client/app/components/gh-notifications.js
+++ b/core/client/app/components/gh-notifications.js
@@ -1,14 +1,15 @@
import Ember from 'ember';
-var NotificationsComponent = Ember.Component.extend({
+
+export default Ember.Component.extend({
tagName: 'aside',
classNames: 'gh-notifications',
- messages: Ember.computed.filter('notifications', function (notification) {
+ notifications: Ember.inject.service(),
+
+ messages: Ember.computed.filter('notifications.content', function (notification) {
var displayStatus = (typeof notification.toJSON === 'function') ?
notification.get('status') : notification.status;
return displayStatus === 'passive';
})
});
-
-export default NotificationsComponent;
diff --git a/core/client/app/components/gh-popover-button.js b/core/client/app/components/gh-popover-button.js
index 7484379212..0b9fb4baf2 100644
--- a/core/client/app/components/gh-popover-button.js
+++ b/core/client/app/components/gh-popover-button.js
@@ -1,8 +1,10 @@
import Ember from 'ember';
import DropdownButton from 'ghost/components/gh-dropdown-button';
-var PopoverButton = DropdownButton.extend({
- click: Ember.K, // We don't want clicks on popovers, but dropdowns have them. So `K`ill them here.
+export default DropdownButton.extend({
+ dropdown: Ember.inject.service(),
+
+ click: Ember.K,
mouseEnter: function (event) {
this._super(event);
@@ -14,5 +16,3 @@ var PopoverButton = DropdownButton.extend({
this.get('dropdown').toggleDropdown(this.get('popoverName'), this);
}
});
-
-export default PopoverButton;
diff --git a/core/client/app/components/gh-popover.js b/core/client/app/components/gh-popover.js
index 5d819d62ae..70c2e8f9e8 100644
--- a/core/client/app/components/gh-popover.js
+++ b/core/client/app/components/gh-popover.js
@@ -1,7 +1,7 @@
+import Ember from 'ember';
import GhostDropdown from 'ghost/components/gh-dropdown';
-var GhostPopover = GhostDropdown.extend({
- classNames: 'ghost-popover'
+export default GhostDropdown.extend({
+ classNames: 'ghost-popover',
+ dropdown: Ember.inject.service()
});
-
-export default GhostPopover;
diff --git a/core/client/app/components/gh-upload-modal.js b/core/client/app/components/gh-upload-modal.js
index e417a3a199..4b54a344d4 100644
--- a/core/client/app/components/gh-upload-modal.js
+++ b/core/client/app/components/gh-upload-modal.js
@@ -6,6 +6,8 @@ import cajaSanitizers from 'ghost/utils/caja-sanitizers';
var UploadModal = ModalDialog.extend({
layoutName: 'components/gh-modal-dialog',
+ config: Ember.inject.service(),
+
didInsertElement: function () {
this._super();
upload.call(this.$('.js-drop-zone'), {fileStorage: this.get('config.fileStorage')});
diff --git a/core/client/app/components/gh-uploader.js b/core/client/app/components/gh-uploader.js
index 75dc86cb68..e136a4efdf 100644
--- a/core/client/app/components/gh-uploader.js
+++ b/core/client/app/components/gh-uploader.js
@@ -4,6 +4,8 @@ import uploader from 'ghost/assets/lib/uploader';
var PostImageUploader = Ember.Component.extend({
classNames: ['image-uploader', 'js-post-image-upload'],
+ config: Ember.inject.service(),
+
imageSource: Ember.computed('image', function () {
return this.get('image') || '';
}),
diff --git a/core/client/app/components/gh-url-preview.js b/core/client/app/components/gh-url-preview.js
index cc46105281..4af38ec85e 100644
--- a/core/client/app/components/gh-url-preview.js
+++ b/core/client/app/components/gh-url-preview.js
@@ -8,9 +8,11 @@ var urlPreview = Ember.Component.extend({
prefix: null,
slug: null,
+ config: Ember.inject.service(),
+
url: Ember.computed('slug', function () {
// Get the blog URL and strip the scheme
- var blogUrl = this.get('config').blogUrl,
+ var blogUrl = this.get('config.blogUrl'),
noSchemeBlogUrl = blogUrl.substr(blogUrl.indexOf('://') + 3), // Remove `http[s]://`
// Get the prefix and slug values
diff --git a/core/client/app/controllers/application.js b/core/client/app/controllers/application.js
index 51cbaecdb9..8bfcd147cb 100644
--- a/core/client/app/controllers/application.js
+++ b/core/client/app/controllers/application.js
@@ -1,6 +1,8 @@
import Ember from 'ember';
export default Ember.Controller.extend({
+ dropdown: Ember.inject.service(),
+
// jscs: disable
signedOut: Ember.computed.match('currentPath', /(signin|signup|setup|reset)/),
// jscs: enable
diff --git a/core/client/app/controllers/modals/copy-html.js b/core/client/app/controllers/modals/copy-html.js
index 161e65baf1..c4550ab9a4 100644
--- a/core/client/app/controllers/modals/copy-html.js
+++ b/core/client/app/controllers/modals/copy-html.js
@@ -1,8 +1,5 @@
import Ember from 'ember';
-var CopyHTMLController = Ember.Controller.extend({
+export default Ember.Controller.extend({
generatedHTML: Ember.computed.alias('model.generatedHTML')
-
});
-
-export default CopyHTMLController;
diff --git a/core/client/app/controllers/modals/delete-all.js b/core/client/app/controllers/modals/delete-all.js
index b7f7307386..30c10f3179 100644
--- a/core/client/app/controllers/modals/delete-all.js
+++ b/core/client/app/controllers/modals/delete-all.js
@@ -2,6 +2,9 @@ import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
export default Ember.Controller.extend({
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
actions: {
confirmAccept: function () {
var self = this;
@@ -9,11 +12,11 @@ export default Ember.Controller.extend({
ajax(this.get('ghostPaths.url').api('db'), {
type: 'DELETE'
}).then(function () {
- self.notifications.showSuccess('All content deleted from database.');
+ self.get('notifications').showSuccess('All content deleted from database.');
self.store.unloadAll('post');
self.store.unloadAll('tag');
}).catch(function (response) {
- self.notifications.showErrors(response);
+ self.get('notifications').showErrors(response);
});
},
diff --git a/core/client/app/controllers/modals/delete-post.js b/core/client/app/controllers/modals/delete-post.js
index 56b08db5d4..1f334c4437 100644
--- a/core/client/app/controllers/modals/delete-post.js
+++ b/core/client/app/controllers/modals/delete-post.js
@@ -1,5 +1,9 @@
import Ember from 'ember';
-var DeletePostController = Ember.Controller.extend({
+
+export default Ember.Controller.extend({
+ dropdown: Ember.inject.service(),
+ notifications: Ember.inject.service(),
+
actions: {
confirmAccept: function () {
var self = this,
@@ -11,9 +15,9 @@ var DeletePostController = Ember.Controller.extend({
model.destroyRecord().then(function () {
self.get('dropdown').closeDropdowns();
self.transitionToRoute('posts.index');
- self.notifications.showSuccess('Your post has been deleted.', {delayed: true});
+ self.get('notifications').showSuccess('Your post has been deleted.', {delayed: true});
}, function () {
- self.notifications.showError('Your post could not be deleted. Please try again.');
+ self.get('notifications').showError('Your post could not be deleted. Please try again.');
});
},
@@ -33,5 +37,3 @@ var DeletePostController = Ember.Controller.extend({
}
}
});
-
-export default DeletePostController;
diff --git a/core/client/app/controllers/modals/delete-tag.js b/core/client/app/controllers/modals/delete-tag.js
index 0657743bf8..0cfabca999 100644
--- a/core/client/app/controllers/modals/delete-tag.js
+++ b/core/client/app/controllers/modals/delete-tag.js
@@ -1,5 +1,8 @@
import Ember from 'ember';
-var DeleteTagController = Ember.Controller.extend({
+
+export default Ember.Controller.extend({
+ notifications: Ember.inject.service(),
+
postInflection: Ember.computed('model.post_count', function () {
return this.get('model.post_count') > 1 ? 'posts' : 'post';
}),
@@ -13,9 +16,9 @@ var DeleteTagController = Ember.Controller.extend({
this.send('closeSettingsMenu');
tag.destroyRecord().then(function () {
- self.notifications.showSuccess('Deleted ' + name);
+ self.get('notifications').showSuccess('Deleted ' + name);
}).catch(function (error) {
- self.notifications.showAPIError(error);
+ self.get('notifications').showAPIError(error);
});
},
@@ -35,5 +38,3 @@ var DeleteTagController = Ember.Controller.extend({
}
}
});
-
-export default DeleteTagController;
diff --git a/core/client/app/controllers/modals/delete-user.js b/core/client/app/controllers/modals/delete-user.js
index 2f8e39bda3..9dc2a1c6a4 100644
--- a/core/client/app/controllers/modals/delete-user.js
+++ b/core/client/app/controllers/modals/delete-user.js
@@ -1,5 +1,8 @@
import Ember from 'ember';
-var DeleteUserController = Ember.Controller.extend({
+
+export default Ember.Controller.extend({
+ notifications: Ember.inject.service(),
+
userPostCount: Ember.computed('model.id', function () {
var promise,
query = {
@@ -28,9 +31,9 @@ var DeleteUserController = Ember.Controller.extend({
user.destroyRecord().then(function () {
self.store.unloadAll('post');
self.transitionToRoute('settings.users');
- self.notifications.showSuccess('The user has been deleted.', {delayed: true});
+ self.get('notifications').showSuccess('The user has been deleted.', {delayed: true});
}, function () {
- self.notifications.showError('The user could not be deleted. Please try again.');
+ self.get('notifications').showError('The user could not be deleted. Please try again.');
});
},
@@ -50,5 +53,3 @@ var DeleteUserController = Ember.Controller.extend({
}
}
});
-
-export default DeleteUserController;
diff --git a/core/client/app/controllers/modals/invite-new-user.js b/core/client/app/controllers/modals/invite-new-user.js
index dd54b976eb..707da53f2c 100644
--- a/core/client/app/controllers/modals/invite-new-user.js
+++ b/core/client/app/controllers/modals/invite-new-user.js
@@ -1,5 +1,8 @@
import Ember from 'ember';
-var InviteNewUserController = Ember.Controller.extend({
+
+export default Ember.Controller.extend({
+ notifications: Ember.inject.service(),
+
// Used to set the initial value for the dropdown
authorRole: Ember.computed(function () {
var self = this;
@@ -45,9 +48,9 @@ var InviteNewUserController = Ember.Controller.extend({
if (invitedUser) {
if (invitedUser.get('status') === 'invited' || invitedUser.get('status') === 'invited-pending') {
- self.notifications.showWarn('A user with that email address was already invited.');
+ self.get('notifications').showWarn('A user with that email address was already invited.');
} else {
- self.notifications.showWarn('A user with that email address already exists.');
+ self.get('notifications').showWarn('A user with that email address already exists.');
}
} else {
newUser = self.store.createRecord('user', {
@@ -62,13 +65,13 @@ var InviteNewUserController = Ember.Controller.extend({
// If sending the invitation email fails, the API will still return a status of 201
// but the user's status in the response object will be 'invited-pending'.
if (newUser.get('status') === 'invited-pending') {
- self.notifications.showWarn('Invitation email was not sent. Please try resending.');
+ self.get('notifications').showWarn('Invitation email was not sent. Please try resending.');
} else {
- self.notifications.showSuccess(notificationText);
+ self.get('notifications').showSuccess(notificationText);
}
}).catch(function (errors) {
newUser.deleteRecord();
- self.notifications.showErrors(errors);
+ self.get('notifications').showErrors(errors);
});
}
});
@@ -79,5 +82,3 @@ var InviteNewUserController = Ember.Controller.extend({
}
}
});
-
-export default InviteNewUserController;
diff --git a/core/client/app/controllers/modals/leave-editor.js b/core/client/app/controllers/modals/leave-editor.js
index 0f01f14d8c..d455ead29d 100644
--- a/core/client/app/controllers/modals/leave-editor.js
+++ b/core/client/app/controllers/modals/leave-editor.js
@@ -1,5 +1,8 @@
import Ember from 'ember';
-var LeaveEditorController = Ember.Controller.extend({
+
+export default Ember.Controller.extend({
+ notifications: Ember.inject.service(),
+
args: Ember.computed.alias('model'),
actions: {
@@ -16,7 +19,7 @@ var LeaveEditorController = Ember.Controller.extend({
}
if (!transition || !editorController) {
- this.notifications.showError('Sorry, there was an error in the application. Please let the Ghost team know what happened.');
+ this.get('notifications').showError('Sorry, there was an error in the application. Please let the Ghost team know what happened.');
return true;
}
@@ -56,5 +59,3 @@ var LeaveEditorController = Ember.Controller.extend({
}
}
});
-
-export default LeaveEditorController;
diff --git a/core/client/app/controllers/modals/signin.js b/core/client/app/controllers/modals/signin.js
index 90d705a691..89a438ef7f 100644
--- a/core/client/app/controllers/modals/signin.js
+++ b/core/client/app/controllers/modals/signin.js
@@ -2,17 +2,18 @@ import Ember from 'ember';
import ValidationEngine from 'ghost/mixins/validation-engine';
export default Ember.Controller.extend(ValidationEngine, {
- needs: 'application',
-
validationType: 'signin',
+ application: Ember.inject.controller(),
+ notifications: Ember.inject.service(),
+
identification: Ember.computed('session.user.email', function () {
return this.get('session.user.email');
}),
actions: {
authenticate: function () {
- var appController = this.get('controllers.application'),
+ var appController = this.get('application'),
authStrategy = 'simple-auth-authenticator:oauth2-password-grant',
data = this.getProperties('identification', 'password'),
self = this;
@@ -21,7 +22,7 @@ export default Ember.Controller.extend(ValidationEngine, {
this.get('session').authenticate(authStrategy, data).then(function () {
self.send('closeModal');
- self.notifications.showSuccess('Login successful.');
+ self.get('notifications').showSuccess('Login successful.');
self.set('password', '');
}).catch(function () {
// if authentication fails a rejected promise will be returned.
@@ -40,10 +41,10 @@ export default Ember.Controller.extend(ValidationEngine, {
$('#login').find('input').trigger('change');
this.validate({format: false}).then(function () {
- self.notifications.closePassive();
+ self.get('notifications').closePassive();
self.send('authenticate');
}).catch(function (errors) {
- self.notifications.showErrors(errors);
+ self.get('notifications').showErrors(errors);
});
},
diff --git a/core/client/app/controllers/modals/transfer-owner.js b/core/client/app/controllers/modals/transfer-owner.js
index 30075c91b2..f721713962 100644
--- a/core/client/app/controllers/modals/transfer-owner.js
+++ b/core/client/app/controllers/modals/transfer-owner.js
@@ -2,6 +2,10 @@ import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
export default Ember.Controller.extend({
+ dropdown: Ember.inject.service(),
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
actions: {
confirmAccept: function () {
var user = this.get('model'),
@@ -29,9 +33,9 @@ export default Ember.Controller.extend({
});
}
- self.notifications.showSuccess('Ownership successfully transferred to ' + user.get('name'));
+ self.get('notifications').showSuccess('Ownership successfully transferred to ' + user.get('name'));
}).catch(function (error) {
- self.notifications.showAPIError(error);
+ self.get('notifications').showAPIError(error);
});
},
diff --git a/core/client/app/controllers/modals/upload.js b/core/client/app/controllers/modals/upload.js
index c2cdf42b22..f186205826 100644
--- a/core/client/app/controllers/modals/upload.js
+++ b/core/client/app/controllers/modals/upload.js
@@ -1,16 +1,20 @@
import Ember from 'ember';
-var UploadController = Ember.Controller.extend({
+export default Ember.Controller.extend({
+ notifications: Ember.inject.service(),
+
acceptEncoding: 'image/*',
+
actions: {
confirmAccept: function () {
- var self = this;
+ var notifications = this.get('notifications');
this.get('model').save().then(function (model) {
- self.notifications.showSuccess('Saved');
+ notifications.showSuccess('Saved');
+
return model;
}).catch(function (err) {
- self.notifications.showErrors(err);
+ notifications.showErrors(err);
});
},
@@ -19,5 +23,3 @@ var UploadController = Ember.Controller.extend({
}
}
});
-
-export default UploadController;
diff --git a/core/client/app/controllers/post-settings-menu.js b/core/client/app/controllers/post-settings-menu.js
index b66a68faf9..b95ddfb4b6 100644
--- a/core/client/app/controllers/post-settings-menu.js
+++ b/core/client/app/controllers/post-settings-menu.js
@@ -1,18 +1,22 @@
-import Ember from 'ember';
/* global moment */
+
+import Ember from 'ember';
import {parseDateString, formatDate} from 'ghost/utils/date-formatting';
import SettingsMenuMixin from 'ghost/mixins/settings-menu-controller';
import SlugGenerator from 'ghost/models/slug-generator';
import boundOneWay from 'ghost/utils/bound-one-way';
import isNumber from 'ghost/utils/isNumber';
-var PostSettingsMenuController = Ember.Controller.extend(SettingsMenuMixin, {
+export default Ember.Controller.extend(SettingsMenuMixin, {
debounceId: null,
lastPromise: null,
selectedAuthor: null,
uploaderReference: null,
application: Ember.inject.controller(),
+ config: Ember.inject.service(),
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
initializeSelectedAuthor: function () {
var self = this;
@@ -212,11 +216,11 @@ var PostSettingsMenuController = Ember.Controller.extend(SettingsMenuMixin, {
showErrors: function (errors) {
errors = Ember.isArray(errors) ? errors : [errors];
- this.notifications.showErrors(errors);
+ this.get('notifications').showErrors(errors);
},
showSuccess: function (message) {
- this.notifications.showSuccess(message);
+ this.get('notifications').showSuccess(message);
},
actions: {
@@ -465,5 +469,3 @@ var PostSettingsMenuController = Ember.Controller.extend(SettingsMenuMixin, {
}
}
});
-
-export default PostSettingsMenuController;
diff --git a/core/client/app/controllers/posts/post.js b/core/client/app/controllers/posts/post.js
index 4ada4f78b2..da909b5318 100644
--- a/core/client/app/controllers/posts/post.js
+++ b/core/client/app/controllers/posts/post.js
@@ -1,8 +1,13 @@
import Ember from 'ember';
-var PostController = Ember.Controller.extend({
- isPublished: Ember.computed.equal('model.status', 'published'),
+
+export default Ember.Controller.extend({
classNameBindings: ['model.featured'],
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
+ isPublished: Ember.computed.equal('model.status', 'published'),
+
authorName: Ember.computed('model.author.name', 'model.author.email', function () {
return this.get('model.author.name') || this.get('model.author.email');
}),
@@ -17,17 +22,16 @@ var PostController = Ember.Controller.extend({
actions: {
toggleFeatured: function () {
- var self = this;
+ var notifications = this.get('notifications');
this.toggleProperty('model.featured');
this.get('model').save().catch(function (errors) {
- self.notifications.showErrors(errors);
+ notifications.showErrors(errors);
});
},
+
showPostContent: function () {
this.transitionToRoute('posts.post', this.get('model'));
}
}
});
-
-export default PostController;
diff --git a/core/client/app/controllers/reset.js b/core/client/app/controllers/reset.js
index ca3ebfe555..a428b30b5c 100644
--- a/core/client/app/controllers/reset.js
+++ b/core/client/app/controllers/reset.js
@@ -10,6 +10,9 @@ export default Ember.Controller.extend(ValidationEngine, {
validationType: 'reset',
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
email: Ember.computed('token', function () {
// The token base64 encodes the email (and some other stuff),
// each section is divided by a '|'. Email comes second.
@@ -40,18 +43,18 @@ export default Ember.Controller.extend(ValidationEngine, {
}
}).then(function (resp) {
self.toggleProperty('submitting');
- self.notifications.showSuccess(resp.passwordreset[0].message, true);
+ self.get('notifications').showSuccess(resp.passwordreset[0].message, true);
self.get('session').authenticate('simple-auth-authenticator:oauth2-password-grant', {
identification: self.get('email'),
password: credentials.newPassword
});
}).catch(function (response) {
- self.notifications.showAPIError(response);
+ self.get('notifications').showAPIError(response);
self.toggleProperty('submitting');
});
}).catch(function (error) {
self.toggleProperty('submitting');
- self.notifications.showErrors(error);
+ self.get('notifications').showErrors(error);
});
}
}
diff --git a/core/client/app/controllers/settings/code-injection.js b/core/client/app/controllers/settings/code-injection.js
index f396f8737b..550338cdff 100644
--- a/core/client/app/controllers/settings/code-injection.js
+++ b/core/client/app/controllers/settings/code-injection.js
@@ -1,20 +1,19 @@
import Ember from 'ember';
-var SettingsCodeInjectionController = Ember.Controller.extend({
+
+export default Ember.Controller.extend({
actions: {
save: function () {
- var self = this;
+ var notifications = this.get('notifications');
return this.get('model').save().then(function (model) {
- self.notifications.closePassive();
- self.notifications.showSuccess('Settings successfully saved.');
+ notifications.closePassive();
+ notifications.showSuccess('Settings successfully saved.');
return model;
}).catch(function (errors) {
- self.notifications.closePassive();
- self.notifications.showErrors(errors);
+ notifications.closePassive();
+ notifications.showErrors(errors);
});
}
}
});
-
-export default SettingsCodeInjectionController;
diff --git a/core/client/app/controllers/settings/general.js b/core/client/app/controllers/settings/general.js
index 7efddc613f..b36ff95230 100644
--- a/core/client/app/controllers/settings/general.js
+++ b/core/client/app/controllers/settings/general.js
@@ -1,7 +1,9 @@
import Ember from 'ember';
import randomPassword from 'ghost/utils/random-password';
-var SettingsGeneralController = Ember.Controller.extend({
+export default Ember.Controller.extend({
+ notifications: Ember.inject.service(),
+
selectedTheme: null,
logoImageSource: Ember.computed('model.logo', function () {
@@ -47,14 +49,14 @@ var SettingsGeneralController = Ember.Controller.extend({
actions: {
save: function () {
- var self = this;
+ var notifications = this.get('notifications');
return this.get('model').save().then(function (model) {
- self.notifications.showSuccess('Settings successfully saved.');
+ notifications.showSuccess('Settings successfully saved.');
return model;
}).catch(function (errors) {
- self.notifications.showErrors(errors);
+ notifications.showErrors(errors);
});
},
@@ -67,5 +69,3 @@ var SettingsGeneralController = Ember.Controller.extend({
}
}
});
-
-export default SettingsGeneralController;
diff --git a/core/client/app/controllers/settings/labs.js b/core/client/app/controllers/settings/labs.js
index 826cd5cd3b..ac5f9a71bf 100644
--- a/core/client/app/controllers/settings/labs.js
+++ b/core/client/app/controllers/settings/labs.js
@@ -2,10 +2,12 @@ import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
export default Ember.Controller.extend(Ember.Evented, {
- needs: ['feature'],
-
uploadButtonText: 'Import',
importErrors: '',
+
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
labsJSON: Ember.computed('model.labs', function () {
return JSON.parse(this.get('model.labs') || {});
}),
@@ -28,11 +30,12 @@ export default Ember.Controller.extend(Ember.Evented, {
actions: {
onUpload: function (file) {
var self = this,
- formData = new FormData();
+ formData = new FormData(),
+ notifications = this.get('notifications');
this.set('uploadButtonText', 'Importing');
this.set('importErrors', '');
- this.notifications.closePassive();
+ notifications.closePassive();
formData.append('importfile', file);
@@ -51,13 +54,13 @@ export default Ember.Controller.extend(Ember.Evented, {
self.store.unloadAll('role');
self.store.unloadAll('setting');
self.store.unloadAll('notification');
- self.notifications.showSuccess('Import successful.');
+ notifications.showSuccess('Import successful.');
}).catch(function (response) {
if (response && response.jqXHR && response.jqXHR.responseJSON && response.jqXHR.responseJSON.errors) {
self.set('importErrors', response.jqXHR.responseJSON.errors);
}
- self.notifications.showError('Import Failed');
+ notifications.showError('Import Failed');
}).finally(function () {
self.set('uploadButtonText', 'Import');
self.trigger('reset');
@@ -77,17 +80,17 @@ export default Ember.Controller.extend(Ember.Evented, {
},
sendTestEmail: function () {
- var self = this;
+ var notifications = this.get('notifications');
ajax(this.get('ghostPaths.url').api('mail', 'test'), {
type: 'POST'
}).then(function () {
- self.notifications.showSuccess('Check your email for the test message.');
+ notifications.showSuccess('Check your email for the test message.');
}).catch(function (error) {
if (typeof error.jqXHR !== 'undefined') {
- self.notifications.showAPIError(error);
+ notifications.showAPIError(error);
} else {
- self.notifications.showErrors(error);
+ notifications.showErrors(error);
}
});
}
diff --git a/core/client/app/controllers/settings/navigation.js b/core/client/app/controllers/settings/navigation.js
index d1bebe4a80..bcb7e91ae7 100644
--- a/core/client/app/controllers/settings/navigation.js
+++ b/core/client/app/controllers/settings/navigation.js
@@ -1,8 +1,6 @@
import Ember from 'ember';
-var NavigationController,
- NavItem;
-NavItem = Ember.Object.extend({
+var NavItem = Ember.Object.extend({
label: '',
url: '',
last: false,
@@ -12,7 +10,10 @@ NavItem = Ember.Object.extend({
})
});
-NavigationController = Ember.Controller.extend({
+export default Ember.Controller.extend({
+ config: Ember.inject.service(),
+ notifications: Ember.inject.service(),
+
blogUrl: Ember.computed('config.blogUrl', function () {
var url = this.get('config.blogUrl');
@@ -96,18 +97,18 @@ NavigationController = Ember.Controller.extend({
},
save: function () {
- var self = this,
- navSetting,
+ var navSetting,
blogUrl = this.get('config').blogUrl,
blogUrlRegex = new RegExp('^' + blogUrl + '(.*)', 'i'),
navItems = this.get('navigationItems'),
message = 'One of your navigation items has an empty label. ' +
'
Please enter a new label or delete the item before saving.',
- match;
+ match,
+ notifications = this.get('notifications');
// Don't save if there's a blank label.
- if (navItems.find(function (item) { return !item.get('isComplete') && !item.get('last');})) {
- self.notifications.showErrors([message.htmlSafe()]);
+ if (navItems.find(function (item) {return !item.get('isComplete') && !item.get('last');})) {
+ notifications.showErrors([message.htmlSafe()]);
return;
}
@@ -147,15 +148,13 @@ NavigationController = Ember.Controller.extend({
// we need to have navigationItems recomputed.
this.get('model').notifyPropertyChange('navigation');
- this.notifications.closePassive();
+ notifications.closePassive();
this.get('model').save().then(function () {
- self.notifications.showSuccess('Navigation items saved.');
+ notifications.showSuccess('Navigation items saved.');
}).catch(function (err) {
- self.notifications.showErrors(err);
+ notifications.showErrors(err);
});
}
}
});
-
-export default NavigationController;
diff --git a/core/client/app/controllers/settings/tags.js b/core/client/app/controllers/settings/tags.js
index 8877a4a331..e4312154f4 100644
--- a/core/client/app/controllers/settings/tags.js
+++ b/core/client/app/controllers/settings/tags.js
@@ -3,7 +3,7 @@ import PaginationMixin from 'ghost/mixins/pagination-controller';
import SettingsMenuMixin from 'ghost/mixins/settings-menu-controller';
import boundOneWay from 'ghost/utils/bound-one-way';
-var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuMixin, {
+export default Ember.ArrayController.extend(PaginationMixin, SettingsMenuMixin, {
tags: Ember.computed.alias('model'),
activeTag: null,
@@ -20,10 +20,12 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
},
application: Ember.inject.controller(),
+ config: Ember.inject.service(),
+ notifications: Ember.inject.service(),
showErrors: function (errors) {
errors = Ember.isArray(errors) ? errors : [errors];
- this.notifications.showErrors(errors);
+ this.get('notifications').showErrors(errors);
},
saveActiveTagProperty: function (propKey, newValue) {
@@ -40,7 +42,7 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
activeTag.set(propKey, newValue);
- this.notifications.closePassive();
+ this.get('notifications').closePassive();
activeTag.save().catch(function (errors) {
self.showErrors(errors);
@@ -62,7 +64,7 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
}),
seoURL: Ember.computed('activeTagSlugScratch', function () {
- var blogUrl = this.get('config').blogUrl,
+ var blogUrl = this.get('config.blogUrl'),
seoSlug = this.get('activeTagSlugScratch') ? this.get('activeTagSlugScratch') : '',
seoURL = blogUrl + '/tag/' + seoSlug;
@@ -137,5 +139,3 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
}
}
});
-
-export default TagsController;
diff --git a/core/client/app/controllers/settings/users/user.js b/core/client/app/controllers/settings/users/user.js
index 091b514ffe..39ff4197c4 100644
--- a/core/client/app/controllers/settings/users/user.js
+++ b/core/client/app/controllers/settings/users/user.js
@@ -3,7 +3,9 @@ import SlugGenerator from 'ghost/models/slug-generator';
import isNumber from 'ghost/utils/isNumber';
import boundOneWay from 'ghost/utils/bound-one-way';
-var SettingsUserController = Ember.Controller.extend({
+export default Ember.Controller.extend({
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
user: Ember.computed.alias('model'),
@@ -16,8 +18,10 @@ var SettingsUserController = Ember.Controller.extend({
coverDefault: Ember.computed('ghostPaths', function () {
return this.get('ghostPaths.url').asset('/shared/img/user-cover.png');
}),
+
coverImageBackground: Ember.computed('user.cover', 'coverDefault', function () {
var url = this.get('user.cover') || this.get('coverDefault');
+
return `background-image: url(${url})`.htmlSafe();
}),
@@ -28,8 +32,10 @@ var SettingsUserController = Ember.Controller.extend({
userDefault: Ember.computed('ghostPaths', function () {
return this.get('ghostPaths.url').asset('/shared/img/user-image.png');
}),
+
userImageBackground: Ember.computed('user.image', 'userDefault', function () {
var url = this.get('user.image') || this.get('userDefault');
+
return `background-image: url(${url})`.htmlSafe();
}),
@@ -68,14 +74,15 @@ var SettingsUserController = Ember.Controller.extend({
if (model.get('invited')) {
model.destroyRecord().then(function () {
var notificationText = 'Invitation revoked. (' + email + ')';
- self.notifications.showSuccess(notificationText, false);
+
+ self.get('notifications').showSuccess(notificationText, false);
}).catch(function (error) {
- self.notifications.showAPIError(error);
+ self.get('notifications').showAPIError(error);
});
} else {
// if the user is no longer marked as "invited", then show a warning and reload the route
self.get('target').send('reload');
- self.notifications.showError('This user has already accepted the invitation.', {delayed: 500});
+ self.get('notifications').showError('This user has already accepted the invitation.', {delayed: 500});
}
});
},
@@ -88,13 +95,13 @@ var SettingsUserController = Ember.Controller.extend({
// If sending the invitation email fails, the API will still return a status of 201
// but the user's status in the response object will be 'invited-pending'.
if (result.users[0].status === 'invited-pending') {
- self.notifications.showWarn('Invitation email was not sent. Please try resending.');
+ self.get('notifications').showWarn('Invitation email was not sent. Please try resending.');
} else {
self.get('model').set('status', result.users[0].status);
- self.notifications.showSuccess(notificationText);
+ self.get('notifications').showSuccess(notificationText);
}
}).catch(function (error) {
- self.notifications.showAPIError(error);
+ self.get('notifications').showAPIError(error);
});
},
@@ -117,7 +124,7 @@ var SettingsUserController = Ember.Controller.extend({
var currentPath,
newPath;
- self.notifications.showSuccess('Settings successfully saved.');
+ self.get('notifications').showSuccess('Settings successfully saved.');
// If the user's slug has changed, change the URL and replace
// the history so refresh and back button still work
@@ -133,7 +140,7 @@ var SettingsUserController = Ember.Controller.extend({
return model;
}).catch(function (errors) {
- self.notifications.showErrors(errors);
+ self.get('notifications').showErrors(errors);
});
this.set('lastPromise', promise);
@@ -152,14 +159,14 @@ var SettingsUserController = Ember.Controller.extend({
ne2Password: ''
});
- self.notifications.showSuccess('Password updated.');
+ self.get('notifications').showSuccess('Password updated.');
return model;
}).catch(function (errors) {
- self.notifications.showAPIError(errors);
+ self.get('notifications').showAPIError(errors);
});
} else {
- self.notifications.showErrors(user.get('passwordValidationErrors'));
+ self.get('notifications').showErrors(user.get('passwordValidationErrors'));
}
},
@@ -217,5 +224,3 @@ var SettingsUserController = Ember.Controller.extend({
}
}
});
-
-export default SettingsUserController;
diff --git a/core/client/app/controllers/setup.js b/core/client/app/controllers/setup.js
index e4827ae183..84e4e891ec 100644
--- a/core/client/app/controllers/setup.js
+++ b/core/client/app/controllers/setup.js
@@ -12,12 +12,16 @@ export default Ember.Controller.extend(ValidationEngine, {
// ValidationEngine settings
validationType: 'setup',
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
actions: {
setup: function () {
var self = this,
- data = self.getProperties('blogTitle', 'name', 'email', 'password');
+ data = self.getProperties('blogTitle', 'name', 'email', 'password'),
+ notifications = this.get('notifications');
- self.notifications.closePassive();
+ notifications.closePassive();
this.toggleProperty('submitting');
this.validate({format: false}).then(function () {
@@ -39,11 +43,11 @@ export default Ember.Controller.extend(ValidationEngine, {
});
}).catch(function (resp) {
self.toggleProperty('submitting');
- self.notifications.showAPIError(resp);
+ notifications.showAPIError(resp);
});
}).catch(function (errors) {
self.toggleProperty('submitting');
- self.notifications.showErrors(errors);
+ notifications.showErrors(errors);
});
}
}
diff --git a/core/client/app/controllers/signin.js b/core/client/app/controllers/signin.js
index ae6774c9dc..a671aeda0a 100644
--- a/core/client/app/controllers/signin.js
+++ b/core/client/app/controllers/signin.js
@@ -7,6 +7,9 @@ export default Ember.Controller.extend(ValidationEngine, {
submitting: false,
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
actions: {
authenticate: function () {
var model = this.get('model'),
@@ -28,10 +31,10 @@ export default Ember.Controller.extend(ValidationEngine, {
$('#login').find('input').trigger('change');
this.validate({format: false}).then(function () {
- self.notifications.closePassive();
+ self.get('notifications').closePassive();
self.send('authenticate');
}).catch(function (errors) {
- self.notifications.showErrors(errors);
+ self.get('notifications').showErrors(errors);
});
},
@@ -55,10 +58,10 @@ export default Ember.Controller.extend(ValidationEngine, {
}
}).then(function () {
self.set('submitting', false);
- self.notifications.showSuccess('Please check your email for instructions.');
+ self.get('notifications').showSuccess('Please check your email for instructions.');
}).catch(function (resp) {
self.set('submitting', false);
- self.notifications.showAPIError(resp, {defaultErrorText: 'There was a problem with the reset, please try again.'});
+ self.get('notifications').showAPIError(resp, {defaultErrorText: 'There was a problem with the reset, please try again.'});
});
}
}
diff --git a/core/client/app/controllers/signup.js b/core/client/app/controllers/signup.js
index 4d98d17017..ed29e2fb0e 100644
--- a/core/client/app/controllers/signup.js
+++ b/core/client/app/controllers/signup.js
@@ -3,18 +3,22 @@ import {request as ajax} from 'ic-ajax';
import ValidationEngine from 'ghost/mixins/validation-engine';
export default Ember.Controller.extend(ValidationEngine, {
- submitting: false,
-
// ValidationEngine settings
validationType: 'signup',
+ submitting: false,
+
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
actions: {
signup: function () {
var self = this,
model = this.get('model'),
- data = model.getProperties('name', 'email', 'password', 'token');
+ data = model.getProperties('name', 'email', 'password', 'token'),
+ notifications = this.get('notifications');
- self.notifications.closePassive();
+ notifications.closePassive();
this.toggleProperty('submitting');
this.validate({format: false}).then(function () {
@@ -37,11 +41,11 @@ export default Ember.Controller.extend(ValidationEngine, {
});
}, function (resp) {
self.toggleProperty('submitting');
- self.notifications.showAPIError(resp);
+ notifications.showAPIError(resp);
});
}, function (errors) {
self.toggleProperty('submitting');
- self.notifications.showErrors(errors);
+ notifications.showErrors(errors);
});
}
}
diff --git a/core/client/app/initializers/dropdown.js b/core/client/app/initializers/dropdown.js
deleted file mode 100644
index db339383f9..0000000000
--- a/core/client/app/initializers/dropdown.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import DropdownService from 'ghost/utils/dropdown-service';
-
-var dropdownInitializer = {
- name: 'dropdown',
-
- initialize: function (container, application) {
- application.register('dropdown:service', DropdownService);
-
- // Inject dropdowns
- application.inject('component:gh-dropdown', 'dropdown', 'dropdown:service');
- application.inject('component:gh-dropdown-button', 'dropdown', 'dropdown:service');
- application.inject('controller:application', 'dropdown', 'dropdown:service');
- application.inject('controller:modals.delete-post', 'dropdown', 'dropdown:service');
- application.inject('controller:modals.transfer-owner', 'dropdown', 'dropdown:service');
- application.inject('route:application', 'dropdown', 'dropdown:service');
-
- // Inject popovers
- application.inject('component:gh-popover', 'dropdown', 'dropdown:service');
- application.inject('component:gh-popover-button', 'dropdown', 'dropdown:service');
- application.inject('route:application', 'dropdown', 'dropdown:service');
- }
-};
-
-export default dropdownInitializer;
diff --git a/core/client/app/initializers/ghost-config.js b/core/client/app/initializers/ghost-config.js
deleted file mode 100644
index a9fc300a1f..0000000000
--- a/core/client/app/initializers/ghost-config.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import getConfig from 'ghost/utils/config-parser';
-
-var ConfigInitializer = {
- name: 'config',
-
- initialize: function (container, application) {
- var config = getConfig();
- application.register('ghost:config', config, {instantiate: false});
-
- application.inject('route', 'config', 'ghost:config');
- application.inject('model:post', 'config', 'ghost:config');
- application.inject('controller', 'config', 'ghost:config');
- application.inject('component', 'config', 'ghost:config');
- }
-};
-
-export default ConfigInitializer;
diff --git a/core/client/app/initializers/ghost-paths.js b/core/client/app/initializers/ghost-paths.js
deleted file mode 100644
index a72f26a8d3..0000000000
--- a/core/client/app/initializers/ghost-paths.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ghostPaths from 'ghost/utils/ghost-paths';
-
-var ghostPathsInitializer = {
- name: 'ghost-paths',
- after: 'store',
-
- initialize: function (container, application) {
- application.register('ghost:paths', ghostPaths(), {instantiate: false});
-
- application.inject('route', 'ghostPaths', 'ghost:paths');
- application.inject('model', 'ghostPaths', 'ghost:paths');
- application.inject('controller', 'ghostPaths', 'ghost:paths');
- }
-};
-
-export default ghostPathsInitializer;
diff --git a/core/client/app/initializers/notifications.js b/core/client/app/initializers/notifications.js
deleted file mode 100644
index 3e0d4fac26..0000000000
--- a/core/client/app/initializers/notifications.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import Notifications from 'ghost/utils/notifications';
-
-var injectNotificationsInitializer = {
- name: 'injectNotifications',
- before: 'authentication',
-
- initialize: function (container, application) {
- application.register('notifications:main', Notifications);
-
- application.inject('controller', 'notifications', 'notifications:main');
- application.inject('component', 'notifications', 'notifications:main');
- application.inject('router', 'notifications', 'notifications:main');
- application.inject('route', 'notifications', 'notifications:main');
- }
-};
-
-export default injectNotificationsInitializer;
diff --git a/core/client/app/mixins/editor-base-controller.js b/core/client/app/mixins/editor-base-controller.js
index 8fb61710af..422dad2e27 100644
--- a/core/client/app/mixins/editor-base-controller.js
+++ b/core/client/app/mixins/editor-base-controller.js
@@ -5,24 +5,24 @@ import PostModel from 'ghost/models/post';
import boundOneWay from 'ghost/utils/bound-one-way';
import imageManager from 'ghost/utils/ed-image-manager';
-var watchedProps,
- EditorControllerMixin;
-
// this array will hold properties we need to watch
// to know if the model has been changed (`controller.isDirty`)
-watchedProps = ['model.scratch', 'model.titleScratch', 'model.isDirty', 'model.tags.[]'];
+var watchedProps = ['model.scratch', 'model.titleScratch', 'model.isDirty', 'model.tags.[]'];
PostModel.eachAttribute(function (name) {
watchedProps.push('model.' + name);
});
-EditorControllerMixin = Ember.Mixin.create({
- needs: ['post-tags-input', 'post-settings-menu'],
+export default Ember.Mixin.create({
+ postTagsInputController: Ember.inject.controller('post-tags-input'),
+ postSettingsMenuController: Ember.inject.controller('post-settings-menu'),
autoSaveId: null,
timedSaveId: null,
editor: null,
+ notifications: Ember.inject.service(),
+
init: function () {
var self = this;
@@ -32,6 +32,7 @@ EditorControllerMixin = Ember.Mixin.create({
return self.get('isDirty') ? self.unloadDirtyMessage() : null;
};
},
+
autoSave: function () {
// Don't save just because we swapped out models
if (this.get('model.isDraft') && !this.get('model.isNew')) {
@@ -213,21 +214,24 @@ EditorControllerMixin = Ember.Mixin.create({
showSaveNotification: function (prevStatus, status, delay) {
var message = this.messageMap.success.post[prevStatus][status],
path = this.get('model.absoluteUrl'),
- type = this.get('postOrPage');
+ type = this.get('postOrPage'),
+ notifications = this.get('notifications');
if (status === 'published') {
message += ` View ${type}`;
}
- this.notifications.showSuccess(message.htmlSafe(), {delayed: delay});
+
+ notifications.showSuccess(message.htmlSafe(), {delayed: delay});
},
showErrorNotification: function (prevStatus, status, errors, delay) {
var message = this.messageMap.errors.post[prevStatus][status],
- error = (errors && errors[0] && errors[0].message) || 'Unknown Error';
+ error = (errors && errors[0] && errors[0].message) || 'Unknown Error',
+ notifications = this.get('notifications');
message += '
' + error;
- this.notifications.showError(message.htmlSafe(), {delayed: delay});
+ notifications.showError(message.htmlSafe(), {delayed: delay});
},
shouldFocusTitle: Ember.computed.alias('model.isNew'),
@@ -241,8 +245,9 @@ EditorControllerMixin = Ember.Mixin.create({
autoSaveId = this.get('autoSaveId'),
timedSaveId = this.get('timedSaveId'),
self = this,
- psmController = this.get('controllers.post-settings-menu'),
- promise;
+ psmController = this.get('postSettingsMenuController'),
+ promise,
+ notifications = this.get('notifications');
options = options || {};
@@ -263,10 +268,10 @@ EditorControllerMixin = Ember.Mixin.create({
this.set('timedSaveId', null);
}
- self.notifications.closePassive();
+ notifications.closePassive();
// ensure an incomplete tag is finalised before save
- this.get('controllers.post-tags-input').send('addNewTag');
+ this.get('postTagsInputController').send('addNewTag');
// Set the properties that are indirected
// set markdown equal to what's in the editor, minus the image markers.
@@ -367,5 +372,3 @@ EditorControllerMixin = Ember.Mixin.create({
}
}
});
-
-export default EditorControllerMixin;
diff --git a/core/client/app/mixins/pagination-controller.js b/core/client/app/mixins/pagination-controller.js
index 5f68111aa7..7957781561 100644
--- a/core/client/app/mixins/pagination-controller.js
+++ b/core/client/app/mixins/pagination-controller.js
@@ -2,6 +2,8 @@ import Ember from 'ember';
import getRequestErrorMessage from 'ghost/utils/ajax';
export default Ember.Mixin.create({
+ notifications: Ember.inject.service(),
+
// set from PaginationRouteMixin
paginationSettings: null,
@@ -23,7 +25,7 @@ export default Ember.Mixin.create({
message += '.';
}
- this.notifications.showError(message);
+ this.get('notifications').showError(message);
},
actions: {
diff --git a/core/client/app/mixins/selective-save.js b/core/client/app/mixins/selective-save.js
deleted file mode 100644
index c3945b5d61..0000000000
--- a/core/client/app/mixins/selective-save.js
+++ /dev/null
@@ -1,122 +0,0 @@
-import Ember from 'ember';
-// SelectiveSaveMixin adds a saveOnly method to a DS.Model.
-//
-// saveOnly provides a way to save one or more properties of a model while
-// preserving outstanding changes to other properties.
-var SelectiveSaveMixin = Ember.Mixin.create({
- saveOnly: function () {
- if (arguments.length === 0) {
- return Ember.RSVP.resolve();
- }
-
- if (arguments.length === 1 && Ember.isArray(arguments[0])) {
- return this.saveOnly.apply(this, Array.prototype.slice.call(arguments[0]));
- }
-
- var propertiesToSave = Array.prototype.slice.call(arguments),
- changed,
- hasMany = {},
- belongsTo = {},
- self = this;
-
- changed = this.changedAttributes();
-
- // disable observers so we can make changes to the model but not have
- // them reflected by the UI
- this.beginPropertyChanges();
-
- // make a copy of any relations the model may have so they can
- // be reapplied later
- this.eachRelationship(function (name, meta) {
- if (meta.kind === 'hasMany') {
- hasMany[name] = self.get(name).slice();
- return;
- }
-
- if (meta.kind === 'belongsTo') {
- belongsTo[name] = self.get(name);
- return;
- }
- });
-
- try {
- // roll back all changes to the model and then reapply only those that
- // are part of the saveOnly
-
- self.rollback();
-
- propertiesToSave.forEach(function (name) {
- if (hasMany.hasOwnProperty(name)) {
- self.get(name).clear();
-
- hasMany[name].forEach(function (relatedType) {
- self.get(name).pushObject(relatedType);
- });
-
- return;
- }
-
- if (belongsTo.hasOwnProperty(name)) {
- return self.updateBelongsTo(name, belongsTo[name]);
- }
-
- if (changed.hasOwnProperty(name)) {
- return self.set(name, changed[name][1]);
- }
- });
- }
- catch (err) {
- // if we were not able to get the model into the correct state
- // put it back the way we found it and return a rejected promise
-
- Ember.keys(changed).forEach(function (name) {
- self.set(name, changed[name][1]);
- });
-
- Ember.keys(hasMany).forEach(function (name) {
- self.updateHasMany(name, hasMany[name]);
- });
-
- Ember.keys(belongsTo).forEach(function (name) {
- self.updateBelongsTo(name, belongsTo[name]);
- });
-
- self.endPropertyChanges();
-
- return Ember.RSVP.reject(new Error(err.message || 'Error during saveOnly. Changes NOT saved.'));
- }
-
- return this.save().finally(function () {
- // reapply any changes that were not part of the save
-
- Ember.keys(changed).forEach(function (name) {
- if (propertiesToSave.hasOwnProperty(name)) {
- return;
- }
-
- self.set(name, changed[name][1]);
- });
-
- Ember.keys(hasMany).forEach(function (name) {
- if (propertiesToSave.hasOwnProperty(name)) {
- return;
- }
-
- self.updateHasMany(name, hasMany[name]);
- });
-
- Ember.keys(belongsTo).forEach(function (name) {
- if (propertiesToSave.hasOwnProperty(name)) {
- return;
- }
-
- self.updateBelongsTo(name, belongsTo[name]);
- });
-
- // signal that we're finished and normal model observation may continue
- self.endPropertyChanges();
- });
- }
-});
-
-export default SelectiveSaveMixin;
diff --git a/core/client/app/mixins/settings-menu-controller.js b/core/client/app/mixins/settings-menu-controller.js
index a2837f394b..6a0509a0db 100644
--- a/core/client/app/mixins/settings-menu-controller.js
+++ b/core/client/app/mixins/settings-menu-controller.js
@@ -1,10 +1,11 @@
import Ember from 'ember';
-var SettingsMenuControllerMixin = Ember.Mixin.create({
- needs: 'application',
- isViewingSubview: Ember.computed('controllers.application.showSettingsMenu', function (key, value) {
+export default Ember.Mixin.create({
+ application: Ember.inject.controller(),
+
+ isViewingSubview: Ember.computed('application.showSettingsMenu', function (key, value) {
// Not viewing a subview if we can't even see the PSM
- if (!this.get('controllers.application.showSettingsMenu')) {
+ if (!this.get('application.showSettingsMenu')) {
return false;
}
if (arguments.length > 1) {
@@ -24,5 +25,3 @@ var SettingsMenuControllerMixin = Ember.Mixin.create({
}
}
});
-
-export default SettingsMenuControllerMixin;
diff --git a/core/client/app/models/post.js b/core/client/app/models/post.js
index db9512e1c7..99c0f18fe7 100644
--- a/core/client/app/models/post.js
+++ b/core/client/app/models/post.js
@@ -2,7 +2,7 @@ import Ember from 'ember';
import DS from 'ember-data';
import ValidationEngine from 'ghost/mixins/validation-engine';
-var Post = DS.Model.extend(ValidationEngine, {
+export default DS.Model.extend(ValidationEngine, {
validationType: 'post',
uuid: DS.attr('string'),
@@ -28,6 +28,9 @@ var Post = DS.Model.extend(ValidationEngine, {
tags: DS.hasMany('tag', {embedded: 'always'}),
url: DS.attr('string'),
+ config: Ember.inject.service(),
+ ghostPaths: Ember.inject.service('ghost-paths'),
+
absoluteUrl: Ember.computed('url', 'ghostPaths.url', 'config.blogUrl', function () {
var blogUrl = this.get('config.blogUrl'),
postUrl = this.get('url');
@@ -69,5 +72,3 @@ var Post = DS.Model.extend(ValidationEngine, {
}
});
-
-export default Post;
diff --git a/core/client/app/models/slug-generator.js b/core/client/app/models/slug-generator.js
index 2252421986..ac0051f8cd 100644
--- a/core/client/app/models/slug-generator.js
+++ b/core/client/app/models/slug-generator.js
@@ -2,10 +2,11 @@ import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
export default Ember.Object.extend({
- ghostPaths: null,
slugType: null,
value: null,
+ ghostPaths: Ember.inject.service('ghost-paths'),
+
toString: function () {
return this.get('value');
},
diff --git a/core/client/app/models/user.js b/core/client/app/models/user.js
index 7536942c49..7243c43bc9 100644
--- a/core/client/app/models/user.js
+++ b/core/client/app/models/user.js
@@ -2,9 +2,8 @@ import Ember from 'ember';
import DS from 'ember-data';
import {request as ajax} from 'ic-ajax';
import ValidationEngine from 'ghost/mixins/validation-engine';
-import SelectiveSaveMixin from 'ghost/mixins/selective-save';
-export default DS.Model.extend(SelectiveSaveMixin, ValidationEngine, {
+export default DS.Model.extend(ValidationEngine, {
validationType: 'user',
uuid: DS.attr('string'),
@@ -28,6 +27,8 @@ export default DS.Model.extend(SelectiveSaveMixin, ValidationEngine, {
updated_by: DS.attr('number'),
roles: DS.hasMany('role', {embedded: 'always'}),
+ ghostPaths: Ember.inject.service('ghost-paths'),
+
role: Ember.computed('roles', function (name, value) {
if (arguments.length > 1) {
// Only one role per user, so remove any old data.
@@ -93,13 +94,13 @@ export default DS.Model.extend(SelectiveSaveMixin, ValidationEngine, {
isPasswordValid: Ember.computed.empty('passwordValidationErrors.[]'),
- active: function () {
+ active: Ember.computed('status', function () {
return ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked'].indexOf(this.get('status')) > -1;
- }.property('status'),
+ }),
- invited: function () {
+ invited: Ember.computed('status', function () {
return ['invited', 'invited-pending'].indexOf(this.get('status')) > -1;
- }.property('status'),
+ }),
pending: Ember.computed.equal('status', 'invited-pending').property('status')
});
diff --git a/core/client/app/router.js b/core/client/app/router.js
index bc44217408..68c17d7c57 100644
--- a/core/client/app/router.js
+++ b/core/client/app/router.js
@@ -6,9 +6,13 @@ var Router = Ember.Router.extend({
location: 'trailing-history', // use HTML5 History API instead of hash-tag based URLs
rootURL: ghostPaths().adminRoot, // admin interface lives under sub-directory /ghost
+ notifications: Ember.inject.service(),
+
clearNotifications: Ember.on('didTransition', function () {
- this.notifications.closePassive();
- this.notifications.displayDelayed();
+ var notifications = this.get('notifications');
+
+ notifications.closePassive();
+ notifications.displayDelayed();
})
});
diff --git a/core/client/app/routes/about.js b/core/client/app/routes/about.js
index 11a0a74835..9c23a7ad6d 100644
--- a/core/client/app/routes/about.js
+++ b/core/client/app/routes/about.js
@@ -1,3 +1,4 @@
+import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
import AuthenticatedRoute from 'ghost/routes/authenticated';
import styleBody from 'ghost/mixins/style-body';
@@ -7,6 +8,8 @@ export default AuthenticatedRoute.extend(styleBody, {
classNames: ['view-about'],
+ ghostPaths: Ember.inject.service('ghost-paths'),
+
cachedConfig: false,
model: function () {
diff --git a/core/client/app/routes/application.js b/core/client/app/routes/application.js
index cd486e7391..54a46473d3 100644
--- a/core/client/app/routes/application.js
+++ b/core/client/app/routes/application.js
@@ -6,16 +6,19 @@ import Configuration from 'simple-auth/configuration';
import ShortcutsRoute from 'ghost/mixins/shortcuts-route';
import ctrlOrCmd from 'ghost/utils/ctrl-or-cmd';
-var ApplicationRoute,
- shortcuts = {};
+var shortcuts = {};
shortcuts.esc = {action: 'closePopups', scope: 'all'};
shortcuts.enter = {action: 'confirmModal', scope: 'modal'};
shortcuts[ctrlOrCmd + '+s'] = {action: 'save', scope: 'all'};
-ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
+export default Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
shortcuts: shortcuts,
+ config: Ember.inject.service(),
+ dropdown: Ember.inject.service(),
+ notifications: Ember.inject.service(),
+
afterModel: function (model, transition) {
if (this.get('session').isAuthenticated) {
transition.send('loadServerNotifications');
@@ -68,10 +71,10 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
err.message = err.message.htmlSafe();
});
- this.notifications.showErrors(error.errors);
+ this.get('notifications').showErrors(error.errors);
} else {
// connection errors don't return proper status message, only req.body
- this.notifications.showError('There was a problem on the server.');
+ this.get('notifications').showError('There was a problem on the server.');
}
},
@@ -96,7 +99,7 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
},
sessionInvalidationFailed: function (error) {
- this.notifications.showError(error.message);
+ this.get('notifications').showError(error.message);
},
openModal: function (modalName, model, type) {
@@ -149,7 +152,7 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
if (!user.get('isAuthor') && !user.get('isEditor')) {
self.store.findAll('notification').then(function (serverNotifications) {
serverNotifications.forEach(function (notification) {
- self.notifications.handleNotification(notification, isDelayed);
+ self.get('notifications').handleNotification(notification, isDelayed);
});
});
}
@@ -158,11 +161,11 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
},
handleErrors: function (errors) {
- var self = this;
+ var notifications = this.get('notifications');
- this.notifications.clear();
+ notifications.clear();
errors.forEach(function (errorObj) {
- self.notifications.showError(errorObj.message || errorObj);
+ notifications.showError(errorObj.message || errorObj);
if (errorObj.hasOwnProperty('el')) {
errorObj.el.addClass('input-error');
@@ -174,5 +177,3 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
save: Ember.K
}
});
-
-export default ApplicationRoute;
diff --git a/core/client/app/routes/reset.js b/core/client/app/routes/reset.js
index ff9dc1b0b5..9497f6d121 100644
--- a/core/client/app/routes/reset.js
+++ b/core/client/app/routes/reset.js
@@ -2,12 +2,14 @@ import Ember from 'ember';
import Configuration from 'simple-auth/configuration';
import styleBody from 'ghost/mixins/style-body';
-var ResetRoute = Ember.Route.extend(styleBody, {
+export default Ember.Route.extend(styleBody, {
classNames: ['ghost-reset'],
+ notifications: Ember.inject.service(),
+
beforeModel: function () {
if (this.get('session').isAuthenticated) {
- this.notifications.showWarn('You can\'t reset your password while you\'re signed in.', {delayed: true});
+ this.get('notifications').showWarn('You can\'t reset your password while you\'re signed in.', {delayed: true});
this.transitionTo(Configuration.routeAfterAuthentication);
}
},
@@ -22,5 +24,3 @@ var ResetRoute = Ember.Route.extend(styleBody, {
this.controller.clearData();
}
});
-
-export default ResetRoute;
diff --git a/core/client/app/routes/settings/apps.js b/core/client/app/routes/settings/apps.js
index 143a64b1e0..93aeab1d09 100644
--- a/core/client/app/routes/settings/apps.js
+++ b/core/client/app/routes/settings/apps.js
@@ -1,12 +1,15 @@
+import Ember from 'ember';
import AuthenticatedRoute from 'ghost/routes/authenticated';
import CurrentUserSettings from 'ghost/mixins/current-user-settings';
import styleBody from 'ghost/mixins/style-body';
-var AppsRoute = AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
+export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
titleToken: 'Apps',
classNames: ['settings-view-apps'],
+ config: Ember.inject.service(),
+
beforeModel: function () {
if (!this.get('config.apps')) {
return this.transitionTo('settings.general');
@@ -21,5 +24,3 @@ var AppsRoute = AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
return this.store.find('app');
}
});
-
-export default AppsRoute;
diff --git a/core/client/app/routes/setup.js b/core/client/app/routes/setup.js
index d6a1fc19d7..a1397f98ab 100644
--- a/core/client/app/routes/setup.js
+++ b/core/client/app/routes/setup.js
@@ -8,9 +8,10 @@ export default Ember.Route.extend(styleBody, {
classNames: ['ghost-setup'],
+ ghostPaths: Ember.inject.service('ghost-paths'),
+
// use the beforeModel hook to check to see whether or not setup has been
// previously completed. If it has, stop the transition into the setup page.
-
beforeModel: function () {
var self = this;
diff --git a/core/client/app/routes/signout.js b/core/client/app/routes/signout.js
index f20e920a02..12e0925d6d 100644
--- a/core/client/app/routes/signout.js
+++ b/core/client/app/routes/signout.js
@@ -2,13 +2,15 @@ import Ember from 'ember';
import AuthenticatedRoute from 'ghost/routes/authenticated';
import styleBody from 'ghost/mixins/style-body';
-var SignoutRoute = AuthenticatedRoute.extend(styleBody, {
+export default AuthenticatedRoute.extend(styleBody, {
titleToken: 'Sign Out',
classNames: ['ghost-signout'],
+ notifications: Ember.inject.service(),
+
afterModel: function (model, transition) {
- this.notifications.clear();
+ this.get('notifications').closeAll();
if (Ember.canInvoke(transition, 'send')) {
transition.send('invalidateSession');
transition.abort();
@@ -17,5 +19,3 @@ var SignoutRoute = AuthenticatedRoute.extend(styleBody, {
}
}
});
-
-export default SignoutRoute;
diff --git a/core/client/app/routes/signup.js b/core/client/app/routes/signup.js
index bcf27656fb..369aafba5a 100644
--- a/core/client/app/routes/signup.js
+++ b/core/client/app/routes/signup.js
@@ -6,9 +6,12 @@ import styleBody from 'ghost/mixins/style-body';
export default Ember.Route.extend(styleBody, {
classNames: ['ghost-signup'],
+ ghostPaths: Ember.inject.service('ghost-paths'),
+ notifications: Ember.inject.service(),
+
beforeModel: function () {
if (this.get('session').isAuthenticated) {
- this.notifications.showWarn('You need to sign out to register as a new user.', {delayed: true});
+ this.get('notifications').showWarn('You need to sign out to register as a new user.', {delayed: true});
this.transitionTo(Configuration.routeAfterAuthentication);
}
},
@@ -22,7 +25,7 @@ export default Ember.Route.extend(styleBody, {
return new Ember.RSVP.Promise(function (resolve) {
if (!re.test(params.token)) {
- self.notifications.showError('Invalid token.', {delayed: true});
+ self.get('notifications').showError('Invalid token.', {delayed: true});
return resolve(self.transitionTo('signin'));
}
@@ -42,7 +45,7 @@ export default Ember.Route.extend(styleBody, {
}
}).then(function (response) {
if (response && response.invitation && response.invitation[0].valid === false) {
- self.notifications.showError('The invitation does not exist or is no longer valid.', {delayed: true});
+ self.get('notifications').showError('The invitation does not exist or is no longer valid.', {delayed: true});
return resolve(self.transitionTo('signin'));
}
diff --git a/core/client/app/services/config.js b/core/client/app/services/config.js
new file mode 100644
index 0000000000..0d554de5b3
--- /dev/null
+++ b/core/client/app/services/config.js
@@ -0,0 +1,43 @@
+import Ember from 'ember';
+
+function isNumeric(num) {
+ return !isNaN(num);
+}
+
+function _mapType(val) {
+ if (val === '') {
+ return null;
+ } else if (val === 'true') {
+ return true;
+ } else if (val === 'false') {
+ return false;
+ } else if (isNumeric(val)) {
+ return +val;
+ } else if (val.indexOf('{') === 0) {
+ try {
+ return JSON.parse(val);
+ } catch (e) {
+ /*jshint unused:false */
+ return val;
+ }
+ } else {
+ return val;
+ }
+}
+
+export default Ember.Service.extend(Ember._ProxyMixin, {
+ content: Ember.computed(function () {
+ var metaConfigTags = Ember.$('meta[name^="env-"]'),
+ config = {};
+
+ metaConfigTags.each(function (i, el) {
+ var key = el.name,
+ value = el.content,
+ propertyName = key.substring(4);
+
+ config[propertyName] = _mapType(value);
+ });
+
+ return config;
+ })
+});
diff --git a/core/client/app/utils/dropdown-service.js b/core/client/app/services/dropdown.js
similarity index 82%
rename from core/client/app/utils/dropdown-service.js
rename to core/client/app/services/dropdown.js
index e9aa2b1740..be25396944 100644
--- a/core/client/app/utils/dropdown-service.js
+++ b/core/client/app/services/dropdown.js
@@ -2,17 +2,17 @@ import Ember from 'ember';
// This is used by the dropdown initializer (and subsequently popovers) to manage closing & toggling
import BodyEventListener from 'ghost/mixins/body-event-listener';
-var DropdownService = Ember.Object.extend(Ember.Evented, BodyEventListener, {
+export default Ember.Service.extend(Ember.Evented, BodyEventListener, {
bodyClick: function (event) {
/*jshint unused:false */
this.closeDropdowns();
},
+
closeDropdowns: function () {
this.trigger('close');
},
+
toggleDropdown: function (dropdownName, dropdownButton) {
this.trigger('toggle', {target: dropdownName, button: dropdownButton});
}
});
-
-export default DropdownService;
diff --git a/core/client/app/services/ghost-paths.js b/core/client/app/services/ghost-paths.js
new file mode 100644
index 0000000000..12563a0b4f
--- /dev/null
+++ b/core/client/app/services/ghost-paths.js
@@ -0,0 +1,6 @@
+import Ember from 'ember';
+import ghostPaths from 'ghost/utils/ghost-paths';
+
+export default Ember.Service.extend(Ember._ProxyMixin, {
+ content: ghostPaths()
+});
diff --git a/core/client/app/utils/notifications.js b/core/client/app/services/notifications.js
similarity index 87%
rename from core/client/app/utils/notifications.js
rename to core/client/app/services/notifications.js
index c59c3ccbe3..4e4c10d6b4 100644
--- a/core/client/app/utils/notifications.js
+++ b/core/client/app/services/notifications.js
@@ -1,8 +1,8 @@
import Ember from 'ember';
import Notification from 'ghost/models/notification';
-var Notifications = Ember.ArrayProxy.extend({
- delayedNotifications: [],
+export default Ember.Service.extend({
+ delayedNotifications: Ember.A(),
content: Ember.A(),
timeout: 3000,
@@ -25,6 +25,7 @@ var Notifications = Ember.ArrayProxy.extend({
this._super(object);
},
+
handleNotification: function (message, delayed) {
if (typeof message.toJSON === 'function') {
// If this is a persistent message from the server, treat it as html safe
@@ -42,11 +43,12 @@ var Notifications = Ember.ArrayProxy.extend({
}
if (!delayed) {
- this.pushObject(message);
+ this.get('content').pushObject(message);
} else {
- this.delayedNotifications.push(message);
+ this.delayedNotifications.pushObject(message);
}
},
+
showError: function (message, options) {
options = options || {};
@@ -59,6 +61,7 @@ var Notifications = Ember.ArrayProxy.extend({
message: message
}, options.delayed);
},
+
showErrors: function (errors, options) {
options = options || {};
@@ -70,6 +73,7 @@ var Notifications = Ember.ArrayProxy.extend({
this.showError(errors[i].message || errors[i], {doNotClosePassive: true});
}
},
+
showAPIError: function (resp, options) {
options = options || {};
@@ -89,6 +93,7 @@ var Notifications = Ember.ArrayProxy.extend({
this.showError(options.defaultErrorText, {doNotClosePassive: true});
}
},
+
showInfo: function (message, options) {
options = options || {};
@@ -101,6 +106,7 @@ var Notifications = Ember.ArrayProxy.extend({
message: message
}, options.delayed);
},
+
showSuccess: function (message, options) {
options = options || {};
@@ -113,6 +119,7 @@ var Notifications = Ember.ArrayProxy.extend({
message: message
}, options.delayed);
},
+
showWarn: function (message, options) {
options = options || {};
@@ -125,35 +132,38 @@ var Notifications = Ember.ArrayProxy.extend({
message: message
}, options.delayed);
},
+
displayDelayed: function () {
var self = this;
self.delayedNotifications.forEach(function (message) {
- self.pushObject(message);
+ self.get('content').pushObject(message);
});
self.delayedNotifications = [];
},
+
closeNotification: function (notification) {
- var self = this;
+ var content = this.get('content');
if (notification instanceof Notification) {
notification.deleteRecord();
notification.save().finally(function () {
- self.removeObject(notification);
+ content.removeObject(notification);
});
} else {
- this.removeObject(notification);
+ content.removeObject(notification);
}
},
+
closePassive: function () {
- this.set('content', this.rejectBy('status', 'passive'));
+ this.set('content', this.get('content').rejectBy('status', 'passive'));
},
+
closePersistent: function () {
- this.set('content', this.rejectBy('status', 'persistent'));
+ this.set('content', this.get('content').rejectBy('status', 'persistent'));
},
+
closeAll: function () {
- this.clear();
+ this.get('content').clear();
}
});
-
-export default Notifications;
diff --git a/core/client/app/utils/config-parser.js b/core/client/app/utils/config-parser.js
deleted file mode 100644
index cb2a97ecc0..0000000000
--- a/core/client/app/utils/config-parser.js
+++ /dev/null
@@ -1,43 +0,0 @@
-var isNumeric = function (num) {
- return !isNaN(num);
- },
-
- _mapType = function (val) {
- if (val === '') {
- return null;
- } else if (val === 'true') {
- return true;
- } else if (val === 'false') {
- return false;
- } else if (isNumeric(val)) {
- return +val;
- } else if (val.indexOf('{') === 0) {
- try {
- return JSON.parse(val);
- } catch (e) {
- /*jshint unused:false */
- return val;
- }
- } else {
- return val;
- }
- },
-
- parseConfiguration = function () {
- var metaConfigTags = $('meta[name^="env-"]'),
- propertyName,
- config = {},
- value,
- key,
- i;
-
- for (i = 0; i < metaConfigTags.length; i += 1) {
- key = $(metaConfigTags[i]).prop('name');
- value = $(metaConfigTags[i]).prop('content');
- propertyName = key.substring(4); // produce config name ignoring the initial 'env-'.
- config[propertyName] = _mapType(value); // map string values to types if possible
- }
- return config;
- };
-
-export default parseConfiguration;