Debugging concurrent typing:

track whether there are local operations in progress, such that we can tell
whether a remote change is interrupting the DOM's conversion to hjson.
This commit is contained in:
ansuz 2016-03-30 14:36:11 +02:00
parent e446a3645c
commit 523df40d09
1 changed files with 42 additions and 7 deletions

View File

@ -18,6 +18,8 @@ define([
var Ckeditor; // to be initialized later... var Ckeditor; // to be initialized later...
var DiffDom = window.diffDOM; var DiffDom = window.diffDOM;
window.Hyperjson = Hyperjson;
var hjsonToDom = function (H) { var hjsonToDom = function (H) {
return Hyperjson.callOn(H, Hyperscript); return Hyperjson.callOn(H, Hyperscript);
}; };
@ -25,7 +27,9 @@ define([
var userName = Crypto.rand64(8), var userName = Crypto.rand64(8),
toolbar; toolbar;
var module = {}; var module = window.REALTIME_MODULE = {
localChangeInProgress: 0
};
var isNotMagicLine = function (el) { var isNotMagicLine = function (el) {
// factor as: // factor as:
@ -179,12 +183,29 @@ define([
var DD = new DiffDom(diffOptions); var DD = new DiffDom(diffOptions);
var localWorkInProgress = function (stage) {
if (module.localChangeInProgress) {
console.error("Applied a change while a local patch was in progress");
alert("local work was interrupted at stage: " + stage);
//module.realtimeInput.onLocal();
return true;
}
return false;
};
// 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) {
localWorkInProgress(1); // check if this would interrupt local work
var userDocStateDom = hjsonToDom(JSON.parse(shjson)); var userDocStateDom = hjsonToDom(JSON.parse(shjson));
localWorkInProgress(2); // check again
userDocStateDom.setAttribute("contenteditable", "true"); // lol wtf userDocStateDom.setAttribute("contenteditable", "true"); // lol wtf
localWorkInProgress(3); // check again
var patch = (DD).diff(inner, userDocStateDom); var patch = (DD).diff(inner, userDocStateDom);
localWorkInProgress(4); // check again
(DD).apply(inner, patch); (DD).apply(inner, patch);
localWorkInProgress(5); // check again
}; };
var initializing = true; var initializing = true;
@ -192,6 +213,8 @@ define([
var onRemote = realtimeOptions.onRemote = function (info) { var onRemote = realtimeOptions.onRemote = function (info) {
if (initializing) { return; } if (initializing) { return; }
localWorkInProgress(0);
var shjson = info.realtime.getUserDoc(); var shjson = info.realtime.getUserDoc();
// remember where the cursor is // remember where the cursor is
@ -202,6 +225,7 @@ define([
var shjson2 = JSON.stringify(Hyperjson.fromDOM(inner)); var shjson2 = JSON.stringify(Hyperjson.fromDOM(inner));
if (shjson2 !== shjson) { if (shjson2 !== shjson) {
console.error("shjson2 !== shjson");
module.realtimeInput.patchText(shjson2); module.realtimeInput.patchText(shjson2);
} }
}; };
@ -209,6 +233,7 @@ define([
var onInit = realtimeOptions.onInit = function (info) { var onInit = realtimeOptions.onInit = function (info) {
var $bar = $('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox'); var $bar = $('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox');
toolbar = info.realtime.toolbar = Toolbar.create($bar, userName, info.realtime); toolbar = info.realtime.toolbar = Toolbar.create($bar, userName, info.realtime);
/* TODO handle disconnects and such*/ /* TODO handle disconnects and such*/
}; };
@ -230,16 +255,15 @@ define([
toolbar.failed(); toolbar.failed();
}; };
var rti = window.CRYPTPAD_REALTIME = module.realtimeInput = var rti = module.realtimeInput = realtimeInput.start(realtimeOptions);
realtimeInput.start(realtimeOptions);
/* catch `type="_moz"` before it goes over the wire */
var brFilter = function (hj) { var brFilter = function (hj) {
if (hj[1].type === '_moz') { hj[1].type = undefined; } if (hj[1].type === '_moz') { hj[1].type = undefined; }
return hj; return hj;
}; };
/* /* It's incredibly important that you assign 'rti.onLocal'
It's incredibly important that you assign 'rti.onLocal'
It's used inside of realtimeInput to make sure that all changes It's used inside of realtimeInput to make sure that all changes
make it into chainpad. make it into chainpad.
@ -248,9 +272,20 @@ define([
the code less extensible. the code less extensible.
*/ */
var propogate = rti.onLocal = function () { var propogate = rti.onLocal = function () {
/* if the problem were a matter of external patches being
applied while a local patch were in progress, then we would
expect to be able to check and find
'module.localChangeInProgress' with a non-zero value while
we were applying a remote change.
*/
module.localChangeInProgress += 1;
var shjson = JSON.stringify(Hyperjson.fromDOM(inner, isNotMagicLine, brFilter)); var shjson = JSON.stringify(Hyperjson.fromDOM(inner, isNotMagicLine, brFilter));
if (!rti.patchText(shjson)) { return; } if (!rti.patchText(shjson)) {
//rti.onEvent(shjson); module.localChangeInProgress -= 1;
return;
}
rti.onEvent(shjson);
module.localChangeInProgress -= 1;
}; };
/* hitting enter makes a new line, but places the cursor inside /* hitting enter makes a new line, but places the cursor inside