1(function () { 2 'use strict'; 3 4 var RS = function (conf) { 5 this.input = null; 6 this.inputDisplay = null; 7 this.slider = null; 8 this.sliderWidth = 0; 9 this.sliderLeft = 0; 10 this.pointerWidth = 0; 11 this.pointerR = null; 12 this.pointerL = null; 13 this.activePointer = null; 14 this.selected = null; 15 this.scale = null; 16 this.step = 0; 17 this.tipL = null; 18 this.tipR = null; 19 this.timeout = null; 20 this.valRange = false; 21 22 this.values = { 23 start: null, 24 end: null 25 }; 26 this.conf = { 27 target: null, 28 values: null, 29 set: null, 30 range: false, 31 width: null, 32 scale: true, 33 labels: true, 34 tooltip: true, 35 step: null, 36 disabled: false, 37 onChange: null 38 }; 39 40 this.cls = { 41 container: 'rs-container', 42 background: 'rs-bg', 43 selected: 'rs-selected', 44 pointer: 'rs-pointer', 45 scale: 'rs-scale', 46 noscale: 'rs-noscale', 47 tip: 'rs-tooltip' 48 }; 49 50 for (var i in this.conf) { if (conf.hasOwnProperty(i)) this.conf[i] = conf[i]; } 51 52 this.init(); 53 }; 54 55 RS.prototype.init = function () { 56 if (typeof this.conf.target === 'object') this.input = this.conf.target; 57 else this.input = document.getElementById(this.conf.target.replace('#', '')); 58 59 if (!this.input) return console.log('Cannot find target element...'); 60 61 this.inputDisplay = getComputedStyle(this.input, null).display; 62 this.input.style.display = 'none'; 63 this.valRange = !(this.conf.values instanceof Array); 64 65 if (this.valRange) { 66 if (!this.conf.values.hasOwnProperty('min') || !this.conf.values.hasOwnProperty('max')) 67 return console.log('Missing min or max value...'); 68 } 69 return this.createSlider(); 70 }; 71 72 RS.prototype.createSlider = function () { 73 this.slider = createElement('div', this.cls.container); 74 this.slider.innerHTML = '<div class="rs-bg"></div>'; 75 this.selected = createElement('div', this.cls.selected); 76 this.pointerL = createElement('div', this.cls.pointer, ['dir', 'left']); 77 this.scale = createElement('div', this.cls.scale); 78 79 if (this.conf.tooltip) { 80 this.tipL = createElement('div', this.cls.tip); 81 this.tipR = createElement('div', this.cls.tip); 82 this.pointerL.appendChild(this.tipL); 83 } 84 this.slider.appendChild(this.selected); 85 this.slider.appendChild(this.scale); 86 this.slider.appendChild(this.pointerL); 87 88 if (this.conf.range) { 89 this.pointerR = createElement('div', this.cls.pointer, ['dir', 'right']); 90 if (this.conf.tooltip) this.pointerR.appendChild(this.tipR); 91 this.slider.appendChild(this.pointerR); 92 } 93 94 this.input.parentNode.insertBefore(this.slider, this.input.nextSibling); 95 96 if (this.conf.width) this.slider.style.width = parseInt(this.conf.width) + 'px'; 97 this.sliderLeft = this.slider.getBoundingClientRect().left; 98 this.sliderWidth = this.slider.clientWidth; 99 this.pointerWidth = this.pointerL.clientWidth; 100 101 if (!this.conf.scale) this.slider.classList.add(this.cls.noscale); 102 103 return this.setInitialValues(); 104 }; 105 106 RS.prototype.setInitialValues = function () { 107 this.disabled(this.conf.disabled); 108 109 if (this.valRange) this.conf.values = prepareArrayValues(this.conf); 110 111 this.values.start = 0; 112 this.values.end = this.conf.range ? this.conf.values.length - 1 : 0; 113 114 115 if (this.conf.set && this.conf.set.length && checkInitial(this.conf)) { 116 var vals = this.conf.set; 117 118 if (this.conf.range) { 119 this.values.start = this.conf.values.indexOf(vals[0]); 120 this.values.end = this.conf.set[1] ? this.conf.values.indexOf(vals[1]) : null; 121 } 122 else this.values.end = this.conf.values.indexOf(vals[0]); 123 } 124 return this.createScale(); 125 }; 126 127 RS.prototype.createScale = function (resize) { 128 this.step = this.sliderWidth / (this.conf.values.length - 1); 129 130 for (var i = 0, iLen = this.conf.values.length; i < iLen; i++) { 131 var span = createElement('span'), 132 ins = createElement('ins'); 133 134 span.appendChild(ins); 135 this.scale.appendChild(span); 136 137 span.style.width = i === iLen - 1 ? 0 : this.step + 'px'; 138 139 if (!this.conf.labels) { 140 if (i === 0 || i === iLen - 1) ins.innerHTML = this.conf.values[i] 141 } 142 else ins.innerHTML = this.conf.values[i]; 143 144 ins.style.marginLeft = (ins.clientWidth / 2) * - 1 + 'px'; 145 } 146 return this.addEvents(); 147 }; 148 149 RS.prototype.updateScale = function () { 150 this.step = this.sliderWidth / (this.conf.values.length - 1); 151 152 var pieces = this.slider.querySelectorAll('span'); 153 154 for (var i = 0, iLen = pieces.length; i < iLen; i++) 155 pieces[i].style.width = this.step + 'px'; 156 157 return this.setValues(); 158 }; 159 160 RS.prototype.addEvents = function () { 161 var pointers = this.slider.querySelectorAll('.' + this.cls.pointer), 162 pieces = this.slider.querySelectorAll('span'); 163 164 createEvents(document, 'mousemove touchmove', this.move.bind(this)); 165 createEvents(document, 'mouseup touchend touchcancel', this.drop.bind(this)); 166 167 for (var i = 0, iLen = pointers.length; i < iLen; i++) 168 createEvents(pointers[i], 'mousedown touchstart', this.drag.bind(this)); 169 170 for (var i = 0, iLen = pieces.length; i < iLen; i++) 171 createEvents(pieces[i], 'click', this.onClickPiece.bind(this)); 172 173 window.addEventListener('resize', this.onResize.bind(this)); 174 175 return this.setValues(); 176 }; 177 178 RS.prototype.drag = function (e) { 179 e.preventDefault(); 180 181 if (this.conf.disabled) return; 182 183 var dir = e.target.getAttribute('data-dir'); 184 if (dir === 'left') this.activePointer = this.pointerL; 185 if (dir === 'right') this.activePointer = this.pointerR; 186 187 return this.slider.classList.add('sliding'); 188 }; 189 190 RS.prototype.move = function (e) { 191 if (this.activePointer && !this.conf.disabled) { 192 var coordX = e.type === 'touchmove' ? e.touches[0].clientX : e.pageX, 193 index = coordX - this.sliderLeft - (this.pointerWidth / 2); 194 195 index = Math.round(index / this.step); 196 197 if (index <= 0) index = 0; 198 if (index > this.conf.values.length - 1) index = this.conf.values.length - 1; 199 200 if (this.conf.range) { 201 if (this.activePointer === this.pointerL) this.values.start = index; 202 if (this.activePointer === this.pointerR) this.values.end = index; 203 } 204 else this.values.end = index; 205 206 return this.setValues(); 207 } 208 }; 209 210 RS.prototype.drop = function () { 211 this.activePointer = null; 212 }; 213 214 RS.prototype.setValues = function (start, end) { 215 var activePointer = this.conf.range ? 'start' : 'end'; 216 217 if (start && this.conf.values.indexOf(start) > -1) 218 this.values[activePointer] = this.conf.values.indexOf(start); 219 220 if (end && this.conf.values.indexOf(end) > -1) 221 this.values.end = this.conf.values.indexOf(end); 222 223 if (this.conf.range && this.values.start > this.values.end) 224 this.values.start = this.values.end; 225 226 this.pointerL.style.left = (this.values[activePointer] * this.step - (this.pointerWidth / 2)) + 'px'; 227 228 if (this.conf.range) { 229 if (this.conf.tooltip) { 230 this.tipL.innerHTML = this.conf.values[this.values.start]; 231 this.tipR.innerHTML = this.conf.values[this.values.end]; 232 } 233 this.input.value = this.conf.values[this.values.start] + ',' + this.conf.values[this.values.end]; 234 this.pointerR.style.left = (this.values.end * this.step - (this.pointerWidth / 2)) + 'px'; 235 } 236 else { 237 if (this.conf.tooltip) 238 this.tipL.innerHTML = this.conf.values[this.values.end]; 239 this.input.value = this.conf.values[this.values.end]; 240 } 241 242 if (this.values.end > this.conf.values.length - 1) this.values.end = this.conf.values.length - 1; 243 if (this.values.start < 0) this.values.start = 0; 244 245 this.selected.style.width = (this.values.end - this.values.start) * this.step + 'px'; 246 this.selected.style.left = this.values.start * this.step + 'px'; 247 248 return this.onChange(); 249 }; 250 251 RS.prototype.onClickPiece = function (e) { 252 253 if (this.conf.disabled) return; 254 255 var idx = Math.round((e.clientX - this.sliderLeft) / this.step); 256 257 if (idx > this.conf.values.length - 1) idx = this.conf.values.length - 1; 258 if (idx < 0) idx = 0; 259 260 if (this.conf.range) { 261 if (idx - this.values.start <= this.values.end - idx) { 262 this.values.start = idx; 263 } 264 else this.values.end = idx; 265 } 266 else this.values.end = idx; 267 268 this.slider.classList.remove('sliding'); 269 270 return this.setValues(); 271 }; 272 273 RS.prototype.onChange = function () { 274 var _this = this; 275 276 if (this.timeout) clearTimeout(this.timeout); 277 278 this.timeout = setTimeout(function () { 279 if (_this.conf.onChange && typeof _this.conf.onChange === 'function') { 280 return _this.conf.onChange(_this.input.value); 281 } 282 }, 500); 283 }; 284 285 RS.prototype.onResize = function () { 286 this.sliderLeft = this.slider.getBoundingClientRect().left; 287 this.sliderWidth = this.slider.clientWidth; 288 return this.updateScale(); 289 }; 290 291 RS.prototype.disabled = function (disabled) { 292 this.conf.disabled = disabled; 293 this.slider.classList[disabled ? 'add' : 'remove']('disabled'); 294 }; 295 296 RS.prototype.getValue = function () { 297 return this.input.value; 298 }; 299 300 RS.prototype.destroy = function () { 301 this.input.style.display = this.inputDisplay; 302 this.slider.remove(); 303 }; 304 305 var createElement = function (el, cls, dataAttr) { 306 var element = document.createElement(el); 307 if (cls) element.className = cls; 308 if (dataAttr && dataAttr.length === 2) 309 element.setAttribute('data-' + dataAttr[0], dataAttr[1]); 310 311 return element; 312 }, 313 314 createEvents = function (el, ev, callback) { 315 var events = ev.split(' '); 316 317 for (var i = 0, iLen = events.length; i < iLen; i++) 318 el.addEventListener(events[i], callback); 319 }, 320 321 prepareArrayValues = function (conf) { 322 var values = [], 323 range = conf.values.max - conf.values.min; 324 325 if (!conf.step) { 326 console.log('No step defined...'); 327 return [conf.values.min, conf.values.max]; 328 } 329 330 for (var i = 0, iLen = (range / conf.step); i < iLen; i++) 331 values.push(conf.values.min + i * conf.step); 332 333 if (values.indexOf(conf.values.max) < 0) values.push(conf.values.max); 334 335 return values; 336 }, 337 338 checkInitial = function (conf) { 339 if (!conf.set || conf.set.length < 1) return null; 340 if (conf.values.indexOf(conf.set[0]) < 0) return null; 341 342 if (conf.range) { 343 if (conf.set.length < 2 || conf.values.indexOf(conf.set[1]) < 0) return null; 344 } 345 return true; 346 }; 347 348 window.rSlider = RS; 349 350})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.