eslint-plugin-no-jquery 2.4.0 → 2.7.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.
Files changed (41) hide show
  1. package/Changelog.md +87 -11
  2. package/README.md +114 -98
  3. package/README.md.template +14 -3
  4. package/package.json +14 -12
  5. package/src/all-methods.js +2 -0
  6. package/src/index.js +174 -53
  7. package/src/rules/no-ajax-events.js +10 -12
  8. package/src/rules/no-and-self.js +1 -1
  9. package/src/rules/no-animate-toggle.js +4 -3
  10. package/src/rules/no-animate.js +1 -1
  11. package/src/rules/no-append-html.js +53 -0
  12. package/src/rules/no-class-state.js +1 -1
  13. package/src/rules/no-constructor-attributes.js +1 -1
  14. package/src/rules/no-deferred.js +1 -1
  15. package/src/rules/no-error.js +7 -1
  16. package/src/rules/no-escape-selector.js +14 -0
  17. package/src/rules/no-event-shorthand.js +7 -7
  18. package/src/rules/no-extend.js +1 -1
  19. package/src/rules/no-global-selector.js +1 -1
  20. package/src/rules/no-html.js +2 -1
  21. package/src/rules/no-is-array.js +1 -1
  22. package/src/rules/no-is-function.js +1 -1
  23. package/src/rules/no-jquery-constructor.js +31 -0
  24. package/src/rules/no-load-shorthand.js +2 -2
  25. package/src/rules/no-noop.js +1 -1
  26. package/src/rules/no-now.js +2 -2
  27. package/src/rules/no-on-ready.js +17 -2
  28. package/src/rules/no-other-methods.js +121 -0
  29. package/src/rules/no-other-utils.js +88 -0
  30. package/src/rules/no-parse-html-literal.js +18 -7
  31. package/src/rules/no-parse-json.js +1 -1
  32. package/src/rules/no-parse-xml.js +12 -1
  33. package/src/rules/no-proxy.js +19 -1
  34. package/src/rules/no-ready-shorthand.js +9 -1
  35. package/src/rules/no-ready.js +1 -1
  36. package/src/rules/no-size.js +2 -2
  37. package/src/rules/no-sizzle.js +2 -2
  38. package/src/rules/no-submit.js +2 -1
  39. package/src/rules/no-unique.js +1 -1
  40. package/src/rules/variable-pattern.js +4 -3
  41. package/src/utils.js +59 -25
