The Big Rewrite to AMD format - had to do lots of them at once

express-require
Egil Moeller 2015-04-12 21:03:59 +02:00
parent 2472cd365e
commit 250b8928bd
20 changed files with 4582 additions and 4448 deletions

View File

@ -22,7 +22,7 @@
var ERR = require("async-stacktrace");
var db = require("./DB").db;
var customError = require("../utils/customError");
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
var randomString = require('ep_etherpad-lite/static/js/random_utils').randomString;
exports.getColorPalette = function(){
return ["#ffc7c7", "#fff1c7", "#e3ffc7", "#c7ffd5", "#c7ffff", "#c7d5ff", "#e3c7ff", "#ffc7f1", "#ff8f8f", "#ffe38f", "#c7ff8f", "#8fffab", "#8fffff", "#8fabff", "#c78fff", "#ff8fe3", "#d97979", "#d9c179", "#a9d979", "#79d991", "#79d9d9", "#7991d9", "#a979d9", "#d979c1", "#d9a9a9", "#d9cda9", "#c1d9a9", "#a9d9b5", "#a9d9d9", "#a9b5d9", "#c1a9d9", "#d9a9cd", "#4c9c82", "#12d1ad", "#2d8e80", "#7485c3", "#a091c7", "#3185ab", "#6818b4", "#e6e76d", "#a42c64", "#f386e5", "#4ecc0c", "#c0c236", "#693224", "#b5de6a", "#9b88fd", "#358f9b", "#496d2f", "#e267fe", "#d23056", "#1a1a64", "#5aa335", "#d722bb", "#86dc6c", "#b5a714", "#955b6a", "#9f2985", "#4b81c8", "#3d6a5b", "#434e16", "#d16084", "#af6a0e", "#8c8bd8"];

View File

@ -21,7 +21,7 @@
var ERR = require("async-stacktrace");
var customError = require("../utils/customError");
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
var randomString = require('ep_etherpad-lite/static/js/random_utils').randomString;
var db = require("./DB").db;
var async = require("async");
var padManager = require("./PadManager");

View File

@ -22,481 +22,490 @@
// 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)
{
var BroadcastSlider;
define([
'ep_etherpad-lite/static/js/pad_modals',
'underscore'
], function(padModalsModule, _) {
var exports = {};
// Hack to ensure timeslider i18n values are in
$("[data-key='timeslider_returnToPad'] > a > span").html(html10n.get("timeslider.toolbar.returnbutton"));
var padmodals = padModalsModule.padmodals;
(function()
{ // wrap this code in its own namespace
var sliderLength = 1000;
var sliderPos = 0;
var sliderActive = false;
var slidercallbacks = [];
var savedRevisions = [];
var sliderPlaying = false;
function disableSelection(element)
{
element.onselectstart = function()
{
return false;
};
element.unselectable = "on";
element.style.MozUserSelect = "none";
element.style.cursor = "default";
}
var _callSliderCallbacks = function(newval)
{
sliderPos = newval;
for (var i = 0; i < slidercallbacks.length; i++)
{
slidercallbacks[i](newval);
}
}
var updateSliderElements = function()
{
for (var i = 0; i < savedRevisions.length; i++)
{
var position = parseInt(savedRevisions[i].attr('pos'));
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>');
newSavedRevision.addClass("star");
newSavedRevision.attr('pos', position);
newSavedRevision.css('position', 'absolute');
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
$("#timeslider-slider").append(newSavedRevision);
newSavedRevision.mouseup(function(evt)
{
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
var removeSavedRevision = function(position)
{
var element = $("div.star [pos=" + position + "]");
savedRevisions.remove(element);
element.remove();
return element;
};
/* Begin small 'API' */
function onSlider(callback)
{
slidercallbacks.push(callback);
}
function getSliderPosition()
{
return sliderPos;
}
function setSliderPosition(newpos)
{
newpos = Number(newpos);
if (newpos < 0 || newpos > sliderLength) return;
if(!newpos){
newpos = 0; // stops it from displaying NaN if newpos isn't set
}
window.location.hash = "#" + newpos;
$("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
$("a.tlink").map(function()
{
$(this).attr('href', $(this).attr('thref').replace("%revision%", newpos));
});
$("#revision_label").html(html10n.get("timeslider.version", { "version": newpos}));
if (newpos == 0)
{
$("#leftstar").css('opacity', .5);
$("#leftstep").css('opacity', .5);
}
else
{
$("#leftstar").css('opacity', 1);
$("#leftstep").css('opacity', 1);
}
if (newpos == sliderLength)
{
$("#rightstar").css('opacity', .5);
$("#rightstep").css('opacity', .5);
}
else
{
$("#rightstar").css('opacity', 1);
$("#rightstep").css('opacity', 1);
}
sliderPos = newpos;
_callSliderCallbacks(newpos);
}
function getSliderLength()
{
return sliderLength;
}
function setSliderLength(newlength)
{
sliderLength = newlength;
updateSliderElements();
}
// just take over the whole slider screen with a reconnect message
function showReconnectUI()
{
padmodals.showModal("disconnected");
}
// Throttle seems like overkill here... Not sure why we do it!
var fixPadHeight = _.throttle(function(){
var height = $('#timeslider-top').height();
$('#editorcontainerbox').css({marginTop: height});
}, 600);
function setAuthors(authors)
{
var authorsList = $("#authorsList");
authorsList.empty();
var numAnonymous = 0;
var numNamed = 0;
var colorsAnonymous = [];
_.each(authors, function(author)
{
if(author)
{
var authorColor = clientVars.colorPalette[author.colorId] || author.colorId;
if (author.name)
{
if (numNamed !== 0) authorsList.append(', ');
$('<span />')
.text(author.name || "unnamed")
.css('background-color', authorColor)
.addClass('author')
.appendTo(authorsList);
numNamed++;
}
else
{
numAnonymous++;
if(authorColor) colorsAnonymous.push(authorColor);
}
}
});
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(' ');
$('<span>&nbsp;</span>')
.css('background-color', color)
.addClass('author author-anonymous')
.appendTo(authorsList);
});
authorsList.append(')');
}
}
if (authors.length == 0)
{
authorsList.append(html10n.get("timeslider.toolbar.authorsList"));
}
fixPadHeight();
}
BroadcastSlider = {
onSlider: onSlider,
getSliderPosition: getSliderPosition,
setSliderPosition: setSliderPosition,
getSliderLength: getSliderLength,
setSliderLength: setSliderLength,
isSliderActive: function()
{
return sliderActive;
},
playpause: playpause,
addSavedRevision: addSavedRevision,
showReconnectUI: showReconnectUI,
setAuthors: setAuthors
}
function playButtonUpdater()
{
if (sliderPlaying)
{
if (getSliderPosition() + 1 > sliderLength)
{
$("#playpause_button_icon").toggleClass('pause');
sliderPlaying = false;
return;
}
setSliderPosition(getSliderPosition() + 1);
setTimeout(playButtonUpdater, 100);
}
}
function playpause()
{
$("#playpause_button_icon").toggleClass('pause');
if (!sliderPlaying)
{
if (getSliderPosition() == sliderLength) setSliderPosition(0);
sliderPlaying = true;
playButtonUpdater();
}
else
{
sliderPlaying = false;
}
}
// assign event handlers to html UI elements after page load
//$(window).load(function ()
fireWhenAllScriptsAreLoaded.push(function()
{
disableSelection($("#playpause_button")[0]);
disableSelection($("#timeslider")[0]);
$(document).keyup(function(e)
{
// If focus is on editbar, don't do anything
var target = $(':focus');
if($(target).parents(".toolbar").length === 1){
return;
}
var code = -1;
if (!e) var e = window.event;
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
if (code == 37)
{ // left
if (!e.shiftKey)
{
setSliderPosition(getSliderPosition() - 1);
}
else
{
var nextStar = 0; // default to first revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
}
else if (code == 39)
{
if (!e.shiftKey)
{
setSliderPosition(getSliderPosition() + 1);
}
else
{
var nextStar = sliderLength; // default to last revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
}
else if (code == 32) playpause();
});
$(window).resize(function()
{
updateSliderElements();
});
$("#ui-slider-bar").mousedown(function(evt)
{
$("#ui-slider-handle").css('left', (evt.clientX - $("#ui-slider-bar").offset().left));
$("#ui-slider-handle").trigger(evt);
});
// Slider dragging
$("#ui-slider-handle").mousedown(function(evt)
{
this.startLoc = evt.clientX;
this.currentLoc = parseInt($(this).css('left'));
var self = this;
sliderActive = true;
$(document).mousemove(function(evt2)
{
$(self).css('pointer', 'move')
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
$("#revision_label").html(html10n.get("timeslider.version", { "version": Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))}));
$(self).css('left', newloc);
if (getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) _callSliderCallbacks(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
});
$(document).mouseup(function(evt2)
{
$(document).unbind('mousemove');
$(document).unbind('mouseup');
sliderActive = false;
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
$(self).css('left', newloc);
// if(getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2)))
setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
if(parseInt($(self).css('left')) < 2){
$(self).css('left', '2px');
}else{
self.currentLoc = parseInt($(self).css('left'));
}
});
})
// play/pause toggling
$("#playpause_button").mousedown(function(evt)
{
var self = this;
// $(self).css('background-image', 'url(/static/img/crushed_button_depressed.png)');
$(self).mouseup(function(evt2)
{
// $(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(self).unbind('mouseup');
BroadcastSlider.playpause();
});
$(document).mouseup(function(evt2)
{
// $(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(document).unbind('mouseup');
});
});
// next/prev saved revision and changeset
$('.stepper').mousedown(function(evt)
{
var self = this;
var origcss = $(self).css('background-position');
if (!origcss)
{
origcss = $(self).css('background-position-x') + " " + $(self).css('background-position-y');
}
var origpos = parseInt(origcss.split(" ")[1]);
var newpos = (origpos - 43);
if (newpos < 0) newpos += 87;
var newcss = (origcss.split(" ")[0] + " " + newpos + "px");
if ($(self).css('opacity') != 1.0) newcss = origcss;
$(self).css('background-position', newcss)
$(self).mouseup(function(evt2)
{
$(self).css('background-position', origcss);
$(self).unbind('mouseup');
$(document).unbind('mouseup');
if ($(self).attr("id") == ("leftstep"))
{
setSliderPosition(getSliderPosition() - 1);
}
else if ($(self).attr("id") == ("rightstep"))
{
setSliderPosition(getSliderPosition() + 1);
}
else if ($(self).attr("id") == ("leftstar"))
{
var nextStar = 0; // default to first revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
else if ($(self).attr("id") == ("rightstar"))
{
var nextStar = sliderLength; // default to last revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
});
$(document).mouseup(function(evt2)
{
$(self).css('background-position', origcss);
$(self).unbind('mouseup');
$(document).unbind('mouseup');
});
})
if (clientVars)
{
$("#timeslider").show();
var startPos = clientVars.collab_client_vars.rev;
if(window.location.hash.length > 1)
{
var hashRev = Number(window.location.hash.substr(1));
if(!isNaN(hashRev))
{
// this is necessary because of the socket.io-event which loads the changesets
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);
})
}
});
})();
BroadcastSlider.onSlider(function(loc)
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
$("#viewlatest").html(loc == BroadcastSlider.getSliderLength() ? "Viewing latest content" : "View latest content");
})
var BroadcastSlider;
return BroadcastSlider;
}
// Hack to ensure timeslider i18n values are in
$("[data-key='timeslider_returnToPad'] > a > span").html(html10n.get("timeslider.toolbar.returnbutton"));
exports.loadBroadcastSliderJS = loadBroadcastSliderJS;
(function()
{ // wrap this code in its own namespace
var sliderLength = 1000;
var sliderPos = 0;
var sliderActive = false;
var slidercallbacks = [];
var savedRevisions = [];
var sliderPlaying = false;
function disableSelection(element)
{
element.onselectstart = function()
{
return false;
};
element.unselectable = "on";
element.style.MozUserSelect = "none";
element.style.cursor = "default";
}
var _callSliderCallbacks = function(newval)
{
sliderPos = newval;
for (var i = 0; i < slidercallbacks.length; i++)
{
slidercallbacks[i](newval);
}
}
var updateSliderElements = function()
{
for (var i = 0; i < savedRevisions.length; i++)
{
var position = parseInt(savedRevisions[i].attr('pos'));
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>');
newSavedRevision.addClass("star");
newSavedRevision.attr('pos', position);
newSavedRevision.css('position', 'absolute');
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
$("#timeslider-slider").append(newSavedRevision);
newSavedRevision.mouseup(function(evt)
{
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
var removeSavedRevision = function(position)
{
var element = $("div.star [pos=" + position + "]");
savedRevisions.remove(element);
element.remove();
return element;
};
/* Begin small 'API' */
function onSlider(callback)
{
slidercallbacks.push(callback);
}
function getSliderPosition()
{
return sliderPos;
}
function setSliderPosition(newpos)
{
newpos = Number(newpos);
if (newpos < 0 || newpos > sliderLength) return;
if(!newpos){
newpos = 0; // stops it from displaying NaN if newpos isn't set
}
window.location.hash = "#" + newpos;
$("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
$("a.tlink").map(function()
{
$(this).attr('href', $(this).attr('thref').replace("%revision%", newpos));
});
$("#revision_label").html(html10n.get("timeslider.version", { "version": newpos}));
if (newpos == 0)
{
$("#leftstar").css('opacity', .5);
$("#leftstep").css('opacity', .5);
}
else
{
$("#leftstar").css('opacity', 1);
$("#leftstep").css('opacity', 1);
}
if (newpos == sliderLength)
{
$("#rightstar").css('opacity', .5);
$("#rightstep").css('opacity', .5);
}
else
{
$("#rightstar").css('opacity', 1);
$("#rightstep").css('opacity', 1);
}
sliderPos = newpos;
_callSliderCallbacks(newpos);
}
function getSliderLength()
{
return sliderLength;
}
function setSliderLength(newlength)
{
sliderLength = newlength;
updateSliderElements();
}
// just take over the whole slider screen with a reconnect message
function showReconnectUI()
{
padmodals.showModal("disconnected");
}
// Throttle seems like overkill here... Not sure why we do it!
var fixPadHeight = _.throttle(function(){
var height = $('#timeslider-top').height();
$('#editorcontainerbox').css({marginTop: height});
}, 600);
function setAuthors(authors)
{
var authorsList = $("#authorsList");
authorsList.empty();
var numAnonymous = 0;
var numNamed = 0;
var colorsAnonymous = [];
_.each(authors, function(author)
{
if(author)
{
var authorColor = clientVars.colorPalette[author.colorId] || author.colorId;
if (author.name)
{
if (numNamed !== 0) authorsList.append(', ');
$('<span />')
.text(author.name || "unnamed")
.css('background-color', authorColor)
.addClass('author')
.appendTo(authorsList);
numNamed++;
}
else
{
numAnonymous++;
if(authorColor) colorsAnonymous.push(authorColor);
}
}
});
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(' ');
$('<span>&nbsp;</span>')
.css('background-color', color)
.addClass('author author-anonymous')
.appendTo(authorsList);
});
authorsList.append(')');
}
}
if (authors.length == 0)
{
authorsList.append(html10n.get("timeslider.toolbar.authorsList"));
}
fixPadHeight();
}
BroadcastSlider = {
onSlider: onSlider,
getSliderPosition: getSliderPosition,
setSliderPosition: setSliderPosition,
getSliderLength: getSliderLength,
setSliderLength: setSliderLength,
isSliderActive: function()
{
return sliderActive;
},
playpause: playpause,
addSavedRevision: addSavedRevision,
showReconnectUI: showReconnectUI,
setAuthors: setAuthors
}
function playButtonUpdater()
{
if (sliderPlaying)
{
if (getSliderPosition() + 1 > sliderLength)
{
$("#playpause_button_icon").toggleClass('pause');
sliderPlaying = false;
return;
}
setSliderPosition(getSliderPosition() + 1);
setTimeout(playButtonUpdater, 100);
}
}
function playpause()
{
$("#playpause_button_icon").toggleClass('pause');
if (!sliderPlaying)
{
if (getSliderPosition() == sliderLength) setSliderPosition(0);
sliderPlaying = true;
playButtonUpdater();
}
else
{
sliderPlaying = false;
}
}
// assign event handlers to html UI elements after page load
//$(window).load(function ()
fireWhenAllScriptsAreLoaded.push(function()
{
disableSelection($("#playpause_button")[0]);
disableSelection($("#timeslider")[0]);
$(document).keyup(function(e)
{
// If focus is on editbar, don't do anything
var target = $(':focus');
if($(target).parents(".toolbar").length === 1){
return;
}
var code = -1;
if (!e) var e = window.event;
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
if (code == 37)
{ // left
if (!e.shiftKey)
{
setSliderPosition(getSliderPosition() - 1);
}
else
{
var nextStar = 0; // default to first revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
}
else if (code == 39)
{
if (!e.shiftKey)
{
setSliderPosition(getSliderPosition() + 1);
}
else
{
var nextStar = sliderLength; // default to last revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
}
else if (code == 32) playpause();
});
$(window).resize(function()
{
updateSliderElements();
});
$("#ui-slider-bar").mousedown(function(evt)
{
$("#ui-slider-handle").css('left', (evt.clientX - $("#ui-slider-bar").offset().left));
$("#ui-slider-handle").trigger(evt);
});
// Slider dragging
$("#ui-slider-handle").mousedown(function(evt)
{
this.startLoc = evt.clientX;
this.currentLoc = parseInt($(this).css('left'));
var self = this;
sliderActive = true;
$(document).mousemove(function(evt2)
{
$(self).css('pointer', 'move')
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
$("#revision_label").html(html10n.get("timeslider.version", { "version": Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))}));
$(self).css('left', newloc);
if (getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) _callSliderCallbacks(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
});
$(document).mouseup(function(evt2)
{
$(document).unbind('mousemove');
$(document).unbind('mouseup');
sliderActive = false;
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
$(self).css('left', newloc);
// if(getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2)))
setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
if(parseInt($(self).css('left')) < 2){
$(self).css('left', '2px');
}else{
self.currentLoc = parseInt($(self).css('left'));
}
});
})
// play/pause toggling
$("#playpause_button").mousedown(function(evt)
{
var self = this;
// $(self).css('background-image', 'url(/static/img/crushed_button_depressed.png)');
$(self).mouseup(function(evt2)
{
// $(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(self).unbind('mouseup');
BroadcastSlider.playpause();
});
$(document).mouseup(function(evt2)
{
// $(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(document).unbind('mouseup');
});
});
// next/prev saved revision and changeset
$('.stepper').mousedown(function(evt)
{
var self = this;
var origcss = $(self).css('background-position');
if (!origcss)
{
origcss = $(self).css('background-position-x') + " " + $(self).css('background-position-y');
}
var origpos = parseInt(origcss.split(" ")[1]);
var newpos = (origpos - 43);
if (newpos < 0) newpos += 87;
var newcss = (origcss.split(" ")[0] + " " + newpos + "px");
if ($(self).css('opacity') != 1.0) newcss = origcss;
$(self).css('background-position', newcss)
$(self).mouseup(function(evt2)
{
$(self).css('background-position', origcss);
$(self).unbind('mouseup');
$(document).unbind('mouseup');
if ($(self).attr("id") == ("leftstep"))
{
setSliderPosition(getSliderPosition() - 1);
}
else if ($(self).attr("id") == ("rightstep"))
{
setSliderPosition(getSliderPosition() + 1);
}
else if ($(self).attr("id") == ("leftstar"))
{
var nextStar = 0; // default to first revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
else if ($(self).attr("id") == ("rightstar"))
{
var nextStar = sliderLength; // default to last revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
});
$(document).mouseup(function(evt2)
{
$(self).css('background-position', origcss);
$(self).unbind('mouseup');
$(document).unbind('mouseup');
});
})
if (clientVars)
{
$("#timeslider").show();
var startPos = clientVars.collab_client_vars.rev;
if(window.location.hash.length > 1)
{
var hashRev = Number(window.location.hash.substr(1));
if(!isNaN(hashRev))
{
// this is necessary because of the socket.io-event which loads the changesets
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);
})
}
});
})();
BroadcastSlider.onSlider(function(loc)
{
$("#viewlatest").html(loc == BroadcastSlider.getSliderLength() ? "Viewing latest content" : "View latest content");
})
return BroadcastSlider;
}
exports.loadBroadcastSliderJS = loadBroadcastSliderJS;
return exports;
});

View File

@ -14,258 +14,268 @@
* limitations under the License.
*/
var padutils = require('./pad_utils').padutils;
var padcookie = require('./pad_cookie').padcookie;
var Tinycon = require('tinycon/tinycon');
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
var padeditor = require('./pad_editor').padeditor;
define([
'ep_etherpad-lite/static/js/pad_utils',
'ep_etherpad-lite/static/js/pad_cookie',
'ep_etherpad-lite/static/js/pad_editor',
'ep_etherpad-lite/static/js/pluginfw/hooks',
], function (padUtilsModule, padCookieModule, padEditorModule, hooks) {
var exports = {};
var chat = (function()
{
var isStuck = false;
var userAndChat = false;
var gotInitialMessages = false;
var historyPointer = 0;
var chatMentions = 0;
var self = {
show: function ()
{
$("#chaticon").hide();
$("#chatbox").show();
$("#gritter-notice-wrapper").hide();
self.scrollDown();
chatMentions = 0;
Tinycon.setBubble(0);
},
focus: function ()
{
// I'm not sure why we need a setTimeout here but without it we don't get focus...
// Animation maybe?
setTimeout(function(){
$("#chatinput").focus();
},100);
},
stickToScreen: function(fromInitialCall) // Make chat stick to right hand side of screen
{
chat.show();
if(!isStuck || fromInitialCall) { // Stick it to
padcookie.setPref("chatAlwaysVisible", true);
$('#chatbox').addClass("stickyChat");
$('#titlesticky').hide();
$('#editorcontainer').css({"right":"192px"});
$('.stickyChat').css("top",$('#editorcontainer').offset().top+"px");
isStuck = true;
} else { // Unstick it
padcookie.setPref("chatAlwaysVisible", false);
$('.stickyChat').css("top", "auto");
$('#chatbox').removeClass("stickyChat");
$('#titlesticky').show();
$('#editorcontainer').css({"right":"0px"});
isStuck = false;
}
},
chatAndUsers: function(fromInitialCall)
{
var toEnable = $('#options-chatandusers').is(":checked");
if(toEnable || !userAndChat || fromInitialCall){
padcookie.setPref("chatAndUsers", true);
chat.stickToScreen(true);
$('#options-stickychat').prop('checked', true)
$('#options-chatandusers').prop('checked', true)
$('#options-stickychat').prop("disabled", "disabled");
$('#users').addClass("chatAndUsers");
$("#chatbox").addClass("chatAndUsersChat");
// redraw
userAndChat = true;
padeditbar.redrawHeight()
}else{
padcookie.setPref("chatAndUsers", false);
$('#options-stickychat').prop("disabled", false);
$('#users').removeClass("chatAndUsers");
$("#chatbox").removeClass("chatAndUsersChat");
}
},
hide: function ()
{
// decide on hide logic based on chat window being maximized or not
if ($('#options-stickychat').prop('checked')) {
chat.stickToScreen();
$('#options-stickychat').prop('checked', false);
}
else {
$("#chatcounter").text("0");
$("#chaticon").show();
$("#chatbox").hide();
$.gritter.removeAll();
$("#gritter-notice-wrapper").show();
}
},
scrollDown: function()
{
if($('#chatbox').css("display") != "none"){
if(!self.lastMessage || !self.lastMessage.position() || self.lastMessage.position().top < $('#chattext').height()) {
// if we use a slow animate here we can have a race condition when a users focus can not be moved away
// from the last message recieved.
$('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, { duration: 400, queue: false });
self.lastMessage = $('#chattext > p').eq(-1);
}
}
},
send: function()
{
var text = $("#chatinput").val();
if(text.replace(/\s+/,'').length == 0)
return;
this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text});
$("#chatinput").val("");
},
addMessage: function(msg, increment, isHistoryAdd)
{
//correct the time
msg.time += this._pad.clientTimeOffset;
//create the time string
var minutes = "" + new Date(msg.time).getMinutes();
var hours = "" + new Date(msg.time).getHours();
if(minutes.length == 1)
minutes = "0" + minutes ;
if(hours.length == 1)
hours = "0" + hours ;
var timeStr = hours + ":" + minutes;
//create the authorclass
var authorClass = "author-" + msg.userId.replace(/[^a-y0-9]/g, function(c)
{
if (c == ".") return "-";
return 'z' + c.charCodeAt(0) + 'z';
});
var padutils = padUtilsModule.padutils;
var padcookie = padCookieModule.padcookie;
var padeditor = padEditorModule.padeditor;
var text = padutils.escapeHtmlWithClickableLinks(msg.text, "_blank");
var Tinycon = window.requireKernel('tinycon/tinycon');
var authorName = msg.userName == null ? _('pad.userlist.unnamed') : padutils.escapeHtml(msg.userName);
// the hook args
var ctx = {
"authorName" : authorName,
"author" : msg.userId,
"text" : text,
"sticky" : false,
"timestamp" : msg.time,
"timeStr" : timeStr
}
// is the users focus already in the chatbox?
var alreadyFocused = $("#chatinput").is(":focus");
// does the user already have the chatbox open?
var chatOpen = $("#chatbox").is(":visible");
// does this message contain this user's name? (is the curretn user mentioned?)
var myName = $('#myusernameedit').val();
var wasMentioned = (text.toLowerCase().indexOf(myName.toLowerCase()) !== -1 && myName != "undefined");
if(wasMentioned && !alreadyFocused && !isHistoryAdd && !chatOpen)
{ // If the user was mentioned show for twice as long and flash the browser window
chatMentions++;
Tinycon.setBubble(chatMentions);
ctx.sticky = true;
}
// Call chat message hook
hooks.aCallAll("chatNewMessage", ctx, function() {
var html = "<p data-authorId='" + msg.userId + "' class='" + authorClass + "'><b>" + authorName + ":</b><span class='time " + authorClass + "'>" + ctx.timeStr + "</span> " + ctx.text + "</p>";
if(isHistoryAdd)
$(html).insertAfter('#chatloadmessagesbutton');
else
$("#chattext").append(html);
//should we increment the counter??
if(increment && !isHistoryAdd)
{
// Update the counter of unread messages
var count = Number($("#chatcounter").text());
count++;
$("#chatcounter").text(count);
if(!chatOpen) {
$.gritter.add({
// (string | mandatory) the heading of the notification
title: ctx.authorName,
// (string | mandatory) the text inside the notification
text: ctx.text,
// (bool | optional) if you want it to fade out on its own or just sit there
sticky: ctx.sticky,
// (int | optional) the time you want it to be alive for before fading out
time: '4000'
});
}
}
});
// Clear the chat mentions when the user clicks on the chat input box
$('#chatinput').click(function(){
var chat = (function()
{
var isStuck = false;
var userAndChat = false;
var gotInitialMessages = false;
var historyPointer = 0;
var chatMentions = 0;
var self = {
show: function ()
{
$("#chaticon").hide();
$("#chatbox").show();
$("#gritter-notice-wrapper").hide();
self.scrollDown();
chatMentions = 0;
Tinycon.setBubble(0);
});
if(!isHistoryAdd)
self.scrollDown();
},
init: function(pad)
{
this._pad = pad;
$("#chatinput").keyup(function(evt)
},
focus: function ()
{
// If the event is Alt C or Escape & we're already in the chat menu
// Send the users focus back to the pad
if((evt.altKey == true && evt.which === 67) || evt.which === 27){
// If we're in chat already..
$(':focus').blur(); // required to do not try to remove!
padeditor.ace.focus(); // Sends focus back to pad
}
});
$('body:not(#chatinput)').on("keydown", function(evt){
if (evt.altKey && evt.which == 67){
// Alt c focuses on the Chat window
$(this).blur();
parent.parent.chat.show();
parent.parent.chat.focus();
evt.preventDefault();
}
});
$("#chatinput").keypress(function(evt){
//if the user typed enter, fire the send
if(evt.which == 13 || evt.which == 10)
{
evt.preventDefault();
self.send();
}
});
// initial messages are loaded in pad.js' _afterHandshake
$("#chatcounter").text(0);
$("#chatloadmessagesbutton").click(function()
// I'm not sure why we need a setTimeout here but without it we don't get focus...
// Animation maybe?
setTimeout(function(){
$("#chatinput").focus();
},100);
},
stickToScreen: function(fromInitialCall) // Make chat stick to right hand side of screen
{
var start = Math.max(self.historyPointer - 20, 0);
var end = self.historyPointer;
if(start == end) // nothing to load
chat.show();
if(!isStuck || fromInitialCall) { // Stick it to
padcookie.setPref("chatAlwaysVisible", true);
$('#chatbox').addClass("stickyChat");
$('#titlesticky').hide();
$('#editorcontainer').css({"right":"192px"});
$('.stickyChat').css("top",$('#editorcontainer').offset().top+"px");
isStuck = true;
} else { // Unstick it
padcookie.setPref("chatAlwaysVisible", false);
$('.stickyChat').css("top", "auto");
$('#chatbox').removeClass("stickyChat");
$('#titlesticky').show();
$('#editorcontainer').css({"right":"0px"});
isStuck = false;
}
},
chatAndUsers: function(fromInitialCall)
{
var toEnable = $('#options-chatandusers').is(":checked");
if(toEnable || !userAndChat || fromInitialCall){
padcookie.setPref("chatAndUsers", true);
chat.stickToScreen(true);
$('#options-stickychat').prop('checked', true)
$('#options-chatandusers').prop('checked', true)
$('#options-stickychat').prop("disabled", "disabled");
$('#users').addClass("chatAndUsers");
$("#chatbox").addClass("chatAndUsersChat");
// redraw
userAndChat = true;
padeditbar.redrawHeight()
}else{
padcookie.setPref("chatAndUsers", false);
$('#options-stickychat').prop("disabled", false);
$('#users').removeClass("chatAndUsers");
$("#chatbox").removeClass("chatAndUsersChat");
}
},
hide: function ()
{
// decide on hide logic based on chat window being maximized or not
if ($('#options-stickychat').prop('checked')) {
chat.stickToScreen();
$('#options-stickychat').prop('checked', false);
}
else {
$("#chatcounter").text("0");
$("#chaticon").show();
$("#chatbox").hide();
$.gritter.removeAll();
$("#gritter-notice-wrapper").show();
}
},
scrollDown: function()
{
if($('#chatbox').css("display") != "none"){
if(!self.lastMessage || !self.lastMessage.position() || self.lastMessage.position().top < $('#chattext').height()) {
// if we use a slow animate here we can have a race condition when a users focus can not be moved away
// from the last message recieved.
$('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, { duration: 400, queue: false });
self.lastMessage = $('#chattext > p').eq(-1);
}
}
},
send: function()
{
var text = $("#chatinput").val();
if(text.replace(/\s+/,'').length == 0)
return;
this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text});
$("#chatinput").val("");
},
addMessage: function(msg, increment, isHistoryAdd)
{
//correct the time
msg.time += this._pad.clientTimeOffset;
$("#chatloadmessagesbutton").css("display", "none");
$("#chatloadmessagesball").css("display", "block");
//create the time string
var minutes = "" + new Date(msg.time).getMinutes();
var hours = "" + new Date(msg.time).getHours();
if(minutes.length == 1)
minutes = "0" + minutes ;
if(hours.length == 1)
hours = "0" + hours ;
var timeStr = hours + ":" + minutes;
pad.collabClient.sendMessage({"type": "GET_CHAT_MESSAGES", "start": start, "end": end});
self.historyPointer = start;
});
//create the authorclass
var authorClass = "author-" + msg.userId.replace(/[^a-y0-9]/g, function(c)
{
if (c == ".") return "-";
return 'z' + c.charCodeAt(0) + 'z';
});
var text = padutils.escapeHtmlWithClickableLinks(msg.text, "_blank");
var authorName = msg.userName == null ? _('pad.userlist.unnamed') : padutils.escapeHtml(msg.userName);
// the hook args
var ctx = {
"authorName" : authorName,
"author" : msg.userId,
"text" : text,
"sticky" : false,
"timestamp" : msg.time,
"timeStr" : timeStr
}
// is the users focus already in the chatbox?
var alreadyFocused = $("#chatinput").is(":focus");
// does the user already have the chatbox open?
var chatOpen = $("#chatbox").is(":visible");
// does this message contain this user's name? (is the curretn user mentioned?)
var myName = $('#myusernameedit').val();
var wasMentioned = (text.toLowerCase().indexOf(myName.toLowerCase()) !== -1 && myName != "undefined");
if(wasMentioned && !alreadyFocused && !isHistoryAdd && !chatOpen)
{ // If the user was mentioned show for twice as long and flash the browser window
chatMentions++;
Tinycon.setBubble(chatMentions);
ctx.sticky = true;
}
// Call chat message hook
hooks.aCallAll("chatNewMessage", ctx, function() {
var html = "<p data-authorId='" + msg.userId + "' class='" + authorClass + "'><b>" + authorName + ":</b><span class='time " + authorClass + "'>" + ctx.timeStr + "</span> " + ctx.text + "</p>";
if(isHistoryAdd)
$(html).insertAfter('#chatloadmessagesbutton');
else
$("#chattext").append(html);
//should we increment the counter??
if(increment && !isHistoryAdd)
{
// Update the counter of unread messages
var count = Number($("#chatcounter").text());
count++;
$("#chatcounter").text(count);
if(!chatOpen) {
$.gritter.add({
// (string | mandatory) the heading of the notification
title: ctx.authorName,
// (string | mandatory) the text inside the notification
text: ctx.text,
// (bool | optional) if you want it to fade out on its own or just sit there
sticky: ctx.sticky,
// (int | optional) the time you want it to be alive for before fading out
time: '4000'
});
}
}
});
// Clear the chat mentions when the user clicks on the chat input box
$('#chatinput').click(function(){
chatMentions = 0;
Tinycon.setBubble(0);
});
if(!isHistoryAdd)
self.scrollDown();
},
init: function(pad)
{
this._pad = pad;
$("#chatinput").keyup(function(evt)
{
// If the event is Alt C or Escape & we're already in the chat menu
// Send the users focus back to the pad
if((evt.altKey == true && evt.which === 67) || evt.which === 27){
// If we're in chat already..
$(':focus').blur(); // required to do not try to remove!
padeditor.ace.focus(); // Sends focus back to pad
}
});
$('body:not(#chatinput)').on("keydown", function(evt){
if (evt.altKey && evt.which == 67){
// Alt c focuses on the Chat window
$(this).blur();
parent.parent.chat.show();
parent.parent.chat.focus();
evt.preventDefault();
}
});
$("#chatinput").keypress(function(evt){
//if the user typed enter, fire the send
if(evt.which == 13 || evt.which == 10)
{
evt.preventDefault();
self.send();
}
});
// initial messages are loaded in pad.js' _afterHandshake
$("#chatcounter").text(0);
$("#chatloadmessagesbutton").click(function()
{
var start = Math.max(self.historyPointer - 20, 0);
var end = self.historyPointer;
if(start == end) // nothing to load
return;
$("#chatloadmessagesbutton").css("display", "none");
$("#chatloadmessagesball").css("display", "block");
pad.collabClient.sendMessage({"type": "GET_CHAT_MESSAGES", "start": start, "end": end});
self.historyPointer = start;
});
}
}
}
return self;
}());
return self;
}());
exports.chat = chat;
exports.chat = chat;
return exports;
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,69 +20,77 @@
* limitations under the License.
*/
var padmodals = require('./pad_modals').padmodals;
define([
'ep_etherpad-lite/static/js/pad_modals'
], function(padModalsModule) {
var exports = {};
var padconnectionstatus = (function()
{
var padmodals = padModalsModule.padmodals;
var status = {
what: 'connecting'
};
var padconnectionstatus = (function()
{
var self = {
init: function()
{
$('button#forcereconnect').click(function()
var status = {
what: 'connecting'
};
var self = {
init: function()
{
window.location.reload();
});
},
connected: function()
{
status = {
what: 'connected'
};
padmodals.showModal('connected');
padmodals.hideOverlay();
},
reconnecting: function()
{
status = {
what: 'reconnecting'
};
padmodals.showModal('reconnecting');
padmodals.showOverlay();
},
disconnected: function(msg)
{
if(status.what == "disconnected")
return;
status = {
what: 'disconnected',
why: msg
};
var k = String(msg); // known reason why
if (!(k == 'userdup' || k == 'deleted' || k == 'looping' || k == 'slowcommit' || k == 'initsocketfail' || k == 'unauth' || k == 'badChangeset' || k == 'corruptPad'))
$('button#forcereconnect').click(function()
{
window.location.reload();
});
},
connected: function()
{
k = 'disconnected';
status = {
what: 'connected'
};
padmodals.showModal('connected');
padmodals.hideOverlay();
},
reconnecting: function()
{
status = {
what: 'reconnecting'
};
padmodals.showModal('reconnecting');
padmodals.showOverlay();
},
disconnected: function(msg)
{
if(status.what == "disconnected")
return;
status = {
what: 'disconnected',
why: msg
};
var k = String(msg); // known reason why
if (!(k == 'userdup' || k == 'deleted' || k == 'looping' || k == 'slowcommit' || k == 'initsocketfail' || k == 'unauth' || k == 'badChangeset' || k == 'corruptPad'))
{
k = 'disconnected';
}
padmodals.showModal(k);
padmodals.showOverlay();
},
isFullyConnected: function()
{
return status.what == 'connected';
},
getStatus: function()
{
return status;
}
};
return self;
}());
padmodals.showModal(k);
padmodals.showOverlay();
},
isFullyConnected: function()
{
return status.what == 'connected';
},
getStatus: function()
{
return status;
}
};
return self;
}());
exports.padconnectionstatus = padconnectionstatus;
exports.padconnectionstatus = padconnectionstatus;
return exports;
});

View File

@ -21,113 +21,118 @@
*/
var padcookie = (function()
{
function getRawCookie()
define([], function () {
var exports = {};
var padcookie = (function()
{
// returns null if can't get cookie text
if (!document.cookie)
function getRawCookie()
{
return null;
}
// look for (start of string OR semicolon) followed by whitespace followed by prefs=(something);
var regexResult = document.cookie.match(/(?:^|;)\s*prefs=([^;]*)(?:;|$)/);
if ((!regexResult) || (!regexResult[1]))
{
return null;
}
return regexResult[1];
}
function setRawCookie(safeText)
{
var expiresDate = new Date();
expiresDate.setFullYear(3000);
document.cookie = ('prefs=' + safeText + ';expires=' + expiresDate.toGMTString());
}
function parseCookie(text)
{
// returns null if can't parse cookie.
try
{
var cookieData = JSON.parse(unescape(text));
return cookieData;
}
catch (e)
{
return null;
}
}
function stringifyCookie(data)
{
return escape(JSON.stringify(data));
}
function saveCookie()
{
if (!inited)
{
return;
}
setRawCookie(stringifyCookie(cookieData));
if ((!getRawCookie()) && (!alreadyWarnedAboutNoCookies))
{
alert("Warning: it appears that your browser does not have cookies enabled." + " EtherPad uses cookies to keep track of unique users for the purpose" + " of putting a quota on the number of active users. Using EtherPad without " + " cookies may fill up your server's user quota faster than expected.");
alreadyWarnedAboutNoCookies = true;
}
}
var wasNoCookie = true;
var cookieData = {};
var alreadyWarnedAboutNoCookies = false;
var inited = false;
var pad = undefined;
var self = {
init: function(prefsToSet, _pad)
{
pad = _pad;
var rawCookie = getRawCookie();
if (rawCookie)
// returns null if can't get cookie text
if (!document.cookie)
{
var cookieObj = parseCookie(rawCookie);
if (cookieObj)
return null;
}
// look for (start of string OR semicolon) followed by whitespace followed by prefs=(something);
var regexResult = document.cookie.match(/(?:^|;)\s*prefs=([^;]*)(?:;|$)/);
if ((!regexResult) || (!regexResult[1]))
{
return null;
}
return regexResult[1];
}
function setRawCookie(safeText)
{
var expiresDate = new Date();
expiresDate.setFullYear(3000);
document.cookie = ('prefs=' + safeText + ';expires=' + expiresDate.toGMTString());
}
function parseCookie(text)
{
// returns null if can't parse cookie.
try
{
var cookieData = JSON.parse(unescape(text));
return cookieData;
}
catch (e)
{
return null;
}
}
function stringifyCookie(data)
{
return escape(JSON.stringify(data));
}
function saveCookie()
{
if (!inited)
{
return;
}
setRawCookie(stringifyCookie(cookieData));
if ((!getRawCookie()) && (!alreadyWarnedAboutNoCookies))
{
alert("Warning: it appears that your browser does not have cookies enabled." + " EtherPad uses cookies to keep track of unique users for the purpose" + " of putting a quota on the number of active users. Using EtherPad without " + " cookies may fill up your server's user quota faster than expected.");
alreadyWarnedAboutNoCookies = true;
}
}
var wasNoCookie = true;
var cookieData = {};
var alreadyWarnedAboutNoCookies = false;
var inited = false;
var pad = undefined;
var self = {
init: function(prefsToSet, _pad)
{
pad = _pad;
var rawCookie = getRawCookie();
if (rawCookie)
{
wasNoCookie = false; // there was a cookie
delete cookieObj.userId;
delete cookieObj.name;
delete cookieObj.colorId;
cookieData = cookieObj;
var cookieObj = parseCookie(rawCookie);
if (cookieObj)
{
wasNoCookie = false; // there was a cookie
delete cookieObj.userId;
delete cookieObj.name;
delete cookieObj.colorId;
cookieData = cookieObj;
}
}
}
for (var k in prefsToSet)
for (var k in prefsToSet)
{
cookieData[k] = prefsToSet[k];
}
inited = true;
saveCookie();
},
wasNoCookie: function()
{
cookieData[k] = prefsToSet[k];
return wasNoCookie;
},
getPref: function(prefName)
{
return cookieData[prefName];
},
setPref: function(prefName, value)
{
cookieData[prefName] = value;
saveCookie();
}
};
return self;
}());
inited = true;
saveCookie();
},
wasNoCookie: function()
{
return wasNoCookie;
},
getPref: function(prefName)
{
return cookieData[prefName];
},
setPref: function(prefName, value)
{
cookieData[prefName] = value;
saveCookie();
}
};
return self;
}());
exports.padcookie = padcookie;
exports.padcookie = padcookie;
return exports;
});

