Merge branch 'master' into aceEditEvent

This commit is contained in:
Egil Moeller 2012-06-22 12:12:15 +02:00
commit 476cfc8da0
18 changed files with 688 additions and 858 deletions

View file

@ -19,6 +19,9 @@ textarea {
iframe {
position: absolute
}
.readonly .acl-write {
display: none;
}
#users {
background: #f7f7f7;
background: -webkit-linear-gradient( #F7F7F7,#EEE);
@ -992,4 +995,7 @@ input[type=checkbox] {
.toolbar ul li .separator {
display: none
}
#online_count {
line-height: 24px
}
}

View file

@ -84,14 +84,14 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
var appLevelDisconnectReason = null;
var padContents = {
currentRevision: clientVars.revNum,
currentTime: clientVars.currentTime,
currentLines: Changeset.splitTextLines(clientVars.initialStyledContents.atext.text),
currentRevision: clientVars.collab_client_vars.rev,
currentTime: clientVars.collab_client_vars.time,
currentLines: Changeset.splitTextLines(clientVars.collab_client_vars.initialAttributedText.text),
currentDivs: null,
// to be filled in once the dom loads
apool: (new AttribPool()).fromJsonable(clientVars.initialStyledContents.apool),
apool: (new AttribPool()).fromJsonable(clientVars.collab_client_vars.apool),
alines: Changeset.splitAttributionLines(
clientVars.initialStyledContents.atext.attribs, clientVars.initialStyledContents.atext.text),
clientVars.collab_client_vars.initialAttributedText.attribs, clientVars.collab_client_vars.initialAttributedText.text),
// generates a jquery element containing HTML for a line
lineToElement: function(line, aline)
@ -271,7 +271,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
Changeset.mutateTextLines(changeset, padContents);
padContents.currentRevision = revision;
padContents.currentTime += timeDelta * 1000;
padContents.currentTime += timeDelta;
debugLog('Time Delta: ', timeDelta)
updateTimer();
@ -432,19 +432,6 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
var start = request.rev;
var requestID = Math.floor(Math.random() * 100000);
/*var msg = { "component" : "timeslider",
"type":"CHANGESET_REQ",
"padId": padId,
"token": token,
"protocolVersion": 2,
"data"
{
"start": start,
"granularity": granularity
}};
socket.send(msg);*/
sendSocketMsg("CHANGESET_REQ", {
"start": start,
"granularity": granularity,
@ -452,19 +439,6 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
});
self.reqCallbacks[requestID] = callback;
/*debugLog("loadinging revision", start, "through ajax");
$.getJSON("/ep/pad/changes/" + clientVars.padIdForUrl + "?s=" + start + "&g=" + granularity, function (data, textStatus)
{
if (textStatus !== "success")
{
console.log(textStatus);
BroadcastSlider.showReconnectUI();
}
self.handleResponse(data, start, granularity, callback);
setTimeout(self.loadFromQueue, 10); // load the next ajax function
});*/
},
handleSocketResponse: function(message)
{
@ -493,130 +467,58 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
revisionInfo.addChangeset(astart, aend, forwardcs, backwardcs, data.timeDeltas[i]);
}
if (callback) callback(start - 1, start + data.forwardsChangesets.length * granularity - 1);
},
handleMessageFromServer: function (obj)
{
debugLog("handleMessage:", arguments);
if (obj.type == "COLLABROOM")
{
obj = obj.data;
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.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);
}
}
else if(obj.type == "CHANGESET_REQ")
{
changesetLoader.handleSocketResponse(obj);
}
else
{
debugLog("Unknown message type: " + obj.type);
}
}
};
function handleMessageFromServer()
{
debugLog("handleMessage:", arguments);
var obj = arguments[0]['data'];
var expectedType = "COLLABROOM";
obj = JSON.parse(obj);
if (obj['type'] == expectedType)
{
obj = obj['data'];
if (obj['type'] == "NEW_CHANGES")
{
debugLog(obj);
var changeset = Changeset.moveOpsToNewPool(
obj.changeset, (new AttribPool()).fromJsonable(obj.apool), padContents.apool);
var changesetBack = Changeset.moveOpsToNewPool(
obj.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);
}
}
else
{
debugLog("incorrect message type: " + obj['type'] + ", expected " + expectedType);
}
}
function handleSocketClosed(params)
{
debugLog("socket closed!", params);
socket = null;
BroadcastSlider.showReconnectUI();
// var reason = appLevelDisconnectReason || params.reason;
// var shouldReconnect = params.reconnect;
// if (shouldReconnect) {
// // determine if this is a tight reconnect loop due to weird connectivity problems
// // reconnectTimes.push(+new Date());
// var TOO_MANY_RECONNECTS = 8;
// var TOO_SHORT_A_TIME_MS = 10000;
// if (reconnectTimes.length >= TOO_MANY_RECONNECTS &&
// ((+new Date()) - reconnectTimes[reconnectTimes.length-TOO_MANY_RECONNECTS]) <
// TOO_SHORT_A_TIME_MS) {
// setChannelState("DISCONNECTED", "looping");
// }
// else {
// setChannelState("RECONNECTING", reason);
// setUpSocket();
// }
// }
// else {
// BroadcastSlider.showReconnectUI();
// setChannelState("DISCONNECTED", reason);
// }
}
function sendMessage(msg)
{
socket.postMessage(JSON.stringify(
{
type: "COLLABROOM",
data: msg
}));
}
function setChannelState(newChannelState, moreInfo)
{
if (newChannelState != channelState)
{
channelState = newChannelState;
// callbacks.onChannelStateChange(channelState, moreInfo);
}
}
function abandonConnection(reason)
{
if (socket)
{
socket.onclosed = function()
{};
socket.onhiccup = function()
{};
socket.disconnect();
}
socket = null;
setChannelState("DISCONNECTED", reason);
}
/// Since its not used, import 'forEach' has been dropped
/*window['onloadFuncts'] = [];
window.onload = function ()
{
window['isloaded'] = true;
forEach(window['onloadFuncts'],function (funct)
{
funct();
});
};*/
// to start upon window load, just push a function onto this array
//window['onloadFuncts'].push(setUpSocket);
//window['onloadFuncts'].push(function ()
@ -637,36 +539,19 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
// this is necessary to keep infinite loops of events firing,
// since goToRevision changes the slider position
var goToRevisionIfEnabledCount = 0;
var goToRevisionIfEnabled = function()
var goToRevisionIfEnabled = function() {
if (goToRevisionIfEnabledCount > 0)
{
if (goToRevisionIfEnabledCount > 0)
{
goToRevisionIfEnabledCount--;
}
else
{
goToRevision.apply(goToRevision, arguments);
}
}
goToRevisionIfEnabledCount--;
}
else
{
goToRevision.apply(goToRevision, arguments);
}
}
BroadcastSlider.onSlider(goToRevisionIfEnabled);
(function()
{
for (var i = 0; i < clientVars.initialChangesets.length; i++)
{
var csgroup = clientVars.initialChangesets[i];
var start = clientVars.initialChangesets[i].start;
var granularity = clientVars.initialChangesets[i].granularity;
debugLog("loading changest on startup: ", start, granularity, csgroup);
changesetLoader.handleResponse(csgroup, start, granularity, null);
}
})();
var dynamicCSS = makeCSSManager('dynamicsyntax');
var authorData = {};
@ -686,7 +571,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
}
receiveAuthorData(clientVars.historicalAuthorData);
receiveAuthorData(clientVars.collab_client_vars.historicalAuthorData);
return changesetLoader;
}

