From bbdc9da85391d07d1c4e5db0fbde127a3db7a980 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 08:19:28 +0200 Subject: [PATCH 01/13] delete duplicated file --- www/common/RealtimeTextarea.js | 207 --------------------------------- 1 file changed, 207 deletions(-) delete mode 100644 www/common/RealtimeTextarea.js diff --git a/www/common/RealtimeTextarea.js b/www/common/RealtimeTextarea.js deleted file mode 100644 index ee9fcdeb8..000000000 --- a/www/common/RealtimeTextarea.js +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2014 XWiki SAS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -define([ - '/common/messages.js', - '/bower_components/reconnectingWebsocket/reconnecting-websocket.js', - '/common/crypto.js', - '/common/chainpad.js', - '/bower_components/jquery/dist/jquery.min.js', -], function (Messages, ReconnectingWebSocket, Crypto) { - var $ = window.jQuery; - var ChainPad = window.ChainPad; - var PARANOIA = true; - var module = { exports: {} }; - - /** - * If an error is encountered but it is recoverable, do not immediately fail - * but if it keeps firing errors over and over, do fail. - */ - var MAX_RECOVERABLE_ERRORS = 15; - - /** Maximum number of milliseconds of lag before we fail the connection. */ - var MAX_LAG_BEFORE_DISCONNECT = 20000; - - var warn = function (x) { console.error(x); }; - - /* websocket stuff */ - var isSocketDisconnected = function (socket, realtime) { - var sock = socket._socket; - return sock.readyState === sock.CLOSING - || sock.readyState === sock.CLOSED - || (realtime.getLag().waiting && realtime.getLag().lag > MAX_LAG_BEFORE_DISCONNECT); - }; - - // this differs from other functions with similar names in that - // you are expected to pass a socket into it. - var checkSocket = function (socket) { - if (isSocketDisconnected(socket, socket.realtime) && - !socket.intentionallyClosing) { - return true; - } else { - return false; - } - }; - - // TODO before removing websocket implementation - // bind abort to onLeaving - var abort = function (socket, realtime) { - realtime.abort(); - try { socket._socket.close(); } catch (e) { warn(e); } - }; - - var makeWebsocket = function (url) { - var socket = new ReconnectingWebSocket(url); - var out = { - onOpen: [], - onClose: [], - onError: [], - onMessage: [], - send: function (msg) { socket.send(msg); }, - close: function () { socket.close(); }, - _socket: socket - }; - var mkHandler = function (name) { - return function (evt) { - for (var i = 0; i < out[name].length; i++) { - if (out[name][i](evt) === false) { - console.log(name +"Handler"); - return; - } - } - }; - }; - socket.onopen = mkHandler('onOpen'); - socket.onclose = mkHandler('onClose'); - socket.onerror = mkHandler('onError'); - socket.onmessage = mkHandler('onMessage'); - return out; - }; - /* end websocket stuff */ - - var start = module.exports.start = function (config) { - - var websocketUrl = config.websocketURL; - var userName = config.userName; - var channel = config.channel; - var cryptKey = config.cryptKey; - var passwd = 'y'; - - var toReturn = {}; - - var socket = makeWebsocket(websocketUrl); - - var allMessages = []; - var isErrorState = false; - var initializing = true; - var recoverableErrorCount = 0; - - socket.onOpen.push(function (evt) { - var realtime = socket.realtime = ChainPad.create(userName, - passwd, - channel, - config.initialState || '', - { - transformFunction: config.transformFunction - }); - - if (config.onInit) { - // extend as you wish - config.onInit({ - realtime: realtime - }); - } - - realtime.onUserListChange(function (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; - - // execute an onReady callback if one was supplied - // pass an object so we can extend this later - if (config.onReady) { - // extend as you wish - config.onReady({ - userList: userList, - realtime: realtime - }); - } - }); - - // when you receive a message... - socket.onMessage.push(function (evt) { - if (isErrorState) { return; } - - var message = Crypto.decrypt(evt.data, cryptKey); - allMessages.push(message); - - // super important step that avoids us having - // the 'backspace bug' - if (config.onLocal) { - config.onLocal(); - } - - realtime.message(message); - }); - - // when you receive a patch - realtime.onPatch(function () { - if (config.onRemote) { - config.onRemote({ - realtime: realtime - }); - } - }); - - // when a message is ready to send - realtime.onMessage(function (message) { - if (isErrorState) { return; } - message = Crypto.encrypt(message, cryptKey); - try { - socket.send(message); - } catch (e) { - warn(e); - } - }); - - var socketChecker = setInterval(function () { - if (checkSocket(socket)) { - warn("Socket disconnected!"); - - recoverableErrorCount += 1; - - if (recoverableErrorCount >= MAX_RECOVERABLE_ERRORS) { - warn("Giving up!"); - abort(socket, realtime); - if (config.onAbort) { - config.onAbort({ - realtime: realtime - }); - } - if (socketChecker) { clearInterval(socketChecker); } - } - } - },200); - - realtime.start(); - }); - return toReturn; - }; - return module.exports; -}); From 2c6cf9883b11bd888737aaebde1aaf9629b21568 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 08:19:58 +0200 Subject: [PATCH 02/13] stop using deleted file --- www/text/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/text/main.js b/www/text/main.js index 0143a0f10..0db823560 100644 --- a/www/text/main.js +++ b/www/text/main.js @@ -1,6 +1,6 @@ define([ '/api/config?cb=' + Math.random().toString(16).substring(2), - '/common/RealtimeTextarea.js', + '/common/RealtimeTextSocket.js', '/common/messages.js', '/common/crypto.js', '/common/TextPatcher.js', From b140b6429d64b79bf9190c168f774bd3a4149876 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 09:46:06 +0200 Subject: [PATCH 03/13] remove a little bit of dead code --- www/common/realtime-input.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/www/common/realtime-input.js b/www/common/realtime-input.js index 7e818f8ae..6a958e406 100644 --- a/www/common/realtime-input.js +++ b/www/common/realtime-input.js @@ -51,8 +51,6 @@ define([ // make sure configuration is defined config = config || {}; - var doc = config.doc || null; - var allMessages = []; var initializing = true; var recoverableErrorCount = 0; // unused @@ -107,8 +105,6 @@ define([ // we're fully synced initializing = false; - // execute an onReady callback if one was supplied - // FIXME this should be once the chain has synced if (config.onReady) { config.onReady({ realtime: realtime From 4c9560234795fbed738d20d8679ddc3e8be9dc95 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 09:46:41 +0200 Subject: [PATCH 04/13] remove a little bit more dead code --- www/pad/main.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/www/pad/main.js b/www/pad/main.js index c535b678b..09055bc33 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -250,14 +250,10 @@ define([ // our encryption key cryptKey: key, - // configuration :D - doc: inner, - setMyID: setMyID, // really basic operational transform transformFunction : JsonOT.validate - // pass in websocket/netflux object TODO }; var onRemote = realtimeOptions.onRemote = function (info) { From d4943511fe47d1efbff20d201fcab6534f7a6553 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 09:47:26 +0200 Subject: [PATCH 05/13] move text/ and hack/ to Netflux --- www/hack/main.js | 36 +++++++++++++++++++++++------------- www/text/main.js | 31 ++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/www/hack/main.js b/www/hack/main.js index 8805a3169..8830b9007 100644 --- a/www/hack/main.js +++ b/www/hack/main.js @@ -1,21 +1,28 @@ define([ '/api/config?cb=' + Math.random().toString(16).substring(2), - '/common/RealtimeTextarea.js', + '/common/realtime-input.js', '/common/crypto.js', '/common/TextPatcher.js', '/bower_components/jquery/dist/jquery.min.js' ], function (Config, Realtime, Crypto, TextPatcher) { var $ = window.jQuery; + /* $(window).on('hashchange', function() { window.location.reload(); - }); + });*/ + + var key; + var channel = ''; if (window.location.href.indexOf('#') === -1) { - window.location.href = window.location.href + '#' + Crypto.genKey(); - return; + key = Crypto.genKey(); + //window.location.href = window.location.href + '#' + Crypto.genKey(); + //return; + } else { + var hash = window.location.hash.substr(1); + channel = hash.substr(0,32); + key = hash.substr(32); } - var key = Crypto.parseKey(window.location.hash.substring(1)); - var $textarea = $('textarea'), $run = $('#run'); @@ -29,13 +36,14 @@ define([ transformFunction */ + var userName = Crypto.rand64(8); + var config = { - textarea: $textarea[0], - websocketURL: Config.websocketURL + '_old', - webrtcURL: Config.webrtcURL, - userName: Crypto.rand64(8), - channel: key.channel, - cryptKey: key.cryptKey, + initialState: '', + websocketURL: Config.websocketURL, + userName: userName, + channel: channel, + cryptKey: key, }; var initializing = true; @@ -44,7 +52,9 @@ define([ setEditable(false); - var onInit = config.onInit = function (info) { }; + var onInit = config.onInit = function (info) { + window.location.hash = info.channel + key; + }; var onRemote = config.onRemote = function (info) { if (initializing) { return; } diff --git a/www/text/main.js b/www/text/main.js index 0db823560..644fa86f6 100644 --- a/www/text/main.js +++ b/www/text/main.js @@ -1,6 +1,6 @@ define([ '/api/config?cb=' + Math.random().toString(16).substring(2), - '/common/RealtimeTextSocket.js', + '/common/realtime-input.js', '/common/messages.js', '/common/crypto.js', '/common/TextPatcher.js', @@ -11,22 +11,37 @@ define([ $(window).on('hashchange', function() { window.location.reload(); }); + /* if (window.location.href.indexOf('#') === -1) { window.location.href = window.location.href + '#' + Crypto.genKey(); return; + }*/ + + + var key; + var channel = ''; + if (window.location.href.indexOf('#') === -1) { + key = Crypto.genKey(); + } else { + var hash = window.location.hash.substr(1); + channel = hash.substr(0, 32); + key = hash.substr(32); } var module = window.APP = {}; - var key = Crypto.parseKey(window.location.hash.substring(1)); + + var userName = module.userName = Crypto.rand64(8); + var initializing = true; var $textarea = $('textarea'); var config = module.config = { + initialState: '', textarea: $textarea[0], - websocketURL: Config.websocketURL + '_old', - userName: Crypto.rand64(8), - channel: key.channel, - cryptKey: key.cryptKey + websocketURL: Config.websocketURL, + userName: userName, + channel: channel, + cryptKey: key, }; var setEditable = function (bool) { $textarea.attr('disabled', !bool); }; @@ -34,7 +49,9 @@ define([ setEditable(false); - var onInit = config.onInit = function (info) { }; + var onInit = config.onInit = function (info) { + window.location.hash = info.channel + key; + }; var onRemote = config.onRemote = function (info) { if (initializing) { return; } From be1ef7abe32c42a9048f4afae8d1cbf7f1eee872 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 10:04:54 +0200 Subject: [PATCH 06/13] migrate canvas to netflux --- www/canvas/main.js | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/www/canvas/main.js b/www/canvas/main.js index f25b64ecb..1a52213ff 100644 --- a/www/canvas/main.js +++ b/www/canvas/main.js @@ -4,7 +4,7 @@ require.config({ paths: { define([ '/api/config?cb=' + Math.random().toString(16).substring(2), - '/common/RealtimeTextarea.js', + '/common/realtime-input.js', '/common/messages.js', '/common/crypto.js', '/common/TextPatcher.js', @@ -17,12 +17,15 @@ define([ var $ = module.$ = window.jQuery; var Fabric = module.Fabric = window.fabric; - $(window).on('hashchange', function() { - window.location.reload(); - }); - if (window.location.href.indexOf('#') === -1) { - window.location.href = window.location.href + '#' + Crypto.genKey(); - return; + + var key; + var channel = ''; + if (!/#/.test(window.location.href)) { + key = Crypto.genKey(); + } else { + var hash = window.location.hash.slice(1); + channel = hash.slice(0, 32); + key = hash.slice(32); } /* Initialize Fabric */ @@ -56,17 +59,22 @@ define([ $canvas.css('border-color', bool? 'black': 'red'); }; - var key = Crypto.parseKey(window.location.hash.substring(1)); var initializing = true; var config = module.config = { - websocketURL: Config.websocketURL + '_old', + // TODO initialState ? + websocketURL: Config.websocketURL, userName: Crypto.rand64(8), - channel: key.channel, - cryptKey: key.cryptKey + channel: channel, + cryptKey: key, }; - var onInit = config.onInit = function (info) { }; + var onInit = config.onInit = function (info) { + window.location.hash = info.channel + key; + $(window).on('hashchange', function() { + window.location.reload(); + }); + }; var onRemote = config.onRemote = function () { if (initializing) { return; } From e83e5026cec3826d4e91a4b16adf9d71dc543d2f Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 10:54:44 +0200 Subject: [PATCH 07/13] make amnesiadb compatible with netflux --- storage/amnesia.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/storage/amnesia.js b/storage/amnesia.js index f068a5e75..bd414b8fb 100644 --- a/storage/amnesia.js +++ b/storage/amnesia.js @@ -18,6 +18,7 @@ module.exports.create = function(conf, cb){ var db=[], index=0; + cb({ message: function(channelName, content, cb){ var val = { @@ -27,17 +28,18 @@ module.exports.create = function(conf, cb){ time: new Date().getTime(), }; db.push(val); - cb(); + if (cb) { cb(); } }, - getMessages: function(channelName, cb){ + getMessages: function(channelName, handler, cb){ db.sort(function(a,b){ return a.id - b.id; }); db.filter(function(val){ return val.chan === channelName; }).forEach(function(doc){ - cb(doc.msg); + handler(doc.msg); }); + if (cb) { cb(); } }, }); }; From 60eb8b52a9e908350327b0b2e001e5e1f847e407 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 10:55:20 +0200 Subject: [PATCH 08/13] listen for websockets on the same port as the httpd --- config.js.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.js.dist b/config.js.dist index f61828e4c..e2f521963 100644 --- a/config.js.dist +++ b/config.js.dist @@ -10,7 +10,7 @@ module.exports = { // the port on which your httpd will listen httpPort: 3000, // the port used for websockets - websocketPort: 3001, + websocketPort: 3000, // You now have a choice of storage engines From 2c158558f5558d28ea47c15cfbaf67ea2aa488d7 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 11:05:54 +0200 Subject: [PATCH 09/13] use leveldb adaptor by default --- config.js.dist | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.js.dist b/config.js.dist index e2f521963..b79777eb7 100644 --- a/config.js.dist +++ b/config.js.dist @@ -19,7 +19,7 @@ module.exports = { * it will not scale well if your server stays alive for a long time. * but it is completely dependency free */ - storage: './storage/amnesia', + //storage: './storage/amnesia', /* the 'lvl' storage module uses leveldb * it persists, and will perform better than amnesiadb @@ -31,8 +31,8 @@ module.exports = { * * to delete all pads, run `rm -rf $YOUR_DB` */ - // storage: './storage/lvl', - // levelPath: './test.level.db' + storage: './storage/lvl', + levelPath: './test.level.db' /* mongo is the original storage engine for cryptpad * it has been more thoroughly tested, but requires a little more setup From 8ac69ca2621cd2311300815ce2ea42c39fddd9b1 Mon Sep 17 00:00:00 2001 From: Yann Flory Date: Fri, 22 Apr 2016 11:46:27 +0200 Subject: [PATCH 10/13] Add a missing "time" property in the netflux client causing incorrect timeout errors --- www/common/netflux-client.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/common/netflux-client.js b/www/common/netflux-client.js index e6567229a..7d436f018 100644 --- a/www/common/netflux-client.js +++ b/www/common/netflux-client.js @@ -51,6 +51,7 @@ const mkChannel = (ctx, id) => { }; const chan = { _: internal, + time: now(), id: id, members: internal.members, bcast: (msg) => channelBcast(ctx, chan.id, msg), From d3203d1c2a4afda9ba52d48ec3ae825bdfac391c Mon Sep 17 00:00:00 2001 From: Yann Flory Date: Fri, 22 Apr 2016 14:26:37 +0200 Subject: [PATCH 11/13] Remove Crypto from the modules loaded with RequireJS in realtime-input It now has to be passed in the config in the main JS file --- www/common/realtime-input.js | 44 ++++++++++++++++++++---------------- www/pad/main.js | 32 ++++++++++++++------------ 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/www/common/realtime-input.js b/www/common/realtime-input.js index 6a958e406..5a8726e35 100644 --- a/www/common/realtime-input.js +++ b/www/common/realtime-input.js @@ -15,16 +15,15 @@ * along with this program. If not, see . */ define([ - '/common/messages.js', '/common/netflux-client.js', - '/common/crypto.js', '/common/es6-promise.min.js', '/common/chainpad.js', '/bower_components/jquery/dist/jquery.min.js', -], function (Messages, Netflux, Crypto) { +], function (Netflux) { var $ = window.jQuery; var ChainPad = window.ChainPad; var PARANOIA = true; + var USE_HISTORY = true; var module = { exports: {} }; /** @@ -44,14 +43,14 @@ define([ var websocketUrl = config.websocketURL; var userName = config.userName; var channel = config.channel; - var chanKey = config.cryptKey; + var chanKey = config.cryptKey || ''; + var Crypto = config.crypto; var cryptKey = Crypto.parseKey(chanKey).cryptKey; var passwd = 'y'; // make sure configuration is defined config = config || {}; - var allMessages = []; var initializing = true; var recoverableErrorCount = 0; // unused var toReturn = {}; @@ -99,6 +98,11 @@ define([ }; var onReady = function(wc, network) { + if(config.setMyID) { + config.setMyID({ + myID: wc.myID + }); + } // Trigger onJoining with our own Cryptpad username to tell the toolbar that we are synced onJoining(wc.myID); @@ -127,11 +131,10 @@ define([ var message = chainpadAdapter.msgIn(peer, msg); verbose(message); - allMessages.push(message); if (!initializing) { - if (toReturn.onLocal) { - toReturn.onLocal(); + if (config.onLocal) { + config.onLocal(); } } // pass the message into Chainpad @@ -205,11 +208,6 @@ define([ wc.on('join', onJoining); wc.on('leave', onLeaving); - if(config.setMyID) { - config.setMyID({ - myID: wc.myID - }); - } // Open a Chainpad session realtime = createRealtime(); @@ -249,14 +247,22 @@ define([ }); // Get the channel history - var hc; - wc.members.forEach(function (p) { - if (p.length === 16) { hc = p; } - }); - wc.history_keeper = hc; - if (hc) { network.sendto(hc, JSON.stringify(['GET_HISTORY', wc.id])); } + if(USE_HISTORY) { + var hc; + + wc.members.forEach(function (p) { + if (p.length === 16) { hc = p; } + }); + wc.history_keeper = hc; + + if (hc) { network.sendto(hc, JSON.stringify(['GET_HISTORY', wc.id])); } + } realtime.start(); + + if(!USE_HISTORY) { + onReady(wc, network); + } }; var findChannelById = function(webChannels, channelId) { diff --git a/www/pad/main.js b/www/pad/main.js index 09055bc33..11b45843e 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -87,7 +87,6 @@ define([ } var fixThings = false; - // var key = Crypto.parseKey(window.location.hash.substring(1)); var editor = window.editor = Ckeditor.replace('editor1', { // https://dev.ckeditor.com/ticket/10907 needsBrFiller: fixThings, @@ -184,7 +183,6 @@ define([ } }; - var now = function () { return new Date().getTime(); }; var initializing = true; var userList = {}; // List of pretty name of all users (mapped with their server ID) @@ -250,12 +248,29 @@ define([ // our encryption key cryptKey: key, + // method which allows us to get the id of the user setMyID: setMyID, + // Crypto object to avoid loading it twice in Cryptpad + crypto: Crypto, + // really basic operational transform transformFunction : JsonOT.validate }; + var updateUserList = function(shjson) { + // Extract the user list (metadata) from the hyperjson + var hjson = JSON.parse(shjson); + var peerUserList = hjson[hjson.length-1]; + if(peerUserList.metadata) { + var userData = peerUserList.metadata; + // Update the local user data + addToUserList(userData); + hjson.pop(); + } + return hjson; + } + var onRemote = realtimeOptions.onRemote = function (info) { if (initializing) { return; } @@ -265,18 +280,7 @@ define([ cursor.update(); // Extract the user list (metadata) from the hyperjson - var hjson = JSON.parse(shjson); - var peerUserList = hjson[hjson.length-1]; - if(peerUserList.metadata) { - var userData = peerUserList.metadata; - // Update the local user data - userList = userData; - // Send the new data to the toolbar - if(toolbarList && typeof toolbarList.onChange === "function") { - toolbarList.onChange(userList); - } - hjson.pop(); - } + var hjson = updateUserList(shjson); // build a dom from HJSON, diff, and patch the editor applyHjson(shjson); From aa07dd31eee4e70df32c9135c01a5247350ec125 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 17:35:07 +0200 Subject: [PATCH 12/13] have json-ot initialize its own debug module, instead of relying on a window variable's existence --- www/common/json-ot.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/www/common/json-ot.js b/www/common/json-ot.js index a785d524c..f04cf3b75 100644 --- a/www/common/json-ot.js +++ b/www/common/json-ot.js @@ -4,10 +4,9 @@ define([ var ChainPad = window.ChainPad; var JsonOT = {}; -/* FIXME - resultOp after transform0() might be null, in which case you should return null - because it is simply a transformation which yields a "do nothing" operation */ var validate = JsonOT.validate = function (text, toTransform, transformBy) { + var DEBUG = window.REALTIME_DEBUG = window.REALTIME_DEBUG || {}; + var resultOp, text2, text3; try { // text = O (mutual common ancestor) @@ -28,7 +27,7 @@ define([ return resultOp; } catch (e) { console.error(e); - var info = window.REALTIME_MODULE.ot_parseError = { + var info = DEBUG.ot_parseError = { type: 'resultParseError', resultOp: resultOp, @@ -40,11 +39,11 @@ define([ text3: text3, error: e }; - console.log('Debugging info available at `window.REALTIME_MODULE.ot_parseError`'); + console.log('Debugging info available at `window.REALTIME_DEBUG.ot_parseError`'); } } catch (x) { console.error(x); - window.REALTIME_MODULE.ot_applyError = { + window.DEBUG.ot_applyError = { type: 'resultParseError', resultOp: resultOp, @@ -56,7 +55,7 @@ define([ text3: text3, error: x }; - console.log('Debugging info available at `window.REALTIME_MODULE.ot_applyError`'); + console.log('Debugging info available at `window.REALTIME_DEBUG.ot_applyError`'); } // returning **null** breaks out of the loop From 69e8f54e8f1f2278d05292e310c5c77a4f41ed95 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 22 Apr 2016 18:54:24 +0200 Subject: [PATCH 13/13] pass in Crypto to realtime-input --- www/canvas/main.js | 1 + www/hack/main.js | 6 +-- www/p/main.js | 7 ++-- www/padrtc/main.js | 8 ++-- www/style/index.html | 1 - www/style/main.js | 89 +++++++++++++++++++++++++++----------------- www/text/main.js | 16 +++----- 7 files changed, 69 insertions(+), 59 deletions(-) diff --git a/www/canvas/main.js b/www/canvas/main.js index 1a52213ff..212f12bfe 100644 --- a/www/canvas/main.js +++ b/www/canvas/main.js @@ -67,6 +67,7 @@ define([ userName: Crypto.rand64(8), channel: channel, cryptKey: key, + crypto: Crypto, }; var onInit = config.onInit = function (info) { diff --git a/www/hack/main.js b/www/hack/main.js index 8830b9007..fe71ac64d 100644 --- a/www/hack/main.js +++ b/www/hack/main.js @@ -6,10 +6,6 @@ define([ '/bower_components/jquery/dist/jquery.min.js' ], function (Config, Realtime, Crypto, TextPatcher) { var $ = window.jQuery; - /* - $(window).on('hashchange', function() { - window.location.reload(); - });*/ var key; var channel = ''; @@ -44,6 +40,7 @@ define([ userName: userName, channel: channel, cryptKey: key, + crypto: Crypto, }; var initializing = true; @@ -54,6 +51,7 @@ define([ var onInit = config.onInit = function (info) { window.location.hash = info.channel + key; + $(window).on('hashchange', function() { window.location.reload(); }); }; var onRemote = config.onRemote = function (info) { diff --git a/www/p/main.js b/www/p/main.js index 023f9b9f1..64eda9f70 100644 --- a/www/p/main.js +++ b/www/p/main.js @@ -194,9 +194,6 @@ define([ var now = function () { return new Date().getTime(); }; var realtimeOptions = { - // configuration :D - doc: inner, - // provide initialstate... initialState: stringifyDOM(inner) || '{}', @@ -213,7 +210,9 @@ define([ channel: key.channel, // encryption key - cryptKey: key.cryptKey + cryptKey: key.cryptKey, + + crypto: Crypto, }; var DD = new DiffDom(diffOptions); diff --git a/www/padrtc/main.js b/www/padrtc/main.js index ba983e799..233241a86 100644 --- a/www/padrtc/main.js +++ b/www/padrtc/main.js @@ -206,14 +206,12 @@ define([ // our encryption key cryptKey: key, - // configuration :D - doc: inner, - setMyID: setMyID, // really basic operational transform - transformFunction : JsonOT.validate - // pass in websocket/netflux object TODO + transformFunction : JsonOT.validate, + + crypto: Crypto, }; var onRemote = realtimeOptions.onRemote = function (info) { diff --git a/www/style/index.html b/www/style/index.html index e9fdf2855..4ede5c688 100644 --- a/www/style/index.html +++ b/www/style/index.html @@ -8,7 +8,6 @@ Edit this document's style -

HTML Ipsum Presents

diff --git a/www/style/main.js b/www/style/main.js index b230bbb3f..7fe78cc34 100644 --- a/www/style/main.js +++ b/www/style/main.js @@ -1,31 +1,34 @@ define([ '/api/config?cb=' + Math.random().toString(16).substring(2), '/common/realtime-input.js', - '/common/messages.js', '/common/crypto.js', + '/common/TextPatcher.js', '/bower_components/jquery/dist/jquery.min.js', '/customize/pad.js' -], function (Config, Realtime, Messages, Crypto) { +], function (Config, Realtime, Crypto, TextPatcher) { // TODO consider adding support for less.js var $ = window.jQuery; - $(window).on('hashchange', function() { - window.location.reload(); - }); - var userName = Crypto.rand64(8); + var module = window.APP = {}; - if (window.location.href.indexOf('#') === -1) { - window.location.href = window.location.href + '#' + Crypto.genKey(); - return; + var key; + var channel = ''; + if (!/#/.test(window.location.href)) { + key = Crypto.genKey(); + } else { + var hash = window.location.hash.slice(1); + channel = hash.slice(0, 32); + key = hash.slice(32); } - var key = Crypto.parseKey(window.location.hash.slice(1)); - - var $style = $('style').first(), - $css = $('#css'), - $edit = $('#edit'); + var config = { + websocketURL: Config.websocketURL, + channel: channel, + cryptKey: key, + crypto: Crypto, + }; - $edit.attr('href', '/text/'+ window.location.hash); + var userName = module.userName = config.userName = Crypto.rand64(8); var lazyDraw = (function () { var to, @@ -38,29 +41,47 @@ define([ }; }()); - var draw = function () { - lazyDraw($css.val()); + var draw = function (content) { lazyDraw(content); }; + + var initializing = true; + + var onInit = config.onInit = function (info) { + window.location.hash = info.channel + key; + var realtime = module.realtime = info.realtime; + module.patchText = TextPatcher.create({ + realtime: realtime, + logging: true, + }); + + $(window).on('hashchange', function() { + window.location.reload(); + }); + }; + + var onReady = config.onReady = function (info) { + var userDoc = module.realtime.getUserDoc(); + draw(userDoc); + console.log("Ready"); + initializing = false; }; - $css // set the initial value - .val($style.text()) - .on('change', draw); + var onRemote = config.onRemote = function () { + draw(module.realtime.getUserDoc()); + }; - var rts = $('textarea').toArray().map(function (e, i) { + var onAbort = config.onAbort = function (info) { + // notify the user of the abort + window.alert("Network Connection Lost"); + }; - var config = { - onRemote: draw, - onInit: draw, - onReady: draw, + var onLocal = config.onLocal = function () { + // nope + }; - textarea: e, - websocketURL: Config.websocketURL, - userName: userName, - channel: key.channel, - cryptKey: key.cryptKey - }; + var $style = $('style').first(), + $edit = $('#edit'); + + $edit.attr('href', '/text/'+ window.location.hash); - var rt = Realtime.start(config); - return rt; - }); + var rt = Realtime.start(config); }); diff --git a/www/text/main.js b/www/text/main.js index 644fa86f6..2b91c446d 100644 --- a/www/text/main.js +++ b/www/text/main.js @@ -1,22 +1,12 @@ define([ '/api/config?cb=' + Math.random().toString(16).substring(2), '/common/realtime-input.js', - '/common/messages.js', '/common/crypto.js', '/common/TextPatcher.js', '/bower_components/jquery/dist/jquery.min.js', '/customize/pad.js' -], function (Config, Realtime, Messages, Crypto, TextPatcher) { +], function (Config, Realtime, Crypto, TextPatcher) { var $ = window.jQuery; - $(window).on('hashchange', function() { - window.location.reload(); - }); - /* - if (window.location.href.indexOf('#') === -1) { - window.location.href = window.location.href + '#' + Crypto.genKey(); - return; - }*/ - var key; var channel = ''; @@ -42,6 +32,7 @@ define([ userName: userName, channel: channel, cryptKey: key, + crypto: Crypto, }; var setEditable = function (bool) { $textarea.attr('disabled', !bool); }; @@ -51,6 +42,9 @@ define([ var onInit = config.onInit = function (info) { window.location.hash = info.channel + key; + $(window).on('hashchange', function() { + window.location.reload(); + }); }; var onRemote = config.onRemote = function (info) {