123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- ( function( $, Backbone, _, settings, undefined ) {
- 'use strict';
- var document = window.document;
- var $postContainer = $( document.getElementById( 'main' ) );
- var moreButtonTemplate = document.getElementById( 'more-button-template' );
- var contentTemplate = document.getElementById( 'content-template' );
- // Abort completely if we don't have this stuff
- if ( ! $postContainer || ! moreButtonTemplate || ! contentTemplate ) {
- return false;
- }
- var $moreButton = $( _.template( moreButtonTemplate.innerHTML )() );
- var postTemplate = _.template( contentTemplate.innerHTML );
- var origURL = window.location.href;
- var offset = 1;
- var page = 1;
- var timer;
- var posts = new wp.api.collections.Posts();
- var options = {
- data: {
- page: settings.page || 2
- }
- };
- if ( 'archive' === settings.loopType ) {
- options.data.filter = {};
- options.data.filter[settings.taxonomy['query_var']] = settings.queriedObject.slug;
- } else if ( 'search' === settings.loopType ) {
- options.data.filter = {
- s: settings.searchQuery
- };
- } else if ( 'author' === settings.loopType ) {
- options.data.filter = {
- author: settings.queriedObject.data.ID
- };
- }
- /**
- * Update current url using HTML5 history API
- *
- * @param {Number} pageNum
- */
- function updateURL( pageNum ) {
- var offset = offset > 0 ? offset - 1 : 0;
- var pageSlug = ( -1 === pageNum ) ? origURL : window.location.protocol + '//' + settings.pathInfo.host + settings.pathInfo.path.replace( /%d/, pageNum + offset ) + settings.pathInfo.parameters;
- if ( window.location.href !== pageSlug ) {
- history.pushState( null, null, pageSlug );
- }
- }
- /**
- * Determine URL for pushing new history. Props to Automattic's Jetpack plugin
- * for much of this code.
- */
- function determineURL() {
- var windowTop = $( window ).scrollTop();
- var windowBottom = windowTop + $( window ).height();
- var windowSize = $( window ).height();
- var setsInView = [];
- var pageNum = false;
- $postContainer.find( '.post-set' ).each( function() {
- var $currentSet = $( this );
- var setTop = $currentSet.offset().top;
- var setHeight = $currentSet.outerHeight( false );
- var setBottom = setTop + setHeight;
- var setPageNum = parseInt( $currentSet.attr( 'data-page-num' ) );
- if ( 0 === setHeight ) {
- $( '> *', this ).each( function() {
- setHeight += $currentSet.outerHeight( false );
- });
- }
- if ( setTop < windowTop && setBottom > windowBottom ) { // top of set is above window, bottom is below
- setsInView.push( { 'id': $currentSet.attr( 'id' ), 'top': setTop, 'bottom': setBottom, 'pageNum': setPageNum } );
- } else if( setTop > windowTop && setTop < windowBottom ) { // top of set is between top (gt) and bottom (lt)
- setsInView.push( { 'id': $currentSet.attr( 'id' ), 'top': setTop, 'bottom': setBottom, 'pageNum': setPageNum } );
- } else if( setBottom > windowTop && setBottom < windowBottom ) { // bottom of set is between top (gt) and bottom (lt)
- setsInView.push( { 'id': $currentSet.attr( 'id' ), 'top': setTop, 'bottom': setBottom, 'pageNum': setPageNum } );
- }
- });
- // Parse number of sets found in view in an attempt to update the URL to match the set that comprises the majority of the window.
- if ( 0 === setsInView.length ) {
- pageNum = -1;
- } else if ( 1 === setsInView.length ) {
- var setData = setsInView.pop();
- // If the first set of IS posts is in the same view as the posts loaded in the template by WordPress, determine how much of the view is comprised of IS-loaded posts
- if ( ( ( windowBottom - setData.top ) / windowSize ) < 0.5 ) {
- pageNum = -1;
- } else {
- pageNum = setData.pageNum;
- }
- } else {
- var majorityPercentageInView = 0;
- // Identify the IS set that comprises the majority of the current window and set the URL to it.
- $.each( setsInView, function( i, setData ) {
- var topInView = 0;
- var bottomInView = 0;
- var percentOfView = 0;
- // Figure percentage of view the current set represents
- if ( setData.top > windowTop && setData.top < windowBottom ) {
- topInView = ( windowBottom - setData.top ) / windowSize;
- }
- if ( setData.bottom > windowTop && setData.bottom < windowBottom ) {
- bottomInView = ( setData.bottom - windowTop ) / windowSize;
- }
- // Figure out largest percentage of view for current set
- if ( topInView >= bottomInView ) {
- percentOfView = topInView;
- } else if ( bottomInView >= topInView ) {
- percentOfView = bottomInView;
- }
- // Does current set's percentage of view supplant the largest previously-found set?
- if ( percentOfView > majorityPercentageInView ) {
- pageNum = setData.pageNum;
- majorityPercentageInView = percentOfView;
- }
- } );
- }
- // We do this last check in case something bad happened
- if ( 'number' == typeof pageNum ) {
- updateURL( pageNum );
- }
- }
- /**
- * Setup scroll listeners for changing history
- */
- function setupScrollListener() {
- $( window ).on( 'scroll', function() {
- clearTimeout( timer );
- timer = setTimeout( determineURL , 100 );
- });
- }
- /**
- * Grab more posts if more button is clicked and append them to loop
- */
- function setupMoreListener() {
- $postContainer.on( 'click', '.more-button', function( event ) {
- event.preventDefault();
- $moreButton.hide();
- var $setContainer = $( '<div data-page-num="' + posts.state.currentPage + '" class="post-set"></div>' );
- posts.each( function( model ) {
- $setContainer.append( postTemplate( { post: model.attributes, settings: settings } ) );
- });
- $postContainer.append( $setContainer );
- if ( posts.hasMore() ) {
- posts.more().done( function() {
- $moreButton.appendTo( $postContainer).show();
- } );
- }
- });
- };
- /**
- * Initial posts fetch
- */
- posts.fetch( options ).done( function() {
- if ( posts.length > 0 ) {
- $postContainer.append( $moreButton );
- setupMoreListener();
- setupScrollListener();
- }
- });
- })( jQuery, Backbone, _, settings );
|