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.7 KiB
97 lines
2.7 KiB
7 years ago
|
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.pathname), this.view = ref[0], this.params = ref[1];
|
||
|
this._safe_params();
|
||
|
},
|
||
|
split_path: function(path) {
|
||
|
if (path.length == 1) {
|
||
|
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();
|
||
|
}
|
||
|
|
||
|
};
|