|
|
|
@ -18,12 +18,13 @@ define([
|
|
|
|
|
'html-patcher',
|
|
|
|
|
'errorbox',
|
|
|
|
|
'messages',
|
|
|
|
|
'bower/reconnectingWebsocket/reconnecting-websocket',
|
|
|
|
|
'rangy',
|
|
|
|
|
'chainpad',
|
|
|
|
|
'otaml',
|
|
|
|
|
'bower/jquery/dist/jquery.min',
|
|
|
|
|
'bower/tweetnacl/nacl-fast.min'
|
|
|
|
|
], function (HTMLPatcher, ErrorBox, Messages) {
|
|
|
|
|
], function (HTMLPatcher, ErrorBox, Messages, ReconnectingWebSocket) {
|
|
|
|
|
|
|
|
|
|
window.ErrorBox = ErrorBox;
|
|
|
|
|
|
|
|
|
@ -129,33 +130,29 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
var updateUserList = function (myUserName, listElement, userList) {
|
|
|
|
|
var meIdx = userList.indexOf(myUserName);
|
|
|
|
|
if (meIdx === -1) {
|
|
|
|
|
listElement.text(Messages.synchronizing);
|
|
|
|
|
listElement.textContent = Messages.synchronizing;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (userList.length === 1) {
|
|
|
|
|
listElement.text(Messages.editingAlone);
|
|
|
|
|
listElement.textContent = Messages.editingAlone;
|
|
|
|
|
} else if (userList.length === 2) {
|
|
|
|
|
listElement.text(Messages.editingWithOneOtherPerson);
|
|
|
|
|
listElement.textContent = Messages.editingWithOneOtherPerson;
|
|
|
|
|
} else {
|
|
|
|
|
listElement.text(Messages.editingWith + ' ' + (userList.length - 1) +
|
|
|
|
|
Messages.otherPeople);
|
|
|
|
|
listElement.textContent = Messages.editingWith + ' ' + (userList.length - 1) +
|
|
|
|
|
Messages.otherPeople;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var createUserList = function (realtime, myUserName, container) {
|
|
|
|
|
var createUserList = function (container) {
|
|
|
|
|
var id = uid();
|
|
|
|
|
$(container).prepend('<div class="' + USER_LIST_CLS + '" id="'+id+'"></div>');
|
|
|
|
|
var listElement = $('#'+id);
|
|
|
|
|
realtime.onUserListChange(function (userList) {
|
|
|
|
|
updateUserList(myUserName, listElement, userList);
|
|
|
|
|
});
|
|
|
|
|
return listElement;
|
|
|
|
|
return $('#'+id)[0];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var abort = function (socket, realtime) {
|
|
|
|
|
realtime.abort();
|
|
|
|
|
try { socket._socket.close(); } catch (e) { }
|
|
|
|
|
$('.'+USER_LIST_CLS).text("Disconnected");
|
|
|
|
|
$('.'+USER_LIST_CLS).text(Messages.disconnected);
|
|
|
|
|
$('.'+LAG_ELEM_CLS).text("");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -300,18 +297,13 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
} else {
|
|
|
|
|
lagMsg += lagSec;
|
|
|
|
|
}
|
|
|
|
|
lagElement.text(lagMsg);
|
|
|
|
|
lagElement.textContent = lagMsg;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var createLagElement = function (socket, realtime, container) {
|
|
|
|
|
var createLagElement = function (container) {
|
|
|
|
|
var id = uid();
|
|
|
|
|
$(container).append('<div class="' + LAG_ELEM_CLS + '" id="'+id+'"></div>');
|
|
|
|
|
var lagElement = $('#'+id);
|
|
|
|
|
var intr = setInterval(function () {
|
|
|
|
|
checkLag(realtime, lagElement);
|
|
|
|
|
}, 3000);
|
|
|
|
|
socket.onClose.push(function () { clearTimeout(intr); });
|
|
|
|
|
return lagElement;
|
|
|
|
|
return $('#'+id)[0];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var createSpinner = function (container) {
|
|
|
|
@ -376,7 +368,7 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var makeWebsocket = function (url) {
|
|
|
|
|
var socket = new WebSocket(url);
|
|
|
|
|
var socket = new ReconnectingWebSocket(url);
|
|
|
|
|
var out = {
|
|
|
|
|
onOpen: [],
|
|
|
|
|
onClose: [],
|
|
|
|
@ -460,16 +452,12 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
|
|
|
|
|
var toolbar = createRealtimeToolbar('#cke_1_toolbox');
|
|
|
|
|
|
|
|
|
|
socket.onClose.push(function () {
|
|
|
|
|
$(toolbar).remove();
|
|
|
|
|
checkSocket();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var allMessages = [];
|
|
|
|
|
var isErrorState = false;
|
|
|
|
|
var initializing = true;
|
|
|
|
|
var recoverableErrorCount = 0;
|
|
|
|
|
var error = function (recoverable, err) {
|
|
|
|
|
console.log(new Error().stack);
|
|
|
|
|
console.log('error: ' + err.stack);
|
|
|
|
|
if (recoverable && recoverableErrorCount++ < MAX_RECOVERABLE_ERRORS) { return; }
|
|
|
|
|
var realtime = socket.realtime;
|
|
|
|
@ -489,15 +477,19 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
};
|
|
|
|
|
var checkSocket = function () {
|
|
|
|
|
if (isSocketDisconnected(socket, socket.realtime) && !socket.intentionallyClosing) {
|
|
|
|
|
isErrorState = true;
|
|
|
|
|
abort(socket, socket.realtime);
|
|
|
|
|
ErrorBox.show('disconnected', getDocHTML(doc));
|
|
|
|
|
//isErrorState = true;
|
|
|
|
|
//abort(socket, socket.realtime);
|
|
|
|
|
//ErrorBox.show('disconnected', getDocHTML(doc));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
socket.onOpen.push(function (evt) {
|
|
|
|
|
if (!initializing) {
|
|
|
|
|
socket.realtime.start();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var realtime = socket.realtime =
|
|
|
|
|
ChainPad.create(userName,
|
|
|
|
@ -508,11 +500,14 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
|
|
|
|
|
//createDebugLink(realtime, doc, allMessages, toolbar);
|
|
|
|
|
|
|
|
|
|
createUserList(realtime,
|
|
|
|
|
userName,
|
|
|
|
|
toolbar.find('.rtwysiwyg-toolbar-leftside'));
|
|
|
|
|
|
|
|
|
|
var userListElement = createUserList(toolbar.find('.rtwysiwyg-toolbar-leftside'));
|
|
|
|
|
var spinner = createSpinner(toolbar.find('.rtwysiwyg-toolbar-rightside'));
|
|
|
|
|
var lagElement = createLagElement(toolbar.find('.rtwysiwyg-toolbar-rightside'));
|
|
|
|
|
|
|
|
|
|
setInterval(function () {
|
|
|
|
|
if (initializing || isSocketDisconnected(socket, realtime)) { return; }
|
|
|
|
|
checkLag(realtime, lagElement);
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
|
|
onEvent = function () {
|
|
|
|
|
if (isErrorState) { return; }
|
|
|
|
@ -552,13 +547,11 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
realtime.onUserListChange(function (userList) {
|
|
|
|
|
updateUserList(userName, userListElement, userList);
|
|
|
|
|
if (!initializing || userList.indexOf(userName) === -1) { return; }
|
|
|
|
|
// if we spot ourselves being added to the document, we'll switch
|
|
|
|
|
// 'initializing' off because it means we're fully synced.
|
|
|
|
|
initializing = false;
|
|
|
|
|
createLagElement(socket,
|
|
|
|
|
realtime,
|
|
|
|
|
toolbar.find('.rtwysiwyg-toolbar-rightside'));
|
|
|
|
|
incomingPatch();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -578,21 +571,19 @@ window.ErrorBox = ErrorBox;
|
|
|
|
|
try {
|
|
|
|
|
socket.send(message);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
if (!checkSocket()) { error(true, e.stack); }
|
|
|
|
|
error(true, e.stack);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
realtime.onPatch(incomingPatch);
|
|
|
|
|
|
|
|
|
|
socket.onError.push(function (err) {
|
|
|
|
|
if (isErrorState) { return; }
|
|
|
|
|
if (!checkSocket()) { error(true, err); }
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
bindAllEvents(wysiwygDiv, doc.body, onEvent, false);
|
|
|
|
|
|
|
|
|
|
setInterval(function () {
|
|
|
|
|
if (isErrorState || checkSocket()) { return; }
|
|
|
|
|
if (isErrorState || checkSocket()) {
|
|
|
|
|
userListElement.textContent = Messages.reconnecting;
|
|
|
|
|
lagElement.textContent = '';
|
|
|
|
|
}
|
|
|
|
|
}, 200);
|
|
|
|
|
|
|
|
|
|
realtime.start();
|
|
|
|
|