yay, they talk and they don't fight

This commit is contained in:
Caleb James DeLisle 2017-08-10 18:31:44 +02:00
parent e786a66ff3
commit 1e56fa31c0
7 changed files with 99 additions and 43 deletions

View File

@ -1,24 +1,38 @@
define([], function () { define([], function () {
var UNINIT = 'uninitialized';
var create = function (sframeChan) { var create = function (sframeChan) {
var personalMetadata = 'uninitialized'; var meta = UNINIT;
var myID = 'uninitialized'; var myID = UNINIT;
var members = []; var members = [];
var metadataObj = 'unintialized'; var metadataObj = UNINIT;
var dirty = true; var dirty = true;
var changeHandlers = []; var changeHandlers = [];
var checkUpdate = function () { var checkUpdate = function () {
if (!dirty) { return; } if (!dirty) { return; }
if (metadataObj === 'uninitialized') { throw new Error(); } if (meta === UNINIT) { throw new Error(); }
if (myID === 'uninitialized') { throw new Error(); } if (myID === UNINIT) { myID = meta.myID; }
if (personalMetadata === 'uninitialized') { throw new Error(); } if (metadataObj === UNINIT) {
metadataObj = {
defaultTitle: meta.doc.defaultTitle,
title: meta.doc.defaultTitle,
users: {}
};
}
var mdo = {}; var mdo = {};
Object.keys(metadataObj).forEach(function (x) { // We don't want to add our user data to the object multiple times.
var containsYou = false;
console.log(metadataObj);
Object.keys(metadataObj.users).forEach(function (x) {
if (members.indexOf(x) === -1) { return; } if (members.indexOf(x) === -1) { return; }
mdo[x] = metadataObj[x]; mdo[x] = metadataObj.users[x];
if (metadataObj.users[x].uid === meta.user.uid) {
console.log('document already contains you');
containsYou = true;
}
}); });
mdo[myID] = personalMetadata; if (!containsYou) { mdo[myID] = meta.user; }
metadataObj = mdo; metadataObj.users = mdo;
dirty = false; dirty = false;
changeHandlers.forEach(function (f) { f(); }); changeHandlers.forEach(function (f) { f(); });
}; };
@ -27,8 +41,8 @@ define([], function () {
setTimeout(checkUpdate); setTimeout(checkUpdate);
}; };
sframeChan.on('EV_USERDATA_UPDATE', function (ev) { sframeChan.on('EV_METADATA_UPDATE', function (ev) {
personalMetadata = ev; meta = ev;
change(); change();
}); });
sframeChan.on('EV_RT_CONNECT', function (ev) { sframeChan.on('EV_RT_CONNECT', function (ev) {
@ -52,8 +66,9 @@ define([], function () {
}); });
return Object.freeze({ return Object.freeze({
metadataChange: function (meta) { updateMetadata: function (m) {
metadataObj = meta; if (JSON.stringify(metadataObj) === JSON.stringify(m)) { return; }
metadataObj = m;
change(); change();
}, },
getMetadata: function () { getMetadata: function () {

View File

@ -52,7 +52,7 @@ define([
onConnectionChange({ state: false }); onConnectionChange({ state: false });
}); });
sframeChan.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;
if (chainpad) { if (chainpad) {

View File

@ -228,7 +228,9 @@ define([], function () {
return { return {
start: function (config) { start: function (config) {
config.sframeChan.whenReg('EV_RT_READY', function () { start(config); }); config.sframeChan.whenReg('EV_RT_READY', function () {
start(config);
});
} }
}; };
}); });

View File

@ -18,6 +18,7 @@ define([
var chan = {}; var chan = {};
// Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
chan.query = function (q, content, cb) { chan.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]) {
@ -40,6 +41,7 @@ define([
}), '*'); }), '*');
}; };
// Fire an event. channel.event('EV_SOMETHING', { args: "whatever" });
var event = chan.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]) {
@ -51,13 +53,17 @@ define([
otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*'); otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
}; };
// Be notified on query or event. channel.on('EV_SOMETHING', function (args, reply) { ... });
// If the type is a query, your handler will be invoked with a reply function that takes
// one argument (the content to reply with).
chan.on = function (queryType, handler, quiet) { chan.on = function (queryType, handler, quiet) {
if (!otherWindow) { throw new Error('not yet initialized'); } if (!otherWindow && !quiet) { 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');
} }
(handlers[queryType] = handlers[queryType] || []).push(function (data, msg) { (handlers[queryType] = handlers[queryType] || []).push(function (data, msg) {
handler(data.content, function (replyContent) { handler(data.content, function (replyContent) {
if (queryType.indexOf('Q_') !== 0) { throw new Error("replies to events are invalid"); }
msg.source.postMessage(JSON.stringify({ msg.source.postMessage(JSON.stringify({
txid: data.txid, txid: data.txid,
content: replyContent content: replyContent
@ -69,25 +75,35 @@ define([
} }
}; };
chan.whenReg = function (queryType, handler) { // If a particular handler is registered, call the callback immediately, otherwise it will be called
// when that handler is first registered.
// channel.whenReg('Q_SOMETHING', function () { ...query Q_SOMETHING?... });
chan.whenReg = function (queryType, cb, always) {
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');
} }
var reg = always;
if (insideHandlers.indexOf(queryType) > -1) { if (insideHandlers.indexOf(queryType) > -1) {
handler(); cb();
} else { } else {
(callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(handler); reg = true;
}
if (reg) {
(callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(cb);
} }
}; };
(handlers['EV_REGISTER_HANDLER'] = handlers['EV_REGISTER_HANDLER'] || []).push(function (data) { // Same as whenReg except it will invoke every time there is another registration, not just once.
if (callWhenRegistered[data.content]) { chan.onReg = function (queryType, cb) { chan.whenReg(queryType, cb, true); };
callWhenRegistered[data.content].forEach(function (f) { f(); });
delete callWhenRegistered[data.content]; chan.on('EV_REGISTER_HANDLER', function (content) {
if (callWhenRegistered[content]) {
callWhenRegistered[content].forEach(function (f) { f(); });
delete callWhenRegistered[content];
} }
insideHandlers.push(data.content); insideHandlers.push(content);
}); }, true);
var intr; var intr;
var txid; var txid;

View File

@ -34,5 +34,5 @@ define({
// Called from the outside, this informs the inside whenever the user's data has been changed. // Called from the outside, this informs the inside whenever the user's data has been changed.
// The argument is the object representing the content of the user profile minus the netfluxID // The argument is the object representing the content of the user profile minus the netfluxID
// which changes per-reconnect. // which changes per-reconnect.
'EV_USERDATA_UPDATE': true 'EV_METADATA_UPDATE': true
}); });

View File

@ -260,6 +260,7 @@ define([
// secret.keys = secret.key; // secret.keys = secret.key;
//} //}
var readOnly = false; // TODO var readOnly = false; // TODO
var cpNfInner;
var $bar = $('#cke_1_toolbox'); var $bar = $('#cke_1_toolbox');
@ -339,7 +340,9 @@ define([
var stringifyDOM = module.stringifyDOM = function (dom) { var stringifyDOM = module.stringifyDOM = function (dom) {
var hjson = Hyperjson.fromDOM(dom, isNotMagicLine, brFilter); var hjson = Hyperjson.fromDOM(dom, isNotMagicLine, brFilter);
hjson[3] = {
metadata: cpNfInner.metadataMgr.getMetadata()
};
/*hjson[3] = { TODO /*hjson[3] = { TODO
users: UserList.userData, users: UserList.userData,
defaultTitle: Title.defaultTitle, defaultTitle: Title.defaultTitle,
@ -380,9 +383,6 @@ define([
} }
}; };
var meta;
var metaStr;
realtimeOptions.onRemote = function () { realtimeOptions.onRemote = function () {
if (initializing) { return; } if (initializing) { return; }
if (isHistoryMode) { return; } if (isHistoryMode) { return; }
@ -403,6 +403,10 @@ define([
newSInner = stringify(newInner[2]); newSInner = stringify(newInner[2]);
} }
if (newInner[3]) {
cpNfInner.metadataMgr.updateMetadata(newInner[3].metadata);
}
// build a dom from HJSON, diff, and patch the editor // build a dom from HJSON, diff, and patch the editor
applyHjson(shjson); applyHjson(shjson);
@ -446,14 +450,6 @@ define([
if (newSInner && newSInner !== oldSInner) { if (newSInner && newSInner !== oldSInner) {
Cryptpad.notify(); Cryptpad.notify();
} }
var newMeta = newInner[3];
var newMetaStr = JSON.stringify(newMeta);
if (newMetaStr !== metaStr) {
metaStr = newMetaStr;
meta = newMeta;
//meta[] HERE
}
}; };
var exportFile = function () { var exportFile = function () {
@ -473,7 +469,7 @@ define([
}; };
realtimeOptions.onInit = function (info) { realtimeOptions.onInit = function (info) {
console.log('onInit');
// TODO // TODO
return; return;
@ -599,6 +595,7 @@ define([
// this should only ever get called once, when the chain syncs // this should only ever get called once, when the chain syncs
realtimeOptions.onReady = function (info) { realtimeOptions.onReady = function (info) {
console.log('onReady');
if (!module.isMaximized) { if (!module.isMaximized) {
module.isMaximized = true; module.isMaximized = true;
$('iframe.cke_wysiwyg_frame').css('width', ''); $('iframe.cke_wysiwyg_frame').css('width', '');
@ -686,9 +683,7 @@ define([
} }
}; };
var cpNfInner = CpNfInner.start(realtimeOptions); cpNfInner = CpNfInner.start(realtimeOptions);
Cryptpad.onLogout(function () { setEditable(false); }); Cryptpad.onLogout(function () { setEditable(false); });

View File

@ -18,6 +18,34 @@ define([
})); }));
Cryptpad.ready(waitFor()); Cryptpad.ready(waitFor());
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
var parsed = Cryptpad.parsePadUrl(window.location.href);
if (!parsed.type) { throw new Error(); }
var defaultTitle = Cryptpad.getDefaultName(parsed);
var updateMeta = function () {
console.log('EV_METADATA_UPDATE');
var name;
nThen(function (waitFor) {
Cryptpad.getLastName(waitFor(function (n) { name = n }));
}).nThen(function (waitFor) {
sframeChan.event('EV_METADATA_UPDATE', {
doc: {
defaultTitle: defaultTitle,
type: parsed.type
},
myID: Cryptpad.getNetwork().webChannels[0].myID,
user: {
name: name,
uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl(),
curvePublic: Cryptpad.getProxy().curvePublic
}
});
});
};
Cryptpad.onDisplayNameChanged(updateMeta);
sframeChan.onReg('EV_METADATA_UPDATE', updateMeta);
Cryptpad.onError(function (info) { Cryptpad.onError(function (info) {
console.log('error'); console.log('error');
console.log(info); console.log(info);