Created
October 14, 2014 16:10
-
-
Save 0b10011/dfd74cb0aed4b144b3c7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*jslint nomen: true */ | |
/*global $, ga, findAll, FB, HTMLFormElement */ | |
/*jslint nomen: false */ | |
(function () { | |
"use strict"; | |
if (!$.support.pjax) { | |
// If PJAX isn't supported, there is no need to run this code | |
return; | |
} | |
$.pjax.cancel = function () { | |
var xhr = $.pjax.xhr; | |
if (xhr && xhr.readyState < 4) { | |
xhr.onreadystatechange = $.noop; | |
xhr.abort(); | |
} | |
}; | |
// Use PJAX to load regular links | |
$(document).pjax('a:not([download]):not([data-ignore-pjax])', '#pjax-container', { | |
timeout: 2000 // A bit of a cushion for long-loading pages | |
}); | |
$(document).on('pjax:click', function (event, options) { | |
// Blur focused element asap to avoid header position flickering | |
$(':focus').blur(); | |
var target = $(event.target); | |
options.append = target.data("pjax-append"); | |
if (target.data("pjax-remove")) { | |
target.remove(); | |
} | |
}); | |
// Use PJAX to submit forms | |
$(document).on('submit', 'form', function (event) { | |
// Blur focused element asap to avoid header position flickering | |
// (Isn't always the event target. Sometimes it's an input.) | |
$(':focus').blur(); | |
$.pjax.submit(event, '#pjax-container', { | |
xhr: function () { | |
var progressBar = $('#pjax-loading-progress'), | |
progressHeader = $('#pjax-loading-progress-header'), | |
xhr = $.ajaxSettings.xhr(), | |
downloading = false; | |
progressBar.removeAttr("value"); | |
function updateProgress(type, progress) { | |
progressHeader.text(type + "..."); | |
if (progress === null || progress >= 100) { | |
progressBar.removeAttr("value"); | |
return; | |
} | |
progressBar.attr("value", progress); | |
progressBar.text(progress + "%"); | |
} | |
// Load progress | |
xhr.onprogress = function (event) { | |
downloading = true; | |
var progress = null; | |
if (event.lengthComputable) { | |
progress = event.loaded / event.total * 100; | |
} | |
updateProgress("Loading", progress); | |
}; | |
xhr.onloadend = function () { | |
downloading = true; | |
updateProgress("Loading", null); | |
}; | |
// Upload progress | |
xhr.upload.onprogress = function (event) { | |
if (downloading) { | |
return; | |
} | |
var progress = null; | |
if (event.lengthComputable) { | |
progress = event.loaded / event.total * 100; | |
} | |
updateProgress("Uploading", progress); | |
}; | |
xhr.upload.onloadend = function () { | |
if (downloading) { | |
return; | |
} | |
updateProgress("Uploading", null); | |
}; | |
// Return the customized object | |
return xhr; | |
} | |
}); | |
}); | |
// Request sent | |
$(document).on('pjax:send', function (event, xhr, options) { | |
// Add loading class | |
$('body').addClass('pjax-loading'); | |
// Set href for retry link | |
$('#pjax-loading-timeout-retry').attr('href', options.url); | |
}); | |
// Request complete (error or success) | |
$(document).on('pjax:complete', function () { | |
// Remove loading and timeout classes | |
$('body').removeClass('pjax-loading pjax-timeout'); | |
// Remove href from retry link | |
$('#pjax-loading-timeout-retry').attr('href', '#'); | |
}); | |
function extractNodes(container, updateBodyClass) { | |
var selector, nav, navCurrentText; | |
// Update account menu | |
selector = '#primary-nav-account'; | |
// Update existing | |
$(selector).html(findAll(container.contents, selector).last().html()); | |
// Remove node (should be top level) | |
container.contents = container.contents.not(selector); | |
// Update existing | |
nav = container.contents.filter('#primary-nav'); | |
navCurrentText = nav.find('.primary-nav-current').text(); | |
$('#primary-nav, #primary-nav-mobile').find('ul > li > a').each(function () { | |
if ($(this).text() === navCurrentText) { | |
$(this).addClass('primary-nav-current'); | |
} else { | |
$(this).removeClass('primary-nav-current'); | |
} | |
}); | |
// Remove node (should be top level) | |
container.contents = container.contents.not('#primary-nav'); | |
// Update body-inner class | |
if (updateBodyClass !== false) { | |
$('#body-inner').attr("class", findAll(container.contents, '#body-inner').last().attr("class")); | |
} | |
// Remove node (should be top level) | |
container.contents = container.contents.not('#body-inner'); | |
} | |
// Request successful - Alter response | |
$(document).on('pjax:beforeSuccess', function (event, container, status, xhr, options) { | |
extractNodes(container, !options.append); | |
}); | |
// Request successful (before inline scripts are inserted, after title is set) | |
$(document).on('pjax:beforeHtml', function () { | |
// Track pageview for Google Analytics | |
ga('send', 'pageview', "/" + window.location.pathname); | |
}); | |
// Request successful | |
$(document).on('pjax:success', function () { | |
// Parse Facebook comments box | |
if (typeof FB !== 'undefined') { | |
FB.XFBML.parse(); | |
} | |
}); | |
// Request timeout | |
$(document).on('pjax:timeout', function (event) { | |
// Add timeout class | |
$('body').addClass('pjax-timeout'); | |
// Prevent default timeout handling | |
event.preventDefault(); | |
}); | |
// Request error | |
$(document).on('pjax:error', function (event, xhr, textStatus, errorThrown, options) { | |
// Links and forms | |
switch (xhr.status) { | |
case 404: // Not found | |
case 410: // Gone | |
// Not 200, but should still display response as if it were | |
// | |
// Fake a successful request | |
options.success(xhr.responseText, textStatus, xhr); | |
// Cancel default behavior | |
return false; | |
} | |
// If a normal link, try loading it without PJAX | |
if (!$(event.relatedTarget).is("form")) { | |
return; | |
} | |
// Forms only | |
switch (xhr.status) { | |
case 412: | |
// Outdated code on client, submit request again normally | |
// | |
// Disable pjax | |
$.pjax.disable(); | |
// Turn off event handlers | |
$(document).off('submit', 'form'); | |
// Don't double submit "../" | |
$(event.relatedTarget).attr("action", window.location.href); | |
// Submit form | |
// This is an ugly hack to workaround submit buttons without a name that | |
// automatically take the name 'submit', thereby breaking form.submit(). | |
HTMLFormElement.prototype.submit.call(event.relatedTarget); | |
// Cancel default behavior | |
return false; | |
case 500: | |
// Server error, probably too large of an upload | |
// | |
// Alert the user so they can try submitting the form again manually | |
window.alert("Our server couldn't fully handle your request. If you " + | |
"are trying to upload a file, please make sure it is within " + | |
"the size requirements listed. If you continue to run into " + | |
"issues, give us a call at 231.933.3699 and we'll help you " + | |
"out."); | |
return; | |
} | |
}); | |
function findAll(elems, selector) { | |
return elems.filter(selector).add(elems.find(selector)); | |
} | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment