1/*! 2 * $.fn.scrollIntoView - similar to the default browser scrollIntoView 3 * The default browser behavior always places the element at the top or bottom of its container. 4 * This override is smart enough to not scroll if the element is already visible. 5 * 6 * Copyright 2011 Arwid Bancewicz 7 * Licensed under the MIT license 8 * http://www.opensource.org/licenses/mit-license.php 9 * 10 * @date 8 Jan 2013 11 * @author Arwid Bancewicz http://arwid.ca 12 * @version 0.3 13 */ 14 (function($) { 15 $.fn.scrollIntoView = function(duration, easing, complete) { 16 // The arguments are optional. 17 // The first argment can be false for no animation or a duration. 18 // The first argment could also be a map of options. 19 // Refer to http://api.jquery.com/animate/. 20 var opts = $.extend({}, 21 $.fn.scrollIntoView.defaults); 22 23 // Get options 24 if ($.type(duration) == "object") { 25 $.extend(opts, duration); 26 } else if ($.type(duration) == "number") { 27 $.extend(opts, { duration: duration, easing: easing, complete: complete }); 28 } else if (duration == false) { 29 opts.smooth = false; 30 } 31 32 // get enclosing offsets 33 var elY = Infinity, elH = 0; 34 if (this.size()==1)((elY=this.get(0).offsetTop)==null||(elH=elY+this.get(0).offsetHeight)); 35 else this.each(function(i,el){(el.offsetTop<elY?elY=el.offsetTop:el.offsetTop+el.offsetHeight>elH?elH=el.offsetTop+el.offsetHeight:null)}); 36 elH -= elY; 37 38 // start from the common ancester 39 var pEl = this.commonAncestor().get(0); 40 41 var wH = $(window).height(); 42 43 // go up parents until we find one that scrolls 44 while (pEl) { 45 var pY = pEl.scrollTop, pH = pEl.clientHeight; 46 if (pH > wH) pH = wH; 47 48 // case: if body's elements are all absolutely/fixed positioned, use window height 49 if (pH == 0 && pEl.tagName == "BODY") pH = wH; 50 51 if ( 52 // it wiggles? 53 (pEl.scrollTop != ((pEl.scrollTop += 1) == null || pEl.scrollTop) && (pEl.scrollTop -= 1) != null) || 54 (pEl.scrollTop != ((pEl.scrollTop -= 1) == null || pEl.scrollTop) && (pEl.scrollTop += 1) != null)) { 55 if (elY <= pY) scrollTo(pEl, elY); // scroll up 56 else if ((elY + elH) > (pY + pH)) scrollTo(pEl, elY + elH - pH); // scroll down 57 else scrollTo(pEl, undefined) // no scroll 58 return; 59 } 60 61 // try next parent 62 pEl = pEl.parentNode; 63 } 64 65 function scrollTo(el, scrollTo) { 66 if (el.tagName=="BODY" || el.tagName=="HTML") { 67 // Hyperion customisation to prevent it scrolling the entire body just 68 // because the audio player hasn't quite painted yet so doesn't seem to 69 // be scrollable. 70 } else { 71 if (scrollTo === undefined) { 72 if ($.isFunction(opts.complete)) opts.complete.call(el); 73 } else if (opts.smooth) { 74 $(el).stop().animate({ scrollTop: scrollTo }, opts); 75 } else { 76 el.scrollTop = scrollTo; 77 if ($.isFunction(opts.complete)) opts.complete.call(el); 78 } } 79 } 80 return this; 81 }; 82 83 $.fn.scrollIntoView.defaults = { 84 smooth: true, 85 duration: null, 86 easing: $.easing && $.easing.easeOutExpo ? 'easeOutExpo': null, 87 // Note: easeOutExpo requires jquery.effects.core.js 88 // otherwise jQuery will default to use 'swing' 89 complete: $.noop(), 90 step: null, 91 specialEasing: {} // cannot be null in jQuery 1.8.3 92 }; 93 94 /* 95 Returns whether the elements are in view 96 */ 97 $.fn.isOutOfView = function(completely) { 98 // completely? whether element is out of view completely 99 var outOfView = true; 100 this.each(function() { 101 var pEl = this.parentNode, pY = pEl.scrollTop, pH = pEl.clientHeight, elY = this.offsetTop, elH = this.offsetHeight; 102 if (completely ? (elY) > (pY + pH) : (elY + elH) > (pY + pH)) {} 103 else if (completely ? (elY + elH) < pY: elY < pY) {} 104 else outOfView = false; 105 }); 106 return outOfView; 107 }; 108 109 /* 110 Returns the common ancestor of the elements. 111 It was taken from http://stackoverflow.com/questions/3217147/jquery-first-parent-containing-all-children 112 It has received minimal testing. 113 */ 114 $.fn.commonAncestor = function() { 115 var parents = []; 116 var minlen = Infinity; 117 118 $(this).each(function() { 119 var curparents = $(this).parents(); 120 parents.push(curparents); 121 minlen = Math.min(minlen, curparents.length); 122 }); 123 124 for (var i = 0; i < parents.length; i++) { 125 parents[i] = parents[i].slice(parents[i].length - minlen); 126 } 127 128 // Iterate until equality is found 129 for (var i = 0; i < parents[0].length; i++) { 130 var equal = true; 131 for (var j in parents) { 132 if (parents[j][i] != parents[0][i]) { 133 equal = false; 134 break; 135 } 136 } 137 if (equal) return $(parents[0][i]); 138 } 139 return $([]); 140 } 141 142})(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.