PageSourceSearch

https://julietroha.com/wp-content/themes/tower/js/smoothscroll.js?ver=1

js julietroha.com collected 2026-10-10 01:58:28 UTC 15,964 bytes, 600 lines download raw bytes

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

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.