cleanup semicolon from js
This commit is contained in:
130
js/router.js
130
js/router.js
@@ -1,155 +1,155 @@
|
||||
class Router {
|
||||
constructor() {
|
||||
this.routes = new Map();
|
||||
this.currentRoute = null;
|
||||
this.outlet = null;
|
||||
this.beforeNavigate = null;
|
||||
this.afterNavigate = null;
|
||||
this.routes = new Map()
|
||||
this.currentRoute = null
|
||||
this.outlet = null
|
||||
this.beforeNavigate = null
|
||||
this.afterNavigate = null
|
||||
|
||||
window.addEventListener('hashchange', () => this.handleRouteChange());
|
||||
window.addEventListener('hashchange', () => this.handleRouteChange())
|
||||
}
|
||||
|
||||
setOutlet(element) {
|
||||
this.outlet = element;
|
||||
this.outlet = element
|
||||
}
|
||||
|
||||
register(path, componentTag) {
|
||||
this.routes.set(path, componentTag);
|
||||
return this;
|
||||
this.routes.set(path, componentTag)
|
||||
return this
|
||||
}
|
||||
|
||||
parseHash() {
|
||||
const hash = window.location.hash.slice(1) || '/';
|
||||
const [path, queryString] = hash.split('?');
|
||||
const params = new URLSearchParams(queryString || '');
|
||||
const hash = window.location.hash.slice(1) || '/'
|
||||
const [path, queryString] = hash.split('?')
|
||||
const params = new URLSearchParams(queryString || '')
|
||||
|
||||
return { path, params: Object.fromEntries(params) };
|
||||
return { path, params: Object.fromEntries(params) }
|
||||
}
|
||||
|
||||
matchRoute(path) {
|
||||
if (this.routes.has(path)) {
|
||||
return { componentTag: this.routes.get(path), params: {} };
|
||||
return { componentTag: this.routes.get(path), params: {} }
|
||||
}
|
||||
|
||||
for (const [routePath, componentTag] of this.routes) {
|
||||
const routeParts = routePath.split('/');
|
||||
const pathParts = path.split('/');
|
||||
const routeParts = routePath.split('/')
|
||||
const pathParts = path.split('/')
|
||||
|
||||
if (routeParts.length !== pathParts.length) continue;
|
||||
if (routeParts.length !== pathParts.length) continue
|
||||
|
||||
const params = {};
|
||||
let match = true;
|
||||
const params = {}
|
||||
let match = true
|
||||
|
||||
for (let i = 0; i < routeParts.length; i++) {
|
||||
if (routeParts[i].startsWith(':')) {
|
||||
params[routeParts[i].slice(1)] = pathParts[i];
|
||||
params[routeParts[i].slice(1)] = pathParts[i]
|
||||
} else if (routeParts[i] !== pathParts[i]) {
|
||||
match = false;
|
||||
break;
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
return { componentTag, params };
|
||||
return { componentTag, params }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
async handleRouteChange() {
|
||||
const { path, params: queryParams } = this.parseHash();
|
||||
const match = this.matchRoute(path);
|
||||
const { path, params: queryParams } = this.parseHash()
|
||||
const match = this.matchRoute(path)
|
||||
|
||||
if (this.beforeNavigate) {
|
||||
const shouldContinue = await this.beforeNavigate(path);
|
||||
if (!shouldContinue) return;
|
||||
const shouldContinue = await this.beforeNavigate(path)
|
||||
if (!shouldContinue) return
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
this.renderNotFound();
|
||||
return;
|
||||
this.renderNotFound()
|
||||
return
|
||||
}
|
||||
|
||||
const { componentTag, params: routeParams } = match;
|
||||
const { componentTag, params: routeParams } = match
|
||||
|
||||
this.currentRoute = {
|
||||
path,
|
||||
params: { ...routeParams, ...queryParams },
|
||||
componentTag
|
||||
};
|
||||
}
|
||||
|
||||
this.render();
|
||||
this.render()
|
||||
|
||||
if (this.afterNavigate) {
|
||||
this.afterNavigate(this.currentRoute);
|
||||
this.afterNavigate(this.currentRoute)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.outlet || !this.currentRoute) return;
|
||||
if (!this.outlet || !this.currentRoute) return
|
||||
|
||||
const { componentTag, params } = this.currentRoute;
|
||||
const oldComponent = this.outlet.firstElementChild;
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
const { componentTag, params } = this.currentRoute
|
||||
const oldComponent = this.outlet.firstElementChild
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||
|
||||
const component = document.createElement(componentTag);
|
||||
const component = document.createElement(componentTag)
|
||||
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
component.setAttribute(`data-${key}`, value);
|
||||
});
|
||||
component.setAttribute(`data-${key}`, value)
|
||||
})
|
||||
|
||||
if (prefersReducedMotion || !oldComponent) {
|
||||
if (oldComponent) oldComponent.remove();
|
||||
this.outlet.appendChild(component);
|
||||
return;
|
||||
if (oldComponent) oldComponent.remove()
|
||||
this.outlet.appendChild(component)
|
||||
return
|
||||
}
|
||||
|
||||
component.classList.add('animate__animated', 'animate__fadeIn', 'animate__faster');
|
||||
oldComponent.classList.add('animate__animated', 'animate__fadeOut', 'animate__faster');
|
||||
component.classList.add('animate__animated', 'animate__fadeIn', 'animate__faster')
|
||||
oldComponent.classList.add('animate__animated', 'animate__fadeOut', 'animate__faster')
|
||||
|
||||
const fallbackTimer = setTimeout(() => {
|
||||
oldComponent.remove();
|
||||
this.outlet.appendChild(component);
|
||||
}, 300);
|
||||
oldComponent.remove()
|
||||
this.outlet.appendChild(component)
|
||||
}, 300)
|
||||
|
||||
oldComponent.addEventListener('animationend', () => {
|
||||
clearTimeout(fallbackTimer);
|
||||
oldComponent.remove();
|
||||
this.outlet.appendChild(component);
|
||||
}, { once: true });
|
||||
clearTimeout(fallbackTimer)
|
||||
oldComponent.remove()
|
||||
this.outlet.appendChild(component)
|
||||
}, { once: true })
|
||||
}
|
||||
|
||||
renderNotFound() {
|
||||
if (!this.outlet) return;
|
||||
if (!this.outlet) return
|
||||
|
||||
this.outlet.innerHTML = '';
|
||||
const notFound = document.createElement('page-not-found');
|
||||
this.outlet.appendChild(notFound);
|
||||
this.outlet.innerHTML = ''
|
||||
const notFound = document.createElement('page-not-found')
|
||||
this.outlet.appendChild(notFound)
|
||||
}
|
||||
|
||||
navigate(path, params = {}) {
|
||||
let url = `#${path}`;
|
||||
let url = `#${path}`
|
||||
|
||||
if (Object.keys(params).length > 0) {
|
||||
const queryString = new URLSearchParams(params).toString();
|
||||
url += `?${queryString}`;
|
||||
const queryString = new URLSearchParams(params).toString()
|
||||
url += `?${queryString}`
|
||||
}
|
||||
|
||||
window.location.hash = url.slice(1);
|
||||
window.location.hash = url.slice(1)
|
||||
}
|
||||
|
||||
back() {
|
||||
window.history.back();
|
||||
window.history.back()
|
||||
}
|
||||
|
||||
forward() {
|
||||
window.history.forward();
|
||||
window.history.forward()
|
||||
}
|
||||
|
||||
getCurrentRoute() {
|
||||
return this.currentRoute;
|
||||
return this.currentRoute
|
||||
}
|
||||
}
|
||||
|
||||
export const router = new Router();
|
||||
export const router = new Router()
|
||||
|
||||
Reference in New Issue
Block a user