*/ public function validate(Theme $theme): array { $issues = []; foreach ($this->files->allFiles($theme->path().'/views') as $file) { $content = $file->getContents(); $relative = $file->getRelativePathname(); $missingAlt = 0; if (preg_match_all('/])*>/is', $content, $images)) { foreach ($images[0] as $image) { if (! preg_match('/\\balt\\s*=\\s*(?:"[^"]*"|\'[^\']*\')/is', $image)) { $missingAlt++; } } } if ($missingAlt > 0) { $issues[] = [ 'severity' => 'error', 'message' => $missingAlt.' image(s) missing alt text.', 'file' => $relative, ]; } if (preg_match('/]*\\blang=)/i', $content)) { $issues[] = [ 'severity' => 'warning', 'message' => 'HTML element is missing a lang attribute.', 'file' => $relative, ]; } $unnamedButtons = 0; if (preg_match_all('/])*)>(.*?)<\\/button>/is', $content, $buttons, PREG_SET_ORDER)) { foreach ($buttons as $button) { $attributes = $button[1]; $body = $button[2]; $hasAccessibleAttribute = preg_match('/\\b(?:aria-label|aria-labelledby|title)\\s*=\\s*(?:"[^"]+"|\'[^\']+\')/is', $attributes) === 1; $visibleText = trim(html_entity_decode(strip_tags($body), ENT_QUOTES | ENT_HTML5)); if (! $hasAccessibleAttribute && $visibleText === '') { $unnamedButtons++; } } } if ($unnamedButtons > 0) { $issues[] = [ 'severity' => 'warning', 'message' => $unnamedButtons.' button(s) may lack an accessible name.', 'file' => $relative, ]; } } return $issues; } }