Introduce timeslider object

This commit introduces a new TimesliderClient object which will
eventually handle all communication with the server in a sane fashion.

At the moment, minimal work has been done to wire the existing code into
this object. The current 'on("MESSAGE_TYPE")' model will change so that
the timeslider object is actually the one managing all the information,
instead of delegating it all out to callbacks.

This current version still works just as the stock version did.
This commit is contained in:
s1341 2013-11-23 19:39:52 +02:00
parent d1cad04647
commit e55ef0fe95
5 changed files with 284 additions and 140 deletions

View file

@ -1,5 +1,5 @@
/**
* This code is mostly from the old Etherpad. Please help us to comment this code.
* This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/
@ -27,13 +27,12 @@ var Changeset = require('./Changeset');
var linestylefilter = require('./linestylefilter').linestylefilter;
var colorutils = require('./colorutils').colorutils;
var _ = require('./underscore');
require("./jquery.class");
// These parameters were global, now they are injected. A reference to the
// Timeslider controller would probably be more appropriate.
function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider)
function loadBroadcastJS(tsclient, fireWhenAllScriptsAreLoaded, BroadcastSlider)
{
var changesetLoader = undefined;
var changesetLoader;
// Below Array#indexOf code was direct pasted by AppJet/Etherpad, licence unknown. Possible source: http://www.tutorialspoint.com/javascript/array_indexof.htm
if (!Array.prototype.indexOf)
{
@ -83,14 +82,14 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
var appLevelDisconnectReason = null;
var padContents = {
currentRevision: clientVars.collab_client_vars.rev,
currentTime: clientVars.collab_client_vars.time,
currentLines: Changeset.splitTextLines(clientVars.collab_client_vars.initialAttributedText.text),
currentRevision: tsclient.clientVars.collab_client_vars.rev,
currentTime: tsclient.clientVars.collab_client_vars.time,
currentLines: Changeset.splitTextLines(tsclient.clientVars.collab_client_vars.initialAttributedText.text),
currentDivs: null,
// to be filled in once the dom loads
apool: (new AttribPool()).fromJsonable(clientVars.collab_client_vars.apool),
apool: (new AttribPool()).fromJsonable(tsclient.clientVars.collab_client_vars.apool),
alines: Changeset.splitAttributionLines(
clientVars.collab_client_vars.initialAttributedText.attribs, clientVars.collab_client_vars.initialAttributedText.text),
tsclient.clientVars.collab_client_vars.initialAttributedText.attribs, tsclient.clientVars.collab_client_vars.initialAttributedText.text),
// generates a jquery element containing HTML for a line
lineToElement: function(line, aline)
@ -250,7 +249,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
*/
function applyChangeset(changeset, revision, preventSliderMovement, timeDelta)
{
{
// disable the next 'gotorevision' call handled by a timeslider update
if (!preventSliderMovement)
{
@ -274,12 +273,12 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
debugLog('Time Delta: ', timeDelta)
updateTimer();
var authors = _.map(padContents.getActiveAuthors(), function(name)
{
return authorData[name];
});
BroadcastSlider.setAuthors(authors);
}
@ -292,7 +291,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
str = '0' + str;
return str;
}
var date = new Date(padContents.currentTime);
var dateFormat = function()
{
@ -307,15 +306,15 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
"month": month,
"year": year,
"hours": hours,
"minutes": minutes,
"minutes": minutes,
"seconds": seconds
}));
}
$('#timer').html(dateFormat());
var revisionDate = html10n.get("timeslider.saved", {
"day": date.getDate(),
@ -338,7 +337,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
$('#revision_date').html(revisionDate)
}
updateTimer();
function goToRevision(newRevision)
@ -401,7 +400,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
changesetLoader.queueUp(start, 1, update);
}
var authors = _.map(padContents.getActiveAuthors(), function(name){
return authorData[name];
});
@ -453,7 +452,8 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
var start = request.rev;
var requestID = Math.floor(Math.random() * 100000);
sendSocketMsg("CHANGESET_REQ", {
//sendSocketMsg("CHANGESET_REQ", {
tsclient.sendMessage("CHANGESET_REQ", {
"start": start,
"granularity": granularity,
"requestID": requestID
@ -461,21 +461,21 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
self.reqCallbacks[requestID] = callback;
},
handleSocketResponse: function(message)
handle_CHANGESET_REQ: function(data)
{
var self = changesetLoader;
var start = message.data.start;
var granularity = message.data.granularity;
var callback = self.reqCallbacks[message.data.requestID];
delete self.reqCallbacks[message.data.requestID];
var start = data.start;
var granularity = data.granularity;
var callback = self.reqCallbacks[data.requestID];
delete self.reqCallbacks[data.requestID];
self.handleResponse(message.data, start, granularity, callback);
self.handleResponse(data, start, granularity, callback);
setTimeout(self.loadFromQueue, 10);
},
handleResponse: function(data, start, granularity, callback)
{
debugLog("response: ", data);
debugLog("handleResponse: ", data);
var pool = (new AttribPool()).fromJsonable(data.apool);
for (var i = 0; i < data.forwardsChangesets.length; i++)
{
@ -489,56 +489,44 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
if (callback) callback(start - 1, start + data.forwardsChangesets.length * granularity - 1);
},
handleMessageFromServer: function (obj)
handle_COLLABROOM: function (obj)
{
debugLog("handleMessage:", arguments);
if (obj.type == "COLLABROOM")
debugLog("handle_COLLABROOM:", arguments);
if (obj.type == "NEW_CHANGES")
{
obj = obj.data;
debugLog(obj);
var changeset = Changeset.moveOpsToNewPool(
obj.changeset, (new AttribPool()).fromJsonable(obj.apool), padContents.apool);
if (obj.type == "NEW_CHANGES")
{
debugLog(obj);
var changeset = Changeset.moveOpsToNewPool(
obj.changeset, (new AttribPool()).fromJsonable(obj.apool), padContents.apool);
var changesetBack = Changeset.inverse(
obj.changeset, padContents.currentLines, padContents.alines, padContents.apool);
var changesetBack = Changeset.inverse(
obj.changeset, padContents.currentLines, padContents.alines, padContents.apool);
changesetBack = Changeset.moveOpsToNewPool(
changesetBack, (new AttribPool()).fromJsonable(obj.apool), padContents.apool);
var changesetBack = Changeset.moveOpsToNewPool(
changesetBack, (new AttribPool()).fromJsonable(obj.apool), padContents.apool);
loadedNewChangeset(changeset, changesetBack, obj.newRev - 1, obj.timeDelta);
}
else if (obj.type == "NEW_AUTHORDATA")
{
var authorMap = {};
authorMap[obj.author] = obj.data;
receiveAuthorData(authorMap);
var authors = _.map(padContents.getActiveAuthors(), function(name) {
return authorData[name];
});
BroadcastSlider.setAuthors(authors);
}
else if (obj.type == "NEW_SAVEDREV")
{
var savedRev = obj.savedRev;
BroadcastSlider.addSavedRevision(savedRev.revNum, savedRev);
}
loadedNewChangeset(changeset, changesetBack, obj.newRev - 1, obj.timeDelta);
}
else if(obj.type == "CHANGESET_REQ")
else if (obj.type == "NEW_AUTHORDATA")
{
changesetLoader.handleSocketResponse(obj);
var authorMap = {};
authorMap[obj.author] = obj.data;
receiveAuthorData(authorMap);
var authors = _.map(padContents.getActiveAuthors(), function(name) {
return authorData[name];
});
BroadcastSlider.setAuthors(authors);
}
else
else if (obj.type == "NEW_SAVEDREV")
{
debugLog("Unknown message type: " + obj.type);
var savedRev = obj.savedRev;
BroadcastSlider.addSavedRevision(savedRev.revNum, savedRev);
}
}
};
tsclient.on("CHANGESET_REQ", changesetLoader.handle_CHANGESET_REQ);
tsclient.on("COLLABROOM", changesetLoader.handle_COLLABROOM);
// to start upon window load, just push a function onto this array
//window['onloadFuncts'].push(setUpSocket);
@ -570,7 +558,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
goToRevision.apply(goToRevision, arguments);
}
}
BroadcastSlider.onSlider(goToRevisionIfEnabled);
var dynamicCSS = makeCSSManager('dynamicsyntax');
@ -581,7 +569,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
for (var author in newAuthorData)
{
var data = newAuthorData[author];
var bgcolor = typeof data.colorId == "number" ? clientVars.colorPalette[data.colorId] : data.colorId;
var bgcolor = typeof data.colorId == "number" ? tsclient.clientVars.colorPalette[data.colorId] : data.colorId;
if (bgcolor && dynamicCSS)
{
var selector = dynamicCSS.selectorStyle('.' + linestylefilter.getAuthorClassName(author));
@ -592,7 +580,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
}
receiveAuthorData(clientVars.collab_client_vars.historicalAuthorData);
receiveAuthorData(tsclient.clientVars.collab_client_vars.historicalAuthorData);
return changesetLoader;
}

View file

@ -1,5 +1,5 @@
/**
* This code is mostly from the old Etherpad. Please help us to comment this code.
* This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/
@ -23,7 +23,7 @@
// of the document. These revisions are connected together by various
// changesets, or deltas, between any two revisions.
function loadBroadcastRevisionsJS()
function loadBroadcastRevisionsJS(clientVars)
{
function Revision(revNum)
{
@ -44,9 +44,9 @@ function loadBroadcastRevisionsJS()
this.changesets.push(changesetWrapper);
this.changesets.sort(function(a, b)
{
return (b.deltaRev - a.deltaRev)
return (b.deltaRev - a.deltaRev);
});
}
};
revisionInfo = {};
revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta)

View file

@ -1,5 +1,5 @@
/**
* This code is mostly from the old Etherpad. Please help us to comment this code.
* This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/
@ -24,8 +24,9 @@
// Timeslider controller would probably be more appropriate.
var _ = require('./underscore');
var padmodals = require('./pad_modals').padmodals;
require("./jquery.class");
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
function loadBroadcastSliderJS(_clientVars, fireWhenAllScriptsAreLoaded)
{
var BroadcastSlider;
@ -37,6 +38,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
var slidercallbacks = [];
var savedRevisions = [];
var sliderPlaying = false;
clientVars = _clientVars;
function disableSelection(element)
{
@ -56,7 +58,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
slidercallbacks[i](newval);
}
}
var updateSliderElements = function()
{
for (var i = 0; i < savedRevisions.length; i++)
@ -65,7 +67,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
savedRevisions[i].css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
}
$("#ui-slider-handle").css('left', sliderPos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
}
}
var addSavedRevision = function(position, info)
{
@ -167,7 +169,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
var height = $('#timeslider-top').height();
$('#editorcontainerbox').css({marginTop: height});
}, 600);
function setAuthors(authors)
{
var authorsList = $("#authorsList");
@ -181,7 +183,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
if (author.name)
{
if (numNamed !== 0) authorsList.append(', ');
$('<span />')
.text(author.name || "unnamed")
.css('background-color', authorColor)
@ -199,17 +201,17 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
if (numAnonymous > 0)
{
var anonymousAuthorString = html10n.get("timeslider.unnamedauthors", { num: numAnonymous });
if (numNamed !== 0){
authorsList.append(' + ' + anonymousAuthorString);
} else {
authorsList.append(anonymousAuthorString);
}
if(colorsAnonymous.length > 0){
authorsList.append(' (');
_.each(colorsAnonymous, function(color, i){
if( i > 0 ) authorsList.append(' ');
if( i > 0 ) authorsList.append(' ');
$('<span>&nbsp;</span>')
.css('background-color', color)
.addClass('author author-anonymous')
@ -217,13 +219,13 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
});
authorsList.append(')');
}
}
if (authors.length == 0)
{
authorsList.append(html10n.get("timeslider.toolbar.authorsList"));
}
fixPadHeight();
}
@ -281,7 +283,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
disableSelection($("#playpause_button")[0]);
disableSelection($("#timeslider")[0]);
$(document).keyup(function(e)
{
var code = -1;
@ -326,7 +328,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
else if (code == 32) playpause();
});
$(window).resize(function()
{
updateSliderElements();
@ -457,7 +459,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
if (clientVars)
{
$("#timeslider").show();
var startPos = clientVars.collab_client_vars.rev;
if(window.location.hash.length > 1)
{
@ -468,15 +470,15 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
setTimeout(function() { setSliderPosition(hashRev); }, 1);
}
}
setSliderLength(clientVars.collab_client_vars.rev);
setSliderPosition(clientVars.collab_client_vars.rev);
_.each(clientVars.savedRevisions, function(revision)
{
addSavedRevision(revision.revNum, revision);
})
}
});
})();

View file

@ -23,6 +23,7 @@
// These jQuery things should create local references, but for now `require()`
// assigns to the global `$` and augments it with plugins.
require('./jquery');
require('./jquery.class');
JSON = require('./json2');
var createCookie = require('./pad_utils').createCookie;
@ -32,9 +33,165 @@ var hooks = require('./pluginfw/hooks');
var token, padId, export_links;
function init() {
$.Class("SocketClient",
{ //statics
},
{ //instance
init: function (baseurl) {
this.baseurl = baseurl;
// connect to the server
console.log("[socket_client] connecting to:", this.baseurl);
this.socket = io.connect(this.baseurl, {resource: "socket.io"});
// setup the socket callbacks:
_this = this;
this.socket.on("connect", function(callback) {
_this.onConnect(callback);
});
this.socket.on("disconnect", function(callback) {
_this.onDisconnect(callback);
});
this.socket.on("message", function(message, callback) {
_this.onMessage(message, callback);
});
},
onConnect: function(callback) {
console.log("[socket_client] > onConnect");
},
onDisconnect: function(callback) {
console.log("[socket_client] > onDisconnect");
},
onMessage: function(message, callback) {
console.log("[socket_client] > onMessage: ", message);
},
sendMessage: function(message, callback) {
this.socket.json.send(message);
if (callback)
callback();
},
}
);
SocketClient("AuthenticatedSocketClient",
{ //statics
},
{ //instance
init: function (baseurl, padID) {
//make sure we have a token
this.token = readCookie("token");
if(this.token == null)
{
this.token = "t." + randomString();
createCookie("token", this.token, 60);
}
this.padID = padID;
this.sessionID = decodeURIComponent(readCookie("sessionID"));
this.password = readCookie("password");
this._super(baseurl);
},
sendMessage: function (type, data, callback) {
this.sessionID = decodeURIComponent(readCookie("sessionID"));
this.password = readCookie("password");
var msg = { "component" : "pad", // FIXME: Remove this stupidity!
"type": type,
"data": data,
"padId": this.padID,
"token": this.token,
"sessionID": this.sessionID,
"password": this.password,
"protocolVersion": 2};
this._super(msg, callback);
},
onMessage: function (message, callback) {
console.log("[authorized_client] > onMessage:", message);
if (message.accessStatus)
{ //access denied?
//TODO raise some kind of error?
console.log("ACCESS ERROR!");
}
this.dispatchMessage(message.type, message.data, callback);
},
dispatchMessage: function(type, data, callback) {
console.log("[authorized_client] > dispatchMessage('%s', %s)", type, data);
// first call local handlers
if ("handle_" + type in this)
this["handle_" + type](data, callback);
// then call registered handlers
if (type in this.handlers)
for(var h in this.handlers[type])
{ //TODO: maybe chain the handlers into some kind of chain-of-responsibility?
var handler = this.handlers[type][h];
handler.handler.call(this, data, handler.context, callback);
}
},
on: function(type, callback, context) {
if (!(type in this.handlers))
this.handlers[type] = [];
this.handlers[type].push({handler: callback, context: context});
return this;
},
registerHandler: this.on,
unregisterHandler: function(type, context) {
if(type in this.handlers)
{
for(var h in this.handlers[type])
if (this.handlers[type][h].context == context)
{
delete this.handlers[type][h];
break;
}
}
},
}
);
AuthenticatedSocketClient("TimesliderClient",
{ //statics
},
{ //instance
init: function (baseurl, padID) {
this._super(baseurl, padID);
this.handlers = {};
},
onConnect: function (callback) {
this.sendMessage("CLIENT_READY", {}, function() { console.log("CLIENT_READY sent");});
},
// ------------------------------------------
// Handling events
handle_CLIENT_VARS: function(data, callback) {
console.log("[timeslider_client] handle_CLIENT_VARS: ", data);
this.clientVars = data;
},
handle_COLLABROOM: function(data, callback) {
console.log("[timeslider_client] handle_COLLABROOM: ", data);
},
handle_CHANGESET_REQ: function(data, callback) {
console.log("[timeslider_client] handle_COLLABROOM: ", data);
},
}
);
function init(baseURL) {
$(document).ready(function ()
{
console.log("<<<<<<<<<<<<<<<<<<<<<<<<");
console.log("HELLO");
console.log("<<<<<<<<<<<<<<<<<<<<<<<<");
// start the custom js
if (typeof customStart == "function") customStart();
@ -47,7 +204,7 @@ function init() {
//ensure we have a token
token = readCookie("token");
if(token == null)
if(token === null)
{
token = "t." + randomString();
createCookie("token", token, 60);
@ -55,12 +212,42 @@ function init() {
var loc = document.location;
//get the correct port
var port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port;
var port = loc.port === "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port;
//create the url
var url = loc.protocol + "//" + loc.hostname + ":" + port + "/";
//find out in which subfolder we are
var resource = exports.baseURL.substring(1) + 'socket.io';
var resource = baseURL.substring(1) + 'socket.io';
console.log(url, baseURL, resource, padId);
var timesliderclient = new TimesliderClient(url, padId)
.on("CLIENT_VARS", function(data, context, callback) {
//load all script that doesn't work without the clientVars
BroadcastSlider = require('./broadcast_slider').loadBroadcastSliderJS(this.clientVars,fireWhenAllScriptsAreLoaded);
require('./broadcast_revisions').loadBroadcastRevisionsJS(this.clientVars);
changesetLoader = require('./broadcast').loadBroadcastJS(this, fireWhenAllScriptsAreLoaded, BroadcastSlider);
//initialize export ui
require('./pad_impexp').padimpexp.init();
//change export urls when the slider moves
BroadcastSlider.onSlider(function(revno)
{
// export_links is a jQuery Array, so .each is allowed.
export_links.each(function()
{
this.setAttribute('href', this.href.replace( /(.+?)\/\w+\/(\d+\/)?export/ , '$1/' + padId + '/' + revno + '/export'));
});
});
//fire all start functions of these scripts, formerly fired with window.load
for(var i=0;i < fireWhenAllScriptsAreLoaded.length;i++)
{
fireWhenAllScriptsAreLoaded[i]();
}
$("#ui-slider-handle").css('left', $("#ui-slider-bar").width() - 2);
});
/*
//build up the socket io connection
socket = io.connect(url, {resource: resource});
@ -78,7 +265,7 @@ function init() {
//route the incoming messages
socket.on('message', function(message)
{
if(window.console) console.log(message);
//if(window.console) console.log(message);
if(message.type == "CLIENT_VARS")
{
@ -86,14 +273,14 @@ function init() {
}
else if(message.accessStatus)
{
$("body").html("<h2>You have no permission to access this pad</h2>")
$("body").html("<h2>You have no permission to access this pad</h2>");
} else {
changesetLoader.handleMessageFromServer(message);
}
});
*/
//get all the export links
export_links = $('#export > .exportlink')
export_links = $('#export > .exportlink');
if(document.referrer.length > 0 && document.referrer.substring(document.referrer.lastIndexOf("/")-1,document.referrer.lastIndexOf("/")) === "p") {
$("#returnbutton").attr("href", document.referrer);
@ -106,7 +293,7 @@ function init() {
window.location.reload();
});
exports.socket = socket; // make the socket available
//exports.socket = socket; // make the socket available
exports.BroadcastSlider = BroadcastSlider; // Make the slider available
hooks.aCallAll("postTimesliderInit");
@ -128,42 +315,10 @@ function sendSocketMsg(type, data)
"password": password,
"protocolVersion": 2};
socket.json.send(msg);
}
var fireWhenAllScriptsAreLoaded = [];
var changesetLoader;
function handleClientVars(message)
{
//save the client Vars
clientVars = message.data;
//load all script that doesn't work without the clientVars
BroadcastSlider = require('./broadcast_slider').loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded);
require('./broadcast_revisions').loadBroadcastRevisionsJS();
changesetLoader = require('./broadcast').loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider);
//initialize export ui
require('./pad_impexp').padimpexp.init();
//change export urls when the slider moves
BroadcastSlider.onSlider(function(revno)
{
// export_links is a jQuery Array, so .each is allowed.
export_links.each(function()
{
this.setAttribute('href', this.href.replace( /(.+?)\/\w+\/(\d+\/)?export/ , '$1/' + padId + '/' + revno + '/export'));
});
});
//fire all start functions of these scripts, formerly fired with window.load
for(var i=0;i < fireWhenAllScriptsAreLoaded.length;i++)
{
fireWhenAllScriptsAreLoaded[i]();
}
$("#ui-slider-handle").css('left', $("#ui-slider-bar").width() - 2);
}
exports.baseURL = '';
exports.init = init;

View file

@ -226,17 +226,16 @@
}
var plugins = require('ep_etherpad-lite/static/js/pluginfw/client_plugins');
var socket = require('ep_etherpad-lite/static/js/timeslider').socket;
BroadcastSlider = require('ep_etherpad-lite/static/js/timeslider').BroadcastSlider;
var timeslider = require('ep_etherpad-lite/static/js/timeslider')
var socket = timeslider.socket;
BroadcastSlider = timeslider.BroadcastSlider;
plugins.baseURL = baseURL;
plugins.update(function () {
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
hooks.plugins = plugins;
var timeslider = require('ep_etherpad-lite/static/js/timeslider')
timeslider.baseURL = baseURL;
timeslider.init();
timeslider.init(baseURL);
/* TODO: These globals shouldn't exist. */
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;