UI clean-up for pad and timeslider

- cleaned CSS (sorted and grouped rules, removed unnecessary
!importants and selectors, etc.)
- added new edit bar icons (including PSD source files) and removed
obsolete images
- removed HTML bloat;
- adjusted selectors etc. in JS to new markup structure;
This commit is contained in:
Dominik Rodler 2012-02-26 00:04:50 +01:00
parent 4e54ebb0b8
commit f23e6a3f3b
30 changed files with 1732 additions and 3032 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,106 +1,51 @@
#editorcontainerbox {overflow:auto; top:40px;} /* adjust page layout to show timeslider */
.maximized #padpage {left:8px; margin-left:0; right:8px; width:auto;}
.fullwidth #padpage {margin-left:6px; margin-right:6px; width:auto;}
.squish1width #padpage {width:800px;}
.squish2width #padpage {width:700px;}
#padcontent {font-size:12px; padding:10px;} #padmain {top:59px;}
#editorcontainerbox {overflow:auto; top:34px;} /* #FIXME: the HTML structure is totally destroyed! */
#timeslider-wrapper {left:0; position:relative; right:0; top:0;} /* timeslider sprite */
#timeslider-left {background-image:url(../../static/img/timeslider_left.png); height:63px; left:0; position:absolute; width:134px;} #ui-slider-handle, #playpause_button, #steppers A, #timeslider .star {background:url(../../static/img/timeslider-sprite.png) 0 0 no-repeat;}
#timeslider-right {background-image:url(../../static/img/timeslider_right.png); height:63px; position:absolute; right:0; top:0; width:155px;}
#timeslider {background-image:url(../../static/img/timeslider_background.png); height:63px; margin:0 9px;}
#timeslider #timeslider-slider {height:61px; left:0; position:absolute; top:1px; width:100%;}
#ui-slider-handle {
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
-webkit-user-select:none;
background-image:url(../../static/img/crushed_current_location.png);
cursor:pointer;
height:61px;
left:0;
position:absolute;
top:0;
user-select:none;
width:13px;
}
#ui-slider-bar {
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
-webkit-user-select:none;
cursor:pointer;
height:35px;
margin-left:5px;
margin-right:148px;
position:relative;
top:20px;
user-select:none;
}
#playpause_button, #playpause_button_icon {height:47px; position:absolute; width:47px;} #timeslider {background:#f5f5f5; border-bottom:1px solid #d5d5d5; padding:6px 0; position:absolute; top:0; width:100%;}
#playpause_button {background-image:url(../../static/img/crushed_button_undepressed.png); right:77px; top:9px;} #timer {background-color:#aaa; border-radius:3px; color:#fff; font-family:Arial, sans-serif; font-size:11px; left:6px; min-width:101px; padding:2px 4px 1px; position:absolute; top:7px;}
#playpause_button_icon {background-image:url(../../static/img/play.png); left:0; top:0;} #timeslider-wrapper {float:left; width:100%;}
.pause#playpause_button_icon {background-image:url(../../static/img/pause.png);} #timeslider-slider {margin:0 164px 0 6px;}
#timeslider-slider DIV {cursor:pointer;}
#ui-slider-handle {background-position:-142px 0; height:22px; left:0; position:absolute; top:30px; width:13px;}
#ui-slider-bar {background-color:#ddd; height:6px; margin-top:40px;}
#ui-slider-bar:hover {background-color:#00b7ed;}
#timeslider .star {background-position:-80px 0; cursor:pointer; height:16px; position:absolute; top:40px; width:16px;}
#timeslider .star:hover {background-position:-100px 0;}
#leftstar, #rightstar, #leftstep, #rightstep #playpause_button {background-color:#ddd; background-position:-60px 0; border-radius:30px; float:right; height:46px; width:46px;}
{background:url(../../static/img/stepper_buttons.png) 0 0 no-repeat; height:21px; overflow:hidden; position:absolute;} #playpause_button:hover {background-position:-60px -40px;}
#leftstar {background-position:0 44px; right:34px; top:8px; width:30px;} #playpause_button.pause {background-position:-100px 0;}
#rightstar {background-position:29px 44px; right:5px; top:8px; width:29px;} #playpause_button.pause:hover {background-position:-100px -40px;}
#leftstep {background-position:0 22px; right:34px; top:20px; width:30px;}
#rightstep {background-position:29px 22px; right:5px; top:20px; width:29px;}
#timeslider .star { #steppers {float:right; margin:0 35px 0 10px; width:60px;}
background-image:url(../../static/img/star.png); #steppers A {border:1px solid #d5d5d5; box-shadow:0 1px 0 #fff; float:left; height:20px; margin:0 0 4px; width:28px;}
cursor:pointer; #steppers .group-start {border-radius:3px 0 0 3px;}
height:16px; #steppers .group-end {border-radius:0 3px 3px 0; border-width:1px 1px 1px 0; width:29px;}
position:absolute;
top:40px;
width:15px;
}
#timeslider #timer { A#leftstar, #leftstar.inactive:hover {background-position:0 0;}
color:#fff; A#rightstar, #rightstar.inactive:hover {background-position:-30px 0;}
font-family:Arial, sans-serif; A#leftstep, #leftstep.inactive:hover {background-position:0 -20px;}
font-size:11px; A#rightstep, #rightstep.inactive:hover {background-position:-30px -20px;}
left:7px; A#leftstar:hover {background-position:0 -40px;}
position:absolute; A#rightstar:hover {background-position:-30px -40px;}
text-align:center; A#leftstep:hover {background-position:0 -60px;}
top:9px; A#rightstep:hover {background-position:-30px -60px;}
width:122px;
}
.topbarcenter, #docbar {display:none;} .topbarcenter, #docbar {display:none;} /* hide document title etc. */
#padmain {top:30px;} #editbarinner H1 {color:#999; font-size:16px; line-height:29px; margin-top:0; padding-left:6px;}
#editbarright {float:right;} #editbarinner H1 A {font-size:12px;}
#returnbutton {color:#222; font-size:16px; line-height:29px; margin-top:0; padding-right:6px;} #revision_label {background-color:#aaa; border-radius:3px; color:#fff; padding:2px 5px;}
#importexport {top:118px;}
#importexport .popup {width:185px;}
/* lists */ #editbarright #returnbutton {background:0 none; border:0 none; box-shadow:none; padding:4px 6px; width:auto;}
.list-bullet2, .list-indent2, .list-number2 {margin-left:3em;} #returnbutton A {color:#999; font-size:12px; line-height:20px;}
.list-bullet3, .list-indent3, .list-number3 {margin-left:4.5em;}
.list-bullet4, .list-indent4, .list-number4 {margin-left:6em;}
.list-bullet5, .list-indent5, .list-number5 {margin-left:7.5em;}
.list-bullet6, .list-indent6, .list-number6 {margin-left:9em;}
.list-bullet7, .list-indent7, .list-number7 {margin-left:10.5em;}
.list-bullet8, .list-indent8, .list-number8 {margin-left:12em;}
/* unordered lists */ #importexport.popup {top:95px; width:140px;}
UL {list-style-type:disc; margin-left:1.5em;}
UL UL {margin-left:0 !important;}
.list-bullet2, .list-bullet5, .list-bullet8 {list-style-type:circle;}
.list-bullet3, .list-bullet6 {list-style-type:square;}
.list-indent1, .list-indent2, .list-indent3, .list-indent5, .list-indent5, .list-indent6, .list-indent7, .list-indent8 {list-style-type:none;}
/* ordered lists */
OL {list-style-type:decimal; margin-left:1.5em;}
.list-number2, .list-number5, .list-number8 {list-style-type:lower-latin;}
.list-number3, .list-number6 {list-style-type:lower-roman;}
/* IE 6/7 fixes ################################################################ */
* HTML #ui-slider-handle {background-image:url(../../static/img/current_location.gif);}
* HTML #timeslider .star {background-image:url(../../static/img/star.gif);}
* HTML #playpause_button_icon {background-image:url(../../static/img/play.gif);}
* HTML .pause#playpause_button_icon {background-image:url(../../static/img/pause.gif);}

BIN
static/img/ajax-loader.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,009 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

View file

@ -1,5 +1,5 @@
/** /**
* This code is mostly from the old Etherpad. Please help us to comment this code. * This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it. * This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/ */
@ -23,64 +23,51 @@
// of the document. These revisions are connected together by various // of the document. These revisions are connected together by various
// changesets, or deltas, between any two revisions. // changesets, or deltas, between any two revisions.
function loadBroadcastRevisionsJS() function loadBroadcastRevisionsJS() {
{
function Revision(revNum) function Revision(revNum) {
{
this.rev = revNum; this.rev = revNum;
this.changesets = []; this.changesets = [];
} }
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta) Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta) {
{
var changesetWrapper = { var changesetWrapper = {
deltaRev: destIndex - this.rev, deltaRev : destIndex - this.rev,
deltaTime: timeDelta, deltaTime : timeDelta,
getValue: function() getValue : function() {return changeset;}
{
return changeset;
}
}; };
this.changesets.push(changesetWrapper); this.changesets.push(changesetWrapper);
this.changesets.sort(function(a, b) this.changesets.sort(function(a, b) {
{ return (b.deltaRev - a.deltaRev);
return (b.deltaRev - a.deltaRev)
}); });
} };
revisionInfo = {}; revisionInfo = {};
revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta) revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta) {
{ var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex),
var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex); endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
var endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
startRevision.addChangeset(toIndex, changeset, timeDelta); startRevision.addChangeset(toIndex, changeset, timeDelta);
endRevision.addChangeset(fromIndex, backChangeset, -1 * timeDelta); endRevision.addChangeset(fromIndex, backChangeset, -1 * timeDelta);
} };
revisionInfo.latest = clientVars.totalRevs || -1; revisionInfo.latest = clientVars.totalRevs || -1;
revisionInfo.createNew = function(index) revisionInfo.createNew = function(index) {
{
revisionInfo[index] = new Revision(index); revisionInfo[index] = new Revision(index);
if (index > revisionInfo.latest) if (index > revisionInfo.latest)
{
revisionInfo.latest = index; revisionInfo.latest = index;
}
return revisionInfo[index]; return revisionInfo[index];
} };
// assuming that there is a path from fromIndex to toIndex, and that the links // assuming that there is a path from fromIndex to toIndex, and that the links
// are laid out in a skip-list format // are laid out in a skip-list format
revisionInfo.getPath = function(fromIndex, toIndex) revisionInfo.getPath = function(fromIndex, toIndex) {
{ var changesets = [],
var changesets = []; spans = [],
var spans = []; times = [],
var times = []; elem = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex);
var elem = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex); if (elem.changesets.length != 0 && fromIndex != toIndex) {
if (elem.changesets.length != 0 && fromIndex != toIndex) var reverse = !(fromIndex < toIndex);
{
var reverse = !(fromIndex < toIndex)
while (((elem.rev < toIndex) && !reverse) || ((elem.rev > toIndex) && reverse)) while (((elem.rev < toIndex) && !reverse) || ((elem.rev > toIndex) && reverse))
{ {
var couldNotContinue = false; var couldNotContinue = false;
@ -107,22 +94,24 @@ function loadBroadcastRevisionsJS()
} }
} }
if (couldNotContinue || oldRev == elem.rev) break; if (couldNotContinue || oldRev == elem.rev)
break;
} }
} }
var status = 'partial'; var status = 'partial';
if (elem.rev == toIndex) status = 'complete'; if (elem.rev == toIndex)
status = 'complete';
return { return {
'fromRev': fromIndex, 'fromRev' : fromIndex,
'rev': elem.rev, 'rev' : elem.rev,
'status': status, 'status' : status,
'changesets': changesets, 'changesets' : changesets,
'spans': spans, 'spans' : spans,
'times': times 'times' : times
}; };
} };
} }
exports.loadBroadcastRevisionsJS = loadBroadcastRevisionsJS; exports.loadBroadcastRevisionsJS = loadBroadcastRevisionsJS;

View file

