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