1
0
Fork 0
mirror of https://github.com/TryGhost/Ghost-Admin.git synced 2023-12-14 02:33:04 +01:00
Ghost-Admin/app/mixins/editor-base-route.js
Kevin Ansfield 7eefbba69f 💄🐷 sort-imports eslint rule (#712)
no issue

- adds `eslint-plugin-sort-imports-es6-autofix` dependency
  - implements ESLint's base `sort-imports` rule but has a distinction in that `import {foo} from 'bar';` is considered `multiple` rather than `single`
  - fixes ESLint's autofix behaviour so `eslint --fix` will actually fix the sort order
- updates all unordered import rules by using `eslint --fix`

With the increased number of `import` statements since Ember+ecosystem started moving towards es6 modules I've found it frustrating at times trying to search through randomly ordered import statements. Recently I've been sorting imports manually when I've added new code or touched old code so I thought I'd add an ESLint rule to codify it.
2017-05-29 20:50:03 +02:00

140 lines
5.3 KiB
JavaScript

import $ from 'jquery';
import Mixin from 'ember-metal/mixin';
import ShortcutsRoute from 'ghost-admin/mixins/shortcuts-route';
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import run from 'ember-runloop';
import styleBody from 'ghost-admin/mixins/style-body';
let generalShortcuts = {};
generalShortcuts[`${ctrlOrCmd}+alt+p`] = 'publish';
export default Mixin.create(styleBody, ShortcutsRoute, {
classNames: ['editor'],
shortcuts: generalShortcuts,
actions: {
save() {
let selectedElement = $(document.activeElement);
if (selectedElement.is('input[type="text"]')) {
selectedElement.trigger('focusout');
}
run.scheduleOnce('actions', this, function () {
this.get('controller').send('save');
});
},
publish() {
let controller = this.get('controller');
controller.send('setSaveType', 'publish');
controller.send('save');
},
willTransition(transition) {
let controller = this.get('controller');
let scratch = controller.get('model.scratch');
let controllerIsDirty = controller.get('hasDirtyAttributes');
let model = controller.get('model');
let state = model.getProperties('isDeleted', 'isSaving', 'hasDirtyAttributes', 'isNew');
let deletedWithoutChanges,
fromNewToEdit;
if (this.get('upgradeStatus.isRequired')) {
return this._super(...arguments);
}
// if a save is in-flight we don't know whether or not it's safe to leave
// so we abort the transition and retry after the save has completed.
if (state.isSaving) {
transition.abort();
controller.get('generateSlug.last').then(() => {
transition.retry();
});
}
fromNewToEdit = this.get('routeName') === 'editor.new'
&& transition.targetName === 'editor.edit'
&& transition.intent.contexts
&& transition.intent.contexts[0]
&& transition.intent.contexts[0].id === model.get('id');
deletedWithoutChanges = state.isDeleted
&& (state.isSaving || !state.hasDirtyAttributes);
if (!fromNewToEdit && !deletedWithoutChanges && controllerIsDirty) {
transition.abort();
controller.send('toggleLeaveEditorModal', transition);
return;
}
// The controller may hold model state that will be lost in the
// new->edit transition, so we need to apply it now.
if (fromNewToEdit && controllerIsDirty) {
if (scratch !== model.get('mobiledoc')) {
model.set('mobiledoc', scratch);
}
}
// make sure the save tasks aren't still running in the background
// after leaving the edit route
// TODO: the edit screen should really be a component so that we get
// automatic state cleanup and task cancellation
controller.send('cancelAutosave');
if (state.isNew) {
model.deleteRecord();
}
// since the transition is now certain to complete..
window.onbeforeunload = null;
// remove model-related listeners created in editor-base-route
this.detachModelHooks(controller, model);
}
},
attachModelHooks(controller, model) {
// this will allow us to track when the model is saved and update the controller
// so that we can be sure controller.hasDirtyAttributes is correct, without having to update the
// controller on each instance of `model.save()`.
//
// another reason we can't do this on `model.save().then()` is because the post-settings-menu
// also saves the model, and passing messages is difficult because we have two
// types of editor controllers, and the PSM also exists on the posts.post route.
//
// The reason we can't just keep this functionality in the editor controller is
// because we need to remove these handlers on `willTransition` in the editor route.
model.on('didCreate', controller, controller.get('modelSaved'));
model.on('didUpdate', controller, controller.get('modelSaved'));
},
detachModelHooks(controller, model) {
model.off('didCreate', controller, controller.get('modelSaved'));
model.off('didUpdate', controller, controller.get('modelSaved'));
},
setupController(controller, model) {
let tags = model.get('tags');
model.set('scratch', model.get('mobiledoc'));
model.set('titleScratch', model.get('title'));
this._super(...arguments);
if (tags) {
// used to check if anything has changed in the editor
controller.set('previousTagNames', tags.mapBy('name'));
} else {
controller.set('previousTagNames', []);
}
// reset save-on-first-change
controller._hasChanged = false;
// attach model-related listeners created in editor-base-route
this.attachModelHooks(controller, model);
}
});