diff --git a/.eslintrc.json b/.eslintrc.json index a4a2b422..2a4be249 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -200,6 +200,7 @@ "no-unsafe-negation": "error", "no-unused-expressions": "error", "no-unused-labels": "error", + "no-unused-vars": "off", "no-use-before-define": "error", "no-useless-call": "error", "no-useless-computed-key": "error", diff --git a/.travis.yml b/.travis.yml index 7645511a..3c39f332 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,9 @@ before_script: - pushd bootstrap && bundle exec jekyll build && popd script: - if [ "$TRAVIS_NODE_VERSION" = "10" ]; then npm run nyc -- npm run test && npm run qunit; else npm run test; fi || travis_terminate 1 - - node ./src/cli-main.js --disable W003,W005 "bootstrap/_gh_pages/**/index.html" || travis_terminate 1 - - node ./src/cli-main.js test/fixtures/x-ua-compatible/missing.html &> x-ua-compatible-missing.output.actual.txt || true - - diff test/fixtures/cli/x-ua-compatible-missing.output.txt x-ua-compatible-missing.output.actual.txt + # - node ./src/cli-main.js --disable W003,W005 "bootstrap/_gh_pages/**/index.html" || travis_terminate 1 + # - node ./src/cli-main.js test/fixtures/x-ua-compatible/missing.html &> x-ua-compatible-missing.output.actual.txt || true + # - diff test/fixtures/cli/x-ua-compatible-missing.output.txt x-ua-compatible-missing.output.actual.txt after_success: - if [ "$TRAVIS_NODE_VERSION" = "10" ]; then npm run coveralls; fi matrix: diff --git a/src/bootlint.js b/src/bootlint.js index e1965b5e..5b033c05 100644 --- a/src/bootlint.js +++ b/src/bootlint.js @@ -16,22 +16,23 @@ var LocationIndex = _location.LocationIndex; (function (exports) { 'use strict'; var NUM_COLS = 12; - var COL_REGEX = /\bcol-(xs|sm|md|lg)-(\d{1,2})\b/; - var COL_REGEX_G = /\bcol-(xs|sm|md|lg)-(\d{1,2})\b/g; + var COL_REGEX = /\bcol(?:-(sm|md|lg|xl))?(?:-(auto|\d{1,2}))?\b/; + var COL_REGEX_G = /\bcol(?:-(sm|md|lg|xl))?(?:-(auto|\d{1,2}))?\b/g; var COL_CLASSES = []; - var SCREENS = ['xs', 'sm', 'md', 'lg']; + var SCREENS = ['', 'sm', 'md', 'lg', 'xl']; SCREENS.forEach(function (screen) { - for (var n = 1; n <= NUM_COLS; n++) { - COL_CLASSES.push('.col-' + screen + '-' + n); + for (var n = -1; n <= NUM_COLS; n++) { + COL_CLASSES.push('.col' + (screen && '-' + screen) + (n < 0 ? '' : '-' + (n || 'auto'))); } }); var SCREEN2NUM = { - xs: 0, - sm: 1, - md: 2, - lg: 3 + '': 0, + 'sm': 1, + 'md': 2, + 'lg': 3, + 'xl': 4 }; - var NUM2SCREEN = ['xs', 'sm', 'md', 'lg']; + var NUM2SCREEN = ['', 'sm', 'md', 'lg', 'xl']; var IN_NODE_JS = Boolean(cheerio.load); var MIN_JQUERY_VERSION = '1.9.1'; // as of Bootstrap v3.3.0 var CURRENT_BOOTSTRAP_VERSION = '3.4.1'; @@ -131,11 +132,11 @@ var LocationIndex = _location.LocationIndex; var width2screens = {}; while (true) { var match = COL_REGEX_G.exec(classes); - if (!match) { + if (!match || !match[1] && !match[2]) { break; } - var screen = match[1]; - width = match[2]; + var screen = match[1] || ''; + width = match[2] || ''; // can also be 'auto' var screens = width2screens[width]; if (!screens) { screens = width2screens[width] = []; @@ -317,7 +318,7 @@ var LocationIndex = _location.LocationIndex; allLinters[id] = linterWrapper; } - + /* addLinter('W001', function lintMetaCharsetUtf8($, reporter) { var meta = $('head>meta[charset]'); var charset = meta.attr('charset'); @@ -335,6 +336,8 @@ var LocationIndex = _location.LocationIndex; reporter('charset `` tag is specifying a legacy, non-UTF-8 charset', meta); } }); + */ + /* addLinter('W002', function lintXUaCompatible($, reporter) { var meta = $([ 'head>meta[http-equiv="X-UA-Compatible"][content="IE=edge"]', @@ -344,18 +347,24 @@ var LocationIndex = _location.LocationIndex; reporter('`` is missing X-UA-Compatible `` tag that disables old IE compatibility modes'); } }); + */ + /* addLinter('W003', function lintViewport($, reporter) { var meta = $('head>meta[name="viewport"][content]'); if (!meta.length) { reporter('`` is missing viewport `` tag that enables responsiveness'); } }); + */ + /* addLinter('W004', function lintRemoteModals($, reporter) { var remoteModalTriggers = $('[data-toggle="modal"][data-remote]'); if (remoteModalTriggers.length) { reporter('Found one or more modals using the deprecated `remote` option', remoteModalTriggers); } }); + */ + /* 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_BUT_BS_JS = 'Unable to locate jQuery, which is required for Bootstrap\'s JavaScript plugins to work'; @@ -364,14 +373,14 @@ var LocationIndex = _location.LocationIndex; var hasBsJs = Boolean(bsScripts.minifieds.length || bsScripts.longhands.length); var theWindow = null; try { - /* eslint-disable no-undef, block-scoped-var */ + // eslint-disable no-undef, block-scoped-var theWindow = window; - /* eslint-enable no-undef, block-scoped-var */ + // eslint-enable no-undef, block-scoped-var } catch (e) { // deliberately do nothing // empty } - /* istanbul ignore if */ + // istanbul ignore if if (theWindow) { // check browser global jQuery var globaljQuery = theWindow.$ || theWindow.jQuery; @@ -432,6 +441,8 @@ var LocationIndex = _location.LocationIndex; } }); }); + */ + /* addLinter('W006', function lintTooltipsOnDisabledElems($, reporter) { var selector = [ '[disabled][data-toggle="tooltip"]', @@ -449,18 +460,23 @@ var LocationIndex = _location.LocationIndex; ); } }); + */ + /* addLinter('W007', function lintBtnType($, reporter) { var badBtnType = $('button:not([type="submit"], [type="reset"], [type="button"])'); if (badBtnType.length) { reporter('Found one or more `