1/** 2 * IAS History Extension 3 * An IAS extension to enable browser history 4 * http://infiniteajaxscroll.com 5 * 6 * This file is part of the Infinite AJAX Scroll package 7 * 8 * Copyright 2014-2017 Webcreate (Jeroen Fiege) 9 */ 10 11var IASHistoryExtension = function (options) { 12 options = jQuery.extend({}, this.defaults, options); 13 14 this.ias = null; 15 this.prevSelector = options.prev; 16 this.prevUrl = null; 17 this.listeners = { 18 prev: new IASCallbacks(jQuery) 19 }; 20 21 /** 22 * @private 23 * @param pageNum 24 * @param scrollOffset 25 * @param url 26 */ 27 this.onPageChange = function (pageNum, scrollOffset, url) { 28 if (!window.history || !window.history.replaceState) { 29 return; 30 } 31 32 var state = history.state; 33 34 history.replaceState(state, document.title, url); 35 }; 36 37 /** 38 * @private 39 * @param currentScrollOffset 40 * @param scrollThreshold 41 */ 42 this.onScroll = function (currentScrollOffset, scrollThreshold) { 43 var firstItemScrollThreshold = this.getScrollThresholdFirstItem(); 44 45 if (!this.prevUrl) { 46 return; 47 } 48 49 currentScrollOffset -= this.ias.$scrollContainer.height(); 50 51 if (currentScrollOffset <= firstItemScrollThreshold) { 52 this.prev(); 53 } 54 }; 55 56 this.onReady = function () { 57 var currentScrollOffset = this.ias.getCurrentScrollOffset(this.ias.$scrollContainer), 58 firstItemScrollThreshold = this.getScrollThresholdFirstItem(); 59 60 currentScrollOffset -= this.ias.$scrollContainer.height(); 61 62 if (currentScrollOffset <= firstItemScrollThreshold) { 63 this.prev(); 64 } 65 }; 66 67 /** 68 * Returns the url for the next page 69 * 70 * @private 71 */ 72 this.getPrevUrl = function (container) { 73 if (!container) { 74 container = this.ias.$container; 75 } 76 77 // always take the last matching item 78 return jQuery(this.prevSelector, container).last().attr('href'); 79 }; 80 81 /** 82 * Returns scroll threshold. This threshold marks the line from where 83 * IAS should start loading the next page. 84 * 85 * @private 86 * @return {number} 87 */ 88 this.getScrollThresholdFirstItem = function () { 89 var $firstElement; 90 91 $firstElement = this.ias.getFirstItem(); 92 93 // if the don't have a first element, the DOM might not have been loaded, 94 // or the selector is invalid 95 if (0 === $firstElement.length) { 96 return -1; 97 } 98 99 return ($firstElement.offset().top); 100 }; 101 102 /** 103 * Renders items 104 * 105 * @private 106 * @param items 107 * @param callback 108 */ 109 this.renderBefore = function (items, callback) { 110 var ias = this.ias, 111 $firstItem = ias.getFirstItem(), 112 count = 0; 113 114 ias.fire('render', [items]); 115 116 jQuery(items).hide(); // at first, hide it so we can fade it in later 117 118 $firstItem.before(items); 119 120 jQuery(items).fadeIn(400, function () { 121 if (++count < items.length) { 122 return; 123 } 124 125 ias.fire('rendered', [items]); 126 127 if (callback) { 128 callback(); 129 } 130 }); 131 }; 132 133 return this; 134}; 135 136/** 137 * @public 138 */ 139IASHistoryExtension.prototype.initialize = function (ias) { 140 var self = this; 141 142 this.ias = ias; 143 144 // expose the extensions listeners 145 jQuery.extend(ias.listeners, this.listeners); 146 147 // expose prev method 148 ias.prev = function() { 149 return self.prev(); 150 }; 151 152 this.prevUrl = this.getPrevUrl(); 153}; 154 155/** 156 * Bind to events 157 * 158 * @public 159 * @param ias 160 */ 161IASHistoryExtension.prototype.bind = function (ias) { 162 //ias.on('pageChange', jQuery.proxy(this.onPageChange, this)); 163 ias.on('scroll', jQuery.proxy(this.onScroll, this)); 164 ias.on('ready', jQuery.proxy(this.onReady, this)); 165}; 166 167/** 168 * @public 169 * @param {object} ias 170 */ 171IASHistoryExtension.prototype.unbind = function(ias) { 172 //ias.off('pageChange', this.onPageChange); 173 ias.off('scroll', this.onScroll); 174 ias.off('ready', this.onReady); 175}; 176 177/** 178 * Load the prev page 179 * 180 * @public 181 */ 182IASHistoryExtension.prototype.prev = function () { 183 var url = this.prevUrl, 184 self = this, 185 ias = this.ias; 186 187 if (!url) { 188 return false; 189 } 190 191 ias.pause(); 192 193 var promise = ias.fire('prev', [url]); 194 195 promise.done(function () { 196 ias.load(url, function (data, items) { 197 self.renderBefore(items, function () { 198 self.prevUrl = self.getPrevUrl(data); 199 200 ias.resume(); 201 202 if (self.prevUrl) { 203 self.prev(); 204 } 205 }); 206 }); 207 }); 208 209 promise.fail(function () { 210 ias.resume(); 211 }); 212 213 return true; 214}; 215 216/** 217 * @public 218 */ 219IASHistoryExtension.prototype.defaults = { 220 prev: ".prev" 221};
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.