-
Notifications
You must be signed in to change notification settings - Fork 235
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rule): no distracting elements should be used (#760)
- Loading branch information
1 parent
fdcb07a
commit 6b21a9e
Showing
3 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { ElementAst } from '@angular/compiler'; | ||
import { sprintf } from 'sprintf-js'; | ||
import { IRuleMetadata, RuleFailure, Rules } from 'tslint/lib'; | ||
import { SourceFile } from 'typescript/lib/typescript'; | ||
import { NgWalker } from './angular/ngWalker'; | ||
import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor'; | ||
|
||
export class Rule extends Rules.AbstractRule { | ||
static readonly metadata: IRuleMetadata = { | ||
description: 'Enforces that no distracting elements are used', | ||
options: null, | ||
optionsDescription: 'Not configurable.', | ||
rationale: 'Elements that can be visually distracting can cause accessibility issues with visually impaired users.', | ||
ruleName: 'template-no-distracting-elements', | ||
type: 'functionality', | ||
typescriptOnly: true | ||
}; | ||
|
||
static readonly FAILURE_STRING = 'Avoid using <%s/> elements as they create visual accessibility issues.'; | ||
|
||
apply(sourceFile: SourceFile): RuleFailure[] { | ||
return this.applyWithWalker( | ||
new NgWalker(sourceFile, this.getOptions(), { | ||
templateVisitorCtrl: TemplateNoDistractingElementsVisitor | ||
}) | ||
); | ||
} | ||
} | ||
|
||
export function getFailureMessage(element: string) { | ||
return sprintf(Rule.FAILURE_STRING, element); | ||
} | ||
|
||
class TemplateNoDistractingElementsVisitor extends BasicTemplateAstVisitor { | ||
visitElement(prop: ElementAst, context: any): any { | ||
this.validateElement(prop); | ||
super.visitElement(prop, context); | ||
} | ||
|
||
private validateElement(el: ElementAst): void { | ||
if (el.name === 'marquee' || el.name === 'blink') { | ||
const { | ||
sourceSpan: { | ||
end: { offset: endOffset }, | ||
start: { offset: startOffset } | ||
} | ||
} = el; | ||
this.addFailureFromStartToEnd(startOffset, endOffset, getFailureMessage(el.name)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { getFailureMessage, Rule } from '../src/templateNoDistractingElementsRule'; | ||
import { assertAnnotated, assertSuccess } from './testHelper'; | ||
|
||
const { | ||
metadata: { ruleName } | ||
} = Rule; | ||
|
||
describe(ruleName, () => { | ||
describe('failure', () => { | ||
it('should fail when distracting element marquee is used', () => { | ||
const source = ` | ||
@Component({ | ||
template: \` | ||
<marquee></marquee> | ||
~~~~~~~~~ | ||
\` | ||
}) | ||
class Bar {} | ||
`; | ||
assertAnnotated({ | ||
message: getFailureMessage('marquee'), | ||
ruleName, | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when distracting element blink is used', () => { | ||
const source = ` | ||
@Component({ | ||
template: \` | ||
<blink></blink> | ||
~~~~~~~ | ||
\` | ||
}) | ||
class Bar {} | ||
`; | ||
assertAnnotated({ | ||
message: getFailureMessage('blink'), | ||
ruleName, | ||
source | ||
}); | ||
}); | ||
}); | ||
|
||
describe('success', () => { | ||
it('should work when distracting element is not used', () => { | ||
const source = ` | ||
@Component({ | ||
template: \` | ||
<div>Valid</div> | ||
\` | ||
}) | ||
class Bar {} | ||
`; | ||
assertSuccess(ruleName, source); | ||
}); | ||
}); | ||
}); |