less 3.7.0 → 3.9.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 (91) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/Gruntfile.js +45 -7
  3. package/bin/lessc +24 -5
  4. package/dist/less.js +644 -210
  5. package/dist/less.min.js +7 -7
  6. package/lib/less/constants.js +13 -0
  7. package/lib/less/contexts.js +38 -10
  8. package/lib/less/default-options.js +1 -1
  9. package/lib/less/functions/color.js +84 -41
  10. package/lib/less/functions/data-uri.js +1 -1
  11. package/lib/less/functions/list.js +44 -9
  12. package/lib/less/import-manager.js +3 -3
  13. package/lib/less/index.js +1 -1
  14. package/lib/less/parse.js +1 -1
  15. package/lib/less/parser/parser.js +2 -9
  16. package/lib/less/source-map-output.js +2 -2
  17. package/lib/less/tree/color.js +58 -18
  18. package/lib/less/tree/declaration.js +1 -1
  19. package/lib/less/tree/expression.js +1 -1
  20. package/lib/less/tree/import.js +9 -8
  21. package/lib/less/tree/operation.js +1 -1
  22. package/lib/less/tree/url.js +12 -8
  23. package/lib/less/tree/variable-call.js +6 -3
  24. package/lib/less/utils.js +36 -26
  25. package/lib/less-browser/add-default-options.js +4 -0
  26. package/lib/less-browser/index.js +9 -2
  27. package/lib/less-node/image-size.js +1 -1
  28. package/lib/less-node/lessc-helper.js +2 -1
  29. package/package.json +5 -3
  30. package/test/browser/css/rewrite-urls/urls.css +36 -0
  31. package/test/browser/css/rootpath-rewrite-urls/urls.css +35 -0
  32. package/test/browser/less/rewrite-urls/urls.less +34 -0
  33. package/test/browser/less/rootpath-rewrite-urls/urls.less +33 -0
  34. package/test/browser/less.js +644 -210
  35. package/test/browser/runner-rewrite-urls-options.js +3 -0
  36. package/test/browser/runner-rewrite-urls-spec.js +3 -0
  37. package/test/browser/runner-rootpath-relative-spec.js +1 -1
  38. package/test/browser/runner-rootpath-rewrite-urls-options.js +4 -0
  39. package/test/browser/runner-rootpath-rewrite-urls-spec.js +3 -0
  40. package/test/css/colors.css +20 -3
  41. package/test/css/css-escapes.css +3 -0
  42. package/test/css/functions-each.css +34 -0
  43. package/test/css/functions.css +4 -4
  44. package/test/css/rewrite-urls-all/rewrite-urls-all.css +17 -0
  45. package/test/css/rewrite-urls-local/rewrite-urls-local.css +17 -0
  46. package/test/css/rootpath-rewrite-urls-all/rootpath-rewrite-urls-all.css +17 -0
  47. package/test/css/rootpath-rewrite-urls-local/rootpath-rewrite-urls-local.css +17 -0
  48. package/test/css/static-urls/urls.css +2 -2
  49. package/test/css/urls.css +2 -2
  50. package/test/index.js +8 -2
  51. package/test/less/colors.less +18 -0
  52. package/test/less/css-escapes.less +4 -0
  53. package/test/less/errors/color-func-invalid-color.txt +1 -1
  54. package/test/less/functions-each.less +51 -1
  55. package/test/less/rewrite-urls-all/folder/file.less +8 -0
  56. package/test/less/rewrite-urls-all/rewrite-urls-all.less +11 -0
  57. package/test/less/rewrite-urls-local/folder/file.less +8 -0
  58. package/test/less/rewrite-urls-local/rewrite-urls-local.less +11 -0
  59. package/test/less/rootpath-rewrite-urls-all/folder/file.less +8 -0
  60. package/test/less/rootpath-rewrite-urls-all/rootpath-rewrite-urls-all.less +11 -0
  61. package/test/less/rootpath-rewrite-urls-local/folder/file.less +8 -0
  62. package/test/less/rootpath-rewrite-urls-local/rootpath-rewrite-urls-local.less +11 -0
  63. package/test/less/sourcemaps/custom-props.less +8 -0
  64. package/test/less-bom/colors.less +18 -0
  65. package/test/less-bom/css-escapes.less +4 -0
  66. package/test/less-bom/errors/color-func-invalid-color.txt +1 -1
  67. package/test/less-bom/functions-each.less +51 -1
  68. package/test/less-bom/rewrite-urls-all/folder/file.less +8 -0
  69. package/test/less-bom/rewrite-urls-all/rewrite-urls-all.less +11 -0
  70. package/test/less-bom/rewrite-urls-local/folder/file.less +8 -0
  71. package/test/less-bom/rewrite-urls-local/rewrite-urls-local.less +11 -0
  72. package/test/less-bom/rootpath-rewrite-urls-all/folder/file.less +8 -0
  73. package/test/less-bom/rootpath-rewrite-urls-all/rootpath-rewrite-urls-all.less +11 -0
  74. package/test/less-bom/rootpath-rewrite-urls-local/folder/file.less +8 -0
  75. package/test/less-bom/rootpath-rewrite-urls-local/rootpath-rewrite-urls-local.less +11 -0
  76. package/test/less-bom/sourcemaps/custom-props.less +8 -0
  77. package/test/less-test.js +26 -12
  78. package/test/sourcemaps/custom-props.json +1 -0
  79. package/.npmignore +0 -8
  80. package/lib/less/math-constants.js +0 -6
  81. package/test/css/3rd-party/bootstrap.css +0 -6814
  82. package/test/less/3rd-party/bootstrap.less +0 -1
  83. package/test/less/errors/color-invalid-hex-code.less +0 -4
  84. package/test/less/errors/color-invalid-hex-code.txt +0 -4
  85. package/test/less/errors/color-invalid-hex-code2.less +0 -4
  86. package/test/less/errors/color-invalid-hex-code2.txt +0 -4
  87. package/test/less-bom/3rd-party/bootstrap.less +0 -1
  88. package/test/less-bom/errors/color-invalid-hex-code.less +0 -4
  89. package/test/less-bom/errors/color-invalid-hex-code.txt +0 -4
  90. package/test/less-bom/errors/color-invalid-hex-code2.less +0 -4
  91. package/test/less-bom/errors/color-invalid-hex-code2.txt +0 -4
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ Math: {
3
+ ALWAYS: 0,
4
+ PARENS_DIVISION: 1,
5
+ PARENS: 2,
6
+ STRICT_LEGACY: 3
7
+ },
8
+ RewriteUrls: {
9
+ OFF: 0,
10
+ LOCAL: 1,
11
+ ALL: 2
12
+ }
13
+ };
@@ -1,6 +1,6 @@
1
1
  var contexts = {};
