Skip to content

Commit 90b7967

Browse files
committed
Extract rule: template-no-whitespace-for-layout
1 parent 9801f32 commit 90b7967

4 files changed

Lines changed: 244 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ rules in templates can be disabled with eslint directives with mustache or html
255255
| [template-no-obsolete-elements](docs/rules/template-no-obsolete-elements.md) | disallow obsolete HTML elements | | | |
256256
| [template-no-outlet-outside-routes](docs/rules/template-no-outlet-outside-routes.md) | disallow {{outlet}} outside of route templates | | | |
257257
| [template-no-page-title-component](docs/rules/template-no-page-title-component.md) | disallow usage of ember-page-title component | | | |
258+
| [template-no-whitespace-for-layout](docs/rules/template-no-whitespace-for-layout.md) | disallow using whitespace for layout purposes | | | |
258259
| [template-no-yield-block-params-to-else-inverse](docs/rules/template-no-yield-block-params-to-else-inverse.md) | disallow yielding block params to else or inverse block | | | |
259260
| [template-no-yield-only](docs/rules/template-no-yield-only.md) | disallow components that only yield | | | |
260261
| [template-no-yield-to-default](docs/rules/template-no-yield-to-default.md) | disallow yield to default block | | | |
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# ember/template-no-whitespace-for-layout
2+
3+
<!-- end auto-generated rule header -->
4+
5+
Disallow using multiple consecutive spaces for layout purposes in templates. CSS should be used for spacing and layout instead.
6+
7+
## Rule Details
8+
9+
This rule discourages the use of multiple consecutive spaces (2 or more) for layout purposes in templates. CSS should be used for spacing and layout instead.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<div>Hello World</div>
18+
</template>
19+
```
20+
21+
```gjs
22+
<template>
23+
<div>Text with spaces</div>
24+
</template>
25+
```
26+
27+
```gjs
28+
<template>
29+
<div>Multiple spaces</div>
30+
</template>
31+
```
32+
33+
Examples of **correct** code for this rule:
34+
35+
```gjs
36+
<template>
37+
<div>Hello World</div>
38+
</template>
39+
```
40+
41+
```gjs
42+
<template>
43+
<div class="spaced-layout">Text with proper spacing</div>
44+
</template>
45+
```
46+
47+
## Migration
48+
49+
To fix issues caused by using whitespace for layout, the following are recommended:
50+
51+
- use the appropriate HTML markup to contain the information
52+
- use CSS to add padding or margins to the semantic HTML markup
53+
54+
## References
55+
56+
- [eslint-plugin-ember template-no-whitespace-for-layout](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/template-no-whitespace-for-layout.md)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'suggestion',
5+
docs: {
6+
description: 'disallow using whitespace for layout purposes',
7+
category: 'Best Practices',
8+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-whitespace-for-layout.md',
9+
templateMode: 'both',
10+
},
11+
schema: [],
12+
messages: {
13+
noWhitespaceForLayout:
14+
'Unexpected use of whitespace for layout. Use CSS for spacing instead of multiple spaces.',
15+
},
16+
originallyFrom: {
17+
name: 'ember-template-lint',
18+
rule: 'lib/rules/no-whitespace-for-layout.js',
19+
docs: 'docs/rule/no-whitespace-for-layout.md',
20+
tests: 'test/unit/rules/no-whitespace-for-layout-test.js',
21+
},
22+
},
23+
24+
create(context) {
25+
const sourceCode = context.getSourceCode();
26+
27+
return {
28+
GlimmerTextNode(node) {
29+
const text = sourceCode.getText(node);
30+
if (!text) {
31+
return;
32+
}
33+
34+
const lines = text.split('\n');
35+
for (const line of lines) {
36+
// Ignore whitespace at the start and end of the line
37+
const trimmed = line.trim();
38+
39+
// Check for two consecutive ` ` or `&nbsp;` in a row
40+
if (/(( )|(&nbsp;))(( )|(&nbsp;))/.test(trimmed)) {
41+
context.report({
42+
node,
43+
messageId: 'noWhitespaceForLayout',
44+
});
45+
return;
46+
}
47+
}
48+
},
49+
};
50+
},
51+
};
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
//------------------------------------------------------------------------------
2+
// Requirements
3+
//------------------------------------------------------------------------------
4+
5+
const rule = require('../../../lib/rules/template-no-whitespace-for-layout');
6+
const RuleTester = require('eslint').RuleTester;
7+
8+
const ruleTester = new RuleTester({
9+
parser: require.resolve('ember-eslint-parser'),
10+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
11+
});
12+
13+
ruleTester.run('template-no-whitespace-for-layout', rule, {
14+
valid: [
15+
'<template><div>Hello World</div></template>',
16+
'<template><div>Text</div></template>',
17+
18+
'<template>Start to finish</template>',
19+
'<template>Start&nbsp;to&nbsp;finish</template>',
20+
'<template>Start<br>to<br>finish</template>',
21+
`<template><div>
22+
example
23+
</div></template>`,
24+
`<template><div
25+
foo="bar"
26+
baz="qux"
27+
>
28+
example
29+
</div></template>`,
30+
],
31+
invalid: [
32+
{
33+
code: '<template><div>Hello World</div></template>',
34+
output: null,
35+
errors: [{ messageId: 'noWhitespaceForLayout' }],
36+
},
37+
{
38+
code: '<template><div>Text with spaces</div></template>',
39+
output: null,
40+
errors: [{ messageId: 'noWhitespaceForLayout' }],
41+
},
42+
{
43+
code: '<template><div>Multiple spaces</div></template>',
44+
output: null,
45+
errors: [{ messageId: 'noWhitespaceForLayout' }],
46+
},
47+
48+
{
49+
code: '<template>START FINISH</template>',
50+
output: null,
51+
errors: [{ messageId: 'noWhitespaceForLayout' }],
52+
},
53+
{
54+
code: '<template>START&nbsp;&nbsp;FINISH</template>',
55+
output: null,
56+
errors: [{ messageId: 'noWhitespaceForLayout' }],
57+
},
58+
{
59+
code: '<template>START&nbsp; FINISH</template>',
60+
output: null,
61+
errors: [{ messageId: 'noWhitespaceForLayout' }],
62+
},
63+
{
64+
code: '<template>START &nbsp;FINISH</template>',
65+
output: null,
66+
errors: [{ messageId: 'noWhitespaceForLayout' }],
67+
},
68+
],
69+
});
70+
71+
const hbsRuleTester = new RuleTester({
72+
parser: require.resolve('ember-eslint-parser/hbs'),
73+
parserOptions: {
74+
ecmaVersion: 2022,
75+
sourceType: 'module',
76+
},
77+
});
78+
79+
hbsRuleTester.run('template-no-whitespace-for-layout', rule, {
80+
valid: [
81+
'Start to finish',
82+
'Start&nbsp;to&nbsp;finish',
83+
'Start<br>to<br>finish',
84+
`<div>
85+
example
86+
</div>`,
87+
`<div
88+
foo="bar"
89+
baz="qux"
90+
>
91+
example
92+
</div>`,
93+
],
94+
invalid: [
95+
{
96+
code: 'START FINISH',
97+
output: null,
98+
errors: [
99+
{
100+
message:
101+
'Unexpected use of whitespace for layout. Use CSS for spacing instead of multiple spaces.',
102+
},
103+
],
104+
},
105+
{
106+
code: 'START&nbsp;&nbsp;FINISH',
107+
output: null,
108+
errors: [
109+
{
110+
message:
111+
'Unexpected use of whitespace for layout. Use CSS for spacing instead of multiple spaces.',
112+
},
113+
],
114+
},
115+
{
116+
code: 'START&nbsp; FINISH',
117+
output: null,
118+
errors: [
119+
{
120+
message:
121+
'Unexpected use of whitespace for layout. Use CSS for spacing instead of multiple spaces.',
122+
},
123+
],
124+
},
125+
{
126+
code: 'START &nbsp;FINISH',
127+
output: null,
128+
errors: [
129+
{
130+
message:
131+
'Unexpected use of whitespace for layout. Use CSS for spacing instead of multiple spaces.',
132+
},
133+
],
134+
},
135+
],
136+
});

0 commit comments

Comments
 (0)