UI refactoring and code clean-up

- Improved maintainability of UI (very much work still remaining)
- Improved performance of UI
- Consistent coding style
This commit is contained in:
Dominik Rodler 2012-02-20 23:16:25 +01:00
parent f93fba2511
commit 65ec8a1b47
29 changed files with 2069 additions and 3532 deletions

View file

@ -104,7 +104,7 @@ body.doesWrap {
font-family: monospace;
line-height: 16px; /* overridden by sideDiv.style */
padding-top: 8px; /* EDIT_BODY_PADDING_TOP */
padding-right: 3px; /* LINE_NUMBER_PADDING_RIGHT - 1 */
padding-right: 4px; /* LINE_NUMBER_PADDING_RIGHT - 1 */
position: absolute;
width: 20px; /* MIN_LINEDIV_WIDTH */
top: 0;
@ -119,8 +119,8 @@ body.doesWrap {
.sidedivdelayed { /* class set after sizes are set */
background-color: #eee;
color: #888 !important;
border-right: 1px solid #999;
color: #aaa !important;
border-right: 1px solid #d5d5d5;
}
.sidedivhidden {
display: none;

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 fucking 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 {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:#ddd; height:6px; margin-top:40px;}
#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;}
/* #TODO: this image does not exist */
#timeslider .star {background-image:url(../../static/img/star.png); cursor:pointer; height:16px; position:absolute; top:40px; width:15px;}
/* 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;}
.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;}
/* unordered lists */
UL {list-style-type:disc; margin-left:1.5em;}
UL UL {margin-left:0 !important;}
#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;}
.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;}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

BIN
static/favicon.psd Normal file

Binary file not shown.

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: 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.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

Binary file not shown.

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: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

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

@ -22,186 +22,136 @@
// These parameters were global, now they are injected. A reference to the
// Timeslider controller would probably be more appropriate.
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
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.style.MozUserSelect = "none";
element.style.cursor = "default";
}
var _callSliderCallbacks = function(newval)
{
var _callSliderCallbacks = function(newval) {
sliderPos = newval;
for (var i = 0; i < slidercallbacks.length; i++)
{
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);
}
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)
{
$('#ui-slider-handle').css('left', sliderPos * ($('#ui-slider-bar').width() - 2) / (sliderLength * 1.0));
};
var addSavedRevision = function(position, info) {
var newSavedRevision = $('<div></div>');
newSavedRevision.addClass("star");
newSavedRevision.attr('pos', position);
newSavedRevision.css('position', 'absolute');
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
$("#timeslider-slider").append(newSavedRevision);
newSavedRevision.mouseup(function(evt)
{
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);
};
var removeSavedRevision = function(position)
{
var element = $("div.star [pos=" + position + "]");
var removeSavedRevision = function(position) {
var element = $('.star [pos=' + position + ']');
savedRevisions.remove(element);
element.remove();
return element;
};
/* Begin small 'API' */
function onSlider(callback)
{
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));
}
}
@ -211,280 +161,226 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
setSliderPosition : setSliderPosition,
getSliderLength : getSliderLength,
setSliderLength : setSliderLength,
isSliderActive: function()
{
isSliderActive : function() {
return sliderActive;
},
playpause : playpause,
addSavedRevision : addSavedRevision,
showReconnectUI : showReconnectUI,
setAuthors : setAuthors
}
};
function playButtonUpdater()
{
if (sliderPlaying)
{
if (getSliderPosition() + 1 > sliderLength)
{
$("#playpause_button_icon").toggleClass('pause');
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)
{
switch (code) {
case 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;
} 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);
}
}
else if (code == 39)
{
if (!e.shiftKey)
{
break;
case 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;
} 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);
}
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)
{
$('#ui-slider-handle')
.mousedown(function(evt) {
this.startLoc = evt.clientX;
this.currentLoc = parseInt($(this).css('left'));
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)
{
$('#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)
{
$('#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"))
{
var id = $(self).attr('id'),
i, l, nextStar, pos;
switch (id) {
case 'leftstep':
setSliderPosition(getSliderPosition() - 1);
}
else if ($(self).attr("id") == ("rightstep"))
{
break;
case '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;
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);
}
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;
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').css({"right":"0px", "top":"36px", "border-radius":"0px", "height":"auto", "border-right":"none", "border-left":"1px solid #ccc", "border-top":"none", "background-color":"#f1f1f1", "width":"185px"});
$('#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').css({"right":"20px", "top":"auto", "border-top-left-radius":"5px", "border-top-right-radius":"5px", "border-right":"1px solid #999", "height":"200px", "border-top":"1px solid #999", "background-color":"#f7f7f7"});
$('#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)
{
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();
var minutes = '' + new Date(msg.time).getMinutes(),
hours = '' + new Date(msg.time).getHours(),
timeStr;
if (minutes.length == 1)
minutes = "0" + minutes ;
minutes = '0' + minutes;
if (hours.length == 1)
hours = "0" + hours ;
var timeStr = hours + ":" + minutes;
hours = '0' + hours;
timeStr = hours + ':' + minutes;
// create the authorclass
var authorClass = "author-" + msg.userId.replace(/[^a-y0-9]/g, function(c)
{
if (c == ".") return "-";
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(padutils.escapeHtml(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 html = "<p class='" + authorClass + "'><b>" + authorName + ":</b><span class='time " + authorClass + "'>" + timeStr + "</span> " + text + "</p>";
$("#chattext").append(html);
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);
// should we increment the counter??
if(increment)
{
var count = Number($("#chatcounter").text());
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;

File diff suppressed because it is too large Load diff

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) {
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,158 +77,115 @@ 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')
{
toolbarClick: function(cmd) {
if (self.isEnabled()) {
switch(cmd) {
case 'showusers':
self.toggleDropDown('usersmenu');
break;
case 'settings':
self.toggleDropDown('settingsmenu');
break;
case 'embed':
self.setEmbedLinks();
$('#linkinput').focus().select();
self.toogleDropDown("embed");
}
else if (cmd == 'import_export')
{
self.toogleDropDown("importexport");
}
else if (cmd == 'save')
{
self.toggleDropDown('embedmenu');
break;
case 'import_export':
self.toggleDropDown('importexportmenu');
break;
case '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))
{
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')
{
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?"))
{
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
{
} else {
ace.ace_setAttributeOnSelection('author', '');
}
}
}, cmd, true);
}
}
if(padeditor.ace) padeditor.ace.focus();
if (padeditor.ace)
padeditor.ace.focus();
},
toogleDropDown: function(moduleName)
{
var modules = ["settingsmenu", "importexport", "embed", "users"];
toggleDropDown: function(moduleName) {
var modules = ['settingsmenu', 'importexportmenu', 'embedmenu', 'usersmenu'];
// hide all modules
if(moduleName == "none")
{
$("#editbar ul#menu_right > li").removeClass("selected");
for(var i=0;i<modules.length;i++)
{
if (moduleName == 'none') {
$('#editbar UL.right LI').removeClass('selected');
for (var i=0, l=modules.length; i < l; i++) {
// skip the userlist
if(modules[i] == "users")
if (modules[i] == 'users')
continue;
var module = $("#" + modules[i]);
if(module.css('display') != "none")
{
module.slideUp("fast");
var module = $('#' + modules[i]);
if (module.is(':visible'))
module.slideUp(250);
}
}
}
else
{
} 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");
$('#editbar UL.right LI:not(:nth-child(' + nth_child + '))').removeClass('selected');
$('#editbar UL.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");
}
for (i=0, l=modules.length; i < l; i++) {
module = $('#' + modules[i]);
if (module.is(':visible'))
module.slideUp(250);
else if (modules[i] == moduleName)
{
module.slideDown("fast");
}
module.slideDown(250);
}
}
},
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=H|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=H|0&chl=" + padurl);
$('#embedreadonlyqr').attr('src', "https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=H|0&chl=" + padurl);
}
}
};

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 = {
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,78 +213,60 @@ 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);
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
}
@ -351,45 +277,34 @@ var paduserlist = (function()
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 knocksToIgnore = {},
guestPromptFlashState = 0;
var guestPromptFlash = padutils.makeAnimationScheduler(
function()
{
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,42 +388,20 @@ 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;
@ -537,40 +411,28 @@ var paduserlist = (function()
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,176 +486,120 @@ 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")
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);
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
}
}

View file

@ -225,7 +225,7 @@ var padutils = {
// Use keypress instead of keyup in bindEnterAndEscape
// Keyup event is fired on enter in IME (Input Method Editor), But
// keypress is not. So, I changed to use keypress instead of keyup.
// It is work on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox 3.6.10, Chrome 6.0.472, Safari 5.0).
// It is working on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox 3.6.10, Chrome 6.0.472, Safari 5.0).
if (onEnter)
{
node.keypress(function(evt)

View file

@ -5,32 +5,33 @@
*/
var plugins = {
callHook: function(hookName, args)
{
var global = (function () {return this}());
var hook = ((global.clientVars || {}).hooks || {})[hookName];
if (hook === undefined) return [];
var res = [];
for (var i = 0, N = hook.length; i < N; i++)
{
var plugin = hook[i];
var pluginRes = eval(plugin.plugin)[plugin.original || hookName](args);
if (pluginRes != undefined && pluginRes != null) res = res.concat(pluginRes);
callHook: function(hookName, args) {
var global = (function() {return this;}()),
hook = ((global.clientVars || {}).hooks || {})[hookName],
res = [];
if (hook === undefined)
return [];
for (var i = 0, N = hook.length; i < N; i++) {
var plugin = hook[i],
pluginRes = eval(plugin.plugin)[plugin.original || hookName](args);
if (pluginRes != undefined && pluginRes != null)
res = res.concat(pluginRes);
}
return res;
},
callHookStr: function(hookName, args, sep, pre, post)
{
if (sep == undefined) sep = '';
if (pre == undefined) pre = '';
if (post == undefined) post = '';
var newCallhooks = [];
var callhooks = plugins.callHook(hookName, args);
callHookStr: function(hookName, args, sep, pre, post) {
if (sep == undefined)
sep = '';
if (pre == undefined)
pre = '';
if (post == undefined)
post = '';
var newCallhooks = [],
callhooks = plugins.callHook(hookName, args);
for (var i=0, ii=callhooks.length; i < ii; i++) {
newCallhooks[i] = pre + callhooks[i] + post;
}
return newCallhooks.join(sep || "");
return newCallhooks.join(sep || '');
}
};

View file

@ -26,107 +26,90 @@ 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("/");
// 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;
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);
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
socket = io.connect(url, {resource: resource});
// send the ready message once we're connected
socket.on('connect', function()
{
sendSocketMsg("CLIENT_READY", {});
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")
{
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>")
}
$('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 fireWhenAllScriptsAreLoaded = [],
BroadcastSlider, changesetLoader;
var BroadcastSlider, changesetLoader;
function handleClientVars(message)
{
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);
@ -135,18 +118,15 @@ function handleClientVars(message)
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()
{
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++)
{
for (var i=0, l=fireWhenAllScriptsAreLoaded.length; i < l; i++) {
fireWhenAllScriptsAreLoaded[i]();
}
}

View file

@ -1,114 +1,44 @@
<!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 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 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 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 class="right">
<li id="settings" onClick="window.pad&amp;&amp;pad.editbarClick('settings');return false;" title="Settings of this pad"></li>
<li id="import_export" onClick="window.pad&amp;&amp;pad.editbarClick('import_export');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="showusers" onClick="window.pad&amp;&amp;pad.editbarClick('showusers');return false;" title="Show connected users">1</li>
</ul>
</div>
<div id="users">
<div id="usersmenu" class="popup">
<div id="connectionstatus"></div>
<div id="myuser">
<div id="mycolorpicker">
<div id="colorpicker"></div>
<button id="mycolorpickersave">Save</button>
<button id="mycolorpickersave" class="button">Save</button>
<button id="mycolorpickercancel">Cancel</button>
<span id="mycolorpickerpreview" class="myswatchboxhoverable"></span>
</div>
@ -126,15 +56,10 @@
<div id="userlistbuttonarea"></div>
</div>
<div id="editorcontainerbox">
<div id="editorcontainer"></div>
<div id="editorloadingbox">Loading...</div>
</div>
<div id="settingsmenu" class="popup">
<h1>Pad settings</h1>
<h2>Pad settings</h2>
<div class="left_popup">
<h2>My view</h2>
<h3>My view</h3>
<p>
<input type="checkbox" id="options-stickychat" onClick="chat.stickToScreen();">
<label for="options-stickychat">Chat always on screen</label>
@ -156,15 +81,15 @@
</p>
</div>
<div class="right_popup">
<h2>Global view</h2>
<h3>Global view</h3>
<p>Currently nothing.</p>
<p class="note">These options affect everyone viewing this pad.</p>
</div>
</div>
<div id="importexport" class="popup">
<div id="importexportmenu" class="popup">
<div class="left_popup">
<h2>Import from text file, HTML, PDF, Word, ODT or RTF</h2><br>
<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">
@ -173,16 +98,12 @@
<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>
<input id="importsubmitinput" class="button" type="submit" name="submit" value="Import Now" disabled="disabled">
</div>
</form>
</div>
<div class="right_popup">
<h2>Export current pad as</h2>
<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>
@ -193,40 +114,42 @@
</div>
</div>
<div id="embed" class="popup">
<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>
<h1>Share this pad</h1>
<h2>Share this pad</h2>
<div id="linkcode">
<h2>Link</h2>
<h3>Link</h3>
<input id="linkinput" type="text" value="">
</div>
<br>
<div id="embedcode">
<h2>Embed URL</h2>
<h3>Embed URL</h3>
<input id="embedinput" type="text" value="">
</div>
<br>
<div id="qrcode">
<h2>QR code</h2>
<h3>QR code</h3>
<div id="qr_center"><img id="embedreadonlyqr"></div>
</div>
</div>
<div id="chatthrob"></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>
<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="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>
@ -285,7 +208,6 @@
<input type="hidden" class="missedChanges" name="missedChanges">
</form>
</div>
</div>
<script type="text/javascript" src="../static/js/require-kernel.js"></script>
@ -306,5 +228,5 @@
padimpexp = require('/pad_impexp').padimpexp;
}());
</script>
</body>
</html>

View file

@ -1,101 +1,58 @@
<!doctype html>
<html lang="en">
<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 id="padbody" class="timeslider limwidth nonpropad nonprouser">
<body>
<div id="padpage">
<div id="padtop">
<div class="topbar">
<div class="topbarleft">
<!-- -->
</div>
<div class="topbarright">
<!-- -->
</div>
<div class="topbarleft"><!-- --></div>
<div class="topbarright"><!-- --></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 class="fullscreen" onclick="$('body').toggleClass('maximized');">Full screen</div>
</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>
<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 id="navigation"></div>
<div id="docbar" class="menu docbar">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="docbartable"
class="docbartable">
<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></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>
<td></td>
</tr>
</table>
</div><!-- /docbar -->
</div>
</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 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>
<div id="timeslider" unselectable="on" style="display: none">
<div id="timeslider-left"></div>
<div id="timeslider-right"></div>
<div id="timer"></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 id="playpause_button">
<div id="playpause_button_icon" class=""></div>
</div>
<div id="steppers">
<div class="stepper" id="leftstep"></div>
<div class="stepper" id="rightstep"></div>
</div>
</div>
</div>
@ -109,7 +66,6 @@
<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>
@ -121,25 +77,15 @@
<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-->
<div id="editbarleft" class="left"></div>
<div id="editbarright" class="right">
<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>
<li id="returnbutton"><a href="#">Return to pad</a></li>
<li id="import_export" onClick="window.padeditbar.toolbarClick('import_export');return false;" title="Export to different document formats"></li>
</ul>
<a id = "returnbutton">Return to pad</a>
</div>
<div id="editbarinner" class="editbarinner">
<table cellpadding="0" cellspacing="0" border="0" id="editbartable" class=
"editbartable">
<div id="editbarinner">
<table cellpadding="0" cellspacing="0" border="0" id="editbartable" class="editbartable">
<tr>
<td>
<h1>
@ -147,11 +93,9 @@
<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>
@ -161,28 +105,19 @@
</div>
</div>
</div>
<div id="editorcontainerbox">
<div id="padcontent">
</div>
<div id="padcontent"></div>
</div>
</div><!-- /padeditor -->
</div><!-- /padmain -->
</div><!-- /padpage -->
<div id="modaloverlay">
<div id="modaloverlay-inner">
<!-- -->
<div id="modaloverlay-inner"></div>
</div>
</div>
<div id="mainmodals"></div>
<!-- export code -->
<div id="importexport">
<div id="export" class="popup">
<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>
@ -195,7 +130,6 @@
<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>
@ -215,4 +149,3 @@
</script>
</body>
</html>