Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revert(color-contrast): revert upgrade to colorjs.io v0.5.0 to work with prototype.js #4429

Merged
merged 4 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 40 additions & 1 deletion lib/commons/color/color.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Colorjs } from '../../core/imports';
import { Colorjs, ArrayFrom } from '../../core/imports';

const hexRegex = /^#[0-9a-f]{3,8}$/i;
const hslRegex = /hsl\(\s*([-\d.]+)(rad|turn)/;

/**
* @class Color
Expand Down Expand Up @@ -129,9 +130,37 @@ export default class Color {
* @instance
*/
parseString(colorString) {
// Colorjs <v0.5.0 does not support rad or turn angle values
// @see https://github.com/LeaVerou/color.js/issues/311
colorString = colorString.replace(hslRegex, (match, angle, unit) => {
const value = angle + unit;

switch (unit) {
case 'rad':
return match.replace(value, radToDeg(angle));
case 'turn':
return match.replace(value, turnToDeg(angle));
}
});

try {
// revert prototype.js override of Array.from
// in order to get color-contrast working
// @see https://github.com/dequelabs/axe-core/issues/4428
let prototypeArrayFrom;
if ('Prototype' in window && 'Version' in window.Prototype) {
prototypeArrayFrom = Array.from;
Array.from = ArrayFrom;
}

// srgb values are between 0 and 1
const color = new Colorjs(colorString).to('srgb');

if (prototypeArrayFrom) {
Array.from = prototypeArrayFrom;
prototypeArrayFrom = null;
}

this.r = color.r;
this.g = color.g;
this.b = color.b;
Expand Down Expand Up @@ -328,3 +357,13 @@ export default class Color {
function clamp(value, min, max) {
return Math.min(Math.max(min, value), max);
}

// convert radians to degrees
function radToDeg(rad) {
return (rad * 180) / Math.PI;
}

// convert turn to degrees
function turnToDeg(turn) {
return turn * 360;
}
10 changes: 9 additions & 1 deletion lib/core/imports/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import doT from '@deque/dot';
import emojiRegexText from 'emoji-regex';
import memoize from 'memoizee';
import Color from 'colorjs.io';
import ArrayFrom from 'core-js-pure/actual/array/from';

// prevent striping newline characters from strings (e.g. failure
// summaries). value must be synced with build/configure.js
Expand All @@ -17,4 +18,11 @@ doT.templateSettings.strip = false;
* @namespace imports
* @memberof axe
*/
export { CssSelectorParser, doT, emojiRegexText, memoize, Color as Colorjs };
export {
CssSelectorParser,
doT,
emojiRegexText,
memoize,
Color as Colorjs,
ArrayFrom
};
91 changes: 2 additions & 89 deletions lib/core/imports/polyfills.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Uint32Array } from 'typedarray';
import 'weakmap-polyfill';
import hasOwn from 'core-js-pure/actual/object/has-own';
import values from 'core-js-pure/actual/object/values';
import ArrayFrom from 'core-js-pure/actual/array/from';

if (!('hasOwn' in Object)) {
Object.hasOwn = hasOwn;
Expand Down Expand Up @@ -177,95 +178,7 @@ if (!Array.prototype.some) {
}

if (!Array.from) {
Object.defineProperty(Array, 'from', {
value: (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return (
typeof fn === 'function' || toStr.call(fn) === '[object Function]'
);
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) {
return 0;
}
if (number === 0 || !isFinite(number)) {
return number;
}
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};

// The length property of the from method is 1.
return function from(arrayLike /*, mapFn, thisArg */) {
// 1. Let C be the this value.
var C = this;

// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);

// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError(
'Array.from requires an array-like object - not null or undefined'
);
}

// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError(
'Array.from: when provided, the second argument must be a function'
);
}

// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
}

// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);

// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);

// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] =
typeof T === 'undefined'
? mapFn(kValue, k)
: mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
};
})()
});
Array.from = ArrayFrom;
}

if (!String.prototype.includes) {
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
"chromedriver": "latest",
"clean-jsdoc-theme": "^4.2.17",
"clone": "^2.1.2",
"colorjs.io": "^0.5.0",
"colorjs.io": "^0.4.3",
"conventional-commits-parser": "^5.0.0",
"core-js": "^3.27.1",
"css-selector-parser": "^1.4.1",
Expand Down
18 changes: 18 additions & 0 deletions test/commons/color/color.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,15 @@ describe('color.Color', () => {
assert.equal(c.alpha, 1);
});

it('supports negative rad on hue', () => {
const c = new Color();
c.parseColorFnString('hsl(-3.49rad, 40%, 50%)');
assert.equal(c.red, 77);
assert.equal(c.green, 179);
assert.equal(c.blue, 145);
assert.equal(c.alpha, 1);
});

it('supports turn on hue', () => {
const c = new Color();
c.parseColorFnString('hsl(0.444turn, 40%, 50%)');
Expand All @@ -174,6 +183,15 @@ describe('color.Color', () => {
assert.equal(c.blue, 144);
assert.equal(c.alpha, 1);
});

it('supports negative turn on hue', () => {
const c = new Color();
c.parseColorFnString('hsl(-0.556turn, 40%, 50%)');
assert.equal(c.red, 77);
assert.equal(c.green, 179);
assert.equal(c.blue, 144);
assert.equal(c.alpha, 1);
});
});

describe('with hwb()', () => {
Expand Down