wip
This commit is contained in:
parent
e49a42db18
commit
c304071492
112
www/common/common-userlist2.js
Normal file
112
www/common/common-userlist2.js
Normal file
@ -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,22 +2,92 @@
|
|||||||
define([
|
define([
|
||||||
'/common/sframe-protocol.js'
|
'/common/sframe-protocol.js'
|
||||||
], function (SFrameProtocol) {
|
], 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 () {
|
var mkTxid = function () {
|
||||||
return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', '');
|
return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', '');
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.init = function (ow, cb) {
|
var create = function (ow, cb) {
|
||||||
if (otherWindow) { throw new Error('already initialized'); }
|
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 intr;
|
||||||
var txid;
|
var txid;
|
||||||
window.addEventListener('message', function (msg) {
|
window.addEventListener('message', function (msg) {
|
||||||
@ -32,7 +102,7 @@ define([
|
|||||||
}
|
}
|
||||||
clearInterval(intr);
|
clearInterval(intr);
|
||||||
otherWindow = ow;
|
otherWindow = ow;
|
||||||
cb();
|
cb(chan);
|
||||||
} else if (typeof(data.q) === 'string' && handlers[data.q]) {
|
} else if (typeof(data.q) === 'string' && handlers[data.q]) {
|
||||||
handlers[data.q](data, msg);
|
handlers[data.q](data, msg);
|
||||||
} else if (typeof(data.q) === 'undefined' && queries[data.txid]) {
|
} else if (typeof(data.q) === 'undefined' && queries[data.txid]) {
|
||||||
@ -48,7 +118,7 @@ define([
|
|||||||
if (window !== window.top) {
|
if (window !== window.top) {
|
||||||
// we're in the sandbox
|
// we're in the sandbox
|
||||||
otherWindow = ow;
|
otherWindow = ow;
|
||||||
cb();
|
cb(chan);
|
||||||
} else {
|
} else {
|
||||||
require(['/common/requireconfig.js'], function (RequireConfig) {
|
require(['/common/requireconfig.js'], function (RequireConfig) {
|
||||||
txid = mkTxid();
|
txid = mkTxid();
|
||||||
@ -63,75 +133,5 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.query = function (q, content, cb) {
|
return { create: create };
|
||||||
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;
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
230
www/pad2/main.js
230
www/pad2/main.js
@ -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,67 +85,48 @@ 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 forbiddenTags = [
|
||||||
|
'SCRIPT',
|
||||||
|
'IFRAME',
|
||||||
|
'OBJECT',
|
||||||
|
'APPLET',
|
||||||
|
'VIDEO',
|
||||||
|
'AUDIO'
|
||||||
|
];
|
||||||
|
|
||||||
var $bar = $('#cke_1_toolbox');
|
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 $html = $bar.closest('html');
|
var getHTML = function (inner) {
|
||||||
var $faLink = $html.find('head link[href*="/bower_components/components-font-awesome/css/font-awesome.min.css"]');
|
return ('<!DOCTYPE html>\n' + '<html>\n' + inner.innerHTML);
|
||||||
if ($faLink.length) {
|
};
|
||||||
$html.find('iframe').contents().find('head').append($faLink.clone());
|
|
||||||
}
|
|
||||||
var isHistoryMode = false;
|
|
||||||
|
|
||||||
if (readOnly) {
|
var CKEDITOR_CHECK_INTERVAL = 100;
|
||||||
$('#cke_1_toolbox > .cke_toolbox_main').hide();
|
var ckEditorAvailable = function (cb) {
|
||||||
}
|
var intr;
|
||||||
|
var check = function () {
|
||||||
/* add a class to the magicline plugin so we can pick it out more easily */
|
if (window.CKEDITOR) {
|
||||||
|
clearTimeout(intr);
|
||||||
var ml = window.CKEDITOR.instances.editor1.plugins.magicline.backdoor.that.line.$;
|
cb(window.CKEDITOR);
|
||||||
|
|
||||||
[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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
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
|
var mkDiffOptions = function (cursor, readOnly) {
|
||||||
setEditable(false);
|
return {
|
||||||
|
|
||||||
var forbiddenTags = [
|
|
||||||
'SCRIPT',
|
|
||||||
'IFRAME',
|
|
||||||
'OBJECT',
|
|
||||||
'APPLET',
|
|
||||||
'VIDEO',
|
|
||||||
'AUDIO'
|
|
||||||
];
|
|
||||||
|
|
||||||
var diffOptions = {
|
|
||||||
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…
x
Reference in New Issue
Block a user