Merge pull request #5046 from novaugust/autosave-cleanup

Autosave by observing model.scratch in editor
This commit is contained in:
Hannah Wolfe 2015-04-05 23:12:38 +01:00
commit 880c911d22
4 changed files with 35 additions and 51 deletions

View File

@ -39,38 +39,12 @@ Editor = Ember.TextArea.extend(EditorAPI, EditorShortcuts, EditorScroll, {
} }
}, },
/**
* Use keypress events to trigger autosave
*/
changeHandler: function () {
// onChange is sent to trigger autosave
this.sendAction('onChange');
},
/**
* Bind to the keypress event once the element is in the DOM
* Use keypress because it's the most reliable cross browser
*/
attachChangeHandler: function () {
this.$().on('keypress', Ember.run.bind(this, this.changeHandler));
}.on('didInsertElement'),
/**
* Unbind from the keypress event when the element is no longer in the DOM
*/
detachChangeHandler: function () {
this.$().off('keypress');
Ember.run.cancel(this.get('fixHeightThrottle'));
}.on('willDestroyElement'),
/** /**
* Disable editing in the textarea (used while an upload is in progress) * Disable editing in the textarea (used while an upload is in progress)
*/ */
disable: function () { disable: function () {
var textarea = this.get('element'); var textarea = this.get('element');
textarea.setAttribute('readonly', 'readonly'); textarea.setAttribute('readonly', 'readonly');
this.detachChangeHandler();
}, },
/** /**
@ -79,11 +53,6 @@ Editor = Ember.TextArea.extend(EditorAPI, EditorShortcuts, EditorScroll, {
enable: function () { enable: function () {
var textarea = this.get('element'); var textarea = this.get('element');
textarea.removeAttribute('readonly'); textarea.removeAttribute('readonly');
// clicking the trash button on an image dropzone causes this function to fire.
// this line is a hack to prevent multiple event handlers from being attached.
this.detachChangeHandler();
this.attachChangeHandler();
} }
}); });

View File

@ -31,6 +31,36 @@ EditorControllerMixin = Ember.Mixin.create({
return self.get('isDirty') ? self.unloadDirtyMessage() : null; return self.get('isDirty') ? self.unloadDirtyMessage() : null;
}; };
}, },
lastModelId: null,
modelChanged: Ember.computed('model.id', function (key, value) {
var modelId = this.get('model.id');
if (arguments.length > 1) {
return value;
}
if (this.get('lastModelId') === modelId) {
return false;
}
this.set('lastModelId', modelId);
return true;
}),
autoSave: function () {
// Don't save just because we swapped out models
if (this.get('modelChanged')) {
this.set('modelChanged', false);
} else if (this.get('model.isDraft') && !this.get('model.isNew')) {
var autoSaveId,
timedSaveId;
timedSaveId = Ember.run.throttle(this, 'send', 'save', {silent: true, disableNProgress: true}, 60000, false);
this.set('timedSaveId', timedSaveId);
autoSaveId = Ember.run.debounce(this, 'send', 'save', {silent: true, disableNProgress: true}, 3000);
this.set('autoSaveId', autoSaveId);
}
}.observes('model.scratch'),
/** /**
* By default, a post will not change its publish state. * By default, a post will not change its publish state.
@ -332,19 +362,6 @@ EditorControllerMixin = Ember.Mixin.create({
this.set('isPreview', preview); this.set('isPreview', preview);
}, },
autoSave: function () {
if (this.get('model.isDraft')) {
var autoSaveId,
timedSaveId;
timedSaveId = Ember.run.throttle(this, 'send', 'save', {silent: true, disableNProgress: true}, 60000, false);
this.set('timedSaveId', timedSaveId);
autoSaveId = Ember.run.debounce(this, 'send', 'save', {silent: true, disableNProgress: true}, 3000);
this.set('autoSaveId', autoSaveId);
}
},
autoSaveNew: function () { autoSaveNew: function () {
if (this.get('model.isNew')) { if (this.get('model.isNew')) {
this.send('save', {silent: true, disableNProgress: true}); this.send('save', {silent: true, disableNProgress: true});

View File

@ -110,13 +110,12 @@ var EditorBaseRoute = Ember.Mixin.create(styleBody, ShortcutsRoute, loadingIndic
}, },
setupController: function (controller, model) { setupController: function (controller, model) {
model.set('scratch', model.get('markdown'));
model.set('titleScratch', model.get('title'));
this._super(controller, model); this._super(controller, model);
var tags = model.get('tags'); var tags = model.get('tags');
controller.set('model.scratch', model.get('markdown'));
controller.set('model.titleScratch', model.get('title'));
if (tags) { if (tags) {
// used to check if anything has changed in the editor // used to check if anything has changed in the editor
controller.set('previousTagNames', tags.mapBy('name')); controller.set('previousTagNames', tags.mapBy('name'));

View File

@ -18,9 +18,8 @@
</header> </header>
<section id="entry-markdown-content" class="entry-markdown-content"> <section id="entry-markdown-content" class="entry-markdown-content">
{{gh-ed-editor classNames="markdown-editor js-markdown-editor" tabindex="1" spellcheck="true" value=model.scratch {{gh-ed-editor classNames="markdown-editor js-markdown-editor" tabindex="1" spellcheck="true" value=model.scratch
scrollInfo=view.editorScrollInfo scrollInfo=view.editorScrollInfo focus=shouldFocusEditor focusCursorAtEnd=model.isDirty
setEditor="setEditor" openModal="openModal" onChange="autoSave" setEditor="setEditor" openModal="openModal" onFocusIn="autoSaveNew"}}
focus=shouldFocusEditor focusCursorAtEnd=model.isDirty onFocusIn="autoSaveNew"}}
</section> </section>
</section> </section>