diff --git a/packages/less/src/less/functions/math-helper.js b/packages/less/src/less/functions/math-helper.js index 4cca18668..2b5c73d7e 100644 --- a/packages/less/src/less/functions/math-helper.js +++ b/packages/less/src/less/functions/math-helper.js @@ -4,8 +4,8 @@ import Dimension from '../tree/dimension'; const MathHelper = (fn, unit, n) => { if (n instanceof Call && n.name === 'var') { - if (n.args && n.args.length === 1) { - return new Call(fn.name, [new CustomProperty(n.args[0].toCSS(), n._index, n._fileInfo)], n._index, n._fileInfo); + if (n.args && n.args.length >= 1) { + return new Call(fn.name, [new CustomProperty(n.args[0].toCSS(), n.args[1] ? n.args[1].toCSS() : null, n._index, n._fileInfo)], n._index, n._fileInfo); } else { throw { type: 'Argument', message: 'var must contain one expression' }; } diff --git a/packages/less/src/less/functions/number.js b/packages/less/src/less/functions/number.js index ccb97afef..5b5cac91e 100644 --- a/packages/less/src/less/functions/number.js +++ b/packages/less/src/less/functions/number.js @@ -1,6 +1,7 @@ import Dimension from '../tree/dimension'; import Anonymous from '../tree/anonymous'; import mathHelper from './math-helper.js'; +import Call from '../tree/call'; const minMax = function (isMin, args) { args = Array.prototype.slice.call(args); @@ -78,6 +79,10 @@ export default { return new Dimension(a.value % b.value, a.unit); }, pow: function(x, y) { + if (x instanceof Call || y instanceof Call) { + // Must return Node + return new Anonymous(x.toCSS() + ', ' + y.toCSS()); + } if (typeof x === 'number' && typeof y === 'number') { x = new Dimension(x); y = new Dimension(y); diff --git a/packages/less/src/less/tree/call.js b/packages/less/src/less/tree/call.js index 15e98eb80..1bdfd1791 100644 --- a/packages/less/src/less/tree/call.js +++ b/packages/less/src/less/tree/call.js @@ -1,6 +1,7 @@ import Node from './node'; import Anonymous from './anonymous'; import FunctionCaller from '../functions/function-caller'; +import CustomProperty from './custom-property'; // // A function call node. @@ -98,11 +99,34 @@ Call.prototype = Object.assign(new Node(), { genCSS(context, output) { output.add(`${this.name}(`, this.fileInfo(), this.getIndex()); + let isCustomProperty = false; + let customExpressionCount = 0; for (let i = 0; i < this.args.length; i++) { this.args[i].genCSS(context, output); + + if (this.args[i] instanceof CustomProperty + || ((i + 2 < this.args.length && this.args[i + 2] instanceof CustomProperty))) { + if (isCustomProperty) { + isCustomProperty = false; + } else { + isCustomProperty = true; + customExpressionCount = 1; + } + } + + if (customExpressionCount === 3) { + isCustomProperty = false; + customExpressionCount = 0; + } + if (i + 1 < this.args.length) { - output.add(', '); + if (!isCustomProperty) { + output.add(', '); + } else { + output.add(' '); + customExpressionCount++; + } } } diff --git a/packages/less/src/less/tree/custom-property.js b/packages/less/src/less/tree/custom-property.js index 3eaa284b9..993cf5ade 100644 --- a/packages/less/src/less/tree/custom-property.js +++ b/packages/less/src/less/tree/custom-property.js @@ -1,8 +1,9 @@ /* eslint-disable no-prototype-builtins */ import Node from './node'; -const CustomProperty = function (name, index, currentFileInfo) { +const CustomProperty = function (name, initialValue, index, currentFileInfo) { this.name = name; + this.initialValue = initialValue; this._index = index; this._fileInfo = currentFileInfo; }; @@ -11,7 +12,7 @@ CustomProperty.prototype = Object.assign(new Node(), { type: 'CustomProperty', genCSS: function (context, output) { - output.add('var(' + this.name + ')'); + output.add('var(' + this.name + (this.initialValue ? ', ' + this.initialValue : '') + ')'); } }); diff --git a/packages/less/src/less/tree/operation.js b/packages/less/src/less/tree/operation.js index 982d571d5..241da7ff7 100644 --- a/packages/less/src/less/tree/operation.js +++ b/packages/less/src/less/tree/operation.js @@ -3,6 +3,8 @@ import Color from './color'; import Dimension from './dimension'; import * as Constants from '../constants'; import Call from './call'; +import CustomProperty from './custom-property'; +import Anonymous from './anonymous'; const MATH = Constants.Math; @@ -38,6 +40,12 @@ Operation.prototype = Object.assign(new Node(), { if (b instanceof Dimension && a instanceof Color) { b = b.toColor(); } + if (a instanceof Dimension && b instanceof CustomProperty) { + return [a, new Anonymous(op), b]; + } + if (b instanceof Dimension && a instanceof CustomProperty) { + return [a, new Anonymous(op), b]; + } if (!a.operate || !b.operate) { if ( (a instanceof Operation || b instanceof Operation) @@ -78,7 +86,7 @@ Operation.prototype = Object.assign(new Node(), { }, evalVariable: function (context, operand) { - if (operand.name === 'var' && operand.args.length === 1) { + if (operand.name === 'var' && operand.args.length >= 1) { var varName = operand.args[0].toCSS(); var variable = this.find(context.frames, function (frame) { var v = frame.variable(varName); @@ -92,7 +100,7 @@ Operation.prototype = Object.assign(new Node(), { return (new Call('_SELF', [v.value])).eval(context); } else { - return v.value.eval(context); + return new CustomProperty(v.name, operand.args[1] ? operand.args[1].toCSS() : null, 0, {}); } } }); diff --git a/packages/test-data/css/_main/custom-property.css b/packages/test-data/css/_main/custom-property.css index 243947443..ad430c143 100644 --- a/packages/test-data/css/_main/custom-property.css +++ b/packages/test-data/css/_main/custom-property.css @@ -4,13 +4,21 @@ } .test2 { --some-var: 5%; - prop: min(95%, 10px); + prop: min(100% - var(--some-var), 10px); } .test3 { --some-var: 55%; - prop: min(60%, 15px); + prop: min(var(--some-var) + 5%, 15px); } .test4 { color: red; --other-color: green; } +.test5 { + --font-level: 5; + prop: var(--font-ratio-min), var(--font-level, 0); +} +.test6 { + --some-var: 5px; + prop: min(100% - var(--some-var, var(--somevar, 0)), 10px); +} diff --git a/packages/test-data/less/_main/custom-property.less b/packages/test-data/less/_main/custom-property.less index 960267dcd..b50bfcb58 100644 --- a/packages/test-data/less/_main/custom-property.less +++ b/packages/test-data/less/_main/custom-property.less @@ -17,3 +17,14 @@ color: red; --other-color: green; } + +.test5 { + --font-level: 5; + prop: pow(var(--font-ratio-min), var(--font-level, 0)) +} + + +.test6 { + --some-var: 5px; + prop: min(100% - var(--some-var, var(--somevar, 0)), 10px); +}