mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-05 20:15:58 +00:00
Bug 1567249 - Update a11y contrast calculation to make it work with applied simulation matrices, r=yzen,nchevobbe
Differential Revision: https://phabricator.services.mozilla.com/D42417 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
f29b892aa0
commit
4922526a64
@ -471,6 +471,7 @@ const AccessibleActor = ActorClassWithSpec(accessibleSpec, {
|
||||
const contrastRatio = await getContrastRatioFor(rawNode.parentNode, {
|
||||
bounds: getBounds(win, bounds),
|
||||
win,
|
||||
appliedColorMatrix: this.walker.colorMatrix,
|
||||
});
|
||||
|
||||
walker.restoreStyles(win);
|
||||
|
@ -112,6 +112,40 @@ function getImageCtx(win, bounds, zoom, scale, node) {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the transformed RGBA when a color matrix is set in docShell by
|
||||
* multiplying the color matrix with the RGBA vector.
|
||||
*
|
||||
* @param {Array} rgba
|
||||
* Original RGBA array which we want to transform.
|
||||
* @param {Array} colorMatrix
|
||||
* Flattened 4x5 color matrix that is set in docShell.
|
||||
* A 4x5 matrix of the form:
|
||||
* 1 2 3 4 5
|
||||
* 6 7 8 9 10
|
||||
* 11 12 13 14 15
|
||||
* 16 17 18 19 20
|
||||
* will be set in docShell as:
|
||||
* [1, 6, 11, 16, 2, 7, 12, 17, 3, 8, 13, 18, 4, 9, 14, 19, 5, 10, 15, 20]
|
||||
* @return {Array}
|
||||
* Transformed RGBA after the color matrix is multiplied with the original RGBA.
|
||||
*/
|
||||
function getTransformedRGBA(rgba, colorMatrix) {
|
||||
const transformedRGBA = [0, 0, 0, 0];
|
||||
|
||||
// Only use the first four columns of the color matrix corresponding to R, G, B and A
|
||||
// color channels respectively. The fifth column is a fixed offset that does not need
|
||||
// to be considered for the matrix multiplication. We end up multiplying a 4x4 color
|
||||
// matrix with a 4x1 RGBA vector.
|
||||
for (let i = 0; i < 16; i++) {
|
||||
const row = i % 4;
|
||||
const col = Math.floor(i / 4);
|
||||
transformedRGBA[row] += colorMatrix[i] * rgba[col];
|
||||
}
|
||||
|
||||
return transformedRGBA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find RGBA or a range of RGBAs for the background pixels under the text.
|
||||
*
|
||||
@ -190,6 +224,9 @@ function getBackgroundFor(node, { win, bounds, size, isBoldText }) {
|
||||
* Bounds for the accessible object.
|
||||
* - win {Object}
|
||||
* Target window.
|
||||
* - appliedColorMatrix {Array|null}
|
||||
* Simulation color matrix applied to
|
||||
* to the viewport, if it exists.
|
||||
* @return {Object}
|
||||
* An object that may contain one or more of the following fields: error,
|
||||
* isLargeText, value, min, max values for contrast.
|
||||
@ -204,9 +241,12 @@ async function getContrastRatioFor(node, options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
const { color, isLargeText, isBoldText, size, opacity } = props;
|
||||
|
||||
const rgba = await getBackgroundFor(node, {
|
||||
const { isLargeText, isBoldText, size, opacity } = props;
|
||||
const { appliedColorMatrix } = options;
|
||||
const color = appliedColorMatrix
|
||||
? getTransformedRGBA(props.color, appliedColorMatrix)
|
||||
: props.color;
|
||||
let rgba = await getBackgroundFor(node, {
|
||||
...options,
|
||||
isBoldText,
|
||||
size,
|
||||
@ -235,7 +275,9 @@ async function getContrastRatioFor(node, options = {}) {
|
||||
|
||||
return getContrastRatioAgainstBackground(
|
||||
{
|
||||
value: [r, g, b, a],
|
||||
value: appliedColorMatrix
|
||||
? getTransformedRGBA([r, g, b, a], appliedColorMatrix)
|
||||
: [r, g, b, a],
|
||||
},
|
||||
{
|
||||
color,
|
||||
@ -244,6 +286,17 @@ async function getContrastRatioFor(node, options = {}) {
|
||||
);
|
||||
}
|
||||
|
||||
if (appliedColorMatrix) {
|
||||
rgba = rgba.value
|
||||
? {
|
||||
value: getTransformedRGBA(rgba.value, appliedColorMatrix),
|
||||
}
|
||||
: {
|
||||
min: getTransformedRGBA(rgba.min, appliedColorMatrix),
|
||||
max: getTransformedRGBA(rgba.max, appliedColorMatrix),
|
||||
};
|
||||
}
|
||||
|
||||
return getContrastRatioAgainstBackground(rgba, {
|
||||
color,
|
||||
isLargeText,
|
||||
|
@ -8,6 +8,9 @@ const { Cc, Ci } = require("chrome");
|
||||
const Services = require("Services");
|
||||
const { Actor, ActorClassWithSpec } = require("devtools/shared/protocol");
|
||||
const { accessibleWalkerSpec } = require("devtools/shared/specs/accessibility");
|
||||
const {
|
||||
simulation: { COLOR_TRANSFORMATION_MATRICES },
|
||||
} = require("./constants");
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
@ -321,6 +324,22 @@ const AccessibleWalkerActor = ActorClassWithSpec(accessibleWalkerSpec, {
|
||||
return this.targetActor && this.targetActor.window.document;
|
||||
},
|
||||
|
||||
get colorMatrix() {
|
||||
if (!this.targetActor.docShell) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const colorMatrix = this.targetActor.docShell.getColorMatrix();
|
||||
if (
|
||||
colorMatrix.length === 0 ||
|
||||
colorMatrix === COLOR_TRANSFORMATION_MATRICES.NONE
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return colorMatrix;
|
||||
},
|
||||
|
||||
reset() {
|
||||
try {
|
||||
Services.obs.removeObserver(this, "accessible-event");
|
||||
|
Loading…
Reference in New Issue
Block a user