Skip to content

Commit c965792

Browse files
committed
Delete empty posts when leaving editor route
Closes TryGhost#4321 - Renamed editor-route-base to editor-base-route to fit the naming scheme of editor-base-view and editor-base-controller - Moved duplicate willTransition functionality from editor/edit and editor/new to editor-base-route - editor-base-route passes willTransition actions up the route chain - EditorRoute deletes a post with no bodyScratch and a title of `(Untitled)` on willTransition
1 parent bc728c3 commit c965792

File tree

6 files changed

+62
-77
lines changed

6 files changed

+62
-77
lines changed

core/client/mixins/editor-base-controller.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
6666
return hashCurrent === hashPrevious;
6767
},
6868

69-
// a hook created in editor-route-base's setupController
69+
// a hook created in editor-base-route's setupController
7070
modelSaved: function () {
7171
var model = this.get('model');
7272

core/client/mixins/editor-route-base.js core/client/mixins/editor-base-route.js

+47
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,53 @@ var EditorRouteBase = Ember.Mixin.create(styleBody, ShortcutsRoute, loadingIndic
2323
// The actual functionality is implemented in utils/codemirror-shortcuts
2424
codeMirrorShortcut: function (options) {
2525
this.get('controller.codemirror').shortcut(options.type);
26+
},
27+
28+
willTransition: function (transition) {
29+
var controller = this.get('controller'),
30+
isDirty = controller.get('isDirty'),
31+
32+
model = controller.get('model'),
33+
isSaving = model.get('isSaving'),
34+
isDeleted = model.get('isDeleted'),
35+
modelIsDirty = model.get('isDirty');
36+
37+
this.send('closeSettingsMenu');
38+
39+
// when `isDeleted && isSaving`, model is in-flight, being saved
40+
// to the server. when `isDeleted && !isSaving && !modelIsDirty`,
41+
// the record has already been deleted and the deletion persisted.
42+
//
43+
// in either case we can probably just transition now.
44+
// in the former case the server will return the record, thereby updating it.
45+
// @TODO: this will break if the model fails server-side validation.
46+
if (!(isDeleted && isSaving) && !(isDeleted && !isSaving && !modelIsDirty) && isDirty) {
47+
transition.abort();
48+
this.send('openModal', 'leave-editor', [controller, transition]);
49+
return;
50+
}
51+
// since the transition is now certain to complete..
52+
window.onbeforeunload = null;
53+
54+
// remove model-related listeners created in editor-base-route
55+
this.detachModelHooks(controller, model);
56+
// Bubble the action for the EditorRoute to catch
57+
return true;
58+
},
59+
60+
// Delete empty posts locally, or autosaved posts on the server
61+
// when leaving the editor route.
62+
deleteEmptyPosts: function () {
63+
var model = this.controller.get('model');
64+
// Delete unsaved, empty records from the store
65+
if (model.get('isNew')) {
66+
model.deleteRecord();
67+
return;
68+
}
69+
// A blank, autosaved post - kill it serverside as well.
70+
if (model.get('title') === '(Untitled)' && !model.get('markdown')) {
71+
return model.destroyRecord();
72+
}
2673
}
2774
},
2875

core/client/routes/editor.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var EditorRoute = Ember.Route.extend({
2+
actions: {
3+
willTransition: function () {
4+
this.send('deleteEmptyPosts');
5+
}
6+
}
7+
});
8+
9+
export default EditorRoute;

core/client/routes/editor/edit.js

+2-35
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import base from 'ghost/mixins/editor-route-base';
1+
import base from 'ghost/mixins/editor-base-route';
22
import isNumber from 'ghost/utils/isNumber';
33
import isFinite from 'ghost/utils/isFinite';
44

@@ -65,41 +65,8 @@ var EditorEditRoute = Ember.Route.extend(SimpleAuth.AuthenticatedRouteMixin, bas
6565
// used to check if anything has changed in the editor
6666
controller.set('previousTagNames', model.get('tags').mapBy('name'));
6767

68-
// attach model-related listeners created in editor-route-base
68+
// attach model-related listeners created in editor-base-route
6969
this.attachModelHooks(controller, model);
70-
},
71-
72-
actions: {
73-
willTransition: function (transition) {
74-
var controller = this.get('controller'),
75-
isDirty = controller.get('isDirty'),
76-
77-
model = controller.get('model'),
78-
isSaving = model.get('isSaving'),
79-
isDeleted = model.get('isDeleted'),
80-
modelIsDirty = model.get('isDirty');
81-
82-
this.send('closeSettingsMenu');
83-
84-
// when `isDeleted && isSaving`, model is in-flight, being saved
85-
// to the server. when `isDeleted && !isSaving && !modelIsDirty`,
86-
// the record has already been deleted and the deletion persisted.
87-
//
88-
// in either case we can probably just transition now.
89-
// in the former case the server will return the record, thereby updating it.
90-
// @TODO: this will break if the model fails server-side validation.
91-
if (!(isDeleted && isSaving) && !(isDeleted && !isSaving && !modelIsDirty) && isDirty) {
92-
transition.abort();
93-
this.send('openModal', 'leave-editor', [controller, transition]);
94-
return;
95-
}
96-
97-
// since the transition is now certain to complete..
98-
window.onbeforeunload = null;
99-
100-
// remove model-related listeners created in editor-route-base
101-
this.detachModelHooks(controller, model);
102-
}
10370
}
10471
});
10572

