Marek Piasecki
7 years ago
commit
96fb5878f6
8 changed files with 394 additions and 0 deletions
@ -0,0 +1,10 @@ |
|||||
|
<html> |
||||
|
<body> |
||||
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js'></script> |
||||
|
<script src='https://unpkg.com/pro-router@3.2.0/pro-router-standalone.min.js'></script> |
||||
|
<script> |
||||
|
window.render = function(){ console.log(R.view); console.log(JSON.stringify(R.params)) } |
||||
|
R.init({helpers: _}) |
||||
|
</script> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,20 @@ |
|||||
|
{ |
||||
|
"name": "pro-router", |
||||
|
"description": "Fully automated singleton router service for frontend. Use url as data store", |
||||
|
"version": "4.3.0", |
||||
|
"main": "router.js", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/madmaniak/pro.git" |
||||
|
}, |
||||
|
"keywords": [ |
||||
|
"frontend", |
||||
|
"router" |
||||
|
], |
||||
|
"author": "Marek Piasecki", |
||||
|
"license": "ISC", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/madmaniak/pro/issues" |
||||
|
}, |
||||
|
"homepage": "https://github.com/madmaniak/pro/framework/components/router/npm_router_service" |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
window.R={_l:location,_r:history.replaceState.bind(history),_p:history.pushState.bind(history),_d:decodeURIComponent,_e:encodeURIComponent,init:function(o){if(o==null){o={}}this.root||(this.root=o.root||"root");this.views||(this.views=o.views||window.Views||[this.root]);this.render||(this.render=o.render||window.render);this.h||(this.h=o.helpers||window._);window.onpopstate=this.url_changed.bind(this);this.read()},cache:{},getters:{},setters:{},param:function(k){var base;if(this.getters[k]){return(base=this.cache)[k]||(base[k]=this.getters[k](this._d(this.params[k]||"")))}else{return this._d(this.params[k]||"")}},write:function(){var i,j,k,l,v;for(i=j=0,l=arguments.length;j<l;i=++j){k=arguments[i];if(!(i%2)){v=arguments[i+1];this._write(k,v)}}this._r({},this._l.pathname,this.to_path(this.view,this.params));this.url_changed()},_write:function(k,v){var _v=this.setters[k]?this.setters[k](v):v;_v?this.params[k]=this._e(_v):delete this.params[k]},toggle:function(f,s){this.write(f,s!=null?s?1:void 0:!this.params[f]?1:void 0)},go:function(p){this._p({},null,p);this.url_changed()},read:function(){var ref;ref=this.split_path(this._l.hash),this.view=ref[0],this.params=ref[1];this._safe_params()},split_path:function(p){p=p.slice(2);if(!p.length){return [this.root,{}]}var list,params,view;list=this.h.compact(p.split("/"));view=this._existance(list.shift());params=this.h.fromPairs(this.h.chunk(list,2));return[view,params]},_existance:function(v){if(this.h.includes(this.views,v)){return v}else{return"not_found"}},_safe_params:function(){return this.safe_params=this.h.fromPairs(this.h.reject(this.h.toPairs(this.params),function(p){return/^_/.test(p[0])}))},to_path:function(v,p){var a;if(v==null){v=this.view}if(p==null){p=this.safe_params}a=this.h.flatten(this.h.reject(this.h.toPairs(p),function(p){return!p[1]}));return"#/"+v+"/"+a.join("/")},url_changed:function(){this.cache={};this.read();this.render()}}; |
@ -0,0 +1 @@ |
|||||
|
window.R={_l:location,_r:history.replaceState.bind(history),_p:history.pushState.bind(history),_d:decodeURIComponent,_e:encodeURIComponent,init:function(o){if(o==null){o={}}this.root||(this.root=o.root||"root");this.views||(this.views=o.views||window.Views||[this.root]);this.render||(this.render=o.render||window.render);this.h||(this.h=o.helpers||window._);window.onpopstate=this.url_changed.bind(this);this.read()},cache:{},getters:{},setters:{},param:function(k){var base;if(this.getters[k]){return(base=this.cache)[k]||(base[k]=this.getters[k](this._d(this.params[k]||"")))}else{return this._d(this.params[k]||"")}},write:function(){var i,j,k,l,v;for(i=j=0,l=arguments.length;j<l;i=++j){k=arguments[i];if(!(i%2)){v=arguments[i+1];this._write(k,v)}}this._r({},this._l.pathname,this.to_path(this.view,this.params));this.url_changed()},_write:function(k,v){var _v=this.setters[k]?this.setters[k](v):v;_v?this.params[k]=this._e(_v):delete this.params[k]},toggle:function(f,s){this.write(f,s!=null?s?1:void 0:!this.params[f]?1:void 0)},go:function(p){this._p({},null,p);this.url_changed()},read:function(){var ref;ref=this.split_path(this._l.pathname),this.view=ref[0],this.params=ref[1];this._safe_params()},split_path:function(p){if(p.length==1){return [this.root,{}]}var list,params,view;list=this.h.compact(p.split("/"));view=this._existance(list.shift());params=this.h.fromPairs(this.h.chunk(list,2));return[view,params]},_existance:function(v){if(this.h.includes(this.views,v)){return v}else{return"not_found"}},_safe_params:function(){return this.safe_params=this.h.fromPairs(this.h.reject(this.h.toPairs(this.params),function(p){return/^_/.test(p[0])}))},to_path:function(v,p){var a;if(v==null){v=this.view}if(p==null){p=this.safe_params}a=this.h.flatten(this.h.reject(this.h.toPairs(p),function(p){return!p[1]}));return"/"+v+"/"+a.join("/")},url_changed:function(){this.cache={};this.read();this.render()}}; |
@ -0,0 +1,84 @@ |
|||||
|
module.exports = window.R = |
||||
|
|
||||
|
# local cache |
||||
|
_location: location |
||||
|
_replaceState: history.replaceState.bind(history) |
||||
|
_pushState: history.pushState.bind(history) |
||||
|
_decodeURIComponent: decodeURIComponent |
||||
|
_encodeURIComponent: encodeURIComponent |
||||
|
|
||||
|
init: (opts = {}) -> |
||||
|
@root ||= opts.root || 'root' |
||||
|
@views ||= opts.views || window.Views || [@root] |
||||
|
@render ||= opts.render || window.render |
||||
|
@h ||= opts.helpers || window._ |
||||
|
window.onpopstate = @url_changed.bind(@) |
||||
|
@read() |
||||
|
|
||||
|
cache: {} |
||||
|
getters: {} |
||||
|
setters: {} |
||||
|
|
||||
|
# <MAIN API> |
||||
|
|
||||
|
param: (key) -> |
||||
|
if @getters[key] |
||||
|
then @cache[key] ||= @getters[key]( @_decodeURIComponent(@params[key] || '') ) |
||||
|
else @_decodeURIComponent(@params[key] || '') |
||||
|
|
||||
|
write: -> |
||||
|
# accept arguments keeping key, value, key, value order |
||||
|
# serialize using setters |
||||
|
# if no argument given just refresh url and rerender |
||||
|
for k, i in arguments |
||||
|
unless i % 2 |
||||
|
v = arguments[i+1] |
||||
|
@_write(k,v) |
||||
|
|
||||
|
@_replaceState {}, |
||||
|
@_location.pathname, @to_path(@view, @params) |
||||
|
@url_changed() |
||||
|
|
||||
|
_write: (k,v) -> |
||||
|
value = if @setters[k] then @setters[k](v) else v |
||||
|
if value |
||||
|
then @params[k] = @_encodeURIComponent(value) |
||||
|
else delete @params[k] |
||||
|
|
||||
|
toggle: (flag, state) -> |
||||
|
@write flag, if state? |
||||
|
then ( 1 if state ) |
||||
|
else ( 1 if !@params[flag] ) |
||||
|
|
||||
|
go: (path) -> |
||||
|
@_pushState {}, null, path |
||||
|
@url_changed() |
||||
|
|
||||
|
# </MAIN API> |
||||
|
|
||||
|
read: -> |
||||
|
[@view, @params] = @split_path @_location.pathname |
||||
|
@_safe_params() |
||||
|
|
||||
|
split_path: (path) -> |
||||
|
return [ @root, {} ] if path.length == 1 |
||||
|
list = @h.compact path.split("/") |
||||
|
view = @_existance list.shift() |
||||
|
params = @h.fromPairs @h.chunk(list, 2) |
||||
|
[ view, params ] |
||||
|
|
||||
|
_existance: (view) -> |
||||
|
if @h.includes(@views, view) then view else 'not_found' |
||||
|
|
||||
|
_safe_params: -> |
||||
|
@safe_params = @h.fromPairs @h.reject @h.toPairs(@params), (pair) -> |
||||
|
/^_/.test pair[0] |
||||
|
|
||||
|
to_path: (view = @view, params = @safe_params) -> |
||||
|
array = @h.flatten @h.toPairs(params) |
||||
|
'/' + view + '/' + array.join('/') |
||||
|
|
||||
|
url_changed: -> |
||||
|
@cache = {} |
||||
|
@read() |
||||
|
@render() |
@ -0,0 +1,96 @@ |
|||||
|
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(); |
||||
|
} |
||||
|
|
||||
|
}; |
@ -0,0 +1,85 @@ |
|||||
|
module.exports = window.R = |
||||
|
|
||||
|
# local cache |
||||
|
_location: location |
||||
|
_replaceState: history.replaceState.bind(history) |
||||
|
_pushState: history.pushState.bind(history) |
||||
|
_decodeURIComponent: decodeURIComponent |
||||
|
_encodeURIComponent: encodeURIComponent |
||||
|
|
||||
|
init: (opts = {}) -> |
||||
|
@root ||= opts.root || 'root' |
||||
|
@views ||= opts.views || window.Views || [@root] |
||||
|
@render ||= opts.render || window.render |
||||
|
@h ||= opts.helpers || window._ |
||||
|
window.onpopstate = @url_changed.bind(@) |
||||
|
@read() |
||||
|
|
||||
|
cache: {} |
||||
|
getters: {} |
||||
|
setters: {} |
||||
|
|
||||
|
# <MAIN API> |
||||
|
|
||||
|
param: (key) -> |
||||
|
if @getters[key] |
||||
|
then @cache[key] ||= @getters[key]( @_decodeURIComponent(@params[key] || '') ) |
||||
|
else @_decodeURIComponent(@params[key] || '') |
||||
|
|
||||
|
write: -> |
||||
|
# accept arguments keeping key, value, key, value order |
||||
|
# serialize using setters |
||||
|
# if no argument given just refresh url and rerender |
||||
|
for k, i in arguments |
||||
|
unless i % 2 |
||||
|
v = arguments[i+1] |
||||
|
@_write(k,v) |
||||
|
|
||||
|
@_replaceState {}, |
||||
|
@_location.pathname, @to_path(@view, @params) |
||||
|
@url_changed() |
||||
|
|
||||
|
_write: (k,v) -> |
||||
|
value = if @setters[k] then @setters[k](v) else v |
||||
|
if value |
||||
|
then @params[k] = @_encodeURIComponent(value) |
||||
|
else delete @params[k] |
||||
|
|
||||
|
toggle: (flag, state) -> |
||||
|
@write flag, if state? |
||||
|
then ( 1 if state ) |
||||
|
else ( 1 if !@params[flag] ) |
||||
|
|
||||
|
go: (path) -> |
||||
|
@_pushState {}, null, path |
||||
|
@url_changed() |
||||
|
|
||||
|
# </MAIN API> |
||||
|
|
||||
|
read: -> |
||||
|
[@view, @params] = @split_path @_location.hash |
||||
|
@_safe_params() |
||||
|
|
||||
|
split_path: (path) -> |
||||
|
path = path.slice(2) |
||||
|
return [ @root, {} ] unless path.length |
||||
|
list = @h.compact path.split("/") |
||||
|
view = @_existance list.shift() |
||||
|
params = @h.fromPairs @h.chunk(list, 2) |
||||
|
[ view, params ] |
||||
|
|
||||
|
_existance: (view) -> |
||||
|
if @h.includes(@views, view) then view else 'not_found' |
||||
|
|
||||
|
_safe_params: -> |
||||
|
@safe_params = @h.fromPairs @h.reject @h.toPairs(@params), (pair) -> |
||||
|
/^_/.test pair[0] |
||||
|
|
||||
|
to_path: (view = @view, params = @safe_params) -> |
||||
|
array = @h.flatten @h.toPairs(params) |
||||
|
'#/' + view + '/' + array.join('/') |
||||
|
|
||||
|
url_changed: -> |
||||
|
@cache = {} |
||||
|
@read() |
||||
|
@render() |
@ -0,0 +1,97 @@ |
|||||
|
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(); |
||||
|
} |
||||
|
|
||||
|
}; |
Loading…
Reference in new issue