clean up realtime-input.js, break API

use an object for configuration, so as to be more extensible.
modify applications which use the API to match.
pull/1/head
ansuz 9 years ago
parent e43b9715e8
commit d96124229b

@ -64,8 +64,11 @@ define([
var bindAllEvents = function (textarea, docBody, onEvent, unbind) var bindAllEvents = function (textarea, docBody, onEvent, unbind)
{ {
// FIXME why docBody? /*
we use docBody for the purposes of CKEditor.
because otherwise special keybindings like ctrl-b and ctrl-i
would open bookmarks and info instead of applying bold/italic styles
*/
docBody && bindEvents(docBody, docBody && bindEvents(docBody,
['textInput', 'keydown', 'keyup', 'select', 'cut', 'paste'], ['textInput', 'keydown', 'keyup', 'select', 'cut', 'paste'],
onEvent, onEvent,
@ -133,17 +136,20 @@ define([
}; };
var start = module.exports.start = var start = module.exports.start =
function (textarea, websocketUrl, userName, channel, cryptKey, doc, onRemote) function (textarea, websocketUrl, userName, channel, cryptKey, config)
{ {
var passwd = 'y'; var passwd = 'y';
console.log({ // make sure configuration is defined
textarea: textarea, config = config || {};
websocketUrl: websocketUrl,
userName: userName, var doc = config.doc || null;
channel: channel,
cryptKey: cryptKey // trying to deprecate onRemote, prefer loading it via the conf
}); onRemote = config.onRemote || onRemote;
transformFunction = config.transformFunction || null;
var socket = makeWebsocket(websocketUrl); var socket = makeWebsocket(websocketUrl);
// define this in case it gets called before the rest of our stuff is ready. // define this in case it gets called before the rest of our stuff is ready.
@ -156,12 +162,6 @@ define([
var $textarea = $(textarea); var $textarea = $(textarea);
var inputDisabled = function (cond) {
$textarea.attr("disabled", cond||false);
};
inputDisabled(false);
var bump = function () {}; var bump = function () {};
socket.onOpen.push(function (evt) { socket.onOpen.push(function (evt) {
@ -176,24 +176,11 @@ define([
channel, channel,
$(textarea).val(), $(textarea).val(),
{ {
transformFunction: function (text, toTransform, transformBy) { transformFunction: config.transformFunction
console.log({
text: text,
toTransform: toTransform,
transformBy: transformBy
});
// returning **null** breaks out of the loop
// which transforms conflicting operations
// in theory this should prevent us from producing bad JSON
return null;
}
}); });
onEvent = function () { onEvent = function () {
if (isErrorState || initializing) { return; } if (isErrorState || initializing) { return; }
/* var currentDoc = $textarea.val();
if (currentDoc !== realtime.getUserDoc()) { warn("currentDoc !== realtime.getUserDoc()"); } */
}; };
realtime.onUserListChange(function (userList) { realtime.onUserListChange(function (userList) {
@ -202,14 +189,13 @@ define([
} }
// if we spot ourselves being added to the document, we'll switch // if we spot ourselves being added to the document, we'll switch
// 'initializing' off because it means we're fully synced. // 'initializing' off because it means we're fully synced.
// we should only see this happen once
initializing = false; initializing = false;
debug("Done initializing:");
debug("Userlist: ["+userList.join(",")+"]");
/* TODO execute a callback here */
inputDisabled(true); // execute an onReady callback if one was supplied
// pass an object so we can extend this later
config.onReady && config.onReady({
userList: userList
});
}); });
var whoami = new RegExp(userName.replace(/\/\+/g, function (c) { var whoami = new RegExp(userName.replace(/\/\+/g, function (c) {
@ -274,7 +260,6 @@ define([
var socketChecker = setInterval(function () { var socketChecker = setInterval(function () {
if (checkSocket(socket)) { if (checkSocket(socket)) {
warn("Socket disconnected!"); warn("Socket disconnected!");
inputDisabled(true);
recoverableErrorCount += 1; recoverableErrorCount += 1;
@ -284,7 +269,7 @@ define([
socketChecker && clearInterval(socketChecker); socketChecker && clearInterval(socketChecker);
} }
} else { } else {
inputDisabled(false); // TODO
} }
},200); },200);
@ -296,7 +281,6 @@ define([
realtime.start(); realtime.start();
debug('started'); debug('started');
// this has three names :|
bump = realtime.bumpSharejs; bump = realtime.bumpSharejs;
}); });
return { return {

@ -34,9 +34,18 @@
code { code {
font-family: monospace; font-family: monospace;
} }
/* TODO
bump up text size on mobile /* bigger text size for difficult to read elements */
*/ blockquote, p, pre, code, li {
font-size: 20px;
}
/* tables */
table, thead, tbody, th, tr, td{
border: 1pt solid #586e75;
background-color: #002b36;
padding: 15px;
}
</style> </style>
</head> </head>
<body> <body>
@ -46,4 +55,3 @@
<textarea></textarea> <textarea></textarea>
</body> </body>
</html> </html>

@ -28,7 +28,7 @@ define([
var key = Crypto.parseKey(window.location.hash.substring(1)); var key = Crypto.parseKey(window.location.hash.substring(1));
var $textarea = $('textarea'), var $textarea = $('textarea').first(),
$target = $('#target'); $target = $('#target');
window.$textarea = $textarea; window.$textarea = $textarea;
@ -107,18 +107,23 @@ define([
}, 450); }, 450);
}; };
var rts = $textarea.toArray().map(function (e, i) { var rts = Realtime.start($textarea[0], // window
var rt = Realtime.start(e, // window
Config.websocketURL, // websocketUrl Config.websocketURL, // websocketUrl
Crypto.rand64(8), // userName Crypto.rand64(8), // userName
key.channel, // channel key.channel, // channel
key.cryptKey, // cryptkey key.cryptKey, // cryptkey
null, // docBody {
function (){ // onChange received // when remote editors do things...
onRemote: function () {
lazyDraw($textarea.val()); lazyDraw($textarea.val());
},
// when your editor is ready
onReady: function (info) {
info.userList && console.log("Userlist: [%s]", info.userList.join(','));
console.log("Realtime is ready!");
$textarea.trigger('keyup');
}
}); });
return rt;
})[0];
$textarea.on('change keyup keydown', function () { $textarea.on('change keyup keydown', function () {
redrawTimeout && clearTimeout(redrawTimeout); redrawTimeout && clearTimeout(redrawTimeout);

@ -49,7 +49,14 @@ define([
var vdom1 = Convert.dom.to.vdom(inner); var vdom1 = Convert.dom.to.vdom(inner);
var onChange = function (shjson) { var applyHjson = function (shjson) {
// 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(); // [0] // {startContainer, startOffset, endContainer, endOffset, collapsed, document, root}
*/
var authDoc = JSON.parse(shjson); var authDoc = JSON.parse(shjson);
var vdom2 = Convert.hjson.to.vdom(authDoc); var vdom2 = Convert.hjson.to.vdom(authDoc);
var patches = Vdom.diff(vdom1, vdom2); var patches = Vdom.diff(vdom1, vdom2);
@ -57,15 +64,57 @@ define([
// try resyncing the dom? // try resyncing the dom?
vdom1 = Convert.dom.to.vdom(inner); vdom1 = Convert.dom.to.vdom(inner);
// vdom1 = vdom2; // vdom1 = vdom2;
/*
// correct the cursor after doing dom stuff
sel.selectElement(element);
ranges[0].setStart(element.getFirst(), ranges[0].startOffset); //
ranges[0].setEnd(element.getFirst(), ranges[0].endOffset);
sel.selectRanges([ranges[0]]);
*/
}; };
window.rti = realtimeInput.start($textarea[0], window.rti = realtimeInput.start($textarea[0], // synced element
Config.websocketURL, Config.websocketURL, // websocketURL, ofc
Crypto.rand64(8), Crypto.rand64(8), // userName
key.channel, key.channel, // channelName
key.cryptKey, key.cryptKey, // key
inner, { // configuration :D
onChange); doc: inner,
onReady: function (info) {
applyHjson($textarea.val());
$textarea.trigger('keyup');
},
onRemote: applyHjson,
transformFunction : function (text, toTransform, transformBy) {
/* FIXME
operational transform on json shouldn't be in all editors
just those transmitting/expecting JSON
*/
false && console.log({
text: text,
toTransform: toTransform,
transformBy: transformBy
});
// returning **null** breaks out of the loop
// which transforms conflicting operations
// in theory this should prevent us from producing bad JSON
return null;
}
/*
FIXME NOT A REAL FUNCTION WONT WORK
transformFunction: function (state0str, toTransform, transformBy) {
var state1A = JSON.parse(Operation.apply(state0str, transformBy));
var state1B = JSON.parse(Operation.apply(state0str, toTransform));
var state0 = JSON.parse(state0str);
}
*/
});
$textarea.val(JSON.stringify(Convert.dom.to.hjson(inner))); $textarea.val(JSON.stringify(Convert.dom.to.hjson(inner)));

Loading…
Cancel
Save