38 | * Creates the StateMachine instance, registers all the states
39 | * and registers the StateMachine with the IFacade.
40 | * @method inject
41 | * @return
42 | */
43 | FSMInjector.prototype.inject = function() {
44 | // Create the StateMachine
45 | var stateMachine = new puremvc.statemachine.StateMachine();
46 |
47 | // Register all the states with the StateMachine
48 | var states = this.getStates();
49 | for(var i=0; i
60 | * Creates and returns the array of State objects
61 | * from the FSM on first call, subsequently returns
62 | * the existing array.
63 | *
64 | * @method getStates
65 | * @return {Array} Array of States
66 | */
67 | FSMInjector.prototype.getStates = function() {
68 | if(this.stateList == null) {
69 | this.stateList = [];
70 |
71 | var stateDefs = this.fsm.state ? this.fsm.state : [];
72 | for(var i=0; iState instance from its JSON definition.
83 | * @method createState
84 | * @param {Object} stateDef JSON Object
85 | * @return {State}
86 | */
87 | FSMInjector.prototype.createState = function(stateDef) {
88 | // Create State object
89 | var name = stateDef['@name'];
90 | var exiting = stateDef['@exiting'];
91 | var entering = stateDef['@entering'];
92 | var changed = stateDef['@changed'];
93 | var state = new puremvc.statemachine.State(name, entering, exiting, changed);
94 |
95 | // Create transitions
96 | var transitions = stateDef.transition ? stateDef.transition : [];
97 | for(var i=0; i
10 | * Handles regisistration and removal of state definitions,
11 | * which include optional entry and exit commands for each
12 | * state.
13 | */
14 |
15 | /**
16 | * Constructor
17 | *
18 | * @method StateMachine
19 | * @return
20 | */
21 | function StateMachine() {
22 | puremvc.Mediator.call(this, StateMachine.NAME, null);
23 | this.states = {};
24 | }
25 |
26 | StateMachine.prototype = new puremvc.Mediator;
27 | StateMachine.prototype.constructor = StateMachine;
28 |
29 | /**
30 | * Transitions to initial state once registered with Facade
31 | * @method onRegister
32 | * @return
33 | */
34 | StateMachine.prototype.onRegister = function() {
35 | if(this.initial) this.transitionTo(this.initial, null);
36 | }
37 |
38 | /**
39 | * Registers the entry and exit commands for a given state.
40 | * @method registerState
41 | * @param {State} state the state to which to register the above commands
42 | * @param {boolean} initial boolean telling if this is the initial state of the system
43 | * @return
44 | */
45 | StateMachine.prototype.registerState = function(state, initial) {
46 | if(state == null || this.states[state.name] != null) return;
47 | this.states[state.name] = state;
48 | if(initial) this.initial = state;
49 | }
50 |
51 | /**
52 | * Remove a state mapping. Removes the entry and exit commands for a given state as well as the state mapping itself.
53 | * @method removeState
54 | * @param {string} stateName
55 | * @return
56 | */
57 | StateMachine.prototype.removeState = function(stateName) {
58 | var state = this.states[stateName];
59 | if(state == null) return;
60 | this.states[stateName] = null;
61 | }
62 |
63 | /**
64 | * Transitions to the given state from the current state.
65 | *
66 | * Sends the exiting notification for the current state
67 | * followed by the entering notification for the new state.
68 | * Once finally transitioned to the new state, the changed
69 | * notification for the new state is sent.
70 | *
71 | * If a data parameter is provided, it is included as the body of all
72 | * three state-specific transition notes.
73 | *
74 | * Finally, when all the state-specific transition notes have been
75 | * sent, a StateMachine.CHANGED note is sent, with the
76 | * new State object as the body and the name of the
77 | * new state in the type.
78 | *
79 | * @method transitionTo
80 | * @param {State} nextState the next State to transition to.
81 | * @param {Object} data is the optional Object that was sent in the StateMachine.ACTION notification body
82 | * @return
83 | */
84 | StateMachine.prototype.transitionTo = function(nextState, data) {
85 | // Going nowhere?
86 | if(nextState == null) return;
87 |
88 | // Clear the cancel flag
89 | this.canceled = false;
90 |
91 | // Exit the current State
92 | if(this.getCurrentState() && this.getCurrentState().exiting)
93 | this.sendNotification(this.getCurrentState().exiting, data, nextState.name);
94 |
95 | // Check to see whether the exiting guard has canceled the transition
96 | if(this.canceled) {
97 | this.canceled = false;
98 | return;
99 | }
100 |
101 | // Enter the next State
102 | if(nextState.entering)
103 | this.sendNotification(nextState.entering, data);
104 |
105 | // Check to see whether the entering guard has canceled the transition
106 | if(this.canceled) {
107 | this.canceled = false;
108 | return;
109 | }
110 |
111 | // change the current state only when both guards have been passed
112 | this.setCurrentState(nextState);
113 |
114 | // Send the notification configured to be sent when this specific state becomes current
115 | if(nextState.changed) {
116 | this.sendNotification(this.getCurrentState().changed, data);
117 | }
118 |
119 | // Notify the app generally that the state changed and what the new state is
120 | this.sendNotification(StateMachine.CHANGED, this.getCurrentState(), this.getCurrentState().name);
121 | }
122 |
123 | /**
124 | * Notification interests for the StateMachine.
125 | * @method listNotificationInterests
126 | * @return {Array} Array of Notifications
127 | */
128 | StateMachine.prototype.listNotificationInterests = function() {
129 | return [
130 | StateMachine.ACTION,
131 | StateMachine.CANCEL
132 | ];
133 | }
134 |
135 | /**
136 | * Handle notifications the StateMachine is interested in.
137 | *
138 | * StateMachine.ACTION: Triggers the transition to a new state.
139 | * StateMachine.CANCEL: Cancels the transition if sent in response to the exiting note for the current state.
140 | *
141 | * @method handleNotification
142 | * @param {Notification} notification
143 | * @return
144 | */
145 | StateMachine.prototype.handleNotification = function(notification) {
146 | switch(notification.getName()) {
147 | case StateMachine.ACTION:
148 | var action = notification.getType();
149 | var target = this.getCurrentState().getTarget(action);
150 | var newState = this.states[target];
151 | if(newState) this.transitionTo(newState, notification.getBody());
152 | break;
153 |
154 | case StateMachine.CANCEL:
155 | this.canceled = true;
156 | break;
157 | }
158 | }
159 |
160 | /**
161 | * Get the current state.
162 | * @method getCurrentState
163 | * @return a State defining the machine's current state
164 | */
165 | StateMachine.prototype.getCurrentState = function() {
166 | return this.viewComponent;
167 | }
168 |
169 | /**
170 | * Set the current state.
171 | * @method setCurrentState
172 | * @param {State} state
173 | * @return
174 | */
175 | StateMachine.prototype.setCurrentState = function(state) {
176 | this.viewComponent = state;
177 | }
178 |
179 | /**
180 | * Map of States objects by name.
181 | */
182 | StateMachine.prototype.states = null;
183 |
184 | /**
185 | * The initial state of the FSM.
186 | */
187 | StateMachine.prototype.initial = null;
188 |
189 | /**
190 | * The transition has been canceled.
191 | */
192 | StateMachine.prototype.canceled = null;
193 |
194 | StateMachine.NAME = "StateMachine";
195 |
196 | /**
197 | * Action Notification name.
198 | */
199 | StateMachine.ACTION = StateMachine.NAME + "/notes/action";
200 |
201 | /**
202 | * Changed Notification name
203 | */
204 | StateMachine.CHANGED = StateMachine.NAME + "/notes/changed";
205 |
206 | /**
207 | * Cancel Notification name
208 | */
209 | StateMachine.CANCEL = StateMachine.NAME + "/notes/cancel";
210 |
--------------------------------------------------------------------------------
/test/js/api/puremvc-1.0.1.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileOverview
3 | * PureMVC JS Native Port by David Foley, Frédéric Saunier, & Alain Duchesneau
4 | * Copyright(c) 2006-2012 Futurescale, Inc., Some rights reserved.
5 | * Reuse governed by Creative Commons Attribution 3.0
6 | * http://creativecommons.org/licenses/by/3.0/us/
7 | * @author david.foley@puremvc.org
8 | * returns registered Proxy and Mediator on onRegister
9 | * added queryString (@object) to Facade
10 | */
11 |
12 | (function(n){function i(a,d){this.setNotifyMethod(a);this.setNotifyContext(d)}function j(a,d,b){this.name=a;this.body=d;this.type=b}function k(){}function m(){}function l(){this.subCommands=[];this.initializeMacroCommand()}function g(a,d){this.mediatorName=a||this.constructor.NAME;this.viewComponent=d}function h(a,d){this.proxyName=a||this.constructor.NAME;null!=d&&this.setData(d)}function b(a){if(null!=b.instanceMap[a])throw Error(b.MULTITON_MSG);this.initializeNotifier(a);b.instanceMap[a]=this;
13 | this.initializeFacade();
14 | this.url=null;this.queryString={};var query=window.location.search.substring(1);var vars=query.split("&");for(var i=0;i
96 | * Handles regisistration and removal of state definitions,
97 | * which include optional entry and exit commands for each
98 | * state.
99 | */
100 |
101 | /**
102 | * Constructor
103 | *
104 | * @method StateMachine
105 | * @return
106 | */
107 | function StateMachine() {
108 | puremvc.Mediator.call(this, StateMachine.NAME, null);
109 | this.states = {};
110 | }
111 |
112 | StateMachine.prototype = new puremvc.Mediator;
113 | StateMachine.prototype.constructor = StateMachine;
114 |
115 | /**
116 | * Transitions to initial state once registered with Facade
117 | * @method onRegister
118 | * @return
119 | */
120 | StateMachine.prototype.onRegister = function() {
121 | if(this.initial) this.transitionTo(this.initial, null);
122 | }
123 |
124 | /**
125 | * Registers the entry and exit commands for a given state.
126 | * @method registerState
127 | * @param {State} state the state to which to register the above commands
128 | * @param {boolean} initial boolean telling if this is the initial state of the system
129 | * @return
130 | */
131 | StateMachine.prototype.registerState = function(state, initial) {
132 | if(state == null || this.states[state.name] != null) return;
133 | this.states[state.name] = state;
134 | if(initial) this.initial = state;
135 | }
136 |
137 | /**
138 | * Remove a state mapping. Removes the entry and exit commands for a given state as well as the state mapping itself.
139 | * @method removeState
140 | * @param {string} stateName
141 | * @return
142 | */
143 | StateMachine.prototype.removeState = function(stateName) {
144 | var state = this.states[stateName];
145 | if(state == null) return;
146 | this.states[stateName] = null;
147 | }
148 |
149 | /**
150 | * Transitions to the given state from the current state.
151 | *
152 | * Sends the exiting notification for the current state
153 | * followed by the entering notification for the new state.
154 | * Once finally transitioned to the new state, the changed
155 | * notification for the new state is sent.
156 | *
157 | * If a data parameter is provided, it is included as the body of all
158 | * three state-specific transition notes.
159 | *
160 | * Finally, when all the state-specific transition notes have been
161 | * sent, a StateMachine.CHANGED note is sent, with the
162 | * new State object as the body and the name of the
163 | * new state in the type.
164 | *
165 | * @method transitionTo
166 | * @param {State} nextState the next State to transition to.
167 | * @param {Object} data is the optional Object that was sent in the StateMachine.ACTION notification body
168 | * @return
169 | */
170 | StateMachine.prototype.transitionTo = function(nextState, data) {
171 | // Going nowhere?
172 | if(nextState == null) return;
173 |
174 | // Clear the cancel flag
175 | this.canceled = false;
176 |
177 | // Exit the current State
178 | if(this.getCurrentState() && this.getCurrentState().exiting)
179 | this.sendNotification(this.getCurrentState().exiting, data, nextState.name);
180 |
181 | // Check to see whether the exiting guard has canceled the transition
182 | if(this.canceled) {
183 | this.canceled = false;
184 | return;
185 | }
186 |
187 | // Enter the next State
188 | if(nextState.entering)
189 | this.sendNotification(nextState.entering, data);
190 |
191 | // Check to see whether the entering guard has canceled the transition
192 | if(this.canceled) {
193 | this.canceled = false;
194 | return;
195 | }
196 |
197 | // change the current state only when both guards have been passed
198 | this.setCurrentState(nextState);
199 |
200 | // Send the notification configured to be sent when this specific state becomes current
201 | if(nextState.changed) {
202 | this.sendNotification(this.getCurrentState().changed, data);
203 | }
204 |
205 | // Notify the app generally that the state changed and what the new state is
206 | this.sendNotification(StateMachine.CHANGED, this.getCurrentState(), this.getCurrentState().name);
207 | }
208 |
209 | /**
210 | * Notification interests for the StateMachine.
211 | * @method listNotificationInterests
212 | * @return {Array} Array of Notifications
213 | */
214 |
215 | StateMachine.prototype.listNotificationInterests = function() {
216 | return [
217 | StateMachine.ACTION,
218 | StateMachine.CANCEL
219 | ];
220 | }
221 |
222 | /**
223 | * Handle notifications the StateMachine is interested in.
224 | *
225 | * StateMachine.ACTION: Triggers the transition to a new state.
226 | * StateMachine.CANCEL: Cancels the transition if sent in response to the exiting note for the current state.
227 | *
228 | * @method handleNotification
229 | * @param {Notification} notification
230 | * @return
231 | */
232 | StateMachine.prototype.handleNotification = function(notification) {
233 | switch(notification.getName()) {
234 | case StateMachine.ACTION:
235 | var action = notification.getType();
236 | var target = this.getCurrentState().getTarget(action);
237 | var newState = this.states[target];
238 | if(newState) this.transitionTo(newState, notification.getBody());
239 | break;
240 |
241 | case StateMachine.CANCEL:
242 | this.canceled = true;
243 | break;
244 | }
245 | }
246 |
247 | /**
248 | * Get the current state.
249 | * @method getCurrentState
250 | * @return a State defining the machine's current state
251 | */
252 | StateMachine.prototype.getCurrentState = function() {
253 | return this.viewComponent;
254 | }
255 |
256 | /**
257 | * Set the current state.
258 | * @method setCurrentState
259 | * @param {State} state
260 | * @return
261 | */
262 | StateMachine.prototype.setCurrentState = function(state) {
263 | this.viewComponent = state;
264 | }
265 |
266 | /**
267 | * Map of States objects by name.
268 | */
269 | StateMachine.prototype.states = null;
270 |
271 | /**
272 | * The initial state of the FSM.
273 | */
274 | StateMachine.prototype.initial = null;
275 |
276 | /**
277 | * The transition has been canceled.
278 | */
279 | StateMachine.prototype.canceled = null;
280 |
281 | StateMachine.NAME = "StateMachine";
282 |
283 | /**
284 | * Action Notification name.
285 | */
286 | StateMachine.ACTION = StateMachine.NAME + "/notes/action";
287 |
288 | /**
289 | * Changed Notification name
290 | */
291 | StateMachine.CHANGED = StateMachine.NAME + "/notes/changed";
292 |
293 | /**
294 | * Cancel Notification name
295 | */
296 | StateMachine.CANCEL = StateMachine.NAME + "/notes/cancel";
297 |
298 |
299 | /**
300 | * Creates and registers a StateMachine described in JSON.
301 | *
302 | *
303 | * This allows reconfiguration of the StateMachine
304 | * without changing any code, as well as making it
305 | * easier than creating all the State
306 | * instances and registering them with the
307 | * StateMachine at startup time.
308 | *
309 | * @ see State
310 | * @ see StateMachine
311 | */
312 |
313 | /**
314 | * Constructor
315 | * @method FSMInjector
316 | * @param {Object} fsm JSON Object
317 | * @return
318 | */
319 | function FSMInjector(fsm) {
320 | puremvc.Notifier.call(this);
321 | this.fsm = fsm;
322 | }
323 |
324 | FSMInjector.prototype = new puremvc.Notifier;
325 | FSMInjector.prototype.constructor = FSMInjector;
326 |
327 | /**
328 | * Inject the StateMachine into the PureMVC apparatus.
329 | *
330 | * Creates the StateMachine instance, registers all the states
331 | * and registers the StateMachine with the IFacade.
332 | * @method inject
333 | * @return
334 | */
335 | FSMInjector.prototype.inject = function() {
336 | // Create the StateMachine
337 | var stateMachine = new puremvc.statemachine.StateMachine();
338 |
339 | // Register all the states with the StateMachine
340 | var states = this.getStates();
341 | for(var i=0; i
352 | * Creates and returns the array of State objects
353 | * from the FSM on first call, subsequently returns
354 | * the existing array.
355 | *
356 | * @method getStates
357 | * @return {Array} Array of States
358 | */
359 | FSMInjector.prototype.getStates = function() {
360 | if(this.stateList == null) {
361 | this.stateList = [];
362 |
363 | var stateDefs = this.fsm.state ? this.fsm.state : [];
364 | for(var i=0; iState instance from its JSON definition.
375 | * @method createState
376 | * @param {Object} stateDef JSON Object
377 | * @return {State}
378 | */
379 | /**
380 |
381 | */
382 | FSMInjector.prototype.createState = function(stateDef) {
383 | // Create State object
384 | var name = stateDef['@name'];
385 | var exiting = stateDef['@exiting'];
386 | var entering = stateDef['@entering'];
387 | var changed = stateDef['@changed'];
388 | var state = new puremvc.statemachine.State(name, entering, exiting, changed);
389 |
390 | // Create transitions
391 | var transitions = stateDef.transition ? stateDef.transition : [];
392 | for(var i=0; i