Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 'use strict'; | 1 'use strict'; |
2 | 2 |
3 | 3 |
4 /** | 4 /** |
5 * SubApp for the Browser | 5 SubApp for the Browser |
6 * | 6 |
7 * @module juju | 7 @module juju |
8 * @submodule subapps | 8 @submodule subapps |
9 * | |
10 */ | 9 */ |
11 YUI.add('subapp-browser', function(Y) { | 10 YUI.add('subapp-browser', function(Y) { |
12 var ns = Y.namespace('juju.subapps'), | 11 var ns = Y.namespace('juju.subapps'), |
13 models = Y.namespace('juju.models'); | 12 models = Y.namespace('juju.models'); |
14 | 13 |
15 /** | 14 /** |
16 * Browser Sub App for the Juju Gui. | 15 Browser Sub App for the Juju Gui. |
17 * | 16 |
18 * @class Browser | 17 @class Browser |
19 * @extends {juju.SubApp} | 18 @extends {juju.SubApp} |
20 * | |
21 */ | 19 */ |
22 ns.Browser = Y.Base.create('subapp-browser', Y.juju.SubApp, [], { | 20 ns.Browser = Y.Base.create('subapp-browser', Y.juju.SubApp, [], { |
23 /** | 21 /** |
24 * Show or hide the details panel. | 22 Show or hide the details panel. |
jeff.pihach
2013/04/24 17:05:57
We decided against the *'s in a Friday call.
| |
25 * | 23 |
26 * @method _detailsVisible | 24 @method _detailsVisible |
27 * @param {Boolean} visible set the panel to hide or show. | 25 @param {Boolean} visible set the panel to hide or show. |
28 * | |
29 */ | 26 */ |
30 _detailsVisible: function(visible) { | 27 _detailsVisible: function(visible) { |
31 var detailsNode = Y.one('.bws-view-data'); | 28 var detailsNode = Y.one('.bws-view-data'); |
32 if (detailsNode) { | 29 if (detailsNode) { |
33 if (visible) { | 30 if (visible) { |
34 detailsNode.show(); | 31 detailsNode.show(); |
35 } | 32 } |
36 else { | 33 else { |
37 detailsNode.hide(); | 34 detailsNode.hide(); |
38 } | 35 } |
39 } | 36 } |
40 }, | 37 }, |
41 | 38 |
42 /** | 39 /** |
43 * Given the current subapp state, generate a url to pass up to the | 40 Given the current subapp state, generate a url to pass up to the |
44 * routing code to route to. | 41 routing code to route to. |
45 * | 42 |
46 * @method _getStateUrl | 43 @method _getStateUrl |
47 * @param {Object} change the values to change in the current state. | 44 @param {Object} change the values to change in the current state. |
48 * | |
49 */ | 45 */ |
50 _getStateUrl: function(change) { | 46 _getStateUrl: function(change) { |
51 var urlParts = ['/bws']; | 47 var urlParts = ['/bws']; |
52 this._oldState = this._viewState; | 48 this._oldState = this._viewState; |
53 this._viewState = Y.merge(this._viewState, change); | 49 this._viewState = Y.merge(this._viewState, change); |
54 | 50 |
55 urlParts.push(this._viewState.viewmode); | 51 urlParts.push(this._viewState.viewmode); |
56 if (this._viewState.search) { | 52 if (this._viewState.search) { |
57 urlParts.push('search'); | 53 urlParts.push('search'); |
58 } | 54 } |
59 if (this._viewState.charmID) { | 55 if (this._viewState.charmID) { |
60 urlParts.push(this._viewState.charmID); | 56 urlParts.push(this._viewState.charmID); |
61 } | 57 } |
62 var url = urlParts.join('/'); | 58 var url = urlParts.join('/'); |
63 if (this._viewState.querystring) { | 59 if (this._viewState.querystring) { |
64 url = Y.Lang.sub('{ url }?{ qs }', { | 60 url = Y.Lang.sub('{ url }?{ qs }', { |
65 url: url, | 61 url: url, |
66 qs: this._viewState.querystring | 62 qs: this._viewState.querystring |
67 }); | 63 }); |
68 } | 64 } |
69 return url; | 65 return url; |
70 }, | 66 }, |
71 | 67 |
72 /** | 68 /** |
73 * Generate a standard shared set of cfg all Views can expect to see. | 69 Generate a standard shared set of cfg all Views can expect to see. |
74 * | 70 |
75 * @method _getViewCfg | 71 @method _getViewCfg |
76 * @param {Object} cfg additional config to merge into the default view | 72 @param {Object} cfg additional config to merge into the default view |
77 * config. | 73 config. |
78 * | |
79 */ | 74 */ |
80 _getViewCfg: function(cfg) { | 75 _getViewCfg: function(cfg) { |
81 return Y.merge(cfg, { | 76 return Y.merge(cfg, { |
82 db: this.get('db'), | 77 db: this.get('db'), |
83 store: this.get('store') | 78 store: this.get('store') |
84 }); | 79 }); |
85 }, | 80 }, |
86 | 81 |
87 /** | 82 /** |
88 * Create an initial subapp state for later url generation. | 83 Create an initial subapp state for later url generation. |
89 * | 84 |
90 * @method _initState | 85 @method _initState |
91 * | |
92 */ | 86 */ |
93 _initState: function() { | 87 _initState: function() { |
94 this._oldState = { | 88 this._oldState = { |
95 charmID: null, | 89 charmID: null, |
96 querystring: null, | 90 querystring: null, |
97 search: null, | 91 search: null, |
98 viewmode: null | 92 viewmode: null |
99 }; | 93 }; |
100 this._viewState = Y.merge(this._oldState, {}); | 94 this._viewState = Y.merge(this._oldState, {}); |
101 }, | 95 }, |
102 | 96 |
103 /** | 97 /** |
104 * Determine if we should render the charm details based on the current | 98 Determine if we should render the charm details based on the current |
105 * state. | 99 state. |
106 * | 100 |
107 * @return {Boolean} true if should show. | 101 @return {Boolean} true if should show. |
108 * | |
109 */ | 102 */ |
110 _shouldShowCharm: function() { | 103 _shouldShowCharm: function() { |
111 if ( | 104 if ( |
112 this._viewState.charmID && | 105 this._viewState.charmID && |
113 ( | 106 ( |
114 this._hasStateChanged('charmID') || | 107 this._hasStateChanged('charmID') || |
115 this._hasStateChanged('viewmode') | 108 this._hasStateChanged('viewmode') |
116 ) | 109 ) |
117 ) { | 110 ) { |
118 return true; | 111 return true; |
119 } else { | 112 } else { |
120 return false; | 113 return false; |
121 } | 114 } |
122 }, | 115 }, |
123 | 116 |
124 /** | 117 /** |
125 * Determine if we should render the editorial content based on the current | 118 Determine if we should render the editorial content based on the current |
126 * state. | 119 state. |
127 * | 120 |
128 * @return {Boolean} true if should show. | 121 @return {Boolean} true if should show. |
129 * | |
130 */ | 122 */ |
131 _shouldShowEditorial: function() { | 123 _shouldShowEditorial: function() { |
132 if ( | 124 if ( |
133 !this._viewState.search && | 125 !this._viewState.search && |
134 this._hasStateChanged('viewmode') | 126 this._hasStateChanged('viewmode') |
135 ) { | 127 ) { |
136 return true; | 128 return true; |
137 } else { | 129 } else { |
138 return false; | 130 return false; |
139 } | 131 } |
140 }, | 132 }, |
141 | 133 |
142 /** | 134 /** |
143 * Determine if we should render the search results based on the current | 135 Determine if we should render the search results based on the current |
144 * state. | 136 state. |
145 * | 137 |
146 * @return {Boolean} true if should show. | 138 @return {Boolean} true if should show. |
147 * | |
148 */ | 139 */ |
149 _shouldShowSearch: function() { | 140 _shouldShowSearch: function() { |
150 if ( | 141 if ( |
151 this._viewState.search && | 142 this._viewState.search && |
152 ( | 143 ( |
153 this._hasStateChanged('search') || | 144 this._hasStateChanged('search') || |
154 this._hasStateChanged('viewmode') || | 145 this._hasStateChanged('viewmode') || |
155 this._hasStateChanged('querystring') || | 146 this._hasStateChanged('querystring') || |
156 (this._hasStateChanged('charmID') && !this._viewState.charmID) | 147 (this._hasStateChanged('charmID') && !this._viewState.charmID) |
157 ) | 148 ) |
158 ) { | 149 ) { |
159 return true; | 150 return true; |
160 } else { | 151 } else { |
161 return false; | 152 return false; |
162 } | 153 } |
163 }, | 154 }, |
164 | 155 |
165 /** | 156 /** |
166 * Verify that a particular part of the state has changed. | 157 Verify that a particular part of the state has changed. |
167 * | 158 |
168 * @method _hasStateChanged | 159 @method _hasStateChanged |
169 * @param {String} field the part of the state to check. | 160 @param {String} field the part of the state to check. |
170 * | |
171 */ | 161 */ |
172 _hasStateChanged: function(field) { | 162 _hasStateChanged: function(field) { |
173 if (this._oldState[field] === this._viewState[field]) { | 163 if (this._oldState[field] === this._viewState[field]) { |
174 return false; | 164 return false; |
175 } else { | 165 } else { |
176 return true; | 166 return true; |
177 } | 167 } |
178 }, | 168 }, |
179 | 169 |
180 /** | 170 /** |
181 * Update the oldState with the viewState now that we're done processing | 171 Update the oldState with the viewState now that we're done processing |
182 * the request. | 172 the request. |
183 * | 173 |
184 * @method _saveState | 174 @method _saveState |
185 * | |
186 */ | 175 */ |
187 _saveState: function() { | 176 _saveState: function() { |
188 this._oldState = Y.merge( | 177 this._oldState = Y.merge( |
189 this._oldState, | 178 this._oldState, |
190 this._viewState); | 179 this._viewState); |
191 }, | 180 }, |
192 | 181 |
193 /** | 182 /** |
194 * Given the params in the route determine what the new state is going to | 183 Given the params in the route determine what the new state is going to |
195 * be. | 184 be. |
196 * | 185 |
197 * @method _updateState | 186 @method _updateState |
198 * @param {Object} req the request payload. | 187 @param {Object} req the request payload. |
199 * | |
200 */ | 188 */ |
201 _updateState: function(req) { | 189 _updateState: function(req) { |
202 // Update the viewmode. Every request has a viewmode. | 190 // Update the viewmode. Every request has a viewmode. |
203 var path = req.path, | 191 var path = req.path, |
204 params = req.params, | 192 params = req.params, |
205 query = req.query; | 193 query = req.query; |
206 | 194 |
207 this._viewState.viewmode = params.viewmode; | 195 this._viewState.viewmode = params.viewmode; |
208 | 196 |
209 // Check for a charm id in the request. | 197 // Check for a charm id in the request. |
(...skipping 15 matching lines...) Expand all Loading... | |
225 // Check if there's a query string to set. | 213 // Check if there's a query string to set. |
226 if (query) { | 214 if (query) { |
227 // Store it as a straight string. | 215 // Store it as a straight string. |
228 this._viewState.querystring = Y.QueryString.stringify(query); | 216 this._viewState.querystring = Y.QueryString.stringify(query); |
229 } else { | 217 } else { |
230 this._viewState.querystring = null; | 218 this._viewState.querystring = null; |
231 } | 219 } |
232 }, | 220 }, |
233 | 221 |
234 /** | 222 /** |
235 * The available Views run from this sub app. | 223 The available Views run from this sub app. |
236 * @attribute views | 224 @attribute views |
237 * | |
238 */ | 225 */ |
239 views: { | 226 views: { |
240 fullscreen: { | 227 fullscreen: { |
241 type: 'juju.browser.views.FullScreen', | 228 type: 'juju.browser.views.FullScreen', |
242 preserve: false | 229 preserve: false |
243 }, | 230 }, |
244 sidebar: { | 231 sidebar: { |
245 type: 'juju.browser.views.Sidebar', | 232 type: 'juju.browser.views.Sidebar', |
246 preserve: false | 233 preserve: false |
247 } | 234 } |
248 }, | 235 }, |
249 | 236 |
250 /** | 237 /** |
251 * Cleanup after ourselves on destroy. | 238 Cleanup after ourselves on destroy. |
252 * | 239 |
253 * @method destructor | 240 @method destructor |
254 * | |
255 */ | 241 */ |
256 destructor: function() { | 242 destructor: function() { |
257 this._cacheCharms.destroy(); | 243 this._cacheCharms.destroy(); |
258 delete this._viewState; | 244 delete this._viewState; |
259 }, | 245 }, |
260 | 246 |
261 /** | 247 /** |
262 * General app initializer | 248 General app initializer |
263 * | 249 |
264 * @method initializer | 250 @method initializer |
265 * @param {Object} cfg general init config object. | 251 @param {Object} cfg general init config object. |
266 * | |
267 */ | 252 */ |
268 initializer: function(cfg) { | 253 initializer: function(cfg) { |
269 // Hold onto charm data so we can pass model instances to other views when | 254 // Hold onto charm data so we can pass model instances to other views when |
270 // charms are selected. | 255 // charms are selected. |
271 this._cacheCharms = new models.BrowserCharmList(); | 256 this._cacheCharms = new models.BrowserCharmList(); |
272 this._initState(); | 257 this._initState(); |
273 | 258 |
274 // Listen for navigate events from any views we're rendering. | 259 // Listen for navigate events from any views we're rendering. |
275 this.on('*:viewNavigate', function(ev) { | 260 this.on('*:viewNavigate', function(ev) { |
276 var url; | 261 var url; |
277 if (ev.url) { | 262 if (ev.url) { |
278 url = ev.url; | 263 url = ev.url; |
279 } else if (ev.change) { | 264 } else if (ev.change) { |
280 url = this._getStateUrl(ev.change); | 265 url = this._getStateUrl(ev.change); |
281 } | 266 } |
282 this.navigate(url); | 267 this.navigate(url); |
283 }); | 268 }); |
284 }, | 269 }, |
285 | 270 |
286 /** | 271 /** |
287 * Render the charm details view | 272 Render the charm details view |
288 * | 273 |
289 * @method renderCharmDetails | 274 @method renderCharmDetails |
290 * @param {Request} req current request object. | 275 @param {Request} req current request object. |
291 * @param {Response} res current response object. | 276 @param {Response} res current response object. |
292 * @param {function} next callable for the next route in the chain. | 277 @param {function} next callable for the next route in the chain. |
293 * | |
294 */ | 278 */ |
295 renderCharmDetails: function(req, res, next) { | 279 renderCharmDetails: function(req, res, next) { |
296 var charmID = this._viewState.charmID; | 280 var charmID = this._viewState.charmID; |
297 var extraCfg = { | 281 var extraCfg = { |
298 charmID: charmID, | 282 charmID: charmID, |
299 container: Y.Node.create('<div class="charmview"/>'), | 283 container: Y.Node.create('<div class="charmview"/>'), |
300 deploy: this.get('deploy') | 284 deploy: this.get('deploy') |
301 }; | 285 }; |
302 | 286 |
303 // The details view needs to know if we're using a fullscreen template | 287 // The details view needs to know if we're using a fullscreen template |
304 // or the sidebar version. | 288 // or the sidebar version. |
305 if (this._viewState.viewmode === 'fullscreen') { | 289 if (this._viewState.viewmode === 'fullscreen') { |
306 extraCfg.isFullscreen = true; | 290 extraCfg.isFullscreen = true; |
307 } | 291 } |
308 | 292 |
309 // Gotten from the sidebar creating the cache. | 293 // Gotten from the sidebar creating the cache. |
310 var model = this._cacheCharms.getById(charmID); | 294 var model = this._cacheCharms.getById(charmID); |
311 | 295 |
312 if (model) { | 296 if (model) { |
313 extraCfg.charm = model; | 297 extraCfg.charm = model; |
314 } | 298 } |
315 | 299 |
316 this._details = new Y.juju.browser.views.BrowserCharmView( | 300 this._details = new Y.juju.browser.views.BrowserCharmView( |
317 this._getViewCfg(extraCfg)); | 301 this._getViewCfg(extraCfg)); |
318 this._details.render(); | 302 this._details.render(); |
319 this._details.addTarget(this); | 303 this._details.addTarget(this); |
320 }, | 304 }, |
321 | 305 |
322 /** | 306 /** |
323 * Render editorial content into the parent view when required. | 307 Render editorial content into the parent view when required. |
324 * | 308 |
325 * The parent view is either fullscreen/sidebar which determines how the | 309 The parent view is either fullscreen/sidebar which determines how the |
326 * editorial content is to be rendered. | 310 editorial content is to be rendered. |
327 * | 311 |
328 * @method renderEditorial | 312 @method renderEditorial |
329 * @param {Request} req current request object. | 313 @param {Request} req current request object. |
330 * @param {Response} res current response object. | 314 @param {Response} res current response object. |
331 * @param {function} next callable for the next route in the chain. | 315 @param {function} next callable for the next route in the chain. |
332 * | |
333 */ | 316 */ |
334 renderEditorial: function(req, res, next) { | 317 renderEditorial: function(req, res, next) { |
335 // If loading the interesting content then it's not a search going on. | 318 // If loading the interesting content then it's not a search going on. |
336 var container = this.get('container'), | 319 var container = this.get('container'), |
337 extraCfg = {}; | 320 extraCfg = {}; |
338 | 321 |
339 if (this._viewState.viewmode === 'fullscreen') { | 322 if (this._viewState.viewmode === 'fullscreen') { |
340 // The fullscreen view requires that there be no editorial content if | 323 // The fullscreen view requires that there be no editorial content if |
341 // we're looking at a specific charm. The div we dump our content into | 324 // we're looking at a specific charm. The div we dump our content into |
342 // is shared. So if the url is /fullscreen show editorial content, but | 325 // is shared. So if the url is /fullscreen show editorial content, but |
(...skipping 18 matching lines...) Expand all Loading... | |
361 this._getViewCfg(extraCfg)); | 344 this._getViewCfg(extraCfg)); |
362 | 345 |
363 this._editorial.render(); | 346 this._editorial.render(); |
364 this._editorial.addTarget(this); | 347 this._editorial.addTarget(this); |
365 | 348 |
366 // Add any sidebar charms to the running cache. | 349 // Add any sidebar charms to the running cache. |
367 this._cacheCharms.add(this._editorial._cacheCharms); | 350 this._cacheCharms.add(this._editorial._cacheCharms); |
368 }, | 351 }, |
369 | 352 |
370 /** | 353 /** |
371 * Render search results | 354 Render search results |
372 * | 355 |
373 * @method renderSearchResults | 356 @method renderSearchResults |
374 * @param {Request} req current request object. | 357 @param {Request} req current request object. |
375 * @param {Response} res current response object. | 358 @param {Response} res current response object. |
376 * @param {function} next callable for the next route in the chain. | 359 @param {function} next callable for the next route in the chain. |
377 */ | 360 */ |
378 renderSearchResults: function(req, res, next) { | 361 renderSearchResults: function(req, res, next) { |
379 var container = this.get('container'), | 362 var container = this.get('container'), |
380 extraCfg = {}, | 363 extraCfg = {}, |
381 query; | 364 query; |
382 if (req.query) { | 365 if (req.query) { |
383 query = req.query; | 366 query = req.query; |
384 } else { | 367 } else { |
385 // If there's no querystring, we need a default "empty" search. | 368 // If there's no querystring, we need a default "empty" search. |
386 query = {text: ''}; | 369 query = {text: ''}; |
387 } | 370 } |
388 | 371 |
389 if (req.params.viewmode === 'fullscreen') { | 372 if (req.params.viewmode === 'fullscreen') { |
390 extraCfg.renderTo = container.one('.bws-view-data'); | 373 extraCfg.renderTo = container.one('.bws-view-data'); |
391 extraCfg.isFullscreen = true; | 374 extraCfg.isFullscreen = true; |
392 } else { | 375 } else { |
393 extraCfg.renderTo = container.one('.bws-content'); | 376 extraCfg.renderTo = container.one('.bws-content'); |
394 } | 377 } |
395 extraCfg.text = query.text; | 378 extraCfg.text = query.text; |
396 this._search = new Y.juju.browser.views.BrowserSearchView( | 379 this._search = new Y.juju.browser.views.BrowserSearchView( |
397 this._getViewCfg(extraCfg)); | 380 this._getViewCfg(extraCfg)); |
398 this._search.render(); | 381 this._search.render(); |
399 this._search.addTarget(this); | 382 this._search.addTarget(this); |
400 }, | 383 }, |
401 | 384 |
402 /** | 385 /** |
403 * Render the fullscreen view to the client. | 386 Render the fullscreen view to the client. |
404 * | 387 |
405 * @method fullscreen | 388 @method fullscreen |
406 * @param {Request} req current request object. | 389 @param {Request} req current request object. |
407 * @param {Response} res current response object. | 390 @param {Response} res current response object. |
408 * @param {function} next callable for the next route in the chain. | 391 @param {function} next callable for the next route in the chain. |
409 * | |
410 */ | 392 */ |
411 fullscreen: function(req, res, next) { | 393 fullscreen: function(req, res, next) { |
412 // If we've switched to viewmode fullscreen, we need to render it. | 394 // If we've switched to viewmode fullscreen, we need to render it. |
413 // We know the viewmode is already fullscreen because we're in this | 395 // We know the viewmode is already fullscreen because we're in this |
414 // function. | 396 // function. |
415 if (this._hasStateChanged('viewmode')) { | 397 if (this._hasStateChanged('viewmode')) { |
416 Y.one('#subapp-browser').setStyle('display', 'block'); | 398 Y.one('#subapp-browser').setStyle('display', 'block'); |
417 this._fullscreen = this.showView('fullscreen', this._getViewCfg()); | 399 this._fullscreen = this.showView('fullscreen', this._getViewCfg()); |
418 } | 400 } |
419 | 401 |
(...skipping 24 matching lines...) Expand all Loading... | |
444 // Render the editorial in fullscreen only if we don't have a charmid | 426 // Render the editorial in fullscreen only if we don't have a charmid |
445 this.renderEditorial(req, res, next); | 427 this.renderEditorial(req, res, next); |
446 } | 428 } |
447 | 429 |
448 // Sync that the state has changed. | 430 // Sync that the state has changed. |
449 this._saveState(); | 431 this._saveState(); |
450 next(); | 432 next(); |
451 }, | 433 }, |
452 | 434 |
453 /** | 435 /** |
454 * Handle the route for the sidebar view. | 436 Handle the route for the sidebar view. |
455 * | 437 |
456 * @method sidebar | 438 @method sidebar |
457 * @param {Request} req current request object. | 439 @param {Request} req current request object. |
458 * @param {Response} res current response object. | 440 @param {Response} res current response object. |
459 * @param {function} next callable for the next route in the chain. | 441 @param {function} next callable for the next route in the chain. |
460 * | |
461 */ | 442 */ |
462 sidebar: function(req, res, next) { | 443 sidebar: function(req, res, next) { |
463 // If we've switched to viewmode sidebar, we need to render it. | 444 // If we've switched to viewmode sidebar, we need to render it. |
464 if (this._hasStateChanged('viewmode')) { | 445 if (this._hasStateChanged('viewmode')) { |
465 Y.one('#subapp-browser').setStyle('display', 'block'); | 446 Y.one('#subapp-browser').setStyle('display', 'block'); |
466 this._sidebar = this.showView('sidebar', this._getViewCfg()); | 447 this._sidebar = this.showView('sidebar', this._getViewCfg()); |
467 } | 448 } |
468 | 449 |
469 // Render search results if search is in the url and the viewmode or the | 450 // Render search results if search is in the url and the viewmode or the |
470 // search has been changed in the state. | 451 // search has been changed in the state. |
(...skipping 15 matching lines...) Expand all Loading... | |
486 this.renderEditorial(req, res, next); | 467 this.renderEditorial(req, res, next); |
487 } | 468 } |
488 | 469 |
489 // If we've changed the charmID or the viewmode has changed and we have | 470 // If we've changed the charmID or the viewmode has changed and we have |
490 // a charmID, render charmDetails. | 471 // a charmID, render charmDetails. |
491 if (this._shouldShowCharm()) { | 472 if (this._shouldShowCharm()) { |
492 this._detailsVisible(true); | 473 this._detailsVisible(true); |
493 this.renderCharmDetails(req, res, next); | 474 this.renderCharmDetails(req, res, next); |
494 } | 475 } |
495 | 476 |
496 // If no details in the route then hide the div for | 477 // If there are no details in the route then hide the div for |
matthew.scott
2013/04/24 17:26:55
Minor:
// If there are no details in the route, t
| |
497 // viewing the charm details. | 478 // viewing the charm details. |
498 if (!this._viewState.charmID) { | 479 if (!this._viewState.charmID) { |
499 this._detailsVisible(false); | 480 this._detailsVisible(false); |
500 var detailsNode = Y.one('.bws-view-data'); | 481 var detailsNode = Y.one('.bws-view-data'); |
501 if (detailsNode) { | 482 if (detailsNode) { |
502 detailsNode.hide(); | 483 detailsNode.hide(); |
503 } | 484 } |
504 // Clean up any details we've got. | 485 // Clean up any details we've got. |
505 if (this._details) { | 486 if (this._details) { |
506 this._details.destroy({remove: true}); | 487 this._details.destroy({remove: true}); |
507 } | 488 } |
508 } | 489 } |
509 | 490 |
510 // Sync that the state has changed. | 491 // Sync that the state has changed. |
511 this._saveState(); | 492 this._saveState(); |
512 next(); | 493 next(); |
513 }, | 494 }, |
514 | 495 |
515 /** | 496 /** |
516 * Dispatch to the correct viewmode based on the route that was hit. | 497 Dispatch to the correct viewmode based on the route that was hit. |
517 * | 498 |
518 * @method routeView | 499 @method routeView |
519 * @param {Request} req current request object. | 500 @param {Request} req current request object. |
520 * @param {Response} res current response object. | 501 @param {Response} res current response object. |
521 * @param {function} next callable for the next route in the chain. | 502 @param {function} next callable for the next route in the chain. |
522 * | |
523 */ | 503 */ |
524 routeView: function(req, res, next) { | 504 routeView: function(req, res, next) { |
525 // Update the state for the rest of things to figure out what to do. | 505 // Update the state for the rest of things to figure out what to do. |
526 this._updateState(req); | 506 this._updateState(req); |
527 this[req.params.viewmode](req, res, next); | 507 this[req.params.viewmode](req, res, next); |
528 } | 508 } |
529 | 509 |
530 }, { | 510 }, { |
531 ATTRS: { | 511 ATTRS: { |
532 /** | 512 /** |
533 * @attribute container | 513 @attribute container |
534 * @default '#subapp-browser' | 514 @default '#subapp-browser' |
535 * @type {String} | 515 @type {String} |
536 * | |
537 */ | 516 */ |
538 container: { | 517 container: { |
539 value: '#subapp-browser' | 518 value: '#subapp-browser' |
540 }, | 519 }, |
541 | 520 |
542 /** | 521 /** |
543 * @attribute store | 522 @attribute store |
544 * @default Charmworld0 | 523 @default Charmworld0 |
545 * @type {Charmworld0} | 524 @type {Charmworld0} |
546 * | |
547 */ | 525 */ |
548 store: { | 526 store: { |
549 /** | 527 /** |
550 * We keep one instance of the store and will work on caching results | 528 We keep one instance of the store and will work on caching results |
551 * at the app level so that routes can share api calls. However, in | 529 at the app level so that routes can share api calls. However, in |
552 * tests there's no config for talking to the api so we have to watch | 530 tests there's no config for talking to the api so we have to watch |
553 * out in test runs and allow the store to be broken. | 531 out in test runs and allow the store to be broken. |
554 * | 532 |
555 * method store.valueFn | 533 method store.valueFn |
556 * | |
557 */ | 534 */ |
558 valueFn: function() { | 535 valueFn: function() { |
559 var url = ''; | 536 var url = ''; |
560 if (!window.juju_config || ! window.juju_config.charmworldURL) { | 537 if (!window.juju_config || ! window.juju_config.charmworldURL) { |
561 console.error('No juju config to fetch charmworld store url'); | 538 console.error('No juju config to fetch charmworld store url'); |
562 } else { | 539 } else { |
563 url = window.juju_config.charmworldURL; | 540 url = window.juju_config.charmworldURL; |
564 } | 541 } |
565 return new Y.juju.Charmworld0({ | 542 return new Y.juju.Charmworld0({ |
566 'apiHost': url | 543 'apiHost': url |
567 }); | 544 }); |
568 } | 545 } |
569 }, | 546 }, |
570 | 547 |
571 /** | 548 /** |
572 * @attribute routes | 549 @attribute routes |
573 * @default Array of subapp routes. | 550 @default Array of subapp routes. |
574 * @type {Array} | 551 @type {Array} |
575 * | |
576 */ | 552 */ |
577 routes: { | 553 routes: { |
578 value: [ | 554 value: [ |
579 // Double routes are needed to catch /fullscreen and /fullscreen/ | 555 // Double routes are needed to catch /fullscreen and /fullscreen/ |
580 { path: '/bws/:viewmode/', callbacks: 'routeView' }, | 556 { path: '/bws/:viewmode/', callbacks: 'routeView' }, |
581 { path: '/bws/:viewmode/search/', callbacks: 'routeView' }, | 557 { path: '/bws/:viewmode/search/', callbacks: 'routeView' }, |
582 { path: '/bws/:viewmode/search/*id/', callbacks: 'routeView' }, | 558 { path: '/bws/:viewmode/search/*id/', callbacks: 'routeView' }, |
583 { path: '/bws/:viewmode/*id/', callbacks: 'routeView' } | 559 { path: '/bws/:viewmode/*id/', callbacks: 'routeView' } |
584 ] | 560 ] |
585 }, | 561 }, |
586 | 562 |
587 /** | 563 /** |
588 * @attribute urlNamespace | 564 @attribute urlNamespace |
589 * @default 'charmstore' | 565 @default 'charmstore' |
590 * @type {String} | 566 @type {String} |
591 * | |
592 */ | 567 */ |
593 urlNamespace: { | 568 urlNamespace: { |
594 value: 'charmstore' | 569 value: 'charmstore' |
595 }, | 570 }, |
596 | 571 |
597 /** | 572 /** |
598 * The "deploy" function prompts the user for service configuration and | 573 The "deploy" function prompts the user for service configuration and |
599 * deploys a service. | 574 deploys a service. |
600 * | 575 |
601 * @attribute deploy | 576 @attribute deploy |
602 * @default undefined | 577 @default undefined |
603 * @type {Function} | 578 @type {Function} |
604 * | |
605 */ | 579 */ |
606 deploy: {} | 580 deploy: {} |
607 | 581 |
608 } | 582 } |
609 }); | 583 }); |
610 | 584 |
611 }, '0.1.0', { | 585 }, '0.1.0', { |
612 requires: [ | 586 requires: [ |
613 'juju-charm-store', | 587 'juju-charm-store', |
614 'juju-models', | 588 'juju-models', |
615 'querystring', | 589 'querystring', |
616 'sub-app', | 590 'sub-app', |
617 'subapp-browser-charmview', | 591 'subapp-browser-charmview', |
618 'subapp-browser-editorial', | 592 'subapp-browser-editorial', |
619 'subapp-browser-fullscreen', | 593 'subapp-browser-fullscreen', |
620 'subapp-browser-searchview', | 594 'subapp-browser-searchview', |
621 'subapp-browser-sidebar' | 595 'subapp-browser-sidebar' |
622 ] | 596 ] |
623 }); | 597 }); |
LEFT | RIGHT |