Skip to content

Commit 704f5d9

Browse files
committed
Merge branch 'master' into patch-1
2 parents 71b522a + d225a11 commit 704f5d9

19 files changed

+236
-104
lines changed

docs/rules/jsx-no-bind.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,70 @@ A `bind` call or [arrow function](https://developer.mozilla.org/en-US/docs/Web/J
77
The following patterns are considered warnings:
88

99
```jsx
10-
<div onClick={this._handleClick.bind(this)}></div>
10+
<Foo onClick={this._handleClick.bind(this)}></Foo>
1111
```
1212
```jsx
13-
<div onClick={() => console.log('Hello!')}></div>
13+
<Foo onClick={() => console.log('Hello!')}></Foo>
1414
```
1515

1616
The following patterns are **not** considered warnings:
1717
```jsx
18-
<div onClick={this._handleClick}></div>
18+
<Foo onClick={this._handleClick}></Foo>
1919
```
2020

2121
## Rule Options
2222

2323
```js
2424
"react/jsx-no-bind": [<enabled>, {
25+
"ignoreDOMComponents": <boolean> || false,
2526
"ignoreRefs": <boolean> || false,
2627
"allowArrowFunctions": <boolean> || false,
2728
"allowFunctions": <boolean> || false,
2829
"allowBind": <boolean> || false
2930
}]
3031
```
3132

33+
### `ignoreDOMComponents`
34+
35+
When `true` the following are **not** considered warnings:
36+
37+
```jsx
38+
<div onClick={this._handleClick.bind(this) />
39+
<span onClick={() => console.log("Hello!")} />
40+
<button onClick={function() { alert("1337") }} />
41+
```
42+
3243
### `ignoreRefs`
3344
3445
When `true` the following are **not** considered warnings:
3546
3647
```jsx
37-
<div ref={c => this._div = c} />
38-
<div ref={this._refCallback.bind(this)} />
48+
<Foo ref={c => this._div = c} />
49+
<Foo ref={this._refCallback.bind(this)} />
3950
```
4051
4152
### `allowArrowFunctions`
4253
4354
When `true` the following is **not** considered a warning:
4455
4556
```jsx
46-
<div onClick={() => alert("1337")} />
57+
<Foo onClick={() => alert("1337")} />
4758
```
4859
4960
### `allowFunctions`
5061
5162
When `true` the following is not considered a warning:
5263
5364
```jsx
54-
<div onClick={function () { alert("1337") }} />
65+
<Foo onClick={function () { alert("1337") }} />
5566
```
5667
5768
### `allowBind`
5869
5970
When `true` the following is **not** considered a warning:
6071
6172
```jsx
62-
<div onClick={this._handleClick.bind(this)} />
73+
<Foo onClick={this._handleClick.bind(this)} />
6374
```
6475
6576
## Protips

docs/rules/jsx-one-expression-per-line.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ The following patterns are considered warnings:
2020
</Hello></App>
2121

2222
<App>
23-
</Hello> World
23+
<Hello /> World
2424
</App>
2525

2626
<App>
27-
</Hello> { 'World' }
27+
<Hello /> { 'World' }
2828
</App>
2929

3030
<App>
31-
</Hello> { this.world() }
31+
<Hello /> { this.world() }
3232
</App>
3333

3434
<App>
@@ -64,17 +64,17 @@ The following patterns are **not** warnings:
6464
</App>
6565

6666
<App>
67-
</Hello>
67+
<Hello />
6868
World
6969
</App>
7070

7171
<App>
72-
</Hello>
72+
<Hello />
7373
{ 'World' }
7474
</App>
7575

7676
<App>
77-
</Hello>
77+
<Hello />
7878
{ this.world() }
7979
</App>
8080

lib/rules/button-has-type.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,17 @@ module.exports = {
7171
});
7272
}
7373

