summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuiza Pagliari <lpagliari@gmail.com>2017-05-29 11:05:37 -0300
committerGitHub <noreply@github.com>2017-05-29 11:05:37 -0300
commitb6cb46271bb0dede08831da20d7146465693f207 (patch)
tree68f570f4ca800aa9dfe20bf0ee9b8fa29cba9400
parentfaefa8a9efde5394a1bfbced295e2ed1565e5ab3 (diff)
parent894ebffcaf3d5fcab957f5e40d1fc94359003d54 (diff)
downloadetherpad-lite-b6cb46271bb0dede08831da20d7146465693f207.zip
Merge pull request #3182 from storytouch/fix/do_not_hide_force_reconnect_modal
Improvements on modals and "force reconnect" messages
-rw-r--r--src/static/js/ace2_inner.js9
-rw-r--r--src/static/js/pad.js44
-rw-r--r--src/static/js/pad_editbar.js24
-rw-r--r--tests/frontend/specs/pad_modal.js131
4 files changed, 180 insertions, 28 deletions
diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js
index b3759e52..424bacf5 100644
--- a/src/static/js/ace2_inner.js
+++ b/src/static/js/ace2_inner.js
@@ -3367,7 +3367,12 @@ function Ace2Inner(){
evt.preventDefault();
}
}
- //hide the dropdownso
+
+ hideEditBarDropdowns();
+ }
+
+ function hideEditBarDropdowns()
+ {
if(window.parent.parent.padeditbar){ // required in case its in an iframe should probably use parent.. See Issue 327 https://github.com/ether/etherpad-lite/issues/327
window.parent.parent.padeditbar.toggleDropDown("none");
}
@@ -4984,6 +4989,8 @@ function Ace2Inner(){
$(document).on("keypress", handleKeyEvent);
$(document).on("keyup", handleKeyEvent);
$(document).on("click", handleClick);
+ // dropdowns on edit bar need to be closed on clicks on both pad inner and pad outer
+ $(outerWin.document).on("click", hideEditBarDropdowns);
// Disabled: https://github.com/ether/etherpad-lite/issues/2546
// Will break OL re-numbering: https://github.com/ether/etherpad-lite/pull/2533
// $(document).on("cut", handleCut);
diff --git a/src/static/js/pad.js b/src/static/js/pad.js
index c967e461..4fefadf3 100644
--- a/src/static/js/pad.js
+++ b/src/static/js/pad.js
@@ -1,5 +1,5 @@
/**
- * This code is mostly from the old Etherpad. Please help us to comment this code.
+ * This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/
@@ -99,15 +99,15 @@ function getParams()
setting.callback(value);
}
}
-
+
// Then URL applied stuff
var params = getUrlVars()
-
+
for(var i = 0; i < getParameters.length; i++)
{
var setting = getParameters[i];
var value = params[setting.name];
-
+
if(value && (value == setting.checkVal || setting.checkVal == null))
{
setting.callback(value);
@@ -156,7 +156,7 @@ function sendClientReady(isReconnect, messageType)
token = "t." + randomString();
createCookie("token", token, 60);
}
-
+
var sessionID = decodeURIComponent(readCookie("sessionID"));
var password = readCookie("password");
@@ -169,14 +169,14 @@ function sendClientReady(isReconnect, messageType)
"token": token,
"protocolVersion": 2
};
-
+
//this is a reconnect, lets tell the server our revisionnumber
if(isReconnect == true)
{
msg.client_rev=pad.collabClient.getCurrentRevisionNumber();
msg.reconnect=true;
}
-
+
socket.json.send(msg);
}
@@ -203,12 +203,12 @@ function handshake()
socket.once('connect', function () {
sendClientReady(false);
});
-
+
socket.on('reconnect', function () {
pad.collabClient.setChannelState("CONNECTED");
pad.sendClientReady(true);
});
-
+
socket.on('reconnecting', function() {
pad.collabClient.setChannelState("RECONNECTING");
});
@@ -254,7 +254,7 @@ function handshake()
$("#passwordinput").focus();
}
}
-
+
//if we haven't recieved the clientVars yet, then this message should it be
else if (!receivedClientVars && obj.type == "CLIENT_VARS")
{
@@ -267,7 +267,7 @@ function handshake()
clientVars = obj.data;
clientVars.userAgent = "Anonymous";
clientVars.collab_client_vars.clientAgent = "Anonymous";
-
+
//initalize the pad
pad._afterHandshake();
initalized = true;
@@ -298,7 +298,7 @@ function handshake()
{
pad.changeViewOption('noColors', true);
}
-
+
if (settings.rtlIsTrue == true)
{
pad.changeViewOption('rtlIsTrue', true);
@@ -335,6 +335,12 @@ function handshake()
console.warn(obj);
padconnectionstatus.disconnected(obj.disconnect);
socket.disconnect();
+
+ // block user from making any change to the pad
+ padeditor.disable();
+ padeditbar.disable();
+ padimpexp.disable();
+
return;
}
else
@@ -345,13 +351,13 @@ function handshake()
});
// Bind the colorpicker
var fb = $('#colorpicker').farbtastic({ callback: '#mycolorpickerpreview', width: 220});
- // Bind the read only button
+ // Bind the read only button
$('#readonlyinput').on('click',function(){
padeditbar.setEmbedLinks();
});
}
-$.extend($.gritter.options, {
+$.extend($.gritter.options, {
position: 'bottom-right', // defaults to 'top-right' but can be 'bottom-left', 'bottom-right', 'top-left', 'top-right' (added in 1.7.1)
fade: false, // dont fade, too jerky on mobile
time: 6000 // hang on the screen for...
@@ -424,7 +430,7 @@ var pad = {
if(window.history && window.history.pushState)
{
$('#chattext p').remove(); //clear the chat messages
- window.history.pushState("", "", newHref);
+ window.history.pushState("", "", newHref);
receivedClientVars = false;
sendClientReady(false, 'SWITCH_TO_PAD');
}
@@ -731,20 +737,20 @@ var pad = {
pad.diagnosticInfo.disconnectedMessage = message;
pad.diagnosticInfo.padId = pad.getPadId();
pad.diagnosticInfo.socket = {};
-
- //we filter non objects from the socket object and put them in the diagnosticInfo
+
+ //we filter non objects from the socket object and put them in the diagnosticInfo
//this ensures we have no cyclic data - this allows us to stringify the data
for(var i in socket.socket)
{
var value = socket.socket[i];
var type = typeof value;
-
+
if(type == "string" || type == "number")
{
pad.diagnosticInfo.socket[i] = value;
}
}
-
+
pad.asyncSendDiagnosticInfo();
if (typeof window.ajlog == "string")
{
diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js
index dd1c377a..9cf357aa 100644
--- a/src/static/js/pad_editbar.js
+++ b/src/static/js/pad_editbar.js
@@ -259,18 +259,25 @@ var padeditbar = (function()
// hide all modules and remove highlighting of all buttons
if(moduleName == "none")
{
- var returned = false
+ var returned = false;
for(var i=0;i<self.dropdowns.length;i++)
{
+ var thisModuleName = self.dropdowns[i];
+
//skip the userlist
- if(self.dropdowns[i] == "users")
+ if(thisModuleName == "users")
continue;
- var module = $("#" + self.dropdowns[i]);
+ var module = $("#" + thisModuleName);
+
+ //skip any "force reconnect" message
+ var isAForceReconnectMessage = module.find('button#forcereconnect:visible').length > 0;
+ if(isAForceReconnectMessage)
+ continue;
if(module.css('display') != "none")
{
- $("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected");
+ $("li[data-key=" + thisModuleName + "] > a").removeClass("selected");
module.slideUp("fast", cb);
returned = true;
}
@@ -283,16 +290,17 @@ var padeditbar = (function()
// respectively add highlighting to the corresponding button
for(var i=0;i<self.dropdowns.length;i++)
{
- var module = $("#" + self.dropdowns[i]);
+ var thisModuleName = self.dropdowns[i];
+ var module = $("#" + thisModuleName);
if(module.css('display') != "none")
{
- $("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected");
+ $("li[data-key=" + thisModuleName + "] > a").removeClass("selected");
module.slideUp("fast");
}
- else if(self.dropdowns[i]==moduleName)
+ else if(thisModuleName==moduleName)
{
- $("li[data-key=" + self.dropdowns[i] + "] > a").addClass("selected");
+ $("li[data-key=" + thisModuleName + "] > a").addClass("selected");
module.slideDown("fast", cb);
}
}
diff --git a/tests/frontend/specs/pad_modal.js b/tests/frontend/specs/pad_modal.js
new file mode 100644
index 00000000..80752e4b
--- /dev/null
+++ b/tests/frontend/specs/pad_modal.js
@@ -0,0 +1,131 @@
+describe('Pad modal', function() {
+ context('when modal is a "force reconnect" message', function() {
+ var MODAL_SELECTOR = '#connectivity .slowcommit';
+
+ beforeEach(function(done) {
+ helper.newPad(function() {
+ // force a "slowcommit" error
+ helper.padChrome$.window.pad.handleChannelStateChange('DISCONNECTED', 'slowcommit');
+
+ // wait for modal to be displayed
+ var $modal = helper.padChrome$(MODAL_SELECTOR);
+ helper.waitFor(function() {
+ return $modal.is(':visible');
+ }, 50000).done(done);
+ });
+
+ this.timeout(60000);
+ });
+
+ it('disables editor', function(done) {
+ expect(isEditorDisabled()).to.be(true);
+
+ done();
+ });
+
+ context('and user clicks on editor', function() {
+ beforeEach(function() {
+ clickOnPadInner();
+ });
+
+ it('does not close the modal', function(done) {
+ var $modal = helper.padChrome$(MODAL_SELECTOR);
+ var modalIsVisible = $modal.is(':visible');
+
+ expect(modalIsVisible).to.be(true);
+
+ done();
+ });
+ });
+
+ context('and user clicks on pad outer', function() {
+ beforeEach(function() {
+ clickOnPadOuter();
+ });
+
+ it('does not close the modal', function(done) {
+ var $modal = helper.padChrome$(MODAL_SELECTOR);
+ var modalIsVisible = $modal.is(':visible');
+
+ expect(modalIsVisible).to.be(true);
+
+ done();
+ });
+ });
+ });
+
+ // we use "settings" here, but other modals have the same behaviour
+ context('when modal is not an error message', function() {
+ var MODAL_SELECTOR = '#settings';
+
+ beforeEach(function(done) {
+ helper.newPad(function() {
+ openSettingsAndWaitForModalToBeVisible(done);
+ });
+
+ this.timeout(60000);
+ });
+
+ it('does not disable editor', function(done) {
+ expect(isEditorDisabled()).to.be(false);
+ done();
+ });
+
+ context('and user clicks on editor', function() {
+ beforeEach(function() {
+ clickOnPadInner();
+ });
+
+ it('closes the modal', function(done) {
+ expect(isModalOpened(MODAL_SELECTOR)).to.be(false);
+ done();
+ });
+ });
+
+ context('and user clicks on pad outer', function() {
+ beforeEach(function() {
+ clickOnPadOuter();
+ });
+
+ it('closes the modal', function(done) {
+ expect(isModalOpened(MODAL_SELECTOR)).to.be(false);
+ done();
+ });
+ });
+ });
+
+ var clickOnPadInner = function() {
+ var $editor = helper.padInner$('#innerdocbody');
+ $editor.click();
+ }
+
+ var clickOnPadOuter = function() {
+ var $lineNumbersColumn = helper.padOuter$('#sidedivinner');
+ $lineNumbersColumn.click();
+ }
+
+ var openSettingsAndWaitForModalToBeVisible = function(done) {
+ helper.padChrome$('.buttonicon-settings').click();
+
+ // wait for modal to be displayed
+ var modalSelector = '#settings';
+ helper.waitFor(function() {
+ return isModalOpened(modalSelector);
+ }, 10000).done(done);
+ }
+
+ var isEditorDisabled = function() {
+ var editorDocument = helper.padOuter$("iframe[name='ace_inner']").get(0).contentDocument;
+ var editorBody = editorDocument.getElementById('innerdocbody');
+
+ var editorIsDisabled = editorBody.contentEditable === 'false' // IE/Safari
+ || editorDocument.designMode === 'off'; // other browsers
+
+ return editorIsDisabled;
+ }
+
+ var isModalOpened = function(modalSelector) {
+ var $modal = helper.padChrome$(modalSelector);
+ return $modal.is(':visible');
+ }
+});