Merge branch 'diffdom' into netflux

pull/1/head
Yann Flory 9 years ago
commit e207d8b579

@ -45,6 +45,16 @@ define([
return true;
};
/* catch `type="_moz"` before it goes over the wire */
var brFilter = function (hj) {
if (hj[1].type === '_moz') { hj[1].type = undefined; }
return hj;
};
var stringifyDOM = function (dom) {
return JSON.stringify(Hyperjson.fromDOM(dom, isNotMagicLine, brFilter));
};
var andThen = function (Ckeditor) {
$(window).on('hashchange', function() {
window.location.reload();
@ -76,6 +86,8 @@ define([
var inner = window.inner = documentBody;
var cursor = window.cursor = Cursor(inner);
var setEditable = function (bool) {
// careful about putting attributes onto the DOM
// they get put into the chain, and you can have trouble
@ -165,8 +177,7 @@ define([
doc: inner,
// provide initialstate...
initialState: JSON.stringify(Hyperjson
.fromDOM(inner, isNotMagicLine)) || '{}',
initialState: stringifyDOM(inner) || '{}',
// really basic operational transform
// reject patch if it results in invalid JSON
@ -221,7 +232,8 @@ define([
// build a dom from HJSON, diff, and patch the editor
applyHjson(shjson);
var shjson2 = JSON.stringify(Hyperjson.fromDOM(inner));
var shjson2 = stringifyDOM(inner);
if (shjson2 !== shjson) {
console.error("shjson2 !== shjson");
module.realtimeInput.patchText(shjson2);
@ -255,11 +267,6 @@ define([
var rti = module.realtimeInput = realtimeInput.start(realtimeOptions);
/* catch `type="_moz"` before it goes over the wire */
var brFilter = function (hj) {
if (hj[1].type === '_moz') { hj[1].type = undefined; }
return hj;
};
/* It's incredibly important that you assign 'rti.onLocal'
It's used inside of realtimeInput to make sure that all changes
@ -270,7 +277,7 @@ define([
the code less extensible.
*/
var propogate = rti.onLocal = function () {
var shjson = JSON.stringify(Hyperjson.fromDOM(inner, isNotMagicLine, brFilter));
var shjson = stringifyDOM(inner);
if (!rti.patchText(shjson)) {
return;
}

@ -264,7 +264,8 @@ define([
}, 200);
toReturn.patchText = TextPatcher.create({
realtime: realtime
realtime: realtime,
logging: true
});
realtime.start();

@ -23,8 +23,8 @@ var diff = function (oldval, newval) {
commonEnd++;
}
var toRemove;
var toInsert;
var toRemove = 0;
var toInsert = '';
/* throw some assertions in here before dropping patches into the realtime */
if (oldval.length !== commonStart + commonEnd) {
@ -79,14 +79,15 @@ var log = function (text, op) {
Due to its reliance on patch, applyChange has side effects on the supplied
realtime facade.
*/
var applyChange = function(ctx, oldval, newval) {
var applyChange = function(ctx, oldval, newval, logging) {
var op = diff(oldval, newval);
// log(oldval, op)
if (logging) { log(oldval, op) }
patch(ctx, op);
};
var create = function(config) {
var ctx = config.realtime;
var logging = config.logging;
// initial state will always fail the !== check in genop.
// because nothing will equal this object
@ -100,7 +101,7 @@ var create = function(config) {
// propogate()
return function (newContent) {
if (newContent !== content) {
applyChange(ctx, ctx.getUserDoc(), newContent);
applyChange(ctx, ctx.getUserDoc(), newContent, logging);
if (ctx.getUserDoc() !== newContent) {
console.log("Expected that: `ctx.getUserDoc() === newContent`!");
}

@ -368,7 +368,7 @@ var random = Patch.random = function (doc, opCount) {
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
var PARANOIA = module.exports.PARANOIA = false;
var PARANOIA = module.exports.PARANOIA = true;
/* throw errors over non-compliant messages which would otherwise be treated as invalid */
var TESTING = module.exports.TESTING = true;
@ -832,7 +832,7 @@ var check = ChainPad.check = function(realtime) {
Common.assert(uiDoc === realtime.userInterfaceContent);
}
var doc = realtime.authDoc;
/*var doc = realtime.authDoc;
var patchMsg = realtime.best;
Common.assert(patchMsg.content.inverseOf.parentHash === realtime.uncommitted.parentHash);
var patches = [];
@ -844,7 +844,7 @@ var check = ChainPad.check = function(realtime) {
while ((patchMsg = patches.pop())) {
doc = Patch.apply(patchMsg.content, doc);
}
Common.assert(doc === realtime.authDoc);
Common.assert(doc === realtime.authDoc);*/
};
var doOperation = ChainPad.doOperation = function (realtime, op) {

@ -12,8 +12,14 @@
box-sizing: border-box;
}
textarea{
position: absolute;
top: 5vh;
left: 0px;
border: 0px;
padding-top: 15px;
width: 100%;
height: 100vh;
height: 95vh;
max-width: 100%;
max-height: 100vh;
@ -32,26 +38,41 @@
color: #637476;
}
#run {
#panel {
position: fixed;
top: 0px;
right: 0px;
z-index: 100;
width: 5vw;
width: 100%;
height: 5vh;
z-index: 95;
background-color: #777;
/* min-height: 75px; */
}
#run {
display: block;
float: right;
height: 100%;
width: 10vw;
z-index: 100;
line-height: 5vw;
font-size: 1.5em;
background-color: #222;
color: #CCC;
display: block;
text-align: center;
border-radius: 5%;
border: 0px;
}
</style>
</head>
<body>
<textarea></textarea>
<div id="panel">
<!-- TODO update this element when new users join -->
<span id="users"></span>
<!-- what else should go in the panel? -->
<a href="#" id="run">RUN</a>
</div>
</body>
</html>

@ -3,9 +3,10 @@ define([
'/common/realtime-input.js',
'/common/messages.js',
'/common/crypto.js',
'/common/cursor.js',
'/bower_components/jquery/dist/jquery.min.js',
'/customize/pad.js'
], function (Config, Realtime, Messages, Crypto) {
], function (Config, Realtime, Messages, Crypto, Cursor) {
var $ = window.jQuery;
$(window).on('hashchange', function() {
window.location.reload();
@ -58,7 +59,75 @@ define([
window.alert("Server Connection Lost");
};
var rt = Realtime.start(config);
var rt = window.rt = Realtime.start(config);
var cursor = Cursor($textarea[0]);
var splice = function (str, index, chars) {
var count = chars.length;
return str.slice(0, index) + chars + str.slice((index -1) + count);
};
var setSelectionRange = function (input, start, end) {
if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(start, end);
} else if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
};
var setCursor = function (el, pos) {
setSelectionRange(el, pos, pos);
};
var state = {};
// TODO
$textarea.on('keydown', function (e) {
// track when control keys are pushed down
//switch (e.key) { }
});
// TODO
$textarea.on('keyup', function (e) {
// track when control keys are released
});
$textarea.on('keypress', function (e) {
switch (e.key) {
case 'Tab':
// insert a tab wherever the cursor is...
var start = $textarea.prop('selectionStart');
var end = $textarea.prop('selectionEnd');
if (typeof start !== 'undefined') {
if (start === end) {
$textarea.val(function (i, val) {
return splice(val, start, "\t");
});
setCursor($textarea[0], start +1);
} else {
// indentation?? this ought to be fun.
}
}
// simulate a keypress so the event goes through..
// prevent default behaviour for tab
e.preventDefault();
rt.bumpSharejs();
break;
default:
break;
}
});
$textarea.on('change', function () {
rt.bumpSharejs();
});
$run.click(function (e) {
e.preventDefault();

Loading…
Cancel
Save