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

loadUrl enhancements #134

Merged
merged 2 commits into from
Mar 6, 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
34 changes: 25 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,13 @@ To see if Pjax is actually supported by your browser, use `Pjax.isSupported()`.

## Usage

### `new Pjax()`
### Methods

Let's talk more about the most basic way to get started:
#### `new Pjax()`

Let's talk more about the most basic way to get started.

When instantiating `Pjax`, you can pass options in to the constructor as an object:

```js
new Pjax({
Expand All @@ -153,12 +157,24 @@ Pjax.prototype.getElements = function() {
return document.getElementsByClassName(".js-Pjax")
}

new Pjax({})
new Pjax()
```

When instantiating a `Pjax` object, you need to pass all options as an object:
#### `loadUrl(href, [options])`

With this method, you can manually trigger loading of a URL:

```js
var pjax = new Pjax()

// use case 1 (without options override)
pjax.loadUrl("/your-url")

// use case 2 (with options override)
pjax.loadUrl("/your-other-url", {timeout: 10})
```

#### Options
### Options

##### `elements` (String, default: `"a[href], form[action]"`)

Expand Down Expand Up @@ -398,8 +414,8 @@ Enables verbose mode. Useful to debug page layout differences.

When set to true, clicking on a link that points to the current URL will trigger a full page reload.

The default is `false`, so clicking on such a link will do nothing.
If you want to add some custom behavior, add a click listener to the link,
The default is `false`, so clicking on such a link will do nothing.
If you want to add some custom behavior, add a click listener to the link,
and set `preventDefault` to true, to prevent Pjax from receiving the event.

