-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated: Convert the route hoc into a pure component
- Loading branch information
1 parent
cdfcc06
commit 352a3c9
Showing
11 changed files
with
160 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { PATH_ATTRIBUTE } from '../constants.js' | ||
import { | ||
route, | ||
toRegexp, | ||
match, | ||
router, | ||
createURLStreamPipe, | ||
} from '../index.js' | ||
import getCurrentRoute from '../get-current-route.js' | ||
import { get as getAttr } from 'bianco.attr' | ||
import { createDefaultSlot, getAttribute } from '../util.js' | ||
import compose from 'cumpa' | ||
|
||
const getInitialRouteValue = (pathToRegexp, path, options) => { | ||
const route = compose( | ||
...createURLStreamPipe(pathToRegexp, options).reverse(), | ||
)(path) | ||
|
||
return route.params ? route : null | ||
} | ||
|
||
const clearDOMBetweenNodes = (first, last, includeBoundaries) => { | ||
const clear = (node) => { | ||
if (!node || (node === last && !includeBoundaries)) return | ||
const { nextSibling } = node | ||
node.remove() | ||
clear(nextSibling) | ||
} | ||
|
||
clear(includeBoundaries ? first : first.nextSibling) | ||
} | ||
|
||
export const routeHoc = ({ slots, attributes }) => { | ||
return { | ||
mount(el, context) { | ||
// create the component state | ||
const currentRoute = getCurrentRoute() | ||
const path = | ||
getAttribute(attributes, PATH_ATTRIBUTE) || getAttr(el, PATH_ATTRIBUTE) | ||
const pathToRegexp = toRegexp(path, []) | ||
const state = { | ||
pathToRegexp, | ||
route: | ||
currentRoute && match(currentRoute, pathToRegexp) | ||
? getInitialRouteValue(pathToRegexp, currentRoute, {}) | ||
: null, | ||
} | ||
this.el = el | ||
this.slot = createDefaultSlot([ | ||
{ | ||
isBoolean: false, | ||
name: 'route', | ||
evaluate: () => this.state.route, | ||
}, | ||
]) | ||
this.context = context | ||
this.state = state | ||
// set the route listeners | ||
this.boundOnBeforeRoute = this.onBeforeRoute.bind(this) | ||
this.boundOnRoute = this.onRoute.bind(this) | ||
router.on.value(this.boundOnBeforeRoute) | ||
this.stream = route(path).on.value(this.boundOnRoute) | ||
// update the DOM | ||
this.beforePlaceholder = document.createTextNode('') | ||
this.afterPlaceholder = document.createTextNode('') | ||
el.replaceWith(this.beforePlaceholder) | ||
this.beforePlaceholder.parentNode.insertBefore( | ||
this.afterPlaceholder, | ||
this.beforePlaceholder.nextSibling, | ||
) | ||
}, | ||
update(context) { | ||
this.context = context | ||
if (this.state.route) this.slot.update({}, context) | ||
}, | ||
mountSlot(context) { | ||
this.beforePlaceholder.parentNode.insertBefore( | ||
this.el, | ||
this.beforePlaceholder.nextSibling, | ||
) | ||
this.slot.mount( | ||
this.el, | ||
{ | ||
slots, | ||
}, | ||
context, | ||
) | ||
}, | ||
clearDOM(includeBoundaries) { | ||
clearDOMBetweenNodes( | ||
this.beforePlaceholder, | ||
this.afterPlaceholder, | ||
includeBoundaries, | ||
) | ||
}, | ||
unmount() { | ||
router.off.value(this.boundOnBeforeRoute) | ||
this.slot.unmount({}, this.context, true) | ||
this.clearDOM(true) | ||
this.stream.end() | ||
}, | ||
onBeforeRoute(path) { | ||
if (this.state.route && !match(path, this.state.pathToRegexp)) { | ||
this.callLifecycleProperty('onBeforeUnmount', route) | ||
this.slot.unmount({}, this.context, true) | ||
this.clearDOM(false) | ||
this.state.route = null | ||
this.callLifecycleProperty('onUnmounted', route) | ||
} | ||
}, | ||
onRoute(route) { | ||
this.callLifecycleProperty('onBeforeMount', route) | ||
this.state.route = route | ||
this.mountSlot(this.context) | ||
this.callLifecycleProperty('onMounted', route) | ||
}, | ||
callLifecycleProperty(method, ...params) { | ||
const attr = getAttribute(attributes, method) | ||
if (attr) attr(...params) | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,8 @@ | ||
<route-hoc> | ||
<template if={state.route}> | ||
<slot route={state.route}/> | ||
</template> | ||
|
||
<script> | ||
import {route, toRegexp, match, router, createURLStreamPipe} from '../index.js' | ||
import getCurrentRoute from '../get-current-route.js' | ||
import {getLocation} from '../util.js' | ||
import compose from 'cumpa' | ||
const getInitialRouteValue = (pathToRegexp, path, options) => { | ||
const route = compose( | ||
...createURLStreamPipe(pathToRegexp, options).reverse() | ||
)(path) | ||
return route.params ? route : null | ||
} | ||
export default { | ||
onBeforeMount(props) { | ||
const currentRoute = getCurrentRoute() | ||
const pathToRegexp = toRegexp(props.path, [], props) | ||
this.state = { | ||
pathToRegexp, | ||
route: currentRoute && match(currentRoute, pathToRegexp) ? | ||
getInitialRouteValue(pathToRegexp, currentRoute, props) : | ||
null | ||
} | ||
router.on.value(this.onBeforeRoute) | ||
this.stream = route(props.path, props).on.value(this.onRoute) | ||
}, | ||
onBeforeRoute(path, pathToRegexp) { | ||
if (this.state.route && !match(path, this.state.pathToRegexp)) { | ||
this.callLifecycleProperty('onBeforeUnmount', route) | ||
this.update({ | ||
route: null | ||
}) | ||
this.callLifecycleProperty('onUnmounted', route) | ||
} | ||
}, | ||
onRoute(route) { | ||
const loc = getLocation() | ||
import { pure } from 'riot' | ||
import { routeHoc } from './route-hoc.js' | ||
this.callLifecycleProperty('onBeforeMount', route) | ||
this.update({route}) | ||
// make browser scroll to fragment | ||
if (route.hash && loc.hash !== route.hash) loc.hash = route.hash | ||
this.callLifecycleProperty('onMounted', route) | ||
}, | ||
callLifecycleProperty(method, ...params) { | ||
if (this.props[method]) this.props[method](...params) | ||
}, | ||
onUnmounted() { | ||
router.off.value(this.onBeforeRoute) | ||
this.stream.end() | ||
} | ||
} | ||
export default pure(routeHoc) | ||
</script> | ||
</route-hoc> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,7 @@ | ||
<router-hoc> | ||
<script> | ||
import { pure } from 'riot' | ||
import { routerHoc } from './router-hoc.js' | ||
export default pure(routerHoc) | ||
</script> | ||
<script> | ||
import { pure } from 'riot' | ||
import { routerHoc } from './router-hoc.js' | ||
export default pure(routerHoc) | ||
</script> | ||
</router-hoc> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters