Skip to content
Snippets Groups Projects
Select Git revision
  • 872fc610722662c5539c3ac8e1b060d6783d9381
  • main default protected
  • demo protected
  • master
  • icon-set-mapping
  • production protected
  • revert-62666d1a
  • favorites-and-recent-files
  • lit2
  • wc-part
  • mark-downloaded-files
  • feature/annotpdf-test
  • fix-zip-upload
  • config-cleanup
  • wip
  • app-shell-update
16 results

router.js

Blame
  • router.js 4.19 KiB
    import UniversalRouter from 'universal-router';
    import generateUrls from 'universal-router/generateUrls';
    
    /**
     * A wrapper around UniversalRouter which adds history integration
     */
    export class Router {
    
        /**
         * @param {Array} routes The routes passed to UniversalRouter
         * @param {object} options Options
         * @param {string} options.routeName The main route name
         * @param {Function} options.getState Function which should return the current state
         * @param {Function} options.setState Function which gets passed the new state based on the route
         * @param {object} unioptions options passed to UniversalRouter
         */
        constructor(routes, options, unioptions) {
            this.getState = options.getState;
            this.setState = options.setState;
            // XXX: We only have one route atm
            // If we need more we need to pass the route name to each function
            this.routeName = options.routeName;
    
            console.assert(this.getState);
            console.assert(this.setState);
            console.assert(this.routeName);
    
            // https://github.com/kriasoft/universal-router
            this.router = new UniversalRouter(routes, unioptions);
    
            window.addEventListener('popstate', (event) => {
                this.setStateFromCurrentLocation();
                this.dispatchLocationChanged();
            });
        }
    
        /**
         * In case something else has changed the location, update the app state accordingly.
         */
        setStateFromCurrentLocation() {
            const oldPathName = location.pathname;
            this.router.resolve({pathname: oldPathName}).then(page => {
                const newPathname = this.getPathname(page);
                // In case of a router redirect, set the new location
                if (newPathname !== oldPathName) {
                    const referrerUrl = location.href;
                    window.history.replaceState({}, '', newPathname);
                    this.dispatchLocationChanged(referrerUrl);
                }
                this.setState(page);
            }).catch((e) => {
                // In case we can't resolve the location, just leave things as is.
                // This happens when a user enters a wrong URL or when testing with karma.
            });
        }
    
        /**
         * Update the router after some internal state change.
         */
        update() {
            // Queue updates so we can call this multiple times when changing state
            // without it resulting in multiple location changes
            setTimeout(() => {
                const newPathname = this.getPathname();
                const oldPathname = location.pathname;
                if (newPathname === oldPathname)
                    return;
                const referrerUrl = location.href;
                window.history.pushState({}, '', newPathname);
                this.dispatchLocationChanged(referrerUrl);