Skip to content

Instantly share code, notes, and snippets.

@majido
Last active August 29, 2015 14:21
Show Gist options
  • Save majido/4cbd0b68d742de319aeb to your computer and use it in GitHub Desktop.
Save majido/4cbd0b68d742de319aeb to your computer and use it in GitHub Desktop.
Global scroll restoration flag
/* jshint esnext: true */
// A simple experimental poly-fill to create a global flag that controls scroll restoration.
// To use simply set window.history.scrollRestoration to 'manual' or 'auto'.
// Requires Chrome v44 with "--enable-web-experimental-features" flag.
(function(window, console, undefined) {
"use strict";
var history = window.history;
// History API does not support scroll restoration option
if (!('options' in history && 'scrollRestoration' in history.options)) {
console.log('Warning: scrollRestoration option is not available.');
return;
}
// Exit early if this poly-fill has already been executed
if (history.scrollRestoration) {
console.log('Warning: history.scrollRestoration is already defined.');
return;
}
// create global flag and ensure its changes are reflected to the per-state option
Object.defineProperty(history, 'scrollRestoration', {
set: function(v) {
if (v !== 'auto' && v !== 'manual')
throw 'scrollRestoration can only be {auto|manual}.';
var changed = v !== this.scrollRestoration;
if (changed) {
// update current state to reflect the new scroll restoration option
history.replaceState(history.state, '', undefined, {'scrollRestoration': v});
console.assert(history.options.scrollRestoration == v);
}
},
get: function() {
return history.options.scrollRestoration;
}
});
// Curry {push, replace}State functions to pass the global flag
for (var property of ['pushState', 'replaceState']) {
Object.defineProperty(History.prototype, property, {
value: curry(History.prototype[property])
});
}
function curry(fn) {
if (!fn) {
console.warn("Warning: can't curry " + fn);
return fn;
}
return function() {
var options = {'scrollRestoration': history.scrollRestoration};
var args = Array.prototype.slice.call(arguments);
switch(args.length) {
// first two arguments are required.If not provided we will let fn throw.
case 2: args.push(undefined);
case 3: args.push(options);
case 4: /* no-op: allow user to override global flag */
}
fn.apply(this, args);
};
}
}(window, console));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment