diff --git a/example/index.html b/example/index.html index 4d375e0..f9e3da5 100644 --- a/example/index.html +++ b/example/index.html @@ -10,7 +10,7 @@

Index

Hello. - Go to Page 2 and view your console to see Pjax events. + Go to Page 2 or Page 3 and view your console to see Pjax events. Clicking on this page will just reload the page entirely.
diff --git a/example/page3.html b/example/page3.html new file mode 100644 index 0000000..7546dd1 --- /dev/null +++ b/example/page3.html @@ -0,0 +1,15 @@ + + + + + Hello + + + + +
+

Page 3

+ Hello. Go to Index. +
+ + diff --git a/index.js b/index.js index e8ca6e6..b9802e9 100644 --- a/index.js +++ b/index.js @@ -145,16 +145,21 @@ Pjax.prototype = { // } }, - doRequest: require("./lib/request.js"), + abortRequest: require("./lib/abort-request.js"), + + doRequest: require("./lib/send-request.js"), loadUrl: function(href, options) { this.log("load href", href, options) + // Abort any previous request + this.abortRequest(this.request) + trigger(document, "pjax:send", options); // Do the request options.requestOptions.timeout = this.options.timeout - this.doRequest(href, options.requestOptions, function(html, request) { + this.request = this.doRequest(href, options.requestOptions, function(html, request) { // Fail if unable to load HTML via AJAX if (html === false) { trigger(document,"pjax:complete pjax:error", options) diff --git a/lib/abort-request.js b/lib/abort-request.js new file mode 100644 index 0000000..e68f01b --- /dev/null +++ b/lib/abort-request.js @@ -0,0 +1,8 @@ +var noop = require("./util/noop") + +module.exports = function(request) { + if (request && request.readyState < 4) { + request.onreadystatechange = noop + request.abort() + } +} diff --git a/lib/request.js b/lib/send-request.js similarity index 100% rename from lib/request.js rename to lib/send-request.js diff --git a/lib/util/noop b/lib/util/noop new file mode 100644 index 0000000..756c6be --- /dev/null +++ b/lib/util/noop @@ -0,0 +1 @@ +module.exports = function() {} diff --git a/tests/lib/abort-request.js b/tests/lib/abort-request.js new file mode 100644 index 0000000..edaa774 --- /dev/null +++ b/tests/lib/abort-request.js @@ -0,0 +1,54 @@ +var tape = require("tape") + +var abortRequest = require("../../lib/abort-request.js") +var sendRequest = require("../../lib/send-request.js") + +// Polyfill responseURL property into XMLHttpRequest if it doesn't exist, +// just for the purposes of this test +// This polyfill is not complete; it won't show the updated location if a +// redirection occurred, but it's fine for our purposes. +if (!("responseURL" in XMLHttpRequest.prototype)) { + var nativeOpen = XMLHttpRequest.prototype.open + XMLHttpRequest.prototype.open = function(method, url) { + this.responseURL = url + return nativeOpen.apply(this, arguments) + } +} + +tape("test aborting xhr request", function(t) { + var requestCacheBust = sendRequest.bind({ + options: { + cacheBust: true, + }, + }) + + t.test("- pending request is aborted", function(t) { + var r = requestCacheBust("https://httpbin.org/delay/10", {}, function() {}) + t.equal(r.readyState, 1, "xhr readyState is '1' (SENT)") + abortRequest(r) + t.equal(r.readyState, 0, "xhr readyState is '0' (ABORTED)") + t.equal(r.status, 0, "xhr HTTP status is '0' (ABORTED)") + t.equal(r.responseText, "", "xhr response is empty") + t.end() + }) + t.test("- request is not aborted if it has already completed", function(t) { + var r = requestCacheBust("https://httpbin.org/get", {}, function() { + abortRequest(r) + t.equal(r.readyState, 4, "xhr readyState is '4' (DONE)") + t.equal(r.status, 200, "xhr HTTP status is '200' (OK)") + t.end() + }) + }) + t.test("- request is not aborted if it is undefined", function(t) { + var r + try { + abortRequest(r) + } + catch (e) { + t.fail("aborting an undefined request threw an error") + } + t.equal(typeof r, "undefined", "undefined xhr was ignored") + t.end() + }) + t.end() +}) diff --git a/tests/lib/request.js b/tests/lib/send-request.js similarity index 90% rename from tests/lib/request.js rename to tests/lib/send-request.js index 0f1e365..f33b28c 100644 --- a/tests/lib/request.js +++ b/tests/lib/send-request.js @@ -1,6 +1,6 @@ var tape = require("tape") -var request = require("../../lib/request.js") +var sendRequest = require("../../lib/send-request.js") // Polyfill responseURL property into XMLHttpRequest if it doesn't exist, // just for the purposes of this test @@ -18,7 +18,7 @@ tape("test xhr request", function(t) { var url = "https://httpbin.org/get" t.test("- request is made, gets a result, and is cache-busted", function(t) { - var requestCacheBust = request.bind({ + var requestCacheBust = sendRequest.bind({ options: { cacheBust: true, }, @@ -36,7 +36,7 @@ tape("test xhr request", function(t) { }) }) t.test("- request is not cache-busted when configured not to be", function(t) { - var requestNoCacheBust = request.bind({ + var requestNoCacheBust = sendRequest.bind({ options: { cacheBust: false, },