Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix async switches #110

Merged
merged 3 commits into from
Jan 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 72 additions & 47 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ var defaultSwitches = require("./lib/switches")

var Pjax = function(options) {
this.firstrun = true
this.state = {
numPendingSwitches: 0,
href: null,
options: null
}

var parseOptions = require("./lib/proto/parse-options.js");
parseOptions.apply(this,[options])
Expand Down Expand Up @@ -83,8 +88,12 @@ Pjax.prototype = {
},

onSwitch: function() {
this.parseDOM(document)
trigger(window, "resize scroll")
this.state.numPendingSwitches--

// debounce calls, so we only run this once after all switches are finished.
if (this.state.numPendingSwitches === 0) {
this.afterAllSwitches()
}
},

loadContent: function(html, options) {
Expand Down Expand Up @@ -125,22 +134,6 @@ Pjax.prototype = {
// try {
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) {
// if (this.options.debug) {
Expand Down Expand Up @@ -181,6 +174,8 @@ Pjax.prototype = {
else if (request.getResponseHeader("X-XHR-Redirected-To")) {
href = request.getResponseHeader("X-XHR-Redirected-To")
}
this.state.href = href
this.state.options = clone(options)

try {
this.loadContent(html, options)
Expand All @@ -197,49 +192,79 @@ Pjax.prototype = {
throw e
}
}
}.bind(this))
},

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();
}

if (options.history) {
if (this.firstrun) {
this.lastUid = this.maxUid = newUid()
this.firstrun = false
window.history.replaceState({
// execute scripts when DOM have been completely updated
this.options.selectors.forEach(function(selector) {
forEachEls(document.querySelectorAll(selector), function(el) {
executeScripts(el)
})
})

var state = this.state

if (state.options.history) {
if (this.firstrun) {
this.lastUid = this.maxUid = newUid()
this.firstrun = false
window.history.replaceState({
url: window.location.href,
title: document.title,
uid: this.maxUid
},
document.title)
}
}

// Update browser history
this.lastUid = this.maxUid = newUid()
window.history.pushState({
url: href,
title: options.title,
// Update browser history
this.lastUid = this.maxUid = newUid()

window.history.pushState({
url: state.href,
title: state.options.title,
uid: this.maxUid
},
options.title,
href)
}
state.options.title,
state.href)
}

this.forEachSelectors(function(el) {
this.parseDOM(el)
}, this)
this.forEachSelectors(function(el) {
this.parseDOM(el)
}, this)

// Fire Events
trigger(document,"pjax:complete pjax:success", options)
// Fire Events
trigger(document,"pjax:complete pjax:success", state.options)

options.analytics()
state.options.analytics()

// Scroll page to top on new page load
if (options.scrollTo !== false) {
if (options.scrollTo.length > 1) {
window.scrollTo(options.scrollTo[0], options.scrollTo[1])
}
else {
window.scrollTo(0, options.scrollTo)
}
// Scroll page to top on new page load
if (state.options.scrollTo !== false) {
if (state.options.scrollTo.length > 1) {
window.scrollTo(state.options.scrollTo[0], state.options.scrollTo[1])
}
}.bind(this))
else {
window.scrollTo(0, state.options.scrollTo)
}
}

this.state = {
numPendingSwitches: 0,
href: null,
options: null
}
}
}

Expand Down
20 changes: 14 additions & 6 deletions lib/switches-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ var forEachEls = require("./foreach-els")
var defaultSwitches = require("./switches")

module.exports = function(switches, switchesOptions, selectors, fromEl, toEl, options) {
var switchesQueue = [];

selectors.forEach(function(selector) {
var newEls = fromEl.querySelectorAll(selector)
var oldEls = toEl.querySelectorAll(selector)
Expand All @@ -24,12 +26,18 @@ module.exports = function(switches, switchesOptions, selectors, fromEl, toEl, op
if (this.log) {
this.log("newEl", newEl, "oldEl", oldEl)
}
if (switches[selector]) {
switches[selector].bind(this)(oldEl, newEl, options, switchesOptions[selector])
}
else {
defaultSwitches.outerHTML.bind(this)(oldEl, newEl, options)
}

var callback = (switches[selector]) ?
switches[selector].bind(this, oldEl, newEl, options, switchesOptions[selector]) :
defaultSwitches.outerHTML.bind(this, oldEl, newEl, options)

switchesQueue.push(callback)
}, this)
}, this)

this.state.numPendingSwitches = switchesQueue.length

switchesQueue.forEach(function(queuedSwitch) {
queuedSwitch()
})
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"lint": "jscs . && jshint . --exclude-path .gitignore",
"standalone": "browserify index.js --standalone Pjax > pjax.js",
"build-debug": "browserify index.js --debug --standalone Pjax > pjax.js",
"tests": "tape -r ./tests/index.js ./tests/**/*.js",
"tests": "tape -r ./tests/setup.js ./tests/**/*.js",
"test": "npm run lint && npm run tests | tap-spec",
"coverage-tests": "npm run tests | tap-nyc",
"coverage": "nyc -x \"tests/**\" npm run coverage-tests",
Expand Down
3 changes: 2 additions & 1 deletion tests/lib/switch-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ tape("test switchesSelectors", function(t) {
var pjax = {
onSwitch: function() {
console.log("Switched")
}
},
state: {}
}

var tmpEl = document.implementation.createHTMLDocument()
Expand Down
File renamed without changes.