LEFT | RIGHT |
1 'use strict'; | 1 'use strict'; |
2 | 2 |
3 var spinner; | 3 var spinner; |
4 | 4 |
5 /** | 5 /** |
6 * Provide the main App class, based on the YUI App framework. Also provide | 6 * Provide the main App class, based on the YUI App framework. Also provide |
7 * the routing definitions, which map the request paths to the top-level | 7 * the routing definitions, which map the request paths to the top-level |
8 * views defined by the App class. | 8 * views defined by the App class. |
9 * | 9 * |
10 * @module app | 10 * @module app |
11 */ | 11 */ |
12 | 12 |
13 // Create a global for debug console access to YUI context. | 13 // Create a global for debug console access to YUI context. |
14 var yui; | 14 var yui; |
15 | 15 |
16 YUI.add('juju-gui', function(Y) { | 16 YUI.add('juju-gui', function(Y) { |
17 | 17 |
18 // Assign the global for console access. | 18 // Assign the global for console access. |
19 yui = Y; | 19 yui = Y; |
20 | 20 |
21 var juju = Y.namespace('juju'), | 21 var juju = Y.namespace('juju'), |
22 models = Y.namespace('juju.models'), | 22 models = Y.namespace('juju.models'), |
23 views = Y.namespace('juju.views'); | 23 views = Y.namespace('juju.views'); |
24 | 24 |
25 /** | 25 /** |
26 * The main app class. | 26 * The main app class. |
27 * | 27 * |
28 * @class App | 28 * @class App |
29 */ | 29 */ |
30 var JujuGUI = Y.Base.create('juju-gui', Y.App, [], { | 30 var JujuGUI = Y.Base.create('juju-gui', Y.App, [Y.juju.SubAppRegistration], { |
31 | 31 |
32 /* | 32 /* |
33 * Views | 33 * Views |
34 * | 34 * |
35 * The views encapsulate the functionality blocks that output | 35 * The views encapsulate the functionality blocks that output |
36 * the GUI pages. The "parent" attribute defines the hierarchy. | 36 * the GUI pages. The "parent" attribute defines the hierarchy. |
37 * | 37 * |
38 * FIXME: not included in the generated doc output. | 38 * FIXME: not included in the generated doc output. |
39 * | 39 * |
40 * @attribute views | 40 * @attribute views |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 235 |
236 // These two attributes are used by the namespaced URL tracker. | 236 // These two attributes are used by the namespaced URL tracker. |
237 // _routeSeen is part of a mechanism to prevent non-namespaced routes | 237 // _routeSeen is part of a mechanism to prevent non-namespaced routes |
238 // from being processed multiple times when multiple namespaces are | 238 // from being processed multiple times when multiple namespaces are |
239 // present in the URL. The data structure is reset for each URL (in | 239 // present in the URL. The data structure is reset for each URL (in |
240 // _dispatch). It holds a mapping between route callback uids and a | 240 // _dispatch). It holds a mapping between route callback uids and a |
241 // flag to indicate that the callback has been used. | 241 // flag to indicate that the callback has been used. |
242 this._routeSeen = {}; | 242 this._routeSeen = {}; |
243 // _nsRouter is a juju.Router. It provides a lot of utility methods for | 243 // _nsRouter is a juju.Router. It provides a lot of utility methods for |
244 // working with namespaced URLs. See the module for details. | 244 // working with namespaced URLs. See the module for details. |
245 this._nsRouter = juju.Router('charmstore'); | 245 this._nsRouter = juju.Router('root'); |
246 | 246 |
247 | 247 |
248 // Create a client side database to store state. | 248 // Create a client side database to store state. |
249 this.db = new models.Database(); | 249 this.db = new models.Database(); |
250 this.serviceEndpoints = {}; | 250 this.serviceEndpoints = {}; |
251 | 251 |
252 // Update the on-screen environment name provided in the configuration or | 252 // Update the on-screen environment name provided in the configuration or |
253 // a default if none is configured. | 253 // a default if none is configured. |
254 var environment_name = this.get('environment_name') || 'Environment', | 254 var environment_name = this.get('environment_name') || 'Environment', |
255 environment_node = Y.one('#environment-name'); | 255 environment_node = Y.one('#environment-name'); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 return self; | 435 return self; |
436 } | 436 } |
437 | 437 |
438 req = self._getRequest(fragment, url, src); | 438 req = self._getRequest(fragment, url, src); |
439 res = self._getResponse(req); | 439 res = self._getResponse(req); |
440 | 440 |
441 // This method is a recursive closure, which mutates a number of | 441 // This method is a recursive closure, which mutates a number of |
442 // variables in the enclosing scope, most notably the callbacks and | 442 // variables in the enclosing scope, most notably the callbacks and |
443 // routes. Read carefully! | 443 // routes. Read carefully! |
444 req.next = function(err) { | 444 req.next = function(err) { |
445 var callback, route; | 445 var subApp, callback, route; |
446 | 446 |
447 if (err) { | 447 if (err) { |
448 // Special case "route" to skip to the next route handler | 448 // Special case "route" to skip to the next route handler |
449 // avoiding any additional callbacks for the current route. | 449 // avoiding any additional callbacks for the current route. |
450 if (err === 'route') { | 450 if (err === 'route') { |
451 callbacks = []; | 451 callbacks = []; |
452 req.next(); | 452 req.next(); |
453 } else { | 453 } else { |
454 Y.error(err); | 454 Y.error(err); |
455 } | 455 } |
456 | 456 |
457 } else if ((callback = callbacks.shift())) { | 457 } else if ((callback = callbacks.shift())) { |
458 if (typeof callback === 'string') { | 458 if (typeof callback === 'string') { |
459 callback = self[callback]; | 459 // If the namespace isn't root see if the callback is in the |
| 460 // subapp if not then it must be in the parent app |
| 461 if (namespace !== 'root') { |
| 462 subApp = self.get('subApps')[namespace]; |
| 463 if (typeof subApp[callback] === 'function') { |
| 464 callback = Y.bind(subApp[callback], subApp); |
| 465 } else { |
| 466 callback = self[callback]; |
| 467 } |
| 468 } else { |
| 469 callback = self[callback]; |
| 470 } |
460 } | 471 } |
461 | 472 |
462 // Allow access to the num or remaining callbacks for the route. | 473 // Allow access to the num or remaining callbacks for the route. |
463 req.pendingCallbacks = callbacks.length; | 474 req.pendingCallbacks = callbacks.length; |
464 // Attach the callback id to the request. | 475 // Attach the callback id to the request. |
465 req.callbackId = Y.stamp(callback, true); | 476 req.callbackId = Y.stamp(callback, true); |
466 callback.call(self, req, res, req.next); | 477 callback.call(self, req, res, req.next); |
467 | 478 |
468 } else if ((route = routes.shift())) { | 479 } else if ((route = routes.shift())) { |
469 // Make a copy of this route's `callbacks` and find its matches. | 480 // Make a copy of this route's `callbacks` and find its matches. |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 'juju-env', | 1190 'juju-env', |
1180 'juju-charm-models', | 1191 'juju-charm-models', |
1181 'juju-views', | 1192 'juju-views', |
1182 'juju-view-login', | 1193 'juju-view-login', |
1183 'io', | 1194 'io', |
1184 'json-parse', | 1195 'json-parse', |
1185 'app-base', | 1196 'app-base', |
1186 'app-transitions', | 1197 'app-transitions', |
1187 'base', | 1198 'base', |
1188 'node', | 1199 'node', |
1189 'model'] | 1200 'model', |
| 1201 'app-subapp-extension'] |
1190 }); | 1202 }); |
LEFT | RIGHT |