Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Custom binding for the webstore API.
      6 
      7 var webstoreNatives = requireNative('webstore');
      8 var Event = require('event_bindings').Event;
      9 
     10 function Installer() {
     11   this._pendingInstall = null;
     12   this.onInstallStageChanged =
     13       new Event(null, [{name: 'stage', type: 'string'}], {unmanaged: true});
     14   this.onDownloadProgress =
     15       new Event(null, [{name: 'progress', type: 'number'}], {unmanaged: true});
     16 }
     17 
     18 Installer.prototype.install = function(url, onSuccess, onFailure) {
     19   if (this._pendingInstall)
     20     throw new Error('A Chrome Web Store installation is already pending.');
     21   if (url !== undefined && typeof(url) !== 'string') {
     22     throw new Error(
     23         'The Chrome Web Store item link URL parameter must be a string.');
     24   }
     25   if (onSuccess !== undefined && typeof(onSuccess) !== 'function')
     26     throw new Error('The success callback parameter must be a function.');
     27   if (onFailure !== undefined && typeof(onFailure) !== 'function')
     28     throw new Error('The failure callback parameter must be a function.');
     29 
     30   // Since we call Install() with a bool for if we have listeners, listeners
     31   // must be set prior to the inline installation starting (this is also
     32   // noted in the Event documentation in
     33   // chrome/common/extensions/api/webstore.json).
     34   var installId = webstoreNatives.Install(
     35       this.onInstallStageChanged.hasListeners(),
     36       this.onDownloadProgress.hasListeners(),
     37       url,
     38       onSuccess,
     39       onFailure);
     40   if (installId !== undefined) {
     41     this._pendingInstall = {
     42       installId: installId,
     43       onSuccess: onSuccess,
     44       onFailure: onFailure
     45     };
     46   }
     47 };
     48 
     49 Installer.prototype.onInstallResponse = function(installId, success, error) {
     50   var pendingInstall = this._pendingInstall;
     51   if (!pendingInstall || pendingInstall.installId != installId) {
     52     // TODO(kalman): should this be an error?
     53     return;
     54   }
     55 
     56   try {
     57     if (success && pendingInstall.onSuccess)
     58       pendingInstall.onSuccess();
     59     else if (!success && pendingInstall.onFailure)
     60       pendingInstall.onFailure(error);
     61   } catch (e) {
     62     console.error('Exception in chrome.webstore.install response handler: ' +
     63                   e.stack);
     64   } finally {
     65     this._pendingInstall = null;
     66   }
     67 };
     68 
     69 Installer.prototype.onInstallStageChanged = function(installStage) {
     70   this.onInstallStageChanged.dispatch(installStage);
     71 };
     72 
     73 Installer.prototype.onDownloadProgress = function(progress) {
     74   this.onDownloadProgress.dispatch(progress);
     75 };
     76 
     77 var installer = new Installer();
     78 
     79 var chromeWebstore = {
     80   install: function (url, onSuccess, onFailure) {
     81     installer.install(url, onSuccess, onFailure);
     82   },
     83   onInstallStageChanged: installer.onInstallStageChanged,
     84   onDownloadProgress: installer.onDownloadProgress
     85 };
     86 
     87 exports.binding = chromeWebstore;
     88 
     89 // Called by webstore_bindings.cc.
     90 exports.onInstallResponse =
     91     Installer.prototype.onInstallResponse.bind(installer);
     92 exports.onInstallStageChanged =
     93     Installer.prototype.onInstallStageChanged.bind(installer);
     94 exports.onDownloadProgress =
     95     Installer.prototype.onDownloadProgress.bind(installer);
     96