You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Router.svelte 1.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. <main>
  2. <svelte:component this={currentElement} {...currentProps} />
  3. </main>
  4. <script>
  5. export let routes;
  6. let routeMap = new Map();
  7. for (let route of routes) {
  8. let [descriptor, el] = route;
  9. let parts = descriptor.split("/:");
  10. let props = parts.slice(1);
  11. let base = parts[0] + "@" + props.length;
  12. routeMap.set(base, {props, el});
  13. }
  14. let currentElement = null;
  15. let currentProps = null;
  16. function route() {
  17. let path = location.hash.substr(1);
  18. if (path[0] != "/") {
  19. console.error("Illegal path:", path);
  20. path = "/";
  21. } else if (path == "") {
  22. path = "/";
  23. }
  24. let parts = path.split("/").filter(el => el != "");
  25. let base = "/" + parts.join("/") + "@0";
  26. let propVals = [];
  27. let route = routeMap.get(base);
  28. // Check if we match anything, removing one path component every iteration
  29. while (route == null && parts.length > 0) {
  30. propVals.push(parts.pop());
  31. base = "/" + parts.join("/") + "@" + propVals.length;
  32. route = routeMap.get(base);
  33. }
  34. if (route == null) {
  35. console.warn("No route matches", path);
  36. route = routeMap.get("/@0");
  37. }
  38. let props = {};
  39. for (let propName of route.props) {
  40. props[propName] = propVals.pop();
  41. }
  42. currentElement = route.el;
  43. currentProps = props;
  44. }
  45. route();
  46. window.addEventListener("hashchange", route);
  47. </script>