--- /dev/null
+/*----------------------------------------------------------------------------\\r
+| Slider 1.02 |\r
+|-----------------------------------------------------------------------------|\r
+| Created by Erik Arvidsson |\r
+| (http://webfx.eae.net/contact.html#erik) |\r
+| For WebFX (http://webfx.eae.net/) |\r
+|-----------------------------------------------------------------------------|\r
+| A slider control that degrades to an input control for non supported |\r
+| browsers. |\r
+|-----------------------------------------------------------------------------|\r
+| Copyright (c) 2002, 2003, 2006 Erik Arvidsson |\r
+|-----------------------------------------------------------------------------|\r
+| Licensed under the Apache License, Version 2.0 (the "License"); you may not |\r
+| use this file except in compliance with the License. You may obtain a copy |\r
+| of the License at http://www.apache.org/licenses/LICENSE-2.0 |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| Unless required by applicable law or agreed to in writing, software |\r
+| distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |\r
+| WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |\r
+| License for the specific language governing permissions and limitations |\r
+| under the License. |\r
+|-----------------------------------------------------------------------------|\r
+| Dependencies: timer.js - an OO abstraction of timers |\r
+| range.js - provides the data model for the slider |\r
+| winclassic.css or any other css file describing the look |\r
+|-----------------------------------------------------------------------------|\r
+| 2002-10-14 | Original version released |\r
+| 2003-03-27 | Added a test in the constructor for missing oElement arg |\r
+| 2003-11-27 | Only use mousewheel when focused |\r
+| 2006-05-28 | Changed license to Apache Software License 2.0. |\r
+|-----------------------------------------------------------------------------|\r
+| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |\r
+\----------------------------------------------------------------------------*/\r
+\r
+Slider.isSupported = typeof document.createElement != "undefined" &&\r
+ typeof document.documentElement != "undefined" &&\r
+ typeof document.documentElement.offsetWidth == "number";\r
+\r
+\r
+function Slider(oElement, oInput, sOrientation) {\r
+ if (!oElement) return;\r
+ this._orientation = sOrientation || "horizontal";\r
+ this._range = new Range();\r
+ this._range.setExtent(0);\r
+ this._blockIncrement = 10;\r
+ this._unitIncrement = 1;\r
+ this._timer = new Timer(100);\r
+\r
+\r
+ if (Slider.isSupported && oElement) {\r
+\r
+ this.document = oElement.ownerDocument || oElement.document;\r
+\r
+ this.element = oElement;\r
+ this.element.slider = this;\r
+ this.element.unselectable = "on";\r
+\r
+ // add class name tag to class name\r
+ this.element.className = this._orientation + " " + this.classNameTag + " " + this.element.className;\r
+\r
+ // create line\r
+ this.line = this.document.createElement("DIV");\r
+ this.line.className = "line";\r
+ this.line.unselectable = "on";\r
+ this.line.appendChild(this.document.createElement("DIV"));\r
+ this.element.appendChild(this.line);\r
+\r
+ // create handle\r
+ this.handle = this.document.createElement("DIV");\r
+ this.handle.className = "handle";\r
+ this.handle.unselectable = "on";\r
+ this.handle.appendChild(this.document.createElement("DIV"));\r
+ this.handle.firstChild.appendChild(\r
+ this.document.createTextNode(String.fromCharCode(160)));\r
+ this.element.appendChild(this.handle);\r
+ }\r
+\r
+ this.input = oInput;\r
+\r
+ // events\r
+ var oThis = this;\r
+ this._range.onchange = function () {\r
+ oThis.recalculate();\r
+ if (typeof oThis.onchange == "function")\r
+ oThis.onchange();\r
+ };\r
+\r
+ if (Slider.isSupported && oElement) {\r
+ this.element.onfocus = Slider.eventHandlers.onfocus;\r
+ this.element.onblur = Slider.eventHandlers.onblur;\r
+ this.element.onmousedown = Slider.eventHandlers.onmousedown;\r
+ this.element.onmouseover = Slider.eventHandlers.onmouseover;\r
+ this.element.onmouseout = Slider.eventHandlers.onmouseout;\r
+ this.element.onkeydown = Slider.eventHandlers.onkeydown;\r
+ this.element.onkeypress = Slider.eventHandlers.onkeypress;\r
+ this.element.onmousewheel = Slider.eventHandlers.onmousewheel;\r
+ this.handle.onselectstart =\r
+ this.element.onselectstart = function () { return false; };\r
+\r
+ this._timer.ontimer = function () {\r
+ oThis.ontimer();\r
+ };\r
+\r
+ // extra recalculate for ie\r
+ window.setTimeout(function() {\r
+ oThis.recalculate();\r
+ }, 1);\r
+ }\r
+ else {\r
+ this.input.onchange = function (e) {\r
+ oThis.setValue(oThis.input.value);\r
+ };\r
+ }\r
+}\r
+\r
+Slider.eventHandlers = {\r
+\r
+ // helpers to make events a bit easier\r
+ getEvent: function (e, el) {\r
+ if (!e) {\r
+ if (el)\r
+ e = el.document.parentWindow.event;\r
+ else\r
+ e = window.event;\r
+ }\r
+ if (!e.srcElement) {\r
+ var el = e.target;\r
+ while (el != null && el.nodeType != 1)\r
+ el = el.parentNode;\r
+ e.srcElement = el;\r
+ }\r
+ if (typeof e.offsetX == "undefined") {\r
+ e.offsetX = e.layerX;\r
+ e.offsetY = e.layerY;\r
+ }\r
+\r
+ return e;\r
+ },\r
+\r
+ getDocument: function (e) {\r
+ if (e.target)\r
+ return e.target.ownerDocument;\r
+ return e.srcElement.document;\r
+ },\r
+\r
+ getSlider: function (e) {\r
+ var el = e.target || e.srcElement;\r
+ while (el != null && el.slider == null) {\r
+ el = el.parentNode;\r
+ }\r
+ if (el)\r
+ return el.slider;\r
+ return null;\r
+ },\r
+\r
+ getLine: function (e) {\r
+ var el = e.target || e.srcElement;\r
+ while (el != null && el.className != "line") {\r
+ el = el.parentNode;\r
+ }\r
+ return el;\r
+ },\r
+\r
+ getHandle: function (e) {\r
+ var el = e.target || e.srcElement;\r
+ var re = /handle/;\r
+ while (el != null && !re.test(el.className)) {\r
+ el = el.parentNode;\r
+ }\r
+ return el;\r
+ },\r
+ // end helpers\r
+\r
+ onfocus: function (e) {\r
+ var s = this.slider;\r
+ s._focused = true;\r
+ s.handle.className = "handle hover";\r
+ },\r
+\r
+ onblur: function (e) {\r
+ var s = this.slider\r
+ s._focused = false;\r
+ s.handle.className = "handle";\r
+ },\r
+\r
+ onmouseover: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+ var s = this.slider;\r
+ if (e.srcElement == s.handle)\r
+ s.handle.className = "handle hover";\r
+ },\r
+\r
+ onmouseout: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+ var s = this.slider;\r
+ if (e.srcElement == s.handle && !s._focused)\r
+ s.handle.className = "handle";\r
+ },\r
+\r
+ onmousedown: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+ var s = this.slider;\r
+ if (s.element.focus)\r
+ s.element.focus();\r
+\r
+ Slider._currentInstance = s;\r
+ var doc = s.document;\r
+\r
+ if (doc.addEventListener) {\r
+ doc.addEventListener("mousemove", Slider.eventHandlers.onmousemove, true);\r
+ doc.addEventListener("mouseup", Slider.eventHandlers.onmouseup, true);\r
+ }\r
+ else if (doc.attachEvent) {\r
+ doc.attachEvent("onmousemove", Slider.eventHandlers.onmousemove);\r
+ doc.attachEvent("onmouseup", Slider.eventHandlers.onmouseup);\r
+ doc.attachEvent("onlosecapture", Slider.eventHandlers.onmouseup);\r
+ s.element.setCapture();\r
+ }\r
+\r
+ if (Slider.eventHandlers.getHandle(e)) { // start drag\r
+ Slider._sliderDragData = {\r
+ screenX: e.screenX,\r
+ screenY: e.screenY,\r
+ dx: e.screenX - s.handle.offsetLeft,\r
+ dy: e.screenY - s.handle.offsetTop,\r
+ startValue: s.getValue(),\r
+ slider: s\r
+ };\r
+ }\r
+ else {\r
+ var lineEl = Slider.eventHandlers.getLine(e);\r
+ s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);\r
+ s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);\r
+ s._increasing = null;\r
+ s.ontimer();\r
+ }\r
+ },\r
+\r
+ onmousemove: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+\r
+ if (Slider._sliderDragData) { // drag\r
+ var s = Slider._sliderDragData.slider;\r
+\r
+ var boundSize = s.getMaximum() - s.getMinimum();\r
+ var size, pos, reset;\r
+\r
+ if (s._orientation == "horizontal") {\r
+ size = s.element.offsetWidth - s.handle.offsetWidth;\r
+ pos = e.screenX - Slider._sliderDragData.dx;\r
+ reset = Math.abs(e.screenY - Slider._sliderDragData.screenY) > 100;\r
+ }\r
+ else {\r
+ size = s.element.offsetHeight - s.handle.offsetHeight;\r
+ pos = s.element.offsetHeight - s.handle.offsetHeight -\r
+ (e.screenY - Slider._sliderDragData.dy);\r
+ reset = Math.abs(e.screenX - Slider._sliderDragData.screenX) > 100;\r
+ }\r
+ s.setValue(reset ? Slider._sliderDragData.startValue :\r
+ s.getMinimum() + boundSize * pos / size);\r
+ return false;\r
+ }\r
+ else {\r
+ var s = Slider._currentInstance;\r
+ if (s != null) {\r
+ var lineEl = Slider.eventHandlers.getLine(e);\r
+ s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);\r
+ s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);\r
+ }\r
+ }\r
+\r
+ },\r
+\r
+ onmouseup: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+ var s = Slider._currentInstance;\r
+ var doc = s.document;\r
+ if (doc.removeEventListener) {\r
+ doc.removeEventListener("mousemove", Slider.eventHandlers.onmousemove, true);\r
+ doc.removeEventListener("mouseup", Slider.eventHandlers.onmouseup, true);\r
+ }\r
+ else if (doc.detachEvent) {\r
+ doc.detachEvent("onmousemove", Slider.eventHandlers.onmousemove);\r
+ doc.detachEvent("onmouseup", Slider.eventHandlers.onmouseup);\r
+ doc.detachEvent("onlosecapture", Slider.eventHandlers.onmouseup);\r
+ s.element.releaseCapture();\r
+ }\r
+\r
+ if (Slider._sliderDragData) { // end drag\r
+ Slider._sliderDragData = null;\r
+ }\r
+ else {\r
+ s._timer.stop();\r
+ s._increasing = null;\r
+ }\r
+ Slider._currentInstance = null;\r
+ },\r
+\r
+ onkeydown: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+ //var s = Slider.eventHandlers.getSlider(e);\r
+ var s = this.slider;\r
+ var kc = e.keyCode;\r
+ switch (kc) {\r
+ case 33: // page up\r
+ s.setValue(s.getValue() + s.getBlockIncrement());\r
+ break;\r
+ case 34: // page down\r
+ s.setValue(s.getValue() - s.getBlockIncrement());\r
+ break;\r
+ case 35: // end\r
+ s.setValue(s.getOrientation() == "horizontal" ?\r
+ s.getMaximum() :\r
+ s.getMinimum());\r
+ break;\r
+ case 36: // home\r
+ s.setValue(s.getOrientation() == "horizontal" ?\r
+ s.getMinimum() :\r
+ s.getMaximum());\r
+ break;\r
+ case 38: // up\r
+ case 39: // right\r
+ s.setValue(s.getValue() + s.getUnitIncrement());\r
+ break;\r
+\r
+ case 37: // left\r
+ case 40: // down\r
+ s.setValue(s.getValue() - s.getUnitIncrement());\r
+ break;\r
+ }\r
+\r
+ if (kc >= 33 && kc <= 40) {\r
+ return false;\r
+ }\r
+ },\r
+\r
+ onkeypress: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+ var kc = e.keyCode;\r
+ if (kc >= 33 && kc <= 40) {\r
+ return false;\r
+ }\r
+ },\r
+\r
+ onmousewheel: function (e) {\r
+ e = Slider.eventHandlers.getEvent(e, this);\r
+ var s = this.slider;\r
+ if (s._focused) {\r
+ s.setValue(s.getValue() + e.wheelDelta / 120 * s.getUnitIncrement());\r
+ // windows inverts this on horizontal sliders. That does not\r
+ // make sense to me\r
+ return false;\r
+ }\r
+ }\r
+};\r
+\r
+\r
+\r
+Slider.prototype.classNameTag = "dynamic-slider-control",\r
+\r
+Slider.prototype.setValue = function (v) {\r
+ this._range.setValue(v);\r
+ this.input.value = this.getValue();\r
+};\r
+\r
+Slider.prototype.getValue = function () {\r
+ return this._range.getValue();\r
+};\r
+\r
+Slider.prototype.setMinimum = function (v) {\r
+ this._range.setMinimum(v);\r
+ this.input.value = this.getValue();\r
+};\r
+\r
+Slider.prototype.getMinimum = function () {\r
+ return this._range.getMinimum();\r
+};\r
+\r
+Slider.prototype.setMaximum = function (v) {\r
+ this._range.setMaximum(v);\r
+ this.input.value = this.getValue();\r
+};\r
+\r
+Slider.prototype.getMaximum = function () {\r
+ return this._range.getMaximum();\r
+};\r
+\r
+Slider.prototype.setUnitIncrement = function (v) {\r
+ this._unitIncrement = v;\r
+};\r
+\r
+Slider.prototype.getUnitIncrement = function () {\r
+ return this._unitIncrement;\r
+};\r
+\r
+Slider.prototype.setBlockIncrement = function (v) {\r
+ this._blockIncrement = v;\r
+};\r
+\r
+Slider.prototype.getBlockIncrement = function () {\r
+ return this._blockIncrement;\r
+};\r
+\r
+Slider.prototype.getOrientation = function () {\r
+ return this._orientation;\r
+};\r
+\r
+Slider.prototype.setOrientation = function (sOrientation) {\r
+ if (sOrientation != this._orientation) {\r
+ if (Slider.isSupported && this.element) {\r
+ // add class name tag to class name\r
+ this.element.className = this.element.className.replace(this._orientation,\r
+ sOrientation);\r
+ }\r
+ this._orientation = sOrientation;\r
+ this.recalculate();\r
+\r
+ }\r
+};\r
+\r
+Slider.prototype.recalculate = function() {\r
+ if (!Slider.isSupported || !this.element) return;\r
+\r
+ var w = this.element.offsetWidth;\r
+ var h = this.element.offsetHeight;\r
+ var hw = this.handle.offsetWidth;\r
+ var hh = this.handle.offsetHeight;\r
+ var lw = this.line.offsetWidth;\r
+ var lh = this.line.offsetHeight;\r
+\r
+ // this assumes a border-box layout\r
+\r
+ if (this._orientation == "horizontal") {\r
+ this.handle.style.left = (w - hw) * (this.getValue() - this.getMinimum()) /\r
+ (this.getMaximum() - this.getMinimum()) + "px";\r
+ this.handle.style.top = (h - hh) / 2 + "px";\r
+\r
+ this.line.style.top = (h - lh) / 2 + "px";\r
+ this.line.style.left = hw / 2 + "px";\r
+ //this.line.style.right = hw / 2 + "px";\r
+ this.line.style.width = Math.max(0, w - hw - 2)+ "px";\r
+ this.line.firstChild.style.width = Math.max(0, w - hw - 4)+ "px";\r
+ }\r
+ else {\r
+ this.handle.style.left = (w - hw) / 2 + "px";\r
+ this.handle.style.top = h - hh - (h - hh) * (this.getValue() - this.getMinimum()) /\r
+ (this.getMaximum() - this.getMinimum()) + "px";\r
+\r
+ this.line.style.left = (w - lw) / 2 + "px";\r
+ this.line.style.top = hh / 2 + "px";\r
+ this.line.style.height = Math.max(0, h - hh - 2) + "px"; //hard coded border width\r
+ //this.line.style.bottom = hh / 2 + "px";\r
+ this.line.firstChild.style.height = Math.max(0, h - hh - 4) + "px"; //hard coded border width\r
+ }\r
+};\r
+\r
+Slider.prototype.ontimer = function () {\r
+ var hw = this.handle.offsetWidth;\r
+ var hh = this.handle.offsetHeight;\r
+ var hl = this.handle.offsetLeft;\r
+ var ht = this.handle.offsetTop;\r
+\r
+ if (this._orientation == "horizontal") {\r
+ if (this._mouseX > hl + hw &&\r
+ (this._increasing == null || this._increasing)) {\r
+ this.setValue(this.getValue() + this.getBlockIncrement());\r
+ this._increasing = true;\r
+ }\r
+ else if (this._mouseX < hl &&\r
+ (this._increasing == null || !this._increasing)) {\r
+ this.setValue(this.getValue() - this.getBlockIncrement());\r
+ this._increasing = false;\r
+ }\r
+ }\r
+ else {\r
+ if (this._mouseY > ht + hh &&\r
+ (this._increasing == null || !this._increasing)) {\r
+ this.setValue(this.getValue() - this.getBlockIncrement());\r
+ this._increasing = false;\r
+ }\r
+ else if (this._mouseY < ht &&\r
+ (this._increasing == null || this._increasing)) {\r
+ this.setValue(this.getValue() + this.getBlockIncrement());\r
+ this._increasing = true;\r
+ }\r
+ }\r
+\r
+ this._timer.start();\r
+};
\ No newline at end of file