less 2.3.1 → 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 (301) hide show
  1. package/.idea/workspace.xml +277 -237
  2. package/.jscsrc +36 -1
  3. package/.travis.yml +1 -0
  4. package/CHANGELOG.md +14 -0
  5. package/Gruntfile.js +1 -1
  6. package/appveyor.yml +5 -0
  7. package/bin/lessc +8 -5
  8. package/bower.json +1 -1
  9. package/dist/less.js +909 -814
  10. package/dist/less.min.js +6 -6
  11. package/lib/less/contexts.js +2 -2
  12. package/lib/less/environment/abstract-file-manager.js +6 -6
  13. package/lib/less/environment/environment.js +2 -2
  14. package/lib/less/functions/color.js +13 -5
  15. package/lib/less/functions/math.js +1 -1
  16. package/lib/less/functions/number.js +2 -2
  17. package/lib/less/functions/types.js +18 -8
  18. package/lib/less/import-manager.js +5 -5
  19. package/lib/less/index.js +1 -1
  20. package/lib/less/less-error.js +1 -1
  21. package/lib/less/logger.js +2 -2
  22. package/lib/less/parse-tree.js +45 -45
  23. package/lib/less/parse.js +5 -2
  24. package/lib/less/parser/parser-input.js +3 -3
  25. package/lib/less/parser/parser.js +52 -18
  26. package/lib/less/plugin-manager.js +30 -3
  27. package/lib/less/render.js +5 -2
  28. package/lib/less/source-map-builder.js +4 -0
  29. package/lib/less/source-map-output.js +3 -3
  30. package/lib/less/transform-tree.js +4 -4
  31. package/lib/less/tree/anonymous.js +1 -1
  32. package/lib/less/tree/call.js +1 -1
  33. package/lib/less/tree/color.js +2 -2
  34. package/lib/less/tree/condition.js +8 -4
  35. package/lib/less/tree/dimension.js +4 -4
  36. package/lib/less/tree/element.js +1 -1
  37. package/lib/less/tree/expression.js +1 -1
  38. package/lib/less/tree/extend.js +3 -3
  39. package/lib/less/tree/javascript.js +2 -2
  40. package/lib/less/tree/media.js +20 -20
  41. package/lib/less/tree/mixin-call.js +2 -2
  42. package/lib/less/tree/mixin-definition.js +29 -8
  43. package/lib/less/tree/quoted.js +3 -3
  44. package/lib/less/tree/rule.js +1 -1
  45. package/lib/less/tree/ruleset.js +35 -28
  46. package/lib/less/tree/selector.js +1 -1
  47. package/lib/less/tree/unit.js +2 -0
  48. package/lib/less/tree/value.js +1 -1
  49. package/lib/less/visitors/extend-visitor.js +15 -14
  50. package/lib/less/visitors/import-sequencer.js +2 -2
  51. package/lib/less/visitors/import-visitor.js +2 -2
  52. package/lib/less/visitors/to-css-visitor.js +5 -5
  53. package/lib/less-browser/cache.js +2 -2
  54. package/lib/less-browser/file-manager.js +96 -96
  55. package/lib/less-browser/index.js +205 -205
  56. package/lib/less-browser/log-listener.js +2 -2
  57. package/lib/less-browser/utils.js +6 -6
  58. package/lib/less-node/file-manager.js +9 -4
  59. package/lib/less-node/index.js +3 -3
  60. package/lib/less-node/plugin-loader.js +3 -3
  61. package/lib/less-node/url-file-manager.js +5 -2
  62. package/lib/less-rhino/index.js +13 -9
  63. package/lib/source-map/source-map-0.1.31.js +1 -1
  64. package/package.json +1 -1
  65. package/test/browser/css/relative-urls/urls.css +1 -0
  66. package/test/browser/less/relative-urls/urls.less +1 -0
  67. package/test/browser/runner-browser-options.js +23 -23
  68. package/test/browser/runner-errors-spec.js +1 -1
  69. package/test/browser/runner-global-vars-spec.js +1 -1
  70. package/test/browser/runner-main-options.js +5 -5
  71. package/test/browser/runner-main-spec.js +1 -1
  72. package/test/copy-bom.js +35 -35
  73. package/test/css/functions.css +8 -0
  74. package/test/css/import-interpolation.css +1 -0
  75. package/test/css/mixins-important.css +6 -0
  76. package/test/css/selectors.css +5 -0
  77. package/test/css/static-urls/urls.css +1 -0
  78. package/test/css/urls.css +1 -0
  79. package/test/index.js +2 -1
  80. package/test/less/functions.less +13 -0
  81. package/test/less/import/imports/logo.less +1 -0
  82. package/test/less/mixins-important.less +17 -1
  83. package/test/less/selectors.less +10 -0
  84. package/test/less/sourcemaps-empty/empty.less +0 -0
  85. package/test/less/sourcemaps-empty/var-defs.less +1 -0
  86. package/test/less/urls.less +1 -1
  87. package/test/less-test.js +49 -27
  88. package/test/modify-vars.js +13 -13
  89. package/test/browser/less.js +0 -29
  90. package/test/less-bom/charsets.less +0 -3
  91. package/test/less-bom/colors.less +0 -98
  92. package/test/less-bom/comments.less +0 -102
  93. package/test/less-bom/comments2.less +0 -20
  94. package/test/less-bom/compression/compression.less +0 -36
  95. package/test/less-bom/css-3.less +0 -154
  96. package/test/less-bom/css-escapes.less +0 -33
  97. package/test/less-bom/css-guards.less +0 -103
  98. package/test/less-bom/css.less +0 -108
  99. package/test/less-bom/debug/import/test.less +0 -25
  100. package/test/less-bom/debug/linenumbers.less +0 -33
  101. package/test/less-bom/detached-rulesets.less +0 -103
  102. package/test/less-bom/empty.less +0 -1
  103. package/test/less-bom/errors/add-mixed-units.less +0 -3
  104. package/test/less-bom/errors/add-mixed-units.txt +0 -4
  105. package/test/less-bom/errors/add-mixed-units2.less +0 -3
  106. package/test/less-bom/errors/add-mixed-units2.txt +0 -4
  107. package/test/less-bom/errors/at-rules-undefined-var.less +0 -4
  108. package/test/less-bom/errors/at-rules-undefined-var.txt +0 -4
  109. package/test/less-bom/errors/bad-variable-declaration1.less +0 -1
  110. package/test/less-bom/errors/bad-variable-declaration1.txt +0 -2
  111. package/test/less-bom/errors/color-func-invalid-color.less +0 -3
  112. package/test/less-bom/errors/color-func-invalid-color.txt +0 -4
  113. package/test/less-bom/errors/color-invalid-hex-code.less +0 -3
  114. package/test/less-bom/errors/color-invalid-hex-code.txt +0 -4
  115. package/test/less-bom/errors/color-invalid-hex-code2.less +0 -3
  116. package/test/less-bom/errors/color-invalid-hex-code2.txt +0 -4
  117. package/test/less-bom/errors/css-guard-default-func.less +0 -4
  118. package/test/less-bom/errors/css-guard-default-func.txt +0 -4
  119. package/test/less-bom/errors/detached-ruleset-1.less +0 -6
  120. package/test/less-bom/errors/detached-ruleset-1.txt +0 -4
  121. package/test/less-bom/errors/detached-ruleset-2.less +0 -6
  122. package/test/less-bom/errors/detached-ruleset-2.txt +0 -4
  123. package/test/less-bom/errors/detached-ruleset-3.less +0 -4
  124. package/test/less-bom/errors/detached-ruleset-3.txt +0 -4
  125. package/test/less-bom/errors/detached-ruleset-4.less +0 -5
  126. package/test/less-bom/errors/detached-ruleset-4.txt +0 -4
  127. package/test/less-bom/errors/detached-ruleset-5.less +0 -4
  128. package/test/less-bom/errors/detached-ruleset-5.txt +0 -3
  129. package/test/less-bom/errors/detached-ruleset-6.less +0 -5
  130. package/test/less-bom/errors/detached-ruleset-6.txt +0 -4
  131. package/test/less-bom/errors/divide-mixed-units.less +0 -3
  132. package/test/less-bom/errors/divide-mixed-units.txt +0 -4
  133. package/test/less-bom/errors/extend-no-selector.less +0 -3
  134. package/test/less-bom/errors/extend-no-selector.txt +0 -3
  135. package/test/less-bom/errors/extend-not-at-end.less +0 -3
  136. package/test/less-bom/errors/extend-not-at-end.txt +0 -3
  137. package/test/less-bom/errors/import-malformed.less +0 -1
  138. package/test/less-bom/errors/import-malformed.txt +0 -3
  139. package/test/less-bom/errors/import-missing.less +0 -6
  140. package/test/less-bom/errors/import-missing.txt +0 -3
  141. package/test/less-bom/errors/import-no-semi.less +0 -1
  142. package/test/less-bom/errors/import-no-semi.txt +0 -2
  143. package/test/less-bom/errors/import-subfolder1.less +0 -1
  144. package/test/less-bom/errors/import-subfolder1.txt +0 -3
  145. package/test/less-bom/errors/import-subfolder2.less +0 -1
  146. package/test/less-bom/errors/import-subfolder2.txt +0 -4
  147. package/test/less-bom/errors/imports/import-subfolder1.less +0 -1
  148. package/test/less-bom/errors/imports/import-subfolder2.less +0 -1
  149. package/test/less-bom/errors/imports/import-test.less +0 -4
  150. package/test/less-bom/errors/imports/subfolder/mixin-not-defined.less +0 -1
  151. package/test/less-bom/errors/imports/subfolder/parse-error-curly-bracket.less +0 -1
  152. package/test/less-bom/errors/javascript-error.less +0 -3
  153. package/test/less-bom/errors/javascript-error.txt +0 -4
  154. package/test/less-bom/errors/javascript-undefined-var.less +0 -3
  155. package/test/less-bom/errors/javascript-undefined-var.txt +0 -4
  156. package/test/less-bom/errors/mixed-mixin-definition-args-1.less +0 -6
  157. package/test/less-bom/errors/mixed-mixin-definition-args-1.txt +0 -4
  158. package/test/less-bom/errors/mixed-mixin-definition-args-2.less +0 -6
  159. package/test/less-bom/errors/mixed-mixin-definition-args-2.txt +0 -4
  160. package/test/less-bom/errors/mixin-not-defined.less +0 -11
  161. package/test/less-bom/errors/mixin-not-defined.txt +0 -3
  162. package/test/less-bom/errors/mixin-not-matched.less +0 -6
  163. package/test/less-bom/errors/mixin-not-matched.txt +0 -3
  164. package/test/less-bom/errors/mixin-not-matched2.less +0 -6
  165. package/test/less-bom/errors/mixin-not-matched2.txt +0 -3
  166. package/test/less-bom/errors/mixin-not-visible-in-scope-1.less +0 -9
  167. package/test/less-bom/errors/mixin-not-visible-in-scope-1.txt +0 -4
  168. package/test/less-bom/errors/mixins-guards-default-func-1.less +0 -9
  169. package/test/less-bom/errors/mixins-guards-default-func-1.txt +0 -4
  170. package/test/less-bom/errors/mixins-guards-default-func-2.less +0 -9
  171. package/test/less-bom/errors/mixins-guards-default-func-2.txt +0 -4
  172. package/test/less-bom/errors/mixins-guards-default-func-3.less +0 -9
  173. package/test/less-bom/errors/mixins-guards-default-func-3.txt +0 -4
  174. package/test/less-bom/errors/multiple-guards-on-css-selectors.less +0 -4
  175. package/test/less-bom/errors/multiple-guards-on-css-selectors.txt +0 -4
  176. package/test/less-bom/errors/multiple-guards-on-css-selectors2.less +0 -4
  177. package/test/less-bom/errors/multiple-guards-on-css-selectors2.txt +0 -4
  178. package/test/less-bom/errors/multiply-mixed-units.less +0 -7
  179. package/test/less-bom/errors/multiply-mixed-units.txt +0 -4
  180. package/test/less-bom/errors/parens-error-1.less +0 -3
  181. package/test/less-bom/errors/parens-error-1.txt +0 -4
  182. package/test/less-bom/errors/parens-error-2.less +0 -3
  183. package/test/less-bom/errors/parens-error-2.txt +0 -4
  184. package/test/less-bom/errors/parens-error-3.less +0 -3
  185. package/test/less-bom/errors/parens-error-3.txt +0 -4
  186. package/test/less-bom/errors/parse-error-curly-bracket.less +0 -4
  187. package/test/less-bom/errors/parse-error-curly-bracket.txt +0 -4
  188. package/test/less-bom/errors/parse-error-extra-parens.less +0 -5
  189. package/test/less-bom/errors/parse-error-extra-parens.txt +0 -3
  190. package/test/less-bom/errors/parse-error-missing-bracket.less +0 -2
  191. package/test/less-bom/errors/parse-error-missing-bracket.txt +0 -3
  192. package/test/less-bom/errors/parse-error-missing-parens.less +0 -5
  193. package/test/less-bom/errors/parse-error-missing-parens.txt +0 -3
  194. package/test/less-bom/errors/parse-error-with-import.less +0 -13
  195. package/test/less-bom/errors/parse-error-with-import.txt +0 -4
  196. package/test/less-bom/errors/percentage-missing-space.less +0 -3
  197. package/test/less-bom/errors/percentage-missing-space.txt +0 -4
  198. package/test/less-bom/errors/property-asterisk-only-name.less +0 -3
  199. package/test/less-bom/errors/property-asterisk-only-name.txt +0 -4
  200. package/test/less-bom/errors/property-ie5-hack.less +0 -3
  201. package/test/less-bom/errors/property-ie5-hack.txt +0 -3
  202. package/test/less-bom/errors/property-in-root.less +0 -4
  203. package/test/less-bom/errors/property-in-root.txt +0 -4
  204. package/test/less-bom/errors/property-in-root2.less +0 -1
  205. package/test/less-bom/errors/property-in-root2.txt +0 -4
  206. package/test/less-bom/errors/property-in-root3.less +0 -4
  207. package/test/less-bom/errors/property-in-root3.txt +0 -3
  208. package/test/less-bom/errors/property-interp-not-defined.less +0 -1
  209. package/test/less-bom/errors/property-interp-not-defined.txt +0 -2
  210. package/test/less-bom/errors/recursive-variable.less +0 -1
  211. package/test/less-bom/errors/recursive-variable.txt +0 -2
  212. package/test/less-bom/errors/single-character.less +0 -1
  213. package/test/less-bom/errors/single-character.txt +0 -2
  214. package/test/less-bom/errors/svg-gradient1.less +0 -3
  215. package/test/less-bom/errors/svg-gradient1.txt +0 -4
  216. package/test/less-bom/errors/svg-gradient2.less +0 -3
  217. package/test/less-bom/errors/svg-gradient2.txt +0 -4
  218. package/test/less-bom/errors/svg-gradient3.less +0 -3
  219. package/test/less-bom/errors/svg-gradient3.txt +0 -4
  220. package/test/less-bom/errors/unit-function.less +0 -3
  221. package/test/less-bom/errors/unit-function.txt +0 -4
  222. package/test/less-bom/extend-chaining.less +0 -91
  223. package/test/less-bom/extend-clearfix.less +0 -19
  224. package/test/less-bom/extend-exact.less +0 -46
  225. package/test/less-bom/extend-media.less +0 -24
  226. package/test/less-bom/extend-nest.less +0 -65
  227. package/test/less-bom/extend-selector.less +0 -99
  228. package/test/less-bom/extend.less +0 -81
  229. package/test/less-bom/extract-and-length.less +0 -133
  230. package/test/less-bom/functions.less +0 -201
  231. package/test/less-bom/globalVars/extended.json +0 -5
  232. package/test/less-bom/globalVars/extended.less +0 -10
  233. package/test/less-bom/globalVars/simple.json +0 -3
  234. package/test/less-bom/globalVars/simple.less +0 -3
  235. package/test/less-bom/ie-filters.less +0 -15
  236. package/test/less-bom/import/deeper/deeper-2/url-import-2.less +0 -3
  237. package/test/less-bom/import/deeper/deeper-2/url-import.less +0 -1
  238. package/test/less-bom/import/deeper/import-once-test-a.less +0 -1
  239. package/test/less-bom/import/deeper/url-import.less +0 -1
  240. package/test/less-bom/import/import-and-relative-paths-test.less +0 -17
  241. package/test/less-bom/import/import-charset-test.less +0 -1
  242. package/test/less-bom/import/import-interpolation.less +0 -2
  243. package/test/less-bom/import/import-interpolation2.less +0 -5
  244. package/test/less-bom/import/import-once-test-c.less +0 -6
  245. package/test/less-bom/import/import-reference.less +0 -89
  246. package/test/less-bom/import/import-test-a.less +0 -4
  247. package/test/less-bom/import/import-test-b.less +0 -8
  248. package/test/less-bom/import/import-test-c.less +0 -6
  249. package/test/less-bom/import/import-test-d.css +0 -1
  250. package/test/less-bom/import/import-test-e.less +0 -2
  251. package/test/less-bom/import/import-test-f.less +0 -5
  252. package/test/less-bom/import/imports/font.less +0 -8
  253. package/test/less-bom/import/imports/logo.less +0 -5
  254. package/test/less-bom/import/interpolation-vars.less +0 -6
  255. package/test/less-bom/import/invalid-css.less +0 -1
  256. package/test/less-bom/import/urls.less +0 -1
  257. package/test/less-bom/import-inline.less +0 -3
  258. package/test/less-bom/import-interpolation.less +0 -8
  259. package/test/less-bom/import-once.less +0 -6
  260. package/test/less-bom/import-reference.less +0 -23
  261. package/test/less-bom/import.less +0 -30
  262. package/test/less-bom/include-path/include-path.less +0 -6
  263. package/test/less-bom/javascript.less +0 -38
  264. package/test/less-bom/lazy-eval.less +0 -6
  265. package/test/less-bom/legacy/legacy.less +0 -7
  266. package/test/less-bom/media.less +0 -234
  267. package/test/less-bom/merge.less +0 -78
  268. package/test/less-bom/mixins-args.less +0 -215
  269. package/test/less-bom/mixins-closure.less +0 -26
  270. package/test/less-bom/mixins-guards-default-func.less +0 -195
  271. package/test/less-bom/mixins-guards.less +0 -271
  272. package/test/less-bom/mixins-important.less +0 -37
  273. package/test/less-bom/mixins-interpolated.less +0 -75
  274. package/test/less-bom/mixins-named-args.less +0 -36
  275. package/test/less-bom/mixins-nested.less +0 -22
  276. package/test/less-bom/mixins-pattern.less +0 -102
  277. package/test/less-bom/mixins.less +0 -145
  278. package/test/less-bom/modifyVars/extended.json +0 -5
  279. package/test/less-bom/modifyVars/extended.less +0 -11
  280. package/test/less-bom/nested-gradient-with-svg-gradient/mixin-consumer.less +0 -5
  281. package/test/less-bom/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +0 -15
  282. package/test/less-bom/no-js-errors/no-js-errors.less +0 -3
  283. package/test/less-bom/no-js-errors/no-js-errors.txt +0 -4
  284. package/test/less-bom/no-output.less +0 -2
  285. package/test/less-bom/operations.less +0 -62
  286. package/test/less-bom/parens.less +0 -45
  287. package/test/less-bom/property-name-interp.less +0 -56
  288. package/test/less-bom/rulesets.less +0 -30
  289. package/test/less-bom/scope.less +0 -104
  290. package/test/less-bom/selectors.less +0 -174
  291. package/test/less-bom/sourcemaps/basic.json +0 -3
  292. package/test/less-bom/sourcemaps/basic.less +0 -27
  293. package/test/less-bom/sourcemaps/imported.css +0 -7
  294. package/test/less-bom/static-urls/urls.less +0 -33
  295. package/test/less-bom/strict-units/strict-units.less +0 -4
  296. package/test/less-bom/strings.less +0 -73
  297. package/test/less-bom/url-args/urls.less +0 -63
  298. package/test/less-bom/urls.less +0 -94
  299. package/test/less-bom/variables-in-at-rules.less +0 -20
  300. package/test/less-bom/variables.less +0 -119
  301. package/test/less-bom/whitespace.less +0 -44
