PageSourceSearch

https://waqtnews.tv/assets/waqt_tv/js/smoothscroll.js?mdate=1753861281

js waqtnews.tv collected 2026-09-25 04:11:08 UTC 14,224 bytes, 535 lines download raw bytes

1// SmoothScroll for websites v1.2.1
2// Licensed under the terms of the MIT license.
3
4// People involved
5//  - Balazs Galambosi (maintainer)  
6//  - Michael Herf     (Pulse Algorithm)
7
8(function(){
9  
10// Scroll Variables (tweakable)
11var defaultOptions = {
12
13    // Scrolling Core
14    frameRate        : 150, // [Hz]
15    animationTime    : 400, // [px]
16    stepSize         : 120, // [px]
17
18    // Pulse (less tweakable)
19    // ratio of "tail" to "acceleration"
20    pulseAlgorithm   : true,
21    pulseScale       : 8,
22    pulseNormalize   : 1,
23
24    // Acceleration
25    accelerationDelta : 20,  // 20
26    accelerationMax   : 1,   // 1
27
28    // Keyboard Settings
29    keyboardSupport   : true,  // option
30    arrowScroll       : 50,     // [px]
31
32    // Other
33    touchpadSupport   : true,
34    fixedBackground   : true, 
35    excluded          : ""    
36};
37
38var options = defaultOptions;
39
40
41// Other Variables
42var isExcluded = false;
43var isFrame = false;
44var direction = { x: 0, y: 0 };
45var initDone  = false;
46var root = document.documentElement;
47var activeElement;
48var observer;
49var deltaBuffer = [ 120, 120, 120 ];
50
51var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, 
52            pageup: 33, pagedown: 34, end: 35, home: 36 };
53
54
55/***********************************************
56 * SETTINGS
57 ***********************************************/
58
59var options = defaultOptions;
60
61
62/***********************************************
63 * INITIALIZE
64 ***********************************************/
65
66/**
67 * Tests if smooth scrolling is allowed. Shuts down everything if not.
68 */
69function initTest() {
70
71    var disableKeyboard = false; 
72    
73    // disable keyboard support if anything above requested it
74    if (disableKeyboard) {
75        removeEvent("keydown", keydown);
76    }
77
78    if (options.keyboardSupport && !disableKeyboard) {
79        addEvent("keydown", keydown);
80    }
81}
82
83/**
84 * Sets up scrolls array, determines if frames are involved.
85 */
86function init() {
87  
88    if (!document.body) return;
89
90    var body = document.body;
91    var html = document.documentElement;
92    var windowHeight = window.innerHeight; 
93    var scrollHeight = body.scrollHeight;
94    
95    // check compat mode for root element
96    root = (document.compatMode.indexOf('CSS') >= 0) ? html : body;
97    activeElement = body;
98    
99    initTest();
100    initDone = true;
101
102    // Checks if this script is running in a frame
103    if (top != self) {
104        isFrame = true;
105    }
106
107    /**
108     * This fixes a bug where the areas left and right to 
109     * the content does not trigger the onmousewheel event
110     * on some pages. e.g.: html, body { height: 100% }
111     */
112    else if (scrollHeight > windowHeight &&
113            (body.offsetHeight <= windowHeight || 
114             html.offsetHeight <= windowHeight)) {
115
116        // DOMChange (throttle): fix height
117        var pending = false;
118        var refresh = function () {
119            if (!pending && html.scrollHeight != document.height) {
120                pending = true; // add a new pending action
121                setTimeout(function () {
122                    html.style.height = document.height + 'px';
123                    pending = false;
124                }, 500); // act rarely to stay fast
125            }
126        };
127        html.style.height = 'auto';
128        setTimeout(refresh, 10);
129
130        // clearfix
131        if (root.offsetHeight <= windowHeight) {
132            var underlay = document.createElement("div"); 	
133            underlay.style.clear = "both";
134            body.appendChild(underlay);
135        }
136    }
137
138    // disable fixed background
139    if (!options.fixedBackground && !isExcluded) {
140        body.style.backgroundAttachment = "scroll";
141        html.style.backgroundAttachment = "scroll";
142    }
143}
144
145
146/************************************************
147 * SCROLLING 
148 ************************************************/
149 
150var que = [];
151var pending = false;
152var lastScroll = +new Date;
153
154/**
155 * Pushes scroll actions to the scrolling queue.
156 */
157function scrollArray(elem, left, top, delay) {
158    
159    delay || (delay = 1000);
160    directionCheck(left, top);
161
162    if (options.accelerationMax != 1) {
163        var now = +new Date;
164        var elapsed = now - lastScroll;
165        if (elapsed < options.accelerationDelta) {
166            var factor = (1 + (30 / elapsed)) / 2;
167            if (factor > 1) {
168                factor = Math.min(factor, options.accelerationMax);
169                left *= factor;
170                top  *= factor;
171            }
172        }
173        lastScroll = +new Date;
174    }          
175    
176    // push a scroll command
177    que.push({
178        x: left, 
179        y: top, 
180        lastX: (left < 0) ? 0.99 : -0.99,
181        lastY: (top  < 0) ? 0.99 : -0.99, 
182        start: +new Date
183    });
184        
185    // don't act if there's a pending queue
186    if (pending) {
187        return;
188    }  
189
190    var scrollWindow = (elem === document.body);
191    
192    var step = function (time) {
193        
194        var now = +new Date;
195        var scrollX = 0;
196        var scrollY = 0; 
197    
198        for (var i = 0; i < que.length; i++) {
199            
200            var item = que[i];
201            var elapsed  = now - item.start;
202            var finished = (elapsed >= options.animationTime);
203            
204            // scroll position: [0, 1]
205            var position = (finished) ? 1 : elapsed / options.animationTime;
206            
207            // easing [optional]
208            if (options.pulseAlgorithm) {
209                position = pulse(position);
210            }
211            
212            // only need the difference
213            var x = (item.x * position - item.lastX) >> 0;
214            var y = (item.y * position - item.lastY) >> 0;
215            
216            // add this to the total scrolling
217            scrollX += x;
218            scrollY += y;            
219            
220            // update last values
221            item.lastX += x;
222            item.lastY += y;
223        
224            // delete and step back if it's over
225            if (finished) {
226                que.splice(i, 1); i--;
227            }           
228        }
229
230        // scroll left and top
231        if (scrollWindow) {
232            window.scrollBy(scrollX, scrollY);
233        } 
234        else {
235            if (scrollX) elem.scrollLeft += scrollX;
236            if (scrollY) elem.scrollTop  += scrollY;                    
237        }
238        
239        // clean up if there's nothing left to do
240        if (!left && !top) {
241            que = [];
242        }
243        
244        if (que.length) { 
245            requestFrame(step, elem, (delay / options.frameRate + 1)); 
246        } else { 
247            pending = false;
248        }
249    };
250    
251    // start a new queue of actions
252    requestFrame(step, elem, 0);
253    pending = true;
254}
255
256
257/***********************************************
258 * EVENTS
259 ***********************************************/
260
261/**
262 * Mouse wheel handler.
263 * @param {Object} event
264 */
265function wheel(event) {
266
267    if (!initDone) {
268        init();
269    }
270    
271    var target = event.target;
272    var overflowing = overflowingAncestor(target);
273    
274    // use default if there's no overflowing
275    // element or default action is prevented    
276    if (!overflowing || event.defaultPrevented ||
277        isNodeName(activeElement, "embed") ||
278       (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) {
279        return true;
280    }
281
282    var deltaX = event.wheelDeltaX || 0;
283    var deltaY = event.wheelDeltaY || 0;
284    
285    // use wheelDelta if deltaX/Y is not available
286    if (!deltaX && !deltaY) {
287        deltaY = event.wheelDelta || 0;
288    }
289
290    // check if it's a touchpad scroll that should be ignored
291    if (!options.touchpadSupport && isTouchpad(deltaY)) {
292        return true;
293    }
294
295    // scale by step size
296    // delta is 120 most of the time
297    // synaptics seems to send 1 sometimes
298    if (Math.abs(deltaX) > 1.2) {
299        deltaX *= options.stepSize / 120;
300    }
301    if (Math.abs(deltaY) > 1.2) {
302        deltaY *= options.stepSize / 120;
303    }
304    
305    scrollArray(overflowing, -deltaX, -deltaY);
306    event.preventDefault();
307}
308
309/**
310 * Keydown event handler.
311 * @param {Object} event
312 */
313function keydown(event) {
314
315    var target   = event.target;
316    var modifier = event.ctrlKey || event.altKey || event.metaKey || 
317                  (event.shiftKey && event.keyCode !== key.spacebar);
318    
319    // do nothing if user is editing text
320    // or using a modifier key (except shift)
321    // or in a dropdown
322    if ( /input|textarea|select|embed/i.test(target.nodeName) ||
323         target.isContentEditable || 
324         event.defaultPrevented   ||
325         modifier ) {
326      return true;
327    }
328    // spacebar should trigger button press
329    if (isNodeName(target, "button") &&
330        event.keyCode === key.spacebar) {
331      return true;
332    }
333    
334    var shift, x = 0, y = 0;
335    var elem = overflowingAncestor(activeElement);
336    var clientHeight = elem.clientHeight;
337
338    if (elem == document.body) {
339        clientHeight = window.innerHeight;
340    }
341
342    switch (event.keyCode) {
343        case key.up:
344            y = -options.arrowScroll;
345            break;
346        case key.down:
347            y = options.arrowScroll;
348            break;         
349        case key.spacebar: // (+ shift)
350            shift = event.shiftKey ? 1 : -1;
351            y = -shift * clientHeight * 0.9;
352            break;
353        case key.pageup:
354            y = -clientHeight * 0.9;
355            break;
356        case key.pagedown:
357            y = clientHeight * 0.9;
358            break;
359        case key.home:
360            y = -elem.scrollTop;
361            break;
362        case key.end:
363            var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
364            y = (damt > 0) ? damt+10 : 0;
365            break;
366        case key.left:
367            x = -options.arrowScroll;
368            break;
369        case key.right:
370            x = options.arrowScroll;
371            break;            
372        default:
373            return true; // a key we don't care about
374    }
375
376    scrollArray(elem, x, y);
377    event.preventDefault();
378}
379
380/**
381 * Mousedown event only for updating activeElement
382 */
383function mousedown(event) {
384    activeElement = event.target;
385}
386
387
388/***********************************************
389 * OVERFLOW
390 ***********************************************/
391 
392var cache = {}; // cleared out every once in while
393setInterval(function () { cache = {}; }, 10 * 1000);
394
395var uniqueID = (function () {
396    var i = 0;
397    return function (el) {
398        return el.uniqueID || (el.uniqueID = i++);
399    };
400})();
401
402function setCache(elems, overflowing) {
403    for (var i = elems.length; i--;)
404        cache[uniqueID(elems[i])] = overflowing;
405    return overflowing;
406}
407
408function overflowingAncestor(el) {
409    var elems = [];
410    var rootScrollHeight = root.scrollHeight;
411    do {
412        var cached = cache[uniqueID(el)];
413        if (cached) {
414            return setCache(elems, cached);
415        }
416        elems.push(el);
417        if (rootScrollHeight === el.scrollHeight) {
418            if (!isFrame || root.clientHeight + 10 < rootScrollHeight) {
419                return setCache(elems, document.body); // scrolling root in WebKit
420            }
421        } else if (el.clientHeight + 10 < el.scrollHeight) {
422            overflow = getComputedStyle(el, "").getPropertyValue("overflow-y");
423            if (overflow === "scroll" || overflow === "auto") {
424                return setCache(elems, el);
425            }
426        }
427    } while (el = el.parentNode);
428}
429
430
431/***********************************************
432 * HELPERS
433 ***********************************************/
434
435function addEvent(type, fn, bubble) {
436    window.addEventListener(type, fn, (bubble||false));
437}
438
439function removeEvent(type, fn, bubble) {
440    window.removeEventListener(type, fn, (bubble||false));  
441}
442
443function isNodeName(el, tag) {
444    return (el.nodeName||"").toLowerCase() === tag.toLowerCase();
445}
446
447function directionCheck(x, y) {
448    x = (x > 0) ? 1 : -1;
449    y = (y > 0) ? 1 : -1;
450    if (direction.x !== x || direction.y !== y) {
451        direction.x = x;
452        direction.y = y;
453        que = [];
454        lastScroll = 0;
455    }
456}
457
458var deltaBufferTimer;
459
460function isTouchpad(deltaY) {
461    if (!deltaY) return;
462    deltaY = Math.abs(deltaY)
463    deltaBuffer.push(deltaY);
464    deltaBuffer.shift();
465    clearTimeout(deltaBufferTimer);
466    var allDivisable = (isDivisible(deltaBuffer[0], 120) &&
467                        isDivisible(deltaBuffer[1], 120) &&
468                        isDivisible(deltaBuffer[2], 120));
469    return !allDivisable;
470} 
471
472function isDivisible(n, divisor) {
473    return (Math.floor(n / divisor) == n / divisor);
474}
475
476var requestFrame = (function () {
477      return  window.requestAnimationFrame       || 
478              window.webkitRequestAnimationFrame || 
479              function (callback, element, delay) {
480                  window.setTimeout(callback, delay || (1000/60));
481              };
482})();
483
484
485/***********************************************
486 * PULSE
487 ***********************************************/
488 
489/**
490 * Viscous fluid with a pulse for part and decay for the rest.
491 * - Applies a fixed force over an interval (a damped acceleration), and
492 * - Lets the exponential bleed away the velocity over a longer interval
493 * - Michael Herf, http://stereopsis.com/stopping/
494 */
495function pulse_(x) {
496    var val, start, expx;
497    // test
498    x = x * options.pulseScale;
499    if (x < 1) { // acceleartion
500        val = x - (1 - Math.exp(-x));
501    } else {     // tail
502        // the previous animation ended here:
503        start = Math.exp(-1);
504        // simple viscous drag
505        x -= 1;
506        expx = 1 - Math.exp(-x);
507        val = start + (expx * (1 - start));
508    }
509    return val * options.pulseNormalize;
510}
511
512function pulse(x) {
513    if (x >= 1) return 1;
514    if (x <= 0) return 0;
515
516    if (options.pulseNormalize == 1) {
517        options.pulseNormalize /= pulse_(1);
518    }
519    return pulse_(x);
520}
521
522var isChrome = /chrome/i.test(window.navigator.userAgent);
523var wheelEvent = null;
524if ("onwheel" in document.createElement("div"))
525	wheelEvent = "wheel";
526else if ("onmousewheel" in document.createElement("div"))
527	wheelEvent = "mousewheel";
528
529if (wheelEvent && isChrome) {
530	addEvent(wheelEvent, wheel);
531	addEvent("mousedown", mousedown);
532	addEvent("load", init);
533}
534
535})();

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.