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