package/src/index.js CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  module.exports = {
4
4
  rules: {
5
- 'variable-pattern': require( './rules/variable-pattern' ),
6
5
  'no-ajax': require( './rules/no-ajax' ),
7
6
  'no-ajax-events': require( './rules/no-ajax-events' ),
8
7
  'no-and-self': require( './rules/no-and-self' ),
9
8
  'no-animate': require( './rules/no-animate' ),
10
9
  'no-animate-toggle': require( './rules/no-animate-toggle' ),
10
+ 'no-append-html': require( './rules/no-append-html' ),
11
11
  'no-attr': require( './rules/no-attr' ),
12
12
  'no-bind': require( './rules/no-bind' ),
13
13
  'no-box-model': require( './rules/no-box-model' ),
@@ -30,6 +30,7 @@ module.exports = {
30
30
  'no-each-util': require( './rules/no-each-util' ),
31
31
  'no-error': require( './rules/no-error' ),
32
32
  'no-error-shorthand': require( './rules/no-error-shorthand' ),
33
+ 'no-escape-selector': require( './rules/no-escape-selector' ),
33
34
  'no-event-shorthand': require( './rules/no-event-shorthand' ),
34
35
  'no-extend': require( './rules/no-extend' ),
35
36
  'no-fade': require( './rules/no-fade' ),
@@ -39,19 +40,21 @@ module.exports = {
39
40
  'no-find-util': require( './rules/no-find-util' ),
40
41
  'no-fx-interval': require( './rules/no-fx-interval' ),
41
42
  'no-global-eval': require( './rules/no-global-eval' ),
43
+ 'no-global-selector': require( './rules/no-global-selector' ),
42
44
  'no-grep': require( './rules/no-grep' ),
43
45
  'no-has': require( './rules/no-has' ),
44
46
  'no-hide': require( './rules/no-hide' ),
45
47
  'no-hold-ready': require( './rules/no-hold-ready' ),
46
48
  'no-html': require( './rules/no-html' ),
47
49
  'no-in-array': require( './rules/no-in-array' ),
50
+ 'no-is': require( './rules/no-is' ),
48
51
  'no-is-array': require( './rules/no-is-array' ),
49
52
  'no-is-empty-object': require( './rules/no-is-empty-object' ),
50
- 'no-is-plain-object': require( './rules/no-is-plain-object' ),
51
53
  'no-is-function': require( './rules/no-is-function' ),
52
54
  'no-is-numeric': require( './rules/no-is-numeric' ),
55
+ 'no-is-plain-object': require( './rules/no-is-plain-object' ),
53
56
  'no-is-window': require( './rules/no-is-window' ),
54
- 'no-is': require( './rules/no-is' ),
57
+ 'no-jquery-constructor': require( './rules/no-jquery-constructor' ),
55
58
  'no-live': require( './rules/no-live' ),
56
59
  'no-load': require( './rules/no-load' ),
57
60
  'no-load-shorthand': require( './rules/no-load-shorthand' ),
@@ -63,6 +66,8 @@ module.exports = {
63
66
  'no-noop': require( './rules/no-noop' ),
64
67
  'no-now': require( './rules/no-now' ),
65
68
  'no-on-ready': require( './rules/no-on-ready' ),
69
+ 'no-other-methods': require( './rules/no-other-methods' ),
70
+ 'no-other-utils': require( './rules/no-other-utils' ),
66
71
  'no-param': require( './rules/no-param' ),
67
72
  'no-parent': require( './rules/no-parent' ),
68
73
  'no-parents': require( './rules/no-parents' ),
@@ -76,7 +81,6 @@ module.exports = {
76
81
  'no-ready-shorthand': require( './rules/no-ready-shorthand' ),
77
82
  'no-selector-prop': require( './rules/no-selector-prop' ),
78
83
  'no-serialize': require( './rules/no-serialize' ),
79
- 'no-global-selector': require( './rules/no-global-selector' ),
80
84
  'no-show': require( './rules/no-show' ),
81
85
  'no-size': require( './rules/no-size' ),
82
86
  'no-sizzle': require( './rules/no-sizzle' ),
@@ -96,10 +100,16 @@ module.exports = {
96
100
  'no-val': require( './rules/no-val' ),
97
101
  'no-visibility': require( './rules/no-visibility' ),
98
102
  'no-when': require( './rules/no-when' ),
99
- 'no-wrap': require( './rules/no-wrap' )
103
+ 'no-wrap': require( './rules/no-wrap' ),
104
+ 'variable-pattern': require( './rules/variable-pattern' )
100
105
  },
101
106
  configs: {
102
- // Use this profile if you are using jQuery slim build
107
+ recommended: {
108
+ rules: {
109
+ 'no-jquery/variable-pattern': 'error'
110
+ }
111
+ },
112
+ // Use this config if you are using jQuery slim build
103
113
  slim: {
104
114
  rules: {
105
115
  // Effects
@@ -114,103 +124,214 @@ module.exports = {
114
124
  'no-jquery/no-parse-xml': 'error'
115
125
  }
116
126
  },
117
- // Use this profile if you want to avoid all known deprecated jQuery tools.
127
+ // Use this config if you want to avoid all known deprecated jQuery tools.
118
128
  deprecated: {
129
+ extends: 'plugin:no-jquery/deprecated-3.6'
130
+ },
131
+ // Use this config if you're writing code targetting jQuery 3.6.x environments.
132
+ 'deprecated-3.6': {
119
133
  extends: 'plugin:no-jquery/deprecated-3.5'
120
134
  },
121
- // Use this profile if you're writing code targetting jQuery 3.5.x environments.
122
135
  'deprecated-3.5': {
123
136
  extends: 'plugin:no-jquery/deprecated-3.4',
124
137
  rules: {
125
- 'no-jquery/no-event-shorthand': 'error',
126
- 'no-jquery/no-trim': 'error'
138
+ // Pass empty options here to override options set in deprecated-3.3
139
+ 'no-jquery/no-event-shorthand': [ 'warn', {} ],
140
+ 'no-jquery/no-trim': 'warn'
127
141
  }
128
142
  },
129
- // Use this profile if you're writing code targetting jQuery 3.4.x environments.
130
143
  'deprecated-3.4': {
131
144
  extends: 'plugin:no-jquery/deprecated-3.3',
132
145
  rules: {
133
- 'no-jquery/no-sizzle': [ 'error', { allowPositional: false, allowOther: true } ]
146
+ 'no-jquery/no-sizzle': [ 'warn', { allowPositional: false, allowOther: true } ]
134
147
  }
135
148
  },
136
- // Use this profile if you're writing code targetting jQuery 3.3.x environments.
137
149
  'deprecated-3.3': {
138
150
  extends: 'plugin:no-jquery/deprecated-3.2',
139
151
  rules: {
140
- 'no-jquery/no-camel-case': 'error',
141
- 'no-jquery/no-event-shorthand': [ 'error', { allowAjaxEvents: true } ],
142
- 'no-jquery/no-is-function': 'error',
143
- 'no-jquery/no-is-numeric': 'error',
144
- 'no-jquery/no-is-window': 'error',
145
- 'no-jquery/no-now': 'error',
146
- 'no-jquery/no-proxy': 'error',
147
- 'no-jquery/no-type': 'error'
152
+ 'no-jquery/no-camel-case': 'warn',
153
+ 'no-jquery/no-event-shorthand': [ 'warn', { allowAjaxEvents: true } ],
154
+ 'no-jquery/no-is-function': 'warn',
155
+ 'no-jquery/no-is-numeric': 'warn',
156
+ 'no-jquery/no-is-window': 'warn',
157
+ 'no-jquery/no-now': 'warn',
158
+ 'no-jquery/no-proxy': 'warn',
159
+ 'no-jquery/no-type': 'warn'
148
160
  }
149
161
  },
150
- // Use this profile if you're writing code targetting jQuery 3.3.x environments.
151
162
  'deprecated-3.2': {
152
- extends: 'plugin:no-jquery/deprecated-3.0',
163
+ extends: 'plugin:no-jquery/deprecated-3.1',
153
164
  rules: {
154
- 'no-jquery/no-hold-ready': 'error',
155
- 'no-jquery/no-is-array': 'error',
156
- 'no-jquery/no-node-name': 'error'
165
+ 'no-jquery/no-hold-ready': 'warn',
166
+ 'no-jquery/no-is-array': 'warn',
167
+ 'no-jquery/no-node-name': 'warn'
157
168
  }
158
169
  },
159
- // Use this profile if you're writing code targetting jQuery 3.0.x environments.
170
+ 'deprecated-3.1': {
171
+ extends: 'plugin:no-jquery/deprecated-3.0'
172
+ },
160
173
  'deprecated-3.0': {
161
- extends: 'plugin:no-jquery/deprecated-1.10',
174
+ extends: 'plugin:no-jquery/deprecated-2.2',
162
175
  rules: {
163
- 'no-jquery/no-bind': 'error',
164
- 'no-jquery/no-delegate': 'error',
165
- 'no-jquery/no-fx-interval': 'error',
166
- 'no-jquery/no-parse-json': 'error',
167
- 'no-jquery/no-ready-shorthand': 'error',
168
- 'no-jquery/no-unique': 'error'
176
+ 'no-jquery/no-bind': 'warn',
177
+ 'no-jquery/no-delegate': 'warn',
178
+ 'no-jquery/no-fx-interval': 'warn',
179
+ 'no-jquery/no-parse-json': 'warn',
180
+ 'no-jquery/no-ready-shorthand': 'warn',
181
+ 'no-jquery/no-unique': 'warn'
169
182
  }
170
183
  },
171
- // Use this profile if you're writing code targetting jQuery 1.10.x environments.
184
+ 'deprecated-2.2': {
185
+ extends: 'plugin:no-jquery/deprecated-2.1'
186
+ },
187
+ 'deprecated-2.1': {
188
+ extends: 'plugin:no-jquery/deprecated-2.0'
189
+ },
190
+ 'deprecated-2.0': {
191
+ extends: 'plugin:no-jquery/deprecated-1.12'
192
+ },
193
+ 'deprecated-1.12': {
194
+ extends: 'plugin:no-jquery/deprecated-1.11'
195
+ },
196
+ 'deprecated-1.11': {
197
+ extends: 'plugin:no-jquery/deprecated-1.10'
198
+ },
172
199
  'deprecated-1.10': {
173
200
  extends: 'plugin:no-jquery/deprecated-1.9',
174
201
  rules: {
175
- 'no-jquery/no-context-prop': 'error'
202
+ 'no-jquery/no-context-prop': 'warn'
176
203
  }
177
204
  },
178
- // Use this profile if you're writing code targetting jQuery 1.9.x environments.
179
205
  'deprecated-1.9': {
180
206
  extends: 'plugin:no-jquery/deprecated-1.8',
181
207
  rules: {
182
- 'no-jquery/no-support': 'error'
208
+ 'no-jquery/no-support': 'warn'
183
209
  }
184
210
  },
185
- // Use this profile if you're writing code targetting jQuery 1.8.x environments.
186
211
  'deprecated-1.8': {
187
212
  extends: 'plugin:no-jquery/deprecated-1.7',
188
213
  rules: {
189
- 'no-jquery/no-and-self': 'error',
214
+ 'no-jquery/no-and-self': 'warn',
190
215
  // FIXME: `deferred.pipe()`
191
- 'no-jquery/no-error-shorthand': 'error',
192
- 'no-jquery/no-load-shorthand': 'error',
193
- 'no-jquery/no-on-ready': 'error',
194
- 'no-jquery/no-size': 'error',
216
+ 'no-jquery/no-error-shorthand': 'warn',
217
+ 'no-jquery/no-load-shorthand': 'warn',
218
+ 'no-jquery/no-on-ready': 'warn',
219
+ 'no-jquery/no-size': 'warn',
195
220
  // FIXME: `$(...).toggle(fn,fn) (excluding https://api.jquery.com/toggle/)
196
- 'no-jquery/no-unload-shorthand': 'error'
221
+ 'no-jquery/no-unload-shorthand': 'warn'
197
222
  }
198
223
  },
199
- // Use this profile if you're writing code targetting jQuery 1.7.x environments.
200
224
  'deprecated-1.7': {
201
- extends: 'plugin:no-jquery/deprecated-1.3',
225
+ extends: 'plugin:no-jquery/deprecated-1.6',
202
226
  rules: {
203
227
  // FIXME: `deferred.isRejected()/isResolved()`
204
- 'no-jquery/no-live': 'error',
205
- 'no-jquery/no-sub': 'error',
206
- 'no-jquery/no-selector-prop': 'error'
228
+ 'no-jquery/no-live': 'warn',
229
+ 'no-jquery/no-sub': 'warn',
230
+ 'no-jquery/no-selector-prop': 'warn'
207
231
  }
208
232
  },
209
- // Use this profile if you're writing code targetting jQuery 1.3.x environments.
233
+ 'deprecated-1.6': {
234
+ extends: 'plugin:no-jquery/deprecated-1.5'
235
+ },
236
+ 'deprecated-1.5': {
237
+ extends: 'plugin:no-jquery/deprecated-1.4'
238
+ },
239
+ 'deprecated-1.4': {
240
+ extends: 'plugin:no-jquery/deprecated-1.3'
241
+ },
210
242
  'deprecated-1.3': {
243
+ extends: 'plugin:no-jquery/deprecated-1.2',
244
+ rules: {
245
+ 'no-jquery/no-box-model': 'warn',
246
+ 'no-jquery/no-browser': 'warn'
247
+ }
248
+ },
249
+ 'deprecated-1.2': {
250
+ extends: 'plugin:no-jquery/deprecated-1.1'
251
+ },
252
+ 'deprecated-1.1': {
253
+ extends: 'plugin:no-jquery/deprecated-1.0'
254
+ },
255
+ 'deprecated-1.0': {},
256
+ // Use this config to disallow all usage of jQuery
257
+ all: {
211
258
  rules: {
212
- 'no-jquery/no-box-model': 'error',
213
- 'no-jquery/no-browser': 'error'
259
+ 'no-jquery/no-other-methods': 'warn',
260
+ 'no-jquery/no-other-utils': 'warn',
261
+ 'no-jquery/no-jquery-constructor': 'warn',
262
+
263
+ // methods
264
+ 'no-jquery/no-animate': 'warn',
265
+ 'no-jquery/no-bind': 'warn',
266
+ 'no-jquery/no-class': 'warn',
267
+ 'no-jquery/no-closest': 'warn',
268
+ 'no-jquery/no-delegate': 'warn',
269
+ 'no-jquery/no-each-collection': 'warn',
270
+ 'no-jquery/no-event-shorthand': 'warn',
271
+ 'no-jquery/no-fade': 'warn',
272
+ 'no-jquery/no-find-collection': 'warn',
273
+ 'no-jquery/no-has': 'warn',
274
+ 'no-jquery/no-html': 'warn',
275
+ 'no-jquery/no-is': 'warn',
276
+ 'no-jquery/no-live': 'warn',
277
+ 'no-jquery/no-load': 'warn',
278
+ 'no-jquery/no-map-collection': 'warn',
279
+ 'no-jquery/no-parent': 'warn',
280
+ 'no-jquery/no-parents': 'warn',
281
+ 'no-jquery/no-ready-shorthand': 'warn',
282
+ 'no-jquery/no-serialize': 'warn',
283
+ 'no-jquery/no-size': 'warn',
284
+ 'no-jquery/no-slide': 'warn',
285
+ 'no-jquery/no-trigger': 'warn',
286
+ 'no-jquery/no-val': 'warn',
287
+ 'no-jquery/no-visibility': 'warn',
288
+ 'no-jquery/no-wrap': 'warn',
289
+
290
+ // Utils
291
+ 'no-jquery/no-ajax': 'warn',
292
+ 'no-jquery/no-camel-case': 'warn',
293
+ 'no-jquery/no-contains': 'warn',
294
+ 'no-jquery/no-deferred': 'warn',
295
+ 'no-jquery/no-each-util': 'warn',
296
+ 'no-jquery/no-error': 'warn',
297
+ 'no-jquery/no-escape-selector': 'warn',
298
+ 'no-jquery/no-extend': 'warn',
299
+ 'no-jquery/no-find-util': 'warn',
300
+ 'no-jquery/no-global-eval': 'warn',
301
+ 'no-jquery/no-grep': 'warn',
302
+ 'no-jquery/no-hold-ready': 'warn',
303
+ 'no-jquery/no-in-array': 'warn',
304
+ 'no-jquery/no-is-array': 'warn',
305
+ 'no-jquery/no-is-empty-object': 'warn',
306
+ 'no-jquery/no-is-function': 'warn',
307
+ 'no-jquery/no-is-numeric': 'warn',
308
+ 'no-jquery/no-is-plain-object': 'warn',
309
+ 'no-jquery/no-is-window': 'warn',
310
+ 'no-jquery/no-map-util': 'warn',
311
+ 'no-jquery/no-merge': 'warn',
312
+ 'no-jquery/no-node-name': 'warn',
313
+ 'no-jquery/no-noop': 'warn',
314
+ 'no-jquery/no-now': 'warn',
315
+ 'no-jquery/no-param': 'warn',
316
+ 'no-jquery/no-parse-html': 'warn',
317
+ 'no-jquery/no-parse-json': 'warn',
318
+ 'no-jquery/no-parse-xml': 'warn',
319
+ 'no-jquery/no-proxy': 'warn',
320
+ 'no-jquery/no-trim': 'warn',
321
+ 'no-jquery/no-type': 'warn',
322
+ 'no-jquery/no-unique': 'warn',
323
+ 'no-jquery/no-when': 'warn',
324
+
325
+ // Method+utils
326
+ 'no-jquery/no-attr': 'warn',
327
+ 'no-jquery/no-clone': 'warn',
328
+ 'no-jquery/no-css': 'warn',
329
+ 'no-jquery/no-data': 'warn',
330
+ 'no-jquery/no-filter': 'warn',
331
+ 'no-jquery/no-prop': 'warn',
332
+ 'no-jquery/no-sub': 'warn',
333
+ 'no-jquery/no-text': 'warn'
334
+
214
335
  }
215
336
  }
216
337
  }
@@ -3,17 +3,14 @@
3
3
  const utils = require( '../utils.js' );
4
4
 
5
5
  const disallowedEvents = [
6
- 'ajaxStart',
7
- 'ajaxSend',
8
- 'ajaxSuccess',
9
- 'ajaxError',
10
6
  'ajaxComplete',
11
- 'ajaxStop'
7
+ 'ajaxError',
8
+ 'ajaxSend',
9
+ 'ajaxStart',
10
+ 'ajaxStop',
11
+ 'ajaxSuccess'
12
12
  ];
13
13
 
14
- const MemberExpression = 'MemberExpression';
15
- const Literal = 'Literal';
16
-
17
14
  module.exports = {
18
15
  meta: {
19
16
  type: 'suggestion',
@@ -25,8 +22,8 @@ module.exports = {
25
22
 
26
23
  create: function ( context ) {
27
24
  return {
28
- CallExpression: function ( node ) {
29
- if ( node.callee.type !== MemberExpression ) {
25
+ 'CallExpression:exit': function ( node ) {
26
+ if ( node.callee.type !== 'MemberExpression' ) {
30
27
  return;
31
28
  }
32
29
  let usedMethod;
@@ -36,7 +33,7 @@ module.exports = {
36
33
  ) {
37
34
  const arg = node.arguments[ 0 ];
38
35
  if (
39
- arg.type === Literal &&
36
+ arg.type === 'Literal' &&
40
37
  disallowedEvents.includes( arg.value )
41
38
  ) {
42
39
  usedMethod = arg.value;
@@ -48,7 +45,8 @@ module.exports = {
48
45
  if ( usedMethod && utils.isjQuery( context, node ) ) {
49
46
  context.report( {
50
47
  node: node,
51
- message: `Prefer local event to ${usedMethod}`
48
+ message: 'Prefer local event to {{method}}',
49
+ data: { method: usedMethod }
52
50
  } );
53
51
  }
54
52
  }
@@ -7,7 +7,7 @@ module.exports = utils.createCollectionMethodRule(
7
7
  'Prefer `.addBack` to `.andSelf`',
8
8
  {
9
9
  fixable: 'code',
10
- fix: function ( node, fixer ) {
10
+ fix: function ( node, context, fixer ) {
11
11
  return fixer.replaceText( node.callee.property, 'addBack' );
12
12
  }
13
13
  }
@@ -18,10 +18,10 @@ module.exports = {
18
18
  const forbidden = [ 'show', 'hide', 'toggle' ];
19
19
 
20
20
  return {
21
- CallExpression: function ( node ) {
21
+ 'CallExpression:exit': function ( node ) {
22
22
  if (
23
23
  node.callee.type !== 'MemberExpression' ||
24
- forbidden.indexOf( node.callee.property.name ) === -1 ||
24
+ !forbidden.includes( node.callee.property.name ) ||
25
25
  node.arguments.length === 0
26
26
  ) {
27
27
  return;
@@ -46,7 +46,8 @@ module.exports = {
46
46
  if ( utils.isjQuery( context, node ) ) {
47
47
  context.report( {
48
48
  node: node,
49
- message: 'Prefer CSS transitions to .' + node.callee.property.name
49
+ message: 'Prefer CSS transitions to .{{method}}',
50
+ data: { method: node.callee.property.name }
50
51
  } );
51
52
  }
52
53
  }
@@ -25,7 +25,7 @@ module.exports = {
25
25
 
26
26
  create: function ( context ) {
27
27
  return {
28
- CallExpression: function ( node ) {
28
+ 'CallExpression:exit': function ( node ) {
29
29
  if (
30
30
  node.callee.type !== 'MemberExpression' ||
31
31
  node.callee.property.name !== 'animate'
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ const utils = require( '../utils.js' );
4
+ const methods = [ 'append', 'prepend', 'before', 'after', 'replaceWith' ];
5
+
6
+ function alljQueryOrEmpty( context, node ) {
7
+ if ( node.type === 'ConditionalExpression' ) {
8
+ return alljQueryOrEmpty( context, node.consequent ) &&
9
+ alljQueryOrEmpty( context, node.alternate );
10
+ } else if ( node.type === 'Literal' ) {
11
+ return node.value === null || (
12
+ typeof node.value === 'string' && node.value.match( /^\s*$/ )
13
+ );
14
+ } else if ( node.type === 'Identifier' && node.name === 'undefined' ) {
15
+ return true;
16
+ } else {
17
+ return utils.isjQuery( context, node );
18
+ }
19
+ }
20
+
21
+ module.exports = {
22
+ meta: {
23
+ type: 'suggestion',
24
+ docs: {
25
+ description: 'Disallows using ' + methods.map( utils.jQueryCollectionLink ).join( '/' ) +
26
+ ' to inject HTML, in order to prevent possible XSS bugs.'
27
+ },
28
+ schema: []
29
+ },
30
+
31
+ create: function ( context ) {
32
+ return {
33
+ 'CallExpression:exit': function ( node ) {
34
+ if ( !(
35
+ node.callee.type === 'MemberExpression' &&
36
+ methods.includes( node.callee.property.name )
37
+ ) ) {
38
+ return;
39
+ }
40
+ if ( node.arguments.every( ( arg ) => alljQueryOrEmpty( context, arg ) ) ) {
41
+ return;
42
+ }
43
+
44
+ if ( utils.isjQuery( context, node.callee ) ) {
45
+ context.report( {
46
+ node: node,
47
+ message: 'Avoid injection of possibly unescaped HTML. Create DOM elements instead, or use .text.'
48
+ } );
49
+ }
50
+ }
51
+ };
52
+ }
53
+ };
@@ -17,7 +17,7 @@ module.exports = {
17
17
 
18
18
  create: function ( context ) {
19
19
  return {
20
- CallExpression: function ( node ) {
20
+ 'CallExpression:exit': function ( node ) {
21
21
  if ( !(
22
22
  node.callee.type === 'MemberExpression' && (
23
23
  node.callee.property.name === 'hasClass' ||
@@ -13,7 +13,7 @@ module.exports = {
13
13
 
14
14
  create: function ( context ) {
15
15
  return {
16
- CallExpression: function ( node ) {
16
+ 'CallExpression:exit': function ( node ) {
17
17
  if ( node.callee.type === 'MemberExpression' ) {
18
18
  if ( !(
19
19
  node.callee.property.name === 'add' &&
@@ -28,7 +28,7 @@ module.exports = {
28
28
  }
29
29
 
30
30
  return {
31
- CallExpression: enforce,
31
+ 'CallExpression:exit': enforce,
32
32
  NewExpression: enforce
33
33
  };
34
34
  }
@@ -4,5 +4,11 @@ const utils = require( '../utils.js' );
4
4
 
5
5
  module.exports = utils.createUtilMethodRule(
6
6
  'error',
7
- 'Prefer `throw` to `$.error`'
7
+ 'Prefer `throw` to `$.error`',
8
+ {
9
+ fixable: 'code',
10
+ fix: function ( node, context, fixer ) {
11
+ return fixer.replaceText( node.callee, 'throw new Error' );
12
+ }
13
+ }
8
14
  );
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const utils = require( '../utils.js' );
4
+
5
+ module.exports = utils.createUtilMethodRule(
6
+ 'escapeSelector',
7
+ 'Prefer `CSS.escape` to `$.escapeSelector`',
8
+ {
9
+ fixable: 'code',
10
+ fix: function ( node, context, fixer ) {
11
+ return fixer.replaceText( node.callee, 'CSS.escape' );
12
+ }
13
+ }
14
+ );
@@ -3,12 +3,12 @@
3
3
  const utils = require( '../utils.js' );
4
4
 
5
5
  const ajaxEvents = [
6
- 'ajaxStart',
7
- 'ajaxStop',
8
6
  'ajaxComplete',
9
7
  'ajaxError',
10
- 'ajaxSuccess',
11
- 'ajaxSend'
8
+ 'ajaxSend',
9
+ 'ajaxStart',
10
+ 'ajaxStop',
11
+ 'ajaxSuccess'
12
12
  ];
13
13
 
14
14
  const rule = utils.createCollectionMethodRule(
@@ -72,17 +72,17 @@ const parentCreate = rule.create;
72
72
  rule.create = function ( context ) {
73
73
  const rules = parentCreate( context );
74
74
  return {
75
- CallExpression: function ( node ) {
75
+ 'CallExpression:exit': function ( node ) {
76
76
  if (
77
77
  node.callee.type === 'MemberExpression' &&
78
78
  context.options[ 0 ] && context.options[ 0 ].allowAjaxEvents
79
79
  ) {
80
80
  const name = node.callee.property.name;
81
- if ( ajaxEvents.indexOf( name ) !== -1 ) {
81
+ if ( ajaxEvents.includes( name ) ) {
82
82
  return;
83
83
  }
84
84
  }
85
- return rules.CallExpression( node );
85
+ return rules[ 'CallExpression:exit' ]( node );
86
86
  }
87
87
  };
88
88
  };
@@ -23,7 +23,7 @@ module.exports = {
23
23
 
24
24
  create: function ( context ) {
25
25
  return {
26
- CallExpression: function ( node ) {
26
+ 'CallExpression:exit': function ( node ) {
27
27
  if ( node.callee.type !== 'MemberExpression' ) {
28
28
  return;
29
29
  }
@@ -30,7 +30,7 @@ module.exports = {
30
30
 
31
31
  create: function ( context ) {
32
32
  return {
33
- CallExpression: function ( node ) {
33
+ 'CallExpression:exit': function ( node ) {
34
34
  if (
35
35
  node.callee.type !== 'Identifier' ||
36
36
  !utils.isjQueryConstructor( context, node.callee.name ) ||
@@ -4,5 +4,6 @@ const utils = require( '../utils.js' );
4
4
 
5
5
  module.exports = utils.createCollectionMethodRule(
6
6
  'html',
7
- 'Prefer `Element#innerHTML` to `.html`'
7
+ 'Prefer `Element#innerHTML` to `.html`',
8
+ { getAndSetOptions: true }
8
9
  );
@@ -7,7 +7,7 @@ module.exports = utils.createUtilMethodRule(
7
7
  'Prefer `Array.isArray` to `$.isArray`',
8
8
  {
9
9
  fixable: 'code',
10
- fix: function ( node, fixer ) {
10
+ fix: function ( node, context, fixer ) {
11
11
  return fixer.replaceText( node.callee, 'Array.isArray' );
12
12
  }
13
13
  }
@@ -7,7 +7,7 @@ module.exports = utils.createUtilMethodRule(
7
7
  'Prefer `typeof` to `$.isFunction`',
8
8
  {
9
9
  fixable: 'code',
10
- fix: function ( node, fixer ) {
10
+ fix: function ( node, context, fixer ) {
11
11
  const calleeRange = node.callee.range;
12
12
  return [
13
13
  fixer.replaceTextRange( [ calleeRange[ 0 ], calleeRange[ 1 ] + 1 ], 'typeof ' ),