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 () {
var UNINIT = 'uninitialized';
var create = function (sframeChan) {
var personalMetadata = 'uninitialized';
var myID = 'uninitialized';
var meta = UNINIT;
var myID = UNINIT;
var members = [];
var metadataObj = 'unintialized';
var metadataObj = UNINIT;
var dirty = true;
var changeHandlers = [];
var checkUpdate = function () {
if (!dirty) { return; }
if (metadataObj === 'uninitialized') { throw new Error(); }
if (myID === 'uninitialized') { throw new Error(); }
if (personalMetadata === 'uninitialized') { throw new Error(); }
if (meta === UNINIT) { throw new Error(); }
if (myID === UNINIT) { myID = meta.myID; }
if (metadataObj === UNINIT) {
metadataObj = {
defaultTitle: meta.doc.defaultTitle,
title: meta.doc.defaultTitle,
users: {}
};
}
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; }
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;
metadataObj = mdo;
if (!containsYou) { mdo[myID] = meta.user; }
metadataObj.users = mdo;
dirty = false;
changeHandlers.forEach(function (f) { f(); });
};
@ -27,8 +41,8 @@ define([], function () {
setTimeout(checkUpdate);
};
sframeChan.on('EV_USERDATA_UPDATE', function (ev) {
personalMetadata = ev;
sframeChan.on('EV_METADATA_UPDATE', function (ev) {
meta = ev;
change();
});
sframeChan.on('EV_RT_CONNECT', function (ev) {
@ -52,8 +66,9 @@ define([], function () {
});
return Object.freeze({
metadataChange: function (meta) {
metadataObj = meta;
updateMetadata: function (m) {
if (JSON.stringify(metadataObj) === JSON.stringify(m)) { return; }
metadataObj = m;
change();
},
getMetadata: function () {

View File

@ -52,7 +52,7 @@ define([
onConnectionChange({ state: false });
});
sframeChan.on('EV_RT_CONNECT', function (content) {
content.members.forEach(userList.onJoin);
//content.members.forEach(userList.onJoin);
myID = content.myID;
isReady = false;
if (chainpad) {

View File

@ -228,7 +228,9 @@ define([], function () {
return {
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 = {};
// Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
chan.query = function (q, content, cb) {
if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[q]) {
@ -40,6 +41,7 @@ define([
}), '*');
};
// Fire an event. channel.event('EV_SOMETHING', { args: "whatever" });
var event = chan.event = function (e, content) {
if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[e]) {
@ -51,13 +53,17 @@ define([
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) {
if (!otherWindow) { throw new Error('not yet initialized'); }
if (!otherWindow && !quiet) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[queryType]) {
throw new Error('please only register handlers which are defined in sframe-protocol.js');
}
(handlers[queryType] = handlers[queryType] || []).push(function (data, msg) {
handler(data.content, function (replyContent) {
if (queryType.indexOf('Q_') !== 0) { throw new Error("replies to events are invalid"); }
msg.source.postMessage(JSON.stringify({
txid: data.txid,
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 (!SFrameProtocol[queryType]) {
throw new Error('please only register handlers which are defined in sframe-protocol.js');
}
var reg = always;
if (insideHandlers.indexOf(queryType) > -1) {
handler();
cb();
} 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) {
if (callWhenRegistered[data.content]) {
callWhenRegistered[data.content].forEach(function (f) { f(); });
delete callWhenRegistered[data.content];
// Same as whenReg except it will invoke every time there is another registration, not just once.
chan.onReg = function (queryType, cb) { chan.whenReg(queryType, cb, true); };
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 txid;

View File

@ -34,5 +34,5 @@ define({
// 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
// which changes per-reconnect.
'EV_USERDATA_UPDATE': true
'EV_METADATA_UPDATE': true
});

View File

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

View File

@ -18,6 +18,34 @@ define([
}));
Cryptpad.ready(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) {
console.log('error');
console.log(info);