UI clean-up for pad and timeslider

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

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

View file

@ -23,64 +23,51 @@
// of the document. These revisions are connected together by various // of the document. These revisions are connected together by various
// changesets, or deltas, between any two revisions. // changesets, or deltas, between any two revisions.
function loadBroadcastRevisionsJS() function loadBroadcastRevisionsJS() {
{
function Revision(revNum) function Revision(revNum) {
{
this.rev = revNum; this.rev = revNum;
this.changesets = []; this.changesets = [];
} }
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta) Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta) {
{
var changesetWrapper = { var changesetWrapper = {
deltaRev : destIndex - this.rev, deltaRev : destIndex - this.rev,
deltaTime : timeDelta, deltaTime : timeDelta,
getValue: function() getValue : function() {return changeset;}
{
return changeset;
}
}; };
this.changesets.push(changesetWrapper); this.changesets.push(changesetWrapper);
this.changesets.sort(function(a, b) this.changesets.sort(function(a, b) {
{ return (b.deltaRev - a.deltaRev);
return (b.deltaRev - a.deltaRev)
}); });
} };
revisionInfo = {}; revisionInfo = {};
revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta) revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta) {
{ var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex),
var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex); endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
var endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
startRevision.addChangeset(toIndex, changeset, timeDelta); startRevision.addChangeset(toIndex, changeset, timeDelta);
endRevision.addChangeset(fromIndex, backChangeset, -1 * timeDelta); endRevision.addChangeset(fromIndex, backChangeset, -1 * timeDelta);
} };
revisionInfo.latest = clientVars.totalRevs || -1; revisionInfo.latest = clientVars.totalRevs || -1;
revisionInfo.createNew = function(index) revisionInfo.createNew = function(index) {
{
revisionInfo[index] = new Revision(index); revisionInfo[index] = new Revision(index);
if (index > revisionInfo.latest) if (index > revisionInfo.latest)
{
revisionInfo.latest = index; revisionInfo.latest = index;
}
return revisionInfo[index]; return revisionInfo[index];
} };
// assuming that there is a path from fromIndex to toIndex, and that the links // assuming that there is a path from fromIndex to toIndex, and that the links
// are laid out in a skip-list format // are laid out in a skip-list format
revisionInfo.getPath = function(fromIndex, toIndex) revisionInfo.getPath = function(fromIndex, toIndex) {
{ var changesets = [],
var changesets = []; spans = [],
var spans = []; times = [],
var times = []; elem = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex);
var elem = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex); if (elem.changesets.length != 0 && fromIndex != toIndex) {
if (elem.changesets.length != 0 && fromIndex != toIndex) var reverse = !(fromIndex < toIndex);
{
var reverse = !(fromIndex < toIndex)
while (((elem.rev < toIndex) && !reverse) || ((elem.rev > toIndex) && reverse)) while (((elem.rev < toIndex) && !reverse) || ((elem.rev > toIndex) && reverse))
{ {
var couldNotContinue = false; var couldNotContinue = false;
@ -107,12 +94,14 @@ function loadBroadcastRevisionsJS()
} }
} }
if (couldNotContinue || oldRev == elem.rev) break; if (couldNotContinue || oldRev == elem.rev)
break;
} }
} }
var status = 'partial'; var status = 'partial';
if (elem.rev == toIndex) status = 'complete'; if (elem.rev == toIndex)
status = 'complete';
return { return {
'fromRev' : fromIndex, 'fromRev' : fromIndex,
@ -122,7 +111,7 @@ function loadBroadcastRevisionsJS()
'spans' : spans, 'spans' : spans,
'times' : times 'times' : times
}; };
} };
} }
exports.loadBroadcastRevisionsJS = loadBroadcastRevisionsJS; exports.loadBroadcastRevisionsJS = loadBroadcastRevisionsJS;

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' */ /* small 'API' START */
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 // toggle play / pause
$("#playpause_button").mousedown(function(evt) $('#playpause_button').mousedown(function(evt) {
{
var self = this; var self = this;
$(self)
$(self).css('background-image', 'url(/static/img/crushed_button_depressed.png)'); .addClass('pressed')
$(self).mouseup(function(evt2) .mouseup(function(evt2) {
{ $(self).removeClass('pressed');
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(self).unbind('mouseup'); $(self).unbind('mouseup');
BroadcastSlider.playpause(); BroadcastSlider.playpause();
}); });
$(document).mouseup(function(evt2) $(document).mouseup(function(evt2) {
{ $(self).removeClass('pressed');
$(self).css('background-image', 'url(/static/img/crushed_button_undepressed.png)');
$(document).unbind('mouseup'); $(document).unbind('mouseup');
}); });
}); });
// next / prev saved revision and changeset // next / prev saved revision and changeset
$('.stepper').mousedown(function(evt) $('#steppers A').mousedown(function(evt) {
{
var self = this; var self = this;
var origcss = $(self).css('background-position'); $(self)
if (!origcss) .addClass('clicked')
{ .mouseup(function(evt2) {
origcss = $(self).css('background-position-x') + " " + $(self).css('background-position-y'); $(self)
} .removeClass('clicked')
var origpos = parseInt(origcss.split(" ")[1]); .unbind('mouseup');
var newpos = (origpos - 43);
if (newpos < 0) newpos += 87;
var newcss = (origcss.split(" ")[0] + " " + newpos + "px");
if ($(self).css('opacity') != 1.0) newcss = origcss;
$(self).css('background-position', newcss)
$(self).mouseup(function(evt2)
{
$(self).css('background-position', origcss);
$(self).unbind('mouseup');
$(document).unbind('mouseup'); $(document).unbind('mouseup');
if ($(self).attr("id") == ("leftstep")) var id = $(self).attr('id'),
{ i, l, nextStar, pos;
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').addClass("stickyChat"); $('BODY').addClass('chat-visible');
$('#chattext').css({"top":"0px"});
$('#editorcontainer').css({"right":"192px", "width":"auto"});
isStuck = true; isStuck = true;
} else { // Unstick it } else { // unstick it
padcookie.setPref("chatAlwaysVisible", false); padcookie.setPref('chatAlwaysVisible', false);
$('#chatbox').removeClass("stickyChat"); $('BODY').removeClass('chat-visible');
$('#chattext').css({"top":"25px"});
$('#editorcontainer').css({"right":"0px", "width":"100%"});
isStuck = false; isStuck = false;
} }
}, },
hide: function () hide: function() {
{ $('#chatcounter').text('0');
$("#chatcounter").text("0"); $('#chaticon').show();
$("#chaticon").show(); $('#chatbox').hide();
$("#chatbox").hide();
}, },
scrollDown: function() scrollDown: function() {
{ if ($('#chatbox').is(':visible'))
if($('#chatbox').css("display") != "none") $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, 600);
$('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, "slow");
}, },
send: function() send: function() {
{ var text = $('#chatinput').val();
var text = $("#chatinput").val(); this._pad.collabClient.sendMessage({
this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text}); 'type': 'CHAT_MESSAGE',
$("#chatinput").val(""); 'text': text
});
$('#chatinput').val('');
}, },
addMessage: function(msg, increment) addMessage: function(msg, increment) {
{
// correct the time // correct the time
msg.time += this._pad.clientTimeOffset; msg.time += this._pad.clientTimeOffset;
// create the time string // create the time string
var minutes = "" + new Date(msg.time).getMinutes(); var minutes = '' + new Date(msg.time).getMinutes(),
var hours = "" + new Date(msg.time).getHours(); hours = '' + new Date(msg.time).getHours(),
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(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;

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,113 @@ var padeditbar = (function()
}()); }());
var self = { var self = {
init: function() init: function() {
{ $('#editbar A').attr('unselectable', 'on'); // for IE
$("#editbar .editbarbutton").attr("unselectable", "on"); // for IE $('#editbar').removeClass('disabledtoolbar').addClass('enabledtoolbar');
$("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
}, },
isEnabled: function() isEnabled: function() {
{
// return !$("#editbar").hasClass('disabledtoolbar'); // return !$("#editbar").hasClass('disabledtoolbar');
return true; return true;
}, },
disable: function() disable: function() {
{ $('#editbar').addClass('disabledtoolbar').removeClass('enabledtoolbar');
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
}, },
toolbarClick: function(cmd) toolbarClick: function(cmd) {
{ if (self.isEnabled()) {
if (self.isEnabled()) switch(cmd) {
{ case 'users':
if(cmd == "showusers") self.toggleDropDown('users');
{ break;
self.toogleDropDown("users"); case 'settings':
} self.toggleDropDown('settings');
else if (cmd == 'settings') break;
{ case 'embed':
self.toogleDropDown("settingsmenu");
}
else if (cmd == 'embed')
{
self.setEmbedLinks(); self.setEmbedLinks();
$('#linkinput').focus().select(); self.toggleDropDown('embed');
self.toogleDropDown("embed"); break;
} case 'importexport':
else if (cmd == 'import_export') self.toggleDropDown('importexport');
{ 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 = ['settings', 'importexport', 'embed', 'users'],
var modules = ["settingsmenu", "importexport", "embed", "users"]; $module, i, l;
$('#editbar UL.right LI').removeClass('selected');
//hide all modules // hide all modules if no module was passed to this method
if(moduleName == "none") if (moduleName == 'none') {
{ for (i=0, l=modules.length; i < l; i++) {
$("#editbar ul#menu_right > li").removeClass("selected");
for(var i=0;i<modules.length;i++)
{
// skip the userlist // skip the userlist
if(modules[i] == "users") if (modules[i] == 'users')
continue; continue;
$module = $('#' + modules[i] + 'menu');
var module = $("#" + modules[i]); if ($module.is(':visible'))
$module.slideUp(250);
if(module.css('display') != "none")
{
module.slideUp("fast");
}
}
}
else
{
var nth_child = indexOf(modules, moduleName) + 1;
if (nth_child > 0 && nth_child <= 3) {
$("#editbar ul#menu_right li:not(:nth-child(" + nth_child + "))").removeClass("selected");
$("#editbar ul#menu_right li:nth-child(" + nth_child + ")").toggleClass("selected");
} }
} else {
// 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] + 'menu');
var module = $("#" + modules[i]); if ($module.is(':visible'))
$module.slideUp(250);
if(module.css('display') != "none") else if (modules[i] == moduleName) {
{ $module.slideDown(250);
module.slideUp("fast"); $('#' + modules[i]).addClass('selected');
}
else if(modules[i]==moduleName)
{
module.slideDown("fast");
} }
} }
} }
}, },
setSyncStatus: function(status) setSyncStatus: function(status) {
{ if (status == 'syncing')
if (status == "syncing")
{
syncAnimation.syncing(); syncAnimation.syncing();
} else if (status == 'done')
else if (status == "done")
{
syncAnimation.done(); syncAnimation.done();
}
}, },
setEmbedLinks: function() setEmbedLinks: function() {
{ if ($('#readonlyinput').is(':checked')) {
if ($('#readonlyinput').is(':checked')) var basePath = document.location.href.substring(0, document.location.href.indexOf('/p/')),
{ readonlyLink = basePath + '/ro/' + clientVars.readOnlyId;
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
var readonlyLink = basePath + "/ro/" + clientVars.readOnlyId;
$('#embedinput').val("<iframe src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>"); $('#embedinput').val("<iframe src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
$('#linkinput').val(readonlyLink); $('#linkinput').val(readonlyLink);
$('#embedreadonlyqr').attr("src","https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=|0&chl=" + readonlyLink); $('#embedreadonlyqr').attr('src', 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=H|0&chl=' + readonlyLink);
} } else {
else var padurl = window.location.href.split('?')[0];
{
var padurl = window.location.href.split("?")[0];
$('#embedinput').val("<iframe src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>"); $('#embedinput').val("<iframe src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
$('#linkinput').val(padurl); $('#linkinput').val(padurl);
$('#embedreadonlyqr').attr("src","https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=|0&chl=" + padurl); $('#embedreadonlyqr').attr('src', "https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=H|0&chl=" + padurl);
} }
} }
}; };

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

@ -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, 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="importexport" onClick="window.pad&amp;&amp;pad.editbarClick('importexport');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="users" onClick="window.pad&amp;&amp;pad.editbarClick('users');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,34 +81,29 @@
</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">
<div class="importmessage" id="importmessagefail"></div> <div class="importmessage" id="importmessagefail"></div>
</div> </div>
<div id="import"></div>
<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>
@ -194,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>
@ -286,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>
@ -307,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="importexport" onClick="window.padeditbar.toolbarClick('importexport');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>