From ebdadaedac2ba2be377ae190060f9ca8086253a4 Mon Sep 17 00:00:00 2001 From: seven-phases-max Date: Wed, 18 Dec 2013 07:10:00 +0400 Subject: [PATCH] Experimental support for "property name interpolation", part-2. --- lib/less/parser.js | 39 ++++++++++++++++++++++++++++++--------- lib/less/tree/rule.js | 10 +++++++--- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/less/parser.js b/lib/less/parser.js index cff2fa86..59b8db55 100644 --- a/lib/less/parser.js +++ b/lib/less/parser.js @@ -1460,16 +1460,15 @@ less.Parser = function Parser(env) { if (name) { // prefer to try to parse first if its a variable or we are compressing // but always fallback on the other one - value = !tryAnonymous && (env.compress || (name.charAt(0) === '@')) ? + value = !tryAnonymous && (env.compress || (name.charAt && (name.charAt(0) === '@'))) ? (this.value() || this.anonymousValue()) : (this.anonymousValue() || this.value()); - important = this.important(); - if (name[name.length-1] === "+") { - merge = true; - name = name.substr(0, name.length - 1); - } + + // a name returned by this.ruleProperty() is always an array of the form: + // ["", "string-1", ..., "string-n", ""] or ["", "string-1", ..., "string-n", "+"] + merge = name.pop && (name.pop() === "+"); if (value && this.end()) { return new (tree.Rule)(name, value, important, merge, memo, env.currentFileInfo); @@ -1897,9 +1896,31 @@ less.Parser = function Parser(env) { } }, ruleProperty: function () { - var name = $re(/^(\*?-?[_a-zA-Z0-9-]+)\s*(\+?)\s*:/); - if (name) { - return name[1] + (name[2] || ""); + var c = current, name = [], index = [], length = 0; + + function match(re) { + var a = re.exec(c); + if (a) { + index.push(i + length); + length += a[0].length; + c = c.slice(a[1].length); + return name.push(a[1]); + } + } + + match(/^(\*?)/); + while (match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)); // ! + if ((name.length > 1) && match(/^\s*(\+?)\s*:/)) { + // at last, we have the complete match now. move forward, + // convert @{var}s to tree.Variable(s) and return: + skipWhitespace(length); + for (var k in name) { + if (name[k].charAt(0) === '@') { + name[k] = new tree.Variable('@' + name[k].slice(2, -1), + index[k], env.currentFileInfo); + } + } + return name; } } } diff --git a/lib/less/tree/rule.js b/lib/less/tree/rule.js index 029befb3..3ef22733 100644 --- a/lib/less/tree/rule.js +++ b/lib/less/tree/rule.js @@ -8,7 +8,7 @@ tree.Rule = function (name, value, important, merge, index, currentFileInfo, inl this.index = index; this.currentFileInfo = currentFileInfo; this.inline = inline || false; - this.variable = (name.charAt(0) === '@'); + this.variable = name.charAt && (name.charAt(0) === '@'); }; tree.Rule.prototype = { @@ -31,12 +31,16 @@ tree.Rule.prototype = { toCSS: tree.toCSS, eval: function (env) { var strictMathBypass = false; - if (this.name === "font" && !env.strictMath) { + var name = this.name.map ? + this.name.map( function(v) { + return v.eval ? v.eval(env).value : v; + }).join('') : this.name; + if (name === "font" && !env.strictMath) { strictMathBypass = true; env.strictMath = true; } try { - return new(tree.Rule)(this.name, + return new(tree.Rule)(name, this.value.eval(env), this.important, this.merge,