Switch to eslint-plugin-ghost extending plugin:ghost/ember

no issue
- fix lint errors in lib/gh-koenig
- fix ghost:base eslint errors
- update ember plugin refs, remove ember-suave plugin refs
- remove old jshint refs
- add `lint:js` script
- switch to `eslint-plugin-ghost` extending `plugin:ghost/ember`
This commit is contained in:
Kevin Ansfield 2018-01-05 15:38:23 +00:00
parent e4d34d4221
commit 7afb88a0c2
187 changed files with 597 additions and 752 deletions

View File

@ -1,38 +1,15 @@
/* eslint-env node */
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 2017,
sourceType: 'module'
},
env: {
browser: true
},
extends: [
'eslint:recommended',
'plugin:ember/recommended',
'plugin:ember-suave/recommended'
],
plugins: [
'sort-imports-es6-autofix'
'ghost'
],
extends: [
'plugin:ghost/ember'
],
rules: {
indent: ['error', 4],
'space-before-function-paren': ['error', {anonymous: 'ignore', named: 'never'}],
'object-curly-spacing': ['error', 'never'],
'array-bracket-spacing': ['error', 'never'],
'key-spacing': ['error', {mode: 'minimum'}],
'keyword-spacing': ['error', {overrides: {
'catch': {'after': true}
}}],
'ember-suave/require-access-in-comments': 'off',
'sort-imports-es6-autofix/sort-imports-es6': ['error', {
memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple']
}],
// TODO: re-enable this rule once this lands
// https://github.com/ember-cli/eslint-plugin-ember/pull/186
'ember/no-global-jquery': 'off'
// disable linting of `this.get` until there's a reliable autofix
'ghost/ember/use-ember-get-and-set': 'off'
},
globals: {
validator: false

View File

@ -38,6 +38,7 @@ before_script:
- export DISPLAY=:99; sh -e /etc/init.d/xvfb start; sleep 3;
script:
- npm run lint:js
- COVERAGE=true npm test
after_success:

View File

@ -2,8 +2,7 @@
/* eslint-disable object-shorthand */
'use strict';
module.exports = function(grunt) {
module.exports = function (grunt) {
// Find all of the task which start with `grunt-` and load them, rather than explicitly declaring them all
require('matchdep').filterDev(['grunt-*', '!grunt-cli']).forEach(grunt.loadNpmTasks);

View File

@ -38,7 +38,7 @@ export default Authenticator.extend({
let options = {
data,
dataType: 'json',
dataType: 'json',
contentType: 'application/x-www-form-urlencoded'
};
@ -63,7 +63,7 @@ export default Authenticator.extend({
authenticate(identification, password, scope = [], headers = {}) {
return new RSVP.Promise((resolve, reject) => {
let data = {'grant_type': 'password', username: identification, password};
let data = {grant_type: 'password', username: identification, password};
let serverTokenEndpoint = this.get('serverTokenEndpoint');
let scopesString = wrap(scope).join(' ');
if (!isEmpty(scopesString)) {
@ -77,7 +77,7 @@ export default Authenticator.extend({
/* eslint-enable camelcase */
if (!isEmpty(expiresAt)) {
response = assign(response, {'expires_at': expiresAt});
response = assign(response, {expires_at: expiresAt});
}
resolve(response);

View File

@ -8,7 +8,7 @@ import {bind, once, scheduleOnce} from '@ember/runloop';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
const CmEditorComponent = Component.extend(InvokeActionMixin, {
const CmEditorComponent = Component.extend(InvokeActionMixin, {
classNameBindings: ['isFocused:focus'],
_value: boundOneWay('value'), // make sure a value exists

View File

@ -109,7 +109,7 @@ export default Component.extend({
// the counter technique prevents flickering of the drag class when
// dragging across child elements
this._dragCounter++;
this._dragCounter += 1;
this.set('isDraggedOver', true);
},
@ -118,7 +118,7 @@ export default Component.extend({
event.preventDefault();
event.stopPropagation();
this._dragCounter--;
this._dragCounter -= 1;
if (this._dragCounter === 0) {
this.set('isDraggedOver', false);
}

View File

@ -361,18 +361,16 @@ export default Component.extend(ShortcutsMixin, {
_connectSplitPreview() {
let cm = this._editor.codemirror;
let editor = this._editor;
/* eslint-disable ember-suave/prefer-destructuring */
let editorPane = this.$('.gh-markdown-editor-pane')[0];
let previewPane = this.$('.gh-markdown-editor-preview')[0];
let previewContent = this.$('.gh-markdown-editor-preview-content')[0];
/* eslint-enable ember-suave/prefer-destructuring */
this._editorPane = editorPane;
this._previewPane = previewPane;
this._previewContent = previewContent;
// from SimpleMDE -------
let sideBySideRenderingFunction = function() {
let sideBySideRenderingFunction = function () {
previewContent.innerHTML = editor.options.previewRender(
editor.value(),
previewContent
@ -613,9 +611,7 @@ export default Component.extend(ShortcutsMixin, {
if (isSplitScreen) {
// disable the normal SimpleMDE preview if it's active
if (this._editor.isPreviewActive()) {
let preview = this._editor.toolbar.find((button) => {
return button.name === 'preview';
});
let preview = this._editor.toolbar.find(button => button.name === 'preview');
preview.action(this._editor);
}

View File

@ -27,15 +27,15 @@ export default Component.extend({
this._setIconStyle();
},
showMenuExtension: computed('config.clientExtensions.menu', 'session.user.isOwner', function() {
showMenuExtension: computed('config.clientExtensions.menu', 'session.user.isOwner', function () {
return this.get('config.clientExtensions.menu') && this.get('session.user.isOwner');
}),
showDropdownExtension: computed('config.clientExtensions.dropdown', 'session.user.isOwner', function() {
showDropdownExtension: computed('config.clientExtensions.dropdown', 'session.user.isOwner', function () {
return this.get('config.clientExtensions.dropdown') && this.get('session.user.isOwner');
}),
showScriptExtension: computed('config.clientExtensions.script', 'session.user.isOwner', function() {
showScriptExtension: computed('config.clientExtensions.script', 'session.user.isOwner', function () {
return this.get('config.clientExtensions.script') && this.get('session.user.isOwner');
}),

View File

@ -253,9 +253,7 @@ export default Component.extend(SettingsMenuMixin, {
model.set('customExcerpt', excerpt);
return model.validate({property: 'customExcerpt'}).then(() => {
return this.get('savePost').perform();
});
return model.validate({property: 'customExcerpt'}).then(() => this.get('savePost').perform());
},
setHeaderInjection(code) {
@ -268,9 +266,7 @@ export default Component.extend(SettingsMenuMixin, {
model.set('codeinjectionHead', code);
return model.validate({property: 'codeinjectionHead'}).then(() => {
return this.get('savePost').perform();
});
return model.validate({property: 'codeinjectionHead'}).then(() => this.get('savePost').perform());
},
setFooterInjection(code) {
@ -283,9 +279,7 @@ export default Component.extend(SettingsMenuMixin, {
model.set('codeinjectionFoot', code);
return model.validate({property: 'codeinjectionFoot'}).then(() => {
return this.get('savePost').perform();
});
return model.validate({property: 'codeinjectionFoot'}).then(() => this.get('savePost').perform());
},
setMetaTitle(metaTitle) {

View File

@ -101,7 +101,6 @@ export default Component.extend({
// wait for fade-in animation to finish before removing placeholder
yield timeout(ANIMATION_TIMEOUT);
this._setPlaceholderImage('');
} catch (e) {
// gravatar doesn't exist so make sure we're still showing the placeholder
this._setPlaceholderImage(this._defaultImageUrl);

View File

@ -16,9 +16,7 @@ export default Component.extend({
}),
availableTagNames: computed('availableTags.@each.name', function () {
return this.get('availableTags').map((tag) => {
return tag.get('name').toLowerCase();
});
return this.get('availableTags').map(tag => tag.get('name').toLowerCase());
}),
actions: {
@ -46,9 +44,7 @@ export default Component.extend({
createTag(tagName) {
let currentTags = this.get('post.tags');
let currentTagNames = currentTags.map((tag) => {
return tag.get('name').toLowerCase();
});
let currentTagNames = currentTags.map(tag => tag.get('name').toLowerCase());
let tagToAdd;
tagName = tagName.trim();
@ -78,10 +74,9 @@ export default Component.extend({
// methods
_findTagByName(name) {
return this.get('availableTags').then((availableTags) => {
return availableTags.find((tag) => {
return tag.get('name').toLowerCase() === name.toLowerCase();
});
});
let withMatchingName = function (tag) {
return tag.get('name').toLowerCase() === name.toLowerCase();
};
return this.get('availableTags').then(availableTags => availableTags.find(withMatchingName));
}
});

View File

@ -40,7 +40,7 @@ export default Component.extend({
}
}),
_runningText: computed('postState', 'saveType', function() {
_runningText: computed('postState', 'saveType', function () {
let saveType = this.get('saveType');
let postState = this.get('postState');
let runningText;
@ -62,7 +62,7 @@ export default Component.extend({
runningText: null,
buttonText: computed('postState', 'saveType', function() {
buttonText: computed('postState', 'saveType', function () {
let saveType = this.get('saveType');
let postState = this.get('postState');
let buttonText;
@ -82,7 +82,7 @@ export default Component.extend({
return buttonText || 'Publish';
}),
successText: computed('_previousStatus', 'postState', function() {
successText: computed('_previousStatus', 'postState', function () {
let postState = this.get('postState');
let previousStatus = this.get('_previousStatus');
let buttonText;
@ -118,7 +118,6 @@ export default Component.extend({
this._cachePublishedAtBlogTZ();
return post;
} catch (error) {
// re-throw if we don't have a validation error
if (error) {

View File

@ -96,13 +96,11 @@ export default Component.extend({
let content = this.get('content');
return this.get('ajax').request(postsUrl, {data: postsQuery}).then((posts) => {
content.pushObjects(posts.posts.map((post) => {
return {
id: `post.${post.id}`,
title: post.title,
category: post.page ? 'Pages' : 'Stories'
};
}));
content.pushObjects(posts.posts.map(post => ({
id: `post.${post.id}`,
title: post.title,
category: post.page ? 'Pages' : 'Stories'
})));
}).catch((error) => {
this.get('notifications').showAPIError(error, {key: 'search.loadPosts.error'});
});
@ -115,13 +113,11 @@ export default Component.extend({
let content = this.get('content');
return this.get('ajax').request(usersUrl, {data: usersQuery}).then((users) => {
content.pushObjects(users.users.map((user) => {
return {
id: `user.${user.slug}`,
title: user.name,
category: 'Users'
};
}));
content.pushObjects(users.users.map(user => ({
id: `user.${user.slug}`,
title: user.name,
category: 'Users'
})));
}).catch((error) => {
this.get('notifications').showAPIError(error, {key: 'search.loadUsers.error'});
});
@ -134,13 +130,11 @@ export default Component.extend({
let content = this.get('content');
return this.get('ajax').request(tagsUrl, {data: tagsQuery}).then((tags) => {
content.pushObjects(tags.tags.map((tag) => {
return {
id: `tag.${tag.slug}`,
title: tag.name,
category: 'Tags'
};
}));
content.pushObjects(tags.tags.map(tag => ({
id: `tag.${tag.slug}`,
title: tag.name,
category: 'Tags'
})));
}).catch((error) => {
this.get('notifications').showAPIError(error, {key: 'search.loadTags.error'});
});

View File

@ -95,7 +95,7 @@ export default TextArea.extend({
}
},
willDestroyElement() {
willDestroyElement() {
this.onEditorDestroy();
this._editor.toTextArea();
delete this._editor;

View File

@ -81,7 +81,7 @@ export default Component.extend({
optionsWithoutSelectedTask: task(function* () {
let options = yield this.get('options');
let selected = yield this.get('selected');
return options.filter((o) => !selected.includes(o));
return options.filter(o => !selected.includes(o));
}),
shouldShowCreateOption(term, options) {
@ -140,9 +140,7 @@ export default Component.extend({
return;
}
let suggestion = selection.find((option) => {
return option.__isSuggestion__;
});
let suggestion = selection.find(option => option.__isSuggestion__);
if (suggestion) {
this.get('oncreate')(suggestion.__value__, select);

View File

@ -13,7 +13,7 @@ let triangleClassPositions = {
targetAttachment: 'bottom center',
offset: '0 28px'
},
'top': {
top: {
attachment: 'top center',
targetAttachment: 'bottom center'
},
@ -27,7 +27,7 @@ let triangleClassPositions = {
targetAttachment: 'middle left',
offset: '28px 0'
},
'right': {
right: {
attachment: 'middle right',
targetAttachment: 'middle left'
},
@ -41,7 +41,7 @@ let triangleClassPositions = {
targetAttachment: 'top center',
offset: '0 -28px'
},
'bottom': {
bottom: {
attachment: 'bottom center',
targetAttachment: 'top center'
},
@ -55,7 +55,7 @@ let triangleClassPositions = {
targetAttachment: 'middle right',
offset: '-28px 0'
},
'left': {
left: {
attachment: 'middle left',
targetAttachment: 'middle right'
},
@ -98,7 +98,7 @@ const GhTourItemComponent = Component.extend({
init() {
this._super(...arguments);
// this is a tagless component so we need to generate our own elementId
this._elementId = instancesCounter++;
this._elementId = instancesCounter += 1;
this._throbberElementId = `throbber-${this._elementId}`;
this._throbberElementSelector = `#throbber-${this._elementId}`;

View File

@ -16,7 +16,7 @@ export default Component.extend({
zoom() {},
// avoid "binding style attributes" warnings
style: computed('photo.color', 'zoomed', function() {
style: computed('photo.color', 'zoomed', function () {
let styles = [];
let ratio = this.get('photo.ratio');
let zoomed = this.get('zoomed');

View File

@ -124,7 +124,7 @@ export default Component.extend({
// NOTE: for...of loop results in a transpilation that errors in Edge,
// once we drop IE11 support we should be able to use native for...of
for (let i = 0; i < files.length; i++) {
for (let i = 0; i < files.length; i += 1) {
let file = files[i];
let result = validate(file);
if (result === true) {
@ -174,7 +174,7 @@ export default Component.extend({
// NOTE: for...of loop results in a transpilation that errors in Edge,
// once we drop IE11 support we should be able to use native for...of
for (let i = 0; i < files.length; i++) {
for (let i = 0; i < files.length; i += 1) {
let file = files[i];
let tracker = new UploadTracker({file});
@ -233,7 +233,6 @@ export default Component.extend({
this.onUploadSuccess(result);
return true;
} catch (error) {
// grab custom error message if present
let message = error.payload.errors && error.payload.errors[0].message;
@ -266,14 +265,8 @@ export default Component.extend({
// computation but that hypothesis needs testing
_updateProgress() {
let trackers = this._uploadTrackers;
let totalSize = trackers.reduce((total, tracker) => {
return total + tracker.get('total');
}, 0);
let uploadedSize = trackers.reduce((total, tracker) => {
return total + tracker.get('loaded');
}, 0);
let totalSize = trackers.reduce((total, tracker) => total + tracker.get('total'), 0);
let uploadedSize = trackers.reduce((total, tracker) => total + tracker.get('loaded'), 0);
this.set('totalSize', totalSize);
this.set('uploadedSize', uploadedSize);

View File

@ -51,38 +51,34 @@ export default ModalComponent.extend(ValidationEngine, {
// TODO: either the validator should check the email's existence or
// the API should return an appropriate error when attempting to save
return new Promise((resolve, reject) => {
return this._super().then(() => {
return RSVP.hash({
users: this.get('store').findAll('user', {reload: true}),
invites: this.get('store').findAll('invite', {reload: true})
}).then((data) => {
let existingUser = data.users.findBy('email', email);
let existingInvite = data.invites.findBy('email', email);
return new Promise((resolve, reject) => this._super().then(() => RSVP.hash({
users: this.get('store').findAll('user', {reload: true}),
invites: this.get('store').findAll('invite', {reload: true})
}).then((data) => {
let existingUser = data.users.findBy('email', email);
let existingInvite = data.invites.findBy('email', email);
if (existingUser || existingInvite) {
this.get('errors').clear('email');
if (existingUser) {
this.get('errors').add('email', 'A user with that email address already exists.');
} else {
this.get('errors').add('email', 'A user with that email address was already invited.');
}
if (existingUser || existingInvite) {
this.get('errors').clear('email');
if (existingUser) {
this.get('errors').add('email', 'A user with that email address already exists.');
} else {
this.get('errors').add('email', 'A user with that email address was already invited.');
}
// TODO: this shouldn't be needed, ValidationEngine doesn't mark
// properties as validated when validating an entire object
this.get('hasValidated').addObject('email');
reject();
} else {
resolve();
}
});
}, () => {
// TODO: this shouldn't be needed, ValidationEngine doesn't mark
// properties as validated when validating an entire object
this.get('hasValidated').addObject('email');
reject();
});
});
} else {
resolve();
}
}), () => {
// TODO: this shouldn't be needed, ValidationEngine doesn't mark
// properties as validated when validating an entire object
this.get('hasValidated').addObject('email');
reject();
}));
},
sendInvitation: task(function* () {

View File

@ -43,26 +43,24 @@ export default ModalComponent.extend(ValidationEngine, {
this.set('authenticationError', null);
return this.validate({property: 'signin'}).then(() => {
return this._authenticate().then(() => {
this.get('notifications').closeAlerts();
this.send('closeModal');
return true;
}).catch((error) => {
if (error && error.payload && error.payload.errors) {
error.payload.errors.forEach((err) => {
if (isVersionMismatchError(err)) {
return this.get('notifications').showAPIError(error);
}
err.message = htmlSafe(err.context || err.message);
});
return this.validate({property: 'signin'}).then(() => this._authenticate().then(() => {
this.get('notifications').closeAlerts();
this.send('closeModal');
return true;
}).catch((error) => {
if (error && error.payload && error.payload.errors) {
error.payload.errors.forEach((err) => {
if (isVersionMismatchError(err)) {
return this.get('notifications').showAPIError(error);
}
err.message = htmlSafe(err.context || err.message);
});
this.get('errors').add('password', 'Incorrect password');
this.get('hasValidated').pushObject('password');
this.set('authenticationError', error.payload.errors[0].message);
}
});
}, () => {
this.get('errors').add('password', 'Incorrect password');
this.get('hasValidated').pushObject('password');
this.set('authenticationError', error.payload.errors[0].message);
}
}), () => {
this.get('hasValidated').pushObject('password');
return false;
});

View File

@ -139,7 +139,7 @@ export default ModalComponent.extend({
// to have a proper grouping of fatal errors and none fatal, we need to check
// our errors for the fatal property
if (errors && errors.length > 0) {
for (let i = 0; i < errors.length; i++) {
for (let i = 0; i < errors.length; i += 1) {
if (errors[i].fatal) {
fatalErrors.push(errors[i]);
} else {

View File

@ -69,9 +69,7 @@ export default Controller.extend({
}),
availableTags: computed('_availableTags.[]', function () {
let tags = this.get('_availableTags').filter((tag) => {
return tag.get('id') !== null;
});
let tags = this.get('_availableTags').filter(tag => tag.get('id') !== null);
let options = tags.toArray();
options.unshiftObject({name: 'All tags', slug: null});

View File

@ -203,7 +203,7 @@ export default Controller.extend({
// to have a proper grouping of fatal errors and none fatal, we need to check
// our errors for the fatal property
if (errors.length > 0) {
for (let i = 0; i < errors.length; i++) {
for (let i = 0; i < errors.length; i += 1) {
if (errors[i].fatal) {
fatalErrors.push(errors[i]);
} else {

View File

@ -87,7 +87,6 @@ export default Controller.extend({
this.send('collectTitleTokens', []);
return model;
} catch (error) {
if (error) {
notifications.showAPIError(error, {key: 'settings.save'});
@ -223,7 +222,6 @@ export default Controller.extend({
run.schedule('afterRender', this, function () {
this.set('model.facebook', newUrl);
});
} catch (e) {
if (e === 'invalid url') {
errMessage = 'The URL must be in a format like '
@ -233,7 +231,6 @@ export default Controller.extend({
}
throw e;
} finally {
this.get('model.hasValidated').pushObject('facebook');
}

View File

@ -15,7 +15,7 @@ import {task, timeout} from 'ember-concurrency';
const {Promise} = RSVP;
const IMPORT_MIME_TYPES = [
const IMPORT_MIME_TYPES = [
'application/json',
'application/zip',
'application/x-zip-compressed'
@ -98,7 +98,6 @@ export default Controller.extend({
yield this.get('ajax').post(emailUrl);
notifications.showAlert('Check your email for the test message.', {type: 'info', key: 'test-email.send.success'});
return true;
} catch (error) {
notifications.showAPIError(error, {key: 'test-email:send'});
}

View File

@ -48,9 +48,7 @@ export default Controller.extend({
invalidUsersArray: computed('usersArray', 'ownerEmail', function () {
let ownerEmail = this.get('ownerEmail');
return this.get('usersArray').reject((user) => {
return validator.isEmail(user) || user === ownerEmail;
});
return this.get('usersArray').reject(user => validator.isEmail(user) || user === ownerEmail);
}),
validationResult: computed('invalidUsersArray', function () {
@ -131,9 +129,7 @@ export default Controller.extend({
}),
authorRole: computed(function () {
return this.store.findAll('role', {reload: true}).then((roles) => {
return roles.findBy('name', 'Author');
});
return this.store.findAll('role', {reload: true}).then(roles => roles.findBy('name', 'Author'));
}),
_transitionAfterSubmission() {
@ -162,7 +158,6 @@ export default Controller.extend({
this.send('loadServerNotifications');
this._transitionAfterSubmission();
});
} else if (users.length === 0) {
this.get('errors').add('users', 'No users to invite');
}
@ -183,18 +178,14 @@ export default Controller.extend({
role: authorRole
});
return invite.save().then(() => {
return {
email: user,
success: invite.get('status') === 'sent'
};
}).catch((error) => {
return {
error,
email: user,
success: false
};
});
return invite.save().then(() => ({
email: user,
success: invite.get('status') === 'sent'
})).catch(error => ({
error,
email: user,
success: false
}));
})
);
},
@ -207,7 +198,7 @@ export default Controller.extend({
invites.forEach((invite) => {
if (invite.success) {
successCount++;
successCount += 1;
} else if (isInvalidError(invite.error)) {
message = `${invite.email} was invalid: ${invite.error.payload.errors[0].message}`;
notifications.showAlert(message, {type: 'error', delayed: true, key: `signup.send-invitations.${invite.email}`});
@ -220,7 +211,7 @@ export default Controller.extend({
invitationsString = erroredEmails.length > 1 ? ' invitations: ' : ' invitation: ';
message = `Failed to send ${erroredEmails.length} ${invitationsString}`;
message += erroredEmails.join(', ');
message += ". Please check your email configuration, see <a href='https://docs.ghost.org/v1.0.0/docs/mail-config' target='_blank'>https://docs.ghost.org/v1.0.0/docs/mail-config</a> for instructions";
message += '. Please check your email configuration, see <a href=\'https://docs.ghost.org/v1.0.0/docs/mail-config\' target=\'_blank\'>https://docs.ghost.org/v1.0.0/docs/mail-config</a> for instructions';
message = htmlSafe(message);
notifications.showAlert(message, {type: 'error', delayed: successCount > 0, key: 'signup.send-invitations.failed'});

View File

@ -42,7 +42,6 @@ export default Controller.extend(ValidationEngine, {
this.get('errors').remove('session');
return authResult;
} catch (error) {
if (error && error.payload && error.payload.errors) {
if (isVersionMismatchError(error)) {
@ -158,26 +157,21 @@ export default Controller.extend(ValidationEngine, {
},
_afterAuthentication(result) {
let promises = [];
promises.pushObject(this.get('settings').fetch());
promises.pushObject(this.get('config').fetchPrivate());
// fetch settings and private config for synchronous access before transitioning
let fetchSettingsAndConfig = RSVP.all([
this.get('settings').fetch(),
this.get('config').fetchPrivate()
]);
if (this.get('profileImage')) {
return this._sendImage(result.users[0])
.then(() => {
// fetch settings and private config for synchronous access before transitioning
return RSVP.all(promises).then(() => {
return this.transitionToRoute('setup.three');
});
}).catch((resp) => {
.then(() => (fetchSettingsAndConfig))
.then(() => (this.transitionToRoute('setup.three')))
.catch((resp) => {
this.get('notifications').showAPIError(resp, {key: 'setup.blog-details'});
});
} else {
// fetch settings and private config for synchronous access before transitioning
return RSVP.all(promises).then(() => {
return this.transitionToRoute('setup.three');
});
return fetchSettingsAndConfig.then(() => this.transitionToRoute('setup.three'));
}
},

View File

@ -43,7 +43,6 @@ export default Controller.extend(ValidationEngine, {
yield RSVP.all(promises);
return authResult;
} catch (error) {
if (isVersionMismatchError(error)) {
return this.get('notifications').showAPIError(error);
@ -86,7 +85,6 @@ export default Controller.extend(ValidationEngine, {
yield this.validate({property: 'signin'});
return yield this.get('authenticate')
.perform(authStrategy, [model.get('identification'), model.get('password')]);
} catch (error) {
this.set('flowErrors', 'Please fill out the form to sign in.');
}
@ -109,7 +107,6 @@ export default Controller.extend(ValidationEngine, {
{type: 'info', key: 'forgot-password.send.success'}
);
return true;
} catch (error) {
// ValidationEngine throws "undefined" for failed validation
if (!error) {

View File

@ -36,7 +36,6 @@ export default Controller.extend(ValidationEngine, {
yield RSVP.all(promises);
return authResult;
} catch (error) {
if (error && error.payload && error.payload.errors) {
// we don't get back an ember-data/ember-ajax error object
@ -81,11 +80,10 @@ export default Controller.extend(ValidationEngine, {
try {
yield this._authenticateWithPassword();
yield this._sendImage();
yield this.get('_sendImage').perform();
} catch (error) {
notifications.showAPIError(error, {key: 'signup.complete'});
}
} catch (error) {
// ValidationEngine throws undefined
if (!error) {
@ -128,7 +126,7 @@ export default Controller.extend(ValidationEngine, {
.authenticate('authenticator:oauth2', email, password);
},
_sendImage() {
_sendImage: task(function* () {
let formData = new FormData();
let imageFile = this.get('profileImage');
let uploadUrl = this.get('ghostPaths.url').api('uploads');
@ -136,27 +134,26 @@ export default Controller.extend(ValidationEngine, {
if (imageFile) {
formData.append('uploadimage', imageFile, imageFile.name);
return this.get('session.user').then((user) => {
return this.get('ajax').post(uploadUrl, {
data: formData,
processData: false,
contentType: false,
dataType: 'text'
}).then((response) => {
let imageUrl = JSON.parse(response);
let usersUrl = this.get('ghostPaths.url').api('users', user.id.toString());
// eslint-disable-next-line
user.profile_image = imageUrl;
let user = yield this.get('session.user');
let response = yield this.get('ajax').post(uploadUrl, {
data: formData,
processData: false,
contentType: false,
dataType: 'text'
});
return this.get('ajax').put(usersUrl, {
data: {
users: [user]
}
});
});
let imageUrl = JSON.parse(response);
let usersUrl = this.get('ghostPaths.url').api('users', user.id.toString());
user.profile_image = imageUrl;
return yield this.get('ajax').put(usersUrl, {
data: {
users: [user]
}
});
}
},
}),
actions: {
signup() {

View File

@ -283,7 +283,6 @@ export default Controller.extend({
run.schedule('afterRender', this, function () {
this.set('user.facebook', newUrl);
});
} catch (e) {
if (e === 'invalid url') {
errMessage = 'The URL must be in a format like '
@ -293,7 +292,6 @@ export default Controller.extend({
}
throw e;
} finally {
this.get('user.hasValidated').pushObject('facebook');
}

View File

@ -7,7 +7,7 @@ import setupSessionService from 'ember-simple-auth/initializers/setup-session-se
export default {
name: 'ember-simple-auth',
initialize(registry) {
let config = ENV['ember-simple-auth'] || {};
let config = ENV['ember-simple-auth'] || {};
config.baseURL = ghostPaths().adminRoot;
Configuration.load(config);

View File

@ -30,9 +30,7 @@ export default Mixin.create({
return;
}
this._clickHandler = (event) => {
return this.bodyClick(event);
};
this._clickHandler = event => this.bodyClick(event);
return $(this.get('bodyElementSelector')).on('click', this._clickHandler);
},

View File

@ -58,7 +58,9 @@ export default Mixin.create({
init() {
this._super(...arguments);
window.onbeforeunload = () => {
return this.get('hasDirtyAttributes') ? this.unloadDirtyMessage() : null;
if (this.get('hasDirtyAttributes')) {
return this.unloadDirtyMessage();
}
};
},
@ -192,7 +194,6 @@ export default Mixin.create({
}
return model;
} catch (error) {
// re-throw if we have a general server error
if (error && !isInvalidError(error)) {

View File

@ -31,7 +31,7 @@ Router.map(function () {
this.route('reset', {path: '/reset/:token'});
this.route('about', {path: '/about'});
this.route('posts', {path: '/'}, function() {});
this.route('posts', {path: '/'}, function () {});
this.route('editor', function () {
this.route('new', {path: ''});

View File

@ -5,11 +5,11 @@ export default AuthenticatedRoute.extend(base, {
titleToken: 'Editor',
model() {
return this.get('session.user').then((user) => {
return this.store.createRecord('post', {
return this.get('session.user').then(user => (
this.store.createRecord('post', {
author: user
});
});
})
));
},
renderTemplate(controller, model) {

View File

@ -33,9 +33,7 @@ export default AuthenticatedRoute.extend(CurrentUserSettings, ShortcutsRoute, {
// pausing to show the loading spinner if no tags have been loaded yet
model() {
let promise = this.store.query('tag', {limit: 'all', include: 'count.posts'});
let filter = this.store.filter('tag', (tag) => {
return !tag.get('isNew');
});
let filter = this.store.filter('tag', tag => !tag.get('isNew'));
if (this.store.peekAll('tag').get('length') === 0) {
return promise.then(() => filter);

View File

@ -30,11 +30,8 @@ export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, Infinit
// authors do not have permission to hit the invites or suspended users endpoint
if (!user.get('isAuthor')) {
modelPromises.invites = this.store.query('invite', {limit: 'all'}).then(() => {
return this.store.filter('invite', (invite) => {
return !invite.get('isNew');
});
});
modelPromises.invites = this.store.query('invite', {limit: 'all'})
.then(() => this.store.filter('invite', invite => !invite.get('isNew')));
// fetch suspended users separately so that infinite scroll still works
modelPromises.suspendedUsers = this.store.query('user', {limit: 'all', filter: 'status:inactive'});
@ -42,9 +39,7 @@ export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, Infinit
// we need to load the roles into ember cache
// invites return role_id only and we do not offer a /role/:id endpoint
modelPromises.roles = this.get('store').query('role', {}).then((roles) => {
return roles;
});
modelPromises.roles = this.get('store').query('role', {});
return RSVP.hash(modelPromises);
});

View File

@ -161,9 +161,7 @@ let ajaxService = AjaxService.extend({
// huge deal because the session will be invalidated and app reloaded
// but it would be nice to be consistent
if (isAuthenticated && isGhostRequest && !isTokenRequest && isTokenExpired) {
return this.get('session').restore().then(() => {
return this._makeRequest(hash);
});
return this.get('session').restore().then(() => this._makeRequest(hash));
}
return this._super(...arguments);
@ -202,7 +200,7 @@ let ajaxService = AjaxService.extend({
errors = [errors];
}
payload.errors = errors.map(function(error) {
payload.errors = errors.map(function (error) {
if (typeof error === 'string') {
return {message: error};
} else {

View File

@ -10,7 +10,7 @@ const ONE_SECOND = 1000;
export default Service.extend({
second: null,
minute: null,
hour: null,
hour: null,
init() {
this.tick();
@ -22,7 +22,7 @@ export default Service.extend({
this.setProperties({
second: now.seconds(),
minute: now.minutes(),
hour: now.hours()
hour: now.hours()
});
if (!Ember.testing) { // eslint-disable-line
@ -30,7 +30,6 @@ export default Service.extend({
this.tick();
}, ONE_SECOND);
}
}
});

View File

@ -86,7 +86,6 @@ export default Service.extend({
// return the labs key value that we get from the server
this.notifyPropertyChange(serviceProperty);
return this.get(`${serviceProperty}.${key}`);
}).catch((error) => {
model.rollbackAttributes();
this.notifyPropertyChange(serviceProperty);

View File

@ -20,9 +20,7 @@ export default SessionService.extend({
this.get('tour').fetchViewed()
];
return RSVP.all(preloadPromises).then(() => {
return authResult;
});
return RSVP.all(preloadPromises).then(() => authResult);
});
}
});

View File

@ -72,9 +72,7 @@ export default Service.extend(Evented, {
let viewed = this.get('viewed');
let throbbers = this.get('throbbers');
return throbbers.reject((throbber) => {
return viewed.includes(throbber.id);
});
return throbbers.reject(throbber => viewed.includes(throbber.id));
}),
// retrieve the IDs of the viewed throbbers from the server, always returns

View File

@ -115,7 +115,7 @@ export default Service.extend({
_addPhotosFromResponse(response) {
let photos = response.results || response;
photos.forEach((photo) => this._addPhoto(photo));
photos.forEach(photo => this._addPhoto(photo));
},
_addPhoto(photo) {
@ -150,7 +150,7 @@ export default Service.extend({
let columnHeights = [];
// pre-fill column arrays based on columnCount
for (let i = 0; i < this.get('columnCount'); i++) {
for (let i = 0; i < this.get('columnCount'); i += 1) {
columns[i] = [];
columnHeights[i] = 0;
}
@ -184,10 +184,10 @@ export default Service.extend({
headers['X-Unsplash-Cache'] = true;
return fetch(url, {headers})
.then((response) => this._checkStatus(response))
.then((response) => this._extractPagination(response))
.then((response) => response.json())
.then((response) => this._addPhotosFromResponse(response))
.then(response => this._checkStatus(response))
.then(response => this._extractPagination(response))
.then(response => response.json())
.then(response => this._addPhotosFromResponse(response))
.catch(() => {
// if the error text isn't already set then we've get a connection error from `fetch`
if (!options.ignoreErrors && !this.get('error')) {
@ -206,9 +206,7 @@ export default Service.extend({
let responseTextPromise = resolve();
if (response.headers.map['content-type'] === 'application/json') {
responseTextPromise = response.json().then((json) => {
return json.errors[0];
});
responseTextPromise = response.json().then(json => json.errors[0]);
} else if (response.headers.map['content-type'] === 'text/xml') {
responseTextPromise = response.text();
}

View File

@ -12,9 +12,7 @@ export default Transform.extend({
settingsArray = [];
}
navItems = settingsArray.map((itemDetails) => {
return NavigationItem.create(itemDetails);
});
navItems = settingsArray.map(itemDetails => NavigationItem.create(itemDetails));
return emberA(navItems);
},

View File

@ -12,9 +12,7 @@ export default Transform.extend({
settingsArray = [];
}
slackObj = settingsArray.map((itemDetails) => {
return SlackObject.create(itemDetails);
});
slackObj = settingsArray.map(itemDetails => SlackObject.create(itemDetails));
return emberA(slackObj);
},

View File

@ -8,7 +8,7 @@ import markdownitMark from 'npm:markdown-it-mark';
let slugify = function slugify(inputString, usedHeaders) {
let slug = inputString.replace(/[^\w]/g, '').toLowerCase();
if (usedHeaders[slug]) {
usedHeaders[slug]++;
usedHeaders[slug] += 1;
slug += usedHeaders[slug];
}
return slug;

View File

@ -2,7 +2,7 @@
export default function () {
let word = generatePassword(6);
let randomN = Math.floor(Math.random() * 1000);
let randomN = Math.floor(Math.random() * 1000);
return word + randomN;
}

View File

@ -61,7 +61,7 @@ codemirrorAssets = function () {
// put the files in vendor ready for importing into the test-support file
if (environment === 'development') {
config.vendor = codemirrorFiles;
config.vendor = codemirrorFiles;
}
return config;
@ -120,7 +120,7 @@ module.exports = function (defaults) {
}
},
vendor: {
js: assetLocation('vendor.js'),
js: assetLocation('vendor.js'),
css: assetLocation('vendor.css')
}
},
@ -152,7 +152,7 @@ module.exports = function (defaults) {
'password-generator': {
import: ['lib/password-generator.js']
},
'simplemde': {
simplemde: {
srcDir: 'debug',
import: ['simplemde.js', 'simplemde.css']
}

View File

@ -27,7 +27,7 @@ export default Component.extend({
altText: '',
saveButton: true,
accept: 'image/gif,image/jpg,image/jpeg,image/png,image/svg+xml',
extensions: ['gif', 'jpg', 'jpeg', 'png', 'svg'],
extensions: null,
validate: null,
dragClass: null,
@ -39,6 +39,11 @@ export default Component.extend({
ajax: service(),
notifications: service(),
init() {
this._super(...arguments);
this.extensions = ['gif', 'jpg', 'jpeg', 'png', 'svg'];
},
// TODO: this wouldn't be necessary if the server could accept direct
// file uploads
formData: computed('file', function () {
@ -75,7 +80,6 @@ export default Component.extend({
} else if (image.file) {
this.send('fileSelected', image.file);
delete image.file;
}
},
@ -186,8 +190,8 @@ export default Component.extend({
// TODO: remove console.logs
/* eslint-disable no-console */
xhr.addEventListener('error', (event) => console.log('error', event));
xhr.upload.addEventListener('error', (event) => console.log('errorupload', event));
xhr.addEventListener('error', event => console.log('error', event));
xhr.upload.addEventListener('error', event => console.log('errorupload', event));
/* eslint-enabled no-console */
return xhr;

View File

@ -20,10 +20,10 @@ import {inject as service} from '@ember/service';
export default Component.extend({
layout,
accept: 'image/gif,image/jpg,image/jpeg,image/png,image/svg+xml',
extensions: ['gif', 'jpg', 'jpeg', 'png', 'svg'],
extensions: null,
ajax: service(),
preview: computed('value', function() {
preview: computed('value', function () {
return formatMarkdown([this.get('payload').markdown]);
}),
@ -38,6 +38,7 @@ export default Component.extend({
init() {
this._super(...arguments);
this.extensions = ['gif', 'jpg', 'jpeg', 'png', 'svg'];
this.set('value', this.get('payload').markdown);
},
@ -83,7 +84,11 @@ export default Component.extend({
let el = this.$('textarea')[0]; // array destructuring on jquery causes ember to throw an error about calling an Object as a Function
el.value = el.value.replace(placeholderText, imageText);
this.sendAction('updateValue');
let action = this.get('updateValue');
if (action) {
action();
}
},
_validate(file) {
@ -159,8 +164,8 @@ export default Component.extend({
// TODO: remove console.logs
/* eslint-disable no-console */
xhr.addEventListener('error', (event) => console.log('error', event));
xhr.upload.addEventListener('error', (event) => console.log('errorupload', event));
xhr.addEventListener('error', event => console.log('error', event));
xhr.upload.addEventListener('error', event => console.log('errorupload', event));
/* eslint-enabled no-console */
return xhr;

View File

@ -43,7 +43,7 @@ export default Component.extend({
cards: null,
atoms: null,
serializeVersion: MOBILEDOC_VERSION,
options: {},
options: null,
// exposed properties
editor: null,
@ -61,7 +61,7 @@ export default Component.extend({
// merge in named options with the `options` property data-bag
editorOptions: computed(function () {
let options = this.get('options');
let options = this.get('options') || {};
let cards = this.get('cards') || [];
let atoms = this.get('atoms') || [];
@ -69,7 +69,7 @@ export default Component.extend({
// with Ghost specific functionality
// TODO: this also sets the emberCards property - do we need that indirection?
let createCard = createCardFactory.apply(this, {}); // need to pass the toolbar
cards = defaultCards.concat(cards).map((card) => createCard(card));
cards = defaultCards.concat(cards).map(card => createCard(card));
// add our default atoms
atoms.concat([{
@ -206,17 +206,13 @@ export default Component.extend({
// events in the cards.
// TODO: is there a better way to handle this?
if (!document.onkeydown) {
document.onkeydown = (event) => {
// if any of the keydown handlers return false then we return false
// therefore stopping the event from propogating.
return this._keyDownHandler.reduce((returnType, handler) => {
let result = handler(event);
if (returnType !== false) {
return result;
}
return returnType;
}, true);
};
document.onkeydown = event => this._keyDownHandler.reduce((returnType, handler) => {
let result = handler(event);
if (returnType !== false) {
return result;
}
return returnType;
}, true);
}
let editor = this.get('editor');
@ -309,15 +305,25 @@ export default Component.extend({
}
});
}
this.sendAction('wordcountDidChange', wordcount);
let action = this.get('wordcountDidChange');
if (action) {
action(wordcount);
}
},
_willCreateEditor() {
this.sendAction('willCreateEditor');
let action = this.get('willCreateEditor');
if (action) {
action();
}
},
_didCreateEditor(editor) {
this.sendAction('didCreateEditor', editor);
let action = this.get('didCreateEditor');
if (action) {
action(editor);
}
},
willDestroyElement() {
@ -331,14 +337,23 @@ export default Component.extend({
// store a cache of the local doc so that we don't need to reinitialise it.
let serializeVersion = this.get('serializeVersion');
let updatedMobiledoc = editor.serialize(serializeVersion);
let onChangeAction = this.get('onChange');
let onFirstChangeAction = this.get('onFirstChange');
this._localMobiledoc = updatedMobiledoc;
this.sendAction('onChange', updatedMobiledoc);
if (onChangeAction) {
onChangeAction(updatedMobiledoc);
}
// we need to trigger a first-change action so that we can trigger a
// save and transition from new-> edit
if (this._localMobiledoc !== BLANK_DOC && !this._hasChanged) {
this._hasChanged = true;
this.sendAction('onFirstChange', this._localMobiledoc);
if (onFirstChangeAction) {
onFirstChangeAction(this._localMobiledoc);
}
}
this.processWordcount();
@ -360,7 +375,7 @@ export default Component.extend({
throw new Error('A selection must include a cardId');
}
let card = this.get('emberCards').find((card) => card.id === cardId);
let card = this.get('emberCards').find(card => card.id === cardId);
let cardHolder = $(`#${cardId}`).parent('.kg-card');
let selectedCard = this.get('selectedCard');
if (selectedCard && selectedCard !== card) {
@ -397,7 +412,7 @@ export default Component.extend({
return;
}
let card = this.get('emberCards').find((card) => card.id === cardId);
let card = this.get('emberCards').find(card => card.id === cardId);
let cardHolder = $(`#${cardId}`).parents('.kg-card');
let selectedCard = this.get('selectedCard');
if (selectedCard && selectedCard !== card) {
@ -476,7 +491,6 @@ export default Component.extend({
postEditor.insertSectionAtEnd(newSection);
postEditor.setRange(newSection.toRange());
});
}
this.send('deselectCard');
});
@ -510,14 +524,14 @@ export default Component.extend({
},
editCard(cardId) {
let card = this.get('emberCards').find((card) => card.id === cardId);
let card = this.get('emberCards').find(card => card.id === cardId);
this.set('editedCard', card);
this.send('selectCard', cardId);
},
deleteCard(cardId, forwards = false) {
let editor = this.get('editor');
let card = this.get('emberCards').find((card) => card.id === cardId);
let card = this.get('emberCards').find(card => card.id === cardId);
getCardFromDoc(cardId, editor).then(function (section) {
let range;
@ -556,7 +570,7 @@ export default Component.extend({
dropImage(event) {
if (event.dataTransfer.files.length) {
event.preventDefault();
for (let i = 0; i < event.dataTransfer.files.length; i++) {
for (let i = 0; i < event.dataTransfer.files.length; i += 1) {
let file = [event.dataTransfer.files[i]];
this.editor.insertCard('card-image', {pos: 'top', file});
}

View File

@ -60,7 +60,6 @@ export default Component.extend({
this.send('selectCardHard');
}
});
}
);
},
@ -79,12 +78,20 @@ export default Component.extend({
},
selectCard() {
this.sendAction('selectCard', this.card.id);
let action = this.get('selectCard');
if (action) {
action(this.card.id);
}
},
deselectCard() {
this.sendAction('deselectCard', this.card.id);
let action = this.get('deselectCard');
if (action) {
action(this.card.id);
}
this.send('stopEdit');
if (this.get('isNew')) {
let mobiledocCard = this.$().parents('.kg-card');
mobiledocCard.removeClass('new');
@ -93,20 +100,32 @@ export default Component.extend({
},
selectCardHard() {
this.sendAction('selectCardHard', this.card.id);
let action = this.get('selectCardHard');
if (action) {
action(this.card.id);
}
},
delete() {
this.sendAction('deleteCard', this.card.id);
let action = this.get('deleteCard');
if (action) {
action(this.card.id);
}
},
startEdit() {
this.sendAction('edit', this.card.id);
let action = this.get('edit');
if (action) {
action(this.card.id);
}
},
stopEdit() {
this.send('save');
this.sendAction('stopEdit', this.card.id);
let action = this.get('stopEdit');
if (action) {
action(this.card.id);
}
}
}
});

View File

@ -19,7 +19,11 @@ export default Component.extend({
editor.range = Range.create(section, startOffset, section, endOffset);
this.sendAction('clicked');
let action = this.get('clicked');
if (action) {
action();
}
this.get('tool').onClick(editor, section);
}
});

View File

@ -42,10 +42,13 @@ export default Component.extend({
};
tools.push(t);
i++;
i += 1;
}
});
this.set('toolsLength', i);
// TODO: this needs to go away because side effects should not be introduced in CPs
this.set('toolsLength', i); // eslint-disable-line
tools.sort((a, b) => a.order > b.order);
if (selected > -1) {
let selectedTool = tools[selected] || tools[0];
@ -78,7 +81,6 @@ export default Component.extend({
});
editor.cursorDidChange(() => {
if (!editor.range || !editor.range.head.section) {
return;
}
@ -138,7 +140,11 @@ export default Component.extend({
this.$('.gh-cardmenu-search-input').focus();
});
});
this.sendAction('menuIsOpen');
let action = this.get('menuIsOpen');
if (action) {
action();
}
},
closeMenu() {
@ -146,7 +152,11 @@ export default Component.extend({
this.$('.gh-cardmenu').fadeOut('fast', () => {
this.set('isOpen', false);
});
this.sendAction('menuIsClosed');
let action = this.get('menuIsClosed');
if (action) {
action();
}
},
closeMenuKeepButton() {

View File

@ -37,10 +37,13 @@ export default Component.extend({
};
tools.push(t);
i++;
i += 1;
}
});
this.set('toolsLength', i);
// TODO: this needs to go away because side effects should not be introduced in CPs
this.set('toolsLength', i); // eslint-disable-line
tools.sort((a, b) => a.order > b.order);
let selectedTool = tools[selected];
@ -181,7 +184,6 @@ export default Component.extend({
str: 'ENTER',
name: 'slash',
run(postEditor) {
let {range} = postEditor;
range.head.offset = self.get('range').startOffset - 1;
@ -223,14 +225,17 @@ export default Component.extend({
menu.hide().fadeIn('fast');
});
this.sendAction('menuIsOpen');
let action = this.get('menuIsOpen');
if (action) {
action();
}
},
closeMenu() {
let editor = this.get('editor');
// this.get('editor').unregisterKeyCommand('slash'); -- waiting for the next release for this
for (let i = editor._keyCommands.length - 1; i > -1; i--) {
for (let i = editor._keyCommands.length - 1; i > -1; i -= 1) {
let keyCommand = editor._keyCommands[i];
if (keyCommand.name === 'slash') {
editor._keyCommands.splice(i, 1);
@ -240,7 +245,11 @@ export default Component.extend({
this.$('.gh-cardmenu').fadeOut('fast', () => {
this.set('isOpen', false);
});
this.sendAction('menuIsClosed');
let action = this.get('menuIsClosed');
if (action) {
action();
}
},
clickedMenu() {

View File

@ -45,10 +45,18 @@ export default Component.extend({
}
if (this.get('val') !== textContent) {
let onChangeAction = this.get('onChange');
let updateAction = this.get('update');
this.set('_cachedVal', textContent);
this.set('val', textContent);
this.sendAction('onChange', textContent);
this.sendAction('update', textContent);
if (onChangeAction) {
onChangeAction(textContent);
}
if (updateAction) {
updateAction(textContent);
}
}
});
@ -111,7 +119,7 @@ export default Component.extend({
}
let offset = title.offset();
let bottomOfHeading = offset.top + title.height();
let bottomOfHeading = offset.top + title.height();
if (cursorPositionOnScreen.bottom > bottomOfHeading - 13) {
let editor = this.get('editor');
let loc = editor.element.getBoundingClientRect();
@ -203,7 +211,7 @@ export default Component.extend({
let len = title.textContent.length;
let range = document.createRange();
for (let i = len - 1; i > -1; i--) {
for (let i = len - 1; i > -1; i -= 1) {
range.setStart(title, i);
range.setEnd(title, i + 1);
let rect = range.getBoundingClientRect();
@ -213,7 +221,7 @@ export default Component.extend({
if (rect.left <= horizontalOffset && rect.right >= horizontalOffset) {
// if the horizontalOffset is on the left hand side of the
// character then return `i`, if it's on the right return `i + 1`
return i + (horizontalOffset >= (rect.left + rect.right) / 2 ? 1 : 0);
return i + (horizontalOffset >= (rect.left + rect.right) / 2 ? 1 : 0);
}
}
@ -231,7 +239,7 @@ export default Component.extend({
run.next(() => {
if (selection.modify) {
for (let i = 0; i < offset; i++) {
for (let i = 0; i < offset; i += 1) {
selection.modify('move', 'forward', 'character');
}
}

View File

@ -7,7 +7,7 @@ import {computed} from '@ember/object';
export default Component.extend({
layout,
classNames: ['toolbar-block'],
tools: [],
tools: null,
isBlank: false,
toolbar: computed('tools.@each.selected', function () {
@ -22,7 +22,6 @@ export default Component.extend({
postTools.push(tool);
}
}
});
return selectedPostTools.concat(postTools);
@ -42,7 +41,6 @@ export default Component.extend({
let $editor = $(this.get('containerSelector')); // TODO this is part of Ghost-Admin
editor.cursorDidChange(() => {
// if there is no cursor:
if (!editor.range || !editor.range.head.section) {
$this.fadeOut();
@ -66,7 +64,7 @@ export default Component.extend({
this.__state = 'normal';
let offset = this.$(element).position();
let offset = this.$(element).position();
let edOffset = $editor.offset();
$this.css('top', offset.top + $editor.scrollTop() - edOffset.top - 5);
@ -89,7 +87,6 @@ export default Component.extend({
});
this.propertyDidChange('toolbar');
});
},

View File

@ -25,7 +25,7 @@ export default Component.extend({
}),
// returns "primary" or null
visibilityClass: computed('tool.visibility', function() {
visibilityClass: computed('tool.visibility', function () {
return this.get('tool.visibility');
}),
@ -46,6 +46,5 @@ export default Component.extend({
if (this.tool.visibility) {
this.set(this.tool.visibility, true);
}
}
});

View File

@ -50,7 +50,7 @@ export default Component.extend({
this.__state = 'normal';
this.isBlank = true;
let offset = this.$(element).position();
let offset = this.$(element).position();
let edOffset = $editor.offset();
$this.css('top', offset.top + $editor.scrollTop() - edOffset.top - 13);

View File

@ -33,7 +33,7 @@ export default Component.extend({
// internal properties
hasRendered: false,
activeTags: null,
tools: [],
tools: null,
isVisible: false,
tickFullLeft: false,
tickFullRight: false,
@ -222,7 +222,7 @@ export default Component.extend({
doLink(range) {
// if a link is already selected then we remove the links from within the range.
let currentLinks = this.get('activeTags').filter((element) => element.tagName === 'a');
let currentLinks = this.get('activeTags').filter(element => element.tagName === 'a');
if (currentLinks.length) {
this.get('editor').run((postEditor) => {
currentLinks.forEach((link) => {

View File

@ -14,7 +14,7 @@ export default function createCardFactory(toolbar) {
function createCard(cardObject) {
// if we have an array of cards then we convert them one by one.
if (cardObject instanceof Array) {
return cardObject.map((card) => createCard(card));
return cardObject.map(card => createCard(card));
}
// an ember card doesn't need a render or edit method
@ -23,7 +23,6 @@ export default function createCardFactory(toolbar) {
}
cardObject.render = ({env, options, payload: _payload}) => {
// setupUI({env, options, payload});
// TODO: setup non ember UI
@ -41,7 +40,6 @@ export default function createCardFactory(toolbar) {
};
cardObject.edit = ({env, options, payload: _payload}) => {
// setupUI({env, options, payload});
let payload = copy(_payload);
payload.card_name = env.name;

View File

@ -73,10 +73,9 @@ export function getPositionOnScreenFromRange(editor, holder, range) {
// if getBoundingClientRect doesn't work then create it from the client rects
if ((!position || (position.left === 0 && position.top === 0)) && range.getClientRects) {
let rects = range.getClientRects();
for (let i = 0; i < rects.length; i++) {
for (let i = 0; i < rects.length; i += 1) {
let rect = rects[i];
if (position.left === 0 || position.left > rect.left) {
position.left = rect.left;
@ -104,8 +103,8 @@ export function getPositionOnScreenFromRange(editor, holder, range) {
left: position.left - offset.left,
right: position.right - offset.left,
top: position.top - offset.top,
bottom: position.bottom - offset.top,
bottom: position.bottom - offset.top,
width: position.right - position.left,
height: position.bottom - position.top
};
}
}

View File

@ -17,7 +17,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'h1').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'h1').length > 0);
}
},
{
@ -35,7 +35,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'h2').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'h2').length > 0);
}
},
{
@ -51,7 +51,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'h3').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'h3').length > 0);
}
},
{
@ -68,7 +68,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'p').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'p').length > 0);
}
},
{
@ -85,7 +85,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'blockquote').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'blockquote').length > 0);
}
},
{
@ -102,7 +102,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'ul').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'ul').length > 0);
}
},
{
@ -119,7 +119,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'ol').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'ol').length > 0);
}
},
{
@ -154,7 +154,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'em').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'em').length > 0);
}
},
{
@ -170,7 +170,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 's').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 's').length > 0);
}
},
{
@ -185,7 +185,7 @@ export default function (editor, toolbar) {
toolbar.send('doLink', editor.range);
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'a').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'a').length > 0);
}
},
{
@ -214,7 +214,7 @@ export default function (editor, toolbar) {
});
},
checkElements(elements) {
set(this, 'selected', elements.filter((element) => element.tagName === 'sup').length > 0);
set(this, 'selected', elements.filter(element => element.tagName === 'sup').length > 0);
}
},
{

View File

@ -2,7 +2,6 @@
// https://github.com/bustlelabs/mobiledoc-kit#configuring-hot-keys
export default function (editor) {
let softReturnKeyCommand = {
str: 'SHIFT+ENTER',
@ -14,5 +13,4 @@ export default function (editor) {
}
};
editor.registerKeyCommand(softReturnKeyCommand);
}

View File

@ -1,4 +1,3 @@
/* eslint-disable ember-suave/prefer-destructuring, no-unused-vars */
import {
replaceWithHeaderSection,
replaceWithListSection
@ -9,7 +8,6 @@ import {
// https://github.com/bustlelabs/mobiledoc-kit#responding-to-text-input
export default function (editor) {
// We don't want to run all our content rules on every text entry event,
// instead we check to see if this text entry event could match a content
// rule, and only then run the rules. Right now we only want to match
@ -93,7 +91,7 @@ export default function (editor) {
function matchEmStar(editor, text) {
let {range} = editor;
let matches = text.match(/(^|[^\*])\*([^\*].*?)\*$/);
let matches = text.match(/(^|[^*])\*([^*].*?)\*$/);
if (matches) {
let match = matches[0][0] === '*' ? matches[0] : matches[0].substr(1);
range = range.extend(-(match.length));
@ -139,16 +137,17 @@ export default function (editor) {
}
function matchImage(editor, text) {
let {range} = editor;
let matches = text.match(/!\[(.*?)\]\((.*?)\)$/);
if (matches) {
let img = matches[2];
let alt = matches[1];
range = range.extend(-(matches[0].length));
editor.run((postEditor) => {
let card = postEditor.builder.createCardSection('card-image', {pos: 'top', img, alt});
editor.range.extend(-(matches[0].length));
postEditor.replaceSection(editor.range.headSection, card);
if (!editor.range.headSection.next) {
let newSection = editor.builder.createMarkupSection('p');
postEditor.insertSectionAtEnd(newSection);
@ -172,14 +171,16 @@ export default function (editor) {
}
function matchMarkdown(editor, text) {
let {range} = editor;
let matches = text.match(/```([\s\S]*?)```$/);
if (matches) {
let code = matches[0];
range = range.extend(-(matches[0].length));
editor.run((postEditor) => {
let card = postEditor.builder.createCardSection('card-markdown', {pos: 'top', markdown: code});
editor.range.extend(-(matches[0].length));
postEditor.replaceSection(editor.range.headSection, card);
if (!editor.range.headSection.next) {
let newSection = editor.builder.createMarkupSection('p');
postEditor.insertSectionAtEnd(newSection);

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import $ from 'jquery';
import hbs from 'htmlbars-inline-precompile';
import {

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import hbs from 'htmlbars-inline-precompile';
import sinon from 'sinon';
import {

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import {describe, it} from 'mocha';
import {expect} from 'chai';
import {setupComponentTest} from 'ember-mocha';

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import {describe, it} from 'mocha';
import {editorShim} from '../../utils';
import {expect} from 'chai';

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import {describe, it} from 'mocha';
import {expect} from 'chai';
import {setupComponentTest} from 'ember-mocha';
@ -15,7 +14,7 @@ describe('gh-koenig: Unit: Component: koenig-toolbar', function () {
it('contains tools', function () {
let component = this.subject();
// the standard toolbar tools (strong, em, strikethrough, link)
// the standard toolbar tools (strong, em, strikethrough, link)
expect(component.get('toolbar').length).to.be.greaterThan(0);
// extended toolbar block bases tools (h1, h2, quote);
expect(component.get('toolbarBlocks').length).to.be.greaterThan(0);

View File

@ -15,8 +15,8 @@ import mockUsers from './config/users';
export default function () {
// this.urlPrefix = ''; // make this `http://localhost:8080`, for example, if your API is on a different server
this.namespace = '/ghost/api/v0.1'; // make this `api`, for example, if your API is namespaced
this.timing = 400; // delay for each request, automatically set to 0 during testing
this.namespace = '/ghost/api/v0.1'; // make this `api`, for example, if your API is namespaced
this.timing = 400; // delay for each request, automatically set to 0 during testing
// Mock endpoints here to override real API requests during development, eg...
// this.put('/posts/:id/', versionMismatchResponse);
@ -35,7 +35,7 @@ export default function () {
export function testConfig() {
this.passthrough('/write-coverage'); // For code coverage
// this.urlPrefix = ''; // make this `http://localhost:8080`, for example, if your API is on a different server
this.namespace = '/ghost/api/v0.1'; // make this `api`, for example, if your API is namespaced
this.namespace = '/ghost/api/v0.1'; // make this `api`, for example, if your API is namespaced
// this.timing = 400; // delay for each request, automatically set to 0 during testing
// this.logging = true;
@ -66,7 +66,7 @@ export function testConfig() {
let downloadCount = 0;
this.get('https://count.ghost.org/', function () {
downloadCount++;
downloadCount += 1;
return {
count: downloadCount
};

View File

@ -16,7 +16,7 @@ export default function mockThemes(server) {
}
};
themeCount++;
themeCount += 1;
theme = themes.create(theme);

View File

@ -1,18 +1,18 @@
import {Factory, faker} from 'ember-cli-mirage';
export default Factory.extend({
uuid(i) { return `post-${i}`; },
uuid(i) { return `post-${i}`; },
title(i) { return `Post ${i}`; },
description(i) { return `Title for post ${i}.`; },
slug(i) { return `post-${i}`; },
html(i) { return `<p>HTML for post ${i}.</p>`; },
description(i) { return `Title for post ${i}.`; },
slug(i) { return `post-${i}`; },
html(i) { return `<p>HTML for post ${i}.</p>`; },
plaintext(i) { return `Plaintext for post ${i}.`; },
featureImage(i) { return `/content/images/2015/10/post-${i}.jpg`; },
featureImage(i) { return `/content/images/2015/10/post-${i}.jpg`; },
featured: false,
page: false,
status(i) { return faker.list.cycle('draft', 'published', 'scheduled')(i); },
metaDescription(i) { return `Meta description for post ${i}.`; },
metaTitle(i) { return `Meta Title for post ${i}`; },
metaDescription(i) { return `Meta description for post ${i}.`; },
metaTitle(i) { return `Meta Title for post ${i}`; },
authorId: 1,
updatedAt: '2015-10-19T16:25:07.756Z',
updatedBy: 1,

View File

@ -19,7 +19,7 @@
"start": "ember server",
"build": "ember build",
"test": "ember test",
"lint": "ember test --launch phantomjs -f 'ESLint'",
"lint:js": "eslint ./*.js app config lib mirage server tests",
"coverage": "cat ./coverage/lcov.info | coveralls"
},
"engines": {
@ -94,9 +94,7 @@
"ember-truth-helpers": "2.0.0",
"ember-wormhole": "0.5.4",
"emberx-file-input": "1.2.1",
"eslint-plugin-ember": "5.0.3",
"eslint-plugin-ember-suave": "1.0.0",
"eslint-plugin-sort-imports-es6-autofix": "https://github.com/kevinansfield/eslint-plugin-sort-imports-es6-autofix.git#node-4-compat",
"eslint-plugin-ghost": "0.0.21",
"fs-extra": "4.0.3",
"glob": "7.1.2",
"grunt": "1.0.1",

View File

@ -1,3 +1,4 @@
/* eslint-env node */
module.exports = {
env: {
'embertest': true,

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import $ from 'jquery';
import OAuth2Authenticator from 'ghost-admin/authenticators/oauth2';
import destroyApp from '../helpers/destroy-app';
@ -132,13 +131,11 @@ describe('Acceptance: Authentication', function () {
it('invalidates session on 401 API response', async function () {
// return a 401 when attempting to retrieve users
server.get('/users/', () => {
return new Response(401, {}, {
errors: [
{message: 'Access denied.', errorType: 'UnauthorizedError'}
]
});
});
server.get('/users/', () => new Response(401, {}, {
errors: [
{message: 'Access denied.', errorType: 'UnauthorizedError'}
]
}));
await authenticateSession(application);
await visit('/team');
@ -242,9 +239,7 @@ describe('Acceptance: Authentication', function () {
let role = server.create('role', {name: 'Administrator'});
server.create('user', {roles: [role]});
server.post('/uploads', (schema, request) => {
return request;
});
server.post('/uploads', (schema, request) => request);
/* eslint-disable camelcase */
authenticateSession(application, {
@ -257,7 +252,7 @@ describe('Acceptance: Authentication', function () {
// necessary to visit a page to fully boot the app in testing
await visit('/');
/* eslint-disable ember/jquery-ember-run */
/* eslint-disable ghost/ember/jquery-ember-run */
await $.ajax({
type: 'POST',
url: `${Ghost.apiRoot}/uploads/`,
@ -270,6 +265,6 @@ describe('Acceptance: Authentication', function () {
}).always(() => {
done();
});
/* eslint-enable ember/jquery-ember-run */
/* eslint-enable ghost/ember/jquery-ember-run */
});
});

View File

@ -7,14 +7,14 @@ import {
} from 'ghost-admin/tests/helpers/ember-simple-auth';
import {expect} from 'chai';
describe('Acceptance: Content', function() {
describe('Acceptance: Content', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});
@ -37,9 +37,9 @@ describe('Acceptance: Content', function() {
publishedPost = server.create('post', {authorId: admin.id, status: 'published', title: 'Published Post'});
scheduledPost = server.create('post', {authorId: admin.id, status: 'scheduled', title: 'Scheduled Post'});
draftPost = server.create('post', {authorId: admin.id, status: 'draft', title: 'Draft Post'});
draftPost = server.create('post', {authorId: admin.id, status: 'draft', title: 'Draft Post'});
publishedPage = server.create('post', {authorId: admin.id, status: 'published', page: true, title: 'Published Page'});
authorPost = server.create('post', {authorId: editor.id, status: 'published', title: 'Editor Published Post'});
authorPost = server.create('post', {authorId: editor.id, status: 'published', title: 'Editor Published Post'});
return authenticateSession(application);
});

View File

@ -9,10 +9,10 @@ import {expect} from 'chai';
// keyCodes
const KEY_S = 83;
describe('Acceptance: Custom Post Templates', function() {
describe('Acceptance: Custom Post Templates', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
server.loadFixtures('settings');
@ -23,7 +23,7 @@ describe('Acceptance: Custom Post Templates', function() {
authenticateSession(application);
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import Mirage from 'ember-cli-mirage';
import destroyApp from '../helpers/destroy-app';
import moment from 'moment';
@ -8,14 +7,14 @@ import {afterEach, beforeEach, describe, it} from 'mocha';
import {authenticateSession, invalidateSession} from 'ghost-admin/tests/helpers/ember-simple-auth';
import {expect} from 'chai';
describe('Acceptance: Editor', function() {
describe('Acceptance: Editor', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import Mirage from 'ember-cli-mirage';
import destroyApp from '../helpers/destroy-app';
import startApp from '../helpers/start-app';
@ -15,14 +14,14 @@ let htmlErrorResponse = function () {
);
};
describe('Acceptance: Error Handling', function() {
describe('Acceptance: Error Handling', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import destroyApp from '../helpers/destroy-app';
import startApp from '../helpers/start-app';
import {afterEach, beforeEach, describe, it} from 'mocha';
@ -28,30 +27,30 @@ const restoreUserAgent = function () {
setUserAgent(originalAgent);
};
describe('Acceptance: Ghost Desktop', function() {
describe('Acceptance: Ghost Desktop', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});
describe('update alerts for broken versions', function () {
beforeEach(function() {
beforeEach(function () {
let role = server.create('role', {name: 'Administrator'});
server.create('user', {roles: [role]});
return authenticateSession(application);
});
afterEach(function() {
afterEach(function () {
restoreUserAgent();
});
it('displays alert for broken version', async function() {
it('displays alert for broken version', async function () {
setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ghost-desktop/0.4.0 Chrome/51.0.2704.84 Electron/1.2.2 Safari/537.36');
await visit('/');

View File

@ -1,17 +1,16 @@
/* jshint expr:true */
import destroyApp from '../helpers/destroy-app';
import startApp from '../helpers/start-app';
import {afterEach, beforeEach, describe, it} from 'mocha';
import {expect} from 'chai';
describe('Acceptance: Password Reset', function() {
describe('Acceptance: Password Reset', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import destroyApp from '../../helpers/destroy-app';
import startApp from '../../helpers/start-app';
@ -14,11 +13,11 @@ import {expect} from 'chai';
describe('Acceptance: Settings - Apps - AMP', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});
@ -112,7 +111,7 @@ describe('Acceptance: Settings - Apps - AMP', function () {
expect(find('.fullscreen-modal').length, 'modal exists').to.equal(1);
// Leave without saving
await(click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
await (click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
expect(currentURL(), 'currentURL').to.equal('/team');

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import destroyApp from '../../helpers/destroy-app';
import startApp from '../../helpers/start-app';
import {

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import $ from 'jquery';
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import destroyApp from '../../helpers/destroy-app';
@ -12,14 +11,14 @@ import {
import {authenticateSession, invalidateSession} from 'ghost-admin/tests/helpers/ember-simple-auth';
import {expect} from 'chai';
describe('Acceptance: Settings - Code-Injection', function() {
describe('Acceptance: Settings - Code-Injection', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
/* eslint-disable camelcase */
import Mirage from 'ember-cli-mirage';
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
@ -120,7 +119,7 @@ describe('Acceptance: Settings - Design', function () {
expect(find('.fullscreen-modal').length, 'modal exists').to.equal(1);
// Leave without saving
await(click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
await (click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
expect(currentURL(), 'currentURL').to.equal('/settings/code-injection');

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import $ from 'jquery';
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import destroyApp from '../../helpers/destroy-app';
@ -347,7 +346,7 @@ describe('Acceptance: Settings - General', function () {
});
it('handles social blog settings correctly', async function () {
let testSocialInput = async function(type, input, expectedValue, expectedError = '') {
let testSocialInput = async function (type, input, expectedValue, expectedError = '') {
await fillIn(`[data-test-${type}-input]`, input);
await triggerEvent(`[data-test-${type}-input]`, 'blur');
@ -484,7 +483,7 @@ describe('Acceptance: Settings - General', function () {
expect(find('.fullscreen-modal').length, 'modal exists').to.equal(1);
// Leave without saving
await(click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
await (click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
expect(currentURL(), 'currentURL').to.equal('/settings/team');

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import $ from 'jquery';
import destroyApp from '../../helpers/destroy-app';
import startApp from '../../helpers/start-app';
@ -8,14 +7,14 @@ import {authenticateSession, invalidateSession} from 'ghost-admin/tests/helpers/
import {expect} from 'chai';
// import {timeout} from 'ember-concurrency';
describe('Acceptance: Settings - Labs', function() {
describe('Acceptance: Settings - Labs', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import Mirage from 'ember-cli-mirage';
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import destroyApp from '../../helpers/destroy-app';
@ -10,11 +9,11 @@ import {expect} from 'chai';
describe('Acceptance: Settings - Apps - Slack', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});
@ -122,7 +121,7 @@ describe('Acceptance: Settings - Apps - Slack', function () {
expect(find('.fullscreen-modal').length, 'modal exists').to.equal(1);
// Leave without saving
await(click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
await (click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
expect(currentURL(), 'currentURL').to.equal('/settings/design');

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
/* eslint-disable camelcase */
import $ from 'jquery';
import destroyApp from '../../helpers/destroy-app';

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import destroyApp from '../../helpers/destroy-app';
import startApp from '../../helpers/start-app';
@ -113,7 +112,7 @@ describe('Acceptance: Settings - Apps - Unsplash', function () {
expect(find('.fullscreen-modal').length, 'modal exists').to.equal(1);
// Leave without saving
await(click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
await (click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
expect(currentURL(), 'currentURL').to.equal('/settings/labs');

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import destroyApp from '../helpers/destroy-app';
import moment from 'moment';
import startApp from '../helpers/start-app';
@ -151,7 +150,7 @@ describe('Acceptance: Setup', function () {
server.loadFixtures('roles');
server.post('/authentication/setup', function () {
postCount++;
postCount += 1;
// validation error
if (postCount === 1) {
@ -241,7 +240,7 @@ describe('Acceptance: Setup', function () {
server.post('/invites/', function ({invites}) {
let attrs = this.normalizedRequestAttrs();
postCount++;
postCount += 1;
// invalid
if (postCount === 1) {

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import $ from 'jquery';
import destroyApp from '../helpers/destroy-app';
import startApp from '../helpers/start-app';
@ -12,7 +11,7 @@ import {
import {authenticateSession, invalidateSession} from '../helpers/ember-simple-auth';
import {expect} from 'chai';
describe('Acceptance: Signin', function() {
describe('Acceptance: Signin', function () {
let application;
beforeEach(function () {

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import destroyApp from '../helpers/destroy-app';
import startApp from '../helpers/start-app';
import {
@ -9,18 +8,18 @@ import {
} from 'mocha';
import {expect} from 'chai';
describe('Acceptance: Signup', function() {
describe('Acceptance: Signup', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});
it('can signup successfully', async function() {
it('can signup successfully', async function () {
server.get('/authentication/invitation', function () {
return {
invitation: [{valid: true}]

View File

@ -1,18 +1,17 @@
/* jshint expr:true */
import destroyApp from '../helpers/destroy-app';
import startApp from '../helpers/start-app';
import {afterEach, beforeEach, describe, it} from 'mocha';
import {authenticateSession, invalidateSession} from 'ghost-admin/tests/helpers/ember-simple-auth';
import {expect} from 'chai';
describe('Acceptance: Subscribers', function() {
describe('Acceptance: Subscribers', function () {
let application;
beforeEach(function() {
beforeEach(function () {
application = startApp();
});
afterEach(function() {
afterEach(function () {
destroyApp(application);
});

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import destroyApp from '../helpers/destroy-app';
import moment from 'moment';
@ -547,7 +546,7 @@ describe('Acceptance: Team', function () {
expect(find('[data-test-website-input]').closest('.form-group').hasClass('error'), 'website input should be in error state').to.be.true;
let testSocialInput = async function(type, input, expectedValue, expectedError = '') {
let testSocialInput = async function (type, input, expectedValue, expectedError = '') {
await fillIn(`[data-test-${type}-input]`, input);
await triggerEvent(`[data-test-${type}-input]`, 'blur');
@ -791,7 +790,7 @@ describe('Acceptance: Team', function () {
expect(find('.fullscreen-modal').length, 'modal exists').to.equal(1);
// Leave without saving
await(click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
await (click('.fullscreen-modal [data-test-leave-button]'), 'leave without saving');
expect(currentURL(), 'currentURL').to.equal('/settings/team');

View File

@ -110,7 +110,5 @@ export function testEditorInputTimeout(input) {
}
export function waitForRender(selector) {
return waitUntil(() => {
return find(selector);
});
return waitUntil(() => find(selector));
}

View File

@ -24,7 +24,7 @@ export function fileUpload($element, content, options) {
$element.trigger(event);
}
export default registerAsyncHelper('fileUpload', function(app, selector, content, options) {
export default registerAsyncHelper('fileUpload', function (app, selector, content, options) {
let file = createFile(content, options);
return triggerEvent(

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import Pretender from 'pretender';
import {describe, it} from 'mocha';
import {expect} from 'chai';

View File

@ -1,4 +1,3 @@
/* jshint expr:true */
import Pretender from 'pretender';
import {describe, it} from 'mocha';
import {expect} from 'chai';

Some files were not shown because too many files have changed in this diff Show More