|
2 | 2 | import {extend, inherit, isString, pluck, equalForKeys, abstractKey} from "../common/common";
|
3 | 3 | import {StateDeclaration} from "./interface";
|
4 | 4 | import {State} from "./module";
|
| 5 | +import {StateBuilder} from "./stateBuilder"; |
| 6 | +import {StateService} from "./interface"; |
5 | 7 |
|
6 |
| -export function StateQueueManager(states, builder, $urlRouterProvider, $state) { |
7 |
| - let queue = []; |
| 8 | +export class StateQueueManager { |
| 9 | + queue: State[]; |
8 | 10 |
|
9 |
| - let queueManager = extend(this, { |
10 |
| - register: function(config: StateDeclaration, pre?: boolean) { |
11 |
| - // Wrap a new object around the state so we can store our private details easily. |
12 |
| - // @TODO: state = new State(extend({}, config, { ... })) |
13 |
| - let state = inherit(new State(), extend({}, config, { |
14 |
| - self: config, |
15 |
| - resolve: config.resolve || {}, |
16 |
| - toString: () => config.name |
17 |
| - })); |
| 11 | + constructor( |
| 12 | + public states: { [key: string]: State; }, |
| 13 | + public builder: StateBuilder, |
| 14 | + public $urlRouterProvider, |
| 15 | + public $state: StateService) { |
| 16 | + this.queue = []; |
| 17 | + } |
18 | 18 |
|
19 |
| - if (!isString(state.name)) throw new Error("State must have a valid name"); |
20 |
| - if (states.hasOwnProperty(state.name) || pluck(queue, 'name').indexOf(state.name) !== -1) |
21 |
| - throw new Error(`State '${state.name}' is already defined`); |
| 19 | + register(config: StateDeclaration, pre?: boolean) { |
| 20 | + let {states, queue, $state} = this; |
| 21 | + // Wrap a new object around the state so we can store our private details easily. |
| 22 | + // @TODO: state = new State(extend({}, config, { ... })) |
| 23 | + let state = inherit(new State(), extend({}, config, { |
| 24 | + self: config, |
| 25 | + resolve: config.resolve || {}, |
| 26 | + toString: () => config.name |
| 27 | + })); |
22 | 28 |
|
23 |
| - queue[pre ? "unshift" : "push"](state); |
| 29 | + if (!isString(state.name)) throw new Error("State must have a valid name"); |
| 30 | + if (states.hasOwnProperty(state.name) || pluck(queue, 'name').indexOf(state.name) !== -1) |
| 31 | + throw new Error(`State '${state.name}' is already defined`); |
24 | 32 |
|
25 |
| - if (queueManager.autoFlush) { |
26 |
| - queueManager.flush($state); |
27 |
| - } |
28 |
| - return state; |
29 |
| - }, |
| 33 | + queue[pre ? "unshift" : "push"](state); |
30 | 34 |
|
31 |
| - flush: function($state) { |
32 |
| - let result, state, orphans = [], orphanIdx, previousQueueLength = {}; |
| 35 | + if (this.autoFlush) { |
| 36 | + this.flush($state); |
| 37 | + } |
| 38 | + return state; |
| 39 | + } |
33 | 40 |
|
34 |
| - while (queue.length > 0) { |
35 |
| - state = queue.shift(); |
36 |
| - result = builder.build(state); |
37 |
| - orphanIdx = orphans.indexOf(state); |
| 41 | + flush($state) { |
| 42 | + let {queue, states, builder} = this; |
| 43 | + let result, state, orphans = [], orphanIdx, previousQueueLength = {}; |
38 | 44 |
|
39 |
| - if (result) { |
40 |
| - if (states.hasOwnProperty(state.name)) |
41 |
| - throw new Error(`State '${name}' is already defined`); |
42 |
| - states[state.name] = state; |
43 |
| - this.attachRoute($state, state); |
44 |
| - if (orphanIdx >= 0) orphans.splice(orphanIdx, 1); |
45 |
| - continue; |
46 |
| - } |
| 45 | + while (queue.length > 0) { |
| 46 | + state = queue.shift(); |
| 47 | + result = builder.build(state); |
| 48 | + orphanIdx = orphans.indexOf(state); |
47 | 49 |
|
48 |
| - let prev = previousQueueLength[state.name]; |
49 |
| - previousQueueLength[state.name] = queue.length; |
50 |
| - if (orphanIdx >= 0 && prev === queue.length) { |
51 |
| - // Wait until two consecutive iterations where no additional states were dequeued successfully. |
52 |
| - throw new Error(`Cannot register orphaned state '${state.name}'`); |
53 |
| - } else if (orphanIdx < 0) { |
54 |
| - orphans.push(state); |
55 |
| - } |
| 50 | + if (result) { |
| 51 | + if (states.hasOwnProperty(state.name)) |
| 52 | + throw new Error(`State '${name}' is already defined`); |
| 53 | + states[state.name] = state; |
| 54 | + this.attachRoute($state, state); |
| 55 | + if (orphanIdx >= 0) orphans.splice(orphanIdx, 1); |
| 56 | + continue; |
| 57 | + } |
56 | 58 |
|
57 |
| - queue.push(state); |
| 59 | + let prev = previousQueueLength[state.name]; |
| 60 | + previousQueueLength[state.name] = queue.length; |
| 61 | + if (orphanIdx >= 0 && prev === queue.length) { |
| 62 | + // Wait until two consecutive iterations where no additional states were dequeued successfully. |
| 63 | + throw new Error(`Cannot register orphaned state '${state.name}'`); |
| 64 | + } else if (orphanIdx < 0) { |
| 65 | + orphans.push(state); |
58 | 66 | }
|
59 |
| - return states; |
60 |
| - }, |
61 | 67 |
|
62 |
| - autoFlush: false, |
| 68 | + queue.push(state); |
| 69 | + } |
| 70 | + return states; |
| 71 | + } |
63 | 72 |
|
64 |
| - attachRoute: function($state, state) { |
65 |
| - if (state[abstractKey] || !state.url) return; |
| 73 | + autoFlush: boolean = false; |
66 | 74 |
|
67 |
| - $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) { |
68 |
| - if ($state.$current.navigable !== state || !equalForKeys($match, $stateParams)) { |
69 |
| - $state.transitionTo(state, $match, { inherit: true, location: false }); |
70 |
| - } |
71 |
| - }]); |
72 |
| - } |
73 |
| - }); |
| 75 | + attachRoute($state, state) { |
| 76 | + let {$urlRouterProvider} = this; |
| 77 | + if (state[abstractKey] || !state.url) return; |
| 78 | + |
| 79 | + $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) { |
| 80 | + if ($state.$current.navigable !== state || !equalForKeys($match, $stateParams)) { |
| 81 | + $state.transitionTo(state, $match, { inherit: true, location: false }); |
| 82 | + } |
| 83 | + }]); |
| 84 | + } |
74 | 85 | }
|
0 commit comments