-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSkipLinkRule.php
More file actions
55 lines (43 loc) · 1.46 KB
/
SkipLinkRule.php
File metadata and controls
55 lines (43 loc) · 1.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
declare(strict_types=1);
namespace TwigA11y\Rules\Structure;
use TwigA11y\Rules\AbstractA11yRule;
use TwigA11y\Template\TemplateKind;
use TwigCsFixer\Token\Token;
use TwigCsFixer\Token\Tokens;
final class SkipLinkRule extends AbstractA11yRule
{
public function evaluate(Tokens $tokens, int $tokenIndex, callable $emit): void
{
$token = $tokens->get($tokenIndex);
if (!$token->isMatching(Token::TEXT_TYPE)) {
return;
}
// Only perform the page-level checks once per file; AbstractA11yRule
// will enforce the evaluateOncePerFile behaviour if needed. Here we
// simply run the detection logic and emit on the current token.
$content = $this->getFullContent($tokens);
if (!str_contains($content, '<body') && !str_contains(strtoupper($content), '<!DOCTYPE')) {
return;
}
if (preg_match('/href\s*=\s*["\']#([^"\']+)["\'][^>]*>.*?skip/i', $content)) {
return;
}
if (preg_match('/href\s*=\s*["\']#(main|content)["\'][^>]*>/i', $content)) {
return;
}
$first = $tokens->get(0);
$emit('Page should include a skip link to bypass navigation', $first, 'SkipLink.Missing');
}
/**
* @return TemplateKind[]
*/
protected function supportedKinds(): array
{
return [TemplateKind::FullPage];
}
protected function evaluateOncePerFile(): bool
{
return true;
}
}