pull/1/head
Caleb James DeLisle 7 years ago
parent e49a42db18
commit c304071492

@ -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;
});

@ -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 };
});

@ -1,11 +1,8 @@
// This is stage 1, it can be changed but you must bump the version of the project. // 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. // Note: This must only be loaded from inside of a sandbox-iframe.
define([ define(['/common/requireconfig.js'], function (RequireConfig) {
'/common/requireconfig.js',
'/common/sframe-channel.js'
], function (RequireConfig, SFrameChannel) {
require.config(RequireConfig); require.config(RequireConfig);
console.log('boot2');
// most of CryptPad breaks if you don't support isArray // most of CryptPad breaks if you don't support isArray
if (!Array.isArray) { if (!Array.isArray) {
Array.isArray = function(arg) { // CRYPTPAD_SHIM Array.isArray = function(arg) { // CRYPTPAD_SHIM
@ -23,7 +20,5 @@ console.log('boot2');
window.__defineGetter__('localStorage', function () { return mkFakeStore(); }); window.__defineGetter__('localStorage', function () { return mkFakeStore(); });
window.__defineGetter__('sessionStorage', function () { return mkFakeStore(); }); window.__defineGetter__('sessionStorage', function () { return mkFakeStore(); });
SFrameChannel.init(window.top, function () { });
require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]); require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]);
}); });

