mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
🐛 fix autosave+transition on title blur with empty title (#767)
refs TryGhost/Ghost#8525 - fix `saveTitle` action - don't abort title save when we have an empty title - force a "dirty" state so that the save actually happens - add acceptance test for title blur behaviour - extract multiple instances `"(Untitled)"` into a const
This commit is contained in:
parent
9738ecc9dd
commit
d37f68adcb
3 changed files with 41 additions and 5 deletions
|
@ -25,6 +25,7 @@ const {testing} = Ember;
|
||||||
// to know if the model has been changed (`controller.hasDirtyAttributes`)
|
// to know if the model has been changed (`controller.hasDirtyAttributes`)
|
||||||
const watchedProps = ['model.scratch', 'model.titleScratch', 'model.hasDirtyAttributes', 'model.tags.[]'];
|
const watchedProps = ['model.scratch', 'model.titleScratch', 'model.hasDirtyAttributes', 'model.tags.[]'];
|
||||||
|
|
||||||
|
const DEFAULT_TITLE = '(Untitled)';
|
||||||
const TITLE_DEBOUNCE = testing ? 10 : 700;
|
const TITLE_DEBOUNCE = testing ? 10 : 700;
|
||||||
|
|
||||||
PostModel.eachAttribute(function (name) {
|
PostModel.eachAttribute(function (name) {
|
||||||
|
@ -148,7 +149,7 @@ export default Mixin.create({
|
||||||
|
|
||||||
// Set a default title
|
// Set a default title
|
||||||
if (!this.get('model.titleScratch').trim()) {
|
if (!this.get('model.titleScratch').trim()) {
|
||||||
this.set('model.titleScratch', '(Untitled)');
|
this.set('model.titleScratch', DEFAULT_TITLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('model.title', this.get('model.titleScratch'));
|
this.set('model.title', this.get('model.titleScratch'));
|
||||||
|
@ -492,9 +493,9 @@ export default Mixin.create({
|
||||||
|
|
||||||
model.set('titleScratch', newTitle);
|
model.set('titleScratch', newTitle);
|
||||||
|
|
||||||
// if model is not new and title is not '(Untitled)', or model is new and
|
// if model is not new and title is not DEFAULT_TITLE, or model is new and
|
||||||
// has a title, don't generate a slug
|
// has a title, don't generate a slug
|
||||||
if ((!model.get('isNew') || model.get('title')) && newTitle !== '(Untitled)') {
|
if ((!model.get('isNew') || model.get('title')) && newTitle !== DEFAULT_TITLE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +509,7 @@ export default Mixin.create({
|
||||||
let title = this.get('model.titleScratch');
|
let title = this.get('model.titleScratch');
|
||||||
|
|
||||||
// Only set an "untitled" slug once per post
|
// Only set an "untitled" slug once per post
|
||||||
if (title === '(Untitled)' && this.get('model.slug')) {
|
if (title === DEFAULT_TITLE && this.get('model.slug')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,10 +607,13 @@ export default Mixin.create({
|
||||||
let currentTitle = this.get('model.title');
|
let currentTitle = this.get('model.title');
|
||||||
let newTitle = this.get('model.titleScratch').trim();
|
let newTitle = this.get('model.titleScratch').trim();
|
||||||
|
|
||||||
if (newTitle === currentTitle) {
|
if (currentTitle && newTitle && newTitle === currentTitle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is necessary to force a save when the title is blank
|
||||||
|
this.set('hasDirtyAttributes', true);
|
||||||
|
|
||||||
if (this.get('model.isDraft')) {
|
if (this.get('model.isDraft')) {
|
||||||
this.send('save', {
|
this.send('save', {
|
||||||
silent: true,
|
silent: true,
|
||||||
|
|
|
@ -7,6 +7,10 @@ export default function mockPosts(server) {
|
||||||
server.post('/posts', function ({posts}) {
|
server.post('/posts', function ({posts}) {
|
||||||
let attrs = this.normalizedRequestAttrs();
|
let attrs = this.normalizedRequestAttrs();
|
||||||
|
|
||||||
|
// mirage expects `author` to be a reference but we only have an ID
|
||||||
|
attrs.authorId = attrs.author;
|
||||||
|
delete attrs.author;
|
||||||
|
|
||||||
if (isBlank(attrs.slug) && !isBlank(attrs.title)) {
|
if (isBlank(attrs.slug) && !isBlank(attrs.title)) {
|
||||||
attrs.slug = dasherize(attrs.title);
|
attrs.slug = dasherize(attrs.title);
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,5 +520,33 @@ describe('Acceptance: Editor', function() {
|
||||||
expect(find('select[name="post-setting-author"]').val()).to.equal('2');
|
expect(find('select[name="post-setting-author"]').val()).to.equal('2');
|
||||||
expect(server.db.posts[0].authorId).to.equal(author.id);
|
expect(server.db.posts[0].authorId).to.equal(author.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('autosaves when title loses focus', async function () {
|
||||||
|
let role = server.create('role', {name: 'Administrator'});
|
||||||
|
server.create('user', {name: 'Admin', roles: [role]});
|
||||||
|
|
||||||
|
await visit('/editor');
|
||||||
|
|
||||||
|
// NOTE: there were checks here for the title element having focus
|
||||||
|
// but they were very temperamental whilst running tests in the
|
||||||
|
// browser so they've been left out for now
|
||||||
|
|
||||||
|
expect(
|
||||||
|
currentURL(),
|
||||||
|
'url on initial visit'
|
||||||
|
).to.equal('/editor');
|
||||||
|
|
||||||
|
await triggerEvent(testSelector('editor-title-input'), 'blur');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
find(testSelector('editor-title-input')).val(),
|
||||||
|
'title value after autosave'
|
||||||
|
).to.equal('(Untitled)');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
currentURL(),
|
||||||
|
'url after autosave'
|
||||||
|
).to.equal('/editor/1');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue