From dcc3b6cd21bd41479cf27a3ee4e85c4903b5e869 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 31 Aug 2016 17:58:57 +0200 Subject: [PATCH 01/17] Send a more precise message when the history is synced --- NetfluxWebsocketSrv.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NetfluxWebsocketSrv.js b/NetfluxWebsocketSrv.js index d92510749..8f557d6eb 100644 --- a/NetfluxWebsocketSrv.js +++ b/NetfluxWebsocketSrv.js @@ -157,7 +157,8 @@ const handleMessage = function (ctx, user, msg) { getHistory(ctx, parsed[1], function (msg) { sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify(msg)]); }, function () { - sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, 0]); + let parsedMsg = {state: 1, channel: parsed[1]}; + sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify(parsedMsg)]); }); } return; From ebae2c3bece7f390a09502a12ad0576f22dd1c18 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 29 Sep 2016 11:09:06 +0200 Subject: [PATCH 02/17] Fix the noscript tag --- customize.dist/index.html | 10 ++++++---- customize.dist/privacy.html | 2 -- customize.dist/src/fragments/index.html | 8 ++++++-- customize.dist/src/template.html | 2 -- customize.dist/terms.html | 2 -- customize.dist/translations/messages.fr.js | 1 - customize.dist/translations/messages.js | 3 +-- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/customize.dist/index.html b/customize.dist/index.html index acaed958b..32e09f4f2 100644 --- a/customize.dist/index.html +++ b/customize.dist/index.html @@ -57,8 +57,12 @@
@@ -87,8 +91,6 @@ - -
diff --git a/customize.dist/privacy.html b/customize.dist/privacy.html index b7d4b15cc..b152269da 100644 --- a/customize.dist/privacy.html +++ b/customize.dist/privacy.html @@ -74,8 +74,6 @@ - -
diff --git a/customize.dist/src/fragments/index.html b/customize.dist/src/fragments/index.html index 6ca24310b..d37dca8ba 100644 --- a/customize.dist/src/fragments/index.html +++ b/customize.dist/src/fragments/index.html @@ -17,8 +17,12 @@
diff --git a/customize.dist/src/template.html b/customize.dist/src/template.html index b165c377e..e696d42a5 100644 --- a/customize.dist/src/template.html +++ b/customize.dist/src/template.html @@ -20,8 +20,6 @@
{{main}}
- -
diff --git a/customize.dist/terms.html b/customize.dist/terms.html index 8db25b6cb..b2c1d4916 100644 --- a/customize.dist/terms.html +++ b/customize.dist/terms.html @@ -51,8 +51,6 @@ - -
diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 6f5fc6c8d..18b1a9623 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -135,7 +135,6 @@ define(function () { out.main_about = 'À propos'; out.main_about_p1 = 'Vous pouvez en apprendre davantage sur notre politique de confidentialité et nos conditions d\'utilisation.'; out.main_about_p2 = 'Si vous avez des questions ou commentaires, vous pouvez nous tweeter, ouvrir une issue sur Github, venir dire bonjour sur IRC (irc.freenode.net), ou nous envoyer un email.'; - out.main_oops = 'OUPS Afin de pouvoir réaliser le cryptage depuis votre navigateur, Javascript est vraiment requis.'; out.table_type = 'Type'; out.table_link = 'Lien'; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index f13409b72..8b98346db 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -51,7 +51,7 @@ define(function () { out.renameConflict = 'Another pad already has that title'; out.forgetButton = 'FORGET'; - out.forgetButtonTitle = 'remove this document from your home page listings'; + out.forgetButtonTitle = 'Remove this document from your home page listings'; out.forgetPrompt = 'Clicking OK will remove the URL for this pad from localStorage, are you sure?'; out.shareButton = 'SHARE'; @@ -135,7 +135,6 @@ define(function () { out.main_about = 'About'; out.main_about_p1 = 'You can read more about our privacy policy and terms of service.'; out.main_about_p2 = 'If you have any questions or comments, you can tweet us, open an issue on github, come say hi on irc (irc.freenode.net), or send us an email.'; - out.main_oops = 'OOPS In order to do encryption in your browser, Javascript is really really required.'; out.table_type = 'Type'; out.table_link = 'Link'; From 9fa7da60b994d06a8af9dad3b3df711afd566057 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 3 Oct 2016 15:38:42 +0200 Subject: [PATCH 03/17] confirm that a socket is ready to send before sending --- NetfluxWebsocketSrv.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NetfluxWebsocketSrv.js b/NetfluxWebsocketSrv.js index 98d79f72f..a96e41f2d 100644 --- a/NetfluxWebsocketSrv.js +++ b/NetfluxWebsocketSrv.js @@ -14,7 +14,12 @@ let historyKeeperKeys = {}; const now = function () { return (new Date()).getTime(); }; +const socketSendable = function (socket) { + return socket && socket.readyState === 1; +}; + const sendMsg = function (ctx, user, msg) { + if (!socketSendable(user.socket)) { return; } try { if (ctx.config.logToStdout) { console.log('<' + JSON.stringify(msg)); } user.socket.send(JSON.stringify(msg)); From 17b4f918100c2242be8b351e725749ffd2b997cf Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 3 Oct 2016 16:05:39 +0200 Subject: [PATCH 04/17] Do not share the title in the doc if it is the default title --- www/code/main.js | 74 ++++++++++++++++++--------------- www/common/cryptpad-common.js | 4 ++ www/pad/main.js | 74 +++++++++++++++++---------------- www/slide/main.js | 77 +++++++++++++++++++---------------- 4 files changed, 127 insertions(+), 102 deletions(-) diff --git a/www/code/main.js b/www/code/main.js index 71f3bfd14..ae8d783e0 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -158,9 +158,11 @@ define([ // append the userlist to the hyperjson structure obj.metadata = { - users: userList, - title: document.title + users: userList }; + if (!isDefaultTitle()) { + obj.metadata.title = document.title; + } // set mode too... obj.highlightMode = module.highlightMode; @@ -239,11 +241,15 @@ define([ return text.trim(); }; + var isDefaultTitle = function () { + var parsed = Cryptpad.parsePadUrl(window.location.href); + return Cryptpad.isDefaultName(parsed, document.title); + }; var suggestName = function () { var parsed = Cryptpad.parsePadUrl(window.location.href); var name = Cryptpad.getDefaultName(parsed, []); - if (document.title.slice(0, name.length) === name) { + if (Cryptpad.isDefaultName(parsed, document.title)) { return getHeadingText() || document.title; } else { return document.title || getHeadingText() || name; @@ -328,42 +334,42 @@ define([ onLocal(); })); $rightside.append($import); - } - /* add a rename button */ - var $setTitle = Cryptpad.createButton('rename', true) - .click(function () { - var suggestion = suggestName(); - - Cryptpad.prompt(Messages.renamePrompt, - suggestion, function (title, ev) { - if (title === null) { return; } - - Cryptpad.causesNamingConflict(title, function (err, conflicts) { - if (err) { - console.log("Unable to determine if name caused a conflict"); - console.error(err); - return; - } + /* add a rename button */ + var $setTitle = Cryptpad.createButton('rename', true) + .click(function () { + var suggestion = suggestName(); - if (conflicts) { - Cryptpad.alert(Messages.renameConflict); - return; - } + Cryptpad.prompt(Messages.renamePrompt, + suggestion, function (title, ev) { + if (title === null) { return; } - Cryptpad.setPadTitle(title, function (err, data) { + Cryptpad.causesNamingConflict(title, function (err, conflicts) { if (err) { - console.log("unable to set pad title"); - console.log(err); + console.log("Unable to determine if name caused a conflict"); + console.error(err); return; } - document.title = title; - onLocal(); + + if (conflicts) { + Cryptpad.alert(Messages.renameConflict); + return; + } + + Cryptpad.setPadTitle(title, function (err, data) { + if (err) { + console.log("unable to set pad title"); + console.log(err); + return; + } + document.title = title; + onLocal(); + }); }); }); - }); - }); - $rightside.append($setTitle); + }); + $rightside.append($setTitle); + } /* add a forget button */ var $forgetPad = Cryptpad.createButton('forget', true) @@ -657,11 +663,13 @@ define([ var hjson2 = { content: localDoc, metadata: { - users: userList, - title: document.title + users: userList }, highlightMode: highlightMode, }; + if (!isDefaultTitle()) { + hjson2.metadata.title = document.title; + } var shjson2 = stringify(hjson2); if (shjson2 !== shjson) { console.error("shjson2 !== shjson"); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 68fa9be7a..7387808fa 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -295,6 +295,10 @@ define([ while (!isNameAvailable(name + ' - ' + untitledIndex, parsed, recentPads)) { untitledIndex++; } return name + ' - ' + untitledIndex; }; + var isDefaultName = common.isDefaultName = function (parsed, title) { + var name = getDefaultName(parsed, []); + return title.slice(0, name.length) === name; + }; var makePad = function (href, title) { var now = ''+new Date(); diff --git a/www/pad/main.js b/www/pad/main.js index 18274079f..9fb92992e 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -294,6 +294,21 @@ define([ }); }; + var isDefaultTitle = function () { + var parsed = Cryptpad.parsePadUrl(window.location.href); + return Cryptpad.isDefaultName(parsed, document.title); + }; + var suggestName = function () { + var parsed = Cryptpad.parsePadUrl(window.location.href); + var name = Cryptpad.getDefaultName(parsed, []); + + if (Cryptpad.isDefaultName(parsed, document.title)) { + return getHeadingText() || document.title; + } else { + return document.title || getHeadingText() || name; + } + }; + var DD = new DiffDom(diffOptions); // apply patches, and try not to lose the cursor in the process! @@ -312,9 +327,11 @@ define([ hjson[3] = { metadata: { users: userList, - title: document.title } }; + if (!isDefaultTitle()) { + hjson[3].metadata.title = document.title; + } return stringify(hjson); }; @@ -472,17 +489,6 @@ define([ })) { return text; } }; - var suggestName = module.suggestName = function () { - var parsed = Cryptpad.parsePadUrl(window.location.href); - var name = Cryptpad.getDefaultName(parsed, []); - - if (document.title.slice(0, name.length) === name) { - return getHeadingText() || document.title; - } else { - return document.title || getHeadingText() || name; - } - }; - var exportFile = function () { var html = getHTML(); var suggestion = suggestName(); @@ -536,34 +542,34 @@ define([ realtimeOptions.onLocal(); })); $rightside.append($import); - } - /* add a rename button */ - var $rename = Cryptpad.createButton('rename', true) - .click(function () { - var suggestion = suggestName(); - - Cryptpad.prompt(Messages.renamePrompt, suggestion, function (title) { - if (title === null) { return; } - Cryptpad.causesNamingConflict(title, function (err, conflicts) { - if (conflicts) { - Cryptpad.alert(Messages.renameConflict); - return; - } - - Cryptpad.setPadTitle(title, function (err, data) { - if (err) { - console.log("Couldn't set pad title"); - console.error(err); + /* add a rename button */ + var $rename = Cryptpad.createButton('rename', true) + .click(function () { + var suggestion = suggestName(); + + Cryptpad.prompt(Messages.renamePrompt, suggestion, function (title) { + if (title === null) { return; } + Cryptpad.causesNamingConflict(title, function (err, conflicts) { + if (conflicts) { + Cryptpad.alert(Messages.renameConflict); return; } - document.title = title; - editor.fire('change'); + + Cryptpad.setPadTitle(title, function (err, data) { + if (err) { + console.log("Couldn't set pad title"); + console.error(err); + return; + } + document.title = title; + editor.fire('change'); + }); }); }); }); - }); - $rightside.append($rename); + $rightside.append($rename); + } /* add a forget button */ var $forgetPad = Cryptpad.createButton('forget', true) diff --git a/www/slide/main.js b/www/slide/main.js index c9ff8d6aa..78ca23fb3 100644 --- a/www/slide/main.js +++ b/www/slide/main.js @@ -193,10 +193,11 @@ define([ // append the userlist to the hyperjson structure obj.metadata = { - users: userList, - title: APP.title + users: userList }; - + if (!isDefaultTitle()) { + obj.metadata.title = APP.title; + } // stringify the json and send it into chainpad var shjson = stringify(obj); @@ -254,11 +255,15 @@ define([ return text.trim(); }; + var isDefaultTitle = function () { + var parsed = Cryptpad.parsePadUrl(window.location.href); + return Cryptpad.isDefaultName(parsed, APP.title); + }; var suggestName = function () { var parsed = Cryptpad.parsePadUrl(window.location.href); var name = Cryptpad.getDefaultName(parsed, []); - if (APP.title.slice(0, name.length) === name) { + if (Cryptpad.isDefaultName(parsed, APP.title)) { return getHeadingText() || APP.title; } else { return APP.title || getHeadingText() || name; @@ -343,43 +348,43 @@ define([ onLocal(); })); $rightside.append($import); - } - /* add a rename button */ - var $setTitle = Cryptpad.createButton('rename', true) - .click(function () { - var suggestion = suggestName(); - - Cryptpad.prompt(Messages.renamePrompt, - suggestion, function (title, ev) { - if (title === null) { return; } - - Cryptpad.causesNamingConflict(title, function (err, conflicts) { - if (err) { - console.log("Unable to determine if name caused a conflict"); - console.error(err); - return; - } + /* add a rename button */ + var $setTitle = Cryptpad.createButton('rename', true) + .click(function () { + var suggestion = suggestName(); - if (conflicts) { - Cryptpad.alert(Messages.renameConflict); - return; - } + Cryptpad.prompt(Messages.renamePrompt, + suggestion, function (title, ev) { + if (title === null) { return; } - Cryptpad.setPadTitle(title, function (err, data) { + Cryptpad.causesNamingConflict(title, function (err, conflicts) { if (err) { - console.log("unable to set pad title"); - console.log(err); + console.log("Unable to determine if name caused a conflict"); + console.error(err); return; } - APP.title = title; - setTabTitle(); - onLocal(); + + if (conflicts) { + Cryptpad.alert(Messages.renameConflict); + return; + } + + Cryptpad.setPadTitle(title, function (err, data) { + if (err) { + console.log("unable to set pad title"); + console.log(err); + return; + } + APP.title = title; + setTabTitle(); + onLocal(); + }); }); }); - }); - }); - $rightside.append($setTitle); + }); + $rightside.append($setTitle); + } /* add a forget button */ var $forgetPad = Cryptpad.createButton('forget', true) @@ -684,11 +689,13 @@ define([ var hjson2 = { content: localDoc, metadata: { - users: userList, - title: APP.title + users: userList }, highlightMode: highlightMode, }; + if (!isDefaultTitle()) { + hjson2.metadata.title = APP.title; + } var shjson2 = stringify(hjson2); if (shjson2 !== shjson) { console.error("shjson2 !== shjson"); From 76fdadee7f929ede08270de077c21175935c6a97 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 3 Oct 2016 18:23:59 +0200 Subject: [PATCH 05/17] Store only the strongest hash in the localstorage --- www/code/main.js | 2 +- www/common/cryptpad-common.js | 82 +++++++++++++++++------------------ www/pad/main.js | 2 +- www/poll/main.js | 2 +- www/slide/main.js | 2 +- 5 files changed, 44 insertions(+), 46 deletions(-) diff --git a/www/code/main.js b/www/code/main.js index ae8d783e0..fc10fd7c9 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -476,7 +476,7 @@ define([ return; } document.title = title || info.channel.slice(0, 8); - Cryptpad.rememberPad(title, function (err, data) { + Cryptpad.setPadTitle(title, function (err, data) { if (err) { console.log("Unable to set pad title"); console.error(err); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 7387808fa..6b7562551 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -137,6 +137,26 @@ define([ }; + var parseHash = common.parseHash = function (hash) { + var parsed = {}; + if (hash.slice(0,1) !== '/' && hash.length >= 56) { + // Old hash + parsed.channel = hash.slice(0, 32); + parsed.key = hash.slice(32); + parsed.version = 0; + return parsed; + } + var hashArr = hash.split('/'); + if (hashArr[1] && hashArr[1] === '1') { + parsed.version = 1; + parsed.mode = hashArr[2]; + parsed.channel = hashArr[3]; + parsed.key = hashArr[4]; + parsed.present = hashArr[5] && hashArr[5] === 'present'; + return parsed; + } + return; + }; var getEditHashFromKeys = common.getEditHashFromKeys = function (chanKey, keys) { if (typeof keys === 'string') { return chanKey + keys; @@ -401,51 +421,10 @@ define([ }, legacy); }; - // STORAGE - var rememberPad = common.rememberPad = window.rememberPad = function (title, cb) { - // bail out early - if (!/#/.test(window.location.hash)) { return; } - - getRecentPads(function (err, pads) { - if (err) { - cb(err); - return; - } - - var now = ''+new Date(); - var href = window.location.href; - - var parsed = parsePadUrl(window.location.href); - var isUpdate = false; - - var out = pads.map(function (pad) { - var p = parsePadUrl(pad.href); - if (p.hash === parsed.hash && p.type === parsed.type) { - isUpdate = true; - // bump the atime - pad.atime = now; - - pad.title = title; - pad.href = href; - } - return pad; - }); - - if (!isUpdate) { - // href, ctime, atime, title - out.push(makePad(href, title)); - } - setRecentPads(out, function (err, data) { - cb(err, data); - }); - }); - }; - // STORAGE var setPadTitle = common.setPadTitle = function (name, cb) { var href = window.location.href; var parsed = parsePadUrl(href); - getRecentPads(function (err, recent) { if (err) { cb(err); @@ -456,7 +435,26 @@ define([ var renamed = recent.map(function (pad) { var p = parsePadUrl(pad.href); - if (p.hash === parsed.hash && p.type === parsed.type) { + + if (p.type !== parsed.type) { return pad; } + + // Version 1 : we have up to 4 differents hash for 1 pad, keep the strongest : + // Edit > Edit (present) > View > View (present) + var bypass = false; + var pHash = parseHash(p.hash); + var parsedHash = parseHash(parsed.hash); + if (pHash.version === 1 && parsedHash.version === 1 && pHash.channel === parsedHash.channel) { + if (pHash.mode === 'view' && parsedHash.mode === 'edit') { bypass = true; } + else if (pHash.mode === parsedHash.mode && pHash.present) { bypass = true; } + else { + // Editing a "weaker" version of a stored hash : update the date and do not push the current hash + pad.atime = new Date().toISOString(); + contains = true; + return pad; + } + } + + if (p.hash === parsed.hash || bypass) { contains = true; // update the atime pad.atime = new Date().toISOString(); diff --git a/www/pad/main.js b/www/pad/main.js index 9fb92992e..0c28055f6 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -608,7 +608,7 @@ define([ return; } document.title = title || info.channel.slice(0, 8); - Cryptpad.rememberPad(title, function (err, data) { + Cryptpad.setPadTitle(title, function (err, data) { if (err) { console.log("Couldn't remember pad"); console.error(err); diff --git a/www/poll/main.js b/www/poll/main.js index 9b1ab0e68..05c452f5a 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -923,7 +923,7 @@ define([ Cryptpad.getPadTitle(function (err, title) { title = document.title = title || info.channel.slice(0, 8); - Cryptpad.rememberPad(title, function (err, data) { + Cryptpad.setPadTitle(title, function (err, data) { if (err) { console.log("unable to remember pad"); console.log(err); diff --git a/www/slide/main.js b/www/slide/main.js index 78ca23fb3..f0f139a6a 100644 --- a/www/slide/main.js +++ b/www/slide/main.js @@ -490,7 +490,7 @@ define([ return; } document.title = APP.title = title || info.channel.slice(0, 8); - Cryptpad.rememberPad(title, function (err, data) { + Cryptpad.setPadTitle(title, function (err, data) { if (err) { console.log("Unable to set pad title"); console.error(err); From 3dfa19b786afb81c801e5b6615a6d6f920f613f0 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 3 Oct 2016 19:19:38 +0200 Subject: [PATCH 06/17] more flexible websocket configuration (WIP) --- NetfluxWebsocketSrv.js | 2 +- server.js | 3 +-- www/common/cryptpad-common.js | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/NetfluxWebsocketSrv.js b/NetfluxWebsocketSrv.js index a96e41f2d..02a8f8b19 100644 --- a/NetfluxWebsocketSrv.js +++ b/NetfluxWebsocketSrv.js @@ -277,7 +277,7 @@ let run = module.exports.run = function (storage, socketServer, config) { }); }, 5000); socketServer.on('connection', function(socket) { - if(socket.upgradeReq.url !== '/cryptpad_websocket') { return; } + if(socket.upgradeReq.url !== (config.websocketPath || '/cryptpad_websocket')) { return; } let conn = socket.upgradeReq.connection; let user = { addr: conn.remoteAddress + '|' + conn.remotePort, diff --git a/server.js b/server.js index c490698b3..120ae04e5 100644 --- a/server.js +++ b/server.js @@ -56,10 +56,9 @@ app.get('/api/config', function(req, res){ var host = req.headers.host.replace(/\:[0-9]+/, ''); res.setHeader('Content-Type', 'text/javascript'); res.send('define(' + JSON.stringify({ + websocketPath: config.websocketPath, websocketURL:'ws' + ((httpsOpts) ? 's' : '') + '://' + host + ':' + config.websocketPort + '/cryptpad_websocket', - webrtcURL:'ws' + ((httpsOpts) ? 's' : '') + '://' + host + ':' + - config.websocketPort + '/cryptpad_webrtc', }) + ');'); }); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index be31e9f5e..f0e0c5bf4 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1,4 +1,5 @@ define([ + '/api/config?cb=' + Math.random().toString(16).slice(2), '/customize/messages.js', '/customize/store.js', '/bower_components/chainpad-crypto/crypto.js', @@ -8,7 +9,7 @@ define([ '/customize/user.js', '/bower_components/jquery/dist/jquery.min.js', -], function (Messages, Store, Crypto, Alertify, Spinner, User) { +], function (Config, Messages, Store, Crypto, Alertify, Spinner, User) { /* This file exposes functionality which is specific to Cryptpad, but not to any particular pad type. This includes functions for committing metadata about pads to your local storage for future use and improved usability. @@ -36,6 +37,20 @@ define([ throw new Error("Store is not ready!"); }; + var getWebsocketURL = common.getWebsocketURL = function () { + if (!Config.websocketPath) { return Config.websocketURL; } + var path = Config.websocketPath; + if (/^ws{1,2}:\/\//.test(path)) { return path; } + + var protocol = window.location.protocol.replace(/http/, 'ws'); + var host = window.location.host; + var url = protocol + '//' + host + path; + + console.log(url); + + return url; + }; + /* * cb(err, proxy); */ From 0ece2cf6a1e35105b274f8726264bba6db0c946a Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 3 Oct 2016 19:28:14 +0200 Subject: [PATCH 07/17] add to default configuration and comment --- config.js.dist | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/config.js.dist b/config.js.dist index e88b06b0a..c75748508 100644 --- a/config.js.dist +++ b/config.js.dist @@ -9,8 +9,22 @@ module.exports = { // the port on which your httpd will listen httpPort: 3000, - // the port used for websockets - websocketPort: 3000, + + /* your server's websocket url is configurable + (default: '/cryptpad_websocket') + + websocketPath can be relative, of the form '/path/to/websocket' + or absolute, specifying a particular URL + + 'wss://cryptpad.fr:3000/cryptpad_websocket' + */ + websocketPath: '/cryptpad_websocket', + + /* it is assumed that your websocket will bind to the same port as http + you can override this behaviour by supplying a number via websocketPort + */ + //websocketPort: 3000, + /* Cryptpad can log activity to stdout * This may be useful for debugging From 5e761942625c783e51be9e99648287585860a951 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 3 Oct 2016 19:28:36 +0200 Subject: [PATCH 08/17] use new config api --- www/pad/main.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/www/pad/main.js b/www/pad/main.js index 18274079f..6eee27d50 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -1,6 +1,5 @@ require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify' } }); define([ - '/api/config?cb=' + Math.random().toString(16).substring(2), '/customize/messages.js?app=pad', '/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-netflux/chainpad-netflux.js', @@ -18,7 +17,7 @@ define([ '/bower_components/diff-dom/diffDOM.js', '/bower_components/jquery/dist/jquery.min.js', '/customize/pad.js' -], function (Config, Messages, Crypto, realtimeInput, Hyperjson, +], function (Messages, Crypto, realtimeInput, Hyperjson, Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad, Visible, Notify) { var $ = window.jQuery; @@ -323,7 +322,7 @@ define([ initialState: stringifyDOM(inner) || '{}', // the websocket URL - websocketURL: Config.websocketURL, + websocketURL: Cryptpad.getWebsocketURL(), // the channel we will communicate over channel: secret.channel, From e84a54556c9d7ab4ee1b89a5c2a280a65ddbf760 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 4 Oct 2016 15:44:12 +0200 Subject: [PATCH 09/17] Move the toolbar buttons' events handlers in cryptpad-common --- customize.dist/main.css | 3 + customize.dist/src/cryptpad.less | 3 + customize.dist/translations/messages.fr.js | 5 +- customize.dist/translations/messages.js | 4 +- www/code/main.js | 132 +++++++------------ www/common/cryptpad-common.js | 105 +++++++++++++++- www/pad/main.js | 80 ++++-------- www/poll/main.js | 130 ++++++++----------- www/slide/main.js | 140 +++++++-------------- 9 files changed, 287 insertions(+), 315 deletions(-) diff --git a/customize.dist/main.css b/customize.dist/main.css index 72190a3a1..0c063e6e8 100644 --- a/customize.dist/main.css +++ b/customize.dist/main.css @@ -154,6 +154,9 @@ tr { margin-bottom: 12px; white-space: nowrap; } +.alertify button { + margin: 3px 0px; +} /* Tables */ table { border-collapse: collapse; diff --git a/customize.dist/src/cryptpad.less b/customize.dist/src/cryptpad.less index 16448646f..c41af4de9 100644 --- a/customize.dist/src/cryptpad.less +++ b/customize.dist/src/cryptpad.less @@ -187,6 +187,9 @@ p, pre, td, a, table, tr { margin-bottom: 2 * 6px; white-space: nowrap; } +.alertify button { + margin: 3px 0px; +} /* Tables */ table { diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index c6a9be3fe..cd41d5fb5 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -74,7 +74,10 @@ define(function () { out.getViewButton = 'LECTURE SEULE'; out.getViewButtonTitle = "Obtenir l'adresse d'accès à ce document en lecture seule"; - out.readonlyUrl = 'URL de lecture seule'; + out.readonlyUrl = 'Document en lecture seule'; + out.copyReadOnly = "Copier l'URL dans le presse-papiers"; + out.openReadOnly = "Ouvrir dans un nouvel onglet"; + out.disconnectAlert = 'Perte de la connexion au réseau !'; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index df1bd18de..63a0dc40e 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -75,7 +75,9 @@ define(function () { out.getViewButton = 'READ-ONLY URL'; out.getViewButtonTitle = 'Get the read-only URL for this document'; - out.readonlyUrl = 'Read only URL'; + out.readonlyUrl = 'Read only document'; + out.copyReadOnly = "Copy URL to clipboard"; + out.openReadOnly = "Open in a new tab"; out.disconnectAlert = 'Network connection lost!'; diff --git a/www/code/main.js b/www/code/main.js index 71f3bfd14..35e475098 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -265,6 +265,32 @@ define([ saveAs(blob, filename); }); }; + var importText = function (content, file) { + var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox'); + var mode; + var mime = CodeMirror.findModeByMIME(file.type); + + if (!mime) { + var ext = /.+\.([^.]+)$/.exec(file.name); + if (ext[1]) { + mode = CodeMirror.findModeByExtension(ext[1]); + } + } else { + mode = mime && mime.mode || null; + } + + if (mode && Modes.list.some(function (o) { return o.mode === mode; })) { + setMode(mode); + $bar.find('#language-mode').val(mode); + } else { + console.log("Couldn't find a suitable highlighting mode: %s", mode); + setMode('text'); + $bar.find('#language-mode').val('text'); + } + + editor.setValue(content); + onLocal(); + }; var onInit = config.onInit = function (info) { var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox'); @@ -285,113 +311,45 @@ define([ editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys); } + /* add a "change username" button */ getLastName(function (err, lastName) { - var $username = Cryptpad.createButton('username', true) - .click(function() { - Cryptpad.prompt(Messages.changeNamePrompt, lastName, function (newName) { - setName(newName); - }); - }); + var usernameCb = function (newName) { + setName (newName); + }; + var $username = Cryptpad.createButton('username', true, {lastName: lastName}, usernameCb); $rightside.append($username); }); /* add an export button */ - var $export = Cryptpad.createButton('export', true).click(exportText); + var $export = Cryptpad.createButton('export', true, {}, exportText); $rightside.append($export); if (!readOnly) { /* add an import button */ - var $import = Cryptpad.createButton('import', true) - .click(Cryptpad.importContent('text/plain', function (content, file) { - var mode; - var mime = CodeMirror.findModeByMIME(file.type); - - if (!mime) { - var ext = /.+\.([^.]+)$/.exec(file.name); - if (ext[1]) { - mode = CodeMirror.findModeByExtension(ext[1]); - } - } else { - mode = mime && mime.mode || null; - } - - if (mode && Modes.list.some(function (o) { return o.mode === mode; })) { - setMode(mode); - $bar.find('#language-mode').val(mode); - } else { - console.log("Couldn't find a suitable highlighting mode: %s", mode); - setMode('text'); - $bar.find('#language-mode').val('text'); - } - - editor.setValue(content); - onLocal(); - })); + var $import = Cryptpad.createButton('import', true, {}, importText); $rightside.append($import); } /* add a rename button */ - var $setTitle = Cryptpad.createButton('rename', true) - .click(function () { - var suggestion = suggestName(); - - Cryptpad.prompt(Messages.renamePrompt, - suggestion, function (title, ev) { - if (title === null) { return; } - - Cryptpad.causesNamingConflict(title, function (err, conflicts) { - if (err) { - console.log("Unable to determine if name caused a conflict"); - console.error(err); - return; - } - - if (conflicts) { - Cryptpad.alert(Messages.renameConflict); - return; - } - - Cryptpad.setPadTitle(title, function (err, data) { - if (err) { - console.log("unable to set pad title"); - console.log(err); - return; - } - document.title = title; - onLocal(); - }); - }); - }); - }); + var renameCb = function (err, title) { + if (err) { return; } + document.title = title; + onLocal(); + }; + var $setTitle = Cryptpad.createButton('rename', true, {suggestName: suggestName}, renameCb); $rightside.append($setTitle); /* add a forget button */ - var $forgetPad = Cryptpad.createButton('forget', true) - .click(function () { - var href = window.location.href; - Cryptpad.confirm(Messages.forgetPrompt, function (yes) { - if (!yes) { return; } - Cryptpad.forgetPad(href, function (err, data) { - if (err) { - console.log("unable to forget pad"); - console.error(err); - return; - } - var parsed = Cryptpad.parsePadUrl(href); - document.title = Cryptpad.getDefaultName(parsed, []); - }); - }); - }); + var forgetCb = function (err, title) { + if (err) { return; } + document.title = title; + }; + var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb); $rightside.append($forgetPad); if (!readOnly && viewHash) { /* add a 'links' button */ - var $links = Cryptpad.createButton('readonly', true) - .click(function () { - var baseUrl = window.location.origin + window.location.pathname + '#'; - var content = '' + Messages.readonlyUrl + '
' + baseUrl + viewHash + '
'; - Cryptpad.alert(content); - }); + var $links = Cryptpad.createButton('readonly', true, {viewHash: viewHash}); $rightside.append($links); } diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 68fa9be7a..b2a2fce50 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -4,11 +4,12 @@ define([ '/bower_components/chainpad-crypto/crypto.js', '/bower_components/alertifyjs/dist/js/alertify.js', '/bower_components/spin.js/spin.min.js', + '/common/clipboard.js', '/customize/user.js', '/bower_components/jquery/dist/jquery.min.js', -], function (Messages, Store, Crypto, Alertify, Spinner, User) { +], function (Messages, Store, Crypto, Alertify, Spinner, Clipboard, User) { /* This file exposes functionality which is specific to Cryptpad, but not to any particular pad type. This includes functions for committing metadata about pads to your local storage for future use and improved usability. @@ -610,7 +611,7 @@ define([ /* * Buttons */ - var createButton = common.createButton = function (type, rightside) { + var createButton = common.createButton = function (type, rightside, data, callback) { var button; var size = "17px"; switch (type) { @@ -620,6 +621,9 @@ define([ 'class': "fa fa-download", style: 'font:'+size+' FontAwesome' }); + if (callback) { + button.click(callback); + } break; case 'import': button = $('