Skip to content

Commit

Permalink
MDL-78785 tool_brickfield: Processing rgb color contrasts
Browse files Browse the repository at this point in the history
  • Loading branch information
learningtechnologyservices committed Jul 21, 2023
1 parent 272fdb3 commit 337a9bd
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -227,7 +240,8 @@ public function luminosity(string $r, string $r2, string $g, string $g2, string
$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;
}

Expand All @@ -254,13 +268,21 @@ public function get_rgb(string $color): ?array {
*/
public function convert_color(string $color): string {
$color = trim($color);
if (strpos($color, ' ') !== false) {
$colors = explode(' ', $color);
foreach ($colors as $backgroundpart) {
if (substr(trim($backgroundpart), 0, 1) == '#' ||
in_array(trim($backgroundpart), array_keys($this->colornames)) ||
strtolower(substr(trim($backgroundpart), 0, 3)) == 'rgb') {
$color = $backgroundpart;
// Search for color in rgb format first, as this can potentially contain a space.
if (strpos($color, 'rgb') !== false) {
$colors = explode('rgb', $color, 2); // Getting 2 only in array.
// Getting end point of rgb value, i.e. the end bracket.
$endpos = strpos($colors[1], ')');
$color = 'rgb' . substr($colors[1], 0, ($endpos + 1)); // Recompiling rgb value.
} else {
// Splitting multi-value css background value.
if (strpos($color, ' ') !== false) {
$colors = explode(' ', $color);
foreach ($colors as $backgroundpart) {
if (substr(trim($backgroundpart), 0, 1) == '#' ||
in_array(trim($backgroundpart), array_keys($this->colornames))) {
$color = $backgroundpart;
}
}
}
}
Expand Down Expand Up @@ -362,4 +384,31 @@ public function get_wai_diffs(array $forergb, array $backrgb): array {
: $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.

// Search for em and px initially, typical font-size values.
$pos1 = stripos($fontsize, 'em');
$pos2 = stripos($fontsize, 'px');
if ($pos1 !== false) {
$em = substr($fontsize, 0, -2);
$newfontsize = $newfontsize * $em;
} else if ($pos2 !== 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 $newfontsize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,18 @@ public function check(): void {
foreach ($entries as $element) {
$style = $this->css->get_style($element);

if (isset($style['background-color']) || isset($style['color'])) {
if (isset($style['background-color']) || isset($style['color']) || isset($style['background'])) {
if (!isset($style['background-color'])) {
$style['background-color'] = $this->defaultbackground;
if (isset($style['background'])) {
// Parsing background-color from CSS background shortcut string.
$style['background-color'] = '#' . $this->convert_color($style['background']);
// If value is empty after hash, then use defaultbackground.
if ($style['background-color'] == '#') {
$style['background-color'] = $this->defaultbackground;
}
} else {
$style['background-color'] = $this->defaultbackground;
}
}

if (!isset($style['color'])) {
Expand All @@ -82,11 +91,7 @@ public function check(): void {
$style['color'] = '#' . $this->convert_color($style['color']);
$style['background-color'] = '#' . $this->convert_color($background);

if (substr($background, 0, 3) == "rgb") {
$background = '#' . $this->convert_color($background);
}

$luminosity = $this->get_luminosity($style['color'], $background);
$luminosity = $this->get_luminosity($style['color'], $style['background-color']);
$fontsize = 0;
$bold = false;
$italic = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,94 @@ public function test_check_for_emptyvalues() {
$results = $this->get_checker_results($this->emptyvalue);
$this->assertEmpty($results);
}

/**
* Test for rgb colors with insufficient contrast.
*/
public function test_bad_rgbcolor() {
$html = '<body><p style="color:rgb(255, 255, 255); background-color:rgb(204, 204, 204);">
This is not contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertTrue($results[0]->element->tagName == 'p');
}

/**
* Test for rgb colors with sufficient contrast.
*/
public function test_good_rgbcolor() {
$html = '<body><p style="color:rgb(255, 255, 255); background-color:rgb(0, 0, 0);">
This is contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertEmpty($results);
}

/**
* Test for named colors with insufficient contrast.
*/
public function test_bad_namedcolor2() {
$html = '<body><p style="color:lightcyan; background-color:lavender;">
This is not contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertTrue($results[0]->element->tagName == 'p');
}

/**
* Test for named colors with sufficient contrast.
*/
public function test_good_namedcolor2() {
$html = '<body><p style="color:linen; background-color:darkslategray;">
This is contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertEmpty($results);
}

/**
* Test for background value with insufficient contrast.
*/
public function test_bad_backgroundcss() {
$html = '<body><p style="color:lightcyan; background:fixed lavender center;">
This is not contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertTrue($results[0]->element->tagName == 'p');
}

/**
* Test for background value with sufficient contrast.
*/
public function test_good_backgroundcss() {
$html = '<body><p style="color:linen; background:fixed darkslategray center;">
This is contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertEmpty($results);
}

/**
* Test for background value with rgb with insufficient contrast.
*/
public function test_bad_backgroundcssrgb() {
$html = '<body><p style="color:rgb(255, 255, 255); background:fixed rgb(204, 204, 204) center;">
This is not contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertTrue($results[0]->element->tagName == 'p');
}

/**
* Test for background value with rgb with sufficient contrast.
*/
public function test_good_backgroundcssrgb() {
$html = '<body><p style="color:rgb(255, 255, 255); background:fixed rgb(0, 0, 0) center;">
This is contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertEmpty($results);
}

/**
* Test for text with insufficient contrast of 4.49.
*/
public function test_bad_contrastrounding() {
$html = '<body><p style="color:#EF0000; background-color:white; font-size: 18px">
This is not contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertTrue($results[0]->element->tagName == 'p');
}
}

0 comments on commit 337a9bd

Please sign in to comment.