0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Merge pull request #4259 from novaugust/auto-save

Auto save draft posts
This commit is contained in:
Hannah Wolfe 2014-10-17 19:04:07 +03:00
commit a2b7fe718b
4 changed files with 47 additions and 38 deletions

View file

@ -9,19 +9,20 @@ codeMirrorShortcuts.init();
var onChangeHandler = function (cm, changeObj) {
var line,
component = cm.component,
checkLine = _.bind(component.checkLine, component),
checkMarkers = _.bind(component.checkMarkers, component);
component = cm.component;
// fill array with a range of numbers
for (line = changeObj.from.line; line < changeObj.from.line + changeObj.text.length; line += 1) {
checkLine(line, changeObj.origin);
component.checkLine(line, changeObj.origin);
}
// Is this a line which may have had a marker on it?
checkMarkers();
component.checkMarkers();
cm.component.set('value', cm.getValue());
// Send an action notifying a 5 second pause in typing/changes.
Ember.run.debounce(component, 'sendAction', 'typingPause', 5000);
};
var onScrollHandler = function (cm) {

View file

@ -5,9 +5,9 @@ var EditorNewController = Ember.ObjectController.extend(EditorControllerMixin, {
/**
* Redirect to editor after the first save
*/
save: function () {
save: function (options) {
var self = this;
this._super().then(function (model) {
return this._super(options).then(function (model) {
if (model.get('id')) {
self.transitionToRoute('editor.edit', model);
}

View file

@ -5,17 +5,13 @@ import boundOneWay from 'ghost/utils/bound-one-way';
// this array will hold properties we need to watch
// to know if the model has been changed (`controller.isDirty`)
var watchedProps = ['scratch', 'titleScratch', 'model.isDirty'];
var watchedProps = ['scratch', 'titleScratch', 'model.isDirty', 'tags.[]'];
PostModel.eachAttribute(function (name) {
watchedProps.push('model.' + name);
});
// watch if number of tags changes on the model
watchedProps.push('tags.[]');
var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
needs: ['post-tags-input'],
init: function () {
@ -34,11 +30,14 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
*/
willPublish: boundOneWay('isPublished'),
// Make sure editor starts with markdown shown
isPreview: false,
// set by the editor route and `isDirty`. useful when checking
// whether the number of tags has changed for `isDirty`.
previousTagNames: null,
tagNames: Ember.computed('tags.[]', function () {
tagNames: Ember.computed('tags.@each.name', function () {
return this.get('tags').mapBy('name');
}),
@ -130,11 +129,7 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
// which does *not* change the model's `isDirty` property,
// `isDirty` will tell us if the other props have changed,
// as long as the model is not new (model.isNew === false).
if (model.get('isDirty')) {
return true;
}
return false;
return model.get('isDirty');
})),
// used on window.onbeforeunload
@ -152,12 +147,12 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
errors: {
post: {
published: {
'published': 'Update failed.',
'draft': 'Saving failed.'
published: 'Update failed.',
draft: 'Saving failed.'
},
draft: {
'published': 'Publish failed.',
'draft': 'Saving failed.'
published: 'Publish failed.',
draft: 'Saving failed.'
}
}
@ -166,12 +161,12 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
success: {
post: {
published: {
'published': 'Updated.',
'draft': 'Saved.'
published: 'Updated.',
draft: 'Saved.'
},
draft: {
'published': 'Published!',
'draft': 'Saved.'
published: 'Published!',
draft: 'Saved.'
}
}
}
@ -191,16 +186,15 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
this.notifications.showError(message, { delayed: delay });
},
shouldFocusTitle: Ember.computed('model', function () {
return !!this.get('model.isNew');
}),
shouldFocusTitle: Ember.computed.alias('model.isNew'),
actions: {
save: function () {
save: function (options) {
var status = this.get('willPublish') ? 'published' : 'draft',
prevStatus = this.get('status'),
isNew = this.get('isNew'),
self = this;
options = options || {};
self.notifications.closePassive();
@ -210,15 +204,23 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
// Set the properties that are indirected
// set markdown equal to what's in the editor, minus the image markers.
this.set('markdown', this.getMarkdown().withoutMarkers);
this.set('title', this.get('titleScratch'));
this.set('status', status);
// Set a default title
if (!this.get('titleScratch')) {
this.set('titleScratch', '(Untitled)');
}
this.set('title', this.get('titleScratch'));
return this.get('model').save().then(function (model) {
if (!options.silent) {
self.showSaveNotification(prevStatus, model.get('status'), isNew ? true : false);
}
return model;
}).catch(function (errors) {
if (!options.silent) {
self.showErrorNotification(prevStatus, self.get('status'), errors);
}
self.set('status', prevStatus);
return Ember.RSVP.reject(errors);
@ -286,11 +288,14 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
editor.replaceSelection(result_src);
},
// Make sure editor starts with markdown shown
isPreview: false,
togglePreview: function (preview) {
this.set('isPreview', preview);
},
autoSave: function () {
if (this.get('model.isDraft')) {
this.send('save', {silent: true, disableNProgress: true});
}
}
}
});

View file

@ -16,7 +16,10 @@
<a class="markdown-help" href="" {{action "openModal" "markdown"}}><span class="hidden">What is Markdown?</span></a>
</header>
<section id="entry-markdown-content" class="entry-markdown-content">
{{gh-codemirror value=scratch scrollInfo=view.markdownScrollInfo setCodeMirror="setCodeMirror" openModal="openModal"}}
{{gh-codemirror value=scratch scrollInfo=view.markdownScrollInfo
setCodeMirror="setCodeMirror"
openModal="openModal"
typingPause="autoSave"}}
</section>
</section>