UNPKG

3.67 kBJavaScriptView Raw
1import { r as registerInstance, c as getContext, h, g as getElement } from './stencilrouter-1307249c.js';
2import { A as ActiveRouter } from './chunk-cfc6485e.js';
3import { m as matchPath } from './chunk-8fc41abb.js';
4import './chunk-d2e78d53.js';
5
6const getUniqueId = () => {
7 return ((Math.random() * 10e16).toString().match(/.{4}/g) || []).join('-');
8};
9const getMatch = (pathname, url, exact) => {
10 return matchPath(pathname, {
11 path: url,
12 exact: exact,
13 strict: true
14 });
15};
16const isHTMLStencilRouteElement = (elm) => {
17 return elm.tagName === 'STENCIL-ROUTE';
18};
19class RouteSwitch {
20 constructor(hostRef) {
21 registerInstance(this, hostRef);
22 this.group = getUniqueId();
23 this.subscribers = [];
24 this.queue = getContext(this, "queue");
25 }
26 componentWillLoad() {
27 if (this.location != null) {
28 this.regenerateSubscribers(this.location);
29 }
30 }
31 async regenerateSubscribers(newLocation) {
32 if (newLocation == null) {
33 return;
34 }
35 let newActiveIndex = -1;
36 this.subscribers = Array.prototype.slice.call(this.el.children)
37 .filter(isHTMLStencilRouteElement)
38 .map((childElement, index) => {
39 const match = getMatch(newLocation.pathname, childElement.url, childElement.exact);
40 if (match && newActiveIndex === -1) {
41 newActiveIndex = index;
42 }
43 return {
44 el: childElement,
45 match: match
46 };
47 });
48 if (newActiveIndex === -1) {
49 return;
50 }
51 // Check if this actually changes which child is active
52 // then just pass the new match down if the active route isn't changing.
53 if (this.activeIndex === newActiveIndex) {
54 this.subscribers[newActiveIndex].el.match = this.subscribers[newActiveIndex].match;
55 return;
56 }
57 this.activeIndex = newActiveIndex;
58 // Set all props on the new active route then wait until it says that it
59 // is completed
60 const activeChild = this.subscribers[this.activeIndex];
61 if (this.scrollTopOffset) {
62 activeChild.el.scrollTopOffset = this.scrollTopOffset;
63 }
64 activeChild.el.group = this.group;
65 activeChild.el.match = activeChild.match;
66 activeChild.el.componentUpdated = (routeViewUpdatedOptions) => {
67 // After the new active route has completed then update visibility of routes
68 this.queue.write(() => {
69 this.subscribers.forEach((child, index) => {
70 child.el.componentUpdated = undefined;
71 if (index === this.activeIndex) {
72 return child.el.style.display = '';
73 }
74 if (this.scrollTopOffset) {
75 child.el.scrollTopOffset = this.scrollTopOffset;
76 }
77 child.el.group = this.group;
78 child.el.match = null;
79 child.el.style.display = 'none';
80 });
81 });
82 if (this.routeViewsUpdated) {
83 this.routeViewsUpdated(Object.assign({ scrollTopOffset: this.scrollTopOffset }, routeViewUpdatedOptions));
84 }
85 };
86 }
87 render() {
88 return (h("slot", null));
89 }
90 get el() { return getElement(this); }
91 static get watchers() { return {
92 "location": ["regenerateSubscribers"]
93 }; }
94}
95ActiveRouter.injectProps(RouteSwitch, [
96 'location',
97 'routeViewsUpdated'
98]);
99
100export { RouteSwitch as stencil_route_switch };