From 07e0b64822da53a7a958a605ab8812eb95d17e63 Mon Sep 17 00:00:00 2001 From: Karen Holland <karen@brickfieldlabs.ie> Date: Mon, 17 Jul 2023 16:43:20 +0000 Subject: [PATCH] MDL-73974 tool_brickfield: Processing alpha fontsizes --- .../brickfield_accessibility_color_test.php | 47 +++++++- .../common/checks/css_text_has_contrast.php | 3 +- .../checks/css_text_has_contrast_test.php | 112 ++++++++++++++++++ 3 files changed, 159 insertions(+), 3 deletions(-) diff --git a/admin/tool/brickfield/classes/local/htmlchecker/common/brickfield_accessibility_color_test.php b/admin/tool/brickfield/classes/local/htmlchecker/common/brickfield_accessibility_color_test.php index fb12c17f962..a392d1106e4 100644 --- a/admin/tool/brickfield/classes/local/htmlchecker/common/brickfield_accessibility_color_test.php +++ b/admin/tool/brickfield/classes/local/htmlchecker/common/brickfield_accessibility_color_test.php @@ -170,6 +170,19 @@ class brickfield_accessibility_color_test extends brickfield_accessibility_test 'yellowgreen' => '9acd32' ]; + /** @var string[] Define estimated relative font-size codes to pt values. */ + public $fontsizenames = [ + 'xx-small' => 9, + 'x-small' => 10, + 'small' => 11, + 'smaller' => 11, + 'medium' => 12, + 'large' => 14, + 'larger' => 14, + 'x-large' => 18, + 'xx-large' => 24, + ]; + /** * Helper method that finds the luminosity between the provided * foreground and background parameters. @@ -227,7 +240,8 @@ class brickfield_accessibility_color_test extends brickfield_accessibility_test $l2 = (.2126 * $r4 + 0.7152 * $g4 + 0.0722 * $b4); } - $luminosity = round(($l1 + 0.05) / ($l2 + 0.05), 2); + // Increase round to 4 to avoid a 4.49 contrast being round up to a false pass of 4.5. + $luminosity = round(($l1 + 0.05) / ($l2 + 0.05), 4); return $luminosity; } @@ -362,4 +376,35 @@ class brickfield_accessibility_color_test extends brickfield_accessibility_test : $backrgb['b'] - $forergb['b']; return ['red' => $reddiff, 'green' => $greendiff, 'blue' => $bluediff]; } + + /** + * Helper method that finds the estimated font-size for the provided + * string font-size parameter. + * @param string $fontsize The css font-size, in various formats + * @return int The estimated font-size + */ + public function get_fontsize(string $fontsize): int { + $newfontsize = 12; // Default value, in pt, equivalent to 16px. + + // Search for rem, em, and px initially, typical font-size values. + $pos1 = stripos($fontsize, 'rem'); + $pos2 = stripos($fontsize, 'em'); + $pos3 = stripos($fontsize, 'px'); + if ($pos1 !== false) { + $rem = substr($fontsize, 0, -3); + $newfontsize = $newfontsize * $rem; + } else if ($pos2 !== false) { + $em = substr($fontsize, 0, -2); + $newfontsize = $newfontsize * $em; + } else if ($pos3 !== false) { + $px = substr($fontsize, 0, -2); + $newfontsize = 0.75 * $px; + } else if (in_array($fontsize, array_keys($this->fontsizenames))) { + $newfontsize = $this->fontsizenames[$fontsize]; + } else { + preg_match_all('!\d+!', $fontsize, $matches); + $newfontsize = $matches[0][0] ?? $newfontsize; + } + return (int) $newfontsize; + } } diff --git a/admin/tool/brickfield/classes/local/htmlchecker/common/checks/css_text_has_contrast.php b/admin/tool/brickfield/classes/local/htmlchecker/common/checks/css_text_has_contrast.php index 1ae273c3180..76be8c8ca4f 100644 --- a/admin/tool/brickfield/classes/local/htmlchecker/common/checks/css_text_has_contrast.php +++ b/admin/tool/brickfield/classes/local/htmlchecker/common/checks/css_text_has_contrast.php @@ -92,8 +92,7 @@ class css_text_has_contrast extends brickfield_accessibility_color_test { $italic = false; if (isset($style['font-size'])) { - preg_match_all('!\d+!', $style['font-size'], $matches); - $fontsize = $matches[0][0]; + $fontsize = $this->get_fontsize($style['font-size']); } if (isset($style['font-weight'])) { diff --git a/admin/tool/brickfield/tests/local/htmlchecker/common/checks/css_text_has_contrast_test.php b/admin/tool/brickfield/tests/local/htmlchecker/common/checks/css_text_has_contrast_test.php index ddc6763a054..f19f09bb147 100644 --- a/admin/tool/brickfield/tests/local/htmlchecker/common/checks/css_text_has_contrast_test.php +++ b/admin/tool/brickfield/tests/local/htmlchecker/common/checks/css_text_has_contrast_test.php @@ -178,6 +178,54 @@ EOD; </html> EOD; + /** @var string HTML with px18 fail colour values. */ + private $px18 = <<<EOD + <body><p style="color:#EF0000; background-color:white; font-size: 18px"> + This is not contrasty enough.</p></body> +EOD; + + /** @var string HTML with px19bold pass colour values. */ + private $px19bold = <<<EOD + <body><p style="color:#EF0000; background-color:white; font-size: 19px; font-weight: bold;"> + This is contrasty enough.</p></body> +EOD; + + /** @var string HTML with px18 pass colour values. */ + private $px18pass = <<<EOD + <body><p style="color:#E60000; background-color:white; font-size: 18px"> + This is contrasty enough.</p></body> +EOD; + + /** @var string HTML with medium size colour values. */ + private $mediumfail = <<<EOD + <body><p style="color:#EF0000; background-color:white; font-size: medium"> + This is not contrasty enough.</p></body> +EOD; + + /** @var string HTML with px18 colour values. */ + private $mediumpass = <<<EOD + <body><p style="color:#E60000; background-color:white; font-size: medium"> + This is contrasty enough.</p></body> +EOD; + + /** @var string HTML with larger fail colour values. */ + private $largerfail = <<<EOD + <body><p style="color:#FF6161; background-color:white; font-size: larger"> + This is not contrasty enough.</p></body> +EOD; + + /** @var string HTML with px18 colour values. */ + private $largerpass = <<<EOD + <body><p style="color:#FF5C5C; background-color:white; font-size: larger;"> + This is contrasty enough.</p></body> +EOD; + + /** @var string HTML with px18 colour values. */ + private $largerboldpass = <<<EOD + <body><p style="color:#FF5C5C; background-color:white; font-size: larger; font-weight: bold;"> + This is contrasty enough.</p></body> +EOD; + /** * Test for the area assign intro */ @@ -235,4 +283,68 @@ EOD; $results = $this->get_checker_results($this->emptyvalue); $this->assertEmpty($results); } + + /** + * Test for text px18 with insufficient contrast of 4.49. + */ + public function test_check_for_px18_fail() { + $results = $this->get_checker_results($this->px18); + $this->assertTrue($results[0]->element->tagName == 'p'); + } + + /** + * Test for text px19 bold with sufficient contrast of 4.49. + */ + public function test_check_for_px19bold_pass() { + $results = $this->get_checker_results($this->px19bold); + $this->assertEmpty($results); + } + + /** + * Test for text px18 with sufficient contrast of 4.81. + */ + public function test_check_for_px18_pass() { + $results = $this->get_checker_results($this->px18pass); + $this->assertEmpty($results); + } + + /** + * Test for medium (12pt) text with insufficient contrast of 4.49. + */ + public function test_check_for_medium_fail() { + $results = $this->get_checker_results($this->mediumfail); + $this->assertTrue($results[0]->element->tagName == 'p'); + } + + /** + * Test for medium (12pt) text with sufficient contrast of 4.81. + */ + public function test_check_for_medium_pass() { + $results = $this->get_checker_results($this->mediumpass); + $this->assertEmpty($results); + } + + /** + * Test for larger (14pt) text with insufficient contrast of 2.94. + */ + public function test_check_for_larger_fail() { + $results = $this->get_checker_results($this->largerfail); + $this->assertTrue($results[0]->element->tagName == 'p'); + } + + /** + * Test for larger (14pt) text with insufficient contrast of 3.02. + */ + public function test_check_for_larger_pass() { + $results = $this->get_checker_results($this->largerpass); + $this->assertTrue($results[0]->element->tagName == 'p'); + } + + /** + * Test for larger (14pt) bold text with sufficient contrast of 3.02. + */ + public function test_check_for_largerbold_pass() { + $results = $this->get_checker_results($this->largerboldpass); + $this->assertEmpty($results); + } }