diff --git a/docs/rule/no-meta-redirect-with-time-limit.md b/docs/rule/no-meta-redirect-with-time-limit.md new file mode 100644 index 000000000..919336e94 --- /dev/null +++ b/docs/rule/no-meta-redirect-with-time-limit.md @@ -0,0 +1,30 @@ +## (no-meta-redirect-with-time-limit) + +Sometimes a page automatically redirects to a different page. When this happens after a timed delay, it is an unexpected change of context that may interrupt the user. Redirects without timed delays are okay, but pleasae consider a server-side method for redirecting instead (method will vary based on your server type). + +This rule checks for the meta tag with a redirect; if it exists, it checks for a timed delay greater than 0. + +### Examples + +This rule **forbids** the following: + +```hbs + +``` + +This rule **allows** the following: + +```hbs + +``` + +### Migration + +* To fix, reduce the timed delay to zero, or use the appropriate server-side redirect method for your server type. + +### References + +* [F40: Failure due to using meta redirect with a time limit](https://www.w3.org/WAI/WCAG21/Techniques/failures/F40) +* [Success Criterion 2.2.1: Timing Adjustable](https://www.w3.org/WAI/WCAG21/Understanding/timing-adjustable) +* [Success Criterion 2.2.4: Interruptions](https://www.w3.org/WAI/WCAG21/Understanding/interruptions) +* [Success Criterion 3.2.5: Change on Request](https://www.w3.org/WAI/WCAG21/Understanding/change-on-request) diff --git a/docs/rules.md b/docs/rules.md index c3c74aeae..4e67fc312 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -26,6 +26,7 @@ * [no-input-tagname](rule/no-input-tagname.md) * [no-invalid-interactive](rule/no-invalid-interactive.md) * [no-log](rule/no-log.md) +* [no-meta-redirect-with-time-limit](rule/no-meta-redirect-with-time-limit.md) * [no-negated-condition](rule/no-negated-condition.md) * [no-nested-interactive](rule/no-nested-interactive.md) * [no-obsolete-elements](rule/no-obsolete-elements.md) diff --git a/lib/rules/index.js b/lib/rules/index.js index a0f6269a5..77b1c51ae 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -30,6 +30,7 @@ module.exports = { 'no-input-tagname': require('./lint-no-input-tagname'), 'no-invalid-interactive': require('./lint-no-invalid-interactive'), 'no-log': require('./lint-no-log'), + 'no-meta-redirect-with-time-limit': require('./lint-no-meta-redirect-with-time-limit'), 'no-negated-condition': require('./lint-no-negated-condition'), 'no-nested-interactive': require('./lint-no-nested-interactive'), 'no-obsolete-elements': require('./lint-no-obsolete-elements'), diff --git a/lib/rules/lint-no-meta-redirect-with-time-limit.js b/lib/rules/lint-no-meta-redirect-with-time-limit.js new file mode 100644 index 000000000..19125e873 --- /dev/null +++ b/lib/rules/lint-no-meta-redirect-with-time-limit.js @@ -0,0 +1,39 @@ +'use strict'; + +const AstNodeInfo = require('../helpers/ast-node-info'); +const Rule = require('./base'); + +module.exports = class NoMetaRedirectWithTimeLimit extends Rule { + logNode({ node, message }) { + return this.log({ + message, + line: node.loc && node.loc.start.line, + column: node.loc && node.loc.start.column, + source: this.sourceForNode(node), + }); + } + visitor() { + return { + ElementNode(node) { + const isMeta = node.tag === 'meta'; + const hasMetaRedirect = AstNodeInfo.hasAttribute(node, 'http-equiv'); + + if (isMeta && hasMetaRedirect) { + const contentAttr = AstNodeInfo.hasAttribute(node, 'content'); + const contentAttrValue = AstNodeInfo.elementAttributeValue(node, 'content'); + if (contentAttr) { + // since the content attribute will have both the delay (in seconds) and the new URL, we only need to check the first character in the value string. + if (contentAttrValue.charAt(0) !== '0') { + this.log({ + message: 'a meta redirect should not have a delay value greater than zero', + line: node.loc && node.loc.start.line, + column: node.loc && node.loc.start.column, + source: this.sourceForNode(node), + }); + } + } + } + }, + }; + } +}; diff --git a/test/unit/rules/lint-no-meta-redirect-with-time-limit-test.js b/test/unit/rules/lint-no-meta-redirect-with-time-limit-test.js new file mode 100644 index 000000000..d7d67f0a1 --- /dev/null +++ b/test/unit/rules/lint-no-meta-redirect-with-time-limit-test.js @@ -0,0 +1,25 @@ +'use strict'; + +const generateRuleTests = require('../../helpers/rule-test-harness'); + +generateRuleTests({ + name: 'no-meta-redirect-with-time-limit', + + config: true, + + good: [''], + + bad: [ + { + template: '', + + result: { + moduleId: 'layout.hbs', + message: 'a meta redirect should not have a delay value greater than zero', + line: 1, + column: 0, + source: '', + }, + }, + ], +});