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; font-family: monospace;
line-height: 16px; /* overridden by sideDiv.style */ line-height: 16px; /* overridden by sideDiv.style */
padding-top: 8px; /* EDIT_BODY_PADDING_TOP */ 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; position: absolute;
width: 20px; /* MIN_LINEDIV_WIDTH */ width: 20px; /* MIN_LINEDIV_WIDTH */
top: 0; top: 0;
@ -119,8 +119,8 @@ body.doesWrap {
.sidedivdelayed { /* class set after sizes are set */ .sidedivdelayed { /* class set after sizes are set */
background-color: #eee; background-color: #eee;
color: #888 !important; color: #aaa !important;
border-right: 1px solid #999; border-right: 1px solid #d5d5d5;
} }
.sidedivhidden { .sidedivhidden {
display: none; 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 sprite */
#timeslider-left {background-image:url(../../static/img/timeslider_left.png); height:63px; left:0; position:absolute; width:134px;} #ui-slider-handle, #playpause_button, #steppers A {background:url(../../static/img/timeslider-sprite.png) 0 0 no-repeat;}
#timeslider-right {background-image:url(../../static/img/timeslider_right.png); height:63px; position:absolute; right:0; top:0; width:155px;}
#timeslider {background-image:url(../../static/img/timeslider_background.png); height:63px; margin:0 9px;}
#timeslider #timeslider-slider {height:61px; left:0; position:absolute; top:1px; width:100%;}
#ui-slider-handle {
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
-webkit-user-select:none;
background-image:url(../../static/img/crushed_current_location.png);
cursor:pointer;
height:61px;
left:0;
position:absolute;
top:0;
user-select:none;
width:13px;
}
#ui-slider-bar {
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
-webkit-user-select:none;
cursor:pointer;
height:35px;
margin-left:5px;
margin-right:148px;
position:relative;
top:20px;
user-select:none;
}
#playpause_button, #playpause_button_icon {height:47px; position:absolute; width:47px;} #timeslider {background:#f5f5f5; border-bottom:1px solid #d5d5d5; padding:6px 0; position:absolute; top:0; width:100%;}
#playpause_button {background-image:url(../../static/img/crushed_button_undepressed.png); right:77px; top:9px;} #timer {background-color:#aaa; border-radius:3px; color:#fff; font-family:Arial, sans-serif; font-size:11px; left:6px; min-width:101px; padding:2px 4px 1px; position:absolute; top:7px;}
#playpause_button_icon {background-image:url(../../static/img/play.png); left:0; top:0;} #timeslider-wrapper {float:left; width:100%;}
.pause#playpause_button_icon {background-image:url(../../static/img/pause.png);} #timeslider-slider {margin:0 164px 0 6px;}
#timeslider-slider DIV {cursor:pointer;}
#ui-slider-handle {background-position:-142px 0; height:22px; left:0; position:absolute; top:30px; width:13px;}
#ui-slider-bar {background:#ddd; height:6px; margin-top:40px;}
#leftstar, #rightstar, #leftstep, #rightstep #playpause_button {background-color:#ddd; background-position:-60px 0; border-radius:30px; float:right; height:46px; width:46px;}
{background:url(../../static/img/stepper_buttons.png) 0 0 no-repeat; height:21px; overflow:hidden; position:absolute;} #playpause_button:hover {background-position:-60px -40px;}
#leftstar {background-position:0 44px; right:34px; top:8px; width:30px;} #playpause_button.pause {background-position:-100px 0;}
#rightstar {background-position:29px 44px; right:5px; top:8px; width:29px;} #playpause_button.pause:hover {background-position:-100px -40px;}
#leftstep {background-position:0 22px; right:34px; top:20px; width:30px;}
#rightstep {background-position:29px 22px; right:5px; top:20px; width:29px;}
#timeslider .star { #steppers {float:right; margin:0 35px 0 10px; width:60px;}
background-image:url(../../static/img/star.png); #steppers A {border:1px solid #d5d5d5; box-shadow:0 1px 0 #fff; float:left; height:20px; margin:0 0 4px; width:28px;}
cursor:pointer; #steppers .group-start {border-radius:3px 0 0 3px;}
height:16px; #steppers .group-end {border-radius:0 3px 3px 0; border-width:1px 1px 1px 0; width:29px;}
position:absolute;
top:40px;
width:15px;
}
#timeslider #timer { A#leftstar, #leftstar.inactive:hover {background-position:0 0;}
color:#fff; A#rightstar, #rightstar.inactive:hover {background-position:-30px 0;}
font-family:Arial, sans-serif; A#leftstep, #leftstep.inactive:hover {background-position:0 -20px;}
font-size:11px; A#rightstep, #rightstep.inactive:hover {background-position:-30px -20px;}
left:7px; A#leftstar:hover {background-position:0 -40px;}
position:absolute; A#rightstar:hover {background-position:-30px -40px;}
text-align:center; A#leftstep:hover {background-position:0 -60px;}
top:9px; A#rightstep:hover {background-position:-30px -60px;}
width:122px;
}
.topbarcenter, #docbar {display:none;} /* #TODO: this image does not exist */
#padmain {top:30px;} #timeslider .star {background-image:url(../../static/img/star.png); cursor:pointer; height:16px; position:absolute; top:40px; width:15px;}
#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;}
/* lists */ .topbarcenter, #docbar {display:none;} /* hide document title etc. */
.list-bullet2, .list-indent2, .list-number2 {margin-left:3em;} #editbarinner H1 {color:#999; font-size:16px; line-height:29px; margin-top:0; padding-left:6px;}
.list-bullet3, .list-indent3, .list-number3 {margin-left:4.5em;} #editbarinner H1 A {font-size:12px;}
.list-bullet4, .list-indent4, .list-number4 {margin-left:6em;} #revision_label {background-color:#aaa; border-radius:3px; color:#fff; padding:2px 5px;}
.list-bullet5, .list-indent5, .list-number5 {margin-left:7.5em;}
.list-bullet6, .list-indent6, .list-number6 {margin-left:9em;}
.list-bullet7, .list-indent7, .list-number7 {margin-left:10.5em;}
.list-bullet8, .list-indent8, .list-number8 {margin-left:12em;}
/* unordered lists */ #editbarright #returnbutton {background:0 none; border:0 none; box-shadow:none; padding:4px 6px; width:auto;}
UL {list-style-type:disc; margin-left:1.5em;} #returnbutton A {color:#999; font-size:12px; line-height:20px;}
UL UL {margin-left:0 !important;}
.list-bullet2, .list-bullet5, .list-bullet8 {list-style-type:circle;} #importexport.popup {top:95px; width:140px;}
.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);}

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -20,74 +20,56 @@
* limitations under the License. * limitations under the License.
*/ */
var padutils = require('/pad_utils').padutils; var padutils = require('/pad_utils').padutils,
var padeditor = require('/pad_editor').padeditor; padeditor = require('/pad_editor').padeditor,
var padsavedrevs = require('/pad_savedrevs').padsavedrevs; padsavedrevs = require('/pad_savedrevs').padsavedrevs;
function indexOf(array, value) { function indexOf(array, value) {
for (var i=0, ii=array.length; i < ii; i++) { for (var i=0, ii=array.length; i < ii; i++) {
if (array[i] == value) { if (array[i] == value)
return i; return i;
} }
}
return -1; return -1;
} }
var padeditbar = (function() var padeditbar = (function() {
{ var syncAnimation = (function() {
var SYNCING = -100,
var syncAnimation = (function() DONE = 100,
{ state = DONE,
var SYNCING = -100; fps = 25,
var DONE = 100; step = 1 / fps,
var state = DONE; T_START = -0.5,
var fps = 25; T_FADE = 1.0,
var step = 1 / fps; T_GONE = 1.5;
var T_START = -0.5; var animator = padutils.makeAnimationScheduler(function() {
var T_FADE = 1.0;
var T_GONE = 1.5;
var animator = padutils.makeAnimationScheduler(function()
{
if (state == SYNCING || state == DONE) if (state == SYNCING || state == DONE)
{
return false; return false;
} else if (state >= T_GONE) {
else if (state >= T_GONE)
{
state = DONE; state = DONE;
$("#syncstatussyncing").css('display', 'none'); $('#syncstatussyncing, #syncstatusdone').hide();
$("#syncstatusdone").css('display', 'none');
return false; return false;
} } else if (state < 0) {
else if (state < 0)
{
state += step; state += step;
if (state >= 0) if (state >= 0) {
{ $('#syncstatussyncing').hide();
$("#syncstatussyncing").css('display', 'none'); $('#syncstatusdone').show().css({opacity: 1});
$("#syncstatusdone").css('display', 'block').css('opacity', 1);
} }
return true; return true;
} } else {
else
{
state += step; state += step;
if (state >= T_FADE) if (state >= T_FADE)
{ $('#syncstatusdone').css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
$("#syncstatusdone").css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
}
return true; return true;
} }
}, step * 1000); }, step * 1000);
return { return {
syncing: function() syncing: function() {
{
state = SYNCING; state = SYNCING;
$("#syncstatussyncing").css('display', 'block'); $('#syncstatussyncing').show();
$("#syncstatusdone").css('display', 'none'); $('#syncstatusdone').hide();
}, },
done: function() done: function() {
{
state = T_START; state = T_START;
animator.scheduleAnimation(); animator.scheduleAnimation();
} }
@ -95,158 +77,115 @@ var padeditbar = (function()
}()); }());
var self = { var self = {
init: function() init: function() {
{ $('#editbar A').attr('unselectable', 'on'); // for IE
$("#editbar .editbarbutton").attr("unselectable", "on"); // for IE $('#editbar').removeClass('disabledtoolbar').addClass('enabledtoolbar');
$("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
}, },
isEnabled: function() isEnabled: function() {
{
// return !$("#editbar").hasClass('disabledtoolbar'); // return !$("#editbar").hasClass('disabledtoolbar');
return true; return true;
}, },
disable: function() disable: function() {
{ $('#editbar').addClass('disabledtoolbar').removeClass('enabledtoolbar');
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
}, },
toolbarClick: function(cmd) toolbarClick: function(cmd) {
{ if (self.isEnabled()) {
if (self.isEnabled()) switch(cmd) {
{ case 'showusers':
if(cmd == "showusers") self.toggleDropDown('usersmenu');
{ break;
self.toogleDropDown("users"); case 'settings':
} self.toggleDropDown('settingsmenu');
else if (cmd == 'settings') break;
{ case 'embed':
self.toogleDropDown("settingsmenu");
}
else if (cmd == 'embed')
{
self.setEmbedLinks(); self.setEmbedLinks();
$('#linkinput').focus().select(); self.toggleDropDown('embedmenu');
self.toogleDropDown("embed"); break;
} case 'import_export':
else if (cmd == 'import_export') self.toggleDropDown('importexportmenu');
{ break;
self.toogleDropDown("importexport"); case 'save':
}
else if (cmd == 'save')
{
padsavedrevs.saveNow(); padsavedrevs.saveNow();
} break;
else default:
{ padeditor.ace.callWithAce(function(ace) {
padeditor.ace.callWithAce(function(ace) if (cmd == 'bold' || cmd == 'italic' || cmd == 'underline' || cmd == 'strikethrough')
{ ace.ace_toggleAttributeOnSelection(cmd);
if (cmd == 'bold' || cmd == 'italic' || cmd == 'underline' || cmd == 'strikethrough') ace.ace_toggleAttributeOnSelection(cmd); else if (cmd == 'undo' || cmd == 'redo')
else if (cmd == 'undo' || cmd == 'redo') ace.ace_doUndoRedo(cmd); ace.ace_doUndoRedo(cmd);
else if (cmd == 'insertunorderedlist') ace.ace_doInsertUnorderedList(); else if (cmd == 'insertunorderedlist')
else if (cmd == 'insertorderedlist') ace.ace_doInsertOrderedList();
else if (cmd == 'indent')
{
if (!ace.ace_doIndentOutdent(false))
{
ace.ace_doInsertUnorderedList(); ace.ace_doInsertUnorderedList();
} else if (cmd == 'insertorderedlist')
} ace.ace_doInsertOrderedList();
else if (cmd == 'outdent') else if (cmd == 'indent') {
{ if (!ace.ace_doIndentOutdent(false))
ace.ace_doInsertUnorderedList();
} else if (cmd == 'outdent')
ace.ace_doIndentOutdent(true); ace.ace_doIndentOutdent(true);
} else if (cmd == 'clearauthorship') {
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?")) {
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, [ ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [
['author', ''] ['author', '']
]); ]);
} }
} } else {
else
{
ace.ace_setAttributeOnSelection('author', ''); ace.ace_setAttributeOnSelection('author', '');
} }
} }
}, cmd, true); }, cmd, true);
} }
} }
if(padeditor.ace) padeditor.ace.focus(); if (padeditor.ace)
padeditor.ace.focus();
}, },
toogleDropDown: function(moduleName) toggleDropDown: function(moduleName) {
{ var modules = ['settingsmenu', 'importexportmenu', 'embedmenu', 'usersmenu'];
var modules = ["settingsmenu", "importexport", "embed", "users"];
// hide all modules // hide all modules
if(moduleName == "none") if (moduleName == 'none') {
{ $('#editbar UL.right LI').removeClass('selected');
$("#editbar ul#menu_right > li").removeClass("selected"); for (var i=0, l=modules.length; i < l; i++) {
for(var i=0;i<modules.length;i++)
{
// skip the userlist // skip the userlist
if(modules[i] == "users") if (modules[i] == 'users')
continue; continue;
var module = $('#' + modules[i]);
var module = $("#" + modules[i]); if (module.is(':visible'))
module.slideUp(250);
if(module.css('display') != "none")
{
module.slideUp("fast");
} }
} } else {
}
else
{
var nth_child = indexOf(modules, moduleName) + 1; var nth_child = indexOf(modules, moduleName) + 1;
if (nth_child > 0 && nth_child <= 3) { if (nth_child > 0 && nth_child <= 3) {
$("#editbar ul#menu_right li:not(:nth-child(" + nth_child + "))").removeClass("selected"); $('#editbar UL.right LI:not(:nth-child(' + nth_child + '))').removeClass('selected');
$("#editbar ul#menu_right li:nth-child(" + nth_child + ")").toggleClass("selected"); $('#editbar UL.right LI:nth-child(' + nth_child + ')').toggleClass('selected');
} }
// hide all modules that are not selected and show the selected one // hide all modules that are not selected and show the selected one
for(var i=0;i<modules.length;i++) for (i=0, l=modules.length; i < l; i++) {
{ module = $('#' + modules[i]);
var module = $("#" + modules[i]); if (module.is(':visible'))
module.slideUp(250);
if(module.css('display') != "none")
{
module.slideUp("fast");
}
else if (modules[i] == moduleName) else if (modules[i] == moduleName)
{ module.slideDown(250);
module.slideDown("fast");
}
} }
} }
}, },
setSyncStatus: function(status) setSyncStatus: function(status) {
{ if (status == 'syncing')
if (status == "syncing")
{
syncAnimation.syncing(); syncAnimation.syncing();
} else if (status == 'done')
else if (status == "done")
{
syncAnimation.done(); syncAnimation.done();
}
}, },
setEmbedLinks: function() setEmbedLinks: function() {
{ if ($('#readonlyinput').is(':checked')) {
if ($('#readonlyinput').is(':checked')) var basePath = document.location.href.substring(0, document.location.href.indexOf('/p/')),
{ readonlyLink = basePath + '/ro/' + clientVars.readOnlyId;
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
var readonlyLink = basePath + "/ro/" + clientVars.readOnlyId;
$('#embedinput').val("<iframe src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>"); $('#embedinput').val("<iframe src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
$('#linkinput').val(readonlyLink); $('#linkinput').val(readonlyLink);
$('#embedreadonlyqr').attr("src","https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=H|0&chl=" + readonlyLink); $('#embedreadonlyqr').attr('src', 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=H|0&chl=' + readonlyLink);
} } else {
else var padurl = window.location.href.split('?')[0];
{
var padurl = window.location.href.split("?")[0];
$('#embedinput').val("<iframe src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>"); $('#embedinput').val("<iframe src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
$('#linkinput').val(padurl); $('#linkinput').val(padurl);
$('#embedreadonlyqr').attr("src","https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=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. * limitations under the License.
*/ */
var padutils = require('/pad_utils').padutils; var padutils = require('/pad_utils').padutils,
myUserInfo = {},
colorPickerOpen = false,
colorPickerSetup = false,
previousColorId = 0;
var myUserInfo = {}; var paduserlist = (function() {
var colorPickerOpen = false; var rowManager = (function() {
var colorPickerSetup = false;
var previousColorId = 0;
var paduserlist = (function()
{
var rowManager = (function()
{
// The row manager handles rendering rows of the user list and animating // The row manager handles rendering rows of the user list and animating
// their insertion, removal, and reordering. It manipulates TD height // their insertion, removal, and reordering. It manipulates TD height
// and TD opacity. // and TD opacity.
function nextRowId() function nextRowId() {
{
return "usertr" + (nextRowId.counter++); return "usertr" + (nextRowId.counter++);
} }
nextRowId.counter = 1; nextRowId.counter = 1;
// objects are shared; fields are "domId","data","animationStep" // objects are shared; fields are "domId","data","animationStep"
var rowsFadingOut = []; // unordered set var rowsFadingOut = [], // unordered set
var rowsFadingIn = []; // unordered set rowsFadingIn = [], // unordered set
var rowsPresent = []; // in order rowsPresent = [], // in order
var ANIMATION_START = -12; // just starting to fade in ANIMATION_START = -12, // just starting to fade in
var ANIMATION_END = 12; // just finishing fading out ANIMATION_END = 12; // just finishing fading out
function getAnimationHeight(step, power) {
function getAnimationHeight(step, power)
{
var a = Math.abs(step / 12); var a = Math.abs(step / 12);
if (power == 2) a = a * a; if (power == 2)
else if (power == 3) a = a * a * a; a = a * a;
else if (power == 4) a = a * a * a * a; else if (power == 3)
else if (power >= 5) a = a * a * a * a * a; a = a * a * a;
else if (power == 4)
a = a * a * a * a;
else if (power >= 5)
a = a * a * a * a * a;
return Math.round(26 * (1 - a)); return Math.round(26 * (1 - a));
} }
var OPACITY_STEPS = 6; var OPACITY_STEPS = 6,
ANIMATION_STEP_TIME = 20,
var ANIMATION_STEP_TIME = 20; LOWER_FRAMERATE_FACTOR = 2,
var LOWER_FRAMERATE_FACTOR = 2; scheduleAnimation = padutils.makeAnimationScheduler(animateStep, ANIMATION_STEP_TIME, LOWER_FRAMERATE_FACTOR).scheduleAnimation,
var scheduleAnimation = padutils.makeAnimationScheduler(animateStep, ANIMATION_STEP_TIME, LOWER_FRAMERATE_FACTOR).scheduleAnimation; NUMCOLS = 4;
var NUMCOLS = 4;
// we do lots of manipulation of table rows and stuff that JQuery makes ok, despite // we do lots of manipulation of table rows and stuff that JQuery makes ok, despite
// IE's poor handling when manipulating the DOM directly. // IE's poor handling when manipulating the DOM directly.
function getEmptyRowHtml(height) function getEmptyRowHtml(height) {
{
return '<td colspan="' + NUMCOLS + '" style="border:0;height:' + height + 'px"><!-- --></td>'; return '<td colspan="' + NUMCOLS + '" style="border:0;height:' + height + 'px"><!-- --></td>';
} }
function isNameEditable(data) function isNameEditable(data) {
{
return (!data.name) && (data.status != 'Disconnected'); return (!data.name) && (data.status != 'Disconnected');
} }
function replaceUserRowContents(tr, height, data) function replaceUserRowContents(tr, height, data) {
{
var tds = getUserRowHtml(height, data).match(/<td.*?<\/td>/gi); var tds = getUserRowHtml(height, data).match(/<td.*?<\/td>/gi);
if (isNameEditable(data) && tr.find("td.usertdname input:enabled").length > 0) if (isNameEditable(data) && tr.find("td.usertdname input:enabled").length > 0) {
{
// preserve input field node // preserve input field node
for (var i = 0; i < tds.length; i++) for (var i=0, l=tds.length; i < l; i++) {
{
var oldTd = $(tr.find("td").get(i)); var oldTd = $(tr.find("td").get(i));
if (!oldTd.hasClass('usertdname')) if (!oldTd.hasClass('usertdname'))
{
oldTd.replaceWith(tds[i]); oldTd.replaceWith(tds[i]);
} }
} } else {
}
else
{
tr.html(tds.join('')); tr.html(tds.join(''));
} }
return tr; return tr;
} }
function getUserRowHtml(height, data) function getUserRowHtml(height, data) {
{ var isGuest = (data.id.charAt(0) != 'p'),
var nameHtml; nameHtml;
var isGuest = (data.id.charAt(0) != 'p'); if (data.name) {
if (data.name)
{
nameHtml = padutils.escapeHtml(data.name); nameHtml = padutils.escapeHtml(data.name);
if (isGuest && pad.getIsProPad()) if (isGuest && pad.getIsProPad())
{
nameHtml += ' (Guest)'; nameHtml += ' (Guest)';
} } else {
}
else
{
nameHtml = '<input type="text" class="editempty newinput" value="unnamed" ' + (isNameEditable(data) ? '' : 'disabled="disabled" ') + '/>'; nameHtml = '<input type="text" class="editempty newinput" value="unnamed" ' + (isNameEditable(data) ? '' : 'disabled="disabled" ') + '/>';
} }
return ['<td style="height:', height, 'px" class="usertdswatch"><div class="swatch" style="background:' + data.color + '">&nbsp;</div></td>', '<td style="height:', height, 'px" class="usertdname">', nameHtml, '</td>', '<td style="height:', height, 'px" class="usertdstatus">', padutils.escapeHtml(data.status), '</td>', '<td style="height:', height, 'px" class="activity">', padutils.escapeHtml(data.activity), '</td>'].join(''); return ['<td style="height:', height, 'px" class="usertdswatch"><div class="swatch" style="background:' + data.color + '">&nbsp;</div></td>', '<td style="height:', height, 'px" class="usertdname">', nameHtml, '</td>', '<td style="height:', height, 'px" class="usertdstatus">', padutils.escapeHtml(data.status), '</td>', '<td style="height:', height, 'px" class="activity">', padutils.escapeHtml(data.activity), '</td>'].join('');
} }
function getRowHtml(id, innerHtml) function getRowHtml(id, innerHtml) {
{
return '<tr id="' + id + '">' + innerHtml + '</tr>'; return '<tr id="' + id + '">' + innerHtml + '</tr>';
} }
function rowNode(row) function rowNode(row) {
{
return $("#" + row.domId); return $("#" + row.domId);
} }
function handleRowData(row) function handleRowData(row) {
{ if (row.data && row.data.status == 'Disconnected') {
if (row.data && row.data.status == 'Disconnected')
{
row.opacity = 0.5; row.opacity = 0.5;
} } else {
else
{
delete row.opacity; delete row.opacity;
} }
} }
function handleRowNode(tr, data) function handleRowNode(tr, data) {
{ if (data.titleText) {
if (data.titleText)
{
var titleText = data.titleText; var titleText = data.titleText;
window.setTimeout(function() window.setTimeout(function() {
{
/* tr.attr('title', titleText)*/ /* tr.attr('title', titleText)*/
}, 0); }, 0);
} } else {
else
{
tr.removeAttr('title'); tr.removeAttr('title');
} }
} }
function handleOtherUserInputs() function handleOtherUserInputs() {
{
// handle 'INPUT' elements for naming other unnamed users // handle 'INPUT' elements for naming other unnamed users
$("#otheruserstable input.newinput").each(function() $('#otheruserstable .newinput')
{ .each(function() {
var input = $(this); var input = $(this),
var tr = input.closest("tr"); tr = input.closest('tr');
if (tr.length > 0) if (tr.length > 0) {
{
var index = tr.parent().children().index(tr); var index = tr.parent().children().index(tr);
if (index >= 0) if (index >= 0) {
{
var userId = rowsPresent[index].data.id; var userId = rowsPresent[index].data.id;
rowManagerMakeNameEditor($(this), userId); rowManagerMakeNameEditor($(this), userId);
} }
} }
}).removeClass('newinput'); })
.removeClass('newinput');
} }
// animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc. // animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc.
function insertRow(position, data, animationPower) {
function insertRow(position, data, animationPower)
{
position = Math.max(0, Math.min(rowsPresent.length, position)); position = Math.max(0, Math.min(rowsPresent.length, position));
animationPower = (animationPower === undefined ? 4 : animationPower); animationPower = (animationPower === undefined ? 4 : animationPower);
var domId = nextRowId(); var domId = nextRowId(),
var row = { row = {
data : data, data : data,
animationStep : ANIMATION_START, animationStep : ANIMATION_START,
domId : domId, domId : domId,
animationPower: animationPower animationPower: animationPower
}; },
tr;
handleRowData(row); handleRowData(row);
rowsPresent.splice(position, 0, row); rowsPresent.splice(position, 0, row);
var tr; if (animationPower == 0) {
if (animationPower == 0)
{
tr = $(getRowHtml(domId, getUserRowHtml(getAnimationHeight(0), data))); tr = $(getRowHtml(domId, getUserRowHtml(getAnimationHeight(0), data)));
row.animationStep = 0; row.animationStep = 0;
} } else {
else
{
rowsFadingIn.push(row); rowsFadingIn.push(row);
tr = $(getRowHtml(domId, getEmptyRowHtml(getAnimationHeight(ANIMATION_START)))); tr = $(getRowHtml(domId, getEmptyRowHtml(getAnimationHeight(ANIMATION_START))));
} }
handleRowNode(tr, data); handleRowNode(tr, data);
if (position == 0) if (position == 0)
{ $('#otheruserstable').prepend(tr);
$("table#otheruserstable").prepend(tr);
}
else else
{
rowNode(rowsPresent[position - 1]).after(tr); rowNode(rowsPresent[position - 1]).after(tr);
}
if (animationPower != 0) if (animationPower != 0)
{
scheduleAnimation(); scheduleAnimation();
}
handleOtherUserInputs(); handleOtherUserInputs();
return row; return row;
} }
function updateRow(position, data) function updateRow(position, data) {
{
var row = rowsPresent[position]; var row = rowsPresent[position];
if (row) if (row) {
{
row.data = data; row.data = data;
handleRowData(row); handleRowData(row);
if (row.animationStep == 0) if (row.animationStep == 0) {
{
// not currently animating // not currently animating
var tr = rowNode(row); var tr = rowNode(row);
replaceUserRowContents(tr, getAnimationHeight(0), row.data).find("td").css('opacity', (row.opacity === undefined ? 1 : row.opacity)); replaceUserRowContents(tr, getAnimationHeight(0), row.data).find("td").css('opacity', (row.opacity === undefined ? 1 : row.opacity));
@ -246,19 +195,14 @@ var paduserlist = (function()
} }
} }
function removeRow(position, animationPower) function removeRow(position, animationPower) {
{
animationPower = (animationPower === undefined ? 4 : animationPower); animationPower = (animationPower === undefined ? 4 : animationPower);
var row = rowsPresent[position]; var row = rowsPresent[position];
if (row) if (row) {
{
rowsPresent.splice(position, 1); // remove rowsPresent.splice(position, 1); // remove
if (animationPower == 0) if (animationPower == 0) {
{
rowNode(row).remove(); rowNode(row).remove();
} } else {
else
{
row.animationStep = -row.animationStep; // use symmetry row.animationStep = -row.animationStep; // use symmetry
row.animationPower = animationPower; row.animationPower = animationPower;
rowsFadingOut.push(row); rowsFadingOut.push(row);
@ -269,78 +213,60 @@ var paduserlist = (function()
// newPosition is position after the row has been removed // newPosition is position after the row has been removed
function moveRow(oldPosition, newPosition, animationPower) {
function moveRow(oldPosition, newPosition, animationPower)
{
animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best
var row = rowsPresent[oldPosition]; var row = rowsPresent[oldPosition];
if (row && oldPosition != newPosition) if (row && oldPosition != newPosition) {
{
var rowData = row.data; var rowData = row.data;
removeRow(oldPosition, animationPower); removeRow(oldPosition, animationPower);
insertRow(newPosition, rowData, animationPower); insertRow(newPosition, rowData, animationPower);
} }
} }
function animateStep() function animateStep() {
{ var row, step, node, $td, animHeight, baseOpacity, i;
// animation must be symmetrical // animation must be symmetrical
for (var i = rowsFadingIn.length - 1; i >= 0; i--) for (i=rowsFadingIn.length - 1; i >= 0; i--) { // backwards to allow removal
{ // backwards to allow removal row = rowsFadingIn[i];
var row = rowsFadingIn[i]; step = ++row.animationStep;
var step = ++row.animationStep; animHeight = getAnimationHeight(step, row.animationPower);
var animHeight = getAnimationHeight(step, row.animationPower); node = rowNode(row);
var node = rowNode(row); $td = node.find('TD');
var baseOpacity = (row.opacity === undefined ? 1 : row.opacity); baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
if (step <= -OPACITY_STEPS) if (step <= -OPACITY_STEPS)
{ $td.height(animHeight);
node.find("td").height(animHeight); else if (step == -OPACITY_STEPS + 1) {
} node.html(getUserRowHtml(animHeight, row.data)).find('TD').css('opacity', baseOpacity * 1 / OPACITY_STEPS);
else if (step == -OPACITY_STEPS + 1)
{
node.html(getUserRowHtml(animHeight, row.data)).find("td").css('opacity', baseOpacity * 1 / OPACITY_STEPS);
handleRowNode(node, row.data); handleRowNode(node, row.data);
} } else if (step < 0) {
else if (step < 0) $td.css('opacity', baseOpacity * (OPACITY_STEPS - (-step)) / OPACITY_STEPS).height(animHeight);
{ } else if (step == 0) {
node.find("td").css('opacity', baseOpacity * (OPACITY_STEPS - (-step)) / OPACITY_STEPS).height(animHeight);
}
else if (step == 0)
{
// set HTML in case modified during animation // set HTML in case modified during animation
node.html(getUserRowHtml(animHeight, row.data)).find("td").css('opacity', baseOpacity * 1).height(animHeight); node.html(getUserRowHtml(animHeight, row.data)).find("td").css('opacity', baseOpacity * 1).height(animHeight);
handleRowNode(node, row.data); handleRowNode(node, row.data);
rowsFadingIn.splice(i, 1); // remove from set rowsFadingIn.splice(i, 1); // remove from set
} }
} }
for (var i = rowsFadingOut.length - 1; i >= 0; i--) for (i=rowsFadingOut.length - 1; i >= 0; i--) { // backwards to allow removal
{ // backwards to allow removal row = rowsFadingOut[i];
var row = rowsFadingOut[i]; step = ++row.animationStep;
var step = ++row.animationStep; node = rowNode(row);
var node = rowNode(row); $td = node.find('TD');
var animHeight = getAnimationHeight(step, row.animationPower); animHeight = getAnimationHeight(step, row.animationPower);
var baseOpacity = (row.opacity === undefined ? 1 : row.opacity); baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
if (step < OPACITY_STEPS) if (step < OPACITY_STEPS)
{ $td.css('opacity', baseOpacity * (OPACITY_STEPS - step) / OPACITY_STEPS).height(animHeight);
node.find("td").css('opacity', baseOpacity * (OPACITY_STEPS - step) / OPACITY_STEPS).height(animHeight);
}
else if (step == OPACITY_STEPS) else if (step == OPACITY_STEPS)
{
node.html(getEmptyRowHtml(animHeight)); node.html(getEmptyRowHtml(animHeight));
}
else if (step <= ANIMATION_END) else if (step <= ANIMATION_END)
{ $td.height(animHeight);
node.find("td").height(animHeight); else {
}
else
{
rowsFadingOut.splice(i, 1); // remove from set rowsFadingOut.splice(i, 1); // remove from set
node.remove(); node.remove();
} }
} }
handleOtherUserInputs(); handleOtherUserInputs();
return (rowsFadingIn.length > 0) || (rowsFadingOut.length > 0); // is more to do return (rowsFadingIn.length > 0) || (rowsFadingOut.length > 0); // is more to do
} }
@ -351,45 +277,34 @@ var paduserlist = (function()
updateRow : updateRow updateRow : updateRow
}; };
return self; return self;
}()); ////////// rowManager }());
var otherUsersInfo = []; // rowManager END #########################################################
var otherUsersData = [];
function rowManagerMakeNameEditor(jnode, userId) var otherUsersInfo = [],
{ otherUsersData = [];
setUpEditable(jnode, function()
{ function rowManagerMakeNameEditor(jnode, userId) {
setUpEditable(jnode, function() {
var existingIndex = findExistingIndex(userId); var existingIndex = findExistingIndex(userId);
if (existingIndex >= 0) if (existingIndex >= 0)
{
return otherUsersInfo[existingIndex].name || ''; return otherUsersInfo[existingIndex].name || '';
}
else else
{
return ''; return '';
} }, function(newName) {
}, function(newName) if (!newName) {
{
if (!newName)
{
jnode.addClass("editempty"); jnode.addClass("editempty");
jnode.val("unnamed"); jnode.val("unnamed");
} } else {
else
{
jnode.attr('disabled', 'disabled'); jnode.attr('disabled', 'disabled');
pad.suggestUserName(userId, newName); pad.suggestUserName(userId, newName);
} }
}); });
} }
function findExistingIndex(userId) function findExistingIndex(userId) {
{
var existingIndex = -1; var existingIndex = -1;
for (var i = 0; i < otherUsersInfo.length; i++) for (var i=0, l=otherUsersInfo.length; i < l; i++) {
{ if (otherUsersInfo[i].userId == userId) {
if (otherUsersInfo[i].userId == userId)
{
existingIndex = i; existingIndex = i;
break; break;
} }
@ -397,68 +312,49 @@ var paduserlist = (function()
return existingIndex; return existingIndex;
} }
function setUpEditable(jqueryNode, valueGetter, valueSetter) function setUpEditable(jqueryNode, valueGetter, valueSetter) {
{ jqueryNode
jqueryNode.bind('focus', function(evt) .bind('focus', function(evt) {
{
var oldValue = valueGetter(); var oldValue = valueGetter();
if (jqueryNode.val() !== oldValue) if (jqueryNode.val() !== oldValue)
{
jqueryNode.val(oldValue); jqueryNode.val(oldValue);
} jqueryNode.addClass('editactive').removeClass('editempty');
jqueryNode.addClass("editactive").removeClass("editempty"); })
}); .bind('blur', function(evt) {
jqueryNode.bind('blur', function(evt) var newValue = jqueryNode.removeClass('editactive').val();
{
var newValue = jqueryNode.removeClass("editactive").val();
valueSetter(newValue); valueSetter(newValue);
}); });
padutils.bindEnterAndEscape(jqueryNode, function onEnter()
{ padutils.bindEnterAndEscape(jqueryNode,
jqueryNode.blur(); function onEnter() {jqueryNode.blur();},
}, function onEscape() function onEscape() {jqueryNode.val(valueGetter()).blur();
{
jqueryNode.val(valueGetter()).blur();
}); });
jqueryNode.removeAttr('disabled').addClass('editable'); jqueryNode.removeAttr('disabled').addClass('editable');
} }
function updateInviteNotice() function updateInviteNotice() {
{ if (otherUsersInfo.length == 0) {
if (otherUsersInfo.length == 0) $('#otheruserstable').hide();
{ $('#nootherusers').show();
$("#otheruserstable").hide(); } else {
$("#nootherusers").show(); $('#nootherusers').hide();
} $('#otheruserstable').show();
else
{
$("#nootherusers").hide();
$("#otheruserstable").show();
} }
} }
var knocksToIgnore = {}; var knocksToIgnore = {},
var guestPromptFlashState = 0; guestPromptFlashState = 0;
var guestPromptFlash = padutils.makeAnimationScheduler( var guestPromptFlash = padutils.makeAnimationScheduler(
function() {
function()
{
var prompts = $("#guestprompts .guestprompt"); var prompts = $("#guestprompts .guestprompt");
if (prompts.length == 0) if (prompts.length == 0)
{
return false; // no more to do return false; // no more to do
}
guestPromptFlashState = 1 - guestPromptFlashState; guestPromptFlashState = 1 - guestPromptFlashState;
if (guestPromptFlashState) if (guestPromptFlashState)
{
prompts.css('background', '#ffa'); prompts.css('background', '#ffa');
}
else else
{
prompts.css('background', '#ffe'); prompts.css('background', '#ffe');
}
return true; return true;
}, 1000); }, 1000);
@ -492,42 +388,20 @@ var paduserlist = (function()
} }
// color picker // color picker
$("#myswatchbox").click(showColorPicker); $('#myswatchbox').click(showColorPicker);
$("#mycolorpicker .pickerswatchouter").click(function() $('#mycolorpickersave').click(function() {closeColorPicker(true);});
{ $('#mycolorpickercancel').click(function() {closeColorPicker(false);});
$("#mycolorpicker .pickerswatchouter").removeClass('picked');
$(this).addClass('picked');
});
$("#mycolorpickersave").click(function()
{
closeColorPicker(true);
});
$("#mycolorpickercancel").click(function()
{
closeColorPicker(false);
});
//
}, },
setMyUserInfo: function(info) setMyUserInfo: function(info) {
{
//translate the colorId //translate the colorId
if(typeof info.colorId == "number") if (typeof info.colorId == 'number')
{
info.colorId = clientVars.colorPalette[info.colorId]; info.colorId = clientVars.colorPalette[info.colorId];
} myUserInfo = $.extend({}, info);
myUserInfo = $.extend(
{}, info);
self.renderMyUserInfo(); self.renderMyUserInfo();
}, },
userJoinOrUpdate: function(info) userJoinOrUpdate: function(info) {
{
if ((!info.userId) || (info.userId == myUserInfo.userId)) if ((!info.userId) || (info.userId == myUserInfo.userId))
{ return; // not sure how this would happen
// not sure how this would happen
return;
}
var userData = {}; var userData = {};
userData.color = typeof info.colorId == "number" ? clientVars.colorPalette[info.colorId] : info.colorId; userData.color = typeof info.colorId == "number" ? clientVars.colorPalette[info.colorId] : info.colorId;
@ -537,40 +411,28 @@ var paduserlist = (function()
userData.id = info.userId; userData.id = info.userId;
// Firefox ignores \n in title text; Safari does a linebreak // Firefox ignores \n in title text; Safari does a linebreak
userData.titleText = [info.userAgent || '', info.ip || ''].join(' \n'); userData.titleText = [info.userAgent || '', info.ip || ''].join(' \n');
var existingIndex = findExistingIndex(info.userId); var existingIndex = findExistingIndex(info.userId);
var numUsersBesides = otherUsersInfo.length; var numUsersBesides = otherUsersInfo.length;
if (existingIndex >= 0) if (existingIndex >= 0)
{
numUsersBesides--; numUsersBesides--;
} var newIndex = padutils.binarySearch(numUsersBesides, function(n) {
var newIndex = padutils.binarySearch(numUsersBesides, function(n)
{
if (existingIndex >= 0 && n >= existingIndex) if (existingIndex >= 0 && n >= existingIndex)
{ n++; // pretend existingIndex isn't there
// pretend existingIndex isn't there var infoN = otherUsersInfo[n],
n++; nameN = (infoN.name || '').toLowerCase(),
} nameThis = (info.name || '').toLowerCase(),
var infoN = otherUsersInfo[n]; idN = infoN.userId,
var nameN = (infoN.name || '').toLowerCase(); idThis = info.userId;
var nameThis = (info.name || '').toLowerCase();
var idN = infoN.userId;
var idThis = info.userId;
return (nameN > nameThis) || (nameN == nameThis && idN > idThis); return (nameN > nameThis) || (nameN == nameThis && idN > idThis);
}); });
if (existingIndex >= 0) if (existingIndex >= 0) {
{
// update // update
if (existingIndex == newIndex) if (existingIndex == newIndex) {
{
otherUsersInfo[existingIndex] = info; otherUsersInfo[existingIndex] = info;
otherUsersData[existingIndex] = userData; otherUsersData[existingIndex] = userData;
rowManager.updateRow(existingIndex, userData); rowManager.updateRow(existingIndex, userData);
} } else {
else
{
otherUsersInfo.splice(existingIndex, 1); otherUsersInfo.splice(existingIndex, 1);
otherUsersData.splice(existingIndex, 1); otherUsersData.splice(existingIndex, 1);
otherUsersInfo.splice(newIndex, 0, info); otherUsersInfo.splice(newIndex, 0, info);
@ -578,56 +440,42 @@ var paduserlist = (function()
rowManager.updateRow(existingIndex, userData); rowManager.updateRow(existingIndex, userData);
rowManager.moveRow(existingIndex, newIndex); rowManager.moveRow(existingIndex, newIndex);
} }
} } else {
else
{
otherUsersInfo.splice(newIndex, 0, info); otherUsersInfo.splice(newIndex, 0, info);
otherUsersData.splice(newIndex, 0, userData); otherUsersData.splice(newIndex, 0, userData);
rowManager.insertRow(newIndex, userData); rowManager.insertRow(newIndex, userData);
} }
updateInviteNotice(); updateInviteNotice();
self.updateNumberOfOnlineUsers(); self.updateNumberOfOnlineUsers();
}, },
updateNumberOfOnlineUsers: function() updateNumberOfOnlineUsers: function() {
{
var online = 1; // you are always online! var online = 1; // you are always online!
for (var i = 0; i < otherUsersData.length; i++) for (var i=0, l=otherUsersData.length; i < l; i++) {
{ if (otherUsersData[i].status === '')
if (otherUsersData[i].status == "")
{
online++; online++;
} }
}
$("#online_count").text(online);
$('#usericonback').text(online);
return online; return online;
}, },
userLeave: function(info) userLeave: function(info) {
{
var existingIndex = findExistingIndex(info.userId); var existingIndex = findExistingIndex(info.userId);
if (existingIndex >= 0) if (existingIndex >= 0) {
{
var userData = otherUsersData[existingIndex]; var userData = otherUsersData[existingIndex];
userData.status = 'Disconnected'; userData.status = 'Disconnected';
rowManager.updateRow(existingIndex, userData); rowManager.updateRow(existingIndex, userData);
if (userData.leaveTimer) if (userData.leaveTimer)
{
window.clearTimeout(userData.leaveTimer); window.clearTimeout(userData.leaveTimer);
}
// set up a timer that will only fire if no leaves, // set up a timer that will only fire if no leaves,
// joins, or updates happen for this user in the // joins, or updates happen for this user in the
// next N seconds, to remove the user from the list. // next N seconds, to remove the user from the list.
var thisUserId = info.userId; var thisUserId = info.userId;
var thisLeaveTimer = window.setTimeout(function() var thisLeaveTimer = window.setTimeout(function() {
{
var newExistingIndex = findExistingIndex(thisUserId); var newExistingIndex = findExistingIndex(thisUserId);
if (newExistingIndex >= 0) if (newExistingIndex >= 0) {
{
var newUserData = otherUsersData[newExistingIndex]; var newUserData = otherUsersData[newExistingIndex];
if (newUserData.status == 'Disconnected' && newUserData.leaveTimer == thisLeaveTimer) if (newUserData.status == 'Disconnected' && newUserData.leaveTimer == thisLeaveTimer) {
{
otherUsersInfo.splice(newExistingIndex, 1); otherUsersInfo.splice(newExistingIndex, 1);
otherUsersData.splice(newExistingIndex, 1); otherUsersData.splice(newExistingIndex, 1);
rowManager.removeRow(newExistingIndex); rowManager.removeRow(newExistingIndex);
@ -638,176 +486,120 @@ var paduserlist = (function()
userData.leaveTimer = thisLeaveTimer; userData.leaveTimer = thisLeaveTimer;
} }
updateInviteNotice(); updateInviteNotice();
self.updateNumberOfOnlineUsers(); self.updateNumberOfOnlineUsers();
}, },
showGuestPrompt: function(userId, displayName) showGuestPrompt: function(userId, displayName) {
{
if (knocksToIgnore[userId]) if (knocksToIgnore[userId])
{
return; return;
}
var encodedUserId = padutils.encodeUserId(userId); var encodedUserId = padutils.encodeUserId(userId);
var actionName = 'hide-guest-prompt-' + encodedUserId; var actionName = 'hide-guest-prompt-' + encodedUserId;
padutils.cancelActions(actionName); padutils.cancelActions(actionName);
var box = $('#guestprompt-' + encodedUserId);
var box = $("#guestprompt-" + encodedUserId); if (box.length == 0) {
if (box.length == 0)
{
// make guest prompt box // make guest prompt box
box = $('<div id="'+padutils.escapeHtml('guestprompt-' + encodedUserId) + '" class="guestprompt"><div class="choices"><a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',false))')+'">Deny</a> <a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',true))') + '">Approve</a></div><div class="guestname"><strong>Guest:</strong> ' + padutils.escapeHtml(displayName) + '</div></div>'); box = $('<div id="'+padutils.escapeHtml('guestprompt-' + encodedUserId) + '" class="guestprompt"><div class="choices"><a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',false))')+'">Deny</a> <a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',true))') + '">Approve</a></div><div class="guestname"><strong>Guest:</strong> ' + padutils.escapeHtml(displayName) + '</div></div>');
$("#guestprompts").append(box); $('#guestprompts').append(box);
} } else {
else
{
// update display name // update display name
box.find(".guestname").html('<strong>Guest:</strong> ' + padutils.escapeHtml(displayName)); box.find('.guestname').html('<strong>Guest:</strong> ' + padutils.escapeHtml(displayName));
} }
var hideLater = padutils.getCancellableAction(actionName, function() var hideLater = padutils.getCancellableAction(actionName, function() {
{
self.removeGuestPrompt(userId); self.removeGuestPrompt(userId);
}); });
window.setTimeout(hideLater, 15000); // time-out with no knock window.setTimeout(hideLater, 15000); // time-out with no knock
guestPromptFlash.scheduleAnimation(); guestPromptFlash.scheduleAnimation();
}, },
removeGuestPrompt: function(userId) removeGuestPrompt: function(userId) {
{
var box = $("#guestprompt-" + padutils.encodeUserId(userId)); var box = $("#guestprompt-" + padutils.encodeUserId(userId));
// remove ID now so a new knock by same user gets new, unfaded box // remove ID now so a new knock by same user gets new, unfaded box
box.removeAttr('id').fadeOut("fast", function() box.removeAttr('id').fadeOut(250, function() {
{
box.remove(); box.remove();
}); });
knocksToIgnore[userId] = true; knocksToIgnore[userId] = true;
window.setTimeout(function() window.setTimeout(function() {
{
delete knocksToIgnore[userId]; delete knocksToIgnore[userId];
}, 5000); }, 5000);
}, },
answerGuestPrompt: function(encodedUserId, approve) answerGuestPrompt: function(encodedUserId, approve) {
{
var guestId = padutils.decodeUserId(encodedUserId); var guestId = padutils.decodeUserId(encodedUserId);
var msg = { var msg = {
type : 'guestanswer', type : 'guestanswer',
authId : pad.getUserId(), authId : pad.getUserId(),
guestId : guestId, guestId : guestId,
answer: (approve ? "approved" : "denied") answer : (approve ? 'approved' : 'denied')
}; };
pad.sendClientMessage(msg); pad.sendClientMessage(msg);
self.removeGuestPrompt(guestId); self.removeGuestPrompt(guestId);
}, },
renderMyUserInfo: function() renderMyUserInfo: function() {
{
if (myUserInfo.name) if (myUserInfo.name)
{ $('#myusernameedit').removeClass('editempty').val(myUserInfo.name);
$("#myusernameedit").removeClass("editempty").val(
myUserInfo.name);
}
else else
{ $('#myusernameedit').addClass('editempty').val('Enter your name');
$("#myusernameedit").addClass("editempty").val("Enter your name");
}
if (colorPickerOpen) if (colorPickerOpen)
{ $('#myswatchbox').addClass('myswatchboxunhoverable').removeClass('myswatchboxhoverable');
$("#myswatchbox").addClass('myswatchboxunhoverable').removeClass('myswatchboxhoverable');
}
else else
{ $('#myswatchbox').addClass('myswatchboxhoverable').removeClass('myswatchboxunhoverable');
$("#myswatchbox").addClass('myswatchboxhoverable').removeClass('myswatchboxunhoverable'); $('#myswatch').css({backgroundColor: myUserInfo.colorId});
} $('#usericon').css({backgroundColor: myUserInfo.colorId});
$("#myswatch").css({'background-color': myUserInfo.colorId});
if ($.browser.msie && parseInt($.browser.version) <= 8) {
$("#usericon").css({'box-shadow': 'inset 0 0 30px ' + myUserInfo.colorId,'background-color': myUserInfo.colorId});
}
else
{
$("#usericon").css({'box-shadow': 'inset 0 0 30px ' + myUserInfo.colorId});
}
} }
}; };
return self; return self;
}()); }());
function getColorPickerSwatchIndex(jnode) function getColorPickerSwatchIndex(jnode) {
{ return $('#colorpickerswatches LI').index(jnode);
// return Number(jnode.get(0).className.match(/\bn([0-9]+)\b/)[1])-1;
return $("#colorpickerswatches li").index(jnode);
} }
function closeColorPicker(accept) function closeColorPicker(accept) {
{ if (accept) {
if (accept) var newColor = $("#mycolorpickerpreview").css('background-color'),
{ parts = newColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
var newColor = $("#mycolorpickerpreview").css("background-color");
var parts = newColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
// parts now should be ["rgb(0, 70, 255", "0", "70", "255"] // parts now should be ["rgb(0, 70, 255", "0", "70", "255"]
delete (parts[0]); delete (parts[0]);
for (var i = 1; i <= 3; ++i) { for (var i = 1; i <= 3; ++i) {
parts[i] = parseInt(parts[i]).toString(16); parts[i] = parseInt(parts[i], 10).toString(16);
if (parts[i].length == 1) parts[i] = '0' + parts[i]; if (parts[i].length == 1) parts[i] = '0' + parts[i];
} }
var newColor = "#" +parts.join(''); // "0070ff" newColor = "#" + parts.join(''); // "0070ff"
myUserInfo.colorId = newColor; myUserInfo.colorId = newColor;
pad.notifyChangeColor(newColor); pad.notifyChangeColor(newColor);
paduserlist.renderMyUserInfo(); paduserlist.renderMyUserInfo();
} } else {
else
{
//pad.notifyChangeColor(previousColorId); //pad.notifyChangeColor(previousColorId);
//paduserlist.renderMyUserInfo(); //paduserlist.renderMyUserInfo();
} }
colorPickerOpen = false; colorPickerOpen = false;
$("#mycolorpicker").fadeOut("fast"); $('#mycolorpicker').fadeOut(250);
} }
function showColorPicker() function showColorPicker() {
{ var previousColorId = myUserInfo.colorId,
previousColorId = myUserInfo.colorId; $colorsList = $('#colorpickerswatches'),
picked = 'picked',
$swatchesList, $li;
if (!colorPickerOpen) if (!colorPickerOpen) {
{
var palette = pad.getColorPalette(); var palette = pad.getColorPalette();
if (!colorPickerSetup) {
if (!colorPickerSetup) for (var i=0, l=palette.length; i < l; i++) {
{ $li = $('<li>', {style: 'background: ' + palette[i] + ';'});
var colorsList = $("#colorpickerswatches") $li.appendTo($colorsList);
for (var i = 0; i < palette.length; i++) $li.bind('click', function(e) {
{ $('LI', $colorsList).removeClass(picked);
$(e.target).addClass(picked);
var li = $('<li>', { var newColorId = getColorPickerSwatchIndex($('#colorpickerswatches .picked'));
style: 'background: ' + palette[i] + ';'
});
li.appendTo(colorsList);
li.bind('click', function(event)
{
$("#colorpickerswatches li").removeClass('picked');
$(event.target).addClass("picked");
var newColorId = getColorPickerSwatchIndex($("#colorpickerswatches .picked"));
pad.notifyChangeColor(newColorId); pad.notifyChangeColor(newColorId);
}); });
} }
colorPickerSetup = true; colorPickerSetup = true;
} }
$('#mycolorpicker').fadeIn(250);
$("#mycolorpicker").fadeIn(); $swatchesList = $('#colorpickerswatches LI');
colorPickerOpen = true; colorPickerOpen = true;
$swatchesList.removeClass(picked);
$("#colorpickerswatches li").removeClass('picked'); $($swatchesList[myUserInfo.colorId]).addClass(picked); //seems weird
$($("#colorpickerswatches li")[myUserInfo.colorId]).addClass("picked"); //seems weird
} }
} }

View file

@ -225,7 +225,7 @@ var padutils = {
// Use keypress instead of keyup in bindEnterAndEscape // Use keypress instead of keyup in bindEnterAndEscape
// Keyup event is fired on enter in IME (Input Method Editor), But // Keyup event is fired on enter in IME (Input Method Editor), But
// keypress is not. So, I changed to use keypress instead of keyup. // 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) if (onEnter)
{ {
node.keypress(function(evt) node.keypress(function(evt)

View file

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

View file

@ -1,114 +1,44 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<title>Etherpad Lite</title> <title>Etherpad Lite</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="robots" content="noindex, nofollow"> <meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <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/css/pad.css" rel="stylesheet">
<link href="../static/custom/pad.css" rel="stylesheet"> <link href="../static/custom/pad.css" rel="stylesheet">
<style title="dynamicsyntax"></style> <style title="dynamicsyntax"></style>
</head>
<body>
<div id="editbar"> <div id="editbar">
<ul id="menu_left"> <ul class="left">
<li onClick="window.pad&amp;&amp;pad.editbarClick('bold');return false" > <li id="bold" class="group-start" onClick="window.pad&amp;&amp;pad.editbarClick('bold');return false" title="Bold (ctrl-B)"></li>
<a title="Bold (ctrl-B)"> <li id="italic" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('italic'); return false;" title="Italics (ctrl-I)"></li>
<div class="buttonicon buttonicon-bold"></div> <li id="underline" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('underline');return false;" title="Underline (ctrl-U)"></li>
</a> <li id="strikethrough" class="group-end" onClick="window.pad&amp;&amp;pad.editbarClick('strikethrough');return false;" title="Strikethrough"></li>
</li> <li id="orderedlist" class="group-start" onClick="window.pad&amp;&amp;pad.editbarClick('insertorderedlist');return false;" title="Toggle Ordered List"></li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('italic'); return false;" > <li id="unorderedlist" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('insertunorderedlist');return false;" title="Toggle Bullet List"></li>
<a title="Italics (ctrl-I)"> <li id="indent" class="group-mid" onClick="window.pad&amp;&amp;pad.editbarClick('indent');return false;" title="Indent"></li>
<div class="buttonicon buttonicon-italic"></div> <li id="outdent" class="group-end" onClick="window.pad&amp;&amp;pad.editbarClick('outdent');return false;" title="Unindent"></li>
</a> <li id="undo" class="group-start" onClick="window.pad&amp;&amp;pad.editbarClick('undo');return false;" title="Undo (ctrl-Z)"></li>
</li> <li id="redo" class="group-end" onClick="window.pad&amp;&amp;pad.editbarClick('redo');return false;" title="Redo (ctrl-Y)"></li>
<li onClick="window.pad&amp;&amp;pad.editbarClick('underline');return false;" > <li id="clearauthorship" onClick="window.pad&amp;&amp;pad.editbarClick('clearauthorship');return false;" title="Clear Authorship Colors"></li>
<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>
<ul id="menu_right"> <ul class="right">
<li onClick="window.pad&amp;&amp;pad.editbarClick('settings');return false;"> <li id="settings" onClick="window.pad&amp;&amp;pad.editbarClick('settings');return false;" title="Settings of this pad"></li>
<a id="settingslink" title="Settings of this pad"> <li id="import_export" onClick="window.pad&amp;&amp;pad.editbarClick('import_export');return false;" title="Import/Export from/to different document formats"></li>
<div class="buttonicon buttonicon-settings"></div> <li id="embed" onClick="window.pad&amp;&amp;pad.editbarClick('embed');return false;" title="Share and Embed this pad"></li>
</a> <li id="history" onClick="document.location = document.location.pathname + '/timeslider'" title="Show previous versions"></li>
</li> <li id="showusers" onClick="window.pad&amp;&amp;pad.editbarClick('showusers');return false;" title="Show connected users">1</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> </ul>
</div> </div>
<div id="users"> <div id="usersmenu" class="popup">
<div id="connectionstatus"></div> <div id="connectionstatus"></div>
<div id="myuser"> <div id="myuser">
<div id="mycolorpicker"> <div id="mycolorpicker">
<div id="colorpicker"></div> <div id="colorpicker"></div>
<button id="mycolorpickersave">Save</button> <button id="mycolorpickersave" class="button">Save</button>
<button id="mycolorpickercancel">Cancel</button> <button id="mycolorpickercancel">Cancel</button>
<span id="mycolorpickerpreview" class="myswatchboxhoverable"></span> <span id="mycolorpickerpreview" class="myswatchboxhoverable"></span>
</div> </div>
@ -126,15 +56,10 @@
<div id="userlistbuttonarea"></div> <div id="userlistbuttonarea"></div>
</div> </div>
<div id="editorcontainerbox">
<div id="editorcontainer"></div>
<div id="editorloadingbox">Loading...</div>
</div>
<div id="settingsmenu" class="popup"> <div id="settingsmenu" class="popup">
<h1>Pad settings</h1> <h2>Pad settings</h2>
<div class="left_popup"> <div class="left_popup">
<h2>My view</h2> <h3>My view</h3>
<p> <p>
<input type="checkbox" id="options-stickychat" onClick="chat.stickToScreen();"> <input type="checkbox" id="options-stickychat" onClick="chat.stickToScreen();">
<label for="options-stickychat">Chat always on screen</label> <label for="options-stickychat">Chat always on screen</label>
@ -156,15 +81,15 @@
</p> </p>
</div> </div>
<div class="right_popup"> <div class="right_popup">
<h2>Global view</h2> <h3>Global view</h3>
<p>Currently nothing.</p> <p>Currently nothing.</p>
<p class="note">These options affect everyone viewing this pad.</p> <p class="note">These options affect everyone viewing this pad.</p>
</div> </div>
</div> </div>
<div id="importexport" class="popup"> <div id="importexportmenu" class="popup">
<div class="left_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"> <form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data">
<div class="importformdiv" id="importformfilediv"> <div class="importformdiv" id="importformfilediv">
<input type="file" name="file" size="15" id="importfileinput"> <input type="file" name="file" size="15" id="importfileinput">
@ -173,16 +98,12 @@
<div class="importmessage" id="importmessagesuccess">Successful!</div> <div class="importmessage" id="importmessagesuccess">Successful!</div>
<div class="importformdiv" id="importformsubmitdiv"> <div class="importformdiv" id="importformsubmitdiv">
<input type="hidden" name="padId" value="blpmaXT35R"> <input type="hidden" name="padId" value="blpmaXT35R">
<span class="nowrap"> <input id="importsubmitinput" class="button" type="submit" name="submit" value="Import Now" disabled="disabled">
<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> </div>
</form> </form>
</div> </div>
<div class="right_popup"> <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="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="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="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword">Microsoft Word</div></a>
@ -193,40 +114,42 @@
</div> </div>
</div> </div>
<div id="embed" class="popup"> <div id="embedmenu" class="popup">
<div id="embedreadonly" class="right"> <div id="embedreadonly" class="right">
<input type="checkbox" id="readonlyinput" onClick="padeditbar.setEmbedLinks();"> <input type="checkbox" id="readonlyinput" onClick="padeditbar.setEmbedLinks();">
<label for="readonlyinput">Read only</label> <label for="readonlyinput">Read only</label>
</div> </div>
<h1>Share this pad</h1> <h2>Share this pad</h2>
<div id="linkcode"> <div id="linkcode">
<h2>Link</h2> <h3>Link</h3>
<input id="linkinput" type="text" value=""> <input id="linkinput" type="text" value="">
</div> </div>
<br> <br>
<div id="embedcode"> <div id="embedcode">
<h2>Embed URL</h2> <h3>Embed URL</h3>
<input id="embedinput" type="text" value=""> <input id="embedinput" type="text" value="">
</div> </div>
<br> <br>
<div id="qrcode"> <div id="qrcode">
<h2>QR code</h2> <h3>QR code</h3>
<div id="qr_center"><img id="embedreadonlyqr"></div> <div id="qr_center"><img id="embedreadonlyqr"></div>
</div> </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"> <div id="chaticon">
<a onClick="chat.show();return false;" title="Open the chat for this pad"> <a onClick="chat.show();return false;" title="Open the chat for this pad">
<span id="chatlabel">Chat</span> <span id="chatlabel">Chat</span>
<div class="buttonicon buttonicon-chat"></div>
</a> </a>
<span id="chatcounter">0</span> <span id="chatcounter">0</span>
</div> </div>
<div id="chatbox"> <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="chattext" class="authorColors"></div>
<div id="chatinputbox"> <div id="chatinputbox">
<form> <form>
@ -285,7 +208,6 @@
<input type="hidden" class="missedChanges" name="missedChanges"> <input type="hidden" class="missedChanges" name="missedChanges">
</form> </form>
</div> </div>
</div> </div>
<script type="text/javascript" src="../static/js/require-kernel.js"></script> <script type="text/javascript" src="../static/js/require-kernel.js"></script>
@ -306,5 +228,5 @@
padimpexp = require('/pad_impexp').padimpexp; padimpexp = require('/pad_impexp').padimpexp;
}()); }());
</script> </script>
</body>
</html> </html>

View file

@ -1,101 +1,58 @@
<!doctype html> <!doctype html>
<html lang="en"> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="robots" content="noindex, nofollow"> <meta name="robots" content="noindex, nofollow">
<title>Etherpad Lite Timeslider</title> <title>Etherpad Lite Timeslider</title>
<link rel="stylesheet" href="../../static/css/pad.css"> <link rel="stylesheet" href="../../static/css/pad.css">
<link rel="stylesheet" href="../../static/css/timeslider.css"> <link rel="stylesheet" href="../../static/css/timeslider.css">
<link rel="stylesheet" href="../../static/custom/timeslider.css"> <link rel="stylesheet" href="../../static/custom/timeslider.css">
<style type="text/css" title="dynamicsyntax"></style> <style type="text/css" title="dynamicsyntax"></style>
</head> </head>
<body>
<body id="padbody" class="timeslider limwidth nonpropad nonprouser">
<div id="padpage"> <div id="padpage">
<div id="padtop"> <div id="padtop">
<div class="topbar"> <div class="topbar">
<div class="topbarleft"> <div class="topbarleft"><!-- --></div>
<!-- --> <div class="topbarright"><!-- --></div>
</div>
<div class="topbarright">
<!-- -->
</div>
<div class="topbarcenter"> <div class="topbarcenter">
<a href="/" class="topbarBrand">Etherpad v1.1</a> <a href="http://etherpad.org" <div class="fullscreen" onclick="$('body').toggleClass('maximized');">Full screen</div>
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 class="specialkeyarea"><!-- --></div>
</div> </div>
<div id="alertbar"> <div id="alertbar">
<div id="servermsg"> <div id="servermsg">
<h3>Server Notice<span id="servermsgdate"><!-- --></span>:</h3><a id= <h3>Server Notice<span id="servermsgdate"><!-- --></span>:</h3>
"hidetopmsg" href="javascript:%20void%20pad.hideServerMessage()" name= <a id="hidetopmsg" href="javascript:%20void%20pad.hideServerMessage()" name="hidetopmsg">hide</a>
"hidetopmsg">hide</a>
<p id="servermsgtext"><!-- --></p> <p id="servermsgtext"><!-- --></p>
</div> </div>
</div> </div>
<div id="navigation"></div>
<div id="docbar" class="menu docbar"> <div id="docbar" class="menu docbar">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="docbartable" <table border="0" cellpadding="0" cellspacing="0" width="100%" id="docbartable" class="docbartable">
class="docbartable">
<tr> <tr>
<td><img src="../../static/img/roundcorner_left.gif" /></td> <td></td>
<td id="docbarpadtitle" class="docbarpadtitle" title="Public Pad: Public Pad"><span>Public Pad</span></td>
<td id="docbarpadtitle" class="docbarpadtitle" title=
"Public Pad: Public Pad"><span>Public Pad</span></td>
<td width="100%">&nbsp;</td> <td width="100%">&nbsp;</td>
<td></td>
<td><img src="../../static/img/roundcorner_right.gif" /></td>
</tr> </tr>
</table> </table>
</div><!-- /docbar --> </div>
</div> </div>
<div id="timeslider-wrapper"> <div id="timeslider-wrapper">
<div id="error" style="display: none"> <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>
It looks like you're having connection troubles. <a href= <div id="timeslider" unselectable="on">
"/ep/pad/view/test/latest">Reconnect now</a>. <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>
<a id="playpause_button" href="#"></a>
<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="timeslider-slider">
<div id="ui-slider-handle"></div> <div id="ui-slider-handle"></div>
<div id="ui-slider-bar"></div> <div id="ui-slider-bar"></div>
</div> </div>
<div id="playpause_button">
<div id="playpause_button_icon" class=""></div>
</div>
<div id="steppers">
<div class="stepper" id="leftstep"></div>
<div class="stepper" id="rightstep"></div>
</div>
</div> </div>
</div> </div>
@ -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/doc.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=doc" href="/ep/pad/export/c6fg9GM51V/rev.0?format=doc" class="tlink">Microsoft Word</a><br>
<img src="../../static/img/may09/pdf.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=pdf" href="/ep/pad/export/c6fg9GM51V/rev.0?format=pdf" class="tlink">PDF</a> <img src="../../static/img/may09/pdf.gif"><a thref="/ep/pad/export/c6fg9GM51V/rev.%revision%?format=pdf" href="/ep/pad/export/c6fg9GM51V/rev.0?format=pdf" class="tlink">PDF</a>
</div> </div>
<div id="legend"> <div id="legend">
<h2>Authors</h2> <h2>Authors</h2>
@ -121,25 +77,15 @@
<div id="padeditor"> <div id="padeditor">
<div id="editbar" class="editbar disabledtoolbar"> <div id="editbar" class="editbar disabledtoolbar">
<div id="editbarinner" class="editbarinner"> <div id="editbarinner" class="editbarinner">
<div id="editbarleft" class="editbarleft"> <div id="editbarleft" class="left"></div>
<!-- --> <div id="editbarright" class="right">
</div>
<div id="editbarright" class="editbarright">
<!-- termporary place holder-->
<ul> <ul>
<li onClick="window.padeditbar.toolbarClick('import_export');return false;"> <li id="returnbutton"><a href="#">Return to pad</a></li>
<a id="exportlink" title="Export to different document formats"> <li id="import_export" onClick="window.padeditbar.toolbarClick('import_export');return false;" title="Export to different document formats"></li>
<div class="buttonicon buttonicon-import_export"></div>
</a>
</li>
</ul> </ul>
<a id = "returnbutton">Return to pad</a>
</div> </div>
<div id="editbarinner">
<div id="editbarinner" class="editbarinner"> <table cellpadding="0" cellspacing="0" border="0" id="editbartable" class="editbartable">
<table cellpadding="0" cellspacing="0" border="0" id="editbartable" class=
"editbartable">
<tr> <tr>
<td> <td>
<h1> <h1>
@ -147,11 +93,9 @@
<span id="revision_date"></span> <span id="revision_date"></span>
</h1> </h1>
</td> </td>
<td width="100%">&nbsp;</td> <td width="100%">&nbsp;</td>
</tr> </tr>
</table> </table>
<table cellpadding="0" cellspacing="0" border="0" id="editbarsavetable" <table cellpadding="0" cellspacing="0" border="0" id="editbarsavetable"
class="editbarsavetable"> class="editbarsavetable">
<tr> <tr>
@ -161,28 +105,19 @@
</div> </div>
</div> </div>
</div> </div>
<div id="editorcontainerbox"> <div id="editorcontainerbox">
<div id="padcontent"> <div id="padcontent"></div>
</div>
</div> </div>
</div><!-- /padeditor --> </div><!-- /padeditor -->
</div><!-- /padmain --> </div><!-- /padmain -->
</div><!-- /padpage --> </div><!-- /padpage -->
<div id="modaloverlay"> <div id="modaloverlay">
<div id="modaloverlay-inner"> <div id="modaloverlay-inner"></div>
<!-- -->
</div> </div>
</div>
<div id="mainmodals"></div> <div id="mainmodals"></div>
<!-- export code --> <div id="importexport" class="popup">
<div id="importexport">
<div id="export" class="popup">
Export current version as: Export current version as:
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml">HTML</div></a> <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="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> <div id="hidetext" style=""><textarea id="text" name="text" id="text" style="display:none;">Coming soon!</textarea></div>
</form> </form>
</div> </div>
</div>
<script type="text/javascript" src="../../static/js/require-kernel.js"></script> <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="../../socket.io/socket.io.js"></script>
@ -215,4 +149,3 @@
</script> </script>
</body> </body>
</html> </html>