diff --git a/www/common/common-userlist2.js b/www/common/common-userlist2.js
new file mode 100644
index 000000000..e7f2449fa
--- /dev/null
+++ b/www/common/common-userlist2.js
@@ -0,0 +1,112 @@
+define(function () {
+ var module = {};
+
+ module.create = function (info, onLocal, Cryptget, Cryptpad) {
+ var exp = {};
+
+ var userData = exp.userData = {};
+ var userList = exp.userList = info.userList;
+ var myData = exp.myData = {};
+ exp.myUserName = info.myID;
+ exp.myNetfluxId = info.myID;
+
+ var network = Cryptpad.getNetwork();
+
+ var parsed = Cryptpad.parsePadUrl(window.location.href);
+ var appType = parsed ? parsed.type : undefined;
+
+ var addToUserData = exp.addToUserData = function(data) {
+ var users = userList.users;
+ for (var attrname in data) { userData[attrname] = data[attrname]; }
+
+ if (users && users.length) {
+ for (var userKey in userData) {
+ if (users.indexOf(userKey) === -1) {
+ delete userData[userKey];
+ }
+ }
+ }
+
+ if(userList && typeof userList.onChange === "function") {
+ userList.onChange(userData);
+ }
+ };
+
+ exp.getToolbarConfig = function () {
+ return {
+ data: userData,
+ list: userList,
+ userNetfluxId: exp.myNetfluxId
+ };
+ };
+
+ var setName = exp.setName = function (newName, cb) {
+ if (typeof(newName) !== 'string') { return; }
+ var myUserNameTemp = newName.trim();
+ if(myUserNameTemp.length > 32) {
+ myUserNameTemp = myUserNameTemp.substr(0, 32);
+ }
+ exp.myUserName = myUserNameTemp;
+ myData = {};
+ myData[exp.myNetfluxId] = {
+ name: exp.myUserName,
+ uid: Cryptpad.getUid(),
+ avatar: Cryptpad.getAvatarUrl(),
+ profile: Cryptpad.getProfileUrl(),
+ curvePublic: Cryptpad.getProxy().curvePublic
+ };
+ addToUserData(myData);
+ /*Cryptpad.setAttribute('username', exp.myUserName, function (err) {
+ if (err) {
+ console.log("Couldn't set username");
+ console.error(err);
+ return;
+ }
+ if (typeof cb === "function") { cb(); }
+ });*/
+ if (typeof cb === "function") { cb(); }
+ };
+
+ exp.getLastName = function ($changeNameButton, isNew) {
+ Cryptpad.getLastName(function (err, lastName) {
+ if (err) {
+ console.log("Could not get previous name");
+ console.error(err);
+ return;
+ }
+ // Update the toolbar list:
+ // Add the current user in the metadata
+ if (typeof(lastName) === 'string') {
+ setName(lastName, onLocal);
+ } else {
+ myData[exp.myNetfluxId] = {
+ name: "",
+ uid: Cryptpad.getUid(),
+ avatar: Cryptpad.getAvatarUrl(),
+ profile: Cryptpad.getProfileUrl(),
+ curvePublic: Cryptpad.getProxy().curvePublic
+ };
+ addToUserData(myData);
+ onLocal();
+ $changeNameButton.click();
+ }
+ if (isNew && appType) {
+ Cryptpad.selectTemplate(appType, info.realtime, Cryptget);
+ }
+ });
+ };
+
+ Cryptpad.onDisplayNameChanged(function (newName) {
+ setName(newName, onLocal);
+ });
+
+ network.on('reconnect', function (uid) {
+ exp.myNetfluxId = uid;
+ exp.setName(exp.myUserName);
+ });
+
+ return exp;
+ };
+
+ return module;
+});
diff --git a/www/common/metadata-manager.js b/www/common/metadata-manager.js
index e69de29bb..9d26d5588 100644
--- a/www/common/metadata-manager.js
+++ b/www/common/metadata-manager.js
@@ -0,0 +1,17 @@
+define([], function () {
+ var metadataChange = function (ctx, newMeta) {
+
+ };
+ var getMetadata = function (ctx) {
+
+ };
+ var create = function (sframeChan, cpNfInner) {
+ var ctx = {
+ sframeChan: sframeChan,
+ personalMetadata: {}
+ };
+
+ };
+ return { create: create };
+
+});
\ No newline at end of file
diff --git a/www/common/sframe-boot2.js b/www/common/sframe-boot2.js
index 94ec9d511..8285032d2 100644
--- a/www/common/sframe-boot2.js
+++ b/www/common/sframe-boot2.js
@@ -1,11 +1,8 @@
// This is stage 1, it can be changed but you must bump the version of the project.
// Note: This must only be loaded from inside of a sandbox-iframe.
-define([
- '/common/requireconfig.js',
- '/common/sframe-channel.js'
-], function (RequireConfig, SFrameChannel) {
+define(['/common/requireconfig.js'], function (RequireConfig) {
require.config(RequireConfig);
-console.log('boot2');
+
// most of CryptPad breaks if you don't support isArray
if (!Array.isArray) {
Array.isArray = function(arg) { // CRYPTPAD_SHIM
@@ -23,7 +20,5 @@ console.log('boot2');
window.__defineGetter__('localStorage', function () { return mkFakeStore(); });
window.__defineGetter__('sessionStorage', function () { return mkFakeStore(); });
- SFrameChannel.init(window.top, function () { });
-
require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]);
});
diff --git a/www/common/sframe-chainpad-netflux-inner.js b/www/common/sframe-chainpad-netflux-inner.js
index 32e1beb0f..efce47a91 100644
--- a/www/common/sframe-chainpad-netflux-inner.js
+++ b/www/common/sframe-chainpad-netflux-inner.js
@@ -15,9 +15,8 @@
* along with this program. If not, see .
*/
define([
- '/common/sframe-channel.js',
'/bower_components/chainpad/chainpad.dist.js',
-], function (SFrameChannel) {
+], function () {
var ChainPad = window.ChainPad;
var module = { exports: {} };
@@ -81,6 +80,7 @@ define([
var avgSyncMilliseconds = config.avgSyncMilliseconds;
var logLevel = typeof(config.logLevel) !== 'undefined'? config.logLevel : 1;
var readOnly = config.readOnly || false;
+ var sframeChan = config.sframeChan;
config = undefined;
var chainpad;
@@ -88,14 +88,14 @@ define([
var myID;
var isReady = false;
- SFrameChannel.on('EV_RT_JOIN', userList.onJoin);
- SFrameChannel.on('EV_RT_LEAVE', userList.onLeave);
- SFrameChannel.on('EV_RT_DISCONNECT', function () {
+ sframeChan.on('EV_RT_JOIN', userList.onJoin);
+ sframeChan.on('EV_RT_LEAVE', userList.onLeave);
+ sframeChan.on('EV_RT_DISCONNECT', function () {
isReady = false;
userList.onReset();
onConnectionChange({ state: false });
});
- SFrameChannel.on('EV_RT_CONNECT', function (content) {
+ sframeChan.on('EV_RT_CONNECT', function (content) {
content.members.forEach(userList.onJoin);
myID = content.myID;
isReady = false;
@@ -113,26 +113,26 @@ define([
logLevel: logLevel
});
chainpad.onMessage(function(message, cb) {
- SFrameChannel.query('Q_RT_MESSAGE', message, cb);
+ sframeChan.query('Q_RT_MESSAGE', message, cb);
});
chainpad.onPatch(function () {
onRemote({ realtime: chainpad });
});
onInit({
- myID: content.myID,
+ myID: myID,
realtime: chainpad,
userList: userList,
readOnly: readOnly
});
});
- SFrameChannel.on('Q_RT_MESSAGE', function (content, cb) {
+ sframeChan.on('Q_RT_MESSAGE', function (content, cb) {
if (isReady) {
onLocal(); // should be onBeforeMessage
}
chainpad.message(content);
cb('OK');
});
- SFrameChannel.on('EV_RT_READY', function () {
+ sframeChan.on('EV_RT_READY', function () {
if (isReady) { return; }
isReady = true;
chainpad.start();
@@ -141,7 +141,9 @@ define([
if (!readOnly) { userList.onJoin(myID); }
onReady({ realtime: chainpad });
});
- return;
+ return {
+ getMyID: function () { return myID; }
+ };
};
return module.exports;
});
\ No newline at end of file
diff --git a/www/common/sframe-chainpad-netflux-outer.js b/www/common/sframe-chainpad-netflux-outer.js
index d28fbe631..078a920e7 100644
--- a/www/common/sframe-chainpad-netflux-outer.js
+++ b/www/common/sframe-chainpad-netflux-outer.js
@@ -14,11 +14,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-define([
- '/common/sframe-channel.js',
-], function (SFrameChannel) {
+define([], function () {
var USE_HISTORY = true;
- var module = { exports: {} };
var verbose = function (x) { console.log(x); };
verbose = function () {}; // comment out to enable verbose logging
@@ -31,6 +28,7 @@ define([
var validateKey = conf.validateKey;
var readOnly = conf.readOnly || false;
var network = conf.network;
+ var sframeChan = conf.sframeChan;
conf = undefined;
var initializing = true;
@@ -38,15 +36,15 @@ define([
var queue = [];
var messageFromInner = function (m, cb) { queue.push([ m, cb ]); };
- SFrameChannel.on('Q_RT_MESSAGE', function (message, cb) {
+ sframeChan.on('Q_RT_MESSAGE', function (message, cb) {
messageFromInner(message, cb);
});
- var onReady = function(wc) {
+ var onReady = function () {
// Trigger onReady only if not ready yet. This is important because the history keeper sends a direct
// message through "network" when it is synced, and it triggers onReady for each channel joined.
if (!initializing) { return; }
- SFrameChannel.event('EV_RT_READY', null);
+ sframeChan.event('EV_RT_READY', null);
// we're fully synced
initializing = false;
};
@@ -122,7 +120,7 @@ define([
message = unBencode(message);//.slice(message.indexOf(':[') + 1);
// pass the message into Chainpad
- SFrameChannel.query('Q_RT_MESSAGE', message, function () { });
+ sframeChan.query('Q_RT_MESSAGE', message, function () { });
};
// We use an object to store the webchannel so that we don't have to push new handlers to chainpad
@@ -134,14 +132,14 @@ define([
channel = wc.id;
// Add the existing peers in the userList
- SFrameChannel.event('EV_RT_CONNECT', { myID: wc.myID, members: wc.members, readOnly: readOnly });
+ sframeChan.event('EV_RT_CONNECT', { myID: wc.myID, members: wc.members, readOnly: readOnly });
// Add the handlers to the WebChannel
wc.on('message', function (msg, sender) { //Channel msg
onMessage(sender, msg, wc, network);
});
- wc.on('join', function (m) { SFrameChannel.event('EV_RT_JOIN', m); });
- wc.on('leave', function (m) { SFrameChannel.event('EV_RT_LEAVE', m); });
+ wc.on('join', function (m) { sframeChan.event('EV_RT_JOIN', m); });
+ wc.on('leave', function (m) { sframeChan.event('EV_RT_LEAVE', m); });
if (firstConnection) {
// Sending a message...
@@ -210,7 +208,7 @@ define([
network.on('disconnect', function (reason) {
if (isIntentionallyLeaving) { return; }
if (reason === "network.disconnect() called") { return; }
- SFrameChannel.event('EV_RT_DISCONNECT');
+ sframeChan.event('EV_RT_DISCONNECT');
});
network.on('reconnect', function (uid) {
@@ -230,7 +228,7 @@ define([
return {
start: function (config) {
- SFrameChannel.whenReg('EV_RT_READY', function () { start(config); });
+ config.sframeChan.whenReg('EV_RT_READY', function () { start(config); });
}
};
});
diff --git a/www/common/sframe-channel.js b/www/common/sframe-channel.js
index 793906c5a..12b390fa7 100644
--- a/www/common/sframe-channel.js
+++ b/www/common/sframe-channel.js
@@ -2,22 +2,92 @@
define([
'/common/sframe-protocol.js'
], function (SFrameProtocol) {
- var otherWindow;
- var handlers = {};
- var queries = {};
-
- // list of handlers which are registered from the other side...
- var insideHandlers = [];
- var callWhenRegistered = {};
-
- var module = { exports: {} };
var mkTxid = function () {
return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', '');
};
- module.exports.init = function (ow, cb) {
- if (otherWindow) { throw new Error('already initialized'); }
+ var create = function (ow, cb) {
+ var otherWindow;
+ var handlers = {};
+ var queries = {};
+
+ // list of handlers which are registered from the other side...
+ var insideHandlers = [];
+ var callWhenRegistered = {};
+
+ var chan = {};
+
+ chan.query = function (q, content, cb) {
+ if (!otherWindow) { throw new Error('not yet initialized'); }
+ if (!SFrameProtocol[q]) {
+ throw new Error('please only make queries are defined in sframe-protocol.js');
+ }
+ var txid = mkTxid();
+ var timeout = setTimeout(function () {
+ delete queries[txid];
+ console.log("Timeout making query " + q);
+ }, 30000);
+ queries[txid] = function (data, msg) {
+ clearTimeout(timeout);
+ delete queries[txid];
+ cb(undefined, data.content, msg);
+ };
+ otherWindow.postMessage(JSON.stringify({
+ txid: txid,
+ content: content,
+ q: q
+ }), '*');
+ };
+
+ var event = chan.event = function (e, content) {
+ if (!otherWindow) { throw new Error('not yet initialized'); }
+ if (!SFrameProtocol[e]) {
+ throw new Error('please only fire events that are defined in sframe-protocol.js');
+ }
+ if (e.indexOf('EV_') !== 0) {
+ throw new Error('please only use events (starting with EV_) for event messages');
+ }
+ otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
+ };
+
+ chan.on = function (queryType, handler) {
+ if (!otherWindow) { throw new Error('not yet initialized'); }
+ if (typeof(handlers[queryType]) !== 'undefined') { throw new Error('already registered'); }
+ if (!SFrameProtocol[queryType]) {
+ throw new Error('please only register handlers which are defined in sframe-protocol.js');
+ }
+ handlers[queryType] = function (data, msg) {
+ handler(data.content, function (replyContent) {
+ msg.source.postMessage(JSON.stringify({
+ txid: data.txid,
+ content: replyContent
+ }), '*');
+ }, msg);
+ };
+ event('EV_REGISTER_HANDLER', queryType);
+ };
+
+ chan.whenReg = function (queryType, handler) {
+ if (!otherWindow) { throw new Error('not yet initialized'); }
+ if (!SFrameProtocol[queryType]) {
+ throw new Error('please only register handlers which are defined in sframe-protocol.js');
+ }
+ if (insideHandlers.indexOf(queryType) > -1) {
+ handler();
+ } else {
+ (callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(handler);
+ }
+ };
+
+ handlers['EV_REGISTER_HANDLER'] = function (data) {
+ if (callWhenRegistered[data.content]) {
+ callWhenRegistered[data.content].forEach(function (f) { f(); });
+ delete callWhenRegistered[data.content];
+ }
+ insideHandlers.push(data.content);
+ };
+
var intr;
var txid;
window.addEventListener('message', function (msg) {
@@ -32,7 +102,7 @@ define([
}
clearInterval(intr);
otherWindow = ow;
- cb();
+ cb(chan);
} else if (typeof(data.q) === 'string' && handlers[data.q]) {
handlers[data.q](data, msg);
} else if (typeof(data.q) === 'undefined' && queries[data.txid]) {
@@ -48,7 +118,7 @@ define([
if (window !== window.top) {
// we're in the sandbox
otherWindow = ow;
- cb();
+ cb(chan);
} else {
require(['/common/requireconfig.js'], function (RequireConfig) {
txid = mkTxid();
@@ -63,75 +133,5 @@ define([
}
};
- module.exports.query = function (q, content, cb) {
- if (!otherWindow) { throw new Error('not yet initialized'); }
- if (!SFrameProtocol[q]) {
- throw new Error('please only make queries are defined in sframe-protocol.js');
- }
- var txid = mkTxid();
- var timeout = setTimeout(function () {
- delete queries[txid];
- console.log("Timeout making query " + q);
- }, 30000);
- queries[txid] = function (data, msg) {
- clearTimeout(timeout);
- delete queries[txid];
- cb(undefined, data.content, msg);
- };
- otherWindow.postMessage(JSON.stringify({
- txid: txid,
- content: content,
- q: q
- }), '*');
- };
-
- var event = module.exports.event = function (e, content) {
- if (!otherWindow) { throw new Error('not yet initialized'); }
- if (!SFrameProtocol[e]) {
- throw new Error('please only fire events that are defined in sframe-protocol.js');
- }
- if (e.indexOf('EV_') !== 0) {
- throw new Error('please only use events (starting with EV_) for event messages');
- }
- otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
- };
-
- module.exports.on = function (queryType, handler) {
- if (!otherWindow) { throw new Error('not yet initialized'); }
- if (typeof(handlers[queryType]) !== 'undefined') { throw new Error('already registered'); }
- if (!SFrameProtocol[queryType]) {
- throw new Error('please only register handlers which are defined in sframe-protocol.js');
- }
- handlers[queryType] = function (data, msg) {
- handler(data.content, function (replyContent) {
- msg.source.postMessage(JSON.stringify({
- txid: data.txid,
- content: replyContent
- }), '*');
- }, msg);
- };
- event('EV_REGISTER_HANDLER', queryType);
- };
-
- module.exports.whenReg = function (queryType, handler) {
- if (!otherWindow) { throw new Error('not yet initialized'); }
- if (!SFrameProtocol[queryType]) {
- throw new Error('please only register handlers which are defined in sframe-protocol.js');
- }
- if (insideHandlers.indexOf(queryType) > -1) {
- handler();
- } else {
- (callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(handler);
- }
- };
-
- handlers['EV_REGISTER_HANDLER'] = function (data) {
- if (callWhenRegistered[data.content]) {
- callWhenRegistered[data.content].forEach(function (f) { f(); });
- delete callWhenRegistered[data.content];
- }
- insideHandlers.push(data.content);
- };
-
- return module.exports;
+ return { create: create };
});
diff --git a/www/common/sframe-protocol.js b/www/common/sframe-protocol.js
index 503dc2983..b6ab3f7b8 100644
--- a/www/common/sframe-protocol.js
+++ b/www/common/sframe-protocol.js
@@ -4,6 +4,11 @@
// Please document the queries and events you create, and please please avoid making generic
// "do stuff" events/queries which are used for many different things because it makes the
// protocol unclear.
+//
+// WARNING: At this point, this protocol is still EXPERIMENTAL. This is not it's final form.
+// We need to define protocol one piece at a time and then when we are satisfied that we
+// fully understand the problem, we will define the *right* protocol and this file will be dynomited.
+//
define({
// When the iframe first launches, this query is sent repeatedly by the controller
// to wait for it to awake and give it the requirejs config to use.
diff --git a/www/pad2/main.js b/www/pad2/main.js
index bf92010e8..064153914 100644
--- a/www/pad2/main.js
+++ b/www/pad2/main.js
@@ -14,6 +14,7 @@ define([
'/common/cryptget.js',
'/pad/links.js',
'/bower_components/nthen/index.js',
+ '/common/sframe-channel.js',
'/bower_components/file-saver/FileSaver.min.js',
'/bower_components/diff-dom/diffDOM.js',
@@ -21,8 +22,8 @@ define([
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/customize/src/less/cryptpad.less',
'less!/customize/src/less/toolbar.less'
-], function ($, Crypto, realtimeInput, Hyperjson,
- Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad, Cryptget, Links, nThen) {
+], function ($, Crypto, CpNfInner, Hyperjson,
+ Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad, Cryptget, Links, nThen, SFrameChannel) {
var saveAs = window.saveAs;
var Messages = Cryptpad.Messages;
var DiffDom = window.diffDOM;
@@ -84,67 +85,48 @@ define([
Cryptpad.errorLoadingScreen(Messages.websocketError);
};
- var andThen = function (editor) {
- //var $iframe = $('#pad-iframe').contents();
- //var secret = Cryptpad.getSecrets();
- //var readOnly = secret.keys && !secret.keys.editKeyStr;
- //if (!secret.keys) {
- // secret.keys = secret.key;
- //}
- var readOnly = false; // TODO
-
-
- var $bar = $('#cke_1_toolbox');
-
- var $html = $bar.closest('html');
- var $faLink = $html.find('head link[href*="/bower_components/components-font-awesome/css/font-awesome.min.css"]');
- if ($faLink.length) {
- $html.find('iframe').contents().find('head').append($faLink.clone());
- }
- var isHistoryMode = false;
-
- if (readOnly) {
- $('#cke_1_toolbox > .cke_toolbox_main').hide();
- }
-
- /* add a class to the magicline plugin so we can pick it out more easily */
-
- var ml = window.CKEDITOR.instances.editor1.plugins.magicline.backdoor.that.line.$;
-
- [ml, ml.parentElement].forEach(function (el) {
- el.setAttribute('class', 'non-realtime');
- });
-
- var documentBody = $html.find('iframe')[0].contentWindow.document.body;
+ var domFromHTML = function (html) {
+ return new DOMParser().parseFromString(html, 'text/html');
+ };
- var inner = window.inner = documentBody;
+ var forbiddenTags = [
+ 'SCRIPT',
+ 'IFRAME',
+ 'OBJECT',
+ 'APPLET',
+ 'VIDEO',
+ 'AUDIO'
+ ];
+
+ var openLink = function (e) {
+ var el = e.currentTarget;
+ if (!el || el.nodeName !== 'A') { return; }
+ var href = el.getAttribute('href');
+ if (href) { window.open(href, '_blank'); }
+ };
- var cursor = module.cursor = Cursor(inner);
+ var getHTML = function (inner) {
+ return ('\n' + '\n' + inner.innerHTML);
+ };
- var setEditable = module.setEditable = function (bool) {
- if (bool) {
- $(inner).css({
- color: '#333',
- });
- }
- if (!readOnly || !bool) {
- inner.setAttribute('contenteditable', bool);
+ var CKEDITOR_CHECK_INTERVAL = 100;
+ var ckEditorAvailable = function (cb) {
+ var intr;
+ var check = function () {
+ if (window.CKEDITOR) {
+ clearTimeout(intr);
+ cb(window.CKEDITOR);
}
};
+ intr = setInterval(function () {
+ console.log("Ckeditor was not defined. Trying again in %sms", CKEDITOR_CHECK_INTERVAL);
+ check();
+ }, CKEDITOR_CHECK_INTERVAL);
+ check();
+ };
- // don't let the user edit until the pad is ready
- setEditable(false);
-
- var forbiddenTags = [
- 'SCRIPT',
- 'IFRAME',
- 'OBJECT',
- 'APPLET',
- 'VIDEO',
- 'AUDIO'
- ];
-
- var diffOptions = {
+ var mkDiffOptions = function (cursor, readOnly) {
+ return {
preDiffApply: function (info) {
/*
Don't accept attributes that begin with 'on'
@@ -262,12 +244,69 @@ define([
}
}
};
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ var andThen = function (editor, Ckeditor, sframeChan) {
+ //var $iframe = $('#pad-iframe').contents();
+ //var secret = Cryptpad.getSecrets();
+ //var readOnly = secret.keys && !secret.keys.editKeyStr;
+ //if (!secret.keys) {
+ // secret.keys = secret.key;
+ //}
+ var readOnly = false; // TODO
+
+
+ var $bar = $('#cke_1_toolbox');
+
+ var $html = $bar.closest('html');
+ var $faLink = $html.find('head link[href*="/bower_components/components-font-awesome/css/font-awesome.min.css"]');
+ if ($faLink.length) {
+ $html.find('iframe').contents().find('head').append($faLink.clone());
+ }
+ var isHistoryMode = false;
+
+ if (readOnly) {
+ $('#cke_1_toolbox > .cke_toolbox_main').hide();
+ }
+
+ /* add a class to the magicline plugin so we can pick it out more easily */
+
+ var ml = Ckeditor.instances.editor1.plugins.magicline.backdoor.that.line.$;
+ [ml, ml.parentElement].forEach(function (el) {
+ el.setAttribute('class', 'non-realtime');
+ });
+
+ var documentBody = $html.find('iframe')[0].contentWindow.document.body;
+
+ var inner = window.inner = documentBody;
+
+ var cursor = module.cursor = Cursor(inner);
+
+ var setEditable = module.setEditable = function (bool) {
+ if (bool) {
+ $(inner).css({
+ color: '#333',
+ });
+ }
+ if (!readOnly || !bool) {
+ inner.setAttribute('contenteditable', bool);
+ }
+ };
+
+ // don't let the user edit until the pad is ready
+ setEditable(false);
var initializing = true;
- var Title;
- var UserList;
- var Metadata;
+ //var Title;
+ //var UserList;
+ //var Metadata;
var getHeadingText = function () {
var text;
@@ -280,14 +319,7 @@ define([
})) { return text; }
};
- var DD = new DiffDom(diffOptions);
-
- var openLink = function (e) {
- var el = e.currentTarget;
- if (!el || el.nodeName !== 'A') { return; }
- var href = el.getAttribute('href');
- if (href) { window.open(href, '_blank'); }
- };
+ var DD = new DiffDom(mkDiffOptions(cursor, readOnly));
// apply patches, and try not to lose the cursor in the process!
var applyHjson = function (shjson) {
@@ -323,28 +355,12 @@ define([
};
var realtimeOptions = {
- // the websocket URL
- websocketURL: Cryptpad.getWebsocketURL(),
-
- // the channel we will communicate over
- channel: 'x',//secret.channel,
-
- // the nework used for the file store if it exists
- network: Cryptpad.getNetwork(),
-
- // our public key
- validateKey: undefined,//secret.keys.validateKey || undefined,
+ sframeChan: sframeChan,
readOnly: readOnly,
-
- // Pass in encrypt and decrypt methods
- crypto: undefined,//Crypto.createEncryptor(secret.keys),
-
// really basic operational transform
transformFunction : JsonOT.validate,
-
// cryptpad debug logging (default is 1)
// logLevel: 0,
-
validateContent: function (content) {
try {
JSON.parse(content);
@@ -440,16 +456,8 @@ define([
}
};
- var getHTML = function () {
- return ('\n' + '\n' + inner.innerHTML);
- };
-
- var domFromHTML = function (html) {
- return new DOMParser().parseFromString(html, 'text/html');
- };
-
var exportFile = function () {
- var html = getHTML();
+ var html = getHTML(inner);
var suggestion = Title.suggestTitle('cryptpad-document');
Cryptpad.prompt(Messages.exportPrompt,
Cryptpad.fixFileName(suggestion) + '.html', function (filename) {
@@ -477,7 +485,8 @@ define([
Metadata = Cryptpad.createMetadata(UserList, Title, null, Cryptpad);
var configTb = {
- displayed: ['title', 'useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad', 'limit', 'upgrade'],
+ displayed: [
+ 'title', 'useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad', 'limit', 'upgrade'],
userList: UserList.getToolbarConfig(),
share: {
secret: secret,
@@ -648,14 +657,6 @@ define([
cursor.setToStart();
}
};
-/* unreachable
- realtimeOptions.onAbort = function () {
- console.log("Aborting the session!");
- // stop the user from continuing to edit
- setEditable(false);
- toolbar.failed();
- Cryptpad.alert(Messages.common_connectionLost, undefined, true);
- }; */
realtimeOptions.onConnectionChange = function (info) {
setEditable(info.state);
@@ -685,7 +686,9 @@ define([
}
};
- module.realtimeInput = realtimeInput.start(realtimeOptions);
+ var cpNfInner = CpNfInner.start(realtimeOptions);
+
+
Cryptpad.onLogout(function () { setEditable(false); });
@@ -725,32 +728,17 @@ define([
});
};
-
- var CKEDITOR_CHECK_INTERVAL = 100;
- var ckEditorAvailable = function (cb) {
- var intr;
- var check = function () {
- if (window.CKEDITOR) {
- clearTimeout(intr);
- cb(window.CKEDITOR);
- }
- };
- intr = setInterval(function () {
- console.log("Ckeditor was not defined. Trying again in %sms", CKEDITOR_CHECK_INTERVAL);
- check();
- }, CKEDITOR_CHECK_INTERVAL);
- check();
- };
-
var main = function () {
var Ckeditor;
var editor;
+ var sframeChan;
nThen(function (waitFor) {
ckEditorAvailable(waitFor(function (ck) { Ckeditor = ck; }));
$(waitFor(function () {
Cryptpad.addLoadingScreen();
}));
+ SFrameChannel.create(window.top, waitFor(function (sfc) { sframeChan = sfc; }));
}).nThen(function (waitFor) {
Ckeditor.config.toolbarCanCollapse = true;
if (screen.height < 800) {
@@ -770,7 +758,7 @@ define([
onConnectError();
}
});
- andThen(editor);
+ andThen(editor, Ckeditor, sframeChan);
});
};
main();
diff --git a/www/pad2/outer.js b/www/pad2/outer.js
index 8e09a6ea0..e24a9a4b8 100644
--- a/www/pad2/outer.js
+++ b/www/pad2/outer.js
@@ -8,10 +8,12 @@ define([
'/bower_components/chainpad-crypto/crypto.js'
], function (SFrameChannel, $, CpNfOuter, nThen, Cryptpad, Crypto) {
console.log('xxx');
+ var sframeChan;
nThen(function (waitFor) {
$(waitFor());
}).nThen(function (waitFor) {
- SFrameChannel.init($('#sbox-iframe')[0].contentWindow, waitFor(function () {
+ SFrameChannel.create($('#sbox-iframe')[0].contentWindow, waitFor(function (sfc) {
+ sframeChan = sfc;
console.log('sframe initialized');
}));
Cryptpad.ready(waitFor());
@@ -23,12 +25,13 @@ define([
//onConnectError();
}
});
- }).nThen(function (waitFor) {
+
var secret = Cryptpad.getSecrets();
var readOnly = secret.keys && !secret.keys.editKeyStr;
if (!secret.keys) { secret.keys = secret.key; }
- var outer = CpNfOuter.start({
+ CpNfOuter.start({
+ sframeChan: sframeChan,
channel: secret.channel,
network: Cryptpad.getNetwork(),
validateKey: secret.keys.validateKey || undefined,