var fixConfig = {
baseURI: 'http://localhost/mwc2013/wp-fix/',
pageURI: 'page/',
// Should match the starting page URL of your inf scroll experience, but not an inner page (eg page2)
homePattern: new RegExp('mwc2013/wp-fix/$'),
// Needs to extract the page number we landed on when we loaded up this script
getCurrentPage: function () {
var matches = window.location.href.match(/page\/(\d*)/);
if (matches && matches.length == 2) {
return matches[1];
}
return '1';
},
_pageBoundaries: [],
_end: false,
_recoveryURL: false,
// Firefox and Chrome don't fire onpopstate the same way
// Firefox/Safari actually DO remember the manipulated DOM when you hit the back button sometimes
// _prevURL: window.location.href.replace(/#.*$/, '')
_prevURL: false
};
if (window.history) {
window.addEventListener('popstate', function (e) {
console.log('popstate', e, history.state);
if (!navigator.userAgent.match(/Chrome/)) {
if (window.location.href.match(fixConfig.homePattern)) {
setTimeout(function () {window.scrollTo(0, 1);}, 0);
}
return;
}
//
// Ok, attempt to address the fact that Chrome does not restore the manipulated DOM of the page you are going back to... it only remembers the scroll position.
//
// Look for changes to only the #hash
var url = window.location.href.replace(/#.*$/, '');
console.log(url, fixConfig._prevURL);
if (fixConfig._prevURL === false) {
var $backPost,
scrollTop = 1;
if (window.localStorage.back_scroll_top && !window.location.href.match(fixConfig.homePattern)) {
console.log('back_scroll_top ' + window.localStorage.back_scroll_top);///
scrollTop = window.localStorage.back_scroll_top - 100;
}
console.log('back post? ' + scrollTop);///
setTimeout(function () {window.scrollTo(0, scrollTop);}, 0);
} else if (url != fixConfig._prevURL) {
setTimeout(function () {window.scrollTo(0, 1);}, 0);
setTimeout(function () {window.location.reload();}, 1);
}
fixConfig._prevURL = url;
}, false);
/*
window.addEventListener('pageshow', function (e) {
console.log('pageshow', e);
}, false);
window.addEventListener('pagehide', function (e) {
console.log('pagehide', e);
}, false);
*/
}
$(function () {
console.log(new Date());
// http://infinite-scroll.com/
// https://github.com/paulirish/infinite-scroll
$('#content').infinitescroll(
{
// debug: true,
loading : {
img : '/mwc2013/wp-fix/wp-content/themes/mwc2013/css/images/ajax-loader.gif',
msgText : 'Loading Next Page...',
finishedMsg : '
The End!
'
},
// We must set the current page if we want to support starting at a deep link, or when you scroll down on page 14, inf scroll will load page 2 instead of page 15
state : {
currPage : fixConfig.getCurrentPage()
},
bufferPx: 400,
nextSelector : '.nav-previous a',
navSelector : '.navigation',
itemSelector : '.post',
// contentSelector : ' .inner',
// Needed so inf scroll doesn't replace the 2 or the 3 in 2013 with the current page
// This is an issue specific to THIS particular site's URL structure.
///pathParse : function () {return ['/mwc2013/wp-fix/page/', '']},
path: ['/mwc2013/wp-fix/page/', ''],
errorCallback: function () {
var instance = $('#content').data('infinitescroll');
// console.log('errorCallback!', arguments, instance.options.state, fixConfig._recoveryURL);
}
},
// Success
function (elements, data, url) {
if (window.history) {
// We want to give people the ability to hit back to return to home so they can more easily reload for new content at the top of the infinite scroll experience
if (window.location.href.match(fixConfig.homePattern)) {
history.pushState('', '', url);
} else {
history.replaceState('', '', url);
}
fixConfig._prevURL = url;
}
}
);
function applyFix() {
var instance = $('#content').data('infinitescroll'),
proxyRetreive = instance.retrieve,
proxyLoadCallback = instance._loadcallback,
proxyError = instance._error;
// If the page we loaded has a next page link, then we expect that it will load!
if ($(instance.options.nextSelector).length) {
fixConfig._recoveryURL = window.location.href;
}
function replacePageURLFromScroll(scrollTop, modified) {
var url,
i = 1;
if (!window.history) {
return;
}
if (!window.location.href.match(fixConfig.homePattern)) {
window.localStorage.back_scroll_top = modified ? instance.options.binder.scrollTop() : scrollTop;
console.log('--');
console.log(window.localStorage.back_scroll_top);
}
while (i < fixConfig._pageBoundaries.length) {
console.log(i, scrollTop, scrollTop < fixConfig._pageBoundaries[i]);
// What page are we scrolled to? Any scroll position past the 2nd to last page should match for the last page. That way if the user scrolls to the very bottom of the site, it'll match for the last page.
if (scrollTop < fixConfig._pageBoundaries[i] || i == fixConfig._pageBoundaries.length - 1) {
url = fixConfig.baseURI + (i <= 1 ? '' : fixConfig.pageURI + i);
history.replaceState('', '', url);
if (i > 0 && !window.location.href.match(fixConfig.homePattern)) {
window.localStorage.back_scroll_top -= fixConfig._pageBoundaries[i - 1];
console.log(window.localStorage.back_scroll_top);
}
return;
}
i++;
}
return false;
}
instance.options.binder.on('smartscroll', function () {
replacePageURLFromScroll(instance.options.binder.scrollTop() + $(window).height(), true);
});
instance._loadcallback = function (box, data, url) {
console.log('_loadcallback', this.options.state.currPage);
var $lastItem = $(instance.options.itemSelector).last();
// We are adding a page, so set the boundary of the previous page to where ever its last item ends
fixConfig._pageBoundaries[this.options.state.currPage - 1] = $lastItem.offset().top + $lastItem.outerHeight();
// We are adding a page, so set the boundary of the new page (not added yet) to some value so that it becomes the new last page boundary for the purposes of the replacePageURLFromScroll() function. (Previously, I set this to 9999999 as an improbably large value, but that's no longer necessary.)
// Note that this code gets fired even in the case of a 404 (ie we tried to load another page but we already reached the end of the content), so we'll pop this boundary in the error callback.
fixConfig._pageBoundaries[this.options.state.currPage] = true;
// URL we will offer to try again if there is a loading failure
fixConfig._recoveryURL = url;
// This is a bit wasteful since box is already a collection of content/post DOM nodes
// Ideally inf scroll would already be looking for the nav in the ajax data
$data = $(data);
if ($data.find(this.options.nextSelector).length == 0) {
if (fixConfig._end) {
fixConfig._recoveryURL = false;
}
// Since we didn't find a link to the next page, that means we had an error loading this page or we've loaded the last page (and thus it has no next page link)... either way, we expect that if we try to request a page beyond this it will fail. That is an expected failure rather than an error failure, so in that case we would not provide a recovery URL.
fixConfig._end = true;
}
$('a.inf_retry').parent().remove();
return proxyLoadCallback.apply(this, arguments);
};
instance._error = function () {
// We added a boundary for a page that never was added, so pop it
fixConfig._pageBoundaries.pop();
if (fixConfig._recoveryURL) {
fixConfig._end = false;
$('#infscr-loading').remove();
$(this.options.contentSelector).append('Drat! An error! Try Again
');
var self = this;
$('.inf_retry').click(function (e) {
e.preventDefault();
self.options.state.currPage--;
self.beginAjax(self.options);
});
return;
}
return proxyError.apply(this, arguments);
};
$(instance.options.contentSelector).on('click', instance.options.itemSelector + ' a', function (e) {
var $article = $(this).parents('article');
// The user might click a link from the previous page, so make sure to adjust the URL state to the previous page if that is the case for better back button behavior
replacePageURLFromScroll($article.offset().top);
});
}
if ($('#content').data('infinitescroll')) {
applyFix();
}
});