eslint-plugin-no-jquery 3.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -96,7 +96,7 @@ Where rules are included in the configs `recommended`, `slim`, `all` or `depreca
96
96
  * [`no-jquery/no-box-model`](docs/rules/no-box-model.md) `1.3`
97
97
  * [`no-jquery/no-browser`](docs/rules/no-browser.md) `1.3`
98
98
  * [`no-jquery/no-camel-case`](docs/rules/no-camel-case.md) `3.3`, `all`
99
- * [`no-jquery/no-class`](docs/rules/no-class.md) `all`
99
+ * [`no-jquery/no-class`](docs/rules/no-class.md) ⚙️ `3.0†`, `all`
100
100
  * [`no-jquery/no-class-state`](docs/rules/no-class-state.md)
101
101
  * [`no-jquery/no-clone`](docs/rules/no-clone.md) `all`
102
102
  * [`no-jquery/no-closest`](docs/rules/no-closest.md) `all`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-no-jquery",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "description": "Disallow jQuery functions with native equivalents.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,21 +27,21 @@
27
27
  "src"
28
28
  ],
29
29
  "engine": {
30
- "node": ">=16"
30
+ "node": ">=20"
31
31
  },
32
32
  "peerDependencies": {
33
- "eslint": ">=8.0.0"
33
+ "eslint": ">=8.0.0 <9.0.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "codecov": "^3.8.3",
37
- "eslint-config-wikimedia": "^0.28.2",
37
+ "eslint-config-wikimedia": "^0.32.3",
38
38
  "eslint-docgen": "^0.7.1",
39
- "eslint-plugin-eslint-plugin": "^6.1.0",
39
+ "eslint-plugin-eslint-plugin": "^6.5.0",
40
40
  "eslint-plugin-self": "^1.2.1",
41
41
  "jquery": "3.7.1",
42
- "jsdom": "^22.1.0",
43
- "mocha": "^10.2.0",
44
- "nyc": "^15.1.0"
42
+ "jsdom": "^27.0.0",
43
+ "mocha": "^11.7.4",
44
+ "nyc": "^17.1.0"
45
45
  },
46
46
  "bugs": {
47
47
  "url": "https://github.com/wikimedia/eslint-plugin-no-jquery/issues"
package/src/index.js CHANGED
@@ -180,6 +180,7 @@ module.exports = {
180
180
  extends: 'plugin:no-jquery/deprecated-2.2',
181
181
  rules: {
182
182
  'no-jquery/no-bind': 'warn',
183
+ 'no-jquery/no-class': [ 'warn', { onlyDeprecated: true } ],
183
184
  'no-jquery/no-delegate': 'warn',
184
185
  'no-jquery/no-fx-interval': 'warn',
185
186
  'no-jquery/no-parse-json': 'warn',
@@ -17,11 +17,15 @@ module.exports = {
17
17
  type: 'object',
18
18
  properties: {
19
19
  allowScroll: {
20
- type: 'boolean'
20
+ type: 'boolean',
21
+ description: 'Allow animations which are just used for scrolling'
21
22
  }
22
23
  },
23
24
  additionalProperties: false
24
25
  }
26
+ ],
27
+ defaultOptions: [
28
+ { allowScroll: false }
25
29
  ]
26
30
  },
27
31
 
@@ -34,16 +38,23 @@ module.exports = {
34
38
  return;
35
39
  }
36
40
  const allowScroll = context.options[ 0 ] && context.options[ 0 ].allowScroll;
37
- if ( node.callee.property.name === 'animate' && allowScroll ) {
38
- const arg = node.arguments[ 0 ];
39
- // Check properties list has more than just scrollTop/scrollLeft
40
- if ( arg && arg.type === 'ObjectExpression' ) {
41
- if (
42
- arg.properties.every(
43
- ( prop ) => prop.key.name === 'scrollTop' || prop.key.name === 'scrollLeft'
44
- )
45
- ) {
46
- return;
41
+ const name = node.callee.property.name;
42
+ if ( allowScroll ) {
43
+ if ( name === 'stop' || name === 'finish' ) {
44
+ // We can't tell what animation we are stopping, so assume
45
+ // it is an allowed scroll
46
+ return;
47
+ } else if ( name === 'animate' ) {
48
+ const arg = node.arguments[ 0 ];
49
+ // Check properties list has more than just scrollTop/scrollLeft
50
+ if ( arg && arg.type === 'ObjectExpression' ) {
51
+ if (
52
+ arg.properties.every(
53
+ ( prop ) => prop.key.name === 'scrollTop' || prop.key.name === 'scrollLeft'
54
+ )
55
+ ) {
56
+ return;
57
+ }
47
58
  }
48
59
  }
49
60
  }
@@ -2,9 +2,83 @@
2
2
 
3
3
  const utils = require( '../utils.js' );
4
4
 
5
- module.exports = utils.createCollectionMethodRule(
6
- [ 'addClass', 'hasClass', 'removeClass', 'toggleClass' ],
7
- ( node ) => node === true ?
8
- 'Prefer `Element#classList`' :
9
- `Prefer Element#classList to .${ node.callee.property.name }`
10
- );
5
+ const methods = [ 'addClass', 'hasClass', 'removeClass', 'toggleClass' ];
6
+
7
+ module.exports = {
8
+ meta: {
9
+ type: 'suggestion',
10
+ docs: {
11
+ description: 'Disallows the ' + methods.map( utils.jQueryCollectionLink ).join( '/' ) +
12
+ ' methods. User the `onlyDeprecated` option to only report deprecated usages. Prefer `Element#classList`.'
13
+ },
14
+ schema: [
15
+ {
16
+ type: 'object',
17
+ properties: {
18
+ onlyDeprecated: {
19
+ type: 'boolean',
20
+ description: 'Only report deprecated usages of the methods.'
21
+ }
22
+ },
23
+ additionalProperties: false
24
+ }
25
+ ],
26
+ defaultOptions: [
27
+ { onlyDeprecated: false }
28
+ ]
29
+ },
30
+
31
+ create: ( context ) => ( {
32
+ 'CallExpression:exit': ( node ) => {
33
+ if (
34
+ node.callee.type !== 'MemberExpression' ||
35
+ !methods.includes( node.callee.property.name )
36
+ ) {
37
+ return;
38
+ }
39
+ const name = node.callee.property.name;
40
+ const onlyDeprecated = context.options[ 0 ] && context.options[ 0 ].onlyDeprecated;
41
+
42
+ if ( !onlyDeprecated ) {
43
+ if ( utils.isjQuery( context, node.callee ) ) {
44
+ const message = node === true ?
45
+ 'Prefer `Element#classList`' :
46
+ `Prefer Element#classList to .${ name }`;
47
+ context.report( {
48
+ node,
49
+ message
50
+ } );
51
+ }
52
+ } else {
53
+ if ( name !== 'toggleClass' || utils.isjQueryConstructor( context, node.callee.object.name ) ) {
54
+ return;
55
+ }
56
+
57
+ if ( node.arguments.length >= 2 ) {
58
+ return;
59
+ }
60
+ if ( node.arguments.length === 1 ) {
61
+ const arg = node.arguments[ 0 ];
62
+ if (
63
+ !(
64
+ arg.type === 'Literal' &&
65
+ ( arg.value === true || arg.value === false )
66
+ ) &&
67
+ !(
68
+ arg.type === 'Identifier' && arg.name === 'undefined'
69
+ )
70
+ ) {
71
+ return;
72
+ }
73
+ }
74
+
75
+ if ( utils.isjQuery( context, node.callee ) ) {
76
+ context.report( {
77
+ node,
78
+ message: '.toggleClass(boolean|undefined) is deprecated'
79
+ } );
80
+ }
81
+ }
82
+ }
83
+ } )
84
+ };
@@ -6,7 +6,9 @@ module.exports = {
6
6
  meta: {
7
7
  type: 'suggestion',
8
8
  docs: {
9
- description: 'Disallows the ' + utils.jQueryGlobalLink( 'extend' ) + ' utility. Prefer `Object.assign` or the spread operator.'
9
+ description:
10
+ 'Disallows the ' + utils.jQueryGlobalLink( 'extend' ) + ' utility. Prefer `Object.assign` or the spread operator. ' +
11
+ 'Use the `allowDeep` option to allow using the method with the `deep` argument.'
10
12
  },
11
13
  fixable: 'code',
12
14
  schema: [
@@ -14,11 +16,15 @@ module.exports = {
14
16
  type: 'object',
15
17
  properties: {
16
18
  allowDeep: {
17
- type: 'boolean'
19
+ type: 'boolean',
20
+ description: 'Allow when used with the `deep` argument'
18
21
  }
19
22
  },
20
23
  additionalProperties: false
21
24
  }
25
+ ],
26
+ defaultOptions: [
27
+ { allowDeep: false }
22
28
  ]
23
29
  },
24
30
 
@@ -20,11 +20,15 @@ module.exports = {
20
20
  type: 'object',
21
21
  properties: {
22
22
  allowIds: {
23
- type: 'boolean'
23
+ type: 'boolean',
24
+ description: 'Allow single ID selectors'
24
25
  }
25
26
  },
26
27
  additionalProperties: false
27
28
  }
29
+ ],
30
+ defaultOptions: [
31
+ { allowIds: false }
28
32
  ]
