mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 17:59:55 +02:00
184 lines
5.1 KiB
JavaScript
184 lines
5.1 KiB
JavaScript
// history
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
window,
|
|
require('./core'),
|
|
require('fizzy-ui-utils'),
|
|
);
|
|
} else {
|
|
// browser global
|
|
factory(
|
|
window,
|
|
window.InfiniteScroll,
|
|
window.fizzyUIUtils,
|
|
);
|
|
}
|
|
|
|
}( window, function factory( window, InfiniteScroll, utils ) {
|
|
|
|
let proto = InfiniteScroll.prototype;
|
|
|
|
Object.assign( InfiniteScroll.defaults, {
|
|
history: 'replace',
|
|
// historyTitle: false,
|
|
} );
|
|
|
|
let link = document.createElement('a');
|
|
|
|
// ----- create/destroy ----- //
|
|
|
|
InfiniteScroll.create.history = function() {
|
|
if ( !this.options.history ) return;
|
|
|
|
// check for same origin
|
|
link.href = this.getAbsolutePath();
|
|
// MS Edge does not have origin on link
|
|
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12236493/
|
|
let linkOrigin = link.origin || link.protocol + '//' + link.host;
|
|
let isSameOrigin = linkOrigin == location.origin;
|
|
if ( !isSameOrigin ) {
|
|
console.error( '[InfiniteScroll] cannot set history with different origin: ' +
|
|
`${link.origin} on ${location.origin} . History behavior disabled.` );
|
|
return;
|
|
}
|
|
|
|
// two ways to handle changing history
|
|
if ( this.options.append ) {
|
|
this.createHistoryAppend();
|
|
} else {
|
|
this.createHistoryPageLoad();
|
|
}
|
|
};
|
|
|
|
proto.createHistoryAppend = function() {
|
|
this.updateMeasurements();
|
|
this.updateScroller();
|
|
// array of scroll positions of appended pages
|
|
this.scrollPages = [
|
|
// first page
|
|
{
|
|
top: 0,
|
|
path: location.href,
|
|
title: document.title,
|
|
},
|
|
];
|
|
this.scrollPage = this.scrollPages[0];
|
|
// events
|
|
this.scrollHistoryHandler = this.onScrollHistory.bind( this );
|
|
this.unloadHandler = this.onUnload.bind( this );
|
|
this.scroller.addEventListener( 'scroll', this.scrollHistoryHandler );
|
|
this.on( 'append', this.onAppendHistory );
|
|
this.bindHistoryAppendEvents( true );
|
|
};
|
|
|
|
proto.bindHistoryAppendEvents = function( isBind ) {
|
|
let addRemove = isBind ? 'addEventListener' : 'removeEventListener';
|
|
this.scroller[ addRemove ]( 'scroll', this.scrollHistoryHandler );
|
|
window[ addRemove ]( 'unload', this.unloadHandler );
|
|
};
|
|
|
|
proto.createHistoryPageLoad = function() {
|
|
this.on( 'load', this.onPageLoadHistory );
|
|
};
|
|
|
|
InfiniteScroll.destroy.history =
|
|
proto.destroyHistory = function() {
|
|
let isHistoryAppend = this.options.history && this.options.append;
|
|
if ( isHistoryAppend ) {
|
|
this.bindHistoryAppendEvents( false );
|
|
}
|
|
};
|
|
|
|
// ----- append history ----- //
|
|
|
|
proto.onAppendHistory = function( response, path, items ) {
|
|
// do not proceed if no items. #779
|
|
if ( !items || !items.length ) return;
|
|
|
|
let firstItem = items[0];
|
|
let elemScrollY = this.getElementScrollY( firstItem );
|
|
// resolve path
|
|
link.href = path;
|
|
// add page data to hash
|
|
this.scrollPages.push({
|
|
top: elemScrollY,
|
|
path: link.href,
|
|
title: response.title,
|
|
});
|
|
};
|
|
|
|
proto.getElementScrollY = function( elem ) {
|
|
if ( this.options.elementScroll ) {
|
|
return elem.offsetTop - this.top;
|
|
} else {
|
|
let rect = elem.getBoundingClientRect();
|
|
return rect.top + window.scrollY;
|
|
}
|
|
};
|
|
|
|
proto.onScrollHistory = function() {
|
|
// cycle through positions, find biggest without going over
|
|
let scrollPage = this.getClosestScrollPage();
|
|
// set history if changed
|
|
if ( scrollPage != this.scrollPage ) {
|
|
this.scrollPage = scrollPage;
|
|
this.setHistory( scrollPage.title, scrollPage.path );
|
|
}
|
|
};
|
|
|
|
utils.debounceMethod( InfiniteScroll, 'onScrollHistory', 150 );
|
|
|
|
proto.getClosestScrollPage = function() {
|
|
let scrollViewY;
|
|
if ( this.options.elementScroll ) {
|
|
scrollViewY = this.scroller.scrollTop + this.scroller.clientHeight / 2;
|
|
} else {
|
|
scrollViewY = window.scrollY + this.windowHeight / 2;
|
|
}
|
|
|
|
let scrollPage;
|
|
for ( let page of this.scrollPages ) {
|
|
if ( page.top >= scrollViewY ) break;
|
|
|
|
scrollPage = page;
|
|
}
|
|
return scrollPage;
|
|
};
|
|
|
|
proto.setHistory = function( title, path ) {
|
|
let optHistory = this.options.history;
|
|
let historyMethod = optHistory && history[ optHistory + 'State' ];
|
|
if ( !historyMethod ) return;
|
|
|
|
history[ optHistory + 'State' ]( null, title, path );
|
|
if ( this.options.historyTitle ) document.title = title;
|
|
this.dispatchEvent( 'history', null, [ title, path ] );
|
|
};
|
|
|
|
// scroll to top to prevent initial scroll-reset after page refresh
|
|
// https://stackoverflow.com/a/18633915/182183
|
|
proto.onUnload = function() {
|
|
if ( this.scrollPage.top === 0 ) return;
|
|
|
|
// calculate where scroll position would be on refresh
|
|
let scrollY = window.scrollY - this.scrollPage.top + this.top;
|
|
// disable scroll event before setting scroll #679
|
|
this.destroyHistory();
|
|
scrollTo( 0, scrollY );
|
|
};
|
|
|
|
// ----- load history ----- //
|
|
|
|
// update URL
|
|
proto.onPageLoadHistory = function( response, path ) {
|
|
this.setHistory( response.title, path );
|
|
};
|
|
|
|
// -------------------------- -------------------------- //
|
|
|
|
return InfiniteScroll;
|
|
|
|
} ) );
|