| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 |  
 
 
 
 
 
 
1×
 
18×
 
 
18×
18×
18×
 
 
 
 
18×
18×
 
 
 
9×
9×
 
5×
5×
1×
 
 
 
 
5×
 
5×
 
9×
2×
2×
 
 
 
 
 
 
 
18×
 
8×
1×
 
7×
7×
7×
 
 
7×
7×
7×
 
7×
1×
 
 
 
1×
 
6×
 
 
 
 
 
 
1×
 
 
 
18×
 
1×
1×
1×
1×
1×
 
 
 
 
 
 
 
1×
19×
 
19×
 
 
 
19×
 
 
 
18×
 
 
 
18×
 
 
 
 
 
1×
 
 
 
1×
 
 
 
  | import angular from 'angular';
 
const [handlingStateChangeError, hasOtherwise, stateCounts] = [
    Symbol(), Symbol(), Symbol()
];
 
class RouterHelper {
    constructor (config, $stateProvider, $urlRouterProvider,
        $rootScope, $state, Logger, Resolve) {
        Object.assign(this, {config, $stateProvider, $urlRouterProvider,
            $rootScope, $state, Logger, Resolve});
        // private variable
        this[handlingStateChangeError] = false;
        this[hasOtherwise] = false;
        this[stateCounts] = {
            errors: 0,
            changes: 0
        };
 
        this.handleRoutingErrors();
        this.updateDocTitle();
    }
 
    configureStates (states, otherwisePath) {
        const self = this;
        states.forEach((state) => {
            // add login check if requireLogin is true
            const data = state.config.data;
            if (data && data.requireLogin === true) {
                state.config.resolve = angular.extend(
                    state.config.resolve || {},
                    {loginResolve: self.Resolve.login}
                );
            }
            state.config.resolve =
                angular.extend(state.config.resolve || {}, self.config.resolveAlways);
            this.$stateProvider.state(state.state, state.config);
        });
        if (otherwisePath && !this[hasOtherwise]) {
            this[hasOtherwise] = true;
            this.$urlRouterProvider.otherwise(otherwisePath);
        }
    }
 
    handleRoutingErrors () {
        // Route cancellation:
        // On routing error, go to the dashboard.
        // Provide an exit clause if it tries to do it twice.
        this.$rootScope.$on('$stateChangeError',
            (event, toState, toParams, fromState, fromParams, error) => {
                if (this[handlingStateChangeError]) {
                    return;
                }
                this[stateCounts].errors++;
                this[handlingStateChangeError] = true;
                const destination = (toState &&
                    (toState.title || toState.name || toState.loadedTemplateUrl)) ||
                    'unknown target';
                const errorMessage = (error && error.message) || error;
                const msg = `Error routing to ${destination}.\nReason: ${errorMessage}.`;
                this.Logger.warning(msg);
                // handle requireLogin issue
                if (error === 'requireLogin') {
                    this.$state.prev = {
                        state: toState.name,
                        params: toParams
                    };
                    this.$state.go('root.layout.login');
                } else {
                    this.$state.go('root.layout.home');
                }
            }
        );
    }
 
    getStates () {
        return this.$state.get();
    }
 
    updateDocTitle () {
        this.$rootScope.$on('$stateChangeSuccess',
            (event, toState) => {
                this[stateCounts].changes++;
                this[handlingStateChangeError] = false;
                const title = `${toState.data.title} - ${this.config.mainTitle}`;
                this.$rootScope.title = title; // data bind to <title>
                this.$rootScope._class = toState.data._class; // data bind to <body>
            }
        );
    }
}
 
// Help configure the state-base ui.router
class RouterHelperProvider {
    constructor ($locationProvider, $stateProvider, $urlRouterProvider) {
        Object.assign(this, {$locationProvider, $stateProvider, $urlRouterProvider});
 
        this.config = {
            mainTitle: '',
            resolveAlways: {}
        };
        this.$locationProvider.html5Mode(true);
    }
 
    configure (cfg) {
        angular.extend(this.config, cfg);
    }
 
    $get ($rootScope, $state, Logger, Resolve) {
        return new RouterHelper(
            this.config, this.$stateProvider, this.$urlRouterProvider,
            $rootScope, $state, Logger, Resolve);
    }
}
 
RouterHelperProvider.prototype.$get.$inject = [
    '$rootScope', '$state', 'Logger', 'Resolve'
];
 
RouterHelperProvider.$inject = ['$locationProvider', '$stateProvider', '$urlRouterProvider'];
 
export default RouterHelperProvider;
 
  |