From 340206fa4bf4f90d68d58c87a661b2415b1b937f Mon Sep 17 00:00:00 2001 From: Zach Geis Date: Tue, 29 Oct 2013 11:54:48 -0500 Subject: [PATCH 1/3] Displays alert if editor is dirty before unload closes #1327 - Prevents user from accidently losing changes --- core/client/views/editor.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/core/client/views/editor.js b/core/client/views/editor.js index f99743cc8a..e54d03a7ef 100644 --- a/core/client/views/editor.js +++ b/core/client/views/editor.js @@ -227,6 +227,7 @@ message: this.notificationMap[status], status: 'passive' }); + Ghost.currentView.setEditorDirty(false); }, reportSaveError: function (response, model, status) { @@ -447,6 +448,10 @@ return this.uploadMgr.getEditorValue(); }, + setEditorDirty: function (dirty) { + return this.uploadMgr.setEditorDirty(dirty); + }, + initUploads: function () { var filestorage = $('#entry-markdown-content').data('filestorage'); this.$('.js-drop-zone').upload({editor: true, fileStorage: filestorage}); @@ -657,15 +662,30 @@ return value; } + function unloadDirtyMessage() { + return "==============================\n\n" + + "Hey there! It looks like you're in the middle of writing" + + " something and you haven't saved all of your content." + + "\n\nSave before you go!\n\n" + + "=============================="; + } + + function setEditorDirty(dirty) { + window.onbeforeunload = dirty ? unloadDirtyMessage : null; + } + // Public API _.extend(this, { getEditorValue: getEditorValue, - handleUpload: handleUpload + handleUpload: handleUpload, + setEditorDirty: setEditorDirty }); // initialise editor.on('change', function (cm, changeObj) { /*jslint unparam:true*/ + setEditorDirty(true); + var linesChanged = _.range(changeObj.from.line, changeObj.from.line + changeObj.text.length); _.each(linesChanged, function (ln) { From 3fd310248653a6ff4824654f24aab10678d130fd Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Mon, 11 Nov 2013 09:14:18 +0000 Subject: [PATCH 2/3] Moving dirty editor handling out of uploadMgr issue #1327 - just moved to be in editor obj, everything else is the same --- core/client/views/editor.js | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/core/client/views/editor.js b/core/client/views/editor.js index e54d03a7ef..eed240615f 100644 --- a/core/client/views/editor.js +++ b/core/client/views/editor.js @@ -448,8 +448,16 @@ return this.uploadMgr.getEditorValue(); }, + unloadDirtyMessage: function () { + return "==============================\n\n" + + "Hey there! It looks like you're in the middle of writing" + + " something and you haven't saved all of your content." + + "\n\nSave before you go!\n\n" + + "=============================="; + }, + setEditorDirty: function (dirty) { - return this.uploadMgr.setEditorDirty(dirty); + window.onbeforeunload = dirty ? this.unloadDirtyMessage : null; }, initUploads: function () { @@ -465,6 +473,7 @@ var self = this; this.editor.setOption("readOnly", false); this.editor.on('change', function () { + self.setEditorDirty(true); self.renderPreview(); }); }, @@ -662,30 +671,16 @@ return value; } - function unloadDirtyMessage() { - return "==============================\n\n" + - "Hey there! It looks like you're in the middle of writing" + - " something and you haven't saved all of your content." + - "\n\nSave before you go!\n\n" + - "=============================="; - } - - function setEditorDirty(dirty) { - window.onbeforeunload = dirty ? unloadDirtyMessage : null; - } // Public API _.extend(this, { getEditorValue: getEditorValue, - handleUpload: handleUpload, - setEditorDirty: setEditorDirty + handleUpload: handleUpload }); // initialise editor.on('change', function (cm, changeObj) { /*jslint unparam:true*/ - setEditorDirty(true); - var linesChanged = _.range(changeObj.from.line, changeObj.from.line + changeObj.text.length); _.each(linesChanged, function (ln) { From 2c3de6706261017beca13f02ea4d67ee08266fd9 Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Mon, 11 Nov 2013 09:36:29 +0000 Subject: [PATCH 3/3] Preventing incorrectly shown unload alert issue #1327 - IE9 fires an unload when using Backbone.history.navigate which meant the alert always got shown on first save when the url changes from from /editor/ to /editor/id. Not sure if other browsers do this, but this workaround fixes it --- core/client/views/editor.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/client/views/editor.js b/core/client/views/editor.js index eed240615f..c64bfe45b6 100644 --- a/core/client/views/editor.js +++ b/core/client/views/editor.js @@ -100,9 +100,6 @@ self.updatePost(); }); this.listenTo(this.model, 'change:status', this.render); - this.listenTo(this.model, 'change:id', function (m) { - Backbone.history.navigate('/editor/' + m.id + '/'); - }); }, toggleStatus: function () { @@ -279,6 +276,7 @@ Ghost.Views.Editor = Ghost.View.extend({ initialize: function () { + var self = this; // Add the container view for the Publish Bar this.addSubview(new PublishBar({el: "#publish-bar", model: this.model})).render(); @@ -287,6 +285,13 @@ this.$('#entry-markdown').text(this.model.get('markdown')); this.listenTo(this.model, 'change:title', this.renderTitle); + this.listenTo(this.model, 'change:id', function (m) { + // This is a special case for browsers which fire an unload event when using navigate. The id change + // happens before the save success and can cause the unload alert to appear incorrectly on first save + // The id only changes in the event that the save has been successful, so this workaround is safes + self.setEditorDirty(false); + Backbone.history.navigate('/editor/' + m.id + '/'); + }); this.initMarkdown(); this.renderPreview();