diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d0de88e60..153e4e21af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [`jsx-handler-names`]: false positive when handler name begins with number ([#1689][] @jsphstls) * [`prop-types`]: Detect JSX returned by sequential expression ([#2801][] @mikol) * [`jsx-props-no-multi-spaces`]: "Expected no line gap between" false positive ([#2792][] @karolina-benitez) +* [`no-unknown-property`]: check attributes with any input case ([#2790][] @julienw) ### Changed * [Tests] [`jsx-one-expression-per-line`]: add passing tests ([#2799][] @TaLeaMonet) @@ -30,6 +31,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel [#2796]: https://github.com/yannickcr/eslint-plugin-react/pull/2796 [#2792]: https://github.com/yannickcr/eslint-plugin-react/pull/2792 [#2791]: https://github.com/yannickcr/eslint-plugin-react/pull/2791 +[#2790]: https://github.com/yannickcr/eslint-plugin-react/pull/2790 [#2789]: https://github.com/yannickcr/eslint-plugin-react/pull/2789 [#2782]: https://github.com/yannickcr/eslint-plugin-react/pull/2782 [#2780]: https://github.com/yannickcr/eslint-plugin-react/pull/2780 diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js index 18634951c3..352c8e24e1 100644 --- a/lib/rules/no-unknown-property.js +++ b/lib/rules/no-unknown-property.js @@ -147,7 +147,8 @@ function getDOMPropertyNames(context) { // ------------------------------------------------------------------------------ /** - * Checks if a node matches the JSX tag convention. + * Checks if a node matches the JSX tag convention. This also checks if a node + * is extended as a webcomponent using the attribute "is". * @param {Object} node - JSX element being tested. * @returns {boolean} Whether or not the node name match the JSX tag convention. */ @@ -194,7 +195,7 @@ function tagNameHasDot(node) { * Get the standard name of the attribute. * @param {String} name - Name of the attribute. * @param {String} context - eslint context - * @returns {String} The standard name of the attribute. + * @returns {String | undefined} The standard name of the attribute, or undefined if no standard name was found. */ function getStandardName(name, context) { if (DOM_ATTRIBUTE_NAMES[name]) { @@ -203,13 +204,9 @@ function getStandardName(name, context) { if (SVGDOM_ATTRIBUTE_NAMES[name]) { return SVGDOM_ATTRIBUTE_NAMES[name]; } - let i = -1; const names = getDOMPropertyNames(context); - const found = names.some((element, index) => { - i = index; - return element.toLowerCase() === name; - }); - return found ? names[i] : null; + // Let's find a possible attribute match with a case-insensitive search. + return names.find((element) => element.toLowerCase() === name.toLowerCase()); } // ------------------------------------------------------------------------------ @@ -259,6 +256,8 @@ module.exports = { } const tagName = getTagName(node); + + // 1. Some attributes are allowed on some tags only. const allowedTags = ATTRIBUTE_TAGS_MAP[name]; if (tagName && allowedTags && /[^A-Z]/.test(tagName.charAt(0)) && allowedTags.indexOf(tagName) === -1) { context.report({ @@ -272,8 +271,12 @@ module.exports = { }); } + // 2. Otherwise, we'll try to find if the attribute is a close version + // of what we should normally have with React. If yes, we'll report an + // error. We don't want to report if the input attribute name is the + // standard name though! const standardName = getStandardName(name, context); - if (!isTagName(node) || !standardName) { + if (!isTagName(node) || !standardName || standardName === name) { return; } context.report({ diff --git a/tests/lib/rules/no-unknown-property.js b/tests/lib/rules/no-unknown-property.js index 21197a4e06..5d9effecfa 100644 --- a/tests/lib/rules/no-unknown-property.js +++ b/tests/lib/rules/no-unknown-property.js @@ -37,6 +37,7 @@ ruleTester.run('no-unknown-property', rule, { {code: ';'}, {code: ';'}, {code: '
;'}, + {code: '
;'}, {code: '
;'}, {code: '
;'}, {code: '
;'}, @@ -75,6 +76,10 @@ ruleTester.run('no-unknown-property', rule, { code: '
;', output: '
;', errors: [{message: 'Unknown property \'onmousedown\' found, use \'onMouseDown\' instead'}] + }, { + code: '
;', + output: '
;', + errors: [{message: 'Unknown property \'onMousedown\' found, use \'onMouseDown\' instead'}] }, { code: ';', output: ';',