• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
7var webstoreNatives = requireNative('webstore');
8var Event = require('event_bindings').Event;
9
10function 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
18Installer.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
49Installer.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
69Installer.prototype.onInstallStageChanged = function(installStage) {
70  this.onInstallStageChanged.dispatch(installStage);
71};
72
73Installer.prototype.onDownloadProgress = function(progress) {
74  this.onDownloadProgress.dispatch(progress);
75};
76
77var installer = new Installer();
78
79var chromeWebstore = {
80  install: function (url, onSuccess, onFailure) {
81    installer.install(url, onSuccess, onFailure);
82  },
83  onInstallStageChanged: installer.onInstallStageChanged,
84  onDownloadProgress: installer.onDownloadProgress
85};
86
87exports.binding = chromeWebstore;
88
89// Called by webstore_bindings.cc.
90exports.onInstallResponse =
91    Installer.prototype.onInstallResponse.bind(installer);
92exports.onInstallStageChanged =
93    Installer.prototype.onInstallStageChanged.bind(installer);
94exports.onDownloadProgress =
95    Installer.prototype.onDownloadProgress.bind(installer);
96