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-left {background-image:url(../../static/img/timeslider_left.png); height:63px; left:0; position:absolute; width:134px;}
#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;
}
/* timeslider sprite */
#ui-slider-handle, #playpause_button, #steppers A, #timeslider .star {background:url(../../static/img/timeslider-sprite.png) 0 0 no-repeat;}
#playpause_button, #playpause_button_icon {height:47px; position:absolute; width:47px;}
#playpause_button {background-image:url(../../static/img/crushed_button_undepressed.png); right:77px; top:9px;}
#playpause_button_icon {background-image:url(../../static/img/play.png); left:0; top:0;}
.pause#playpause_button_icon {background-image:url(../../static/img/pause.png);}
#timeslider {background:#f5f5f5; border-bottom:1px solid #d5d5d5; padding:6px 0; position:absolute; top:0; width:100%;}
#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;}
#timeslider-wrapper {float:left; width:100%;}
#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
{background:url(../../static/img/stepper_buttons.png) 0 0 no-repeat; height:21px; overflow:hidden; position:absolute;}
#leftstar {background-position:0 44px; right:34px; top:8px; width:30px;}
#rightstar {background-position:29px 44px; right:5px; top:8px; width:29px;}
#leftstep {background-position:0 22px; right:34px; top:20px; width:30px;}
#rightstep {background-position:29px 22px; right:5px; top:20px; width:29px;}
#playpause_button {background-color:#ddd; background-position:-60px 0; border-radius:30px; float:right; height:46px; width:46px;}
#playpause_button:hover {background-position:-60px -40px;}
#playpause_button.pause {background-position:-100px 0;}
#playpause_button.pause:hover {background-position:-100px -40px;}
#timeslider .star {
background-image:url(../../static/img/star.png);
cursor:pointer;
height:16px;
position:absolute;
top:40px;
width:15px;
}
#steppers {float:right; margin:0 35px 0 10px; width:60px;}
#steppers A {border:1px solid #d5d5d5; box-shadow:0 1px 0 #fff; float:left; height:20px; margin:0 0 4px; width:28px;}
#steppers .group-start {border-radius:3px 0 0 3px;}
#steppers .group-end {border-radius:0 3px 3px 0; border-width:1px 1px 1px 0; width:29px;}
#timeslider #timer {
color:#fff;
font-family:Arial, sans-serif;
font-size:11px;
left:7px;
position:absolute;
text-align:center;
top:9px;
width:122px;
}
A#leftstar, #leftstar.inactive:hover {background-position:0 0;}
A#rightstar, #rightstar.inactive:hover {background-position:-30px 0;}
A#leftstep, #leftstep.inactive:hover {background-position:0 -20px;}
A#rightstep, #rightstep.inactive:hover {background-position:-30px -20px;}
A#leftstar:hover {background-position:0 -40px;}
A#rightstar:hover {background-position:-30px -40px;}
A#leftstep:hover {background-position:0 -60px;}
A#rightstep:hover {background-position:-30px -60px;}
.topbarcenter, #docbar {display:none;}
#padmain {top:30px;}
#editbarright {float:right;}
#returnbutton {color:#222; font-size:16px; line-height:29px; margin-top:0; padding-right:6px;}
#importexport {top:118px;}
#importexport .popup {width:185px;}
.topbarcenter, #docbar {display:none;} /* hide document title etc. */
#editbarinner H1 {color:#999; font-size:16px; line-height:29px; margin-top:0; padding-left:6px;}
#editbarinner H1 A {font-size:12px;}
#revision_label {background-color:#aaa; border-radius:3px; color:#fff; padding:2px 5px;}
/* lists */
.list-bullet2, .list-indent2, .list-number2 {margin-left:3em;}
.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;}
#editbarright #returnbutton {background:0 none; border:0 none; box-shadow:none; padding:4px 6px; width:auto;}
#returnbutton A {color:#999; font-size:12px; line-height:20px;}
/* unordered lists */
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);}
#importexport.popup {top:95px; width:140px;}

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.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/
@ -23,64 +23,51 @@
// of the document. These revisions are connected together by various
// changesets, or deltas, between any two revisions.
function loadBroadcastRevisionsJS()
{
function Revision(revNum)
{
function loadBroadcastRevisionsJS() {
function Revision(revNum) {
this.rev = revNum;
this.changesets = [];
}
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta)
{
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta) {
var changesetWrapper = {
deltaRev: destIndex - this.rev,
deltaTime: timeDelta,
getValue: function()
{
return changeset;
}
deltaRev : destIndex - this.rev,
deltaTime : timeDelta,
getValue : function() {return changeset;}
};
this.changesets.push(changesetWrapper);
this.changesets.sort(function(a, b)
{
return (b.deltaRev - a.deltaRev)
this.changesets.sort(function(a, b) {
return (b.deltaRev - a.deltaRev);
});
}
};
revisionInfo = {};
revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta)
{
var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex);
var endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta) {
var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex),
endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
startRevision.addChangeset(toIndex, changeset, timeDelta);
endRevision.addChangeset(fromIndex, backChangeset, -1 * timeDelta);
}
};
revisionInfo.latest = clientVars.totalRevs || -1;
revisionInfo.createNew = function(index)
{
revisionInfo.createNew = function(index) {
revisionInfo[index] = new Revision(index);
if (index > revisionInfo.latest)
{
revisionInfo.latest = index;
}
return revisionInfo[index];
}
};
// assuming that there is a path from fromIndex to toIndex, and that the links
// are laid out in a skip-list format
revisionInfo.getPath = function(fromIndex, toIndex)
{
var changesets = [];
var spans = [];
var times = [];
var elem = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex);
if (elem.changesets.length != 0 && fromIndex != toIndex)
{
var reverse = !(fromIndex < toIndex)
revisionInfo.getPath = function(fromIndex, toIndex) {
var changesets = [],
spans = [],
times = [],
elem = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex);
if (elem.changesets.length != 0 && fromIndex != toIndex) {
var reverse = !(fromIndex < toIndex);
while (((elem.rev < toIndex) && !reverse) || ((elem.rev > toIndex) && reverse))
{
var couldNotContinue = false;
@ -107,22 +94,24 @@ function loadBroadcastRevisionsJS()
}
}
if (couldNotContinue || oldRev == elem.rev) break;
if (couldNotContinue || oldRev == elem.rev)
break;
}
}
var status = 'partial';
if (elem.rev == toIndex) status = 'complete';
if (elem.rev == toIndex)
status = 'complete';
return {
'fromRev': fromIndex,
'rev': elem.rev,
'status': status,
'changesets': changesets,
'spans': spans,
'times': times
'fromRev' : fromIndex,
'rev' : elem.rev,
'status' : status,
'changesets' : changesets,
'spans' : spans,
'times' : times
};
}
};
}
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.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/
@ -20,471 +20,367 @@
* limitations under the License.
*/
// These parameters were global, now they are injected. A reference to the
// Timeslider controller would probably be more appropriate.
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
// These parameters were global, now they are injected. A reference to the
// Timeslider controller would probably be more appropriate.
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) {
var BroadcastSlider;
(function()
{ // wrap this code in its own namespace
var sliderLength = 1000;
var sliderPos = 0;
var sliderActive = false;
var slidercallbacks = [];
var savedRevisions = [];
var sliderPlaying = false;
(function() { // wrap this code in its own namespace
var sliderLength = 1000,
sliderPos = 0,
sliderActive = false,
slidercallbacks = [],
savedRevisions = [],
sliderPlaying = false;
function disableSelection(element)
{
element.onselectstart = function()
{
function disableSelection(element) {
element.onselectstart = function() {
return false;
};
element.unselectable = "on";
element.unselectable = "on";
element.style.MozUserSelect = "none";
element.style.cursor = "default";
}
var _callSliderCallbacks = function(newval)
{
sliderPos = newval;
for (var i = 0; i < slidercallbacks.length; i++)
{
slidercallbacks[i](newval);
}
}
var updateSliderElements = function()
{
for (var i = 0; i < savedRevisions.length; i++)
{
var position = parseInt(savedRevisions[i].attr('pos'));
savedRevisions[i].css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
}
$("#ui-slider-handle").css('left', sliderPos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
}
var addSavedRevision = function(position, info)
{
var newSavedRevision = $('<div></div>');
newSavedRevision.addClass("star");
var _callSliderCallbacks = function(newval) {
sliderPos = newval;
for (var i=0, l=slidercallbacks.length; i < l; i++) {
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 addSavedRevision = function(position, info) {
var newSavedRevision = $('<div></div>');
newSavedRevision
.addClass('star')
.attr('pos', position)
.css('position', 'absolute')
.css('left', (position * ($('#ui-slider-bar').width() - 2) / (sliderLength * 1.0)) - 1);
$('#timeslider-slider').append(newSavedRevision);
newSavedRevision.mouseup(function(evt) {
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
newSavedRevision.attr('pos', position);
newSavedRevision.css('position', 'absolute');
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
$("#timeslider-slider").append(newSavedRevision);
newSavedRevision.mouseup(function(evt)
{
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
var removeSavedRevision = function(position) {
var element = $('.star [pos=' + position + ']');
savedRevisions.remove(element);
element.remove();
return element;
};
var removeSavedRevision = function(position)
{
var element = $("div.star [pos=" + position + "]");
savedRevisions.remove(element);
element.remove();
return element;
};
/* Begin small 'API' */
function onSlider(callback)
{
/* small 'API' START */
function onSlider(callback) {
slidercallbacks.push(callback);
}
function getSliderPosition()
{
function getSliderPosition() {
return sliderPos;
}
function setSliderPosition(newpos)
{
function setSliderPosition(newpos) {
newpos = Number(newpos);
if (newpos < 0 || newpos > sliderLength) return;
$("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
$("a.tlink").map(function()
{
$(this).attr('href', $(this).attr('thref').replace("%revision%", newpos));
if (newpos < 0 || newpos > sliderLength)
return;
$('#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));
});
$("#revision_label").html("Version " + newpos);
$('#revision_label').html('Version ' + newpos);
if (newpos == 0)
{
$("#leftstar").css('opacity', .5);
$("#leftstep").css('opacity', .5);
}
$('#leftstar, #leftstep').addClass('inactive');
else
{
$("#leftstar").css('opacity', 1);
$("#leftstep").css('opacity', 1);
}
$('#leftstar, #leftstep').removeClass('inactive');
if (newpos == sliderLength)
{
$("#rightstar").css('opacity', .5);
$("#rightstep").css('opacity', .5);
}
$('#rightstar, #rightstep').addClass('inactive');
else
{
$("#rightstar").css('opacity', 1);
$("#rightstep").css('opacity', 1);
}
$('#rightstar, #rightstep').removeClass('inactive');
sliderPos = newpos;
_callSliderCallbacks(newpos);
}
function getSliderLength()
{
function getSliderLength() {
return sliderLength;
}
function setSliderLength(newlength)
{
function setSliderLength(newlength) {
sliderLength = newlength;
updateSliderElements();
}
// just take over the whole slider screen with a reconnect message
function showReconnectUI()
{
if (!clientVars.sliderEnabled || !clientVars.supportsSlider)
{
$("#padmain, #rightbars").css('top', "130px");
$("#timeslider").show();
}
// take over the whole slider screen with a reconnect message
function showReconnectUI() {
$('#error').show();
}
function setAuthors(authors)
{
$("#authorstable").empty();
var numAnonymous = 0;
var numNamed = 0;
authors.forEach(function(author)
{
if (author.name)
{
function setAuthors(authors) {
$('#authorstable').empty();
var numAnonymous = 0,
numNamed = 0,
html;
authors.forEach(function(author) {
if (author.name) {
numNamed++;
var tr = $('<tr></tr>');
var swatchtd = $('<td></td>');
var swatch = $('<div class="swatch"></div>');
var tr = $('<tr></tr>'),
swatchtd = $('<td></td>'),
swatch = $('<div class="swatch"></div>'),
nametd = $('<td></td>');
swatch.css('background-color', clientVars.colorPalette[author.colorId]);
swatchtd.append(swatch);
tr.append(swatchtd);
var nametd = $('<td></td>');
nametd.text(author.name || "unnamed");
nametd.text(author.name || 'unnamed');
tr.append(nametd);
$("#authorstable").append(tr);
}
else
{
$('#authorstable').append(tr);
} else {
numAnonymous++;
}
});
if (numAnonymous > 0)
{
var html = "<tr><td colspan=\"2\" style=\"color:#999; padding-left: 10px\">" + (numNamed > 0 ? "...and " : "") + numAnonymous + " unnamed author" + (numAnonymous > 1 ? "s" : "") + "</td></tr>";
$("#authorstable").append($(html));
if (numAnonymous > 0) {
html = '<tr><td colspan="2" style="color:#999; padding-left:10px">' +
(numNamed > 0 ? '...and ' : '') + numAnonymous + ' unnamed author' +
(numAnonymous > 1 ? 's' : '') + '</td></tr>';
$('#authorstable').append($(html));
}
if (authors.length == 0)
{
$("#authorstable").append($("<tr><td colspan=\"2\" style=\"color:#999; padding-left: 10px\">No Authors</td></tr>"))
if (authors.length == 0) {
html = '<tr><td colspan="2" style="color:#999; padding-left:10px">No Authors</td></tr>';
$('#authorstable').append($(html));
}
}
BroadcastSlider = {
onSlider: onSlider,
getSliderPosition: getSliderPosition,
setSliderPosition: setSliderPosition,
getSliderLength: getSliderLength,
setSliderLength: setSliderLength,
isSliderActive: function()
{
onSlider : onSlider,
getSliderPosition : getSliderPosition,
setSliderPosition : setSliderPosition,
getSliderLength : getSliderLength,
setSliderLength : setSliderLength,
isSliderActive : function() {
return sliderActive;
},
playpause: playpause,
addSavedRevision: addSavedRevision,
showReconnectUI: showReconnectUI,
setAuthors: setAuthors
}
playpause : playpause,
addSavedRevision : addSavedRevision,
showReconnectUI : showReconnectUI,
setAuthors : setAuthors
};
function playButtonUpdater()
{
if (sliderPlaying)
{
if (getSliderPosition() + 1 > sliderLength)
{
$("#playpause_button_icon").toggleClass('pause');
function playButtonUpdater() {
if (sliderPlaying) {
if (getSliderPosition() + 1 > sliderLength) {
$('#playpause_button').toggleClass('pause');
sliderPlaying = false;
return;
}
setSliderPosition(getSliderPosition() + 1);
setTimeout(playButtonUpdater, 100);
}
}
function playpause()
{
$("#playpause_button_icon").toggleClass('pause');
if (!sliderPlaying)
{
function playpause() {
$('#playpause_button').toggleClass('pause');
if (!sliderPlaying) {
if (getSliderPosition() == sliderLength) setSliderPosition(0);
sliderPlaying = true;
playButtonUpdater();
}
else
{
} else {
sliderPlaying = false;
}
}
// assign event handlers to html UI elements after page load
//$(window).load(function ()
fireWhenAllScriptsAreLoaded.push(function()
{
fireWhenAllScriptsAreLoaded.push(function() {
disableSelection($("#playpause_button")[0]);
disableSelection($("#timeslider")[0]);
if (clientVars.sliderEnabled && clientVars.supportsSlider)
{
$(document).keyup(function(e)
{
var code = -1;
if (!e) var e = window.event;
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
if (clientVars.sliderEnabled && clientVars.supportsSlider) {
$(document).keyup(function(e) {
var code = -1,
i, l, nextStar, pos;
if (!e)
var e = window.event;
code = (e.keyCode) ? e.keyCode : e.which;
if (code == 37)
{ // left
if (!e.shiftKey)
{
setSliderPosition(getSliderPosition() - 1);
}
else
{
var nextStar = 0; // default to first revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
switch (code) {
case 37: // left
if (!e.shiftKey) {
setSliderPosition(getSliderPosition() - 1);
} else {
nextStar = 0; // default to first revision in document
for (i=0, l=savedRevisions.length; i < l; i++) {
pos = parseInt(savedRevisions[i].attr('pos'), 10);
if (pos < getSliderPosition() && nextStar < pos)
nextStar = pos;
}
setSliderPosition(nextStar);
}
setSliderPosition(nextStar);
}
}
else if (code == 39)
{
if (!e.shiftKey)
{
setSliderPosition(getSliderPosition() + 1);
}
else
{
var nextStar = sliderLength; // default to last revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
break;
case 39:
if (!e.shiftKey) {
setSliderPosition(getSliderPosition() + 1);
} else {
nextStar = sliderLength; // default to last revision in document
for (i=0, l=savedRevisions.length; i < l; i++) {
pos = parseInt(savedRevisions[i].attr('pos'), 10);
if (pos > getSliderPosition() && nextStar > pos)
nextStar = pos;
}
setSliderPosition(nextStar);
}
setSliderPosition(nextStar);
}
break;
case 32:
playpause();
break;
}
else if (code == 32) playpause();
});
}
$(window).resize(function()
{
$(window).resize(function() {
updateSliderElements();
});
$("#ui-slider-bar").mousedown(function(evt)
{
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").trigger(evt);
$('#ui-slider-bar')
.mousedown(function(evt) {
setSliderPosition(Math.floor((evt.clientX - $('#ui-slider-bar').offset().left) * sliderLength / 742));
$('#ui-slider-handle')
.css('left', (evt.clientX - $('#ui-slider-bar').offset().left))
.trigger(evt);
});
// Slider dragging
$("#ui-slider-handle").mousedown(function(evt)
{
this.startLoc = evt.clientX;
this.currentLoc = parseInt($(this).css('left'));
// slider dragging
$('#ui-slider-handle')
.mousedown(function(evt) {
this.startLoc = evt.clientX;
this.currentLoc = parseInt($(this).css('left'), 10);
var self = this;
sliderActive = true;
$(document).mousemove(function(evt2)
{
$(self).css('pointer', 'move')
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
$("#revision_label").html("Version " + Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)));
$(document).mousemove(function(evt2) {
var newloc = self.currentLoc + (evt2.clientX - self.startLoc),
adjustedWidth = $('#ui-slider-bar').width() - 2,
pos;
if (newloc < 0)
newloc = 0;
if (newloc > adjustedWidth)
newloc = adjustedWidth;
$('#revision_label').html('Version ' + Math.floor(newloc * sliderLength / adjustedWidth));
$(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).unbind('mousemove');
$(document).unbind('mouseup');
$(document).mouseup(function(evt2) {
$(document)
.unbind('mousemove')
.unbind('mouseup');
sliderActive = false;
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
if (newloc < 0)
newloc = 0;
if (newloc > ($("#ui-slider-bar").width() - 2))
newloc = ($("#ui-slider-bar").width() - 2);
$(self).css('left', newloc);
// if(getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2)))
setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
self.currentLoc = parseInt($(self).css('left'));
setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)));
self.currentLoc = parseInt($(self).css('left'), 10);
});
})
});
// play/pause toggling
$("#playpause_button").mousedown(function(evt)
{
// toggle play / pause
$('#playpause_button').mousedown(function(evt) {
var self = this;
$(self).css('background-image', 'url(/static/img/crushed_button_depressed.png)');
$(self).mouseup(function(evt2)
{
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(self)
.addClass('pressed')
.mouseup(function(evt2) {
$(self).removeClass('pressed');
$(self).unbind('mouseup');
BroadcastSlider.playpause();
});
$(document).mouseup(function(evt2)
{
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(document).mouseup(function(evt2) {
$(self).removeClass('pressed');
$(document).unbind('mouseup');
});
});
// next/prev saved revision and changeset
$('.stepper').mousedown(function(evt)
{
// next / prev saved revision and changeset
$('#steppers A').mousedown(function(evt) {
var self = this;
var origcss = $(self).css('background-position');
if (!origcss)
{
origcss = $(self).css('background-position-x') + " " + $(self).css('background-position-y');
}
var origpos = parseInt(origcss.split(" ")[1]);
var newpos = (origpos - 43);
if (newpos < 0) newpos += 87;
var newcss = (origcss.split(" ")[0] + " " + newpos + "px");
if ($(self).css('opacity') != 1.0) newcss = origcss;
$(self).css('background-position', newcss)
$(self).mouseup(function(evt2)
{
$(self).css('background-position', origcss);
$(self).unbind('mouseup');
$(self)
.addClass('clicked')
.mouseup(function(evt2) {
$(self)
.removeClass('clicked')
.unbind('mouseup');
$(document).unbind('mouseup');
if ($(self).attr("id") == ("leftstep"))
{
setSliderPosition(getSliderPosition() - 1);
}
else if ($(self).attr("id") == ("rightstep"))
{
setSliderPosition(getSliderPosition() + 1);
}
else if ($(self).attr("id") == ("leftstar"))
{
var nextStar = 0; // default to first revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
}
setSliderPosition(nextStar);
}
else if ($(self).attr("id") == ("rightstar"))
{
var nextStar = sliderLength; // default to last revision in document
for (var i = 0; i < savedRevisions.length; i++)
{
var pos = parseInt(savedRevisions[i].attr('pos'));
if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
}
setSliderPosition(nextStar);
var id = $(self).attr('id'),
i, l, nextStar, pos;
switch (id) {
case 'leftstep':
setSliderPosition(getSliderPosition() - 1);
break;
case 'rightstep':
setSliderPosition(getSliderPosition() + 1);
break;
case 'leftstar':
nextStar = 0; // default to first revision in document
for (i=0, l=savedRevisions.length; i < l; i++) {
pos = parseInt(savedRevisions[i].attr('pos'), 10);
if (pos < getSliderPosition() && nextStar < pos)
nextStar = pos;
}
setSliderPosition(nextStar);
break;
case 'rightstar':
nextStar = sliderLength; // default to last revision in document
for (i=0, l=savedRevisions.length; i < l; i++) {
pos = parseInt(savedRevisions[i].attr('pos'), 10);
if (pos > getSliderPosition() && nextStar > pos)
nextStar = pos;
}
setSliderPosition(nextStar);
break;
}
});
$(document).mouseup(function(evt2)
{
$(self).css('background-position', origcss);
$(self).unbind('mouseup');
$(document).mouseup(function(evt2) {
$(self)
.removeClass('clicked')
.unbind('mouseup');
$(document).unbind('mouseup');
});
})
});
if (clientVars)
{
if (clientVars) {
if (clientVars.fullWidth)
{
$("#padpage").css('width', '100%');
$("#revision").css('position', "absolute")
$("#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');
$('#padpage').addClass('full-width');
if (clientVars.disableRightBar) {
$('#rightbars').css('display', 'none');
$('#padmain').css('width', 'auto');
if (clientVars.fullWidth) $("#padmain").css('right', '7px');
else $("#padmain").css('width', '860px');
$("#revision").css('position', "absolute");
$("#revision").css('right', "20px");
$("#revision").css('top', "20px");
if (clientVars.fullWidth)
$('#padmain').css({right: 7});
else
$('#padmain').css('width', '860px');
$('#revision').css({
position: 'absolute',
right : 20,
top : 20
});
}
if (clientVars.sliderEnabled)
{
if (clientVars.supportsSlider)
{
$("#padmain, #rightbars").css('top', "130px");
$("#timeslider").show();
if (clientVars.sliderEnabled) {
if (clientVars.supportsSlider) {
setSliderLength(clientVars.totalRevs);
setSliderPosition(clientVars.revNum);
clientVars.savedRevisions.forEach(function(revision)
{
clientVars.savedRevisions.forEach(function(revision) {
addSavedRevision(revision.revNum, revision);
})
}
else
{
});
} else {
// slider is not supported
$("#padmain, #rightbars").css('top', "130px");
$("#timeslider").show();
$("#error").html("The timeslider feature is not supported on this pad. <a href=\"/ep/about/faq#disabledslider\">Why not?</a>");
$("#error").show();
$('#error').html('The timeslider feature is not supported on this pad. <a href="/ep/about/faq#disabledslider">Why not?</a>').show();
}
}
else
{
if (clientVars.supportsSlider)
{
} else {
if (clientVars.supportsSlider) {
setSliderLength(clientVars.totalRevs);
setSliderPosition(clientVars.revNum);
}
@ -493,10 +389,9 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
});
})();
BroadcastSlider.onSlider(function(loc)
{
$("#viewlatest").html(loc == BroadcastSlider.getSliderLength() ? "Viewing latest content" : "View latest content");
})
BroadcastSlider.onSlider(function(loc) {
$('#viewlatest').html(loc == BroadcastSlider.getSliderLength() ? 'Viewing latest content' : 'View latest content');
});
return BroadcastSlider;
}

View file

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

View file

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

View file

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

View file

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

View file

@ -1,311 +1,232 @@
<!doctype 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>
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, user-scalable=0">
<link href="../static/css/pad.css" rel="stylesheet">
<link href="../static/custom/pad.css" rel="stylesheet">
<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 id="usersmenu" class="popup">
<div id="connectionstatus"></div>
<div id="myuser">
<div id="mycolorpicker">
<div id="colorpicker"></div>
<button id="mycolorpickersave" class="button">Save</button>
<button id="mycolorpickercancel">Cancel</button>
<span id="mycolorpickerpreview" class="myswatchboxhoverable"></span>
</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="connectionstatus"></div>
<div id="myuser">
<div id="mycolorpicker">
<div id="colorpicker"></div>
<button id="mycolorpickersave">Save</button>
<button id="mycolorpickercancel">Cancel</button>
<span id="mycolorpickerpreview" class="myswatchboxhoverable"></span>
</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 id="settingsmenu" class="popup">
<h2>Pad settings</h2>
<div class="left_popup">
<h3>My view</h3>
<p>
<input type="checkbox" id="options-stickychat" onClick="chat.stickToScreen();">
<label for="options-stickychat">Chat always on screen</label>
</p>
<p>
<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">
<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 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 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="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>
<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">
<div id="editorcontainer"></div>
<div id="editorloadingbox">Loading...</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();
<div id="settingsmenu" class="popup">
<h1>Pad settings</h1>
<div class="left_popup">
<h2>My view</h2>
<p>
<input type="checkbox" id="options-stickychat" onClick="chat.stickToScreen();">
<label for="options-stickychat">Chat always on screen</label>
</p>
<p>
<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>
/* 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>
</body>
</html>

View file

@ -1,218 +1,151 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
<html>
<head>
<meta charset="utf-8">
<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>
<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 id="padbody" class="timeslider limwidth nonpropad nonprouser">
<div id="padpage">
<div id="padtop">
<div class="topbar">
<div class="topbarleft">
<!-- -->
<div id="padtop">
<div class="topbar">
<div class="topbarleft"><!-- --></div>
<div class="topbarright"><!-- --></div>
<div class="topbarcenter">
<div class="fullscreen" onclick="$('BODY').toggleClass('maximized');">Full screen</div>
</div>
<div class="specialkeyarea"><!-- --></div>
</div>
<div class="topbarright">
<!-- -->
<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 class="topbarcenter">
<a href="/" class="topbarBrand">Etherpad v1.1</a> <a href="http://etherpad.org"
class="EtherpadLink">Etherpad is</a> <a href="../../static/LICENSE" class=
"Licensing">free software</a>
<div class="fullscreen" onclick="$('body').toggleClass('maximized');">
Full screen
</div><a href="javascript:void(0);" onclick=
"$('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 id="docbar" class="menu docbar">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="docbartable" class="docbartable">
<tr>
<td></td>
<td id="docbarpadtitle" class="docbarpadtitle" title="Public Pad: Public Pad"><span>Public Pad</span></td>
<td width="100%">&nbsp;</td>
<td></td>
</tr>
</table>
</div>
</div>
<div id="navigation"></div>
<div id="docbar" class="menu docbar">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="docbartable"
class="docbartable">
<tr>
<td><img src="../../static/img/roundcorner_left.gif" /></td>
<td id="docbarpadtitle" class="docbarpadtitle" title=
"Public Pad: Public Pad"><span>Public Pad</span></td>
<td width="100%">&nbsp;</td>
<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 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">
<div id="timer">&nbsp;</div>
<div id="steppers">
<a id="leftstep" class="group-start" href="#"></a>
<a id="rightstep" class="group-end" href="#"></a>
</div>
<a id="playpause_button" href="#"></a>
<div id="timeslider-slider">
<div id="ui-slider-handle"></div>
<div id="ui-slider-bar"></div>
</div>
</div>
</div>
</div>
<!--<div id="rightbars" style="top: 95px;">
<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>
<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>
<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/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>
<!--<div id="rightbars" style="top: 95px;">
<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>
<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>
<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/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>
</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="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 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="padmain">
<div id="padeditor">
<div id="editbar" class="editbar disabledtoolbar">
<div id="editbarinner" class="editbarinner">
<table cellpadding="0" cellspacing="0" border="0" id="editbartable" class=
"editbartable">
<tr>
<td>
<h1>
<span id="revision_label"></span>
<span id="revision_date"></span>
</h1>
</td>
<td width="100%">&nbsp;</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" border="0" id="editbarsavetable"
class="editbarsavetable">
<tr>
<td></td>
</tr>
</table>
<div id="editbarleft" class="left"></div>
<div id="editbarright" class="right">
<ul>
<li id="returnbutton"><a href="#">Return to pad</a></li>
<li id="importexport" onClick="window.padeditbar.toolbarClick('importexport');return false;" title="Export to different document formats"></li>
</ul>
</div>
<div id="editbarinner">
<table cellpadding="0" cellspacing="0" border="0" id="editbartable" class="editbartable">
<tr>
<td>
<h1>
<span id="revision_label"></span>
<span id="revision_date"></span>
</h1>
</td>
<td width="100%">&nbsp;</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" border="0" id="editbarsavetable"
class="editbarsavetable">
<tr>
<td></td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div id="editorcontainerbox">
<div id="padcontent">
<div id="editorcontainerbox">
<div id="padcontent"></div>
</div>
</div>
</div><!-- /padeditor -->
</div><!-- /padmain -->
</div><!-- /padpage -->
</div><!-- /padeditor -->
</div><!-- /padmain -->
</div><!-- /padpage -->
<div id="modaloverlay">
<div id="modaloverlay-inner">
<!-- -->
<div id="modaloverlay">
<div id="modaloverlay-inner"></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 -->
<div id="importexport">
<div id="export" 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>
</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>
<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>