View File

@ -20,462 +20,471 @@
* limitations under the License.
*/
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
var padutils = require('./pad_utils').padutils;
var padeditor = require('./pad_editor').padeditor;
var padsavedrevs = require('./pad_savedrevs');
define([
'ep_etherpad-lite/static/js/pluginfw/hooks',
'ep_etherpad-lite/static/js/pad_utils',
'ep_etherpad-lite/static/js/pad_editor',
'ep_etherpad-lite/static/js/pad_savedrevs'
], function(hooks, padUtilsModule, padEditorModule, padsavedrevs) {
var exports = {};
var ToolbarItem = function (element) {
this.$el = element;
};
var padutils = padUtilsModule.padutils;
var padeditor = padEditorModule.padeditor;
ToolbarItem.prototype.getCommand = function () {
return this.$el.attr("data-key");
};
var ToolbarItem = function (element) {
this.$el = element;
};
ToolbarItem.prototype.getValue = function () {
if (this.isSelect()) {
return this.$el.find("select").val();
}
};
ToolbarItem.prototype.getCommand = function () {
return this.$el.attr("data-key");
};
ToolbarItem.prototype.setValue = function (val) {
if (this.isSelect()) {
return this.$el.find("select").val(val);
}
};
ToolbarItem.prototype.getType = function () {
return this.$el.attr("data-type");
};
ToolbarItem.prototype.isSelect = function () {
return this.getType() == "select";
};
ToolbarItem.prototype.isButton = function () {
return this.getType() == "button";
};
ToolbarItem.prototype.bind = function (callback) {
var self = this;
if (self.isButton()) {
self.$el.click(function (event) {
$(':focus').blur();
callback(self.getCommand(), self);
event.preventDefault();
});
}
else if (self.isSelect()) {
self.$el.find("select").change(function () {
callback(self.getCommand(), self);
});
}
};
var padeditbar = (function()
{
var syncAnimation = (function()
{
var SYNCING = -100;
var DONE = 100;
var state = DONE;
var fps = 25;
var step = 1 / fps;
var T_START = -0.5;
var T_FADE = 1.0;
var T_GONE = 1.5;
var animator = padutils.makeAnimationScheduler(function()
{
if (state == SYNCING || state == DONE)
{
return false;
}
else if (state >= T_GONE)
{
state = DONE;
$("#syncstatussyncing").css('display', 'none');
$("#syncstatusdone").css('display', 'none');
return false;
}
else if (state < 0)
{
state += step;
if (state >= 0)
{
$("#syncstatussyncing").css('display', 'none');
$("#syncstatusdone").css('display', 'block').css('opacity', 1);
}
return true;
}
else
{
state += step;
if (state >= T_FADE)
{
$("#syncstatusdone").css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
}
return true;
}
}, step * 1000);
return {
syncing: function()
{
state = SYNCING;
$("#syncstatussyncing").css('display', 'block');
$("#syncstatusdone").css('display', 'none');
},
done: function()
{
state = T_START;
animator.scheduleAnimation();
}
};
}());
var self = {
init: function() {
var self = this;
self.dropdowns = [];
// Listen for resize events (sucks but needed as iFrame ace_inner has to be position absolute
// A CSS fix for this would be nice but I'm not sure how we'd do it.
$(window).resize(function(){
self.redrawHeight();
});
$("#editbar .editbarbutton").attr("unselectable", "on"); // for IE
$("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
$("#editbar [data-key]").each(function () {
$(this).unbind("click");
(new ToolbarItem($(this))).bind(function (command, item) {
self.triggerCommand(command, item);
});
});
$('body:not(#editorcontainerbox)').on("keydown", function(evt){
bodyKeyEvent(evt);
});
$('#editbar').show();
this.redrawHeight();
registerDefaultCommands(self);
hooks.callAll("postToolbarInit", {
toolbar: self,
ace: padeditor.ace
});
},
isEnabled: function()
{
// return !$("#editbar").hasClass('disabledtoolbar');
return true;
},
disable: function()
{
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
},
commands: {},
registerCommand: function (cmd, callback) {
this.commands[cmd] = callback;
return this;
},
redrawHeight: function(){
var editbarHeight = $('.menu_left').height() + 1 + "px";
var containerTop = $('.menu_left').height() + 6 + "px";
$('#editbar').css("height", editbarHeight);
$('#editorcontainer').css("top", containerTop);
// make sure pop ups are in the right place
if($('#editorcontainer').offset()){
$('.popup').css("top", $('#editorcontainer').offset().top + "px");
}
// If sticky chat is enabled..
if($('#options-stickychat').is(":checked")){
if($('#editorcontainer').offset()){
$('#chatbox').css("top", $('#editorcontainer').offset().top + "px");
}
};
// If chat and Users is enabled..
if($('#options-chatandusers').is(":checked")){
if($('#editorcontainer').offset()){
$('#users').css("top", $('#editorcontainer').offset().top + "px");
}
}
},
registerDropdownCommand: function (cmd, dropdown) {
dropdown = dropdown || cmd;
self.dropdowns.push(dropdown)
this.registerCommand(cmd, function () {
self.toggleDropDown(dropdown);
});
},
registerAceCommand: function (cmd, callback) {
this.registerCommand(cmd, function (cmd, ace) {
ace.callWithAce(function (ace) {
callback(cmd, ace);
}, cmd, true);
});
},
triggerCommand: function (cmd, item) {
if (self.isEnabled() && this.commands[cmd]) {
this.commands[cmd](cmd, padeditor.ace, item);
}
if(padeditor.ace) padeditor.ace.focus();
},
toggleDropDown: function(moduleName, cb)
{
// hide all modules and remove highlighting of all buttons
if(moduleName == "none")
{
var returned = false
for(var i=0;i<self.dropdowns.length;i++)
{
//skip the userlist
if(self.dropdowns[i] == "users")
continue;
var module = $("#" + self.dropdowns[i]);
if(module.css('display') != "none")
{
$("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected");
module.slideUp("fast", cb);
returned = true;
}
}
if(!returned && cb) return cb();
}
else
{
// hide all modules that are not selected and remove highlighting
// respectively add highlighting to the corresponding button
for(var i=0;i<self.dropdowns.length;i++)
{
var module = $("#" + self.dropdowns[i]);
if(module.css('display') != "none")
{
$("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected");
module.slideUp("fast");
}
else if(self.dropdowns[i]==moduleName)
{
$("li[data-key=" + self.dropdowns[i] + "] > a").addClass("selected");
module.slideDown("fast", cb);
}
}
}
},
setSyncStatus: function(status)
{
if (status == "syncing")
{
syncAnimation.syncing();
}
else if (status == "done")
{
syncAnimation.done();
}
},
setEmbedLinks: function()
{
if ($('#readonlyinput').is(':checked'))
{
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
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></iframe>");
$('#linkinput').val(readonlyLink);
}
else
{
var padurl = window.location.href.split("?")[0];
$('#embedinput').val("<iframe name='embed_readwrite' src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400></iframe>");
$('#linkinput').val(padurl);
}
ToolbarItem.prototype.getValue = function () {
if (this.isSelect()) {
return this.$el.find("select").val();
}
};
var editbarPosition = 0;
ToolbarItem.prototype.setValue = function (val) {
if (this.isSelect()) {
return this.$el.find("select").val(val);
}
};
function bodyKeyEvent(evt){
// If the event is Alt F9 or Escape & we're already in the editbar menu
// Send the users focus back to the pad
if((evt.keyCode === 120 && evt.altKey) || evt.keyCode === 27){
if($(':focus').parents(".toolbar").length === 1){
// If we're in the editbar already..
// Close any dropdowns we have open..
padeditbar.toggleDropDown("none");
// Check we're on a pad and not on the timeslider
// Or some other window I haven't thought about!
if(typeof pad === 'undefined'){
// Timeslider probably..
// Shift focus away from any drop downs
$(':focus').blur(); // required to do not try to remove!
$('#padmain').focus(); // Focus back onto the pad
ToolbarItem.prototype.getType = function () {
return this.$el.attr("data-type");
};
ToolbarItem.prototype.isSelect = function () {
return this.getType() == "select";
};
ToolbarItem.prototype.isButton = function () {
return this.getType() == "button";
};
ToolbarItem.prototype.bind = function (callback) {
var self = this;
if (self.isButton()) {
self.$el.click(function (event) {
$(':focus').blur();
callback(self.getCommand(), self);
event.preventDefault();
});
}
else if (self.isSelect()) {
self.$el.find("select").change(function () {
callback(self.getCommand(), self);
});
}
};
var padeditbar = (function()
{
var syncAnimation = (function()
{
var SYNCING = -100;
var DONE = 100;
var state = DONE;
var fps = 25;
var step = 1 / fps;
var T_START = -0.5;
var T_FADE = 1.0;
var T_GONE = 1.5;
var animator = padutils.makeAnimationScheduler(function()
{
if (state == SYNCING || state == DONE)
{
return false;
}
else if (state >= T_GONE)
{
state = DONE;
$("#syncstatussyncing").css('display', 'none');
$("#syncstatusdone").css('display', 'none');
return false;
}
else if (state < 0)
{
state += step;
if (state >= 0)
{
$("#syncstatussyncing").css('display', 'none');
$("#syncstatusdone").css('display', 'block').css('opacity', 1);
}
return true;
}
else
{
state += step;
if (state >= T_FADE)
{
$("#syncstatusdone").css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
}
return true;
}
}, step * 1000);
return {
syncing: function()
{
state = SYNCING;
$("#syncstatussyncing").css('display', 'block');
$("#syncstatusdone").css('display', 'none');
},
done: function()
{
state = T_START;
animator.scheduleAnimation();
}
};
}());
var self = {
init: function() {
var self = this;
self.dropdowns = [];
// Listen for resize events (sucks but needed as iFrame ace_inner has to be position absolute
// A CSS fix for this would be nice but I'm not sure how we'd do it.
$(window).resize(function(){
self.redrawHeight();
});
$("#editbar .editbarbutton").attr("unselectable", "on"); // for IE
$("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
$("#editbar [data-key]").each(function () {
$(this).unbind("click");
(new ToolbarItem($(this))).bind(function (command, item) {
self.triggerCommand(command, item);
});
});
$('body:not(#editorcontainerbox)').on("keydown", function(evt){
bodyKeyEvent(evt);
});
$('#editbar').show();
this.redrawHeight();
registerDefaultCommands(self);
hooks.callAll("postToolbarInit", {
toolbar: self,
ace: padeditor.ace
});
},
isEnabled: function()
{
// return !$("#editbar").hasClass('disabledtoolbar');
return true;
},
disable: function()
{
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
},
commands: {},
registerCommand: function (cmd, callback) {
this.commands[cmd] = callback;
return this;
},
redrawHeight: function(){
var editbarHeight = $('.menu_left').height() + 1 + "px";
var containerTop = $('.menu_left').height() + 6 + "px";
$('#editbar').css("height", editbarHeight);
$('#editorcontainer').css("top", containerTop);
// make sure pop ups are in the right place
if($('#editorcontainer').offset()){
$('.popup').css("top", $('#editorcontainer').offset().top + "px");
}
// If sticky chat is enabled..
if($('#options-stickychat').is(":checked")){
if($('#editorcontainer').offset()){
$('#chatbox').css("top", $('#editorcontainer').offset().top + "px");
}
};
// If chat and Users is enabled..
if($('#options-chatandusers').is(":checked")){
if($('#editorcontainer').offset()){
$('#users').css("top", $('#editorcontainer').offset().top + "px");
}
}
},
registerDropdownCommand: function (cmd, dropdown) {
dropdown = dropdown || cmd;
self.dropdowns.push(dropdown)
this.registerCommand(cmd, function () {
self.toggleDropDown(dropdown);
});
},
registerAceCommand: function (cmd, callback) {
this.registerCommand(cmd, function (cmd, ace) {
ace.callWithAce(function (ace) {
callback(cmd, ace);
}, cmd, true);
});
},
triggerCommand: function (cmd, item) {
if (self.isEnabled() && this.commands[cmd]) {
this.commands[cmd](cmd, padeditor.ace, item);
}
if(padeditor.ace) padeditor.ace.focus();
},
toggleDropDown: function(moduleName, cb)
{
// hide all modules and remove highlighting of all buttons
if(moduleName == "none")
{
var returned = false
for(var i=0;i<self.dropdowns.length;i++)
{
//skip the userlist
if(self.dropdowns[i] == "users")
continue;
var module = $("#" + self.dropdowns[i]);
if(module.css('display') != "none")
{
$("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected");
module.slideUp("fast", cb);
returned = true;
}
}
if(!returned && cb) return cb();
}
else
{
// hide all modules that are not selected and remove highlighting
// respectively add highlighting to the corresponding button
for(var i=0;i<self.dropdowns.length;i++)
{
var module = $("#" + self.dropdowns[i]);
if(module.css('display') != "none")
{
$("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected");
module.slideUp("fast");
}
else if(self.dropdowns[i]==moduleName)
{
$("li[data-key=" + self.dropdowns[i] + "] > a").addClass("selected");
module.slideDown("fast", cb);
}
}
}
},
setSyncStatus: function(status)
{
if (status == "syncing")
{
syncAnimation.syncing();
}
else if (status == "done")
{
syncAnimation.done();
}
},
setEmbedLinks: function()
{
if ($('#readonlyinput').is(':checked'))
{
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
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></iframe>");
$('#linkinput').val(readonlyLink);
}
else
{
var padurl = window.location.href.split("?")[0];
$('#embedinput').val("<iframe name='embed_readwrite' src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400></iframe>");
$('#linkinput').val(padurl);
}
}
};
var editbarPosition = 0;
function bodyKeyEvent(evt){
// If the event is Alt F9 or Escape & we're already in the editbar menu
// Send the users focus back to the pad
if((evt.keyCode === 120 && evt.altKey) || evt.keyCode === 27){
if($(':focus').parents(".toolbar").length === 1){
// If we're in the editbar already..
// Close any dropdowns we have open..
padeditbar.toggleDropDown("none");
// Check we're on a pad and not on the timeslider
// Or some other window I haven't thought about!
if(typeof pad === 'undefined'){
// Timeslider probably..
// Shift focus away from any drop downs
$(':focus').blur(); // required to do not try to remove!
$('#padmain').focus(); // Focus back onto the pad
}else{
// Shift focus away from any drop downs
$(':focus').blur(); // required to do not try to remove!
padeditor.ace.focus(); // Sends focus back to pad
// The above focus doesn't always work in FF, you have to hit enter afterwards
evt.preventDefault();
}
}else{
// Shift focus away from any drop downs
$(':focus').blur(); // required to do not try to remove!
padeditor.ace.focus(); // Sends focus back to pad
// The above focus doesn't always work in FF, you have to hit enter afterwards
// Focus on the editbar :)
var firstEditbarElement = parent.parent.$('#editbar').children("ul").first().children().first().children().first().children().first();
$(this).blur();
firstEditbarElement.focus();
evt.preventDefault();
}
}else{
// Focus on the editbar :)
var firstEditbarElement = parent.parent.$('#editbar').children("ul").first().children().first().children().first().children().first();
$(this).blur();
firstEditbarElement.focus();
evt.preventDefault();
}
}
// Are we in the toolbar??
if($(':focus').parents(".toolbar").length === 1){
// On arrow keys go to next/previous button item in editbar
if(evt.keyCode !== 39 && evt.keyCode !== 37) return;
// Are we in the toolbar??
if($(':focus').parents(".toolbar").length === 1){
// On arrow keys go to next/previous button item in editbar
if(evt.keyCode !== 39 && evt.keyCode !== 37) return;
// Get all the focusable items in the editbar
var focusItems = $('#editbar').find('button, select');
// Get all the focusable items in the editbar
var focusItems = $('#editbar').find('button, select');
// On left arrow move to next button in editbar
if(evt.keyCode === 37){
// If a dropdown is visible or we're in an input don't move to the next button
if($('.popup').is(":visible") || evt.target.localName === "input") return;
// On left arrow move to next button in editbar
if(evt.keyCode === 37){
// If a dropdown is visible or we're in an input don't move to the next button
if($('.popup').is(":visible") || evt.target.localName === "input") return;
editbarPosition--;
// Allow focus to shift back to end of row and start of row
if(editbarPosition === -1) editbarPosition = focusItems.length -1;
$(focusItems[editbarPosition]).focus()
}
// On right arrow move to next button in editbar
if(evt.keyCode === 39){
// If a dropdown is visible or we're in an input don't move to the next button
if($('.popup').is(":visible") || evt.target.localName === "input") return;
editbarPosition++;
// Allow focus to shift back to end of row and start of row
if(editbarPosition >= focusItems.length) editbarPosition = 0;
$(focusItems[editbarPosition]).focus();
}
}
}
function aceAttributeCommand(cmd, ace) {
ace.ace_toggleAttributeOnSelection(cmd);
}
function registerDefaultCommands(toolbar) {
toolbar.registerDropdownCommand("showusers", "users");
toolbar.registerDropdownCommand("settings");
toolbar.registerDropdownCommand("connectivity");
toolbar.registerDropdownCommand("import_export");
toolbar.registerDropdownCommand("embed");
toolbar.registerCommand("settings", function () {
toolbar.toggleDropDown("settings", function(){
$('#options-stickychat').focus();
});
});
toolbar.registerCommand("import_export", function () {
toolbar.toggleDropDown("import_export", function(){
// If Import file input exists then focus on it..
if($('#importfileinput').length !== 0){
setTimeout(function(){
$('#importfileinput').focus();
}, 100);
}else{
$('.exportlink').first().focus();
editbarPosition--;
// Allow focus to shift back to end of row and start of row
if(editbarPosition === -1) editbarPosition = focusItems.length -1;
$(focusItems[editbarPosition]).focus()
}
// On right arrow move to next button in editbar
if(evt.keyCode === 39){
// If a dropdown is visible or we're in an input don't move to the next button
if($('.popup').is(":visible") || evt.target.localName === "input") return;
editbarPosition++;
// Allow focus to shift back to end of row and start of row
if(editbarPosition >= focusItems.length) editbarPosition = 0;
$(focusItems[editbarPosition]).focus();
}
}
}
function aceAttributeCommand(cmd, ace) {
ace.ace_toggleAttributeOnSelection(cmd);
}
function registerDefaultCommands(toolbar) {
toolbar.registerDropdownCommand("showusers", "users");
toolbar.registerDropdownCommand("settings");
toolbar.registerDropdownCommand("connectivity");
toolbar.registerDropdownCommand("import_export");
toolbar.registerDropdownCommand("embed");
toolbar.registerCommand("settings", function () {
toolbar.toggleDropDown("settings", function(){
$('#options-stickychat').focus();
});
});
});
toolbar.registerCommand("showusers", function () {
toolbar.toggleDropDown("users", function(){
$('#myusernameedit').focus();
toolbar.registerCommand("import_export", function () {
toolbar.toggleDropDown("import_export", function(){
// If Import file input exists then focus on it..
if($('#importfileinput').length !== 0){
setTimeout(function(){
$('#importfileinput').focus();
}, 100);
}else{
$('.exportlink').first().focus();
}
});
});
});
toolbar.registerCommand("embed", function () {
toolbar.setEmbedLinks();
toolbar.toggleDropDown("embed", function(){
$('#linkinput').focus().select();
toolbar.registerCommand("showusers", function () {
toolbar.toggleDropDown("users", function(){
$('#myusernameedit').focus();
});
});
});
toolbar.registerCommand("savedRevision", function () {
padsavedrevs.saveNow();
});
toolbar.registerCommand("embed", function () {
toolbar.setEmbedLinks();
toolbar.toggleDropDown("embed", function(){
$('#linkinput').focus().select();
});
});
toolbar.registerCommand("showTimeSlider", function () {
document.location = document.location.pathname+ '/timeslider';
});
toolbar.registerCommand("savedRevision", function () {
padsavedrevs.saveNow();
});
toolbar.registerAceCommand("bold", aceAttributeCommand);
toolbar.registerAceCommand("italic", aceAttributeCommand);
toolbar.registerAceCommand("underline", aceAttributeCommand);
toolbar.registerAceCommand("strikethrough", aceAttributeCommand);
toolbar.registerCommand("showTimeSlider", function () {
document.location = document.location.pathname+ '/timeslider';
});
toolbar.registerAceCommand("undo", function (cmd, ace) {
ace.ace_doUndoRedo(cmd);
});
toolbar.registerAceCommand("bold", aceAttributeCommand);
toolbar.registerAceCommand("italic", aceAttributeCommand);
toolbar.registerAceCommand("underline", aceAttributeCommand);
toolbar.registerAceCommand("strikethrough", aceAttributeCommand);
toolbar.registerAceCommand("redo", function (cmd, ace) {
ace.ace_doUndoRedo(cmd);
});
toolbar.registerAceCommand("undo", function (cmd, ace) {
ace.ace_doUndoRedo(cmd);
});
toolbar.registerAceCommand("insertunorderedlist", function (cmd, ace) {
ace.ace_doInsertUnorderedList();
});
toolbar.registerAceCommand("redo", function (cmd, ace) {
ace.ace_doUndoRedo(cmd);
});
toolbar.registerAceCommand("insertorderedlist", function (cmd, ace) {
ace.ace_doInsertOrderedList();
});
toolbar.registerAceCommand("indent", function (cmd, ace) {
if (!ace.ace_doIndentOutdent(false)) {
toolbar.registerAceCommand("insertunorderedlist", function (cmd, ace) {
ace.ace_doInsertUnorderedList();
}
});
});
toolbar.registerAceCommand("outdent", function (cmd, ace) {
ace.ace_doIndentOutdent(true);
});
toolbar.registerAceCommand("insertorderedlist", function (cmd, ace) {
ace.ace_doInsertOrderedList();
});
toolbar.registerAceCommand("clearauthorship", function (cmd, ace) {
if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) {
if (window.confirm(html10n.get("pad.editbar.clearcolors"))) {
ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [
['author', '']
]);
toolbar.registerAceCommand("indent", function (cmd, ace) {
if (!ace.ace_doIndentOutdent(false)) {
ace.ace_doInsertUnorderedList();
}
}
else {
ace.ace_setAttributeOnSelection('author', '');
}
});
});
toolbar.registerCommand('timeslider_returnToPad', function(cmd) {
if( document.referrer.length > 0 && document.referrer.substring(document.referrer.lastIndexOf("/")-1, document.referrer.lastIndexOf("/")) === "p") {
document.location = document.referrer;
} else {
document.location = document.location.href.substring(0,document.location.href.lastIndexOf("/"));
}
});
}
toolbar.registerAceCommand("outdent", function (cmd, ace) {
ace.ace_doIndentOutdent(true);
});
return self;
}());
toolbar.registerAceCommand("clearauthorship", function (cmd, ace) {
if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) {
if (window.confirm(html10n.get("pad.editbar.clearcolors"))) {
ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [
['author', '']
]);
}
}
else {
ace.ace_setAttributeOnSelection('author', '');
}
});
exports.padeditbar = padeditbar;
toolbar.registerCommand('timeslider_returnToPad', function(cmd) {
if( document.referrer.length > 0 && document.referrer.substring(document.referrer.lastIndexOf("/")-1, document.referrer.lastIndexOf("/")) === "p") {
document.location = document.referrer;
} else {
document.location = document.location.href.substring(0,document.location.href.lastIndexOf("/"));
}
});
}
return self;
}());
exports.padeditbar = padeditbar;
return exports;
});

View File

@ -20,203 +20,212 @@
* limitations under the License.
*/
var padcookie = require('./pad_cookie').padcookie;
var padutils = require('./pad_utils').padutils;
define([
'ep_etherpad-lite/static/js/pad_cookie',
'ep_etherpad-lite/static/js/pad_utils'
], function (padCookieModule, padUtilsModule) {
exports = {};
var padeditor = (function()
{
var Ace2Editor = undefined;
var pad = undefined;
var settings = undefined;
var padcookie = padCookieModule.padcookie;
var padutils = padUtilsModule.padutils;
// Array of available fonts
var fonts = ['useMonospaceFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', 'useGeorgiaFont', 'useImpactFont',
'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useTahomaFont', 'useTimesNewRomanFont',
'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', 'useWingDingsFont', 'useSansSerifFont',
'useSerifFont'];
var padeditor = (function()
{
var Ace2Editor = undefined;
var pad = undefined;
var settings = undefined;
var self = {
ace: null,
// this is accessed directly from other files
viewZoom: 100,
init: function(readyFunc, initialViewOptions, _pad) {
requirejs(['ep_etherpad-lite/static/js/ace'], function (ace) {
// Array of available fonts
var fonts = ['useMonospaceFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', 'useGeorgiaFont', 'useImpactFont',
'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useTahomaFont', 'useTimesNewRomanFont',
'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', 'useWingDingsFont', 'useSansSerifFont',
'useSerifFont'];
Ace2Editor = ace.Ace2Editor;
pad = _pad;
settings = pad.settings;
var self = {
ace: null,
// this is accessed directly from other files
viewZoom: 100,
init: function(readyFunc, initialViewOptions, _pad) {
requirejs(['ep_etherpad-lite/static/js/ace'], function (ace) {
function aceReady()
{
$("#editorloadingbox").hide();
if (readyFunc)
Ace2Editor = ace.Ace2Editor;
pad = _pad;
settings = pad.settings;
function aceReady()
{
readyFunc();
$("#editorloadingbox").hide();
if (readyFunc)
{
readyFunc();
}
}
}
self.ace = new Ace2Editor();
self.ace.init("editorcontainer", "", aceReady);
self.ace.setProperty("wraps", true);
if (pad.getIsDebugEnabled())
self.ace = new Ace2Editor();
self.ace.init("editorcontainer", "", aceReady);
self.ace.setProperty("wraps", true);
if (pad.getIsDebugEnabled())
{
self.ace.setProperty("dmesg", pad.dmesg);
}
self.initViewOptions();
self.setViewOptions(initialViewOptions);
// view bar
$("#viewbarcontents").show();
});
},
initViewOptions: function()
{
// Line numbers
padutils.bindCheckboxChange($("#options-linenoscheck"), function()
{
self.ace.setProperty("dmesg", pad.dmesg);
}
self.initViewOptions();
self.setViewOptions(initialViewOptions);
// view bar
$("#viewbarcontents").show();
});
},
initViewOptions: function()
{
// Line numbers
padutils.bindCheckboxChange($("#options-linenoscheck"), function()
{
pad.changeViewOption('showLineNumbers', padutils.getCheckbox($("#options-linenoscheck")));
});
// Author colors
padutils.bindCheckboxChange($("#options-colorscheck"), function()
{
padcookie.setPref('showAuthorshipColors', padutils.getCheckbox("#options-colorscheck"));
pad.changeViewOption('showAuthorColors', padutils.getCheckbox("#options-colorscheck"));
});
// Right to left
padutils.bindCheckboxChange($("#options-rtlcheck"), function()
{
pad.changeViewOption('rtlIsTrue', padutils.getCheckbox($("#options-rtlcheck")))
});
html10n.bind('localized', function() {
pad.changeViewOption('rtlIsTrue', ('rtl' == html10n.getDirection()));
padutils.setCheckbox($("#options-rtlcheck"), ('rtl' == html10n.getDirection()));
})
// font family change
$("#viewfontmenu").change(function()
{
$.each(fonts, function(i, font){
var sfont = font.replace("use","");
sfont = sfont.replace("Font","");
sfont = sfont.toLowerCase();
pad.changeViewOption(font, $("#viewfontmenu").val() == sfont);
pad.changeViewOption('showLineNumbers', padutils.getCheckbox($("#options-linenoscheck")));
});
});
// Language
html10n.bind('localized', function() {
// Author colors
padutils.bindCheckboxChange($("#options-colorscheck"), function()
{
padcookie.setPref('showAuthorshipColors', padutils.getCheckbox("#options-colorscheck"));
pad.changeViewOption('showAuthorColors', padutils.getCheckbox("#options-colorscheck"));
});
// Right to left
padutils.bindCheckboxChange($("#options-rtlcheck"), function()
{
pad.changeViewOption('rtlIsTrue', padutils.getCheckbox($("#options-rtlcheck")))
});
html10n.bind('localized', function() {
pad.changeViewOption('rtlIsTrue', ('rtl' == html10n.getDirection()));
padutils.setCheckbox($("#options-rtlcheck"), ('rtl' == html10n.getDirection()));
})
// font family change
$("#viewfontmenu").change(function()
{
$.each(fonts, function(i, font){
var sfont = font.replace("use","");
sfont = sfont.replace("Font","");
sfont = sfont.toLowerCase();
pad.changeViewOption(font, $("#viewfontmenu").val() == sfont);
});
});
// Language
html10n.bind('localized', function() {
$("#languagemenu").val(html10n.getLanguage());
// translate the value of 'unnamed' and 'Enter your name' textboxes in the userlist
// this does not interfere with html10n's normal value-setting because html10n just ingores <input>s
// also, a value which has been set by the user will be not overwritten since a user-edited <input>
// does *not* have the editempty-class
$('input[data-l10n-id]').each(function(key, input){
input = $(input);
if(input.hasClass("editempty")){
input.val(html10n.get(input.attr("data-l10n-id")));
}
});
})
$("#languagemenu").val(html10n.getLanguage());
// translate the value of 'unnamed' and 'Enter your name' textboxes in the userlist
// this does not interfere with html10n's normal value-setting because html10n just ingores <input>s
// also, a value which has been set by the user will be not overwritten since a user-edited <input>
// does *not* have the editempty-class
$('input[data-l10n-id]').each(function(key, input){
input = $(input);
if(input.hasClass("editempty")){
input.val(html10n.get(input.attr("data-l10n-id")));
$("#languagemenu").change(function() {
pad.createCookie("language",$("#languagemenu").val(),null,'/');
window.html10n.localize([$("#languagemenu").val(), 'en']);
});
},
setViewOptions: function(newOptions)
{
function getOption(key, defaultValue)
{
var value = String(newOptions[key]);
if (value == "true") return true;
if (value == "false") return false;
return defaultValue;
}
var v;
v = getOption('rtlIsTrue', ('rtl' == html10n.getDirection()));
// Override from parameters if true
if(settings.rtlIsTrue === true) v = true;
self.ace.setProperty("rtlIsTrue", v);
padutils.setCheckbox($("#options-rtlcheck"), v);
v = getOption('showLineNumbers', true);
self.ace.setProperty("showslinenumbers", v);
padutils.setCheckbox($("#options-linenoscheck"), v);
v = getOption('showAuthorColors', true);
self.ace.setProperty("showsauthorcolors", v);
padutils.setCheckbox($("#options-colorscheck"), v);
// Override from parameters if true
if (settings.noColors !== false){
self.ace.setProperty("showsauthorcolors", !settings.noColors);
}
var normalFont = true;
// Go through each font and see if the option is set..
$.each(fonts, function(i, font){
var isEnabled = getOption(font, false);
if(isEnabled){
font = font.replace("use","");
font = font.replace("Font","");
font = font.toLowerCase();
if(font === "monospace") self.ace.setProperty("textface", "Courier new");
if(font === "opendyslexic") self.ace.setProperty("textface", "OpenDyslexic");
if(font === "comicsans") self.ace.setProperty("textface", "Comic Sans MS");
if(font === "georgia") self.ace.setProperty("textface", "Georgia");
if(font === "impact") self.ace.setProperty("textface", "Impact");
if(font === "lucida") self.ace.setProperty("textface", "Lucida");
if(font === "lucidasans") self.ace.setProperty("textface", "Lucida Sans Unicode");
if(font === "palatino") self.ace.setProperty("textface", "Palatino Linotype");
if(font === "tahoma") self.ace.setProperty("textface", "Tahoma");
if(font === "timesnewroman") self.ace.setProperty("textface", "Times New Roman");
if(font === "trebuchet") self.ace.setProperty("textface", "Trebuchet MS");
if(font === "verdana") self.ace.setProperty("textface", "Verdana");
if(font === "symbol") self.ace.setProperty("textface", "Symbol");
if(font === "webdings") self.ace.setProperty("textface", "Webdings");
if(font === "wingdings") self.ace.setProperty("textface", "Wingdings");
if(font === "sansserif") self.ace.setProperty("textface", "MS Sans Serif");
if(font === "serif") self.ace.setProperty("textface", "MS Serif");
// $("#viewfontmenu").val(font);
normalFont = false;
}
});
})
$("#languagemenu").val(html10n.getLanguage());
$("#languagemenu").change(function() {
pad.createCookie("language",$("#languagemenu").val(),null,'/');
window.html10n.localize([$("#languagemenu").val(), 'en']);
});
},
setViewOptions: function(newOptions)
{
function getOption(key, defaultValue)
{
var value = String(newOptions[key]);
if (value == "true") return true;
if (value == "false") return false;
return defaultValue;
}
var v;
v = getOption('rtlIsTrue', ('rtl' == html10n.getDirection()));
// Override from parameters if true
if(settings.rtlIsTrue === true) v = true;
self.ace.setProperty("rtlIsTrue", v);
padutils.setCheckbox($("#options-rtlcheck"), v);
v = getOption('showLineNumbers', true);
self.ace.setProperty("showslinenumbers", v);
padutils.setCheckbox($("#options-linenoscheck"), v);
v = getOption('showAuthorColors', true);
self.ace.setProperty("showsauthorcolors", v);
padutils.setCheckbox($("#options-colorscheck"), v);
// Override from parameters if true
if (settings.noColors !== false){
self.ace.setProperty("showsauthorcolors", !settings.noColors);
}
var normalFont = true;
// Go through each font and see if the option is set..
$.each(fonts, function(i, font){
var isEnabled = getOption(font, false);
if(isEnabled){
font = font.replace("use","");
font = font.replace("Font","");
font = font.toLowerCase();
if(font === "monospace") self.ace.setProperty("textface", "Courier new");
if(font === "opendyslexic") self.ace.setProperty("textface", "OpenDyslexic");
if(font === "comicsans") self.ace.setProperty("textface", "Comic Sans MS");
if(font === "georgia") self.ace.setProperty("textface", "Georgia");
if(font === "impact") self.ace.setProperty("textface", "Impact");
if(font === "lucida") self.ace.setProperty("textface", "Lucida");
if(font === "lucidasans") self.ace.setProperty("textface", "Lucida Sans Unicode");
if(font === "palatino") self.ace.setProperty("textface", "Palatino Linotype");
if(font === "tahoma") self.ace.setProperty("textface", "Tahoma");
if(font === "timesnewroman") self.ace.setProperty("textface", "Times New Roman");
if(font === "trebuchet") self.ace.setProperty("textface", "Trebuchet MS");
if(font === "verdana") self.ace.setProperty("textface", "Verdana");
if(font === "symbol") self.ace.setProperty("textface", "Symbol");
if(font === "webdings") self.ace.setProperty("textface", "Webdings");
if(font === "wingdings") self.ace.setProperty("textface", "Wingdings");
if(font === "sansserif") self.ace.setProperty("textface", "MS Sans Serif");
if(font === "serif") self.ace.setProperty("textface", "MS Serif");
// $("#viewfontmenu").val(font);
normalFont = false;
// No font has been previously selected so use the Normal font
if(normalFont){
self.ace.setProperty("textface", "Arial, sans-serif");
// $("#viewfontmenu").val("normal");
}
});
// No font has been previously selected so use the Normal font
if(normalFont){
self.ace.setProperty("textface", "Arial, sans-serif");
// $("#viewfontmenu").val("normal");
}
},
dispose: function()
{
if (self.ace)
},
dispose: function()
{
self.ace.destroy();
self.ace = null;
}
},
disable: function()
{
if (self.ace)
if (self.ace)
{
self.ace.destroy();
self.ace = null;
}
},
disable: function()
{
self.ace.setProperty("grayedOut", true);
self.ace.setEditable(false);
if (self.ace)
{
self.ace.setProperty("grayedOut", true);
self.ace.setEditable(false);
}
},
restoreRevisionText: function(dataFromServer)
{
pad.addHistoricalAuthors(dataFromServer.historicalAuthorData);
self.ace.importAText(dataFromServer.atext, dataFromServer.apool, true);
}
},
restoreRevisionText: function(dataFromServer)
{
pad.addHistoricalAuthors(dataFromServer.historicalAuthorData);
self.ace.importAText(dataFromServer.atext, dataFromServer.apool, true);
}
};
return self;
}());
};
return self;
}());
exports.padeditor = padeditor;
exports.padeditor = padeditor;
return exports;
});

View File

@ -20,32 +20,40 @@
* limitations under the License.
*/
var padeditbar = require('./pad_editbar').padeditbar;
define([
'ep_etherpad-lite/static/js/pad_editbar'
], function (padEditbarModule) {
var exports = {};
var padmodals = (function()
{
var pad = undefined;
var self = {
init: function(_pad)
{
pad = _pad;
},
showModal: function(messageId)
{
padeditbar.toggleDropDown("none", function() {
$("#connectivity .visible").removeClass('visible');
$("#connectivity ."+messageId).addClass('visible');
padeditbar.toggleDropDown("connectivity");
});
},
showOverlay: function() {
$("#overlay").show();
},
hideOverlay: function() {
$("#overlay").hide();
}
};
return self;
}());
var padeditbar = padEditbarModule.padeditbar;
exports.padmodals = padmodals;
var padmodals = (function()
{
var pad = undefined;
var self = {
init: function(_pad)
{
pad = _pad;
},
showModal: function(messageId)
{
padeditbar.toggleDropDown("none", function() {
$("#connectivity .visible").removeClass('visible');
$("#connectivity ."+messageId).addClass('visible');
padeditbar.toggleDropDown("connectivity");
});
},
showOverlay: function() {
$("#overlay").show();
},
hideOverlay: function() {
$("#overlay").hide();
}
};
return self;
}());
exports.padmodals = padmodals;
return exports;
});

View File

@ -14,22 +14,27 @@
* limitations under the License.
*/
var pad;
define([], function() {
var exports = {};
var pad;
exports.saveNow = function(){
pad.collabClient.sendMessage({"type": "SAVE_REVISION"});
$.gritter.add({
// (string | mandatory) the heading of the notification
title: _("pad.savedrevs.marked"),
// (string | mandatory) the text inside the notification
text: _("pad.savedrevs.timeslider") || "You can view saved revisions in the timeslider",
// (bool | optional) if you want it to fade out on its own or just sit there
sticky: false,
// (int | optional) the time you want it to be alive for before fading out
time: '2000'
});
}
exports.saveNow = function(){
pad.collabClient.sendMessage({"type": "SAVE_REVISION"});
$.gritter.add({
// (string | mandatory) the heading of the notification
title: _("pad.savedrevs.marked"),
// (string | mandatory) the text inside the notification
text: _("pad.savedrevs.timeslider") || "You can view saved revisions in the timeslider",
// (bool | optional) if you want it to fade out on its own or just sit there
sticky: false,
// (int | optional) the time you want it to be alive for before fading out
time: '2000'
});
}
exports.init = function(_pad){
pad = _pad;
}
exports.init = function(_pad){
pad = _pad;
}
return exports;
});

File diff suppressed because it is too large Load Diff

View File

@ -20,528 +20,517 @@
* limitations under the License.
*/
var Security = require('./security');
define(['ep_etherpad-lite/static/js/pad', 'ep_etherpad-lite/static/js/random_utils'], function(padModule, random_utils) {
var exports = {};
/**
* Generates a random String with the given length. Is needed to generate the Author, Group, readonly, session Ids
*/
var Security = window.requireKernel('./security');
function randomString(len)
{
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var randomstring = '';
len = len || 20
for (var i = 0; i < len; i++)
{
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
function createCookie(name, value, days, path){ /* Used by IE */
if (days)
{
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
}
else{
var expires = "";
}
if(!path){ // IF the Path of the cookie isn't set then just create it on root
path = "/";
}
//Check if the browser is IE and if so make sure the full path is set in the cookie
if((navigator.appName == 'Microsoft Internet Explorer') || ((navigator.appName == 'Netscape') && (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null))){
document.cookie = name + "=" + value + expires + "; path=/"; /* Note this bodge fix for IE is temporary until auth is rewritten */
}
else{
document.cookie = name + "=" + value + expires + "; path=" + path;
}
}
function readCookie(name)
{
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++)
{
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
var padutils = {
escapeHtml: function(x)
{
return Security.escapeHTML(String(x));
},
uniqueId: function()
{
var pad = require('./pad').pad; // Sidestep circular dependency
function encodeNum(n, width)
function createCookie(name, value, days, path){ /* Used by IE */
if (days)
{
// returns string that is exactly 'width' chars, padding with zeros
// and taking rightmost digits
return (Array(width + 1).join('0') + Number(n).toString(35)).slice(-width);
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
}
else{
var expires = "";
}
return [pad.getClientIp(), encodeNum(+new Date, 7), encodeNum(Math.floor(Math.random() * 1e9), 4)].join('.');
},
uaDisplay: function(ua)
{
var m;
function clean(a)
if(!path){ // IF the Path of the cookie isn't set then just create it on root
path = "/";
}
//Check if the browser is IE and if so make sure the full path is set in the cookie
if((navigator.appName == 'Microsoft Internet Explorer') || ((navigator.appName == 'Netscape') && (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null))){
document.cookie = name + "=" + value + expires + "; path=/"; /* Note this bodge fix for IE is temporary until auth is rewritten */
}
else{
document.cookie = name + "=" + value + expires + "; path=" + path;
}
}
function readCookie(name)
{
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++)
{
var maxlen = 16;
a = a.replace(/[^a-zA-Z0-9\.]/g, '');
if (a.length > maxlen)
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
var padutils = {
escapeHtml: function(x)
{
return Security.escapeHTML(String(x));
},
uniqueId: function()
{
var pad = padModule.pad; // Sidestep circular dependency
function encodeNum(n, width)
{
a = a.substr(0, maxlen);
// returns string that is exactly 'width' chars, padding with zeros
// and taking rightmost digits
return (Array(width + 1).join('0') + Number(n).toString(35)).slice(-width);
}
return a;
}
function checkver(name)
return [pad.getClientIp(), encodeNum(+new Date, 7), encodeNum(Math.floor(Math.random() * 1e9), 4)].join('.');
},
uaDisplay: function(ua)
{
var m = ua.match(RegExp(name + '\\/([\\d\\.]+)'));
var m;
function clean(a)
{
var maxlen = 16;
a = a.replace(/[^a-zA-Z0-9\.]/g, '');
if (a.length > maxlen)
{
a = a.substr(0, maxlen);
}
return a;
}
function checkver(name)
{
var m = ua.match(RegExp(name + '\\/([\\d\\.]+)'));
if (m && m.length > 1)
{
return clean(name + m[1]);
}
return null;
}
// firefox
if (checkver('Firefox'))
{
return checkver('Firefox');
}
// misc browsers, including IE
m = ua.match(/compatible; ([^;]+);/);
if (m && m.length > 1)
{
return clean(name + m[1]);
}
return null;
}
// firefox
if (checkver('Firefox'))
{
return checkver('Firefox');
}
// misc browsers, including IE
m = ua.match(/compatible; ([^;]+);/);
if (m && m.length > 1)
{
return clean(m[1]);
}
// iphone
if (ua.match(/\(iPhone;/))
{
return 'iPhone';
}
// chrome
if (checkver('Chrome'))
{
return checkver('Chrome');
}
// safari
m = ua.match(/Safari\/[\d\.]+/);
if (m)
{
var v = '?';
m = ua.match(/Version\/([\d\.]+)/);
if (m && m.length > 1)
{
v = m[1];
}
return clean('Safari' + v);
}
// everything else
var x = ua.split(' ')[0];
return clean(x);
},
// e.g. "Thu Jun 18 2009 13:09"
simpleDateTime: function(date)
{
var d = new Date(+date); // accept either number or date
var dayOfWeek = (['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'])[d.getDay()];
var month = (['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])[d.getMonth()];
var dayOfMonth = d.getDate();
var year = d.getFullYear();
var hourmin = d.getHours() + ":" + ("0" + d.getMinutes()).slice(-2);
return dayOfWeek + ' ' + month + ' ' + dayOfMonth + ' ' + year + ' ' + hourmin;
},
findURLs: function(text)
{
// copied from ACE
var _REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
var _REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/?=&#;()$]/.source + '|' + _REGEX_WORDCHAR.source + ')');
var _REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|nfs):\/\/|mailto:)/.source + _REGEX_URLCHAR.source + '*(?![:.,;])' + _REGEX_URLCHAR.source, 'g');
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
function _findURLs(text)
{
_REGEX_URL.lastIndex = 0;
var urls = null;
var execResult;
while ((execResult = _REGEX_URL.exec(text)))
{
urls = (urls || []);
var startIndex = execResult.index;
var url = execResult[0];
urls.push([startIndex, url]);
return clean(m[1]);
}
return urls;
}
return _findURLs(text);
},
escapeHtmlWithClickableLinks: function(text, target)
{
var idx = 0;
var pieces = [];
var urls = padutils.findURLs(text);
function advanceTo(i)
{
if (i > idx)
// iphone
if (ua.match(/\(iPhone;/))
{
pieces.push(Security.escapeHTML(text.substring(idx, i)));
idx = i;
return 'iPhone';
}
}
if (urls)
{
for (var j = 0; j < urls.length; j++)
{
var startIndex = urls[j][0];
var href = urls[j][1];
advanceTo(startIndex);
pieces.push('<a ', (target ? 'target="' + Security.escapeHTMLAttribute(target) + '" ' : ''), 'href="', Security.escapeHTMLAttribute(href), '">');
advanceTo(startIndex + href.length);
pieces.push('</a>');
}
}
advanceTo(text.length);
return pieces.join('');
},
bindEnterAndEscape: function(node, onEnter, onEscape)
{
// Use keypress instead of keyup in bindEnterAndEscape
// Keyup event is fired on enter in IME (Input Method Editor), But
// keypress is not. So, I changed to use keypress instead of keyup.
// It is work on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox 3.6.10, Chrome 6.0.472, Safari 5.0).
if (onEnter)
{
node.keypress(function(evt)
// chrome
if (checkver('Chrome'))
{
if (evt.which == 13)
return checkver('Chrome');
}
// safari
m = ua.match(/Safari\/[\d\.]+/);
if (m)
{
var v = '?';
m = ua.match(/Version\/([\d\.]+)/);
if (m && m.length > 1)
{
onEnter(evt);
v = m[1];
}
});
}
if (onEscape)
{
node.keydown(function(evt)
{
if (evt.which == 27)
{
onEscape(evt);
}
});
}
},
timediff: function(d)
{
var pad = require('./pad').pad; // Sidestep circular dependency
function format(n, word)
{
n = Math.round(n);
return ('' + n + ' ' + word + (n != 1 ? 's' : '') + ' ago');
}
d = Math.max(0, (+(new Date) - (+d) - pad.clientTimeOffset) / 1000);
if (d < 60)
{
return format(d, 'second');
}
d /= 60;
if (d < 60)
{
return format(d, 'minute');
}
d /= 60;
if (d < 24)
{
return format(d, 'hour');
}
d /= 24;
return format(d, 'day');
},
makeAnimationScheduler: function(funcToAnimateOneStep, stepTime, stepsAtOnce)
{
if (stepsAtOnce === undefined)
{
stepsAtOnce = 1;
}
var animationTimer = null;
function scheduleAnimation()
{
if (!animationTimer)
{
animationTimer = window.setTimeout(function()
{
animationTimer = null;
var n = stepsAtOnce;
var moreToDo = true;
while (moreToDo && n > 0)
{
moreToDo = funcToAnimateOneStep();
n--;
}
if (moreToDo)
{
// more to do
scheduleAnimation();
}
}, stepTime * stepsAtOnce);
return clean('Safari' + v);
}
}
return {
scheduleAnimation: scheduleAnimation
};
},
makeShowHideAnimator: function(funcToArriveAtState, initiallyShown, fps, totalMs)
{
var animationState = (initiallyShown ? 0 : -2); // -2 hidden, -1 to 0 fade in, 0 to 1 fade out
var animationFrameDelay = 1000 / fps;
var animationStep = animationFrameDelay / totalMs;
var scheduleAnimation = padutils.makeAnimationScheduler(animateOneStep, animationFrameDelay).scheduleAnimation;
function doShow()
// everything else
var x = ua.split(' ')[0];
return clean(x);
},
// e.g. "Thu Jun 18 2009 13:09"
simpleDateTime: function(date)
{
animationState = -1;
funcToArriveAtState(animationState);
scheduleAnimation();
}
var d = new Date(+date); // accept either number or date
var dayOfWeek = (['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'])[d.getDay()];
var month = (['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])[d.getMonth()];
var dayOfMonth = d.getDate();
var year = d.getFullYear();
var hourmin = d.getHours() + ":" + ("0" + d.getMinutes()).slice(-2);
return dayOfWeek + ' ' + month + ' ' + dayOfMonth + ' ' + year + ' ' + hourmin;
},
findURLs: function(text)
{
// copied from ACE
var _REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
var _REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/?=&#;()$]/.source + '|' + _REGEX_WORDCHAR.source + ')');
var _REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|nfs):\/\/|mailto:)/.source + _REGEX_URLCHAR.source + '*(?![:.,;])' + _REGEX_URLCHAR.source, 'g');
function doQuickShow()
{ // start showing without losing any fade-in progress
if (animationState < -1)
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
function _findURLs(text)
{
_REGEX_URL.lastIndex = 0;
var urls = null;
var execResult;
while ((execResult = _REGEX_URL.exec(text)))
{
urls = (urls || []);
var startIndex = execResult.index;
var url = execResult[0];
urls.push([startIndex, url]);
}
return urls;
}
return _findURLs(text);
},
escapeHtmlWithClickableLinks: function(text, target)
{
var idx = 0;
var pieces = [];
var urls = padutils.findURLs(text);
function advanceTo(i)
{
if (i > idx)
{
pieces.push(Security.escapeHTML(text.substring(idx, i)));
idx = i;
}
}
if (urls)
{
for (var j = 0; j < urls.length; j++)
{
var startIndex = urls[j][0];
var href = urls[j][1];
advanceTo(startIndex);
pieces.push('<a ', (target ? 'target="' + Security.escapeHTMLAttribute(target) + '" ' : ''), 'href="', Security.escapeHTMLAttribute(href), '">');
advanceTo(startIndex + href.length);
pieces.push('</a>');
}
}
advanceTo(text.length);
return pieces.join('');
},
bindEnterAndEscape: function(node, onEnter, onEscape)
{
// Use keypress instead of keyup in bindEnterAndEscape
// Keyup event is fired on enter in IME (Input Method Editor), But
// keypress is not. So, I changed to use keypress instead of keyup.
// It is work on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox 3.6.10, Chrome 6.0.472, Safari 5.0).
if (onEnter)
{
node.keypress(function(evt)
{
if (evt.which == 13)
{
onEnter(evt);
}
});
}
if (onEscape)
{
node.keydown(function(evt)
{
if (evt.which == 27)
{
onEscape(evt);
}
});
}
},
timediff: function(d)
{
var pad = padModule.pad; // Sidestep circular dependency
function format(n, word)
{
n = Math.round(n);
return ('' + n + ' ' + word + (n != 1 ? 's' : '') + ' ago');
}
d = Math.max(0, (+(new Date) - (+d) - pad.clientTimeOffset) / 1000);
if (d < 60)
{
return format(d, 'second');
}
d /= 60;
if (d < 60)
{
return format(d, 'minute');
}
d /= 60;
if (d < 24)
{
return format(d, 'hour');
}
d /= 24;
return format(d, 'day');
},
makeAnimationScheduler: function(funcToAnimateOneStep, stepTime, stepsAtOnce)
{
if (stepsAtOnce === undefined)
{
stepsAtOnce = 1;
}
var animationTimer = null;
function scheduleAnimation()
{
if (!animationTimer)
{
animationTimer = window.setTimeout(function()
{
animationTimer = null;
var n = stepsAtOnce;
var moreToDo = true;
while (moreToDo && n > 0)
{
moreToDo = funcToAnimateOneStep();
n--;
}
if (moreToDo)
{
// more to do
scheduleAnimation();
}
}, stepTime * stepsAtOnce);
}
}
return {
scheduleAnimation: scheduleAnimation
};
},
makeShowHideAnimator: function(funcToArriveAtState, initiallyShown, fps, totalMs)
{
var animationState = (initiallyShown ? 0 : -2); // -2 hidden, -1 to 0 fade in, 0 to 1 fade out
var animationFrameDelay = 1000 / fps;
var animationStep = animationFrameDelay / totalMs;
var scheduleAnimation = padutils.makeAnimationScheduler(animateOneStep, animationFrameDelay).scheduleAnimation;
function doShow()
{
animationState = -1;
}
else if (animationState <= 0)
{
animationState = animationState;
}
else
{
animationState = Math.max(-1, Math.min(0, -animationState));
}
funcToArriveAtState(animationState);
scheduleAnimation();
}
function doHide()
{
if (animationState >= -1 && animationState <= 0)
{
animationState = 1e-6;
funcToArriveAtState(animationState);
scheduleAnimation();
}
}
function animateOneStep()
{
if (animationState < -1 || animationState == 0)
{
return false;
}
else if (animationState < 0)
{
// animate show
animationState += animationStep;
if (animationState >= 0)
function doQuickShow()
{ // start showing without losing any fade-in progress
if (animationState < -1)
{
animationState = 0;
funcToArriveAtState(animationState);
return false;
animationState = -1;
}
else if (animationState <= 0)
{
animationState = animationState;
}
else
{
funcToArriveAtState(animationState);
return true;
animationState = Math.max(-1, Math.min(0, -animationState));
}
funcToArriveAtState(animationState);
scheduleAnimation();
}
function doHide()
{
if (animationState >= -1 && animationState <= 0)
{
animationState = 1e-6;
scheduleAnimation();
}
}
else if (animationState > 0)
function animateOneStep()
{
// animate hide
animationState += animationStep;
if (animationState >= 1)
if (animationState < -1 || animationState == 0)
{
animationState = 1;
funcToArriveAtState(animationState);
animationState = -2;
return false;
}
else
else if (animationState < 0)
{
funcToArriveAtState(animationState);
return true;
// animate show
animationState += animationStep;
if (animationState >= 0)
{
animationState = 0;
funcToArriveAtState(animationState);
return false;
}
else
{
funcToArriveAtState(animationState);
return true;
}
}
else if (animationState > 0)
{
// animate hide
animationState += animationStep;
if (animationState >= 1)
{
animationState = 1;
funcToArriveAtState(animationState);
animationState = -2;
return false;
}
else
{
funcToArriveAtState(animationState);
return true;
}
}
}
}
return {
show: doShow,
hide: doHide,
quickShow: doQuickShow
};
},
_nextActionId: 1,
uncanceledActions: {},
getCancellableAction: function(actionType, actionFunc)
{
var o = padutils.uncanceledActions[actionType];
if (!o)
return {
show: doShow,
hide: doHide,
quickShow: doQuickShow
};
},
_nextActionId: 1,
uncanceledActions: {},
getCancellableAction: function(actionType, actionFunc)
{
o = {};
padutils.uncanceledActions[actionType] = o;
}
var actionId = (padutils._nextActionId++);
o[actionId] = true;
return function()
{
var p = padutils.uncanceledActions[actionType];
if (p && p[actionId])
var o = padutils.uncanceledActions[actionType];
if (!o)
{
actionFunc();
o = {};
padutils.uncanceledActions[actionType] = o;
}
};
},
cancelActions: function(actionType)
{
var o = padutils.uncanceledActions[actionType];
if (o)
var actionId = (padutils._nextActionId++);
o[actionId] = true;
return function()
{
var p = padutils.uncanceledActions[actionType];
if (p && p[actionId])
{
actionFunc();
}
};
},
cancelActions: function(actionType)
{
// clear it
delete padutils.uncanceledActions[actionType];
}
},
makeFieldLabeledWhenEmpty: function(field, labelText)
{
field = $(field);
var o = padutils.uncanceledActions[actionType];
if (o)
{
// clear it
delete padutils.uncanceledActions[actionType];
}
},
makeFieldLabeledWhenEmpty: function(field, labelText)
{
field = $(field);
function clear()
{
field.addClass('editempty');
field.val(labelText);
}
field.focus(function()
{
if (field.hasClass('editempty'))
function clear()
{
field.val('');
field.addClass('editempty');
field.val(labelText);
}
field.removeClass('editempty');
});
field.blur(function()
{
if (!field.val())
field.focus(function()
{
clear();
}
});
return {
clear: clear
};
},
getCheckbox: function(node)
{
return $(node).is(':checked');
},
setCheckbox: function(node, value)
{
if (value)
{
$(node).attr('checked', 'checked');
}
else
{
$(node).removeAttr('checked');
}
},
bindCheckboxChange: function(node, func)
{
$(node).change(func);
},
encodeUserId: function(userId)
{
return userId.replace(/[^a-y0-9]/g, function(c)
{
if (c == ".") return "-";
return 'z' + c.charCodeAt(0) + 'z';
});
},
decodeUserId: function(encodedUserId)
{
return encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, function(cc)
{
if (cc == '-') return '.';
else if (cc.charAt(0) == 'z')
if (field.hasClass('editempty'))
{
field.val('');
}
field.removeClass('editempty');
});
field.blur(function()
{
return String.fromCharCode(Number(cc.slice(1, -1)));
if (!field.val())
{
clear();
}
});
return {
clear: clear
};
},
getCheckbox: function(node)
{
return $(node).is(':checked');
},
setCheckbox: function(node, value)
{
if (value)
{
$(node).attr('checked', 'checked');
}
else
{
return cc;
$(node).removeAttr('checked');
}
});
}
};
var globalExceptionHandler = undefined;
function setupGlobalExceptionHandler() {
if (!globalExceptionHandler) {
globalExceptionHandler = function test (msg, url, linenumber)
},
bindCheckboxChange: function(node, func)
{
var errorId = randomString(20);
var userAgent = padutils.escapeHtml(navigator.userAgent);
if ($("#editorloadingbox").attr("display") != "none"){
//show javascript errors to the user
$("#editorloadingbox").css("padding", "10px");
$("#editorloadingbox").css("padding-top", "45px");
$("#editorloadingbox").html("<div style='text-align:left;color:red;font-size:16px;'><b>An error occured</b><br>The error was reported with the following id: '" + errorId + "'<br><br><span style='color:black;font-weight:bold;font-size:16px'>Please press and hold Ctrl and press F5 to reload this page, if the problem persists please send this error message to your webmaster: </span><div style='color:black;font-size:14px'>'"
+ "ErrorId: " + errorId + "<br>URL: " + window.location.href + "<br>UserAgent: " + userAgent + "<br>" + msg + " in " + url + " at line " + linenumber + "'</div></div>");
}
$(node).change(func);
},
encodeUserId: function(userId)
{
return userId.replace(/[^a-y0-9]/g, function(c)
{
if (c == ".") return "-";
return 'z' + c.charCodeAt(0) + 'z';
});
},
decodeUserId: function(encodedUserId)
{
return encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, function(cc)
{
if (cc == '-') return '.';
else if (cc.charAt(0) == 'z')
{
return String.fromCharCode(Number(cc.slice(1, -1)));
}
else
{
return cc;
}
});
}
};
//send javascript errors to the server
var errObj = {errorInfo: JSON.stringify({errorId: errorId, msg: msg, url: window.location.href, linenumber: linenumber, userAgent: navigator.userAgent})};
var loc = document.location;
var url = loc.protocol + "//" + loc.hostname + ":" + loc.port + "/" + loc.pathname.substr(1, loc.pathname.indexOf("/p/")) + "jserror";
$.post(url, errObj);
return false;
};
window.onerror = globalExceptionHandler;
var globalExceptionHandler = undefined;
function setupGlobalExceptionHandler() {
if (!globalExceptionHandler) {
globalExceptionHandler = function test (msg, url, linenumber)
{
var errorId = random_utils.randomString(20);
var userAgent = padutils.escapeHtml(navigator.userAgent);
if ($("#editorloadingbox").attr("display") != "none"){
//show javascript errors to the user
$("#editorloadingbox").css("padding", "10px");
$("#editorloadingbox").css("padding-top", "45px");
$("#editorloadingbox").html("<div style='text-align:left;color:red;font-size:16px;'><b>An error occured</b><br>The error was reported with the following id: '" + errorId + "'<br><br><span style='color:black;font-weight:bold;font-size:16px'>Please press and hold Ctrl and press F5 to reload this page, if the problem persists please send this error message to your webmaster: </span><div style='color:black;font-size:14px'>'"
+ "ErrorId: " + errorId + "<br>URL: " + window.location.href + "<br>UserAgent: " + userAgent + "<br>" + msg + " in " + url + " at line " + linenumber + "'</div></div>");
}
//send javascript errors to the server
var errObj = {errorInfo: JSON.stringify({errorId: errorId, msg: msg, url: window.location.href, linenumber: linenumber, userAgent: navigator.userAgent})};
var loc = document.location;
var url = loc.protocol + "//" + loc.hostname + ":" + loc.port + "/" + loc.pathname.substr(1, loc.pathname.indexOf("/p/")) + "jserror";
$.post(url, errObj);
return false;
};
window.onerror = globalExceptionHandler;
}
}
}
padutils.setupGlobalExceptionHandler = setupGlobalExceptionHandler;
padutils.setupGlobalExceptionHandler = setupGlobalExceptionHandler;
padutils.binarySearch = require('./ace2_common').binarySearch;
padutils.binarySearch = require('./ace2_common').binarySearch;
exports.randomString = randomString;
exports.createCookie = createCookie;
exports.readCookie = readCookie;
exports.padutils = padutils;
exports.randomString = random_utils.randomString;
exports.createCookie = createCookie;
exports.readCookie = readCookie;
exports.padutils = padutils;
return exports;
});

View File

@ -82,6 +82,7 @@ exports.loadModule = function(path, cb) {
cb(require(path));
console.warn("Module uses old CommonJS format: " + path);
} catch (e) {
console.warn("Error loading CommonJS module: " + path + "\n" + e.toString());
requirejs([path], cb);
}
}

View File

@ -0,0 +1,44 @@
/**
* Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function defineRandomUtils(exports) {
if (exports == undefined) exports = {};
/**
* Generates a random String with the given length. Is needed to generate the Author, Group, readonly, session Ids
*/
exports.randomString = function(len)
{
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var randomstring = '';
len = len || 20
for (var i = 0; i < len; i++)
{
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
return exports;
}
if (typeof(define) != 'undefined' && define.amd != undefined && typeof(exports) == 'undefined') {
define([], defineRandomUtils);
} else {
defineRandomUtils(exports);
}

View File

@ -3,5 +3,7 @@
*/
define.amd.jQuery = true;
define(["ep_etherpad-lite/static/js/jquery"], function (dummy) {
return window.$.noConflict(true);
return window.$;
// Loading jQuery extensions won't work if you use noConflict :/
// return window.$.noConflict(true);
});

View File

@ -22,174 +22,184 @@
// These jQuery things should create local references, but for now `require()`
// assigns to the global `$` and augments it with plugins.
require('./jquery');
JSON = require('./json2');
var createCookie = require('./pad_utils').createCookie;
var readCookie = require('./pad_utils').readCookie;
var randomString = require('./pad_utils').randomString;
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
define([
'ep_etherpad-lite/static/js/rjquery',
'ep_etherpad-lite/static/js/pluginfw/hooks',
'ep_etherpad-lite/static/js/pad_utils',
'ep_etherpad-lite/static/js/broadcast_slider'
], function($, hooks, padUtilsMod, broadcastSliderMod) {
var exports = {};
var token, padId, export_links;
JSON = window.requireKernel('./json2');
function init() {
$(document).ready(function ()
{
// start the custom js
if (typeof customStart == "function") customStart();
var createCookie = padUtilsMod.createCookie;
var readCookie = padUtilsMod.readCookie;
var randomString = padUtilsMod.randomString;
//get the padId out of the url
var urlParts= document.location.pathname.split("/");
padId = decodeURIComponent(urlParts[urlParts.length-2]);
var token, padId, export_links;
//set the title
document.title = padId.replace(/_+/g, ' ') + " | " + document.title;
//ensure we have a token
token = readCookie("token");
if(token == null)
function init() {
$(document).ready(function ()
{
token = "t." + randomString();
createCookie("token", token, 60);
}
// start the custom js
if (typeof customStart == "function") customStart();
var loc = document.location;
//get the correct 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';
//build up the socket io connection
socket = io.connect(url, {path: exports.baseURL + 'socket.io', resource: resource});
//send the ready message once we're connected
socket.on('connect', function()
{
sendSocketMsg("CLIENT_READY", {});
});
//get the padId out of the url
var urlParts= document.location.pathname.split("/");
padId = decodeURIComponent(urlParts[urlParts.length-2]);
socket.on('disconnect', function()
{
BroadcastSlider.showReconnectUI();
});
//set the title
document.title = padId.replace(/_+/g, ' ') + " | " + document.title;
//route the incoming messages
socket.on('message', function(message)
{
if(window.console) console.log(message);
if(message.type == "CLIENT_VARS")
//ensure we have a token
token = readCookie("token");
if(token == null)
{
handleClientVars(message);
token = "t." + randomString();
createCookie("token", token, 60);
}
else if(message.accessStatus)
var loc = document.location;
//get the correct 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';
//build up the socket io connection
socket = io.connect(url, {path: exports.baseURL + 'socket.io', resource: resource});
//send the ready message once we're connected
socket.on('connect', function()
{
$("body").html("<h2>You have no permission to access this pad</h2>")
} else {
changesetLoader.handleMessageFromServer(message);
}
sendSocketMsg("CLIENT_READY", {});
});
socket.on('disconnect', function()
{
BroadcastSlider.showReconnectUI();
});
//route the incoming messages
socket.on('message', function(message)
{
if(window.console) console.log(message);
if(message.type == "CLIENT_VARS")
{
handleClientVars(message);
}
else if(message.accessStatus)
{
$("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')
$('button#forcereconnect').click(function()
{
window.location.reload();
});
exports.socket = socket; // make the socket available
exports.BroadcastSlider = BroadcastSlider; // Make the slider available
hooks.aCallAll("postTimesliderInit");
});
//get all the export links
export_links = $('#export > .exportlink')
$('button#forcereconnect').click(function()
{
window.location.reload();
});
exports.socket = socket; // make the socket available
exports.BroadcastSlider = BroadcastSlider; // Make the slider available
hooks.aCallAll("postTimesliderInit");
});
}
//sends a message over the socket
function sendSocketMsg(type, data)
{
var sessionID = decodeURIComponent(readCookie("sessionID"));
var password = readCookie("password");
var msg = { "component" : "pad", // FIXME: Remove this stupidity!
"type": type,
"data": data,
"padId": padId,
"token": token,
"sessionID": sessionID,
"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);
// Translate some strings where we only want to set the title not the actual values
$('#playpause_button_icon').attr("title", html10n.get("timeslider.playPause"));
$('#leftstep').attr("title", html10n.get("timeslider.backRevision"));
$('#rightstep').attr("title", html10n.get("timeslider.forwardRevision"));
//sends a message over the socket
function sendSocketMsg(type, data)
{
var sessionID = decodeURIComponent(readCookie("sessionID"));
var password = readCookie("password");
// font family change
$("#viewfontmenu").change(function(){
var font = $("#viewfontmenu").val();
if(font === "monospace") setFont("Courier new");
if(font === "opendyslexic") setFont("OpenDyslexic");
if(font === "comicsans") setFont("Comic Sans MS");
if(font === "georgia") setFont("Georgia");
if(font === "impact") setFont("Impact");
if(font === "lucida") setFont("Lucida");
if(font === "lucidasans") setFont("Lucida Sans Unicode");
if(font === "palatino") setFont("Palatino Linotype");
if(font === "tahoma") setFont("Tahoma");
if(font === "timesnewroman") setFont("Times New Roman");
if(font === "trebuchet") setFont("Trebuchet MS");
if(font === "verdana") setFont("Verdana");
if(font === "symbol") setFont("Symbol");
if(font === "webdings") setFont("Webdings");
if(font === "wingdings") setFont("Wingdings");
if(font === "sansserif") setFont("MS Sans Serif");
if(font === "serif") setFont("MS Serif");
});
var msg = { "component" : "pad", // FIXME: Remove this stupidity!
"type": type,
"data": data,
"padId": padId,
"token": token,
"sessionID": sessionID,
"password": password,
"protocolVersion": 2};
}
socket.json.send(msg);
}
function setFont(font){
$('#padcontent').css("font-family", font);
}
var fireWhenAllScriptsAreLoaded = [];
exports.baseURL = '';
exports.init = init;
var changesetLoader;
function handleClientVars(message)
{
//save the client Vars
clientVars = message.data;
//load all script that doesn't work without the clientVars
BroadcastSlider = broadcastSliderMod.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);
// Translate some strings where we only want to set the title not the actual values
$('#playpause_button_icon').attr("title", html10n.get("timeslider.playPause"));
$('#leftstep').attr("title", html10n.get("timeslider.backRevision"));
$('#rightstep').attr("title", html10n.get("timeslider.forwardRevision"));
// font family change
$("#viewfontmenu").change(function(){
var font = $("#viewfontmenu").val();
if(font === "monospace") setFont("Courier new");
if(font === "opendyslexic") setFont("OpenDyslexic");
if(font === "comicsans") setFont("Comic Sans MS");
if(font === "georgia") setFont("Georgia");
if(font === "impact") setFont("Impact");
if(font === "lucida") setFont("Lucida");
if(font === "lucidasans") setFont("Lucida Sans Unicode");
if(font === "palatino") setFont("Palatino Linotype");
if(font === "tahoma") setFont("Tahoma");
if(font === "timesnewroman") setFont("Times New Roman");
if(font === "trebuchet") setFont("Trebuchet MS");
if(font === "verdana") setFont("Verdana");
if(font === "symbol") setFont("Symbol");
if(font === "webdings") setFont("Webdings");
if(font === "wingdings") setFont("Wingdings");
if(font === "sansserif") setFont("MS Sans Serif");
if(font === "serif") setFont("MS Serif");
});
}
function setFont(font){
$('#padcontent').css("font-family", font);
}
exports.baseURL = '';
exports.init = init;
return exports;
});

View File

@ -370,10 +370,6 @@
<script type="text/javascript" src="../static/plugins/requirejs/require.js"></script>
<!-- Include base packages manually (this help with debugging) -->
<!-- script type="text/javascript" src="../javascripts/lib/ep_etherpad-lite/static/js/pad.js?callback=require.define"></script>
<script type="text/javascript" src="../javascripts/lib/ep_etherpad-lite/static/js/ace2_common.js?callback=require.define"></script -->
<% e.begin_block("customScripts"); %>
<script type="text/javascript" src="../static/custom/pad.js"></script>
<% e.end_block(); %>
@ -402,8 +398,11 @@
[
'ep_etherpad-lite/static/js/rjquery',
'ep_etherpad-lite/static/js/pluginfw/client_plugins',
'ep_etherpad-lite/static/js/pluginfw/hooks'
], function ($, plugins, hooks) {
'ep_etherpad-lite/static/js/pluginfw/hooks',
'ep_etherpad-lite/static/js/pad',
'ep_etherpad-lite/static/js/chat',
'ep_etherpad-lite/static/js/pad_editbar',
], function ($, plugins, hooks, padMod, chatMod, padEditbarMod) {
window.$ = $; // Expose jQuery #HACK
window.jQuery = $;
@ -421,16 +420,15 @@
hooks.aCallAll('documentReady');
});
var pad = require('ep_etherpad-lite/static/js/pad');
pad.baseURL = baseURL;
pad.init();
padMod.baseURL = baseURL;
padMod.init();
});
/* TODO: These globals shouldn't exist. */
pad = require('ep_etherpad-lite/static/js/pad').pad;
chat = require('ep_etherpad-lite/static/js/chat').chat;
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;
padimpexp = require('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
pad = padMod.pad;
chat = chatMod.chat;
padeditbar = padEditbarMod.padeditbar;
padimpexp = window.requireKernel('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
}
);
}());

View File

@ -222,9 +222,7 @@
<script type="text/javascript" src="../../static/js/require-kernel.js"></script>
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
<!-- Include base packages manually (this help with debugging) -->
<script type="text/javascript" src="../../javascripts/lib/ep_etherpad-lite/static/js/timeslider.js?callback=require.define"></script>
<script type="text/javascript" src="../../javascripts/lib/ep_etherpad-lite/static/js/ace2_common.js?callback=require.define"></script>
<script type="text/javascript" src="../static/plugins/requirejs/require.js"></script>
<script type="text/javascript" src="../../static/custom/timeslider.js"></script>
@ -243,31 +241,47 @@
require.setLibraryURI(baseURL + "javascripts/lib");
require.setGlobalKeyPath("require");
$ = jQuery = require('ep_etherpad-lite/static/js/rjquery').jQuery; // Expose jQuery #HACK
browser = require('ep_etherpad-lite/static/js/browser').browser;
window.requireKernel = require;
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet
}
requirejs.config({
baseUrl: baseURL + "static/plugins",
paths: {'underscore': baseURL + "static/plugins/underscore/underscore"},
});
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;
plugins.baseURL = baseURL;
plugins.update(function () {
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
hooks.plugins = plugins;
requirejs([
'ep_etherpad-lite/static/js/rjquery',
'ep_etherpad-lite/static/js/pluginfw/client_plugins',
'ep_etherpad-lite/static/js/pluginfw/hooks'
'ep_etherpad-lite/static/js/pad_editbar',
'ep_etherpad-lite/static/js/browser',
'ep_etherpad-lite/static/js/timeslider'
], function ($, plugins, hooks, padEditbarMod, browserMod, timesliderMod) {
window.$ = $; // Expose jQuery #HACK
window.jQuery = $;
var timeslider = require('ep_etherpad-lite/static/js/timeslider')
timeslider.baseURL = baseURL;
timeslider.init();
browser = browserMod.browser;
/* TODO: These globals shouldn't exist. */
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;
padimpexp = require('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet
}
padeditbar.init()
var socket = timesliderMod.socket;
BroadcastSlider = timesliderMod.BroadcastSlider;
plugins.baseURL = baseURL;
plugins.update(function () {
hooks.plugins = plugins;
timesliderMod.baseURL = baseURL;
timesliderMod.init();
/* TODO: These globals shouldn't exist. */
padeditbar = padEditbarMod.padeditbar;
padimpexp = window.requireKernel('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
padeditbar.init();
});
});
})();
</script>