Merge pull request #5309 from svbergerem/confirm-unload-publisher
Ask for confirmation when leaving a submittable publisher
This commit is contained in:
commit
cd4502f476
15 changed files with 75 additions and 15 deletions
|
|
@ -95,6 +95,7 @@ This maintenance is not enabled by default. Podmins can enable it by for example
|
||||||
* Infinite scrolling in the notifications dropdown [#5237](https://github.com/diaspora/diaspora/pull/5237)
|
* Infinite scrolling in the notifications dropdown [#5237](https://github.com/diaspora/diaspora/pull/5237)
|
||||||
* Maintenance feature to automatically expire inactive accounts [#5288](https://github.com/diaspora/diaspora/pull/5288)
|
* Maintenance feature to automatically expire inactive accounts [#5288](https://github.com/diaspora/diaspora/pull/5288)
|
||||||
* Add LibreJS markers to JavaScript [5320](https://github.com/diaspora/diaspora/pull/5320)
|
* Add LibreJS markers to JavaScript [5320](https://github.com/diaspora/diaspora/pull/5320)
|
||||||
|
* Ask for confirmation when leaving a submittable publisher [#5309](https://github.com/diaspora/diaspora/pull/5309)
|
||||||
|
|
||||||
# 0.4.1.2
|
# 0.4.1.2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,10 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
// init autoresize plugin
|
// init autoresize plugin
|
||||||
this.el_input.autoResize({ 'extraSpace' : 10, 'maxHeight' : Infinity });
|
this.el_input.autoResize({ 'extraSpace' : 10, 'maxHeight' : Infinity });
|
||||||
|
|
||||||
|
// if there is data in the publisher we ask for a confirmation
|
||||||
|
// before the user is able to leave the page
|
||||||
|
$(window).on('beforeunload', _.bind(this._beforeUnload, this));
|
||||||
|
|
||||||
// sync textarea content
|
// sync textarea content
|
||||||
if( this.el_hiddenInput.val() == "" ) {
|
if( this.el_hiddenInput.val() == "" ) {
|
||||||
this.el_hiddenInput.val( this.el_input.val() );
|
this.el_hiddenInput.val( this.el_input.val() );
|
||||||
|
|
@ -77,14 +81,14 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
this.close();
|
this.close();
|
||||||
this.showSpinner(true);
|
this.showSpinner(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// open publisher on post error
|
// open publisher on post error
|
||||||
this.on('publisher:error', function() {
|
this.on('publisher:error', function() {
|
||||||
this.open();
|
this.open();
|
||||||
this.showSpinner(false);
|
this.showSpinner(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// resetting the poll view
|
// resetting the poll view
|
||||||
this.on('publisher:sync', function() {
|
this.on('publisher:sync', function() {
|
||||||
this.view_poll_creator.render();
|
this.view_poll_creator.render();
|
||||||
});
|
});
|
||||||
|
|
@ -159,7 +163,7 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
if(evt){ evt.preventDefault(); }
|
if(evt){ evt.preventDefault(); }
|
||||||
|
|
||||||
// Auto-adding a poll answer always leaves an empty box when the user starts
|
// Auto-adding a poll answer always leaves an empty box when the user starts
|
||||||
// typing in the last box. We'll delete the last one to avoid submitting an
|
// typing in the last box. We'll delete the last one to avoid submitting an
|
||||||
// empty poll answer and failing validation.
|
// empty poll answer and failing validation.
|
||||||
this.view_poll_creator.removeLastAnswer();
|
this.view_poll_creator.removeLastAnswer();
|
||||||
|
|
||||||
|
|
@ -378,7 +382,7 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
|
|
||||||
// enable input
|
// enable input
|
||||||
this.setInputEnabled(true);
|
this.setInputEnabled(true);
|
||||||
|
|
||||||
// enable buttons
|
// enable buttons
|
||||||
this.setButtonsEnabled(true);
|
this.setButtonsEnabled(true);
|
||||||
|
|
||||||
|
|
@ -428,7 +432,7 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
else
|
else
|
||||||
this.$('#publisher_spinner').addClass('hidden');
|
this.$('#publisher_spinner').addClass('hidden');
|
||||||
},
|
},
|
||||||
|
|
||||||
checkSubmitAvailability: function() {
|
checkSubmitAvailability: function() {
|
||||||
if( this._submittable() ) {
|
if( this._submittable() ) {
|
||||||
this.setButtonsEnabled(true);
|
this.setButtonsEnabled(true);
|
||||||
|
|
@ -472,8 +476,15 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
this.el_input.mentionsInput("val", function(value){
|
this.el_input.mentionsInput("val", function(value){
|
||||||
self.el_hiddenInput.val(value);
|
self.el_hiddenInput.val(value);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
|
_beforeUnload: function(e) {
|
||||||
|
if(this._submittable()){
|
||||||
|
var confirmationMessage = Diaspora.I18n.t("confirm_unload");
|
||||||
|
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
|
||||||
|
return confirmationMessage; //Webkit, Safari, Chrome, etc.
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// jQuery helper for serializing a <form> into JSON
|
// jQuery helper for serializing a <form> into JSON
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
app.publisher.open();
|
app.publisher.open();
|
||||||
$("#publisher").bind('ajax:success', function(){
|
$("#publisher").bind('ajax:success', function(){
|
||||||
$("#mentionModal").modal('hide');
|
$("#mentionModal").modal('hide');
|
||||||
|
app.publisher.clear();
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
en:
|
en:
|
||||||
javascripts:
|
javascripts:
|
||||||
confirm_dialog: "Are you sure?"
|
confirm_dialog: "Are you sure?"
|
||||||
|
confirm_unload: "Please confirm that you want to leave this page - data you have entered won't be saved."
|
||||||
delete: "Delete"
|
delete: "Delete"
|
||||||
ignore: "Ignore"
|
ignore: "Ignore"
|
||||||
report:
|
report:
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ Feature: following and being followed
|
||||||
And I fill in the following:
|
And I fill in the following:
|
||||||
| status_message_fake_text | I am following you |
|
| status_message_fake_text | I am following you |
|
||||||
And I press "Share"
|
And I press "Share"
|
||||||
Then I sign out
|
Then I should see "I am following you" within "#main_stream"
|
||||||
|
And I sign out
|
||||||
|
|
||||||
Scenario: seeing a follower's posts on their profile page, but not in your stream
|
Scenario: seeing a follower's posts on their profile page, but not in your stream
|
||||||
When I sign in as "alice@alice.alice"
|
When I sign in as "alice@alice.alice"
|
||||||
|
|
@ -35,6 +36,7 @@ Feature: following and being followed
|
||||||
And I press the first ".toggle" within "#publisher"
|
And I press the first ".toggle" within "#publisher"
|
||||||
And I press the first ".public" within "#publisher"
|
And I press the first ".public" within "#publisher"
|
||||||
And I press "Share"
|
And I press "Share"
|
||||||
|
Then I should see "I am ALICE" within "#main_stream"
|
||||||
And I sign out
|
And I sign out
|
||||||
|
|
||||||
When I sign in as "bob@bob.bob"
|
When I sign in as "bob@bob.bob"
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ Feature: Keyboard navigation
|
||||||
Given I expand the publisher
|
Given I expand the publisher
|
||||||
When I press the "J" key in the publisher
|
When I press the "J" key in the publisher
|
||||||
Then post 2 should be highlighted
|
Then post 2 should be highlighted
|
||||||
|
And I close the publisher
|
||||||
|
|
||||||
Scenario: navigate upwards
|
Scenario: navigate upwards
|
||||||
When I am on the home page
|
When I am on the home page
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ Feature: Mentions
|
||||||
| status_message_fake_text | @Bo |
|
| status_message_fake_text | @Bo |
|
||||||
And I click on the first user in the mentions dropdown list
|
And I click on the first user in the mentions dropdown list
|
||||||
And I press "Share"
|
And I press "Share"
|
||||||
And I follow "Bob Jones"
|
Then I should see "Bob Jones" within ".stream_element"
|
||||||
|
When I follow "Bob Jones"
|
||||||
Then I should see "Bob Jones"
|
Then I should see "Bob Jones"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ Feature: mentioning a contact from their profile page
|
||||||
And I want to mention her from the profile
|
And I want to mention her from the profile
|
||||||
And I append "I am eating a yogurt" to the publisher
|
And I append "I am eating a yogurt" to the publisher
|
||||||
And I press "Share" in the mention modal
|
And I press "Share" in the mention modal
|
||||||
|
Then I should see a flash message indicating success
|
||||||
When I am on the aspects page
|
When I am on the aspects page
|
||||||
And I follow "PostingTo" within "#aspects_list"
|
And I follow "PostingTo" within "#aspects_list"
|
||||||
Then I should see "I am eating a yogurt"
|
Then I should see "I am eating a yogurt"
|
||||||
|
|
@ -42,6 +43,7 @@ Feature: mentioning a contact from their profile page
|
||||||
And I press the aspect dropdown in the mention modal
|
And I press the aspect dropdown in the mention modal
|
||||||
And I append "I am eating a yogurt" to the publisher
|
And I append "I am eating a yogurt" to the publisher
|
||||||
And I press "Share" in the mention modal
|
And I press "Share" in the mention modal
|
||||||
|
Then I should see a flash message indicating success
|
||||||
|
|
||||||
When I am on the aspects page
|
When I am on the aspects page
|
||||||
And I select only "PostingTo" aspect
|
And I select only "PostingTo" aspect
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,14 @@ Feature: preview posts in the stream
|
||||||
And I press "Preview"
|
And I press "Preview"
|
||||||
Then I should see a "img" within ".stream_element div.photo_attachments"
|
Then I should see a "img" within ".stream_element div.photo_attachments"
|
||||||
And I should see "Look at this dog" within ".stream_element"
|
And I should see "Look at this dog" within ".stream_element"
|
||||||
|
And I close the publisher
|
||||||
|
|
||||||
Scenario: preview a post with mentions
|
Scenario: preview a post with mentions
|
||||||
Given I expand the publisher
|
Given I expand the publisher
|
||||||
And I mention Alice in the publisher
|
And I mention Alice in the publisher
|
||||||
And I press "Preview"
|
And I press "Preview"
|
||||||
And I follow "Alice Smith"
|
And I follow "Alice Smith"
|
||||||
|
And I confirm the alert
|
||||||
Then I should see "Alice Smith"
|
Then I should see "Alice Smith"
|
||||||
|
|
||||||
Scenario: preview a post on tag page
|
Scenario: preview a post on tag page
|
||||||
|
|
@ -67,6 +69,7 @@ Feature: preview posts in the stream
|
||||||
And I press "Preview"
|
And I press "Preview"
|
||||||
Then "This preview rocks" should be post 1
|
Then "This preview rocks" should be post 1
|
||||||
And the first post should be a preview
|
And the first post should be a preview
|
||||||
|
And I close the publisher
|
||||||
|
|
||||||
Scenario: preview a post with the poll
|
Scenario: preview a post with the poll
|
||||||
Given I expand the publisher
|
Given I expand the publisher
|
||||||
|
|
@ -82,3 +85,4 @@ Feature: preview posts in the stream
|
||||||
And I press "Preview"
|
And I press "Preview"
|
||||||
Then I should see a ".poll_form" within ".stream_element"
|
Then I should see a ".poll_form" within ".stream_element"
|
||||||
And I should see a "form" within ".stream_element"
|
And I should see a "form" within ".stream_element"
|
||||||
|
And I close the publisher
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,8 @@ Feature: posting from the main page
|
||||||
And I attach "spec/fixtures/button.png" to the publisher
|
And I attach "spec/fixtures/button.png" to the publisher
|
||||||
Then I should see an uploaded image within the photo drop zone
|
Then I should see an uploaded image within the photo drop zone
|
||||||
When I press "Share"
|
When I press "Share"
|
||||||
And I go to the aspects page
|
Then I should see a "img" within ".stream_element div.photo_attachments"
|
||||||
|
When I go to the aspects page
|
||||||
Then I should see a "img" within ".stream_element div.photo_attachments"
|
Then I should see a "img" within ".stream_element div.photo_attachments"
|
||||||
When I log out
|
When I log out
|
||||||
And I sign in as "alice@alice.alice"
|
And I sign in as "alice@alice.alice"
|
||||||
|
|
@ -108,6 +109,7 @@ Feature: posting from the main page
|
||||||
And I click to delete the first uploaded photo
|
And I click to delete the first uploaded photo
|
||||||
Then I should not see an uploaded image within the photo drop zone
|
Then I should not see an uploaded image within the photo drop zone
|
||||||
And the publisher should be expanded
|
And the publisher should be expanded
|
||||||
|
And I close the publisher
|
||||||
|
|
||||||
Scenario: back out of uploading a picture when another has been attached
|
Scenario: back out of uploading a picture when another has been attached
|
||||||
Given I expand the publisher
|
Given I expand the publisher
|
||||||
|
|
@ -118,6 +120,7 @@ Feature: posting from the main page
|
||||||
And I click to delete the first uploaded photo
|
And I click to delete the first uploaded photo
|
||||||
Then I should see an uploaded image within the photo drop zone
|
Then I should see an uploaded image within the photo drop zone
|
||||||
And the publisher should be expanded
|
And the publisher should be expanded
|
||||||
|
And I close the publisher
|
||||||
|
|
||||||
@wip
|
@wip
|
||||||
Scenario: hide a contact's post
|
Scenario: hide a contact's post
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,4 @@ Feature: posting from own profile page
|
||||||
And I attach "spec/fixtures/button.png" to the publisher
|
And I attach "spec/fixtures/button.png" to the publisher
|
||||||
And I click to delete the first uploaded photo
|
And I click to delete the first uploaded photo
|
||||||
Then I should not see an uploaded image within the photo drop zone
|
Then I should not see an uploaded image within the photo drop zone
|
||||||
|
And I close the publisher
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ Feature: show photos
|
||||||
And I have turned off jQuery effects
|
And I have turned off jQuery effects
|
||||||
And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload"
|
And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload"
|
||||||
And I press "Share"
|
And I press "Share"
|
||||||
|
Then I should see a "img" within ".stream_element div.photo_attachments"
|
||||||
|
|
||||||
Scenario: see my own photos
|
Scenario: see my own photos
|
||||||
When I am on "robert@grimm.grimm"'s page
|
When I am on "robert@grimm.grimm"'s page
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,10 @@ And /^I expand the publisher$/ do
|
||||||
click_publisher
|
click_publisher
|
||||||
end
|
end
|
||||||
|
|
||||||
|
And /^I close the publisher$/ do
|
||||||
|
find("#publisher #hide_publisher").click
|
||||||
|
end
|
||||||
|
|
||||||
Then /^the publisher should be expanded$/ do
|
Then /^the publisher should be expanded$/ do
|
||||||
find("#publisher")["class"].should_not include("closed")
|
find("#publisher")["class"].should_not include("closed")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
3
features/step_definitions/modal_steps.rb
Normal file
3
features/step_definitions/modal_steps.rb
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Then /I should see the mention modal/ do
|
||||||
|
step %{I should see a "#mentionModal.in"}
|
||||||
|
end
|
||||||
|
|
@ -176,6 +176,32 @@ describe("app.views.Publisher", function() {
|
||||||
expect(submitCallback).toHaveBeenCalled();
|
expect(submitCallback).toHaveBeenCalled();
|
||||||
expect($(this.view.el)).not.toHaveClass("closed");
|
expect($(this.view.el)).not.toHaveClass("closed");
|
||||||
})
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("_beforeUnload", function(){
|
||||||
|
beforeEach(function(){
|
||||||
|
Diaspora.I18n.load({ confirm_unload: "Please confirm that you want to leave this page - data you have entered won't be saved."});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls _submittable", function(){
|
||||||
|
spyOn(this.view, "_submittable");
|
||||||
|
$(window).trigger('beforeunload');
|
||||||
|
expect(this.view._submittable).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns a confirmation if the publisher is submittable", function(){
|
||||||
|
spyOn(this.view, "_submittable").and.returnValue(true);
|
||||||
|
var e = $.Event();
|
||||||
|
expect(this.view._beforeUnload(e)).toBe(Diaspora.I18n.t('confirm_unload'));
|
||||||
|
expect(e.returnValue).toBe(Diaspora.I18n.t('confirm_unload'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't ask for a confirmation if the publisher isn't submittable", function(){
|
||||||
|
spyOn(this.view, "_submittable").and.returnValue(false);
|
||||||
|
var e = $.Event();
|
||||||
|
expect(this.view._beforeUnload(e)).toBe(undefined);
|
||||||
|
expect(e.returnValue).toBe(undefined);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -280,7 +306,7 @@ describe("app.views.Publisher", function() {
|
||||||
// visibility icon is set to the lock icon
|
// visibility icon is set to the lock icon
|
||||||
expect(this.visibility_icon.hasClass('globe')).toBeFalsy();
|
expect(this.visibility_icon.hasClass('globe')).toBeFalsy();
|
||||||
expect(this.visibility_icon.hasClass('lock')).toBeTruthy();
|
expect(this.visibility_icon.hasClass('lock')).toBeTruthy();
|
||||||
|
|
||||||
// click on public
|
// click on public
|
||||||
this.radio_els.first().trigger('click');
|
this.radio_els.first().trigger('click');
|
||||||
// public is selected, "all aspects" is deselected
|
// public is selected, "all aspects" is deselected
|
||||||
|
|
@ -293,10 +319,10 @@ describe("app.views.Publisher", function() {
|
||||||
// visibility icon is set to the globe icon
|
// visibility icon is set to the globe icon
|
||||||
expect(this.visibility_icon.hasClass('globe')).toBeTruthy();
|
expect(this.visibility_icon.hasClass('globe')).toBeTruthy();
|
||||||
expect(this.visibility_icon.hasClass('lock')).toBeFalsy();
|
expect(this.visibility_icon.hasClass('lock')).toBeFalsy();
|
||||||
|
|
||||||
// click on "all aspects"
|
// click on "all aspects"
|
||||||
this.radio_els.last().trigger('click');
|
this.radio_els.last().trigger('click');
|
||||||
// public is deselected, "all aspects" is selected
|
// public is deselected, "all aspects" is selected
|
||||||
expect(this.radio_els.first().hasClass('selected')).toBeFalsy();
|
expect(this.radio_els.first().hasClass('selected')).toBeFalsy();
|
||||||
expect(this.radio_els.last().hasClass('selected')).toBeTruthy();
|
expect(this.radio_els.last().hasClass('selected')).toBeTruthy();
|
||||||
// the aspects are deselected
|
// the aspects are deselected
|
||||||
|
|
@ -305,7 +331,7 @@ describe("app.views.Publisher", function() {
|
||||||
});
|
});
|
||||||
// visibility icon is set to the lock icon
|
// visibility icon is set to the lock icon
|
||||||
expect(this.visibility_icon.hasClass('globe')).toBeFalsy();
|
expect(this.visibility_icon.hasClass('globe')).toBeFalsy();
|
||||||
expect(this.visibility_icon.hasClass('lock')).toBeTruthy();
|
expect(this.visibility_icon.hasClass('lock')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("hidden form elements", function(){
|
describe("hidden form elements", function(){
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue