B2G/gecko/toolkit/mozapps/extensions/XPIProvider.jsm
/**
   * Loads add-on manifests from a multi-package XPI file. Each of the
   * XPI and JAR files contained in the XPI will be extracted. Any that
   * do not contain valid add-ons will be ignored. The first valid add-on will
   * be installed by this AddonInstall instance, the rest will have new
   * AddonInstall instances created for them.
   *
   * @param  aZipReader
   *         An open nsIZipReader for the multi-package XPI's files. This will
   *         be closed before this method returns.
   * @param  aCallback
   *         A function to call when all of the add-on manifests have been
   *         loaded.
   */
Loads add-on manifests from a multi-package XPI file. Each of the
XPI and JAR files contained in the XPI will be extracted. Any that
do not contain valid add-ons will be ignored. The first valid add-on will
be installed by this AddonInstall instance, the rest will have new
AddonInstall instances created for them.

@param  aZipReader
An open nsIZipReader for the multi-package XPI's files. This will
be closed before this method returns.
@param  aCallback
A function to call when all of the add-on manifests have been
loaded.
Loads add - on manifests from a multi - package XPI file . Each of the XPI and JAR files contained in the XPI will be extracted . Any that do not contain valid add - ons will be ignored . The first valid add - on will be installed by this AddonInstall instance the rest will have new AddonInstall instances created for them . @param aZipReader An open nsIZipReader for the multi - package XPI ' s files . This will be closed before this method returns . @param aCallback A function to call when all of the add - on manifests have been loaded .
function AI_loadMultipackageManifests(aZipReader,
                                                                   aCallback) {
    let files = [];
    let entries = aZipReader.findEntries("(*.[Xx][Pp][Ii]|*.[Jj][Aa][Rr])");
    while (entries.hasMore()) {
      let entryName = entries.getNext();
      var target = getTemporaryFile();
      try {
        aZipReader.extract(entryName, target);
        files.push(target);
      }
      catch (e) {
        WARN("Failed to extract " + entryName + " from multi-package " +
             "XPI", e);
        target.remove(false);
      }
    }
    aZipReader.close();
    if (files.length == 0) {
      throw new Error("Multi-package XPI does not contain any packages " +
                      "to install");
    }
    let addon = null;
    while (files.length > 0) {
      this.removeTemporaryFile();
      this.file = files.shift();
      this.ownsTempFile = true;
      try {
        addon = loadManifestFromZipFile(this.file);
        break;
      }
      catch (e) {
        WARN(this.file.leafName + " cannot be installed from multi-package " +
             "XPI", e);
      }
    }
    if (!addon) {
      aCallback();
      return;
    }
    this.addon = addon;
    this.updateAddonURIs();
    this.addon._install = this;
    this.name = this.addon.selectedLocale.name;
    this.type = this.addon.type;
    this.version = this.addon.version;
    if (files.length > 0) {
      this.linkedInstalls = [];
      let count = 0;
      let self = this;
      files.forEach(function(file) {
        AddonInstall.createInstall(function loadMultipackageManifests_createInstall(aInstall) {
          if (aInstall.state == AddonManager.STATE_DOWNLOAD_FAILED) {
            file.remove(true);
          }
          else {
            aInstall.ownsTempFile = true;
            self.linkedInstalls.push(aInstall)
            aInstall.sourceURI = self.sourceURI;
            aInstall.releaseNotesURI = self.releaseNotesURI;
            aInstall.updateAddonURIs();
          }
          count++;
          if (count == files.length)
            aCallback();
        }, file);
      }, this);
    }
    else {
      aCallback();
    }
  }
function AI_loadMultipackageManifests ( aZipReader , aCallback ) { let files = [ ] ; let entries = aZipReader . findEntries ( "(*.[Xx][Pp][Ii]|*.[Jj][Aa][Rr])" ) ; while ( entries . hasMore ( ) ) { let entryName = entries . getNext ( ) ; var target = getTemporaryFile ( ) ; try { aZipReader . extract ( entryName , target ) ; files . push ( target ) ; } catch ( e ) { WARN ( "Failed to extract " + entryName + " from multi-package " + "XPI" , e ) ; target . remove ( false ) ; } } aZipReader . close ( ) ; if ( files . length == 0 ) { throw new Error ( "Multi-package XPI does not contain any packages " + "to install" ) ; } let addon = null ; while ( files . length > 0 ) { this . removeTemporaryFile ( ) ; this . file = files . shift ( ) ; this . ownsTempFile = true ; try { addon = loadManifestFromZipFile ( this . file ) ; break ; } catch ( e ) { WARN ( this . file . leafName + " cannot be installed from multi-package " + "XPI" , e ) ; } } if ( ! addon ) { aCallback ( ) ; return ; } this . addon = addon ; this . updateAddonURIs ( ) ; this . addon . _install = this ; this . name = this . addon . selectedLocale . name ; this . type = this . addon . type ; this . version = this . addon . version ; if ( files . length > 0 ) { this . linkedInstalls = [ ] ; let count = 0 ; let self = this ; files . forEach ( function ( file ) { AddonInstall . createInstall ( function loadMultipackageManifests_createInstall ( aInstall ) { if ( aInstall . state == AddonManager . STATE_DOWNLOAD_FAILED ) { file . remove ( true ) ; } else { aInstall . ownsTempFile = true ; self . linkedInstalls . push ( aInstall ) aInstall . sourceURI = self . sourceURI ; aInstall . releaseNotesURI = self . releaseNotesURI ; aInstall . updateAddonURIs ( ) ; } count ++ ; if ( count == files . length ) aCallback ( ) ; } , file ) ; } , this ) ; } else { aCallback ( ) ; } }
Loads add-on manifests from a multi-package XPI file.
Loads add - on manifests from a multi - package XPI file .
// Find the first file that has a valid install manifest and use it for // the add-on that this AddonInstall instance will install. // No valid add-on was found // Setting the iconURL to something inside the XPI locks the XPI and // makes it impossible to delete on Windows. //let newIcon = createWrapper(this.addon).iconURL; //if (newIcon) //  this.iconURL = newIcon; // Create new AddonInstall instances for every remaining file // Ignore bad add-ons (createInstall will have logged the error) // Manually remove the temporary file // Make the new install own its temporary file