B2G/gecko/toolkit/mozapps/extensions/AddonManager.jsm
/**
   * Replaces %...% strings in an addon url (update and updateInfo) with
   * appropriate values.
   *
   * @param  aAddon
   *         The Addon representing the add-on
   * @param  aUri
   *         The string representation of the URI to escape
   * @param  aAppVersion
   *         The optional application version to use for %APP_VERSION%
   * @return The appropriately escaped URI.
   */
Replaces %...% strings in an addon url (update and updateInfo) with
appropriate values.

@param  aAddon
The Addon representing the add-on
@param  aUri
The string representation of the URI to escape
@param  aAppVersion
The optional application version to use for %APP_VERSION%
@return The appropriately escaped URI.
Replaces % ... % strings in an addon url ( update and updateInfo ) with appropriate values . @param aAddon The Addon representing the add - on @param aUri The string representation of the URI to escape @param aAppVersion The optional application version to use for %APP_VERSION% @return The appropriately escaped URI .
function AMI_escapeAddonURI(aAddon, aUri, aAppVersion)
  {
    if (!aAddon || typeof aAddon != "object")
      throw Components.Exception("aAddon must be an Addon object",
                                 Cr.NS_ERROR_INVALID_ARG);
    if (!aUri || typeof aUri != "string")
      throw Components.Exception("aUri must be a non-empty string",
                                 Cr.NS_ERROR_INVALID_ARG);
    if (aAppVersion && typeof aAppVersion != "string")
      throw Components.Exception("aAppVersion must be a string or null",
                                 Cr.NS_ERROR_INVALID_ARG);
    var addonStatus = aAddon.userDisabled || aAddon.softDisabled ? "userDisabled"
                                                                 : "userEnabled";
    if (!aAddon.isCompatible)
      addonStatus += ",incompatible";
    if (aAddon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
      addonStatus += ",blocklisted";
    if (aAddon.blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
      addonStatus += ",softblocked";
    try {
      var xpcomABI = Services.appinfo.XPCOMABI;
    } catch (ex) {
      xpcomABI = UNKNOWN_XPCOM_ABI;
    }
    let uri = aUri.replace(/%ITEM_ID%/g, aAddon.id);
    uri = uri.replace(/%ITEM_VERSION%/g, aAddon.version);
    uri = uri.replace(/%ITEM_STATUS%/g, addonStatus);
    uri = uri.replace(/%APP_ID%/g, Services.appinfo.ID);
    uri = uri.replace(/%APP_VERSION%/g, aAppVersion ? aAppVersion :
                                                      Services.appinfo.version);
    uri = uri.replace(/%REQ_VERSION%/g, UPDATE_REQUEST_VERSION);
    uri = uri.replace(/%APP_OS%/g, Services.appinfo.OS);
    uri = uri.replace(/%APP_ABI%/g, xpcomABI);
    uri = uri.replace(/%APP_LOCALE%/g, getLocale());
    uri = uri.replace(/%CURRENT_APP_VERSION%/g, Services.appinfo.version);
    var catMan = null;
    uri = uri.replace(/%(\w{3,})%/g, function(aMatch, aParam) {
      if (!catMan) {
        catMan = Cc["@mozilla.org/categorymanager;1"].
                 getService(Ci.nsICategoryManager);
      }
      try {
        var contractID = catMan.getCategoryEntry(CATEGORY_UPDATE_PARAMS, aParam);
        var paramHandler = Cc[contractID].getService(Ci.nsIPropertyBag2);
        return paramHandler.getPropertyAsAString(aParam);
      }
      catch(e) {
        return aMatch;
      }
    });
    return uri.replace(/\+/g, "%2B");
  }
function AMI_escapeAddonURI ( aAddon , aUri , aAppVersion ) { if ( ! aAddon || typeof aAddon != "object" ) throw Components . Exception ( "aAddon must be an Addon object" , Cr . NS_ERROR_INVALID_ARG ) ; if ( ! aUri || typeof aUri != "string" ) throw Components . Exception ( "aUri must be a non-empty string" , Cr . NS_ERROR_INVALID_ARG ) ; if ( aAppVersion && typeof aAppVersion != "string" ) throw Components . Exception ( "aAppVersion must be a string or null" , Cr . NS_ERROR_INVALID_ARG ) ; var addonStatus = aAddon . userDisabled || aAddon . softDisabled ? "userDisabled" : "userEnabled" ; if ( ! aAddon . isCompatible ) addonStatus += ",incompatible" ; if ( aAddon . blocklistState == Ci . nsIBlocklistService . STATE_BLOCKED ) addonStatus += ",blocklisted" ; if ( aAddon . blocklistState == Ci . nsIBlocklistService . STATE_SOFTBLOCKED ) addonStatus += ",softblocked" ; try { var xpcomABI = Services . appinfo . XPCOMABI ; } catch ( ex ) { xpcomABI = UNKNOWN_XPCOM_ABI ; } let uri = aUri . replace ( / %ITEM_ID% / g , aAddon . id ) ; uri = uri . replace ( / %ITEM_VERSION% / g , aAddon . version ) ; uri = uri . replace ( / %ITEM_STATUS% / g , addonStatus ) ; uri = uri . replace ( / %APP_ID% / g , Services . appinfo . ID ) ; uri = uri . replace ( / %APP_VERSION% / g , aAppVersion ? aAppVersion : Services . appinfo . version ) ; uri = uri . replace ( / %REQ_VERSION% / g , UPDATE_REQUEST_VERSION ) ; uri = uri . replace ( / %APP_OS% / g , Services . appinfo . OS ) ; uri = uri . replace ( / %APP_ABI% / g , xpcomABI ) ; uri = uri . replace ( / %APP_LOCALE% / g , getLocale ( ) ) ; uri = uri . replace ( / %CURRENT_APP_VERSION% / g , Services . appinfo . version ) ; var catMan = null ; uri = uri . replace ( / %(\w{3,})% / g , function ( aMatch , aParam ) { if ( ! catMan ) { catMan = Cc [ "@mozilla.org/categorymanager;1" ] . getService ( Ci . nsICategoryManager ) ; } try { var contractID = catMan . getCategoryEntry ( CATEGORY_UPDATE_PARAMS , aParam ) ; var paramHandler = Cc [ contractID ] . getService ( Ci . nsIPropertyBag2 ) ; return paramHandler . getPropertyAsAString ( aParam ) ; } catch ( e ) { return aMatch ; } } ) ; return uri . replace ( / \+ / g , "%2B" ) ; }
Replaces %...% strings in an addon url (update and updateInfo) with
 appropriate values.
Replaces % ... % strings in an addon url ( update and updateInfo ) with appropriate values .
// Replace custom parameters (names of custom parameters must have at // least 3 characters to prevent lookups for something like %D0%C8) // escape() does not properly encode + symbols in any embedded FVF strings.