From 76c10345334bd2e4fb4b58e55475d26c185af301 Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Fri, 6 Jul 2018 23:37:28 -0700 Subject: [PATCH] Fixes #1880 - Adds two new math modes and deprecates strictMath --- bin/lessc | 12 +- lib/less-browser/add-default-options.js | 4 +- lib/less-node/lessc-helper.js | 13 +- lib/less/contexts.js | 7 +- lib/less/default-options.js | 9 +- lib/less/math-constants.js | 6 + lib/less/parse.js | 4 +- lib/less/render.js | 4 +- lib/less/tree/declaration.js | 19 +- lib/less/tree/expression.js | 10 +- lib/less/tree/operation.js | 6 +- lib/less/utils.js | 24 ++ test/browser/runner-browser-options.js | 2 +- test/browser/runner-errors-options.js | 2 +- test/browser/runner-legacy-options.js | 2 +- test/css/calc.css | 4 +- .../{strict-math => math/parens-all}/css.css | 0 test/css/math/parens-all/media-math.css | 10 + test/css/math/parens-all/mixins-args.css | 169 +++++++++++ test/css/math/parens-all/parens.css | 37 +++ test/css/math/parens-division/media-math.css | 10 + test/css/math/parens-division/mixins-args.css | 169 +++++++++++ .../parens-division}/new-division.css | 3 + test/css/math/parens-division/parens.css | 37 +++ test/css/math/strict-legacy/css.css | 95 +++++++ test/css/math/strict-legacy/media-math.css | 10 + .../strict-legacy}/mixins-args.css | 0 .../strict-legacy}/parens.css | 6 +- test/index.js | 18 +- test/less/functions.less | 2 +- .../{strict-math => math/parens-all}/css.less | 0 test/less/math/parens-all/media-math.less | 9 + test/less/math/parens-all/mixins-args.less | 264 ++++++++++++++++++ .../parens-all}/parens.less | 3 +- .../less/math/parens-division/media-math.less | 9 + .../math/parens-division/mixins-args.less | 264 ++++++++++++++++++ .../parens-division}/new-division.less | 0 test/less/math/parens-division/parens.less | 46 +++ test/less/math/strict-legacy/css.less | 108 +++++++ test/less/math/strict-legacy/media-math.less | 9 + .../strict-legacy}/mixins-args.less | 0 test/less/math/strict-legacy/parens.less | 50 ++++ 42 files changed, 1410 insertions(+), 46 deletions(-) create mode 100644 lib/less/math-constants.js rename test/css/{strict-math => math/parens-all}/css.css (100%) create mode 100644 test/css/math/parens-all/media-math.css create mode 100644 test/css/math/parens-all/mixins-args.css create mode 100644 test/css/math/parens-all/parens.css create mode 100644 test/css/math/parens-division/media-math.css create mode 100644 test/css/math/parens-division/mixins-args.css rename test/css/{strict-math-division => math/parens-division}/new-division.css (83%) create mode 100644 test/css/math/parens-division/parens.css create mode 100644 test/css/math/strict-legacy/css.css create mode 100644 test/css/math/strict-legacy/media-math.css rename test/css/{strict-math => math/strict-legacy}/mixins-args.css (100%) rename test/css/{strict-math => math/strict-legacy}/parens.css (88%) rename test/less/{strict-math => math/parens-all}/css.less (100%) create mode 100644 test/less/math/parens-all/media-math.less create mode 100644 test/less/math/parens-all/mixins-args.less rename test/less/{strict-math => math/parens-all}/parens.less (94%) create mode 100644 test/less/math/parens-division/media-math.less create mode 100644 test/less/math/parens-division/mixins-args.less rename test/less/{strict-math-division => math/parens-division}/new-division.less (100%) create mode 100644 test/less/math/parens-division/parens.less create mode 100644 test/less/math/strict-legacy/css.less create mode 100644 test/less/math/strict-legacy/media-math.less rename test/less/{strict-math => math/strict-legacy}/mixins-args.less (100%) create mode 100644 test/less/math/strict-legacy/parens.less diff --git a/bin/lessc b/bin/lessc index 7360ff07..e596ec10 100755 --- a/bin/lessc +++ b/bin/lessc @@ -4,6 +4,7 @@ var path = require('path'), fs = require('../lib/less-node/fs'), os = require('os'), utils = require('../lib/less/utils'), + MATH = require('../lib/less/math-constants'), errno, mkdirp; @@ -481,8 +482,17 @@ function processPluginQueue() { break; case 'sm': case 'strict-math': + console.warning('Strict math is deprecated. Use --math'); if (checkArgFunc(arg, match[2])) { - options.strictMath = checkBooleanArg(match[2]); + if (checkBooleanArg(match[2])) { + options.math = MATH.STRICT_LEGACY; + } + } + break; + case 'm': + case 'math': + if (checkArgFunc(arg, match[2])) { + options.math = match[2]; } break; case 'su': diff --git a/lib/less-browser/add-default-options.js b/lib/less-browser/add-default-options.js index 5155afbc..5c7ace8a 100644 --- a/lib/less-browser/add-default-options.js +++ b/lib/less-browser/add-default-options.js @@ -43,7 +43,5 @@ module.exports = function(window, options) { options.onReady = true; } - // TODO: deprecate and remove 'inlineJavaScript' thing - where it came from at all? - options.javascriptEnabled = (options.javascriptEnabled || options.inlineJavaScript) ? true : false; - + options.javascriptEnabled = options.javascriptEnabled ? true : false; }; diff --git a/lib/less-node/lessc-helper.js b/lib/less-node/lessc-helper.js index 8b40f4fd..ec705be3 100644 --- a/lib/less-node/lessc-helper.js +++ b/lib/less-node/lessc-helper.js @@ -48,9 +48,13 @@ var lessc_helper = { console.log(' -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls'); console.log(' Works with or without the relative-urls option.'); console.log(' -ru, --relative-urls Re-writes relative urls to the base less file.'); - console.log(' -sm=on|off Turns on or off strict math, where in strict mode, math.'); - console.log(' --strict-math=on|off Requires brackets. This option may default to on and then'); - console.log(' be removed in the future.'); + console.log(''); + console.log(' -m=, --math='); + console.log(' always Less will eagerly perform math operations always.'); + console.log(' parens-division Math performed except for division (/) operator'); + console.log(' parens-all Math only performed inside parentheses'); + console.log(' strict-legacy Parens required in very strict terms (legacy --strict-math)'); + console.log(''); console.log(' -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units'); console.log(' --strict-units=on|off that cannot be represented.'); console.log(' --global-var=\'VAR=VALUE\' Defines a variable that can be referenced by the file.'); @@ -64,6 +68,9 @@ var lessc_helper = { console.log(' or --clean-css="advanced"'); console.log(''); console.log('-------------------------- Deprecated ----------------'); + console.log(' -sm=on|off Legacy parens-only math. Use --math'); + console.log(' --strict-math=on|off '); + console.log(''); console.log(' --line-numbers=TYPE Outputs filename and line numbers.'); console.log(' TYPE can be either \'comments\', which will output'); console.log(' the debug info within comments, \'mediaquery\''); diff --git a/lib/less/contexts.js b/lib/less/contexts.js index 17067ec5..69b84cac 100644 --- a/lib/less/contexts.js +++ b/lib/less/contexts.js @@ -1,5 +1,6 @@ var contexts = {}; module.exports = contexts; +var MATH = require('./math-constants'); var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) { if (!original) { return; } @@ -43,7 +44,7 @@ var evalCopyProperties = [ 'paths', // additional include paths 'compress', // whether to compress 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) - 'strictMath', // whether math has to be within parenthesis + 'math', // whether math has to be within parenthesis 'strictUnits', // whether units need to evaluate correctly 'sourceMap', // whether to output a source map 'importMultiple', // whether we are currently importing multiple copies @@ -94,10 +95,10 @@ contexts.Eval.prototype.isMathOn = function (op) { if (!this.mathOn) { return false; } - if (op === '/' && this.strictMath && (!this.parensStack || !this.parensStack.length)) { + if (op === '/' && this.math !== MATH.ALWAYS && (!this.parensStack || !this.parensStack.length)) { return false; } - if (this.strictMath === true) { + if (this.math > MATH.PARENS_DIVISION) { return this.parensStack && this.parensStack.length; } return true; diff --git a/lib/less/default-options.js b/lib/less/default-options.js index 09c0b3cf..89603950 100644 --- a/lib/less/default-options.js +++ b/lib/less/default-options.js @@ -44,8 +44,13 @@ module.exports = function() { /* Compatibility with IE8. Used for limiting data-uri length */ ieCompat: false, // true until 3.0 - /* Without this option on, Less will try and process all math in your css */ - strictMath: false, + /* How to process math + * 0 always - eagerly try to solve all operations + * 1 parens-division - require parens for division "/" + * 2 parens-all - require parens for all operations + * 3 strict-legacy - legacy strict behavior (super-strict) + */ + math: 0, /* Without this option, less attempts to guess at the output unit when it does maths. */ strictUnits: false, diff --git a/lib/less/math-constants.js b/lib/less/math-constants.js new file mode 100644 index 00000000..185f3128 --- /dev/null +++ b/lib/less/math-constants.js @@ -0,0 +1,6 @@ +module.exports = { + ALWAYS: 0, + PARENS_DIVISION: 1, + PARENS_ALL: 2, + STRICT_LEGACY: 3 +}; \ No newline at end of file diff --git a/lib/less/parse.js b/lib/less/parse.js index d1c4fad5..cc254ba3 100644 --- a/lib/less/parse.js +++ b/lib/less/parse.js @@ -10,10 +10,10 @@ module.exports = function(environment, ParseTree, ImportManager) { if (typeof options === 'function') { callback = options; - options = utils.defaults(this.options, {}); + options = utils.copyOptions(this.options, {}); } else { - options = utils.defaults(this.options, options || {}); + options = utils.copyOptions(this.options, options || {}); } if (!callback) { diff --git a/lib/less/render.js b/lib/less/render.js index 1743f352..8ea6f9ea 100644 --- a/lib/less/render.js +++ b/lib/less/render.js @@ -5,10 +5,10 @@ module.exports = function(environment, ParseTree, ImportManager) { var render = function (input, options, callback) { if (typeof options === 'function') { callback = options; - options = utils.defaults(this.options, {}); + options = utils.copyOptions(this.options, {}); } else { - options = utils.defaults(this.options, options || {}); + options = utils.copyOptions(this.options, options || {}); } if (!callback) { diff --git a/lib/less/tree/declaration.js b/lib/less/tree/declaration.js index 10916029..c0b327d0 100644 --- a/lib/less/tree/declaration.js +++ b/lib/less/tree/declaration.js @@ -1,7 +1,8 @@ var Node = require('./node'), Value = require('./value'), Keyword = require('./keyword'), - Anonymous = require('./anonymous'); + Anonymous = require('./anonymous'), + MATH = require('../math-constants'); var Declaration = function (name, value, important, merge, index, currentFileInfo, inline, variable) { this.name = name; @@ -41,7 +42,7 @@ Declaration.prototype.genCSS = function (context, output) { output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index); }; Declaration.prototype.eval = function (context) { - var strictMathBypass = false, prevMath, name = this.name, evaldValue, variable = this.variable; + var mathBypass = false, prevMath, name = this.name, evaldValue, variable = this.variable; if (typeof name !== 'string') { // expand 'primitive' name directly to get // things faster (~10% for benchmark.less): @@ -49,10 +50,12 @@ Declaration.prototype.eval = function (context) { name[0].value : evalName(context, name); variable = false; // never treat expanded interpolation as new variable name } - if (name === 'font' && !context.strictMath) { - strictMathBypass = true; - prevMath = context.strictMath; - context.strictMath = 'division'; + + // @todo remove when parens-division is default + if (name === 'font' && context.math === MATH.ALWAYS) { + mathBypass = true; + prevMath = context.math; + context.math = MATH.PARENS_DIVISION; } try { context.importantScope.push({}); @@ -83,8 +86,8 @@ Declaration.prototype.eval = function (context) { throw e; } finally { - if (strictMathBypass) { - context.strictMath = prevMath; + if (mathBypass) { + context.math = prevMath; } } }; diff --git a/lib/less/tree/expression.js b/lib/less/tree/expression.js index 92cad86c..7e0ff1a0 100644 --- a/lib/less/tree/expression.js +++ b/lib/less/tree/expression.js @@ -1,6 +1,8 @@ var Node = require('./node'), Paren = require('./paren'), - Comment = require('./comment'); + Comment = require('./comment'), + Dimension = require('./dimension'), + MATH = require('../math-constants'); var Expression = function (value, noSpacing) { this.value = value; @@ -17,7 +19,8 @@ Expression.prototype.accept = function (visitor) { Expression.prototype.eval = function (context) { var returnValue, mathOn = context.isMathOn(), - inParenthesis = this.parens && !this.parensInOp, + inParenthesis = this.parens && + (context.math !== MATH.STRICT_LEGACY || !this.parensInOp), doubleParen = false; if (inParenthesis) { context.inParenthesis(); @@ -40,7 +43,8 @@ Expression.prototype.eval = function (context) { if (inParenthesis) { context.outOfParenthesis(); } - if (this.parens && this.parensInOp && !mathOn && !doubleParen) { + if (this.parens && this.parensInOp && !mathOn && !doubleParen + && (!(returnValue instanceof Dimension))) { returnValue = new Paren(returnValue); } return returnValue; diff --git a/lib/less/tree/operation.js b/lib/less/tree/operation.js index e7bafb56..08ac152b 100644 --- a/lib/less/tree/operation.js +++ b/lib/less/tree/operation.js @@ -1,6 +1,7 @@ var Node = require('./node'), Color = require('./color'), - Dimension = require('./dimension'); + Dimension = require('./dimension'), + MATH = require('../math-constants'); var Operation = function (op, operands, isSpaced) { this.op = op.trim(); @@ -26,6 +27,9 @@ Operation.prototype.eval = function (context) { b = b.toColor(); } if (!a.operate) { + if (a instanceof Operation && a.op === '/' && context.math === MATH.PARENS_DIVISION) { + return new Operation(this.op, [a, b], this.isSpaced); + } throw { type: 'Operation', message: 'Operation on an invalid type' }; } diff --git a/lib/less/utils.js b/lib/less/utils.js index 1c830e7c..62f2cbec 100644 --- a/lib/less/utils.js +++ b/lib/less/utils.js @@ -1,4 +1,6 @@ /* jshint proto: true */ +var MATH = require('./math-constants'); + var utils = { getLocation: function(index, inputStream) { var n = index + 1, @@ -36,6 +38,28 @@ var utils = { } return cloned; }, + copyOptions: function(obj1, obj2) { + var opts = utils.defaults(obj1, obj2); + if (opts.strictMath) { + opts.math = MATH.STRICT_LEGACY; + } + if (opts.hasOwnProperty('math') && typeof opts.math === 'string') { + switch (opts.math.toLowerCase()) { + case 'always': + opts.math = MATH.ALWAYS; + break; + case 'parens-division': + opts.math = MATH.PARENS_DIVISION; + break; + case 'parens-all': + opts.math = MATH.PARENS_ALL; + break; + case 'strict-legacy': + opts.math = MATH.STRICT_LEGACY; + } + } + return opts; + }, defaults: function(obj1, obj2) { if (!obj2._defaults || obj2._defaults !== obj1) { for (var prop in obj1) { diff --git a/test/browser/runner-browser-options.js b/test/browser/runner-browser-options.js index be8e3e3e..780de386 100644 --- a/test/browser/runner-browser-options.js +++ b/test/browser/runner-browser-options.js @@ -2,7 +2,7 @@ var less = { logLevel: 4, errorReporting: 'console', javascriptEnabled: true, - strictMath: false + math: 'always' }; // There originally run inside describe method. However, since they have not diff --git a/test/browser/runner-errors-options.js b/test/browser/runner-errors-options.js index 97b211d9..852ea5f7 100644 --- a/test/browser/runner-errors-options.js +++ b/test/browser/runner-errors-options.js @@ -1,6 +1,6 @@ var less = { strictUnits: true, - strictMath: true, + math: 'strict-legacy', logLevel: 4, javascriptEnabled: true }; diff --git a/test/browser/runner-legacy-options.js b/test/browser/runner-legacy-options.js index 66376b36..893447ce 100644 --- a/test/browser/runner-legacy-options.js +++ b/test/browser/runner-legacy-options.js @@ -1,6 +1,6 @@ var less = { logLevel: 4, errorReporting: 'console', - strictMath: false, + math: 'always', strictUnits: false }; diff --git a/test/css/calc.css b/test/css/calc.css index e8b5dcc9..9b29d7bf 100644 --- a/test/css/calc.css +++ b/test/css/calc.css @@ -3,12 +3,12 @@ root2: calc(100% - 40px); width: calc(50% + (25vh - 20px)); height: calc(50% + (25vh - 20px)); - min-height: calc((10vh) + calc(5vh)); + min-height: calc(10vh + calc(5vh)); foo: 3 calc(3 + 4) 11; bar: calc(1 + 20%); } .b { - one: calc(100% - (20px)); + one: calc(100% - 20px); two: calc(100% - (10px + 10px)); three: calc(100% - (3 * 1)); four: calc(100% - (3 * 1)); diff --git a/test/css/strict-math/css.css b/test/css/math/parens-all/css.css similarity index 100% rename from test/css/strict-math/css.css rename to test/css/math/parens-all/css.css diff --git a/test/css/math/parens-all/media-math.css b/test/css/math/parens-all/media-math.css new file mode 100644 index 00000000..1d2452a0 --- /dev/null +++ b/test/css/math/parens-all/media-math.css @@ -0,0 +1,10 @@ +@media (min-width: 16 + 1) { + .foo { + bar: 1; + } +} +@media (min-width: 16 / 9) { + .foo { + bar: 1; + } +} diff --git a/test/css/math/parens-all/mixins-args.css b/test/css/math/parens-all/mixins-args.css new file mode 100644 index 00000000..82a3fd14 --- /dev/null +++ b/test/css/math/parens-all/mixins-args.css @@ -0,0 +1,169 @@ +#hidden { + color: transparent; +} +#hidden1 { + color: transparent; +} +.two-args { + color: blue; + width: 10px; + height: 99%; + depth: 100% - 1%; + border: 2px dotted black; +} +.one-arg { + width: 15px; + height: 49%; + depth: 50% - 1%; +} +.no-parens { + width: 5px; + height: 49%; + depth: 50% - 1%; +} +.no-args { + width: 5px; + height: 49%; + depth: 50% - 1%; +} +.var-args { + width: 45; + height: 8%; + depth: 18 / 2 - 1%; +} +.multi-mix { + width: 10px; + height: 29%; + depth: 30% - 1%; + margin: 4; + padding: 5; +} +body { + padding: 30px; + color: #f00; +} +.scope-mix { + width: 8; +} +.content { + width: 600px; +} +.content .column { + margin: 600px; +} +#same-var-name { + radius: 5px; +} +#var-inside { + width: 10px; +} +.arguments { + border: 1px solid black; + width: 1px; +} +.arguments2 { + border: 0px; + width: 0px; +} +.arguments3 { + border: 0px; + width: 0px; +} +.arguments4 { + border: 0 1 2 3 4; + rest: 1 2 3 4; + width: 0; +} +.edge-case { + border: "{"; + width: "{"; +} +.slash-vs-math { + border-radius: 2px/5px; + border-radius: 5px/10px; + border-radius: 6px; +} +.comma-vs-semi-colon { + one: a; + two: b, c; + one: d, e; + two: f; + one: g; + one: h; + one: i; + one: j; + one: k; + two: l; + one: m, n; + one: o, p; + two: q; + one: r, s; + two: t; +} +#named-conflict { + four: a, 11, 12, 13; + four: a, 21, 22, 23; +} +.test-mixin-default-arg { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} +.selector { + margin: 2, 2, 2, 2; +} +.selector2 { + margin: 2, 2, 2, 2; +} +.selector3 { + margin: 4; +} +mixins-args-expand-op-1 { + m3: 1, 2, 3; +} +mixins-args-expand-op-2 { + m3: 4, 5, 6; +} +mixins-args-expand-op-3a { + m3: a, b, c; +} +mixins-args-expand-op-3b { + m4: 0, a, b, c; +} +mixins-args-expand-op-3c { + m4: a, b, c, 4; +} +mixins-args-expand-op-4a { + m3: a, b, c, d; +} +mixins-args-expand-op-4b { + m4: 0, a, b, c, d; +} +mixins-args-expand-op-4c { + m4: a, b, c, d, 4; +} +mixins-args-expand-op-5a { + m3: 1, 2, 3; +} +mixins-args-expand-op-5b { + m4: 0, 1, 2, 3; +} +mixins-args-expand-op-5c { + m4: 1, 2, 3, 4; +} +mixins-args-expand-op-6 { + m4: 0, 1, 2, 3; +} +mixins-args-expand-op-7 { + m4: 0, 1, 2, 3; +} +mixins-args-expand-op-8 { + m4: 1, 1.5, 2, 3; +} +mixins-args-expand-op-9 { + aa: 4 5 6 1 2 3 and again 4 5 6; + a4: and; + a8: 5; +} +#test-mixin-matching-when-default-2645 { + height: 20px; +} diff --git a/test/css/math/parens-all/parens.css b/test/css/math/parens-all/parens.css new file mode 100644 index 00000000..f7b8f977 --- /dev/null +++ b/test/css/math/parens-all/parens.css @@ -0,0 +1,37 @@ +.parens { + border: 2px solid black; + margin: 1px 3px 16 3; + width: 36; + padding: 2px 36px; +} +.more-parens { + padding: 8 4 4 4px; + width-all: 96; + width-first: 16 * 6; + width-keep: 16 * 6; + height: calc(100% + (25vh - 20px)); + height-keep: 49 + 64; + height-all: 113; + height-parts: 49 + 64; + margin-keep: 20 - 8; + margin-parts: 20 - 8; + margin-all: 12; + border-radius-keep: 4px * 2 / 4 + 3px; + border-radius-parts: 8px / 7px; + border-radius-all: 5px; +} +.negative { + neg-var: -1; + neg-var-paren: -1; +} +.nested-parens { + width: 2 * 36 - 1; + height: 5 + 1; +} +.mixed-units { + margin: 2px 4em 1 5pc; + padding: 6px 1em 2px 2; +} +.test-false-negatives { + a: (; +} diff --git a/test/css/math/parens-division/media-math.css b/test/css/math/parens-division/media-math.css new file mode 100644 index 00000000..0b8be1c9 --- /dev/null +++ b/test/css/math/parens-division/media-math.css @@ -0,0 +1,10 @@ +@media (min-width: 17) { + .foo { + bar: 1; + } +} +@media (min-width: 16 / 9) { + .foo { + bar: 1; + } +} diff --git a/test/css/math/parens-division/mixins-args.css b/test/css/math/parens-division/mixins-args.css new file mode 100644 index 00000000..d95021ee --- /dev/null +++ b/test/css/math/parens-division/mixins-args.css @@ -0,0 +1,169 @@ +#hidden { + color: transparent; +} +#hidden1 { + color: transparent; +} +.two-args { + color: blue; + width: 10px; + height: 99%; + depth: 99%; + border: 2px dotted black; +} +.one-arg { + width: 15px; + height: 49%; + depth: 49%; +} +.no-parens { + width: 5px; + height: 49%; + depth: 49%; +} +.no-args { + width: 5px; + height: 49%; + depth: 49%; +} +.var-args { + width: 45; + height: 8%; + depth: 18 / 2 - 1%; +} +.multi-mix { + width: 10px; + height: 29%; + depth: 29%; + margin: 4; + padding: 5; +} +body { + padding: 30px; + color: #f00; +} +.scope-mix { + width: 8; +} +.content { + width: 600px; +} +.content .column { + margin: 600px; +} +#same-var-name { + radius: 5px; +} +#var-inside { + width: 10px; +} +.arguments { + border: 1px solid black; + width: 1px; +} +.arguments2 { + border: 0px; + width: 0px; +} +.arguments3 { + border: 0px; + width: 0px; +} +.arguments4 { + border: 0 1 2 3 4; + rest: 1 2 3 4; + width: 0; +} +.edge-case { + border: "{"; + width: "{"; +} +.slash-vs-math { + border-radius: 2px/5px; + border-radius: 5px/10px; + border-radius: 6px; +} +.comma-vs-semi-colon { + one: a; + two: b, c; + one: d, e; + two: f; + one: g; + one: h; + one: i; + one: j; + one: k; + two: l; + one: m, n; + one: o, p; + two: q; + one: r, s; + two: t; +} +#named-conflict { + four: a, 11, 12, 13; + four: a, 21, 22, 23; +} +.test-mixin-default-arg { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} +.selector { + margin: 2, 2, 2, 2; +} +.selector2 { + margin: 2, 2, 2, 2; +} +.selector3 { + margin: 4; +} +mixins-args-expand-op-1 { + m3: 1, 2, 3; +} +mixins-args-expand-op-2 { + m3: 4, 5, 6; +} +mixins-args-expand-op-3a { + m3: a, b, c; +} +mixins-args-expand-op-3b { + m4: 0, a, b, c; +} +mixins-args-expand-op-3c { + m4: a, b, c, 4; +} +mixins-args-expand-op-4a { + m3: a, b, c, d; +} +mixins-args-expand-op-4b { + m4: 0, a, b, c, d; +} +mixins-args-expand-op-4c { + m4: a, b, c, d, 4; +} +mixins-args-expand-op-5a { + m3: 1, 2, 3; +} +mixins-args-expand-op-5b { + m4: 0, 1, 2, 3; +} +mixins-args-expand-op-5c { + m4: 1, 2, 3, 4; +} +mixins-args-expand-op-6 { + m4: 0, 1, 2, 3; +} +mixins-args-expand-op-7 { + m4: 0, 1, 2, 3; +} +mixins-args-expand-op-8 { + m4: 1, 1.5, 2, 3; +} +mixins-args-expand-op-9 { + aa: 4 5 6 1 2 3 and again 4 5 6; + a4: and; + a8: 5; +} +#test-mixin-matching-when-default-2645 { + height: 20px; +} diff --git a/test/css/strict-math-division/new-division.css b/test/css/math/parens-division/new-division.css similarity index 83% rename from test/css/strict-math-division/new-division.css rename to test/css/math/parens-division/new-division.css index cd30653e..7b2486d8 100644 --- a/test/css/strict-math-division/new-division.css +++ b/test/css/math/parens-division/new-division.css @@ -10,4 +10,7 @@ a: 2; b: 2px / 2; c: 1px; + d: 1px; + e: 4px / 2; + f: 2px; } diff --git a/test/css/math/parens-division/parens.css b/test/css/math/parens-division/parens.css new file mode 100644 index 00000000..5e61728b --- /dev/null +++ b/test/css/math/parens-division/parens.css @@ -0,0 +1,37 @@ +.parens { + border: 2px solid black; + margin: 1px 3px 16 3; + width: 36; + padding: 2px 36px; +} +.more-parens { + padding: 8 4 4 4px; + width-all: 96; + width-first: 96; + width-keep: 96; + height: calc(100% + (25vh - 20px)); + height-keep: 113; + height-all: 113; + height-parts: 113; + margin-keep: 12; + margin-parts: 12; + margin-all: 12; + border-radius-keep: 8px / 4 + 3px; + border-radius-parts: 8px / 7px; + border-radius-all: 5px; +} +.negative { + neg-var: -1; + neg-var-paren: -1; +} +.nested-parens { + width: 71; + height: 6; +} +.mixed-units { + margin: 2px 4em 1 5pc; + padding: 6px 1em 2px 2; +} +.test-false-negatives { + a: (; +} diff --git a/test/css/math/strict-legacy/css.css b/test/css/math/strict-legacy/css.css new file mode 100644 index 00000000..63364078 --- /dev/null +++ b/test/css/math/strict-legacy/css.css @@ -0,0 +1,95 @@ +@charset "utf-8"; +div { + color: black; +} +div { + width: 99%; +} +* { + min-width: 45em; +} +h1, +h2 > a > p, +h3 { + color: none; +} +div.class { + color: blue; +} +div#id { + color: green; +} +.class#id { + color: purple; +} +.one.two.three { + color: grey; +} +@media print { + * { + font-size: 3em; + } +} +@media screen { + * { + font-size: 10px; + } +} +@font-face { + font-family: 'Garamond Pro'; +} +a:hover, +a:link { + color: #999; +} +p, +p:first-child { + text-transform: none; +} +q:lang(no) { + quotes: none; +} +p + h1 { + font-size: 2.2em; +} +#shorthands { + border: 1px solid #000; + font: 12px/16px Arial; + font: 100%/16px Arial; + margin: 1px 0; + padding: 0 auto; +} +#more-shorthands { + margin: 0; + padding: 1px 0 2px 0; + font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; + font: 0/0 a; + border-radius: 5px / 10px; +} +.misc { + -moz-border-radius: 2px; + display: -moz-inline-stack; + width: 0.1em; + background-color: #009998; + background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); + margin: ; + filter: alpha(opacity=100); + width: auto\9; +} +.misc .nested-multiple { + multiple-semi-colons: yes; +} +#important { + color: red !important; + width: 100%!important; + height: 20px ! important; +} +@font-face { + font-family: font-a; +} +@font-face { + font-family: font-b; +} +.æøå { + margin: 0; +} diff --git a/test/css/math/strict-legacy/media-math.css b/test/css/math/strict-legacy/media-math.css new file mode 100644 index 00000000..1d2452a0 --- /dev/null +++ b/test/css/math/strict-legacy/media-math.css @@ -0,0 +1,10 @@ +@media (min-width: 16 + 1) { + .foo { + bar: 1; + } +} +@media (min-width: 16 / 9) { + .foo { + bar: 1; + } +} diff --git a/test/css/strict-math/mixins-args.css b/test/css/math/strict-legacy/mixins-args.css similarity index 100% rename from test/css/strict-math/mixins-args.css rename to test/css/math/strict-legacy/mixins-args.css diff --git a/test/css/strict-math/parens.css b/test/css/math/strict-legacy/parens.css similarity index 88% rename from test/css/strict-math/parens.css rename to test/css/math/strict-legacy/parens.css index 0e8cc7c8..f880872f 100644 --- a/test/css/strict-math/parens.css +++ b/test/css/math/strict-legacy/parens.css @@ -4,11 +4,15 @@ width: 36; padding: 2px 36px; } +.in-function { + value: 2 + 1; +} .more-parens { padding: 8 4 4 4px; width-all: 96; width-first: 16 * 6; width-keep: (4 * 4) * 6; + height: calc(100% + (25vh - 20px)); height-keep: (7 * 7) + (8 * 8); height-all: 113; height-parts: 49 + 64; @@ -21,7 +25,7 @@ } .negative { neg-var: -1; - neg-var-paren: -(1); + neg-var-paren: -1; } .nested-parens { width: 2 * (4 * (2 + (1 + 6))) - 1; diff --git a/test/index.js b/test/index.js index edc6ad1b..0fb27305 100644 --- a/test/index.js +++ b/test/index.js @@ -17,18 +17,16 @@ var testMap = [ ieCompat: true }], [{ - strictMath: true, + math: 'strict-legacy', ieCompat: true -<<<<<<< HEAD - }, "strict-math/"], + }, 'math/strict-legacy/'], [{ - strictMath: 'division' - }, "strict-math-division/"], - [{strictMath: true, strictUnits: true, javascriptEnabled: true}, "errors/", -======= - }, 'strict-math/'], + math: 'parens-all' + }, 'math/parens-all/'], + [{ + math: 'parens-division' + }, 'math/parens-division/'], [{strictMath: true, strictUnits: true, javascriptEnabled: true}, 'errors/', ->>>>>>> master lessTester.testErrors, null], [{strictMath: true, strictUnits: true, javascriptEnabled: false}, 'no-js-errors/', lessTester.testErrors, null], @@ -69,7 +67,7 @@ testMap.forEach(function(args) { lessTester.runTestSet.apply(lessTester, args) }); lessTester.testSyncronous({syncImport: true}, 'import'); -lessTester.testSyncronous({syncImport: true}, 'strict-math/css'); +lessTester.testSyncronous({syncImport: true}, 'math/strict-legacy/css'); lessTester.testNoOptions(); lessTester.testJSImport(); lessTester.finished(); diff --git a/test/less/functions.less b/test/less/functions.less index 27c614fc..8b1d0e0a 100644 --- a/test/less/functions.less +++ b/test/less/functions.less @@ -265,7 +265,7 @@ html { }, {}); @conditional(); - @falsey: if((@undefined), { + @falsey: if((false), { color: orange; }, { color: purple; diff --git a/test/less/strict-math/css.less b/test/less/math/parens-all/css.less similarity index 100% rename from test/less/strict-math/css.less rename to test/less/math/parens-all/css.less diff --git a/test/less/math/parens-all/media-math.less b/test/less/math/parens-all/media-math.less new file mode 100644 index 00000000..b3df9118 --- /dev/null +++ b/test/less/math/parens-all/media-math.less @@ -0,0 +1,9 @@ +@var: 16; + +@media (min-width: @var + 1) { + .foo { bar: 1; } +} + +@media (min-width: @var / 9) { + .foo { bar: 1; } +} \ No newline at end of file diff --git a/test/less/math/parens-all/mixins-args.less b/test/less/math/parens-all/mixins-args.less new file mode 100644 index 00000000..7b1bef0e --- /dev/null +++ b/test/less/math/parens-all/mixins-args.less @@ -0,0 +1,264 @@ +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + depth: @b - 1%; +} + +.mixina (@style, @width, @color: black) { + border: @width @style @color; +} + +.mixiny +(@a: 0, @b: 0) { + margin: @a; + padding: @b; +} + +.hidden() { + color: transparent; // asd +} + +#hidden { + .hidden; +} + +#hidden1 { + .hidden(); +} + +.two-args { + color: blue; + .mixin(2px, 100%); + .mixina(dotted, 2px); +} + +.one-arg { + .mixin(3px); +} + +.no-parens { + .mixin; +} + +.no-args { + .mixin(); +} + +.var-args { + @var: 9; + .mixin(@var, (@var * 2) / 2); +} + +.multi-mix { + .mixin(2px, 30%); + .mixiny(4, 5); +} + +.maxa(@arg1: 10, @arg2: #f00) { + padding: (@arg1 * 2px); + color: @arg2; +} + +body { + .maxa(15); +} + +@glob: 5; +.global-mixin(@a:2) { + width: (@glob + @a); +} + +.scope-mix { + .global-mixin(3); +} + +.nested-ruleset (@width: 200px) { + width: @width; + .column { margin: @width; } +} +.content { + .nested-ruleset(600px); +} + +// + +.same-var-name2(@radius) { + radius: @radius; +} +.same-var-name(@radius) { + .same-var-name2(@radius); +} +#same-var-name { + .same-var-name(5px); +} + +// + +.var-inside () { + @var: 10px; + width: @var; +} +#var-inside { .var-inside; } + +.mixin-arguments (@width: 0px, ...) { + border: @arguments; + width: @width; +} + +.arguments { + .mixin-arguments(1px, solid, black); +} +.arguments2 { + .mixin-arguments(); +} +.arguments3 { + .mixin-arguments; +} + +.mixin-arguments2 (@width, @rest...) { + border: @arguments; + rest: @rest; + width: @width; +} +.arguments4 { + .mixin-arguments2(0, 1, 2, 3, 4); +} + +// Edge cases + +.edge-case { + .mixin-arguments("{"); +} + +// Division vs. Literal Slash +.border-radius(@r: 2px/5px) { + border-radius: @r; +} +.slash-vs-math { + .border-radius(); + .border-radius(5px/10px); + .border-radius((3px * 2)); +} +// semi-colon vs comma for delimiting + +.mixin-takes-one(@a) { + one: @a; +} + +.mixin-takes-two(@a; @b) { + one: @a; + two: @b; +} + +.comma-vs-semi-colon { + .mixin-takes-two(@a : a; @b : b, c); + .mixin-takes-two(@a : d, e; @b : f); + .mixin-takes-one(@a: g); + .mixin-takes-one(@a : h;); + .mixin-takes-one(i); + .mixin-takes-one(j;); + .mixin-takes-two(k, l); + .mixin-takes-one(m, n;); + .mixin-takes-two(o, p; q); + .mixin-takes-two(r, s; t;); +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC) { + three: @a, @b, @c; +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { + four: @a, @b, @c, @d; +} + +#named-conflict { + .mixin-conflict(11, 12, 13, @a:a); + .mixin-conflict(@a:a, 21, 22, 23); +} +@a: 3px; +.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} + +.test-mixin-default-arg { + .mixin-default-arg(); + .mixin-default-arg(2px); +} + +.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector { + .mixin-comma-default1(#33acfe; 4); +} +.mixin-comma-default2(@margin: 2, 2, 2, 2;) { + margin: @margin; +} +.selector2 { + .mixin-comma-default2(); +} +.mixin-comma-default3(@margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector3 { + .mixin-comma-default3(4,2,2,2); +} + +.test-calling-one-arg-mixin(@a) { +} + +.test-calling-one-arg-mixin(@a, @b, @rest...) { +} + +div { + .test-calling-one-arg-mixin(1); +} + +mixins-args-expand-op- { + @x: 1, 2, 3; + @y: 4 5 6; + + &1 {.m3(@x...)} + &2 {.m3(@y...)} + &3 {.wr(a, b, c)} + &4 {.wr(a; b; c, d)} + &5 {.wr(@x...)} + &6 {.m4(0; @x...)} + &7 {.m4(@x..., @a: 0)} + &8 {.m4(@b: 1.5; @x...)} + &9 {.aa(@y, @x..., and again, @y...)} + + .m3(@a, @b, @c) { + m3: @a, @b, @c; + } + + .m4(@a, @b, @c, @d) { + m4: @a, @b, @c, @d; + } + + .wr(@a...) { + &a {.m3(@a...)} + &b {.m4(0, @a...)} + &c {.m4(@a..., 4)} + } + + .aa(@a...) { + aa: @a; + a4: extract(@a, 5); + a8: extract(@a, 8); + } +} +#test-mixin-matching-when-default-2645 { + .mixin(@height) { + height: @height; + } + + .mixin(@width, @height: 10px) { + width: @width; + + .mixin(@height: @height); + } + + .mixin(@height: 20px); +} \ No newline at end of file diff --git a/test/less/strict-math/parens.less b/test/less/math/parens-all/parens.less similarity index 94% rename from test/less/strict-math/parens.less rename to test/less/math/parens-all/parens.less index eeef3448..becbd04e 100644 --- a/test/less/strict-math/parens.less +++ b/test/less/math/parens-all/parens.less @@ -12,6 +12,7 @@ width-all: ((@var * @var) * 6); width-first: ((@var * @var)) * 6; width-keep: (@var * @var) * 6; + height: calc(100% + (25vh - 20px)); height-keep: (7 * 7) + (8 * 8); height-all: ((7 * 7) + (8 * 8)); height-parts: ((7 * 7)) + ((8 * 8)); @@ -21,7 +22,7 @@ border-radius-keep: 4px * (1 + 1) / @var + 3px; border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); border-radius-all: (4px * (1 + 1) / @var + 3px); - //margin: (6 * 6)px; + // margin: (6 * 6)px; } .negative { diff --git a/test/less/math/parens-division/media-math.less b/test/less/math/parens-division/media-math.less new file mode 100644 index 00000000..b3df9118 --- /dev/null +++ b/test/less/math/parens-division/media-math.less @@ -0,0 +1,9 @@ +@var: 16; + +@media (min-width: @var + 1) { + .foo { bar: 1; } +} + +@media (min-width: @var / 9) { + .foo { bar: 1; } +} \ No newline at end of file diff --git a/test/less/math/parens-division/mixins-args.less b/test/less/math/parens-division/mixins-args.less new file mode 100644 index 00000000..7b1bef0e --- /dev/null +++ b/test/less/math/parens-division/mixins-args.less @@ -0,0 +1,264 @@ +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + depth: @b - 1%; +} + +.mixina (@style, @width, @color: black) { + border: @width @style @color; +} + +.mixiny +(@a: 0, @b: 0) { + margin: @a; + padding: @b; +} + +.hidden() { + color: transparent; // asd +} + +#hidden { + .hidden; +} + +#hidden1 { + .hidden(); +} + +.two-args { + color: blue; + .mixin(2px, 100%); + .mixina(dotted, 2px); +} + +.one-arg { + .mixin(3px); +} + +.no-parens { + .mixin; +} + +.no-args { + .mixin(); +} + +.var-args { + @var: 9; + .mixin(@var, (@var * 2) / 2); +} + +.multi-mix { + .mixin(2px, 30%); + .mixiny(4, 5); +} + +.maxa(@arg1: 10, @arg2: #f00) { + padding: (@arg1 * 2px); + color: @arg2; +} + +body { + .maxa(15); +} + +@glob: 5; +.global-mixin(@a:2) { + width: (@glob + @a); +} + +.scope-mix { + .global-mixin(3); +} + +.nested-ruleset (@width: 200px) { + width: @width; + .column { margin: @width; } +} +.content { + .nested-ruleset(600px); +} + +// + +.same-var-name2(@radius) { + radius: @radius; +} +.same-var-name(@radius) { + .same-var-name2(@radius); +} +#same-var-name { + .same-var-name(5px); +} + +// + +.var-inside () { + @var: 10px; + width: @var; +} +#var-inside { .var-inside; } + +.mixin-arguments (@width: 0px, ...) { + border: @arguments; + width: @width; +} + +.arguments { + .mixin-arguments(1px, solid, black); +} +.arguments2 { + .mixin-arguments(); +} +.arguments3 { + .mixin-arguments; +} + +.mixin-arguments2 (@width, @rest...) { + border: @arguments; + rest: @rest; + width: @width; +} +.arguments4 { + .mixin-arguments2(0, 1, 2, 3, 4); +} + +// Edge cases + +.edge-case { + .mixin-arguments("{"); +} + +// Division vs. Literal Slash +.border-radius(@r: 2px/5px) { + border-radius: @r; +} +.slash-vs-math { + .border-radius(); + .border-radius(5px/10px); + .border-radius((3px * 2)); +} +// semi-colon vs comma for delimiting + +.mixin-takes-one(@a) { + one: @a; +} + +.mixin-takes-two(@a; @b) { + one: @a; + two: @b; +} + +.comma-vs-semi-colon { + .mixin-takes-two(@a : a; @b : b, c); + .mixin-takes-two(@a : d, e; @b : f); + .mixin-takes-one(@a: g); + .mixin-takes-one(@a : h;); + .mixin-takes-one(i); + .mixin-takes-one(j;); + .mixin-takes-two(k, l); + .mixin-takes-one(m, n;); + .mixin-takes-two(o, p; q); + .mixin-takes-two(r, s; t;); +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC) { + three: @a, @b, @c; +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { + four: @a, @b, @c, @d; +} + +#named-conflict { + .mixin-conflict(11, 12, 13, @a:a); + .mixin-conflict(@a:a, 21, 22, 23); +} +@a: 3px; +.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} + +.test-mixin-default-arg { + .mixin-default-arg(); + .mixin-default-arg(2px); +} + +.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector { + .mixin-comma-default1(#33acfe; 4); +} +.mixin-comma-default2(@margin: 2, 2, 2, 2;) { + margin: @margin; +} +.selector2 { + .mixin-comma-default2(); +} +.mixin-comma-default3(@margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector3 { + .mixin-comma-default3(4,2,2,2); +} + +.test-calling-one-arg-mixin(@a) { +} + +.test-calling-one-arg-mixin(@a, @b, @rest...) { +} + +div { + .test-calling-one-arg-mixin(1); +} + +mixins-args-expand-op- { + @x: 1, 2, 3; + @y: 4 5 6; + + &1 {.m3(@x...)} + &2 {.m3(@y...)} + &3 {.wr(a, b, c)} + &4 {.wr(a; b; c, d)} + &5 {.wr(@x...)} + &6 {.m4(0; @x...)} + &7 {.m4(@x..., @a: 0)} + &8 {.m4(@b: 1.5; @x...)} + &9 {.aa(@y, @x..., and again, @y...)} + + .m3(@a, @b, @c) { + m3: @a, @b, @c; + } + + .m4(@a, @b, @c, @d) { + m4: @a, @b, @c, @d; + } + + .wr(@a...) { + &a {.m3(@a...)} + &b {.m4(0, @a...)} + &c {.m4(@a..., 4)} + } + + .aa(@a...) { + aa: @a; + a4: extract(@a, 5); + a8: extract(@a, 8); + } +} +#test-mixin-matching-when-default-2645 { + .mixin(@height) { + height: @height; + } + + .mixin(@width, @height: 10px) { + width: @width; + + .mixin(@height: @height); + } + + .mixin(@height: 20px); +} \ No newline at end of file diff --git a/test/less/strict-math-division/new-division.less b/test/less/math/parens-division/new-division.less similarity index 100% rename from test/less/strict-math-division/new-division.less rename to test/less/math/parens-division/new-division.less diff --git a/test/less/math/parens-division/parens.less b/test/less/math/parens-division/parens.less new file mode 100644 index 00000000..becbd04e --- /dev/null +++ b/test/less/math/parens-division/parens.less @@ -0,0 +1,46 @@ +.parens { + @var: 1px; + border: (@var * 2) solid black; + margin: (@var * 1) (@var + 2) (4 * 4) 3; + width: (6 * 6); + padding: 2px (6 * 6px); +} + +.more-parens { + @var: (2 * 2); + padding: (2 * @var) 4 4 (@var * 1px); + width-all: ((@var * @var) * 6); + width-first: ((@var * @var)) * 6; + width-keep: (@var * @var) * 6; + height: calc(100% + (25vh - 20px)); + height-keep: (7 * 7) + (8 * 8); + height-all: ((7 * 7) + (8 * 8)); + height-parts: ((7 * 7)) + ((8 * 8)); + margin-keep: (4 * (5 + 5) / 2) - (@var * 2); + margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); + margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); + border-radius-keep: 4px * (1 + 1) / @var + 3px; + border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); + border-radius-all: (4px * (1 + 1) / @var + 3px); + // margin: (6 * 6)px; +} + +.negative { + @var: 1; + neg-var: -@var; // -1 ? + neg-var-paren: -(@var); // -(1) ? +} + +.nested-parens { + width: 2 * (4 * (2 + (1 + 6))) - 1; + height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; +} + +.mixed-units { + margin: 2px 4em 1 5pc; + padding: (2px + 4px) 1em 2px 2; +} + +.test-false-negatives { + a: ~"("; +} diff --git a/test/less/math/strict-legacy/css.less b/test/less/math/strict-legacy/css.less new file mode 100644 index 00000000..0cdebae8 --- /dev/null +++ b/test/less/math/strict-legacy/css.less @@ -0,0 +1,108 @@ +@charset "utf-8"; +div { color: black; } +div { width: 99%; } + +* { + min-width: 45em; +} + +h1, h2 > a > p, h3 { + color: none; +} + +div.class { + color: blue; +} + +div#id { + color: green; +} + +.class#id { + color: purple; +} + +.one.two.three { + color: grey; +} + +@media print { + * { + font-size: 3em; + } +} + +@media screen { + * { + font-size: 10px; + } +} + +@font-face { + font-family: 'Garamond Pro'; +} + +a:hover, a:link { + color: #999; +} + +p, p:first-child { + text-transform: none; +} + +q:lang(no) { + quotes: none; +} + +p + h1 { + font-size: +2.2em; +} + +#shorthands { + border: 1px solid #000; + font: 12px/16px Arial; + font: 100%/16px Arial; + margin: 1px 0; + padding: 0 auto; +} + +#more-shorthands { + margin: 0; + padding: 1px 0 2px 0; + font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; + font: 0/0 a; + border-radius: 5px / 10px; +} + +.misc { + -moz-border-radius: 2px; + display: -moz-inline-stack; + width: .1em; + background-color: #009998; + background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); + margin: ; + .nested-multiple { + multiple-semi-colons: yes;;;;;; + }; + filter: alpha(opacity=100); + width: auto\9; +} + +#important { + color: red !important; + width: 100%!important; + height: 20px ! important; +} + +.def-font(@name) { + @font-face { + font-family: @name + } +} + +.def-font(font-a); +.def-font(font-b); + +.æøå { + margin: 0; +} diff --git a/test/less/math/strict-legacy/media-math.less b/test/less/math/strict-legacy/media-math.less new file mode 100644 index 00000000..b3df9118 --- /dev/null +++ b/test/less/math/strict-legacy/media-math.less @@ -0,0 +1,9 @@ +@var: 16; + +@media (min-width: @var + 1) { + .foo { bar: 1; } +} + +@media (min-width: @var / 9) { + .foo { bar: 1; } +} \ No newline at end of file diff --git a/test/less/strict-math/mixins-args.less b/test/less/math/strict-legacy/mixins-args.less similarity index 100% rename from test/less/strict-math/mixins-args.less rename to test/less/math/strict-legacy/mixins-args.less diff --git a/test/less/math/strict-legacy/parens.less b/test/less/math/strict-legacy/parens.less new file mode 100644 index 00000000..01214254 --- /dev/null +++ b/test/less/math/strict-legacy/parens.less @@ -0,0 +1,50 @@ +.parens { + @var: 1px; + border: (@var * 2) solid black; + margin: (@var * 1) (@var + 2) (4 * 4) 3; + width: (6 * 6); + padding: 2px (6 * 6px); +} + +.in-function { + value: min((1 + 1)) + 1; +} + +.more-parens { + @var: (2 * 2); + padding: (2 * @var) 4 4 (@var * 1px); + width-all: ((@var * @var) * 6); + width-first: ((@var * @var)) * 6; + width-keep: (@var * @var) * 6; + height: calc(100% + (25vh - 20px)); + height-keep: (7 * 7) + (8 * 8); + height-all: ((7 * 7) + (8 * 8)); + height-parts: ((7 * 7)) + ((8 * 8)); + margin-keep: (4 * (5 + 5) / 2) - (@var * 2); + margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); + margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); + border-radius-keep: 4px * (1 + 1) / @var + 3px; + border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); + border-radius-all: (4px * (1 + 1) / @var + 3px); + // margin: (6 * 6)px; +} + +.negative { + @var: 1; + neg-var: -@var; // -1 ? + neg-var-paren: -(@var); // -(1) ? +} + +.nested-parens { + width: 2 * (4 * (2 + (1 + 6))) - 1; + height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; +} + +.mixed-units { + margin: 2px 4em 1 5pc; + padding: (2px + 4px) 1em 2px 2; +} + +.test-false-negatives { + a: ~"("; +}