less 2.4.0 → 2.5.3

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 (405) hide show
  1. package/.idea/jsLibraryMappings.xml +7 -7
  2. package/.idea/less.js.iml +9 -16
  3. package/.idea/libraries/less_js_node_modules.xml +14 -0
  4. package/.idea/misc.xml +14 -5
  5. package/.idea/modules.xml +8 -9
  6. package/.idea/vcs.xml +6 -7
  7. package/.idea/workspace.xml +592 -806
  8. package/.jscsrc +72 -72
  9. package/.travis.yml +1 -0
  10. package/CHANGELOG.md +54 -8
  11. package/Gruntfile.js +40 -13
  12. package/README.md +2 -0
  13. package/appveyor.yml +0 -6
  14. package/bin/lessc +22 -24
  15. package/bower.json +1 -2
  16. package/dist/less-rolledup.js +8572 -0
  17. package/dist/less.js +807 -401
  18. package/dist/less.min.js +9 -8
  19. package/lib/less/contexts.js +2 -0
  20. package/lib/less/environment/abstract-file-manager.js +5 -1
  21. package/lib/less/functions/color.js +46 -12
  22. package/lib/less/functions/function-caller.js +31 -2
  23. package/lib/less/functions/function-registry.js +28 -17
  24. package/lib/less/functions/math-helper.js +16 -0
  25. package/lib/less/functions/math.js +4 -16
  26. package/lib/less/functions/number.js +7 -2
  27. package/lib/less/functions/string.js +5 -3
  28. package/lib/less/functions/svg.js +19 -11
  29. package/lib/less/functions/types.js +1 -6
  30. package/lib/less/import-manager.js +8 -3
  31. package/lib/less/index.js +1 -1
  32. package/lib/less/parser/parser-input.js +55 -54
  33. package/lib/less/parser/parser.js +168 -52
  34. package/lib/less/plugins/function-importer.js +35 -0
  35. package/lib/less/source-map-output.js +1 -2
  36. package/lib/less/tree/anonymous.js +10 -2
  37. package/lib/less/tree/color.js +4 -1
  38. package/lib/less/tree/comment.js +0 -3
  39. package/lib/less/tree/dimension.js +5 -3
  40. package/lib/less/tree/directive.js +40 -15
  41. package/lib/less/tree/expression.js +5 -0
  42. package/lib/less/tree/import.js +22 -10
  43. package/lib/less/tree/media.js +3 -23
  44. package/lib/less/tree/mixin-call.js +17 -7
  45. package/lib/less/tree/mixin-definition.js +20 -6
  46. package/lib/less/tree/rule.js +19 -1
  47. package/lib/less/tree/ruleset.js +40 -27
  48. package/lib/less/tree/selector.js +8 -1
  49. package/lib/less/visitors/extend-visitor.js +1 -4
  50. package/lib/less/visitors/import-visitor.js +17 -2
  51. package/lib/less/visitors/join-selector-visitor.js +6 -0
  52. package/lib/less/visitors/to-css-visitor.js +48 -14
  53. package/lib/less-browser/bootstrap.js +5 -6
  54. package/lib/less-browser/index.js +20 -12
  55. package/lib/less-node/image-size.js +54 -31
  56. package/lib/less-node/index.js +1 -1
  57. package/lib/less-node/lessc-helper.js +2 -2
  58. package/lib/less-rhino/index.js +12 -8
  59. package/package.json +9 -13
  60. package/test/browser/less/urls.less +7 -1
  61. package/test/browser/less.js +30 -0
  62. package/test/browser/runner-VisitorPlugin-options.js +3 -0
  63. package/test/browser/runner-VisitorPlugin.js +3 -0
  64. package/test/browser/runner-filemanagerPlugin-options.js +4 -0
  65. package/test/browser/runner-filemanagerPlugin.js +3 -0
  66. package/test/browser/runner-global-vars-options.js +2 -1
  67. package/test/browser/runner-main-options.js +11 -11
  68. package/test/browser/runner-postProcessor.js +1 -1
  69. package/test/browser/runner-postProcessorPlugin-options.js +3 -0
  70. package/test/browser/runner-postProcessorPlugin.js +3 -0
  71. package/test/browser/runner-preProcessorPlugin-options.js +3 -0
  72. package/test/browser/runner-preProcessorPlugin.js +3 -0
  73. package/test/css/comments2.css +1 -1
  74. package/test/css/compression/compression.css +1 -1
  75. package/test/css/detached-rulesets.css +5 -0
  76. package/test/css/directives-bubling.css +119 -0
  77. package/test/css/extract-and-length.css +1 -1
  78. package/test/css/filemanagerPlugin/filemanager.css +3 -0
  79. package/test/css/functions.css +17 -1
  80. package/test/css/import-reference.css +5 -1
  81. package/test/css/import.css +4 -0
  82. package/test/css/include-path/include-path.css +4 -1
  83. package/test/css/include-path-string/include-path-string.css +3 -0
  84. package/test/css/legacy/legacy.css +14 -0
  85. package/test/css/media.css +0 -1
  86. package/test/css/mixins-args.css +51 -1
  87. package/test/css/plugin.css +44 -0
  88. package/test/css/postProcessorPlugin/postProcessor.css +4 -0
  89. package/test/css/preProcessorPlugin/preProcessor.css +3 -0
  90. package/test/css/scope.css +1 -1
  91. package/test/css/strings.css +1 -1
  92. package/test/css/url-args/urls.css +5 -5
  93. package/test/css/urls.css +8 -8
  94. package/test/css/variables.css +5 -5
  95. package/test/css/visitorPlugin/visitor.css +3 -0
  96. package/test/data/image.jpg +0 -0
  97. package/test/data/image.svg +2 -1
  98. package/test/data/page.html +1 -1
  99. package/test/index.js +5 -0
  100. package/test/less/detached-rulesets.less +9 -0
  101. package/test/less/directives-bubling.less +142 -0
  102. package/test/less/errors/at-rules-undefined-var.txt +4 -4
  103. package/test/less/errors/css-guard-default-func.txt +4 -4
  104. package/test/less/errors/javascript-undefined-var.txt +4 -4
  105. package/test/less/errors/mixins-guards-default-func-1.txt +4 -4
  106. package/test/less/errors/mixins-guards-default-func-2.txt +4 -4
  107. package/test/less/errors/mixins-guards-default-func-3.txt +4 -4
  108. package/test/less/errors/{parse-error-extra-parens.less → parse-error-media-no-block-1.less} +0 -0
  109. package/test/less/errors/parse-error-media-no-block-1.txt +3 -0
  110. package/test/less/errors/parse-error-media-no-block-2.less +1 -0
  111. package/test/less/errors/parse-error-media-no-block-2.txt +2 -0
  112. package/test/less/errors/parse-error-media-no-block-3.less +4 -0
  113. package/test/less/errors/parse-error-media-no-block-3.txt +3 -0
  114. package/test/less/errors/percentage-non-number-argument.less +3 -0
  115. package/test/less/errors/percentage-non-number-argument.txt +4 -0
  116. package/test/less/errors/property-interp-not-defined.txt +2 -2
  117. package/test/less/errors/svg-gradient2.txt +1 -1
  118. package/test/less/errors/svg-gradient3.txt +1 -1
  119. package/test/less/errors/svg-gradient4.less +4 -0
  120. package/test/less/errors/svg-gradient4.txt +4 -0
  121. package/test/less/errors/svg-gradient5.less +4 -0
  122. package/test/less/errors/svg-gradient5.txt +4 -0
  123. package/test/less/errors/svg-gradient6.less +4 -0
  124. package/test/less/errors/svg-gradient6.txt +4 -0
  125. package/test/less/filemanagerPlugin/colors.test +1 -0
  126. package/test/less/filemanagerPlugin/filemanager.less +4 -0
  127. package/test/less/functions.less +20 -2
  128. package/test/less/import/css-import.less +1 -0
  129. package/test/less/import/import-inline-invalid-css.less +1 -0
  130. package/test/less/import/import-reference.less +10 -1
  131. package/test/less/import/import-test-a.less +1 -0
  132. package/test/less/import-reference.less +4 -1
  133. package/test/less/import.less +1 -0
  134. package/test/less/include-path/include-path.less +3 -1
  135. package/test/less/include-path-string/include-path-string.less +3 -0
  136. package/test/less/legacy/legacy.less +14 -0
  137. package/test/less/mixins-args.less +48 -0
  138. package/test/less/mixins-guards.less +9 -0
  139. package/test/less/no-output.less +1 -1
  140. package/test/less/plugin/plugin-global.js +9 -0
  141. package/test/less/plugin/plugin-local.js +8 -0
  142. package/test/less/plugin/plugin-transitive.js +5 -0
  143. package/test/less/plugin/plugin-transitive.less +5 -0
  144. package/test/less/plugin.less +85 -0
  145. package/test/less/postProcessorPlugin/postProcessor.less +4 -0
  146. package/test/less/preProcessorPlugin/preProcessor.less +3 -0
  147. package/test/less/sourcemaps/imported.css +6 -6
  148. package/test/less/visitorPlugin/visitor.less +4 -0
  149. package/test/less-bom/charsets.less +3 -0
  150. package/test/less-bom/colors.less +98 -0
  151. package/test/less-bom/comments.less +102 -0
  152. package/test/less-bom/comments2.less +20 -0
  153. package/test/less-bom/compression/compression.less +36 -0
  154. package/test/less-bom/css-3.less +154 -0
  155. package/test/less-bom/css-escapes.less +33 -0
  156. package/test/less-bom/css-guards.less +103 -0
  157. package/test/less-bom/css.less +108 -0
  158. package/test/less-bom/debug/import/test.less +25 -0
  159. package/test/less-bom/debug/linenumbers.less +33 -0
  160. package/test/less-bom/detached-rulesets.less +112 -0
  161. package/test/less-bom/directives-bubling.less +142 -0
  162. package/test/less-bom/empty.less +1 -0
  163. package/test/less-bom/errors/add-mixed-units.less +3 -0
  164. package/test/less-bom/errors/add-mixed-units.txt +4 -0
  165. package/test/less-bom/errors/add-mixed-units2.less +3 -0
  166. package/test/less-bom/errors/add-mixed-units2.txt +4 -0
  167. package/test/less-bom/errors/at-rules-undefined-var.less +4 -0
  168. package/test/less-bom/errors/at-rules-undefined-var.txt +4 -0
  169. package/test/less-bom/errors/bad-variable-declaration1.less +1 -0
  170. package/test/less-bom/errors/bad-variable-declaration1.txt +2 -0
  171. package/test/less-bom/errors/color-func-invalid-color.less +3 -0
  172. package/test/less-bom/errors/color-func-invalid-color.txt +4 -0
  173. package/test/less-bom/errors/color-invalid-hex-code.less +3 -0
  174. package/test/less-bom/errors/color-invalid-hex-code.txt +4 -0
  175. package/test/less-bom/errors/color-invalid-hex-code2.less +3 -0
  176. package/test/less-bom/errors/color-invalid-hex-code2.txt +4 -0
  177. package/test/less-bom/errors/css-guard-default-func.less +4 -0
  178. package/test/less-bom/errors/css-guard-default-func.txt +4 -0
  179. package/test/less-bom/errors/detached-ruleset-1.less +6 -0
  180. package/test/less-bom/errors/detached-ruleset-1.txt +4 -0
  181. package/test/less-bom/errors/detached-ruleset-2.less +6 -0
  182. package/test/less-bom/errors/detached-ruleset-2.txt +4 -0
  183. package/test/less-bom/errors/detached-ruleset-3.less +4 -0
  184. package/test/less-bom/errors/detached-ruleset-3.txt +4 -0
  185. package/test/less-bom/errors/detached-ruleset-5.less +4 -0
  186. package/test/less-bom/errors/detached-ruleset-5.txt +3 -0
  187. package/test/less-bom/errors/detached-ruleset-6.less +5 -0
  188. package/test/less-bom/errors/detached-ruleset-6.txt +4 -0
  189. package/test/less-bom/errors/divide-mixed-units.less +3 -0
  190. package/test/less-bom/errors/divide-mixed-units.txt +4 -0
  191. package/test/less-bom/errors/extend-no-selector.less +3 -0
  192. package/test/less-bom/errors/extend-no-selector.txt +3 -0
  193. package/test/less-bom/errors/extend-not-at-end.less +3 -0
  194. package/test/less-bom/errors/extend-not-at-end.txt +3 -0
  195. package/test/less-bom/errors/import-malformed.less +1 -0
  196. package/test/less-bom/errors/import-malformed.txt +3 -0
  197. package/test/less-bom/errors/import-missing.less +6 -0
  198. package/test/less-bom/errors/import-missing.txt +3 -0
  199. package/test/less-bom/errors/import-no-semi.less +1 -0
  200. package/test/less-bom/errors/import-no-semi.txt +2 -0
  201. package/test/less-bom/errors/import-subfolder1.less +1 -0
  202. package/test/less-bom/errors/import-subfolder1.txt +3 -0
  203. package/test/less-bom/errors/import-subfolder2.less +1 -0
  204. package/test/less-bom/errors/import-subfolder2.txt +4 -0
  205. package/test/less-bom/errors/imports/import-subfolder1.less +1 -0
  206. package/test/less-bom/errors/imports/import-subfolder2.less +1 -0
  207. package/test/less-bom/errors/imports/import-test.less +4 -0
  208. package/test/less-bom/errors/imports/subfolder/mixin-not-defined.less +1 -0
  209. package/test/less-bom/errors/imports/subfolder/parse-error-curly-bracket.less +1 -0
  210. package/test/less-bom/errors/javascript-error.less +3 -0
  211. package/test/less-bom/errors/javascript-error.txt +4 -0
  212. package/test/less-bom/errors/javascript-undefined-var.less +3 -0
  213. package/test/less-bom/errors/javascript-undefined-var.txt +4 -0
  214. package/test/less-bom/errors/mixed-mixin-definition-args-1.less +6 -0
  215. package/test/less-bom/errors/mixed-mixin-definition-args-1.txt +4 -0
  216. package/test/less-bom/errors/mixed-mixin-definition-args-2.less +6 -0
  217. package/test/less-bom/errors/mixed-mixin-definition-args-2.txt +4 -0
  218. package/test/less-bom/errors/mixin-not-defined.less +11 -0
  219. package/test/less-bom/errors/mixin-not-defined.txt +3 -0
  220. package/test/less-bom/errors/mixin-not-matched.less +6 -0
  221. package/test/less-bom/errors/mixin-not-matched.txt +3 -0
  222. package/test/less-bom/errors/mixin-not-matched2.less +6 -0
  223. package/test/less-bom/errors/mixin-not-matched2.txt +3 -0
  224. package/test/less-bom/errors/mixin-not-visible-in-scope-1.less +9 -0
  225. package/test/less-bom/errors/mixin-not-visible-in-scope-1.txt +4 -0
  226. package/test/less-bom/errors/mixins-guards-default-func-1.less +9 -0
  227. package/test/less-bom/errors/mixins-guards-default-func-1.txt +4 -0
  228. package/test/less-bom/errors/mixins-guards-default-func-2.less +9 -0
  229. package/test/less-bom/errors/mixins-guards-default-func-2.txt +4 -0
  230. package/test/less-bom/errors/mixins-guards-default-func-3.less +9 -0
  231. package/test/less-bom/errors/mixins-guards-default-func-3.txt +4 -0
  232. package/test/less-bom/errors/multiple-guards-on-css-selectors.less +4 -0
  233. package/test/less-bom/errors/multiple-guards-on-css-selectors.txt +4 -0
  234. package/test/less-bom/errors/multiple-guards-on-css-selectors2.less +4 -0
  235. package/test/less-bom/errors/multiple-guards-on-css-selectors2.txt +4 -0
  236. package/test/less-bom/errors/multiply-mixed-units.less +7 -0
  237. package/test/less-bom/errors/multiply-mixed-units.txt +4 -0
  238. package/test/less-bom/errors/parens-error-1.less +3 -0
  239. package/test/less-bom/errors/parens-error-1.txt +4 -0
  240. package/test/less-bom/errors/parens-error-2.less +3 -0
  241. package/test/less-bom/errors/parens-error-2.txt +4 -0
  242. package/test/less-bom/errors/parens-error-3.less +3 -0
  243. package/test/less-bom/errors/parens-error-3.txt +4 -0
  244. package/test/less-bom/errors/parse-error-curly-bracket.less +4 -0
  245. package/test/less-bom/errors/parse-error-curly-bracket.txt +4 -0
  246. package/test/less-bom/errors/parse-error-media-no-block-1.less +5 -0
  247. package/test/less-bom/errors/parse-error-media-no-block-1.txt +3 -0
  248. package/test/less-bom/errors/parse-error-media-no-block-2.less +1 -0
  249. package/test/less-bom/errors/parse-error-media-no-block-2.txt +2 -0
  250. package/test/less-bom/errors/parse-error-media-no-block-3.less +4 -0
  251. package/test/less-bom/errors/parse-error-media-no-block-3.txt +3 -0
  252. package/test/less-bom/errors/parse-error-missing-bracket.less +2 -0
  253. package/test/less-bom/errors/parse-error-missing-bracket.txt +3 -0
  254. package/test/less-bom/errors/parse-error-missing-parens.less +5 -0
  255. package/test/less-bom/errors/parse-error-missing-parens.txt +3 -0
  256. package/test/less-bom/errors/parse-error-with-import.less +13 -0
  257. package/test/less-bom/errors/parse-error-with-import.txt +4 -0
  258. package/test/less-bom/errors/percentage-missing-space.less +3 -0
  259. package/test/less-bom/errors/percentage-missing-space.txt +4 -0
  260. package/test/less-bom/errors/percentage-non-number-argument.less +3 -0
  261. package/test/less-bom/errors/percentage-non-number-argument.txt +4 -0
  262. package/test/less-bom/errors/property-asterisk-only-name.less +3 -0
  263. package/test/less-bom/errors/property-asterisk-only-name.txt +4 -0
  264. package/test/less-bom/errors/property-ie5-hack.less +3 -0
  265. package/test/less-bom/errors/property-ie5-hack.txt +3 -0
  266. package/test/less-bom/errors/property-in-root.less +4 -0
  267. package/test/less-bom/errors/property-in-root.txt +4 -0
  268. package/test/less-bom/errors/property-in-root2.less +1 -0
  269. package/test/less-bom/errors/property-in-root2.txt +4 -0
  270. package/test/less-bom/errors/property-in-root3.less +4 -0
  271. package/test/less-bom/errors/property-in-root3.txt +3 -0
  272. package/test/less-bom/errors/property-interp-not-defined.less +1 -0
  273. package/test/less-bom/errors/property-interp-not-defined.txt +2 -0
  274. package/test/less-bom/errors/recursive-variable.less +1 -0
  275. package/test/less-bom/errors/recursive-variable.txt +2 -0
  276. package/test/less-bom/errors/single-character.less +1 -0
  277. package/test/less-bom/errors/single-character.txt +2 -0
  278. package/test/less-bom/errors/svg-gradient1.less +3 -0
  279. package/test/less-bom/errors/svg-gradient1.txt +4 -0
  280. package/test/less-bom/errors/svg-gradient2.less +3 -0
  281. package/test/less-bom/errors/svg-gradient2.txt +4 -0
  282. package/test/less-bom/errors/svg-gradient3.less +3 -0
  283. package/test/less-bom/errors/svg-gradient3.txt +4 -0
  284. package/test/less-bom/errors/svg-gradient4.less +4 -0
  285. package/test/less-bom/errors/svg-gradient4.txt +4 -0
  286. package/test/less-bom/errors/svg-gradient5.less +4 -0
  287. package/test/less-bom/errors/svg-gradient5.txt +4 -0
  288. package/test/less-bom/errors/svg-gradient6.less +4 -0
  289. package/test/less-bom/errors/svg-gradient6.txt +4 -0
  290. package/test/less-bom/errors/unit-function.less +3 -0
  291. package/test/less-bom/errors/unit-function.txt +4 -0
  292. package/test/less-bom/extend-chaining.less +91 -0
  293. package/test/less-bom/extend-clearfix.less +19 -0
  294. package/test/less-bom/extend-exact.less +46 -0
  295. package/test/less-bom/extend-media.less +24 -0
  296. package/test/less-bom/extend-nest.less +65 -0
  297. package/test/less-bom/extend-selector.less +99 -0
  298. package/test/less-bom/extend.less +81 -0
  299. package/test/less-bom/extract-and-length.less +133 -0
  300. package/test/less-bom/filemanagerPlugin/colors.test +1 -0
  301. package/test/less-bom/filemanagerPlugin/filemanager.less +4 -0
  302. package/test/less-bom/functions.less +232 -0
  303. package/test/less-bom/globalVars/extended.json +5 -0
  304. package/test/less-bom/globalVars/extended.less +10 -0
  305. package/test/less-bom/globalVars/simple.json +3 -0
  306. package/test/less-bom/globalVars/simple.less +3 -0
  307. package/test/less-bom/ie-filters.less +15 -0
  308. package/test/less-bom/import/css-import.less +1 -0
  309. package/test/less-bom/import/deeper/deeper-2/url-import-2.less +3 -0
  310. package/test/less-bom/import/deeper/deeper-2/url-import.less +1 -0
  311. package/test/less-bom/import/deeper/import-once-test-a.less +1 -0
  312. package/test/less-bom/import/deeper/url-import.less +1 -0
  313. package/test/less-bom/import/import-and-relative-paths-test.less +17 -0
  314. package/test/less-bom/import/import-charset-test.less +1 -0
  315. package/test/less-bom/import/import-inline-invalid-css.less +1 -0
  316. package/test/less-bom/import/import-interpolation.less +2 -0
  317. package/test/less-bom/import/import-interpolation2.less +5 -0
  318. package/test/less-bom/import/import-once-test-c.less +6 -0
  319. package/test/less-bom/import/import-reference.less +98 -0
  320. package/test/less-bom/import/import-test-a.less +5 -0
  321. package/test/less-bom/import/import-test-b.less +8 -0
  322. package/test/less-bom/import/import-test-c.less +6 -0
  323. package/test/less-bom/import/import-test-d.css +1 -0
  324. package/test/less-bom/import/import-test-e.less +2 -0
  325. package/test/less-bom/import/import-test-f.less +5 -0
  326. package/test/less-bom/import/imports/font.less +8 -0
  327. package/test/less-bom/import/imports/logo.less +6 -0
  328. package/test/less-bom/import/interpolation-vars.less +6 -0
  329. package/test/less-bom/import/invalid-css.less +1 -0
  330. package/test/less-bom/import/urls.less +1 -0
  331. package/test/less-bom/import-inline.less +3 -0
  332. package/test/less-bom/import-interpolation.less +8 -0
  333. package/test/less-bom/import-once.less +6 -0
  334. package/test/less-bom/import-reference.less +26 -0
  335. package/test/less-bom/import.less +31 -0
  336. package/test/less-bom/include-path/include-path.less +8 -0
  337. package/test/less-bom/include-path-string/include-path-string.less +3 -0
  338. package/test/less-bom/javascript.less +38 -0
  339. package/test/less-bom/lazy-eval.less +6 -0
  340. package/test/less-bom/legacy/legacy.less +21 -0
  341. package/test/less-bom/media.less +234 -0
  342. package/test/less-bom/merge.less +78 -0
  343. package/test/less-bom/mixins-args.less +263 -0
  344. package/test/less-bom/mixins-closure.less +26 -0
  345. package/test/less-bom/mixins-guards-default-func.less +195 -0
  346. package/test/less-bom/mixins-guards.less +280 -0
  347. package/test/less-bom/mixins-important.less +53 -0
  348. package/test/less-bom/mixins-interpolated.less +75 -0
  349. package/test/less-bom/mixins-named-args.less +36 -0
  350. package/test/less-bom/mixins-nested.less +22 -0
  351. package/test/less-bom/mixins-pattern.less +102 -0
  352. package/test/less-bom/mixins.less +145 -0
  353. package/test/less-bom/modifyVars/extended.json +5 -0
  354. package/test/less-bom/modifyVars/extended.less +11 -0
  355. package/test/less-bom/nested-gradient-with-svg-gradient/mixin-consumer.less +5 -0
  356. package/test/less-bom/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +15 -0
  357. package/test/less-bom/no-js-errors/no-js-errors.less +3 -0
  358. package/test/less-bom/no-js-errors/no-js-errors.txt +4 -0
  359. package/test/less-bom/no-output.less +2 -0
  360. package/test/less-bom/operations.less +62 -0
  361. package/test/less-bom/parens.less +45 -0
  362. package/test/less-bom/plugin/plugin-global.js +9 -0
  363. package/test/less-bom/plugin/plugin-local.js +8 -0
  364. package/test/less-bom/plugin/plugin-transitive.js +5 -0
  365. package/test/less-bom/plugin/plugin-transitive.less +5 -0
  366. package/test/less-bom/plugin.less +85 -0
  367. package/test/less-bom/postProcessorPlugin/postProcessor.less +4 -0
  368. package/test/less-bom/preProcessorPlugin/preProcessor.less +3 -0
  369. package/test/less-bom/property-name-interp.less +56 -0
  370. package/test/less-bom/rulesets.less +30 -0
  371. package/test/less-bom/scope.less +104 -0
  372. package/test/less-bom/selectors.less +184 -0
  373. package/test/less-bom/sourcemaps/basic.json +3 -0
  374. package/test/less-bom/sourcemaps/basic.less +27 -0
  375. package/test/less-bom/sourcemaps/imported.css +7 -0
  376. package/test/less-bom/sourcemaps-empty/empty.less +1 -0
  377. package/test/less-bom/sourcemaps-empty/var-defs.less +1 -0
  378. package/test/less-bom/static-urls/urls.less +33 -0
  379. package/test/less-bom/strict-units/strict-units.less +4 -0
  380. package/test/less-bom/strings.less +73 -0
  381. package/test/less-bom/url-args/urls.less +63 -0
  382. package/test/less-bom/urls.less +94 -0
  383. package/test/less-bom/variables-in-at-rules.less +20 -0
  384. package/test/less-bom/variables.less +119 -0
  385. package/test/less-bom/visitorPlugin/visitor.less +4 -0
  386. package/test/less-bom/whitespace.less +44 -0
  387. package/test/less-test.js +9 -5
  388. package/test/plugins/filemanager/index.js +19 -0
  389. package/test/plugins/postprocess/index.js +14 -0
  390. package/test/plugins/preprocess/index.js +19 -0
  391. package/test/plugins/visitor/index.js +24 -0
  392. package/test.less +1 -0
  393. package/.idea/codeStyleSettings.xml +0 -13
  394. package/.idea/encodings.xml +0 -5
  395. package/.idea/inspectionProfiles/Project_Default.xml +0 -8
  396. package/.idea/inspectionProfiles/profiles_settings.xml +0 -7
  397. package/.idea/jsLinters/jscs.xml +0 -4
  398. package/.idea/jsLinters/jshint.xml +0 -70
  399. package/.idea/libraries/sass_stdlib.xml +0 -8
  400. package/.idea/scopes/scope_settings.xml +0 -5
  401. package/projectFilesBackup/.idea/libraries/sass_stdlib.xml +0 -8
  402. package/test/less/errors/detached-ruleset-4.less +0 -5
  403. package/test/less/errors/detached-ruleset-4.txt +0 -4
  404. package/test/less/errors/parse-error-extra-parens.txt +0 -3
  405. package/test/sourcemaps/maps/import-map.map +0 -1
