less 2.1.2 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/.idea/inspectionProfiles/Project_Default.xml +1 -0
  2. package/.idea/jsLinters/jscs.xml +4 -0
  3. package/.idea/jsLinters/jshint.xml +58 -4
  4. package/.idea/workspace.xml +499 -760
  5. package/.jscsrc +73 -0
  6. package/.jshintrc +0 -2
  7. package/.travis.yml +1 -0
  8. package/CHANGELOG.md +59 -0
  9. package/Gruntfile.js +37 -3
  10. package/appveyor.yml +5 -0
  11. package/bin/lessc +383 -316
  12. package/bower.json +1 -1
  13. package/dist/less.js +1638 -1244
  14. package/dist/less.min.js +7 -7
  15. package/lib/less/contexts.js +3 -3
  16. package/lib/less/data/unit-conversions.js +3 -3
  17. package/lib/less/environment/abstract-file-manager.js +8 -8
  18. package/lib/less/environment/environment.js +2 -2
  19. package/lib/less/functions/color-blending.js +3 -3
  20. package/lib/less/functions/color.js +20 -12
  21. package/lib/less/functions/data-uri.js +26 -18
  22. package/lib/less/functions/math.js +1 -1
  23. package/lib/less/functions/number.js +2 -2
  24. package/lib/less/functions/string.js +3 -1
  25. package/lib/less/functions/svg.js +12 -15
  26. package/lib/less/functions/types.js +33 -10
  27. package/lib/less/import-manager.js +14 -9
  28. package/lib/less/index.js +2 -1
  29. package/lib/less/less-error.js +1 -1
  30. package/lib/less/logger.js +2 -2
  31. package/lib/less/parse-tree.js +48 -42
  32. package/lib/less/parse.js +68 -0
  33. package/lib/less/parser/parser-input.js +6 -5
  34. package/lib/less/parser/parser.js +76 -29
  35. package/lib/less/plugin-manager.js +30 -3
  36. package/lib/less/render.js +11 -37
  37. package/lib/less/source-map-builder.js +4 -0
  38. package/lib/less/source-map-output.js +6 -6
  39. package/lib/less/transform-tree.js +4 -4
  40. package/lib/less/tree/anonymous.js +1 -1
  41. package/lib/less/tree/assignment.js +0 -1
  42. package/lib/less/tree/call.js +1 -1
  43. package/lib/less/tree/color.js +6 -6
  44. package/lib/less/tree/condition.js +9 -5
  45. package/lib/less/tree/debug-info.js +6 -2
  46. package/lib/less/tree/dimension.js +5 -5
  47. package/lib/less/tree/directive.js +25 -6
  48. package/lib/less/tree/element.js +1 -1
  49. package/lib/less/tree/expression.js +2 -2
  50. package/lib/less/tree/extend.js +3 -3
  51. package/lib/less/tree/import.js +2 -2
  52. package/lib/less/tree/index.js +1 -0
  53. package/lib/less/tree/javascript.js +2 -2
  54. package/lib/less/tree/media.js +20 -19
  55. package/lib/less/tree/mixin-call.js +5 -6
  56. package/lib/less/tree/mixin-definition.js +33 -11
  57. package/lib/less/tree/quoted.js +3 -3
  58. package/lib/less/tree/rule.js +3 -4
  59. package/lib/less/tree/ruleset.js +290 -177
  60. package/lib/less/tree/selector.js +3 -2
  61. package/lib/less/tree/unit.js +2 -0
  62. package/lib/less/tree/url.js +5 -2
  63. package/lib/less/tree/value.js +2 -2
  64. package/lib/less/tree/variable.js +1 -1
  65. package/lib/less/visitors/extend-visitor.js +72 -36
  66. package/lib/less/visitors/import-sequencer.js +20 -14
  67. package/lib/less/visitors/import-visitor.js +15 -12
  68. package/lib/less/visitors/to-css-visitor.js +41 -9
  69. package/lib/less-browser/add-default-options.js +5 -1
  70. package/lib/less-browser/bootstrap.js +10 -8
  71. package/lib/less-browser/cache.js +3 -3
  72. package/lib/less-browser/file-manager.js +96 -96
  73. package/lib/less-browser/index.js +206 -205
  74. package/lib/less-browser/log-listener.js +2 -2
  75. package/lib/less-browser/utils.js +6 -6
  76. package/lib/less-node/file-manager.js +58 -30
  77. package/lib/less-node/image-size.js +34 -0
  78. package/lib/less-node/index.js +6 -3
  79. package/lib/less-node/lessc-helper.js +3 -2
  80. package/lib/less-node/plugin-loader.js +3 -3
  81. package/lib/less-node/url-file-manager.js +6 -3
  82. package/lib/less-rhino/index.js +15 -13
  83. package/lib/source-map/source-map-0.1.31.js +1 -1
  84. package/package.json +10 -7
  85. package/test/browser/common.js +13 -11
  86. package/test/browser/css/relative-urls/urls.css +1 -0
  87. package/test/browser/css/urls.css +6 -3
  88. package/test/browser/jasmine-jsreporter.js +2 -3
  89. package/test/browser/less/nested-gradient-with-svg-gradient/mixin-consumer.less +5 -0
  90. package/test/browser/less/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +15 -0
  91. package/test/browser/less/relative-urls/urls.less +1 -0
  92. package/test/browser/less/urls.less +1 -0
  93. package/test/browser/runner-browser-options.js +23 -23
  94. package/test/browser/runner-errors-options.js +0 -1
  95. package/test/browser/runner-errors-spec.js +1 -2
  96. package/test/browser/runner-global-vars-spec.js +1 -1
  97. package/test/browser/runner-legacy-options.js +0 -1
  98. package/test/browser/runner-main-options.js +5 -5
  99. package/test/browser/runner-main-spec.js +1 -1
  100. package/test/browser/runner-no-js-errors-spec.js +0 -1
  101. package/test/browser/runner-production-options.js +0 -1
  102. package/test/browser/runner-relative-urls-options.js +0 -1
  103. package/test/browser/runner-rootpath-options.js +0 -1
  104. package/test/browser/runner-rootpath-relative-options.js +0 -1
  105. package/test/browser/runner-strict-units-options.js +0 -1
  106. package/test/copy-bom.js +72 -0
  107. package/test/css/comments.css +1 -0
  108. package/test/css/css-3.css +2 -0
  109. package/test/css/functions.css +10 -0
  110. package/test/css/import-interpolation.css +7 -0
  111. package/test/css/import-reference.css +25 -0
  112. package/test/css/include-path/include-path.css +6 -0
  113. package/test/css/mixins-important.css +12 -0
  114. package/test/css/selectors.css +15 -1
  115. package/test/css/static-urls/urls.css +1 -0
  116. package/test/css/url-args/urls.css +3 -3
  117. package/test/css/urls.css +13 -4
  118. package/test/css/variables.css +7 -1
  119. package/test/data/image.svg +3 -0
  120. package/test/index.js +15 -10
  121. package/test/less/comments.less +1 -0
  122. package/test/less/css-3.less +3 -0
  123. package/test/less/css-guards.less +2 -1
  124. package/test/less/errors/detached-ruleset-2.txt +1 -1
  125. package/test/less/errors/import-missing.txt +1 -1
  126. package/test/less/errors/parens-error-1.txt +1 -1
  127. package/test/less/errors/parens-error-2.txt +1 -1
  128. package/test/less/errors/parens-error-3.txt +1 -1
  129. package/test/less/errors/single-character.less +1 -0
  130. package/test/less/errors/single-character.txt +2 -0
  131. package/test/less/functions.less +18 -0
  132. package/test/less/import/import-interpolation.less +1 -0
  133. package/test/less/import/import-reference.less +38 -0
  134. package/test/less/import/imports/logo.less +1 -0
  135. package/test/less/import-reference.less +3 -1
  136. package/test/less/import.less +2 -0
  137. package/test/less/include-path/include-path.less +6 -0
  138. package/test/less/mixins-important.less +28 -0
  139. package/test/less/nested-gradient-with-svg-gradient/mixin-consumer.less +5 -0
  140. package/test/less/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +15 -0
  141. package/test/less/selectors.less +29 -4
  142. package/test/less/sourcemaps-empty/empty.less +0 -0
  143. package/test/less/sourcemaps-empty/var-defs.less +1 -0
  144. package/test/less/urls.less +10 -1
  145. package/test/less/variables.less +17 -3
  146. package/test/less-test.js +133 -52
  147. package/test/modify-vars.js +14 -12
  148. package/test/browser/less.js +0 -9473
@@ -27,11 +27,11 @@ less.formatError = function(ctx, options) {
27
27
  return ctx.stack || ctx.message;
28
28
  }
29
29
 
30
- if (typeof(extract[0]) === 'string') {
30
+ if (typeof extract[0] === 'string') {
31
31
  error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
32
32
  }
33
33
 
34
- if (typeof(extract[1]) === 'string') {
34
+ if (typeof extract[1] === 'string') {
35
35
  var errorTxt = ctx.line + ' ';
36
36
  if (extract[1]) {
37
37
  errorTxt += extract[1].slice(0, ctx.column) +
@@ -41,7 +41,7 @@ less.formatError = function(ctx, options) {
41
41
  error.push(errorTxt);
42
42
  }
43
43
 
44
- if (typeof(extract[2]) === 'string') {
44
+ if (typeof extract[2] === 'string') {
45
45
  error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey'));
46
46
  }
47
47
  error = error.join('\n') + stylize('', 'reset') + '\n';
@@ -68,4 +68,7 @@ less.writeError = function (ctx, options) {
68
68
  console.error(less.formatError(ctx, options));
69
69
  };
70
70
 
71
+ // provide image-size functionality
72
+ require('./image-size');
73
+
71
74
  module.exports = less;
@@ -37,12 +37,11 @@ var lessc_helper = {
37
37
  console.log(" --strict-imports Forces evaluation of imports.");
38
38
  console.log(" --insecure Allows imports from insecure https hosts.");
39
39
  console.log(" -v, --version Prints version number and exit.");
40
- console.log(" -x, --compress Compresses output by removing some whitespaces.");
41
40
  console.log(" --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).");
42
41
  console.log(" --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.");
43
42
  console.log(" --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.");
44
43
  console.log(" --source-map-less-inline Puts the less files into the map instead of referencing them.");
45
- console.log(" --source-map-map-inline Puts the map (and any less files) into the output css file.");
44
+ console.log(" --source-map-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.");
46
45
  console.log(" --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment");
47
46
  console.log(" in generated CSS file.");
48
47
  console.log(" -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls");
@@ -71,6 +70,8 @@ var lessc_helper = {
71
70
  console.log(" media query which is compatible with the SASS");
72
71
  console.log(" format, and 'all' which will do both.");
73
72
  console.log(" --verbose Be verbose.");
73
+ console.log(" -x, --compress Compresses output by removing some whitespaces.");
74
+ console.log(" We recommend you use a dedicated minifer like less-plugin-clean-css");
74
75
  console.log("");
75
76
  console.log("Report bugs to: http://github.com/less/less.js/issues");
76
77
  console.log("Home page: <http://lesscss.org/>");
@@ -38,7 +38,7 @@ PluginLoader.prototype.tryLoadPlugin = function(name, argument) {
38
38
  return null;
39
39
  };
40
40
  PluginLoader.prototype.compareVersion = function(aVersion, bVersion) {
41
- for(var i = 0; i < aVersion.length; i++) {
41
+ for (var i = 0; i < aVersion.length; i++) {
42
42
  if (aVersion[i] !== bVersion[i]) {
43
43
  return parseInt(aVersion[i]) > parseInt(bVersion[i]) ? -1 : 1;
44
44
  }
@@ -47,7 +47,7 @@ PluginLoader.prototype.compareVersion = function(aVersion, bVersion) {
47
47
  };
48
48
  PluginLoader.prototype.versionToString = function(version) {
49
49
  var versionString = "";
50
- for(var i = 0; i < version.length; i++) {
50
+ for (var i = 0; i < version.length; i++) {
51
51
  versionString += (versionString ? "." : "") + version[i];
52
52
  }
53
53
  return versionString;
@@ -81,7 +81,7 @@ PluginLoader.prototype.tryRequirePlugin = function(name) {
81
81
  }
82
82
  };
83
83
  PluginLoader.prototype.printUsage = function(plugins) {
84
- for(var i = 0; i < plugins.length; i++) {
84
+ for (var i = 0; i < plugins.length; i++) {
85
85
  var plugin = plugins[i];
86
86
  if (plugin.printUsage) {
87
87
  plugin.printUsage();
@@ -1,7 +1,7 @@
1
1
  var isUrlRe = /^(?:https?:)?\/\//i,
2
2
  url = require('url'),
3
3
  request,
4
- PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
4
+ PromiseConstructor,
5
5
  AbstractFileManager = require("../less/environment/abstract-file-manager.js"),
6
6
  logger = require("../less/logger");
7
7
 
@@ -15,6 +15,9 @@ UrlFileManager.prototype.supports = function(filename, currentDirectory, options
15
15
  };
16
16
 
17
17
  UrlFileManager.prototype.loadFile = function(filename, currentDirectory, options, environment) {
18
+ if (!PromiseConstructor) {
19
+ PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;
20
+ }
18
21
  return new PromiseConstructor(function(fulfill, reject) {
19
22
  if (request === undefined) {
20
23
  try { request = require('request'); }
@@ -35,7 +38,7 @@ UrlFileManager.prototype.loadFile = function(filename, currentDirectory, options
35
38
 
36
39
  request.get({uri: urlStr, strictSSL: !options.insecure }, function (error, res, body) {
37
40
  if (error) {
38
- reject({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n "+ error +"\n" });
41
+ reject({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n " + error + "\n" });
39
42
  return;
40
43
  }
41
44
  if (res && res.statusCode === 404) {
@@ -43,7 +46,7 @@ UrlFileManager.prototype.loadFile = function(filename, currentDirectory, options
43
46
  return;
44
47
  }
45
48
  if (!body) {
46
- logger.warn('Warning: Empty body (HTTP '+ res.statusCode + ') returned by "' + urlStr +'"');
49
+ logger.warn('Warning: Empty body (HTTP ' + res.statusCode + ') returned by "' + urlStr + '"');
47
50
  }
48
51
  fulfill({ contents: body, filename: urlStr });
49
52
  });
@@ -18,11 +18,11 @@ function formatError(ctx, options) {
18
18
  return ctx.stack || ctx.message;
19
19
  }
20
20
 
21
- if (typeof(extract[0]) === 'string') {
21
+ if (typeof extract[0] === 'string') {
22
22
  error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
23
23
  }
24
24
 
25
- if (typeof(extract[1]) === 'string') {
25
+ if (typeof extract[1] === 'string') {
26
26
  var errorTxt = ctx.line + ' ';
27
27
  if (extract[1]) {
28
28
  errorTxt += extract[1].slice(0, ctx.column) +
@@ -32,14 +32,14 @@ function formatError(ctx, options) {
32
32
  error.push(errorTxt);
33
33
  }
34
34
 
35
- if (typeof(extract[2]) === 'string') {
35
+ if (typeof extract[2] === 'string') {
36
36
  error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey'));
37
37
  }
38
38
  error = error.join('\n') + stylize('', 'reset') + '\n';
39
39
 
40
40
  message += stylize(ctx.type + 'Error: ' + ctx.message, 'red');
41
41
  if (ctx.filename) {
42
- message += stylize(' in ', 'red') + ctx.filename +
42
+ message += stylize(' in ', 'red') + ctx.filename +
43
43
  stylize(' on line ' + ctx.line + ', column ' + (ctx.column + 1) + ':', 'grey');
44
44
  }
45
45
 
@@ -113,8 +113,8 @@ less.Parser.fileLoader = function (file, currentFileInfo, callback, env) {
113
113
  }
114
114
 
115
115
  var j = file.lastIndexOf('/');
116
- if(newFileInfo.relativeUrls && !/^(?:[a-z-]+:|\/)/.test(file) && j != -1) {
117
- var relativeSubDirectory = file.slice(0, j+1);
116
+ if (newFileInfo.relativeUrls && !/^(?:[a-z-]+:|\/)/.test(file) && j != -1) {
117
+ var relativeSubDirectory = file.slice(0, j + 1);
118
118
  newFileInfo.rootpath = newFileInfo.rootpath + relativeSubDirectory; // append (sub|sup) directory path of imported file
119
119
  }
120
120
  newFileInfo.currentDirectory = path;
@@ -135,7 +135,6 @@ less.Parser.fileLoader = function (file, currentFileInfo, callback, env) {
135
135
  }
136
136
  };
137
137
 
138
-
139
138
  function writeFile(filename, content) {
140
139
  var fstream = new java.io.FileWriter(filename);
141
140
  var out = new java.io.BufferedWriter(fstream);
@@ -178,7 +177,7 @@ function writeFile(filename, content) {
178
177
  var checkBooleanArg = function(arg) {
179
178
  var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg);
180
179
  if (!onOff) {
181
- print(" unable to parse "+arg+" as a boolean. use one of on/t/true/y/yes/off/f/false/n/no");
180
+ print(" unable to parse " + arg + " as a boolean. use one of on/t/true/y/yes/off/f/false/n/no");
182
181
  continueProcessing = false;
183
182
  return false;
184
183
  }
@@ -197,8 +196,12 @@ function writeFile(filename, content) {
197
196
  }
198
197
 
199
198
  match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=(.*))?$/i);
200
- if (match) { arg = match[1]; } // was (?:=([^\s]*)), check!
201
- else { return arg; }
199
+ if (match) {
200
+ arg = match[1];
201
+ }
202
+ else {
203
+ return arg;
204
+ }
202
205
 
203
206
  switch (arg) {
204
207
  case 'v':
@@ -306,10 +309,10 @@ function writeFile(filename, content) {
306
309
  case 'source-map-output-map-file':
307
310
  if (checkArgFunc(arg, match[2])) {
308
311
  options.writeSourceMap = function(sourceMapContent) {
309
- writeFile(match[2], sourceMapContent);
312
+ writeFile(match[2], sourceMapContent);
310
313
  };
311
314
  }
312
- break;
315
+ break;
313
316
  case 'rp':
314
317
  case 'rootpath':
315
318
  if (checkArgFunc(arg, match[2])) {
@@ -371,7 +374,6 @@ function writeFile(filename, content) {
371
374
  options.sourceMapOutputFilename = options.sourceMap;
372
375
  }
373
376
 
374
-
375
377
  if (!name) {
376
378
  console.log("lessc: no inout files");
377
379
  console.log("");
@@ -1872,7 +1872,7 @@ define('source-map/source-node', ['require', 'exports', 'module' , 'source-map/
1872
1872
  if (original.source !== null
1873
1873
  && original.line !== null
1874
1874
  && original.column !== null) {
1875
- if(lastOriginalSource !== original.source
1875
+ if (lastOriginalSource !== original.source
1876
1876
  || lastOriginalLine !== original.line
1877
1877
  || lastOriginalColumn !== original.column
1878
1878
  || lastOriginalName !== original.name) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "less",
3
- "version": "2.1.2",
3
+ "version": "2.4.0",
4
4
  "description": "Leaner CSS",
5
5
  "homepage": "http://lesscss.org",
6
6
  "author": {
@@ -40,12 +40,14 @@
40
40
  "test": "grunt test"
41
41
  },
42
42
  "optionalDependencies": {
43
- "graceful-fs": "^3.0.4",
43
+ "errno": "^0.1.1",
44
+ "graceful-fs": "^3.0.5",
45
+ "image-size": "~0.3.5",
44
46
  "mime": "^1.2.11",
45
- "request": "^2.48.0",
46
47
  "mkdirp": "^0.5.0",
47
- "source-map": "^0.1.x",
48
- "promise": "^6.0.1"
48
+ "promise": "^6.0.1",
49
+ "request": "^2.51.0",
50
+ "source-map": "^0.2.0"
49
51
  },
50
52
  "devDependencies": {
51
53
  "diff": "^1.0",
@@ -54,8 +56,9 @@
54
56
  "grunt-contrib-concat": "^0.5.0",
55
57
  "grunt-contrib-connect": "^0.9.0",
56
58
  "grunt-contrib-jasmine": "^0.8.1",
57
- "grunt-contrib-jshint": "^0.10.0",
58
- "grunt-contrib-uglify": "^0.6.0",
59
+ "grunt-contrib-jshint": "^0.11.0",
60
+ "grunt-contrib-uglify": "^0.7.0",
61
+ "grunt-jscs": "^1.2.0",
59
62
  "grunt-shell": "^1.1.1",
60
63
  "grunt-browserify": "^3.2.0",
61
64
  "matchdep": "^0.3.0",
@@ -130,10 +130,10 @@ var testErrorSheet = function (sheet) {
130
130
  .replace(/<h3>|<\/?p>|<a href="[^"]*">|<\/a>|<ul>|<\/?pre( class="?[^">]*"?)?>|<\/li>|<\/?label>/ig, "")
131
131
  .replace(/<\/h3>/ig, " ")
132
132
  .replace(/<li>|<\/ul>|<br>/ig, "\n"))
133
- .replace(/&amp;/ig,"&")
133
+ .replace(/&amp;/ig, "&")
134
134
  // for IE8
135
- .replace(/\r\n/g,"\n")
136
- .replace(/\. \nin/,". in");
135
+ .replace(/\r\n/g, "\n")
136
+ .replace(/\. \nin/, ". in");
137
137
  actualErrorMsg = innerText
138
138
  .replace(/\n\d+/g, function (lineNo) {
139
139
  return lineNo + " ";
@@ -145,10 +145,11 @@ var testErrorSheet = function (sheet) {
145
145
  errorFile
146
146
  .then(function (errorTxt) {
147
147
  errorTxt = errorTxt
148
- .replace("{path}", "")
149
- .replace("{pathrel}", "")
150
- .replace("{pathhref}", "http://localhost:8081/test/less/errors/")
151
- .replace("{404status}", " (404)")
148
+ .replace(/\{path\}/g, "")
149
+ .replace(/\{pathrel\}/g, "")
150
+ .replace(/\{pathhref\}/g, "http://localhost:8081/test/less/errors/")
151
+ .replace(/\{404status\}/g, " (404)")
152
+ .replace(/\{node\}.*\{\/node\}/g, "")
152
153
  .replace(/\n$/, "");
153
154
  expect(actualErrorMsg).toEqual(errorTxt);
154
155
  if (errorTxt == actualErrorMsg) {
@@ -177,10 +178,11 @@ var testErrorSheetConsole = function (sheet) {
177
178
  errorFile
178
179
  .then(function (errorTxt) {
179
180
  errorTxt
180
- .replace("{path}", "")
181
- .replace("{pathrel}", "")
182
- .replace("{pathhref}", "http://localhost:8081/browser/less/")
183
- .replace("{404status}", " (404)")
181
+ .replace(/\{path\}/g, "")
182
+ .replace(/\{pathrel\}/g, "")
183
+ .replace(/\{pathhref\}/g, "http://localhost:8081/browser/less/")
184
+ .replace(/\{404status\}/g, " (404)")
185
+ .replace(/\{node\}.*\{\/node\}/g, "")
184
186
  .trim();
185
187
  expect(actualErrorMsg).toEqual(errorTxt);
186
188
  done();
@@ -15,6 +15,7 @@
15
15
  }
16
16
  #misc {
17
17
  background-image: url(http://localhost:8081/test/browser/less/relative-urls/images/image.jpg);
18
+ background: url("#inline-svg");
18
19
  }
19
20
  #data-uri {
20
21
  background: url(data:image/png;charset=utf-8;base64,
@@ -6,6 +6,9 @@
6
6
  .modify {
7
7
  my-url: url("http://localhost:8081/test/browser/less/b.png");
8
8
  }
9
+ .gray-gradient {
10
+ background: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%220%200%201%201%22%20preserveAspectRatio%3D%22none%22%3E%3ClinearGradient%20id%3D%22gradient%22%20gradientUnits%3D%22userSpaceOnUse%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%220%25%22%20y2%3D%22100%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220%22%2F%3E%3Cstop%20offset%3D%2260%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.05%22%2F%3E%3Cstop%20offset%3D%2270%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.1%22%2F%3E%3Cstop%20offset%3D%2273%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.15%22%2F%3E%3Cstop%20offset%3D%2275%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.2%22%2F%3E%3Cstop%20offset%3D%2280%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.25%22%2F%3E%3Cstop%20offset%3D%2285%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.3%22%2F%3E%3Cstop%20offset%3D%2288%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.35%22%2F%3E%3Cstop%20offset%3D%2290%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.4%22%2F%3E%3Cstop%20offset%3D%2295%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.45%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23999999%22%20stop-opacity%3D%220.5%22%2F%3E%3C%2FlinearGradient%3E%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22url(%23gradient)%22%20%2F%3E%3C%2Fsvg%3E');
11
+ }
9
12
  @font-face {
10
13
  src: url("/fonts/garamond-pro.ttf");
11
14
  src: local(Futura-Medium), url(http://localhost:8081/test/browser/less/fonts.svg#MyGeometricModern) format("svg");
@@ -48,7 +51,7 @@
48
51
  uri: url('http://localhost:8081/test/data/data-uri-fail.png');
49
52
  }
50
53
  #svg-functions {
51
- background-image: url('data:image/svg+xml,<?xml version="1.0" ?><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none"><linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#000000"/><stop offset="100%" stop-color="#ffffff"/></linearGradient><rect x="0" y="0" width="1" height="1" fill="url(#gradient)" /></svg>');
52
- background-image: url('data:image/svg+xml,<?xml version="1.0" ?><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none"><linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#000000"/><stop offset="3%" stop-color="#ffa500"/><stop offset="100%" stop-color="#ffffff"/></linearGradient><rect x="0" y="0" width="1" height="1" fill="url(#gradient)" /></svg>');
53
- background-image: url('data:image/svg+xml,<?xml version="1.0" ?><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none"><linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="1%" stop-color="#c4c4c4"/><stop offset="3%" stop-color="#ffa500"/><stop offset="5%" stop-color="#008000"/><stop offset="95%" stop-color="#ffffff"/></linearGradient><rect x="0" y="0" width="1" height="1" fill="url(#gradient)" /></svg>');
54
+ background-image: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%220%200%201%201%22%20preserveAspectRatio%3D%22none%22%3E%3ClinearGradient%20id%3D%22gradient%22%20gradientUnits%3D%22userSpaceOnUse%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%220%25%22%20y2%3D%22100%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23000000%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23ffffff%22%2F%3E%3C%2FlinearGradient%3E%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22url(%23gradient)%22%20%2F%3E%3C%2Fsvg%3E');
55
+ background-image: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%220%200%201%201%22%20preserveAspectRatio%3D%22none%22%3E%3ClinearGradient%20id%3D%22gradient%22%20gradientUnits%3D%22userSpaceOnUse%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%220%25%22%20y2%3D%22100%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23000000%22%2F%3E%3Cstop%20offset%3D%223%25%22%20stop-color%3D%22%23ffa500%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23ffffff%22%2F%3E%3C%2FlinearGradient%3E%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22url(%23gradient)%22%20%2F%3E%3C%2Fsvg%3E');
56
+ background-image: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%220%200%201%201%22%20preserveAspectRatio%3D%22none%22%3E%3ClinearGradient%20id%3D%22gradient%22%20gradientUnits%3D%22userSpaceOnUse%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%220%25%22%20y2%3D%22100%25%22%3E%3Cstop%20offset%3D%221%25%22%20stop-color%3D%22%23c4c4c4%22%2F%3E%3Cstop%20offset%3D%223%25%22%20stop-color%3D%22%23ffa500%22%2F%3E%3Cstop%20offset%3D%225%25%22%20stop-color%3D%22%23008000%22%2F%3E%3Cstop%20offset%3D%2295%25%22%20stop-color%3D%22%23ffffff%22%2F%3E%3C%2FlinearGradient%3E%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22url(%23gradient)%22%20%2F%3E%3C%2Fsvg%3E');
54
57
  }
@@ -180,7 +180,6 @@
180
180
  // export public
181
181
  jasmine.JSReporter = JSReporter;
182
182
 
183
-
184
183
  // ------------------------------------------------------------------------
185
184
  // Jasmine JSReporter for Jasmine 2.0
186
185
  // ------------------------------------------------------------------------
@@ -240,7 +239,7 @@
240
239
  suite.specs = [];
241
240
  suite.suites = [];
242
241
  suite.passed = true;
243
- suite.parentId = this.suiteStack.slice(this.suiteStack.length -1)[0];
242
+ suite.parentId = this.suiteStack.slice(this.suiteStack.length - 1)[0];
244
243
  if (suite.parentId) {
245
244
  this.suites[suite.parentId].suites.push(suite);
246
245
  } else {
@@ -273,7 +272,7 @@
273
272
  spec = this._cacheSpec(spec);
274
273
  spec.timer = new Timer().start();
275
274
  // build up suites->spec tree as we go
276
- spec.suiteId = this.suiteStack.slice(this.suiteStack.length -1)[0];
275
+ spec.suiteId = this.suiteStack.slice(this.suiteStack.length - 1)[0];
277
276
  this.suites[spec.suiteId].specs.push(spec);
278
277
  };
279
278
 
@@ -0,0 +1,5 @@
1
+ @import "svg-gradient-mixin.less";
2
+
3
+ .gray-gradient {
4
+ .gradient-mixin(#999);
5
+ }
@@ -0,0 +1,15 @@
1
+ .gradient-mixin(@color) {
2
+ background: svg-gradient(to bottom,
3
+ fade(@color, 0%) 0%,
4
+ fade(@color, 5%) 60%,
5
+ fade(@color, 10%) 70%,
6
+ fade(@color, 15%) 73%,
7
+ fade(@color, 20%) 75%,
8
+ fade(@color, 25%) 80%,
9
+ fade(@color, 30%) 85%,
10
+ fade(@color, 35%) 88%,
11
+ fade(@color, 40%) 90%,
12
+ fade(@color, 45%) 95%,
13
+ fade(@color, 50%) 100%
14
+ );
15
+ }
@@ -10,6 +10,7 @@
10
10
  }
11
11
  #misc {
12
12
  background-image: url(images/image.jpg);
13
+ background: url("#inline-svg");
13
14
  }
14
15
  #data-uri {
15
16
  background: url(data:image/png;charset=utf-8;base64,
@@ -1,5 +1,6 @@
1
1
  @import "imports/urls.less";
2
2
  @import "http://localhost:8081/test/browser/less/imports/urls2.less";
3
+ @import "http://localhost:8081/test/browser/less/nested-gradient-with-svg-gradient/mixin-consumer.less";
3
4
  @font-face {
4
5
  src: url("/fonts/garamond-pro.ttf");
5
6
  src: local(Futura-Medium),
@@ -18,34 +18,34 @@ if (window.navigator.userAgent.indexOf("MSIE") >= 0) {
18
18
  // setup style tags with less and link tags pointing to expected css output
19
19
 
20
20
  for (var i = 0; i < testFiles.length; i++) {
21
- var file = testFiles[i],
22
- lessPath = '/test/less/' + file + '.less',
23
- cssPath = '/test/css/' + file + '.css',
24
- lessStyle = document.createElement('style'),
25
- cssLink = document.createElement('link'),
26
- lessText = '@import "' + lessPath + '";';
21
+ var file = testFiles[i],
22
+ lessPath = '/test/less/' + file + '.less',
23
+ cssPath = '/test/css/' + file + '.css',
24
+ lessStyle = document.createElement('style'),
25
+ cssLink = document.createElement('link'),
26
+ lessText = '@import "' + lessPath + '";';
27
27
 
28
- lessStyle.type = 'text/less';
29
- lessStyle.id = file;
30
- lessStyle.href = file;
28
+ lessStyle.type = 'text/less';
29
+ lessStyle.id = file;
30
+ lessStyle.href = file;
31
31
 
32
- if (lessStyle.styleSheet === undefined) {
33
- lessStyle.appendChild(document.createTextNode(lessText));
34
- }
32
+ if (lessStyle.styleSheet === undefined) {
33
+ lessStyle.appendChild(document.createTextNode(lessText));
34
+ }
35
35
 
36
- cssLink.rel = 'stylesheet';
37
- cssLink.type = 'text/css';
38
- cssLink.href = cssPath;
39
- cssLink.id = 'expected-' + file;
36
+ cssLink.rel = 'stylesheet';
37
+ cssLink.type = 'text/css';
38
+ cssLink.href = cssPath;
39
+ cssLink.id = 'expected-' + file;
40
40
 
41
- var head = document.getElementsByTagName('head')[0];
41
+ var head = document.getElementsByTagName('head')[0];
42
42
 
43
- head.appendChild(lessStyle);
43
+ head.appendChild(lessStyle);
44
44
 
45
- if (lessStyle.styleSheet) {
46
- lessStyle.styleSheet.cssText = lessText;
47
- }
45
+ if (lessStyle.styleSheet) {
46
+ lessStyle.styleSheet.cssText = lessText;
47
+ }
48
48
 
49
- head.appendChild(cssLink);
50
- testSheets[i] = lessStyle;
49
+ head.appendChild(cssLink);
50
+ testSheets[i] = lessStyle;
51
51
  }
@@ -2,4 +2,3 @@ var less = {
2
2
  strictUnits: true,
3
3
  strictMath: true,
4
4
  logLevel: 4 };
5
-
@@ -1,4 +1,3 @@
1
1
  describe("less.js error tests", function() {
2
- testLessErrorsInDocument();
2
+ testLessErrorsInDocument();
3
3
  });
4
-
@@ -1,3 +1,3 @@
1
1
  describe("less.js global vars", function() {
2
- testLessEqualsInDocument();
2
+ testLessEqualsInDocument();
3
3
  });
@@ -3,4 +3,3 @@ var less = {
3
3
  errorReporting: "console",
4
4
  strictMath: false,
5
5
  strictUnits: false };
6
-
@@ -5,14 +5,14 @@ var less = {
5
5
  less.strictMath = true;
6
6
  less.functions = {
7
7
  add: function(a, b) {
8
- return new(less.tree.Dimension)(a.value + b.value);
8
+ return new(less.tree.Dimension)(a.value + b.value);
9
9
  },
10
10
  increment: function(a) {
11
- return new(less.tree.Dimension)(a.value + 1);
11
+ return new(less.tree.Dimension)(a.value + 1);
12
12
  },
13
13
  _color: function(str) {
14
- if (str.value === "evil red") {
15
- return new(less.tree.Color)("600");
16
- }
14
+ if (str.value === "evil red") {
15
+ return new(less.tree.Color)("600");
16
+ }
17
17
  }
18
18
  };
@@ -2,6 +2,6 @@ console.warn("start spec");
2
2
  describe("less.js main tests", function() {
3
3
  testLessEqualsInDocument();
4
4
  it("the global environment", function() {
5
- expect(window.require).toBe(undefined);
5
+ expect(window.require).toBe(undefined);
6
6
  });
7
7
  });
@@ -1,4 +1,3 @@
1
1
  describe("less.js javascript disabled error tests", function() {
2
2
  testLessErrorsInDocument();
3
3
  });
4
-
@@ -1,4 +1,3 @@
1
1
  var less = {logLevel: 4,
2
2
  errorReporting: "console"};
3
3
  less.env = "production";
4
-
@@ -1,4 +1,3 @@
1
1
  var less = {logLevel: 4,
2
2
  errorReporting: "console"};
3
3
  less.relativeUrls = true;
4
-
@@ -1,4 +1,3 @@
1
1
  var less = {logLevel: 4,
2
2
  errorReporting: "console"};
3
3
  less.rootpath = "https://localhost/";
4
-
@@ -2,4 +2,3 @@ var less = {logLevel: 4,
2
2
  errorReporting: "console"};
3
3
  less.rootpath = "https://www.github.com/cloudhead/less.js/";
4
4
  less.relativeUrls = true;
5
-
@@ -3,4 +3,3 @@ var less = {
3
3
  errorReporting: "console",
4
4
  strictMath: true,
5
5
  strictUnits: true };
6
-
@@ -0,0 +1,72 @@
1
+ /*jshint latedef: nofunc */
2
+
3
+ // This is used to copy a folder (the test/less/* files & sub-folders), adding a BOM to the start of each LESS and CSS file.
4
+ // This is a based on the copySync method from fs-extra (https://github.com/jprichardson/node-fs-extra/).
5
+
6
+ module.exports = function() {
7
+ var path = require('path'),
8
+ fs = require('fs');
9
+
10
+ var BUF_LENGTH = 64 * 1024;
11
+ var _buff = new Buffer(BUF_LENGTH);
12
+
13
+ function copyFolderWithBom(src, dest) {
14
+ var stats = fs.lstatSync(src);
15
+ var destFolder = path.dirname(dest);
16
+ var destFolderExists = fs.existsSync(destFolder);
17
+ var performCopy = false;
18
+
19
+ if (stats.isFile()) {
20
+ if (!destFolderExists) {
21
+ fs.mkdirSync(destFolder);
22
+ }
23
+ if (src.match(/\.(css|less)$/)) {
24
+ copyFileAddingBomSync(src, dest);
25
+ } else {
26
+ copyFileSync(src, dest);
27
+ }
28
+ }
29
+ else if (stats.isDirectory()) {
30
+ if (!fs.existsSync(destFolder)) {
31
+ fs.mkdirSync(destFolder);
32
+ }
33
+ if (!fs.existsSync(dest)) {
34
+ fs.mkdirSync(dest);
35
+ }
36
+ fs.readdirSync(src).forEach(function(d) {
37
+ if (d !== 'bom') {
38
+ copyFolderWithBom(path.join(src, d), path.join(dest, d));
39
+ }
40
+ });
41
+ }
42
+ }
43
+
44
+ function copyFileAddingBomSync(srcFile, destFile) {
45
+ var contents = fs.readFileSync(srcFile, { encoding: 'utf8' });
46
+ if (!contents.length || contents.charCodeAt(0) !== 0xFEFF) {
47
+ contents = '\ufeff' + contents;
48
+ }
49
+ fs.writeFileSync(destFile, contents, { encoding: 'utf8' });
50
+ }
51
+
52
+ function copyFileSync(srcFile, destFile) {
53
+ var fdr = fs.openSync(srcFile, 'r');
54
+ var stat = fs.fstatSync(fdr);
55
+ var fdw = fs.openSync(destFile, 'w', stat.mode);
56
+ var bytesRead = 1;
57
+ var pos = 0;
58
+
59
+ while (bytesRead > 0) {
60
+ bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos)
61
+ fs.writeSync(fdw, _buff, 0, bytesRead);
62
+ pos += bytesRead;
63
+ }
64
+
65
+ fs.closeSync(fdr);
66
+ fs.closeSync(fdw);
67
+ }
68
+
69
+ return {
70
+ copyFolderWithBom: copyFolderWithBom
71
+ };
72
+ };