Skip to content

Commit

Permalink
Merge pull request #74 from MarcosMenegazzo/master
Browse files Browse the repository at this point in the history
Updates pjax to 1.9.5
  • Loading branch information
route committed Apr 2, 2015
2 parents ece73ab + 2332ac4 commit c82d5a7
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 47 deletions.
4 changes: 2 additions & 2 deletions pjax_rails.gemspec
@@ -1,9 +1,9 @@
Gem::Specification.new do |s|
s.name = 'pjax_rails'
s.version = '0.4.0'
s.version = '0.5.0'
s.author = 'David Heinemeier Hansson (PJAX by Chris Wanstrath)'
s.email = 'david@loudthinking.com'
s.summary = 'PJAX integration for Rails 3.1+'
s.summary = 'PJAX integration for Rails 3.2+'
s.homepage = 'https://github.com/rails/pjax_rails'
s.license = 'MIT'

Expand Down
122 changes: 77 additions & 45 deletions vendor/assets/javascripts/jquery.pjax.js
Expand Up @@ -225,7 +225,9 @@ function pjax(options) {
settings.timeout = 0
}

options.requestUrl = parseURL(settings.url).href
var url = parseURL(settings.url)
if (hash) url.hash = hash
options.requestUrl = stripInternalParams(url.href)
}

options.complete = function(xhr, textStatus) {
Expand Down Expand Up @@ -259,6 +261,12 @@ function pjax(options) {

var container = extractContainer(data, xhr, options)

var url = parseURL(container.url)
if (hash) {
url.hash = hash
container.url = url.href
}

// If there is a layout version mismatch, hard load the new url
if (currentVersion && latestVersion && currentVersion !== latestVersion) {
locationReplace(container.url)
Expand Down Expand Up @@ -309,28 +317,17 @@ function pjax(options) {

executeScriptTags(container.scripts)

// Scroll to top by default
if (typeof options.scrollTo === 'number')
$(window).scrollTop(options.scrollTo)

// If the URL has a hash in it, make sure the browser
// knows to navigate to the hash.
if ( hash !== '' ) {
// Avoid using simple hash set here. Will add another history
// entry. Replace the url with replaceState and scroll to target
// by hand.
//
// window.location.hash = hash
var url = parseURL(container.url)
url.hash = hash

pjax.state.url = url.href
window.history.replaceState(pjax.state, container.title, url.href)
var scrollTo = options.scrollTo

var target = document.getElementById(url.hash.slice(1))
if (target) $(window).scrollTop($(target).offset().top)
// Ensure browser scrolls to the element referenced by the URL anchor
if (hash) {
var name = decodeURIComponent(hash.slice(1))
var target = document.getElementById(name) || document.getElementsByName(name)[0]
if (target) scrollTo = $(target).offset().top
}

if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)

fire('pjax:success', [data, status, xhr, options])
}

Expand All @@ -352,21 +349,17 @@ function pjax(options) {
}

// Cancel the current request if we're already pjaxing
var xhr = pjax.xhr
if ( xhr && xhr.readyState < 4) {
xhr.onreadystatechange = $.noop
xhr.abort()
}
abortXHR(pjax.xhr)

pjax.options = options
var xhr = pjax.xhr = $.ajax(options)

if (xhr.readyState > 0) {
if (options.push && !options.replace) {
// Cache current container element before replacing it
cachePush(pjax.state.id, context.clone().contents())
cachePush(pjax.state.id, cloneContents(context))

window.history.pushState(null, "", stripPjaxParam(options.requestUrl))
window.history.pushState(null, "", options.requestUrl)
}

fire('pjax:start', [xhr, options])
Expand Down Expand Up @@ -423,31 +416,39 @@ if ('state' in window.history) {
// You probably shouldn't use pjax on pages with other pushState
// stuff yet.
function onPjaxPopstate(event) {
var previousState = pjax.state;

// Hitting back or forward should override any pending PJAX request.
if (!initialPop) {
abortXHR(pjax.xhr)
}

var previousState = pjax.state
var state = event.state
var direction

if (state && state.container) {
// When coming forward from a separate history session, will get an
// initial pop with a state we are already at. Skip reloading the current
// page.
if (initialPop && initialURL == state.url) return

// If popping back to the same state, just skip.
// Could be clicking back from hashchange rather than a pushState.
if (pjax.state && pjax.state.id === state.id) return
if (previousState) {
// If popping back to the same state, just skip.
// Could be clicking back from hashchange rather than a pushState.
if (previousState.id === state.id) return

var container = $(state.container)
if (container.length) {
var direction, contents = cacheMapping[state.id]
// Since state IDs always increase, we can deduce the navigation direction
direction = previousState.id < state.id ? 'forward' : 'back'
}

if (pjax.state) {
// Since state ids always increase, we can deduce the history
// direction from the previous state.
direction = pjax.state.id < state.id ? 'forward' : 'back'
var cache = cacheMapping[state.id] || []
var container = $(cache[0] || state.container), contents = cache[1]

if (container.length) {
if (previousState) {
// Cache current container before replacement and inform the
// cache which direction the history shifted.
cachePop(direction, pjax.state.id, container.clone().contents())
cachePop(direction, previousState.id, cloneContents(container))
}

var popstateEvent = $.Event('pjax:popstate', {
Expand Down Expand Up @@ -521,7 +522,12 @@ function fallbackPjax(options) {
var pair = value.split('=')
form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
})
} else if ($.isArray(data)) {
$.each(data, function(index, value) {
form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
})
} else if (typeof data === 'object') {
var key
for (key in data)
form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
}
Expand All @@ -530,6 +536,15 @@ function fallbackPjax(options) {
form.submit()
}

// Internal: Abort an XmlHttpRequest if it hasn't been completed,
// also removing its event handlers.
function abortXHR(xhr) {
if ( xhr && xhr.readyState < 4) {
xhr.onreadystatechange = $.noop
xhr.abort()
}
}

// Internal: Generate unique id for state object.
//
// Use a timestamp instead of a counter since ids should still be
Expand All @@ -540,16 +555,32 @@ function uniqueId() {
return (new Date).getTime()
}

// Internal: Strips _pjax param from url
function cloneContents(container) {
var cloned = container.clone()
// Unmark script tags as already being eval'd so they can get executed again
// when restored from cache. HAXX: Uses jQuery internal method.
cloned.find('script').each(function(){
if (!this.src) jQuery._data(this, 'globalEval', false)
})
return [container.selector, cloned.contents()]
}

// Internal: Strips named query param from url
//
// url - String
//
// Returns String.
function stripPjaxParam(url) {
function stripParam(url, name) {
return url
.replace(new RegExp('[?&]' + name + '=[^&#]*'), '')
.replace(/[?&]($|#)/, '\1')
.replace(/[?&]/, '?')
}

function stripInternalParams(url) {
url = stripParam(url, '_pjax')
url = stripParam(url, '_')
return url
.replace(/\?_pjax=[^&]+&?/, '?')
.replace(/_pjax=[^&]+&?/, '')
.replace(/[\?&]$/, '')
}

// Internal: Parse URL components and returns a Locationish object.
Expand Down Expand Up @@ -665,7 +696,8 @@ function extractContainer(data, xhr, options) {

// Prefer X-PJAX-URL header if it was set, otherwise fallback to
// using the original requested url.
obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.requestUrl)
var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
obj.url = serverUrl ? stripInternalParams(serverUrl) : options.requestUrl

// Attempt to parse response html into elements
if (fullDocument) {
Expand Down

0 comments on commit c82d5a7

Please sign in to comment.