2
2
  module.exports = contexts;
3
- var MATH = require('./math-constants');
3
+ var Constants = require('./constants');
4
4
 
5
5
  var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {
6
6
  if (!original) { return; }
@@ -18,7 +18,7 @@ var copyFromOriginal = function copyFromOriginal(original, destination, properti
18
18
  var parseCopyProperties = [
19
19
  // options
20
20
  'paths', // option - unmodified - paths to search for imports on
21
- 'relativeUrls', // option - whether to adjust URL's to be relative
21
+ 'rewriteUrls', // option - whether to adjust URL's to be relative
22
22
  'rootpath', // option - rootpath to append to URL's
23
23
  'strictImports', // option -
24
24
  'insecure', // option - whether to allow imports from insecure ssl hosts
@@ -51,7 +51,8 @@ var evalCopyProperties = [
51
51
  'urlArgs', // whether to add args into url tokens
52
52
  'javascriptEnabled', // option - whether Inline JavaScript is enabled. if undefined, defaults to false
53
53
  'pluginManager', // Used as the plugin manager for the session
54
- 'importantScope' // used to bubble up !important statements
54
+ 'importantScope', // used to bubble up !important statements
55
+ 'rewriteUrls' // option - whether to adjust URL's to be relative
55
56
  ];
56
57
 
57
58
  contexts.Eval = function(options, frames) {
@@ -95,26 +96,45 @@ contexts.Eval.prototype.isMathOn = function (op) {
95
96
  if (!this.mathOn) {
96
97
  return false;
97
98
  }
98
- if (op === '/' && this.math !== MATH.ALWAYS && (!this.parensStack || !this.parensStack.length)) {
99
+ if (op === '/' && this.math !== Constants.Math.ALWAYS && (!this.parensStack || !this.parensStack.length)) {
99
100
  return false;
100
101
  }
101
- if (this.math > MATH.PARENS_DIVISION) {
102
+ if (this.math > Constants.Math.PARENS_DIVISION) {
102
103
  return this.parensStack && this.parensStack.length;
103
104
  }
104
105
  return true;
105
106
  };
106
107
 
107
- contexts.Eval.prototype.isPathRelative = function (path) {
108
- return !/^(?:[a-z-]+:|\/|#)/i.test(path);
108
+ contexts.Eval.prototype.pathRequiresRewrite = function (path) {
109
+ var isRelative = this.rewriteUrls === Constants.RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative;
110
+
111
+ return isRelative(path);
109
112
  };
110
113
 
111
- contexts.Eval.prototype.normalizePath = function( path ) {
114
+ contexts.Eval.prototype.rewritePath = function (path, rootpath) {
115
+ var newPath;
116
+
117
+ rootpath = rootpath || '';
118
+ newPath = this.normalizePath(rootpath + path);
119
+
120
+ // If a path was explicit relative and the rootpath was not an absolute path
121
+ // we must ensure that the new path is also explicit relative.
122
+ if (isPathLocalRelative(path) &&
123
+ isPathRelative(rootpath) &&
124
+ isPathLocalRelative(newPath) === false) {
125
+ newPath = './' + newPath;
126
+ }
127
+
128
+ return newPath;
129
+ };
130
+
131
+ contexts.Eval.prototype.normalizePath = function (path) {
112
132
  var
113
133
  segments = path.split('/').reverse(),
114
134
  segment;
115
135
 
116
136
  path = [];
117
- while (segments.length !== 0 ) {
137
+ while (segments.length !== 0) {
118
138
  segment = segments.pop();
119
139
  switch ( segment ) {
120
140
  case '.':
@@ -127,7 +147,7 @@ contexts.Eval.prototype.normalizePath = function( path ) {
127
147
  }
128
148
  break;
129
149
  default:
130
- path.push( segment );
150
+ path.push(segment);
131
151
  break;
132
152
  }
133
153
  }
@@ -135,4 +155,12 @@ contexts.Eval.prototype.normalizePath = function( path ) {
135
155
  return path.join('/');
136
156
  };
137
157
 
158
+ function isPathRelative(path) {
159
+ return !/^(?:[a-z-]+:|\/|#)/i.test(path);
160
+ }
161
+
162
+ function isPathLocalRelative(path) {
163
+ return path.charAt(0) === '.';
164
+ }
165
+
138
166
  // todo - do the same for the toCSS ?
@@ -42,7 +42,7 @@ module.exports = function() {
42
42
  * that references an image, exactly the same URL will be output in the css.
43
43
  * This option allows you to re-write URL's in imported files so that the
44
44
  * URL is always relative to the base imported file */
45
- relativeUrls: false,
45
+ rewriteUrls: false,
46
46
 
47
47
  /* Compatibility with IE8. Used for limiting data-uri length */
48
48
  ieCompat: false, // true until 3.0
@@ -8,8 +8,17 @@ var Dimension = require('../tree/dimension'),
8
8
  function clamp(val) {
9
9
  return Math.min(1, Math.max(0, val));
10
10
  }
11
- function hsla(color) {
12
- return colorFunctions.hsla(color.h, color.s, color.l, color.a);
11
+ function hsla(origColor, hsl) {
12
+ var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a);
13
+ if (color) {
14
+ if (origColor.value &&
15
+ /^(rgb|hsl)/.test(origColor.value)) {
16
+ color.value = origColor.value;
17
+ } else {
18
+ color.value = 'rgb';
19
+ }
20
+ return color;
21
+ }
13
22
  }
14
23
  function number(n) {
15
24
  if (n instanceof Dimension) {
@@ -32,46 +41,79 @@ function scaled(n, size) {
32
41
  }
33
42
  colorFunctions = {
34
43
  rgb: function (r, g, b) {
35
- return colorFunctions.rgba(r, g, b, 1.0);
44
+ var color = colorFunctions.rgba(r, g, b, 1.0);
45
+ if (color) {
46
+ color.value = 'rgb';
47
+ return color;
48
+ }
36
49
  },
37
50
  rgba: function (r, g, b, a) {
38
- var rgb = [r, g, b].map(function (c) { return scaled(c, 255); });
39
- a = number(a);
40
- return new Color(rgb, a);
51
+ try {
52
+ if (r instanceof Color) {
53
+ if (g) {
54
+ a = number(g);
55
+ } else {
56
+ a = r.alpha;
57
+ }
58
+ return new Color(r.rgb, a, 'rgba');
59
+ }
60
+ var rgb = [r, g, b].map(function (c) { return scaled(c, 255); });
61
+ a = number(a);
62
+ return new Color(rgb, a, 'rgba');
63
+ }
64
+ catch (e) {}
41
65
  },
42
66
  hsl: function (h, s, l) {
43
- return colorFunctions.hsla(h, s, l, 1.0);
67
+ var color = colorFunctions.hsla(h, s, l, 1.0);
68
+ if (color) {
69
+ color.value = 'hsl';
70
+ return color;
71
+ }
44
72
  },
45
73
  hsla: function (h, s, l, a) {
74
+ try {
75
+ if (h instanceof Color) {
76
+ if (s) {
77
+ a = number(s);
78
+ } else {
79
+ a = h.alpha;
80
+ }
81
+ return new Color(h.rgb, a, 'hsla');
82
+ }
46
83
 
47
- var m1, m2;
84
+ var m1, m2;
48
85
 
49
- function hue(h) {
50
- h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
51
- if (h * 6 < 1) {
52
- return m1 + (m2 - m1) * h * 6;
53
- }
54
- else if (h * 2 < 1) {
55
- return m2;
56
- }
57
- else if (h * 3 < 2) {
58
- return m1 + (m2 - m1) * (2 / 3 - h) * 6;
59
- }
60
- else {
61
- return m1;
86
+ function hue(h) {
87
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
88
+ if (h * 6 < 1) {
89
+ return m1 + (m2 - m1) * h * 6;
90
+ }
91
+ else if (h * 2 < 1) {
92
+ return m2;
93
+ }
94
+ else if (h * 3 < 2) {
95
+ return m1 + (m2 - m1) * (2 / 3 - h) * 6;
96
+ }
97
+ else {
98
+ return m1;
99
+ }
62
100
  }
63
- }
64
101
 
65
- h = (number(h) % 360) / 360;
66
- s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a));
102
+ h = (number(h) % 360) / 360;
103
+ s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a));
67
104
 
68
- m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
69
- m1 = l * 2 - m2;
105
+ m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
106
+ m1 = l * 2 - m2;
70
107
 
71
- return colorFunctions.rgba(hue(h + 1 / 3) * 255,
72
- hue(h) * 255,
73
- hue(h - 1 / 3) * 255,
74
- a);
108
+ var rgb = [
109
+ hue(h + 1 / 3) * 255,
110
+ hue(h) * 255,
111
+ hue(h - 1 / 3) * 255
112
+ ];
113
+ a = number(a);
114
+ return new Color(rgb, a, 'hsla');
115
+ }
116
+ catch (e) {}
75
117
  },
76
118
 
77
119
  hsv: function(h, s, v) {
@@ -159,7 +201,7 @@ colorFunctions = {
159
201
  hsl.s += amount.value / 100;
160
202
  }
161
203
  hsl.s = clamp(hsl.s);
162
- return hsla(hsl);
204
+ return hsla(color, hsl);
163
205
  },
164
206
  desaturate: function (color, amount, method) {
165
207
  var hsl = color.toHSL();
@@ -171,7 +213,7 @@ colorFunctions = {
171
213
  hsl.s -= amount.value / 100;
172
214
  }
173
215
  hsl.s = clamp(hsl.s);
174
- return hsla(hsl);
216
+ return hsla(color, hsl);
175
217
  },
176
218
  lighten: function (color, amount, method) {
177
219
  var hsl = color.toHSL();
@@ -183,7 +225,7 @@ colorFunctions = {
183
225
  hsl.l += amount.value / 100;
184
226
  }
185
227
  hsl.l = clamp(hsl.l);
186
- return hsla(hsl);
228
+ return hsla(color, hsl);
187
229
  },
188
230
  darken: function (color, amount, method) {
189
231
  var hsl = color.toHSL();
@@ -195,7 +237,7 @@ colorFunctions = {
195
237
  hsl.l -= amount.value / 100;
196
238
  }
197
239
  hsl.l = clamp(hsl.l);
198
- return hsla(hsl);
240
+ return hsla(color, hsl);
199
241
  },
200
242
  fadein: function (color, amount, method) {
201
243
  var hsl = color.toHSL();
@@ -207,7 +249,7 @@ colorFunctions = {
207
249
  hsl.a += amount.value / 100;
208
250
  }
209
251
  hsl.a = clamp(hsl.a);
210
- return hsla(hsl);
252
+ return hsla(color, hsl);
211
253
  },
212
254
  fadeout: function (color, amount, method) {
213
255
  var hsl = color.toHSL();
@@ -219,14 +261,14 @@ colorFunctions = {
219
261
  hsl.a -= amount.value / 100;
220
262
  }
221
263
  hsl.a = clamp(hsl.a);
222
- return hsla(hsl);
264
+ return hsla(color, hsl);
223
265
  },
224
266
  fade: function (color, amount) {
225
267
  var hsl = color.toHSL();
226
268
 
227
269
  hsl.a = amount.value / 100;
228
270
  hsl.a = clamp(hsl.a);
229
- return hsla(hsl);
271
+ return hsla(color, hsl);
230
272
  },
231
273
  spin: function (color, amount) {
232
274
  var hsl = color.toHSL();
@@ -234,7 +276,7 @@ colorFunctions = {
234
276
 
235
277
  hsl.h = hue < 0 ? 360 + hue : hue;
236
278
 
237
- return hsla(hsl);
279
+ return hsla(color, hsl);
238
280
  },
239
281
  //
240
282
  // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein
@@ -338,8 +380,9 @@ colorFunctions = {
338
380
  },
339
381
  color: function(c) {
340
382
  if ((c instanceof Quoted) &&
341
- (/^#([a-f0-9]{6}|[a-f0-9]{3})$/i.test(c.value))) {
342
- return new Color(c.value.slice(1));
383
+ (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) {
384
+ var val = c.value.slice(1);
385
+ return new Color(val, undefined, '#' + val);
343
386
  }
344
387
  if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {
345
388
  c.value = undefined;
@@ -347,7 +390,7 @@ colorFunctions = {
347
390
  }
348
391
  throw {
349
392
  type: 'Argument',
350
- message: 'argument must be a color keyword or 3/6 digit hex e.g. #FFF'
393
+ message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF'
351
394
  };
352
395
  },
353
396
  tint: function(color, amount) {
@@ -18,7 +18,7 @@ module.exports = function(environment) {
18
18
  var mimetype = mimetypeNode && mimetypeNode.value;
19
19
  var filePath = filePathNode.value;
20
20
  var currentFileInfo = this.currentFileInfo;
21
- var currentDirectory = currentFileInfo.relativeUrls ?
21
+ var currentDirectory = currentFileInfo.rewriteUrls ?
22
22
  currentFileInfo.currentDirectory : currentFileInfo.entryPath;
23
23
 
24
24
  var fragmentStart = filePath.indexOf('#');
@@ -1,5 +1,7 @@
1
- var Dimension = require('../tree/dimension'),
1
+ var Comment = require('../tree/comment'),
2
+ Dimension = require('../tree/dimension'),
2
3
  Declaration = require('../tree/declaration'),
4
+ Expression = require('../tree/expression'),
3
5
  Ruleset = require('../tree/ruleset'),
4
6
  Selector = require('../tree/selector'),
5
7
  Element = require('../tree/element'),
@@ -26,8 +28,36 @@ functionRegistry.addMultiple({
26
28
  length: function(values) {
27
29
  return new Dimension(getItemsFromNode(values).length);
28
30
  },
31
+ /**
32
+ * Creates a Less list of incremental values.
33
+ * Modeled after Lodash's range function, also exists natively in PHP
34
+ *
35
+ * @param {Dimension} [start=1]
36
+ * @param {Dimension} end - e.g. 10 or 10px - unit is added to output
37
+ * @param {Dimension} [step=1]
38
+ */
39
+ range: function(start, end, step) {
40
+ var from, to, stepValue = 1, list = [];
41
+ if (end) {
42
+ to = end;
43
+ from = start.value;
44
+ if (step) {
45
+ stepValue = step.value;
46
+ }
47
+ }
48
+ else {
49
+ from = 1;
50
+ to = start;
51
+ }
52
+
53
+ for (var i = from; i <= to.value; i += stepValue) {
54
+ list.push(new Dimension(i, to.unit));
55
+ }
56
+
57
+ return new Expression(list);
58
+ },
29
59
  each: function(list, rs) {
30
- var i = 0, rules = [], newRules, iterator;
60
+ var rules = [], newRules, iterator;
31
61
 
32
62
  if (list.value) {
33
63
  if (Array.isArray(list.value)) {
@@ -37,6 +67,8 @@ functionRegistry.addMultiple({
37
67
  }
38
68
  } else if (list.ruleset) {
39
69
  iterator = list.ruleset.rules;
70
+ } else if (list.rules) {
71
+ iterator = list.rules;
40
72
  } else if (Array.isArray(list)) {
41
73
  iterator = list;
42
74
  } else {
@@ -55,17 +87,20 @@ functionRegistry.addMultiple({
55
87
  } else {
56
88
  rs = rs.ruleset;
57
89
  }
58
-
59
- iterator.forEach(function(item) {
60
- i = i + 1;
61
- var key, value;
90
+
91
+ for (var i = 0; i < iterator.length; i++) {
92
+ var key, value, item = iterator[i];
62
93
  if (item instanceof Declaration) {
63
94
  key = typeof item.name === 'string' ? item.name : item.name[0].value;
64
95
  value = item.value;
65
96
  } else {
66
- key = new Dimension(i);
97
+ key = new Dimension(i + 1);
67
98
  value = item;
68
99
  }
100
+
101
+ if (item instanceof Comment) {
102
+ continue;
103
+ }
69
104
 
70
105
  newRules = rs.rules.slice(0);
71
106
  if (valueName) {
@@ -75,7 +110,7 @@ functionRegistry.addMultiple({
75
110
  }
76
111
  if (indexName) {
77
112
  newRules.push(new Declaration(indexName,
78
- new Dimension(i),
113
+ new Dimension(i + 1),
79
114
  false, false, this.index, this.currentFileInfo));
80
115
  }
81
116
  if (keyName) {
@@ -89,7 +124,7 @@ functionRegistry.addMultiple({
89
124
  rs.strictImports,
90
125
  rs.visibilityInfo()
91
126
  ));
92
- });
127
+ }
93
128
 
94
129
  return new Ruleset([ new(Selector)([ new Element("", '&') ]) ],
95
130
  rules,
@@ -8,7 +8,7 @@ var contexts = require('./contexts'),
8
8
  module.exports = function(environment) {
9
9
 
10
10
  // FileInfo = {
11
- // 'relativeUrls' - option - whether to adjust URL's to be relative
11
+ // 'rewriteUrls' - option - whether to adjust URL's to be relative
12
12
  // 'filename' - full resolved filename of current file
13
13
  // 'rootpath' - path to append to normal URLs for this node
14
14
  // 'currentDirectory' - path to the current file, absolute
@@ -65,7 +65,7 @@ module.exports = function(environment) {
65
65
  };
66
66
 
67
67
  var newFileInfo = {
68
- relativeUrls: this.context.relativeUrls,
68
+ rewriteUrls: this.context.rewriteUrls,
69
69
  entryPath: currentFileInfo.entryPath,
70
70
  rootpath: currentFileInfo.rootpath,
71
71
  rootFilename: currentFileInfo.rootFilename
@@ -92,7 +92,7 @@ module.exports = function(environment) {
92
92
  // - If path of imported file is '../mixins.less' and rootpath is 'less/',
93
93
  // then rootpath should become 'less/../'
94
94
  newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
95
- if (newFileInfo.relativeUrls) {
95
+ if (newFileInfo.rewriteUrls) {
96
96
  newFileInfo.rootpath = fileManager.join(
97
97
  (importManager.context.rootpath || ''),
98
98
  fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
package/lib/less/index.js CHANGED
@@ -2,7 +2,7 @@ module.exports = function(environment, fileManagers) {
2
2
  var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment;
3
3
 
4
4
  var initial = {
5
- version: [3, 7, 0],
5
+ version: [3, 9, 0],
6
6
  data: require('./data'),
7
7
  tree: require('./tree'),
8
8
  Environment: (Environment = require('./environment/environment')),
package/lib/less/parse.js CHANGED
@@ -46,7 +46,7 @@ module.exports = function(environment, ParseTree, ImportManager) {
46
46
  var entryPath = filename.replace(/[^\/\\]*$/, '');
47
47
  rootFileInfo = {
48
48
  filename: filename,
49
- relativeUrls: context.relativeUrls,
49
+ rewriteUrls: context.rewriteUrls,
50
50
  rootpath: context.rootpath || '',
51
51
  currentDirectory: entryPath,
52
52
  entryPath: entryPath,
@@ -636,15 +636,8 @@ var Parser = function Parser(context, imports, fileInfo) {
636
636
  color: function () {
637
637
  var rgb;
638
638
 
639
- if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
640
- // strip colons, brackets, whitespaces and other characters that should not
641
- // definitely be part of color string
642
- var colorCandidateString = rgb.input.match(/^#([\w]+).*/);
643
- colorCandidateString = colorCandidateString[1];
644
- if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters
645
- error('Invalid HEX color code');
646
- }
647
- return new(tree.Color)(rgb[1], undefined, '#' + colorCandidateString);
639
+ if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})/))) {
640
+ return new(tree.Color)(rgb[1], undefined, rgb[0]);
648
641
  }
649
642
  },
650
643
 
@@ -58,7 +58,7 @@ module.exports = function (environment) {
58
58
  sourceColumns,
59
59
  i;
60
60
 
61
- if (fileInfo) {
61
+ if (fileInfo && fileInfo.filename) {
62
62
  var inputSource = this._contentsMap[fileInfo.filename];
63
63
 
64
64
  // remove vars/banner added to the top of the file
@@ -77,7 +77,7 @@ module.exports = function (environment) {
77
77
  lines = chunk.split('\n');
78
78
  columns = lines[lines.length - 1];
79
79
 
80
- if (fileInfo) {
80
+ if (fileInfo && fileInfo.filename) {
81
81
  if (!mapLines) {
82
82
  this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column},
83
83
  original: { line: sourceLines.length, column: sourceColumns.length},
@@ -5,6 +5,7 @@ var Node = require('./node'),
5
5
  // RGB Colors - #ff0014, #eee
6
6
  //
7
7
  var Color = function (rgb, a, originalForm) {
8
+ var self = this;
8
9
  //
9
10
  // The end goal here, is to parse the arguments
10
11
  // into an integer triplet, such as `128, 255, 0`
@@ -13,16 +14,26 @@ var Color = function (rgb, a, originalForm) {
13
14
  //
14
15
  if (Array.isArray(rgb)) {
15
16
  this.rgb = rgb;
16
- } else if (rgb.length == 6) {
17
- this.rgb = rgb.match(/.{2}/g).map(function (c) {
18
- return parseInt(c, 16);
17
+ } else if (rgb.length >= 6) {
18
+ this.rgb = [];
19
+ rgb.match(/.{2}/g).map(function (c, i) {
20
+ if (i < 3) {
21
+ self.rgb.push(parseInt(c, 16));
22
+ } else {
23
+ self.alpha = (parseInt(c, 16)) / 255;
24
+ }
19
25
  });
20
26
  } else {
21
- this.rgb = rgb.split('').map(function (c) {
22
- return parseInt(c + c, 16);
27
+ this.rgb = [];
28
+ rgb.split('').map(function (c, i) {
29
+ if (i < 3) {
30
+ self.rgb.push(parseInt(c + c, 16));
31
+ } else {
32
+ self.alpha = (parseInt(c + c, 16)) / 255;
33
+ }
23
34
  });
24
35
  }
25
- this.alpha = typeof a === 'number' ? a : 1;
36
+ this.alpha = this.alpha || (typeof a === 'number' ? a : 1);
26
37
  if (typeof originalForm !== 'undefined') {
27
38
  this.value = originalForm;
28
39
  }
@@ -57,25 +68,54 @@ Color.prototype.genCSS = function (context, output) {
57
68
  output.add(this.toCSS(context));
58
69
  };
59
70
  Color.prototype.toCSS = function (context, doNotCompress) {
60
- var compress = context && context.compress && !doNotCompress, color, alpha;
71
+ var compress = context && context.compress && !doNotCompress, color, alpha,
72
+ colorFunction, args = [];
61
73
 
62
74
  // `value` is set if this color was originally
63
75
  // converted from a named color string so we need
64
76
  // to respect this and try to output named color too.
77
+ alpha = this.fround(context, this.alpha);
78
+
65
79
  if (this.value) {
66
- return this.value;
80
+ if (this.value.indexOf('rgb') === 0) {
81
+ if (alpha < 1) {
82
+ colorFunction = 'rgba';
83
+ }
84
+ } else if (this.value.indexOf('hsl') === 0) {
85
+ if (alpha < 1) {
86
+ colorFunction = 'hsla';
87
+ } else {
88
+ colorFunction = 'hsl';
89
+ }
90
+ } else {
91
+ return this.value;
92
+ }
93
+ } else {
94
+ if (alpha < 1) {
95
+ colorFunction = 'rgba';
96
+ }
67
97
  }
68
98
 
69
- // If we have some transparency, the only way to represent it
70
- // is via `rgba`. Otherwise, we use the hex representation,
71
- // which has better compatibility with older browsers.
72
- // Values are capped between `0` and `255`, rounded and zero-padded.
73
- alpha = this.fround(context, this.alpha);
74
- if (alpha < 1) {
75
- return 'rgba(' + this.rgb.map(function (c) {
76
- return clamp(Math.round(c), 255);
77
- }).concat(clamp(alpha, 1))
78
- .join(',' + (compress ? '' : ' ')) + ')';
99
+ switch (colorFunction) {
100
+ case 'rgba':
101
+ args = this.rgb.map(function (c) {
102
+ return clamp(Math.round(c), 255);
103
+ }).concat(clamp(alpha, 1));
104
+ break;
105
+ case 'hsla':
106
+ args.push(clamp(alpha, 1));
107
+ case 'hsl':
108
+ color = this.toHSL();
109
+ args = [
110
+ this.fround(context, color.h),
111
+ this.fround(context, color.s * 100) + '%',
112
+ this.fround(context, color.l * 100) + '%'
113
+ ].concat(args);
114
+ }
115
+
116
+ if (colorFunction) {
117
+ // Values are capped between `0` and `255`, rounded and zero-padded.
118
+ return colorFunction + '(' + args.join(',' + (compress ? '' : ' ')) + ')';
79
119
  }
80
120
 
81
121
  color = this.toRGB();
@@ -2,7 +2,7 @@ var Node = require('./node'),
2
2
  Value = require('./value'),
3
3
  Keyword = require('./keyword'),
4
4
  Anonymous = require('./anonymous'),
5
- MATH = require('../math-constants');
5
+ MATH = require('../constants').Math;
6
6
 
7
7
  var Declaration = function (name, value, important, merge, index, currentFileInfo, inline, variable) {
8
8
  this.name = name;
@@ -2,7 +2,7 @@ var Node = require('./node'),
2
2
  Paren = require('./paren'),
3
3
  Comment = require('./comment'),
4
4
  Dimension = require('./dimension'),
5
- MATH = require('../math-constants');
5
+ MATH = require('../constants').Math;
6
6
 
7
7
  var Expression = function (value, noSpacing) {
8
8
  this.value = value;