addon-sdk/source/lib/sdk/system/xul-app.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/addon-sdk/source/lib/sdk/system/xul-app.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,184 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +"use strict";
     1.8 +
     1.9 +module.metadata = {
    1.10 +  "stability": "experimental"
    1.11 +};
    1.12 +
    1.13 +var { Cc, Ci } = require("chrome");
    1.14 +
    1.15 +var appInfo = Cc["@mozilla.org/xre/app-info;1"]
    1.16 +              .getService(Ci.nsIXULAppInfo);
    1.17 +var vc = Cc["@mozilla.org/xpcom/version-comparator;1"]
    1.18 +         .getService(Ci.nsIVersionComparator);
    1.19 +
    1.20 +var ID = exports.ID = appInfo.ID;
    1.21 +var name = exports.name = appInfo.name;
    1.22 +var version = exports.version = appInfo.version;
    1.23 +var platformVersion = exports.platformVersion = appInfo.platformVersion;
    1.24 +
    1.25 +// The following mapping of application names to GUIDs was taken from:
    1.26 +//
    1.27 +//   https://addons.mozilla.org/en-US/firefox/pages/appversions
    1.28 +//
    1.29 +// Using the GUID instead of the app's name is preferable because sometimes
    1.30 +// re-branded versions of a product have different names: for instance,
    1.31 +// Firefox, Minefield, Iceweasel, and Shiretoko all have the same
    1.32 +// GUID.
    1.33 +// This mapping is duplicated in `app-extensions/bootstrap.js`. They should keep
    1.34 +// in sync, so if you change one, change the other too!
    1.35 +
    1.36 +var ids = exports.ids = {
    1.37 +  Firefox: "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
    1.38 +  Mozilla: "{86c18b42-e466-45a9-ae7a-9b95ba6f5640}",
    1.39 +  Sunbird: "{718e30fb-e89b-41dd-9da7-e25a45638b28}",
    1.40 +  SeaMonkey: "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}",
    1.41 +  Fennec: "{aa3c5121-dab2-40e2-81ca-7ea25febc110}",
    1.42 +  Thunderbird: "{3550f703-e582-4d05-9a08-453d09bdfdc6}"
    1.43 +};
    1.44 +
    1.45 +function is(name) {
    1.46 +  if (!(name in ids))
    1.47 +    throw new Error("Unkown Mozilla Application: " + name);
    1.48 +  return ID == ids[name];
    1.49 +};
    1.50 +exports.is = is;
    1.51 +
    1.52 +function isOneOf(names) {
    1.53 +  for (var i = 0; i < names.length; i++)
    1.54 +    if (is(names[i]))
    1.55 +      return true;
    1.56 +  return false;
    1.57 +};
    1.58 +exports.isOneOf = isOneOf;
    1.59 +
    1.60 +/**
    1.61 + * Use this to check whether the given version (e.g. xulApp.platformVersion)
    1.62 + * is in the given range. Versions must be in version comparator-compatible
    1.63 + * format. See MDC for details:
    1.64 + * https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIVersionComparator
    1.65 + */
    1.66 +var versionInRange = exports.versionInRange =
    1.67 +function versionInRange(version, lowInclusive, highExclusive) {
    1.68 +  return (vc.compare(version, lowInclusive) >= 0) &&
    1.69 +         (vc.compare(version, highExclusive) < 0);
    1.70 +}
    1.71 +
    1.72 +const reVersionRange = /^((?:<|>)?=?)?\s*((?:\d+[\S]*)|\*)(?:\s+((?:<|>)=?)?(\d+[\S]+))?$/;
    1.73 +const reOnlyInifinity = /^[<>]?=?\s*[*x]$/;
    1.74 +const reSubInfinity = /\.[*x]/g;
    1.75 +const reHyphenRange = /^(\d+.*?)\s*-\s*(\d+.*?)$/;
    1.76 +const reRangeSeparator = /\s*\|\|\s*/;
    1.77 +
    1.78 +const compares = {
    1.79 +  "=": function (c) { return c === 0 },
    1.80 +  ">=": function (c) { return c >= 0 },
    1.81 +  "<=": function (c) { return c <= 0},
    1.82 +  "<": function (c) { return c < 0 },
    1.83 +  ">": function (c) { return c > 0 }
    1.84 +}
    1.85 +
    1.86 +function normalizeRange(range) {
    1.87 +    return range
    1.88 +        .replace(reOnlyInifinity, "")
    1.89 +        .replace(reSubInfinity, ".*")
    1.90 +        .replace(reHyphenRange, ">=$1 <=$2")
    1.91 +}
    1.92 +
    1.93 +/**
    1.94 + * Compare the versions given, using the comparison operator provided.
    1.95 + * Internal use only.
    1.96 + *
    1.97 + * @example
    1.98 + *  compareVersion("1.2", "<=", "1.*") // true
    1.99 + *
   1.100 + * @param {String} version
   1.101 + *  A version to compare
   1.102 + *
   1.103 + * @param {String} comparison
   1.104 + *  The comparison operator
   1.105 + *
   1.106 + * @param {String} compareVersion
   1.107 + *  A version to compare
   1.108 + */
   1.109 +function compareVersion(version, comparison, compareVersion) {
   1.110 +  let hasWildcard = compareVersion.indexOf("*") !== -1;
   1.111 +
   1.112 +  comparison = comparison || "=";
   1.113 +
   1.114 +  if (hasWildcard) {
   1.115 +    switch (comparison) {
   1.116 +      case "=":
   1.117 +        let zeroVersion = compareVersion.replace(reSubInfinity, ".0");
   1.118 +        return versionInRange(version, zeroVersion, compareVersion);
   1.119 +      case ">=":
   1.120 +        compareVersion = compareVersion.replace(reSubInfinity, ".0");
   1.121 +        break;
   1.122 +    }
   1.123 +  }
   1.124 +
   1.125 +  let compare = compares[comparison];
   1.126 +
   1.127 +  return typeof compare === "function" && compare(vc.compare(version, compareVersion));
   1.128 +}
   1.129 +
   1.130 +/**
   1.131 + * Returns `true` if `version` satisfies the `versionRange` given.
   1.132 + * If only an argument is passed, is used as `versionRange` and compared against
   1.133 + * `xulApp.platformVersion`.
   1.134 + *
   1.135 + * `versionRange` is either a string which has one or more space-separated
   1.136 + * descriptors, or a range like "fromVersion - toVersion".
   1.137 + * Version range descriptors may be any of the following styles:
   1.138 + *
   1.139 + * - "version" Must match `version` exactly
   1.140 + * - "=version" Same as just `version`
   1.141 + * - ">version" Must be greater than `version`
   1.142 + * - ">=version" Must be greater or equal than `version`
   1.143 + * - "<version" Must be less than `version`
   1.144 + * - "<=version" Must be less or equal than `version`
   1.145 + * - "1.2.x" or "1.2.*" See 'X version ranges' below
   1.146 + * - "*" or "" (just an empty string) Matches any version
   1.147 + * - "version1 - version2" Same as ">=version1 <=version2"
   1.148 + * - "range1 || range2" Passes if either `range1` or `range2` are satisfied
   1.149 + *
   1.150 + * For example, these are all valid:
   1.151 + * - "1.0.0 - 2.9999.9999"
   1.152 + * - ">=1.0.2 <2.1.2"
   1.153 + * - ">1.0.2 <=2.3.4"
   1.154 + * - "2.0.1"
   1.155 + * - "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
   1.156 + * - "2.x" (equivalent to "2.*")
   1.157 + * - "1.2.x" (equivalent to "1.2.*" and ">=1.2.0 <1.3.0")
   1.158 + */
   1.159 +function satisfiesVersion(version, versionRange) {
   1.160 +  if (arguments.length === 1) {
   1.161 +    versionRange = version;
   1.162 +    version = appInfo.version;
   1.163 +  }
   1.164 +
   1.165 +  let ranges = versionRange.trim().split(reRangeSeparator);
   1.166 +
   1.167 +  return ranges.some(function(range) {
   1.168 +    range = normalizeRange(range);
   1.169 +
   1.170 +    // No versions' range specified means that any version satisfies the
   1.171 +    // requirements.
   1.172 +    if (range === "")
   1.173 +      return true;
   1.174 +
   1.175 +    let matches = range.match(reVersionRange);
   1.176 +
   1.177 +    if (!matches)
   1.178 +      return false;
   1.179 +
   1.180 +    let [, lowMod, lowVer, highMod, highVer] = matches;
   1.181 +
   1.182 +    return compareVersion(version, lowMod, lowVer) && (highVer !== undefined
   1.183 +      ? compareVersion(version, highMod, highVer)
   1.184 +      : true);
   1.185 +  });
   1.186 +}
   1.187 +exports.satisfiesVersion = satisfiesVersion;

mercurial