More or less working goToRevision

There are still some bugs in the traversal algorithm, as well
as bugs being triggered in the server. Also, for some reason it looks
like there is a problem with the attribute pool not containing certain
elements.
This commit is contained in:
s1341 2013-12-14 19:31:24 +02:00
parent f49abe61b7
commit 3013bab251
4 changed files with 51 additions and 25 deletions

View file

@ -112,8 +112,6 @@ function init(tsclient, fireWhenAllScriptsAreLoaded)
var rev = Number(window.location.hash.substr(1)); var rev = Number(window.location.hash.substr(1));
if(!isNaN(rev)) if(!isNaN(rev))
tsui.goToRevision(rev); tsui.goToRevision(rev);
} else {
//tsui.goToRevision()
} }

View file

@ -523,14 +523,16 @@ $.Class("PadClient",
/** /**
* Create a PadClient. * Create a PadClient.
* @constructor * @constructor
* @param {RevisionCache} revisionCache - A RevisionCache object to use.
* @param {number} revision - The current revision of the pad. * @param {number} revision - The current revision of the pad.
* @param {datetime} timestamp - The timestamp of the current revision. * @param {datetime} timestamp - The timestamp of the current revision.
* @param {string} atext - The attributed text. * @param {string} atext - The attributed text.
* @param {string} attribs - The attributes string. * @param {string} attribs - The attributes string.
* @param {object} apool - The attribute pool. * @param {object} apool - The attribute pool.
*/ */
init: function (revision, timestamp, atext, attribs, apool) { init: function (revisionCache, revision, timestamp, atext, attribs, apool) {
this.revision = revision; this.revisionCache = revisionCache;
this.revision = this.revisionCache.getRevision(revision);
this.timestamp = timestamp; this.timestamp = timestamp;
this.alines = libchangeset.splitAttributionLines(attribs, atext); this.alines = libchangeset.splitAttributionLines(attribs, atext);
this.apool = (new AttribPool()).fromJsonable(apool); this.apool = (new AttribPool()).fromJsonable(apool);
@ -548,19 +550,37 @@ $.Class("PadClient",
//TODO: monkey patch divs.splice to use our custom splice function //TODO: monkey patch divs.splice to use our custom splice function
this.divs.original_splice = this.divs.splice; this.divs.original_splice = this.divs.splice;
this.divs.splice = this._spliceDivs; var _this = this;
this.divs.splice = function () {
return _this._spliceDivs.apply(_this, arguments);
}
// we need to provide a get, as we want to give
// libchangeset the text of a div, not the div itself
this.divs.get = function (index) {
return this[index].data('text');
};
}, },
applyChangeset: function (changeset) { goToRevision: function (revnum, atRevision_callback) {
//TODO: changeset should be a Changeset object console.log("[padclient > goToRevision] revnum: %d", revnum);
// var _this = this;
// must mutate attribution lines before text lines this.revisionCache.transition(this.revision.revnum, revnum, function (path) {
libchangeset.mutateAttributionLines(changeset, this.alines, this.apool); console.log("[padclient > applyChangeset_callback] path:", path);
var time = _this.timestamp;
for (var p in path) {
console.log(p, path[p].deltatime, path[p].value);
var changeset = path[p];
time += changeset.deltatime * 1000;
changeset.apply(_this);
}
// Looks like this function can take a regular array of strings // set revision and timestamp
libchangeset.mutateTextLines(changeset, /* padcontents */ /*this.lines */ this.divs); _this.revision = path.slice(-1)[0].to_revision;
_this.timestamp = time;
//TODO: get authors (and set in UI) console.log(_this.revision, _this.timestamp)
// fire the callback
if (atRevision_callback)
atRevision_callback.call(_this,_this.revision, _this.timestamp);
});
}, },
_getDivForLine: function (text, atext) { _getDivForLine: function (text, atext) {
@ -570,8 +590,9 @@ $.Class("PadClient",
linestylefilter.populateDomLine(text, atext, this.apool, dominfo); linestylefilter.populateDomLine(text, atext, this.apool, dominfo);
dominfo.prepareForAdd(); dominfo.prepareForAdd();
var div = $("<div class='" + dominfo.node.className + var div = $("<div class='" + dominfo.node.className + "' " +
"' id='" + Math.random() + "'>" + "id='" + Math.random() + "' " +
"data-text='" + text + "'>" +
dominfo.node.innerHTML + "</div>"); dominfo.node.innerHTML + "</div>");
return div; return div;
}, },
@ -589,9 +610,10 @@ $.Class("PadClient",
* @param {array} elements - The elements to add to the array. In our case, these are lines. * @param {array} elements - The elements to add to the array. In our case, these are lines.
*/ */
_spliceDivs: function (index, howMany, elements) { _spliceDivs: function (index, howMany, elements) {
elements = Array.prototype.slice.call(arguments, 2);
// remove howMany divs starting from index. We need to remove them from // remove howMany divs starting from index. We need to remove them from
// the DOM. // the DOM.
for (var i = index; i < howMany && i < this.divs.length; i++) for (var i = index; i < index + howMany && i < this.divs.length; i++)
this.divs[i].remove(); this.divs[i].remove();
// generate divs for the new elements: // generate divs for the new elements:
@ -609,7 +631,8 @@ $.Class("PadClient",
// perform the splice on our array itself // perform the splice on our array itself
// TODO: monkey patching divs.splice, so use divs.original_splice or something // TODO: monkey patching divs.splice, so use divs.original_splice or something
return this.divs.splice(index, howMany, newdivs); args = [index, howMany].concat(newdivs);
return this.divs.original_splice.apply(this.divs, args);
}, },
} }
); );

