diff --git a/lib/less/functions.js b/lib/less/functions.js index 96dcc8c4c..42acc7545 100644 --- a/lib/less/functions.js +++ b/lib/less/functions.js @@ -158,6 +158,9 @@ tree.functions = { argb: function (color) { return new(tree.Anonymous)(color.toARGB()); + }, + fluid: function(target, container){ + return new tree.Dimension((target.value / container.value) * 100.0, '%'); } }; diff --git a/lib/less/parser.js b/lib/less/parser.js index fe9df0f0f..4eb6f2951 100644 --- a/lib/less/parser.js +++ b/lib/less/parser.js @@ -972,7 +972,14 @@ less.Parser = function Parser(env) { if (value = $(this['import'])) { return value; - } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-)?keyframes/)) { + } else if (name = $(/^@media/)) { + var nodes = [], n; + while(n = $(this.entity) || $(/^[\(|\)|:]/)) { + nodes.push( (typeof n == 'string'? new tree.Keyword(n):n)); + } + rules = $(this.block); + return new(tree.Directive)(name, rules, nodes); + } else if (name = $(/^@page/) || $(/^@(?:-webkit-|-moz-)?keyframes/)) { types = ($(/^[^{]+/) || '').trim(); if (rules = $(this.block)) { return new(tree.Directive)(name + " " + types, rules); diff --git a/lib/less/tree/directive.js b/lib/less/tree/directive.js index 0e8df2437..e7afc1330 100644 --- a/lib/less/tree/directive.js +++ b/lib/less/tree/directive.js @@ -1,25 +1,39 @@ (function (tree) { -tree.Directive = function (name, value) { +tree.Directive = function (name, value, nodes) { this.name = name; if (Array.isArray(value)) { this.ruleset = new(tree.Ruleset)([], value); } else { this.value = value; } + this.nodes = (typeof(nodes) != 'undefined' ? nodes : null); }; tree.Directive.prototype = { toCSS: function (ctx, env) { + var node_css = ''; + if(this.nodes) { + for(var n in this.nodes) { + node_css += ' ' + this.nodes[n].toCSS(ctx, env) ; + } + /* Remove extra spaces in query synax so unit tests pass */ + node_css = node_css.replace(/\(\s+([^\s]+)\s+:\s+([^\s]+)\s\)/g,'($1:$2)'); + } if (this.ruleset) { this.ruleset.root = true; - return this.name + (env.compress ? '{' : ' {\n ') + + return this.name + node_css +(env.compress ? '{' : ' {\n ') + this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') + (env.compress ? '}': '\n}\n'); } else { - return this.name + ' ' + this.value.toCSS() + ';\n'; + return this.name + node_css + ' ' + this.value.toCSS() + ';\n'; } }, eval: function (env) { + if(this.nodes) { + for(var i = 0; i < this.nodes.length; i++) { + this.nodes[i] = this.nodes[i].eval(env); + } + } env.frames.unshift(this); this.ruleset = this.ruleset && this.ruleset.eval(env); env.frames.shift(); diff --git a/test/css/functions.css b/test/css/functions.css index f33b9869b..94471809d 100644 --- a/test/css/functions.css +++ b/test/css/functions.css @@ -4,6 +4,7 @@ height: undefined("self"); border-width: 5; variable: 11; + padding: 5%; } #built-in { escaped: -Some::weird(#thing, y); diff --git a/test/css/media.css b/test/css/media.css index 13b6be0af..e162abdb0 100644 --- a/test/css/media.css +++ b/test/css/media.css @@ -19,3 +19,8 @@ float: none; } } +@media screen and (min-width:42) { + div { + color: #222; + } +} diff --git a/test/less/functions.less b/test/less/functions.less index 1af78bc80..867187be3 100644 --- a/test/less/functions.less +++ b/test/less/functions.less @@ -5,6 +5,7 @@ height: undefined("self"); border-width: add(2, 3); variable: increment(@var); + padding: fluid(10px, 200px); } #built-in { diff --git a/test/less/media.less b/test/less/media.less index 0b08a5918..0c0cd2c12 100644 --- a/test/less/media.less +++ b/test/less/media.less @@ -23,3 +23,6 @@ @media all and (orientation:portrait) { aside { float: none; } } +@media screen and (min-width: @var) { + div { color: #222; } +}