Files
sage/resources/assets/scripts/util/Router.js
Tor Morten Jensen 8f039f1944 Dispatch event when firing routes
It is especially neat when importing the scripts from the parent theme in a child theme. In one of my themes I do it like this:

```js
// routes.js
import home from './routes/home'

export default {
    home: {
      init() {
        console.log('Home route fired.')
      }
    }
}
```

  ```js
// main.js
/**
 * Parent Themes Script
 */
import '../../../../core-theme/resources/assets/scripts/main';

/**
 * Internal modules
 */
import routes from './routes'

/**
 * Hook in to the parent themes router
 */
document.addEventListener('routed', e => {
  let route = e.detail.route,
    fn = e.detail.fn;

  if (routes[route] && typeof routes[route][fn] === 'function') {
    routes[route][fn]();
  }
});
```
2018-06-20 14:08:10 +02:00

72 lines
1.8 KiB
JavaScript

import camelCase from './camelCase';
/**
* DOM-based Routing
*
* Based on {@link http://goo.gl/EUTi53|Markup-based Unobtrusive Comprehensive DOM-ready Execution} by Paul Irish
*
* The routing fires all common scripts, followed by the page specific scripts.
* Add additional events for more control over timing e.g. a finalize event
*/
class Router {
/**
* Create a new Router
* @param {Object} routes
*/
constructor(routes) {
this.routes = routes;
}
/**
* Fire Router events
* @param {string} route DOM-based route derived from body classes (`<body class="...">`)
* @param {string} [event] Events on the route. By default, `init` and `finalize` events are called.
* @param {string} [arg] Any custom argument to be passed to the event.
*/
fire(route, event = 'init', arg) {
document.dispatchEvent(new CustomEvent('routed', {
bubbles: true,
detail: {
route,
fn
}
}));
const fire = route !== '' && this.routes[route] && typeof this.routes[route][event] === 'function';
if (fire) {
this.routes[route][event](arg);
}
}
/**
* Automatically load and fire Router events
*
* Events are fired in the following order:
* * common init
* * page-specific init
* * page-specific finalize
* * common finalize
*/
loadEvents() {
// Fire common init JS
this.fire('common');
// Fire page-specific init JS, and then finalize JS
document.body.className
.toLowerCase()
.replace(/-/g, '_')
.split(/\s+/)
.map(camelCase)
.forEach((className) => {
this.fire(className);
this.fire(className, 'finalize');
});
// Fire common finalize JS
this.fire('common', 'finalize');
}
}
export default Router