Skip to content

Commit 15c3f18

Browse files
burtekljharb
authored andcommitted
[New] jsx-no-script-url: support linkAttributes setting
1 parent b2e744d commit 15c3f18

File tree

3 files changed

+61
-17
lines changed

3 files changed

+61
-17
lines changed

docs/rules/jsx-no-script-url.md

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Examples of **correct** code for this rule:
2323
<a href={"javascript:"}></a>
2424
```
2525

26+
This rule takes the `linkComponents` setting into account.
27+
2628
## Rule Options
2729

2830
```json
@@ -45,6 +47,9 @@ Examples of **correct** code for this rule:
4547

4648
Allows you to indicate a specific list of properties used by a custom component to be checked.
4749

50+
NOTE: This rule now takes into account the `linkComponents` config in [global shared settings](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/README.md#configuration), which should be used as the sole source of truth for link components.
51+
The rule still allows passing link components as rule option for backwards compatibility, but this option is deprecated. If specified, this option will be used together with global `linkComponents` config.
52+
4853
### name
4954

5055
Component name.

lib/rules/jsx-no-script-url.js

+16-17
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
'use strict';
77

8+
const includes = require('array-includes');
89
const docsUrl = require('../util/docsUrl');
10+
const linkComponentsUtil = require('../util/linkComponents');
911
const report = require('../util/report');
1012

1113
// ------------------------------------------------------------------------------
@@ -21,26 +23,20 @@ function hasJavaScriptProtocol(attr) {
2123
&& isJavaScriptProtocol.test(attr.value.value);
2224
}
2325

24-
function shouldVerifyElement(node, config) {
25-
const name = node.name && node.name.name;
26-
return name === 'a' || config.find((i) => i.name === name);
27-
}
28-
2926
function shouldVerifyProp(node, config) {
3027
const name = node.name && node.name.name;
3128
const parentName = node.parent.name && node.parent.name.name;
3229

33-
if (parentName === 'a' && name === 'href') {
34-
return true;
35-
}
30+
if (!name || !parentName || !config.has(parentName)) return false;
3631

37-
const el = config.find((i) => i.name === parentName);
38-
if (!el) {
39-
return false;
40-
}
32+
const attributes = config.get(parentName);
33+
return includes(attributes, name);
34+
}
4135

42-
const props = el.props || [];
43-
return node.name && props.indexOf(name) !== -1;
36+
function parseLegacyOption(config, option) {
37+
option.forEach((opt) => {
38+
config.set(opt.name, opt.props);
39+
});
4440
}
4541

4642
const messages = {
@@ -82,11 +78,14 @@ module.exports = {
8278
},
8379

8480
create(context) {
85-
const config = context.options[0] || [];
81+
const linkComponents = linkComponentsUtil.getLinkComponents(context);
82+
if (context.options[0]) {
83+
parseLegacyOption(linkComponents, context.options[0]);
84+
}
85+
8686
return {
8787
JSXAttribute(node) {
88-
const parent = node.parent;
89-
if (shouldVerifyElement(parent, config) && shouldVerifyProp(node, config) && hasJavaScriptProtocol(node)) {
88+
if (shouldVerifyProp(node, linkComponents) && hasJavaScriptProtocol(node)) {
9089
report(context, messages.noScriptURL, 'noScriptURL', {
9190
node,
9291
});

tests/lib/rules/jsx-no-script-url.js

+40
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ ruleTester.run('jsx-no-script-url', rule, {
6666
[{ name: 'Foo', props: ['to', 'href'] }],
6767
],
6868
},
69+
{
70+
code: '<Foo to="javascript:"></Foo>',
71+
errors: [{ messageId: 'noScriptURL' }],
72+
settings: {
73+
linkComponents: [
74+
{ name: 'Foo', linkAttribute: 'to' },
75+
],
76+
},
77+
},
78+
{
79+
code: '<Foo href="javascript:"></Foo>',
80+
errors: [{ messageId: 'noScriptURL' }],
81+
settings: {
82+
linkComponents: [
83+
{ name: 'Foo', linkAttribute: ['to', 'href'] },
84+
],
85+
},
86+
},
6987
{
7088
code: `
7189
<div>
@@ -84,5 +102,27 @@ ruleTester.run('jsx-no-script-url', rule, {
84102
],
85103
],
86104
},
105+
{
106+
code: `
107+
<div>
108+
<Foo href="javascript:"></Foo>
109+
<Bar link="javascript:"></Bar>
110+
</div>
111+
`,
112+
errors: [
113+
{ messageId: 'noScriptURL' },
114+
{ messageId: 'noScriptURL' },
115+
],
116+
options: [
117+
[
118+
{ name: 'Bar', props: ['link'] },
119+
],
120+
],
121+
settings: {
122+
linkComponents: [
123+
{ name: 'Foo', linkAttribute: ['to', 'href'] },
124+
],
125+
},
126+
},
87127
]),
88128
});

0 commit comments

Comments
 (0)