package/dist/less.js CHANGED
@@ -1,16 +1,16 @@
1
1
  /*!
2
- * Less - Leaner CSS v2.4.0
2
+ * Less - Leaner CSS v2.5.3
3
3
  * http://lesscss.org
4
4
  *
5
5
  * Copyright (c) 2009-2015, Alexis Sellier <self@cloudhead.net>
6
- * Licensed under the Apache v2 License.
6
+ * Licensed under the License.
7
7
  *
8
8
  */
9
9
 
10
- /** * @license Apache v2
10
+ /** * @license
11
11
  */
12
12
 
13
- !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.less=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
13
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.less = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
14
14
  var addDataAttr = require("./utils").addDataAttr,
15
15
  browser = require("./browser");
16
16
 
@@ -74,18 +74,18 @@ require("./add-default-options")(window, options);
74
74
 
75
75
  var less = module.exports = require("./index")(window, options);
76
76
 
77
+ window.less = less;
78
+
77
79
  if (options.onReady) {
78
80
  if (/!watch/.test(window.location.hash)) {
79
81
  less.watch();
80
82
  }
81
83
 
82
- less.pageLoadFinished = less.registerStylesheets().then(
83
- function () {
84
- return less.refresh(less.env === 'development');
85
- }
86
- );
84
+ less.registerStylesheetsImmediately();
85
+ less.pageLoadFinished = less.refresh(less.env === 'development');
87
86
  }
