From 13c1cb1e407ad2628c97c429270d52aea230891c Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Mon, 2 Jul 2018 22:01:20 -0700 Subject: [PATCH] Allow [] to resolve to last declaration's value --- lib/less/parser/parser.js | 6 +++--- lib/less/tree/namespace-value.js | 20 +++++++++++++------ lib/less/tree/ruleset.js | 8 ++++++++ .../{edge => namespacing}/namespacing-1.css | 0 .../{edge => namespacing}/namespacing-2.css | 0 .../{edge => namespacing}/namespacing-3.css | 0 .../{edge => namespacing}/namespacing-4.css | 0 .../{edge => namespacing}/namespacing-5.css | 0 .../{edge => namespacing}/namespacing-6.css | 0 .../{edge => namespacing}/namespacing-7.css | 0 .../css/namespacing/namespacing-functions.css | 4 ++++ .../namespacing-media.css | 0 .../namespacing-operations.css | 0 test/index.js | 2 +- .../imports/a-better-bootstrap.less | 0 .../imports/library.less | 0 .../{edge => namespacing}/namespacing-1.less | 0 .../{edge => namespacing}/namespacing-2.less | 0 .../{edge => namespacing}/namespacing-3.less | 0 .../{edge => namespacing}/namespacing-4.less | 0 .../{edge => namespacing}/namespacing-5.less | 0 .../{edge => namespacing}/namespacing-6.less | 0 .../{edge => namespacing}/namespacing-7.less | 0 .../namespacing/namespacing-functions.less | 11 ++++++++++ .../namespacing-media.less | 2 +- .../namespacing-operations.less | 0 26 files changed, 42 insertions(+), 11 deletions(-) rename test/css/{edge => namespacing}/namespacing-1.css (100%) rename test/css/{edge => namespacing}/namespacing-2.css (100%) rename test/css/{edge => namespacing}/namespacing-3.css (100%) rename test/css/{edge => namespacing}/namespacing-4.css (100%) rename test/css/{edge => namespacing}/namespacing-5.css (100%) rename test/css/{edge => namespacing}/namespacing-6.css (100%) rename test/css/{edge => namespacing}/namespacing-7.css (100%) create mode 100644 test/css/namespacing/namespacing-functions.css rename test/css/{edge => namespacing}/namespacing-media.css (100%) rename test/css/{edge => namespacing}/namespacing-operations.css (100%) rename test/less/{edge => namespacing}/imports/a-better-bootstrap.less (100%) rename test/less/{edge => namespacing}/imports/library.less (100%) rename test/less/{edge => namespacing}/namespacing-1.less (100%) rename test/less/{edge => namespacing}/namespacing-2.less (100%) rename test/less/{edge => namespacing}/namespacing-3.less (100%) rename test/less/{edge => namespacing}/namespacing-4.less (100%) rename test/less/{edge => namespacing}/namespacing-5.less (100%) rename test/less/{edge => namespacing}/namespacing-6.less (100%) rename test/less/{edge => namespacing}/namespacing-7.less (100%) create mode 100644 test/less/namespacing/namespacing-functions.less rename test/less/{edge => namespacing}/namespacing-media.less (84%) rename test/less/{edge => namespacing}/namespacing-operations.less (100%) diff --git a/lib/less/parser/parser.js b/lib/less/parser/parser.js index 0a5f14ade..f7bc4ad59 100644 --- a/lib/less/parser/parser.js +++ b/lib/less/parser/parser.js @@ -1121,7 +1121,7 @@ var Parser = function Parser(context, imports, fileInfo) { parserInput.save(); args = null; rule = this.lookupValue(); - if (!rule) { + if (!rule && rule !== '') { parserInput.restore(); break; } @@ -1141,14 +1141,14 @@ var Parser = function Parser(context, imports, fileInfo) { return; } - var name = parserInput.$re(/^(?:@{0,2}|\$)[_a-zA-Z0-9-]+/); + var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/); if (!parserInput.$char(']')) { parserInput.restore(); return; } - if (name) { + if (name || name === '') { parserInput.forget(); return name; } diff --git a/lib/less/tree/namespace-value.js b/lib/less/tree/namespace-value.js index f8c07ecfe..3ef109cc9 100644 --- a/lib/less/tree/namespace-value.js +++ b/lib/less/tree/namespace-value.js @@ -13,8 +13,7 @@ var NamespaceValue = function (ruleCall, lookups, important, index, fileInfo) { NamespaceValue.prototype = new Node(); NamespaceValue.prototype.type = 'NamespaceValue'; NamespaceValue.prototype.eval = function (context) { - var i, j, name, found, - rules = this.value.eval(context); + var i, j, name, rules = this.value.eval(context); for (i = 0; i < this.lookups.length; i++) { name = this.lookups[i]; @@ -22,13 +21,16 @@ NamespaceValue.prototype.eval = function (context) { /** * Eval'd DRs return rulesets. * Eval'd mixins return rules, so let's make a ruleset if we need it. - * We need to do this because of late parsing of properties + * We need to do this because of late parsing of values */ if (Array.isArray(rules)) { rules = new Ruleset([new Selector()], rules); } - if (name.charAt(0) === '@') { + if (name === '') { + rules = rules.lastDeclaration(); + } + else if (name.charAt(0) === '@') { if (name.charAt(1) === '@') { name = '@' + new Variable(name.substr(1)).eval(context).value; } @@ -44,13 +46,19 @@ NamespaceValue.prototype.eval = function (context) { } } else { + if (name.substring(0, 2) === '$@') { + name = '$' + new Variable(name.substr(1)).eval(context).value; + } + else { + name = name.charAt(0) === '$' ? name : '$' + name; + } if (rules.properties) { - rules = rules.property(name.charAt(0) === '$' ? name : '$' + name); + rules = rules.property(name); } if (!rules) { throw { type: 'Name', - message: 'property "' + name + '" not found', + message: 'property "' + name.substr(1) + '" not found', filename: this.fileInfo().filename, index: this.getIndex() }; } diff --git a/lib/less/tree/ruleset.js b/lib/less/tree/ruleset.js index 565db6849..89622afb6 100644 --- a/lib/less/tree/ruleset.js +++ b/lib/less/tree/ruleset.js @@ -318,6 +318,14 @@ Ruleset.prototype.property = function (name) { return this.parseValue(decl); } }; +Ruleset.prototype.lastDeclaration = function () { + for (var i = this.rules.length; i > 0; i--) { + var decl = this.rules[i - 1]; + if (decl instanceof Declaration) { + return this.parseValue(decl); + } + } +}; Ruleset.prototype.parseValue = function(toParse) { var self = this; function transformDeclaration(decl) { diff --git a/test/css/edge/namespacing-1.css b/test/css/namespacing/namespacing-1.css similarity index 100% rename from test/css/edge/namespacing-1.css rename to test/css/namespacing/namespacing-1.css diff --git a/test/css/edge/namespacing-2.css b/test/css/namespacing/namespacing-2.css similarity index 100% rename from test/css/edge/namespacing-2.css rename to test/css/namespacing/namespacing-2.css diff --git a/test/css/edge/namespacing-3.css b/test/css/namespacing/namespacing-3.css similarity index 100% rename from test/css/edge/namespacing-3.css rename to test/css/namespacing/namespacing-3.css diff --git a/test/css/edge/namespacing-4.css b/test/css/namespacing/namespacing-4.css similarity index 100% rename from test/css/edge/namespacing-4.css rename to test/css/namespacing/namespacing-4.css diff --git a/test/css/edge/namespacing-5.css b/test/css/namespacing/namespacing-5.css similarity index 100% rename from test/css/edge/namespacing-5.css rename to test/css/namespacing/namespacing-5.css diff --git a/test/css/edge/namespacing-6.css b/test/css/namespacing/namespacing-6.css similarity index 100% rename from test/css/edge/namespacing-6.css rename to test/css/namespacing/namespacing-6.css diff --git a/test/css/edge/namespacing-7.css b/test/css/namespacing/namespacing-7.css similarity index 100% rename from test/css/edge/namespacing-7.css rename to test/css/namespacing/namespacing-7.css diff --git a/test/css/namespacing/namespacing-functions.css b/test/css/namespacing/namespacing-functions.css new file mode 100644 index 000000000..78ea7b177 --- /dev/null +++ b/test/css/namespacing/namespacing-functions.css @@ -0,0 +1,4 @@ +.foo { + width: 20px; + bar: val; +} diff --git a/test/css/edge/namespacing-media.css b/test/css/namespacing/namespacing-media.css similarity index 100% rename from test/css/edge/namespacing-media.css rename to test/css/namespacing/namespacing-media.css diff --git a/test/css/edge/namespacing-operations.css b/test/css/namespacing/namespacing-operations.css similarity index 100% rename from test/css/edge/namespacing-operations.css rename to test/css/namespacing/namespacing-operations.css diff --git a/test/index.js b/test/index.js index 3b14cd811..ebc533ce9 100644 --- a/test/index.js +++ b/test/index.js @@ -7,7 +7,7 @@ console.log('\n' + stylize('Less', 'underline') + '\n'); lessTester.prepBomTest(); var testMap = [ - [{}, 'edge/'], + [{}, 'namespacing/'], [{ strictMath: false, relativeUrls: true, diff --git a/test/less/edge/imports/a-better-bootstrap.less b/test/less/namespacing/imports/a-better-bootstrap.less similarity index 100% rename from test/less/edge/imports/a-better-bootstrap.less rename to test/less/namespacing/imports/a-better-bootstrap.less diff --git a/test/less/edge/imports/library.less b/test/less/namespacing/imports/library.less similarity index 100% rename from test/less/edge/imports/library.less rename to test/less/namespacing/imports/library.less diff --git a/test/less/edge/namespacing-1.less b/test/less/namespacing/namespacing-1.less similarity index 100% rename from test/less/edge/namespacing-1.less rename to test/less/namespacing/namespacing-1.less diff --git a/test/less/edge/namespacing-2.less b/test/less/namespacing/namespacing-2.less similarity index 100% rename from test/less/edge/namespacing-2.less rename to test/less/namespacing/namespacing-2.less diff --git a/test/less/edge/namespacing-3.less b/test/less/namespacing/namespacing-3.less similarity index 100% rename from test/less/edge/namespacing-3.less rename to test/less/namespacing/namespacing-3.less diff --git a/test/less/edge/namespacing-4.less b/test/less/namespacing/namespacing-4.less similarity index 100% rename from test/less/edge/namespacing-4.less rename to test/less/namespacing/namespacing-4.less diff --git a/test/less/edge/namespacing-5.less b/test/less/namespacing/namespacing-5.less similarity index 100% rename from test/less/edge/namespacing-5.less rename to test/less/namespacing/namespacing-5.less diff --git a/test/less/edge/namespacing-6.less b/test/less/namespacing/namespacing-6.less similarity index 100% rename from test/less/edge/namespacing-6.less rename to test/less/namespacing/namespacing-6.less diff --git a/test/less/edge/namespacing-7.less b/test/less/namespacing/namespacing-7.less similarity index 100% rename from test/less/edge/namespacing-7.less rename to test/less/namespacing/namespacing-7.less diff --git a/test/less/namespacing/namespacing-functions.less b/test/less/namespacing/namespacing-functions.less new file mode 100644 index 000000000..4be4ce914 --- /dev/null +++ b/test/less/namespacing/namespacing-functions.less @@ -0,0 +1,11 @@ +.add(@a, @b) { + @r: @a + @b; +} +.foo { + width: .add(10px, 10px)[]; + bar: @return[]; +} + +@return: { + single: val; +} \ No newline at end of file diff --git a/test/less/edge/namespacing-media.less b/test/less/namespacing/namespacing-media.less similarity index 84% rename from test/less/edge/namespacing-media.less rename to test/less/namespacing/namespacing-media.less index 8cfe574cd..c23fdbb16 100644 --- a/test/less/edge/namespacing-media.less +++ b/test/less/namespacing/namespacing-media.less @@ -19,7 +19,7 @@ keyword: small; } -@media #ns.breakpoint(.valToGet[keyword])[@max] { +@media #ns.breakpoint(.valToGet[])[@max] { .selector { prop: val; } diff --git a/test/less/edge/namespacing-operations.less b/test/less/namespacing/namespacing-operations.less similarity index 100% rename from test/less/edge/namespacing-operations.less rename to test/less/namespacing/namespacing-operations.less