color-math
Version:
expressions to manipulate colors
668 lines (621 loc) • 22.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _EvaluatorBase2 = _interopRequireDefault(require("./EvaluatorBase"));
var Utils = _interopRequireWildcard(require("../utils"));
var _BlendMode = _interopRequireDefault(require("../BlendMode"));
var _nodes = require("../nodes");
var _CoreEvaluator = _interopRequireDefault(require("./CoreEvaluator"));
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var LessEvaluator =
/*#__PURE__*/
function (_EvaluatorBase) {
_inherits(LessEvaluator, _EvaluatorBase);
function LessEvaluator() {
_classCallCheck(this, LessEvaluator);
return _possibleConstructorReturn(this, _getPrototypeOf(LessEvaluator).call(this, 'less'));
}
_createClass(LessEvaluator, [{
key: "evalProgram",
value: function evalProgram(node) {
var _this = this;
// do core evaluation to perform all necessary validations
this.core.evalProgram(node);
var value = node.statements.length > 1 ? node.statements.map(function (st) {
return "".concat(st.evaluate(_this), ";");
}).join('\n') : node.statements[0].evaluate(this);
return value;
}
}, {
key: "evalStatement",
value: function evalStatement(node) {
var value = node.expr.evaluate(this);
return value;
}
}, {
key: "evalParentheses",
value: function evalParentheses(node) {
var value = "(".concat(node.expr.evaluate(this), ")");
return value;
}
}, {
key: "evalNumberLiteral",
value: function evalNumberLiteral(node) {
var n = this.core.evalNumberLiteral(node);
var value = n % 1 === 0 ? n : n.toFixed(8).replace(/0+$/, '');
return value;
}
}, {
key: "evalPercent",
value: function evalPercent(node) {
var value = "".concat(node.value.evaluate(this), "%");
return value;
}
}, {
key: "evalArrayLiteral",
value: function evalArrayLiteral(node) {
var _this2 = this;
var value = node.value.map(function (expr) {
return expr.evaluate(_this2);
}).join(' ');
return value;
}
}, {
key: "evalArrayElement",
value: function evalArrayElement(node) {
var value = "extract(".concat(this._unwrapParens(node.obj).evaluate(this), ", ").concat(node.name + 1, ")");
return value;
}
}, {
key: "evalColorNameLiteral",
value: function evalColorNameLiteral(node) {
var value = node.value;
return value;
}
}, {
key: "evalColorHexLiteral",
value: function evalColorHexLiteral(node) {
var value = (!node.value.match(/^#/) ? '#' : '') + node.value;
return value;
}
}, {
key: "evalColorByNumber",
value: function evalColorByNumber(node) {
Utils.throwError('defining color by number is not supported by LESS', node.$loc);
}
}, {
key: "evalColorByTemperature",
value: function evalColorByTemperature(node) {
Utils.throwError('defining color by temperature is not supported by LESS', node.$loc);
}
}, {
key: "evalColorByWavelength",
value: function evalColorByWavelength(node) {
Utils.throwError('defining color by wavelength is not supported by LESS', node.$loc);
}
}, {
key: "evalColorBySpaceParams",
value: function evalColorBySpaceParams(node) {
var _this3 = this;
var params = node.params.map(function (expr) {
return expr.evaluate(_this3);
});
var alpha = params.length > (node.space === 'cmyk' ? 4 : 3);
var value = void 0;
switch (node.space) {
case 'argb':
value = "".concat(node.space, "(").concat(params.join(', '), ")");
break;
case 'rgb':
case 'hsl':
case 'hsv':
value = "".concat(node.space + (alpha ? 'a' : ''), "(").concat(params.join(', '), ")");
break;
default:
this._unspColorSpace(node.space, node.$loc);
}
return value;
}
}, {
key: "evalRandomColor",
value: function evalRandomColor()
/*node*/
{
//return "~`(function(){for(var i=0,c='#',m=Math;i<6;i++)c+='0123456789ABCDEF'[m.floor(m.random()*16)];return c;})()`"
return '~"#`(0x1000000+Math.random()*0xffffff).toString(16).substr(1,6)`"';
}
}, {
key: "evalScale",
value: function evalScale(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalBezier",
value: function evalBezier(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalCubehelix",
value: function evalCubehelix(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalBrewerConst",
value: function evalBrewerConst(node) {
var coreValue = this.core.evalBrewerConst(node);
var value = coreValue.map(function (c) {
return c.hex();
}).join(' ');
return value;
}
}, {
key: "evalUnaryMinus",
value: function evalUnaryMinus(node) {
var value = "-".concat(node.value.evaluate(this));
return value;
}
}, {
key: "evalColorInverse",
value: function evalColorInverse(node) {
var value = "(#fff - ".concat(node.value.evaluate(this), ")");
return value;
}
}, {
key: "evalCorrectLightness",
value: function evalCorrectLightness(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalNumbersAddition",
value: function evalNumbersAddition(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalNumbersSubtraction",
value: function evalNumbersSubtraction(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalNumbersMultiplication",
value: function evalNumbersMultiplication(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalNumbersDivision",
value: function evalNumbersDivision(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalColorAndNumberAddition",
value: function evalColorAndNumberAddition(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalColorAndNumberSubtraction",
value: function evalColorAndNumberSubtraction(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalColorAndNumberMultiplication",
value: function evalColorAndNumberMultiplication(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalColorAndNumberDivision",
value: function evalColorAndNumberDivision(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalNumberPower",
value: function evalNumberPower(node) {
var left = this._unwrapParens(node.left).evaluate(this);
var right = this._unwrapParens(node.right).evaluate(this);
var value = "pow(".concat(left, ", ").concat(right, ")");
return value;
}
}, {
key: "evalColorsContrast",
value: function evalColorsContrast(node) {
Utils.throwError('calculating numeric contrast value is not supported by LESS', node.$loc);
}
}, {
key: "evalColorsMix",
value: function evalColorsMix(node) {
var params = [this._unwrapParens(node.left).evaluate(this), this._unwrapParens(node.right).evaluate(this)];
var ratioExpr = (node.options || {}).ratio;
if (ratioExpr) {
params.push(this._toPercentage(ratioExpr));
}
var mode = (node.options || {}).mode;
if (mode && mode !== 'rgb') {
Utils.throwError('LESS supports mixing colors only in RGB color space', node.$loc);
}
var func = 'mix';
var leftColorStr = node.left.evaluate(this.core).hex('rgba').toLowerCase();
if (leftColorStr === '#ffffffff') {
params.shift();
func = 'tint';
} else if (leftColorStr === '#000000ff') {
params.shift();
func = 'shade';
}
var value = "".concat(func, "(").concat(params.join(', '), ")");
return value;
}
}, {
key: "evalColorsFromScaleProduction",
value: function evalColorsFromScaleProduction(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalColorDesaturate",
value: function evalColorDesaturate(node) {
return this._funcOp(node.left, node.right, 'desaturate', true, true);
}
}, {
key: "evalColorSaturate",
value: function evalColorSaturate(node) {
return this._funcOp(node.left, node.right, 'saturate', true, true);
}
}, {
key: "evalColorDarken",
value: function evalColorDarken(node) {
return this._funcOp(node.left, node.right, 'darken', true, true);
}
}, {
key: "evalColorLighten",
value: function evalColorLighten(node) {
return this._funcOp(node.left, node.right, 'lighten', true, true);
}
}, {
key: "evalAddBlend",
value: function evalAddBlend(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalSubtractBlend",
value: function evalSubtractBlend(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalMultiplyBlend",
value: function evalMultiplyBlend(node) {
return this._funcOp(node.left, node.right, 'multiply');
}
}, {
key: "evalDivideBlend",
value: function evalDivideBlend(node) {
return this._arithmeticOp(node);
}
}, {
key: "evalColorBurnBlend",
value: function evalColorBurnBlend(node) {
return this._unspColorBlend(_BlendMode["default"].ColorBurn, node.$loc);
}
}, {
key: "evalColorDodgeBlend",
value: function evalColorDodgeBlend(node) {
return this._unspColorBlend(_BlendMode["default"].ColorDodge, node.$loc);
}
}, {
key: "evalDarkenBlend",
value: function evalDarkenBlend(node) {
return this._unspColorBlend(_BlendMode["default"].Darken, node.$loc);
}
}, {
key: "evalLightenBlend",
value: function evalLightenBlend(node) {
return this._unspColorBlend(_BlendMode["default"].Lighten, node.$loc);
}
}, {
key: "evalScreenBlend",
value: function evalScreenBlend(node) {
return this._funcOp(node.left, node.right, 'screen');
}
}, {
key: "evalOverlayBlend",
value: function evalOverlayBlend(node) {
return this._funcOp(node.left, node.right, 'overlay');
}
}, {
key: "evalHardLightBlend",
value: function evalHardLightBlend(node) {
return this._funcOp(node.left, node.right, 'hardlight');
}
}, {
key: "evalSoftLightBlend",
value: function evalSoftLightBlend(node) {
return this._funcOp(node.left, node.right, 'softlight');
}
}, {
key: "evalDifferenceBlend",
value: function evalDifferenceBlend(node) {
return this._funcOp(node.left, node.right, 'difference');
}
}, {
key: "evalExclusionBlend",
value: function evalExclusionBlend(node) {
return this._funcOp(node.left, node.right, 'exclusion');
}
}, {
key: "evalNegateBlend",
value: function evalNegateBlend(node) {
return this._funcOp(node.left, node.right, 'negation');
}
}, {
key: "evalManageColorNumber",
value: function evalManageColorNumber(node) {
Utils.throwError('defining color by number is not supported by LESS', node.$loc);
}
}, {
key: "evalManageColorTemperature",
value: function evalManageColorTemperature(node) {
Utils.throwError('defining color by temperature is not supported by LESS', node.$loc);
}
}, {
key: "evalManageColorLuminance",
value: function evalManageColorLuminance(node) {
var res = void 0;
if (node.value === void 0) {
res = "luma(".concat(this._unwrapParens(node.obj).evaluate(this), ")");
} else {
Utils.throwError("setting luminance is not supported by LESS", node.$loc);
}
return res;
}
}, {
key: "evalManageColorAlpha",
value: function evalManageColorAlpha(node) {
var res = void 0;
if (node.value === void 0) {
res = "alpha(".concat(this._unwrapParens(node.obj).evaluate(this), ")");
} else {
if (node.operator === '+') {
res = this._funcOp(node.obj, node.value, 'fadein', true);
} else if (node.operator === '-') {
res = this._funcOp(node.obj, node.value, 'fadeout', true);
} else if (!node.operator) {
res = this._funcOp(node.obj, node.value, 'fade', true);
} else {
Utils.throwError("assignment operator '".concat(node.operator, "=' for alpha channel is not supported by LESS"), node.$loc);
}
}
return res;
}
}, {
key: "evalManageColorCompRgbR",
value: function evalManageColorCompRgbR(node) {
return this._getColorCompOp(node, 'rgb', 'red');
}
}, {
key: "evalManageColorCompRgbG",
value: function evalManageColorCompRgbG(node) {
return this._getColorCompOp(node, 'rgb', 'green');
}
}, {
key: "evalManageColorCompRgbB",
value: function evalManageColorCompRgbB(node) {
return this._getColorCompOp(node, 'rgb', 'blue');
}
}, {
key: "evalManageColorCompCmykC",
value: function evalManageColorCompCmykC(node) {
this._unspColorSpace('cmyk', node.$loc);
}
}, {
key: "evalManageColorCompCmykM",
value: function evalManageColorCompCmykM(node) {
this._unspColorSpace('cmyk', node.$loc);
}
}, {
key: "evalManageColorCompCmykY",
value: function evalManageColorCompCmykY(node) {
this._unspColorSpace('cmyk', node.$loc);
}
}, {
key: "evalManageColorCompCmykK",
value: function evalManageColorCompCmykK(node) {
this._unspColorSpace('cmyk', node.$loc);
}
}, {
key: "evalManageColorCompHslH",
value: function evalManageColorCompHslH(node) {
return this._getColorCompOp(node, 'hsl', 'hue');
}
}, {
key: "evalManageColorCompHslS",
value: function evalManageColorCompHslS(node) {
return this._getColorCompOp(node, 'hsl', 'saturation');
}
}, {
key: "evalManageColorCompHslL",
value: function evalManageColorCompHslL(node) {
return this._getColorCompOp(node, 'hsl', 'lightness');
}
}, {
key: "evalManageColorCompHsvH",
value: function evalManageColorCompHsvH(node) {
return this._getColorCompOp(node, 'hsv', 'hsvhue');
}
}, {
key: "evalManageColorCompHsvS",
value: function evalManageColorCompHsvS(node) {
return this._getColorCompOp(node, 'hsv', 'hsvsaturation');
}
}, {
key: "evalManageColorCompHsvV",
value: function evalManageColorCompHsvV(node) {
return this._getColorCompOp(node, 'hsv', 'hsvvalue');
}
}, {
key: "evalManageColorCompHsiH",
value: function evalManageColorCompHsiH(node) {
this._unspColorSpace('hsi', node.$loc);
}
}, {
key: "evalManageColorCompHsiS",
value: function evalManageColorCompHsiS(node) {
this._unspColorSpace('hsi', node.$loc);
}
}, {
key: "evalManageColorCompHsiI",
value: function evalManageColorCompHsiI(node) {
this._unspColorSpace('hsi', node.$loc);
}
}, {
key: "evalManageColorCompLabL",
value: function evalManageColorCompLabL(node) {
this._unspColorSpace('lab', node.$loc);
}
}, {
key: "evalManageColorCompLabA",
value: function evalManageColorCompLabA(node) {
this._unspColorSpace('lab', node.$loc);
}
}, {
key: "evalManageColorCompLabB",
value: function evalManageColorCompLabB(node) {
this._unspColorSpace('lab', node.$loc);
}
}, {
key: "evalManageColorCompLchL",
value: function evalManageColorCompLchL(node) {
this._unspColorSpace('lch', node.$loc);
}
}, {
key: "evalManageColorCompLchC",
value: function evalManageColorCompLchC(node) {
this._unspColorSpace('lch', node.$loc);
}
}, {
key: "evalManageColorCompLchH",
value: function evalManageColorCompLchH(node) {
this._unspColorSpace('lch', node.$loc);
}
}, {
key: "evalSetColorScalePadding",
value: function evalSetColorScalePadding(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalSetScaleDomain",
value: function evalSetScaleDomain(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalSetCubehelixStart",
value: function evalSetCubehelixStart(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalSetCubehelixRotations",
value: function evalSetCubehelixRotations(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalSetCubehelixHue",
value: function evalSetCubehelixHue(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalSetCubehelixGamma",
value: function evalSetCubehelixGamma(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalSetCubehelixLightness",
value: function evalSetCubehelixLightness(node) {
this._unspColorScale(node.$loc);
}
}, {
key: "evalGetVar",
value: function evalGetVar(node) {
var value = "@".concat(node.name.replace(/^\$/, ''));
return value;
}
}, {
key: "evalSetVar",
value: function evalSetVar(node) {
var value = "@".concat(node.name.replace(/^\$/, ''), ": ").concat(node.value.evaluate(this));
return value;
}
}, {
key: "_arithmeticOp",
value: function _arithmeticOp(node) {
var left = node.left.evaluate(this);
var right = node.right.evaluate(this);
var value = "".concat(left, " ").concat(node.operator, " ").concat(right);
return value;
}
}, {
key: "_toPercentage",
value: function _toPercentage(node) {
var value = node.evaluate(this);
var res;
if (node instanceof _nodes.PercentExpr) {
res = value;
} else if (node instanceof _nodes.NumberLiteralExpr) {
res = this.core.evalNumberLiteral(node) * 100 + '%';
} else {
res = "percentage(".concat(value, ")");
}
return res;
}
}, {
key: "_funcOp",
value: function _funcOp(nodeLeft, nodeRight, func) {
var rightIsPercentage = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var relative = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var params = [this._unwrapParens(nodeLeft).evaluate(this), rightIsPercentage ? this._toPercentage(nodeRight) : nodeRight.evaluate(this)];
if (relative) {
params.push('relative');
}
var value = "".concat(func, "(").concat(params.join(', '), ")");
return value;
}
}, {
key: "_getColorCompOp",
value: function _getColorCompOp(node, space, func) {
if (node.value === void 0) {
var res = "".concat(func, "(").concat(node.obj.evaluate(this), ")");
return res;
} else {
Utils.throwError("setting components in ".concat(space.toUpperCase(), " color space is not supported by LESS"), node.$loc);
}
}
}, {
key: "_unspColorScale",
value: function _unspColorScale(loc) {
Utils.throwError('color scales are not supported by LESS', loc);
}
}, {
key: "_unspColorSpace",
value: function _unspColorSpace(space, loc) {
Utils.throwError("color space '".concat(space.toUpperCase(), "' is not supported by LESS"), loc);
}
}, {
key: "_unspColorBlend",
value: function _unspColorBlend(mode, loc) {
Utils.throwError("'".concat(Utils.getObjKey(_BlendMode["default"], mode), "' blending function is not supported by LESS"), loc);
}
}, {
key: "core",
get: function get() {
return _CoreEvaluator["default"].instance;
}
}]);
return LessEvaluator;
}(_EvaluatorBase2["default"]);
exports["default"] = LessEvaluator;