OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * SuggestAppsDialog contains a list box to select an app to be opened the file | 6 * SuggestAppsDialog contains a list box to select an app to be opened the file |
7 * with. This dialog should be used as action picker for file operations. | 7 * with. This dialog should be used as action picker for file operations. |
8 */ | 8 */ |
9 | 9 |
10 /** | 10 /** |
11 * The width of the widget (in pixel). | 11 * The width of the widget (in pixel). |
12 * @type {number} | 12 * @type {number} |
13 * @const | 13 * @const |
14 */ | 14 */ |
15 var WEBVIEW_WIDTH = 735; | 15 var WEBVIEW_WIDTH = 735; |
16 /** | 16 /** |
17 * The height of the widget (in pixel). | 17 * The height of the widget (in pixel). |
18 * @type {number} | 18 * @type {number} |
19 * @const | 19 * @const |
20 */ | 20 */ |
21 var WEBVIEW_HEIGHT = 480; | 21 var WEBVIEW_HEIGHT = 480; |
22 | 22 |
23 /** | 23 /** |
24 * The URL of the widget. | 24 * The URL of the widget showing suggested apps. |
25 * @type {string} | 25 * @type {string} |
26 * @const | 26 * @const |
27 */ | 27 */ |
28 var CWS_WIDGET_URL = | 28 var CWS_WIDGET_URL = |
29 'https://clients5.google.com/webstore/wall/cros-widget-container'; | 29 'https://clients5.google.com/webstore/wall/cros-widget-container'; |
| 30 |
30 /** | 31 /** |
31 * The origin of the widget. | 32 * The origin of the widget. |
32 * @type {string} | 33 * @type {string} |
33 * @const | 34 * @const |
34 */ | 35 */ |
35 var CWS_WIDGET_ORIGIN = 'https://clients5.google.com'; | 36 var CWS_WIDGET_ORIGIN = 'https://clients5.google.com'; |
36 | 37 |
37 /** | 38 /** |
38 * Creates dialog in DOM tree. | 39 * Creates dialog in DOM tree. |
39 * | 40 * |
(...skipping 15 matching lines...) Expand all Loading... |
55 | 56 |
56 var spinnerLayer = this.document_.createElement('div'); | 57 var spinnerLayer = this.document_.createElement('div'); |
57 spinnerLayer.className = 'spinner-layer'; | 58 spinnerLayer.className = 'spinner-layer'; |
58 this.webviewContainer_.appendChild(spinnerLayer); | 59 this.webviewContainer_.appendChild(spinnerLayer); |
59 | 60 |
60 this.buttons_ = this.document_.createElement('div'); | 61 this.buttons_ = this.document_.createElement('div'); |
61 this.buttons_.id = 'buttons'; | 62 this.buttons_.id = 'buttons'; |
62 this.frame_.appendChild(this.buttons_); | 63 this.frame_.appendChild(this.buttons_); |
63 | 64 |
64 this.webstoreButton_ = this.document_.createElement('div'); | 65 this.webstoreButton_ = this.document_.createElement('div'); |
| 66 this.webstoreButton_.hidden = true; |
65 this.webstoreButton_.id = 'webstore-button'; | 67 this.webstoreButton_.id = 'webstore-button'; |
66 this.webstoreButton_.innerHTML = str('SUGGEST_DIALOG_LINK_TO_WEBSTORE'); | 68 this.webstoreButton_.innerHTML = str('SUGGEST_DIALOG_LINK_TO_WEBSTORE'); |
67 this.webstoreButton_.addEventListener( | 69 this.webstoreButton_.addEventListener( |
68 'click', this.onWebstoreLinkClicked_.bind(this)); | 70 'click', this.onWebstoreLinkClicked_.bind(this)); |
69 this.buttons_.appendChild(this.webstoreButton_); | 71 this.buttons_.appendChild(this.webstoreButton_); |
70 | 72 |
71 this.initialFocusElement_ = this.webviewContainer_; | 73 this.initialFocusElement_ = this.webviewContainer_; |
72 | 74 |
73 this.webview_ = null; | 75 this.webview_ = null; |
74 this.accessToken_ = null; | 76 this.accessToken_ = null; |
75 this.widgetUrl_ = | 77 this.widgetUrl_ = state.overrideCwsContainerUrlForTest || CWS_WIDGET_URL; |
76 state.overrideCwsContainerUrlForTest || CWS_WIDGET_URL; | 78 this.widgetOrigin_ = state.overrideCwsContainerOriginForTest || |
77 this.widgetOrigin_ = | 79 CWS_WIDGET_ORIGIN; |
78 state.overrideCwsContainerOriginForTest || CWS_WIDGET_ORIGIN; | |
79 | 80 |
80 this.extension_ = null; | 81 this.options_ = null; |
81 this.mime_ = null; | |
82 this.installingItemId_ = null; | 82 this.installingItemId_ = null; |
83 this.state_ = SuggestAppsDialog.State.UNINITIALIZED; | 83 this.state_ = SuggestAppsDialog.State.UNINITIALIZED; |
84 | 84 |
85 this.initializationTask_ = new AsyncUtil.Group(); | 85 this.initializationTask_ = new AsyncUtil.Group(); |
86 this.initializationTask_.add(this.retrieveAuthorizeToken_.bind(this)); | 86 this.initializationTask_.add(this.retrieveAuthorizeToken_.bind(this)); |
87 this.initializationTask_.run(); | 87 this.initializationTask_.run(); |
88 } | 88 } |
89 | 89 |
90 SuggestAppsDialog.prototype = { | 90 SuggestAppsDialog.prototype = { |
91 __proto__: FileManagerDialogBase.prototype | 91 __proto__: FileManagerDialogBase.prototype |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 /** | 169 /** |
170 * Dummy function for SuggestAppsDialog.show() not to be called unintentionally. | 170 * Dummy function for SuggestAppsDialog.show() not to be called unintentionally. |
171 */ | 171 */ |
172 SuggestAppsDialog.prototype.show = function() { | 172 SuggestAppsDialog.prototype.show = function() { |
173 console.error('SuggestAppsDialog.show() shouldn\'t be called directly.'); | 173 console.error('SuggestAppsDialog.show() shouldn\'t be called directly.'); |
174 }; | 174 }; |
175 | 175 |
176 /** | 176 /** |
177 * Shows suggest-apps dialog by file extension and mime. | 177 * Shows suggest-apps dialog by file extension and mime. |
178 * | 178 * |
179 * @param {string} extension Extension of the file. | 179 * @param {string} extension Extension of the file with a trailing dot. |
180 * @param {string} mime Mime of the file. | 180 * @param {string} mime Mime of the file. |
181 * @param {function(boolean)} onDialogClosed Called when the dialog is closed. | 181 * @param {function(boolean)} onDialogClosed Called when the dialog is closed. |
182 * The argument is the result of installation: true if an app is installed, | 182 * The argument is the result of installation: true if an app is installed, |
183 * false otherwise. | 183 * false otherwise. |
184 */ | 184 */ |
185 SuggestAppsDialog.prototype.showByExtensionAndMime = | 185 SuggestAppsDialog.prototype.showByExtensionAndMime = |
186 function(extension, mime, onDialogClosed) { | 186 function(extension, mime, onDialogClosed) { |
187 this.text_.hidden = true; | 187 assert(extension && extension[0] === '.'); |
188 this.dialogText_ = ''; | 188 this.showInternal_( |
189 this.showInternal_(null, extension, mime, onDialogClosed); | 189 { |
| 190 file_extension: extension.substr(1), |
| 191 mime_type: mime |
| 192 }, |
| 193 str('SUGGEST_DIALOG_TITLE'), |
| 194 FileTasks.createWebStoreLink(extension, mime), |
| 195 onDialogClosed); |
| 196 }; |
| 197 |
| 198 /** |
| 199 * Shows suggest-apps dialog for FSP API |
| 200 * @param {function(boolean)} onDialogClosed Called when the dialog is closed. |
| 201 * The argument is the result of installation: true if an app is installed, |
| 202 * false otherwise. |
| 203 */ |
| 204 SuggestAppsDialog.prototype.showProviders = function(onDialogClosed) { |
| 205 this.showInternal_( |
| 206 { |
| 207 file_system_provider: true |
| 208 }, |
| 209 str('SUGGEST_DIALOG_FOR_PROVIDERS_TITLE'), |
| 210 null /* webStoreUrl */, |
| 211 onDialogClosed); |
190 }; | 212 }; |
191 | 213 |
192 /** | 214 /** |
193 * Internal method to show a dialog. This should be called only from 'Suggest. | 215 * Internal method to show a dialog. This should be called only from 'Suggest. |
194 * appDialog.showXxxx()' functions. | 216 * appDialog.showXxxx()' functions. |
195 * | 217 * |
196 * @param {?string} filename Filename (without extension) of the file. | 218 * @param {!Object<string, *>} options Map of options for the dialog. |
197 * @param {?string} extension Extension of the file. | 219 * @param {string} title Title of the dialog. |
198 * @param {?string} mime Mime of the file. | 220 * @param {?string} webStoreUrl Url for more results. Null if not supported. |
199 * @param {function(boolean)} onDialogClosed Called when the dialog is closed. | 221 * @param {function(boolean)} onDialogClosed Called when the dialog is closed. |
200 * The argument is the result of installation: true if an app is installed, | 222 * The argument is the result of installation: true if an app is installed, |
201 * false otherwise. | 223 * false otherwise. |
202 * @private | 224 * @private |
203 */ | 225 */ |
204 SuggestAppsDialog.prototype.showInternal_ = | 226 SuggestAppsDialog.prototype.showInternal_ = |
205 function(filename, extension, mime, onDialogClosed) { | 227 function(options, title, webStoreUrl, onDialogClosed) { |
206 if (this.state_ != SuggestAppsDialog.State.UNINITIALIZED) { | 228 if (this.state_ != SuggestAppsDialog.State.UNINITIALIZED) { |
207 console.error('Invalid state.'); | 229 console.error('Invalid state.'); |
208 return; | 230 return; |
209 } | 231 } |
210 | 232 |
211 this.extension_ = extension; | 233 this.text_.hidden = true; |
212 this.mimeType_ = mime; | 234 this.webstoreButton_.hidden = (webStoreUrl === null); |
| 235 this.dialogText_ = ''; |
| 236 |
| 237 this.webStoreUrl_ = webStoreUrl; |
| 238 this.options_ = options; |
213 this.onDialogClosed_ = onDialogClosed; | 239 this.onDialogClosed_ = onDialogClosed; |
214 this.state_ = SuggestAppsDialog.State.INITIALIZING; | 240 this.state_ = SuggestAppsDialog.State.INITIALIZING; |
215 | 241 |
216 SuggestAppsDialog.Metrics.recordShowDialog(); | 242 SuggestAppsDialog.Metrics.recordShowDialog(); |
217 SuggestAppsDialog.Metrics.startLoad(); | 243 SuggestAppsDialog.Metrics.startLoad(); |
218 | 244 |
219 // Makes it sure that the initialization is completed. | 245 // Makes it sure that the initialization is completed. |
220 this.initializationTask_.run(function() { | 246 this.initializationTask_.run(function() { |
221 if (!this.accessToken_) { | 247 if (!this.accessToken_) { |
222 this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING; | 248 this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING; |
223 this.onHide_(); | 249 this.onHide_(); |
224 return; | 250 return; |
225 } | 251 } |
226 | 252 |
227 var title = str('SUGGEST_DIALOG_TITLE'); | |
228 var show = this.dialogText_ ? | 253 var show = this.dialogText_ ? |
229 FileManagerDialogBase.prototype.showTitleAndTextDialog.call( | 254 FileManagerDialogBase.prototype.showTitleAndTextDialog.call( |
230 this, title, this.dialogText_) : | 255 this, title, this.dialogText_) : |
231 FileManagerDialogBase.prototype.showTitleOnlyDialog.call( | 256 FileManagerDialogBase.prototype.showTitleOnlyDialog.call( |
232 this, title); | 257 this, title); |
233 if (!show) { | 258 if (!show) { |
234 console.error('SuggestAppsDialog can\'t be shown'); | 259 console.error('SuggestAppsDialog can\'t be shown'); |
235 this.state_ = SuggestAppsDialog.State.UNINITIALIZED; | 260 this.state_ = SuggestAppsDialog.State.UNINITIALIZED; |
236 this.onHide_(); | 261 this.onHide_(); |
237 return; | 262 return; |
(...skipping 14 matching lines...) Expand all Loading... |
252 event.window.discard(); | 277 event.window.discard(); |
253 util.visitURL(event.targetUrl); | 278 util.visitURL(event.targetUrl); |
254 event.preventDefault(); | 279 event.preventDefault(); |
255 }); | 280 }); |
256 this.webviewContainer_.appendChild(this.webview_); | 281 this.webviewContainer_.appendChild(this.webview_); |
257 | 282 |
258 this.frame_.classList.add('show-spinner'); | 283 this.frame_.classList.add('show-spinner'); |
259 | 284 |
260 this.webviewClient_ = new CWSContainerClient( | 285 this.webviewClient_ = new CWSContainerClient( |
261 this.webview_, | 286 this.webview_, |
262 extension, mime, filename, | 287 WEBVIEW_WIDTH, |
263 WEBVIEW_WIDTH, WEBVIEW_HEIGHT, | 288 WEBVIEW_HEIGHT, |
264 this.widgetUrl_, this.widgetOrigin_); | 289 this.widgetUrl_, |
| 290 this.widgetOrigin_, |
| 291 this.options_); |
265 this.webviewClient_.addEventListener(CWSContainerClient.Events.LOADED, | 292 this.webviewClient_.addEventListener(CWSContainerClient.Events.LOADED, |
266 this.onWidgetLoaded_.bind(this)); | 293 this.onWidgetLoaded_.bind(this)); |
267 this.webviewClient_.addEventListener(CWSContainerClient.Events.LOAD_FAILED, | 294 this.webviewClient_.addEventListener(CWSContainerClient.Events.LOAD_FAILED, |
268 this.onWidgetLoadFailed_.bind(this)); | 295 this.onWidgetLoadFailed_.bind(this)); |
269 this.webviewClient_.addEventListener( | 296 this.webviewClient_.addEventListener( |
270 CWSContainerClient.Events.REQUEST_INSTALL, | 297 CWSContainerClient.Events.REQUEST_INSTALL, |
271 this.onInstallRequest_.bind(this)); | 298 this.onInstallRequest_.bind(this)); |
272 this.webviewClient_.load(); | 299 this.webviewClient_.load(); |
273 }.bind(this)); | 300 }.bind(this)); |
274 }; | 301 }; |
275 | 302 |
276 /** | 303 /** |
277 * Called when the 'See more...' link is clicked to be navigated to Webstore. | 304 * Called when the 'See more...' link is clicked to be navigated to Webstore. |
278 * @param {Event} e Event. | 305 * @param {Event} e Event. |
279 * @private | 306 * @private |
280 */ | 307 */ |
281 SuggestAppsDialog.prototype.onWebstoreLinkClicked_ = function(e) { | 308 SuggestAppsDialog.prototype.onWebstoreLinkClicked_ = function(e) { |
282 var webStoreUrl = | 309 if (!this.webStoreUrl_) |
283 FileTasks.createWebStoreLink(this.extension_, this.mimeType_); | 310 return; |
284 util.visitURL(webStoreUrl); | 311 util.visitURL(this.webStoreUrl_); |
285 this.state_ = SuggestAppsDialog.State.OPENING_WEBSTORE_CLOSING; | 312 this.state_ = SuggestAppsDialog.State.OPENING_WEBSTORE_CLOSING; |
286 this.hide(); | 313 this.hide(); |
287 }; | 314 }; |
288 | 315 |
289 /** | 316 /** |
290 * Called when the widget is loaded successfully. | 317 * Called when the widget is loaded successfully. |
291 * @param {Event} event Event. | 318 * @param {Event} event Event. |
292 * @private | 319 * @private |
293 */ | 320 */ |
294 SuggestAppsDialog.prototype.onWidgetLoaded_ = function(event) { | 321 SuggestAppsDialog.prototype.onWidgetLoaded_ = function(event) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 console.error('Invalid state.'); | 447 console.error('Invalid state.'); |
421 } | 448 } |
422 | 449 |
423 if (this.webviewClient_) { | 450 if (this.webviewClient_) { |
424 this.webviewClient_.dispose(); | 451 this.webviewClient_.dispose(); |
425 this.webviewClient_ = null; | 452 this.webviewClient_ = null; |
426 } | 453 } |
427 | 454 |
428 this.webviewContainer_.removeChild(this.webview_); | 455 this.webviewContainer_.removeChild(this.webview_); |
429 this.webview_ = null; | 456 this.webview_ = null; |
430 this.extension_ = null; | 457 this.webStoreUrl_ = null; |
431 this.mime_ = null; | 458 this.options_ = null; |
432 | 459 |
433 FileManagerDialogBase.prototype.hide.call( | 460 FileManagerDialogBase.prototype.hide.call( |
434 this, | 461 this, |
435 this.onHide_.bind(this, opt_originalOnHide)); | 462 this.onHide_.bind(this, opt_originalOnHide)); |
436 }; | 463 }; |
437 | 464 |
438 /** | 465 /** |
439 * @param {Function=} opt_originalOnHide Original onHide function passed to | 466 * @param {Function=} opt_originalOnHide Original onHide function passed to |
440 * SuggestAppsDialog.hide(). | 467 * SuggestAppsDialog.hide(). |
441 * @private | 468 * @private |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 metrics.recordUserAction('SuggestApps.ShowDialog'); | 570 metrics.recordUserAction('SuggestApps.ShowDialog'); |
544 }; | 571 }; |
545 | 572 |
546 SuggestAppsDialog.Metrics.startLoad = function() { | 573 SuggestAppsDialog.Metrics.startLoad = function() { |
547 metrics.startInterval('SuggestApps.LoadTime'); | 574 metrics.startInterval('SuggestApps.LoadTime'); |
548 }; | 575 }; |
549 | 576 |
550 SuggestAppsDialog.Metrics.finishLoad = function() { | 577 SuggestAppsDialog.Metrics.finishLoad = function() { |
551 metrics.recordInterval('SuggestApps.LoadTime'); | 578 metrics.recordInterval('SuggestApps.LoadTime'); |
552 }; | 579 }; |
OLD | NEW |