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 = 50 function(installId, success, error, resultCode) { 51 var pendingInstall = this._pendingInstall; 52 if (!pendingInstall || pendingInstall.installId != installId) { 53 // TODO(kalman): should this be an error? 54 return; 55 } 56 57 try { 58 if (success && pendingInstall.onSuccess) 59 pendingInstall.onSuccess(); 60 else if (!success && pendingInstall.onFailure) 61 pendingInstall.onFailure(error, resultCode); 62 } catch (e) { 63 console.error('Exception in chrome.webstore.install response handler: ' + 64 e.stack); 65 } finally { 66 this._pendingInstall = null; 67 } 68 }; 69 70 Installer.prototype.onInstallStageChanged = function(installStage) { 71 this.onInstallStageChanged.dispatch(installStage); 72 }; 73 74 Installer.prototype.onDownloadProgress = function(progress) { 75 this.onDownloadProgress.dispatch(progress); 76 }; 77 78 var installer = new Installer(); 79 80 var chromeWebstore = { 81 install: function (url, onSuccess, onFailure) { 82 installer.install(url, onSuccess, onFailure); 83 }, 84 onInstallStageChanged: installer.onInstallStageChanged, 85 onDownloadProgress: installer.onDownloadProgress 86 }; 87 88 exports.binding = chromeWebstore; 89 90 // Called by webstore_bindings.cc. 91 exports.onInstallResponse = 92 Installer.prototype.onInstallResponse.bind(installer); 93 exports.onInstallStageChanged = 94 Installer.prototype.onInstallStageChanged.bind(installer); 95 exports.onDownloadProgress = 96 Installer.prototype.onDownloadProgress.bind(installer); 97