74-
function checkValue(node, value) {
74+
function checkValue(node, value, quoteFn) {
75+
const q = quoteFn || (x => `"${x}"`);
7576
if (!(value in configuration)) {
7677
context.report({
7778
node: node,
78-
message: `"${value}" is an invalid value for button type attribute`
79+
message: `${q(value)} is an invalid value for button type attribute`
7980
});
8081
} else if (!configuration[value]) {
8182
context.report({
8283
node: node,
83-
message: `"${value}" is a forbidden value for button type attribute`
84+
message: `${q(value)} is a forbidden value for button type attribute`
8485
});
8586
}
8687
}
@@ -98,7 +99,12 @@ module.exports = {
9899
return;
99100
}
100101

101-
checkValue(node, getLiteralPropValue(typeProp));
102+
const propValue = getLiteralPropValue(typeProp);
103+
if (!propValue && typeProp.value && typeProp.value.expression) {
104+
checkValue(node, typeProp.value.expression.name, x => `\`${x}\``);
105+
} else {
106+
checkValue(node, propValue);
107+
}
102108
},
103109
CallExpression: function(node) {
104110
if (!isCreateElement(node, context)) {

lib/rules/jsx-no-bind.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
const propName = require('jsx-ast-utils/propName');
1010
const Components = require('../util/Components');
1111
const docsUrl = require('../util/docsUrl');
12+
const jsxUtil = require('../util/jsx');
1213

1314
// -----------------------------------------------------------------------------
1415
// Rule Definition
@@ -48,6 +49,10 @@ module.exports = {
4849
ignoreRefs: {
4950
default: false,
5051
type: 'boolean'
52+
},
53+
ignoreDOMComponents: {
54+
default: false,
55+
type: 'boolean'
5156
}
5257
},
5358
additionalProperties: false
@@ -165,6 +170,10 @@ module.exports = {
165170
if (isRef || !node.value || !node.value.expression) {
166171
return;
167172
}
173+
const isDOMComponent = jsxUtil.isDOMComponent(node.parent);
174+
if (configuration.ignoreDOMComponents && isDOMComponent) {
175+
return;
176+
}
168177
const valueNode = node.value.expression;
169178
const valueNodeType = valueNode.type;
170179
const nodeViolationType = getNodeViolationType(valueNode);

lib/rules/jsx-no-undef.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,7 @@
66
'use strict';
77

88
const docsUrl = require('../util/docsUrl');
9-
10-
/**
11-
* Checks if a node name match the JSX tag convention.
12-
* @param {String} name - Name of the node to check.
13-
* @returns {boolean} Whether or not the node name match the JSX tag convention.
14-
*/
15-
const tagConvention = /^[a-z]|\-/;
16-
function isTagName(name) {
17-
return tagConvention.test(name);
18-
}
9+
const jsxUtil = require('../util/jsx');
1910

2011
// ------------------------------------------------------------------------------
2112
// Rule Definition
@@ -95,10 +86,10 @@ module.exports = {
9586
JSXOpeningElement: function(node) {
9687
switch (node.name.type) {
9788
case 'JSXIdentifier':
98-
node = node.name;
99-
if (isTagName(node.name)) {
89+
if (jsxUtil.isDOMComponent(node)) {
10090
return;
10191
}
92+
node = node.name;
10293
break;
10394
case 'JSXMemberExpression':
10495
node = node.name;

lib/rules/jsx-pascal-case.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77

88
const elementType = require('jsx-ast-utils/elementType');
99
const docsUrl = require('../util/docsUrl');
10+
const jsxUtil = require('../util/jsx');
1011

1112
// ------------------------------------------------------------------------------
1213
// Constants
1314
// ------------------------------------------------------------------------------
1415

1516
const PASCAL_CASE_REGEX = /^([A-Z0-9]|[A-Z0-9]+[a-z0-9]+(?:[A-Z0-9]+[a-z0-9]*)*)$/;
16-
const COMPAT_TAG_REGEX = /^[a-z]|\-/;
1717
const ALL_CAPS_TAG_REGEX = /^[A-Z0-9]+$/;
1818

1919
// ------------------------------------------------------------------------------
@@ -60,7 +60,7 @@ module.exports = {
6060
}
6161

6262
const isPascalCase = PASCAL_CASE_REGEX.test(name);
63-
const isCompatTag = COMPAT_TAG_REGEX.test(name);
63+
const isCompatTag = jsxUtil.isDOMComponent(node);
6464
const isAllowedAllCaps = allowAllCaps && ALL_CAPS_TAG_REGEX.test(name);
6565
const isIgnored = ignore.indexOf(name) !== -1;
6666

lib/rules/jsx-sort-props.js

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
*/
55
'use strict';
66

7-
const elementType = require('jsx-ast-utils/elementType');
87
const propName = require('jsx-ast-utils/propName');
98
const docsUrl = require('../util/docsUrl');
9+
const jsxUtil = require('../util/jsx');
1010

1111
// ------------------------------------------------------------------------------
1212
// Rule Definition
@@ -16,20 +16,6 @@ function isCallbackPropName(name) {
1616
return /^on[A-Z]/.test(name);
1717
}
1818

19-
const COMPAT_TAG_REGEX = /^[a-z]|\-/;
20-
function isDOMComponent(node) {
21-
let name = elementType(node);
22-
23-
// Get namespace if the type is JSXNamespacedName or JSXMemberExpression
24-
if (name.indexOf(':') > -1) {
25-
name = name.substring(0, name.indexOf(':'));
26-
} else if (name.indexOf('.') > -1) {
27-
name = name.substring(0, name.indexOf('.'));
28-
}
29-
30-
return COMPAT_TAG_REGEX.test(name);
31-
}
32-
3319
const RESERVED_PROPS_LIST = [
3420
'children',
3521
'dangerouslySetInnerHTML',
@@ -229,7 +215,7 @@ module.exports = {
229215
return {
230216
JSXOpeningElement: function(node) {
231217
// `dangerouslySetInnerHTML` is only "reserved" on DOM components
232-
if (reservedFirst && !isDOMComponent(node)) {
218+
if (reservedFirst && !jsxUtil.isDOMComponent(node)) {
233219
reservedList = reservedList.filter(prop => prop !== 'dangerouslySetInnerHTML');
234220
}
235221

lib/rules/no-danger.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
'use strict';
66

77
const docsUrl = require('../util/docsUrl');
8+
const jsxUtil = require('../util/jsx');
89

910
// ------------------------------------------------------------------------------
1011
// Constants
@@ -25,16 +26,6 @@ const DANGEROUS_PROPERTIES = DANGEROUS_PROPERTY_NAMES.reduce((props, prop) => {
2526
// Helpers
2627
// ------------------------------------------------------------------------------
2728

28-
/**
29-
* Checks if a node name match the JSX tag convention.
30-
* @param {String} name - Name of the node to check.
31-
* @returns {boolean} Whether or not the node name match the JSX tag convention.
32-
*/
33-
const tagConvention = /^[a-z]|\-/;
34-
function isTagName(name) {
35-
return tagConvention.test(name);
36-
}
37-
3829
/**
3930
* Checks if a JSX attribute is dangerous.
4031
* @param {String} name - Name of the attribute to check.
@@ -63,7 +54,7 @@ module.exports = {
6354
return {
6455

6556
JSXAttribute: function(node) {
66-
if (isTagName(node.parent.name.name) && isDangerous(node.name.name)) {
57+
if (jsxUtil.isDOMComponent(node.parent) && isDangerous(node.name.name)) {
6758
context.report({
6859
node: node,
6960
message: DANGEROUS_MESSAGE,

lib/rules/no-deprecated.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,19 @@ module.exports = {
106106
);
107107
}
108108

109-
function checkDeprecation(node, method) {
110-
if (!isDeprecated(method)) {
109+
function checkDeprecation(node, methodName, methodNode) {
110+
if (!isDeprecated(methodName)) {
111111
return;
112112
}
113113
const deprecated = getDeprecated();
114-
const version = deprecated[method][0];
115-
const newMethod = deprecated[method][1];
116-
const refs = deprecated[method][2];
114+
const version = deprecated[methodName][0];
115+
const newMethod = deprecated[methodName][1];
116+
const refs = deprecated[methodName][2];
117117
context.report({
118-
node: node,
118+
node: methodNode || node,
119119
message: DEPRECATED_MESSAGE,
120120
data: {
121-
oldMethod: method,
121+
oldMethod: methodName,
122122
version,
123123
newMethod: newMethod ? `, use ${newMethod} instead` : '',
124124
refs: refs ? `, see ${refs}` : ''
@@ -150,7 +150,10 @@ module.exports = {
150150
*/
151151
function getLifeCycleMethods(node) {
152152
const properties = astUtil.getComponentProperties(node);
153-
return properties.map(property => astUtil.getPropertyName(property));
153+
return properties.map(property => ({
154+
name: astUtil.getPropertyName(property),
155+
node: astUtil.getPropertyNameNode(property)
156+
}));
154157
}
155158

156159
/**
@@ -160,7 +163,7 @@ module.exports = {
160163
function checkLifeCycleMethods(node) {
161164
if (utils.isES5Component(node) || utils.isES6Component(node)) {
162165
const methods = getLifeCycleMethods(node);
163-
methods.forEach(method => checkDeprecation(node, method));
166+
methods.forEach(method => checkDeprecation(node, method.name, method.node));
164167
}
165168
}
166169

lib/rules/no-unknown-property.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ const SVGDOM_ATTRIBUTE_NAMES = {
117117
const DOM_PROPERTY_NAMES = [
118118
// Standard
119119
'acceptCharset', 'accessKey', 'allowFullScreen', 'allowTransparency', 'autoComplete', 'autoFocus', 'autoPlay',
120-
'cellPadding', 'cellSpacing', 'charSet', 'classID', 'className', 'colSpan', 'contentEditable', 'contextMenu',
120+
'cellPadding', 'cellSpacing', 'classID', 'className', 'colSpan', 'contentEditable', 'contextMenu',
121121
'dateTime', 'encType', 'formAction', 'formEncType', 'formMethod', 'formNoValidate', 'formTarget',
122122
'frameBorder', 'hrefLang', 'htmlFor', 'httpEquiv', 'inputMode', 'keyParams', 'keyType', 'marginHeight', 'marginWidth',
123123
'maxLength', 'mediaGroup', 'minLength', 'noValidate', 'onAnimationEnd', 'onAnimationIteration', 'onAnimationStart',

0 commit comments

Comments
 (0)