aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/etherpad/src/static/js/broadcast_slider.js
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/etherpad/src/static/js/broadcast_slider.js')
-rw-r--r--trunk/etherpad/src/static/js/broadcast_slider.js401
1 files changed, 401 insertions, 0 deletions
diff --git a/trunk/etherpad/src/static/js/broadcast_slider.js b/trunk/etherpad/src/static/js/broadcast_slider.js
new file mode 100644
index 0000000..371663e
--- /dev/null
+++ b/trunk/etherpad/src/static/js/broadcast_slider.js
@@ -0,0 +1,401 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var global = this;
+
+(function() { // wrap this code in its own namespace
+ var sliderLength = 1000;
+ var sliderPos = 0;
+ var sliderActive = false;
+ var slidercallbacks = [];
+ var savedRevisions = [];
+ var sliderPlaying = false;
+
+ function disableSelection(element) {
+ element.onselectstart = function() {
+ return false;
+ };
+ element.unselectable = "on";
+ element.style.MozUserSelect = "none";
+ element.style.cursor = "default";
+ }
+ var _callSliderCallbacks = function(newval) {
+ sliderPos = newval;
+ for(var i=0; i<slidercallbacks.length; i++) {
+ slidercallbacks[i](newval);
+ }
+ }
+
+ var updateSliderElements = function() {
+ for(var i=0; i<savedRevisions.length; i++) {
+ var position = parseInt(savedRevisions[i].attr('pos'));
+ savedRevisions[i].css('left', (position * ($("#ui-slider-bar").width()-2) / (sliderLength * 1.0)) - 1);
+ }
+ $("#ui-slider-handle").css('left', sliderPos * ($("#ui-slider-bar").width()-2) / (sliderLength * 1.0));
+ }
+
+ var addSavedRevision = function(position, info) {
+ var newSavedRevision = $('<div></div>');
+ newSavedRevision.addClass("star");
+
+ newSavedRevision.attr('pos', position);
+ newSavedRevision.css('position', 'absolute');
+ newSavedRevision.css('left', (position * ($("#ui-slider-bar").width()-2) / (sliderLength * 1.0)) - 1);
+ $("#timeslider-slider").append(newSavedRevision);
+ newSavedRevision.mouseup(function(evt) {
+ BroadcastSlider.setSliderPosition(position);
+ });
+ savedRevisions.push(newSavedRevision);
+ };
+
+ var removeSavedRevision = function (position) {
+ var element = $("div.star [pos="+position+"]");
+ savedRevisions.remove(element);
+ element.remove();
+ return element;
+ };
+
+ /* Begin small 'API' */
+ function onSlider(callback) {
+ slidercallbacks.push(callback);
+ }
+
+ function getSliderPosition() {
+ return sliderPos;
+ }
+
+ function setSliderPosition(newpos) {
+ newpos = Number(newpos);
+ if(newpos < 0 || newpos > sliderLength) return;
+ $("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width()-2) / (sliderLength * 1.0));
+ $("a.tlink").map(function() {
+ $(this).attr('href', $(this).attr('thref').replace("%revision%", newpos));
+ });
+ $("#revision_label").html("Version " + newpos);
+
+ if(newpos == 0) {
+ $("#leftstar").css('opacity', .5);
+ $("#leftstep").css('opacity', .5);
+ } else {
+ $("#leftstar").css('opacity', 1);
+ $("#leftstep").css('opacity', 1);
+ }
+
+ if(newpos == sliderLength) {
+ $("#rightstar").css('opacity', .5);
+ $("#rightstep").css('opacity', .5);
+ } else {
+ $("#rightstar").css('opacity', 1);
+ $("#rightstep").css('opacity', 1);
+ }
+
+ sliderPos = newpos;
+ _callSliderCallbacks(newpos);
+ }
+
+ function getSliderLength() {
+ return sliderLength;
+ }
+
+ function setSliderLength(newlength) {
+ sliderLength = newlength;
+ updateSliderElements();
+ }
+
+ // just take over the whole slider screen with a reconnect message
+ function showReconnectUI() {
+ if(!clientVars.sliderEnabled || !clientVars.supportsSlider) {
+ $("#padmain, #rightbars").css('top', "95px");
+ $("#timeslider").show();
+ }
+ $('#error').show();
+ }
+
+ function setAuthors(authors) {
+ $("#authorstable").empty();
+ var numAnonymous = 0;
+ var numNamed = 0;
+ authors.forEach(function(author) {
+ if(author.name) {
+ numNamed ++;
+ var tr = $('<tr></tr>');
+ var swatchtd = $('<td></td>');
+ var swatch = $('<div class="swatch"></div>');
+ swatch.css('background-color', clientVars.colorPalette[author.colorId]);
+ swatchtd.append(swatch);
+ tr.append(swatchtd);
+ var nametd = $('<td></td>');
+ nametd.text(author.name || "unnamed");
+ tr.append(nametd);
+ $("#authorstable").append(tr);
+ } else {
+ numAnonymous ++;
+ }
+ });
+ if(numAnonymous > 0) {
+ var html = "<tr><td colspan=\"2\" style=\"color:#999; padding-left: 10px\">"+(numNamed>0?"...and ":"")+numAnonymous+" unnamed author"+(numAnonymous>1?"s":"")+"</td></tr>";
+ $("#authorstable").append($(html));
+ } if(authors.length == 0) {
+ $("#authorstable").append($("<tr><td colspan=\"2\" style=\"color:#999; padding-left: 10px\">No Authors</td></tr>"))
+ }
+ }
+
+ global.BroadcastSlider = {
+ onSlider: onSlider,
+ getSliderPosition: getSliderPosition,
+ setSliderPosition: setSliderPosition,
+ getSliderLength: getSliderLength,
+ setSliderLength: setSliderLength,
+ isSliderActive: function() {return sliderActive;},
+ playpause: playpause,
+ addSavedRevision: addSavedRevision,
+ showReconnectUI : showReconnectUI,
+ setAuthors: setAuthors
+ }
+
+ function playButtonUpdater() {
+ if(sliderPlaying) {
+ if(getSliderPosition()+1 > sliderLength) {
+ $("#playpause_button_icon").toggleClass('pause');
+ sliderPlaying = false;
+ return;
+ }
+ setSliderPosition(getSliderPosition()+1);
+
+ setTimeout(playButtonUpdater, 100);
+ }
+ }
+
+ function playpause() {
+ $("#playpause_button_icon").toggleClass('pause');
+
+ if(!sliderPlaying) {
+ if(getSliderPosition() == sliderLength)
+ setSliderPosition(0);
+ sliderPlaying = true;
+ playButtonUpdater();
+ } else {
+ sliderPlaying = false;
+ }
+ }
+
+ // assign event handlers to html UI elements after page load
+ $(window).load(function() {
+ disableSelection($("#playpause_button")[0]);
+ disableSelection($("#timeslider")[0]);
+
+ if(clientVars.sliderEnabled && clientVars.supportsSlider) {
+ $(document).keyup(function(e) {
+ var code = -1;
+ if (!e) var e = window.event;
+ if (e.keyCode) code = e.keyCode;
+ else if (e.which) code = e.which;
+
+ if(code == 37) { // left
+ if(!e.shiftKey) {
+ setSliderPosition(getSliderPosition() - 1);
+ } else {
+ var nextStar = 0; // default to first revision in document
+ for(var i=0; i<savedRevisions.length; i++) {
+ var pos = parseInt(savedRevisions[i].attr('pos'));
+ if(pos < getSliderPosition() && nextStar < pos)
+ nextStar = pos;
+ }
+ setSliderPosition(nextStar);
+ }
+ } else if(code == 39) {
+ if(!e.shiftKey) {
+ setSliderPosition(getSliderPosition() + 1);
+ } else {
+ var nextStar = sliderLength; // default to last revision in document
+ for(var i=0; i<savedRevisions.length; i++) {
+ var pos = parseInt(savedRevisions[i].attr('pos'));
+ if(pos > getSliderPosition() && nextStar > pos)
+ nextStar = pos;
+ }
+ setSliderPosition(nextStar);
+ }
+ } else if(code == 32)
+ playpause();
+
+ });
+ }
+
+ $(window).resize(function() {
+ updateSliderElements();
+ });
+
+ $("#ui-slider-bar").mousedown(function(evt) {
+ setSliderPosition(Math.floor((evt.clientX-$("#ui-slider-bar").offset().left) * sliderLength / 742));
+ $("#ui-slider-handle").css('left', (evt.clientX-$("#ui-slider-bar").offset().left));
+ $("#ui-slider-handle").trigger(evt);
+ });
+
+ // Slider dragging
+ $("#ui-slider-handle").mousedown(function(evt) {
+ this.startLoc = evt.clientX;
+ this.currentLoc = parseInt($(this).css('left'));
+ var self = this;
+ sliderActive = true;
+ $(document).mousemove(function(evt2) {
+ $(self).css('pointer', 'move')
+ var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
+ if(newloc < 0) newloc = 0;
+ if(newloc > ($("#ui-slider-bar").width()-2)) newloc = ($("#ui-slider-bar").width()-2);
+ $("#revision_label").html("Version " + Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2)));
+ $(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)))
+ });
+ $(document).mouseup(function(evt2) {
+ $(document).unbind('mousemove');
+ $(document).unbind('mouseup');
+ sliderActive = false;
+ var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
+ if(newloc < 0) newloc = 0;
+ if(newloc > ($("#ui-slider-bar").width()-2)) newloc = ($("#ui-slider-bar").width()-2);
+ $(self).css('left', newloc);
+ // if(getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2)))
+ setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2)))
+ self.currentLoc = parseInt($(self).css('left'));
+ });
+ })
+
+ // play/pause toggling
+ $("#playpause_button").mousedown(function(evt) {
+ var self = this;
+
+ $(self).css('background-image', 'url(/static/img/pad/timeslider/crushed_button_depressed.png)');
+ $(self).mouseup(function(evt2) {
+ $(self).css('background-image', 'url(/static/img/pad/timeslider/crushed_button_undepressed.png)');
+ $(self).unbind('mouseup');
+ BroadcastSlider.playpause();
+ });
+ $(document).mouseup(function(evt2) {
+ $(self).css('background-image', 'url(/static/img/pad/timeslider/crushed_button_undepressed.png)');
+ $(document).unbind('mouseup');
+ });
+ });
+
+ // next/prev saved revision and changeset
+ $('.stepper').mousedown(function(evt) {
+ var self = this;
+ var origcss = $(self).css('background-position');
+ if (! origcss) {
+ origcss = $(self).css('background-position-x')+" "+$(self).css('background-position-y');
+ }
+ var origpos = parseInt(origcss.split(" ")[1]);
+ var newpos = (origpos - 43);
+ if(newpos < 0) newpos += 87;
+
+ var newcss = (origcss.split(" ")[0] + " " + newpos + "px");
+ if($(self).css('opacity') != 1.0)
+ newcss = origcss;
+
+ $(self).css('background-position', newcss)
+
+ $(self).mouseup(function(evt2) {
+ $(self).css('background-position',origcss);
+ $(self).unbind('mouseup');
+ $(document).unbind('mouseup');
+ if($(self).attr("id") == ("leftstep")) {
+ setSliderPosition(getSliderPosition() - 1);
+ }
+ else if($(self).attr("id") == ("rightstep")) {
+ setSliderPosition(getSliderPosition() + 1);
+ }
+ else if($(self).attr("id") == ("leftstar")) {
+ var nextStar = 0; // default to first revision in document
+ for(var i=0; i<savedRevisions.length; i++) {
+ var pos = parseInt(savedRevisions[i].attr('pos'));
+ if(pos < getSliderPosition() && nextStar < pos)
+ nextStar = pos;
+ }
+ setSliderPosition(nextStar);
+ }
+ else if($(self).attr("id") == ("rightstar")) {
+ var nextStar = sliderLength; // default to last revision in document
+ for(var i=0; i<savedRevisions.length; i++) {
+ var pos = parseInt(savedRevisions[i].attr('pos'));
+ if(pos > getSliderPosition() && nextStar > pos)
+ nextStar = pos;
+ }
+ setSliderPosition(nextStar);
+ }
+ });
+ $(document).mouseup(function(evt2) {
+ $(self).css('background-position',origcss);
+ $(self).unbind('mouseup');
+ $(document).unbind('mouseup');
+ });
+ })
+
+ if(clientVars) {
+ if(clientVars.fullWidth) {
+ $("#padpage").css('width', '100%');
+ $("#revision").css('position', "absolute")
+ $("#revision").css('right', "20px")
+ $("#revision").css('top', "20px")
+ $("#padmain").css('left', '0px');
+ $("#padmain").css('right', '197px');
+ $("#padmain").css('width', 'auto');
+ $("#rightbars").css('right', '7px');
+ $("#rightbars").css('margin-right', '0px');
+ $("#timeslider").css('width', 'auto');
+ }
+
+ if(clientVars.disableRightBar) {
+ $("#rightbars").css('display', 'none');
+ $('#padmain').css('width', 'auto');
+ if(clientVars.fullWidth)
+ $("#padmain").css('right', '7px');
+ else
+ $("#padmain").css('width', '860px');
+ $("#revision").css('position', "absolute");
+ $("#revision").css('right', "20px");
+ $("#revision").css('top', "20px");
+ }
+
+
+ if(clientVars.sliderEnabled) {
+ if(clientVars.supportsSlider) {
+ $("#padmain, #rightbars").css('top', "95px");
+ $("#timeslider").show();
+ setSliderLength(clientVars.totalRevs);
+ setSliderPosition(clientVars.revNum);
+ clientVars.savedRevisions.forEach(function(revision) {
+ addSavedRevision(revision.revNum, revision);
+ })
+ } else {
+ // slider is not supported
+ $("#padmain, #rightbars").css('top', "95px");
+ $("#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 {
+ if(clientVars.supportsSlider) {
+ setSliderLength(clientVars.totalRevs);
+ setSliderPosition(clientVars.revNum);
+ }
+ }
+ }
+ });
+})();
+
+BroadcastSlider.onSlider(function(loc) {
+ $("#viewlatest").html(loc==BroadcastSlider.getSliderLength()?"Viewing latest content":"View latest content");
+})