|
@@ -0,0 +1,192 @@
|
|
|
+( 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 );
|