Created
October 11, 2017 03:17
-
-
Save bathos/d06723c3dbbe57cfb0be4902950dbd05 to your computer and use it in GitHub Desktop.
urlchange.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This module installs a custom global DOM event, 'urlchange', which is | |
// dispatched when the URL _semantically_ changes for any reason. | |
// | |
// It also alters URL behavior more generally. The URL is kept consistently in a | |
// canonical form, such that differences in the order of query parameters (other | |
// than same-key parameters, whose order is potentially meaningful) are | |
// eliminated. While the event is not fired on load, URL canonicalization may be | |
// performed. | |
// | |
// Like HashChangeEvent, URLChangeEvent has two properties, 'newURL' and | |
// 'oldURL', except they are instances of URL rather than strings. | |
class URLChangeEvent extends CustomEvent { | |
constructor(newURL, oldURL) { | |
super('urlchange'); | |
this.newURL = newURL; | |
this.oldURL = oldURL; | |
} | |
} | |
const { pushState, replaceState } = History.prototype; | |
Object.defineProperties(History.prototype, { | |
pushState: { | |
value() { | |
pushState.apply(this, arguments); | |
respond(); | |
} | |
}, | |
replaceState: { | |
value() { | |
replaceState.apply(this, arguments); | |
respond(); | |
} | |
} | |
}); | |
const respond = () => { | |
const newURL = new URL(location); | |
newURL.searchParams.sort(); | |
if (String(newURL) !== location.href) { | |
history.replaceState(undefined, undefined, newURL); | |
return; | |
} | |
if (String(newURL) !== String(oldURL)) { | |
const event = new URLChangeEvent(newURL, oldURL); | |
oldURL = newURL; | |
console.debug(`Emitting URLChange global DOM event: ${ newURL }`); | |
window.dispatchEvent(event); | |
} | |
}; | |
let oldURL = new URL(location); | |
oldURL.searchParams.sort(); | |
if (String(oldURL) !== location.href) { | |
replaceState.call(history, undefined, undefined, oldURL); | |
} | |
window.addEventListener('hashchange', respond); | |
window.addEventListener('popstate', respond); |
Author
bathos
commented
Oct 11, 2017
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment