Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* Don't escape quotes in an each #3354

* Fixes #3346 - ambiguous mixin call / color parsing

* Fixes #3338 - better error message

* Fixes #3338 - missed mix() function

* Fixes #3345
  • Loading branch information
matthew-dean authored Jul 11, 2019
1 parent 162327a commit 88e126b
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 26 deletions.
52 changes: 32 additions & 20 deletions lib/less/functions/color.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ function hsla(origColor, hsl) {
return color;
}
}
function toHSL(color) {
if (color.toHSL) {
return color.toHSL();
} else {
throw new Error('Argument cannot be evaluated to a color');
}
}

function toHSV(color) {
if (color.toHSV) {
return color.toHSV();
} else {
throw new Error('Argument cannot be evaluated to a color');
}
}

function number(n) {
if (n instanceof Dimension) {
return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);
Expand Down Expand Up @@ -146,22 +162,22 @@ colorFunctions = {
},

hue: function (color) {
return new Dimension(color.toHSL().h);
return new Dimension(toHSL(color).h);
},
saturation: function (color) {
return new Dimension(color.toHSL().s * 100, '%');
return new Dimension(toHSL(color).s * 100, '%');
},
lightness: function (color) {
return new Dimension(color.toHSL().l * 100, '%');
return new Dimension(toHSL(color).l * 100, '%');
},
hsvhue: function(color) {
return new Dimension(color.toHSV().h);
return new Dimension(toHSV(color).h);
},
hsvsaturation: function (color) {
return new Dimension(color.toHSV().s * 100, '%');
return new Dimension(toHSV(color).s * 100, '%');
},
hsvvalue: function (color) {
return new Dimension(color.toHSV().v * 100, '%');
return new Dimension(toHSV(color).v * 100, '%');
},
red: function (color) {
return new Dimension(color.rgb[0]);
Expand All @@ -173,7 +189,7 @@ colorFunctions = {
return new Dimension(color.rgb[2]);
},
alpha: function (color) {
return new Dimension(color.toHSL().a);
return new Dimension(toHSL(color).a);
},
luma: function (color) {
return new Dimension(color.luma() * color.alpha * 100, '%');
Expand All @@ -192,7 +208,7 @@ colorFunctions = {
if (!color.rgb) {
return null;
}
var hsl = color.toHSL();
var hsl = toHSL(color);

if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.s += hsl.s * amount.value / 100;
Expand All @@ -204,7 +220,7 @@ colorFunctions = {
return hsla(color, hsl);
},
desaturate: function (color, amount, method) {
var hsl = color.toHSL();
var hsl = toHSL(color);

if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.s -= hsl.s * amount.value / 100;
Expand All @@ -216,7 +232,7 @@ colorFunctions = {
return hsla(color, hsl);
},
lighten: function (color, amount, method) {
var hsl = color.toHSL();
var hsl = toHSL(color);

if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.l += hsl.l * amount.value / 100;
Expand All @@ -228,7 +244,7 @@ colorFunctions = {
return hsla(color, hsl);
},
darken: function (color, amount, method) {
var hsl = color.toHSL();
var hsl = toHSL(color);

if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.l -= hsl.l * amount.value / 100;
Expand All @@ -240,7 +256,7 @@ colorFunctions = {
return hsla(color, hsl);
},
fadein: function (color, amount, method) {
var hsl = color.toHSL();
var hsl = toHSL(color);

if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.a += hsl.a * amount.value / 100;
Expand All @@ -252,7 +268,7 @@ colorFunctions = {
return hsla(color, hsl);
},
fadeout: function (color, amount, method) {
var hsl = color.toHSL();
var hsl = toHSL(color);

if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.a -= hsl.a * amount.value / 100;
Expand All @@ -264,14 +280,14 @@ colorFunctions = {
return hsla(color, hsl);
},
fade: function (color, amount) {
var hsl = color.toHSL();
var hsl = toHSL(color);

hsl.a = amount.value / 100;
hsl.a = clamp(hsl.a);
return hsla(color, hsl);
},
spin: function (color, amount) {
var hsl = color.toHSL();
var hsl = toHSL(color);
var hue = (hsl.h + amount.value) % 360;

hsl.h = hue < 0 ? 360 + hue : hue;
Expand All @@ -283,16 +299,12 @@ colorFunctions = {
// http://sass-lang.com
//
mix: function (color1, color2, weight) {
if (!color1.toHSL || !color2.toHSL) {
console.log(color2.type);
console.dir(color2);
}
if (!weight) {
weight = new Dimension(50);
}
var p = weight.value / 100.0;
var w = p * 2 - 1;
var a = color1.toHSL().a - color2.toHSL().a;
var a = toHSL(color1).a - toHSL(color2).a;

var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
var w2 = 1 - w1;
Expand Down
3 changes: 2 additions & 1 deletion lib/less/functions/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var Comment = require('../tree/comment'),
Ruleset = require('../tree/ruleset'),
Selector = require('../tree/selector'),
Element = require('../tree/element'),
Quote = require('../tree/quoted'),
functionRegistry = require('./function-registry');

var getItemsFromNode = function(node) {
Expand Down Expand Up @@ -59,7 +60,7 @@ functionRegistry.addMultiple({
each: function(list, rs) {
var rules = [], newRules, iterator;

if (list.value) {
if (list.value && !(list instanceof Quote)) {
if (Array.isArray(list.value)) {
iterator = list.value;
} else {
Expand Down
3 changes: 2 additions & 1 deletion lib/less/functions/string.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
var Quoted = require('../tree/quoted'),
Anonymous = require('../tree/anonymous'),
Quote = require('../tree/quoted'),
JavaScript = require('../tree/javascript'),
functionRegistry = require('./function-registry');

functionRegistry.addMultiple({
e: function (str) {
return new Anonymous(str instanceof JavaScript ? str.evaluated : str.value);
return new Quote('"', str instanceof JavaScript ? str.evaluated : str.value, true);
},
escape: function (str) {
return new Anonymous(
Expand Down
9 changes: 7 additions & 2 deletions lib/less/parser/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,15 @@ var Parser = function Parser(context, imports, fileInfo) {
//
color: function () {
var rgb;
parserInput.save();

if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})/))) {
return new(tree.Color)(rgb[1], undefined, rgb[0]);
if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) {
if (!rgb[2]) {
parserInput.forget();
return new(tree.Color)(rgb[1], undefined, rgb[0]);
}
}
parserInput.restore();
},

colorKeyword: function () {
Expand Down
2 changes: 1 addition & 1 deletion lib/less/tree/quoted.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Quoted.prototype.eval = function (context) {
function iterativeReplace(value, regexp, replacementFnc) {
var evaluatedValue = value;
do {
value = evaluatedValue;
value = evaluatedValue.toString();
evaluatedValue = value.replace(regexp, replacementFnc);
} while (value !== evaluatedValue);
return evaluatedValue;
Expand Down
10 changes: 10 additions & 0 deletions test/css/functions-each.css
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,13 @@
.bar {
content: blue;
}
span {
content: 'foo';
content: 'bar';
}
div {
content: 'foo';
}
.a .w-1 {
width: 90 100 110;
}
4 changes: 4 additions & 0 deletions test/css/namespacing/namespacing-1.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@
#ns1 {
foo: uno;
}
.button {
color: grey;
border-color: #AAA #CCC;
}
2 changes: 1 addition & 1 deletion test/less/colors.less
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,4 @@
test-12: hsla(#5F59, 0.5);
--semi-transparent-dark-background: #001e00ee;
--semi-transparent-dark-background-2: rgba(0, 30, 0, 238); // invalid opacity will be capped
}
}
2 changes: 2 additions & 0 deletions test/less/errors/color-func-invalid-color-2.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// https://github.com/less/less.js/issues/3338
@base-color: darken(var(--baseColor, red), 50%);
3 changes: 3 additions & 0 deletions test/less/errors/color-func-invalid-color-2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RuntimeError: error evaluating function `darken`: Argument cannot be evaluated to a color in {path}color-func-invalid-color-2.less on line 2, column 14:
1 // https://github.com/less/less.js/issues/3338
2 @base-color: darken(var(--baseColor, red), 50%);
32 changes: 32 additions & 0 deletions test/less/functions-each.less
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,35 @@ each(@one[@two], {
content: @value;
}
});

// https://github.com/less/less.js/issues/3354
.log(@msgs) {
each(@msgs; {
content: @value;
});
}

@messages: 'foo', 'bar';

span {
.log(@messages);
}

div {
.log('foo');
}

// https://github.com/less/less.js/issues/3345
.mixin-create-width-style() {
@list: e("90 100 110");

each(@list, {
.w-@{key} {
width: @value;
}
})
}

.a {
.mixin-create-width-style();
}
10 changes: 10 additions & 0 deletions test/less/namespacing/namespacing-1.less
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,14 @@
.vars() {
sub: tres;
}
}

// https://github.com/less/less.js/issues/3346
#DEF() {
.colors() { primary: grey; }
}

.button {
color: #DEF.colors[primary];
border-color: #AAA #CCC;
}

0 comments on commit 88e126b

Please sign in to comment.