Framework agnostic front-end router based on store pattern http://router.maniak.pro
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

97 lines
2.8 KiB

module.exports = window.R = {
_location: location,
_replaceState: history.replaceState.bind(history),
_pushState: history.pushState.bind(history),
_decodeURIComponent: decodeURIComponent,
_encodeURIComponent: encodeURIComponent,
init: function(opts) {
if (opts == null) {
opts = {};
}
this.root || (this.root = opts.root || 'root');
this.views || (this.views = opts.views || window.Views || [this.root]);
this.render || (this.render = opts.render || window.render);
this.h || (this.h = opts.helpers || window._);
window.onpopstate = this.url_changed.bind(this)
this.read();
},
cache: {},
getters: {},
setters: {},
param: function(key) {
var base;
if (this.getters[key]) {
return (base = this.cache)[key] || (base[key] = this.getters[key](this._decodeURIComponent(this.params[key] || '')));
} else {
return this._decodeURIComponent(this.params[key] || '');
}
},
write: function() {
var i, j, k, len, v;
for (i = j = 0, len = arguments.length; j < len; i = ++j) {
k = arguments[i];
if (!(i % 2)) {
v = arguments[i + 1];
this._write(k, v);
}
}
this._replaceState({}, this._location.pathname, this.to_path(this.view, this.params));
this.url_changed();
},
_write: function(k, v) {
var value = this.setters[k] ? this.setters[k](v) : v;
value ? this.params[k] = this._encodeURIComponent(value) : delete this.params[k];
},
toggle: function(flag, state) {
this.write(flag, state != null ? (state ? 1 : void 0) : (!this.params[flag] ? 1 : void 0));
},
go: function(path) {
this._pushState({}, null, path);
this.url_changed();
},
read: function() {
var ref;
ref = this.split_path(this._location.hash), this.view = ref[0], this.params = ref[1];
this._safe_params();
},
split_path: function(path) {
path = path.slice(2);
if (!path.length) {
return [this.root, {}];
}
var list, params, view;
list = this.h.compact(path.split("/"));
view = this._existance(list.shift());
params = this.h.fromPairs(this.h.chunk(list, 2));
return [view, params];
},
_existance: function(view) {
if (this.h.includes(this.views, view)) {
return view;
} else {
return 'not_found';
}
},
_safe_params: function() {
return this.safe_params = this.h.fromPairs(this.h.reject(this.h.toPairs(this.params), function(pair) {
return /^_/.test(pair[0]);
}));
},
to_path: function(view, params) {
var array;
if (view == null) {
view = this.view;
}
if (params == null) {
params = this.safe_params;
}
array = this.h.flatten(this.h.toPairs(params));
return '#/' + view + '/' + array.join('/');
},
url_changed: function() {
this.cache = {};
this.read();
this.render();
}
};