@ -1,5 +1,5 @@
/** /**
* This code is mostly from the old Etherpad. Please help us to comment this code. * This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it. * This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/ */
@ -20,471 +20,367 @@
* limitations under the License. * limitations under the License.
*/ */
// These parameters were global, now they are injected. A reference to the // These parameters were global, now they are injected. A reference to the
// Timeslider controller would probably be more appropriate. // Timeslider controller would probably be more appropriate.
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) {
{
var BroadcastSlider; var BroadcastSlider;
(function() (function() { // wrap this code in its own namespace
{ // wrap this code in its own namespace var sliderLength = 1000,
var sliderLength = 1000; sliderPos = 0,
var sliderPos = 0; sliderActive = false,
var sliderActive = false; slidercallbacks = [],
var slidercallbacks = []; savedRevisions = [],
var savedRevisions = []; sliderPlaying = false;
var sliderPlaying = false;
function disableSelection(element) function disableSelection(element) {
{ element.onselectstart = function() {
element.onselectstart = function()
{
return false; return false;
}; };
element.unselectable = "on"; element.unselectable = "on";
element.style.MozUserSelect = "none"; element.style.MozUserSelect = "none";
element.style.cursor = "default";
} }
var _callSliderCallbacks = function(newval) var _callSliderCallbacks = function(newval) {
{ sliderPos = newval;
sliderPos = newval; for (var i=0, l=slidercallbacks.length; i < l; i++) {
for (var i = 0; i < slidercallbacks.length; i++) slidercallbacks[i](newval);
{ }
slidercallbacks[i](newval); };
} var updateSliderElements = function() {
} for (var i=0, l=savedRevisions.length; i < l; i++) {
var position = parseInt(savedRevisions[i].attr('pos'), 10);
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 updateSliderElements = function() var addSavedRevision = function(position, info) {
{ var newSavedRevision = $('<div></div>');
for (var i = 0; i < savedRevisions.length; i++) newSavedRevision
{ .addClass('star')
var position = parseInt(savedRevisions[i].attr('pos')); .attr('pos', position)
savedRevisions[i].css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1); .css('position', 'absolute')
} .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)); $('#timeslider-slider').append(newSavedRevision);
} newSavedRevision.mouseup(function(evt) {
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
var addSavedRevision = function(position, info)
{
var newSavedRevision = $('<div></div>');
newSavedRevision.addClass("star");
newSavedRevision.attr('pos', position); var removeSavedRevision = function(position) {
newSavedRevision.css('position', 'absolute'); var element = $('.star [pos=' + position + ']');
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1); savedRevisions.remove(element);
$("#timeslider-slider").append(newSavedRevision); element.remove();
newSavedRevision.mouseup(function(evt) return element;
{ };
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
var removeSavedRevision = function(position) /* small 'API' START */
{ function onSlider(callback) {
var element = $("div.star [pos=" + position + "]");
savedRevisions.remove(element);
element.remove();
return element;
};
/* Begin small 'API' */
function onSlider(callback)
{
slidercallbacks.push(callback); slidercallbacks.push(callback);
} }
function getSliderPosition() function getSliderPosition() {
{
return sliderPos; return sliderPos;
} }
function setSliderPosition(newpos) function setSliderPosition(newpos) {
{
newpos = Number(newpos); newpos = Number(newpos);
if (newpos < 0 || newpos > sliderLength) return; if (newpos < 0 || newpos > sliderLength)
$("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)); return;
$("a.tlink").map(function() $('#ui-slider-handle').css('left', newpos * ($('#ui-slider-bar').width() - 2) / (sliderLength * 1.0));
{ $('.tlink').map(function() {
$(this).attr('href', $(this).attr('thref').replace("%revision%", newpos)); $(this).attr('href', $(this).attr('thref').replace('%revision%', newpos));
}); });
$("#revision_label").html("Version " + newpos); $('#revision_label').html('Version ' + newpos);
if (newpos == 0) if (newpos == 0)
{ $('#leftstar, #leftstep').addClass('inactive');
$("#leftstar").css('opacity', .5);
$("#leftstep").css('opacity', .5);
}
else else
{ $('#leftstar, #leftstep').removeClass('inactive');
$("#leftstar").css('opacity', 1);
$("#leftstep").css('opacity', 1);
}
if (newpos == sliderLength) if (newpos == sliderLength)
{ $('#rightstar, #rightstep').addClass('inactive');
$("#rightstar").css('opacity', .5);
$("#rightstep").css('opacity', .5);
}
else else
{ $('#rightstar, #rightstep').removeClass('inactive');
$("#rightstar").css('opacity', 1);
$("#rightstep").css('opacity', 1);
}
sliderPos = newpos; sliderPos = newpos;
_callSliderCallbacks(newpos); _callSliderCallbacks(newpos);
} }
function getSliderLength() function getSliderLength() {
{
return sliderLength; return sliderLength;
} }
function setSliderLength(newlength) function setSliderLength(newlength) {
{
sliderLength = newlength; sliderLength = newlength;
updateSliderElements(); updateSliderElements();
} }
// just take over the whole slider screen with a reconnect message // take over the whole slider screen with a reconnect message
function showReconnectUI() {
function showReconnectUI()
{
if (!clientVars.sliderEnabled || !clientVars.supportsSlider)
{
$("#padmain, #rightbars").css('top', "130px");
$("#timeslider").show();
}
$('#error').show(); $('#error').show();
} }
function setAuthors(authors) function setAuthors(authors) {
{ $('#authorstable').empty();
$("#authorstable").empty(); var numAnonymous = 0,
var numAnonymous = 0; numNamed = 0,
var numNamed = 0; html;
authors.forEach(function(author) authors.forEach(function(author) {
{ if (author.name) {
if (author.name)
{
numNamed++; numNamed++;
var tr = $('<tr></tr>'); var tr = $('<tr></tr>'),
var swatchtd = $('<td></td>'); swatchtd = $('<td></td>'),
var swatch = $('<div class="swatch"></div>'); swatch = $('<div class="swatch"></div>'),
nametd = $('<td></td>');
swatch.css('background-color', clientVars.colorPalette[author.colorId]); swatch.css('background-color', clientVars.colorPalette[author.colorId]);
swatchtd.append(swatch); swatchtd.append(swatch);
tr.append(swatchtd); tr.append(swatchtd);
var nametd = $('<td></td>'); nametd.text(author.name || 'unnamed');
nametd.text(author.name || "unnamed");
tr.append(nametd); tr.append(nametd);
$("#authorstable").append(tr); $('#authorstable').append(tr);
} } else {
else
{
numAnonymous++; numAnonymous++;
} }
}); });
if (numAnonymous > 0) if (numAnonymous > 0) {
{ html = '<tr><td colspan="2" style="color:#999; padding-left:10px">' +
var html = "<tr><td colspan=\"2\" style=\"color:#999; padding-left: 10px\">" + (numNamed > 0 ? "...and " : "") + numAnonymous + " unnamed author" + (numAnonymous > 1 ? "s" : "") + "</td></tr>"; (numNamed > 0 ? '...and ' : '') + numAnonymous + ' unnamed author' +
$("#authorstable").append($(html)); (numAnonymous > 1 ? 's' : '') + '</td></tr>';
$('#authorstable').append($(html));
} }
if (authors.length == 0) if (authors.length == 0) {
{ html = '<tr><td colspan="2" style="color:#999; padding-left:10px">No Authors</td></tr>';
$("#authorstable").append($("<tr><td colspan=\"2\" style=\"color:#999; padding-left: 10px\">No Authors</td></tr>")) $('#authorstable').append($(html));
} }
} }
BroadcastSlider = { BroadcastSlider = {
onSlider: onSlider, onSlider : onSlider,
getSliderPosition: getSliderPosition, getSliderPosition : getSliderPosition,
setSliderPosition: setSliderPosition, setSliderPosition : setSliderPosition,
getSliderLength: getSliderLength, getSliderLength : getSliderLength,
setSliderLength: setSliderLength, setSliderLength : setSliderLength,
isSliderActive: function() isSliderActive : function() {
{
return sliderActive; return sliderActive;
}, },
playpause: playpause, playpause : playpause,
addSavedRevision: addSavedRevision, addSavedRevision : addSavedRevision,
showReconnectUI: showReconnectUI, showReconnectUI : showReconnectUI,
setAuthors: setAuthors setAuthors : setAuthors
} };
function playButtonUpdater() function playButtonUpdater() {
{ if (sliderPlaying) {
if (sliderPlaying) if (getSliderPosition() + 1 > sliderLength) {
{ $('#playpause_button').toggleClass('pause');
if (getSliderPosition() + 1 > sliderLength)
{
$("#playpause_button_icon").toggleClass('pause');
sliderPlaying = false; sliderPlaying = false;
return; return;
} }
setSliderPosition(getSliderPosition() + 1); setSliderPosition(getSliderPosition() + 1);
setTimeout(playButtonUpdater, 100); setTimeout(playButtonUpdater, 100);
} }
} }
function playpause() function playpause() {
{ $('#playpause_button').toggleClass('pause');
$("#playpause_button_icon").toggleClass('pause'); if (!sliderPlaying) {
if (!sliderPlaying)
{
if (getSliderPosition() == sliderLength) setSliderPosition(0); if (getSliderPosition() == sliderLength) setSliderPosition(0);
sliderPlaying = true; sliderPlaying = true;
playButtonUpdater(); playButtonUpdater();
} } else {
else
{
sliderPlaying = false; sliderPlaying = false;
} }
} }
// assign event handlers to html UI elements after page load // assign event handlers to html UI elements after page load
//$(window).load(function () fireWhenAllScriptsAreLoaded.push(function() {
fireWhenAllScriptsAreLoaded.push(function()
{
disableSelection($("#playpause_button")[0]); disableSelection($("#playpause_button")[0]);
disableSelection($("#timeslider")[0]); disableSelection($("#timeslider")[0]);
if (clientVars.sliderEnabled && clientVars.supportsSlider) if (clientVars.sliderEnabled && clientVars.supportsSlider) {
{ $(document).keyup(function(e) {
$(document).keyup(function(e) var code = -1,
{ i, l, nextStar, pos;
var code = -1; if (!e)
if (!e) var e = window.event; var e = window.event;
if (e.keyCode) code = e.keyCode; code = (e.keyCode) ? e.keyCode : e.which;
else if (e.which) code = e.which;
if (code == 37) switch (code) {
{ // left case 37: // left
if (!e.shiftKey) if (!e.shiftKey) {
{ setSliderPosition(getSliderPosition() - 1);
setSliderPosition(getSliderPosition() - 1); } else {
} nextStar = 0; // default to first revision in document
else for (i=0, l=savedRevisions.length; i < l; i++) {
{ pos = parseInt(savedRevisions[i].attr('pos'), 10);
var nextStar = 0; // default to first revision in document if (pos < getSliderPosition() && nextStar < pos)
for (var i = 0; i < savedRevisions.length; i++) nextStar = pos;
{ }
var pos = parseInt(savedRevisions[i].attr('pos')); setSliderPosition(nextStar);
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
} }
setSliderPosition(nextStar); break;
} case 39:
} if (!e.shiftKey) {
else if (code == 39) setSliderPosition(getSliderPosition() + 1);
{ } else {
if (!e.shiftKey) nextStar = sliderLength; // default to last revision in document
{ for (i=0, l=savedRevisions.length; i < l; i++) {
setSliderPosition(getSliderPosition() + 1); pos = parseInt(savedRevisions[i].attr('pos'), 10);
} if (pos > getSliderPosition() && nextStar > pos)
else nextStar = pos;
{ }
var nextStar = sliderLength; // default to last revision in document setSliderPosition(nextStar);
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
} }
setSliderPosition(nextStar); break;
} case 32:
playpause();
break;
} }
else if (code == 32) playpause();
}); });
} }
$(window).resize(function() $(window).resize(function() {
{
updateSliderElements(); updateSliderElements();
}); });
$("#ui-slider-bar").mousedown(function(evt) $('#ui-slider-bar')
{ .mousedown(function(evt) {
setSliderPosition(Math.floor((evt.clientX - $("#ui-slider-bar").offset().left) * sliderLength / 742)); setSliderPosition(Math.floor((evt.clientX - $('#ui-slider-bar').offset().left) * sliderLength / 742));
$("#ui-slider-handle").css('left', (evt.clientX - $("#ui-slider-bar").offset().left)); $('#ui-slider-handle')
$("#ui-slider-handle").trigger(evt); .css('left', (evt.clientX - $('#ui-slider-bar').offset().left))
.trigger(evt);
}); });
// Slider dragging // slider dragging
$("#ui-slider-handle").mousedown(function(evt) $('#ui-slider-handle')
{ .mousedown(function(evt) {
this.startLoc = evt.clientX; this.startLoc = evt.clientX;
this.currentLoc = parseInt($(this).css('left')); this.currentLoc = parseInt($(this).css('left'), 10);
var self = this; var self = this;
sliderActive = true; sliderActive = true;
$(document).mousemove(function(evt2) $(document).mousemove(function(evt2) {
{ var newloc = self.currentLoc + (evt2.clientX - self.startLoc),
$(self).css('pointer', 'move') adjustedWidth = $('#ui-slider-bar').width() - 2,
var newloc = self.currentLoc + (evt2.clientX - self.startLoc); pos;
if (newloc < 0) newloc = 0; if (newloc < 0)
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2); newloc = 0;
$("#revision_label").html("Version " + Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))); if (newloc > adjustedWidth)
newloc = adjustedWidth;
$('#revision_label').html('Version ' + Math.floor(newloc * sliderLength / adjustedWidth));
$(self).css('left', newloc); $(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))) pos = Math.floor(newloc * sliderLength / adjustedWidth);
if (getSliderPosition() != pos)
_callSliderCallbacks(pos);
}); });
$(document).mouseup(function(evt2) $(document).mouseup(function(evt2) {
{ $(document)
$(document).unbind('mousemove'); .unbind('mousemove')
$(document).unbind('mouseup'); .unbind('mouseup');
sliderActive = false; sliderActive = false;
var newloc = self.currentLoc + (evt2.clientX - self.startLoc); var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0; if (newloc < 0)
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2); newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2))
newloc = ($("#ui-slider-bar").width() - 2);
$(self).css('left', newloc); $(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)));
setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) self.currentLoc = parseInt($(self).css('left'), 10);
self.currentLoc = parseInt($(self).css('left'));
}); });
}) });
// play/pause toggling // toggle play / pause
$("#playpause_button").mousedown(function(evt) $('#playpause_button').mousedown(function(evt) {
{
var self = this; var self = this;
$(self)
$(self).css('background-image', 'url(/static/img/crushed_button_depressed.png)'); .addClass('pressed')
$(self).mouseup(function(evt2) .mouseup(function(evt2) {
{ $(self).removeClass('pressed');
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(self).unbind('mouseup'); $(self).unbind('mouseup');
BroadcastSlider.playpause(); BroadcastSlider.playpause();
}); });
$(document).mouseup(function(evt2) $(document).mouseup(function(evt2) {
{ $(self).removeClass('pressed');
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(document).unbind('mouseup'); $(document).unbind('mouseup');
}); });
}); });
// next/prev saved revision and changeset // next / prev saved revision and changeset
$('.stepper').mousedown(function(evt) $('#steppers A').mousedown(function(evt) {
{
var self = this; var self = this;
var origcss = $(self).css('background-position'); $(self)
if (!origcss) .addClass('clicked')
{ .mouseup(function(evt2) {
origcss = $(self).css('background-position-x') + " " + $(self).css('background-position-y'); $(self)
} .removeClass('clicked')
var origpos = parseInt(origcss.split(" ")[1]); .unbind('mouseup');
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'); $(document).unbind('mouseup');
if ($(self).attr("id") == ("leftstep")) var id = $(self).attr('id'),
{ i, l, nextStar, pos;
setSliderPosition(getSliderPosition() - 1); switch (id) {
} case 'leftstep':
else if ($(self).attr("id") == ("rightstep")) setSliderPosition(getSliderPosition() - 1);
{ break;
setSliderPosition(getSliderPosition() + 1); case 'rightstep':
} setSliderPosition(getSliderPosition() + 1);
else if ($(self).attr("id") == ("leftstar")) break;
{ case 'leftstar':
var nextStar = 0; // default to first revision in document nextStar = 0; // default to first revision in document
for (var i = 0; i < savedRevisions.length; i++) for (i=0, l=savedRevisions.length; i < l; i++) {
{ pos = parseInt(savedRevisions[i].attr('pos'), 10);
var pos = parseInt(savedRevisions[i].attr('pos')); if (pos < getSliderPosition() && nextStar < pos)
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos; nextStar = pos;
} }
setSliderPosition(nextStar); setSliderPosition(nextStar);
} break;
else if ($(self).attr("id") == ("rightstar")) case 'rightstar':
{ nextStar = sliderLength; // default to last revision in document
var nextStar = sliderLength; // default to last revision in document for (i=0, l=savedRevisions.length; i < l; i++) {
for (var i = 0; i < savedRevisions.length; i++) pos = parseInt(savedRevisions[i].attr('pos'), 10);
{ if (pos > getSliderPosition() && nextStar > pos)
var pos = parseInt(savedRevisions[i].attr('pos')); nextStar = pos;
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos; }
} setSliderPosition(nextStar);
setSliderPosition(nextStar); break;
} }
}); });
$(document).mouseup(function(evt2) $(document).mouseup(function(evt2) {
{ $(self)
$(self).css('background-position', origcss); .removeClass('clicked')
$(self).unbind('mouseup'); .unbind('mouseup');
$(document).unbind('mouseup'); $(document).unbind('mouseup');
}); });
}) });
if (clientVars) if (clientVars) {
{
if (clientVars.fullWidth) if (clientVars.fullWidth)
{ $('#padpage').addClass('full-width');
$("#padpage").css('width', '100%'); if (clientVars.disableRightBar) {
$("#revision").css('position', "absolute") $('#rightbars').css('display', 'none');
$("#revision").css('right', "20px")
$("#revision").css('top', "20px")
$("#padmain").css('left', '0px');
$("#padmain").css('right', '197px');
$("#padmain").css('width', 'auto');
$("#rightbars").css('right', '7px');
$("#rightbars").css('margin-right', '0px');
$("#timeslider").css('width', 'auto');
}
if (clientVars.disableRightBar)
{
$("#rightbars").css('display', 'none');
$('#padmain').css('width', 'auto'); $('#padmain').css('width', 'auto');
if (clientVars.fullWidth) $("#padmain").css('right', '7px'); if (clientVars.fullWidth)
else $("#padmain").css('width', '860px'); $('#padmain').css({right: 7});
$("#revision").css('position', "absolute"); else
$("#revision").css('right', "20px"); $('#padmain').css('width', '860px');
$("#revision").css('top', "20px"); $('#revision').css({
position: 'absolute',
right : 20,
top : 20
});
} }
if (clientVars.sliderEnabled) {
if (clientVars.supportsSlider) {
if (clientVars.sliderEnabled)
{
if (clientVars.supportsSlider)
{
$("#padmain, #rightbars").css('top', "130px");
$("#timeslider").show();
setSliderLength(clientVars.totalRevs); setSliderLength(clientVars.totalRevs);
setSliderPosition(clientVars.revNum); setSliderPosition(clientVars.revNum);
clientVars.savedRevisions.forEach(function(revision) clientVars.savedRevisions.forEach(function(revision) {
{
addSavedRevision(revision.revNum, revision); addSavedRevision(revision.revNum, revision);
}) });
} } else {
else
{
// slider is not supported // slider is not supported
$("#padmain, #rightbars").css('top', "130px"); $('#error').html('The timeslider feature is not supported on this pad. <a href="/ep/about/faq#disabledslider">Why not?</a>').show();
$("#timeslider").show();
$("#error").html("The timeslider feature is not supported on this pad. <a href=\"/ep/about/faq#disabledslider\">Why not?</a>");
$("#error").show();
} }
} } else {
else if (clientVars.supportsSlider) {
{
if (clientVars.supportsSlider)
{
setSliderLength(clientVars.totalRevs); setSliderLength(clientVars.totalRevs);
setSliderPosition(clientVars.revNum); setSliderPosition(clientVars.revNum);
} }
@ -493,10 +389,9 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
}); });
})(); })();
BroadcastSlider.onSlider(function(loc) BroadcastSlider.onSlider(function(loc) {
{ $('#viewlatest').html(loc == BroadcastSlider.getSliderLength() ? 'Viewing latest content' : 'View latest content');
$("#viewlatest").html(loc == BroadcastSlider.getSliderLength() ? "Viewing latest content" : "View latest content"); });
})
return BroadcastSlider; return BroadcastSlider;
} }

View file

@ -20,143 +20,119 @@
* limitations under the License. * limitations under the License.
*/ */
var padutils = require('/pad_utils').padutils; var padutils = require('/pad_utils').padutils,
var padcookie = require('/pad_cookie').padcookie; padcookie = require('/pad_cookie').padcookie;
var chat = (function() var chat = (function() {
{ var isStuck = false,
var isStuck = false; chatMentions = 0,
var chatMentions = 0; title = document.title;
var title = document.title;
var self = { var self = {
show: function () show: function() {
{ $('#chaticon').hide();
$("#chaticon").hide(); $('#chatbox').show();
$("#chatbox").show();
self.scrollDown(); self.scrollDown();
chatMentions = 0; chatMentions = 0;
document.title = title; document.title = title;
}, },
stickToScreen: function(fromInitialCall) // Make chat stick to right hand side of screen stickToScreen: function(fromInitialCall) { // make chat stick to right hand side of screen
{
chat.show(); chat.show();
if(!isStuck || fromInitialCall) { // Stick it to if (!isStuck || fromInitialCall) { // do stick it
padcookie.setPref("chatAlwaysVisible", true); padcookie.setPref('chatAlwaysVisible', true);
$('#chatbox').addClass("stickyChat"); $('BODY').addClass('chat-visible');
$('#chattext').css({"top":"0px"});
$('#editorcontainer').css({"right":"192px", "width":"auto"});
isStuck = true; isStuck = true;
} else { // Unstick it } else { // unstick it
padcookie.setPref("chatAlwaysVisible", false); padcookie.setPref('chatAlwaysVisible', false);
$('#chatbox').removeClass("stickyChat"); $('BODY').removeClass('chat-visible');
$('#chattext').css({"top":"25px"});
$('#editorcontainer').css({"right":"0px", "width":"100%"});
isStuck = false; isStuck = false;
} }
}, },
hide: function () hide: function() {
{ $('#chatcounter').text('0');
$("#chatcounter").text("0"); $('#chaticon').show();
$("#chaticon").show(); $('#chatbox').hide();
$("#chatbox").hide();
}, },
scrollDown: function() scrollDown: function() {
{ if ($('#chatbox').is(':visible'))
if($('#chatbox').css("display") != "none") $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, 600);
$('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, "slow");
}, },
send: function() send: function() {
{ var text = $('#chatinput').val();
var text = $("#chatinput").val(); this._pad.collabClient.sendMessage({
this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text}); 'type': 'CHAT_MESSAGE',
$("#chatinput").val(""); 'text': text
});
$('#chatinput').val('');
}, },
addMessage: function(msg, increment) addMessage: function(msg, increment) {
{ // correct the time
//correct the time
msg.time += this._pad.clientTimeOffset; msg.time += this._pad.clientTimeOffset;
//create the time string // create the time string
var minutes = "" + new Date(msg.time).getMinutes(); var minutes = '' + new Date(msg.time).getMinutes(),
var hours = "" + new Date(msg.time).getHours(); hours = '' + new Date(msg.time).getHours(),
if(minutes.length == 1) timeStr;
minutes = "0" + minutes ; if (minutes.length == 1)
if(hours.length == 1) minutes = '0' + minutes;
hours = "0" + hours ; if (hours.length == 1)
var timeStr = hours + ":" + minutes; hours = '0' + hours;
timeStr = hours + ':' + minutes;
//create the authorclass // create the authorclass
var authorClass = "author-" + msg.userId.replace(/[^a-y0-9]/g, function(c) var authorClass = 'author-' + msg.userId.replace(/[^a-y0-9]/g, function(c) {
{ if (c == '.')
if (c == ".") return "-"; return '-';
return 'z' + c.charCodeAt(0) + 'z'; return 'z' + c.charCodeAt(0) + 'z';
}); });
var text = padutils.escapeHtmlWithClickableLinks(msg.text, "_blank"); var text = padutils.escapeHtmlWithClickableLinks(padutils.escapeHtml(msg.text), '_blank');
/* Performs an action if your name is mentioned */ // do something when your name is mentioned
var myName = $('#myusernameedit').val(); var myName = $('#myusernameedit').val().toLowerCase(),
myName = myName.toLowerCase(); chatText = text.toLowerCase(),
var chatText = text.toLowerCase(); wasMentioned = false;
var wasMentioned = false; if (chatText.indexOf(myName) !== -1 && myName != 'undefined')
if (chatText.indexOf(myName) !== -1 && myName != "undefined"){
wasMentioned = true; wasMentioned = true;
} // end of action
/* End of new action */
var authorName = msg.userName == null ? "unnamed" : padutils.escapeHtml(msg.userName); var authorName = msg.userName == null ? 'unnamed' : padutils.escapeHtml(msg.userName),
html = '<p class="' + authorClass + '"><strong>' + authorName + ':</strong><span class="time ' + authorClass + '">' + timeStr + '</span>' + text + '</p>';
$('#chattext').append(html);
var html = "<p class='" + authorClass + "'><b>" + authorName + ":</b><span class='time " + authorClass + "'>" + timeStr + "</span> " + text + "</p>"; // should we increment the counter??
$("#chattext").append(html); if (increment) {
var count = Number($('#chatcounter').text());
//should we increment the counter??
if(increment)
{
var count = Number($("#chatcounter").text());
count++; count++;
$("#chatcounter").text(count); $('#chatcounter').text(count);
// chat throb stuff -- Just make it throw for twice as long // chat throb stuff -- Just make it throw for twice as long
if(wasMentioned) if (wasMentioned) { // If the user was mentioned, show twice as long and flash the browser window
{ // If the user was mentioned show for twice as long and flash the browser window if (chatMentions == 0)
if (chatMentions == 0){
title = document.title; title = document.title;
} $('#chatthrob').html('<b>' + authorName + '</b>' + ': ' + text).show().delay(4000).hide(400);
$('#chatthrob').html("<b>"+authorName+"</b>" + ": " + text).show().delay(4000).hide(400);
chatMentions++; chatMentions++;
document.title = "("+chatMentions+") " + title; document.title = '(' + chatMentions + ') ' + title;
} } else {
else $('#chatthrob').html('<b>' + authorName + '</b>' + ': ' + text).show().delay(2000).hide(400);
{
$('#chatthrob').html("<b>"+authorName+"</b>" + ": " + text).show().delay(2000).hide(400);
} }
} }
self.scrollDown(); self.scrollDown();
}, },
init: function(pad) init: function(pad) {
{
this._pad = pad; this._pad = pad;
$("#chatinput").keypress(function(evt) $('#chatinput').keypress(function(evt) {
{ if (evt.which == 13) { // send on enter
//if the user typed enter, fire the send
if(evt.which == 13)
{
evt.preventDefault(); evt.preventDefault();
self.send(); self.send();
} }
}); });
for (var i in clientVars.chatHistory) {
for(var i in clientVars.chatHistory)
{
this.addMessage(clientVars.chatHistory[i], false); this.addMessage(clientVars.chatHistory[i], false);
} }
$("#chatcounter").text(clientVars.chatHistory.length); $('#chatcounter').text(clientVars.chatHistory.length);
} }
} };
return self; return self;
}()); }());
exports.chat = chat; exports.chat = chat;

View file

