Skip to content

Commit 2fe98b4

Browse files
committed
Create no-jquery-selector rule
1 parent 991d904 commit 2fe98b4

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

guides/rules/no-jquery-selector.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# No jQuery Selector
2+
3+
**TL;DR** The intent of this rule is to identify using jQuery to select DOM elements as deprecated.
4+
5+
# Examples
6+
7+
```js
8+
// Deprecated
9+
export default Ember.Component({
10+
getElement(selector) {
11+
return this.$(selector);
12+
},
13+
14+
click() {
15+
this.$().focus();
16+
}
17+
});
18+
19+
// Vanilla JS
20+
export default Ember.Component({
21+
getElement(selector) {
22+
return this.element.querySelector(selector);
23+
},
24+
25+
click() {
26+
this.element.focus();
27+
}
28+
});
29+
```

lib/rules/no-jquery-selector.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @fileOverview Disallow the use of jQuery selector.
3+
*/
4+
'use strict';
5+
6+
const { get } = require('../utils/get');
7+
const componentElementMessage = 'The use of this.$() to get a component\'s element is deprecated. Use \'this.element\' instead';
8+
9+
function getSelectorMessage(selector) {
10+
return `The use of $(${selector}) to select an element is deprecated.`;
11+
}
12+
13+
module.exports = {
14+
docs: {
15+
category: 'Best Practices',
16+
recommended: true
17+
},
18+
meta: {
19+
componentElementMessage,
20+
getSelectorMessage
21+
},
22+
create(context) {
23+
return {
24+
CallExpression(node) {
25+
const calleeName = get(node, 'callee.property.name');
26+
const problemNode = node.callee;
27+
const firstNodeArg = node.arguments && node.arguments[0];
28+
29+
if (calleeName === '$') {
30+
let message;
31+
if (firstNodeArg) {
32+
// Get the arg's value if it's a string or name if it's a variable.
33+
const argName = firstNodeArg.value || firstNodeArg.name;
34+
message = getSelectorMessage(argName);
35+
} else {
36+
message = componentElementMessage;
37+
}
38+
context.report({ node: problemNode, message });
39+
}
40+
}
41+
};
42+
}
43+
};

tests/lib/rules/no-jquery-selector.js

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
const rule = require('../../../lib/rules/no-jquery-selector');
2+
const RuleTester = require('eslint').RuleTester;
3+
const {
4+
componentElementMessage,
5+
getSelectorMessage
6+
} = rule.meta;
7+
const TEST_CLASS = '.some-class';
8+
const ruleTester = new RuleTester({
9+
parserOptions: {
10+
ecmaVersion: 6,
11+
sourceType: 'module'
12+
}
13+
});
14+
15+
ruleTester.run('no-jquery-selector', rule, {
16+
valid: [
17+
{
18+
code: `
19+
export default Ember.Component({
20+
init() {
21+
Ember.$.ajax();
22+
}
23+
});`
24+
},
25+
{
26+
code: `
27+
export default Ember.Component({
28+
init() {
29+
this.$.ajax();
30+
}
31+
});`
32+
},
33+
{
34+
code: `
35+
export default Ember.Component({
36+
myFunc() {
37+
return \`\${someProp}\`;
38+
}
39+
});`
40+
}
41+
],
42+
invalid: [
43+
{
44+
code: `
45+
export default Ember.Component({
46+
init() {
47+
Ember.$('.some-class');
48+
}
49+
});`,
50+
errors: [
51+
{ message: getSelectorMessage(TEST_CLASS) }
52+
]
53+
},
54+
{
55+
code: `
56+
export default Ember.Component({
57+
init() {
58+
this.$('.some-class');
59+
}
60+
});`,
61+
errors: [
62+
{ message: getSelectorMessage(TEST_CLASS) }
63+
]
64+
},
65+
{
66+
code: `
67+
export default Ember.Component({
68+
myFunc(selector) {
69+
Ember.$(selector);
70+
}
71+
});`,
72+
errors: [
73+
{ message: getSelectorMessage('selector') }
74+
]
75+
},
76+
{
77+
code: `
78+
export default Ember.Component({
79+
myFunc(selector) {
80+
this.$(selector);
81+
}
82+
});`,
83+
errors: [
84+
{ message: getSelectorMessage('selector') }
85+
]
86+
},
87+
{
88+
code: `
89+
export default Ember.Component({
90+
init() {
91+
this.$();
92+
}
93+
});`,
94+
errors: [{
95+
message: componentElementMessage
96+
}]
97+
},
98+
{
99+
code: `
100+
export default Ember.Component({
101+
init() {
102+
this.$().focus();
103+
}
104+
});`,
105+
errors: [{
106+
message: componentElementMessage
107+
}]
108+
},
109+
{
110+
code: `
111+
export default Ember.Component({
112+
init() {
113+
Ember.$('.some-class').focus();
114+
}
115+
});`,
116+
errors: [{
117+
message: getSelectorMessage(TEST_CLASS)
118+
}]
119+
},
120+
{
121+
code: `
122+
export default Ember.Component({
123+
myFunc() {
124+
const myVar = '.some-class';
125+
this.$(myVar);
126+
}
127+
});`,
128+
errors: [{
129+
message: getSelectorMessage('myVar')
130+
}]
131+
},
132+
{
133+
code: `
134+
export default Ember.Component({
135+
myFunc() {
136+
const myVar = '.some-class';
137+
Ember.$(myVar);
138+
}
139+
});`,
140+
errors: [{
141+
message: getSelectorMessage('myVar')
142+
}]
143+
}
144+
]
145+
});

0 commit comments

Comments
 (0)