diff --git a/docs/rules/jsx-no-script-url.md b/docs/rules/jsx-no-script-url.md index 6c081459a6..11fffdad16 100644 --- a/docs/rules/jsx-no-script-url.md +++ b/docs/rules/jsx-no-script-url.md @@ -27,6 +27,10 @@ This rule takes the `linkComponents` setting into account. ## Rule Options +This rule accepts array option (optional) and object option (optional). + +### Array option (default `[]`) + ```json { "react/jsx-no-script-url": [ @@ -47,14 +51,11 @@ This rule takes the `linkComponents` setting into account. Allows you to indicate a specific list of properties used by a custom component to be checked. -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. -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. - -### name +#### name Component name. -### props +#### props List of properties that should be validated. @@ -65,3 +66,37 @@ Examples of **incorrect** code for this rule, when configured with the above opt ``` + +### Object option + +#### includeFromSettings (default `false`) + +Indicates if the `linkComponents` config in [global shared settings](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/README.md#configuration) should also be taken into account. If enabled, components and properties defined in settings will be added to the list provided in first option (if provided): + +```json +{ + "react/jsx-no-script-url": [ + "error", + [ + { + "name": "Link", + "props": ["to"] + }, + { + "name": "Foo", + "props": ["href", "to"] + } + ], + { "includeFromSettings": true } + ] +} +``` + +If only global settings should be used for this rule, the array option can be omitted: + +```jsonc +{ + // same as ["error", [], { "includeFromSettings": true }] + "react/jsx-no-script-url": ["error", { "includeFromSettings": true }] +} +``` diff --git a/lib/rules/jsx-no-script-url.js b/lib/rules/jsx-no-script-url.js index 6bca1fd91a..605c8ec082 100644 --- a/lib/rules/jsx-no-script-url.js +++ b/lib/rules/jsx-no-script-url.js @@ -54,34 +54,76 @@ module.exports = { messages, - schema: [{ - type: 'array', - uniqueItems: true, - items: { - type: 'object', - properties: { - name: { - type: 'string', - }, - props: { - type: 'array', - items: { - type: 'string', + schema: { + anyOf: [ + { + type: 'array', + items: [ + { + type: 'array', uniqueItems: true, + items: { + type: 'object', + properties: { + name: { + type: 'string', + }, + props: { + type: 'array', + items: { + type: 'string', + uniqueItems: true, + }, + }, + }, + required: ['name', 'props'], + additionalProperties: false, + }, }, - }, + { + type: 'object', + properties: { + includeFromSettings: { + type: 'boolean', + }, + }, + }, + ], + additionalItems: false, }, - required: ['name', 'props'], - additionalProperties: false, - }, - }], + { + type: 'array', + items: [ + { + type: 'object', + properties: { + includeFromSettings: { + type: 'boolean', + }, + }, + }, + ], + additionalItems: false, + }, + ], + }, }, create(context) { - const linkComponents = linkComponentsUtil.getLinkComponents(context); - if (context.options[0]) { - parseLegacyOption(linkComponents, context.options[0]); + const options = context.options.slice(); + let legacyOptions = []; + let includeFromSettings = false; + + if (Array.isArray(options[0])) { + legacyOptions = options.shift(); } + if (typeof options[0] === 'object') { + const objOption = options.shift(); + includeFromSettings = objOption.includeFromSettings || includeFromSettings; + } + + const linkComponents = linkComponentsUtil.getLinkComponents(includeFromSettings ? context : {}); + parseLegacyOption(linkComponents, legacyOptions); return { JSXAttribute(node) { diff --git a/tests/lib/rules/jsx-no-script-url.js b/tests/lib/rules/jsx-no-script-url.js index dae171bba0..4d0374e08e 100644 --- a/tests/lib/rules/jsx-no-script-url.js +++ b/tests/lib/rules/jsx-no-script-url.js @@ -38,8 +38,22 @@ ruleTester.run('jsx-no-script-url', rule, { { code: '' }, { code: '' }, { code: '' }, + { + code: '', + settings: { + linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }], + }, + }, + { + code: '', + options: [[], { includeFromSettings: false }], + settings: { + linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }], + }, + }, ]), invalid: parsers.all([ + // defaults { code: '', errors: [{ messageId: 'noScriptURL' }], @@ -52,6 +66,8 @@ ruleTester.run('jsx-no-script-url', rule, { code: '', errors: [{ messageId: 'noScriptURL' }], }, + + // with component passed by options { code: '', errors: [{ messageId: 'noScriptURL' }], @@ -66,22 +82,32 @@ ruleTester.run('jsx-no-script-url', rule, { [{ name: 'Foo', props: ['to', 'href'] }], ], }, + { // make sure it still uses defaults when passed options + code: '', + errors: [{ messageId: 'noScriptURL' }], + options: [ + [{ name: 'Foo', props: ['to', 'href'] }], + ], + }, + + // with components passed by settings { code: '', errors: [{ messageId: 'noScriptURL' }], + options: [ + [{ name: 'Bar', props: ['to', 'href'] }], + { includeFromSettings: true }, + ], settings: { - linkComponents: [ - { name: 'Foo', linkAttribute: 'to' }, - ], + linkComponents: [{ name: 'Foo', linkAttribute: 'to' }], }, }, { code: '', errors: [{ messageId: 'noScriptURL' }], + options: [{ includeFromSettings: true }], settings: { - linkComponents: [ - { name: 'Foo', linkAttribute: ['to', 'href'] }, - ], + linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }], }, }, { @@ -96,11 +122,12 @@ ruleTester.run('jsx-no-script-url', rule, { { messageId: 'noScriptURL' }, ], options: [ - [ - { name: 'Foo', props: ['to', 'href'] }, - { name: 'Bar', props: ['link'] }, - ], + [{ name: 'Bar', props: ['link'] }], + { includeFromSettings: true }, ], + settings: { + linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }], + }, }, { code: ` @@ -111,17 +138,12 @@ ruleTester.run('jsx-no-script-url', rule, { `, errors: [ { messageId: 'noScriptURL' }, - { messageId: 'noScriptURL' }, ], options: [ - [ - { name: 'Bar', props: ['link'] }, - ], + [{ name: 'Bar', props: ['link'] }], ], settings: { - linkComponents: [ - { name: 'Foo', linkAttribute: ['to', 'href'] }, - ], + linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }], }, }, ]),