View file

@ -57,7 +57,7 @@ function loadBroadcastRevisionsJS()
endRevision.addChangeset(fromIndex, backChangeset, -1 * timeDelta);
}
revisionInfo.latest = clientVars.totalRevs || -1;
revisionInfo.latest = clientVars.collab_client_vars.rev || -1;
revisionInfo.createNew = function(index)
{

View file

@ -23,6 +23,7 @@
// These parameters were global, now they are injected. A reference to the
// Timeslider controller would probably be more appropriate.
var _ = require('./underscore');
var padmodals = require('./pad_modals').padmodals;
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
@ -54,11 +55,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
slidercallbacks[i](newval);
}
}
}
var updateSliderElements = function()
{
@ -68,12 +65,8 @@ 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)
{
var newSavedRevision = $('<div></div>');
@ -88,7 +81,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
};
var removeSavedRevision = function(position)
{
@ -96,7 +89,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
savedRevisions.remove(element);
element.remove();
return element;
};
};
/* Begin small 'API' */
@ -162,9 +155,9 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
function showReconnectUI()
{
$("#padmain, #rightbars").css('top', "130px");
$("#timeslider").show();
$('#error').show();
var cls = 'modaldialog cboxdisconnected cboxdisconnected_unknown';
$("#connectionbox").get(0).className = cls;
padmodals.showModal("#connectionbox", 500);
}
var fixPadHeight = _.throttle(function(){
@ -481,8 +474,8 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
}
$("#timeslider").show();
setSliderLength(clientVars.totalRevs);
setSliderPosition(clientVars.revNum);
setSliderLength(clientVars.collab_client_vars.rev);
setSliderPosition(clientVars.collab_client_vars.rev);
_.each(clientVars.savedRevisions, function(revision)
{

View file

@ -310,14 +310,20 @@ function handshake()
receivedClientVars = true;
//set some client vars
clientVars = obj;
clientVars = obj.data;
clientVars.userAgent = "Anonymous";
clientVars.collab_client_vars.clientAgent = "Anonymous";
//initalize the pad
pad._afterHandshake();
initalized = true;
$("body").addClass(clientVars.readonly ? "readonly" : "readwrite")
padeditor.ace.callWithAce(function (ace) {
ace.ace_setEditable(!clientVars.readonly);
});
// If the LineNumbersDisabled value is set to true then we need to hide the Line Numbers
if (settings.LineNumbersDisabled == true)
{
@ -354,6 +360,8 @@ function handshake()
//this message advices the client to disconnect
if (obj.disconnect)
{
console.warn("FORCED TO DISCONNECT");
console.warn(obj);
padconnectionstatus.disconnected(obj.disconnect);
socket.disconnect();
return;

View file

@ -241,7 +241,7 @@ var padeditbar = (function()
if ($('#readonlyinput').is(':checked'))
{
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
var readonlyLink = basePath + "/ro/" + clientVars.readOnlyId;
var readonlyLink = basePath + "/p/" + clientVars.readOnlyId;
$('#embedinput').val("<iframe name='embed_readonly' src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
$('#linkinput').val(readonlyLink);
}

View file

@ -102,7 +102,7 @@ exports.aCallAll = function (hook_name, args, cb) {
exports.callFirst = function (hook_name, args) {
if (!args) args = {};
if (plugins.hooks[hook_name][0] === undefined) return [];
if (plugins.hooks[hook_name] === undefined) return [];
return exports.syncMapFirst(plugins.hooks[hook_name], function (hook) {
return hookCallWrapper(hook, hook_name, args);
});

View file

@ -41,14 +41,16 @@ exports.formatParts = function () {
return _.map(exports.parts, function (part) { return part.full_name; }).join("\n");
};
exports.formatHooks = function () {
exports.formatHooks = function (hook_set_name) {
var res = [];
_.chain(exports.hooks).keys().forEach(function (hook_name) {
_.forEach(exports.hooks[hook_name], function (hook) {
res.push(hook.hook_name + ": " + hook.hook_fn_name + " from " + hook.part.full_name);
var hooks = exports.extractHooks(exports.parts, hook_set_name || "hooks");
_.chain(hooks).keys().forEach(function (hook_name) {
_.forEach(hooks[hook_name], function (hook) {
res.push("<dt>" + hook.hook_name + "</dt><dd>" + hook.hook_fn_name + " from " + hook.part.full_name + "</dd>");
});
});
return res.join("\n");
return "<dl>" + res.join("\n") + "</dl>";
};
exports.loadFn = function (path, hookName) {
@ -62,7 +64,7 @@ exports.loadFn = function (path, hookName) {
return fn;
};
exports.extractHooks = function (parts, hook_set_name, plugins) {
exports.extractHooks = function (parts, hook_set_name) {
var hooks = {};
_.each(parts,function (part) {
_.chain(part[hook_set_name] || {})

View file

@ -70,6 +70,11 @@ function init() {
sendSocketMsg("CLIENT_READY", {});
});
socket.on('disconnect', function()
{
BroadcastSlider.showReconnectUI();
});
//route the incoming messages
socket.on('message', function(message)
{
@ -79,13 +84,11 @@ function init() {
{
handleClientVars(message);
}
else if(message.type == "CHANGESET_REQ")
{
changesetLoader.handleSocketResponse(message);
}
else if(message.accessStatus)
{
$("body").html("<h2>You have no permission to access this pad</h2>")
} else {
changesetLoader.handleMessageFromServer(message);
}
});
@ -97,6 +100,12 @@ function init() {
} else {
$("#returnbutton").attr("href", document.location.href.substring(0,document.location.href.lastIndexOf("/")));
}
$('button#forcereconnect').click(function()
{
window.location.reload();
});
});
}
@ -106,7 +115,7 @@ function sendSocketMsg(type, data)
var sessionID = readCookie("sessionID");
var password = readCookie("password");
var msg = { "component" : "timeslider",
var msg = { "component" : "pad", // FIXME: Remove this stupidity!
"type": type,
"data": data,
"padId": padId,