Skip to content

Commit

Permalink
MDL-78785 tool_brickfield: Processing rgb & rgba color contrasts
Browse files Browse the repository at this point in the history
  Including rgb(), rgba() processing for colour contrast checking.
  Including review requests :void and @Covers for phpunit testing.
  • Loading branch information
learningtechnologyservices committed Aug 14, 2024
1 parent a75365f commit 311d2b3
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ public function luminosity(string $r, string $r2, string $g, string $g2, string
return $luminosity;
}


/**
* Returns the decimal equivalents for a HEX color. Returns null if it cannot be determined.
* @param string $color The hex color value
Expand All @@ -268,13 +267,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 All @@ -296,9 +303,20 @@ public function convert_color(string $color): string {
}
// RGB values.
if (strtolower(substr($color, 0, 3)) == 'rgb') {
$colors = explode(',', trim(str_replace('rgb(', '', $color), '()'));
if (count($colors) != 3) {
return false;
if (strpos($color, 'rgba') !== false) {
$tmpbg = $this->get_rgb($this->defaultbackground);
$colors = explode(',', trim(str_replace('rgba(', '', $color), '()'));
if (count($colors) != 4) {
return false;
}
$colors[0] = round(((1 - $colors[3]) * $tmpbg['r']) + ($colors[3] * $colors[0]));
$colors[1] = round((1 - $colors[3]) * $tmpbg['g']) + ($colors[3] * $colors[1]);
$colors[2] = round((1 - $colors[3]) * $tmpbg['b']) + ($colors[3] * $colors[2]);
} else {
$colors = explode(',', trim(str_replace('rgb(', '', $color), '()'));
if (count($colors) != 3) {
return false;
}
}
$r = intval($colors[0]);
$g = intval($colors[1]);
Expand Down
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 @@ -30,6 +30,7 @@

/**
* Class test_css_text_has_contrast_test
* @covers \tool_brickfield\local\htmlchecker\brickfield_accessibility
*/
class css_text_has_contrast_test extends all_checks {
/** @var string The check type. */
Expand Down Expand Up @@ -347,4 +348,114 @@ public function test_check_for_largerbold_pass(): void {
$results = $this->get_checker_results($this->largerboldpass);
$this->assertEmpty($results);
}

/**
* Test for rgb colors with insufficient contrast.
*/
public function test_bad_rgbcolor(): void {
$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(): void {
$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(): void {
$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(): void {
$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(): void {
$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(): void {
$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(): void {
$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(): void {
$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.3.
*/
public function test_bad_contrastrounding(): void {
$html = '<body><p style="color:#F50000; background-color:white; font-size: 12px">
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 rgba with insufficient contrast.
*/
public function test_bad_backgroundcssrgba(): void {
$html = '<body><p style="color:rgba(255, 255, 255, 0.5); background:fixed rgba(0, 204, 204, 0.5) 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 rgba with sufficient contrast.
*/
public function test_good_backgroundcssrgba(): void {
$html = '<body><p style="color:rgba(255, 255, 255, 0.75); background:fixed rgba(0, 0, 0, 0.75) center;">
This is contrasty enough.</p></body>';
$results = $this->get_checker_results($html);
$this->assertEmpty($results);
}
}

0 comments on commit 311d2b3

Please sign in to comment.