From 50c10f818ea726249cdb75307c76d8b69bf9301e Mon Sep 17 00:00:00 2001
From: Caleb James DeLisle
Date: Thu, 29 Jan 2015 17:55:18 +0100
Subject: [PATCH] Added cryptsheet to cryptpad suite!
---
.bowerrc | 2 +-
.gitignore | 2 +-
bower.json | 3 +-
server.js | 6 +
www/{ => common}/chainpad.js | 25 ++--
www/{ => common}/messages.js | 0
www/{ => common}/otaml.js | 0
www/common/toolbar.js | 172 +++++++++++++++++++++++++
www/index.html | 45 ++++---
www/{ => pad}/errorbox.js | 8 +-
www/{ => pad}/html-patcher.js | 4 +-
www/pad/index.html | 11 ++
www/{ => pad}/main.js | 17 ++-
www/{ => pad}/rangy.js | 0
www/{ => pad}/realtime-wysiwyg.js | 18 +--
www/sheet/index.html | 29 +++++
www/sheet/inner.html | 36 ++++++
www/sheet/main.js | 201 ++++++++++++++++++++++++++++++
18 files changed, 525 insertions(+), 54 deletions(-)
rename www/{ => common}/chainpad.js (98%)
rename www/{ => common}/messages.js (100%)
rename www/{ => common}/otaml.js (100%)
create mode 100644 www/common/toolbar.js
rename www/{ => pad}/errorbox.js (93%)
rename www/{ => pad}/html-patcher.js (99%)
create mode 100644 www/pad/index.html
rename www/{ => pad}/main.js (81%)
rename www/{ => pad}/rangy.js (100%)
rename www/{ => pad}/realtime-wysiwyg.js (98%)
create mode 100644 www/sheet/index.html
create mode 100644 www/sheet/inner.html
create mode 100644 www/sheet/main.js
diff --git a/.bowerrc b/.bowerrc
index 67b62e774..6a424c379 100644
--- a/.bowerrc
+++ b/.bowerrc
@@ -1,3 +1,3 @@
{
- "directory" : "www/bower"
+ "directory" : "www/bower_components"
}
diff --git a/.gitignore b/.gitignore
index 1157b14cc..aa661d690 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-www/bower/*
+www/bower_components/*
node_modules
/config.js
diff --git a/bower.json b/bower.json
index e7f0fc2c4..34511bc3e 100644
--- a/bower.json
+++ b/bower.json
@@ -18,7 +18,8 @@
"tests"
],
"dependencies": {
- "jquery": "~2.1.1",
+ "jquery.sheet": "master",
+ "jquery": "~2.1.3",
"tweetnacl": "~0.12.2",
"ckeditor": "~4.4.5",
"requirejs": "~2.1.15",
diff --git a/server.js b/server.js
index bc5b41c0e..4a1f8e39a 100644
--- a/server.js
+++ b/server.js
@@ -12,6 +12,12 @@ config.websocketPort = config.websocketPort || config.httpPort;
var app = Express();
app.use(Express.static(__dirname + '/www'));
+// Bower is broken and does not allow components nested within components...
+// And jquery.sheet expects it!
+// *Workaround*
+app.use("/bower_components/jquery.sheet/bower_components",
+ Express.static(__dirname + '/www/bower_components'));
+
var httpsOpts;
if (config.privKeyAndCertFiles) {
var privKeyAndCerts = '';
diff --git a/www/chainpad.js b/www/common/chainpad.js
similarity index 98%
rename from www/chainpad.js
rename to www/common/chainpad.js
index 82e8102b4..b872b17f0 100644
--- a/www/chainpad.js
+++ b/www/common/chainpad.js
@@ -589,6 +589,18 @@ var unschedule = function (realtime, schedule) {
clearTimeout(schedule);
};
+var onMessage = function (realtime, message, callback) {
+ if (!realtime.messageHandlers.length) {
+ callback("no onMessage() handler registered");
+ }
+ for (var i = 0; i < realtime.messageHandlers.length; i++) {
+ realtime.messageHandlers[i](message, function () {
+ callback.apply(null, arguments);
+ callback = function () { };
+ });
+ }
+};
+
var sync = function (realtime) {
if (Common.PARANOIA) { check(realtime); }
if (realtime.syncSchedule) {
@@ -622,7 +634,7 @@ var sync = function (realtime) {
var strMsg = Message.toString(msg);
- realtime.onMessage(strMsg, function (err) {
+ onMessage(realtime, strMsg, function (err) {
if (err) {
debug(realtime, "Posting to server failed [" + err + "]");
}
@@ -657,7 +669,7 @@ var getMessages = function (realtime) {
realtime.authToken,
realtime.channelId,
Message.REGISTER);
- realtime.onMessage(Message.toString(msg), function (err) {
+ onMessage(realtime, Message.toString(msg), function (err) {
if (err) { throw err; }
});
};
@@ -670,7 +682,7 @@ var sendPing = function (realtime) {
realtime.channelId,
Message.PING,
realtime.lastPingTime);
- realtime.onMessage(Message.toString(msg), function (err) {
+ onMessage(realtime, Message.toString(msg), function (err) {
if (err) { throw err; }
});
};
@@ -706,9 +718,7 @@ var create = ChainPad.create = function (userName, authToken, channelId, initial
patchHandlers: [],
opHandlers: [],
- onMessage: function (message, callback) {
- callback("no onMessage() handler registered");
- },
+ messageHandlers: [],
schedules: [],
@@ -1127,7 +1137,8 @@ module.exports.create = function (userName, authToken, channelId, initialState,
doOperation(realtime, Operation.create(offset, 0, str));
}),
onMessage: enterChainPad(realtime, function (handler) {
- realtime.onMessage = handler;
+ Common.assert(typeof(handler) === 'function');
+ realtime.messageHandlers.push(handler);
}),
message: enterChainPad(realtime, function (message) {
handleMessage(realtime, message);
diff --git a/www/messages.js b/www/common/messages.js
similarity index 100%
rename from www/messages.js
rename to www/common/messages.js
diff --git a/www/otaml.js b/www/common/otaml.js
similarity index 100%
rename from www/otaml.js
rename to www/common/otaml.js
diff --git a/www/common/toolbar.js b/www/common/toolbar.js
new file mode 100644
index 000000000..3399e804b
--- /dev/null
+++ b/www/common/toolbar.js
@@ -0,0 +1,172 @@
+var Toolbar = function ($, container, Messages, myUserName, realtime) {
+
+ /** Id of the element for getting debug info. */
+ var DEBUG_LINK_CLS = 'rtwysiwyg-debug-link';
+
+ /** Id of the div containing the user list. */
+ var USER_LIST_CLS = 'rtwysiwyg-user-list';
+
+ /** Id of the div containing the lag info. */
+ var LAG_ELEM_CLS = 'rtwysiwyg-lag';
+
+ /** The toolbar class which contains the user list, debug link and lag. */
+ var TOOLBAR_CLS = 'rtwysiwyg-toolbar';
+
+ /** Key in the localStore which indicates realtime activity should be disallowed. */
+ var LOCALSTORAGE_DISALLOW = 'rtwysiwyg-disallow';
+
+ var SPINNER_DISAPPEAR_TIME = 3000;
+ var SPINNER = [ '-', '\\', '|', '/' ];
+
+ var uid = function () {
+ return 'rtwysiwyg-uid-' + String(Math.random()).substring(2);
+ };
+
+ var createRealtimeToolbar = function (container) {
+ var id = uid();
+ $(container).prepend(
+ ''
+ );
+ var toolbar = $('#'+id);
+ toolbar.append([
+ ''
+ ].join('\n'));
+ return toolbar;
+ };
+
+ var createSpinner = function (container) {
+ var id = uid();
+ $(container).append('');
+ return $('#'+id)[0];
+ };
+
+ var kickSpinner = function (spinnerElement, reversed) {
+ var txt = spinnerElement.textContent || '-';
+ var inc = (reversed) ? -1 : 1;
+ spinnerElement.textContent = SPINNER[(SPINNER.indexOf(txt) + inc) % SPINNER.length];
+ spinnerElement.timeout && clearTimeout(spinnerElement.timeout);
+ spinnerElement.timeout = setTimeout(function () {
+ spinnerElement.textContent = '';
+ }, SPINNER_DISAPPEAR_TIME);
+ };
+
+ var createUserList = function (container) {
+ var id = uid();
+ $(container).prepend('');
+ return $('#'+id)[0];
+ };
+
+ var updateUserList = function (myUserName, listElement, userList) {
+ var meIdx = userList.indexOf(myUserName);
+ if (meIdx === -1) {
+ listElement.textContent = Messages.synchronizing;
+ return;
+ }
+ if (userList.length === 1) {
+ listElement.textContent = Messages.editingAlone;
+ } else if (userList.length === 2) {
+ listElement.textContent = Messages.editingWithOneOtherPerson;
+ } else {
+ listElement.textContent = Messages.editingWith + ' ' + (userList.length - 1) + ' '
+ Messages.otherPeople;
+ }
+ };
+
+ var createLagElement = function (container) {
+ var id = uid();
+ $(container).append('');
+ return $('#'+id)[0];
+ };
+
+ var checkLag = function (realtime, lagElement) {
+ var lag = realtime.getLag();
+ var lagSec = lag.lag/1000;
+ var lagMsg = Messages.lag + ' ';
+ if (lag.waiting && lagSec > 1) {
+ lagMsg += "?? " + Math.floor(lagSec);
+ } else {
+ lagMsg += lagSec;
+ }
+ lagElement.textContent = lagMsg;
+ };
+
+
+ var toolbar = createRealtimeToolbar(container);
+ var userListElement = createUserList(toolbar.find('.rtwysiwyg-toolbar-leftside'));
+ var spinner = createSpinner(toolbar.find('.rtwysiwyg-toolbar-rightside'));
+ var lagElement = createLagElement(toolbar.find('.rtwysiwyg-toolbar-rightside'));
+
+ var connected = false;
+
+ realtime.onUserListChange(function (userList) {
+ if (userList.indexOf(myUserName) !== -1) { connected = true; }
+ if (!connected) { return; }
+ updateUserList(myUserName, userListElement, userList);
+ });
+
+ var ks = function () {
+ if (connected) { kickSpinner(spinner, false); }
+ };
+
+ realtime.onPatch(ks);
+ realtime.onMessage(ks);
+
+ setInterval(function () {
+ if (!connected) { return; }
+ checkLag(realtime, lagElement);
+ }, 3000);
+
+ return {
+ reconnecting: function () {
+ connected = false;
+ userListElement.textContent = Messages.reconnecting;
+ lagElement.textContent = '';
+ },
+ connected: function () {
+ connected = true;
+ }
+ };
+};
diff --git a/www/index.html b/www/index.html
index 631638b55..ce3cbc7a6 100644
--- a/www/index.html
+++ b/www/index.html
@@ -3,25 +3,32 @@
-
-
+
@@ -48,16 +55,14 @@
get caught and laughed at and humiliated in front of the whole world (again). If you're making
the NSA mad enough for them to use an active attack against you, Great Success Highfive, now take
the battery out of your computer before it spawns Agent Smith.
+
+ Try it out!
+
+
-