function CWSWidgetContainer(document, parentNode, delegate, params) {
  /** @private {!CWSWidgetContainerPlatformDelegate} */
  this.delegate_ = delegate;

  /** @private {!CWSWidgetContainer.MetricsRecorder} */
  this.metricsRecorder_ =
      new CWSWidgetContainer.MetricsRecorder(delegate.metricsImpl);

  /**
   * The document that will contain the container.
   * @const {!HTMLDocument}
   * @private
   */
  this.document_ = document;

  /**
   * The element containing the widget webview.
   * @type {!Element}
   * @private
   */
  this.webviewContainer_ = document.createElement('div');
  this.webviewContainer_.classList.add('cws-widget-webview-container');
  this.webviewContainer_.style.width = WEBVIEW_WIDTH + 'px';
  this.webviewContainer_.style.height = WEBVIEW_HEIGHT + 'px';
  parentNode.appendChild(this.webviewContainer_);

  parentNode.classList.add('cws-widget-container-root');

  /**
   * Element showing spinner layout in place of Web Store widget.
   * @type {!Element}
   */
  var spinnerLayer = document.createElement('div');
  spinnerLayer.className = 'cws-widget-spinner-layer';
  parentNode.appendChild(spinnerLayer);

  /** @private {!CWSWidgetContainer.SpinnerLayerController} */
  this.spinnerLayerController_ =
      new CWSWidgetContainer.SpinnerLayerController(spinnerLayer);

  /**
   * The widget container's button strip.
   * @type {!Element}
   */
  var buttons = document.createElement('div');
  buttons.classList.add('cws-widget-buttons');
  parentNode.appendChild(buttons);

  /**
   * Button that opens the Webstore URL.
   * @const {!Element}
   * @private
   */
  this.webstoreButton_ = document.createElement('div');
  this.webstoreButton_.hidden = true;
  this.webstoreButton_.setAttribute('role', 'button');
  this.webstoreButton_.tabIndex = 0;

  /**
   * Icon for the Webstore button.
   * @type {!Element}
   */
  var webstoreButtonIcon = this.document_.createElement('span');
  webstoreButtonIcon.classList.add('cws-widget-webstore-button-icon');
  this.webstoreButton_.appendChild(webstoreButtonIcon);

  /**
   * The label for the Webstore button.
   * @type {!Element}
   */
  var webstoreButtonLabel = this.document_.createElement('span');
  webstoreButtonLabel.classList.add('cws-widget-webstore-button-label');
  webstoreButtonLabel.textContent = this.delegate_.strings.LINK_TO_WEBSTORE;
  this.webstoreButton_.appendChild(webstoreButtonLabel);

  this.webstoreButton_.addEventListener(
      'click', this.onWebstoreLinkActivated_.bind(this));
  this.webstoreButton_.addEventListener(
      'keydown', this.onWebstoreLinkKeyDown_.bind(this));

  buttons.appendChild(this.webstoreButton_);

  /**
   * The webview element containing the Chrome Web Store widget.
   * @type {?WebView}
   * @private
   */
  this.webview_ = null;

  /**
   * The Chrome Web Store widget URL.
   * @const {string}
   * @private
   */
  this.widgetUrl_ = params.overrideCwsContainerUrlForTest || CWS_WIDGET_URL;

  /**
   * The Chrome Web Store widget origin.
   * @const {string}
   * @private
   */
  this.widgetOrigin_ = params.overrideCwsContainerOriginForTest ||
      CWS_WIDGET_ORIGIN;

  /**
   * Map of options for the widget.
   * @type {?Object<*>}
   * @private
   */
  this.options_ = null;

  /**
   * The ID of the item being installed. Null if no items are being installed.
   * @type {?string}
   * @private
   */
  this.installingItemId_ = null;

  /**
   * The ID of the the installed item. Null if no item was installed.
   * @type {?string}
   * @private
   */
  this.installedItemId_ = null;

  /**
   * The current widget state.
   * @type {CWSWidgetContainer.State}
   * @private
   */
  this.state_ = CWSWidgetContainer.State.UNINITIALIZED;

  /**
   * The Chrome Web Store access token to be used when communicating with the
   * Chrome Web Store widget.
   * @type {?string}
   * @private
   */
  this.accessToken_ = null;

  /**
   * Called when the Chrome Web Store widget is done. It resolves the promise
   * returned by {@code this.start()}.
   * @type {?function(CWSWidgetContainer.ResolveReason)}
   * @private
   */
  this.resolveStart_ = null;

  /**
   * Promise for retriving {@code this.accessToken_}.
   * @type {Promise.<string>}
   * @private
   */
  this.tokenGetter_ = this.createTokenGetter_();

  /**
   * Dialog to be shown when an installation attempt fails.
   * @type {CWSWidgetContainerErrorDialog}
   * @private
   */
  this.errorDialog_ = new CWSWidgetContainerErrorDialog(parentNode);
}
/**
 * Creates the widget container element in DOM tree.
 *
 * @param {!HTMLDocument} document The document to contain this container.
 * @param {!HTMLElement} parentNode Node to be parent for this container.
 * @param {!CWSWidgetContainerPlatformDelegate} delegate Delegate for accessing
 *     Chrome platform APIs.
 * @param {!{
 *   overrideCwsContainerUrlForTest: (string|undefined),
 *   overrideCwsContainerOriginForTest: (string|undefined)
 * }} params Overrides for container params.
 * @constructor
 */
