Fix async switches #110
82
index.js
82
index.js
@@ -14,6 +14,11 @@ var defaultSwitches = require("./lib/switches")
|
|||||||
|
|
||||||
var Pjax = function(options) {
|
var Pjax = function(options) {
|
||||||
this.firstrun = true
|
this.firstrun = true
|
||||||
|
this.state = {
|
||||||
|
numPendingSwitches: 0,
|
||||||
|
href: null,
|
||||||
|
options: null
|
||||||
|
}
|
||||||
|
|
||||||
var parseOptions = require("./lib/proto/parse-options.js");
|
var parseOptions = require("./lib/proto/parse-options.js");
|
||||||
parseOptions.apply(this,[options])
|
parseOptions.apply(this,[options])
|
||||||
@@ -83,8 +88,12 @@ Pjax.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onSwitch: function() {
|
onSwitch: function() {
|
||||||
this.parseDOM(document)
|
this.state.numPendingSwitches--
|
||||||
trigger(window, "resize scroll")
|
|
||||||
|
// debounce calls, so we only run this once after all switches are finished.
|
||||||
|
if (this.state.numPendingSwitches === 0) {
|
||||||
|
this.afterAllSwitches()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
loadContent: function(html, options) {
|
loadContent: function(html, options) {
|
||||||
@@ -125,22 +134,6 @@ Pjax.prototype = {
|
|||||||
// try {
|
// try {
|
||||||
this.switchSelectors(this.options.selectors, tmpEl, document, options)
|
this.switchSelectors(this.options.selectors, tmpEl, document, options)
|
||||||
|
|
||||||
// FF bug: Won’t autofocus fields that are inserted via JS.
|
|
||||||
// This behavior is incorrect. So if theres no current focus, autofocus
|
|
||||||
// the last field.
|
|
||||||
//
|
|
||||||
// http://www.w3.org/html/wg/drafts/html/master/forms.html
|
|
||||||
var autofocusEl = Array.prototype.slice.call(document.querySelectorAll("[autofocus]")).pop()
|
|
||||||
if (autofocusEl && document.activeElement !== autofocusEl) {
|
|
||||||
autofocusEl.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute scripts when DOM have been completely updated
|
|
||||||
this.options.selectors.forEach(function(selector) {
|
|
||||||
forEachEls(document.querySelectorAll(selector), function(el) {
|
|
||||||
executeScripts(el)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// }
|
// }
|
||||||
// catch(e) {
|
// catch(e) {
|
||||||
// if (this.options.debug) {
|
// if (this.options.debug) {
|
||||||
@@ -181,6 +174,8 @@ Pjax.prototype = {
|
|||||||
else if (request.getResponseHeader("X-XHR-Redirected-To")) {
|
else if (request.getResponseHeader("X-XHR-Redirected-To")) {
|
||||||
href = request.getResponseHeader("X-XHR-Redirected-To")
|
href = request.getResponseHeader("X-XHR-Redirected-To")
|
||||||
}
|
}
|
||||||
|
this.state.href = href
|
||||||
|
this.state.options = options
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.loadContent(html, options)
|
this.loadContent(html, options)
|
||||||
@@ -197,8 +192,30 @@ Pjax.prototype = {
|
|||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.bind(this))
|
||||||
|
},
|
||||||
|
|
||||||
if (options.history) {
|
afterAllSwitches: function() {
|
||||||
|
trigger(window, "resize scroll")
|
||||||
|
|
||||||
|
// FF bug: Won’t autofocus fields that are inserted via JS.
|
||||||
|
// This behavior is incorrect. So if theres no current focus, autofocus
|
||||||
|
// the last field.
|
||||||
|
//
|
||||||
|
// http://www.w3.org/html/wg/drafts/html/master/forms.html
|
||||||
|
var autofocusEl = Array.prototype.slice.call(document.querySelectorAll("[autofocus]")).pop()
|
||||||
|
if (autofocusEl && document.activeElement !== autofocusEl) {
|
||||||
|
autofocusEl.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute scripts when DOM have been completely updated
|
||||||
|
this.options.selectors.forEach(function(selector) {
|
||||||
|
forEachEls(document.querySelectorAll(selector), function(el) {
|
||||||
|
executeScripts(el)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.state.options.history) {
|
||||||
if (this.firstrun) {
|
if (this.firstrun) {
|
||||||
this.lastUid = this.maxUid = newUid()
|
this.lastUid = this.maxUid = newUid()
|
||||||
this.firstrun = false
|
this.firstrun = false
|
||||||
@@ -213,12 +230,12 @@ Pjax.prototype = {
|
|||||||
// Update browser history
|
// Update browser history
|
||||||
this.lastUid = this.maxUid = newUid()
|
this.lastUid = this.maxUid = newUid()
|
||||||
window.history.pushState({
|
window.history.pushState({
|
||||||
url: href,
|
url: this.state.href,
|
||||||
title: options.title,
|
title: this.state.options.title,
|
||||||
uid: this.maxUid
|
uid: this.maxUid
|
||||||
},
|
},
|
||||||
options.title,
|
this.state.options.title,
|
||||||
href)
|
this.state.href)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.forEachSelectors(function(el) {
|
this.forEachSelectors(function(el) {
|
||||||
@@ -226,20 +243,25 @@ Pjax.prototype = {
|
|||||||
}, this)
|
}, this)
|
||||||
|
|
||||||
// Fire Events
|
// Fire Events
|
||||||
trigger(document,"pjax:complete pjax:success", options)
|
trigger(document,"pjax:complete pjax:success", this.state.options)
|
||||||
|
|
||||||
options.analytics()
|
this.state.options.analytics()
|
||||||
|
|
||||||
// Scroll page to top on new page load
|
// Scroll page to top on new page load
|
||||||
if (options.scrollTo !== false) {
|
if (this.state.options.scrollTo !== false) {
|
||||||
if (options.scrollTo.length > 1) {
|
if (this.state.options.scrollTo.length > 1) {
|
||||||
window.scrollTo(options.scrollTo[0], options.scrollTo[1])
|
window.scrollTo(this.state.options.scrollTo[0], this.state.options.scrollTo[1])
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
window.scrollTo(0, options.scrollTo)
|
window.scrollTo(0, this.state.options.scrollTo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.bind(this))
|
|
||||||
|
this.state = {
|
||||||
|
numPendingSwitches: 0,
|
||||||
|
href: null,
|
||||||
|
options: null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ module.exports = function(switches, switchesOptions, selectors, fromEl, toEl, op
|
|||||||
if (this.log) {
|
if (this.log) {
|
||||||
this.log("newEl", newEl, "oldEl", oldEl)
|
this.log("newEl", newEl, "oldEl", oldEl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.state.numPendingSwitches++
|
||||||
|
|
||||||
if (switches[selector]) {
|
if (switches[selector]) {
|
||||||
switches[selector].bind(this)(oldEl, newEl, options, switchesOptions[selector])
|
switches[selector].bind(this)(oldEl, newEl, options, switchesOptions[selector])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ tape("test switchesSelectors", function(t) {
|
|||||||
var pjax = {
|
var pjax = {
|
||||||
onSwitch: function() {
|
onSwitch: function() {
|
||||||
console.log("Switched")
|
console.log("Switched")
|
||||||
}
|
},
|
||||||
|
state: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmpEl = document.implementation.createHTMLDocument()
|
var tmpEl = document.implementation.createHTMLDocument()
|
||||||
|
|||||||
Reference in New Issue
Block a user