Skip to content

Commit 93f530f

Browse files
committed
Change internal cache struct to fix restoring mixed containers
When different pjax containers were used for pjax navigations, the popstate restoring mechanism would get confused as to in which container to restore some particular HTML. I tried to remedy this by reading the target container from `previousState` on "back" navigations, however this was subject to at least a couple of flaws: 1. It would break if `previousState` was done via replaceState, which replaces content in a container but doesn't add a history entry. 2. It doesn't handle the case where user jumps several steps of history stack (e.g. by holding the "Back" button pressed and choosing from the drop down menu). A more solid solution to knowing where to restore particular cached HTML is to save the information about the container that the HTML was saved from in the first place. This adds the container selector information to the cache, forming a pair with cached contents for each history entry.
1 parent 98930b4 commit 93f530f

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

jquery.pjax.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -424,29 +424,27 @@ function onPjaxPopstate(event) {
424424

425425
var previousState = pjax.state
426426
var state = event.state
427+
var direction
427428

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

434-
var direction, containerSelector = state.container
435-
436435
if (previousState) {
437436
// If popping back to the same state, just skip.
438437
// Could be clicking back from hashchange rather than a pushState.
439438
if (previousState.id === state.id) return
440439

441440
// Since state IDs always increase, we can deduce the navigation direction
442441
direction = previousState.id < state.id ? 'forward' : 'back'
443-
if (direction == 'back') containerSelector = previousState.container
444442
}
445443

446-
var container = $(containerSelector)
447-
if (container.length) {
448-
var contents = cacheMapping[state.id]
444+
var cache = cacheMapping[state.id] || []
445+
var container = $(cache[0] || state.container), contents = cache[1]
449446

447+
if (container.length) {
450448
if (previousState) {
451449
// Cache current container before replacement and inform the
452450
// cache which direction the history shifted.
@@ -564,7 +562,7 @@ function cloneContents(container) {
564562
cloned.find('script').each(function(){
565563
if (!this.src) jQuery._data(this, 'globalEval', false)
566564
})
567-
return cloned.contents()
565+
return [container.selector, cloned.contents()]
568566
}
569567

570568
// Internal: Strips named query param from url

test/unit/pjax.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ if ($.support.pjax) {
253253
}, 0)
254254
})
255255

256-
asyncTest("mixed containers", 4, function() {
256+
asyncTest("mixed containers", 6, function() {
257257
navigate(this.frame)
258258
.pjax({ url: "fragment.html", container: "#main" })
259259
.pjax({ url: "aliens.html", container: "#foo" }, function(frame) {
@@ -262,6 +262,11 @@ if ($.support.pjax) {
262262
.back(-1, function(frame) {
263263
equal(frame.$("#main > #foo").text().trim(), "Foo")
264264
})
265+
.pjax({ url: "env.html", replace: true, fragment: "#env", container: "#bar" }, function(frame) {
266+
// This replaceState shouldn't affect restoring other popstates
267+
equal(frame.$("#main > #foo").text().trim(), "Foo")
268+
ok(JSON.parse(frame.$("#bar").text()))
269+
})
265270
.back(-1, function(frame) {
266271
equal(frame.$("#main > ul > li").first().text(), "home")
267272
})

0 commit comments

Comments
 (0)