| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 * CWSWidgetContainer contains a Chrome Web Store widget that displays list of | 6 * CWSWidgetContainer contains a Chrome Web Store widget that displays list of |
| 7 * apps that satisfy certain constraints (e.g. fileHandler apps that can handle | 7 * apps that satisfy certain constraints (e.g. fileHandler apps that can handle |
| 8 * files with specific file extension or MIME type) and enables the user to | 8 * files with specific file extension or MIME type) and enables the user to |
| 9 * install apps directly from it. | 9 * install apps directly from it. |
| 10 * CWSWidgetContainer implements client side of the widget, which handles | 10 * CWSWidgetContainer implements client side of the widget, which handles |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 */ | 40 */ |
| 41 var CWS_WIDGET_ORIGIN = 'https://clients5.google.com'; | 41 var CWS_WIDGET_ORIGIN = 'https://clients5.google.com'; |
| 42 | 42 |
| 43 /** | 43 /** |
| 44 * Creates the widget container element in DOM tree. | 44 * Creates the widget container element in DOM tree. |
| 45 * | 45 * |
| 46 * @param {!HTMLDocument} document The document to contain this container. | 46 * @param {!HTMLDocument} document The document to contain this container. |
| 47 * @param {!HTMLElement} parentNode Node to be parent for this container. | 47 * @param {!HTMLElement} parentNode Node to be parent for this container. |
| 48 * @param {!CWSWidgetContainer.PlatformDelegate} delegate Delegate for accessing | 48 * @param {!CWSWidgetContainer.PlatformDelegate} delegate Delegate for accessing |
| 49 * Chrome platform APIs. | 49 * Chrome platform APIs. |
| 50 * @param {!SuggestAppDialogState} state Static state of suggest app dialog. | 50 * @param {!{ |
| 51 * overrideCwsContainerUrlForTest: (string|undefined), |
| 52 * overrideCwsContainerOriginForTest: (string|undefined) |
| 53 * }} params Overrides for container params. |
| 51 * @constructor | 54 * @constructor |
| 52 */ | 55 */ |
| 53 function CWSWidgetContainer(document, parentNode, delegate, state) { | 56 function CWSWidgetContainer(document, parentNode, delegate, params) { |
| 54 /** @private {!CWSWidgetContainer.PlatformDelegate} */ | 57 /** @private {!CWSWidgetContainer.PlatformDelegate} */ |
| 55 this.delegate_ = delegate; | 58 this.delegate_ = delegate; |
| 56 | 59 |
| 57 /** @private {!CWSWidgetContainer.MetricsRecorder} */ | 60 /** @private {!CWSWidgetContainer.MetricsRecorder} */ |
| 58 this.metricsRecorder_ = | 61 this.metricsRecorder_ = |
| 59 new CWSWidgetContainer.MetricsRecorder(delegate.metricsImpl); | 62 new CWSWidgetContainer.MetricsRecorder(delegate.metricsImpl); |
| 60 | 63 |
| 61 /** | 64 /** |
| 62 * The document that will contain the container. | 65 * The document that will contain the container. |
| 63 * @const {!HTMLDocument} | 66 * @const {!HTMLDocument} |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 buttons.classList.add('cws-widget-buttons'); | 104 buttons.classList.add('cws-widget-buttons'); |
| 102 parentNode.appendChild(buttons); | 105 parentNode.appendChild(buttons); |
| 103 | 106 |
| 104 /** | 107 /** |
| 105 * Button that opens the Webstore URL. | 108 * Button that opens the Webstore URL. |
| 106 * @const {!Element} | 109 * @const {!Element} |
| 107 * @private | 110 * @private |
| 108 */ | 111 */ |
| 109 this.webstoreButton_ = document.createElement('div'); | 112 this.webstoreButton_ = document.createElement('div'); |
| 110 this.webstoreButton_.hidden = true; | 113 this.webstoreButton_.hidden = true; |
| 111 this.webstoreButton_.classList.add('cws-widget-webstore-button'); | |
| 112 this.webstoreButton_.setAttribute('role', 'button'); | 114 this.webstoreButton_.setAttribute('role', 'button'); |
| 113 this.webstoreButton_.tabIndex = 0; | 115 this.webstoreButton_.tabIndex = 0; |
| 114 | 116 |
| 115 /** | 117 /** |
| 116 * Icon for the Webstore button. | 118 * Icon for the Webstore button. |
| 117 * @type {!Element} | 119 * @type {!Element} |
| 118 */ | 120 */ |
| 119 var webstoreButtonIcon = this.document_.createElement('span'); | 121 var webstoreButtonIcon = this.document_.createElement('span'); |
| 120 webstoreButtonIcon.classList.add('cws-widget-webstore-button-icon'); | 122 webstoreButtonIcon.classList.add('cws-widget-webstore-button-icon'); |
| 121 this.webstoreButton_.appendChild(webstoreButtonIcon); | 123 this.webstoreButton_.appendChild(webstoreButtonIcon); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 141 * @type {?WebView} | 143 * @type {?WebView} |
| 142 * @private | 144 * @private |
| 143 */ | 145 */ |
| 144 this.webview_ = null; | 146 this.webview_ = null; |
| 145 | 147 |
| 146 /** | 148 /** |
| 147 * The Chrome Web Store widget URL. | 149 * The Chrome Web Store widget URL. |
| 148 * @const {string} | 150 * @const {string} |
| 149 * @private | 151 * @private |
| 150 */ | 152 */ |
| 151 this.widgetUrl_ = state.overrideCwsContainerUrlForTest || CWS_WIDGET_URL; | 153 this.widgetUrl_ = params.overrideCwsContainerUrlForTest || CWS_WIDGET_URL; |
| 152 | 154 |
| 153 /** | 155 /** |
| 154 * The Chrome Web Store widget origin. | 156 * The Chrome Web Store widget origin. |
| 155 * @const {string} | 157 * @const {string} |
| 156 * @private | 158 * @private |
| 157 */ | 159 */ |
| 158 this.widgetOrigin_ = state.overrideCwsContainerOriginForTest || | 160 this.widgetOrigin_ = params.overrideCwsContainerOriginForTest || |
| 159 CWS_WIDGET_ORIGIN; | 161 CWS_WIDGET_ORIGIN; |
| 160 | 162 |
| 161 /** | 163 /** |
| 162 * Map of options for the widget. | 164 * Map of options for the widget. |
| 163 * @type {?Object.<string, *>} | 165 * @type {?Object.<string, *>} |
| 164 * @private | 166 * @private |
| 165 */ | 167 */ |
| 166 this.options_ = null; | 168 this.options_ = null; |
| 167 | 169 |
| 168 /** | 170 /** |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 }.bind(this)); | 384 }.bind(this)); |
| 383 }.bind(this)); | 385 }.bind(this)); |
| 384 }; | 386 }; |
| 385 | 387 |
| 386 /** | 388 /** |
| 387 * Initializes and starts loading the Chrome Web Store widget webview. | 389 * Initializes and starts loading the Chrome Web Store widget webview. |
| 388 * Must not be called before {@code this.ready()} is resolved. | 390 * Must not be called before {@code this.ready()} is resolved. |
| 389 * | 391 * |
| 390 * @param {!Object<string, *>} options Map of options for the dialog. | 392 * @param {!Object<string, *>} options Map of options for the dialog. |
| 391 * @param {?string} webStoreUrl Url for more results. Null if not supported. | 393 * @param {?string} webStoreUrl Url for more results. Null if not supported. |
| 392 * @return {Promise.<CWSWidgetContainer.ResolveReason>} Resolved when app | 394 * @return {!Promise.<CWSWidgetContainer.ResolveReason>} Resolved when app |
| 393 * installation is done, or the installation is cancelled. | 395 * installation is done, or the installation is cancelled. |
| 394 */ | 396 */ |
| 395 CWSWidgetContainer.prototype.start = function(options, webStoreUrl) { | 397 CWSWidgetContainer.prototype.start = function(options, webStoreUrl) { |
| 396 return new Promise(function(resolve, reject) { | 398 return new Promise(function(resolve, reject) { |
| 397 if (this.state_ !== CWSWidgetContainer.State.ACCESS_TOKEN_READY) { | 399 if (this.state_ !== CWSWidgetContainer.State.ACCESS_TOKEN_READY) { |
| 398 this.state_ = CWSWidgetContainer.State.INITIALIZE_FAILED_CLOSING; | 400 this.state_ = CWSWidgetContainer.State.INITIALIZE_FAILED_CLOSING; |
| 399 reject('Invalid state in |start|.'); | 401 reject('Invalid state in |start|.'); |
| 400 return; | 402 return; |
| 401 } | 403 } |
| 402 | 404 |
| 403 if (!this.accessToken_) { | 405 if (!this.accessToken_) { |
| 404 this.state_ = CWSWidgetContainer.State.INITIALIZE_FAILED_CLOSING; | 406 this.state_ = CWSWidgetContainer.State.INITIALIZE_FAILED_CLOSING; |
| 405 reject('No access token.'); | 407 reject('No access token.'); |
| 406 return; | 408 return; |
| 407 } | 409 } |
| 408 | 410 |
| 409 this.resolveStart_ = resolve; | 411 this.resolveStart_ = resolve; |
| 410 | 412 |
| 411 this.state_ = CWSWidgetContainer.State.INITIALIZING; | 413 this.state_ = CWSWidgetContainer.State.INITIALIZING; |
| 412 | 414 |
| 413 this.webStoreUrl_ = webStoreUrl; | 415 this.webStoreUrl_ = webStoreUrl; |
| 414 this.options_ = options; | 416 this.options_ = options; |
| 415 | 417 |
| 416 this.webstoreButton_.hidden = (webStoreUrl === null); | 418 this.webstoreButton_.hidden = !webStoreUrl; |
| 419 this.webstoreButton_.classList.toggle('cws-widget-webstore-button', |
| 420 !!webStoreUrl); |
| 417 | 421 |
| 418 this.webview_ = | 422 this.webview_ = |
| 419 /** @type {!WebView} */(this.document_.createElement('webview')); | 423 /** @type {!WebView} */(this.document_.createElement('webview')); |
| 420 this.webview_.id = 'cws-widget'; | 424 this.webview_.id = 'cws-widget'; |
| 421 this.webview_.partition = 'persist:cwswidgets'; | 425 this.webview_.partition = 'persist:cwswidgets'; |
| 422 this.webview_.style.width = WEBVIEW_WIDTH + 'px'; | 426 this.webview_.style.width = WEBVIEW_WIDTH + 'px'; |
| 423 this.webview_.style.height = WEBVIEW_HEIGHT + 'px'; | 427 this.webview_.style.height = WEBVIEW_HEIGHT + 'px'; |
| 424 this.webview_.request.onBeforeSendHeaders.addListener( | 428 this.webview_.request.onBeforeSendHeaders.addListener( |
| 425 this.authorizeRequest_.bind(this), | 429 this.authorizeRequest_.bind(this), |
| 426 /** @type {!RequestFilter}*/ ({urls: [this.widgetOrigin_ + '/*']}), | 430 /** @type {!RequestFilter}*/ ({urls: [this.widgetOrigin_ + '/*']}), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 /** | 466 /** |
| 463 * Called when the 'See more...' button is activated. It opens | 467 * Called when the 'See more...' button is activated. It opens |
| 464 * {@code this.webstoreUrl_}. | 468 * {@code this.webstoreUrl_}. |
| 465 * @param {Event} e The event that activated the link. Either mouse click or | 469 * @param {Event} e The event that activated the link. Either mouse click or |
| 466 * key down event. | 470 * key down event. |
| 467 * @private | 471 * @private |
| 468 */ | 472 */ |
| 469 CWSWidgetContainer.prototype.onWebstoreLinkActivated_ = function(e) { | 473 CWSWidgetContainer.prototype.onWebstoreLinkActivated_ = function(e) { |
| 470 if (!this.webStoreUrl_) | 474 if (!this.webStoreUrl_) |
| 471 return; | 475 return; |
| 472 util.visitURL(this.webStoreUrl_); | 476 window.open(this.webStoreUrl_); |
| 473 this.state_ = CWSWidgetContainer.State.OPENING_WEBSTORE_CLOSING; | 477 this.state_ = CWSWidgetContainer.State.OPENING_WEBSTORE_CLOSING; |
| 474 this.reportDone_(); | 478 this.reportDone_(); |
| 475 }; | 479 }; |
| 476 | 480 |
| 477 /** | 481 /** |
| 478 * Key down event handler for webstore button element. If the key is enter, it | 482 * Key down event handler for webstore button element. If the key is enter, it |
| 479 * activates the button. | 483 * activates the button. |
| 480 * @param {Event} e The event | 484 * @param {Event} e The event |
| 481 * @private | 485 * @private |
| 482 */ | 486 */ |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 this.metricsImpl_.recordUserAction('SuggestApps.ShowDialog'); | 933 this.metricsImpl_.recordUserAction('SuggestApps.ShowDialog'); |
| 930 }; | 934 }; |
| 931 | 935 |
| 932 CWSWidgetContainer.MetricsRecorder.prototype.startLoad = function() { | 936 CWSWidgetContainer.MetricsRecorder.prototype.startLoad = function() { |
| 933 this.metricsImpl_.startInterval('SuggestApps.LoadTime'); | 937 this.metricsImpl_.startInterval('SuggestApps.LoadTime'); |
| 934 }; | 938 }; |
| 935 | 939 |
| 936 CWSWidgetContainer.MetricsRecorder.prototype.finishLoad = function() { | 940 CWSWidgetContainer.MetricsRecorder.prototype.finishLoad = function() { |
| 937 this.metricsImpl_.recordInterval('SuggestApps.LoadTime'); | 941 this.metricsImpl_.recordInterval('SuggestApps.LoadTime'); |
| 938 }; | 942 }; |
| OLD | NEW |