PageSourceSearch

https://esch.lu/wp-content/plugins/lightbulb-esch-tv/assets/libs/rangeslider.min.js?ver=16

js esch.lu collected 2026-10-02 04:02:54 UTC 17,871 bytes, 497 lines download raw bytes

vendor: 17,871 bytes, lines 1-497
1(function(factory) {
2    'use strict';
3
4    if (typeof define === 'function' && define.amd) {
5        // AMD. Register as an anonymous module.
6        define(['jquery'], factory);
7    } else if (typeof exports === 'object') {
8        // CommonJS
9        module.exports = factory(require('jquery'));
10    } else {
11        // Browser globals
12        factory(jQuery);
13    }
14}(function($) {
15    'use strict';
16
17    // Polyfill Number.isNaN(value)
18    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
19    Number.isNaN = Number.isNaN || function(value) {
20        return typeof value === 'number' && value !== value;
21    };
22
23    /**
24     * Range feature detection
25     * @return {Boolean}
26     */
27    function supportsRange() {
28        var input = document.createElement('input');
29        input.setAttribute('type', 'range');
30        return input.type !== 'text';
31    }
32
33    var pluginName = 'rangeslider',
34        pluginIdentifier = 0,
35        hasInputRangeSupport = supportsRange(),
36        defaults = {
37            polyfill: true,
38            orientation: 'horizontal',
39            rangeClass: 'rangeslider',
40            disabledClass: 'rangeslider--disabled',
41            activeClass: 'rangeslider--active',
42            horizontalClass: 'rangeslider--horizontal',
43            verticalClass: 'rangeslider--vertical',
44            fillClass: 'rangeslider__fill',
45            handleClass: 'rangeslider__handle',
46            startEvent: ['mousedown', 'touchstart', 'pointerdown'],
47            moveEvent: ['mousemove', 'touchmove', 'pointermove'],
48            endEvent: ['mouseup', 'touchend', 'pointerup']
49        },
50        constants = {
51            orientation: {
52                horizontal: {
53                    dimension: 'width',
54                    direction: 'left',
55                    directionStyle: 'left',
56                    coordinate: 'x'
57                },
58                vertical: {
59                    dimension: 'height',
60                    direction: 'top',
61                    directionStyle: 'bottom',
62                    coordinate: 'y'
63                }
64            }
65        };
66
67    /**
68     * Delays a function for the given number of milliseconds, and then calls
69     * it with the arguments supplied.
70     *
71     * @param  {Function} fn   [description]
72     * @param  {Number}   wait [description]
73     * @return {Function}
74     */
75    function delay(fn, wait) {
76        var args = Array.prototype.slice.call(arguments, 2);
77        return setTimeout(function(){ return fn.apply(null, args); }, wait);
78    }
79
80    /**
81     * Returns a debounced function that will make sure the given
82     * function is not triggered too much.
83     *
84     * @param  {Function} fn Function to debounce.
85     * @param  {Number}   debounceDuration OPTIONAL. The amount of time in milliseconds for which we will debounce the function. (defaults to 100ms)
86     * @return {Function}
87     */
88    function debounce(fn, debounceDuration) {
89        debounceDuration = debounceDuration || 100;
90        return function() {
91            if (!fn.debouncing) {
92                var args = Array.prototype.slice.apply(arguments);
93                fn.lastReturnVal = fn.apply(window, args);
94                fn.debouncing = true;
95            }
96            clearTimeout(fn.debounceTimeout);
97            fn.debounceTimeout = setTimeout(function(){
98                fn.debouncing = false;
99            }, debounceDuration);
100            return fn.lastReturnVal;
101        };
102    }
103
104    /**
105     * Check if a `element` is visible in the DOM
106     *
107     * @param  {Element}  element
108     * @return {Boolean}
109     */
110    function isHidden(element) {
111        return (
112            element && (
113                element.offsetWidth === 0 ||
114                element.offsetHeight === 0 ||
115                // Also Consider native `<details>` elements.
116                element.open === false
117            )
118        );
119    }
120
121    /**
122     * Get hidden parentNodes of an `element`
123     *
124     * @param  {Element} element
125     * @return {[type]}
126     */
127    function getHiddenParentNodes(element) {
128        var parents = [],
129            node    = element.parentNode;
130
131        while (isHidden(node)) {
132            parents.push(node);
133            node = node.parentNode;
134        }
135        return parents;
136    }
137
138    /**
139     * Returns dimensions for an element even if it is not visible in the DOM.
140     *
141     * @param  {Element} element
142     * @param  {String}  key     (e.g. offsetWidth …)
143     * @return {Number}
144     */
145    function getDimension(element, key) {
146        var hiddenParentNodes       = getHiddenParentNodes(element),
147            hiddenParentNodesLength = hiddenParentNodes.length,
148            inlineStyle             = [],
149            dimension               = element[key];
150
151        // Used for native `<details>` elements
152        function toggleOpenProperty(element) {
153            if (typeof element.open !== 'undefined') {
154                element.open = (element.open) ? false : true;
155            }
156        }
157
158        if (hiddenParentNodesLength) {
159            for (var i = 0; i < hiddenParentNodesLength; i++) {
160
161                // Cache style attribute to restore it later.
162                inlineStyle[i] = hiddenParentNodes[i].style.cssText;
163
164                // visually hide
165                if (hiddenParentNodes[i].style.setProperty) {
166                    hiddenParentNodes[i].style.setProperty('display', 'block', 'important');
167                } else {
168                    hiddenParentNodes[i].style.cssText += ';display: block !important';
169                }
170                hiddenParentNodes[i].style.height = '0';
171                hiddenParentNodes[i].style.overflow = 'hidden';
172                hiddenParentNodes[i].style.visibility = 'hidden';
173                toggleOpenProperty(hiddenParentNodes[i]);
174            }
175
176            // Update dimension
177            dimension = element[key];
178
179            for (var j = 0; j < hiddenParentNodesLength; j++) {
180
181                // Restore the style attribute
182                hiddenParentNodes[j].style.cssText = inlineStyle[j];
183                toggleOpenProperty(hiddenParentNodes[j]);
184            }
185        }
186        return dimension;
187    }
188
189    /**
190     * Returns the parsed float or the default if it failed.
191     *
192     * @param  {String}  str
193     * @param  {Number}  defaultValue
194     * @return {Number}
195     */
196    function tryParseFloat(str, defaultValue) {
197        var value = parseFloat(str);
198        return Number.isNaN(value) ? defaultValue : value;
199    }
200
201    /**
202     * Capitalize the first letter of string
203     *
204     * @param  {String} str
205     * @return {String}
206     */
207    function ucfirst(str) {
208        return str.charAt(0).toUpperCase() + str.substr(1);
209    }
210
211    /**
212     * Plugin
213     * @param {String} element
214     * @param {Object} options
215     */
216    function Plugin(element, options) {
217        this.$window            = $(window);
218        this.$document          = $(document);
219        this.$element           = $(element);
220        this.options            = $.extend( {}, defaults, options );
221        this.polyfill           = this.options.polyfill;
222        this.orientation        = this.$element[0].getAttribute('data-orientation') || this.options.orientation;
223        this.onInit             = this.options.onInit;
224        this.onSlide            = this.options.onSlide;
225        this.onSlideEnd         = this.options.onSlideEnd;
226        this.DIMENSION          = constants.orientation[this.orientation].dimension;
227        this.DIRECTION          = constants.orientation[this.orientation].direction;
228        this.DIRECTION_STYLE    = constants.orientation[this.orientation].directionStyle;
229        this.COORDINATE         = constants.orientation[this.orientation].coordinate;
230
231        // Plugin should only be used as a polyfill
232        if (this.polyfill) {
233            // Input range support?
234            if (hasInputRangeSupport) { return false; }
235        }
236
237        this.identifier = 'js-' + pluginName + '-' +(pluginIdentifier++);
238        this.startEvent = this.options.startEvent.join('.' + this.identifier + ' ') + '.' + this.identifier;
239        this.moveEvent  = this.options.moveEvent.join('.' + this.identifier + ' ') + '.' + this.identifier;
240        this.endEvent   = this.options.endEvent.join('.' + this.identifier + ' ') + '.' + this.identifier;
241        this.toFixed    = (this.step + '').replace('.', '').length - 1;
242        this.$fill      = $('<div class="' + this.options.fillClass + '" />');
243        this.$handle    = $('<div class="' + this.options.handleClass + '" />');
244        this.$range     = $('<div class="' + this.options.rangeClass + ' ' + this.options[this.orientation + 'Class'] + '" id="' + this.identifier + '" />').insertAfter(this.$element).prepend(this.$fill, this.$handle);
245
246        // visually hide the input
247        this.$element.css({
248            'position': 'absolute',
249            'width': '1px',
250            'height': '1px',
251            'overflow': 'hidden',
252            'opacity': '0'
253        });
254
255        // Store context
256        this.handleDown = $.proxy(this.handleDown, this);
257        this.handleMove = $.proxy(this.handleMove, this);
258        this.handleEnd  = $.proxy(this.handleEnd, this);
259
260        this.init();
261
262        // Attach Events
263        var _this = this;
264        this.$window.on('resize.' + this.identifier, debounce(function() {
265            // Simulate resizeEnd event.
266            delay(function() { _this.update(false, false); }, 300);
267        }, 20));
268
269        this.$document.on(this.startEvent, '#' + this.identifier + ':not(.' + this.options.disabledClass + ')', this.handleDown);
270
271        // Listen to programmatic value changes
272        this.$element.on('change.' + this.identifier, function(e, data) {
273            if (data && data.origin === _this.identifier) {
274                return;
275            }
276
277            var value = e.target.value,
278                pos = _this.getPositionFromValue(value);
279            _this.setPosition(pos);
280        });
281    }
282
283    Plugin.prototype.init = function() {
284        this.update(true, false);
285
286        if (this.onInit && typeof this.onInit === 'function') {
287            this.onInit();
288        }
289    };
290
291    Plugin.prototype.update = function(updateAttributes, triggerSlide) {
292        updateAttributes = updateAttributes || false;
293
294        if (updateAttributes) {
295            this.min    = tryParseFloat(this.$element[0].getAttribute('min'), 0);
296            this.max    = tryParseFloat(this.$element[0].getAttribute('max'), 100);
297            this.value  = tryParseFloat(this.$element[0].value, Math.round(this.min + (this.max-this.min)/2));
298            this.step   = tryParseFloat(this.$element[0].getAttribute('step'), 1);
299        }
300
301        this.handleDimension    = getDimension(this.$handle[0], 'offset' + ucfirst(this.DIMENSION));
302        this.rangeDimension     = getDimension(this.$range[0], 'offset' + ucfirst(this.DIMENSION));
303        this.maxHandlePos       = this.rangeDimension - this.handleDimension;
304        this.grabPos            = this.handleDimension / 2;
305        this.position           = this.getPositionFromValue(this.value);
306
307        // Consider disabled state
308        if (this.$element[0].disabled) {
309            this.$range.addClass(this.options.disabledClass);
310        } else {
311            this.$range.removeClass(this.options.disabledClass);
312        }
313
314        this.setPosition(this.position, triggerSlide);
315    };
316
317    Plugin.prototype.handleDown = function(e) {
318        e.preventDefault();
319
320        // Only respond to mouse main button clicks (usually the left button)
321        if (e.button && e.button !== 0) { return; }
322
323        this.$document.on(this.moveEvent, this.handleMove);
324        this.$document.on(this.endEvent, this.handleEnd);
325
326        // add active class because Firefox is ignoring
327        // the handle:active pseudo selector because of `e.preventDefault();`
328        this.$range.addClass(this.options.activeClass);
329
330        // If we click on the handle don't set the new position
331        if ((' ' + e.target.className + ' ').replace(/[\n\t]/g, ' ').indexOf(this.options.handleClass) > -1) {
332            return;
333        }
334
335        var pos         = this.getRelativePosition(e),
336            rangePos    = this.$range[0].getBoundingClientRect()[this.DIRECTION],
337            handlePos   = this.getPositionFromNode(this.$handle[0]) - rangePos,
338            setPos      = (this.orientation === 'vertical') ? (this.maxHandlePos - (pos - this.grabPos)) : (pos - this.grabPos);
339
340        this.setPosition(setPos);
341
342        if (pos >= handlePos && pos < handlePos + this.handleDimension) {
343            this.grabPos = pos - handlePos;
344        }
345    };
346
347    Plugin.prototype.handleMove = function(e) {
348        e.preventDefault();
349        var pos = this.getRelativePosition(e);
350        var setPos = (this.orientation === 'vertical') ? (this.maxHandlePos - (pos - this.grabPos)) : (pos - this.grabPos);
351        this.setPosition(setPos);
352    };
353
354    Plugin.prototype.handleEnd = function(e) {
355        e.preventDefault();
356        this.$document.off(this.moveEvent, this.handleMove);
357        this.$document.off(this.endEvent, this.handleEnd);
358
359        this.$range.removeClass(this.options.activeClass);
360
361        // Ok we're done fire the change event
362        this.$element.trigger('change', { origin: this.identifier });
363
364        if (this.onSlideEnd && typeof this.onSlideEnd === 'function') {
365            this.onSlideEnd(this.position, this.value);
366        }
367    };
368
369    Plugin.prototype.cap = function(pos, min, max) {
370        if (pos < min) { return min; }
371        if (pos > max) { return max; }
372        return pos;
373    };
374
375    Plugin.prototype.setPosition = function(pos, triggerSlide) {
376        var value, newPos;
377
378        if (triggerSlide === undefined) {
379            triggerSlide = true;
380        }
381
382        // Snapping steps
383        value = this.getValueFromPosition(this.cap(pos, 0, this.maxHandlePos));
384        newPos = this.getPositionFromValue(value);
385
386        // Update ui
387        this.$fill[0].style[this.DIMENSION] = (newPos + this.grabPos) + 'px';
388        this.$handle[0].style[this.DIRECTION_STYLE] = newPos + 'px';
389        this.setValue(value);
390
391        // Update globals
392        this.position = newPos;
393        this.value = value;
394
395        if (triggerSlide && this.onSlide && typeof this.onSlide === 'function') {
396            this.onSlide(newPos, value);
397        }
398    };
399
400    // Returns element position relative to the parent
401    Plugin.prototype.getPositionFromNode = function(node) {
402        var i = 0;
403        while (node !== null) {
404            i += node.offsetLeft;
405            node = node.offsetParent;
406        }
407        return i;
408    };
409
410    Plugin.prototype.getRelativePosition = function(e) {
411        // Get the offset DIRECTION relative to the viewport
412        var ucCoordinate = ucfirst(this.COORDINATE),
413            rangePos = this.$range[0].getBoundingClientRect()[this.DIRECTION],
414            pageCoordinate = 0;
415
416        if (typeof e.originalEvent['client' + ucCoordinate] !== 'undefined') {
417            pageCoordinate = e.originalEvent['client' + ucCoordinate];
418        }
419        else if (
420            e.originalEvent.touches &&
421            e.originalEvent.touches[0] &&
422            typeof e.originalEvent.touches[0]['client' + ucCoordinate] !== 'undefined'
423        ) {
424            pageCoordinate = e.originalEvent.touches[0]['client' + ucCoordinate];
425        }
426        else if(e.currentPoint && typeof e.currentPoint[this.COORDINATE] !== 'undefined') {
427            pageCoordinate = e.currentPoint[this.COORDINATE];
428        }
429
430        return pageCoordinate - rangePos;
431    };
432
433    Plugin.prototype.getPositionFromValue = function(value) {
434        var percentage, pos;
435        percentage = (value - this.min)/(this.max - this.min);
436        pos = (!Number.isNaN(percentage)) ? percentage * this.maxHandlePos : 0;
437        return pos;
438    };
439
440    Plugin.prototype.getValueFromPosition = function(pos) {
441        var percentage, value;
442        percentage = ((pos) / (this.maxHandlePos || 1));
443        value = this.step * Math.round(percentage * (this.max - this.min) / this.step) + this.min;
444        return Number((value).toFixed(this.toFixed));
445    };
446
447    Plugin.prototype.setValue = function(value) {
448        if (value === this.value && this.$element[0].value !== '') {
449            return;
450        }
451
452        // Set the new value and fire the `input` event
453        this.$element
454            .val(value)
455            .trigger('input', { origin: this.identifier });
456    };
457
458    Plugin.prototype.destroy = function() {
459        this.$document.off('.' + this.identifier);
460        this.$window.off('.' + this.identifier);
461
462        this.$element
463            .off('.' + this.identifier)
464            .removeAttr('style')
465            .removeData('plugin_' + pluginName);
466
467        // Remove the generated markup
468        if (this.$range && this.$range.length) {
469            this.$range[0].parentNode.removeChild(this.$range[0]);
470        }
471    };
472
473    // A really lightweight plugin wrapper around the constructor,
474    // preventing against multiple instantiations
475    $.fn[pluginName] = function(options) {
476        var args = Array.prototype.slice.call(arguments, 1);
477
478        return this.each(function() {
479            var $this = $(this),
480                data  = $this.data('plugin_' + pluginName);
481
482            // Create a new instance.
483            if (!data) {
484                $this.data('plugin_' + pluginName, (data = new Plugin(this, options)));
485            }
486
487            // Make it possible to access methods from public.
488            // e.g `$element.rangeslider('method');`
489            if (typeof options === 'string') {
490                data[options].apply(data, args);
491            }
492        });
493    };
494
495    return 'rangeslider.js is available in jQuery context e.g $(selector).rangeslider(options);';
496
497}));

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.