Skip to content

Commit

Permalink
Added no-whitespace-for-layout rule (ember-template-lint#819)
Browse files Browse the repository at this point in the history
  • Loading branch information
MelSumner authored and rwjblue committed Oct 31, 2019
1 parent a25a308 commit 5fff1df
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
38 changes: 38 additions & 0 deletions docs/rule/no-whitespace-for-layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# no-whitespace-for-layout

Formatting of text through the use of multiple whitespace is entirely visual, and therefore is incompatible with screen-reading assistive technology tools.

The rule applies to the content of Handlebars AST TextNodes, and performs a RegExp search for two consecutive white space characters that might indicate the use of whitespace used for layout.

## Examples

This rule **forbids** the following:

```hbs
``Mon. ``&nbsp;&nbsp;&nbsp;&nbsp;``Eggs ``&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Tomato soup``&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``House salad``<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Bacon``&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Hamburger``&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Fried chicken``<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Toast``&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Onion rings``&nbsp;&nbsp;&nbsp;&nbsp;``Green beans``<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Cookie``&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;``Mashed potatoes``
```

This rule **allows** the following:

```hbs
<p>Start to finish</p>
```

```hbs
<p>Start&nbsp;to&nbsp;Finish</p>
```

## Migration

To fix issues caused by using whitespace for layout, the following are recommended:

* use the appropriate HTML markup to contain the information
* use CSS to add padding or margins to the semantic HTML markup

## References

* [F33: Using white space characters to create multiple columns in plain text content](https://www.w3.org/TR/WCAG20-TECHS/failures.html#F33)
* [F34: Using white space characters to format tables in plain text content](https://www.w3.org/TR/WCAG20-TECHS/failures.html#F34)
1 change: 1 addition & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* [no-unnecessary-component-helper](rule/no-unnecessary-component-helper.md)
* [no-unnecessary-concat](rule/no-unnecessary-concat.md)
* [no-unused-block-params](rule/no-unused-block-params.md)
* [no-whitespace-for-layout](rule/no-whitespace-for-layout.md)
* [quotes](rule/quotes.md)
* [require-iframe-title](rule/require-iframe-title.md)
* [require-valid-alt-text](rule/require-valid-alt-text.md)
Expand Down
1 change: 1 addition & 0 deletions lib/rules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ module.exports = {
'no-unnecessary-component-helper': require('./lint-no-unnecessary-component-helper'),
'no-unnecessary-concat': require('./lint-no-unnecessary-concat'),
'no-unused-block-params': require('./lint-no-unused-block-params'),
'no-whitespace-for-layout': require('./lint-no-whitespace-for-layout'),
quotes: require('./lint-quotes'),
'require-iframe-title': require('./lint-require-iframe-title'),
'require-valid-alt-text': require('./lint-require-valid-alt-text'),
Expand Down
26 changes: 26 additions & 0 deletions lib/rules/lint-no-whitespace-for-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';
const Rule = require('./base');

const ERROR_MESSAGE = 'Excess whitespace detected.';

module.exports = class NoWhitespaceForLayout extends Rule {
visitor() {
return {
TextNode(node) {
let source = this.sourceForNode(node);
// check for two ` ` or `&nbsp;` in a row
let matches = source.match(/(( )|(&nbsp;))(( )|(&nbsp;))/g);
if (matches !== null) {
this.log({
message: ERROR_MESSAGE,
line: node.loc && node.loc.start.line,
column: node.loc && node.loc.start.column,
source: this.sourceForNode(node),
});
}
},
};
}
};

module.exports.ERROR_MESSAGE = ERROR_MESSAGE;
57 changes: 57 additions & 0 deletions test/unit/rules/lint-no-whitespace-for-layout-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// no-whitespace-for-layout-test.js

'use strict';

const generateRuleTests = require('../../helpers/rule-test-harness');
const ERROR_MESSAGE = require('../../../lib/rules/lint-no-whitespace-for-layout').ERROR_MESSAGE;

generateRuleTests({
name: 'no-whitespace-for-layout',
config: true,

good: ['Start to finish', 'Start&nbsp;to&nbsp;finish', 'Start<br>to<br>finish'],

bad: [
{
template: 'START FINISH',

result: {
moduleId: 'layout.hbs',
message: ERROR_MESSAGE,
line: 1,
column: 0,
source: 'START FINISH',
},
},
{
template: 'START&nbsp;&nbsp;FINISH',
result: {
moduleId: 'layout.hbs',
message: ERROR_MESSAGE,
line: 1,
column: 0,
source: 'START&nbsp;&nbsp;FINISH',
},
},
{
template: 'START&nbsp; FINISH',
result: {
moduleId: 'layout.hbs',
message: ERROR_MESSAGE,
line: 1,
column: 0,
source: 'START&nbsp; FINISH',
},
},
{
template: 'START &nbsp;FINISH',
result: {
moduleId: 'layout.hbs',
message: ERROR_MESSAGE,
line: 1,
column: 0,
source: 'START &nbsp;FINISH',
},
},
],
});

0 comments on commit 5fff1df

Please sign in to comment.