~ubuntu-branches/ubuntu/oneiric/ubufox/oneiric-proposed

« back to all changes in this revision

Viewing changes to .pc/06_firefox-4.patch/content/pluginInstallerWizard.js

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2011-01-01 14:30:25 UTC
  • Revision ID: james.westby@ubuntu.com-20110101143025-52ew6ngsqev5gcqn
Tags: 0.9~rc2-0ubuntu7
* Add patch to update for Firefox 4:
  - Rename AboutHome to AboutStartup, and have it handle about:startup now 
    (to not conflict with the new about:home handler in Firefox
  - Set default home page to about:startpage
  - Add support for the XPCOM changes in Gecko 2.0
  - In the restart notifier, don't hardcode a list of filenames for different
    browser versions, but just use MOZ_APP_LAUNCHER instead. This will
    indirectly fix LP: #511250 and should prevent it from happening again
  - Look in the new location for the restart-required trigger, it has moved
    to a location not monitored by update-notifier now, so we only get the
    restart required notification in the browser
  - Merge the plugin finder code from Firefox 4. This now uses AddonManager,
    so the MinVersion needs to be bumped
  - Drop the FF2.0 specific code
  - Drop the AddonsOverlay and associated code, this hasn't worked for
    several releases since we started using software-center, and nobody
    really noticed so far. We can reimplement this at a later date if wanted,
    but it throws JS exceptions when loading in FF4.0 now
  - Specify for the extension to be unpacked by the installer. Without this,
    the prefs aren't used
  - Get the distributionID field for the pfs URL from the preferences, rather
    than hard-coding a value

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is Plugin Finder Service.
 
15
 *
 
16
 * The Initial Developer of the Original Code is
 
17
 * IBM Corporation.
 
18
 * Portions created by the IBM Corporation are Copyright (C) 2004
 
19
 * IBM Corporation. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *   Doron Rosenberg <doronr@us.ibm.com>
 
23
 *   Alexander Sack <asac@jwsdot.com> - Canonical Ltd.
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the MPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the MPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
function nsPluginInstallerWizard(){
 
40
 
 
41
  // create the request array
 
42
  this.mPluginRequestArray = new Object();
 
43
  // since the array is a hash, store the length
 
44
  this.mPluginRequestArrayLength = 0;
 
45
 
 
46
  // create the plugin info array.
 
47
  // a hash indexed by plugin id so we don't install 
 
48
  // the same plugin more than once.
 
49
  this.mPluginInfoArray = new Object();
 
50
  this.mPluginInfoArrayLength = 0;
 
51
 
 
52
  this.mMimeTypePluginSelections = new Object();
 
53
 
 
54
  // holds plugins we couldn't find
 
55
  this.mPluginNotFoundArray = new Object();
 
56
  this.mPluginNotFoundArrayLength = 0;
 
57
 
 
58
  // array holding pids of plugins that require a license
 
59
  this.mPluginLicenseArray = new Array();
 
60
 
 
61
  this.mPluginGroupBoxes = new Array();
 
62
  this.mPluginPlaceHolder = null;
 
63
 
 
64
  // how many plugins are to be installed
 
65
  this.pluginsToInstallNum = 0;
 
66
 
 
67
  this.mTab = null;
 
68
  this.mBrowser = null;
 
69
  this.mSuccessfullPluginInstallation = 0;
 
70
 
 
71
  this.mPluginPidArray = new Object();
 
72
  // arguments[0] is an array that contains two items:
 
73
  //     an array of mimetypes that are missing
 
74
  //     a reference to the tab that needs them, so we can reload it
 
75
 
 
76
  if ("arguments" in window) {
 
77
    for (var item in window.arguments[0].plugins){
 
78
      this.mPluginRequestArray[window.arguments[0].plugins[item].mimetype] =
 
79
        new nsPluginRequest(window.arguments[0].plugins[item]);
 
80
 
 
81
      this.mPluginRequestArrayLength++;
 
82
    }
 
83
 
 
84
    this.mBrowser = window.arguments[0].browser; // ffox 3
 
85
    this.mTab = window.arguments[0].tab; // ffox 2
 
86
  }
 
87
 
 
88
  this.WSPluginCounter = 0;
 
89
  this.licenseAcceptCounter = 0;
 
90
 
 
91
  this.prefBranch = null;
 
92
 
 
93
  this.mNeedsRestart = false;
 
94
}
 
95
 
 
96
nsPluginInstallerWizard.prototype.getPluginData = function (){
 
97
  // for each mPluginRequestArray item, call the datasource
 
98
  this.WSPluginCounter = 0;
 
99
 
 
100
  // initiate the datasource call
 
101
  var rdfUpdater = new nsRDFItemUpdater(this.getOS(), this.getChromeLocale());
 
102
 
 
103
  for (item in this.mPluginRequestArray) {
 
104
    rdfUpdater.checkForPlugin(this.mPluginRequestArray[item]);
 
105
  }
 
106
}
 
107
 
 
108
// aPluginInfo is null if the datasource call failed, and pid is -1 if
 
109
// no matching plugin was found.
 
110
nsPluginInstallerWizard.prototype.pluginInfoReceived = function (aPluginInfos){
 
111
  this.WSPluginCounter++;
 
112
 
 
113
  if (aPluginInfos ) {
 
114
    // hash by id
 
115
 
 
116
    var resultSetMimeType = null;
 
117
    var filteredPluginInfoSet = new Array();
 
118
    var noResultInfo = null;
 
119
    var aPluginInfo = null;
 
120
    for (var i = 0; i < aPluginInfos.length; i++) {
 
121
      aPluginInfo = aPluginInfos[i];
 
122
      resultSetMimeType = aPluginInfo.requestedMimetype;
 
123
      if (aPluginInfo && aPluginInfo.pid != -1 &&
 
124
          ( aPluginInfo.XPILocation || aPluginInfo.manualInstallationURL )) {
 
125
        hasResults = true;
 
126
        filteredPluginInfoSet.push(aPluginInfo);
 
127
        this.mPluginPidArray[aPluginInfo.pid] = aPluginInfo;
 
128
      }
 
129
    }
 
130
 
 
131
    if(filteredPluginInfoSet.length > 0)
 
132
    {
 
133
      this.mPluginInfoArray[resultSetMimeType] = filteredPluginInfoSet;
 
134
      this.mPluginInfoArrayLength++;
 
135
    } else {
 
136
      this.mPluginNotFoundArray[resultSetMimeType] = filteredPluginInfoSet;
 
137
      this.mPluginNotFoundArrayLength++;
 
138
    }
 
139
  }
 
140
 
 
141
  var progressMeter = document.getElementById("ws_request_progress");
 
142
 
 
143
  if (progressMeter.getAttribute("mode") == "undetermined")
 
144
    progressMeter.setAttribute("mode", "determined");
 
145
 
 
146
  progressMeter.setAttribute("value",
 
147
      ((this.WSPluginCounter / this.mPluginRequestArrayLength) * 100) + "%");
 
148
 
 
149
  if (this.WSPluginCounter == this.mPluginRequestArrayLength) {
 
150
    // check if no plugins were found
 
151
    if (this.mPluginInfoArrayLength == 0 && this.mPluginInfoAptArrayLength == 0) {
 
152
      this.advancePage("lastpage", true, false, false);
 
153
    } else {
 
154
      // we want to allow user to cancel
 
155
      this.advancePage(null, true, false, true);
 
156
    }
 
157
  } else {
 
158
    // process more.
 
159
  }
 
160
}
 
161
 
 
162
nsPluginInstallerWizard.prototype.createPluginSetGroupBox = function () {
 
163
 
 
164
  var stringBundle = document.getElementById("ubufoxPluginWizardString");
 
165
  var gbox = document.createElement("vbox");
 
166
  gbox.setAttribute("flex", "1");
 
167
 
 
168
  var caption = document.createElement("caption");
 
169
  caption.setAttribute("label", stringBundle.getString("ubufox.pluginWizard.availablePluginsPage.description.label")+" "+mimetype+":");
 
170
  gbox.appendChild(caption);
 
171
 
 
172
  return gbox;
 
173
}
 
174
 
 
175
function doToggleInstallPluginEvent(e) {
 
176
  gPluginInstaller.toggleInstallPlugin(e);
 
177
}
 
178
 
 
179
nsPluginInstallerWizard.prototype.showPluginList = function () {
 
180
  var toReplace = null;
 
181
 
 
182
  if(this.mPluginGroupBoxes.length > 0)
 
183
    this.mPluginGroupBoxes.pop();
 
184
  
 
185
  if (toReplace && this.mPluginPlaceHolder) {
 
186
    toReplace.getParent().replaceChild(toReplace, 
 
187
                                       this.mPluginPlaceHolder);
 
188
  }
 
189
  
 
190
  this.pluginsToInstallNum = 0;
 
191
  var hasPluginWithInstallerUI = false;
 
192
 
 
193
  var groupBox = null;
 
194
  var lastSibling = null;
 
195
 
 
196
  for (mimetype in this.mPluginInfoArray){
 
197
    // [plugin image] [Plugin_Name Plugin_Version]
 
198
    var pluginInfoSet = this.mPluginInfoArray[mimetype];
 
199
    var firstPluginSet = (groupBox == null);
 
200
    groupBox = this.createPluginSetGroupBox(document, mimetype, pluginInfoSet);
 
201
 
 
202
    if(firstPluginSet) {
 
203
      this.mPluginPlaceHolder = document.getElementById("pluginselection-placeholder");
 
204
      this.mPluginPlaceHolder.parentNode.replaceChild(groupBox, this.mPluginPlaceHolder);
 
205
    } else {
 
206
      lastSibling.parentNode.insertBefore(groupBox, lastSibling);
 
207
    }
 
208
    lastSibling = groupBox;
 
209
    this.mPluginGroupBoxes.push(groupBox);
 
210
 
 
211
    var radiogroup = document.createElement("richlistbox");
 
212
    radiogroup.setAttribute("flex", "1");
 
213
    groupBox.appendChild(radiogroup);
 
214
    radiogroup.addEventListener("select", doToggleInstallPluginEvent, false);
 
215
 
 
216
    // OK, lets add the "None" option first
 
217
    var first = true;
 
218
    for (var i = 0; i < pluginInfoSet.length; i++) {
 
219
      var pluginInfo = pluginInfoSet[i];
 
220
      var rli = document.createElement("richlistitem");
 
221
      rli.setAttribute("style", "border-bottom: dotted 1px lightgrey; padding: 0.5em 1em 0.5em 1em");
 
222
      rli._ubufoxPluginInfo = pluginInfo;
 
223
      rli._ubufoxPluginInfoMimeType = mimetype;
 
224
      radiogroup.appendChild(rli);
 
225
 
 
226
      var distributorImageWrap = document.createElement("vbox");
 
227
 
 
228
      var spacer = document.createElement("hbox");
 
229
      spacer.setAttribute("flex", "1");
 
230
      distributorImageWrap.appendChild(spacer);
 
231
 
 
232
      var distributorImage = document.createElement("image");
 
233
      distributorImageWrap.appendChild(distributorImage);
 
234
      distributorImageWrap.setAttribute("style", "vertical-align: middle");
 
235
      distributorImage.setAttribute("style", "vertical-align: middle");
 
236
      distributorImageWrap.setAttribute("flex", "0");
 
237
      distributorImage.setAttribute("class", "distributor-image");
 
238
      if(pluginInfo.XPILocation && pluginInfo.XPILocation.indexOf("apt:") == 0) {
 
239
        distributorImage.setAttribute("src", "chrome://ubufox/content/ubuntulogo32.png");
 
240
        pluginInfo.IconUrl = "chrome://ubufox/content/ubuntulogo32.png";
 
241
      } else {
 
242
        if(!pluginInfo.IconUrl || pluginInfo.IconUrl.length == 0) {
 
243
          distributorImage.setAttribute("src", "chrome://ubufox/content/internet32.png");
 
244
          pluginInfo.IconUrl = "chrome://ubufox/content/internet32.png";
 
245
        } else {
 
246
          distributorImage.setAttribute("src", pluginInfo.IconUrl);
 
247
        }
 
248
      } 
 
249
 
 
250
      spacer = document.createElement("hbox");
 
251
      spacer.setAttribute("flex", "1");
 
252
      distributorImageWrap.appendChild(spacer);
 
253
 
 
254
      rli.appendChild(distributorImageWrap);
 
255
 
 
256
      var nameAndDesc = document.createElement("vbox");
 
257
      rli.appendChild(nameAndDesc);
 
258
 
 
259
      var nameLabel = document.createElement("label");
 
260
      nameLabel.setAttribute("value", pluginInfo.name + " " + (pluginInfo.version ? pluginInfo.version : ""));
 
261
      nameLabel.setAttribute("style", "font-weight: bold");
 
262
      nameAndDesc.appendChild(nameLabel);
 
263
 
 
264
      var descDesc = document.createElement("description");
 
265
      if (!pluginInfo.desc) {
 
266
        pluginInfo.desc = this.getString("ubufox.pluginWizard.description.notfound");
 
267
      }
 
268
      descDesc.appendChild(document.createTextNode(pluginInfo.desc));
 
269
      descDesc.setAttribute("style", "white-space: pre;");
 
270
      nameAndDesc.appendChild(descDesc);
 
271
    }
 
272
 
 
273
    radiogroup.selectedIndex = 0;
 
274
 
 
275
    if (pluginInfo.InstallerShowsUI == "true")
 
276
      hasPluginWithInstallerUI = true;
 
277
 
 
278
    this.pluginsToInstallNum++;
 
279
  }
 
280
 
 
281
  if (hasPluginWithInstallerUI)
 
282
    document.getElementById("installerUI").hidden = false;
 
283
 
 
284
  this.canAdvance(false);
 
285
  this.canRewind(false);
 
286
}
 
287
 
 
288
nsPluginInstallerWizard.prototype.toggleInstallPlugin = function (e) {
 
289
  var selectedItem = e.target.selectedItem;
 
290
  var mime = selectedItem._ubufoxPluginInfoMimeType;
 
291
  this.mMimeTypePluginSelections[mime] = selectedItem._ubufoxPluginInfo.pid;
 
292
 
 
293
  let count  = 0;
 
294
  for (mime in this.mMimeTypePluginSelections) {
 
295
    if(this.mMimeTypePluginSelections[mime] && this.mMimeTypePluginSelections[mime] != "-1")
 
296
      count++;
 
297
  }
 
298
 
 
299
  // if no plugins are checked, don't allow to advance
 
300
  if (count > 0)
 
301
    this.canAdvance(true);
 
302
  else
 
303
    this.canAdvance(false);
 
304
}
 
305
 
 
306
nsPluginInstallerWizard.prototype.canAdvance = function (aBool){
 
307
  document.getElementById("plugin-installer-wizard").canAdvance = aBool;
 
308
}
 
309
 
 
310
nsPluginInstallerWizard.prototype.canRewind = function (aBool){
 
311
  document.getElementById("plugin-installer-wizard").canRewind = aBool;
 
312
}
 
313
 
 
314
nsPluginInstallerWizard.prototype.canCancel = function (aBool){
 
315
  document.documentElement.getButton("cancel").disabled = !aBool;
 
316
}
 
317
 
 
318
nsPluginInstallerWizard.prototype.showLicenses = function (){
 
319
  this.canAdvance(false);
 
320
  this.canRewind(false);
 
321
 
 
322
  // only add if a license is provided and the plugin was selected to
 
323
  // be installed
 
324
  for (mimetype in this.mMimeTypePluginSelections){
 
325
    var pid = this.mMimeTypePluginSelections[mimetype];
 
326
    var pluginInfo = this.mPluginPidArray[pid];
 
327
    if (pluginInfo && pluginInfo.licenseURL && (pluginInfo.licenseURL != "")) {
 
328
      this.mPluginLicenseArray.push(pluginInfo.pid);
 
329
    }
 
330
  }
 
331
 
 
332
  if (this.mPluginLicenseArray.length == 0) {
 
333
    // no plugins require licenses
 
334
    this.advancePage(null, true, false, false);
 
335
  } else {
 
336
    this.licenseAcceptCounter = 0;
 
337
 
 
338
    // add a nsIWebProgress listener to the license iframe.
 
339
    var docShell = document.getElementById("licenseIFrame").docShell;
 
340
    var iiReq = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
 
341
    var webProgress = iiReq.getInterface(Components.interfaces.nsIWebProgress);
 
342
    webProgress.addProgressListener(gPluginInstaller.progressListener,
 
343
                                    Components.interfaces.nsIWebProgress.NOTIFY_ALL);
 
344
 
 
345
 
 
346
    this.showLicense();
 
347
  }
 
348
}
 
349
 
 
350
nsPluginInstallerWizard.prototype.enableNext = function (){
 
351
  // if only one plugin exists, don't enable the next button until
 
352
  // the license is accepted
 
353
  if (gPluginInstaller.pluginsToInstallNum > 1)
 
354
    gPluginInstaller.canAdvance(true);
 
355
 
 
356
  document.getElementById("licenseRadioGroup1").disabled = false;
 
357
  document.getElementById("licenseRadioGroup2").disabled = false;
 
358
}
 
359
 
 
360
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
 
361
nsPluginInstallerWizard.prototype.progressListener = {
 
362
  onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
 
363
  {
 
364
    if ((aStateFlags & nsIWebProgressListener.STATE_STOP) &&
 
365
       (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK)) {
 
366
      // iframe loaded
 
367
      gPluginInstaller.enableNext();
 
368
    }
 
369
  },
 
370
 
 
371
  onProgressChange : function(aWebProgress, aRequest, aCurSelfProgress,
 
372
                              aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
 
373
  {},
 
374
  onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
 
375
  {},
 
376
 
 
377
  QueryInterface : function(aIID)
 
378
  {
 
379
     if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
 
380
         aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
 
381
         aIID.equals(Components.interfaces.nsISupports))
 
382
       return this;
 
383
     throw Components.results.NS_NOINTERFACE;
 
384
   }
 
385
}
 
386
 
 
387
nsPluginInstallerWizard.prototype.showLicense = function (){
 
388
  var pluginInfo = this.mPluginPidArray[this.mPluginLicenseArray[this.licenseAcceptCounter]];
 
389
 
 
390
  this.canAdvance(false);
 
391
 
 
392
  loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE;
 
393
 
 
394
  document.getElementById("licenseIFrame").webNavigation.loadURI(pluginInfo.licenseURL, loadFlags, null, null, null);
 
395
 
 
396
  document.getElementById("pluginLicenseLabel").firstChild.nodeValue = 
 
397
    this.getFormattedString("pluginLicenseAgreement.label", [pluginInfo.name]);
 
398
 
 
399
  document.getElementById("licenseRadioGroup1").disabled = true;
 
400
  document.getElementById("licenseRadioGroup2").disabled = true;
 
401
  document.getElementById("licenseRadioGroup").selectedIndex = 
 
402
    pluginInfo.licenseAccepted ? 0 : 1;
 
403
}
 
404
 
 
405
nsPluginInstallerWizard.prototype.showNextLicense = function (){
 
406
  var rv = true;
 
407
 
 
408
  if (this.mPluginLicenseArray.length > 0) {
 
409
    this.storeLicenseRadioGroup();
 
410
 
 
411
    this.licenseAcceptCounter++;
 
412
 
 
413
    if (this.licenseAcceptCounter < this.mPluginLicenseArray.length) {
 
414
      this.showLicense();
 
415
 
 
416
      rv = false;
 
417
      this.canRewind(true);
 
418
    }
 
419
  }
 
420
 
 
421
  return rv;
 
422
}
 
423
 
 
424
nsPluginInstallerWizard.prototype.showPreviousLicense = function (){
 
425
  this.storeLicenseRadioGroup();
 
426
  this.licenseAcceptCounter--;
 
427
 
 
428
  if (this.licenseAcceptCounter > 0)
 
429
    this.canRewind(true);
 
430
  else
 
431
    this.canRewind(false);
 
432
 
 
433
  this.showLicense();
 
434
  
 
435
  // don't allow to return from the license screens
 
436
  return false;
 
437
}
 
438
 
 
439
nsPluginInstallerWizard.prototype.storeLicenseRadioGroup = function (){
 
440
  var pluginInfo = this.mPluginPidArray[this.mPluginLicenseArray[this.licenseAcceptCounter]];
 
441
  pluginInfo.licenseAccepted = !document.getElementById("licenseRadioGroup").selectedIndex;
 
442
}
 
443
 
 
444
nsPluginInstallerWizard.prototype.licenseRadioGroupChange = function(aAccepted) {
 
445
  // only if one plugin is to be installed should selection change the next button
 
446
  if (this.pluginsToInstallNum == 1)
 
447
    this.canAdvance(aAccepted);
 
448
}
 
449
 
 
450
nsPluginInstallerWizard.prototype.advancePage = function (aPageId, aCanAdvance, aCanRewind, aCanCancel){
 
451
  this.canAdvance(true);
 
452
  document.getElementById("plugin-installer-wizard").advance(aPageId);
 
453
 
 
454
  this.canAdvance(aCanAdvance);
 
455
  this.canRewind(aCanRewind);
 
456
  this.canCancel(aCanCancel);
 
457
}
 
458
 
 
459
nsPluginInstallerWizard.prototype.startPluginInstallation = function (){
 
460
  this.canAdvance(false);
 
461
  this.canRewind(false);
 
462
 
 
463
  // since the user can choose what plugins to install, we need to store
 
464
  // which ones were choosen, as nsIXPInstallManager returns an index and not the
 
465
  // mimetype.  So store the pids.
 
466
 
 
467
  // for ubutfox we deal with multiple cases: first case is XPIInstall, which will
 
468
  // run the "normal" XPIInstall process; second case is XPIInstall url contains
 
469
  // and apt: protocol url ... this will run apt protocol handler 
 
470
  var pluginURLArray = new Array();
 
471
  var pluginHashArray = new Array();
 
472
  var pluginPidArray = new Array();
 
473
  this.mAptPluginURLArray = new Array();
 
474
  this.mAptPluginPidArray = new Array();
 
475
 
 
476
  for (mime in this.mMimeTypePluginSelections) {
 
477
    var pluginPid = this.mMimeTypePluginSelections[mime];
 
478
    var pluginItem = this.mPluginPidArray[pluginPid];
 
479
 
 
480
    // only push to the array if it has an XPILocation, else nsIXPInstallManager
 
481
    // will complain.
 
482
    if (pluginItem && pluginItem.XPILocation && pluginItem.XPILocation.indexOf("apt:") != 0 && pluginItem.licenseAccepted) {
 
483
      pluginURLArray.push(pluginItem.XPILocation);
 
484
      pluginHashArray.push(pluginItem.XPIHash);
 
485
      pluginPidArray.push(pluginItem.pid);
 
486
    } else if (pluginItem && pluginItem.XPILocation && pluginItem.XPILocation.indexOf("apt:") == 0) {
 
487
      this.mAptPluginURLArray.push(pluginItem.XPILocation);
 
488
      this.mAptPluginPidArray.push(pluginPid);
 
489
    } else {
 
490
      window.alert("Unhandled mime install flavour (supported: vendor, apt)");
 
491
      continue;
 
492
    }
 
493
  }
 
494
 
 
495
  if (pluginURLArray.length > 0)
 
496
    PluginXPIInstallService.startPluginInstallation(pluginURLArray,
 
497
                                                    pluginHashArray,
 
498
                                                    pluginPidArray);
 
499
  else if (this.mAptPluginURLArray.length > 0)
 
500
    PluginAPTInstallService.startPluginInstallation(this.mAptPluginURLArray,
 
501
                                                    this.mAptPluginPidArray);
 
502
  else
 
503
    this.advancePage(null, true, false, false);
 
504
}
 
505
 
 
506
/*
 
507
  0    starting download
 
508
  1    download finished
 
509
  2    starting installation
 
510
  3    finished installation
 
511
  4    all done
 
512
*/
 
513
nsPluginInstallerWizard.prototype.pluginXPIInstallationProgress = function (aPid, aProgress, aError) {
 
514
 
 
515
  var statMsg = null;
 
516
  var pluginInfo = null;
 
517
 
 
518
  if(aPid)
 
519
    pluginInfo = gPluginInstaller.mPluginPidArray[aPid];
 
520
 
 
521
  switch (aProgress) {
 
522
 
 
523
    case 0:
 
524
      statMsg = this.getFormattedString("pluginInstallation.download.start", [pluginInfo.name]);
 
525
      break;
 
526
 
 
527
    case 1:
 
528
      statMsg = this.getFormattedString("pluginInstallation.download.finish", [pluginInfo.name]);
 
529
      break;
 
530
 
 
531
    case 2:
 
532
      statMsg = this.getFormattedString("pluginInstallation.install.start", [pluginInfo.name]);
 
533
      break;
 
534
    case 6:
 
535
      statMsg = "APT - " + this.getFormattedString("pluginInstallation.install.start", [pluginInfo.name]);
 
536
      break;
 
537
    case 3:
 
538
      if (aError) {
 
539
        statMsg = this.getFormattedString("pluginInstallation.install.error", [pluginInfo.name, aError]);
 
540
        pluginInfo.error = aError;
 
541
      } else {
 
542
        statMsg = this.getFormattedString("pluginInstallation.install.finish", [pluginInfo.name]);
 
543
        pluginInfo.error = null;
 
544
      }
 
545
      break;
 
546
 
 
547
    case 7:
 
548
      if (aError) {
 
549
        statMsg = "APT - " + this.getFormattedString("pluginInstallation.install.error", [pluginInfo.name, aError]);
 
550
        pluginInfo.error = aError;
 
551
      } else {
 
552
        statMsg = "APT - " + this.getFormattedString("pluginInstallation.install.finish", [pluginInfo.name]);
 
553
        pluginInfo.error = null;
 
554
      }
 
555
      break;
 
556
 
 
557
    case 4:
 
558
      PluginAPTInstallService.startPluginInstallation(this.mAptPluginURLArray,
 
559
                                                      this.mAptPluginPidArray);
 
560
      break;
 
561
    case 8:
 
562
      this.advancePage(null, true, false, false);
 
563
      statMsg = this.getString("pluginInstallation.complete");
 
564
      break;
 
565
    default:
 
566
      window.alert("unexpected error during plugin install [code=1001]");
 
567
      break;
 
568
  }
 
569
 
 
570
  if (statMsg)
 
571
    document.getElementById("plugin_install_progress_message").value = statMsg;
 
572
}
 
573
 
 
574
nsPluginInstallerWizard.prototype.pluginInstallationProgressMeter = function (aPid, aValue, aMaxValue){
 
575
  var progressElm = document.getElementById("plugin_install_progress");
 
576
 
 
577
  if (progressElm.getAttribute("mode") == "undetermined")
 
578
    progressElm.setAttribute("mode", "determined");
 
579
  
 
580
  progressElm.setAttribute("value", Math.ceil((aValue / aMaxValue) * 100) + "%")
 
581
}
 
582
 
 
583
nsPluginInstallerWizard.prototype.addPluginResultRow = function (aImgSrc, aName, aNameTooltip, aStatus, aStatusTooltip, aManualUrl){
 
584
  var myRows = document.getElementById("pluginResultList");
 
585
 
 
586
  var myRow = document.createElement("row");
 
587
  myRow.setAttribute("align", "center");
 
588
 
 
589
  // create the image
 
590
  var myImage = document.createElement("image");
 
591
  myImage.setAttribute("src", aImgSrc);
 
592
  myImage.setAttribute("height", "16px");
 
593
  myImage.setAttribute("width", "16px");
 
594
  myRow.appendChild(myImage)
 
595
 
 
596
  // create the labels
 
597
  var myLabel = document.createElement("label");
 
598
  myLabel.setAttribute("value", aName);
 
599
  if (aNameTooltip)
 
600
    myLabel.setAttribute("tooltiptext", aNameTooltip);
 
601
  myRow.appendChild(myLabel);
 
602
 
 
603
  if (aStatus) {
 
604
    myLabel = document.createElement("label");
 
605
    myLabel.setAttribute("value", aStatus);
 
606
    myRow.appendChild(myLabel);
 
607
  }
 
608
 
 
609
  // manual install
 
610
  if (aManualUrl) {
 
611
    var myButton = document.createElement("button");
 
612
 
 
613
    var manualInstallLabel = this.getString("pluginInstallationSummary.manualInstall.label");
 
614
    var manualInstallTooltip = this.getString("pluginInstallationSummary.manualInstall.tooltip");
 
615
 
 
616
    myButton.setAttribute("label", manualInstallLabel);
 
617
    myButton.setAttribute("tooltiptext", manualInstallTooltip);
 
618
 
 
619
    myRow.appendChild(myButton);
 
620
 
 
621
    // XXX: XUL sucks, need to add the listener after it got added into the document
 
622
    if (aManualUrl)
 
623
      myButton.addEventListener("command", function() { gPluginInstaller.loadURL(aManualUrl) }, false);
 
624
  }
 
625
 
 
626
  myRows.appendChild(myRow);
 
627
}
 
628
 
 
629
nsPluginInstallerWizard.prototype.showPluginResults = function (){
 
630
  var notInstalledList = "?action=missingplugins";
 
631
  var myRows = document.getElementById("pluginResultList");
 
632
 
 
633
  this.mNeedsRestart = false;
 
634
 
 
635
  // clear children
 
636
  for (var run = myRows.childNodes.length; run--; run > 0)
 
637
    myRows.removeChild(myRows.childNodes.item(run));
 
638
 
 
639
  for (mimetype in this.mMimeTypePluginSelections) {
 
640
    var pid = this.mMimeTypePluginSelections[mimetype];
 
641
    var pluginInfoItem = this.mPluginPidArray[pid];
 
642
    // [plugin image] [Plugin_Name Plugin_Version] [Success/Failed] [Manual Install (if Failed)]
 
643
 
 
644
    var myPluginItem = pluginInfoItem; //this.mPluginInfoArray[pluginInfoItem];
 
645
 
 
646
    var statusMsg;
 
647
    var statusTooltip;
 
648
    if (myPluginItem.error){
 
649
      statusMsg = this.getString("pluginInstallationSummary.failed");
 
650
      statusTooltip = myPluginItem.error;
 
651
      notInstalledList += "&mimetype=" + pluginInfoItem;
 
652
    } else if (myPluginItem.licenseURL && !myPluginItem.licenseAccepted) {
 
653
      statusMsg = this.getString("pluginInstallationSummary.licenseNotAccepted");
 
654
    } else if (!myPluginItem.XPILocation) {
 
655
      statusMsg = this.getString("pluginInstallationSummary.notAvailable");
 
656
      notInstalledList += "&mimetype=" + pluginInfoItem;
 
657
    } else {
 
658
      this.mSuccessfullPluginInstallation++;
 
659
      statusMsg = this.getString("pluginInstallationSummary.success");
 
660
 
 
661
      // only check needsRestart if the plugin was successfully installed.
 
662
      if (myPluginItem.needsRestart)
 
663
        this.mNeedsRestart = false;
 
664
    }
 
665
 
 
666
    // manual url - either returned from the webservice or the pluginspage attribute
 
667
    var manualUrl;
 
668
    if ((myPluginItem.error || !myPluginItem.XPILocation) && (myPluginItem.manualInstallationURL || this.mPluginRequestArray[myPluginItem.requestedMimetype].pluginsPage)){
 
669
      manualUrl = myPluginItem.manualInstallationURL ? myPluginItem.manualInstallationURL : this.mPluginRequestArray[myPluginItem.requestedMimetype].pluginsPage;
 
670
    }
 
671
 
 
672
    this.addPluginResultRow(
 
673
                            myPluginItem.IconUrl, 
 
674
                            myPluginItem.name + " " + (myPluginItem.version ? myPluginItem.version : ""),
 
675
                            null,
 
676
                            statusMsg, 
 
677
                            statusTooltip,
 
678
                            manualUrl);
 
679
  }
 
680
 
 
681
  // handle plugins we couldn't find
 
682
  for (pluginInfoItem in this.mPluginNotFoundArray){
 
683
    var pluginRequest = this.mPluginRequestArray[pluginInfoItem];
 
684
 
 
685
    // if there is a pluginspage, show UI
 
686
    if (pluginRequest) {
 
687
      this.addPluginResultRow(
 
688
          "",
 
689
          this.getFormattedString("pluginInstallation.unknownPlugin", [pluginInfoItem]),
 
690
          null,
 
691
          null,
 
692
          null,
 
693
          pluginRequest.pluginsPage);
 
694
    }
 
695
 
 
696
    notInstalledList += "&mimetype=" + pluginInfoItem;
 
697
  }
 
698
 
 
699
  // no plugins were found, so change the description of the final page.
 
700
  if (this.mPluginInfoArrayLength == 0) {
 
701
    var noPluginsFound = this.getString("pluginInstallation.noPluginsFound");
 
702
    document.getElementById("pluginSummaryDescription").setAttribute("value", noPluginsFound);
 
703
  } else if (this.mSuccessfullPluginInstallation == 0) {
 
704
    // plugins found, but none were installed.
 
705
    var noPluginsInstalled = this.getString("pluginInstallation.noPluginsInstalled");
 
706
    document.getElementById("pluginSummaryDescription").setAttribute("value", noPluginsInstalled);
 
707
  }
 
708
 
 
709
  document.getElementById("pluginSummaryRestartNeeded").hidden = !this.mNeedsRestart;
 
710
 
 
711
  var app = Components.classes["@mozilla.org/xre/app-info;1"]
 
712
                      .getService(Components.interfaces.nsIXULAppInfo);
 
713
 
 
714
  // set the get more info link to contain the mimetypes we couldn't install.
 
715
  notInstalledList +=
 
716
    "&appID=" + app.ID +
 
717
    "&appVersion=" + app.platformBuildID +
 
718
    "&clientOS=" + this.getOS() +
 
719
    "&chromeLocale=" + this.getChromeLocale();
 
720
 
 
721
  document.getElementById("moreInfoLink").addEventListener("click", function() { gPluginInstaller.loadURL("https://pfs.mozilla.org/plugins/" + notInstalledList) }, false);
 
722
 
 
723
  this.canAdvance(true);
 
724
  this.canRewind(false);
 
725
  this.canCancel(false);
 
726
}
 
727
 
 
728
nsPluginInstallerWizard.prototype.loadURL = function (aUrl){
 
729
  // Check if the page where the plugin came from can load aUrl before
 
730
  // loading it, and do *not* allow loading javascript: or data: URIs.
 
731
  var pluginPage = window.opener.content.location.href;
 
732
 
 
733
  const nsIScriptSecurityManager =
 
734
    Components.interfaces.nsIScriptSecurityManager;
 
735
  var secMan =
 
736
    Components.classes["@mozilla.org/scriptsecuritymanager;1"]
 
737
    .getService(nsIScriptSecurityManager);
 
738
 
 
739
  secMan.checkLoadURIStr(pluginPage, aUrl,
 
740
                         nsIScriptSecurityManager.DISALLOW_SCRIPT_OR_DATA);
 
741
 
 
742
  window.opener.open(aUrl);
 
743
}
 
744
 
 
745
nsPluginInstallerWizard.prototype.getString = function (aName){
 
746
  var result;
 
747
  try {
 
748
    result = document.getElementById("pluginWizardString").getString(aName);
 
749
  }
 
750
  catch (e) {
 
751
    result = document.getElementById("ubufoxPluginWizardString").getString(aName);
 
752
  }
 
753
  return result;
 
754
}
 
755
 
 
756
nsPluginInstallerWizard.prototype.getFormattedString = function (aName, aArray){
 
757
  var result;
 
758
  try {
 
759
    result = document.getElementById("pluginWizardString").getFormattedString(aName, aArray);
 
760
  }
 
761
  catch (e) {
 
762
    result = document.getElementById("ubufoxPluginWizardString").getFormattedString(aName, aArray);
 
763
  }
 
764
  return result;
 
765
}
 
766
 
 
767
nsPluginInstallerWizard.prototype.getOS = function (){
 
768
  var httpService = Components.classes["@mozilla.org/network/protocol;1?name=http"]
 
769
                              .getService(Components.interfaces.nsIHttpProtocolHandler);
 
770
  return httpService.oscpu;
 
771
}
 
772
 
 
773
nsPluginInstallerWizard.prototype.getChromeLocale = function (){
 
774
  var chromeReg = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
 
775
                            .getService(Components.interfaces.nsIXULChromeRegistry);
 
776
  return chromeReg.getSelectedLocale("global");
 
777
}
 
778
 
 
779
nsPluginInstallerWizard.prototype.getPrefBranch = function (){
 
780
  if (!this.prefBranch)
 
781
    this.prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
 
782
                                .getService(Components.interfaces.nsIPrefBranch);
 
783
  return this.prefBranch;
 
784
}
 
785
function nsPluginRequest(aPlugRequest){
 
786
  this.mimetype = encodeURI(aPlugRequest.mimetype);
 
787
  this.pluginsPage = aPlugRequest.pluginsPage;
 
788
}
 
789
 
 
790
function PluginInfo(aResult) {
 
791
  this.name = aResult.name;
 
792
  this.pid = aResult.pid;
 
793
  this.version = aResult.version;
 
794
  this.IconUrl = aResult.IconUrl;
 
795
  this.XPILocation = aResult.XPILocation;
 
796
  this.XPIHash = aResult.XPIHash;
 
797
  this.InstallerShowsUI = aResult.InstallerShowsUI;
 
798
  this.manualInstallationURL = aResult.manualInstallationURL;
 
799
  this.requestedMimetype = aResult.requestedMimetype;
 
800
  this.licenseURL = aResult.licenseURL;
 
801
  this.needsRestart = (aResult.needsRestart == "true");
 
802
 
 
803
  this.error = null;
 
804
  this.toBeInstalled = true;
 
805
 
 
806
  // no license provided, make it accepted
 
807
  this.licenseAccepted = this.licenseURL ? false : true;
 
808
}
 
809
 
 
810
var gPluginInstaller;
 
811
 
 
812
function wizardInit(){
 
813
  gPluginInstaller = new nsPluginInstallerWizard();
 
814
  gPluginInstaller.canAdvance(false);
 
815
  gPluginInstaller.getPluginData();
 
816
}
 
817
 
 
818
function wizardFinish(){
 
819
  // we restart if we have no choice ...
 
820
  if (gPluginInstaller.mNeedsRestart) {
 
821
    // Notify all windows that an application quit has been requested.
 
822
    var os = Components.classes["@mozilla.org/observer-service;1"]
 
823
                       .getService(Components.interfaces.nsIObserverService);
 
824
    var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
 
825
                               .createInstance(Components.interfaces.nsISupportsPRBool);
 
826
    os.notifyObservers(cancelQuit, "quit-application-requested", "restart");
 
827
 
 
828
    // Something aborted the quit process.
 
829
    if (!cancelQuit.data) {
 
830
      var nsIAppStartup = Components.interfaces.nsIAppStartup;
 
831
      var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
 
832
                                 .getService(nsIAppStartup);
 
833
      appStartup.quit(nsIAppStartup.eAttemptQuit | nsIAppStartup.eRestart);
 
834
      return true;
 
835
    }
 
836
  }
 
837
 
 
838
  if (gPluginInstaller.mBrowser) { // ffox 3 code can autoscan ...
 
839
    // always refresh
 
840
    var event = document.createEvent("Events");
 
841
    event.initEvent("NewPluginInstalled", true, true);
 
842
    var dispatched = gPluginInstaller.mBrowser.dispatchEvent(event);
 
843
  }
 
844
  else if (gPluginInstaller.mTab) { // ffox 2 code can autoscan ...
 
845
    if ((gPluginInstaller.mSuccessfullPluginInstallation > 0) &&
 
846
       (gPluginInstaller.mPluginInfoArrayLength != 0)) {
 
847
      // clear the tab's plugin list only if we installed at least one plugin
 
848
      gPluginInstaller.mTab.missingPlugins = null;
 
849
      // reset UI
 
850
      window.opener.gMissingPluginInstaller.closeNotification();
 
851
      // reload the browser to make the new plugin show
 
852
      window.opener.getBrowser().reloadTab(gPluginInstaller.mTab);
 
853
    }
 
854
  }
 
855
 
 
856
  return true;
 
857
}
 
858