diff --git a/core/client/mixins/editor-base-controller.js b/core/client/mixins/editor-base-controller.js index a75438a1f8..dd4ee9bb85 100644 --- a/core/client/mixins/editor-base-controller.js +++ b/core/client/mixins/editor-base-controller.js @@ -63,6 +63,22 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, { return hashCurrent === hashPrevious; }, + // a hook created in editor-route-base's setupController + modelSaved: function () { + var model = this.get('model'); + + // safer to updateTags on save in one place + // rather than in all other places save is called + model.updateTags(); + + // set previousTagNames to current tagNames for isDirty check + this.set('previousTagNames', this.get('tagNames')); + + // `updateTags` triggers `isDirty => true`. + // for a saved model it would otherwise be false. + this.set('isDirty', false); + }, + // an ugly hack, but necessary to watch all the model's properties // and more, without having to be explicit and do it manually isDirty: Ember.computed.apply(Ember, watchedProps.concat(function (key, value) { @@ -76,7 +92,6 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, { changedAttributes; if (!this.tagNamesEqual()) { - this.set('previousTagNames', this.get('tagNames')); return true; } @@ -183,13 +198,7 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, { this.set('status', status); return this.get('model').save().then(function (model) { - model.updateTags(); - // `updateTags` triggers `isDirty => true`. - // for a saved model it would otherwise be false. - self.set('isDirty', false); - self.showSaveNotification(prevStatus, model.get('status'), isNew ? true : false); - return model; }).catch(function (errors) { self.showErrorNotification(prevStatus, self.get('status'), errors); diff --git a/core/client/mixins/editor-route-base.js b/core/client/mixins/editor-route-base.js index dc12ce1d86..17a66f4325 100644 --- a/core/client/mixins/editor-route-base.js +++ b/core/client/mixins/editor-route-base.js @@ -22,6 +22,26 @@ var EditorRouteBase = Ember.Mixin.create(styleBody, ShortcutsRoute, loadingIndic } }, + attachModelHooks: function (controller, model) { + // this will allow us to track when the model is saved and update the controller + // so that we can be sure controller.isDirty 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: function (controller, model) { + model.off('didCreate', controller, controller.get('modelSaved')); + model.off('didUpdate', controller, controller.get('modelSaved')); + }, + shortcuts: { //General Editor shortcuts 'ctrl+s, command+s': 'save', diff --git a/core/client/routes/editor/edit.js b/core/client/routes/editor/edit.js index eb20df1b64..70647ebec7 100644 --- a/core/client/routes/editor/edit.js +++ b/core/client/routes/editor/edit.js @@ -45,6 +45,9 @@ var EditorEditRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixi controller.set('scratch', model.get('markdown')); // used to check if anything has changed in the editor controller.set('previousTagNames', model.get('tags').mapBy('name')); + + // attach model-related listeners created in editor-route-base + this.attachModelHooks(controller, model); }, actions: { @@ -72,6 +75,9 @@ var EditorEditRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixi // since the transition is now certain to complete.. window.onbeforeunload = null; + + // remove model-related listeners created in editor-route-base + this.detachModelHooks(controller, model); } } }); diff --git a/core/client/routes/editor/new.js b/core/client/routes/editor/new.js index 25f7db0eed..fdb26e0656 100644 --- a/core/client/routes/editor/new.js +++ b/core/client/routes/editor/new.js @@ -13,6 +13,9 @@ var EditorNewRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin // used to check if anything has changed in the editor controller.set('previousTagNames', Ember.A()); + + // attach model-related listeners created in editor-route-base + this.attachModelHooks(controller, model); }, actions: { @@ -45,6 +48,9 @@ var EditorNewRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin // since the transition is now certain to complete.. window.onbeforeunload = null; + + // remove model-related listeners created in editor-route-base + this.detachModelHooks(controller, model); } } });