Add check for minimum jQuery version

Fixes #121
Closes #129
This commit is contained in:
Phil Hughes 2014-10-13 16:45:49 +01:00 коммит произвёл Chris Rebert
Родитель 1da2844abc
Коммит 0b53946a41
6 изменённых файлов: 138 добавлений и 89 удалений

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

@ -46,7 +46,8 @@
"chalk": "^0.5.1",
"cheerio": "^0.17.0",
"commander": "^2.3.0",
"glob": "^4.0.6"
"glob": "^4.0.6",
"semver": "^4.0.3"
},
"main": "./src/bootlint.js",
"bin": {

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

@ -8,6 +8,7 @@
/*eslint-env node */
var cheerio = require('cheerio');
var semver = require('semver');
(function (exports) {
'use strict';
@ -29,6 +30,7 @@ var cheerio = require('cheerio');
};
var NUM2SCREEN = ['xs', 'sm', 'md', 'lg'];
var IN_NODE_JS = !!(cheerio.load);
var MIN_JQUERY_VERSION = '1.9.0';// as of Bootstrap v3.2.0
function compareNums(a, b) {
return a - b;
@ -302,6 +304,8 @@ var cheerio = require('cheerio');
}
});
addLinter("W005", function lintJquery($, reporter) {
var OLD_JQUERY = "Found what might be an outdated version of jQuery; Bootstrap requires jQuery v" + MIN_JQUERY_VERSION + " or higher";
var NO_JQUERY = "Unable to locate jQuery, which is required for Bootstrap's JavaScript plugins to work";
var theWindow = null;
try {
/*eslint-disable no-undef, block-scoped-var */
@ -311,13 +315,56 @@ var cheerio = require('cheerio');
catch (e) {
// deliberately do nothing
}
if (theWindow && (theWindow.$ || theWindow.jQuery)) {
return;
if (theWindow) {
// check browser global jQuery
var globaljQuery = theWindow.$ || theWindow.jQuery;
if (globaljQuery) {
var globalVersion = null;
try {
globalVersion = globaljQuery.fn.jquery;
}
catch (e) {
// skip; not actually jQuery?
}
if (globalVersion) {
// pad out short version numbers (e.g. '1.7')
while (globalVersion.match(/\./g).length < 2) {
globalVersion += ".0";
}
var upToDate = null;
try {
upToDate = semver.gte(globalVersion, MIN_JQUERY_VERSION, true);
}
catch (e) {
// invalid version number
}
if (upToDate === false) {
reporter(OLD_JQUERY);
}
if (upToDate !== null) {
return;
}
}
}
}
// check for jQuery <script>s
var jqueries = $('script[src*="jquery"],script[src*="jQuery"]');
if (!jqueries.length) {
reporter("Unable to locate jQuery, which is required for Bootstrap's JavaScript plugins to work");
reporter(NO_JQUERY);
return;
}
jqueries.each(function () {
var matches = $(this).attr('src').match(/\d+\.\d+\.\d+/g);
if (!matches) {
return;
}
var version = matches[matches.length - 1];
if (!semver.gte(version, MIN_JQUERY_VERSION, true)) {
reporter(OLD_JQUERY);
}
});
});
addLinter("E006", function lintInputGroupFormControlTypes($, reporter) {
var selectInputGroups = $('.input-group select');

116
test-infra/npm-shrinkwrap.json сгенерированный
Просмотреть файл

@ -138,8 +138,8 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-4.0.6.tgz",
"dependencies": {
"graceful-fs": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.3.tgz"
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.4.tgz"
},
"inherits": {
"version": "2.0.1",
@ -1073,8 +1073,8 @@
"dependencies": {
"fsevents": {
"version": "0.2.1",
"from": "fsevents@git://github.com/pipobscure/fsevents#7dcdf9fa3f8956610fd6f69f72c67bace2de7138",
"resolved": "git://github.com/pipobscure/fsevents#7dcdf9fa3f8956610fd6f69f72c67bace2de7138",
"from": "fsevents@git+https://github.com/pipobscure/fsevents#7dcdf9fa3f8956610fd6f69f72c67bace2de7138",
"resolved": "git+https://github.com/pipobscure/fsevents#7dcdf9fa3f8956610fd6f69f72c67bace2de7138",
"dependencies": {
"nan": {
"version": "0.8.0",
@ -1770,44 +1770,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-1.1.0.tgz",
"dependencies": {
"chalk": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
"dependencies": {
"ansi-styles": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz"
},
"escape-string-regexp": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz"
},
"has-ansi": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
}
}
},
"strip-ansi": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
}
}
},
"supports-color": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
}
}
},
"eslint": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-0.8.2.tgz",
@ -1972,6 +1934,30 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
},
"glob": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-4.0.6.tgz",
"dependencies": {
"graceful-fs": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.4.tgz"
},
"inherits": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
},
"once": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/once/-/once-1.3.1.tgz",
"dependencies": {
"wrappy": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
}
}
}
}
},
"minimatch": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz",
@ -2782,10 +2768,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-2.0.0.tgz"
},
"semver": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-4.0.3.tgz"
},
"sorted-object": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/sorted-object/-/sorted-object-1.0.0.tgz"
@ -2802,48 +2784,14 @@
}
}
},
"semver": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-4.0.3.tgz"
},
"time-grunt": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-1.0.0.tgz",
"dependencies": {
"chalk": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
"dependencies": {
"ansi-styles": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz"
},
"escape-string-regexp": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz"
},
"has-ansi": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
}
}
},
"strip-ansi": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
}
}
},
"supports-color": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
}
}
},
"date-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/date-time/-/date-time-1.0.0.tgz"

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

@ -175,10 +175,13 @@ exports.bootlint = {
test.done();
},
'jQuery': function (test) {
test.expect(2);
test.expect(3);
test.deepEqual(lintHtml(utf8Fixture('jquery/present.html')),
[],
'should not complain when jQuery is present.');
test.deepEqual(lintHtml(utf8Fixture('jquery/old-url.html')),
["Found what might be an outdated version of jQuery; Bootstrap requires jQuery v1.9.0 or higher"],
'should complain about old version of jQuery based on URL');
test.deepEqual(lintHtml(utf8Fixture('jquery/missing.html')),
["Unable to locate jQuery, which is required for Bootstrap's JavaScript plugins to work"],
'should complain when jQuery appears to be missing.');

25
test/fixtures/jquery/old-attr.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Test</title>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="http://cdn.jsdelivr.net/jquery/1.7/jquery.min.js"></script>
<link rel="stylesheet" href="../../lib/qunit.css">
<script src="../../lib/qunit.js"></script>
<script src="../../../dist/browser/bootlint.js"></script>
<script src="../generic-qunit.js"></script>
</head>
<body>
<div id="qunit"></div>
<ol id="bootlint">
<li data-lint="Found what might be an outdated version of jQuery; Bootstrap requires jQuery v1.9.0 or higher"></li>
</ol>
</body>
</html>

25
test/fixtures/jquery/old-url.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Test</title>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<link rel="stylesheet" href="../../lib/qunit.css">
<script src="../../lib/qunit.js"></script>
<script src="../../../dist/browser/bootlint.js"></script>
<script src="../generic-qunit.js"></script>
</head>
<body>
<div id="qunit"></div>
<ol id="bootlint">
<li data-lint="Found what might be an outdated version of jQuery; Bootstrap requires jQuery v1.9.0 or higher"></li>
</ol>
</body>
</html>