View file

@ -196,7 +196,8 @@ AuthenticatedSocketClient("TimesliderClient",
this.revisionCache = new RevisionCache(this, collabClientVars.rev || 0); this.revisionCache = new RevisionCache(this, collabClientVars.rev || 0);
this.padClient = new PadClient(collabClientVars.rev, this.padClient = new PadClient(this.revisionCache,
collabClientVars.rev,
collabClientVars.time, collabClientVars.time,
collabClientVars.initialAttributedText.text, collabClientVars.initialAttributedText.text,
collabClientVars.initialAttributedText.attribs, collabClientVars.initialAttributedText.attribs,
@ -206,10 +207,12 @@ AuthenticatedSocketClient("TimesliderClient",
handle_COLLABROOM: function(data) { handle_COLLABROOM: function(data) {
console.log("[timeslider_client] handle_COLLABROOM: ", data); console.log("[timeslider_client] handle_COLLABROOM: ", data);
}, },
} }
); );
function init(baseURL) { function init(baseURL) {
var timesliderclient;
$(document).ready(function () $(document).ready(function ()
{ {
// start the custom js // start the custom js
@ -240,7 +243,7 @@ function init(baseURL) {
var cl; var cl;
console.log(url, baseURL, resource, padId); console.log(url, baseURL, resource, padId);
var timesliderclient = new TimesliderClient(url, padId) timesliderclient = new TimesliderClient(url, padId)
.on("CLIENT_VARS", function(data, context, callback) { .on("CLIENT_VARS", function(data, context, callback) {
//load all script that doesn't work without the clientVars //load all script that doesn't work without the clientVars
BroadcastSlider = require('./broadcast_slider').init(this,fireWhenAllScriptsAreLoaded); BroadcastSlider = require('./broadcast_slider').init(this,fireWhenAllScriptsAreLoaded);
@ -287,6 +290,7 @@ function init(baseURL) {
hooks.aCallAll("postTimesliderInit"); hooks.aCallAll("postTimesliderInit");
}); });
return timesliderclient;
} }
var fireWhenAllScriptsAreLoaded = []; var fireWhenAllScriptsAreLoaded = [];

View file

@ -206,6 +206,7 @@
<script type="text/javascript" > <script type="text/javascript" >
var clientVars = {}; var clientVars = {};
var BroadcastSlider; var BroadcastSlider;
var timeslider;
(function () { (function () {
var pathComponents = location.pathname.split('/'); var pathComponents = location.pathname.split('/');
@ -222,16 +223,16 @@
document.domain = document.domain; // for comet document.domain = document.domain; // for comet
} }
var plugins = require('ep_etherpad-lite/static/js/pluginfw/client_plugins'); var plugins = require('ep_etherpad-lite/static/js/pluginfw/client_plugins');
var timeslider = require('ep_etherpad-lite/static/js/timeslider') var _timeslider = require('ep_etherpad-lite/static/js/timeslider')
var socket = timeslider.socket; var socket = _timeslider.socket;
BroadcastSlider = timeslider.BroadcastSlider; BroadcastSlider = _timeslider.BroadcastSlider;
plugins.baseURL = baseURL; plugins.baseURL = baseURL;
plugins.update(function () { plugins.update(function () {
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
hooks.plugins = plugins; hooks.plugins = plugins;
timeslider.init(baseURL); timeslider = _timeslider.init(baseURL);
/* TODO: These globals shouldn't exist. */ /* TODO: These globals shouldn't exist. */
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar; padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;