Browse Source

rewrite in Svelte v3

master
Conduitry 1 year ago
parent
commit
86a584ddfa
3 changed files with 47 additions and 82 deletions
  1. +7
    -6
      src/components/Redirect.html
  2. +8
    -36
      src/components/Route.html
  3. +32
    -40
      src/components/Router.html

+ 7
- 6
src/components/Redirect.html View File

@ -1,8 +1,9 @@
<script>
export default {
oncreate() {
let { r: { router }, to, push } = this.get()
router.go(to, !push)
},
}
export let to, push;
import { ROUTER } from './Router.html';
import { getContext } from 'svelte';
const { go } = getContext(ROUTER);
go(to, push);
</script>

+ 8
- 36
src/components/Route.html View File

@ -1,40 +1,12 @@
<div ref:mount/>
<script>
import matchPath from '../utils/matchPath.js';
export let path, exact;
export default {
oncreate() {
this.observe('r', update.bind(this))
this.observe('path', update.bind(this))
},
}
import { ROUTER } from './Router.html';
import matchPath from '../utils/matchPath.js';
import { getContext } from 'svelte';
function update() {
let {
r: { match, pathname, router } = {},
path,
exact,
component,
} = this.get()
let { _r } = this
if (path) {
let match = matchPath(pathname, { path, exact })
if (match) {
if (_r) {
_r.set({ match, r: { match, pathname, router } })
} else {
_r = new component({ target: this.refs.mount, data: { match, r: { match, pathname, router } } })
}
} else if (_r) {
_r.destroy()
_r = null
}
} else if (_r) {
_r.set({ match, r: { match, pathname, router } })
} else {
_r = new component({ target: this.refs.mount, data: { match, r: { match, pathname, router } } })
}
this._r = _r
}
const { pathname } = getContext(ROUTER);
let match; $: match = path && matchPath($pathname, { path, exact });
</script>
{#if match}<slot {match}/>{/if}

+ 32
- 40
src/components/Router.html View File

@ -1,47 +1,39 @@
{{yield}}
<script context='module'>
export const ROUTER = {};
</script>
<script>
export default {
oncreate() {
document.addEventListener('click', clickHandler.bind(this))
window.addEventListener('popstate', popHandler.bind(this))
this.set({ r: { router: this, pathname: document.location.pathname } })
},
methods: {
go(url, replace) {
history[replace ? 'replaceState' : 'pushState'](null, '', location.origin + url)
let r = this.get('r')
r.pathname = url
this.set({ r })
},
},
}
import { setContext, onDestroy } from 'svelte';
import { writable } from 'svelte/store';
function clickHandler(event) {
if (event.ctrlKey || event.metaKey || event.shiftKey || event.which !== 1) {
return
}
let elm = event.target
while (elm.nodeName !== 'A') {
elm = elm.parentElement
if (!elm) {
return
const pathname = writable(document.location.pathname);
const go = (url, replace) => {
history[replace ? 'replaceState' : 'pushState'](null, '', location.origin + url);
pathname.set(url);
};
setContext(ROUTER, { pathname, go });
const clickHandler = event => {
if (!event.ctrlKey && !event.metaKey && !event.shiftKey && event.which === 1) {
const elm = event.target.closest('a');
if (elm && !elm.target) {
const url = elm.href;
if (url.startsWith(document.location.origin + '/')) {
event.preventDefault();
go(url.slice(document.location.origin.length));
}
}
}
if (elm.target) {
return
}
let url = elm.href
if (!url.startsWith(document.location.origin + '/')) {
return
}
event.preventDefault()
this.go(url.slice(document.location.origin.length))
}
};
document.addEventListener('click', clickHandler);
const popstateHandler = () => pathname.set(document.location.pathname);
window.addEventListener('popstate', popstateHandler);
function popHandler() {
let r = this.get('r')
r.pathname = document.location.pathname
this.set({ r })
}
onDestroy(() => {
document.removeEventListener('click', clickHandler);
window.removeEventListener('popstate', popstateHandler);
});
</script>
<slot/>

Loading…
Cancel
Save