Skip to content

Commit 6c2c0fd

Browse files
authored
Allow [] to resolve to last declaration's value (#3256)
1 parent d821a37 commit 6c2c0fd

26 files changed

+42
-11
lines changed

lib/less/parser/parser.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ var Parser = function Parser(context, imports, fileInfo) {
11211121
parserInput.save();
11221122
args = null;
11231123
rule = this.lookupValue();
1124-
if (!rule) {
1124+
if (!rule && rule !== '') {
11251125
parserInput.restore();
11261126
break;
11271127
}
@@ -1141,14 +1141,14 @@ var Parser = function Parser(context, imports, fileInfo) {
11411141
return;
11421142
}
11431143

1144-
var name = parserInput.$re(/^(?:@{0,2}|\$)[_a-zA-Z0-9-]+/);
1144+
var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);
11451145

11461146
if (!parserInput.$char(']')) {
11471147
parserInput.restore();
11481148
return;
11491149
}
11501150

1151-
if (name) {
1151+
if (name || name === '') {
11521152
parserInput.forget();
11531153
return name;
11541154
}

lib/less/tree/namespace-value.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,24 @@ var NamespaceValue = function (ruleCall, lookups, important, index, fileInfo) {
1313
NamespaceValue.prototype = new Node();
1414
NamespaceValue.prototype.type = 'NamespaceValue';
1515
NamespaceValue.prototype.eval = function (context) {
16-
var i, j, name, found,
17-
rules = this.value.eval(context);
16+
var i, j, name, rules = this.value.eval(context);
1817

1918
for (i = 0; i < this.lookups.length; i++) {
2019
name = this.lookups[i];
2120

2221
/**
2322
* Eval'd DRs return rulesets.
2423
* Eval'd mixins return rules, so let's make a ruleset if we need it.
25-
* We need to do this because of late parsing of properties
24+
* We need to do this because of late parsing of values
2625
*/
2726
if (Array.isArray(rules)) {
2827
rules = new Ruleset([new Selector()], rules);
2928
}
3029

31-
if (name.charAt(0) === '@') {
30+
if (name === '') {
31+
rules = rules.lastDeclaration();
32+
}
33+
else if (name.charAt(0) === '@') {
3234
if (name.charAt(1) === '@') {
3335
name = '@' + new Variable(name.substr(1)).eval(context).value;
3436
}
@@ -44,13 +46,19 @@ NamespaceValue.prototype.eval = function (context) {
4446
}
4547
}
4648
else {
49+
if (name.substring(0, 2) === '$@') {
50+
name = '$' + new Variable(name.substr(1)).eval(context).value;
51+
}
52+
else {
53+
name = name.charAt(0) === '$' ? name : '$' + name;
54+
}
4755
if (rules.properties) {
48-
rules = rules.property(name.charAt(0) === '$' ? name : '$' + name);
56+
rules = rules.property(name);
4957
}
5058

5159
if (!rules) {
5260
throw { type: 'Name',
53-
message: 'property "' + name + '" not found',
61+
message: 'property "' + name.substr(1) + '" not found',
5462
filename: this.fileInfo().filename,
5563
index: this.getIndex() };
5664
}

lib/less/tree/ruleset.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,14 @@ Ruleset.prototype.property = function (name) {
318318
return this.parseValue(decl);
319319
}
320320
};
321+
Ruleset.prototype.lastDeclaration = function () {
322+
for (var i = this.rules.length; i > 0; i--) {
323+
var decl = this.rules[i - 1];
324+
if (decl instanceof Declaration) {
325+
return this.parseValue(decl);
326+
}
327+
}
328+
};
321329
Ruleset.prototype.parseValue = function(toParse) {
322330
var self = this;
323331
function transformDeclaration(decl) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.foo {
2+
width: 20px;
3+
bar: val;
4+
}

test/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ console.log('\n' + stylize('Less', 'underline') + '\n');
77

88
lessTester.prepBomTest();
99
var testMap = [
10-
[{}, 'edge/'],
10+
[{}, 'namespacing/'],
1111
[{
1212
strictMath: false,
1313
relativeUrls: true,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.add(@a, @b) {
2+
@r: @a + @b;
3+
}
4+
.foo {
5+
width: .add(10px, 10px)[];
6+
bar: @return[];
7+
}
8+
9+
@return: {
10+
single: val;
11+
}

test/less/edge/namespacing-media.less renamed to test/less/namespacing/namespacing-media.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
keyword: small;
2020
}
2121

22-
@media #ns.breakpoint(.valToGet[keyword])[@max] {
22+
@media #ns.breakpoint(.valToGet[])[@max] {
2323
.selector {
2424
prop: val;
2525
}

0 commit comments

Comments
 (0)