Here is some sample code:
Expand All @@ -420,8 +436,8 @@ Here is some sample code:
}
```

(Note that if `cacheBust` is set to true, the code that checks if the href
is the same as the current page's URL will not work, due to the query string
(Note that if `cacheBust` is set to true, the code that checks if the href
is the same as the current page's URL will not work, due to the query string
appended to force a cache bust).

##### `timeout` (Integer, default: `0`)
Expand Down
39 changes: 36 additions & 3 deletions example/example.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
/* global Pjax */
var pjax;
var initButtons = function() {
var buttons = document.querySelectorAll("button[data-manual-trigger]")

if (!buttons) {
return
}

// jshint -W083
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", function(e) {
var el = e.currentTarget

if (el.getAttribute("data-manual-trigger-override") === "true") {
// Manually load URL with overridden Pjax instance options
pjax.loadUrl("/example/page2.html", {cacheBust: false})
}
else
{
// Manually load URL with current Pjax instance options
pjax.loadUrl("/example/page2.html")
}
})
}
// jshint +W083
}

console.log("Document initialized:", window.location.href)

document.addEventListener("pjax:send", function() {
Expand All @@ -15,14 +42,20 @@ document.addEventListener("pjax:error", function() {

document.addEventListener("pjax:success", function() {
console.log("Event: pjax:success", arguments)

// Init page content
initButtons()
})

document.addEventListener("DOMContentLoaded", function() {
var pjax = new Pjax({
// Init Pjax instance
pjax = new Pjax({
elements: [".js-Pjax"],
selectors: [".body", "title"],
cacheBust: true,
// currentUrlFullReload: true,
cacheBust: true
})
console.log("Pjax initialized.", pjax)

// Init page content
initButtons()
})
7 changes: 7 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ <h1>Index</h1>
Go to <a href="page2.html" class="js-Pjax">Page 2</a> or <a href="page3.html" class="js-Pjax">Page 3</a> and view your console to see Pjax events.
Clicking on <a href="index.html">this page</a> will just reload the page entirely.

<h2>Manual URL loading</h2>

You can use Pjax's <i>loadUrl</i> method to manually load a URL. Click the buttons below to try it out!<br /><br />

<button data-manual-trigger>loadUrl with current options</button><br /><br />
<button data-manual-trigger data-manual-trigger-override="true">loadUrl with overridden options (no cache busting)</button>

<h2>Forms</h2>

You can submit GET or POST forms with Pjax! Go to the <a href="forms.html">form examples</a> to try it out.
Expand Down
16 changes: 10 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
var clone = require("./lib/clone.js")
var executeScripts = require("./lib/execute-scripts.js")
var forEachEls = require("./lib/foreach-els.js")
var parseOptions = require("./lib/parse-options.js")
var switches = require("./lib/switches")
var newUid = require("./lib/uniqueid.js")

var on = require("./lib/events/on.js")
var trigger = require("./lib/events/trigger.js")

var clone = require("./lib/util/clone.js")
var contains = require("./lib/util/contains.js")
var extend = require("./lib/util/extend.js")
var noop = require("./lib/util/noop")

var Pjax = function(options) {
Expand All @@ -17,8 +19,8 @@ var Pjax = function(options) {
options: null
}

var parseOptions = require("./lib/proto/parse-options.js")
parseOptions.call(this,options)

this.options = parseOptions(options)
this.log("Pjax options", this.options)

if (this.options.scrollRestoration && "scrollRestoration" in history) {
Expand All @@ -35,7 +37,6 @@ var Pjax = function(options) {
opt.url = st.state.url
opt.title = st.state.title
opt.history = false
opt.requestOptions = {}
opt.scrollPos = st.state.scrollPos
if (st.state.uid < this.lastUid) {
opt.backward = true
Expand Down Expand Up @@ -142,6 +143,10 @@ Pjax.prototype = {
doRequest: require("./lib/send-request.js"),

loadUrl: function(href, options) {
options = typeof options === "object" ?
extend({}, this.options, options) :
clone(this.options)

this.log("load href", href, options)

// Abort any previous request
Expand All @@ -150,8 +155,7 @@ Pjax.prototype = {
trigger(document, "pjax:send", options)

// Do the request
options.requestOptions.timeout = this.options.timeout
this.request = this.doRequest(href, options.requestOptions, function(html, request) {
this.request = this.doRequest(href, options, function(html, request) {
// Fail if unable to load HTML via AJAX
if (html === false) {
trigger(document, "pjax:complete pjax:error", options)
Expand Down
4 changes: 2 additions & 2 deletions lib/proto/parse-options.js → lib/parse-options.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* global _gaq: true, ga: true */

var defaultSwitches = require("../switches")
var defaultSwitches = require("./switches")

module.exports = function(options) {
options = options || {}
Expand Down Expand Up @@ -36,5 +36,5 @@ module.exports = function(options) {
options.switches.body = defaultSwitches.switchElementsAlt
}

this.options = options
return options
}
2 changes: 1 addition & 1 deletion lib/proto/attach-form.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var on = require("../events/on")
var clone = require("../clone")
var clone = require("../util/clone")

var attrClick = "data-pjax-click-state"

Expand Down
5 changes: 1 addition & 4 deletions lib/proto/attach-link.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var on = require("../events/on")
var clone = require("../clone")
var clone = require("../util/clone")

var attrClick = "data-pjax-click-state"
var attrKey = "data-pjax-keyup-state"
Expand All @@ -9,9 +9,6 @@ var linkAction = function(el, event) {
// clone it so the changes don't persist
var options = clone(this.options)

// Initialize requestOptions since loadUrl expects it to be an object
options.requestOptions = {}

// Don’t break browser special behavior on links (like page in new window)
if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
el.setAttribute(attrClick, "modifier")
Expand Down
10 changes: 6 additions & 4 deletions lib/send-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ var updateQueryString = require("./util/update-query-string");
module.exports = function(location, options, callback) {
options = options || {}
var queryString
var requestMethod = (options.requestMethod || "GET").toUpperCase()
var requestParams = options.requestParams || null
var requestOptions = options.requestOptions || {}
var requestMethod = (requestOptions.requestMethod || "GET").toUpperCase()
var requestParams = requestOptions.requestParams || null
var requestPayload = null
var request = new XMLHttpRequest()
var timeout = options.timeout || 0

request.onreadystatechange = function() {
if (request.readyState === 4) {
Expand Down Expand Up @@ -51,12 +53,12 @@ module.exports = function(location, options, callback) {
}

// Add a timestamp as part of the query string if cache busting is enabled
if (this.options.cacheBust) {
if (options.cacheBust) {
location = updateQueryString(location, "t", Date.now())
}

request.open(requestMethod, location, true)
request.timeout = options.timeout
request.timeout = timeout
request.setRequestHeader("X-Requested-With", "XMLHttpRequest")
request.setRequestHeader("X-PJAX", "true")

Expand Down
File renamed without changes.
21 changes: 21 additions & 0 deletions lib/util/extend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = function(target) {
if (target == null) {
return target
}

var to = Object(target)

for (var i = 1; i < arguments.length; i++) {
var source = arguments[i]

if (source != null) {
for (var key in source) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(source, key)) {
to[key] = source[key]
}
}
}
}
return to
}
17 changes: 0 additions & 17 deletions tests/lib/clone.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
var tape = require("tape")

var parseOptions = require("../../../lib/proto/parse-options.js")
var parseOptions = require("../../lib/parse-options.js")
tape("test parse initalization options function", function(t) {
t.test("- default options", function(t) {
var pjax = {}
parseOptions.call(pjax, {})
pjax.options = parseOptions({})

t.equal(pjax.options.elements, "a[href], form[action]")
t.equal(pjax.options.selectors.length, 2, "selectors length")
Expand All @@ -30,7 +30,7 @@ tape("test parse initalization options function", function(t) {
// verify analytics always ends up as a function even when passed not a function
t.test("- analytics is a function", function(t) {
var pjax = {}
parseOptions.call(pjax, {analytics: "some string"})
pjax.options = parseOptions({analytics: "some string"})

t.deepEqual(typeof pjax.options.analytics, "function")
t.end()
Expand All @@ -39,7 +39,7 @@ tape("test parse initalization options function", function(t) {
// verify that the value false for scrollTo is not squashed
t.test("- scrollTo remains false", function(t) {
var pjax = {}
parseOptions.call(pjax, {scrollTo: false})
pjax.options = parseOptions({scrollTo: false})

t.deepEqual(pjax.options.scrollTo, false)
t.end()
Expand Down
14 changes: 2 additions & 12 deletions tests/lib/send-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +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 = sendRequest.bind({
options: {
cacheBust: true
}
})
var r = requestCacheBust(url, {}, function(result) {
var r = sendRequest(url, {cacheBust: true}, function(result) {
t.equal(r.responseURL.indexOf("?"), url.length, "XHR URL is cache-busted when configured to be")
try {
result = JSON.parse(result)
Expand All @@ -36,12 +31,7 @@ tape("test xhr request", function(t) {
})
})
t.test("- request is not cache-busted when configured not to be", function(t) {
var requestNoCacheBust = sendRequest.bind({
options: {
cacheBust: false
}
})
var r = requestNoCacheBust(url, {}, function() {
var r = sendRequest(url, {}, function() {
t.equal(r.responseURL, url, "XHR URL is left untouched")
t.end()
})
Expand Down
17 changes: 17 additions & 0 deletions tests/lib/util/clone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var tape = require("tape")

var clone = require("../../../lib/util/clone")

tape("test clone method", function(t) {
var obj = {one: 1, two: 2}
var cloned = clone(obj)

t.notEqual(obj, cloned, "cloned object isn't the original object")

t.same(obj, cloned, "cloned object has the same values as original object")

cloned.three = 3
t.notSame(obj, cloned, "modified cloned object doesn't have the same values as original object")

t.end()
})
16 changes: 16 additions & 0 deletions tests/lib/util/extend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var tape = require("tape")

var extend = require("../../../lib/util/extend")

tape("test extend method", function(t) {
var obj = {one: 1, two: 2}
var extended = extend({}, obj, {two: "two", three: 3})

t.notEqual(obj, extended, "extended object isn't the original object")

t.notSame(obj, extended, "extended object doesn't have the same values as original object")

t.notSame(obj.two, extended.two, "extended object value overwrites value from original object")

t.end()
})