Merge pull request #3182 from storytouch/fix/do_not_hide_force_reconnect_modal

Improvements on modals and "force reconnect" messages
pull/3196/head
Luiza Pagliari 2017-05-29 11:05:37 -03:00 committed by GitHub
commit b6cb46271b
4 changed files with 180 additions and 28 deletions

View File

@ -3367,7 +3367,12 @@ function Ace2Inner(){
evt.preventDefault(); 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 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"); window.parent.parent.padeditbar.toggleDropDown("none");
} }
@ -4984,6 +4989,8 @@ function Ace2Inner(){
$(document).on("keypress", handleKeyEvent); $(document).on("keypress", handleKeyEvent);
$(document).on("keyup", handleKeyEvent); $(document).on("keyup", handleKeyEvent);
$(document).on("click", handleClick); $(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 // Disabled: https://github.com/ether/etherpad-lite/issues/2546
// Will break OL re-numbering: https://github.com/ether/etherpad-lite/pull/2533 // Will break OL re-numbering: https://github.com/ether/etherpad-lite/pull/2533
// $(document).on("cut", handleCut); // $(document).on("cut", handleCut);

View File

@ -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. * This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/ */
@ -99,15 +99,15 @@ function getParams()
setting.callback(value); setting.callback(value);
} }
} }
// Then URL applied stuff // Then URL applied stuff
var params = getUrlVars() var params = getUrlVars()
for(var i = 0; i < getParameters.length; i++) for(var i = 0; i < getParameters.length; i++)
{ {
var setting = getParameters[i]; var setting = getParameters[i];
var value = params[setting.name]; var value = params[setting.name];
if(value && (value == setting.checkVal || setting.checkVal == null)) if(value && (value == setting.checkVal || setting.checkVal == null))
{ {
setting.callback(value); setting.callback(value);
@ -156,7 +156,7 @@ function sendClientReady(isReconnect, messageType)
token = "t." + randomString(); token = "t." + randomString();
createCookie("token", token, 60); createCookie("token", token, 60);
} }
var sessionID = decodeURIComponent(readCookie("sessionID")); var sessionID = decodeURIComponent(readCookie("sessionID"));
var password = readCookie("password"); var password = readCookie("password");
@ -169,14 +169,14 @@ function sendClientReady(isReconnect, messageType)
"token": token, "token": token,
"protocolVersion": 2 "protocolVersion": 2
}; };
//this is a reconnect, lets tell the server our revisionnumber //this is a reconnect, lets tell the server our revisionnumber
if(isReconnect == true) if(isReconnect == true)
{ {
msg.client_rev=pad.collabClient.getCurrentRevisionNumber(); msg.client_rev=pad.collabClient.getCurrentRevisionNumber();
msg.reconnect=true; msg.reconnect=true;
} }
socket.json.send(msg); socket.json.send(msg);
} }
@ -203,12 +203,12 @@ function handshake()
socket.once('connect', function () { socket.once('connect', function () {
sendClientReady(false); sendClientReady(false);
}); });
socket.on('reconnect', function () { socket.on('reconnect', function () {
pad.collabClient.setChannelState("CONNECTED"); pad.collabClient.setChannelState("CONNECTED");
pad.sendClientReady(true); pad.sendClientReady(true);
}); });
socket.on('reconnecting', function() { socket.on('reconnecting', function() {
pad.collabClient.setChannelState("RECONNECTING"); pad.collabClient.setChannelState("RECONNECTING");
}); });
@ -254,7 +254,7 @@ function handshake()
$("#passwordinput").focus(); $("#passwordinput").focus();
} }
} }
//if we haven't recieved the clientVars yet, then this message should it be //if we haven't recieved the clientVars yet, then this message should it be
else if (!receivedClientVars && obj.type == "CLIENT_VARS") else if (!receivedClientVars && obj.type == "CLIENT_VARS")
{ {
@ -267,7 +267,7 @@ function handshake()
clientVars = obj.data; clientVars = obj.data;
clientVars.userAgent = "Anonymous"; clientVars.userAgent = "Anonymous";
clientVars.collab_client_vars.clientAgent = "Anonymous"; clientVars.collab_client_vars.clientAgent = "Anonymous";
//initalize the pad //initalize the pad
pad._afterHandshake(); pad._afterHandshake();
initalized = true; initalized = true;
@ -298,7 +298,7 @@ function handshake()
{ {
pad.changeViewOption('noColors', true); pad.changeViewOption('noColors', true);
} }
if (settings.rtlIsTrue == true) if (settings.rtlIsTrue == true)
{ {
pad.changeViewOption('rtlIsTrue', true); pad.changeViewOption('rtlIsTrue', true);
@ -335,6 +335,12 @@ function handshake()
console.warn(obj); console.warn(obj);
padconnectionstatus.disconnected(obj.disconnect); padconnectionstatus.disconnected(obj.disconnect);
socket.disconnect(); socket.disconnect();
// block user from making any change to the pad
padeditor.disable();
padeditbar.disable();
padimpexp.disable();
return; return;
} }
else else
@ -345,13 +351,13 @@ function handshake()
}); });
// Bind the colorpicker // Bind the colorpicker
var fb = $('#colorpicker').farbtastic({ callback: '#mycolorpickerpreview', width: 220}); var fb = $('#colorpicker').farbtastic({ callback: '#mycolorpickerpreview', width: 220});
// Bind the read only button // Bind the read only button
$('#readonlyinput').on('click',function(){ $('#readonlyinput').on('click',function(){
padeditbar.setEmbedLinks(); 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) 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 fade: false, // dont fade, too jerky on mobile
time: 6000 // hang on the screen for... time: 6000 // hang on the screen for...
@ -424,7 +430,7 @@ var pad = {
if(window.history && window.history.pushState) if(window.history && window.history.pushState)
{ {
$('#chattext p').remove(); //clear the chat messages $('#chattext p').remove(); //clear the chat messages
window.history.pushState("", "", newHref); window.history.pushState("", "", newHref);
receivedClientVars = false; receivedClientVars = false;
sendClientReady(false, 'SWITCH_TO_PAD'); sendClientReady(false, 'SWITCH_TO_PAD');
} }
@ -731,20 +737,20 @@ var pad = {
pad.diagnosticInfo.disconnectedMessage = message; pad.diagnosticInfo.disconnectedMessage = message;
pad.diagnosticInfo.padId = pad.getPadId(); pad.diagnosticInfo.padId = pad.getPadId();
pad.diagnosticInfo.socket = {}; 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 //this ensures we have no cyclic data - this allows us to stringify the data
for(var i in socket.socket) for(var i in socket.socket)
{ {
var value = socket.socket[i]; var value = socket.socket[i];
var type = typeof value; var type = typeof value;
if(type == "string" || type == "number") if(type == "string" || type == "number")
{ {
pad.diagnosticInfo.socket[i] = value; pad.diagnosticInfo.socket[i] = value;
} }
} }
pad.asyncSendDiagnosticInfo(); pad.asyncSendDiagnosticInfo();
if (typeof window.ajlog == "string") if (typeof window.ajlog == "string")
{ {

View File

@ -259,18 +259,25 @@ var padeditbar = (function()
// hide all modules and remove highlighting of all buttons // hide all modules and remove highlighting of all buttons
if(moduleName == "none") if(moduleName == "none")
{ {
var returned = false var returned = false;
for(var i=0;i<self.dropdowns.length;i++) for(var i=0;i<self.dropdowns.length;i++)
{ {
var thisModuleName = self.dropdowns[i];
//skip the userlist //skip the userlist
if(self.dropdowns[i] == "users") if(thisModuleName == "users")
continue; 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") 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); module.slideUp("fast", cb);
returned = true; returned = true;
} }
@ -283,16 +290,17 @@ var padeditbar = (function()
// respectively add highlighting to the corresponding button // respectively add highlighting to the corresponding button
for(var i=0;i<self.dropdowns.length;i++) 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") if(module.css('display') != "none")
{ {
$("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected"); $("li[data-key=" + thisModuleName + "] > a").removeClass("selected");
module.slideUp("fast"); 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); module.slideDown("fast", cb);
} }
} }

View File

@ -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');
}
});