pull cursor correction code out of main.js

put it in cursor.js
This commit is contained in:
ansuz 2016-02-10 11:38:53 +01:00
parent 3b0ac3af4c
commit 9b13fd8f34
1 changed files with 41 additions and 93 deletions

View File

@ -4,12 +4,17 @@ define([
'/common/crypto.js',
'/common/realtime-input.js',
'/common/convert.js',
'/common/toolbar.js',
'/common/cursor.js',
'/bower_components/jquery/dist/jquery.min.js',
'/customize/pad.js'
], function (Config, Messages, Crypto, realtimeInput, Convert) {
], function (Config, Messages, Crypto, realtimeInput, Convert, Toolbar, Cursor) {
var $ = window.jQuery;
var ifrw = $('#pad-iframe')[0].contentWindow;
var Ckeditor = ifrw.CKEDITOR;
window.Ckeditor = ifrw.CKEDITOR;
var userName = Crypto.rand64(8),
toolbar;
var Vdom = Convert.core.vdom,
Hyperjson = Convert.core.hyperjson;
@ -27,7 +32,7 @@ define([
var fixThings = false;
var key = Crypto.parseKey(window.location.hash.substring(1));
var editor = Ckeditor.replace('editor1', {
window.editor = Ckeditor.replace('editor1', {
// https://dev.ckeditor.com/ticket/10907
needsBrFiller: fixThings,
needsNbspFiller: fixThings,
@ -37,106 +42,54 @@ define([
removePlugins: 'magicline,resize'
});
window.editor = editor;
editor.on('instanceReady', function () {
editor.execCommand('maximize');
ifrw.$('iframe')[0].contentDocument.body.innerHTML = Messages.initialState;
var documentBody = ifrw.$('iframe')[0].contentDocument.body;
var inner = ifrw.$('iframe')[0].contentDocument.body;
documentBody.innerHTML = Messages.initialState;
var inner = documentBody;
window.inner = inner;
window.cursor = Cursor(Ckeditor, editor, inner);
var $textarea = $('#feedback'),
$problem = $('#problemo');
var debug = function (info) {
$problem.text(JSON.stringify(info,null,2));
};
var $textarea = $('#feedback');
var vdom1 = Convert.dom.to.vdom(inner);
var cursor = {
startEl: null,
startOffset: 0,
endEl: null,
endOffset: 0
};
var getCursor = function () {
// where is your cursor?
// TODO optimize this if it works
var sel = editor.getSelection(); // { rev, document, root, isLocked, _ }
var element = sel.getStartElement();
var ranges = sel.getRanges();
if (!ranges.length) { return; }
var range = ranges[0]; // {startContainer, startOffset, endContainer, endOffset, collapsed, document, root}
cursor.startEl = range.startContainer;
cursor.startOffset = range.startOffset;
cursor.endEl = range.endContainer;
cursor.endOffset = range.endOffset;
debug(cursor);
};
window.rangeElements = {};
var setCursor = function () {
try {
var sel = editor.getSelection(); // { rev, document, root, isLocked, _ }
// correct the cursor after doing dom stuff
// sel.selectElement(element);
var ranges = sel.getRanges();
if (!ranges.length) { return; }
var range = ranges[0]; // {startContainer, startOffset, endContainer, endOffset, collapsed, document, root}
range.setStart(cursor.startEl, cursor.startOffset);
range.setEnd(cursor.endEl, cursor.endOffset);
sel.selectRanges([range]);
/* FIXME TODO
This fails because the element that we're operating on
can stop existing because vdom determines that we should
get rid of it. if it doesn't exist anymore, we should
walk up the tree or something. Or just not try to
relocate the cursor. Default behaviour might be ok.
DONT FIGHT THE DOM
*/
} catch (err) {
console.log("junk cursor:");
console.log(cursor);
debug(cursor);
console.error(err);
console.error(err.stack);
}
};
var applyHjson = function (shjson) {
console.log("Applying HJSON");
// before integrating external changes, check in your own
vdom1 = Convert.dom.to.vdom(inner);
// remember where the cursor is
getCursor()
// the authoritative document is hyperjson, parse it
var authDoc = JSON.parse(shjson);
// use the authdoc to construct a second vdom
var vdom2 = Convert.hjson.to.vdom(authDoc);
// diff it against your version
var patches = Vdom.diff(vdom1, vdom2);
// apply the resulting patches
Vdom.patch(inner, patches);
};
var onRemote = function (shjson) {
// remember where the cursor is
cursor.update()
applyHjson(shjson);
cursor.find();
// put the cursor back where you left it
setCursor();
cursor.replace();
};
var onInit = function (info) {
// TODO initialize the toolbar
};
window.rti = realtimeInput.start($textarea[0], // synced element
Config.websocketURL, // websocketURL, ofc
Crypto.rand64(8), // userName
userName, // userName
key.channel, // channelName
key.cryptKey, // key
{ // configuration :D
@ -147,7 +100,8 @@ define([
$textarea.trigger('keyup');
},
onRemote: applyHjson,
onRemote: onRemote,
onInit: onInit,
transformFunction : function (text, toTransform, transformBy) {
/* FIXME
@ -175,28 +129,22 @@ define([
*/
});
$(inner).on('keyup', function () {
getCursor();
});
$textarea.val(JSON.stringify(Convert.dom.to.hjson(inner)));
editor.on('change', function () {
var hjson = Hyperjson.fromDOM(inner);
/*
hjson = Hyperjson.callOn(hjson, function (a, b, c) {
Object.keys(b).forEach(function (k) {
if (a === "BR" && b[k] === '_moz') {
delete b[k];
}
});
return [a,b,c];
});*/
$textarea.val(JSON.stringify(hjson));
rti.bumpSharejs();
getCursor()
cursor.update()
});
['mouseup', 'keyup'].forEach(function (type) {
editor.document.on(type, function (e) {
cursor.update();
});
});
});
};