Skip to content
This repository has been archived by the owner on Feb 1, 2022. It is now read-only.

Commit

Permalink
warn about outdated versions of Bootstrap; fixes #163
Browse files Browse the repository at this point in the history
  • Loading branch information
cvrebert committed Nov 23, 2014
1 parent ecfb75c commit 30436d4
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/bootlint.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var LocationIndex = _location.LocationIndex;
var NUM2SCREEN = ['xs', 'sm', 'md', 'lg'];
var IN_NODE_JS = !!(cheerio.load);
var MIN_JQUERY_VERSION = '1.9.1';// as of Bootstrap v3.3.0
var CURRENT_BOOTSTRAP_VERSION = '3.3.1';

function compareNums(a, b) {
return a - b;
Expand All @@ -43,6 +44,13 @@ var LocationIndex = _location.LocationIndex;
return node.type === 'directive' && node.name === '!doctype';
}

var tagNameOf = IN_NODE_JS ? function (element) {
return element.name.toUpperCase();
} : function (element) {
/* @covignore */
return element.tagName.toUpperCase();
};

function filenameFromUrl(url) {
var filename = url.replace(/[#?].*$/, ''); // strip querystring & fragment ID
var lastSlash = filename.lastIndexOf('/');
Expand Down Expand Up @@ -780,6 +788,78 @@ var LocationIndex = _location.LocationIndex;
reporter('Using `.pull-left` or `.pull-right` as part of the media object component is deprecated as of Bootstrap v3.3.0. Use `.media-left` or `.media-right` instead.', mediaPulls);
}
});
addLinter("W011", function lintOutdatedBootstrap($, reporter) {
var OUTDATED_BOOTSTRAP = "Bootstrap version might be outdated. Latest version is at least " + CURRENT_BOOTSTRAP_VERSION + " ; saw what appears to be usage of Bootstrap ";
var PLUGINS = [
'affix',
'alert',
'button',
'carousel',
'collapse',
'dropdown',
'modal',
'popover',
'scrollspy',
'tab',
'tooltip'
];
var theWindow = null;
try {
/*eslint-disable no-undef, block-scoped-var */
theWindow = window;// jshint ignore:line
/*eslint-enable no-undef, block-scoped-var */
}
catch (e) {
// deliberately do nothing
}
var globaljQuery = theWindow && (theWindow.$ || theWindow.jQuery);
/* @covignore */
if (globaljQuery) {
var versions = PLUGINS.map(function (pluginName) {
var plugin = globaljQuery.fn[pluginName];
if (!plugin) {
return undefined;
}
var constructor = plugin.Constructor;
if (!constructor) {
return undefined;
}
return constructor.VERSION;
}).filter(function (version) {
return version !== undefined;
}).sort(semver.compare);
if (versions.length) {
var minVersion = versions[0];
reporter(OUTDATED_BOOTSTRAP + minVersion);
return;
}
}
// check for Bootstrap <link>s and <script>s
var bootstraps = $([
'link[rel="stylesheet"][href$="bootstrap.css"]',
'link[rel="stylesheet"][href$="bootstrap.min.css"]',
'script[src$="bootstrap.js"]',
'script[src$="bootstrap.min.js"]'
].join(','));
bootstraps.each(function () {
var elem = $(this);
var urlAttr = (tagNameOf(this) === 'LINK') ? 'href' : 'src';
var pathSegments = parseUrl(elem.attr(urlAttr)).pathname.split('/');
var matches = pathSegments.map(function (segment) {
var match = segment.match(/^\d+\.\d+\.\d+$/);
return match ? match[0] : null;
}).filter(function (match) {
return match !== null;
});
if (!matches.length) {
return;
}
var version = matches[matches.length - 1];
if (semver.lt(version, CURRENT_BOOTSTRAP_VERSION, true)) {
reporter(OUTDATED_BOOTSTRAP + version, elem);
}
});
});

exports._lint = function ($, reporter, disabledIdList, html) {
var locationIndex = IN_NODE_JS ? new LocationIndex(html) : null;
Expand Down
17 changes: 17 additions & 0 deletions test/bootlint_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -611,5 +611,22 @@ exports.bootlint = {
'should not complain about .media-left or .media-right classes'
);
test.done();
},

'outdated version of Bootstrap': function (test) {
test.expect(4);
test.deepEqual(lintHtml(utf8Fixture('outdated/bootstrap-css.html')),
['Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0'],
'should complain about outdated bootstrap.css.');
test.deepEqual(lintHtml(utf8Fixture('outdated/bootstrap-min-css.html')),
['Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0'],
'should complain about outdated bootstrap.min.css.');
test.deepEqual(lintHtml(utf8Fixture('outdated/bootstrap-js.html')),
['Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0'],
'should complain about outdated bootstrap.js.');
test.deepEqual(lintHtml(utf8Fixture('outdated/bootstrap-min-js.html')),
['Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0'],
'should complain about outdated bootstrap.min.js.');
test.done();
}
};
26 changes: 26 additions & 0 deletions test/fixtures/outdated/bootstrap-css.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!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>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css">
<!--[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="../../lib/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="Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0"></li>
</ol>
</body>
</html>
26 changes: 26 additions & 0 deletions test/fixtures/outdated/bootstrap-js.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!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="../../lib/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.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="Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0"></li>
</ol>
</body>
</html>
26 changes: 26 additions & 0 deletions test/fixtures/outdated/bootstrap-min-css.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!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>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<!--[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="../../lib/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="Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0"></li>
</ol>
</body>
</html>
26 changes: 26 additions & 0 deletions test/fixtures/outdated/bootstrap-min-js.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!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="../../lib/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.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="Bootstrap version might be outdated. Latest version is at least 3.3.1 ; saw what appears to be usage of Bootstrap 3.2.0"></li>
</ol>
</body>
</html>

0 comments on commit 30436d4

Please sign in to comment.