From 36c307240ab29dc9e00cd1cffd0ad54d4b806b83 Mon Sep 17 00:00:00 2001 From: Marcel Jackwerth Date: Sun, 6 Jan 2013 22:23:35 +0100 Subject: [PATCH] Added support for default variables You can now define default variables via `@var: 1px !default;`. It will behave as `@var: 1px;` if `@var` hasnt't been defined yet. Otherwise it will be ignored. This is useful for frameworks (e.g. Bootstrap) which need to define variables to work but want to allow the user of the framework to change them without messing with the internal less-stylesheets. --- lib/less/parser.js | 10 ++++++++-- lib/less/tree/rule.js | 15 +++++++++++---- lib/less/tree/ruleset.js | 4 +++- test/css/variables.css | 4 ++++ test/less/variables.less | 9 +++++++++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lib/less/parser.js b/lib/less/parser.js index c8c280b43..03a1429ff 100644 --- a/lib/less/parser.js +++ b/lib/less/parser.js @@ -1155,7 +1155,7 @@ less.Parser = function Parser(env) { } }, rule: function () { - var name, value, c = input.charAt(i), important, match; + var name, value, c = input.charAt(i), important, isDefault, match; save(); if (c === '.' || c === '#' || c === '&') { return } @@ -1170,9 +1170,10 @@ less.Parser = function Parser(env) { value = $(this.value); } important = $(this.important); + isDefault = $(this.isDefault); if (value && $(this.end)) { - return new(tree.Rule)(name, value, important, memo); + return new(tree.Rule)(name, value, important, memo, null, isDefault); } else { furthest = i; restore(); @@ -1391,6 +1392,11 @@ less.Parser = function Parser(env) { return $(/^! *important/); } }, + isDefault: function () { + if (input.charAt(i) === '!') { + return $(/^! *default/); + } + }, sub: function () { var e; diff --git a/lib/less/tree/rule.js b/lib/less/tree/rule.js index 8990fef02..91cfd2dd0 100644 --- a/lib/less/tree/rule.js +++ b/lib/less/tree/rule.js @@ -1,6 +1,6 @@ (function (tree) { -tree.Rule = function (name, value, important, index, inline) { +tree.Rule = function (name, value, important, index, inline, isDefault) { this.name = name; this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]); this.important = important ? ' ' + important.trim() : ''; @@ -9,7 +9,10 @@ tree.Rule = function (name, value, important, index, inline) { if (name.charAt(0) === '@') { this.variable = true; - } else { this.variable = false } + this.isDefault = isDefault; + } else { + this.variable = false; + } }; tree.Rule.prototype.toCSS = function (env) { if (this.variable) { return "" } @@ -24,14 +27,18 @@ tree.Rule.prototype.eval = function (context) { return new(tree.Rule)(this.name, this.value.eval(context), this.important, - this.index, this.inline); + this.index, + this.inline, + this.isDefault); }; tree.Rule.prototype.makeImportant = function () { return new(tree.Rule)(this.name, this.value, "!important", - this.index, this.inline); + this.index, + this.inline, + this.isDefault); }; tree.Shorthand = function (a, b) { diff --git a/lib/less/tree/ruleset.js b/lib/less/tree/ruleset.js index a198617c9..1c734d2c7 100644 --- a/lib/less/tree/ruleset.js +++ b/lib/less/tree/ruleset.js @@ -105,7 +105,9 @@ tree.Ruleset.prototype = { else { return this._variables = this.rules.reduce(function (hash, r) { if (r instanceof tree.Rule && r.variable === true) { - hash[r.name] = r; + if (!r.isDefault || !(r.name in hash)) { + hash[r.name] = r; + } } return hash; }, {}); diff --git a/test/css/variables.css b/test/css/variables.css index 43e885aeb..0760cbb1d 100644 --- a/test/css/variables.css +++ b/test/css/variables.css @@ -31,3 +31,7 @@ a:nth-child(2) { .testPollution { a: 'pollution'; } +.defaults { + font-size: 14px; + line-height: 14px; +} diff --git a/test/less/variables.less b/test/less/variables.less index b01097521..c8f3271fb 100644 --- a/test/less/variables.less +++ b/test/less/variables.less @@ -66,3 +66,12 @@ a:nth-child(@a) { .polluteMixin(); a: @a; } + +@baseFontSize: 14px; +@baseFontSize: 12px !default; +@baseLineHeight: 14px; + +.defaults { + font-size: @baseFontSize; + line-height: @baseLineHeight; +}