-
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.
- Loading branch information
1 parent
17e7eac
commit cdfcc06
Showing
4 changed files
with
114 additions
and
96 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ extends: eslint-config-riot | |
|
||
rules: | ||
fp/no-mutating-methods: 0 | ||
fp/no-rest-parameters: 0 |
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,105 @@ | ||
import { router } from '../index.js' | ||
import { defer, cancelDefer, getAttribute } from '../util.js' | ||
import { __ } from 'riot' | ||
import getCurrentRoute from '../get-current-route.js' | ||
import setBase from '../set-base.js' | ||
import { panic } from '@riotjs/util/misc' | ||
import initDomListeners from '../dom.js' | ||
|
||
const BASE_ATTRIBUTE_NAME = 'base' | ||
const INITIAL_ROUTE = 'initialRoute' | ||
const ON_STARTED_ATTRIBUTE_NAME = 'onStarted' | ||
const { template, bindingTypes } = __.DOMBindings | ||
|
||
export function routerHoc({ slots, attributes, props }) { | ||
if (routerHoc.wasInitialized) | ||
panic('Multiple <router> components are not supported') | ||
|
||
return { | ||
slot: null, | ||
el: null, | ||
teardown: null, | ||
mount(el, context) { | ||
const initialRouteAttr = getAttribute(attributes, INITIAL_ROUTE) | ||
const initialRoute = initialRouteAttr | ||
? initialRouteAttr.evaluate(context) | ||
: null | ||
const currentRoute = getCurrentRoute() | ||
const onFirstRoute = () => { | ||
this.createSlot(context) | ||
router.off.value(onFirstRoute) | ||
} | ||
routerHoc.wasInitialized = true | ||
|
||
this.el = el | ||
this.teardown = initDomListeners(this.root) | ||
|
||
this.setBase(context) | ||
|
||
// mount the slots only if the current route was defined | ||
if (currentRoute && !initialRoute) { | ||
this.createSlot(context) | ||
} else { | ||
router.on.value(onFirstRoute) | ||
router.push(initialRoute || window.location.href) | ||
} | ||
}, | ||
createSlot(context) { | ||
if (!slots || !slots.length) return | ||
const onStartedAttr = getAttribute(attributes, ON_STARTED_ATTRIBUTE_NAME) | ||
|
||
this.slot = template(null, [ | ||
{ | ||
type: bindingTypes.SLOT, | ||
name: 'default', | ||
}, | ||
]) | ||
|
||
this.slot.mount( | ||
this.el, | ||
{ | ||
slots, | ||
}, | ||
context, | ||
) | ||
|
||
if (onStartedAttr) { | ||
onStartedAttr.evaluate(context)(getCurrentRoute()) | ||
} | ||
}, | ||
update(context) { | ||
this.setBase(context) | ||
|
||
// defer the updates to avoid internal recursive update calls | ||
// see https://github.com/riot/route/issues/148 | ||
if (this.slot) { | ||
cancelDefer(this.deferred) | ||
|
||
this.deferred = defer(() => { | ||
this.slot.update({}, context) | ||
}) | ||
} | ||
}, | ||
unmount(...args) { | ||
this.teardown() | ||
routerHoc.wasInitialized = false | ||
|
||
if (this.slot) { | ||
this.slot.unmount(...args) | ||
} | ||
}, | ||
getBase(context) { | ||
const baseAttr = getAttribute(attributes, BASE_ATTRIBUTE_NAME) | ||
|
||
return baseAttr | ||
? baseAttr.evaluate(context) | ||
: this.el.getAttribute(BASE_ATTRIBUTE_NAME) || '/' | ||
}, | ||
setBase(context) { | ||
setBase(props ? props.base : this.getBase(context)) | ||
}, | ||
} | ||
} | ||
|
||
// flag to avoid multiple router instances | ||
routerHoc.wasInitialized = false |
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,101 +1,8 @@ | ||
<router-hoc> | ||
<script> | ||
import {router} from '../index.js' | ||
import {defer, cancelDefer} from '../util.js' | ||
import {pure, __} from 'riot' | ||
import getCurrentRoute from '../get-current-route.js' | ||
import setBase from '../set-base.js' | ||
import {panic} from '@riotjs/util/misc' | ||
import {dashToCamelCase} from '@riotjs/util/strings' | ||
import initDomListeners from '../dom.js' | ||
import { pure } from 'riot' | ||
import { routerHoc } from './router-hoc.js' | ||
const BASE_ATTRIBUTE_NAME = 'base' | ||
const INITIAL_ROUTE = 'initialRoute' | ||
const ON_STARTED_ATTRIBUTE_NAME = 'onStarted' | ||
const {template, bindingTypes} = __.DOMBindings | ||
let wasInitialized = false | ||
export default pure(({slots, attributes, props}) => { | ||
if (wasInitialized) panic('Multiple <router> components are not supported') | ||
const getAttribute = name => attributes && attributes.find(a => dashToCamelCase(a.name) === name) | ||
return { | ||
slot: null, | ||
el: null, | ||
teardown: null, | ||
mount(el, context) { | ||
const initialRouteAttr = getAttribute(INITIAL_ROUTE) | ||
const initialRoute = initialRouteAttr ? initialRouteAttr.evaluate(context) : null | ||
const currentRoute = getCurrentRoute() | ||
const onFirstRoute = () => { | ||
this.createSlot(context) | ||
router.off.value(onFirstRoute) | ||
} | ||
wasInitialized = true | ||
this.el = el | ||
this.teardown = initDomListeners(this.root) | ||
this.setBase(context) | ||
// mount the slots only if the current route was defined | ||
if (currentRoute && !initialRoute) { | ||
this.createSlot(context) | ||
} else { | ||
router.on.value(onFirstRoute) | ||
router.push(initialRoute || window.location.href) | ||
} | ||
}, | ||
createSlot(context) { | ||
if (!slots || !slots.length) return | ||
const onStartedAttr = getAttribute(ON_STARTED_ATTRIBUTE_NAME) | ||
this.slot = template(null, [{ | ||
type: bindingTypes.SLOT, | ||
name: 'default' | ||
}]) | ||
this.slot.mount(this.el, { | ||
slots | ||
}, context) | ||
if (onStartedAttr) { | ||
onStartedAttr.evaluate(context)(getCurrentRoute()) | ||
} | ||
}, | ||
update(context) { | ||
this.setBase(context) | ||
// defer the updates to avoid internal recursive update calls | ||
// see https://github.com/riot/route/issues/148 | ||
if (this.slot) { | ||
cancelDefer(this.deferred) | ||
this.deferred = defer(() => { | ||
this.slot.update({}, context) | ||
}) | ||
} | ||
}, | ||
unmount(...args) { | ||
this.teardown() | ||
wasInitialized = false | ||
if (this.slot) { | ||
this.slot.unmount(...args) | ||
} | ||
}, | ||
getBase(context) { | ||
const baseAttr = getAttribute(BASE_ATTRIBUTE_NAME) | ||
return baseAttr ? baseAttr.evaluate(context) : this.el.getAttribute(BASE_ATTRIBUTE_NAME) || '/' | ||
}, | ||
setBase(context) { | ||
setBase(props ? props.base : this.getBase(context)) | ||
} | ||
} | ||
}) | ||
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