Bringing VersionCompare into zamboni, as well as user agent detection.

This commit is contained in:
Matt Claypotch 2011-02-16 17:01:52 -08:00
Родитель dffb52cc03
Коммит 5825249d19
7 изменённых файлов: 164 добавлений и 164 удалений

Просмотреть файл

@ -1,122 +1,3 @@
/* TODO(jbalogh): save from amo2009. */
var UA_PATTERN_FIREFOX = /Mozilla.*(Firefox|Minefield|Namoroka|Shiretoko|GranParadiso|BonEcho|Iceweasel|Fennec|MozillaDeveloperPreview)\/([^\s]*).*$/;
var UA_PATTERN_SEAMONKEY = /Mozilla.*(SeaMonkey|Iceape)\/([^\s]*).*$/;
var UA_PATTERN_MOBILE = /Mozilla.*(Fennec)\/([^\s]*)$/;
var UA_PATTERN_THUNDERBIRD = /Mozilla.*(Thunderbird|Shredder|Lanikai)\/([^\s*]*).*$/;
/* TODO(jbalogh): save from amo2009. */
function VersionCompare() {
/**
* Mozilla-style version numbers comparison in Javascript
* (JS-translated version of PHP versioncompare component)
* @return -1: a<b, 0: a==b, 1: a>b
*/
this.compareVersions = function(a,b) {
var al = a.split('.');
var bl = b.split('.');
for (var i=0; i<al.length || i<bl.length; i++) {
var ap = (i<al.length ? al[i] : null);
var bp = (i<bl.length ? bl[i] : null);
var r = this.compareVersionParts(ap,bp);
if (r != 0)
return r;
}
return 0;
}
/**
* helper function: compare a single version part
*/
this.compareVersionParts = function(ap,bp) {
var avp = this.parseVersionPart(ap);
var bvp = this.parseVersionPart(bp);
var r = this.cmp(avp['numA'],bvp['numA']);
if (r) return r;
r = this.strcmp(avp['strB'],bvp['strB']);
if (r) return r;
r = this.cmp(avp['numC'],bvp['numC']);
if (r) return r;
return this.strcmp(avp['extraD'],bvp['extraD']);
}
/**
* helper function: parse a version part
*/
this.parseVersionPart = function(p) {
if (p == '*') {
return {
'numA' : Number.MAX_VALUE,
'strB' : '',
'numC' : 0,
'extraD' : ''
};
}
var pattern = /^([-\d]*)([^-\d]*)([-\d]*)(.*)$/;
var m = pattern.exec(p);
var r = {
'numA' : parseInt(m[1]),
'strB' : m[2],
'numC' : parseInt(m[3]),
'extraD' : m[4]
};
if (r['strB'] == '+') {
r['numA']++;
r['strB'] = 'pre';
}
return r;
}
/**
* helper function: compare numeric version parts
*/
this.cmp = function(an,bn) {
if (isNaN(an)) an = 0;
if (isNaN(bn)) bn = 0;
if (an < bn)
return -1;
if (an > bn)
return 1;
return 0;
}
/**
* helper function: compare string version parts
*/
this.strcmp = function(as,bs) {
if (as == bs)
return 0;
// any string comes *before* the empty string
if (as == '')
return 1;
if (bs == '')
return -1;
// normal string comparison for non-empty strings (like strcmp)
if (as < bs)
return -1;
else if(as > bs)
return 1;
else
return 0;
}
}
/* TODO(jbalogh): save from amo2009. */
/**

Просмотреть файл

@ -51,7 +51,7 @@ $(document).ready(function() {
/* No restart required box. (Only shown in Fx4+). */
var no_restart = $('#addon-summary #no-restart');
if (no_restart.length && z.browser.firefox
&& (new VersionCompare()).compareVersions(z.browserVersion, '4.0a1') > 0) {
&& VersionCompare.compareVersions(z.browserVersion, '4.0a1') > 0) {
no_restart.show();
}
});

155
media/js/zamboni/browser.js Normal file
Просмотреть файл

