luna-dom-highlighter
Version:
Highlighter for html elements
235 lines (234 loc) • 9.24 kB
JavaScript
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getContrastThreshold = exports.isLargeFont = exports.getAPCAThreshold = exports.desiredLuminanceAPCA = exports.contrastRatioByLuminanceAPCA = exports.contrastRatioAPCA = exports.luminanceAPCA = exports.contrastRatio = exports.luminance = exports.rgbaToHsla = exports.blendColors = void 0;
function blendColors(fgRGBA, bgRGBA) {
var alpha = fgRGBA[3];
return [
((1 - alpha) * bgRGBA[0]) + (alpha * fgRGBA[0]),
((1 - alpha) * bgRGBA[1]) + (alpha * fgRGBA[1]),
((1 - alpha) * bgRGBA[2]) + (alpha * fgRGBA[2]),
alpha + (bgRGBA[3] * (1 - alpha)),
];
}
exports.blendColors = blendColors;
function rgbaToHsla(_a) {
var _b = __read(_a, 4), r = _b[0], g = _b[1], b = _b[2], a = _b[3];
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var diff = max - min;
var sum = max + min;
var h;
if (min === max) {
h = 0;
}
else if (r === max) {
h = ((1 / 6 * (g - b) / diff) + 1) % 1;
}
else if (g === max) {
h = (1 / 6 * (b - r) / diff) + 1 / 3;
}
else {
h = (1 / 6 * (r - g) / diff) + 2 / 3;
}
var l = 0.5 * sum;
var s;
if (l === 0) {
s = 0;
}
else if (l === 1) {
s = 0;
}
else if (l <= 0.5) {
s = diff / sum;
}
else {
s = diff / (2 - sum);
}
return [h, s, l, a];
}
exports.rgbaToHsla = rgbaToHsla;
function luminance(_a) {
var _b = __read(_a, 3), rSRGB = _b[0], gSRGB = _b[1], bSRGB = _b[2];
var r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055) / 1.055), 2.4);
var g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055) / 1.055), 2.4);
var b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055) / 1.055), 2.4);
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
exports.luminance = luminance;
function contrastRatio(fgRGBA, bgRGBA) {
var blendedFg = blendColors(fgRGBA, bgRGBA);
var fgLuminance = luminance(blendedFg);
var bgLuminance = luminance(bgRGBA);
var contrastRatio = (Math.max(fgLuminance, bgLuminance) + 0.05) / (Math.min(fgLuminance, bgLuminance) + 0.05);
return contrastRatio;
}
exports.contrastRatio = contrastRatio;
var mainTRC = 2.4;
var normBgExp = 0.55;
var normFgExp = 0.58;
var revBgExp = 0.62;
var revFgExp = 0.57;
var blkThrs = 0.03;
var blkClmp = 1.45;
var scaleBoW = 1.25;
var scaleWoB = 1.25;
var deltaLuminanceMin = 0.0005;
var loConThresh = 0.078;
var loConFactor = 12.82051282051282;
var loConOffset = 0.06;
var loClip = 0.001;
function luminanceAPCA(_a) {
var _b = __read(_a, 3), rSRGB = _b[0], gSRGB = _b[1], bSRGB = _b[2];
var r = Math.pow(rSRGB, mainTRC);
var g = Math.pow(gSRGB, mainTRC);
var b = Math.pow(bSRGB, mainTRC);
return 0.2126729 * r + 0.7151522 * g + 0.0721750 * b;
}
exports.luminanceAPCA = luminanceAPCA;
function contrastRatioAPCA(fgRGBA, bgRGBA) {
return contrastRatioByLuminanceAPCA(luminanceAPCA(fgRGBA), luminanceAPCA(bgRGBA));
}
exports.contrastRatioAPCA = contrastRatioAPCA;
function clampLuminance(value) {
return value > blkThrs ? value : (value + Math.pow(blkThrs - value, blkClmp));
}
function contrastRatioByLuminanceAPCA(fgLuminance, bgLuminance) {
fgLuminance = clampLuminance(fgLuminance);
bgLuminance = clampLuminance(bgLuminance);
if (Math.abs(fgLuminance - bgLuminance) < deltaLuminanceMin) {
return 0;
}
var result = 0;
if (bgLuminance >= fgLuminance) {
result = (Math.pow(bgLuminance, normBgExp) - Math.pow(fgLuminance, normFgExp)) * scaleBoW;
result = result < loClip ?
0 :
(result < loConThresh ? result - result * loConFactor * loConOffset : result - loConOffset);
}
else {
result = (Math.pow(bgLuminance, revBgExp) - Math.pow(fgLuminance, revFgExp)) * scaleWoB;
result = result > -loClip ?
0 :
(result > -loConThresh ? result - result * loConFactor * loConOffset : result + loConOffset);
}
return result * 100;
}
exports.contrastRatioByLuminanceAPCA = contrastRatioByLuminanceAPCA;
function desiredLuminanceAPCA(luminance, contrast, lighter) {
luminance = clampLuminance(luminance);
contrast /= 100;
function computeLuminance() {
if (!lighter) {
return Math.pow(Math.abs(Math.pow(luminance, normBgExp) - (contrast + loConOffset) / scaleBoW), 1 / normFgExp);
}
return Math.pow(Math.abs(Math.pow(luminance, revBgExp) - (-contrast - loConOffset) / scaleWoB), 1 / revFgExp);
}
var desiredLuminance = computeLuminance();
if (desiredLuminance < 0 || desiredLuminance > 1) {
lighter = !lighter;
desiredLuminance = computeLuminance();
}
return desiredLuminance;
}
exports.desiredLuminanceAPCA = desiredLuminanceAPCA;
var contrastAPCALookupTable = [
[12, -1, -1, -1, -1, 100, 90, 80, -1, -1],
[14, -1, -1, -1, 100, 90, 80, 60, 60, -1],
[16, -1, -1, 100, 90, 80, 60, 55, 50, 50],
[18, -1, -1, 90, 80, 60, 55, 50, 40, 40],
[24, -1, 100, 80, 60, 55, 50, 40, 38, 35],
[30, -1, 90, 70, 55, 50, 40, 38, 35, 40],
[36, -1, 80, 60, 50, 40, 38, 35, 30, 25],
[48, 100, 70, 55, 40, 38, 35, 30, 25, 20],
[60, 90, 60, 50, 38, 35, 30, 25, 20, 20],
[72, 80, 55, 40, 35, 30, 25, 20, 20, 20],
[96, 70, 50, 35, 30, 25, 20, 20, 20, 20],
[120, 60, 40, 30, 25, 20, 20, 20, 20, 20],
];
contrastAPCALookupTable.reverse();
function getAPCAThreshold(fontSize, fontWeight) {
var e_1, _a, e_2, _b;
var size = parseFloat(fontSize.replace('px', ''));
var weight = parseFloat(fontWeight);
try {
for (var contrastAPCALookupTable_1 = __values(contrastAPCALookupTable), contrastAPCALookupTable_1_1 = contrastAPCALookupTable_1.next(); !contrastAPCALookupTable_1_1.done; contrastAPCALookupTable_1_1 = contrastAPCALookupTable_1.next()) {
var _c = __read(contrastAPCALookupTable_1_1.value), rowSize = _c[0], rowWeights = _c.slice(1);
if (size >= rowSize) {
try {
for (var _d = (e_2 = void 0, __values([900, 800, 700, 600, 500, 400, 300, 200, 100].entries())), _e = _d.next(); !_e.done; _e = _d.next()) {
var _f = __read(_e.value, 2), idx = _f[0], keywordWeight = _f[1];
if (weight >= keywordWeight) {
var threshold = rowWeights[rowWeights.length - 1 - idx];
return threshold === -1 ? null : threshold;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_e && !_e.done && (_b = _d.return)) _b.call(_d);
}
finally { if (e_2) throw e_2.error; }
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (contrastAPCALookupTable_1_1 && !contrastAPCALookupTable_1_1.done && (_a = contrastAPCALookupTable_1.return)) _a.call(contrastAPCALookupTable_1);
}
finally { if (e_1) throw e_1.error; }
}
return null;
}
exports.getAPCAThreshold = getAPCAThreshold;
function isLargeFont(fontSize, fontWeight) {
var boldWeights = ['bold', 'bolder', '600', '700', '800', '900'];
var fontSizePx = parseFloat(fontSize.replace('px', ''));
var isBold = (boldWeights.indexOf(fontWeight) !== -1);
var fontSizePt = fontSizePx * 72 / 96;
if (isBold) {
return fontSizePt >= 14;
}
return fontSizePt >= 18;
}
exports.isLargeFont = isLargeFont;
var contrastThresholds = {
largeFont: { aa: 3.0, aaa: 4.5 },
normalFont: { aa: 4.5, aaa: 7.0 },
};
function getContrastThreshold(fontSize, fontWeight) {
if (isLargeFont(fontSize, fontWeight)) {
return contrastThresholds.largeFont;
}
return contrastThresholds.normalFont;
}
exports.getContrastThreshold = getContrastThreshold;