88
- },{"./add-default-options":1,"./index":7,"promise/polyfill.js":"promise/polyfill.js"}],3:[function(require,module,exports){
87
+
88
+ },{"./add-default-options":1,"./index":7,"promise/polyfill.js":95}],3:[function(require,module,exports){
89
89
  var utils = require("./utils");
90
90
  module.exports = {
91
91
  createCSS: function (document, styles, sheet) {
@@ -511,7 +511,7 @@ module.exports = function(window, options) {
511
511
 
512
512
  var typePattern = /^text\/(x-)?less$/;
513
513
 
514
- function postProcessCSS(styles) {
514
+ function postProcessCSS(styles) { // deprecated, use a plugin for postprocesstasks
515
515
  if (options.postProcessor && typeof options.postProcessor === 'function') {
516
516
  styles = options.postProcessor.call(styles, styles) || styles;
517
517
  }
@@ -671,20 +671,28 @@ module.exports = function(window, options) {
671
671
  less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };
672
672
 
673
673
  //
674
- // Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
674
+ // Synchronously get all <link> tags with the 'rel' attribute set to
675
+ // "stylesheet/less".
675
676
  //
676
- less.registerStylesheets = function() {
677
- return new Promise(function(resolve, reject) {
678
- var links = document.getElementsByTagName('link');
679
- less.sheets = [];
677
+ less.registerStylesheetsImmediately = function() {
678
+ var links = document.getElementsByTagName('link');
679
+ less.sheets = [];
680
680
 
681
- for (var i = 0; i < links.length; i++) {
682
- if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
683
- (links[i].type.match(typePattern)))) {
684
- less.sheets.push(links[i]);
685
- }
681
+ for (var i = 0; i < links.length; i++) {
682
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
683
+ (links[i].type.match(typePattern)))) {
684
+ less.sheets.push(links[i]);
686
685
  }
686
+ }
687
+ };
687
688
 
689
+ //
690
+ // Asynchronously get all <link> tags with the 'rel' attribute set to
691
+ // "stylesheet/less", returning a Promise.
692
+ //
693
+ less.registerStylesheets = function() {
694
+ return new Promise(function(resolve, reject) {
695
+ less.registerStylesheetsImmediately();
688
696
  resolve();
689
697
  });
690
698
  };
@@ -739,7 +747,7 @@ module.exports = function(window, options) {
739
747
  return less;
740
748
  };
741
749
 
742
- },{"../less":29,"./browser":3,"./cache":4,"./error-reporting":5,"./file-manager":6,"./log-listener":8,"./utils":9}],8:[function(require,module,exports){
750
+ },{"../less":30,"./browser":3,"./cache":4,"./error-reporting":5,"./file-manager":6,"./log-listener":8,"./utils":9}],8:[function(require,module,exports){
743
751
  module.exports = function(less, options) {
744
752
 
745
753
  var logLevel_debug = 4,
@@ -870,6 +878,8 @@ var evalCopyProperties = [
870
878
  contexts.Eval = function(options, frames) {
871
879
  copyFromOriginal(options, this, evalCopyProperties);
872
880
 
881
+ if (typeof this.paths === "string") { this.paths = [this.paths]; }
882
+
873
883
  this.frames = frames || [];
874
884
  this.importantScope = this.importantScope || [];
875
885
  };
@@ -1120,8 +1130,12 @@ abstractFileManager.prototype.getPath = function (filename) {
1120
1130
  return filename.slice(0, j + 1);
1121
1131
  };
1122
1132
 
1133
+ abstractFileManager.prototype.tryAppendExtension = function(path, ext) {
1134
+ return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext;
1135
+ };
1136
+
1123
1137
  abstractFileManager.prototype.tryAppendLessExtension = function(path) {
1124
- return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + '.less';
1138
+ return this.tryAppendExtension(path, '.less');
1125
1139
  };
1126
1140
 
1127
1141
  abstractFileManager.prototype.supportsSync = function() {
@@ -1275,7 +1289,7 @@ environment.prototype.clearFileManagers = function () {
1275
1289
 
1276
1290
  module.exports = environment;
1277
1291
 
1278
- },{"../logger":31}],16:[function(require,module,exports){
1292
+ },{"../logger":32}],16:[function(require,module,exports){
1279
1293
  var Color = require("../tree/color"),
1280
1294
  functionRegistry = require("./function-registry");
1281
1295
 
@@ -1351,7 +1365,7 @@ for (var f in colorBlendModeFunctions) {
1351
1365
 
1352
1366
  functionRegistry.addMultiple(colorBlend);
1353
1367
 
1354
- },{"../tree/color":47,"./function-registry":21}],17:[function(require,module,exports){
1368
+ },{"../tree/color":49,"./function-registry":21}],17:[function(require,module,exports){
1355
1369
  var Dimension = require("../tree/dimension"),
1356
1370
  Color = require("../tree/color"),
1357
1371
  Quoted = require("../tree/quoted"),
@@ -1495,7 +1509,7 @@ colorFunctions = {
1495
1509
 
1496
1510
  return new Dimension(luminance * color.alpha * 100, '%');
1497
1511
  },
1498
- saturate: function (color, amount) {
1512
+ saturate: function (color, amount, method) {
1499
1513
  // filter: saturate(3.2);
1500
1514
  // should be kept as is, so check for color
1501
1515
  if (!color.rgb) {
@@ -1503,42 +1517,72 @@ colorFunctions = {
1503
1517
  }
1504
1518
  var hsl = color.toHSL();
1505
1519
 
1506
- hsl.s += amount.value / 100;
1520
+ if (typeof method !== "undefined" && method.value === "relative") {
1521
+ hsl.s += hsl.s * amount.value / 100;
1522
+ }
1523
+ else {
1524
+ hsl.s += amount.value / 100;
1525
+ }
1507
1526
  hsl.s = clamp(hsl.s);
1508
1527
  return hsla(hsl);
1509
1528
  },
1510
- desaturate: function (color, amount) {
1529
+ desaturate: function (color, amount, method) {
1511
1530
  var hsl = color.toHSL();
1512
1531
 
1513
- hsl.s -= amount.value / 100;
1532
+ if (typeof method !== "undefined" && method.value === "relative") {
1533
+ hsl.s -= hsl.s * amount.value / 100;
1534
+ }
1535
+ else {
1536
+ hsl.s -= amount.value / 100;
1537
+ }
1514
1538
  hsl.s = clamp(hsl.s);
1515
1539
  return hsla(hsl);
1516
1540
  },
1517
- lighten: function (color, amount) {
1541
+ lighten: function (color, amount, method) {
1518
1542
  var hsl = color.toHSL();
1519
1543
 
1520
- hsl.l += amount.value / 100;
1544
+ if (typeof method !== "undefined" && method.value === "relative") {
1545
+ hsl.l += hsl.l * amount.value / 100;
1546
+ }
1547
+ else {
1548
+ hsl.l += amount.value / 100;
1549
+ }
1521
1550
  hsl.l = clamp(hsl.l);
1522
1551
  return hsla(hsl);
1523
1552
  },
1524
- darken: function (color, amount) {
1553
+ darken: function (color, amount, method) {
1525
1554
  var hsl = color.toHSL();
1526
1555
 
1527
- hsl.l -= amount.value / 100;
1556
+ if (typeof method !== "undefined" && method.value === "relative") {
1557
+ hsl.l -= hsl.l * amount.value / 100;
1558
+ }
1559
+ else {
1560
+ hsl.l -= amount.value / 100;
1561
+ }
1528
1562
  hsl.l = clamp(hsl.l);
1529
1563
  return hsla(hsl);
1530
1564
  },
1531
- fadein: function (color, amount) {
1565
+ fadein: function (color, amount, method) {
1532
1566
  var hsl = color.toHSL();
1533
1567
 
1534
- hsl.a += amount.value / 100;
1568
+ if (typeof method !== "undefined" && method.value === "relative") {
1569
+ hsl.a += hsl.a * amount.value / 100;
1570
+ }
1571
+ else {
1572
+ hsl.a += amount.value / 100;
1573
+ }
1535
1574
  hsl.a = clamp(hsl.a);
1536
1575
  return hsla(hsl);
1537
1576
  },
1538
- fadeout: function (color, amount) {
1577
+ fadeout: function (color, amount, method) {
1539
1578
  var hsl = color.toHSL();
1540
1579
 
1541
- hsl.a -= amount.value / 100;
1580
+ if (typeof method !== "undefined" && method.value === "relative") {
1581
+ hsl.a -= hsl.a * amount.value / 100;
1582
+ }
1583
+ else {
1584
+ hsl.a -= amount.value / 100;
1585
+ }
1542
1586
  hsl.a = clamp(hsl.a);
1543
1587
  return hsla(hsl);
1544
1588
  },
@@ -1562,6 +1606,10 @@ colorFunctions = {
1562
1606
  // http://sass-lang.com
1563
1607
  //
1564
1608
  mix: function (color1, color2, weight) {
1609
+ if (!color1.toHSL || !color2.toHSL) {
1610
+ console.log(color2.type);
1611
+ console.dir(color2);
1612
+ }
1565
1613
  if (!weight) {
1566
1614
  weight = new Dimension(50);
1567
1615
  }
@@ -1638,7 +1686,7 @@ colorFunctions = {
1638
1686
  };
1639
1687
  functionRegistry.addMultiple(colorFunctions);
1640
1688
 
1641
- },{"../tree/anonymous":43,"../tree/color":47,"../tree/dimension":53,"../tree/quoted":70,"./function-registry":21}],18:[function(require,module,exports){
1689
+ },{"../tree/anonymous":45,"../tree/color":49,"../tree/dimension":55,"../tree/quoted":72,"./function-registry":21}],18:[function(require,module,exports){
1642
1690
  module.exports = function(environment) {
1643
1691
  var Quoted = require("../tree/quoted"),
1644
1692
  URL = require("../tree/url"),
@@ -1725,7 +1773,7 @@ module.exports = function(environment) {
1725
1773
  });
1726
1774
  };
1727
1775
 
1728
- },{"../logger":31,"../tree/quoted":70,"../tree/url":77,"./function-registry":21}],19:[function(require,module,exports){
1776
+ },{"../logger":32,"../tree/quoted":72,"../tree/url":79,"./function-registry":21}],19:[function(require,module,exports){
1729
1777
  var Keyword = require("../tree/keyword"),
1730
1778
  functionRegistry = require("./function-registry");
1731
1779
 
@@ -1754,45 +1802,84 @@ functionRegistry.add("default", defaultFunc.eval.bind(defaultFunc));
1754
1802
 
1755
1803
  module.exports = defaultFunc;
1756
1804
 
1757
- },{"../tree/keyword":62,"./function-registry":21}],20:[function(require,module,exports){
1758
- var functionRegistry = require("./function-registry");
1805
+ },{"../tree/keyword":64,"./function-registry":21}],20:[function(require,module,exports){
1806
+ var Expression = require("../tree/expression");
1759
1807
 
1760
1808
  var functionCaller = function(name, context, index, currentFileInfo) {
1761
1809
  this.name = name.toLowerCase();
1762
- this.func = functionRegistry.get(this.name);
1763
1810
  this.index = index;
1764
1811
  this.context = context;
1765
1812
  this.currentFileInfo = currentFileInfo;
1813
+
1814
+ this.func = context.frames[0].functionRegistry.get(this.name);
1766
1815
  };
1767
1816
  functionCaller.prototype.isValid = function() {
1768
1817
  return Boolean(this.func);
1769
1818
  };
1770
1819
  functionCaller.prototype.call = function(args) {
1820
+
1821
+ // This code is terrible and should be replaced as per this issue...
1822
+ // https://github.com/less/less.js/issues/2477
1823
+ if (Array.isArray(args)) {
1824
+ args = args.filter(function (item) {
1825
+ if (item.type === "Comment") {
1826
+ return false;
1827
+ }
1828
+ return true;
1829
+ })
1830
+ .map(function(item) {
1831
+ if (item.type === "Expression") {
1832
+ var subNodes = item.value.filter(function (item) {
1833
+ if (item.type === "Comment") {
1834
+ return false;
1835
+ }
1836
+ return true;
1837
+ });
1838
+ if (subNodes.length === 1) {
1839
+ return subNodes[0];
1840
+ } else {
1841
+ return new Expression(subNodes);
1842
+ }
1843
+ }
1844
+ return item;
1845
+ });
1846
+ }
1847
+
1771
1848
  return this.func.apply(this, args);
1772
1849
  };
1773
1850
 
1774
1851
  module.exports = functionCaller;
1775
1852
 
1776
- },{"./function-registry":21}],21:[function(require,module,exports){
1777
- module.exports = {
1778
- _data: {},
1779
- add: function(name, func) {
1780
- if (this._data.hasOwnProperty(name)) {
1781
- //TODO warn
1853
+ },{"../tree/expression":58}],21:[function(require,module,exports){
1854
+ function makeRegistry( base ) {
1855
+ return {
1856
+ _data: {},
1857
+ add: function(name, func) {
1858
+ // precautionary case conversion, as later querying of
1859
+ // the registry by function-caller uses lower case as well.
1860
+ name = name.toLowerCase();
1861
+
1862
+ if (this._data.hasOwnProperty(name)) {
1863
+ //TODO warn
1864
+ }
1865
+ this._data[name] = func;
1866
+ },
1867
+ addMultiple: function(functions) {
1868
+ Object.keys(functions).forEach(
1869
+ function(name) {
1870
+ this.add(name, functions[name]);
1871
+ }.bind(this));
1872
+ },
1873
+ get: function(name) {
1874
+ return this._data[name] || ( base && base.get( name ));
1875
+ },
1876
+ inherit : function() {
1877
+ return makeRegistry( this );
1782
1878
  }
1783
- this._data[name] = func;
1784
- },
1785
- addMultiple: function(functions) {
1786
- Object.keys(functions).forEach(
1787
- function(name) {
1788
- this.add(name, functions[name]);
1789
- }.bind(this));
1790
- },
1791
- get: function(name) {
1792
- return this._data[name];
1793
- }
1794
- };
1879
+ };
1880
+ }
1795
1881
 
1882
+ module.exports = makeRegistry( null );
1796
1883
  },{}],22:[function(require,module,exports){
1797
1884
  module.exports = function(environment) {
1798
1885
  var functions = {
@@ -1814,9 +1901,26 @@ module.exports = function(environment) {
1814
1901
  return functions;
1815
1902
  };
1816
1903
 
1817
- },{"./color":17,"./color-blending":16,"./data-uri":18,"./default":19,"./function-caller":20,"./function-registry":21,"./math":23,"./number":24,"./string":25,"./svg":26,"./types":27}],23:[function(require,module,exports){
1818
- var Dimension = require("../tree/dimension"),
1819
- functionRegistry = require("./function-registry");
1904
+ },{"./color":17,"./color-blending":16,"./data-uri":18,"./default":19,"./function-caller":20,"./function-registry":21,"./math":24,"./number":25,"./string":26,"./svg":27,"./types":28}],23:[function(require,module,exports){
1905
+ var Dimension = require("../tree/dimension");
1906
+
1907
+ var MathHelper = function() {
1908
+ };
1909
+ MathHelper._math = function (fn, unit, n) {
1910
+ if (!(n instanceof Dimension)) {
1911
+ throw { type: "Argument", message: "argument must be a number" };
1912
+ }
1913
+ if (unit == null) {
1914
+ unit = n.unit;
1915
+ } else {
1916
+ n = n.unify();
1917
+ }
1918
+ return new Dimension(fn(parseFloat(n.value)), unit);
1919
+ };
1920
+ module.exports = MathHelper;
1921
+ },{"../tree/dimension":55}],24:[function(require,module,exports){
1922
+ var functionRegistry = require("./function-registry"),
1923
+ mathHelper = require("./math-helper.js");
1820
1924
 
1821
1925
  var mathFunctions = {
1822
1926
  // name, unit
@@ -1832,35 +1936,24 @@ var mathFunctions = {
1832
1936
  acos: "rad"
1833
1937
  };
1834
1938
 
1835
- function _math(fn, unit, n) {
1836
- if (!(n instanceof Dimension)) {
1837
- throw { type: "Argument", message: "argument must be a number" };
1838
- }
1839
- if (unit == null) {
1840
- unit = n.unit;
1841
- } else {
1842
- n = n.unify();
1843
- }
1844
- return new Dimension(fn(parseFloat(n.value)), unit);
1845
- }
1846
-
1847
1939
  for (var f in mathFunctions) {
1848
1940
  if (mathFunctions.hasOwnProperty(f)) {
1849
- mathFunctions[f] = _math.bind(null, Math[f], mathFunctions[f]);
1941
+ mathFunctions[f] = mathHelper._math.bind(null, Math[f], mathFunctions[f]);
1850
1942
  }
1851
1943
  }
1852
1944
 
1853
1945
  mathFunctions.round = function (n, f) {
1854
1946
  var fraction = typeof f === "undefined" ? 0 : f.value;
1855
- return _math(function(num) { return num.toFixed(fraction); }, null, n);
1947
+ return mathHelper._math(function(num) { return num.toFixed(fraction); }, null, n);
1856
1948
  };
1857
1949
 
1858
1950
  functionRegistry.addMultiple(mathFunctions);
1859
1951
 
1860
- },{"../tree/dimension":53,"./function-registry":21}],24:[function(require,module,exports){
1952
+ },{"./function-registry":21,"./math-helper.js":23}],25:[function(require,module,exports){
1861
1953
  var Dimension = require("../tree/dimension"),
1862
1954
  Anonymous = require("../tree/anonymous"),
1863
- functionRegistry = require("./function-registry");
1955
+ functionRegistry = require("./function-registry"),
1956
+ mathHelper = require("./math-helper.js");
1864
1957
 
1865
1958
  var minMax = function (isMin, args) {
1866
1959
  args = Array.prototype.slice.call(args);
@@ -1931,11 +2024,15 @@ functionRegistry.addMultiple({
1931
2024
  return new Dimension(Math.pow(x.value, y.value), x.unit);
1932
2025
  },
1933
2026
  percentage: function (n) {
1934
- return new Dimension(n.value * 100, '%');
2027
+ var result = mathHelper._math(function(num) {
2028
+ return num * 100;
2029
+ }, '%', n);
2030
+
2031
+ return result;
1935
2032
  }
1936
2033
  });
1937
2034
 
1938
- },{"../tree/anonymous":43,"../tree/dimension":53,"./function-registry":21}],25:[function(require,module,exports){
2035
+ },{"../tree/anonymous":45,"../tree/dimension":55,"./function-registry":21,"./math-helper.js":23}],26:[function(require,module,exports){
1939
2036
  var Quoted = require("../tree/quoted"),
1940
2037
  Anonymous = require("../tree/anonymous"),
1941
2038
  JavaScript = require("../tree/javascript"),
@@ -1952,8 +2049,9 @@ functionRegistry.addMultiple({
1952
2049
  },
1953
2050
  replace: function (string, pattern, replacement, flags) {
1954
2051
  var result = string.value;
1955
-
1956
- result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement.value);
2052
+ replacement = (replacement.type === "Quoted") ?
2053
+ replacement.value : replacement.toCSS();
2054
+ result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
1957
2055
  return new Quoted(string.quote || '', result, string.escaped);
1958
2056
  },
1959
2057
  '%': function (string /* arg, arg, ...*/) {
@@ -1963,7 +2061,8 @@ functionRegistry.addMultiple({
1963
2061
  for (var i = 0; i < args.length; i++) {
1964
2062
  /*jshint loopfunc:true */
1965
2063
  result = result.replace(/%[sda]/i, function(token) {
1966
- var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
2064
+ var value = ((args[i].type === "Quoted") &&
2065
+ token.match(/s/i)) ? args[i].value : args[i].toCSS();
1967
2066
  return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
1968
2067
  });
1969
2068
  }
@@ -1972,7 +2071,7 @@ functionRegistry.addMultiple({
1972
2071
  }
1973
2072
  });
1974
2073
 
1975
- },{"../tree/anonymous":43,"../tree/javascript":60,"../tree/quoted":70,"./function-registry":21}],26:[function(require,module,exports){
2074
+ },{"../tree/anonymous":45,"../tree/javascript":62,"../tree/quoted":72,"./function-registry":21}],27:[function(require,module,exports){
1976
2075
  module.exports = function(environment) {
1977
2076
  var Dimension = require("../tree/dimension"),
1978
2077
  Color = require("../tree/color"),
@@ -1983,23 +2082,31 @@ module.exports = function(environment) {
1983
2082
 
1984
2083
  functionRegistry.add("svg-gradient", function(direction) {
1985
2084
 
1986
- function throwArgumentDescriptor() {
1987
- throw { type: "Argument",
1988
- message: "svg-gradient expects direction, start_color [start_position], [color position,]...," +
1989
- " end_color [end_position]" };
1990
- }
1991
-
1992
- if (arguments.length < 3) {
1993
- throwArgumentDescriptor();
1994
- }
1995
- var stops = Array.prototype.slice.call(arguments, 1),
2085
+ var stops,
1996
2086
  gradientDirectionSvg,
1997
2087
  gradientType = "linear",
1998
2088
  rectangleDimension = 'x="0" y="0" width="1" height="1"',
1999
2089
  renderEnv = {compress: false},
2000
2090
  returner,
2001
2091
  directionValue = direction.toCSS(renderEnv),
2002
- i, color, position, positionValue, alpha;
2092
+ i, color, position, positionValue, alpha;
2093
+
2094
+ function throwArgumentDescriptor() {
2095
+ throw { type: "Argument",
2096
+ message: "svg-gradient expects direction, start_color [start_position], [color position,]...," +
2097
+ " end_color [end_position] or direction, color list" };
2098
+ }
2099
+
2100
+ if (arguments.length == 2) {
2101
+ if (arguments[1].value.length < 2) {
2102
+ throwArgumentDescriptor();
2103
+ }
2104
+ stops = arguments[1].value;
2105
+ } else if (arguments.length < 3) {
2106
+ throwArgumentDescriptor();
2107
+ } else {
2108
+ stops = Array.prototype.slice.call(arguments, 1);
2109
+ }
2003
2110
 
2004
2111
  switch (directionValue) {
2005
2112
  case "to bottom":
@@ -2054,7 +2161,7 @@ module.exports = function(environment) {
2054
2161
  });
2055
2162
  };
2056
2163
 
2057
- },{"../tree/color":47,"../tree/dimension":53,"../tree/expression":56,"../tree/quoted":70,"../tree/url":77,"./function-registry":21}],27:[function(require,module,exports){
2164
+ },{"../tree/color":49,"../tree/dimension":55,"../tree/expression":58,"../tree/quoted":72,"../tree/url":79,"./function-registry":21}],28:[function(require,module,exports){
2058
2165
  var Keyword = require("../tree/keyword"),
2059
2166
  DetachedRuleset = require("../tree/detached-ruleset"),
2060
2167
  Dimension = require("../tree/dimension"),
@@ -2084,12 +2191,7 @@ var isa = function (n, Type) {
2084
2191
  var items = Array.isArray(node.value) ?
2085
2192
  node.value : Array(node);
2086
2193
 
2087
- return items.filter(function(item) {
2088
- if (item.type === "Comment") {
2089
- return false;
2090
- }
2091
- return true;
2092
- });
2194
+ return items;
2093
2195
  };
2094
2196
  functionRegistry.addMultiple({
2095
2197
  isruleset: function (n) {
@@ -2150,9 +2252,10 @@ functionRegistry.addMultiple({
2150
2252
  }
2151
2253
  });
2152
2254
 
2153
- },{"../tree/anonymous":43,"../tree/color":47,"../tree/detached-ruleset":52,"../tree/dimension":53,"../tree/keyword":62,"../tree/operation":68,"../tree/quoted":70,"../tree/url":77,"./function-registry":21}],28:[function(require,module,exports){
2255
+ },{"../tree/anonymous":45,"../tree/color":49,"../tree/detached-ruleset":54,"../tree/dimension":55,"../tree/keyword":64,"../tree/operation":70,"../tree/quoted":72,"../tree/url":79,"./function-registry":21}],29:[function(require,module,exports){
2154
2256
  var contexts = require("./contexts"),
2155
- Parser = require('./parser/parser');
2257
+ Parser = require('./parser/parser'),
2258
+ FunctionImporter = require('./plugins/function-importer');
2156
2259
 
2157
2260
  module.exports = function(environment) {
2158
2261
 
@@ -2218,7 +2321,7 @@ module.exports = function(environment) {
2218
2321
  }
2219
2322
 
2220
2323
  if (tryAppendLessExtension) {
2221
- path = fileManager.tryAppendLessExtension(path);
2324
+ path = fileManager.tryAppendExtension(path, importOptions.plugin ? ".js" : ".less");
2222
2325
  }
2223
2326
 
2224
2327
  var loadFileCallback = function(loadedFile) {
@@ -2254,7 +2357,11 @@ module.exports = function(environment) {
2254
2357
  newFileInfo.reference = true;
2255
2358
  }
2256
2359
 
2257
- if (importOptions.inline) {
2360
+ if (importOptions.plugin) {
2361
+ new FunctionImporter(newEnv, newFileInfo).eval(contents, function (e, root) {
2362
+ fileParsedFunc(e, root, resolvedFilename);
2363
+ });
2364
+ } else if (importOptions.inline) {
2258
2365
  fileParsedFunc(null, contents, resolvedFilename);
2259
2366
  } else {
2260
2367
  new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {
@@ -2278,12 +2385,12 @@ module.exports = function(environment) {
2278
2385
  return ImportManager;
2279
2386
  };
2280
2387
 
2281
- },{"./contexts":10,"./parser/parser":36}],29:[function(require,module,exports){
2388
+ },{"./contexts":10,"./parser/parser":37,"./plugins/function-importer":39}],30:[function(require,module,exports){
2282
2389
  module.exports = function(environment, fileManagers) {
2283
2390
  var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment;
2284
2391
 
2285
2392
  var less = {
2286
- version: [2, 4, 0],
2393
+ version: [2, 5, 3],
2287
2394
  data: require('./data'),
2288
2395
  tree: require('./tree'),
2289
2396
  Environment: (Environment = require("./environment/environment")),
@@ -2309,7 +2416,7 @@ module.exports = function(environment, fileManagers) {
2309
2416
  return less;
2310
2417
  };
2311
2418
 
2312
- },{"./contexts":10,"./data":12,"./environment/abstract-file-manager":14,"./environment/environment":15,"./functions":22,"./import-manager":28,"./less-error":30,"./logger":31,"./parse":33,"./parse-tree":32,"./parser/parser":36,"./plugin-manager":37,"./render":38,"./source-map-builder":39,"./source-map-output":40,"./transform-tree":41,"./tree":59,"./utils":80,"./visitors":84}],30:[function(require,module,exports){
2419
+ },{"./contexts":10,"./data":12,"./environment/abstract-file-manager":14,"./environment/environment":15,"./functions":22,"./import-manager":29,"./less-error":31,"./logger":32,"./parse":34,"./parse-tree":33,"./parser/parser":37,"./plugin-manager":38,"./render":40,"./source-map-builder":41,"./source-map-output":42,"./transform-tree":43,"./tree":61,"./utils":82,"./visitors":86}],31:[function(require,module,exports){
2313
2420
  var utils = require("./utils");
2314
2421
 
2315
2422
  var LessError = module.exports = function LessError(e, importManager, currentFilename) {
@@ -2353,7 +2460,7 @@ if (typeof Object.create === 'undefined') {
2353
2460
 
2354
2461
  LessError.prototype.constructor = LessError;
2355
2462
 
2356
- },{"./utils":80}],31:[function(require,module,exports){
2463
+ },{"./utils":82}],32:[function(require,module,exports){
2357
2464
  module.exports = {
2358
2465
  error: function(msg) {
2359
2466
  this._fireEvent("error", msg);
@@ -2389,7 +2496,7 @@ module.exports = {
2389
2496
  _listeners: []
2390
2497
  };
2391
2498
 
2392
- },{}],32:[function(require,module,exports){
2499
+ },{}],33:[function(require,module,exports){
2393
2500
  var LessError = require('./less-error'),
2394
2501
  transformTree = require("./transform-tree"),
2395
2502
  logger = require("./logger");
@@ -2451,7 +2558,7 @@ module.exports = function(SourceMapBuilder) {
2451
2558
  return ParseTree;
2452
2559
  };
2453
2560
 
2454
- },{"./less-error":30,"./logger":31,"./transform-tree":41}],33:[function(require,module,exports){
2561
+ },{"./less-error":31,"./logger":32,"./transform-tree":43}],34:[function(require,module,exports){
2455
2562
  var PromiseConstructor,
2456
2563
  contexts = require("./contexts"),
2457
2564
  Parser = require('./parser/parser'),
@@ -2521,7 +2628,7 @@ module.exports = function(environment, ParseTree, ImportManager) {
2521
2628
  return parse;
2522
2629
  };
2523
2630
 
2524
- },{"./contexts":10,"./parser/parser":36,"./plugin-manager":37,"promise":undefined}],34:[function(require,module,exports){
2631
+ },{"./contexts":10,"./parser/parser":37,"./plugin-manager":38,"promise":undefined}],35:[function(require,module,exports){
2525
2632
  // Split the input into chunks.
2526
2633
  module.exports = function (input, fail) {
2527
2634
  var len = input.length, level = 0, parenLevel = 0,
@@ -2635,7 +2742,7 @@ module.exports = function (input, fail) {
2635
2742
  return chunks;
2636
2743
  };
2637
2744
 
2638
- },{}],35:[function(require,module,exports){
2745
+ },{}],36:[function(require,module,exports){
2639
2746
  var chunker = require('./chunker');
2640
2747
 
2641
2748
  module.exports = function() {
@@ -2667,56 +2774,11 @@ module.exports = function() {
2667
2774
  parserInput.forget = function() {
2668
2775
  saveStack.pop();
2669
2776
  };
2670
- function sync() {
2671
- if (parserInput.i > currentPos) {
2672
- current = current.slice(parserInput.i - currentPos);
2673
- currentPos = parserInput.i;
2674
- }
2675
- }
2676
2777
  parserInput.isWhitespace = function (offset) {
2677
2778
  var pos = parserInput.i + (offset || 0),
2678
2779
  code = input.charCodeAt(pos);
2679
2780
  return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);
2680
2781
  };
2681
- //
2682
- // Parse from a token, regexp or string, and move forward if match
2683
- //
2684
- parserInput.$ = function(tok) {
2685
- var tokType = typeof tok,
2686
- match, length;
2687
-
2688
- // Either match a single character in the input,
2689
- // or match a regexp in the current chunk (`current`).
2690
- //
2691
- if (tokType === "string") {
2692
- if (input.charAt(parserInput.i) !== tok) {
2693
- return null;
2694
- }
2695
- skipWhitespace(1);
2696
- return tok;
2697
- }
2698
-
2699
- // regexp
2700
- sync();
2701
- if (! (match = tok.exec(current))) {
2702
- return null;
2703
- }
2704
-
2705
- length = match[0].length;
2706
-
2707
- // The match is confirmed, add the match length to `i`,
2708
- // and consume any extra white-space characters (' ' || '\n')
2709
- // which come after that. The reason for this is that LeSS's
2710
- // grammar is mostly white-space insensitive.
2711
- //
2712
- skipWhitespace(length);
2713
-
2714
- if (typeof match === 'string') {
2715
- return match;
2716
- } else {
2717
- return match.length === 1 ? match[0] : match;
2718
- }
2719
- };
2720
2782
 
2721
2783
  // Specialization of $(tok)
2722
2784
  parserInput.$re = function(tok) {
@@ -2724,6 +2786,7 @@ module.exports = function() {
2724
2786
  current = current.slice(parserInput.i - currentPos);
2725
2787
  currentPos = parserInput.i;
2726
2788
  }
2789
+
2727
2790
  var m = tok.exec(current);
2728
2791
  if (!m) {
2729
2792
  return null;
@@ -2737,7 +2800,6 @@ module.exports = function() {
2737
2800
  return m.length === 1 ? m[0] : m;
2738
2801
  };
2739
2802
 
2740
- // Specialization of $(tok)
2741
2803
  parserInput.$char = function(tok) {
2742
2804
  if (input.charAt(parserInput.i) !== tok) {
2743
2805
  return null;
@@ -2746,6 +2808,48 @@ module.exports = function() {
2746
2808
  return tok;
2747
2809
  };
2748
2810
 
2811
+ parserInput.$str = function(tok) {
2812
+ var tokLength = tok.length;
2813
+
2814
+ // https://jsperf.com/string-startswith/21
2815
+ for (var i = 0; i < tokLength; i++) {
2816
+ if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {
2817
+ return null;
2818
+ }
2819
+ }
2820
+
2821
+ skipWhitespace(tokLength);
2822
+ return tok;
2823
+ };
2824
+
2825
+ parserInput.$quoted = function() {
2826
+
2827
+ var startChar = input.charAt(parserInput.i);
2828
+ if (startChar !== "'" && startChar !== '"') {
2829
+ return;
2830
+ }
2831
+ var length = input.length,
2832
+ currentPosition = parserInput.i;
2833
+
2834
+ for (var i = 1; i + currentPosition < length; i++) {
2835
+ var nextChar = input.charAt(i + currentPosition);
2836
+ switch(nextChar) {
2837
+ case "\\":
2838
+ i++;
2839
+ continue;
2840
+ case "\r":
2841
+ case "\n":
2842
+ break;
2843
+ case startChar:
2844
+ var str = input.substr(currentPosition, i + 1);
2845
+ skipWhitespace(i + 1);
2846
+ return str;
2847
+ default:
2848
+ }
2849
+ }
2850
+ return null;
2851
+ };
2852
+
2749
2853
  var CHARCODE_SPACE = 32,
2750
2854
  CHARCODE_TAB = 9,
2751
2855
  CHARCODE_LF = 10,
@@ -2774,7 +2878,7 @@ module.exports = function() {
2774
2878
  nextChar = inp.charAt(parserInput.i + 1);
2775
2879
  if (nextChar === '/') {
2776
2880
  comment = {index: parserInput.i, isLineComment: true};
2777
- var nextNewLine = inp.indexOf("\n", parserInput.i + 1);
2881
+ var nextNewLine = inp.indexOf("\n", parserInput.i + 2);
2778
2882
  if (nextNewLine < 0) {
2779
2883
  nextNewLine = endIndex;
2780
2884
  }
@@ -2783,12 +2887,11 @@ module.exports = function() {
2783
2887
  parserInput.commentStore.push(comment);
2784
2888
  continue;
2785
2889
  } else if (nextChar === '*') {
2786
- var haystack = inp.substr(parserInput.i);
2787
- var comment_search_result = haystack.match(/^\/\*(?:[^*]|\*+[^\/*])*\*+\//);
2788
- if (comment_search_result) {
2890
+ var nextStarSlash = inp.indexOf("*/", parserInput.i + 2);
2891
+ if (nextStarSlash >= 0) {
2789
2892
  comment = {
2790
2893
  index: parserInput.i,
2791
- text: comment_search_result[0],
2894
+ text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),
2792
2895
  isLineComment: false
2793
2896
  };
2794
2897
  parserInput.i += comment.text.length - 1;
@@ -2808,8 +2911,7 @@ module.exports = function() {
2808
2911
  currentPos = parserInput.i;
2809
2912
 
2810
2913
  if (!current.length) {
2811
- if (j < chunks.length - 1)
2812
- {
2914
+ if (j < chunks.length - 1) {
2813
2915
  current = chunks[++j];
2814
2916
  skipWhitespace(0); // skip space at the beginning of a chunk
2815
2917
  return true; // things changed
@@ -2824,7 +2926,13 @@ module.exports = function() {
2824
2926
  // just return the match.
2825
2927
  parserInput.peek = function(tok) {
2826
2928
  if (typeof tok === 'string') {
2827
- return input.charAt(parserInput.i) === tok;
2929
+ // https://jsperf.com/string-startswith/21
2930
+ for (var i = 0; i < tok.length; i++) {
2931
+ if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {
2932
+ return false;
2933
+ }
2934
+ }
2935
+ return true;
2828
2936
  } else {
2829
2937
  return tok.test(current);
2830
2938
  }
@@ -2895,7 +3003,7 @@ module.exports = function() {
2895
3003
  return parserInput;
2896
3004
  };
2897
3005
 
2898
- },{"./chunker":34}],36:[function(require,module,exports){
3006
+ },{"./chunker":35}],37:[function(require,module,exports){
2899
3007
  var LessError = require('../less-error'),
2900
3008
  tree = require("../tree"),
2901
3009
  visitors = require("../visitors"),
@@ -2941,7 +3049,7 @@ var Parser = function Parser(context, imports, fileInfo) {
2941
3049
 
2942
3050
  function expect(arg, msg, index) {
2943
3051
  // some older browsers return typeof 'function' for RegExp
2944
- var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : parserInput.$(arg);
3052
+ var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : parserInput.$re(arg);
2945
3053
  if (result) {
2946
3054
  return result;
2947
3055
  }
@@ -3020,7 +3128,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3020
3128
  // output. The callback is called when the input is parsed.
3021
3129
  try {
3022
3130
  parserInput.start(str, context.chunkInput, function fail(msg, index) {
3023
- throw LessError({
3131
+ throw new LessError({
3024
3132
  index: index,
3025
3133
  type: 'Parse',
3026
3134
  message: msg,
@@ -3115,7 +3223,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3115
3223
  // Ruleset (Selector [Element '>', '.child'], [...])
3116
3224
  // ])
3117
3225
  //
3118
- // In general, most rules will try to parse a token with the `$()` function, and if the return
3226
+ // In general, most rules will try to parse a token with the `$re()` function, and if the return
3119
3227
  // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
3120
3228
  // first, before parsing, that's when we use `peek()`.
3121
3229
  //
@@ -3138,8 +3246,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3138
3246
  primary: function () {
3139
3247
  var mixin = this.mixin, root = [], node;
3140
3248
 
3141
- while (true)
3142
- {
3249
+ while (true) {
3143
3250
  while (true) {
3144
3251
  node = this.comment();
3145
3252
  if (!node) { break; }
@@ -3164,7 +3271,11 @@ var Parser = function Parser(context, imports, fileInfo) {
3164
3271
  if (node) {
3165
3272
  root.push(node);
3166
3273
  } else {
3167
- if (!(parserInput.$re(/^[\s\n]+/) || parserInput.$re(/^;+/))) {
3274
+ var foundSemiColon = false;
3275
+ while (parserInput.$char(";")) {
3276
+ foundSemiColon = true;
3277
+ }
3278
+ if (!foundSemiColon) {
3168
3279
  break;
3169
3280
  }
3170
3281
  }
@@ -3192,12 +3303,20 @@ var Parser = function Parser(context, imports, fileInfo) {
3192
3303
  // "milky way" 'he\'s the one!'
3193
3304
  //
3194
3305
  quoted: function () {
3195
- var str, index = parserInput.i;
3306
+ var str, index = parserInput.i, isEscaped = false;
3196
3307
 
3197
- str = parserInput.$re(/^(~)?("((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)')/);
3198
- if (str) {
3199
- return new(tree.Quoted)(str[2], str[3] || str[4], Boolean(str[1]), index, fileInfo);
3308
+ parserInput.save();
3309
+ if (parserInput.$char("~")) {
3310
+ isEscaped = true;
3200
3311
  }
3312
+ str = parserInput.$quoted();
3313
+ if (!str) {
3314
+ parserInput.restore();
3315
+ return;
3316
+ }
3317
+ parserInput.forget();
3318
+
3319
+ return new(tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);
3201
3320
  },
3202
3321
 
3203
3322
  //
@@ -3206,7 +3325,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3206
3325
  // black border-collapse
3207
3326
  //
3208
3327
  keyword: function () {
3209
- var k = parserInput.$re(/^%|^[_A-Za-z-][_A-Za-z0-9-]*/);
3328
+ var k = parserInput.$char("%") || parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]*/);
3210
3329
  if (k) {
3211
3330
  return tree.Color.fromKeyword(k) || new(tree.Keyword)(k);
3212
3331
  }
@@ -3225,6 +3344,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3225
3344
  call: function () {
3226
3345
  var name, nameLC, args, alpha, index = parserInput.i;
3227
3346
 
3347
+ // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
3228
3348
  if (parserInput.peek(/^url\(/i)) {
3229
3349
  return;
3230
3350
  }
@@ -3240,6 +3360,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3240
3360
  if (nameLC === 'alpha') {
3241
3361
  alpha = parsers.alpha();
3242
3362
  if (alpha) {
3363
+ parserInput.forget();
3243
3364
  return alpha;
3244
3365
  }
3245
3366
  }
@@ -3284,16 +3405,22 @@ var Parser = function Parser(context, imports, fileInfo) {
3284
3405
 
3285
3406
  assignment: function () {
3286
3407
  var key, value;
3408
+ parserInput.save();
3287
3409
  key = parserInput.$re(/^\w+(?=\s?=)/i);
3288
3410
  if (!key) {
3411
+ parserInput.restore();
3289
3412
  return;
3290
3413
  }
3291
3414
  if (!parserInput.$char('=')) {
3415
+ parserInput.restore();
3292
3416
  return;
3293
3417
  }
3294
3418
  value = parsers.entity();
3295
3419
  if (value) {
3420
+ parserInput.forget();
3296
3421
  return new(tree.Assignment)(key, value);
3422
+ } else {
3423
+ parserInput.restore();
3297
3424
  }
3298
3425
  },
3299
3426
 
@@ -3309,7 +3436,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3309
3436
 
3310
3437
  parserInput.autoCommentAbsorb = false;
3311
3438
 
3312
- if (parserInput.currentChar() !== 'u' || !parserInput.$re(/^url\(/)) {
3439
+ if (!parserInput.$str("url(")) {
3313
3440
  parserInput.autoCommentAbsorb = true;
3314
3441
  return;
3315
3442
  }
@@ -3368,7 +3495,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3368
3495
  if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters
3369
3496
  error("Invalid HEX color code");
3370
3497
  }
3371
- return new(tree.Color)(rgb[1]);
3498
+ return new(tree.Color)(rgb[1], undefined, '#' + colorCandidateString);
3372
3499
  }
3373
3500
  },
3374
3501
 
@@ -3410,10 +3537,22 @@ var Parser = function Parser(context, imports, fileInfo) {
3410
3537
  javascript: function () {
3411
3538
  var js, index = parserInput.i;
3412
3539
 
3413
- js = parserInput.$re(/^(~)?`([^`]*)`/);
3540
+ parserInput.save();
3541
+
3542
+ var escape = parserInput.$char("~");
3543
+ var jsQuote = parserInput.$char("`");
3544
+
3545
+ if (!jsQuote) {
3546
+ parserInput.restore();
3547
+ return;
3548
+ }
3549
+
3550
+ js = parserInput.$re(/^[^`]*`/);
3414
3551
  if (js) {
3415
- return new(tree.JavaScript)(js[2], Boolean(js[1]), index, fileInfo);
3552
+ parserInput.forget();
3553
+ return new(tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);
3416
3554
  }
3555
+ parserInput.restore("invalid javascript definition");
3417
3556
  }
3418
3557
  },
3419
3558
 
@@ -3447,7 +3586,9 @@ var Parser = function Parser(context, imports, fileInfo) {
3447
3586
  extend: function(isRule) {
3448
3587
  var elements, e, index = parserInput.i, option, extendList, extend;
3449
3588
 
3450
- if (!(isRule ? parserInput.$re(/^&:extend\(/) : parserInput.$re(/^:extend\(/))) { return; }
3589
+ if (!parserInput.$str(isRule ? "&:extend(" : ":extend(")) {
3590
+ return;
3591
+ }
3451
3592
 
3452
3593
  do {
3453
3594
  option = null;
@@ -3552,7 +3693,8 @@ var Parser = function Parser(context, imports, fileInfo) {
3552
3693
  var entities = parsers.entities,
3553
3694
  returner = { args:null, variadic: false },
3554
3695
  expressions = [], argsSemiColon = [], argsComma = [],
3555
- isSemiColonSeparated, expressionContainsNamed, name, nameLoop, value, arg;
3696
+ isSemiColonSeparated, expressionContainsNamed, name, nameLoop,
3697
+ value, arg, expand;
3556
3698
 
3557
3699
  parserInput.save();
3558
3700
 
@@ -3561,7 +3703,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3561
3703
  arg = parsers.detachedRuleset() || parsers.expression();
3562
3704
  } else {
3563
3705
  parserInput.commentStore.length = 0;
3564
- if (parserInput.currentChar() === '.' && parserInput.$re(/^\.{3}/)) {
3706
+ if (parserInput.$str("...")) {
3565
3707
  returner.variadic = true;
3566
3708
  if (parserInput.$char(";") && !isSemiColonSeparated) {
3567
3709
  isSemiColonSeparated = true;
@@ -3602,10 +3744,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3602
3744
  expressionContainsNamed = true;
3603
3745
  }
3604
3746
 
3605
- // we do not support setting a ruleset as a default variable - it doesn't make sense
3606
- // However if we do want to add it, there is nothing blocking it, just don't error
3607
- // and remove isCall dependency below
3608
- value = (isCall && parsers.detachedRuleset()) || parsers.expression();
3747
+ value = parsers.detachedRuleset() || parsers.expression();
3609
3748
 
3610
3749
  if (!value) {
3611
3750
  if (isCall) {
@@ -3617,14 +3756,18 @@ var Parser = function Parser(context, imports, fileInfo) {
3617
3756
  }
3618
3757
  }
3619
3758
  nameLoop = (name = val.name);
3620
- } else if (!isCall && parserInput.$re(/^\.{3}/)) {
3621
- returner.variadic = true;
3622
- if (parserInput.$char(";") && !isSemiColonSeparated) {
3623
- isSemiColonSeparated = true;
3759
+ } else if (parserInput.$str("...")) {
3760
+ if (!isCall) {
3761
+ returner.variadic = true;
3762
+ if (parserInput.$char(";") && !isSemiColonSeparated) {
3763
+ isSemiColonSeparated = true;
3764
+ }
3765
+ (isSemiColonSeparated ? argsSemiColon : argsComma)
3766
+ .push({ name: arg.name, variadic: true });
3767
+ break;
3768
+ } else {
3769
+ expand = true;
3624
3770
  }
3625
- (isSemiColonSeparated ? argsSemiColon : argsComma)
3626
- .push({ name: arg.name, variadic: true });
3627
- break;
3628
3771
  } else if (!isCall) {
3629
3772
  name = nameLoop = val.name;
3630
3773
  value = null;
@@ -3635,7 +3778,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3635
3778
  expressions.push(value);
3636
3779
  }
3637
3780
 
3638
- argsComma.push({ name:nameLoop, value:value });
3781
+ argsComma.push({ name:nameLoop, value:value, expand:expand });
3639
3782
 
3640
3783
  if (parserInput.$char(',')) {
3641
3784
  continue;
@@ -3652,7 +3795,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3652
3795
  if (expressions.length > 1) {
3653
3796
  value = new(tree.Value)(expressions);
3654
3797
  }
3655
- argsSemiColon.push({ name:name, value:value });
3798
+ argsSemiColon.push({ name:name, value:value, expand:expand });
3656
3799
 
3657
3800
  name = null;
3658
3801
  expressions = [];
@@ -3712,7 +3855,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3712
3855
 
3713
3856
  parserInput.commentStore.length = 0;
3714
3857
 
3715
- if (parserInput.$re(/^when/)) { // Guard
3858
+ if (parserInput.$str("when")) { // Guard
3716
3859
  cond = expect(parsers.conditions, 'expected condition');
3717
3860
  }
3718
3861
 
@@ -3758,6 +3901,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3758
3901
  alpha: function () {
3759
3902
  var value;
3760
3903
 
3904
+ // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
3761
3905
  if (! parserInput.$re(/^opacity=/i)) { return; }
3762
3906
  value = parserInput.$re(/^\d+/);
3763
3907
  if (!value) {
@@ -3861,7 +4005,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3861
4005
  selector: function (isLess) {
3862
4006
  var index = parserInput.i, elements, extendList, c, e, allExtends, when, condition;
3863
4007
 
3864
- while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$re(/^when/))) || (e = this.element())) {
4008
+ while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str("when"))) || (e = this.element())) {
3865
4009
  if (when) {
3866
4010
  condition = expect(this.conditions, 'expected condition');
3867
4011
  } else if (condition) {
@@ -3984,7 +4128,7 @@ var Parser = function Parser(context, imports, fileInfo) {
3984
4128
  rule: function (tryAnonymous) {
3985
4129
  var name, value, startOfRule = parserInput.i, c = parserInput.currentChar(), important, merge, isVariable;
3986
4130
 
3987
- if (c === '.' || c === '#' || c === '&') { return; }
4131
+ if (c === '.' || c === '#' || c === '&' || c === ':') { return; }
3988
4132
 
3989
4133
  parserInput.save();
3990
4134
 
@@ -4001,7 +4145,7 @@ var Parser = function Parser(context, imports, fileInfo) {
4001
4145
  // a name returned by this.ruleProperty() is always an array of the form:
4002
4146
  // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
4003
4147
  // where each item is a tree.Keyword or tree.Variable
4004
- merge = !isVariable && name.pop().value;
4148
+ merge = !isVariable && name.length > 1 && name.pop().value;
4005
4149
 
4006
4150
  // prefer to try to parse first if its a variable or we are compressing
4007
4151
  // but always fallback on the other one
@@ -4014,7 +4158,7 @@ var Parser = function Parser(context, imports, fileInfo) {
4014
4158
  value = this.anonymousValue();
4015
4159
  if (value) {
4016
4160
  parserInput.forget();
4017
- // anonymous values absorb the end ';' which is reequired for them to work
4161
+ // anonymous values absorb the end ';' which is required for them to work
4018
4162
  return new (tree.Rule)(name, value, false, merge, startOfRule, fileInfo);
4019
4163
  }
4020
4164
  }
@@ -4066,15 +4210,14 @@ var Parser = function Parser(context, imports, fileInfo) {
4066
4210
  if ((path = this.entities.quoted() || this.entities.url())) {
4067
4211
  features = this.mediaFeatures();
4068
4212
 
4069
- if (!parserInput.$(';')) {
4213
+ if (!parserInput.$char(';')) {
4070
4214
  parserInput.i = index;
4071
4215
  error("missing semi-colon or unrecognised media features on import");
4072
4216
  }
4073
4217
  features = features && new(tree.Value)(features);
4074
4218
  return new(tree.Import)(path, features, options, index, fileInfo);
4075
4219
  }
4076
- else
4077
- {
4220
+ else {
4078
4221
  parserInput.i = index;
4079
4222
  error("malformed import statement");
4080
4223
  }
@@ -4174,16 +4317,61 @@ var Parser = function Parser(context, imports, fileInfo) {
4174
4317
  debugInfo = getDebugInfo(parserInput.i);
4175
4318
  }
4176
4319
 
4177
- if (parserInput.$re(/^@media/)) {
4320
+ parserInput.save();
4321
+
4322
+ if (parserInput.$str("@media")) {
4178
4323
  features = this.mediaFeatures();
4179
4324
 
4180
4325
  rules = this.block();
4181
- if (rules) {
4182
- media = new(tree.Media)(rules, features, parserInput.i, fileInfo);
4183
- if (context.dumpLineNumbers) {
4184
- media.debugInfo = debugInfo;
4326
+
4327
+ if (!rules) {
4328
+ parserInput.restore("media definitions require block statements after any features");
4329
+ return;
4330
+ }
4331
+
4332
+ parserInput.forget();
4333
+
4334
+ media = new(tree.Media)(rules, features, parserInput.i, fileInfo);
4335
+ if (context.dumpLineNumbers) {
4336
+ media.debugInfo = debugInfo;
4337
+ }
4338
+
4339
+ return media;
4340
+ }
4341
+
4342
+ parserInput.restore();
4343
+ },
4344
+
4345
+ //
4346
+ // A @plugin directive, used to import compiler extensions dynamically.
4347
+ //
4348
+ // @plugin "lib";
4349
+ //
4350
+ // Depending on our environment, importing is done differently:
4351
+ // In the browser, it's an XHR request, in Node, it would be a
4352
+ // file-system operation. The function used for importing is
4353
+ // stored in `import`, which we pass to the Import constructor.
4354
+ //
4355
+ plugin: function () {
4356
+ var path,
4357
+ index = parserInput.i,
4358
+ dir = parserInput.$re(/^@plugin?\s+/);
4359
+
4360
+ if (dir) {
4361
+ var options = { plugin : true };
4362
+
4363
+ if ((path = this.entities.quoted() || this.entities.url())) {
4364
+
4365
+ if (!parserInput.$char(';')) {
4366
+ parserInput.i = index;
4367
+ error("missing semi-colon on plugin");
4185
4368
  }
4186
- return media;
4369
+
4370
+ return new(tree.Import)(path, null, options, index, fileInfo);
4371
+ }
4372
+ else {
4373
+ parserInput.i = index;
4374
+ error("malformed plugin statement");
4187
4375
  }
4188
4376
  }
4189
4377
  },
@@ -4195,11 +4383,11 @@ var Parser = function Parser(context, imports, fileInfo) {
4195
4383
  //
4196
4384
  directive: function () {
4197
4385
  var index = parserInput.i, name, value, rules, nonVendorSpecificName,
4198
- hasIdentifier, hasExpression, hasUnknown, hasBlock = true;
4386
+ hasIdentifier, hasExpression, hasUnknown, hasBlock = true, isRooted = true;
4199
4387
 
4200
4388
  if (parserInput.currentChar() !== '@') { return; }
4201
4389
 
4202
- value = this['import']() || this.media();
4390
+ value = this['import']() || this.plugin() || this.media();
4203
4391
  if (value) {
4204
4392
  return value;
4205
4393
  }
@@ -4236,6 +4424,7 @@ var Parser = function Parser(context, imports, fileInfo) {
4236
4424
  case "@right-middle":
4237
4425
  case "@right-bottom":
4238
4426
  hasBlock = true;
4427
+ isRooted = true;
4239
4428
  break;
4240
4429
  */
4241
4430
  case "@counter-style":
@@ -4255,9 +4444,12 @@ var Parser = function Parser(context, imports, fileInfo) {
4255
4444
  break;
4256
4445
  case "@host":
4257
4446
  case "@page":
4447
+ hasUnknown = true;
4448
+ break;
4258
4449
  case "@document":
4259
4450
  case "@supports":
4260
4451
  hasUnknown = true;
4452
+ isRooted = false;
4261
4453
  break;
4262
4454
  }
4263
4455
 
@@ -4286,8 +4478,11 @@ var Parser = function Parser(context, imports, fileInfo) {
4286
4478
 
4287
4479
  if (rules || (!hasBlock && value && parserInput.$char(';'))) {
4288
4480
  parserInput.forget();
4289
- return new(tree.Directive)(name, value, rules, index, fileInfo,
4290
- context.dumpLineNumbers ? getDebugInfo(index) : null);
4481
+ return new (tree.Directive)(name, value, rules, index, fileInfo,
4482
+ context.dumpLineNumbers ? getDebugInfo(index) : null,
4483
+ false,
4484
+ isRooted
4485
+ );
4291
4486
  }
4292
4487
 
4293
4488
  parserInput.restore("directive options not recognised");
@@ -4412,11 +4607,33 @@ var Parser = function Parser(context, imports, fileInfo) {
4412
4607
  var entities = this.entities, index = parserInput.i, negate = false,
4413
4608
  a, b, c, op;
4414
4609
 
4415
- if (parserInput.$re(/^not/)) { negate = true; }
4610
+ if (parserInput.$str("not")) { negate = true; }
4416
4611
  expectChar('(');
4417
4612
  a = this.addition() || entities.keyword() || entities.quoted();
4418
4613
  if (a) {
4419
- op = parserInput.$re(/^(?:>=|<=|=<|[<=>])/);
4614
+ if (parserInput.$char('>')) {
4615
+ if (parserInput.$char('=')) {
4616
+ op = ">=";
4617
+ } else {
4618
+ op = '>';
4619
+ }
4620
+ } else
4621
+ if (parserInput.$char('<')) {
4622
+ if (parserInput.$char('=')) {
4623
+ op = "<=";
4624
+ } else {
4625
+ op = '<';
4626
+ }
4627
+ } else
4628
+ if (parserInput.$char('=')) {
4629
+ if (parserInput.$char('>')) {
4630
+ op = "=>";
4631
+ } else if (parserInput.$char('<')) {
4632
+ op = '=<';
4633
+ } else {
4634
+ op = '=';
4635
+ }
4636
+ }
4420
4637
  if (op) {
4421
4638
  b = this.addition() || entities.keyword() || entities.quoted();
4422
4639
  if (b) {
@@ -4428,7 +4645,7 @@ var Parser = function Parser(context, imports, fileInfo) {
4428
4645
  c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
4429
4646
  }
4430
4647
  expectChar(')');
4431
- return parserInput.$re(/^and/) ? new(tree.Condition)('and', c, this.condition()) : c;
4648
+ return parserInput.$str("and") ? new(tree.Condition)('and', c, this.condition()) : c;
4432
4649
  }
4433
4650
  },
4434
4651
 
@@ -4498,6 +4715,13 @@ var Parser = function Parser(context, imports, fileInfo) {
4498
4715
 
4499
4716
  parserInput.save();
4500
4717
 
4718
+ var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/);
4719
+ if (simpleProperty) {
4720
+ name = [new(tree.Keyword)(simpleProperty[1])];
4721
+ parserInput.forget();
4722
+ return name;
4723
+ }
4724
+
4501
4725
  function match(re) {
4502
4726
  var i = parserInput.i,
4503
4727
  chunk = parserInput.$re(re);
@@ -4553,7 +4777,7 @@ Parser.serializeVars = function(vars) {
4553
4777
 
4554
4778
  module.exports = Parser;
4555
4779
 
4556
- },{"../less-error":30,"../tree":59,"../utils":80,"../visitors":84,"./parser-input":35}],37:[function(require,module,exports){
4780
+ },{"../less-error":31,"../tree":61,"../utils":82,"../visitors":86,"./parser-input":36}],38:[function(require,module,exports){
4557
4781
  /**
4558
4782
  * Plugin Manager
4559
4783
  */
@@ -4669,7 +4893,44 @@ PluginManager.prototype.getFileManagers = function() {
4669
4893
  };
4670
4894
  module.exports = PluginManager;
4671
4895
 
4672
- },{}],38:[function(require,module,exports){
4896
+ },{}],39:[function(require,module,exports){
4897
+ var LessError = require('../less-error'),
4898
+ tree = require("../tree");
4899
+
4900
+ var FunctionImporter = module.exports = function FunctionImporter(context, fileInfo) {
4901
+ this.fileInfo = fileInfo;
4902
+ };
4903
+
4904
+ FunctionImporter.prototype.eval = function(contents, callback) {
4905
+ var loaded = {},
4906
+ loader,
4907
+ registry;
4908
+
4909
+ registry = {
4910
+ add: function(name, func) {
4911
+ loaded[name] = func;
4912
+ },
4913
+ addMultiple: function(functions) {
4914
+ Object.keys(functions).forEach(function(name) {
4915
+ loaded[name] = functions[name];
4916
+ });
4917
+ }
4918
+ };
4919
+
4920
+ try {
4921
+ loader = new Function("functions", "tree", "fileInfo", contents);
4922
+ loader(registry, tree, this.fileInfo);
4923
+ } catch(e) {
4924
+ callback(new LessError({
4925
+ message: "Plugin evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" ,
4926
+ filename: this.fileInfo.filename
4927
+ }), null );
4928
+ }
4929
+
4930
+ callback(null, { functions: loaded });
4931
+ };
4932
+
4933
+ },{"../less-error":31,"../tree":61}],40:[function(require,module,exports){
4673
4934
  var PromiseConstructor;
4674
4935
 
4675
4936
  module.exports = function(environment, ParseTree, ImportManager) {
@@ -4712,7 +4973,7 @@ module.exports = function(environment, ParseTree, ImportManager) {
4712
4973
  return render;
4713
4974
  };
4714
4975
 
4715
- },{"promise":undefined}],39:[function(require,module,exports){
4976
+ },{"promise":undefined}],41:[function(require,module,exports){
4716
4977
  module.exports = function (SourceMapOutput, environment) {
4717
4978
 
4718
4979
  var SourceMapBuilder = function (options) {
@@ -4783,7 +5044,7 @@ module.exports = function (SourceMapOutput, environment) {
4783
5044
  return SourceMapBuilder;
4784
5045
  };
4785
5046
 
4786
- },{}],40:[function(require,module,exports){
5047
+ },{}],42:[function(require,module,exports){
4787
5048
  module.exports = function (environment) {
4788
5049
 
4789
5050
  var SourceMapOutput = function (options) {
@@ -4891,8 +5152,7 @@ module.exports = function (environment) {
4891
5152
 
4892
5153
  if (this._outputSourceFiles) {
4893
5154
  for (var filename in this._contentsMap) {
4894
- if (this._contentsMap.hasOwnProperty(filename))
4895
- {
5155
+ if (this._contentsMap.hasOwnProperty(filename)) {
4896
5156
  var source = this._contentsMap[filename];
4897
5157
  if (this._contentsIgnoredCharsMap[filename]) {
4898
5158
  source = source.slice(this._contentsIgnoredCharsMap[filename]);
@@ -4924,7 +5184,7 @@ module.exports = function (environment) {
4924
5184
  return SourceMapOutput;
4925
5185
  };
4926
5186
 
4927
- },{}],41:[function(require,module,exports){
5187
+ },{}],43:[function(require,module,exports){
4928
5188
  var contexts = require("./contexts"),
4929
5189
  visitor = require("./visitors"),
4930
5190
  tree = require("./tree");
@@ -4999,7 +5259,7 @@ module.exports = function(root, options) {
4999
5259
  return evaldRoot;
5000
5260
  };
5001
5261
 
5002
- },{"./contexts":10,"./tree":59,"./visitors":84}],42:[function(require,module,exports){
5262
+ },{"./contexts":10,"./tree":61,"./visitors":86}],44:[function(require,module,exports){
5003
5263
  var Node = require("./node");
5004
5264
 
5005
5265
  var Alpha = function (val) {
@@ -5029,20 +5289,21 @@ Alpha.prototype.genCSS = function (context, output) {
5029
5289
 
5030
5290
  module.exports = Alpha;
5031
5291
 
5032
- },{"./node":67}],43:[function(require,module,exports){
5292
+ },{"./node":69}],45:[function(require,module,exports){
5033
5293
  var Node = require("./node");
5034
5294
 
5035
- var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike) {
5295
+ var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, referenced) {
5036
5296
  this.value = value;
5037
5297
  this.index = index;
5038
5298
  this.mapLines = mapLines;
5039
5299
  this.currentFileInfo = currentFileInfo;
5040
5300
  this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
5301
+ this.isReferenced = referenced || false;
5041
5302
  };
5042
5303
  Anonymous.prototype = new Node();
5043
5304
  Anonymous.prototype.type = "Anonymous";
5044
5305
  Anonymous.prototype.eval = function () {
5045
- return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike);
5306
+ return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike, this.isReferenced);
5046
5307
  };
5047
5308
  Anonymous.prototype.compare = function (other) {
5048
5309
  return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
@@ -5053,9 +5314,16 @@ Anonymous.prototype.isRulesetLike = function() {
5053
5314
  Anonymous.prototype.genCSS = function (context, output) {
5054
5315
  output.add(this.value, this.currentFileInfo, this.index, this.mapLines);
5055
5316
  };
5317
+ Anonymous.prototype.markReferenced = function () {
5318
+ this.isReferenced = true;
5319
+ };
5320
+ Anonymous.prototype.getIsReferenced = function () {
5321
+ return !this.currentFileInfo || !this.currentFileInfo.reference || this.isReferenced;
5322
+ };
5323
+
5056
5324
  module.exports = Anonymous;
5057
5325
 
5058
- },{"./node":67}],44:[function(require,module,exports){
5326
+ },{"./node":69}],46:[function(require,module,exports){
5059
5327
  var Node = require("./node");
5060
5328
 
5061
5329
  var Assignment = function (key, val) {
@@ -5084,7 +5352,7 @@ Assignment.prototype.genCSS = function (context, output) {
5084
5352
  };
5085
5353
  module.exports = Assignment;
5086
5354
 
5087
- },{"./node":67}],45:[function(require,module,exports){
5355
+ },{"./node":69}],47:[function(require,module,exports){
5088
5356
  var Node = require("./node");
5089
5357
 
5090
5358
  var Attribute = function (key, op, value) {
@@ -5113,7 +5381,7 @@ Attribute.prototype.toCSS = function (context) {
5113
5381
  };
5114
5382
  module.exports = Attribute;
5115
5383
 
5116
- },{"./node":67}],46:[function(require,module,exports){
5384
+ },{"./node":69}],48:[function(require,module,exports){
5117
5385
  var Node = require("./node"),
5118
5386
  FunctionCaller = require("../functions/function-caller");
5119
5387
  //
@@ -5177,14 +5445,14 @@ Call.prototype.genCSS = function (context, output) {
5177
5445
  };
5178
5446
  module.exports = Call;
5179
5447
 
5180
- },{"../functions/function-caller":20,"./node":67}],47:[function(require,module,exports){
5448
+ },{"../functions/function-caller":20,"./node":69}],49:[function(require,module,exports){
5181
5449
  var Node = require("./node"),
5182
5450
  colors = require("../data/colors");
5183
5451
 
5184
5452
  //
5185
5453
  // RGB Colors - #ff0014, #eee
5186
5454
  //
5187
- var Color = function (rgb, a) {
5455
+ var Color = function (rgb, a, originalForm) {
5188
5456
  //
5189
5457
  // The end goal here, is to parse the arguments
5190
5458
  // into an integer triplet, such as `128, 255, 0`
@@ -5203,6 +5471,9 @@ var Color = function (rgb, a) {
5203
5471
  });
5204
5472
  }
5205
5473
  this.alpha = typeof a === 'number' ? a : 1;
5474
+ if (typeof originalForm !== 'undefined') {
5475
+ this.value = originalForm;
5476
+ }
5206
5477
  };
5207
5478
 
5208
5479
  Color.prototype = new Node();
@@ -5365,7 +5636,7 @@ Color.fromKeyword = function(keyword) {
5365
5636
  };
5366
5637
  module.exports = Color;
5367
5638
 
5368
- },{"../data/colors":11,"./node":67}],48:[function(require,module,exports){
5639
+ },{"../data/colors":11,"./node":69}],50:[function(require,module,exports){
5369
5640
  var Node = require("./node");
5370
5641
 
5371
5642
  var Combinator = function (value) {
@@ -5390,7 +5661,7 @@ Combinator.prototype.genCSS = function (context, output) {
5390
5661
  };
5391
5662
  module.exports = Combinator;
5392
5663
 
5393
- },{"./node":67}],49:[function(require,module,exports){
5664
+ },{"./node":69}],51:[function(require,module,exports){
5394
5665
  var Node = require("./node"),
5395
5666
  getDebugInfo = require("./debug-info");
5396
5667
 
@@ -5415,12 +5686,9 @@ Comment.prototype.isSilent = function(context) {
5415
5686
  Comment.prototype.markReferenced = function () {
5416
5687
  this.isReferenced = true;
5417
5688
  };
5418
- Comment.prototype.isRulesetLike = function(root) {
5419
- return Boolean(root);
5420
- };
5421
5689
  module.exports = Comment;
5422
5690
 
5423
- },{"./debug-info":51,"./node":67}],50:[function(require,module,exports){
5691
+ },{"./debug-info":53,"./node":69}],52:[function(require,module,exports){
5424
5692
  var Node = require("./node");
5425
5693
 
5426
5694
  var Condition = function (op, l, r, i, negate) {
@@ -5459,7 +5727,7 @@ Condition.prototype.eval = function (context) {
5459
5727
  };
5460
5728
  module.exports = Condition;
5461
5729
 
5462
- },{"./node":67}],51:[function(require,module,exports){
5730
+ },{"./node":69}],53:[function(require,module,exports){
5463
5731
  var debugInfo = function(context, ctx, lineSeparator) {
5464
5732
  var result = "";
5465
5733
  if (context.dumpLineNumbers && !context.compress) {
@@ -5499,7 +5767,7 @@ debugInfo.asMediaQuery = function(ctx) {
5499
5767
 
5500
5768
  module.exports = debugInfo;
5501
5769
 
5502
- },{}],52:[function(require,module,exports){
5770
+ },{}],54:[function(require,module,exports){
5503
5771
  var Node = require("./node"),
5504
5772
  contexts = require("../contexts");
5505
5773
 
@@ -5522,7 +5790,7 @@ DetachedRuleset.prototype.callEval = function (context) {
5522
5790
  };
5523
5791
  module.exports = DetachedRuleset;
5524
5792
 
5525
- },{"../contexts":10,"./node":67}],53:[function(require,module,exports){
5793
+ },{"../contexts":10,"./node":69}],55:[function(require,module,exports){
5526
5794
  var Node = require("./node"),
5527
5795
  unitConversions = require("../data/unit-conversions"),
5528
5796
  Unit = require("./unit"),
@@ -5588,8 +5856,10 @@ Dimension.prototype.operate = function (context, op, other) {
5588
5856
 
5589
5857
  if (op === '+' || op === '-') {
5590
5858
  if (unit.numerator.length === 0 && unit.denominator.length === 0) {
5591
- unit.numerator = other.unit.numerator.slice(0);
5592
- unit.denominator = other.unit.denominator.slice(0);
5859
+ unit = other.unit.clone();
5860
+ if (this.unit.backupUnit) {
5861
+ unit.backupUnit = this.unit.backupUnit;
5862
+ }
5593
5863
  } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) {
5594
5864
  // do nothing
5595
5865
  } else {
@@ -5650,7 +5920,7 @@ Dimension.prototype.convertTo = function (conversions) {
5650
5920
  conversions = derivedConversions;
5651
5921
  }
5652
5922
  applyUnit = function (atomicUnit, denominator) {
5653
- /*jshint loopfunc:true */
5923
+ /* jshint loopfunc:true */
5654
5924
  if (group.hasOwnProperty(atomicUnit)) {
5655
5925
  if (denominator) {
5656
5926
  value = value / (group[atomicUnit] / group[targetUnit]);
@@ -5679,21 +5949,32 @@ Dimension.prototype.convertTo = function (conversions) {
5679
5949
  };
5680
5950
  module.exports = Dimension;
5681
5951
 
5682
- },{"../data/unit-conversions":13,"./color":47,"./node":67,"./unit":76}],54:[function(require,module,exports){
5952
+ },{"../data/unit-conversions":13,"./color":49,"./node":69,"./unit":78}],56:[function(require,module,exports){
5683
5953
  var Node = require("./node"),
5954
+ Selector = require("./selector"),
5684
5955
  Ruleset = require("./ruleset");
5685
5956
 
5686
- var Directive = function (name, value, rules, index, currentFileInfo, debugInfo, isReferenced) {
5957
+ var Directive = function (name, value, rules, index, currentFileInfo, debugInfo, isReferenced, isRooted) {
5958
+ var i;
5959
+
5687
5960
  this.name = name;
5688
5961
  this.value = value;
5689
5962
  if (rules) {
5690
- this.rules = rules;
5691
- this.rules.allowImports = true;
5963
+ if (Array.isArray(rules)) {
5964
+ this.rules = rules;
5965
+ } else {
5966
+ this.rules = [rules];
5967
+ this.rules[0].selectors = (new Selector([], null, null, this.index, currentFileInfo)).createEmptySelectors();
5968
+ }
5969
+ for (i = 0; i < this.rules.length; i++) {
5970
+ this.rules[i].allowImports = true;
5971
+ }
5692
5972
  }
5693
5973
  this.index = index;
5694
5974
  this.currentFileInfo = currentFileInfo;
5695
5975
  this.debugInfo = debugInfo;
5696
5976
  this.isReferenced = isReferenced;
5977
+ this.isRooted = isRooted || false;
5697
5978
  };
5698
5979
 
5699
5980
  Directive.prototype = new Node();
@@ -5701,7 +5982,7 @@ Directive.prototype.type = "Directive";
5701
5982
  Directive.prototype.accept = function (visitor) {
5702
5983
  var value = this.value, rules = this.rules;
5703
5984
  if (rules) {
5704
- this.rules = visitor.visit(rules);
5985
+ this.rules = visitor.visitArray(rules);
5705
5986
  }
5706
5987
  if (value) {
5707
5988
  this.value = visitor.visit(value);
@@ -5721,46 +6002,60 @@ Directive.prototype.genCSS = function (context, output) {
5721
6002
  value.genCSS(context, output);
5722
6003
  }
5723
6004
  if (rules) {
5724
- if (rules.type === "Ruleset") {
5725
- rules = [rules];
5726
- }
5727
6005
  this.outputRuleset(context, output, rules);
5728
6006
  } else {
5729
6007
  output.add(';');
5730
6008
  }
5731
6009
  };
5732
6010
  Directive.prototype.eval = function (context) {
5733
- var value = this.value, rules = this.rules;
6011
+ var mediaPathBackup, mediaBlocksBackup, value = this.value, rules = this.rules;
6012
+
6013
+ //media stored inside other directive should not bubble over it
6014
+ //backpup media bubbling information
6015
+ mediaPathBackup = context.mediaPath;
6016
+ mediaBlocksBackup = context.mediaBlocks;
6017
+ //deleted media bubbling information
6018
+ context.mediaPath = [];
6019
+ context.mediaBlocks = [];
6020
+
5734
6021
  if (value) {
5735
6022
  value = value.eval(context);
5736
6023
  }
5737
6024
  if (rules) {
5738
- rules = rules.eval(context);
5739
- rules.root = true;
6025
+ // assuming that there is only one rule at this point - that is how parser constructs the rule
6026
+ rules = [rules[0].eval(context)];
6027
+ rules[0].root = true;
5740
6028
  }
6029
+ //restore media bubbling information
6030
+ context.mediaPath = mediaPathBackup;
6031
+ context.mediaBlocks = mediaBlocksBackup;
6032
+
5741
6033
  return new Directive(this.name, value, rules,
5742
- this.index, this.currentFileInfo, this.debugInfo, this.isReferenced);
6034
+ this.index, this.currentFileInfo, this.debugInfo, this.isReferenced, this.isRooted);
5743
6035
  };
5744
6036
  Directive.prototype.variable = function (name) {
5745
6037
  if (this.rules) {
5746
- return Ruleset.prototype.variable.call(this.rules, name);
6038
+ // assuming that there is only one rule at this point - that is how parser constructs the rule
6039
+ return Ruleset.prototype.variable.call(this.rules[0], name);
5747
6040
  }
5748
6041
  };
5749
6042
  Directive.prototype.find = function () {
5750
6043
  if (this.rules) {
5751
- return Ruleset.prototype.find.apply(this.rules, arguments);
6044
+ // assuming that there is only one rule at this point - that is how parser constructs the rule
6045
+ return Ruleset.prototype.find.apply(this.rules[0], arguments);
5752
6046
  }
5753
6047
  };
5754
6048
  Directive.prototype.rulesets = function () {
5755
6049
  if (this.rules) {
5756
- return Ruleset.prototype.rulesets.apply(this.rules);
6050
+ // assuming that there is only one rule at this point - that is how parser constructs the rule
6051
+ return Ruleset.prototype.rulesets.apply(this.rules[0]);
5757
6052
  }
5758
6053
  };
5759
6054
  Directive.prototype.markReferenced = function () {
5760
6055
  var i, rules;
5761
6056
  this.isReferenced = true;
5762
6057
  if (this.rules) {
5763
- rules = this.rules.rules;
6058
+ rules = this.rules;
5764
6059
  for (i = 0; i < rules.length; i++) {
5765
6060
  if (rules[i].markReferenced) {
5766
6061
  rules[i].markReferenced();
@@ -5804,7 +6099,7 @@ Directive.prototype.outputRuleset = function (context, output, rules) {
5804
6099
  };
5805
6100
  module.exports = Directive;
5806
6101
 
5807
- },{"./node":67,"./ruleset":73}],55:[function(require,module,exports){
6102
+ },{"./node":69,"./ruleset":75,"./selector":76}],57:[function(require,module,exports){
5808
6103
  var Node = require("./node"),
5809
6104
  Paren = require("./paren"),
5810
6105
  Combinator = require("./combinator");
@@ -5859,7 +6154,7 @@ Element.prototype.toCSS = function (context) {
5859
6154
  };
5860
6155
  module.exports = Element;
5861
6156
 
5862
- },{"./combinator":48,"./node":67,"./paren":69}],56:[function(require,module,exports){
6157
+ },{"./combinator":50,"./node":69,"./paren":71}],58:[function(require,module,exports){
5863
6158
  var Node = require("./node"),
5864
6159
  Paren = require("./paren"),
5865
6160
  Comment = require("./comment");
@@ -5915,9 +6210,14 @@ Expression.prototype.throwAwayComments = function () {
5915
6210
  return !(v instanceof Comment);
5916
6211
  });
5917
6212
  };
6213
+ Expression.prototype.markReferenced = function () {
6214
+ this.value.forEach(function (value) {
6215
+ if (value.markReferenced) { value.markReferenced(); }
6216
+ });
6217
+ };
5918
6218
  module.exports = Expression;
5919
6219
 
5920
- },{"./comment":49,"./node":67,"./paren":69}],57:[function(require,module,exports){
6220
+ },{"./comment":51,"./node":69,"./paren":71}],59:[function(require,module,exports){
5921
6221
  var Node = require("./node");
5922
6222
 
5923
6223
  var Extend = function Extend(selector, option, index) {
@@ -5970,7 +6270,7 @@ Extend.prototype.findSelfSelectors = function (selectors) {
5970
6270
  };
5971
6271
  module.exports = Extend;
5972
6272
 
5973
- },{"./node":67}],58:[function(require,module,exports){
6273
+ },{"./node":69}],60:[function(require,module,exports){
5974
6274
  var Node = require("./node"),
5975
6275
  Media = require("./media"),
5976
6276
  URL = require("./url"),
@@ -6023,12 +6323,12 @@ Import.prototype.accept = function (visitor) {
6023
6323
  this.features = visitor.visit(this.features);
6024
6324
  }
6025
6325
  this.path = visitor.visit(this.path);
6026
- if (!this.options.inline && this.root) {
6326
+ if (!this.options.plugin && !this.options.inline && this.root) {
6027
6327
  this.root = visitor.visit(this.root);
6028
6328
  }
6029
6329
  };
6030
6330
  Import.prototype.genCSS = function (context, output) {
6031
- if (this.css) {
6331
+ if (this.css && this.path.currentFileInfo.reference === undefined) {
6032
6332
  output.add("@import ", this.currentFileInfo, this.index);
6033
6333
  this.path.genCSS(context, output);
6034
6334
  if (this.features) {
@@ -6039,12 +6339,8 @@ Import.prototype.genCSS = function (context, output) {
6039
6339
  }
6040
6340
  };
6041
6341
  Import.prototype.getPath = function () {
6042
- if (this.path instanceof Quoted) {
6043
- return this.path.value;
6044
- } else if (this.path instanceof URL) {
6045
- return this.path.value.value;
6046
- }
6047
- return null;
6342
+ return (this.path instanceof URL) ?
6343
+ this.path.value.value : this.path.value;
6048
6344
  };
6049
6345
  Import.prototype.isVariableImport = function () {
6050
6346
  var path = this.path;
@@ -6059,9 +6355,11 @@ Import.prototype.isVariableImport = function () {
6059
6355
  };
6060
6356
  Import.prototype.evalForImport = function (context) {
6061
6357
  var path = this.path;
6358
+
6062
6359
  if (path instanceof URL) {
6063
6360
  path = path.value;
6064
6361
  }
6362
+
6065
6363
  return new Import(path.eval(context), this.features, this.options, this.index, this.currentFileInfo);
6066
6364
  };
6067
6365
  Import.prototype.evalPath = function (context) {
@@ -6082,7 +6380,16 @@ Import.prototype.evalPath = function (context) {
6082
6380
  return path;
6083
6381
  };
6084
6382
  Import.prototype.eval = function (context) {
6085
- var ruleset, features = this.features && this.features.eval(context);
6383
+ var ruleset, registry,
6384
+ features = this.features && this.features.eval(context);
6385
+
6386
+ if (this.options.plugin) {
6387
+ registry = context.frames[0] && context.frames[0].functionRegistry;
6388
+ if ( registry && this.root && this.root.functions ) {
6389
+ registry.addMultiple( this.root.functions );
6390
+ }
6391
+ return [];
6392
+ }
6086
6393
 
6087
6394
  if (this.skip) {
6088
6395
  if (typeof this.skip === "function") {
@@ -6094,7 +6401,12 @@ Import.prototype.eval = function (context) {
6094
6401
  }
6095
6402
 
6096
6403
  if (this.options.inline) {
6097
- var contents = new Anonymous(this.root, 0, {filename: this.importedFilename}, true, true);
6404
+ var contents = new Anonymous(this.root, 0,
6405
+ {
6406
+ filename: this.importedFilename,
6407
+ reference: this.path.currentFileInfo && this.path.currentFileInfo.reference
6408
+ }, true, true, false);
6409
+
6098
6410
  return this.features ? new Media([contents], this.features.value) : [contents];
6099
6411
  } else if (this.css) {
6100
6412
  var newImport = new Import(this.evalPath(context), features, this.options, this.index);
@@ -6112,7 +6424,7 @@ Import.prototype.eval = function (context) {
6112
6424
  };
6113
6425
  module.exports = Import;
6114
6426
 
6115
- },{"./anonymous":43,"./media":63,"./node":67,"./quoted":70,"./ruleset":73,"./url":77}],59:[function(require,module,exports){
6427
+ },{"./anonymous":45,"./media":65,"./node":69,"./quoted":72,"./ruleset":75,"./url":79}],61:[function(require,module,exports){
6116
6428
  var tree = {};
6117
6429
 
6118
6430
  tree.Node = require('./node');
@@ -6155,7 +6467,7 @@ tree.RulesetCall = require('./ruleset-call');
6155
6467
 
6156
6468
  module.exports = tree;
6157
6469
 
6158
- },{"./alpha":42,"./anonymous":43,"./assignment":44,"./attribute":45,"./call":46,"./color":47,"./combinator":48,"./comment":49,"./condition":50,"./detached-ruleset":52,"./dimension":53,"./directive":54,"./element":55,"./expression":56,"./extend":57,"./import":58,"./javascript":60,"./keyword":62,"./media":63,"./mixin-call":64,"./mixin-definition":65,"./negative":66,"./node":67,"./operation":68,"./paren":69,"./quoted":70,"./rule":71,"./ruleset":73,"./ruleset-call":72,"./selector":74,"./unicode-descriptor":75,"./unit":76,"./url":77,"./value":78,"./variable":79}],60:[function(require,module,exports){
6470
+ },{"./alpha":44,"./anonymous":45,"./assignment":46,"./attribute":47,"./call":48,"./color":49,"./combinator":50,"./comment":51,"./condition":52,"./detached-ruleset":54,"./dimension":55,"./directive":56,"./element":57,"./expression":58,"./extend":59,"./import":60,"./javascript":62,"./keyword":64,"./media":65,"./mixin-call":66,"./mixin-definition":67,"./negative":68,"./node":69,"./operation":70,"./paren":71,"./quoted":72,"./rule":73,"./ruleset":75,"./ruleset-call":74,"./selector":76,"./unicode-descriptor":77,"./unit":78,"./url":79,"./value":80,"./variable":81}],62:[function(require,module,exports){
6159
6471
  var JsEvalNode = require("./js-eval-node"),
6160
6472
  Dimension = require("./dimension"),
6161
6473
  Quoted = require("./quoted"),
@@ -6185,7 +6497,7 @@ JavaScript.prototype.eval = function(context) {
6185
6497
 
6186
6498
  module.exports = JavaScript;
6187
6499
 
6188
- },{"./anonymous":43,"./dimension":53,"./js-eval-node":61,"./quoted":70}],61:[function(require,module,exports){
6500
+ },{"./anonymous":45,"./dimension":55,"./js-eval-node":63,"./quoted":72}],63:[function(require,module,exports){
6189
6501
  var Node = require("./node"),
6190
6502
  Variable = require("./variable");
6191
6503
 
@@ -6248,7 +6560,7 @@ JsEvalNode.prototype.jsify = function (obj) {
6248
6560
 
6249
6561
  module.exports = JsEvalNode;
6250
6562
 
6251
- },{"./node":67,"./variable":79}],62:[function(require,module,exports){
6563
+ },{"./node":69,"./variable":81}],64:[function(require,module,exports){
6252
6564
  var Node = require("./node");
6253
6565
 
6254
6566
  var Keyword = function (value) { this.value = value; };
@@ -6264,10 +6576,9 @@ Keyword.False = new Keyword('false');
6264
6576
 
6265
6577
  module.exports = Keyword;
6266
6578
 
6267
- },{"./node":67}],63:[function(require,module,exports){
6579
+ },{"./node":69}],65:[function(require,module,exports){
6268
6580
  var Ruleset = require("./ruleset"),
6269
6581
  Value = require("./value"),
6270
- Element = require("./element"),
6271
6582
  Selector = require("./selector"),
6272
6583
  Anonymous = require("./anonymous"),
6273
6584
  Expression = require("./expression"),
@@ -6277,7 +6588,7 @@ var Media = function (value, features, index, currentFileInfo) {
6277
6588
  this.index = index;
6278
6589
  this.currentFileInfo = currentFileInfo;
6279
6590
 
6280
- var selectors = this.emptySelectors();
6591
+ var selectors = (new Selector([], null, null, this.index, this.currentFileInfo)).createEmptySelectors();
6281
6592
 
6282
6593
  this.features = new Value(features);
6283
6594
  this.rules = [new Ruleset(selectors, value)];
@@ -6327,6 +6638,7 @@ Media.prototype.eval = function (context) {
6327
6638
  context.mediaPath.push(media);
6328
6639
  context.mediaBlocks.push(media);
6329
6640
 
6641
+ this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();
6330
6642
  context.frames.unshift(this.rules[0]);
6331
6643
  media.rules = [this.rules[0].eval(context)];
6332
6644
  context.frames.shift();
@@ -6336,32 +6648,12 @@ Media.prototype.eval = function (context) {
6336
6648
  return context.mediaPath.length === 0 ? media.evalTop(context) :
6337
6649
  media.evalNested(context);
6338
6650
  };
6339
- //TODO merge with directive
6340
- Media.prototype.variable = function (name) { return Ruleset.prototype.variable.call(this.rules[0], name); };
6341
- Media.prototype.find = function () { return Ruleset.prototype.find.apply(this.rules[0], arguments); };
6342
- Media.prototype.rulesets = function () { return Ruleset.prototype.rulesets.apply(this.rules[0]); };
6343
- Media.prototype.emptySelectors = function() {
6344
- var el = new Element('', '&', this.index, this.currentFileInfo),
6345
- sels = [new Selector([el], null, null, this.index, this.currentFileInfo)];
6346
- sels[0].mediaEmpty = true;
6347
- return sels;
6348
- };
6349
- Media.prototype.markReferenced = function () {
6350
- var i, rules = this.rules[0].rules;
6351
- this.rules[0].markReferenced();
6352
- this.isReferenced = true;
6353
- for (i = 0; i < rules.length; i++) {
6354
- if (rules[i].markReferenced) {
6355
- rules[i].markReferenced();
6356
- }
6357
- }
6358
- };
6359
6651
  Media.prototype.evalTop = function (context) {
6360
6652
  var result = this;
6361
6653
 
6362
6654
  // Render all dependent Media blocks.
6363
6655
  if (context.mediaBlocks.length > 1) {
6364
- var selectors = this.emptySelectors();
6656
+ var selectors = (new Selector([], null, null, this.index, this.currentFileInfo)).createEmptySelectors();
6365
6657
  result = new Ruleset(selectors, context.mediaBlocks);
6366
6658
  result.multiMedia = true;
6367
6659
  }
@@ -6428,7 +6720,7 @@ Media.prototype.bubbleSelectors = function (selectors) {
6428
6720
  };
6429
6721
  module.exports = Media;
6430
6722
 
6431
- },{"./anonymous":43,"./directive":54,"./element":55,"./expression":56,"./ruleset":73,"./selector":74,"./value":78}],64:[function(require,module,exports){
6723
+ },{"./anonymous":45,"./directive":56,"./expression":58,"./ruleset":75,"./selector":76,"./value":80}],66:[function(require,module,exports){
6432
6724
  var Node = require("./node"),
6433
6725
  Selector = require("./selector"),
6434
6726
  MixinDefinition = require("./mixin-definition"),
@@ -6436,7 +6728,7 @@ var Node = require("./node"),
6436
6728
 
6437
6729
  var MixinCall = function (elements, args, index, currentFileInfo, important) {
6438
6730
  this.selector = new Selector(elements);
6439
- this.arguments = (args && args.length) ? args : null;
6731
+ this.arguments = args || [];
6440
6732
  this.index = index;
6441
6733
  this.currentFileInfo = currentFileInfo;
6442
6734
  this.important = important;
@@ -6447,17 +6739,18 @@ MixinCall.prototype.accept = function (visitor) {
6447
6739
  if (this.selector) {
6448
6740
  this.selector = visitor.visit(this.selector);
6449
6741
  }
6450
- if (this.arguments) {
6742
+ if (this.arguments.length) {
6451
6743
  this.arguments = visitor.visitArray(this.arguments);
6452
6744
  }
6453
6745
  };
6454
6746
  MixinCall.prototype.eval = function (context) {
6455
- var mixins, mixin, mixinPath, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule,
6747
+ var mixins, mixin, mixinPath, args = [], arg, argValue,
6748
+ rules = [], rule, match = false, i, m, f, isRecursive, isOneFound,
6456
6749
  candidates = [], candidate, conditionResult = [], defaultResult, defFalseEitherCase = -1,
6457
6750
  defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset, noArgumentsFilter;
6458
6751
 
6459
6752
  function calcDefGroup(mixin, mixinPath) {
6460
- var p, namespace;
6753
+ var f, p, namespace;
6461
6754
 
6462
6755
  for (f = 0; f < 2; f++) {
6463
6756
  conditionResult[f] = true;
@@ -6483,9 +6776,18 @@ MixinCall.prototype.eval = function (context) {
6483
6776
  return defFalseEitherCase;
6484
6777
  }
6485
6778
 
6486
- args = this.arguments && this.arguments.map(function (a) {
6487
- return { name: a.name, value: a.value.eval(context) };
6488
- });
6779
+ for (i = 0; i < this.arguments.length; i++) {
6780
+ arg = this.arguments[i];
6781
+ argValue = arg.value.eval(context);
6782
+ if (arg.expand && Array.isArray(argValue.value)) {
6783
+ argValue = argValue.value;
6784
+ for (m = 0; m < argValue.length; m++) {
6785
+ args.push({value: argValue[m]});
6786
+ }
6787
+ } else {
6788
+ args.push({name: arg.name, value: argValue});
6789
+ }
6790
+ }
6489
6791
 
6490
6792
  noArgumentsFilter = function(rule) {return rule.matchArgs(null, context);};
6491
6793
 
@@ -6599,7 +6901,7 @@ MixinCall.prototype.format = function (args) {
6599
6901
  };
6600
6902
  module.exports = MixinCall;
6601
6903
 
6602
- },{"../functions/default":19,"./mixin-definition":65,"./node":67,"./selector":74}],65:[function(require,module,exports){
6904
+ },{"../functions/default":19,"./mixin-definition":67,"./node":69,"./selector":76}],67:[function(require,module,exports){
6603
6905
  var Selector = require("./selector"),
6604
6906
  Element = require("./element"),
6605
6907
  Ruleset = require("./ruleset"),
@@ -6616,14 +6918,17 @@ var Definition = function (name, params, rules, condition, variadic, frames) {
6616
6918
  this.arity = params.length;
6617
6919
  this.rules = rules;
6618
6920
  this._lookups = {};
6921
+ var optionalParameters = [];
6619
6922
  this.required = params.reduce(function (count, p) {
6620
6923
  if (!p.name || (p.name && !p.value)) {
6621
6924
  return count + 1;
6622
6925
  }
6623
6926
  else {
6927
+ optionalParameters.push(p.name);
6624
6928
  return count;
6625
6929
  }
6626
6930
  }, 0);
6931
+ this.optionalParameters = optionalParameters;
6627
6932
  this.frames = frames;
6628
6933
  };
6629
6934
  Definition.prototype = new Ruleset();
@@ -6645,6 +6950,9 @@ Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArgume
6645
6950
  params = this.params.slice(0),
6646
6951
  i, j, val, name, isNamedFound, argIndex, argsLength = 0;
6647
6952
 
6953
+ if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {
6954
+ frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();
6955
+ }
6648
6956
  mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));
6649
6957
 
6650
6958
  if (args) {
@@ -6751,29 +7059,37 @@ Definition.prototype.matchCondition = function (args, context) {
6751
7059
  new contexts.Eval(context,
6752
7060
  [this.evalParams(context, /* the parameter variables*/
6753
7061
  new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]
6754
- .concat(this.frames) // the parent namespace/mixin frames
7062
+ .concat(this.frames || []) // the parent namespace/mixin frames
6755
7063
  .concat(context.frames)))) { // the current environment frames
6756
7064
  return false;
6757
7065
  }
6758
7066
  return true;
6759
7067
  };
6760
7068
  Definition.prototype.matchArgs = function (args, context) {
6761
- var argsLength = (args && args.length) || 0, len;
7069
+ var allArgsCnt = (args && args.length) || 0, len, optionalParameters = this.optionalParameters;
7070
+ var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) {
7071
+ if (optionalParameters.indexOf(p.name) < 0) {
7072
+ return count + 1;
7073
+ } else {
7074
+ return count;
7075
+ }
7076
+ }, 0);
6762
7077
 
6763
7078
  if (! this.variadic) {
6764
- if (argsLength < this.required) {
7079
+ if (requiredArgsCnt < this.required) {
6765
7080
  return false;
6766
7081
  }
6767
- if (argsLength > this.params.length) {
7082
+ if (allArgsCnt > this.params.length) {
6768
7083
  return false;
6769
7084
  }
6770
7085
  } else {
6771
- if (argsLength < (this.required - 1)) {
7086
+ if (requiredArgsCnt < (this.required - 1)) {
6772
7087
  return false;
6773
7088
  }
6774
7089
  }
6775
7090
 
6776
- len = Math.min(argsLength, this.arity);
7091
+ // check patterns
7092
+ len = Math.min(requiredArgsCnt, this.arity);
6777
7093
 
6778
7094
  for (var i = 0; i < len; i++) {
6779
7095
  if (!this.params[i].name && !this.params[i].variadic) {
@@ -6786,7 +7102,7 @@ Definition.prototype.matchArgs = function (args, context) {
6786
7102
  };
6787
7103
  module.exports = Definition;
6788
7104
 
6789
- },{"../contexts":10,"./element":55,"./expression":56,"./rule":71,"./ruleset":73,"./selector":74}],66:[function(require,module,exports){
7105
+ },{"../contexts":10,"./element":57,"./expression":58,"./rule":73,"./ruleset":75,"./selector":76}],68:[function(require,module,exports){
6790
7106
  var Node = require("./node"),
6791
7107
  Operation = require("./operation"),
6792
7108
  Dimension = require("./dimension");
@@ -6808,7 +7124,7 @@ Negative.prototype.eval = function (context) {
6808
7124
  };
6809
7125
  module.exports = Negative;
6810
7126
 
6811
- },{"./dimension":53,"./node":67,"./operation":68}],67:[function(require,module,exports){
7127
+ },{"./dimension":55,"./node":69,"./operation":70}],69:[function(require,module,exports){
6812
7128
  var Node = function() {
6813
7129
  };
6814
7130
  Node.prototype.toCSS = function (context) {
@@ -6884,7 +7200,7 @@ Node.numericCompare = function (a, b) {
6884
7200
  };
6885
7201
  module.exports = Node;
6886
7202
 
6887
- },{}],68:[function(require,module,exports){
7203
+ },{}],70:[function(require,module,exports){
6888
7204
  var Node = require("./node"),
6889
7205
  Color = require("./color"),
6890
7206
  Dimension = require("./dimension");
@@ -6934,7 +7250,7 @@ Operation.prototype.genCSS = function (context, output) {
6934
7250
 
6935
7251
  module.exports = Operation;
6936
7252
 
6937
- },{"./color":47,"./dimension":53,"./node":67}],69:[function(require,module,exports){
7253
+ },{"./color":49,"./dimension":55,"./node":69}],71:[function(require,module,exports){
6938
7254
  var Node = require("./node");
6939
7255
 
6940
7256
  var Paren = function (node) {
@@ -6952,7 +7268,7 @@ Paren.prototype.eval = function (context) {
6952
7268
  };
6953
7269
  module.exports = Paren;
6954
7270
 
6955
- },{"./node":67}],70:[function(require,module,exports){
7271
+ },{"./node":69}],72:[function(require,module,exports){
6956
7272
  var Node = require("./node"),
6957
7273
  JsEvalNode = require("./js-eval-node"),
6958
7274
  Variable = require("./variable");
@@ -7009,7 +7325,7 @@ Quoted.prototype.compare = function (other) {
7009
7325
  };
7010
7326
  module.exports = Quoted;
7011
7327
 
7012
- },{"./js-eval-node":61,"./node":67,"./variable":79}],71:[function(require,module,exports){
7328
+ },{"./js-eval-node":63,"./node":69,"./variable":81}],73:[function(require,module,exports){
7013
7329
  var Node = require("./node"),
7014
7330
  Value = require("./value"),
7015
7331
  Keyword = require("./keyword");
@@ -7104,9 +7420,26 @@ Rule.prototype.makeImportant = function () {
7104
7420
  this.index, this.currentFileInfo, this.inline);
7105
7421
  };
7106
7422
 
7107
- module.exports = Rule;
7423
+ // Recursive marking for rules
7424
+ var mark = function(value) {
7425
+ if (!Array.isArray(value)) {
7426
+ if (value.markReferenced) {
7427
+ value.markReferenced();
7428
+ }
7429
+ } else {
7430
+ value.forEach(function (ar) {
7431
+ mark(ar);
7432
+ });
7433
+ }
7434
+ };
7435
+ Rule.prototype.markReferenced = function () {
7436
+ if (this.value) {
7437
+ mark(this.value);
7438
+ }
7439
+ };
7108
7440
 
7109
- },{"./keyword":62,"./node":67,"./value":78}],72:[function(require,module,exports){
7441
+ module.exports = Rule;
7442
+ },{"./keyword":64,"./node":69,"./value":80}],74:[function(require,module,exports){
7110
7443
  var Node = require("./node"),
7111
7444
  Variable = require("./variable");
7112
7445
 
@@ -7121,13 +7454,14 @@ RulesetCall.prototype.eval = function (context) {
7121
7454
  };
7122
7455
  module.exports = RulesetCall;
7123
7456
 
7124
- },{"./node":67,"./variable":79}],73:[function(require,module,exports){
7457
+ },{"./node":69,"./variable":81}],75:[function(require,module,exports){
7125
7458
  var Node = require("./node"),
7126
7459
  Rule = require("./rule"),
7127
7460
  Selector = require("./selector"),
7128
7461
  Element = require("./element"),
7129
7462
  Paren = require("./paren"),
7130
7463
  contexts = require("../contexts"),
7464
+ globalFunctionRegistry = require("../functions/function-registry"),
7131
7465
  defaultFunc = require("../functions/default"),
7132
7466
  getDebugInfo = require("./debug-info");
7133
7467
 
@@ -7190,6 +7524,19 @@ Ruleset.prototype.eval = function (context) {
7190
7524
  rules.length = 0;
7191
7525
  }
7192
7526
 
7527
+ // inherit a function registry from the frames stack when possible;
7528
+ // otherwise from the global registry
7529
+ ruleset.functionRegistry = (function (frames) {
7530
+ var i = 0,
7531
+ n = frames.length,
7532
+ found;
7533
+ for ( ; i !== n ; ++i ) {
7534
+ found = frames[ i ].functionRegistry;
7535
+ if ( found ) { return found; }
7536
+ }
7537
+ return globalFunctionRegistry;
7538
+ }(context.frames)).inherit();
7539
+
7193
7540
  // push the current ruleset to the frames stack
7194
7541
  var ctxFrames = context.frames;
7195
7542
  ctxFrames.unshift(ruleset);
@@ -7365,7 +7712,7 @@ Ruleset.prototype.variable = function (name) {
7365
7712
  return this.variables()[name];
7366
7713
  };
7367
7714
  Ruleset.prototype.rulesets = function () {
7368
- if (!this.rules) { return null; }
7715
+ if (!this.rules) { return []; }
7369
7716
 
7370
7717
  var filtRules = [], rules = this.rules, cnt = rules.length,
7371
7718
  i, rule;
@@ -7422,8 +7769,6 @@ Ruleset.prototype.genCSS = function (context, output) {
7422
7769
  var i, j,
7423
7770
  charsetRuleNodes = [],
7424
7771
  ruleNodes = [],
7425
- rulesetNodes = [],
7426
- rulesetNodeCnt,
7427
7772
  debugInfo, // Line number debugging
7428
7773
  rule,
7429
7774
  path;
@@ -7438,31 +7783,38 @@ Ruleset.prototype.genCSS = function (context, output) {
7438
7783
  tabSetStr = context.compress ? '' : Array(context.tabLevel).join(" "),
7439
7784
  sep;
7440
7785
 
7441
- function isRulesetLikeNode(rule, root) {
7786
+ function isRulesetLikeNode(rule) {
7442
7787
  // if it has nested rules, then it should be treated like a ruleset
7443
7788
  // medias and comments do not have nested rules, but should be treated like rulesets anyway
7444
7789
  // some directives and anonymous nodes are ruleset like, others are not
7445
7790
  if (typeof rule.isRulesetLike === "boolean") {
7446
7791
  return rule.isRulesetLike;
7447
7792
  } else if (typeof rule.isRulesetLike === "function") {
7448
- return rule.isRulesetLike(root);
7793
+ return rule.isRulesetLike();
7449
7794
  }
7450
7795
 
7451
7796
  //anything else is assumed to be a rule
7452
7797
  return false;
7453
7798
  }
7454
7799
 
7800
+ var charsetNodeIndex = 0;
7801
+ var importNodeIndex = 0;
7455
7802
  for (i = 0; i < this.rules.length; i++) {
7456
7803
  rule = this.rules[i];
7457
- if (isRulesetLikeNode(rule, this.root)) {
7458
- rulesetNodes.push(rule);
7804
+ if (rule.type === "Comment") {
7805
+ if (importNodeIndex === i) {
7806
+ importNodeIndex++;
7807
+ }
7808
+ ruleNodes.push(rule);
7809
+ } else if (rule.isCharset && rule.isCharset()) {
7810
+ ruleNodes.splice(charsetNodeIndex, 0, rule);
7811
+ charsetNodeIndex++;
7812
+ importNodeIndex++;
7813
+ } else if (rule.type === "Import") {
7814
+ ruleNodes.splice(importNodeIndex, 0, rule);
7815
+ importNodeIndex++;
7459
7816
  } else {
7460
- //charsets should float on top of everything
7461
- if (rule.isCharset && rule.isCharset()) {
7462
- charsetRuleNodes.push(rule);
7463
- } else {
7464
- ruleNodes.push(rule);
7465
- }
7817
+ ruleNodes.push(rule);
7466
7818
  }
7467
7819
  }
7468
7820
  ruleNodes = charsetRuleNodes.concat(ruleNodes);
@@ -7503,18 +7855,23 @@ Ruleset.prototype.genCSS = function (context, output) {
7503
7855
  for (i = 0; i < ruleNodes.length; i++) {
7504
7856
  rule = ruleNodes[i];
7505
7857
 
7506
- // @page{ directive ends up with root elements inside it, a mix of rules and rulesets
7507
- // In this instance we do not know whether it is the last property
7508
- if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) {
7858
+ if (i + 1 === ruleNodes.length) {
7509
7859
  context.lastRule = true;
7510
7860
  }
7511
7861
 
7862
+ var currentLastRule = context.lastRule;
7863
+ if (isRulesetLikeNode(rule)) {
7864
+ context.lastRule = false;
7865
+ }
7866
+
7512
7867
  if (rule.genCSS) {
7513
7868
  rule.genCSS(context, output);
7514
7869
  } else if (rule.value) {
7515
7870
  output.add(rule.value.toString());
7516
7871
  }
7517
7872
 
7873
+ context.lastRule = currentLastRule;
7874
+
7518
7875
  if (!context.lastRule) {
7519
7876
  output.add(context.compress ? '' : ('\n' + tabRuleStr));
7520
7877
  } else {
@@ -7527,17 +7884,6 @@ Ruleset.prototype.genCSS = function (context, output) {
7527
7884
  context.tabLevel--;
7528
7885
  }
7529
7886
 
7530
- sep = (context.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr);
7531
- rulesetNodeCnt = rulesetNodes.length;
7532
- if (rulesetNodeCnt) {
7533
- if (ruleNodes.length && sep) { output.add(sep); }
7534
- rulesetNodes[0].genCSS(context, output);
7535
- for (i = 1; i < rulesetNodeCnt; i++) {
7536
- if (sep) { output.add(sep); }
7537
- rulesetNodes[i].genCSS(context, output);
7538
- }
7539
- }
7540
-
7541
7887
  if (!output.isEmpty() && !context.compress && this.firstRoot) {
7542
7888
  output.add('\n');
7543
7889
  }
@@ -7837,8 +8183,9 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
7837
8183
  };
7838
8184
  module.exports = Ruleset;
7839
8185
 
7840
- },{"../contexts":10,"../functions/default":19,"./debug-info":51,"./element":55,"./node":67,"./paren":69,"./rule":71,"./selector":74}],74:[function(require,module,exports){
7841
- var Node = require("./node");
8186
+ },{"../contexts":10,"../functions/default":19,"../functions/function-registry":21,"./debug-info":53,"./element":57,"./node":69,"./paren":71,"./rule":73,"./selector":76}],76:[function(require,module,exports){
8187
+ var Node = require("./node"),
8188
+ Element = require("./element");
7842
8189
 
7843
8190
  var Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) {
7844
8191
  this.elements = elements;
@@ -7870,6 +8217,12 @@ Selector.prototype.createDerived = function(elements, extendList, evaldCondition
7870
8217
  newSelector.mediaEmpty = this.mediaEmpty;
7871
8218
  return newSelector;
7872
8219
  };
8220
+ Selector.prototype.createEmptySelectors = function() {
8221
+ var el = new Element('', '&', this.index, this.currentFileInfo),
8222
+ sels = [new Selector([el], null, null, this.index, this.currentFileInfo)];
8223
+ sels[0].mediaEmpty = true;
8224
+ return sels;
8225
+ };
7873
8226
  Selector.prototype.match = function (other) {
7874
8227
  var elements = this.elements,
7875
8228
  len = elements.length,
@@ -7948,7 +8301,7 @@ Selector.prototype.getIsOutput = function() {
7948
8301
  };
7949
8302
  module.exports = Selector;
7950
8303
 
7951
- },{"./node":67}],75:[function(require,module,exports){
8304
+ },{"./element":57,"./node":69}],77:[function(require,module,exports){
7952
8305
  var Node = require("./node");
7953
8306
 
7954
8307
  var UnicodeDescriptor = function (value) {
@@ -7959,7 +8312,7 @@ UnicodeDescriptor.prototype.type = "UnicodeDescriptor";
7959
8312
 
7960
8313
  module.exports = UnicodeDescriptor;
7961
8314
 
7962
- },{"./node":67}],76:[function(require,module,exports){
8315
+ },{"./node":69}],78:[function(require,module,exports){
7963
8316
  var Node = require("./node"),
7964
8317
  unitConversions = require("../data/unit-conversions");
7965
8318
 
@@ -8081,7 +8434,7 @@ Unit.prototype.cancel = function () {
8081
8434
  };
8082
8435
  module.exports = Unit;
8083
8436
 
8084
- },{"../data/unit-conversions":13,"./node":67}],77:[function(require,module,exports){
8437
+ },{"../data/unit-conversions":13,"./node":69}],79:[function(require,module,exports){
8085
8438
  var Node = require("./node");
8086
8439
 
8087
8440
  var URL = function (val, index, currentFileInfo, isEvald) {
@@ -8137,7 +8490,7 @@ URL.prototype.eval = function (context) {
8137
8490
  };
8138
8491
  module.exports = URL;
8139
8492
 
8140
- },{"./node":67}],78:[function(require,module,exports){
8493
+ },{"./node":69}],80:[function(require,module,exports){
8141
8494
  var Node = require("./node");
8142
8495
 
8143
8496
  var Value = function (value) {
@@ -8173,7 +8526,7 @@ Value.prototype.genCSS = function (context, output) {
8173
8526
  };
8174
8527
  module.exports = Value;
8175
8528
 
8176
- },{"./node":67}],79:[function(require,module,exports){
8529
+ },{"./node":69}],81:[function(require,module,exports){
8177
8530
  var Node = require("./node");
8178
8531
 
8179
8532
  var Variable = function (name, index, currentFileInfo) {
@@ -8228,7 +8581,7 @@ Variable.prototype.find = function (obj, fun) {
8228
8581
  };
8229
8582
  module.exports = Variable;
8230
8583
 
8231
- },{"./node":67}],80:[function(require,module,exports){
8584
+ },{"./node":69}],82:[function(require,module,exports){
8232
8585
  module.exports = {
8233
8586
  getLocation: function(index, inputStream) {
8234
8587
  var n = index + 1,
@@ -8250,7 +8603,7 @@ module.exports = {
8250
8603
  }
8251
8604
  };
8252
8605
 
8253
- },{}],81:[function(require,module,exports){
8606
+ },{}],83:[function(require,module,exports){
8254
8607
  var tree = require("../tree"),
8255
8608
  Visitor = require("./visitor"),
8256
8609
  logger = require("../logger");
@@ -8451,8 +8804,7 @@ ProcessExtendsVisitor.prototype = {
8451
8804
  if (iterationCount > 100) {
8452
8805
  var selectorOne = "{unable to calculate}";
8453
8806
  var selectorTwo = "{unable to calculate}";
8454
- try
8455
- {
8807
+ try {
8456
8808
  selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();
8457
8809
  selectorTwo = extendsToAdd[0].selector.toCSS();
8458
8810
  }
@@ -8689,7 +9041,6 @@ ProcessExtendsVisitor.prototype = {
8689
9041
  },
8690
9042
  visitMediaOut: function (mediaNode) {
8691
9043
  var lastIndex = this.allExtendsStack.length - 1;
8692
- this.checkExtendsForNonMatched(this.allExtendsStack[lastIndex]);
8693
9044
  this.allExtendsStack.length = lastIndex;
8694
9045
  },
8695
9046
  visitDirective: function (directiveNode, visitArgs) {
@@ -8699,14 +9050,13 @@ ProcessExtendsVisitor.prototype = {
8699
9050
  },
8700
9051
  visitDirectiveOut: function (directiveNode) {
8701
9052
  var lastIndex = this.allExtendsStack.length - 1;
8702
- this.checkExtendsForNonMatched(this.allExtendsStack[lastIndex]);
8703
9053
  this.allExtendsStack.length = lastIndex;
8704
9054
  }
8705
9055
  };
8706
9056
 
8707
9057
  module.exports = ProcessExtendsVisitor;
8708
9058
 
8709
- },{"../logger":31,"../tree":59,"./visitor":87}],82:[function(require,module,exports){
9059
+ },{"../logger":32,"../tree":61,"./visitor":89}],84:[function(require,module,exports){
8710
9060
  function ImportSequencer(onSequencerEmpty) {
8711
9061
  this.imports = [];
8712
9062
  this.variableImports = [];
@@ -8762,7 +9112,7 @@ ImportSequencer.prototype.tryRun = function() {
8762
9112
 
8763
9113
  module.exports = ImportSequencer;
8764
9114
 
8765
- },{}],83:[function(require,module,exports){
9115
+ },{}],85:[function(require,module,exports){
8766
9116
  var contexts = require("../contexts"),
8767
9117
  Visitor = require("./visitor"),
8768
9118
  ImportSequencer = require("./import-sequencer");
@@ -8868,6 +9218,8 @@ ImportVisitor.prototype = {
8868
9218
 
8869
9219
  var importVisitor = this,
8870
9220
  inlineCSS = importNode.options.inline,
9221
+ isPlugin = importNode.options.plugin,
9222
+ isOptional = importNode.options.optional,
8871
9223
  duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;
8872
9224
 
8873
9225
  if (!context.importMultiple) {
@@ -8884,11 +9236,15 @@ ImportVisitor.prototype = {
8884
9236
  }
8885
9237
  }
8886
9238
 
9239
+ if (!fullPath && isOptional) {
9240
+ importNode.skip = true;
9241
+ }
9242
+
8887
9243
  if (root) {
8888
9244
  importNode.root = root;
8889
9245
  importNode.importedFilename = fullPath;
8890
9246
 
8891
- if (!inlineCSS && (context.importMultiple || !duplicateImport)) {
9247
+ if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {
8892
9248
  importVisitor.recursionDetector[fullPath] = true;
8893
9249
 
8894
9250
  var oldContext = this.context;
@@ -8909,7 +9265,16 @@ ImportVisitor.prototype = {
8909
9265
  }
8910
9266
  },
8911
9267
  visitRule: function (ruleNode, visitArgs) {
8912
- visitArgs.visitDeeper = false;
9268
+ if (ruleNode.value.type === "DetachedRuleset") {
9269
+ this.context.frames.unshift(ruleNode);
9270
+ } else {
9271
+ visitArgs.visitDeeper = false;
9272
+ }
9273
+ },
9274
+ visitRuleOut : function(ruleNode) {
9275
+ if (ruleNode.value.type === "DetachedRuleset") {
9276
+ this.context.frames.shift();
9277
+ }
8913
9278
  },
8914
9279
  visitDirective: function (directiveNode, visitArgs) {
8915
9280
  this.context.frames.unshift(directiveNode);
@@ -8938,7 +9303,7 @@ ImportVisitor.prototype = {
8938
9303
  };
8939
9304
  module.exports = ImportVisitor;
8940
9305
 
8941
- },{"../contexts":10,"./import-sequencer":82,"./visitor":87}],84:[function(require,module,exports){
9306
+ },{"../contexts":10,"./import-sequencer":84,"./visitor":89}],86:[function(require,module,exports){
8942
9307
  var visitors = {
8943
9308
  Visitor: require("./visitor"),
8944
9309
  ImportVisitor: require('./import-visitor'),
@@ -8949,7 +9314,7 @@ var visitors = {
8949
9314
 
8950
9315
  module.exports = visitors;
8951
9316
 
8952
- },{"./extend-visitor":81,"./import-visitor":83,"./join-selector-visitor":85,"./to-css-visitor":86,"./visitor":87}],85:[function(require,module,exports){
9317
+ },{"./extend-visitor":83,"./import-visitor":85,"./join-selector-visitor":87,"./to-css-visitor":88,"./visitor":89}],87:[function(require,module,exports){
8953
9318
  var Visitor = require("./visitor");
8954
9319
 
8955
9320
  var JoinSelectorVisitor = function() {
@@ -8991,12 +9356,18 @@ JoinSelectorVisitor.prototype = {
8991
9356
  visitMedia: function (mediaNode, visitArgs) {
8992
9357
  var context = this.contexts[this.contexts.length - 1];
8993
9358
  mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);
9359
+ },
9360
+ visitDirective: function (directiveNode, visitArgs) {
9361
+ var context = this.contexts[this.contexts.length - 1];
9362
+ if (directiveNode.rules && directiveNode.rules.length) {
9363
+ directiveNode.rules[0].root = (directiveNode.isRooted || context.length === 0 || null);
9364
+ }
8994
9365
  }
8995
9366
  };
8996
9367
 
8997
9368
  module.exports = JoinSelectorVisitor;
8998
9369
 
8999
- },{"./visitor":87}],86:[function(require,module,exports){
9370
+ },{"./visitor":89}],88:[function(require,module,exports){
9000
9371
  var tree = require("../tree"),
9001
9372
  Visitor = require("./visitor");
9002
9373
 
@@ -9044,6 +9415,13 @@ ToCSSVisitor.prototype = {
9044
9415
  return mediaNode;
9045
9416
  },
9046
9417
 
9418
+ visitImport: function (importNode, visitArgs) {
9419
+ if (importNode.path.currentFileInfo.reference !== undefined && importNode.css) {
9420
+ return;
9421
+ }
9422
+ return importNode;
9423
+ },
9424
+
9047
9425
  visitDirective: function(directiveNode, visitArgs) {
9048
9426
  if (directiveNode.name === "@charset") {
9049
9427
  if (!directiveNode.getIsReferenced()) {
@@ -9062,8 +9440,30 @@ ToCSSVisitor.prototype = {
9062
9440
  }
9063
9441
  this.charset = true;
9064
9442
  }
9065
- if (directiveNode.rules && directiveNode.rules.rules) {
9066
- this._mergeRules(directiveNode.rules.rules);
9443
+ function hasVisibleChild(directiveNode) {
9444
+ //prepare list of childs
9445
+ var rule, bodyRules = directiveNode.rules;
9446
+ //if there is only one nested ruleset and that one has no path, then it is
9447
+ //just fake ruleset that got not replaced and we need to look inside it to
9448
+ //get real childs
9449
+ if (bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0)) {
9450
+ bodyRules = bodyRules[0].rules;
9451
+ }
9452
+ for (var r = 0; r < bodyRules.length; r++) {
9453
+ rule = bodyRules[r];
9454
+ if (rule.getIsReferenced && rule.getIsReferenced()) {
9455
+ //the directive contains something that was referenced (likely by extend)
9456
+ //therefore it needs to be shown in output too
9457
+ return true;
9458
+ }
9459
+ }
9460
+ return false;
9461
+ }
9462
+
9463
+ if (directiveNode.rules && directiveNode.rules.length) {
9464
+ //it is still true that it is only one ruleset in array
9465
+ //this is last such moment
9466
+ this._mergeRules(directiveNode.rules[0].rules);
9067
9467
  //process childs
9068
9468
  directiveNode.accept(this._visitor);
9069
9469
  visitArgs.visitDeeper = false;
@@ -9073,22 +9473,18 @@ ToCSSVisitor.prototype = {
9073
9473
  return directiveNode;
9074
9474
  }
9075
9475
 
9076
- if (!directiveNode.rules.rules) {
9476
+ if (!directiveNode.rules || !directiveNode.rules.length) {
9077
9477
  return ;
9078
9478
  }
9079
9479
 
9080
- //the directive was not directly referenced
9081
- for (var r = 0; r < directiveNode.rules.rules.length; r++) {
9082
- var rule = directiveNode.rules.rules[r];
9083
- if (rule.getIsReferenced && rule.getIsReferenced()) {
9084
- //the directive contains something that was referenced (likely by extend)
9085
- //therefore it needs to be shown in output too
9086
-
9087
- //marking as referenced in case the directive is stored inside another directive
9088
- directiveNode.markReferenced();
9089
- return directiveNode;
9090
- }
9480
+ //the directive was not directly referenced - we need to check whether some of its childs
9481
+ //was referenced
9482
+ if (hasVisibleChild(directiveNode)) {
9483
+ //marking as referenced in case the directive is stored inside another directive
9484
+ directiveNode.markReferenced();
9485
+ return directiveNode;
9091
9486
  }
9487
+
9092
9488
  //The directive was not directly referenced and does not contain anything that
9093
9489
  //was referenced. Therefore it must not be shown in output.
9094
9490
  return ;
@@ -9268,12 +9664,21 @@ ToCSSVisitor.prototype = {
9268
9664
  rule.value = toValue(spacedGroups);
9269
9665
  }
9270
9666
  });
9667
+ },
9668
+
9669
+ visitAnonymous: function(anonymousNode, visitArgs) {
9670
+ if (!anonymousNode.getIsReferenced()) {
9671
+ return ;
9672
+ }
9673
+
9674
+ anonymousNode.accept(this._visitor);
9675
+ return anonymousNode;
9271
9676
  }
9272
9677
  };
9273
9678
 
9274
9679
  module.exports = ToCSSVisitor;
9275
9680
 
9276
- },{"../tree":59,"./visitor":87}],87:[function(require,module,exports){
9681
+ },{"../tree":61,"./visitor":89}],89:[function(require,module,exports){
9277
9682
  var tree = require("../tree");
9278
9683
 
9279
9684
  var _visitArgs = { visitDeeper: true },
@@ -9427,7 +9832,7 @@ Visitor.prototype = {
9427
9832
  };
9428
9833
  module.exports = Visitor;
9429
9834
 
9430
- },{"../tree":59}],88:[function(require,module,exports){
9835
+ },{"../tree":61}],90:[function(require,module,exports){
9431
9836
  // shim for using process in browser
9432
9837
 
9433
9838
  var process = module.exports = {};
@@ -9464,6 +9869,7 @@ process.browser = true;
9464
9869
  process.env = {};
9465
9870
  process.argv = [];
9466
9871
  process.version = ''; // empty string to avoid regexp issues
9872
+ process.versions = {};
9467
9873
 
9468
9874
  function noop() {}
9469
9875
 
@@ -9486,7 +9892,7 @@ process.chdir = function (dir) {
9486
9892
  };
9487
9893
  process.umask = function() { return 0; };
9488
9894
 
9489
- },{}],89:[function(require,module,exports){
9895
+ },{}],91:[function(require,module,exports){
9490
9896
  'use strict';
9491
9897
 
9492
9898
  var asap = require('asap')
@@ -9593,7 +9999,7 @@ function doResolve(fn, onFulfilled, onRejected) {
9593
9999
  }
9594
10000
  }
9595
10001
 
9596
- },{"asap":91}],90:[function(require,module,exports){
10002
+ },{"asap":93}],92:[function(require,module,exports){
9597
10003
  'use strict';
9598
10004
 
9599
10005
  //This file contains the ES6 extensions to the core Promises/A+ API
@@ -9703,7 +10109,7 @@ Promise.prototype['catch'] = function (onRejected) {
9703
10109
  return this.then(null, onRejected);
9704
10110
  }
9705
10111
 
9706
- },{"./core.js":89,"asap":91}],91:[function(require,module,exports){
10112
+ },{"./core.js":91,"asap":93}],93:[function(require,module,exports){
9707
10113
  (function (process){
9708
10114
 
9709
10115
  // Use the fastest possible means to execute a task in a future turn
@@ -9820,7 +10226,7 @@ module.exports = asap;
9820
10226
 
9821
10227
 
9822
10228
  }).call(this,require('_process'))
9823
- },{"_process":88}],92:[function(require,module,exports){
10229
+ },{"_process":90}],94:[function(require,module,exports){
9824
10230
  // should work in any browser without browserify
9825
10231
 
9826
10232
  if (typeof Promise.prototype.done !== 'function') {
@@ -9833,7 +10239,7 @@ if (typeof Promise.prototype.done !== 'function') {
9833
10239
  })
9834
10240
  }
9835
10241
  }
9836
- },{}],"promise/polyfill.js":[function(require,module,exports){
10242
+ },{}],95:[function(require,module,exports){
9837
10243
  // not "use strict" so we can declare global "Promise"
9838
10244
 
9839
10245
  var asap = require('asap');
@@ -9845,5 +10251,5 @@ if (typeof Promise === 'undefined') {
9845
10251
 
9846
10252
  require('./polyfill-done.js');
9847
10253
 
9848
- },{"./lib/core.js":89,"./lib/es6-extensions.js":90,"./polyfill-done.js":92,"asap":91}]},{},[2])(2)
10254
+ },{"./lib/core.js":91,"./lib/es6-extensions.js":92,"./polyfill-done.js":94,"asap":93}]},{},[2])(2)
9849
10255
  });