Skip to content

Commit 20ceeb2

Browse files
committed
Fix popstate with different pjax containers
When navigating back, the container to restore the cached contents of is that of `previousState`, not the current state that was popped.
1 parent 247b255 commit 20ceeb2

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

jquery.pjax.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ if ('state' in window.history) {
423423
// You probably shouldn't use pjax on pages with other pushState
424424
// stuff yet.
425425
function onPjaxPopstate(event) {
426-
var previousState = pjax.state;
426+
var previousState = pjax.state
427427
var state = event.state
428428

429429
if (state && state.container) {
@@ -432,22 +432,26 @@ function onPjaxPopstate(event) {
432432
// page.
433433
if (initialPop && initialURL == state.url) return
434434

435-
// If popping back to the same state, just skip.
436-
// Could be clicking back from hashchange rather than a pushState.
437-
if (pjax.state && pjax.state.id === state.id) return
435+
var direction, containerSelector = state.container
438436

439-
var container = $(state.container)
440-
if (container.length) {
441-
var direction, contents = cacheMapping[state.id]
437+
if (previousState) {
438+
// If popping back to the same state, just skip.
439+
// Could be clicking back from hashchange rather than a pushState.
440+
if (previousState.id === state.id) return
441+
442+
// Since state IDs always increase, we can deduce the navigation direction
443+
direction = previousState.id < state.id ? 'forward' : 'back'
444+
if (direction == 'back') containerSelector = previousState.container
445+
}
442446

443-
if (pjax.state) {
444-
// Since state ids always increase, we can deduce the history
445-
// direction from the previous state.
446-
direction = pjax.state.id < state.id ? 'forward' : 'back'
447+
var container = $(containerSelector)
448+
if (container.length) {
449+
var contents = cacheMapping[state.id]
447450

451+
if (previousState) {
448452
// Cache current container before replacement and inform the
449453
// cache which direction the history shifted.
450-
cachePop(direction, pjax.state.id, cloneContents(container))
454+
cachePop(direction, previousState.id, cloneContents(container))
451455
}
452456

453457
var popstateEvent = $.Event('pjax:popstate', {

test/unit/pjax.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,40 @@ if ($.support.pjax) {
351351
equal(frame.location.search, "?foo=1&bar=2")
352352
})
353353

354+
asyncTest("mixed containers", function() {
355+
var frame = this.frame
356+
357+
frame.$.pjax({
358+
url: "fragment.html",
359+
container: "#main"
360+
})
361+
362+
frame.$("#main").one("pjax:end", function() {
363+
frame.$.pjax({
364+
url: "aliens.html",
365+
container: "#foo"
366+
})
367+
368+
frame.$("#foo").one("pjax:end", function() {
369+
equal(frame.$("#main > #foo > ul > li").last().text(), "aliens")
370+
371+
goBack(frame, function() {
372+
equal(frame.$("#main > #foo").text().trim(), "Foo")
373+
374+
goBack(frame, function() {
375+
equal(frame.$("#main > ul > li").first().text(), "home")
376+
377+
goForward(frame, function() {
378+
goForward(frame, function() {
379+
equal(frame.$("#main > #foo > ul > li").last().text(), "aliens")
380+
start()
381+
})
382+
})
383+
})
384+
})
385+
})
386+
})
387+
})
354388

355389
asyncTest("only fragment is inserted", function() {
356390
var frame = this.frame

0 commit comments

Comments
 (0)