core/client/routes/editor/new.js

+2-40
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import base from 'ghost/mixins/editor-route-base';
1+
import base from 'ghost/mixins/editor-base-route';
22

33
var EditorNewRoute = Ember.Route.extend(SimpleAuth.AuthenticatedRouteMixin, base, {
44
classNames: ['editor'],
@@ -27,46 +27,8 @@ var EditorNewRoute = Ember.Route.extend(SimpleAuth.AuthenticatedRouteMixin, base
2727
// used to check if anything has changed in the editor
2828
controller.set('previousTagNames', Ember.A());
2929

30-
// attach model-related listeners created in editor-route-base
30+
// attach model-related listeners created in editor-base-route
3131
this.attachModelHooks(controller, model);
32-
},
33-
34-
actions: {
35-
willTransition: function (transition) {
36-
var controller = this.get('controller'),
37-
isDirty = controller.get('isDirty'),
38-
39-
model = controller.get('model'),
40-
isNew = model.get('isNew'),
41-
isSaving = model.get('isSaving'),
42-
isDeleted = model.get('isDeleted'),
43-
modelIsDirty = model.get('isDirty');
44-
45-
this.send('closeSettingsMenu');
46-
47-
// when `isDeleted && isSaving`, model is in-flight, being saved
48-
// to the server. when `isDeleted && !isSaving && !modelIsDirty`,
49-
// the record has already been deleted and the deletion persisted.
50-
//
51-
// in either case we can probably just transition now.
52-
// in the former case the server will return the record, thereby updating it.
53-
// @TODO: this will break if the model fails server-side validation.
54-
if (!(isDeleted && isSaving) && !(isDeleted && !isSaving && !modelIsDirty) && isDirty) {
55-
transition.abort();
56-
this.send('openModal', 'leave-editor', [controller, transition]);
57-
return;
58-
}
59-
60-
if (isNew) {
61-
model.deleteRecord();
62-
}
63-
64-
// since the transition is now certain to complete..
65-
window.onbeforeunload = null;
66-
67-
// remove model-related listeners created in editor-route-base
68-
this.detachModelHooks(controller, model);
69-
}
7032
}
7133
});
7234

core/client/utils/codemirror-shortcuts.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// jscs:disable disallowSpacesInsideParentheses
33

44
/** Set up a shortcut function to be called via router actions.
5-
* See editor-route-base
5+
* See editor-base-route
66
*/
77

88
import titleize from 'ghost/utils/titleize';

0 commit comments

Comments
 (0)