@ -0,0 +1,155 @@
/* Browser Utilities
* Based on amo2009/addons.js
**/
var escape_ = function(s){
return s.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;')
.replace("'", '&#39;').replace('"', '&#34;');
};
function BrowserUtils() {
"use strict";
var exports = {},
userAgentStrings = {
'firefox' : /Mozilla.*(Firefox|Minefield|Namoroka|Shiretoko|GranParadiso|BonEcho|Iceweasel|Fennec|MozillaDeveloperPreview)\/([^\s]*).*$/,
'seamonkey': /Mozilla.*(SeaMonkey|Iceape)\/([^\s]*).*$/,
'mobile': /Mozilla.*(Fennec)\/([^\s]*)$/,
'thunderbird': /Mozilla.*(Thunderbird|Shredder|Lanikai)\/([^\s*]*).*$/
},
osStrings = {
'windows': 'Win32',
'mac': 'Mac',
'linux': 'Linux'
};
// browser detection
var browser = exports.browser = {},
browserVersion = 0,
pattern, match, i;
for (i in userAgentStrings) {
if (userAgentStrings.hasOwnProperty(i)) {
pattern = userAgentStrings[i];
match = pattern.exec(navigator.userAgent);
browser[i] = !!(match && match.length === 3);
if (browser[i]) {
browserVersion = escape_(match[2]);
}
}
}
if (browser.mobile) browser.firefox = false;
exports.browserVersion = browserVersion;
var os = exports.os = {},
platform = "";
for (i in osStrings) {
if (osStrings.hasOwnProperty(i)) {
pattern = osStrings[i];
if (navigator.platform.indexOf(pattern) != -1) {
$(document.body).addClass(os);
os[i] = true;
platform = i;
}
}
}
os['other'] = !platform;
exports.platform = platform;
return exports;
}
var VersionCompare = {
/**
* Mozilla-style version numbers comparison in Javascript
* (JS-translated version of PHP versioncompare component)
* @return -1: a<b, 0: a==b, 1: a>b
*/
compareVersions: function(a,b) {
var al = a.split('.'),
bl = b.split('.'),
ap, bp, r, i;
for (var i=0; i<al.length || i<bl.length; i++) {
ap = (i<al.length ? al[i] : null);
bp = (i<bl.length ? bl[i] : null);
r = this.compareVersionParts(ap,bp);
if (r != 0)
return r;
}
return 0;
},
/**
* helper function: compare a single version part
*/
compareVersionParts: function(ap,bp) {
var avp = this.parseVersionPart(ap),
bvp = this.parseVersionPart(bp),
r = this.cmp(avp['numA'],bvp['numA']);
if (r) return r;
r = this.strcmp(avp['strB'],bvp['strB']);
if (r) return r;
r = this.cmp(avp['numC'],bvp['numC']);
if (r) return r;
return this.strcmp(avp['extraD'],bvp['extraD']);
},
/**
* helper function: parse a version part
*/
parseVersionPart: function(p) {
if (p == '*') {
return {
'numA' : Number.MAX_VALUE,
'strB' : '',
'numC' : 0,
'extraD' : ''
};
}
var pattern = /^([-\d]*)([^-\d]*)([-\d]*)(.*)$/,
m = pattern.exec(p),
r = {
'numA' : parseInt(m[1]),
'strB' : m[2],
'numC' : parseInt(m[3]),
'extraD' : m[4]
};
if (r['strB'] == '+') {
r['numA']++;
r['strB'] = 'pre';
}
return r;
},
/**
* helper function: compare numeric version parts
*/
cmp: function(an,bn) {
if (isNaN(an)) an = 0;
if (isNaN(bn)) bn = 0;
if (an < bn)
return -1;
if (an > bn)
return 1;
return 0;
},
/**
* helper function: compare string version parts
*/
strcmp: function(as,bs) {
if (as == bs)
return 0;
// any string comes *before* the empty string
if (as == '')
return 1;
if (bs == '')
return -1;
// normal string comparison for non-empty strings (like strcmp)
if (as < bs)
return -1;
else if(as > bs)
return 1;
else
return 0;
}
};