Creates the widget container element in DOM tree.
@param {!HTMLDocument} document The document to contain this container.
@param {!HTMLElement} parentNode Node to be parent for this container.
@param {!CWSWidgetContainerPlatformDelegate} delegate Delegate for accessing
Chrome platform APIs.
@param {!{
overrideCwsContainerUrlForTest: (string|undefined),
overrideCwsContainerOriginForTest: (string|undefined)
}} params Overrides for container params.
@constructor
Creates the widget container element in DOM tree . @param { !HTMLDocument } document The document to contain this container . @param { !HTMLElement } parentNode Node to be parent for this container . @param { !CWSWidgetContainerPlatformDelegate } delegate Delegate for accessing Chrome platform APIs . @param { ! { overrideCwsContainerUrlForTest : ( string|undefined ) overrideCwsContainerOriginForTest : ( string|undefined ) }} params Overrides for container params . @constructor
function CWSWidgetContainer(document, parentNode, delegate, params) {
  this.delegate_ = delegate;
  this.metricsRecorder_ =
      new CWSWidgetContainer.MetricsRecorder(delegate.metricsImpl);
  this.document_ = document;
  this.webviewContainer_ = document.createElement('div');
  this.webviewContainer_.classList.add('cws-widget-webview-container');
  this.webviewContainer_.style.width = WEBVIEW_WIDTH + 'px';
  this.webviewContainer_.style.height = WEBVIEW_HEIGHT + 'px';
  parentNode.appendChild(this.webviewContainer_);
  parentNode.classList.add('cws-widget-container-root');
  var spinnerLayer = document.createElement('div');
  spinnerLayer.className = 'cws-widget-spinner-layer';
  parentNode.appendChild(spinnerLayer);
  this.spinnerLayerController_ =
      new CWSWidgetContainer.SpinnerLayerController(spinnerLayer);
  var buttons = document.createElement('div');
  buttons.classList.add('cws-widget-buttons');
  parentNode.appendChild(buttons);
  this.webstoreButton_ = document.createElement('div');
  this.webstoreButton_.hidden = true;
  this.webstoreButton_.setAttribute('role', 'button');
  this.webstoreButton_.tabIndex = 0;
  var webstoreButtonIcon = this.document_.createElement('span');
  webstoreButtonIcon.classList.add('cws-widget-webstore-button-icon');
  this.webstoreButton_.appendChild(webstoreButtonIcon);
  var webstoreButtonLabel = this.document_.createElement('span');
  webstoreButtonLabel.classList.add('cws-widget-webstore-button-label');
  webstoreButtonLabel.textContent = this.delegate_.strings.LINK_TO_WEBSTORE;
  this.webstoreButton_.appendChild(webstoreButtonLabel);
  this.webstoreButton_.addEventListener(
      'click', this.onWebstoreLinkActivated_.bind(this));
  this.webstoreButton_.addEventListener(
      'keydown', this.onWebstoreLinkKeyDown_.bind(this));
  buttons.appendChild(this.webstoreButton_);
  this.webview_ = null;
  this.widgetUrl_ = params.overrideCwsContainerUrlForTest || CWS_WIDGET_URL;
  this.widgetOrigin_ = params.overrideCwsContainerOriginForTest ||
      CWS_WIDGET_ORIGIN;
  this.options_ = null;
  this.installingItemId_ = null;
  this.installedItemId_ = null;
  this.state_ = CWSWidgetContainer.State.UNINITIALIZED;
  this.accessToken_ = null;
  this.resolveStart_ = null;
  this.tokenGetter_ = this.createTokenGetter_();
  this.errorDialog_ = new CWSWidgetContainerErrorDialog(parentNode);
}
function CWSWidgetContainer ( document , parentNode , delegate , params ) { this . delegate_ = delegate ; this . metricsRecorder_ = new CWSWidgetContainer . MetricsRecorder ( delegate . metricsImpl ) ; this . document_ = document ; this . webviewContainer_ = document . createElement ( 'div' ) ; this . webviewContainer_ . classList . add ( 'cws-widget-webview-container' ) ; this . webviewContainer_ . style . width = WEBVIEW_WIDTH + 'px' ; this . webviewContainer_ . style . height = WEBVIEW_HEIGHT + 'px' ; parentNode . appendChild ( this . webviewContainer_ ) ; parentNode . classList . add ( 'cws-widget-container-root' ) ; var spinnerLayer = document . createElement ( 'div' ) ; spinnerLayer . className = 'cws-widget-spinner-layer' ; parentNode . appendChild ( spinnerLayer ) ; this . spinnerLayerController_ = new CWSWidgetContainer . SpinnerLayerController ( spinnerLayer ) ; var buttons = document . createElement ( 'div' ) ; buttons . classList . add ( 'cws-widget-buttons' ) ; parentNode . appendChild ( buttons ) ; this . webstoreButton_ = document . createElement ( 'div' ) ; this . webstoreButton_ . hidden = true ; this . webstoreButton_ . setAttribute ( 'role' , 'button' ) ; this . webstoreButton_ . tabIndex = 0 ; var webstoreButtonIcon = this . document_ . createElement ( 'span' ) ; webstoreButtonIcon . classList . add ( 'cws-widget-webstore-button-icon' ) ; this . webstoreButton_ . appendChild ( webstoreButtonIcon ) ; var webstoreButtonLabel = this . document_ . createElement ( 'span' ) ; webstoreButtonLabel . classList . add ( 'cws-widget-webstore-button-label' ) ; webstoreButtonLabel . textContent = this . delegate_ . strings . LINK_TO_WEBSTORE ; this . webstoreButton_ . appendChild ( webstoreButtonLabel ) ; this . webstoreButton_ . addEventListener ( 'click' , this . onWebstoreLinkActivated_ . bind ( this ) ) ; this . webstoreButton_ . addEventListener ( 'keydown' , this . onWebstoreLinkKeyDown_ . bind ( this ) ) ; buttons . appendChild ( this . webstoreButton_ ) ; this . webview_ = null ; this . widgetUrl_ = params . overrideCwsContainerUrlForTest || CWS_WIDGET_URL ; this . widgetOrigin_ = params . overrideCwsContainerOriginForTest || CWS_WIDGET_ORIGIN ; this . options_ = null ; this . installingItemId_ = null ; this . installedItemId_ = null ; this . state_ = CWSWidgetContainer . State . UNINITIALIZED ; this . accessToken_ = null ; this . resolveStart_ = null ; this . tokenGetter_ = this . createTokenGetter_ ( ) ; this . errorDialog_ = new CWSWidgetContainerErrorDialog ( parentNode ) ; }
Creates the widget container element in DOM tree.
Creates the widget container element in DOM tree .
/** @private {!CWSWidgetContainerPlatformDelegate} */ /** @private {!CWSWidgetContainer.MetricsRecorder} */ /**
   * The document that will contain the container.
   * @const {!HTMLDocument}
   * @private
   */ /**
   * The element containing the widget webview.
   * @type {!Element}
   * @private
   */ /**
   * Element showing spinner layout in place of Web Store widget.
   * @type {!Element}
   */ /** @private {!CWSWidgetContainer.SpinnerLayerController} */ /**
   * The widget container's button strip.
   * @type {!Element}
   */ /**
   * Button that opens the Webstore URL.
   * @const {!Element}
   * @private
   */ /**
   * Icon for the Webstore button.
   * @type {!Element}
   */ /**
   * The label for the Webstore button.
   * @type {!Element}
   */ /**
   * The webview element containing the Chrome Web Store widget.
   * @type {?WebView}
   * @private
   */ /**
   * The Chrome Web Store widget URL.
   * @const {string}
   * @private
   */ /**
   * The Chrome Web Store widget origin.
   * @const {string}
   * @private
   */ /**
   * Map of options for the widget.
   * @type {?Object<*>}
   * @private
   */ /**
   * The ID of the item being installed. Null if no items are being installed.
   * @type {?string}
   * @private
   */ /**
   * The ID of the the installed item. Null if no item was installed.
   * @type {?string}
   * @private
   */ /**
   * The current widget state.
   * @type {CWSWidgetContainer.State}
   * @private
   */ /**
   * The Chrome Web Store access token to be used when communicating with the
   * Chrome Web Store widget.
   * @type {?string}
   * @private
   */ /**
   * Called when the Chrome Web Store widget is done. It resolves the promise
   * returned by {@code this.start()}.
   * @type {?function(CWSWidgetContainer.ResolveReason)}
   * @private
   */ /**
   * Promise for retriving {@code this.accessToken_}.
   * @type {Promise.<string>}
   * @private
   */ /**
   * Dialog to be shown when an installation attempt fails.
   * @type {CWSWidgetContainerErrorDialog}
   * @private
   */