@ -15,9 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
define([ define([
'/common/sframe-channel.js',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
], function (SFrameChannel) { ], function () {
var ChainPad = window.ChainPad; var ChainPad = window.ChainPad;
var module = { exports: {} }; var module = { exports: {} };
@ -81,6 +80,7 @@ define([
var avgSyncMilliseconds = config.avgSyncMilliseconds; var avgSyncMilliseconds = config.avgSyncMilliseconds;
var logLevel = typeof(config.logLevel) !== 'undefined'? config.logLevel : 1; var logLevel = typeof(config.logLevel) !== 'undefined'? config.logLevel : 1;
var readOnly = config.readOnly || false; var readOnly = config.readOnly || false;
var sframeChan = config.sframeChan;
config = undefined; config = undefined;
var chainpad; var chainpad;
@ -88,14 +88,14 @@ define([
var myID; var myID;
var isReady = false; var isReady = false;
SFrameChannel.on('EV_RT_JOIN', userList.onJoin); sframeChan.on('EV_RT_JOIN', userList.onJoin);
SFrameChannel.on('EV_RT_LEAVE', userList.onLeave); sframeChan.on('EV_RT_LEAVE', userList.onLeave);
SFrameChannel.on('EV_RT_DISCONNECT', function () { sframeChan.on('EV_RT_DISCONNECT', function () {
isReady = false; isReady = false;
userList.onReset(); userList.onReset();
onConnectionChange({ state: false }); onConnectionChange({ state: false });
}); });
SFrameChannel.on('EV_RT_CONNECT', function (content) { sframeChan.on('EV_RT_CONNECT', function (content) {
content.members.forEach(userList.onJoin); content.members.forEach(userList.onJoin);
myID = content.myID; myID = content.myID;
isReady = false; isReady = false;
@ -113,26 +113,26 @@ define([
logLevel: logLevel logLevel: logLevel
}); });
chainpad.onMessage(function(message, cb) { chainpad.onMessage(function(message, cb) {
SFrameChannel.query('Q_RT_MESSAGE', message, cb); sframeChan.query('Q_RT_MESSAGE', message, cb);
}); });
chainpad.onPatch(function () { chainpad.onPatch(function () {
onRemote({ realtime: chainpad }); onRemote({ realtime: chainpad });
}); });
onInit({ onInit({
myID: content.myID, myID: myID,
realtime: chainpad, realtime: chainpad,
userList: userList, userList: userList,
readOnly: readOnly readOnly: readOnly
}); });
}); });
SFrameChannel.on('Q_RT_MESSAGE', function (content, cb) { sframeChan.on('Q_RT_MESSAGE', function (content, cb) {
if (isReady) { if (isReady) {
onLocal(); // should be onBeforeMessage onLocal(); // should be onBeforeMessage
} }
chainpad.message(content); chainpad.message(content);
cb('OK'); cb('OK');
}); });
SFrameChannel.on('EV_RT_READY', function () { sframeChan.on('EV_RT_READY', function () {
if (isReady) { return; } if (isReady) { return; }
isReady = true; isReady = true;
chainpad.start(); chainpad.start();
@ -141,7 +141,9 @@ define([
if (!readOnly) { userList.onJoin(myID); } if (!readOnly) { userList.onJoin(myID); }
onReady({ realtime: chainpad }); onReady({ realtime: chainpad });
}); });
return; return {
getMyID: function () { return myID; }
};
}; };
return module.exports; return module.exports;
}); });

@ -14,11 +14,8 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
define([ define([], function () {
'/common/sframe-channel.js',
], function (SFrameChannel) {
var USE_HISTORY = true; var USE_HISTORY = true;
var module = { exports: {} };
var verbose = function (x) { console.log(x); }; var verbose = function (x) { console.log(x); };
verbose = function () {}; // comment out to enable verbose logging verbose = function () {}; // comment out to enable verbose logging
@ -31,6 +28,7 @@ define([
var validateKey = conf.validateKey; var validateKey = conf.validateKey;
var readOnly = conf.readOnly || false; var readOnly = conf.readOnly || false;
var network = conf.network; var network = conf.network;
var sframeChan = conf.sframeChan;
conf = undefined; conf = undefined;
var initializing = true; var initializing = true;
@ -38,15 +36,15 @@ define([
var queue = []; var queue = [];
var messageFromInner = function (m, cb) { queue.push([ m, cb ]); }; 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); 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 // 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. // message through "network" when it is synced, and it triggers onReady for each channel joined.
if (!initializing) { return; } if (!initializing) { return; }
SFrameChannel.event('EV_RT_READY', null); sframeChan.event('EV_RT_READY', null);
// we're fully synced // we're fully synced
initializing = false; initializing = false;
}; };
@ -122,7 +120,7 @@ define([
message = unBencode(message);//.slice(message.indexOf(':[') + 1); message = unBencode(message);//.slice(message.indexOf(':[') + 1);
// pass the message into Chainpad // 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 // 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; channel = wc.id;
// Add the existing peers in the userList // 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 // Add the handlers to the WebChannel
wc.on('message', function (msg, sender) { //Channel msg wc.on('message', function (msg, sender) { //Channel msg
onMessage(sender, msg, wc, network); onMessage(sender, msg, wc, network);
}); });
wc.on('join', function (m) { SFrameChannel.event('EV_RT_JOIN', m); }); wc.on('join', function (m) { sframeChan.event('EV_RT_JOIN', m); });
wc.on('leave', function (m) { SFrameChannel.event('EV_RT_LEAVE', m); }); wc.on('leave', function (m) { sframeChan.event('EV_RT_LEAVE', m); });
if (firstConnection) { if (firstConnection) {
// Sending a message... // Sending a message...
@ -210,7 +208,7 @@ define([
network.on('disconnect', function (reason) { network.on('disconnect', function (reason) {
if (isIntentionallyLeaving) { return; } if (isIntentionallyLeaving) { return; }
if (reason === "network.disconnect() called") { return; } if (reason === "network.disconnect() called") { return; }
SFrameChannel.event('EV_RT_DISCONNECT'); sframeChan.event('EV_RT_DISCONNECT');
}); });
network.on('reconnect', function (uid) { network.on('reconnect', function (uid) {
@ -230,7 +228,7 @@ define([
return { return {
start: function (config) { start: function (config) {
SFrameChannel.whenReg('EV_RT_READY', function () { start(config); }); config.sframeChan.whenReg('EV_RT_READY', function () { start(config); });
} }
}; };
}); });

@ -2,6 +2,12 @@
define([ define([
'/common/sframe-protocol.js' '/common/sframe-protocol.js'
], function (SFrameProtocol) { ], function (SFrameProtocol) {
var mkTxid = function () {
return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', '');
};
var create = function (ow, cb) {
var otherWindow; var otherWindow;
var handlers = {}; var handlers = {};
var queries = {}; var queries = {};
@ -10,60 +16,9 @@ define([
var insideHandlers = []; var insideHandlers = [];
var callWhenRegistered = {}; var callWhenRegistered = {};
var module = { exports: {} }; var chan = {};
var mkTxid = function () {
return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', '');
};
module.exports.init = function (ow, cb) { chan.query = function (q, content, cb) {
if (otherWindow) { throw new Error('already initialized'); }
var intr;
var txid;
window.addEventListener('message', function (msg) {
var data = JSON.parse(msg.data);
if (ow !== msg.source) {
console.log("DROP Message from unexpected source");
console.log(msg);
} else if (!otherWindow) {
if (data.txid !== txid) {
console.log("DROP Message with weird txid");
return;
}
clearInterval(intr);
otherWindow = ow;
cb();
} else if (typeof(data.q) === 'string' && handlers[data.q]) {
handlers[data.q](data, msg);
} else if (typeof(data.q) === 'undefined' && queries[data.txid]) {
queries[data.txid](data, msg);
} else if (data.txid === txid) {
// stray message from init
return;
} else {
console.log("DROP Unhandled message");
console.log(msg);
}
});
if (window !== window.top) {
// we're in the sandbox
otherWindow = ow;
cb();
} else {
require(['/common/requireconfig.js'], function (RequireConfig) {
txid = mkTxid();
intr = setInterval(function () {
ow.postMessage(JSON.stringify({
txid: txid,
content: { requireConf: RequireConfig },
q: 'INIT'
}), '*');
});
});
}
};
module.exports.query = function (q, content, cb) {
if (!otherWindow) { throw new Error('not yet initialized'); } if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[q]) { if (!SFrameProtocol[q]) {
throw new Error('please only make queries are defined in sframe-protocol.js'); throw new Error('please only make queries are defined in sframe-protocol.js');
@ -85,7 +40,7 @@ define([
}), '*'); }), '*');
}; };
var event = module.exports.event = function (e, content) { var event = chan.event = function (e, content) {
if (!otherWindow) { throw new Error('not yet initialized'); } if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[e]) { if (!SFrameProtocol[e]) {
throw new Error('please only fire events that are defined in sframe-protocol.js'); throw new Error('please only fire events that are defined in sframe-protocol.js');
@ -96,7 +51,7 @@ define([
otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*'); otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
}; };
module.exports.on = function (queryType, handler) { chan.on = function (queryType, handler) {
if (!otherWindow) { throw new Error('not yet initialized'); } if (!otherWindow) { throw new Error('not yet initialized'); }
if (typeof(handlers[queryType]) !== 'undefined') { throw new Error('already registered'); } if (typeof(handlers[queryType]) !== 'undefined') { throw new Error('already registered'); }
if (!SFrameProtocol[queryType]) { if (!SFrameProtocol[queryType]) {
@ -113,7 +68,7 @@ define([
event('EV_REGISTER_HANDLER', queryType); event('EV_REGISTER_HANDLER', queryType);
}; };
module.exports.whenReg = function (queryType, handler) { chan.whenReg = function (queryType, handler) {
if (!otherWindow) { throw new Error('not yet initialized'); } if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[queryType]) { if (!SFrameProtocol[queryType]) {
throw new Error('please only register handlers which are defined in sframe-protocol.js'); throw new Error('please only register handlers which are defined in sframe-protocol.js');
@ -133,5 +88,50 @@ define([
insideHandlers.push(data.content); insideHandlers.push(data.content);
}; };
return module.exports; var intr;
var txid;
window.addEventListener('message', function (msg) {
var data = JSON.parse(msg.data);
if (ow !== msg.source) {
console.log("DROP Message from unexpected source");
console.log(msg);
} else if (!otherWindow) {
if (data.txid !== txid) {
console.log("DROP Message with weird txid");
return;
}
clearInterval(intr);
otherWindow = ow;
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]) {
queries[data.txid](data, msg);
} else if (data.txid === txid) {
// stray message from init
return;
} else {
console.log("DROP Unhandled message");
console.log(msg);
}
});
if (window !== window.top) {
// we're in the sandbox
otherWindow = ow;
cb(chan);
} else {
require(['/common/requireconfig.js'], function (RequireConfig) {
txid = mkTxid();
intr = setInterval(function () {
ow.postMessage(JSON.stringify({
txid: txid,
content: { requireConf: RequireConfig },
q: 'INIT'
}), '*');
});
});
}
};
return { create: create };
}); });

@ -4,6 +4,11 @@
// Please document the queries and events you create, and please please avoid making generic // 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 // "do stuff" events/queries which are used for many different things because it makes the
// protocol unclear. // 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({ define({
// When the iframe first launches, this query is sent repeatedly by the controller // 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. // to wait for it to awake and give it the requirejs config to use.

@ -14,6 +14,7 @@ define([
'/common/cryptget.js', '/common/cryptget.js',
'/pad/links.js', '/pad/links.js',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/common/sframe-channel.js',
'/bower_components/file-saver/FileSaver.min.js', '/bower_components/file-saver/FileSaver.min.js',
'/bower_components/diff-dom/diffDOM.js', '/bower_components/diff-dom/diffDOM.js',
@ -21,8 +22,8 @@ define([
'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/customize/src/less/cryptpad.less', 'less!/customize/src/less/cryptpad.less',
'less!/customize/src/less/toolbar.less' 'less!/customize/src/less/toolbar.less'
], function ($, Crypto, realtimeInput, Hyperjson, ], function ($, Crypto, CpNfInner, Hyperjson,
Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad, Cryptget, Links, nThen) { Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad, Cryptget, Links, nThen, SFrameChannel) {
var saveAs = window.saveAs; var saveAs = window.saveAs;
var Messages = Cryptpad.Messages; var Messages = Cryptpad.Messages;
var DiffDom = window.diffDOM; var DiffDom = window.diffDOM;
@ -84,57 +85,10 @@ define([
Cryptpad.errorLoadingScreen(Messages.websocketError); Cryptpad.errorLoadingScreen(Messages.websocketError);
}; };
var andThen = function (editor) { var domFromHTML = function (html) {
//var $iframe = $('#pad-iframe').contents(); return new DOMParser().parseFromString(html, 'text/html');
//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 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 forbiddenTags = [ var forbiddenTags = [
'SCRIPT', 'SCRIPT',
'IFRAME', 'IFRAME',
@ -144,7 +98,35 @@ define([
'AUDIO' 'AUDIO'
]; ];
var 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 getHTML = function (inner) {
return ('<!DOCTYPE html>\n' + '<html>\n' + inner.innerHTML);
};
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 mkDiffOptions = function (cursor, readOnly) {
return {
preDiffApply: function (info) { preDiffApply: function (info) {
/* /*
Don't accept attributes that begin with 'on' 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 initializing = true;
var Title; //var Title;
var UserList; //var UserList;
var Metadata; //var Metadata;
var getHeadingText = function () { var getHeadingText = function () {
var text; var text;
@ -280,14 +319,7 @@ define([
})) { return text; } })) { return text; }
}; };
var DD = new DiffDom(diffOptions); var DD = new DiffDom(mkDiffOptions(cursor, readOnly));
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'); }
};
// apply patches, and try not to lose the cursor in the process! // apply patches, and try not to lose the cursor in the process!
var applyHjson = function (shjson) { var applyHjson = function (shjson) {
@ -323,28 +355,12 @@ define([
}; };
var realtimeOptions = { var realtimeOptions = {
// the websocket URL sframeChan: sframeChan,
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,
readOnly: readOnly, readOnly: readOnly,
// Pass in encrypt and decrypt methods
crypto: undefined,//Crypto.createEncryptor(secret.keys),
// really basic operational transform // really basic operational transform
transformFunction : JsonOT.validate, transformFunction : JsonOT.validate,
// cryptpad debug logging (default is 1) // cryptpad debug logging (default is 1)
// logLevel: 0, // logLevel: 0,
validateContent: function (content) { validateContent: function (content) {
try { try {
JSON.parse(content); JSON.parse(content);
@ -440,16 +456,8 @@ define([
} }
}; };
var getHTML = function () {
return ('<!DOCTYPE html>\n' + '<html>\n' + inner.innerHTML);
};
var domFromHTML = function (html) {
return new DOMParser().parseFromString(html, 'text/html');
};
var exportFile = function () { var exportFile = function () {
var html = getHTML(); var html = getHTML(inner);
var suggestion = Title.suggestTitle('cryptpad-document'); var suggestion = Title.suggestTitle('cryptpad-document');
Cryptpad.prompt(Messages.exportPrompt, Cryptpad.prompt(Messages.exportPrompt,
Cryptpad.fixFileName(suggestion) + '.html', function (filename) { Cryptpad.fixFileName(suggestion) + '.html', function (filename) {
@ -477,7 +485,8 @@ define([
Metadata = Cryptpad.createMetadata(UserList, Title, null, Cryptpad); Metadata = Cryptpad.createMetadata(UserList, Title, null, Cryptpad);
var configTb = { 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(), userList: UserList.getToolbarConfig(),
share: { share: {
secret: secret, secret: secret,
@ -648,14 +657,6 @@ define([
cursor.setToStart(); 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) { realtimeOptions.onConnectionChange = function (info) {
setEditable(info.state); setEditable(info.state);
@ -685,7 +686,9 @@ define([
} }
}; };
module.realtimeInput = realtimeInput.start(realtimeOptions); var cpNfInner = CpNfInner.start(realtimeOptions);
Cryptpad.onLogout(function () { setEditable(false); }); 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 main = function () {
var Ckeditor; var Ckeditor;
var editor; var editor;
var sframeChan;
nThen(function (waitFor) { nThen(function (waitFor) {
ckEditorAvailable(waitFor(function (ck) { Ckeditor = ck; })); ckEditorAvailable(waitFor(function (ck) { Ckeditor = ck; }));
$(waitFor(function () { $(waitFor(function () {
Cryptpad.addLoadingScreen(); Cryptpad.addLoadingScreen();
})); }));
SFrameChannel.create(window.top, waitFor(function (sfc) { sframeChan = sfc; }));
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
Ckeditor.config.toolbarCanCollapse = true; Ckeditor.config.toolbarCanCollapse = true;
if (screen.height < 800) { if (screen.height < 800) {
@ -770,7 +758,7 @@ define([
onConnectError(); onConnectError();
} }
}); });
andThen(editor); andThen(editor, Ckeditor, sframeChan);
}); });
}; };
main(); main();

@ -8,10 +8,12 @@ define([
'/bower_components/chainpad-crypto/crypto.js' '/bower_components/chainpad-crypto/crypto.js'
], function (SFrameChannel, $, CpNfOuter, nThen, Cryptpad, Crypto) { ], function (SFrameChannel, $, CpNfOuter, nThen, Cryptpad, Crypto) {
console.log('xxx'); console.log('xxx');
var sframeChan;
nThen(function (waitFor) { nThen(function (waitFor) {
$(waitFor()); $(waitFor());
}).nThen(function (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'); console.log('sframe initialized');
})); }));
Cryptpad.ready(waitFor()); Cryptpad.ready(waitFor());
@ -23,12 +25,13 @@ define([
//onConnectError(); //onConnectError();
} }
}); });
}).nThen(function (waitFor) {
var secret = Cryptpad.getSecrets(); var secret = Cryptpad.getSecrets();
var readOnly = secret.keys && !secret.keys.editKeyStr; var readOnly = secret.keys && !secret.keys.editKeyStr;
if (!secret.keys) { secret.keys = secret.key; } if (!secret.keys) { secret.keys = secret.key; }
var outer = CpNfOuter.start({ CpNfOuter.start({
sframeChan: sframeChan,
channel: secret.channel, channel: secret.channel,
network: Cryptpad.getNetwork(), network: Cryptpad.getNetwork(),
validateKey: secret.keys.validateKey || undefined, validateKey: secret.keys.validateKey || undefined,

Loading…
Cancel
Save