broute v2.2.0
broute - brutal router
import {path, navigate} from 'broute'path
path(f)path(p,f)path(p,f,fe)
Tests the given part fragment p and if current path matches,
consumes the fragment and invokes function f. If not match, no
consume and invoke optional function fe.
p- path fragment to match from current scopef- function to invoke if fragment matchesfe- optional "else" function to invoke if fragment doesnt match- return - the result of
forfe
vararg paths to test
path(p1,f1,p2,f2,...,pn,fn,fe)
Any number of paths can be tested and the first one that matches is run.
function args
The f or fe is invoked with (left, query). The first is the path
that is left after the p fragment has been consumed (not for fe).
left- the path that is left after consuming fragmentpsearch- the search parameters as object?a=bbecomes{a:'b'}
root
On the root level, we can use path without a string arg. This is the starting point of the route function that is invoked for every url change. There can only be one root level path installed for each router.
path(() => {
})
navigate() // run route on startupThe root level path returns the navigate function. path(() => {...})('/start')
path usage
The following usage shows how nested path declarations creates
"scoped" functions that consumes part of the current url.
// the current url is: "/some/path/deep?panda=42"
path(() => {
path('/some', (left, query) => {
// at this point we "consumed" '/some'
// and left is "/path/deep"
// and query is {panda:42}
path('/path/deep', (left, query) => {
// left is "" and query is {panda:42}
})
})
// at this point we haven't consumed anything
path('/another', () => {
// will not be invoked for the current url
})
})
navigate() // run first routepath example 2
path(() => {
path('/news/', (slugId) => { // consume '/news/'
action('selectarticle', slugid) // fire action to fetch article
}, () => {
action('refreshnewslist') // else refresh news list
})
path('/aboutus', () => { // consume '/aboutus'
action('showaboutus')
})
})() // run first routenavigate
navigate(l,trigger)navigate(l)navigate()
Navigates to the location l using pushState and checks to
see if the url changed in which case the path function is
invoked.
l- location to set. example/my/page?foo=42.trigger- whether to trigger the route. defaults totrue.
Navigate with no argument is used to trigger a check of the current
path in the window.location object. It's typically only used on
startup or to detect path changes due to pushState without
using navigate.
navigate example
// if browser is at "http://my.host/some/where"
navigate('other') // changes url to "http://my.host/some/other"
navigate('/news') // changes url to "http://my.host/news"lazy
navigate is lazy when used inside a path. in this example, only /a
and /c would be run. Furthermore the invocation of /c only happens
at the end of the root path function.
path(() => {
navigate("/b")
navigate("/c")
if (someCondition()) {
... // more code
}
// conceptually navigate("/c") happens here
})
navigate("/a")Creating routers
For advanced usages, new routers can be created around arbitrary "window" objects.
Conceptually broute does this for the default path and navigate
functions around a current global window variable:
import router from 'broute' // router function
{path, navigate} = router(window) // create a router around windowIf the window argument has an addEventListener function, a
listener will be added for popstate events. This means
broute will run the path function also for the back button as well as
via navigate.
On each popstate or navigate invocation, the window argument
is inspected for a property window.location which is expected to
hold an object:
{
pathname: "/current/path",
search: "?my=query"
}If this object changes on navigate or popstate, the path function
is run.
If the window doesn't have a window.history.pushState function, navigate
will fall back on manipulating window.location directly.
License
The MIT License (MIT)
Copyright © 2016 Martin Algesten
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.