@ -20,74 +20,56 @@
* limitations under the License. * limitations under the License.
*/ */
var padutils = require('/pad_utils').padutils; var padutils = require('/pad_utils').padutils,
var padeditor = require('/pad_editor').padeditor; padeditor = require('/pad_editor').padeditor,
var padsavedrevs = require('/pad_savedrevs').padsavedrevs; padsavedrevs = require('/pad_savedrevs').padsavedrevs;
function indexOf(array, value) { function indexOf(array, value) {
for (var i = 0, ii = array.length; i < ii; i++) { for (var i=0, ii=array.length; i < ii; i++) {
if (array[i] == value) { if (array[i] == value)
return i; return i;
}
} }
return -1; return -1;
} }
var padeditbar = (function() var padeditbar = (function() {
{ var syncAnimation = (function() {
var SYNCING = -100,
var syncAnimation = (function() DONE = 100,
{ state = DONE,
var SYNCING = -100; fps = 25,
var DONE = 100; step = 1 / fps,
var state = DONE; T_START = -0.5,
var fps = 25; T_FADE = 1.0,
var step = 1 / fps; T_GONE = 1.5;
var T_START = -0.5; var animator = padutils.makeAnimationScheduler(function() {
var T_FADE = 1.0;
var T_GONE = 1.5;
var animator = padutils.makeAnimationScheduler(function()
{
if (state == SYNCING || state == DONE) if (state == SYNCING || state == DONE)
{
return false; return false;
} else if (state >= T_GONE) {
else if (state >= T_GONE)
{
state = DONE; state = DONE;
$("#syncstatussyncing").css('display', 'none'); $('#syncstatussyncing, #syncstatusdone').hide();
$("#syncstatusdone").css('display', 'none');
return false; return false;
} } else if (state < 0) {
else if (state < 0)
{
state += step; state += step;
if (state >= 0) if (state >= 0) {
{ $('#syncstatussyncing').hide();
$("#syncstatussyncing").css('display', 'none'); $('#syncstatusdone').show().css({opacity: 1});
$("#syncstatusdone").css('display', 'block').css('opacity', 1);
} }
return true; return true;
} } else {
else
{
state += step; state += step;
if (state >= T_FADE) if (state >= T_FADE)
{ $('#syncstatusdone').css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
$("#syncstatusdone").css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
}
return true; return true;
} }
}, step * 1000); }, step * 1000);
return { return {
syncing: function() syncing: function() {
{
state = SYNCING; state = SYNCING;
$("#syncstatussyncing").css('display', 'block'); $('#syncstatussyncing').show();
$("#syncstatusdone").css('display', 'none'); $('#syncstatusdone').hide();
}, },
done: function() done: function() {
{
state = T_START; state = T_START;
animator.scheduleAnimation(); animator.scheduleAnimation();
} }
@ -95,162 +77,117 @@ var padeditbar = (function()
}()); }());
var self = { var self = {
init: function() init: function() {
{ $('#editbar A').attr('unselectable', 'on'); // for IE
$("#editbar .editbarbutton").attr("unselectable", "on"); // for IE $('#editbar').removeClass('disabledtoolbar').addClass('enabledtoolbar');
$("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
}, },
isEnabled: function() isEnabled: function() {
{
// return !$("#editbar").hasClass('disabledtoolbar'); // return !$("#editbar").hasClass('disabledtoolbar');
return true; return true;
}, },
disable: function() disable: function() {
{ $('#editbar').addClass('disabledtoolbar').removeClass('enabledtoolbar');
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
}, },
toolbarClick: function(cmd) toolbarClick: function(cmd) {
{ if (self.isEnabled()) {
if (self.isEnabled()) switch(cmd) {
{ case 'users':
if(cmd == "showusers") self.toggleDropDown('users');
{ break;
self.toogleDropDown("users"); case 'settings':
} self.toggleDropDown('settings');
else if (cmd == 'settings') break;
{ case 'embed':
self.toogleDropDown("settingsmenu"); self.setEmbedLinks();
} self.toggleDropDown('embed');
else if (cmd == 'embed') break;
{ case 'importexport':
self.setEmbedLinks(); self.toggleDropDown('importexport');
$('#linkinput').focus().select(); break;
self.toogleDropDown("embed"); case 'save':
} padsavedrevs.saveNow();
else if (cmd == 'import_export') break;
{ default:
self.toogleDropDown("importexport"); padeditor.ace.callWithAce(function(ace) {
} if (cmd == 'bold' || cmd == 'italic' || cmd == 'underline' || cmd == 'strikethrough')
else if (cmd == 'save') ace.ace_toggleAttributeOnSelection(cmd);
{ else if (cmd == 'undo' || cmd == 'redo')
padsavedrevs.saveNow(); ace.ace_doUndoRedo(cmd);
} else if (cmd == 'insertunorderedlist')
else
{
padeditor.ace.callWithAce(function(ace)
{
if (cmd == 'bold' || cmd == 'italic' || cmd == 'underline' || cmd == 'strikethrough') ace.ace_toggleAttributeOnSelection(cmd);
else if (cmd == 'undo' || cmd == 'redo') ace.ace_doUndoRedo(cmd);
else if (cmd == 'insertunorderedlist') ace.ace_doInsertUnorderedList();
else if (cmd == 'insertorderedlist') ace.ace_doInsertOrderedList();
else if (cmd == 'indent')
{
if (!ace.ace_doIndentOutdent(false))
{
ace.ace_doInsertUnorderedList(); ace.ace_doInsertUnorderedList();
} else if (cmd == 'insertorderedlist')
} ace.ace_doInsertOrderedList();
else if (cmd == 'outdent') else if (cmd == 'indent') {
{ if (!ace.ace_doIndentOutdent(false))
ace.ace_doIndentOutdent(true); ace.ace_doInsertUnorderedList();
} } else if (cmd == 'outdent')
else if (cmd == 'clearauthorship') ace.ace_doIndentOutdent(true);
{ else if (cmd == 'clearauthorship') {
if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) {
{ if (window.confirm("Clear authorship colors on entire document?")) {
if (window.confirm("Clear authorship colors on entire document?")) ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [
{ ['author', '']
ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [ ]);
['author', ''] }
]); } else {
ace.ace_setAttributeOnSelection('author', '');
} }
} }
else }, cmd, true);
{
ace.ace_setAttributeOnSelection('author', '');
}
}
}, cmd, true);
} }
} }
if(padeditor.ace) padeditor.ace.focus(); if (padeditor.ace)
padeditor.ace.focus();
}, },
toogleDropDown: function(moduleName) toggleDropDown: function(moduleName) {
{ var modules = ['settings', 'importexport', 'embed', 'users'],
var modules = ["settingsmenu", "importexport", "embed", "users"]; $module, i, l;
$('#editbar UL.right LI').removeClass('selected');
//hide all modules // hide all modules if no module was passed to this method
if(moduleName == "none") if (moduleName == 'none') {
{ for (i=0, l=modules.length; i < l; i++) {
$("#editbar ul#menu_right > li").removeClass("selected"); // skip the userlist
for(var i=0;i<modules.length;i++) if (modules[i] == 'users')
{
//skip the userlist
if(modules[i] == "users")
continue; continue;
$module = $('#' + modules[i] + 'menu');
var module = $("#" + modules[i]); if ($module.is(':visible'))
$module.slideUp(250);
if(module.css('display') != "none")
{
module.slideUp("fast");
}
} }
} } else {
else // hide all modules that are not selected and show the selected one
{ for (i=0, l=modules.length; i < l; i++) {
var nth_child = indexOf(modules, moduleName) + 1; $module = $('#' + modules[i] + 'menu');
if (nth_child > 0 && nth_child <= 3) { if ($module.is(':visible'))
$("#editbar ul#menu_right li:not(:nth-child(" + nth_child + "))").removeClass("selected"); $module.slideUp(250);
$("#editbar ul#menu_right li:nth-child(" + nth_child + ")").toggleClass("selected"); else if (modules[i] == moduleName) {
} $module.slideDown(250);
//hide all modules that are not selected and show the selected one $('#' + modules[i]).addClass('selected');
for(var i=0;i<modules.length;i++)
{
var module = $("#" + modules[i]);
if(module.css('display') != "none")
{
module.slideUp("fast");
}
else if(modules[i]==moduleName)
{
module.slideDown("fast");
} }
} }
} }
}, },
setSyncStatus: function(status) setSyncStatus: function(status) {
{ if (status == 'syncing')
if (status == "syncing")
{
syncAnimation.syncing(); syncAnimation.syncing();
} else if (status == 'done')
else if (status == "done")
{
syncAnimation.done(); syncAnimation.done();
}
}, },
setEmbedLinks: function() setEmbedLinks: function() {
{ if ($('#readonlyinput').is(':checked')) {
if ($('#readonlyinput').is(':checked')) var basePath = document.location.href.substring(0, document.location.href.indexOf('/p/')),
{ readonlyLink = basePath + '/ro/' + clientVars.readOnlyId;
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
var readonlyLink = basePath + "/ro/" + clientVars.readOnlyId;
$('#embedinput').val("<iframe src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>"); $('#embedinput').val("<iframe src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
$('#linkinput').val(readonlyLink); $('#linkinput').val(readonlyLink);
$('#embedreadonlyqr').attr("src","https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=|0&chl=" + readonlyLink); $('#embedreadonlyqr').attr('src', 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=H|0&chl=' + readonlyLink);
} } else {
else var padurl = window.location.href.split('?')[0];
{
var padurl = window.location.href.split("?")[0];
$('#embedinput').val("<iframe src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>"); $('#embedinput').val("<iframe src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
$('#linkinput').val(padurl); $('#linkinput').val(padurl);
$('#embedreadonlyqr').attr("src","https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=|0&chl=" + padurl); $('#embedreadonlyqr').attr('src', "https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=H|0&chl=" + padurl);
} }
} }
}; };
return self; return self;
}()); }());
exports.padeditbar = padeditbar; exports.padeditbar = padeditbar;

View file

@ -20,223 +20,172 @@
* limitations under the License. * limitations under the License.
*/ */
var padutils = require('/pad_utils').padutils; var padutils = require('/pad_utils').padutils,
myUserInfo = {},
colorPickerOpen = false,
colorPickerSetup = false,
previousColorId = 0;
var myUserInfo = {}; var paduserlist = (function() {
var colorPickerOpen = false; var rowManager = (function() {
var colorPickerSetup = false;
var previousColorId = 0;
var paduserlist = (function()
{
var rowManager = (function()
{
// The row manager handles rendering rows of the user list and animating // The row manager handles rendering rows of the user list and animating
// their insertion, removal, and reordering. It manipulates TD height // their insertion, removal, and reordering. It manipulates TD height
// and TD opacity. // and TD opacity.
function nextRowId() function nextRowId() {
{
return "usertr" + (nextRowId.counter++); return "usertr" + (nextRowId.counter++);
} }
nextRowId.counter = 1; nextRowId.counter = 1;
// objects are shared; fields are "domId","data","animationStep" // objects are shared; fields are "domId","data","animationStep"
var rowsFadingOut = []; // unordered set var rowsFadingOut = [], // unordered set
var rowsFadingIn = []; // unordered set rowsFadingIn = [], // unordered set
var rowsPresent = []; // in order rowsPresent = [], // in order
var ANIMATION_START = -12; // just starting to fade in ANIMATION_START = -12, // just starting to fade in
var ANIMATION_END = 12; // just finishing fading out ANIMATION_END = 12; // just finishing fading out
function getAnimationHeight(step, power) {
function getAnimationHeight(step, power)
{
var a = Math.abs(step / 12); var a = Math.abs(step / 12);
if (power == 2) a = a * a; if (power == 2)
else if (power == 3) a = a * a * a; a = a * a;
else if (power == 4) a = a * a * a * a; else if (power == 3)
else if (power >= 5) a = a * a * a * a * a; a = a * a * a;
else if (power == 4)
a = a * a * a * a;
else if (power >= 5)
a = a * a * a * a * a;
return Math.round(26 * (1 - a)); return Math.round(26 * (1 - a));
} }
var OPACITY_STEPS = 6; var OPACITY_STEPS = 6,
ANIMATION_STEP_TIME = 20,
var ANIMATION_STEP_TIME = 20; LOWER_FRAMERATE_FACTOR = 2,
var LOWER_FRAMERATE_FACTOR = 2; scheduleAnimation = padutils.makeAnimationScheduler(animateStep, ANIMATION_STEP_TIME, LOWER_FRAMERATE_FACTOR).scheduleAnimation,
var scheduleAnimation = padutils.makeAnimationScheduler(animateStep, ANIMATION_STEP_TIME, LOWER_FRAMERATE_FACTOR).scheduleAnimation; NUMCOLS = 4;
var NUMCOLS = 4;
// we do lots of manipulation of table rows and stuff that JQuery makes ok, despite // we do lots of manipulation of table rows and stuff that JQuery makes ok, despite
// IE's poor handling when manipulating the DOM directly. // IE's poor handling when manipulating the DOM directly.
function getEmptyRowHtml(height) function getEmptyRowHtml(height) {
{
return '<td colspan="' + NUMCOLS + '" style="border:0;height:' + height + 'px"><!-- --></td>'; return '<td colspan="' + NUMCOLS + '" style="border:0;height:' + height + 'px"><!-- --></td>';
} }
function isNameEditable(data) function isNameEditable(data) {
{
return (!data.name) && (data.status != 'Disconnected'); return (!data.name) && (data.status != 'Disconnected');
} }
function replaceUserRowContents(tr, height, data) function replaceUserRowContents(tr, height, data) {
{
var tds = getUserRowHtml(height, data).match(/<td.*?<\/td>/gi); var tds = getUserRowHtml(height, data).match(/<td.*?<\/td>/gi);
if (isNameEditable(data) && tr.find("td.usertdname input:enabled").length > 0) if (isNameEditable(data) && tr.find("td.usertdname input:enabled").length > 0) {
{
// preserve input field node // preserve input field node
for (var i = 0; i < tds.length; i++) for (var i=0, l=tds.length; i < l; i++) {
{
var oldTd = $(tr.find("td").get(i)); var oldTd = $(tr.find("td").get(i));
if (!oldTd.hasClass('usertdname')) if (!oldTd.hasClass('usertdname'))
{
oldTd.replaceWith(tds[i]); oldTd.replaceWith(tds[i]);
}
} }
} } else {
else
{
tr.html(tds.join('')); tr.html(tds.join(''));
} }
return tr; return tr;
} }
function getUserRowHtml(height, data) function getUserRowHtml(height, data) {
{ var isGuest = (data.id.charAt(0) != 'p'),
var nameHtml; nameHtml;
var isGuest = (data.id.charAt(0) != 'p'); if (data.name) {
if (data.name)
{
nameHtml = padutils.escapeHtml(data.name); nameHtml = padutils.escapeHtml(data.name);
if (isGuest && pad.getIsProPad()) if (isGuest && pad.getIsProPad())
{
nameHtml += ' (Guest)'; nameHtml += ' (Guest)';
} } else {
}
else
{
nameHtml = '<input type="text" class="editempty newinput" value="unnamed" ' + (isNameEditable(data) ? '' : 'disabled="disabled" ') + '/>'; nameHtml = '<input type="text" class="editempty newinput" value="unnamed" ' + (isNameEditable(data) ? '' : 'disabled="disabled" ') + '/>';
} }
return ['<td style="height:', height, 'px" class="usertdswatch"><div class="swatch" style="background:' + data.color + '">&nbsp;</div></td>', '<td style="height:', height, 'px" class="usertdname">', nameHtml, '</td>', '<td style="height:', height, 'px" class="usertdstatus">', padutils.escapeHtml(data.status), '</td>', '<td style="height:', height, 'px" class="activity">', padutils.escapeHtml(data.activity), '</td>'].join(''); return ['<td style="height:', height, 'px" class="usertdswatch"><div class="swatch" style="background:' + data.color + '">&nbsp;</div></td>', '<td style="height:', height, 'px" class="usertdname">', nameHtml, '</td>', '<td style="height:', height, 'px" class="usertdstatus">', padutils.escapeHtml(data.status), '</td>', '<td style="height:', height, 'px" class="activity">', padutils.escapeHtml(data.activity), '</td>'].join('');
} }
function getRowHtml(id, innerHtml) function getRowHtml(id, innerHtml) {
{
return '<tr id="' + id + '">' + innerHtml + '</tr>'; return '<tr id="' + id + '">' + innerHtml + '</tr>';
} }
function rowNode(row) function rowNode(row) {
{
return $("#" + row.domId); return $("#" + row.domId);
} }
function handleRowData(row) function handleRowData(row) {
{ if (row.data && row.data.status == 'Disconnected') {
if (row.data && row.data.status == 'Disconnected')
{
row.opacity = 0.5; row.opacity = 0.5;
} } else {
else
{
delete row.opacity; delete row.opacity;
} }
} }
function handleRowNode(tr, data) function handleRowNode(tr, data) {
{ if (data.titleText) {
if (data.titleText)
{
var titleText = data.titleText; var titleText = data.titleText;
window.setTimeout(function() window.setTimeout(function() {
{
/* tr.attr('title', titleText)*/ /* tr.attr('title', titleText)*/
}, 0); }, 0);
} } else {
else
{
tr.removeAttr('title'); tr.removeAttr('title');
} }
} }
function handleOtherUserInputs() function handleOtherUserInputs() {
{
// handle 'INPUT' elements for naming other unnamed users // handle 'INPUT' elements for naming other unnamed users
$("#otheruserstable input.newinput").each(function() $('#otheruserstable .newinput')
{ .each(function() {
var input = $(this); var input = $(this),
var tr = input.closest("tr"); tr = input.closest('tr');
if (tr.length > 0) if (tr.length > 0) {
{
var index = tr.parent().children().index(tr); var index = tr.parent().children().index(tr);
if (index >= 0) if (index >= 0) {
{
var userId = rowsPresent[index].data.id; var userId = rowsPresent[index].data.id;
rowManagerMakeNameEditor($(this), userId); rowManagerMakeNameEditor($(this), userId);
} }
} }
}).removeClass('newinput'); })
.removeClass('newinput');
} }
// animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc. // animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc.
function insertRow(position, data, animationPower) {
function insertRow(position, data, animationPower)
{
position = Math.max(0, Math.min(rowsPresent.length, position)); position = Math.max(0, Math.min(rowsPresent.length, position));
animationPower = (animationPower === undefined ? 4 : animationPower); animationPower = (animationPower === undefined ? 4 : animationPower);
var domId = nextRowId(); var domId = nextRowId(),
var row = { row = {
data: data, data : data,
animationStep: ANIMATION_START, animationStep : ANIMATION_START,
domId: domId, domId : domId,
animationPower: animationPower animationPower: animationPower
}; },
tr;
handleRowData(row); handleRowData(row);
rowsPresent.splice(position, 0, row); rowsPresent.splice(position, 0, row);
var tr; if (animationPower == 0) {
if (animationPower == 0)
{
tr = $(getRowHtml(domId, getUserRowHtml(getAnimationHeight(0), data))); tr = $(getRowHtml(domId, getUserRowHtml(getAnimationHeight(0), data)));
row.animationStep = 0; row.animationStep = 0;
} } else {
else
{
rowsFadingIn.push(row); rowsFadingIn.push(row);
tr = $(getRowHtml(domId, getEmptyRowHtml(getAnimationHeight(ANIMATION_START)))); tr = $(getRowHtml(domId, getEmptyRowHtml(getAnimationHeight(ANIMATION_START))));
} }
handleRowNode(tr, data); handleRowNode(tr, data);
if (position == 0) if (position == 0)
{ $('#otheruserstable').prepend(tr);
$("table#otheruserstable").prepend(tr);
}
else else
{
rowNode(rowsPresent[position - 1]).after(tr); rowNode(rowsPresent[position - 1]).after(tr);
}
if (animationPower != 0) if (animationPower != 0)
{
scheduleAnimation(); scheduleAnimation();
}
handleOtherUserInputs(); handleOtherUserInputs();
return row; return row;
} }
function updateRow(position, data) function updateRow(position, data) {
{
var row = rowsPresent[position]; var row = rowsPresent[position];
if (row) if (row) {
{
row.data = data; row.data = data;
handleRowData(row); handleRowData(row);
if (row.animationStep == 0) if (row.animationStep == 0) {
{
// not currently animating // not currently animating
var tr = rowNode(row); var tr = rowNode(row);
replaceUserRowContents(tr, getAnimationHeight(0), row.data).find("td").css('opacity', (row.opacity === undefined ? 1 : row.opacity)); replaceUserRowContents(tr, getAnimationHeight(0), row.data).find("td").css('opacity', (row.opacity === undefined ? 1 : row.opacity));
@ -246,19 +195,14 @@ var paduserlist = (function()
} }
} }
function removeRow(position, animationPower) function removeRow(position, animationPower) {
{
animationPower = (animationPower === undefined ? 4 : animationPower); animationPower = (animationPower === undefined ? 4 : animationPower);
var row = rowsPresent[position]; var row = rowsPresent[position];
if (row) if (row) {
{
rowsPresent.splice(position, 1); // remove rowsPresent.splice(position, 1); // remove
if (animationPower == 0) if (animationPower == 0) {
{
rowNode(row).remove(); rowNode(row).remove();
} } else {
else
{
row.animationStep = -row.animationStep; // use symmetry row.animationStep = -row.animationStep; // use symmetry
row.animationPower = animationPower; row.animationPower = animationPower;
rowsFadingOut.push(row); rowsFadingOut.push(row);
@ -269,127 +213,98 @@ var paduserlist = (function()
// newPosition is position after the row has been removed // newPosition is position after the row has been removed
function moveRow(oldPosition, newPosition, animationPower) {
function moveRow(oldPosition, newPosition, animationPower)
{
animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best
var row = rowsPresent[oldPosition]; var row = rowsPresent[oldPosition];
if (row && oldPosition != newPosition) if (row && oldPosition != newPosition) {
{
var rowData = row.data; var rowData = row.data;
removeRow(oldPosition, animationPower); removeRow(oldPosition, animationPower);
insertRow(newPosition, rowData, animationPower); insertRow(newPosition, rowData, animationPower);
} }
} }
function animateStep() function animateStep() {
{ var row, step, node, $td, animHeight, baseOpacity, i;
// animation must be symmetrical // animation must be symmetrical
for (var i = rowsFadingIn.length - 1; i >= 0; i--) for (i=rowsFadingIn.length - 1; i >= 0; i--) { // backwards to allow removal
{ // backwards to allow removal row = rowsFadingIn[i];
var row = rowsFadingIn[i]; step = ++row.animationStep;
var step = ++row.animationStep; animHeight = getAnimationHeight(step, row.animationPower);
var animHeight = getAnimationHeight(step, row.animationPower); node = rowNode(row);
var node = rowNode(row); $td = node.find('TD');
var baseOpacity = (row.opacity === undefined ? 1 : row.opacity); baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
if (step <= -OPACITY_STEPS) if (step <= -OPACITY_STEPS)
{ $td.height(animHeight);
node.find("td").height(animHeight); else if (step == -OPACITY_STEPS + 1) {
} node.html(getUserRowHtml(animHeight, row.data)).find('TD').css('opacity', baseOpacity * 1 / OPACITY_STEPS);
else if (step == -OPACITY_STEPS + 1)
{
node.html(getUserRowHtml(animHeight, row.data)).find("td").css('opacity', baseOpacity * 1 / OPACITY_STEPS);
handleRowNode(node, row.data); handleRowNode(node, row.data);
} } else if (step < 0) {
else if (step < 0) $td.css('opacity', baseOpacity * (OPACITY_STEPS - (-step)) / OPACITY_STEPS).height(animHeight);
{ } else if (step == 0) {
node.find("td").css('opacity', baseOpacity * (OPACITY_STEPS - (-step)) / OPACITY_STEPS).height(animHeight);
}
else if (step == 0)
{
// set HTML in case modified during animation // set HTML in case modified during animation
node.html(getUserRowHtml(animHeight, row.data)).find("td").css('opacity', baseOpacity * 1).height(animHeight); node.html(getUserRowHtml(animHeight, row.data)).find('TD').css('opacity', baseOpacity * 1).height(animHeight);
handleRowNode(node, row.data); handleRowNode(node, row.data);
rowsFadingIn.splice(i, 1); // remove from set rowsFadingIn.splice(i, 1); // remove from set
} }
} }
for (var i = rowsFadingOut.length - 1; i >= 0; i--) for (i=rowsFadingOut.length - 1; i >= 0; i--) { // backwards to allow removal
{ // backwards to allow removal row = rowsFadingOut[i];
var row = rowsFadingOut[i]; step = ++row.animationStep;
var step = ++row.animationStep; node = rowNode(row);
var node = rowNode(row); $td = node.find('TD');
var animHeight = getAnimationHeight(step, row.animationPower); animHeight = getAnimationHeight(step, row.animationPower);
var baseOpacity = (row.opacity === undefined ? 1 : row.opacity); baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
if (step < OPACITY_STEPS) if (step < OPACITY_STEPS)
{ $td.css('opacity', baseOpacity * (OPACITY_STEPS - step) / OPACITY_STEPS).height(animHeight);
node.find("td").css('opacity', baseOpacity * (OPACITY_STEPS - step) / OPACITY_STEPS).height(animHeight);
}
else if (step == OPACITY_STEPS) else if (step == OPACITY_STEPS)
{
node.html(getEmptyRowHtml(animHeight)); node.html(getEmptyRowHtml(animHeight));
}
else if (step <= ANIMATION_END) else if (step <= ANIMATION_END)
{ $td.height(animHeight);
node.find("td").height(animHeight); else {
}
else
{
rowsFadingOut.splice(i, 1); // remove from set rowsFadingOut.splice(i, 1); // remove from set
node.remove(); node.remove();
} }
} }
handleOtherUserInputs(); handleOtherUserInputs();
return (rowsFadingIn.length > 0) || (rowsFadingOut.length > 0); // is more to do return (rowsFadingIn.length > 0) || (rowsFadingOut.length > 0); // is more to do
} }
var self = { var self = {
insertRow: insertRow, insertRow : insertRow,
removeRow: removeRow, removeRow : removeRow,
moveRow: moveRow, moveRow : moveRow,
updateRow: updateRow updateRow : updateRow
}; };
return self; return self;
}()); ////////// rowManager }());
var otherUsersInfo = []; // rowManager END #########################################################
var otherUsersData = [];
function rowManagerMakeNameEditor(jnode, userId) var otherUsersInfo = [],
{ otherUsersData = [];
setUpEditable(jnode, function()
{ function rowManagerMakeNameEditor(jnode, userId) {
setUpEditable(jnode, function() {
var existingIndex = findExistingIndex(userId); var existingIndex = findExistingIndex(userId);
if (existingIndex >= 0) if (existingIndex >= 0)
{
return otherUsersInfo[existingIndex].name || ''; return otherUsersInfo[existingIndex].name || '';
}
else else
{
return ''; return '';
} }, function(newName) {
}, function(newName) if (!newName) {
{
if (!newName)
{
jnode.addClass("editempty"); jnode.addClass("editempty");
jnode.val("unnamed"); jnode.val("unnamed");
} } else {
else
{
jnode.attr('disabled', 'disabled'); jnode.attr('disabled', 'disabled');
pad.suggestUserName(userId, newName); pad.suggestUserName(userId, newName);
} }
}); });
} }
function findExistingIndex(userId) function findExistingIndex(userId) {
{
var existingIndex = -1; var existingIndex = -1;
for (var i = 0; i < otherUsersInfo.length; i++) for (var i=0, l=otherUsersInfo.length; i < l; i++) {
{ if (otherUsersInfo[i].userId == userId) {
if (otherUsersInfo[i].userId == userId)
{
existingIndex = i; existingIndex = i;
break; break;
} }
@ -397,68 +312,49 @@ var paduserlist = (function()
return existingIndex; return existingIndex;
} }
function setUpEditable(jqueryNode, valueGetter, valueSetter) function setUpEditable(jqueryNode, valueGetter, valueSetter) {
{ jqueryNode
jqueryNode.bind('focus', function(evt) .bind('focus', function(evt) {
{
var oldValue = valueGetter(); var oldValue = valueGetter();
if (jqueryNode.val() !== oldValue) if (jqueryNode.val() !== oldValue)
{
jqueryNode.val(oldValue); jqueryNode.val(oldValue);
} jqueryNode.addClass('editactive').removeClass('editempty');
jqueryNode.addClass("editactive").removeClass("editempty"); })
}); .bind('blur', function(evt) {
jqueryNode.bind('blur', function(evt) var newValue = jqueryNode.removeClass('editactive').val();
{
var newValue = jqueryNode.removeClass("editactive").val();
valueSetter(newValue); valueSetter(newValue);
}); });
padutils.bindEnterAndEscape(jqueryNode, function onEnter()
{ padutils.bindEnterAndEscape(jqueryNode,
jqueryNode.blur(); function onEnter() {jqueryNode.blur();},
}, function onEscape() function onEscape() {jqueryNode.val(valueGetter()).blur();
{
jqueryNode.val(valueGetter()).blur();
}); });
jqueryNode.removeAttr('disabled').addClass('editable'); jqueryNode.removeAttr('disabled').addClass('editable');
} }
function updateInviteNotice() function updateInviteNotice() {
{ if (otherUsersInfo.length == 0) {
if (otherUsersInfo.length == 0) $('#otheruserstable').hide();
{ $('#nootherusers').show();
$("#otheruserstable").hide(); } else {
$("#nootherusers").show(); $('#nootherusers').hide();
} $('#otheruserstable').show();
else
{
$("#nootherusers").hide();
$("#otheruserstable").show();
} }
} }
var knocksToIgnore = {}; var knocksToIgnore = {},
var guestPromptFlashState = 0; guestPromptFlashState = 0;
var guestPromptFlash = padutils.makeAnimationScheduler(
function()
{
var prompts = $("#guestprompts .guestprompt");
if (prompts.length == 0)
{
return false; // no more to do
}
guestPromptFlashState = 1 - guestPromptFlashState;
if (guestPromptFlashState)
{
prompts.css('background', '#ffa');
}
else
{
prompts.css('background', '#ffe');
}
var guestPromptFlash = padutils.makeAnimationScheduler(
function() {
var prompts = $("#guestprompts .guestprompt");
if (prompts.length == 0)
return false; // no more to do
guestPromptFlashState = 1 - guestPromptFlashState;
if (guestPromptFlashState)
prompts.css('background', '#ffa');
else
prompts.css('background', '#ffe');
return true; return true;
}, 1000); }, 1000);
@ -492,85 +388,51 @@ var paduserlist = (function()
} }
// color picker // color picker
$("#myswatchbox").click(showColorPicker); $('#myswatchbox').click(showColorPicker);
$("#mycolorpicker .pickerswatchouter").click(function() $('#mycolorpickersave').click(function() {closeColorPicker(true);});
{ $('#mycolorpickercancel').click(function() {closeColorPicker(false);});
$("#mycolorpicker .pickerswatchouter").removeClass('picked');
$(this).addClass('picked');
});
$("#mycolorpickersave").click(function()
{
closeColorPicker(true);
});
$("#mycolorpickercancel").click(function()
{
closeColorPicker(false);
});
//
}, },
setMyUserInfo: function(info) setMyUserInfo: function(info) {
{
//translate the colorId //translate the colorId
if(typeof info.colorId == "number") if (typeof info.colorId == 'number')
{
info.colorId = clientVars.colorPalette[info.colorId]; info.colorId = clientVars.colorPalette[info.colorId];
} myUserInfo = $.extend({}, info);
myUserInfo = $.extend(
{}, info);
self.renderMyUserInfo(); self.renderMyUserInfo();
}, },
userJoinOrUpdate: function(info) userJoinOrUpdate: function(info) {
{
if ((!info.userId) || (info.userId == myUserInfo.userId)) if ((!info.userId) || (info.userId == myUserInfo.userId))
{ return; // not sure how this would happen
// not sure how this would happen
return;
}
var userData = {}; var userData = {};
userData.color = typeof info.colorId == "number" ? clientVars.colorPalette[info.colorId] : info.colorId; userData.color = typeof info.colorId == "number" ? clientVars.colorPalette[info.colorId] : info.colorId;
userData.name = info.name; userData.name = info.name;
userData.status = ''; userData.status = '';
userData.activity = ''; userData.activity = '';
userData.id = info.userId; userData.id = info.userId;
// Firefox ignores \n in title text; Safari does a linebreak // Firefox ignores \n in title text; Safari does a linebreak
userData.titleText = [info.userAgent || '', info.ip || ''].join(' \n'); userData.titleText = [info.userAgent || '', info.ip || ''].join(' \n');
var existingIndex = findExistingIndex(info.userId); var existingIndex = findExistingIndex(info.userId);
var numUsersBesides = otherUsersInfo.length; var numUsersBesides = otherUsersInfo.length;
if (existingIndex >= 0) if (existingIndex >= 0)
{
numUsersBesides--; numUsersBesides--;
} var newIndex = padutils.binarySearch(numUsersBesides, function(n) {
var newIndex = padutils.binarySearch(numUsersBesides, function(n)
{
if (existingIndex >= 0 && n >= existingIndex) if (existingIndex >= 0 && n >= existingIndex)
{ n++; // pretend existingIndex isn't there
// pretend existingIndex isn't there var infoN = otherUsersInfo[n],
n++; nameN = (infoN.name || '').toLowerCase(),
} nameThis = (info.name || '').toLowerCase(),
var infoN = otherUsersInfo[n]; idN = infoN.userId,
var nameN = (infoN.name || '').toLowerCase(); idThis = info.userId;
var nameThis = (info.name || '').toLowerCase();
var idN = infoN.userId;
var idThis = info.userId;
return (nameN > nameThis) || (nameN == nameThis && idN > idThis); return (nameN > nameThis) || (nameN == nameThis && idN > idThis);
}); });
if (existingIndex >= 0) if (existingIndex >= 0) {
{
// update // update
if (existingIndex == newIndex) if (existingIndex == newIndex) {
{
otherUsersInfo[existingIndex] = info; otherUsersInfo[existingIndex] = info;
otherUsersData[existingIndex] = userData; otherUsersData[existingIndex] = userData;
rowManager.updateRow(existingIndex, userData); rowManager.updateRow(existingIndex, userData);
} } else {
else
{
otherUsersInfo.splice(existingIndex, 1); otherUsersInfo.splice(existingIndex, 1);
otherUsersData.splice(existingIndex, 1); otherUsersData.splice(existingIndex, 1);
otherUsersInfo.splice(newIndex, 0, info); otherUsersInfo.splice(newIndex, 0, info);
@ -578,56 +440,42 @@ var paduserlist = (function()
rowManager.updateRow(existingIndex, userData); rowManager.updateRow(existingIndex, userData);
rowManager.moveRow(existingIndex, newIndex); rowManager.moveRow(existingIndex, newIndex);
} }
} } else {
else
{
otherUsersInfo.splice(newIndex, 0, info); otherUsersInfo.splice(newIndex, 0, info);
otherUsersData.splice(newIndex, 0, userData); otherUsersData.splice(newIndex, 0, userData);
rowManager.insertRow(newIndex, userData); rowManager.insertRow(newIndex, userData);
} }
updateInviteNotice(); updateInviteNotice();
self.updateNumberOfOnlineUsers(); self.updateNumberOfOnlineUsers();
}, },
updateNumberOfOnlineUsers: function() updateNumberOfOnlineUsers: function() {
{
var online = 1; // you are always online! var online = 1; // you are always online!
for (var i = 0; i < otherUsersData.length; i++) for (var i=0, l=otherUsersData.length; i < l; i++) {
{ if (otherUsersData[i].status === '')
if (otherUsersData[i].status == "")
{
online++; online++;
}
} }
$("#online_count").text(online);
$('#usericonback').text(online);
return online; return online;
}, },
userLeave: function(info) userLeave: function(info) {
{
var existingIndex = findExistingIndex(info.userId); var existingIndex = findExistingIndex(info.userId);
if (existingIndex >= 0) if (existingIndex >= 0) {
{
var userData = otherUsersData[existingIndex]; var userData = otherUsersData[existingIndex];
userData.status = 'Disconnected'; userData.status = 'Disconnected';
rowManager.updateRow(existingIndex, userData); rowManager.updateRow(existingIndex, userData);
if (userData.leaveTimer) if (userData.leaveTimer)
{
window.clearTimeout(userData.leaveTimer); window.clearTimeout(userData.leaveTimer);
}
// set up a timer that will only fire if no leaves, // set up a timer that will only fire if no leaves,
// joins, or updates happen for this user in the // joins, or updates happen for this user in the
// next N seconds, to remove the user from the list. // next N seconds, to remove the user from the list.
var thisUserId = info.userId; var thisUserId = info.userId;
var thisLeaveTimer = window.setTimeout(function() var thisLeaveTimer = window.setTimeout(function() {
{
var newExistingIndex = findExistingIndex(thisUserId); var newExistingIndex = findExistingIndex(thisUserId);
if (newExistingIndex >= 0) if (newExistingIndex >= 0) {
{
var newUserData = otherUsersData[newExistingIndex]; var newUserData = otherUsersData[newExistingIndex];
if (newUserData.status == 'Disconnected' && newUserData.leaveTimer == thisLeaveTimer) if (newUserData.status == 'Disconnected' && newUserData.leaveTimer == thisLeaveTimer) {
{
otherUsersInfo.splice(newExistingIndex, 1); otherUsersInfo.splice(newExistingIndex, 1);
otherUsersData.splice(newExistingIndex, 1); otherUsersData.splice(newExistingIndex, 1);
rowManager.removeRow(newExistingIndex); rowManager.removeRow(newExistingIndex);
@ -638,177 +486,121 @@ var paduserlist = (function()
userData.leaveTimer = thisLeaveTimer; userData.leaveTimer = thisLeaveTimer;
} }
updateInviteNotice(); updateInviteNotice();
self.updateNumberOfOnlineUsers(); self.updateNumberOfOnlineUsers();
}, },
showGuestPrompt: function(userId, displayName) showGuestPrompt: function(userId, displayName) {
{
if (knocksToIgnore[userId]) if (knocksToIgnore[userId])
{
return; return;
}
var encodedUserId = padutils.encodeUserId(userId); var encodedUserId = padutils.encodeUserId(userId);
var actionName = 'hide-guest-prompt-' + encodedUserId; var actionName = 'hide-guest-prompt-' + encodedUserId;
padutils.cancelActions(actionName); padutils.cancelActions(actionName);
var box = $('#guestprompt-' + encodedUserId);
var box = $("#guestprompt-" + encodedUserId); if (box.length == 0) {
if (box.length == 0)
{
// make guest prompt box // make guest prompt box
box = $('<div id="'+padutils.escapeHtml('guestprompt-' + encodedUserId) + '" class="guestprompt"><div class="choices"><a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',false))')+'">Deny</a> <a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',true))') + '">Approve</a></div><div class="guestname"><strong>Guest:</strong> ' + padutils.escapeHtml(displayName) + '</div></div>'); box = $('<div id="'+padutils.escapeHtml('guestprompt-' + encodedUserId) + '" class="guestprompt"><div class="choices"><a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',false))')+'">Deny</a> <a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',true))') + '">Approve</a></div><div class="guestname"><strong>Guest:</strong> ' + padutils.escapeHtml(displayName) + '</div></div>');
$("#guestprompts").append(box); $('#guestprompts').append(box);
} } else {
else
{
// update display name // update display name
box.find(".guestname").html('<strong>Guest:</strong> ' + padutils.escapeHtml(displayName)); box.find('.guestname').html('<strong>Guest:</strong> ' + padutils.escapeHtml(displayName));
} }
var hideLater = padutils.getCancellableAction(actionName, function() var hideLater = padutils.getCancellableAction(actionName, function() {
{
self.removeGuestPrompt(userId); self.removeGuestPrompt(userId);
}); });
window.setTimeout(hideLater, 15000); // time-out with no knock window.setTimeout(hideLater, 15000); // time-out with no knock
guestPromptFlash.scheduleAnimation(); guestPromptFlash.scheduleAnimation();
}, },
removeGuestPrompt: function(userId) removeGuestPrompt: function(userId) {
{
var box = $("#guestprompt-" + padutils.encodeUserId(userId)); var box = $("#guestprompt-" + padutils.encodeUserId(userId));
// remove ID now so a new knock by same user gets new, unfaded box // remove ID now so a new knock by same user gets new, unfaded box
box.removeAttr('id').fadeOut("fast", function() box.removeAttr('id').fadeOut(250, function() {
{
box.remove(); box.remove();
}); });
knocksToIgnore[userId] = true; knocksToIgnore[userId] = true;
window.setTimeout(function() window.setTimeout(function() {
{
delete knocksToIgnore[userId]; delete knocksToIgnore[userId];
}, 5000); }, 5000);
}, },
answerGuestPrompt: function(encodedUserId, approve) answerGuestPrompt: function(encodedUserId, approve) {
{
var guestId = padutils.decodeUserId(encodedUserId); var guestId = padutils.decodeUserId(encodedUserId);
var msg = { var msg = {
type: 'guestanswer', type : 'guestanswer',
authId: pad.getUserId(), authId : pad.getUserId(),
guestId: guestId, guestId : guestId,
answer: (approve ? "approved" : "denied") answer : (approve ? 'approved' : 'denied')
}; };
pad.sendClientMessage(msg); pad.sendClientMessage(msg);
self.removeGuestPrompt(guestId); self.removeGuestPrompt(guestId);
}, },
renderMyUserInfo: function() renderMyUserInfo: function() {
{
if (myUserInfo.name) if (myUserInfo.name)
{ $('#myusernameedit').removeClass('editempty').val(myUserInfo.name);
$("#myusernameedit").removeClass("editempty").val(
myUserInfo.name);
}
else else
{ $('#myusernameedit').addClass('editempty').val('Enter your name');
$("#myusernameedit").addClass("editempty").val("Enter your name");
}
if (colorPickerOpen) if (colorPickerOpen)
{ $('#myswatchbox').addClass('myswatchboxunhoverable').removeClass('myswatchboxhoverable');
$("#myswatchbox").addClass('myswatchboxunhoverable').removeClass('myswatchboxhoverable');
}
else else
{ $('#myswatchbox').addClass('myswatchboxhoverable').removeClass('myswatchboxunhoverable');
$("#myswatchbox").addClass('myswatchboxhoverable').removeClass('myswatchboxunhoverable'); $('#myswatch').css({backgroundColor: myUserInfo.colorId});
} $('#usericon').css({backgroundColor: myUserInfo.colorId});
$("#myswatch").css({'background-color': myUserInfo.colorId});
if ($.browser.msie && parseInt($.browser.version) <= 8) {
$("#usericon").css({'box-shadow': 'inset 0 0 30px ' + myUserInfo.colorId,'background-color': myUserInfo.colorId});
}
else
{
$("#usericon").css({'box-shadow': 'inset 0 0 30px ' + myUserInfo.colorId});
}
} }
}; };
return self; return self;
}()); }());
function getColorPickerSwatchIndex(jnode) function getColorPickerSwatchIndex(jnode) {
{ return $('#colorpickerswatches LI').index(jnode);
// return Number(jnode.get(0).className.match(/\bn([0-9]+)\b/)[1])-1;
return $("#colorpickerswatches li").index(jnode);
} }
function closeColorPicker(accept) function closeColorPicker(accept) {
{ if (accept) {
if (accept) var newColor = $("#mycolorpickerpreview").css('background-color'),
{ parts = newColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
var newColor = $("#mycolorpickerpreview").css("background-color");
var parts = newColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
// parts now should be ["rgb(0, 70, 255", "0", "70", "255"] // parts now should be ["rgb(0, 70, 255", "0", "70", "255"]
delete (parts[0]); delete (parts[0]);
for (var i = 1; i <= 3; ++i) { for (var i = 1; i <= 3; ++i) {
parts[i] = parseInt(parts[i]).toString(16); parts[i] = parseInt(parts[i], 10).toString(16);
if (parts[i].length == 1) parts[i] = '0' + parts[i]; if (parts[i].length == 1) parts[i] = '0' + parts[i];
} }
var newColor = "#" +parts.join(''); // "0070ff" newColor = "#" + parts.join(''); // "0070ff"
myUserInfo.colorId = newColor; myUserInfo.colorId = newColor;
pad.notifyChangeColor(newColor); pad.notifyChangeColor(newColor);
paduserlist.renderMyUserInfo(); paduserlist.renderMyUserInfo();
} } else {
else
{
//pad.notifyChangeColor(previousColorId); //pad.notifyChangeColor(previousColorId);
//paduserlist.renderMyUserInfo(); //paduserlist.renderMyUserInfo();
} }
colorPickerOpen = false; colorPickerOpen = false;
$("#mycolorpicker").fadeOut("fast"); $('#mycolorpicker').fadeOut(250);
} }
function showColorPicker() function showColorPicker() {
{ var previousColorId = myUserInfo.colorId,
previousColorId = myUserInfo.colorId; $colorsList = $('#colorpickerswatches'),
picked = 'picked',
$swatchesList, $li;
if (!colorPickerOpen) if (!colorPickerOpen) {
{
var palette = pad.getColorPalette(); var palette = pad.getColorPalette();
if (!colorPickerSetup) {
if (!colorPickerSetup) for (var i=0, l=palette.length; i < l; i++) {
{ $li = $('<li>', {style: 'background: ' + palette[i] + ';'});
var colorsList = $("#colorpickerswatches") $li.appendTo($colorsList);
for (var i = 0; i < palette.length; i++) $li.bind('click', function(e) {
{ $('LI', $colorsList).removeClass(picked);
$(e.target).addClass(picked);
var li = $('<li>', { var newColorId = getColorPickerSwatchIndex($('#colorpickerswatches .picked'));
style: 'background: ' + palette[i] + ';'
});
li.appendTo(colorsList);
li.bind('click', function(event)
{
$("#colorpickerswatches li").removeClass('picked');
$(event.target).addClass("picked");
var newColorId = getColorPickerSwatchIndex($("#colorpickerswatches .picked"));
pad.notifyChangeColor(newColorId); pad.notifyChangeColor(newColorId);
}); });
} }
colorPickerSetup = true; colorPickerSetup = true;
} }
$('#mycolorpicker').fadeIn(250);
$("#mycolorpicker").fadeIn(); $swatchesList = $('#colorpickerswatches LI');
colorPickerOpen = true; colorPickerOpen = true;
$swatchesList.removeClass(picked);
$("#colorpickerswatches li").removeClass('picked'); $($swatchesList[myUserInfo.colorId]).addClass(picked); //seems weird
$($("#colorpickerswatches li")[myUserInfo.colorId]).addClass("picked"); //seems weird
} }
} }
exports.paduserlist = paduserlist; exports.paduserlist = paduserlist;

View file

@ -26,129 +26,109 @@ require('/jquery');
JSON = require('/json2'); JSON = require('/json2');
require('/undo-xpopup'); require('/undo-xpopup');
var createCookie = require('/pad_utils').createCookie; var createCookie = require('/pad_utils').createCookie,
var readCookie = require('/pad_utils').readCookie; readCookie = require('/pad_utils').readCookie,
var randomString = require('/pad_utils').randomString; randomString = require('/pad_utils').randomString,
socket, token, padId, export_links;
var socket, token, padId, export_links;
function init() { function init() {
$(document).ready(function () $(document).ready(function () {
{
// start the custom js // start the custom js
if (typeof customStart == "function") customStart(); if (typeof customStart == 'function')
customStart();
//get the padId out of the url // get padId from url
var urlParts= document.location.pathname.split("/"); var urlParts = document.location.pathname.split('/');
padId = decodeURIComponent(urlParts[urlParts.length-2]); padId = decodeURIComponent(urlParts[urlParts.length - 2]);
//set the title // set the title
document.title = padId.replace(/_+/g, ' ') + " | " + document.title; document.title = padId.replace(/_+/g, ' ') + ' | ' + document.title;
//ensure we have a token // ensure we have a token
token = readCookie("token"); token = readCookie('token');
if(token == null) if (token == null) {
{ token = 't.' + randomString();
token = "t." + randomString(); createCookie('token', token, 60);
createCookie("token", token, 60);
} }
var loc = document.location; var loc = document.location,
//get the correct port port = loc.port == '' ? (loc.protocol == 'https:' ? 443 : 80) : loc.port, // get the correct port
var port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port; url = loc.protocol + '//' + loc.hostname + ':' + port + '/', // create the url
//create the url resource = loc.pathname.substr(1, loc.pathname.indexOf('/p/')) + 'socket.io'; // find out in which subfolder we are
var url = loc.protocol + "//" + loc.hostname + ":" + port + "/";
//find out in which subfolder we are
var resource = loc.pathname.substr(1,loc.pathname.indexOf("/p/")) + "socket.io";
//build up the socket io connection // build up the socket io connection
socket = io.connect(url, {resource: resource}); socket = io.connect(url, {resource: resource});
//send the ready message once we're connected // send the ready message once we're connected
socket.on('connect', function() socket.on('connect', function() {
{ sendSocketMsg('CLIENT_READY', {});
sendSocketMsg("CLIENT_READY", {});
}); });
//route the incoming messages // route the incoming messages
socket.on('message', function(message) socket.on('message', function(message) {
{ if (window.console)
if(window.console) console.log(message); console.log(message);
if (message.type == 'CLIENT_VARS')
if(message.type == "CLIENT_VARS")
{
handleClientVars(message); handleClientVars(message);
} else if (message.type == 'CHANGESET_REQ')
else if(message.type == "CHANGESET_REQ")
{
changesetLoader.handleSocketResponse(message); changesetLoader.handleSocketResponse(message);
} else if (message.accessStatus)
else if(message.accessStatus) $('BODY').html('<h2>You have no permission to access this pad</h2>');
{
$("body").html("<h2>You have no permission to access this pad</h2>")
}
}); });
//get all the export links // get all export links
export_links = $('#export > .exportlink') export_links = $('.exportlink');
if(document.referrer.length > 0 && document.referrer.substring(document.referrer.lastIndexOf("/")-1,document.referrer.lastIndexOf("/")) === "p") { if (document.referrer.length > 0 && document.referrer.substring(document.referrer.lastIndexOf('/') - 1, document.referrer.lastIndexOf('/')) === 'p')
$("#returnbutton").attr("href", document.referrer); $('#returnbutton A').attr('href', document.referrer);
} else { else
$("#returnbutton").attr("href", document.location.href.substring(0,document.location.href.lastIndexOf("/"))); $('#returnbutton A').attr('href', document.location.href.substring(0, document.location.href.lastIndexOf('/')));
}
}); });
} }
//sends a message over the socket // send a message over the socket
function sendSocketMsg(type, data) function sendSocketMsg(type, data) {
{ var sessionID = readCookie('sessionID'),
var sessionID = readCookie("sessionID"); password = readCookie('password'),
var password = readCookie("password"); msg = { 'component' : 'timeslider',
'type' : type,
var msg = { "component" : "timeslider", 'data' : data,
"type": type, 'padId' : padId,
"data": data, 'token' : token,
"padId": padId, 'sessionID' : sessionID,
"token": token, 'password' : password,
"sessionID": sessionID, 'protocolVersion' : 2
"password": password, };
"protocolVersion": 2};
socket.json.send(msg); socket.json.send(msg);
} }
var fireWhenAllScriptsAreLoaded = []; var fireWhenAllScriptsAreLoaded = [],
BroadcastSlider, changesetLoader;
var BroadcastSlider, changesetLoader;
function handleClientVars(message) function handleClientVars(message) {
{ // save the client Vars
//save the client Vars
clientVars = message.data; clientVars = message.data;
//load all script that doesn't work without the clientVars // load all scripts that don't work without the clientVars
BroadcastSlider = require('/broadcast_slider').loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded); BroadcastSlider = require('/broadcast_slider').loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded);
require('/broadcast_revisions').loadBroadcastRevisionsJS(); require('/broadcast_revisions').loadBroadcastRevisionsJS();
changesetLoader = require('/broadcast').loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider); changesetLoader = require('/broadcast').loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider);
//initialize export ui // initialize export ui
require('/pad_impexp').padimpexp.init(); require('/pad_impexp').padimpexp.init();
//change export urls when the slider moves // change export urls when the slider moves
var export_rev_regex = /(\/\d+)?\/export/ var export_rev_regex = /(\/\d+)?\/export/;
BroadcastSlider.onSlider(function(revno) BroadcastSlider.onSlider(function(revno) {
{ export_links.each(function() {
export_links.each(function()
{
this.setAttribute('href', this.href.replace(export_rev_regex, '/' + revno + '/export')); this.setAttribute('href', this.href.replace(export_rev_regex, '/' + revno + '/export'));
}); });
}); });
//fire all start functions of these scripts, formerly fired with window.load // fire all start functions of these scripts, formerly fired with window.load
for(var i=0;i < fireWhenAllScriptsAreLoaded.length;i++) for (var i=0, l=fireWhenAllScriptsAreLoaded.length; i < l; i++) {
{
fireWhenAllScriptsAreLoaded[i](); fireWhenAllScriptsAreLoaded[i]();
} }
} }
exports.init = init; exports.init = init;

View file

@ -1,311 +1,232 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<title>Etherpad Lite</title>
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link href="../static/css/pad.css" rel="stylesheet">
<link href="../static/custom/pad.css" rel="stylesheet">
<style title="dynamicsyntax"></style>
</head>
<body>
<div id="editbar">
<ul class="left">
<li id="bold" class="group-start" onClick="window.pad&amp;&amp;pad.editbarClick('bold');return false" title="Bold (ctrl-B)"></li>
<li id="italic" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('italic'); return false;" title="Italics (ctrl-I)"></li>
<li id="underline" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('underline');return false;" title="Underline (ctrl-U)"></li>
<li id="strikethrough" class="group-end" onClick="window.pad&amp;&amp;pad.editbarClick('strikethrough');return false;" title="Strikethrough"></li>
<li id="orderedlist" class="group-start" onClick="window.pad&amp;&amp;pad.editbarClick('insertorderedlist');return false;" title="Toggle Ordered List"></li>
<li id="unorderedlist" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('insertunorderedlist');return false;" title="Toggle Bullet List"></li>
<li id="indent" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('indent');return false;" title="Indent"></li>
<li id="outdent" class="group-end" onClick="window.pad&amp;&amp;pad.editbarClick('outdent');return false;" title="Unindent"></li>
<li id="undo" class="group-start" onClick="window.pad&amp;&amp;pad.editbarClick('undo');return false;" title="Undo (ctrl-Z)"></li>
<li id="redo" class="group-end" onClick="window.pad&amp;&amp;pad.editbarClick('redo');return false;" title="Redo (ctrl-Y)"></li>
<li id="clearauthorship" onClick="window.pad&amp;&amp;pad.editbarClick('clearauthorship');return false;" title="Clear Authorship Colors"></li>
</ul>
<ul class="right">
<li id="settings" onClick="window.pad&amp;&amp;pad.editbarClick('settings');return false;" title="Settings of this pad"></li>
<li id="importexport" onClick="window.pad&amp;&amp;pad.editbarClick('importexport');return false;" title="Import/Export from/to different document formats"></li>
<li id="embed" onClick="window.pad&amp;&amp;pad.editbarClick('embed');return false;" title="Share and Embed this pad"></li>
<li id="history" onClick="document.location = document.location.pathname + '/timeslider'" title="Show previous versions"></li>
<li id="users" onClick="window.pad&amp;&amp;pad.editbarClick('users');return false;" title="Show connected users">1</li>
</ul>
</div>
<title>Etherpad Lite</title> <div id="usersmenu" class="popup">
<div id="connectionstatus"></div>
<meta charset="utf-8"> <div id="myuser">
<meta name="robots" content="noindex, nofollow"> <div id="mycolorpicker">
<meta name="viewport" content="width=device-width, user-scalable=0"> <div id="colorpicker"></div>
<button id="mycolorpickersave" class="button">Save</button>
<link href="../static/css/pad.css" rel="stylesheet"> <button id="mycolorpickercancel">Cancel</button>
<link href="../static/custom/pad.css" rel="stylesheet"> <span id="mycolorpickerpreview" class="myswatchboxhoverable"></span>
<style title="dynamicsyntax"></style>
<div id="editbar">
<ul id="menu_left">
<li onClick="window.pad&amp;&amp;pad.editbarClick('bold');return false" >
<a title="Bold (ctrl-B)">
<div class="buttonicon buttonicon-bold"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('italic'); return false;" >
<a title="Italics (ctrl-I)">
<div class="buttonicon buttonicon-italic"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('underline');return false;" >
<a title="Underline (ctrl-U)">
<div class="buttonicon buttonicon-underline"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('strikethrough');return false;" >
<a title="Strikethrough">
<div class="buttonicon buttonicon-strikethrough"></div>
</a>
</li>
<li class="separator"></li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('insertorderedlist');return false;" >
<a title="Toggle Ordered List">
<div class="buttonicon buttonicon-insertorderedlist"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('insertunorderedlist');return false;" >
<a title="Toggle Bullet List">
<div class="buttonicon buttonicon-insertunorderedlist"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('indent');return false;" >
<a title="Indent">
<div class="buttonicon buttonicon-indent"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('outdent');return false;" >
<a title="Unindent">
<div class="buttonicon buttonicon-outdent"></div>
</a>
</li>
<li class="separator"></li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('undo');return false;" >
<a title="Undo (ctrl-Z)">
<div class="buttonicon buttonicon-undo"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('redo');return false;" >
<a title="Redo (ctrl-Y)">
<div class="buttonicon buttonicon-redo"></div>
</a>
</li>
<li class="separator"></li>
<li id="clearAuthorship" onClick="window.pad&amp;&amp;pad.editbarClick('clearauthorship');return false;" >
<a title="Clear Authorship Colors">
<div class="buttonicon buttonicon-clearauthorship"></div>
</a>
</li>
</ul>
<ul id="menu_right">
<li onClick="window.pad&amp;&amp;pad.editbarClick('settings');return false;">
<a id="settingslink" title="Settings of this pad">
<div class="buttonicon buttonicon-settings"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('import_export');return false;">
<a id="exportlink" title="Import/Export from/to different document formats">
<div class="buttonicon buttonicon-import_export"></div>
</a>
</li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('embed');return false;" >
<a id="embedlink" title="Share and Embed this pad">
<div class="buttonicon buttonicon-embed"></div>
</a>
</li>
<li class="separator"></li>
<li id="timesliderlink" onClick="document.location = document.location.pathname+ '/timeslider'">
<a title="Show the history of this pad">
<div class="buttonicon buttonicon-history"></div>
</a>
</li>
<li id="usericon" onClick="window.pad&amp;&amp;pad.editbarClick('showusers');return false;" >
<a title="Show connected users">
<div class="buttonicon buttonicon-showusers" id="usericonback"></div>
<span id="online_count">1</span>
</a>
</li>
</ul>
</div> </div>
<div id="myswatchbox"><div id="myswatch"></div></div>
<div id="myusernameform"><input type="text" id="myusernameedit" disabled="disabled"></div>
<div id="mystatusform"><input type="text" id="mystatusedit" disabled="disabled"></div>
</div>
<div id="otherusers">
<div id="guestprompts"></div>
<table id="otheruserstable" cellspacing="0" cellpadding="0" border="0">
<tr><td></td></tr>
</table>
<div id="nootherusers"></div>
</div>
<div id="userlistbuttonarea"></div>
</div>
<div id="users"> <div id="settingsmenu" class="popup">
<div id="connectionstatus"></div> <h2>Pad settings</h2>
<div id="myuser"> <div class="left_popup">
<div id="mycolorpicker"> <h3>My view</h3>
<div id="colorpicker"></div> <p>
<button id="mycolorpickersave">Save</button> <input type="checkbox" id="options-stickychat" onClick="chat.stickToScreen();">
<button id="mycolorpickercancel">Cancel</button> <label for="options-stickychat">Chat always on screen</label>
<span id="mycolorpickerpreview" class="myswatchboxhoverable"></span> </p>
</div> <p>
<div id="myswatchbox"><div id="myswatch"></div></div> <input type="checkbox" id="options-colorscheck" checked>
<div id="myusernameform"><input type="text" id="myusernameedit" disabled="disabled"></div> <label for="options-colorscheck">Authorship colors</label>
<div id="mystatusform"><input type="text" id="mystatusedit" disabled="disabled"></div> </p>
<p>
<input type="checkbox" id="options-linenoscheck" checked>
<label for="options-linenoscheck">Line numbers</label>
</p>
<p>
Font type:
<select id="viewfontmenu">
<option value="normal">Normal</option>
<option value="monospace">Monospaced</option>
</select>
</p>
</div>
<div class="right_popup">
<h3>Global view</h3>
<p>Currently nothing.</p>
<p class="note">These options affect everyone viewing this pad.</p>
</div>
</div>
<div id="importexportmenu" class="popup">
<div class="left_popup">
<h3>Import text from file</h3>
<form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data">
<div class="importformdiv" id="importformfilediv">
<input type="file" name="file" size="15" id="importfileinput">
<div class="importmessage" id="importmessagefail"></div>
</div>
<div class="importmessage" id="importmessagesuccess">Successful!</div>
<div class="importformdiv" id="importformsubmitdiv">
<input type="hidden" name="padId" value="blpmaXT35R">
<input id="importsubmitinput" class="button" type="submit" name="submit" value="Import Now" disabled="disabled">
</div>
</form>
</div>
<div class="right_popup">
<h3>Export current pad as</h3>
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml">HTML</div></a>
<a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype" id="exportplain">Plain text</div></a>
<a id="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword">Microsoft Word</div></a>
<a id="exportpdfa" target="_blank" class="exportlink"><div class="exporttype" id="exportpdf">PDF</div></a>
<a id="exportopena" target="_blank" class="exportlink"><div class="exporttype" id="exportopen">OpenDocument</div></a>
<a id="exportdokuwikia" target="_blank" class="exportlink"><div class="exporttype" id="exportdokuwiki">DokuWiki text</div></a>
<a id="exportwordlea" target="_blank" onClick="padimpexp.export2Wordle();return false;" class="exportlink"><div class="exporttype" id="exportwordle">Wordle</div></a>
</div>
</div>
<div id="embedmenu" class="popup">
<div id="embedreadonly" class="right">
<input type="checkbox" id="readonlyinput" onClick="padeditbar.setEmbedLinks();">
<label for="readonlyinput">Read only</label>
</div>
<h2>Share this pad</h2>
<div id="linkcode">
<h3>Link</h3>
<input id="linkinput" type="text" value="">
</div>
<br>
<div id="embedcode">
<h3>Embed URL</h3>
<input id="embedinput" type="text" value="">
</div>
<br>
<div id="qrcode">
<h3>QR code</h3>
<div id="qr_center"><img id="embedreadonlyqr"></div>
</div>
</div>
<div id="editorcontainerbox">
<div id="editorcontainer"></div>
<div id="editorloadingbox">Loading</div>
</div>
<div id="chatthrob"></div>
<div id="chaticon">
<a onClick="chat.show();return false;" title="Open the chat for this pad">
<span id="chatlabel">Chat</span>
</a>
<span id="chatcounter">0</span>
</div>
<div id="chatbox">
<div id="titlebar"><a id="titlecross" onClick="chat.hide();return false;"></a><span id ="titlelabel">Chat</span></div>
<div id="chattext" class="authorColors"></div>
<div id="chatinputbox">
<form>
<input id="chatinput" type="text" maxlength="140">
</form>
</div>
</div>
<div id="focusprotector">&nbsp;</div>
<div id="modaloverlay">
<div id="modaloverlay-inner"></div>
</div>
<div id="mainmodals">
<div id="connectionbox" class="modaldialog">
<div id="connectionboxinner" class="modaldialog-inner">
<div class="connecting">Connecting...</div>
<div class="reconnecting">Reestablishing connection...</div>
<div class="disconnected">
<h2 class="h2_disconnect">Disconnected.</h2>
<h2 class="h2_userdup">Opened in another window.</h2>
<h2 class="h2_unauth">No Authorization.</h2>
<div id="disconnected_looping">
<p><b>We're having trouble talking to the EtherPad lite synchronization server.</b> You may be connecting through an incompatible firewall or proxy server.</p>
</div> </div>
<div id="otherusers"> <div id="disconnected_initsocketfail">
<div id="guestprompts"></div> <p><b>We were unable to connect to the EtherPad lite synchronization server.</b> This may be due to an incompatibility with your web browser or internet connection.</p>
<table id="otheruserstable" cellspacing="0" cellpadding="0" border="0">
<tr><td></td></tr>
</table>
<div id="nootherusers"></div>
</div> </div>
<div id="userlistbuttonarea"></div> <div id="disconnected_userdup">
<p><b>You seem to have opened this pad in another browser window.</b> If you'd like to use this window instead, you can reconnect.</p>
</div>
<div id="disconnected_unknown">
<p><b>Lost connection with the EtherPad lite synchronization server.</b> This may be due to a loss of network connectivity.</p>
</div>
<div id="disconnected_slowcommit">
<p><b>Server not responding.</b> This may be due to network connectivity issues or high load on the server.</p>
</div>
<div id="disconnected_unauth">
<p>Your browser's credentials or permissions have changed while viewing this pad. Try reconnecting.</p>
</div>
<div id="disconnected_deleted">
<p>This pad was deleted.</p>
</div>
<div id="reconnect_advise">
<p>If this continues to happen, please let us know</p>
</div>
<div id="reconnect_form">
<button id="forcereconnect">Reconnect Now</button>
</div>
</div>
</div> </div>
<form id="reconnectform" method="post" action="/ep/pad/reconnect" accept-charset="UTF-8" style="display:none;">
<input type="hidden" class="padId" name="padId">
<input type="hidden" class="diagnosticInfo" name="diagnosticInfo">
<input type="hidden" class="missedChanges" name="missedChanges">
</form>
</div>
</div>
<div id="editorcontainerbox"> <script type="text/javascript" src="../static/js/require-kernel.js"></script>
<div id="editorcontainer"></div> <script type="text/javascript" src="../socket.io/socket.io.js"></script>
<div id="editorloadingbox">Loading...</div> <script type="text/javascript" src="../minified/pad.js"></script>
</div> <script type="text/javascript" src="../static/custom/pad.js"></script>
<script type="text/javascript">
var clientVars = {};
(function () {
require.setRootURI("../minified/");
require.setGlobalKeyPath("require");
require('/pad').init();
<div id="settingsmenu" class="popup"> /* TODO: These globals shouldn't exist. */
<h1>Pad settings</h1> pad = require('/pad').pad;
<div class="left_popup"> chat = require('/chat').chat;
<h2>My view</h2> padeditbar = require('/pad_editbar').padeditbar;
<p> padimpexp = require('/pad_impexp').padimpexp;
<input type="checkbox" id="options-stickychat" onClick="chat.stickToScreen();"> }());
<label for="options-stickychat">Chat always on screen</label> </script>
</p> </body>
<p> </html>
<input type="checkbox" id="options-colorscheck" checked>
<label for="options-colorscheck">Authorship colors</label>
</p>
<p>
<input type="checkbox" id="options-linenoscheck" checked>
<label for="options-linenoscheck">Line numbers</label>
</p>
<p>
Font type:
<select id="viewfontmenu">
<option value="normal">Normal</option>
<option value="monospace">Monospaced</option>
</select>
</p>
</div>
<div class="right_popup">
<h2>Global view</h2>
<p>Currently nothing.</p>
<p class="note">These options affect everyone viewing this pad.</p>
</div>
</div>
<div id="importexport" class="popup">
<div class="left_popup">
<h2>Import from text file, HTML, PDF, Word, ODT or RTF</h2><br>
<form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data">
<div class="importformdiv" id="importformfilediv">
<input type="file" name="file" size="15" id="importfileinput">
<div class="importmessage" id="importmessagefail"></div>
</div>
<div id="import"></div>
<div class="importmessage" id="importmessagesuccess">Successful!</div>
<div class="importformdiv" id="importformsubmitdiv">
<input type="hidden" name="padId" value="blpmaXT35R">
<span class="nowrap">
<input type="submit" name="submit" value="Import Now" disabled="disabled" id="importsubmitinput">
<img alt="" id="importstatusball" src="../static/img/loading.gif" align="top">
<img alt="" id="importarrow" src="../static/img/leftarrow.png" align="top">
</span>
</div>
</form>
</div>
<div class="right_popup">
<h2>Export current pad as</h2>
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml">HTML</div></a>
<a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype" id="exportplain">Plain text</div></a>
<a id="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword">Microsoft Word</div></a>
<a id="exportpdfa" target="_blank" class="exportlink"><div class="exporttype" id="exportpdf">PDF</div></a>
<a id="exportopena" target="_blank" class="exportlink"><div class="exporttype" id="exportopen">OpenDocument</div></a>
<a id="exportdokuwikia" target="_blank" class="exportlink"><div class="exporttype" id="exportdokuwiki">DokuWiki text</div></a>
<a id="exportwordlea" target="_blank" onClick="padimpexp.export2Wordle();return false;" class="exportlink"><div class="exporttype" id="exportwordle">Wordle</div></a>
</div>
</div>
<div id="embed" class="popup">
<div id="embedreadonly" class="right">
<input type="checkbox" id="readonlyinput" onClick="padeditbar.setEmbedLinks();">
<label for="readonlyinput">Read only</label>
</div>
<h1>Share this pad</h1>
<div id="linkcode">
<h2>Link</h2>
<input id="linkinput" type="text" value="">
</div>
<br>
<div id="embedcode">
<h2>Embed URL</h2>
<input id="embedinput" type="text" value="">
</div>
<br>
<div id="qrcode">
<h2>QR code</h2>
<div id="qr_center"><img id="embedreadonlyqr"></div>
</div>
</div>
<div id="chatthrob"></div>
<div id="chaticon">
<a onClick="chat.show();return false;" title="Open the chat for this pad">
<span id="chatlabel">Chat</span>
<div class="buttonicon buttonicon-chat"></div>
</a>
<span id="chatcounter">0</span>
</div>
<div id="chatbox">
<div id="titlebar"><span id ="titlelabel">Chat</span><a id="titlecross" onClick="chat.hide();return false;">-&nbsp;</a></div>
<div id="chattext" class="authorColors"></div>
<div id="chatinputbox">
<form>
<input id="chatinput" type="text" maxlength="140">
</form>
</div>
</div>
<div id="focusprotector">&nbsp;</div>
<div id="modaloverlay">
<div id="modaloverlay-inner"></div>
</div>
<div id="mainmodals">
<div id="connectionbox" class="modaldialog">
<div id="connectionboxinner" class="modaldialog-inner">
<div class="connecting">Connecting...</div>
<div class="reconnecting">Reestablishing connection...</div>
<div class="disconnected">
<h2 class="h2_disconnect">Disconnected.</h2>
<h2 class="h2_userdup">Opened in another window.</h2>
<h2 class="h2_unauth">No Authorization.</h2>
<div id="disconnected_looping">
<p><b>We're having trouble talking to the EtherPad lite synchronization server.</b> You may be connecting through an incompatible firewall or proxy server.</p>
</div>
<div id="disconnected_initsocketfail">
<p><b>We were unable to connect to the EtherPad lite synchronization server.</b> This may be due to an incompatibility with your web browser or internet connection.</p>
</div>
<div id="disconnected_userdup">
<p><b>You seem to have opened this pad in another browser window.</b> If you'd like to use this window instead, you can reconnect.</p>
</div>
<div id="disconnected_unknown">
<p><b>Lost connection with the EtherPad lite synchronization server.</b> This may be due to a loss of network connectivity.</p>
</div>
<div id="disconnected_slowcommit">
<p><b>Server not responding.</b> This may be due to network connectivity issues or high load on the server.</p>
</div>
<div id="disconnected_unauth">
<p>Your browser's credentials or permissions have changed while viewing this pad. Try reconnecting.</p>
</div>
<div id="disconnected_deleted">
<p>This pad was deleted.</p>
</div>
<div id="reconnect_advise">
<p>If this continues to happen, please let us know</p>
</div>
<div id="reconnect_form">
<button id="forcereconnect">Reconnect Now</button>
</div>
</div>
</div>
<form id="reconnectform" method="post" action="/ep/pad/reconnect" accept-charset="UTF-8" style="display: none;">
<input type="hidden" class="padId" name="padId">
<input type="hidden" class="diagnosticInfo" name="diagnosticInfo">
<input type="hidden" class="missedChanges" name="missedChanges">
</form>
</div>
</div>
<script type="text/javascript" src="../static/js/require-kernel.js"></script>
<script type="text/javascript" src="../socket.io/socket.io.js"></script>
<script type="text/javascript" src="../minified/pad.js"></script>
<script type="text/javascript" src="../static/custom/pad.js"></script>
<script type="text/javascript">
var clientVars = {};
(function () {
require.setRootURI("../minified/");
require.setGlobalKeyPath("require");
require('/pad').init();
/* TODO: These globals shouldn't exist. */
pad = require('/pad').pad;
chat = require('/chat').chat;
padeditbar = require('/pad_editbar').padeditbar;
padimpexp = require('/pad_impexp').padimpexp;
}());
</script>
</html>

View file

@ -1,218 +1,151 @@
<!doctype html> <!doctype html>
<html lang="en"> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="robots" content="noindex, nofollow"> <meta name="robots" content="noindex, nofollow">
<title>Etherpad Lite Timeslider</title>
<link rel="stylesheet" href="../../static/css/pad.css">
<link rel="stylesheet" href="../../static/css/timeslider.css">
<link rel="stylesheet" href="../../static/custom/timeslider.css">
<style type="text/css" title="dynamicsyntax"></style>
</head>
<body>
<div id="padpage">
<title>Etherpad Lite Timeslider</title> <div id="padtop">
<link rel="stylesheet" href="../../static/css/pad.css"> <div class="topbar">
<link rel="stylesheet" href="../../static/css/timeslider.css"> <div class="topbarleft"><!-- --></div>
<link rel="stylesheet" href="../../static/custom/timeslider.css"> <div class="topbarright"><!-- --></div>
<style type="text/css" title="dynamicsyntax"></style> <div class="topbarcenter">
</head> <div class="fullscreen" onclick="$('BODY').toggleClass('maximized');">Full screen</div>
</div>
<body id="padbody" class="timeslider limwidth nonpropad nonprouser"> <div class="specialkeyarea"><!-- --></div>
<div id="padpage">
<div id="padtop">
<div class="topbar">
<div class="topbarleft">
<!-- -->
</div> </div>
<div id="alertbar">
<div class="topbarright"> <div id="servermsg">
<!-- --> <h3>Server Notice<span id="servermsgdate"><!-- --></span>:</h3>
<a id="hidetopmsg" href="javascript:%20void%20pad.hideServerMessage()" name="hidetopmsg">hide</a>
<p id="servermsgtext"><!-- --></p>
</div>
</div> </div>
<div id="docbar" class="menu docbar">
<div class="topbarcenter"> <table border="0" cellpadding="0" cellspacing="0" width="100%" id="docbartable" class="docbartable">
<a href="/" class="topbarBrand">Etherpad v1.1</a> <a href="http://etherpad.org" <tr>
class="EtherpadLink">Etherpad is</a> <a href="../../static/LICENSE" class= <td></td>
"Licensing">free software</a> <td id="docbarpadtitle" class="docbarpadtitle" title="Public Pad: Public Pad"><span>Public Pad</span></td>
<td width="100%">&nbsp;</td>
<div class="fullscreen" onclick="$('body').toggleClass('maximized');"> <td></td>
Full screen </tr>
</div><a href="javascript:void(0);" onclick= </table>
"$('body').toggleClass('maximized');" class="topbarmaximize" title=
"Toggle maximization"></a>
</div>
<div class="specialkeyarea">
<!-- -->
</div>
</div>
<div id="alertbar">
<div id="servermsg">
<h3>Server Notice<span id="servermsgdate"><!-- --></span>:</h3><a id=
"hidetopmsg" href="javascript:%20void%20pad.hideServerMessage()" name=
"hidetopmsg">hide</a>
<p id="servermsgtext"><!-- --></p>
</div> </div>
</div> </div>
<div id="navigation"></div> <div id="timeslider-wrapper">
<div id="error" style="display:none;">It looks like you're having connection troubles. <a href="/ep/pad/view/test/latest">Reconnect now</a>.</div>
<div id="docbar" class="menu docbar"> <div id="timeslider" unselectable="on">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="docbartable" <div id="timer">&nbsp;</div>
class="docbartable"> <div id="steppers">
<tr> <a id="leftstep" class="group-start" href="#"></a>
<td><img src="../../static/img/roundcorner_left.gif" /></td> <a id="rightstep" class="group-end" href="#"></a>
</div>
<td id="docbarpadtitle" class="docbarpadtitle" title= <a id="playpause_button" href="#"></a>
"Public Pad: Public Pad"><span>Public Pad</span></td> <div id="timeslider-slider">
<div id="ui-slider-handle"></div>
<td width="100%">&nbsp;</td> <div id="ui-slider-bar"></div>
</div>
<td><img src="../../static/img/roundcorner_right.gif" /></td>
</tr>
</table>
</div><!-- /docbar -->
</div>
<div id="timeslider-wrapper">
<div id="error" style="display: none">
It looks like you're having connection troubles. <a href=
"/ep/pad/view/test/latest">Reconnect now</a>.
</div>
<div id="timeslider" unselectable="on" style="display: none">
<div id="timeslider-left"></div>
<div id="timeslider-right"></div>
<div id="timer"></div>
<div id="timeslider-slider">
<div id="ui-slider-handle"></div>
<div id="ui-slider-bar"></div>
</div>
<div id="playpause_button">
<div id="playpause_button_icon" class=""></div>
</div>
<div id="steppers">
<div class="stepper" id="leftstep"></div>
<div class="stepper" id="rightstep"></div>
</div> </div>
</div> </div>
</div>
<!--<div id="rightbars" style="top: 95px;"> <!--<div id="rightbars" style="top: 95px;">
<div id="rightbar"><a href="/ep/pad/view/c6fg9GM51V/latest" id="viewlatest">Viewing latest content</a><br> <div id="rightbar"><a href="/ep/pad/view/c6fg9GM51V/latest" id="viewlatest">Viewing latest content</a><br>
<a thref="/ep/pad/view/c6fg9GM51V/rev.%revision%" href="/ep/pad/view/c6fg9GM51V/rev.0" class="tlink">Link to this version</a> <a thref="/ep/pad/view/c6fg9GM51V/rev.%revision%" href="/ep/pad/view/c6fg9GM51V/rev.0" class="tlink">Link to this version</a>
<br><a thref="/ep/pad/view/ro.fw470Orpi4T/rev.%revision%" href="/ep/pad/view/ro.fw470Orpi4T/rev.0" class="tlink">Link to read-only page</a><br><a href="/c6fg9GM51V">Edit this pad</a> <br><a thref="/ep/pad/view/ro.fw470Orpi4T/rev.%revision%" href="/ep/pad/view/ro.fw470Orpi4T/rev.0" class="tlink">Link to read-only page</a><br><a href="/c6fg9GM51V">Edit this pad</a>
<h2>Download as</h2> <h2>Download as</h2>
<img src="../../static/img/may09/html.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=html" href="/ep/pad/export/c6fg9GM51V/rev.0?format=html" class="tlink">HTML</a><br> <img src="../../static/img/may09/html.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=html" href="/ep/pad/export/c6fg9GM51V/rev.0?format=html" class="tlink">HTML</a><br>
<img src="../../static/img/may09/txt.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=txt" href="/ep/pad/export/c6fg9GM51V/rev.0?format=txt" class="tlink">Plain text</a><br> <img src="../../static/img/may09/txt.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=txt" href="/ep/pad/export/c6fg9GM51V/rev.0?format=txt" class="tlink">Plain text</a><br>
<img src="../../static/img/may09/doc.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=doc" href="/ep/pad/export/c6fg9GM51V/rev.0?format=doc" class="tlink">Microsoft Word</a><br> <img src="../../static/img/may09/doc.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=doc" href="/ep/pad/export/c6fg9GM51V/rev.0?format=doc" class="tlink">Microsoft Word</a><br>
<img src="../../static/img/may09/pdf.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=pdf" href="/ep/pad/export/c6fg9GM51V/rev.0?format=pdf" class="tlink">PDF</a> <img src="../../static/img/may09/pdf.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=pdf" href="/ep/pad/export/c6fg9GM51V/rev.0?format=pdf" class="tlink">PDF</a>
</div>
<div id="legend">
<h2>Authors</h2>
<table cellspacing="0" cellpadding="0" border="0" id="authorstable"><tbody><tr><td style="color:#999; padding-left: 10px" colspan="2">No Authors</td></tr></tbody></table>
</div>
</div>-->
</div> <div id="padmain">
<div id="legend"> <div id="padeditor">
<h2>Authors</h2> <div id="editbar" class="editbar disabledtoolbar">
<table cellspacing="0" cellpadding="0" border="0" id="authorstable"><tbody><tr><td style="color:#999; padding-left: 10px" colspan="2">No Authors</td></tr></tbody></table>
</div>
</div>-->
<div id="padmain">
<div id="padeditor">
<div id="editbar" class="editbar disabledtoolbar">
<div id="editbarinner" class="editbarinner">
<div id="editbarleft" class="editbarleft">
<!-- -->
</div>
<div id="editbarright" class="editbarright">
<!-- termporary place holder-->
<ul>
<li onClick="window.padeditbar.toolbarClick('import_export');return false;">
<a id="exportlink" title="Export to different document formats">
<div class="buttonicon buttonicon-import_export"></div>
</a>
</li>
</ul>
<a id = "returnbutton">Return to pad</a>
</div>
<div id="editbarinner" class="editbarinner"> <div id="editbarinner" class="editbarinner">
<table cellpadding="0" cellspacing="0" border="0" id="editbartable" class= <div id="editbarleft" class="left"></div>
"editbartable"> <div id="editbarright" class="right">
<tr> <ul>
<td> <li id="returnbutton"><a href="#">Return to pad</a></li>
<h1> <li id="importexport" onClick="window.padeditbar.toolbarClick('importexport');return false;" title="Export to different document formats"></li>
<span id="revision_label"></span> </ul>
<span id="revision_date"></span> </div>
</h1> <div id="editbarinner">
</td> <table cellpadding="0" cellspacing="0" border="0" id="editbartable" class="editbartable">
<tr>
<td width="100%">&nbsp;</td> <td>
</tr> <h1>
</table> <span id="revision_label"></span>
<span id="revision_date"></span>
<table cellpadding="0" cellspacing="0" border="0" id="editbarsavetable" </h1>
class="editbarsavetable"> </td>
<tr> <td width="100%">&nbsp;</td>
<td></td> </tr>
</tr> </table>
</table> <table cellpadding="0" cellspacing="0" border="0" id="editbarsavetable"
class="editbarsavetable">
<tr>
<td></td>
</tr>
</table>
</div>
</div> </div>
</div> </div>
</div> <div id="editorcontainerbox">
<div id="padcontent"></div>
<div id="editorcontainerbox">
<div id="padcontent">
</div> </div>
</div> </div><!-- /padeditor -->
</div><!-- /padeditor --> </div><!-- /padmain -->
</div><!-- /padmain --> </div><!-- /padpage -->
</div><!-- /padpage -->
<div id="modaloverlay"> <div id="modaloverlay">
<div id="modaloverlay-inner"> <div id="modaloverlay-inner"></div>
<!-- -->
</div> </div>
</div> <div id="mainmodals"></div>
<div id="mainmodals"></div> <div id="importexport" class="popup">
Export current version as:
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml">HTML</div></a>
<a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype" id="exportplain">Plain text</div></a>
<a id="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword">Microsoft Word</div></a>
<a id="exportpdfa" target="_blank" class="exportlink"><div class="exporttype" id="exportpdf">PDF</div></a>
<a id="exportopena" target="_blank" class="exportlink"><div class="exporttype" id="exportopen">OpenDocument</div></a>
<a id="exportdokuwikia" target="_blank" class="exportlink"><div class="exporttype" id="exportdokuwiki">DokuWiki text</div></a>
<a id="exportwordlea" target="_blank" onClick="padimpexp.export2Wordle();return false;" class="exportlink"><div class="exporttype" id="exportwordle">Wordle</div></a>
<form id="wordlepost" name="wall" action="http://wordle.net/advanced" method="POST" style="margin-left:0px;">
<div id="hidetext" style=""><textarea id="text" name="text" id="text" style="display:none;">Coming soon!</textarea></div>
</form>
</div>
<!-- export code --> <script type="text/javascript" src="../../static/js/require-kernel.js"></script>
<div id="importexport"> <script type="text/javascript" src="../../socket.io/socket.io.js"></script>
<script type="text/javascript" src="../../minified/timeslider.js"></script>
<div id="export" class="popup"> <script type="text/javascript" src="../../static/custom/timeslider.js"></script>
Export current version as: <script type="text/javascript" >
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml">HTML</div></a> var clientVars = {};
<a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype" id="exportplain">Plain text</div></a> (function () {
<a id="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword">Microsoft Word</div></a> require.setRootURI("../minified/");
<a id="exportpdfa" target="_blank" class="exportlink"><div class="exporttype" id="exportpdf">PDF</div></a> require.setGlobalKeyPath("require");
<a id="exportopena" target="_blank" class="exportlink"><div class="exporttype" id="exportopen">OpenDocument</div></a> require('/timeslider').init();
<a id="exportdokuwikia" target="_blank" class="exportlink"><div class="exporttype" id="exportdokuwiki">DokuWiki text</div></a>
<a id="exportwordlea" target="_blank" onClick="padimpexp.export2Wordle();return false;" class="exportlink"><div class="exporttype" id="exportwordle">Wordle</div></a>
<form id="wordlepost" name="wall" action="http://wordle.net/advanced" method="POST" style="margin-left:0px;">
<div id="hidetext" style=""><textarea id="text" name="text" id="text" style="display:none;">Coming soon!</textarea></div>
</form>
</div>
</div>
<script type="text/javascript" src="../../static/js/require-kernel.js"></script>
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
<script type="text/javascript" src="../../minified/timeslider.js"></script>
<script type="text/javascript" src="../../static/custom/timeslider.js"></script>
<script type="text/javascript" >
var clientVars = {};
(function () {
require.setRootURI("../minified/");
require.setGlobalKeyPath("require");
require('/timeslider').init();
/* TODO: These globals shouldn't exist. */
padeditbar = require('/pad_editbar').padeditbar;
padimpexp = require('/pad_impexp').padimpexp;
})();
</script>
</body>
</html>
/* TODO: These globals shouldn't exist. */
padeditbar = require('/pad_editbar').padeditbar;
padimpexp = require('/pad_impexp').padimpexp;
})();
</script>
</body>
</html>