@@ -1,13 +1,16 @@
1
- var PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;
1
+ var PromiseConstructor;
2
2
 
3
3
  module.exports = function(environment, ParseTree, ImportManager) {
4
4
  var render = function (input, options, callback) {
5
- if (typeof(options) === 'function') {
5
+ if (typeof options === 'function') {
6
6
  callback = options;
7
7
  options = {};
8
8
  }
9
9
 
10
10
  if (!callback) {
11
+ if (!PromiseConstructor) {
12
+ PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;
13
+ }
11
14
  var self = this;
12
15
  return new PromiseConstructor(function (resolve, reject) {
13
16
  render.call(self, input, options, function(err, output) {
@@ -30,8 +30,12 @@ module.exports = function (SourceMapOutput, environment) {
30
30
  };
31
31
 
32
32
  SourceMapBuilder.prototype.getCSSAppendage = function() {
33
+
33
34
  var sourceMapURL = this.sourceMapURL;
34
35
  if (this.options.sourceMapFileInline) {
36
+ if (this.sourceMap === undefined) {
37
+ return "";
38
+ }
35
39
  sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap);
36
40
  }
37
41
 
@@ -34,7 +34,7 @@ module.exports = function (environment) {
34
34
  if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) {
35
35
  filename = filename.substring(this._sourceMapBasepath.length);
36
36
  if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') {
37
- filename = filename.substring(1);
37
+ filename = filename.substring(1);
38
38
  }
39
39
  }
40
40
  return (this._sourceMapRootpath || "") + filename;
@@ -78,7 +78,7 @@ module.exports = function (environment) {
78
78
  original: { line: sourceLines.length, column: sourceColumns.length},
79
79
  source: this.normalizeFilename(fileInfo.filename)});
80
80
  } else {
81
- for(i = 0; i < lines.length; i++) {
81
+ for (i = 0; i < lines.length; i++) {
82
82
  this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0},
83
83
  original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0},
84
84
  source: this.normalizeFilename(fileInfo.filename)});
@@ -104,7 +104,7 @@ module.exports = function (environment) {
104
104
  this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });
105
105
 
106
106
  if (this._outputSourceFiles) {
107
- for(var filename in this._contentsMap) {
107
+ for (var filename in this._contentsMap) {
108
108
  if (this._contentsMap.hasOwnProperty(filename))
109
109
  {
110
110
  var source = this._contentsMap[filename];
@@ -21,7 +21,7 @@ module.exports = function(root, options) {
21
21
  // ])
22
22
  // )
23
23
  //
24
- if (typeof(variables) === 'object' && !Array.isArray(variables)) {
24
+ if (typeof variables === 'object' && !Array.isArray(variables)) {
25
25
  variables = Object.keys(variables).map(function (k) {
26
26
  var value = variables[k];
27
27
 
@@ -45,7 +45,7 @@ module.exports = function(root, options) {
45
45
 
46
46
  if (options.pluginManager) {
47
47
  var pluginVisitors = options.pluginManager.getVisitors();
48
- for(i = 0; i < pluginVisitors.length; i++) {
48
+ for (i = 0; i < pluginVisitors.length; i++) {
49
49
  var pluginVisitor = pluginVisitors[i];
50
50
  if (pluginVisitor.isPreEvalVisitor) {
51
51
  preEvalVisitors.push(pluginVisitor);
@@ -59,13 +59,13 @@ module.exports = function(root, options) {
59
59
  }
60
60
  }
61
61
 
62
- for(i = 0; i < preEvalVisitors.length; i++) {
62
+ for (i = 0; i < preEvalVisitors.length; i++) {
63
63
  preEvalVisitors[i].run(root);
64
64
  }
65
65
 
66
66
  evaldRoot = root.eval(evalEnv);
67
67
 
68
- for(i = 0; i < visitors.length; i++) {
68
+ for (i = 0; i < visitors.length; i++) {
69
69
  visitors[i].run(evaldRoot);
70
70
  }
71
71
 
@@ -5,7 +5,7 @@ var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike)
5
5
  this.index = index;
6
6
  this.mapLines = mapLines;
7
7
  this.currentFileInfo = currentFileInfo;
8
- this.rulesetLike = (typeof rulesetLike === 'undefined')? false : rulesetLike;
8
+ this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
9
9
  };
10
10
  Anonymous.prototype = new Node();
11
11
  Anonymous.prototype.type = "Anonymous";
@@ -50,7 +50,7 @@ Call.prototype.eval = function (context) {
50
50
  Call.prototype.genCSS = function (context, output) {
51
51
  output.add(this.name + "(", this.currentFileInfo, this.index);
52
52
 
53
- for(var i = 0; i < this.args.length; i++) {
53
+ for (var i = 0; i < this.args.length; i++) {
54
54
  this.args[i].genCSS(context, output);
55
55
  if (i + 1 < this.args.length) {
56
56
  output.add(", ");
@@ -22,7 +22,7 @@ var Color = function (rgb, a) {
22
22
  return parseInt(c + c, 16);
23
23
  });
24
24
  }
25
- this.alpha = typeof(a) === 'number' ? a : 1;
25
+ this.alpha = typeof a === 'number' ? a : 1;
26
26
  };
27
27
 
28
28
  Color.prototype = new Node();
@@ -149,7 +149,7 @@ Color.prototype.toHSV = function () {
149
149
  if (max === min) {
150
150
  h = 0;
151
151
  } else {
152
- switch(max){
152
+ switch(max) {
153
153
  case r: h = (g - b) / d + (g < b ? 6 : 0); break;
154
154
  case g: h = (b - r) / d + 2; break;
155
155
  case b: h = (r - g) / d + 4; break;
@@ -20,10 +20,14 @@ Condition.prototype.eval = function (context) {
20
20
  case 'or': return a || b;
21
21
  default:
22
22
  switch (Node.compare(a, b)) {
23
- case -1: return op === '<' || op === '=<' || op === '<=';
24
- case 0: return op === '=' || op === '>=' || op === '=<' || op === '<=';
25
- case 1: return op === '>' || op === '>=';
26
- default: return false;
23
+ case -1:
24
+ return op === '<' || op === '=<' || op === '<=';
25
+ case 0:
26
+ return op === '=' || op === '>=' || op === '=<' || op === '<=';
27
+ case 1:
28
+ return op === '>' || op === '>=';
29
+ default:
30
+ return false;
27
31
  }
28
32
  }
29
33
  })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));
@@ -70,9 +70,9 @@ Dimension.prototype.operate = function (context, op, other) {
70
70
  } else {
71
71
  other = other.convertTo(this.unit.usedUnits());
72
72
 
73
- if(context.strictUnits && other.unit.toString() !== unit.toString()) {
74
- throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() +
75
- "' and '" + other.unit.toString() + "'.");
73
+ if (context.strictUnits && other.unit.toString() !== unit.toString()) {
74
+ throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() +
75
+ "' and '" + other.unit.toString() + "'.");
76
76
  }
77
77
 
78
78
  value = this._operate(context, op, this.value, other.value);
@@ -116,7 +116,7 @@ Dimension.prototype.convertTo = function (conversions) {
116
116
  i, groupName, group, targetUnit, derivedConversions = {}, applyUnit;
117
117
 
118
118
  if (typeof conversions === 'string') {
119
- for(i in unitConversions) {
119
+ for (i in unitConversions) {
120
120
  if (unitConversions[i].hasOwnProperty(conversions)) {
121
121
  derivedConversions = {};
122
122
  derivedConversions[i] = conversions;
@@ -6,7 +6,7 @@ var Element = function (combinator, value, index, currentFileInfo) {
6
6
  this.combinator = combinator instanceof Combinator ?
7
7
  combinator : new Combinator(combinator);
8
8
 
9
- if (typeof(value) === 'string') {
9
+ if (typeof value === 'string') {
10
10
  this.value = value.trim();
11
11
  } else if (value) {
12
12
  this.value = value;
@@ -41,7 +41,7 @@ Expression.prototype.eval = function (context) {
41
41
  return returnValue;
42
42
  };
43
43
  Expression.prototype.genCSS = function (context, output) {
44
- for(var i = 0; i < this.value.length; i++) {
44
+ for (var i = 0; i < this.value.length; i++) {
45
45
  this.value[i].genCSS(context, output);
46
46
  if (i + 1 < this.value.length) {
47
47
  output.add(" ");
@@ -11,11 +11,11 @@ var Extend = function Extend(selector, option, index) {
11
11
  case "all":
12
12
  this.allowBefore = true;
13
13
  this.allowAfter = true;
14
- break;
14
+ break;
15
15
  default:
16
16
  this.allowBefore = false;
17
17
  this.allowAfter = false;
18
- break;
18
+ break;
19
19
  }
20
20
  };
21
21
  Extend.next_id = 0;
@@ -36,7 +36,7 @@ Extend.prototype.findSelfSelectors = function (selectors) {
36
36
  i,
37
37
  selectorElements;
38
38
 
39
- for(i = 0; i < selectors.length; i++) {
39
+ for (i = 0; i < selectors.length; i++) {
40
40
  selectorElements = selectors[i].elements;
41
41
  // duplicate the logic in genCSS function inside the selector node.
42
42
  // future TODO - move both logics into the selector joiner visitor
@@ -14,9 +14,9 @@ JavaScript.prototype.type = "JavaScript";
14
14
  JavaScript.prototype.eval = function(context) {
15
15
  var result = this.evaluateJavaScript(this.expression, context);
16
16
 
17
- if (typeof(result) === 'number') {
17
+ if (typeof result === 'number') {
18
18
  return new Dimension(result);
19
- } else if (typeof(result) === 'string') {
19
+ } else if (typeof result === 'string') {
20
20
  return new Quoted('"' + result + '"', result, this.escaped, this.index);
21
21
  } else if (Array.isArray(result)) {
22
22
  return new Anonymous(result.join(', '));
@@ -39,7 +39,7 @@ Media.prototype.eval = function (context) {
39
39
  }
40
40
 
41
41
  var media = new Media(null, [], this.index, this.currentFileInfo);
42
- if(this.debugInfo) {
42
+ if (this.debugInfo) {
43
43
  this.rules[0].debugInfo = this.debugInfo;
44
44
  media.debugInfo = this.debugInfo;
45
45
  }
@@ -127,7 +127,7 @@ Media.prototype.evalNested = function (context) {
127
127
  return fragment.toCSS ? fragment : new Anonymous(fragment);
128
128
  });
129
129
 
130
- for(i = path.length - 1; i > 0; i--) {
130
+ for (i = path.length - 1; i > 0; i--) {
131
131
  path.splice(i, 0, new Anonymous("and"));
132
132
  }
133
133
 
@@ -138,25 +138,25 @@ Media.prototype.evalNested = function (context) {
138
138
  return new Ruleset([], []);
139
139
  };
140
140
  Media.prototype.permute = function (arr) {
141
- if (arr.length === 0) {
142
- return [];
143
- } else if (arr.length === 1) {
144
- return arr[0];
145
- } else {
146
- var result = [];
147
- var rest = this.permute(arr.slice(1));
148
- for (var i = 0; i < rest.length; i++) {
149
- for (var j = 0; j < arr[0].length; j++) {
150
- result.push([arr[0][j]].concat(rest[i]));
151
- }
152
- }
153
- return result;
154
- }
141
+ if (arr.length === 0) {
142
+ return [];
143
+ } else if (arr.length === 1) {
144
+ return arr[0];
145
+ } else {
146
+ var result = [];
147
+ var rest = this.permute(arr.slice(1));
148
+ for (var i = 0; i < rest.length; i++) {
149
+ for (var j = 0; j < arr[0].length; j++) {
150
+ result.push([arr[0][j]].concat(rest[i]));
151
+ }
152
+ }
153
+ return result;
154
+ }
155
155
  };
156
156
  Media.prototype.bubbleSelectors = function (selectors) {
157
- if (!selectors) {
158
- return;
159
- }
160
- this.rules = [new Ruleset(selectors.slice(0), [this.rules[0]])];
157
+ if (!selectors) {
158
+ return;
159
+ }
160
+ this.rules = [new Ruleset(selectors.slice(0), [this.rules[0]])];
161
161
  };
162
162
  module.exports = Media;
@@ -31,7 +31,7 @@ MixinCall.prototype.eval = function (context) {
31
31
  for (f = 0; f < 2; f++) {
32
32
  conditionResult[f] = true;
33
33
  defaultFunc.value(f);
34
- for(p = 0; p < mixinPath.length && conditionResult[f]; p++) {
34
+ for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {
35
35
  namespace = mixinPath[p];
36
36
  if (namespace.matchCondition) {
37
37
  conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);
@@ -71,7 +71,7 @@ MixinCall.prototype.eval = function (context) {
71
71
  mixin = mixins[m].rule;
72
72
  mixinPath = mixins[m].path;
73
73
  isRecursive = false;
74
- for(f = 0; f < context.frames.length; f++) {
74
+ for (f = 0; f < context.frames.length; f++) {
75
75
  if ((!(mixin instanceof MixinDefinition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {
76
76
  isRecursive = true;
77
77
  break;
@@ -15,8 +15,12 @@ var Definition = function (name, params, rules, condition, variadic, frames) {
15
15
  this.rules = rules;
16
16
  this._lookups = {};
17
17
  this.required = params.reduce(function (count, p) {
18
- if (!p.name || (p.name && !p.value)) { return count + 1; }
19
- else { return count; }
18
+ if (!p.name || (p.name && !p.value)) {
19
+ return count + 1;
20
+ }
21
+ else {
22
+ return count;
23
+ }
20
24
  }, 0);
21
25
  this.frames = frames;
22
26
  };
@@ -45,11 +49,11 @@ Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArgume
45
49
  args = args.slice(0);
46
50
  argsLength = args.length;
47
51
 
48
- for(i = 0; i < argsLength; i++) {
52
+ for (i = 0; i < argsLength; i++) {
49
53
  arg = args[i];
50
54
  if (name = (arg && arg.name)) {
51
55
  isNamedFound = false;
52
- for(j = 0; j < params.length; j++) {
56
+ for (j = 0; j < params.length; j++) {
53
57
  if (!evaldArguments[j] && name === params[j].name) {
54
58
  evaldArguments[j] = arg.value.eval(context);
55
59
  frame.prependRule(new Rule(name, arg.value.eval(context)));
@@ -108,6 +112,17 @@ Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArgume
108
112
 
109
113
  return frame;
110
114
  };
115
+ Definition.prototype.makeImportant = function() {
116
+ var rules = !this.rules ? this.rules : this.rules.map(function (r) {
117
+ if (r.makeImportant) {
118
+ return r.makeImportant(true);
119
+ } else {
120
+ return r;
121
+ }
122
+ });
123
+ var result = new Definition (this.name, this.params, rules, this.condition, this.variadic, this.frames);
124
+ return result;
125
+ };
111
126
  Definition.prototype.eval = function (context) {
112
127
  return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || context.frames.slice(0));
113
128
  };
@@ -125,7 +140,7 @@ Definition.prototype.evalCall = function (context, args, important) {
125
140
  ruleset.originalRuleset = this;
126
141
  ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));
127
142
  if (important) {
128
- ruleset = this.makeImportant.apply(ruleset);
143
+ ruleset = ruleset.makeImportant();
129
144
  }
130
145
  return ruleset;
131
146
  };
@@ -144,10 +159,16 @@ Definition.prototype.matchArgs = function (args, context) {
144
159
  var argsLength = (args && args.length) || 0, len;
145
160
 
146
161
  if (! this.variadic) {
147
- if (argsLength < this.required) { return false; }
148
- if (argsLength > this.params.length) { return false; }
162
+ if (argsLength < this.required) {
163
+ return false;
164
+ }
165
+ if (argsLength > this.params.length) {
166
+ return false;
167
+ }
149
168
  } else {
150
- if (argsLength < (this.required - 1)) { return false; }
169
+ if (argsLength < (this.required - 1)) {
170
+ return false;
171
+ }
151
172
  }
152
173
 
153
174
  len = Math.min(argsLength, this.arity);
@@ -35,9 +35,9 @@ Quoted.prototype.eval = function (context) {
35
35
  function iterativeReplace(value, regexp, replacementFnc) {
36
36
  var evaluatedValue = value;
37
37
  do {
38
- value = evaluatedValue;
39
- evaluatedValue = value.replace(regexp, replacementFnc);
40
- } while (value !== evaluatedValue);
38
+ value = evaluatedValue;
39
+ evaluatedValue = value.replace(regexp, replacementFnc);
40
+ } while (value !== evaluatedValue);
41
41
  return evaluatedValue;
42
42
  }
43
43
  value = iterativeReplace(value, /`([^`]+)`/g, javascriptReplacement);
@@ -44,7 +44,7 @@ Rule.prototype.eval = function (context) {
44
44
  // things faster (~10% for benchmark.less):
45
45
  name = (name.length === 1) && (name[0] instanceof Keyword) ?
46
46
  name[0].value : evalName(context, name);
47
- variable = false; // never treat expanded interpolation as new variable name
47
+ variable = false; // never treat expanded interpolation as new variable name
48
48
  }
49
49
  if (name === "font" && !context.strictMath) {
50
50
  strictMathBypass = true;
@@ -58,7 +58,7 @@ Ruleset.prototype.eval = function (context) {
58
58
  ruleset.firstRoot = this.firstRoot;
59
59
  ruleset.allowImports = this.allowImports;
60
60
 
61
- if(this.debugInfo) {
61
+ if (this.debugInfo) {
62
62
  ruleset.debugInfo = this.debugInfo;
63
63
  }
64
64
 
@@ -143,7 +143,7 @@ Ruleset.prototype.eval = function (context) {
143
143
  if (rule.selectors[0].isJustParentSelector()) {
144
144
  rsRules.splice(i--, 1);
145
145
 
146
- for(var j = 0; j < rule.rules.length; j++) {
146
+ for (var j = 0; j < rule.rules.length; j++) {
147
147
  subRule = rule.rules[j];
148
148
  if (!(subRule instanceof Rule) || !subRule.variable) {
149
149
  rsRules.splice(++i, 0, subRule);
@@ -183,15 +183,17 @@ Ruleset.prototype.evalImports = function(context) {
183
183
  }
184
184
  };
185
185
  Ruleset.prototype.makeImportant = function() {
186
- this.rules = this.rules.map(function (r) {
186
+ var result = new Ruleset(this.selectors, this.rules.map(function (r) {
187
187
  if (r.makeImportant) {
188
188
  return r.makeImportant();
189
189
  } else {
190
190
  return r;
191
191
  }
192
- });
193
- return this;
194
- };Ruleset.prototype.matchArgs = function (args) {
192
+ }), this.strictImports);
193
+
194
+ return result;
195
+ };
196
+ Ruleset.prototype.matchArgs = function (args) {
195
197
  return !args || args.length === 0;
196
198
  };
197
199
  // lets you call a css selector with a guard
@@ -224,7 +226,7 @@ Ruleset.prototype.variables = function () {
224
226
  // guard against root being a string (in the case of inlined less)
225
227
  if (r.type === "Import" && r.root && r.root.variables) {
226
228
  var vars = r.root.variables();
227
- for(var name in vars) {
229
+ for (var name in vars) {
228
230
  if (vars.hasOwnProperty(name)) {
229
231
  hash[name] = vars[name];
230
232
  }
@@ -255,7 +257,11 @@ Ruleset.prototype.rulesets = function () {
255
257
  };
256
258
  Ruleset.prototype.prependRule = function (rule) {
257
259
  var rules = this.rules;
258
- if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; }
260
+ if (rules) {
261
+ rules.unshift(rule);
262
+ } else {
263
+ this.rules = [ rule ];
264
+ }
259
265
  };
260
266
  Ruleset.prototype.find = function (selector, self, filter) {
261
267
  self = self || this;
@@ -270,13 +276,13 @@ Ruleset.prototype.find = function (selector, self, filter) {
270
276
  match = selector.match(rule.selectors[j]);
271
277
  if (match) {
272
278
  if (selector.elements.length > match) {
273
- if (!filter || filter(rule)) {
274
- foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);
275
- for (var i = 0; i < foundMixins.length; ++i) {
276
- foundMixins[i].path.push(rule);
279
+ if (!filter || filter(rule)) {
280
+ foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);
281
+ for (var i = 0; i < foundMixins.length; ++i) {
282
+ foundMixins[i].path.push(rule);
283
+ }
284
+ Array.prototype.push.apply(rules, foundMixins);
277
285
  }
278
- Array.prototype.push.apply(rules, foundMixins);
279
- }
280
286
  } else {
281
287
  rules.push({ rule: rule, path: []});
282
288
  }
@@ -309,19 +315,17 @@ Ruleset.prototype.genCSS = function (context, output) {
309
315
  sep;
310
316
 
311
317
  function isRulesetLikeNode(rule, root) {
312
- // if it has nested rules, then it should be treated like a ruleset
313
- // medias and comments do not have nested rules, but should be treated like rulesets anyway
314
- // some directives and anonymous nodes are ruleset like, others are not
315
- if (typeof rule.isRulesetLike === "boolean")
316
- {
317
- return rule.isRulesetLike;
318
- } else if (typeof rule.isRulesetLike === "function")
319
- {
320
- return rule.isRulesetLike(root);
321
- }
318
+ // if it has nested rules, then it should be treated like a ruleset
319
+ // medias and comments do not have nested rules, but should be treated like rulesets anyway
320
+ // some directives and anonymous nodes are ruleset like, others are not
321
+ if (typeof rule.isRulesetLike === "boolean") {
322
+ return rule.isRulesetLike;
323
+ } else if (typeof rule.isRulesetLike === "function") {
324
+ return rule.isRulesetLike(root);
325
+ }
322
326
 
323
- //anything else is assumed to be a rule
324
- return false;
327
+ //anything else is assumed to be a rule
328
+ return false;
325
329
  }
326
330
 
327
331
  for (i = 0; i < this.rules.length; i++) {
@@ -498,7 +502,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
498
502
  // }
499
503
  // == [[.a] [.c]] [[.b] [.c]]
500
504
  //
501
- var i, j, k, currentElements, newSelectors, selectorsMultiplied, sel, el, hadParentSelector = false;
505
+ var i, j, k, currentElements, newSelectors, selectorsMultiplied, sel, el, hadParentSelector = false, length, lastSelector;
502
506
  function findNestedSelector(element) {
503
507
  var maybeSelector;
504
508
  if (element.value.type !== 'Paren') {
@@ -592,8 +596,11 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
592
596
  mergeElementsOnToSelectors(currentElements, newSelectors);
593
597
 
594
598
  for (i = 0; i < newSelectors.length; i++) {
595
- if (newSelectors[i].length > 0) {
599
+ length = newSelectors[i].length;
600
+ if (length > 0) {
596
601
  paths.push(newSelectors[i]);
602
+ lastSelector = newSelectors[i][length - 1];
603
+ newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);
597
604
  }
598
605
  }
599
606
 
@@ -91,7 +91,7 @@ Selector.prototype.genCSS = function (context, output) {
91
91
  }
92
92
  if (!this._css) {
93
93
  //TODO caching? speed comparison?
94
- for(i = 0; i < this.elements.length; i++) {
94
+ for (i = 0; i < this.elements.length; i++) {
95
95
  element = this.elements[i];
96
96
  element.genCSS(context, output);
97
97
  }
@@ -23,6 +23,8 @@ Unit.prototype.genCSS = function (context, output) {
23
23
  output.add(this.numerator[0]); // the ideal situation
24
24
  } else if (!strictUnits && this.backupUnit) {
25
25
  output.add(this.backupUnit);
26
+ } else if (!strictUnits && this.denominator.length) {
27
+ output.add(this.denominator[0]);
26
28
  }
27
29
  };
28
30
  Unit.prototype.toString = function () {
@@ -24,7 +24,7 @@ Value.prototype.eval = function (context) {
24
24
  };
25
25
  Value.prototype.genCSS = function (context, output) {
26
26
  var i;
27
- for(i = 0; i < this.value.length; i++) {
27
+ for (i = 0; i < this.value.length; i++) {
28
28
  this.value[i].genCSS(context, output);
29
29
  if (i + 1 < this.value.length) {
30
30
  output.add((context && context.compress) ? ',' : ', ');