Skip to content

Commit

Permalink
Fixes #3191 (#3223)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew-dean authored Jun 25, 2018
1 parent 8fbad0c commit 7a12d2f
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 7 deletions.
16 changes: 16 additions & 0 deletions lib/less/contexts.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ contexts.Eval = function(options, frames) {
this.importantScope = this.importantScope || [];
};

contexts.Eval.prototype.enterCalc = function () {
if (!this.calcStack) {
this.calcStack = [];
}
this.calcStack.push(true);
this.inCalc = true;
};

contexts.Eval.prototype.exitCalc = function () {
this.calcStack.pop();
if (!this.calcStack) {
this.inCalc = false;
}
};

contexts.Eval.prototype.inParenthesis = function () {
if (!this.parensStack) {
this.parensStack = [];
Expand All @@ -73,6 +88,7 @@ contexts.Eval.prototype.outOfParenthesis = function () {
this.parensStack.pop();
};

contexts.Eval.prototype.inCalc = false;
contexts.Eval.prototype.mathOn = true;
contexts.Eval.prototype.isMathOn = function () {
if (!this.mathOn) {
Expand Down
8 changes: 6 additions & 2 deletions lib/less/parser/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,13 +351,17 @@ var Parser = function Parser(context, imports, fileInfo) {
//
// "milky way" 'he\'s the one!'
//
quoted: function () {
quoted: function (forceEscaped) {
var str, index = parserInput.i, isEscaped = false;

parserInput.save();
if (parserInput.$char('~')) {
isEscaped = true;
} else if (forceEscaped) {
parserInput.restore();
return;
}

str = parserInput.$quoted();
if (!str) {
parserInput.restore();
Expand Down Expand Up @@ -1938,7 +1942,7 @@ var Parser = function Parser(context, imports, fileInfo) {
var o = this.sub() || entities.dimension() ||
entities.color() || entities.variable() ||
entities.property() || entities.call() ||
entities.colorKeyword();
entities.quoted(true) || entities.colorKeyword();

if (negate) {
o.parensInOp = true;
Expand Down
11 changes: 8 additions & 3 deletions lib/less/tree/call.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var Node = require('./node'),
var Call = function (name, args, index, currentFileInfo) {
this.name = name;
this.args = args;
this.mathOn = name === 'calc' ? false : true;
this.calc = name === 'calc';
this._index = index;
this._fileInfo = currentFileInfo;
};
Expand All @@ -30,13 +30,18 @@ Call.prototype.accept = function (visitor) {
// The function should receive the value, not the variable.
//
Call.prototype.eval = function (context) {

/**
* Turn off math for calc(), and switch back on for evaluating nested functions
*/
var currentMathContext = context.mathOn;
context.mathOn = this.mathOn;
context.mathOn = !this.calc;
if (this.calc || context.inCalc) {
context.enterCalc();
}
var args = this.args.map(function (a) { return a.eval(context); });
if (this.calc || context.inCalc) {
context.exitCalc();
}
context.mathOn = currentMathContext;

var result, funcCaller = new FunctionCaller(this.name, context, this.getIndex(), this.fileInfo());
Expand Down
5 changes: 3 additions & 2 deletions lib/less/tree/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Expression.prototype.accept = function (visitor) {
};
Expression.prototype.eval = function (context) {
var returnValue,
mathOn = context.isMathOn(),
inParenthesis = this.parens && !this.parensInOp,
doubleParen = false;
if (inParenthesis) {
Expand All @@ -26,7 +27,7 @@ Expression.prototype.eval = function (context) {
return e.eval(context);
}), this.noSpacing);
} else if (this.value.length === 1) {
if (this.value[0].parens && !this.value[0].parensInOp) {
if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {
doubleParen = true;
}
returnValue = this.value[0].eval(context);
Expand All @@ -36,7 +37,7 @@ Expression.prototype.eval = function (context) {
if (inParenthesis) {
context.outOfParenthesis();
}
if (this.parens && this.parensInOp && !(context.isMathOn()) && !doubleParen) {
if (this.parens && this.parensInOp && !mathOn && !doubleParen) {
returnValue = new Paren(returnValue);
}
return returnValue;
Expand Down
12 changes: 12 additions & 0 deletions test/css/calc.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
.no-math {
width: calc(50% + (25vh - 20px));
height: calc(50% + (25vh - 20px));
min-height: calc((10vh) + calc(5vh));
foo: 3 calc(3 + 4) 11;
bar: calc(1 + 20%);
}
.b {
one: calc(100% - (20px));
two: calc(100% - (10px + 10px));
three: calc(100% - (3 * 1));
four: calc(100% - (3 * 1));
nested: calc(calc(2.25rem + 2px) - 1px * 2);
}
.c {
height: calc(100% - ((10px * 3) + (10px * 2)));
}
18 changes: 18 additions & 0 deletions test/less/calc.less
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
.no-math {
@var: 50vh/2;
width: calc(50% + (@var - 20px));
height: calc(50% + ((@var - 20px)));
min-height: calc(((10vh)) + calc((5vh)));
foo: 1 + 2 calc(3 + 4) 5 + 6;
@floor: floor(1 + .1);
bar: calc(@floor + 20%);
}

.b {
@a: 10px;
@b: 10px;

one: calc(100% - ((min(@a + @b))));
two: calc(100% - (((@a + @b))));
three: calc(e('100%') - (3 * 1));
four: calc(~'100%' - (3 * 1));
nested: calc(calc(2.25rem + 2px) - 1px * 2);
}

.c {
@v: 10px;
height: calc(100% - ((@v * 3) + (@v * 2)));
}

0 comments on commit 7a12d2f

Please sign in to comment.