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 |
(...skipping 224 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 // Create a client side database to store state. | 248 // Create a client side database to store state. |
248 this.db = new models.Database(); | 249 this.db = new models.Database(); |
249 this.serviceEndpoints = {}; | 250 this.serviceEndpoints = {}; |
250 | |
251 // Optional Landscape integration helper. | |
252 this.landscape = new views.Landscape(); | |
253 this.landscape.set('db', this.db); | |
254 | 251 |
255 // Update the on-screen environment name provided in the configuration or | 252 // Update the on-screen environment name provided in the configuration or |
256 // a default if none is configured. | 253 // a default if none is configured. |
257 var environment_name = this.get('environment_name') || 'Environment', | 254 var environment_name = this.get('environment_name') || 'Environment', |
258 environment_node = Y.one('#environment-name'); | 255 environment_node = Y.one('#environment-name'); |
259 | 256 |
260 // Some tests do not fully populate the DOM, so we check to be sure. | 257 // Some tests do not fully populate the DOM, so we check to be sure. |
261 if (Y.Lang.isValue(environment_node)) { | 258 if (Y.Lang.isValue(environment_node)) { |
262 environment_node.set('text', environment_name); | 259 environment_node.set('text', environment_name); |
263 } | 260 } |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 return self; | 435 return self; |
439 } | 436 } |
440 | 437 |
441 req = self._getRequest(fragment, url, src); | 438 req = self._getRequest(fragment, url, src); |
442 res = self._getResponse(req); | 439 res = self._getResponse(req); |
443 | 440 |
444 // This method is a recursive closure, which mutates a number of | 441 // This method is a recursive closure, which mutates a number of |
445 // variables in the enclosing scope, most notably the callbacks and | 442 // variables in the enclosing scope, most notably the callbacks and |
446 // routes. Read carefully! | 443 // routes. Read carefully! |
447 req.next = function(err) { | 444 req.next = function(err) { |
448 var callback, route; | 445 var subApp, callback, route; |
449 | 446 |
450 if (err) { | 447 if (err) { |
451 // Special case "route" to skip to the next route handler | 448 // Special case "route" to skip to the next route handler |
452 // avoiding any additional callbacks for the current route. | 449 // avoiding any additional callbacks for the current route. |
453 if (err === 'route') { | 450 if (err === 'route') { |
454 callbacks = []; | 451 callbacks = []; |
455 req.next(); | 452 req.next(); |
456 } else { | 453 } else { |
457 Y.error(err); | 454 Y.error(err); |
458 } | 455 } |
459 | 456 |
460 } else if ((callback = callbacks.shift())) { | 457 } else if ((callback = callbacks.shift())) { |
461 if (typeof callback === 'string') { | 458 if (typeof callback === 'string') { |
462 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 } |
463 } | 471 } |
464 | 472 |
465 // Allow access to the num or remaining callbacks for the route. | 473 // Allow access to the num or remaining callbacks for the route. |
466 req.pendingCallbacks = callbacks.length; | 474 req.pendingCallbacks = callbacks.length; |
467 // Attach the callback id to the request. | 475 // Attach the callback id to the request. |
468 req.callbackId = Y.stamp(callback, true); | 476 req.callbackId = Y.stamp(callback, true); |
469 callback.call(self, req, res, req.next); | 477 callback.call(self, req, res, req.next); |
470 | 478 |
471 } else if ((route = routes.shift())) { | 479 } else if ((route = routes.shift())) { |
472 // 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 this.updateEndpoints(); | 563 this.updateEndpoints(); |
556 } else { | 564 } else { |
557 // If any services have been removed, delete them from the map | 565 // If any services have been removed, delete them from the map |
558 // rather than updating it as a whole. | 566 // rather than updating it as a whole. |
559 Y.Object.each(this.serviceEndpoints, function(key, value, obj) { | 567 Y.Object.each(this.serviceEndpoints, function(key, value, obj) { |
560 if (self.db.services.getById(key) === null) { | 568 if (self.db.services.getById(key) === null) { |
561 delete(self.serviceEndpoints[key]); | 569 delete(self.serviceEndpoints[key]); |
562 } | 570 } |
563 }); | 571 }); |
564 } | 572 } |
565 | |
566 // Update Landscape annotations. | |
567 this.landscape.update(); | |
568 | 573 |
569 // Regardless of which view we are rendering | 574 // Regardless of which view we are rendering |
570 // update the env view on db change. | 575 // update the env view on db change. |
571 if (this.views.environment.instance) { | 576 if (this.views.environment.instance) { |
572 this.views.environment.instance.topo.update(); | 577 this.views.environment.instance.topo.update(); |
573 } | 578 } |
574 // Redispatch to current view to update. | 579 // Redispatch to current view to update. |
575 if (active && active.name === 'EnvironmentView') { | 580 if (active && active.name === 'EnvironmentView') { |
576 active.rendered(); | 581 active.rendered(); |
577 } else { | 582 } else { |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 options = { | 901 options = { |
897 getModelURL: Y.bind(this.getModelURL, this), | 902 getModelURL: Y.bind(this.getModelURL, this), |
898 /** | 903 /** |
899 * A simple closure so changes to the value are available. | 904 * A simple closure so changes to the value are available. |
900 * | 905 * |
901 * @method show_environment.options.getServiceEndpoints | 906 * @method show_environment.options.getServiceEndpoints |
902 */ | 907 */ |
903 getServiceEndpoints: function() { | 908 getServiceEndpoints: function() { |
904 return self.serviceEndpoints;}, | 909 return self.serviceEndpoints;}, |
905 loadService: this.loadService, | 910 loadService: this.loadService, |
906 landscape: this.landscape, | |
907 db: this.db, | 911 db: this.db, |
908 env: this.env}; | 912 env: this.env}; |
909 | 913 |
910 this.showView('environment', options, { | 914 this.showView('environment', options, { |
911 /** | 915 /** |
912 * Let the component framework know that the view has been rendered. | 916 * Let the component framework know that the view has been rendered. |
913 * | 917 * |
914 * @method show_environment.callback | 918 * @method show_environment.callback |
915 */ | 919 */ |
916 callback: function() { | 920 callback: function() { |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 'juju-models', | 1184 'juju-models', |
1181 'juju-notifications', | 1185 'juju-notifications', |
1182 'juju-routing', | 1186 'juju-routing', |
1183 // This alias does not seem to work, including references by hand. | 1187 // This alias does not seem to work, including references by hand. |
1184 'juju-controllers', | 1188 'juju-controllers', |
1185 'juju-notification-controller', | 1189 'juju-notification-controller', |
1186 'juju-env', | 1190 'juju-env', |
1187 'juju-charm-models', | 1191 'juju-charm-models', |
1188 'juju-views', | 1192 'juju-views', |
1189 'juju-view-login', | 1193 'juju-view-login', |
1190 'juju-landscape', | |
1191 'io', | 1194 'io', |
1192 'json-parse', | 1195 'json-parse', |
1193 'app-base', | 1196 'app-base', |
1194 'app-transitions', | 1197 'app-transitions', |
1195 'base', | 1198 'base', |
1196 'node', | 1199 'node', |
1197 'model', | 1200 'model', |
1198 'app-subapp-extension', | 1201 'app-subapp-extension'] |
1199 'sub-app'] | |
1200 }); | 1202 }); |
LEFT | RIGHT |