diff --git a/core/client/assets/sass/layouts/editor.scss b/core/client/assets/sass/layouts/editor.scss
index 401dfe5cdf..7ae465ca50 100644
--- a/core/client/assets/sass/layouts/editor.scss
+++ b/core/client/assets/sass/layouts/editor.scss
@@ -559,22 +559,6 @@ body.zen {
}
-#entry-controls {
- &.unsaved {
- .post-settings-menu {
- padding-bottom: 0;
-
- .post-setting:nth-child(3) td {
- border-bottom: none;
- }
-
- .delete {
- display: none;
- }
- }
- }
-}
-
#entry-actions {
margin-right: 6px;
position: relative;
@@ -589,6 +573,14 @@ body.zen {
bottom: 100%;
}
}
+
+ &.unsaved {
+ padding-bottom: 0;
+
+ .delete {
+ display: none;
+ }
+ }
}
#entry-actions-menu {
@@ -750,4 +742,4 @@ body.zen {
th {
text-align: left;
}
-}
\ No newline at end of file
+}
diff --git a/core/client/controllers/post-settings-menu.js b/core/client/controllers/post-settings-menu.js
index 133d927a6c..4d2763a002 100644
--- a/core/client/controllers/post-settings-menu.js
+++ b/core/client/controllers/post-settings-menu.js
@@ -197,6 +197,22 @@ var PostSettingsMenuController = Ember.ObjectController.extend({
self.get('model').rollback();
});
},
+
+ toggleFeatured: function () {
+ var self = this;
+
+ this.toggleProperty('featured');
+ // If this is a new post. Don't save the model. Defer the save
+ // to the user pressing the save button
+ if (this.get('isNew')) {
+ return;
+ }
+
+ this.get('model').save(this.get('saveOptions')).catch(function (errors) {
+ self.showErrors(errors);
+ self.get('model').rollback();
+ });
+ },
/**
* triggered by user manually changing slug
*/
diff --git a/core/client/templates/-publish-bar.hbs b/core/client/templates/-publish-bar.hbs
index f8af05a32f..ca8fbe605c 100644
--- a/core/client/templates/-publish-bar.hbs
+++ b/core/client/templates/-publish-bar.hbs
@@ -1,13 +1,10 @@
diff --git a/core/client/templates/editor-save-button.hbs b/core/client/templates/editor-save-button.hbs
index 0f0c61ecb7..0726fe178c 100644
--- a/core/client/templates/editor-save-button.hbs
+++ b/core/client/templates/editor-save-button.hbs
@@ -11,5 +11,9 @@
+{{#gh-tabs-manager selected="showSubview" id="entry-controls" class="right-outlet"}}
+
diff --git a/core/test/functional/client/editor_test.js b/core/test/functional/client/editor_test.js
index e12a263ac4..2821506f22 100644
--- a/core/test/functional/client/editor_test.js
+++ b/core/test/functional/client/editor_test.js
@@ -322,7 +322,7 @@ CasperTest.begin('Publish menu - new post', 10, function suite(test) {
});
});
-CasperTest.begin('Publish menu - existing post', 19, function suite(test) {
+CasperTest.begin('Publish menu - existing post', 23, function suite(test) {
// Create a post, save it and test refreshed editor
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
@@ -338,6 +338,17 @@ CasperTest.begin('Publish menu - existing post', 19, function suite(test) {
test.assertSelectorHasText('.entry-preview .rendered-markdown', 'test', 'Editor value is correct');
});
+ casper.thenClick('.js-publish-splitbutton .dropdown-toggle');
+
+ casper.waitForOpaque('.js-publish-splitbutton .dropdown-menu', function onSuccess() {
+ test.assert(true, 'popup menu should be visible after clicking post-settings icon');
+ test.assertNotVisible(
+ '.js-publish-splitbutton .delete', 'delete post button shouldn\'t be visible on unsaved drafts'
+ );
+ });
+
+ casper.thenClick('.js-publish-splitbutton .dropdown-toggle');
+
// Create a post in draft status
casper.thenClick('.js-publish-button');
@@ -353,6 +364,17 @@ CasperTest.begin('Publish menu - existing post', 19, function suite(test) {
test.assertSelectorHasText('.js-publish-button', 'Save Draft');
});
+ casper.thenClick('.js-publish-splitbutton .dropdown-toggle');
+
+ casper.waitForOpaque('.js-publish-splitbutton .open', function onSuccess() {
+ test.assert(true, 'delete post button should be visible for saved drafts');
+ test.assertVisible(
+ '.js-publish-splitbutton .delete', 'delete post button should be visible on saved drafts'
+ );
+ });
+
+ casper.thenClick('.js-publish-splitbutton .dropdown-toggle');
+
casper.then(function switchMenuToPublish() {
// Open the publish options menu;
casper.thenClick('.js-publish-splitbutton .dropdown-toggle');
@@ -417,6 +439,58 @@ CasperTest.begin('Publish menu - existing post', 19, function suite(test) {
});
});
+CasperTest.begin('Publish menu - delete post', 7, function testDeleteModal(test) {
+ // Create a post that can be deleted
+ CasperTest.Routines.createTestPost.run(false);
+
+ // Begin test
+ casper.thenOpenAndWaitForPageLoad('content', function testTitleAndUrl() {
+ test.assertTitle('Ghost Admin', 'Title is "Ghost Admin"');
+ test.assertUrlMatch(/ghost\/\d+\/$/, 'Landed on the correct URL');
+ });
+
+ // Transition to the editor
+ casper.thenClick('.post-edit');
+ casper.waitForSelector('#entry-title');
+
+ // Open post settings menu
+ casper.thenClick('.js-publish-splitbutton .dropdown-toggle');
+ casper.waitForOpaque('.js-publish-splitbutton .open');
+ casper.thenClick('.js-publish-splitbutton li:nth-child(4) a');
+
+ casper.waitUntilVisible('#modal-container', function onSuccess() {
+ test.assertSelectorHasText(
+ '.modal-content .modal-header',
+ 'Are you sure you want to delete this post?',
+ 'delete modal has correct text');
+ });
+
+ casper.thenClick('.js-button-reject');
+
+ casper.waitWhileVisible('#modal-container', function onSuccess() {
+ test.assert(true, 'clicking cancel should close the delete post modal');
+ });
+
+ // Test delete
+ casper.thenClick('.js-publish-splitbutton .dropdown-toggle');
+ casper.waitForOpaque('.js-publish-splitbutton .open');
+ casper.thenClick('.js-publish-splitbutton li:nth-child(4) a');
+
+ casper.waitForSelector('#modal-container .modal-content', function onSuccess() {
+ test.assertExists('.modal-content .js-button-accept', 'delete button exists');
+
+ // Delete the post
+ this.click('.modal-content .js-button-accept');
+
+ casper.waitForSelector('.notification-success', function onSuccess() {
+ test.assert(true, 'Got success notification from delete post');
+ test.assertSelectorHasText('.notification-message', 'Your post has been deleted.');
+ }, function onTimeout() {
+ test.fail('No success notification from delete post');
+ });
+ });
+});
+
CasperTest.begin('Publish menu - new post status is correct after failed save', 4, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
diff --git a/core/test/functional/client/psm_test.js b/core/test/functional/client/psm_test.js
index 413431db66..0f1cae4d01 100644
--- a/core/test/functional/client/psm_test.js
+++ b/core/test/functional/client/psm_test.js
@@ -3,7 +3,7 @@
/*globals CasperTest, casper, __utils__ */
-CasperTest.begin('Post settings menu', 14, function suite(test) {
+CasperTest.begin('Post settings menu', 10, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/editor\/$/, 'Landed on the correct URL');
@@ -15,20 +15,8 @@ CasperTest.begin('Post settings menu', 14, function suite(test) {
test.assertExists('.post-settings-menu #url', 'url field exists');
test.assertExists('.post-settings-menu .post-setting-date', 'publication date field exists');
test.assertExists('.post-settings-menu .post-setting-static-page', 'static page checkbox field exists');
- test.assertExists('.post-settings-menu button.delete', 'delete post button exists');
});
- casper.thenClick('.post-settings');
-
- casper.waitForOpaque('.post-settings-menu', function onSuccess() {
- test.assert(true, 'popup menu should be visible after clicking post-settings icon');
- test.assertNotVisible(
- '.post-settings-menu button.delete', 'delete post button shouldn\'t be visible on unsaved drafts'
- );
- });
-
- casper.thenClick('.post-settings');
-
// Enter a title and save draft so converting to/from static post
// will result in notifications and 'Delete This Post' button appears
casper.then(function () {
@@ -51,60 +39,6 @@ CasperTest.begin('Post settings menu', 14, function suite(test) {
casper.waitForOpaque('.post-settings-menu', function onSuccess() {
test.assert(true, 'post settings menu should be visible after clicking post-settings icon');
});
-
- casper.waitUntilVisible('.post-settings-menu button.delete', function onSuccess() {
- test.assert(true, 'delete post button should be visible for saved drafts');
- });
-});
-
-CasperTest.begin('Delete post modal', 7, function testDeleteModal(test) {
- // Create a post that can be deleted
- CasperTest.Routines.createTestPost.run(false);
-
- // Begin test
- casper.thenOpenAndWaitForPageLoad('content', function testTitleAndUrl() {
- test.assertTitle('Ghost Admin', 'Title is "Ghost Admin"');
- test.assertUrlMatch(/ghost\/\d+\/$/, 'Landed on the correct URL');
- });
-
- // Transition to the editor
- casper.thenClick('.post-edit');
- casper.waitForSelector('#entry-title');
-
- // Open post settings menu
- casper.thenClick('.post-settings');
- casper.thenClick('.post-settings-menu button.delete');
-
- casper.waitUntilVisible('#modal-container', function onSuccess() {
- test.assertSelectorHasText(
- '.modal-content .modal-header',
- 'Are you sure you want to delete this post?',
- 'delete modal has correct text');
- });
-
- casper.thenClick('.js-button-reject');
-
- casper.waitWhileVisible('#modal-container', function onSuccess() {
- test.assert(true, 'clicking cancel should close the delete post modal');
- });
-
- // Test delete
- casper.thenClick('.post-settings');
- casper.thenClick('.post-settings-menu button.delete');
-
- casper.waitForSelector('#modal-container .modal-content', function onSuccess() {
- test.assertExists('.modal-content .js-button-accept', 'delete button exists');
-
- // Delete the post
- this.click('.modal-content .js-button-accept');
-
- casper.waitForSelector('.notification-success', function onSuccess() {
- test.assert(true, 'Got success notification from delete post');
- test.assertSelectorHasText('.notification-message', 'Your post has been deleted.');
- }, function onTimeout() {
- test.fail('No success notification from delete post');
- });
- });
});
CasperTest.begin('Post url can be changed', 4, function suite(test) {