Просмотреть файл

@ -11,8 +11,7 @@ z.button.after = {'contrib': function(xpi_url, status) {
}
}};
var vc = new VersionCompare(),
notavail = '<div class="extra"><span class="notavail">{0}</span></div>',
var notavail = '<div class="extra"><span class="notavail">{0}</span></div>',
download_re = new RegExp('(/downloads/(?:latest|file)/\\d+)');
/* Called by the jQuery plugin to set up a single button. */
@ -67,8 +66,8 @@ var installButton = function() {
// min and max only exist if the add-on is compatible with request[APP].
if (appSupported) {
// The user *has* an older/newer browser.
olderBrowser = vc.compareVersions(z.browserVersion, min) < 0;
newerBrowser = vc.compareVersions(z.browserVersion, max) > 0;
olderBrowser = VersionCompare.compareVersions(z.browserVersion, min) < 0;
newerBrowser = VersionCompare.compareVersions(z.browserVersion, max) > 0;
}
// Helper for dealing with lazy-loaded z.button.messages.

Просмотреть файл

@ -98,41 +98,7 @@ _.haskey = function(obj, key) {
/* Detect browser, version, and OS. */
z.browser = {firefox: false, seamonkey: false, mobile: false,
thunderbird: false};
z.browserVersion = 0;
z.os = {windows: false, mac: false, linux: false, other: false};
(function(){
// Globals are coming from amo2009/addons.js.
var ua = function(browser, pattern) {
match = pattern.exec(navigator.userAgent);
if (match && match.length == 3) {
z.browser[browser] = true;
z.browserVersion = escape_(match[2]);
}
}
// Mobile comes after Firefox to overwrite the browser version.
ua('firefox', UA_PATTERN_FIREFOX);
ua('mobile', UA_PATTERN_MOBILE);
ua('seamonkey', UA_PATTERN_SEAMONKEY);
ua('thunderbird', UA_PATTERN_THUNDERBIRD);
var platform = function(os, needle) {
if (navigator.platform.indexOf(needle) != -1) {
$(document.body).addClass(os);
z.os[os] = true;
z.platform = os;
}
}
platform('windows', 'Win32');
platform('mac', 'Mac');
platform('linux', 'Linux');
if (!_.any(_.values(z.os))) {
platform('other', '');
}
})();
$.extend(z, BrowserUtils());
/* Details for the current application. */
z.app = document.body.getAttribute('data-app');
@ -146,9 +112,8 @@ z.media_url = document.body.getAttribute('data-media-url');
z.readonly = JSON.parse(document.body.getAttribute('data-readonly'));
if (z.browser.firefox) {
var vc = new VersionCompare(),
betaVer = document.body.getAttribute('data-min-beta-version');
z.fxBeta = vc.compareVersions(z.browserVersion, betaVer);
var betaVer = document.body.getAttribute('data-min-beta-version');
z.fxBeta = VersionCompare.compareVersions(z.browserVersion, betaVer);
if (z.fxBeta) {
$(document.body).addClass('fxbeta');
}

Просмотреть файл

@ -81,8 +81,7 @@ $.hasPersonas = function() {
if (!jQuery.browser.mozilla) return false;
// Fx 3.6 has lightweight themes (aka personas)
var versionCompare = new VersionCompare();
if (versionCompare.compareVersions(
if (VersionCompare.compareVersions(
$.browser.version, '1.9.2') > -1) {
return true;
}

Просмотреть файл

@ -395,6 +395,7 @@ MINIFY_BUNDLES = {
'js/zamboni/jquery-1.4.2.min.js',
'js/zamboni/jquery-ui/custom-1.8.5.min.js',
'js/zamboni/underscore-min.js',
'js/zamboni/browser.js',
'js/amo2009/addons.js',
'js/zamboni/init.js',
'js/zamboni/format.js',