29
33
  },
30
34
 
@@ -31,6 +31,7 @@ const methodsWithRules = [
31
31
  'fadeToggle',
32
32
  'filter',
33
33
  'find',
34
+ 'finish',
34
35
  'focus',
35
36
  'focusin',
36
37
  'focusout',
@@ -71,6 +72,7 @@ const methodsWithRules = [
71
72
  'slideDown',
72
73
  'slideToggle',
73
74
  'slideUp',
75
+ 'stop',
74
76
  'submit',
75
77
  'text',
76
78
  'toggle',
@@ -26,11 +26,15 @@ module.exports = {
26
26
  type: 'object',
27
27
  properties: {
28
28
  singleTagStyle: {
29
- enum: [ 'minimal', 'self-closing', 'any' ]
29
+ enum: [ 'minimal', 'self-closing', 'any' ],
30
+ description: 'Format of single tags'
30
31
  }
31
32
  },
32
33
  additionalProperties: false
33
34
  }
35
+ ],
36
+ defaultOptions: [
37
+ { singleTagStyle: 'minimal' }
34
38
  ]
35
39
  },
36
40
 
@@ -15,14 +15,20 @@ module.exports = {
15
15
  type: 'object',
16
16
  properties: {
17
17
  allowPositional: {
18
- type: 'boolean'
18
+ type: 'boolean',
19
+ description: 'Allow positional selectors'
19
20
  },
20
21
  allowOther: {
21
- type: 'boolean'
22
+ type: 'boolean',
23
+ description: 'Allow all other selectors'
22
24
  }
23
25
  },
24
26
  additionalProperties: false
25
27
  }
28
+ ],
29
+ defaultOptions: [
30
+ { allowPositional: false },
31
+ { allowOther: false }
26
32
  ]
27
33
  },
28
34