less 2.2.2 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (441) hide show
  1. checksums.yaml +7 -0
  2. data/Changelog.md +17 -0
  3. data/Gemfile +7 -3
  4. data/README.md +29 -13
  5. data/bin/lessc +3 -1
  6. data/less.gemspec +2 -6
  7. data/lib/less/defaults.rb +3 -3
  8. data/lib/less/java_script/rhino_context.rb +17 -27
  9. data/lib/less/java_script/v8_context.rb +11 -11
  10. data/lib/less/js/.gitattributes +10 -0
  11. data/lib/less/js/.gitignore +24 -0
  12. data/lib/less/js/.jshintrc +11 -0
  13. data/lib/less/js/.npmignore +1 -0
  14. data/lib/less/js/.travis.yml +8 -0
  15. data/lib/less/js/CHANGELOG.md +299 -0
  16. data/lib/less/js/CONTRIBUTING.md +50 -0
  17. data/lib/less/js/Gruntfile.js +298 -0
  18. data/lib/less/js/README.md +43 -12
  19. data/lib/less/js/benchmark/benchmark.less +194 -194
  20. data/lib/less/js/benchmark/less-benchmark.js +9 -10
  21. data/lib/less/js/bin/lessc +310 -37
  22. data/lib/less/js/bower.json +18 -0
  23. data/lib/less/js/build/README.md +51 -0
  24. data/lib/less/js/build/amd.js +1 -1
  25. data/lib/less/js/build/browser-header.js +4 -0
  26. data/lib/less/js/build/build.yml +162 -0
  27. data/lib/less/js/build/require-rhino.js +7 -2
  28. data/lib/less/js/build/rhino-header.js +4 -0
  29. data/lib/less/js/build/rhino-modules.js +131 -0
  30. data/lib/less/js/build/tasks/.gitkeep +1 -0
  31. data/lib/less/js/build.gradle +347 -0
  32. data/lib/less/js/dist/less-1.3.1.js +4011 -0
  33. data/lib/less/js/dist/less-1.3.1.min.js +9 -0
  34. data/lib/less/js/dist/less-1.3.2.js +4401 -0
  35. data/lib/less/js/dist/less-1.3.2.min.js +9 -0
  36. data/lib/less/js/dist/less-1.3.3.js +4413 -0
  37. data/lib/less/js/dist/less-1.3.3.min.js +9 -0
  38. data/lib/less/js/dist/less-1.4.0-beta.js +5830 -0
  39. data/lib/less/js/dist/less-1.4.0-beta.min.js +11 -0
  40. data/lib/less/js/dist/less-1.4.0.js +5830 -0
  41. data/lib/less/js/dist/less-1.4.0.min.js +11 -0
  42. data/lib/less/js/dist/less-1.4.1.js +5837 -0
  43. data/lib/less/js/dist/less-1.4.1.min.js +11 -0
  44. data/lib/less/js/dist/less-1.4.2.js +5837 -0
  45. data/lib/less/js/dist/less-1.4.2.min.js +11 -0
  46. data/lib/less/js/dist/less-1.5.0.js +6914 -0
  47. data/lib/less/js/dist/less-1.5.0.min.js +13 -0
  48. data/lib/less/js/dist/less-1.5.1.js +6941 -0
  49. data/lib/less/js/dist/less-1.5.1.min.js +13 -0
  50. data/lib/less/js/dist/less-1.6.0.js +7485 -0
  51. data/lib/less/js/dist/less-1.6.0.min.js +16 -0
  52. data/lib/less/js/dist/less-1.6.1.js +7513 -0
  53. data/lib/less/js/dist/less-1.6.1.min.js +16 -0
  54. data/lib/less/js/dist/less-1.6.2.js +7624 -0
  55. data/lib/less/js/dist/less-1.6.2.min.js +16 -0
  56. data/lib/less/js/dist/less-1.6.3.js +7627 -0
  57. data/lib/less/js/dist/less-1.6.3.min.js +16 -0
  58. data/lib/less/js/dist/less-1.7.0.js +7921 -0
  59. data/lib/less/js/dist/less-1.7.0.min.js +16 -0
  60. data/lib/less/js/dist/less-rhino-1.3.1.js +3725 -0
  61. data/lib/less/js/dist/less-rhino-1.3.2.js +3990 -0
  62. data/lib/less/js/dist/less-rhino-1.3.3.js +4002 -0
  63. data/lib/less/js/dist/less-rhino-1.4.0.js +4273 -0
  64. data/lib/less/js/dist/less-rhino-1.5.1.js +6831 -0
  65. data/lib/less/js/dist/less-rhino-1.6.2.js +9017 -0
  66. data/lib/less/js/dist/less-rhino-1.6.3.js +9020 -0
  67. data/lib/less/js/dist/less-rhino-1.7.0.js +9301 -0
  68. data/lib/less/js/dist/lessc-rhino-1.6.2.js +449 -0
  69. data/lib/less/js/dist/lessc-rhino-1.6.3.js +449 -0
  70. data/lib/less/js/dist/lessc-rhino-1.7.0.js +449 -0
  71. data/lib/less/js/gradle/wrapper/gradle-wrapper.jar +0 -0
  72. data/lib/less/js/gradle/wrapper/gradle-wrapper.properties +6 -0
  73. data/lib/less/js/gradlew +164 -0
  74. data/lib/less/js/gradlew.bat +90 -0
  75. data/lib/less/js/lib/less/browser.js +547 -250
  76. data/lib/less/js/lib/less/encoder.js +4 -0
  77. data/lib/less/js/lib/less/env.js +136 -0
  78. data/lib/less/js/lib/less/extend-visitor.js +416 -0
  79. data/lib/less/js/lib/less/functions.js +576 -36
  80. data/lib/less/js/lib/less/import-visitor.js +142 -0
  81. data/lib/less/js/lib/less/index.js +187 -83
  82. data/lib/less/js/lib/less/join-selector-visitor.js +44 -0
  83. data/lib/less/js/lib/less/lessc_helper.js +82 -0
  84. data/lib/less/js/lib/less/parser.js +1286 -523
  85. data/lib/less/js/lib/less/rhino.js +415 -29
  86. data/lib/less/js/lib/less/source-map-output.js +141 -0
  87. data/lib/less/js/lib/less/to-css-visitor.js +240 -0
  88. data/lib/less/js/lib/less/tree/alpha.js +17 -5
  89. data/lib/less/js/lib/less/tree/anonymous.js +25 -4
  90. data/lib/less/js/lib/less/tree/assignment.js +17 -5
  91. data/lib/less/js/lib/less/tree/call.js +36 -13
  92. data/lib/less/js/lib/less/tree/color.js +119 -31
  93. data/lib/less/js/lib/less/tree/comment.js +18 -4
  94. data/lib/less/js/lib/less/tree/condition.js +35 -28
  95. data/lib/less/js/lib/less/tree/detached-ruleset.js +20 -0
  96. data/lib/less/js/lib/less/tree/dimension.js +291 -16
  97. data/lib/less/js/lib/less/tree/directive.js +56 -22
  98. data/lib/less/js/lib/less/tree/element.js +78 -17
  99. data/lib/less/js/lib/less/tree/expression.js +39 -8
  100. data/lib/less/js/lib/less/tree/extend.js +53 -0
  101. data/lib/less/js/lib/less/tree/import.js +81 -36
  102. data/lib/less/js/lib/less/tree/javascript.js +17 -10
  103. data/lib/less/js/lib/less/tree/keyword.js +8 -3
  104. data/lib/less/js/lib/less/tree/media.js +70 -27
  105. data/lib/less/js/lib/less/tree/mixin.js +250 -70
  106. data/lib/less/js/lib/less/tree/negative.js +24 -0
  107. data/lib/less/js/lib/less/tree/operation.js +38 -13
  108. data/lib/less/js/lib/less/tree/paren.js +9 -2
  109. data/lib/less/js/lib/less/tree/quoted.js +29 -10
  110. data/lib/less/js/lib/less/tree/rule.js +77 -29
  111. data/lib/less/js/lib/less/tree/ruleset-call.js +16 -0
  112. data/lib/less/js/lib/less/tree/ruleset.js +445 -107
  113. data/lib/less/js/lib/less/tree/selector.js +117 -30
  114. data/lib/less/js/lib/less/tree/unicode-descriptor.js +15 -0
  115. data/lib/less/js/lib/less/tree/url.js +43 -15
  116. data/lib/less/js/lib/less/tree/value.js +16 -6
  117. data/lib/less/js/lib/less/tree/variable.js +26 -8
  118. data/lib/less/js/lib/less/tree.js +82 -2
  119. data/lib/less/js/lib/less/visitor.js +146 -0
  120. data/lib/less/js/lib/source-map/source-map-0.1.31.js +1933 -0
  121. data/lib/less/js/lib/source-map/source-map-footer.js +4 -0
  122. data/lib/less/js/lib/source-map/source-map-header.js +3 -0
  123. data/lib/less/js/package.json +86 -11
  124. data/lib/less/js/test/browser/common.js +201 -0
  125. data/lib/less/js/test/browser/css/global-vars/simple.css +3 -0
  126. data/lib/less/js/test/browser/css/modify-vars/simple.css +8 -0
  127. data/lib/less/js/test/browser/css/postProcessor/postProcessor.css +4 -0
  128. data/lib/less/js/test/browser/css/relative-urls/urls.css +35 -0
  129. data/lib/less/js/test/browser/css/rootpath/urls.css +35 -0
  130. data/lib/less/js/test/browser/css/rootpath-relative/urls.css +35 -0
  131. data/lib/less/js/test/browser/css/urls.css +53 -0
  132. data/lib/less/js/test/browser/es5.js +27 -0
  133. data/lib/less/js/test/browser/jasmine-html.js +681 -0
  134. data/lib/less/js/test/browser/jasmine.css +82 -0
  135. data/lib/less/js/test/browser/jasmine.js +2600 -0
  136. data/lib/less/js/test/browser/less/console-errors/test-error.less +3 -0
  137. data/lib/less/js/test/browser/less/console-errors/test-error.txt +2 -0
  138. data/lib/less/js/test/browser/less/global-vars/simple.less +3 -0
  139. data/lib/less/js/test/browser/less/imports/urls.less +4 -0
  140. data/lib/less/js/test/browser/less/imports/urls2.less +4 -0
  141. data/lib/less/js/test/browser/less/modify-vars/imports/simple2.less +4 -0
  142. data/lib/less/js/test/browser/less/modify-vars/simple.less +8 -0
  143. data/lib/less/js/test/browser/less/postProcessor/postProcessor.less +4 -0
  144. data/lib/less/js/test/browser/less/relative-urls/urls.less +33 -0
  145. data/lib/less/js/test/browser/less/rootpath/urls.less +33 -0
  146. data/lib/less/js/test/browser/less/rootpath-relative/urls.less +33 -0
  147. data/lib/less/js/test/browser/less/urls.less +57 -0
  148. data/lib/less/js/test/browser/phantom-runner.js +150 -0
  149. data/lib/less/js/test/browser/runner-browser-options.js +42 -0
  150. data/lib/less/js/test/browser/runner-browser-spec.js +12 -0
  151. data/lib/less/js/test/browser/runner-console-errors.js +5 -0
  152. data/lib/less/js/test/browser/runner-errors-options.js +5 -0
  153. data/lib/less/js/test/browser/runner-errors-spec.js +4 -0
  154. data/lib/less/js/test/browser/runner-global-vars-options.js +4 -0
  155. data/lib/less/js/test/browser/runner-global-vars-spec.js +3 -0
  156. data/lib/less/js/test/browser/runner-legacy-options.js +4 -0
  157. data/lib/less/js/test/browser/runner-legacy-spec.js +3 -0
  158. data/lib/less/js/test/browser/runner-main-options.js +15 -0
  159. data/lib/less/js/test/browser/runner-main-spec.js +3 -0
  160. data/lib/less/js/test/browser/runner-modify-vars-options.js +2 -0
  161. data/lib/less/js/test/browser/runner-modify-vars-spec.js +43 -0
  162. data/lib/less/js/test/browser/runner-no-js-errors-options.js +4 -0
  163. data/lib/less/js/test/browser/runner-no-js-errors-spec.js +4 -0
  164. data/lib/less/js/test/browser/runner-postProcessor-options.js +4 -0
  165. data/lib/less/js/test/browser/runner-postProcessor.js +3 -0
  166. data/lib/less/js/test/browser/runner-production-options.js +3 -0
  167. data/lib/less/js/test/browser/runner-production-spec.js +5 -0
  168. data/lib/less/js/test/browser/runner-relative-urls-options.js +3 -0
  169. data/lib/less/js/test/browser/runner-relative-urls-spec.js +3 -0
  170. data/lib/less/js/test/browser/runner-rootpath-options.js +3 -0
  171. data/lib/less/js/test/browser/runner-rootpath-relative-options.js +4 -0
  172. data/lib/less/js/test/browser/runner-rootpath-relative-spec.js +3 -0
  173. data/lib/less/js/test/browser/runner-rootpath-spec.js +3 -0
  174. data/lib/less/js/test/browser/test-runner-template.tmpl +47 -0
  175. data/lib/less/js/test/css/charsets.css +1 -0
  176. data/lib/less/js/test/css/colors.css +29 -0
  177. data/lib/less/js/test/css/comments.css +15 -2
  178. data/lib/less/js/test/css/compression/compression.css +3 -0
  179. data/lib/less/js/test/css/css-3.css +73 -2
  180. data/lib/less/js/test/css/css-escapes.css +4 -0
  181. data/lib/less/js/test/css/css-guards.css +37 -0
  182. data/lib/less/js/test/css/css.css +20 -14
  183. data/lib/less/js/test/css/debug/linenumbers-all.css +49 -0
  184. data/lib/less/js/test/css/debug/linenumbers-comments.css +40 -0
  185. data/lib/less/js/test/css/debug/linenumbers-mediaquery.css +40 -0
  186. data/lib/less/js/test/css/detached-rulesets.css +71 -0
  187. data/lib/less/js/test/css/empty.css +0 -0
  188. data/lib/less/js/test/css/extend-chaining.css +81 -0
  189. data/lib/less/js/test/css/extend-clearfix.css +19 -0
  190. data/lib/less/js/test/css/extend-exact.css +37 -0
  191. data/lib/less/js/test/css/extend-media.css +24 -0
  192. data/lib/less/js/test/css/extend-nest.css +57 -0
  193. data/lib/less/js/test/css/extend-selector.css +80 -0
  194. data/lib/less/js/test/css/extend.css +76 -0
  195. data/lib/less/js/test/css/extract-and-length.css +133 -0
  196. data/lib/less/js/test/css/functions.css +117 -2
  197. data/lib/less/js/test/css/globalVars/extended.css +12 -0
  198. data/lib/less/js/test/css/globalVars/simple.css +6 -0
  199. data/lib/less/js/test/css/ie-filters.css +7 -3
  200. data/lib/less/js/test/css/import-inline.css +5 -0
  201. data/lib/less/js/test/css/import-interpolation.css +6 -0
  202. data/lib/less/js/test/css/import-once.css +15 -0
  203. data/lib/less/js/test/css/import-reference.css +68 -0
  204. data/lib/less/js/test/css/import.css +23 -10
  205. data/lib/less/js/test/css/javascript.css +3 -2
  206. data/lib/less/js/test/css/legacy/legacy.css +7 -0
  207. data/lib/less/js/test/css/media.css +141 -1
  208. data/lib/less/js/test/css/merge.css +34 -0
  209. data/lib/less/js/test/css/mixins-args.css +41 -4
  210. data/lib/less/js/test/css/mixins-guards-default-func.css +129 -0
  211. data/lib/less/js/test/css/mixins-guards.css +24 -0
  212. data/lib/less/js/test/css/mixins-important.css +28 -0
  213. data/lib/less/js/test/css/mixins-interpolated.css +39 -0
  214. data/lib/less/js/test/css/mixins-named-args.css +27 -0
  215. data/lib/less/js/test/css/mixins-pattern.css +4 -0
  216. data/lib/less/js/test/css/mixins.css +70 -0
  217. data/lib/less/js/test/css/modifyVars/extended.css +9 -0
  218. data/lib/less/js/test/css/no-output.css +0 -0
  219. data/lib/less/js/test/css/parens.css +21 -5
  220. data/lib/less/js/test/css/property-name-interp.css +20 -0
  221. data/lib/less/js/test/css/scope.css +23 -0
  222. data/lib/less/js/test/css/selectors.css +84 -0
  223. data/lib/less/js/test/css/static-urls/urls.css +45 -0
  224. data/lib/less/js/test/css/strings.css +5 -2
  225. data/lib/less/js/test/css/url-args/urls.css +56 -0
  226. data/lib/less/js/test/css/urls.css +71 -0
  227. data/lib/less/js/test/css/variables-in-at-rules.css +18 -0
  228. data/lib/less/js/test/css/variables.css +22 -4
  229. data/lib/less/js/test/css/whitespace.css +4 -0
  230. data/lib/less/js/test/data/data-uri-fail.png +0 -0
  231. data/lib/less/js/test/data/image.jpg +1 -0
  232. data/lib/less/js/test/data/page.html +1 -0
  233. data/lib/less/js/test/index.js +45 -0
  234. data/lib/less/js/test/less/charsets.less +3 -0
  235. data/lib/less/js/test/less/colors.less +37 -4
  236. data/lib/less/js/test/less/comments.less +21 -3
  237. data/lib/less/js/test/less/compression/compression.less +36 -0
  238. data/lib/less/js/test/less/css-3.less +70 -6
  239. data/lib/less/js/test/less/css-escapes.less +6 -1
  240. data/lib/less/js/test/less/css-guards.less +102 -0
  241. data/lib/less/js/test/less/css.less +23 -15
  242. data/lib/less/js/test/less/debug/import/test.less +25 -0
  243. data/lib/less/js/test/less/debug/linenumbers.less +33 -0
  244. data/lib/less/js/test/less/detached-rulesets.less +103 -0
  245. data/lib/less/js/test/less/empty.less +0 -0
  246. data/lib/less/js/test/less/errors/add-mixed-units.less +3 -0
  247. data/lib/less/js/test/less/errors/add-mixed-units.txt +4 -0
  248. data/lib/less/js/test/less/errors/add-mixed-units2.less +3 -0
  249. data/lib/less/js/test/less/errors/add-mixed-units2.txt +4 -0
  250. data/lib/less/js/test/less/errors/at-rules-undefined-var.less +4 -0
  251. data/lib/less/js/test/less/errors/at-rules-undefined-var.txt +4 -0
  252. data/lib/less/js/test/less/errors/bad-variable-declaration1.less +1 -0
  253. data/lib/less/js/test/less/errors/bad-variable-declaration1.txt +2 -0
  254. data/lib/less/js/test/less/errors/color-func-invalid-color.less +3 -0
  255. data/lib/less/js/test/less/errors/color-func-invalid-color.txt +4 -0
  256. data/lib/less/js/test/less/errors/comment-in-selector.less +1 -0
  257. data/lib/less/js/test/less/errors/comment-in-selector.txt +2 -0
  258. data/lib/less/js/test/less/errors/css-guard-default-func.less +4 -0
  259. data/lib/less/js/test/less/errors/css-guard-default-func.txt +4 -0
  260. data/lib/less/js/test/less/errors/detached-ruleset-1.less +6 -0
  261. data/lib/less/js/test/less/errors/detached-ruleset-1.txt +4 -0
  262. data/lib/less/js/test/less/errors/detached-ruleset-2.less +6 -0
  263. data/lib/less/js/test/less/errors/detached-ruleset-2.txt +4 -0
  264. data/lib/less/js/test/less/errors/detached-ruleset-3.less +4 -0
  265. data/lib/less/js/test/less/errors/detached-ruleset-3.txt +4 -0
  266. data/lib/less/js/test/less/errors/detached-ruleset-4.less +5 -0
  267. data/lib/less/js/test/less/errors/detached-ruleset-4.txt +3 -0
  268. data/lib/less/js/test/less/errors/detached-ruleset-5.less +4 -0
  269. data/lib/less/js/test/less/errors/detached-ruleset-5.txt +3 -0
  270. data/lib/less/js/test/less/errors/detached-ruleset-6.less +5 -0
  271. data/lib/less/js/test/less/errors/detached-ruleset-6.txt +4 -0
  272. data/lib/less/js/test/less/errors/divide-mixed-units.less +3 -0
  273. data/lib/less/js/test/less/errors/divide-mixed-units.txt +4 -0
  274. data/lib/less/js/test/less/errors/extend-no-selector.less +3 -0
  275. data/lib/less/js/test/less/errors/extend-no-selector.txt +3 -0
  276. data/lib/less/js/test/less/errors/extend-not-at-end.less +3 -0
  277. data/lib/less/js/test/less/errors/extend-not-at-end.txt +3 -0
  278. data/lib/less/js/test/less/errors/import-missing.less +6 -0
  279. data/lib/less/js/test/less/errors/import-missing.txt +3 -0
  280. data/lib/less/js/test/less/errors/import-no-semi.less +1 -0
  281. data/lib/less/js/test/less/errors/import-no-semi.txt +2 -0
  282. data/lib/less/js/test/less/errors/import-subfolder1.less +1 -0
  283. data/lib/less/js/test/less/errors/import-subfolder1.txt +3 -0
  284. data/lib/less/js/test/less/errors/import-subfolder2.less +1 -0
  285. data/lib/less/js/test/less/errors/import-subfolder2.txt +4 -0
  286. data/lib/less/js/test/less/errors/imports/import-subfolder1.less +1 -0
  287. data/lib/less/js/test/less/errors/imports/import-subfolder2.less +1 -0
  288. data/lib/less/js/test/less/errors/imports/import-test.less +4 -0
  289. data/lib/less/js/test/less/errors/imports/subfolder/mixin-not-defined.less +1 -0
  290. data/lib/less/js/test/less/errors/imports/subfolder/parse-error-curly-bracket.less +1 -0
  291. data/lib/less/js/test/less/errors/javascript-error.less +3 -0
  292. data/lib/less/js/test/less/errors/javascript-error.txt +4 -0
  293. data/lib/less/js/test/less/errors/javascript-undefined-var.less +3 -0
  294. data/lib/less/js/test/less/errors/javascript-undefined-var.txt +4 -0
  295. data/lib/less/js/test/less/errors/mixed-mixin-definition-args-1.less +6 -0
  296. data/lib/less/js/test/less/errors/mixed-mixin-definition-args-1.txt +4 -0
  297. data/lib/less/js/test/less/errors/mixed-mixin-definition-args-2.less +6 -0
  298. data/lib/less/js/test/less/errors/mixed-mixin-definition-args-2.txt +4 -0
  299. data/lib/less/js/test/less/errors/mixin-not-defined.less +11 -0
  300. data/lib/less/js/test/less/errors/mixin-not-defined.txt +3 -0
  301. data/lib/less/js/test/less/errors/mixin-not-matched.less +6 -0
  302. data/lib/less/js/test/less/errors/mixin-not-matched.txt +3 -0
  303. data/lib/less/js/test/less/errors/mixin-not-matched2.less +6 -0
  304. data/lib/less/js/test/less/errors/mixin-not-matched2.txt +3 -0
  305. data/lib/less/js/test/less/errors/mixin-not-visible-in-scope-1.less +9 -0
  306. data/lib/less/js/test/less/errors/mixin-not-visible-in-scope-1.txt +4 -0
  307. data/lib/less/js/test/less/errors/mixins-guards-default-func-1.less +9 -0
  308. data/lib/less/js/test/less/errors/mixins-guards-default-func-1.txt +4 -0
  309. data/lib/less/js/test/less/errors/mixins-guards-default-func-2.less +9 -0
  310. data/lib/less/js/test/less/errors/mixins-guards-default-func-2.txt +4 -0
  311. data/lib/less/js/test/less/errors/mixins-guards-default-func-3.less +9 -0
  312. data/lib/less/js/test/less/errors/mixins-guards-default-func-3.txt +4 -0
  313. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors.less +4 -0
  314. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors.txt +4 -0
  315. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors2.less +4 -0
  316. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors2.txt +4 -0
  317. data/lib/less/js/test/less/errors/multiply-mixed-units.less +7 -0
  318. data/lib/less/js/test/less/errors/multiply-mixed-units.txt +4 -0
  319. data/lib/less/js/test/less/errors/parens-error-1.less +3 -0
  320. data/lib/less/js/test/less/errors/parens-error-1.txt +4 -0
  321. data/lib/less/js/test/less/errors/parens-error-2.less +3 -0
  322. data/lib/less/js/test/less/errors/parens-error-2.txt +4 -0
  323. data/lib/less/js/test/less/errors/parens-error-3.less +3 -0
  324. data/lib/less/js/test/less/errors/parens-error-3.txt +4 -0
  325. data/lib/less/js/test/less/errors/parse-error-curly-bracket.less +4 -0
  326. data/lib/less/js/test/less/errors/parse-error-curly-bracket.txt +4 -0
  327. data/lib/less/js/test/less/errors/parse-error-extra-parens.less +5 -0
  328. data/lib/less/js/test/less/errors/parse-error-extra-parens.txt +3 -0
  329. data/lib/less/js/test/less/errors/parse-error-missing-bracket.less +2 -0
  330. data/lib/less/js/test/less/errors/parse-error-missing-bracket.txt +3 -0
  331. data/lib/less/js/test/less/errors/parse-error-missing-parens.less +5 -0
  332. data/lib/less/js/test/less/errors/parse-error-missing-parens.txt +3 -0
  333. data/lib/less/js/test/less/errors/parse-error-with-import.less +13 -0
  334. data/lib/less/js/test/less/errors/parse-error-with-import.txt +4 -0
  335. data/lib/less/js/test/less/errors/percentage-missing-space.less +3 -0
  336. data/lib/less/js/test/less/errors/percentage-missing-space.txt +4 -0
  337. data/lib/less/js/test/less/errors/property-asterisk-only-name.less +3 -0
  338. data/lib/less/js/test/less/errors/property-asterisk-only-name.txt +4 -0
  339. data/lib/less/js/test/less/errors/property-ie5-hack.less +3 -0
  340. data/lib/less/js/test/less/errors/property-ie5-hack.txt +4 -0
  341. data/lib/less/js/test/less/errors/property-in-root.less +4 -0
  342. data/lib/less/js/test/less/errors/property-in-root.txt +4 -0
  343. data/lib/less/js/test/less/errors/property-in-root2.less +1 -0
  344. data/lib/less/js/test/less/errors/property-in-root2.txt +4 -0
  345. data/lib/less/js/test/less/errors/property-in-root3.less +4 -0
  346. data/lib/less/js/test/less/errors/property-in-root3.txt +3 -0
  347. data/lib/less/js/test/less/errors/property-interp-not-defined.less +1 -0
  348. data/lib/less/js/test/less/errors/property-interp-not-defined.txt +2 -0
  349. data/lib/less/js/test/less/errors/recursive-variable.less +1 -0
  350. data/lib/less/js/test/less/errors/recursive-variable.txt +2 -0
  351. data/lib/less/js/test/less/errors/svg-gradient1.less +3 -0
  352. data/lib/less/js/test/less/errors/svg-gradient1.txt +4 -0
  353. data/lib/less/js/test/less/errors/svg-gradient2.less +3 -0
  354. data/lib/less/js/test/less/errors/svg-gradient2.txt +4 -0
  355. data/lib/less/js/test/less/errors/svg-gradient3.less +3 -0
  356. data/lib/less/js/test/less/errors/svg-gradient3.txt +4 -0
  357. data/lib/less/js/test/less/errors/unit-function.less +3 -0
  358. data/lib/less/js/test/less/errors/unit-function.txt +4 -0
  359. data/lib/less/js/test/less/extend-chaining.less +91 -0
  360. data/lib/less/js/test/less/extend-clearfix.less +19 -0
  361. data/lib/less/js/test/less/extend-exact.less +46 -0
  362. data/lib/less/js/test/less/extend-media.less +24 -0
  363. data/lib/less/js/test/less/extend-nest.less +65 -0
  364. data/lib/less/js/test/less/extend-selector.less +99 -0
  365. data/lib/less/js/test/less/extend.less +81 -0
  366. data/lib/less/js/test/less/extract-and-length.less +133 -0
  367. data/lib/less/js/test/less/functions.less +130 -6
  368. data/lib/less/js/test/less/globalVars/extended.json +5 -0
  369. data/lib/less/js/test/less/globalVars/extended.less +10 -0
  370. data/lib/less/js/test/less/globalVars/simple.json +3 -0
  371. data/lib/less/js/test/less/globalVars/simple.less +3 -0
  372. data/lib/less/js/test/less/ie-filters.less +7 -0
  373. data/lib/less/js/test/less/import/deeper/import-once-test-a.less +1 -0
  374. data/lib/less/js/test/less/import/import-and-relative-paths-test.less +17 -0
  375. data/lib/less/js/test/less/import/import-charset-test.less +1 -0
  376. data/lib/less/js/test/less/import/import-interpolation.less +1 -0
  377. data/lib/less/js/test/less/import/import-interpolation2.less +5 -0
  378. data/lib/less/js/test/less/import/import-once-test-c.less +6 -0
  379. data/lib/less/js/test/less/import/import-reference.less +51 -0
  380. data/lib/less/js/test/less/import/import-test-a.less +1 -0
  381. data/lib/less/js/test/less/import/import-test-c.less +0 -1
  382. data/lib/less/js/test/less/import/import-test-f.less +5 -0
  383. data/lib/less/js/test/less/import/imports/font.less +8 -0
  384. data/lib/less/js/test/less/import/imports/logo.less +5 -0
  385. data/lib/less/js/test/less/import/invalid-css.less +1 -0
  386. data/lib/less/js/test/less/import/urls.less +1 -0
  387. data/lib/less/js/test/less/import-inline.less +2 -0
  388. data/lib/less/js/test/less/import-interpolation.less +8 -0
  389. data/lib/less/js/test/less/import-once.less +6 -0
  390. data/lib/less/js/test/less/import-reference.less +21 -0
  391. data/lib/less/js/test/less/import.less +13 -3
  392. data/lib/less/js/test/less/javascript.less +5 -3
  393. data/lib/less/js/test/less/legacy/legacy.less +7 -0
  394. data/lib/less/js/test/less/media.less +158 -3
  395. data/lib/less/js/test/less/merge.less +78 -0
  396. data/lib/less/js/test/less/mixins-args.less +93 -15
  397. data/lib/less/js/test/less/mixins-guards-default-func.less +195 -0
  398. data/lib/less/js/test/less/mixins-guards.less +65 -0
  399. data/lib/less/js/test/less/mixins-important.less +8 -1
  400. data/lib/less/js/test/less/mixins-interpolated.less +69 -0
  401. data/lib/less/js/test/less/mixins-named-args.less +36 -0
  402. data/lib/less/js/test/less/mixins-nested.less +2 -2
  403. data/lib/less/js/test/less/mixins-pattern.less +4 -1
  404. data/lib/less/js/test/less/mixins.less +74 -0
  405. data/lib/less/js/test/less/modifyVars/extended.json +5 -0
  406. data/lib/less/js/test/less/modifyVars/extended.less +11 -0
  407. data/lib/less/js/test/less/no-js-errors/no-js-errors.less +3 -0
  408. data/lib/less/js/test/less/no-js-errors/no-js-errors.txt +4 -0
  409. data/lib/less/js/test/less/no-output.less +2 -0
  410. data/lib/less/js/test/less/operations.less +27 -27
  411. data/lib/less/js/test/less/parens.less +24 -5
  412. data/lib/less/js/test/less/property-name-interp.less +53 -0
  413. data/lib/less/js/test/less/scope.less +73 -1
  414. data/lib/less/js/test/less/selectors.less +101 -0
  415. data/lib/less/js/test/less/sourcemaps/basic.json +3 -0
  416. data/lib/less/js/test/less/sourcemaps/basic.less +27 -0
  417. data/lib/less/js/test/less/sourcemaps/imported.css +7 -0
  418. data/lib/less/js/test/less/static-urls/urls.less +33 -0
  419. data/lib/less/js/test/less/strings.less +7 -1
  420. data/lib/less/js/test/less/url-args/urls.less +63 -0
  421. data/lib/less/js/test/less/urls.less +72 -0
  422. data/lib/less/js/test/less/variables-in-at-rules.less +20 -0
  423. data/lib/less/js/test/less/variables.less +42 -13
  424. data/lib/less/js/test/less/whitespace.less +7 -0
  425. data/lib/less/js/test/less-test.js +251 -65
  426. data/lib/less/js/test/rhino/test-header.js +15 -0
  427. data/lib/less/js/test/sourcemaps/basic.json +1 -0
  428. data/lib/less/js/test/sourcemaps/index.html +17 -0
  429. data/lib/less/loader.rb +191 -27
  430. data/lib/less/parser.rb +47 -8
  431. data/lib/less/version.rb +2 -2
  432. data/spec/less/loader_spec.rb +45 -0
  433. data/spec/less/parser_spec.rb +43 -17
  434. data/spec/less/some/some.css +0 -0
  435. data/spec/less/some/some.less +4 -0
  436. metadata +352 -57
  437. data/lib/less/js/CHANGELOG +0 -41
  438. data/lib/less/js/Makefile +0 -75
  439. data/lib/less/js/build/ecma-5.js +0 -120
  440. data/lib/less/js/build/header.js +0 -7
  441. data/lib/less/js/lib/less/cssmin.js +0 -355
@@ -1,201 +1,122 @@
1
1
  //
2
2
  // browser.js - client-side engine
3
3
  //
4
+ /*global less, window, document, XMLHttpRequest, location */
4
5
 
5
- var isFileProtocol = (location.protocol === 'file:' ||
6
- location.protocol === 'chrome:' ||
7
- location.protocol === 'chrome-extension:' ||
8
- location.protocol === 'resource:');
6
+ var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
9
7
 
10
8
  less.env = less.env || (location.hostname == '127.0.0.1' ||
11
9
  location.hostname == '0.0.0.0' ||
12
10
  location.hostname == 'localhost' ||
13
- location.port.length > 0 ||
11
+ (location.port &&
12
+ location.port.length > 0) ||
14
13
  isFileProtocol ? 'development'
15
14
  : 'production');
16
15
 
16
+ var logLevel = {
17
+ debug: 3,
18
+ info: 2,
19
+ errors: 1,
20
+ none: 0
21
+ };
22
+
23
+ // The amount of logging in the javascript console.
24
+ // 3 - Debug, information and errors
25
+ // 2 - Information and errors
26
+ // 1 - Errors
27
+ // 0 - None
28
+ // Defaults to 2
29
+ less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : (less.env === 'development' ? logLevel.debug : logLevel.errors);
30
+
17
31
  // Load styles asynchronously (default: false)
18
32
  //
19
33
  // This is set to `false` by default, so that the body
20
34
  // doesn't start loading before the stylesheets are parsed.
21
35
  // Setting this to `true` can result in flickering.
22
36
  //
23
- less.async = false;
37
+ less.async = less.async || false;
38
+ less.fileAsync = less.fileAsync || false;
24
39
 
25
40
  // Interval between watch polls
26
41
  less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
27
42
 
28
- //
29
- // Watch mode
30
- //
31
- less.watch = function () { return this.watchMode = true };
32
- less.unwatch = function () { return this.watchMode = false };
33
-
34
- if (less.env === 'development') {
35
- less.optimization = 0;
36
-
37
- if (/!watch/.test(location.hash)) {
38
- less.watch();
39
- }
40
- less.watchTimer = setInterval(function () {
41
- if (less.watchMode) {
42
- loadStyleSheets(function (e, root, _, sheet, env) {
43
- if (root) {
44
- createCSS(root.toCSS(), sheet, env.lastModified);
45
- }
46
- });
43
+ //Setup user functions
44
+ if (less.functions) {
45
+ for(var func in less.functions) {
46
+ if (less.functions.hasOwnProperty(func)) {
47
+ less.tree.functions[func] = less.functions[func];
47
48
  }
48
- }, less.poll);
49
- } else {
50
- less.optimization = 3;
49
+ }
51
50
  }
52
51
 
53
- var cache;
54
-
55
- try {
56
- cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
57
- } catch (_) {
58
- cache = null;
52
+ var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
53
+ if (dumpLineNumbers) {
54
+ less.dumpLineNumbers = dumpLineNumbers[1];
59
55
  }
60
56
 
61
- //
62
- // Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
63
- //
64
- var links = document.getElementsByTagName('link');
65
57
  var typePattern = /^text\/(x-)?less$/;
58
+ var cache = null;
59
+ var fileCache = {};
66
60
 
67
- less.sheets = [];
68
-
69
- for (var i = 0; i < links.length; i++) {
70
- if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
71
- (links[i].type.match(typePattern)))) {
72
- less.sheets.push(links[i]);
73
- }
74
- }
75
-
76
-
77
- less.refresh = function (reload) {
78
- var startTime, endTime;
79
- startTime = endTime = new(Date);
80
-
81
- loadStyleSheets(function (e, root, _, sheet, env) {
82
- if (env.local) {
83
- log("loading " + sheet.href + " from cache.");
84
- } else {
85
- log("parsed " + sheet.href + " successfully.");
86
- createCSS(root.toCSS(), sheet, env.lastModified);
87
- }
88
- log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
89
- (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
90
- endTime = new(Date);
91
- }, reload);
92
-
93
- loadStyles();
94
- };
95
- less.refreshStyles = loadStyles;
96
-
97
- less.refresh(less.env === 'development');
98
-
99
- function loadStyles() {
100
- var styles = document.getElementsByTagName('style');
101
- for (var i = 0; i < styles.length; i++) {
102
- if (styles[i].type.match(typePattern)) {
103
- new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
104
- var css = tree.toCSS();
105
- var style = styles[i];
106
- style.type = 'text/css';
107
- if (style.styleSheet) {
108
- style.styleSheet.cssText = css;
109
- } else {
110
- style.innerHTML = css;
111
- }
112
- });
113
- }
61
+ function log(str, level) {
62
+ if (typeof(console) !== 'undefined' && less.logLevel >= level) {
63
+ console.log('less: ' + str);
114
64
  }
115
65
  }
116
66
 
117
- function loadStyleSheets(callback, reload) {
118
- for (var i = 0; i < less.sheets.length; i++) {
119
- loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
120
- }
67
+ function extractId(href) {
68
+ return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain
69
+ .replace(/^\//, '' ) // Remove root /
70
+ .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension
71
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
72
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
121
73
  }
122
74
 
123
- function loadStyleSheet(sheet, callback, reload, remaining) {
124
- var url = window.location.href.replace(/[#?].*$/, '');
125
- var href = sheet.href.replace(/\?.*$/, '');
126
- var css = cache && cache.getItem(href);
127
- var timestamp = cache && cache.getItem(href + ':timestamp');
128
- var styles = { css: css, timestamp: timestamp };
75
+ function errorConsole(e, rootHref) {
76
+ var template = '{line} {content}';
77
+ var filename = e.filename || rootHref;
78
+ var errors = [];
79
+ var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
80
+ " in " + filename + " ";
129
81
 
130
- // Stylesheets in IE don't always return the full path
131
- if (! /^(https?|file):/.test(href)) {
132
- if (href.charAt(0) == "/") {
133
- href = window.location.protocol + "//" + window.location.host + href;
134
- } else {
135
- href = url.slice(0, url.lastIndexOf('/') + 1) + href;
136
- }
137
- }
138
- var filename = href.match(/([^\/]+)$/)[1];
139
-
140
- xhr(sheet.href, sheet.type, function (data, lastModified) {
141
- if (!reload && styles && lastModified &&
142
- (new(Date)(lastModified).valueOf() ===
143
- new(Date)(styles.timestamp).valueOf())) {
144
- // Use local copy
145
- createCSS(styles.css, sheet);
146
- callback(null, null, data, sheet, { local: true, remaining: remaining });
147
- } else {
148
- // Use remote copy (re-parse)
149
- try {
150
- new(less.Parser)({
151
- optimization: less.optimization,
152
- paths: [href.replace(/[\w\.-]+$/, '')],
153
- mime: sheet.type,
154
- filename: filename
155
- }).parse(data, function (e, root) {
156
- if (e) { return error(e, href) }
157
- try {
158
- callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
159
- removeNode(document.getElementById('less-error-message:' + extractId(href)));
160
- } catch (e) {
161
- error(e, href);
162
- }
163
- });
164
- } catch (e) {
165
- error(e, href);
166
- }
82
+ var errorline = function (e, i, classname) {
83
+ if (e.extract[i] !== undefined) {
84
+ errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
85
+ .replace(/\{class\}/, classname)
86
+ .replace(/\{content\}/, e.extract[i]));
167
87
  }
168
- }, function (status, url) {
169
- throw new(Error)("Couldn't load " + url + " (" + status + ")");
170
- });
171
- }
88
+ };
172
89
 
173
- function extractId(href) {
174
- return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
175
- .replace(/^\//, '' ) // Remove root /
176
- .replace(/\?.*$/, '' ) // Remove query
177
- .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
178
- .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
179
- .replace(/\./g, ':'); // Replace dots with colons(for valid id)
90
+ if (e.extract) {
91
+ errorline(e, 0, '');
92
+ errorline(e, 1, 'line');
93
+ errorline(e, 2, '');
94
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' +
95
+ errors.join('\n');
96
+ } else if (e.stack) {
97
+ content += e.stack;
98
+ }
99
+ log(content, logLevel.errors);
180
100
  }
181
101
 
182
102
  function createCSS(styles, sheet, lastModified) {
183
- var css;
184
-
185
103
  // Strip the query-string
186
- var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
104
+ var href = sheet.href || '';
187
105
 
188
106
  // If there is no title set, use the filename, minus the extension
189
107
  var id = 'less:' + (sheet.title || extractId(href));
190
108
 
191
- // If the stylesheet doesn't exist, create a new node
192
- if ((css = document.getElementById(id)) === null) {
193
- css = document.createElement('style');
194
- css.type = 'text/css';
195
- css.media = sheet.media || 'screen';
196
- css.id = id;
197
- document.getElementsByTagName('head')[0].appendChild(css);
109
+ // If this has already been inserted into the DOM, we may need to replace it
110
+ var oldCss = document.getElementById(id);
111
+ var keepOldCss = false;
112
+
113
+ // Create a new stylesheet node for insertion or (if necessary) replacement
114
+ var css = document.createElement('style');
115
+ css.setAttribute('type', 'text/css');
116
+ if (sheet.media) {
117
+ css.setAttribute('media', sheet.media);
198
118
  }
119
+ css.id = id;
199
120
 
200
121
  if (css.styleSheet) { // IE
201
122
  try {
@@ -204,151 +125,118 @@ function createCSS(styles, sheet, lastModified) {
204
125
  throw new(Error)("Couldn't reassign styleSheet.cssText.");
205
126
  }
206
127
  } else {
207
- (function (node) {
208
- if (css.childNodes.length > 0) {
209
- if (css.firstChild.nodeValue !== node.nodeValue) {
210
- css.replaceChild(node, css.firstChild);
211
- }
212
- } else {
213
- css.appendChild(node);
214
- }
215
- })(document.createTextNode(styles));
216
- }
128
+ css.appendChild(document.createTextNode(styles));
217
129
 
218
- // Don't update the local store if the file wasn't modified
219
- if (lastModified && cache) {
220
- log('saving ' + href + ' to cache.');
221
- cache.setItem(href, styles);
222
- cache.setItem(href + ':timestamp', lastModified);
130
+ // If new contents match contents of oldCss, don't replace oldCss
131
+ keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 &&
132
+ oldCss.firstChild.nodeValue === css.firstChild.nodeValue);
223
133
  }
224
- }
225
134
 
226
- function xhr(url, type, callback, errback) {
227
- var xhr = getXMLHttpRequest();
228
- var async = isFileProtocol ? false : less.async;
135
+ var head = document.getElementsByTagName('head')[0];
229
136
 
230
- if (typeof(xhr.overrideMimeType) === 'function') {
231
- xhr.overrideMimeType('text/css');
232
- }
233
- xhr.open('GET', url, async);
234
- xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
235
- xhr.send(null);
236
-
237
- if (isFileProtocol) {
238
- if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
239
- callback(xhr.responseText);
137
+ // If there is no oldCss, just append; otherwise, only append if we need
138
+ // to replace oldCss with an updated stylesheet
139
+ if (oldCss === null || keepOldCss === false) {
140
+ var nextEl = sheet && sheet.nextSibling || null;
141
+ if (nextEl) {
142
+ nextEl.parentNode.insertBefore(css, nextEl);
240
143
  } else {
241
- errback(xhr.status, url);
144
+ head.appendChild(css);
242
145
  }
243
- } else if (async) {
244
- xhr.onreadystatechange = function () {
245
- if (xhr.readyState == 4) {
246
- handleResponse(xhr, callback, errback);
247
- }
248
- };
249
- } else {
250
- handleResponse(xhr, callback, errback);
251
146
  }
252
-
253
- function handleResponse(xhr, callback, errback) {
254
- if (xhr.status >= 200 && xhr.status < 300) {
255
- callback(xhr.responseText,
256
- xhr.getResponseHeader("Last-Modified"));
257
- } else if (typeof(errback) === 'function') {
258
- errback(xhr.status, url);
259
- }
147
+ if (oldCss && keepOldCss === false) {
148
+ oldCss.parentNode.removeChild(oldCss);
260
149
  }
261
- }
262
150
 
263
- function getXMLHttpRequest() {
264
- if (window.XMLHttpRequest) {
265
- return new(XMLHttpRequest);
266
- } else {
151
+ // Don't update the local store if the file wasn't modified
152
+ if (lastModified && cache) {
153
+ log('saving ' + href + ' to cache.', logLevel.info);
267
154
  try {
268
- return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
269
- } catch (e) {
270
- log("browser doesn't support AJAX.");
271
- return null;
155
+ cache.setItem(href, styles);
156
+ cache.setItem(href + ':timestamp', lastModified);
157
+ } catch(e) {
158
+ //TODO - could do with adding more robust error handling
159
+ log('failed to save', logLevel.errors);
272
160
  }
273
161
  }
274
162
  }
275
163
 
276
- function removeNode(node) {
277
- return node && node.parentNode.removeChild(node);
278
- }
279
-
280
- function log(str) {
281
- if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
164
+ function postProcessCSS(styles) {
165
+ if (less.postProcessor && typeof less.postProcessor === 'function') {
166
+ styles = less.postProcessor.call(styles, styles) || styles;
167
+ }
168
+ return styles;
282
169
  }
283
170
 
284
- function error(e, href) {
285
- var id = 'less-error-message:' + extractId(href);
171
+ function errorHTML(e, rootHref) {
172
+ var id = 'less-error-message:' + extractId(rootHref || "");
286
173
  var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
287
- var elem = document.createElement('div'), timer, content, error = [];
288
- var filename = e.filename || href;
174
+ var elem = document.createElement('div'), timer, content, errors = [];
175
+ var filename = e.filename || rootHref;
176
+ var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
289
177
 
290
178
  elem.id = id;
291
179
  elem.className = "less-error-message";
292
180
 
293
- content = '<h3>' + (e.message || 'There is an error in your .less file') +
294
- '</h3>' + '<p>in <a href="' + filename + '">' + filename + "</a> ";
181
+ content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
182
+ '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
295
183
 
296
184
  var errorline = function (e, i, classname) {
297
- if (e.extract[i]) {
298
- error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
299
- .replace(/\{class\}/, classname)
300
- .replace(/\{content\}/, e.extract[i]));
185
+ if (e.extract[i] !== undefined) {
186
+ errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
187
+ .replace(/\{class\}/, classname)
188
+ .replace(/\{content\}/, e.extract[i]));
301
189
  }
302
190
  };
303
191
 
304
- if (e.stack) {
305
- content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
306
- } else if (e.extract) {
192
+ if (e.extract) {
307
193
  errorline(e, 0, '');
308
194
  errorline(e, 1, 'line');
309
195
  errorline(e, 2, '');
310
196
  content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
311
- '<ul>' + error.join('') + '</ul>';
197
+ '<ul>' + errors.join('') + '</ul>';
198
+ } else if (e.stack) {
199
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
312
200
  }
313
201
  elem.innerHTML = content;
314
202
 
315
203
  // CSS for error messages
316
204
  createCSS([
317
205
  '.less-error-message ul, .less-error-message li {',
318
- 'list-style-type: none;',
319
- 'margin-right: 15px;',
320
- 'padding: 4px 0;',
321
- 'margin: 0;',
206
+ 'list-style-type: none;',
207
+ 'margin-right: 15px;',
208
+ 'padding: 4px 0;',
209
+ 'margin: 0;',
322
210
  '}',
323
211
  '.less-error-message label {',
324
- 'font-size: 12px;',
325
- 'margin-right: 15px;',
326
- 'padding: 4px 0;',
327
- 'color: #cc7777;',
212
+ 'font-size: 12px;',
213
+ 'margin-right: 15px;',
214
+ 'padding: 4px 0;',
215
+ 'color: #cc7777;',
328
216
  '}',
329
217
  '.less-error-message pre {',
330
- 'color: #dd6666;',
331
- 'padding: 4px 0;',
332
- 'margin: 0;',
333
- 'display: inline-block;',
218
+ 'color: #dd6666;',
219
+ 'padding: 4px 0;',
220
+ 'margin: 0;',
221
+ 'display: inline-block;',
334
222
  '}',
335
223
  '.less-error-message pre.line {',
336
- 'color: #ff0000;',
224
+ 'color: #ff0000;',
337
225
  '}',
338
226
  '.less-error-message h3 {',
339
- 'font-size: 20px;',
340
- 'font-weight: bold;',
341
- 'padding: 15px 0 5px 0;',
342
- 'margin: 0;',
227
+ 'font-size: 20px;',
228
+ 'font-weight: bold;',
229
+ 'padding: 15px 0 5px 0;',
230
+ 'margin: 0;',
343
231
  '}',
344
232
  '.less-error-message a {',
345
- 'color: #10a',
233
+ 'color: #10a',
346
234
  '}',
347
235
  '.less-error-message .error {',
348
- 'color: red;',
349
- 'font-weight: bold;',
350
- 'padding-bottom: 2px;',
351
- 'border-bottom: 1px dashed red;',
236
+ 'color: red;',
237
+ 'font-weight: bold;',
238
+ 'padding-bottom: 2px;',
239
+ 'border-bottom: 1px dashed red;',
352
240
  '}'
353
241
  ].join('\n'), { title: 'error-message' });
354
242
 
@@ -378,3 +266,412 @@ function error(e, href) {
378
266
  }
379
267
  }
380
268
 
269
+ function error(e, rootHref) {
270
+ if (!less.errorReporting || less.errorReporting === "html") {
271
+ errorHTML(e, rootHref);
272
+ } else if (less.errorReporting === "console") {
273
+ errorConsole(e, rootHref);
274
+ } else if (typeof less.errorReporting === 'function') {
275
+ less.errorReporting("add", e, rootHref);
276
+ }
277
+ }
278
+
279
+ function removeErrorHTML(path) {
280
+ var node = document.getElementById('less-error-message:' + extractId(path));
281
+ if (node) {
282
+ node.parentNode.removeChild(node);
283
+ }
284
+ }
285
+
286
+ function removeErrorConsole(path) {
287
+ //no action
288
+ }
289
+
290
+ function removeError(path) {
291
+ if (!less.errorReporting || less.errorReporting === "html") {
292
+ removeErrorHTML(path);
293
+ } else if (less.errorReporting === "console") {
294
+ removeErrorConsole(path);
295
+ } else if (typeof less.errorReporting === 'function') {
296
+ less.errorReporting("remove", path);
297
+ }
298
+ }
299
+
300
+ function loadStyles(modifyVars) {
301
+ var styles = document.getElementsByTagName('style'),
302
+ style;
303
+ for (var i = 0; i < styles.length; i++) {
304
+ style = styles[i];
305
+ if (style.type.match(typePattern)) {
306
+ var env = new less.tree.parseEnv(less),
307
+ lessText = style.innerHTML || '';
308
+ env.filename = document.location.href.replace(/#.*$/, '');
309
+
310
+ if (modifyVars || less.globalVars) {
311
+ env.useFileCache = true;
312
+ }
313
+
314
+ /*jshint loopfunc:true */
315
+ // use closure to store current value of i
316
+ var callback = (function(style) {
317
+ return function (e, cssAST) {
318
+ if (e) {
319
+ return error(e, "inline");
320
+ }
321
+ var css = cssAST.toCSS(less);
322
+ style.type = 'text/css';
323
+ if (style.styleSheet) {
324
+ style.styleSheet.cssText = css;
325
+ } else {
326
+ style.innerHTML = css;
327
+ }
328
+ };
329
+ })(style);
330
+ new(less.Parser)(env).parse(lessText, callback, {globalVars: less.globalVars, modifyVars: modifyVars});
331
+ }
332
+ }
333
+ }
334
+
335
+ function extractUrlParts(url, baseUrl) {
336
+ // urlParts[1] = protocol&hostname || /
337
+ // urlParts[2] = / if path relative to host base
338
+ // urlParts[3] = directories
339
+ // urlParts[4] = filename
340
+ // urlParts[5] = parameters
341
+
342
+ var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
343
+ urlParts = url.match(urlPartsRegex),
344
+ returner = {}, directories = [], i, baseUrlParts;
345
+
346
+ if (!urlParts) {
347
+ throw new Error("Could not parse sheet href - '"+url+"'");
348
+ }
349
+
350
+ // Stylesheets in IE don't always return the full path
351
+ if (!urlParts[1] || urlParts[2]) {
352
+ baseUrlParts = baseUrl.match(urlPartsRegex);
353
+ if (!baseUrlParts) {
354
+ throw new Error("Could not parse page url - '"+baseUrl+"'");
355
+ }
356
+ urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
357
+ if (!urlParts[2]) {
358
+ urlParts[3] = baseUrlParts[3] + urlParts[3];
359
+ }
360
+ }
361
+
362
+ if (urlParts[3]) {
363
+ directories = urlParts[3].replace(/\\/g, "/").split("/");
364
+
365
+ // extract out . before .. so .. doesn't absorb a non-directory
366
+ for(i = 0; i < directories.length; i++) {
367
+ if (directories[i] === ".") {
368
+ directories.splice(i, 1);
369
+ i -= 1;
370
+ }
371
+ }
372
+
373
+ for(i = 0; i < directories.length; i++) {
374
+ if (directories[i] === ".." && i > 0) {
375
+ directories.splice(i-1, 2);
376
+ i -= 2;
377
+ }
378
+ }
379
+ }
380
+
381
+ returner.hostPart = urlParts[1];
382
+ returner.directories = directories;
383
+ returner.path = urlParts[1] + directories.join("/");
384
+ returner.fileUrl = returner.path + (urlParts[4] || "");
385
+ returner.url = returner.fileUrl + (urlParts[5] || "");
386
+ return returner;
387
+ }
388
+
389
+ function pathDiff(url, baseUrl) {
390
+ // diff between two paths to create a relative path
391
+
392
+ var urlParts = extractUrlParts(url),
393
+ baseUrlParts = extractUrlParts(baseUrl),
394
+ i, max, urlDirectories, baseUrlDirectories, diff = "";
395
+ if (urlParts.hostPart !== baseUrlParts.hostPart) {
396
+ return "";
397
+ }
398
+ max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
399
+ for(i = 0; i < max; i++) {
400
+ if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
401
+ }
402
+ baseUrlDirectories = baseUrlParts.directories.slice(i);
403
+ urlDirectories = urlParts.directories.slice(i);
404
+ for(i = 0; i < baseUrlDirectories.length-1; i++) {
405
+ diff += "../";
406
+ }
407
+ for(i = 0; i < urlDirectories.length-1; i++) {
408
+ diff += urlDirectories[i] + "/";
409
+ }
410
+ return diff;
411
+ }
412
+
413
+ function getXMLHttpRequest() {
414
+ if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject)) {
415
+ return new XMLHttpRequest();
416
+ } else {
417
+ try {
418
+ /*global ActiveXObject */
419
+ return new ActiveXObject("Microsoft.XMLHTTP");
420
+ } catch (e) {
421
+ log("browser doesn't support AJAX.", logLevel.errors);
422
+ return null;
423
+ }
424
+ }
425
+ }
426
+
427
+ function doXHR(url, type, callback, errback) {
428
+ var xhr = getXMLHttpRequest();
429
+ var async = isFileProtocol ? less.fileAsync : less.async;
430
+
431
+ if (typeof(xhr.overrideMimeType) === 'function') {
432
+ xhr.overrideMimeType('text/css');
433
+ }
434
+ log("XHR: Getting '" + url + "'", logLevel.debug);
435
+ xhr.open('GET', url, async);
436
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
437
+ xhr.send(null);
438
+
439
+ function handleResponse(xhr, callback, errback) {
440
+ if (xhr.status >= 200 && xhr.status < 300) {
441
+ callback(xhr.responseText,
442
+ xhr.getResponseHeader("Last-Modified"));
443
+ } else if (typeof(errback) === 'function') {
444
+ errback(xhr.status, url);
445
+ }
446
+ }
447
+
448
+ if (isFileProtocol && !less.fileAsync) {
449
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
450
+ callback(xhr.responseText);
451
+ } else {
452
+ errback(xhr.status, url);
453
+ }
454
+ } else if (async) {
455
+ xhr.onreadystatechange = function () {
456
+ if (xhr.readyState == 4) {
457
+ handleResponse(xhr, callback, errback);
458
+ }
459
+ };
460
+ } else {
461
+ handleResponse(xhr, callback, errback);
462
+ }
463
+ }
464
+
465
+ function loadFile(originalHref, currentFileInfo, callback, env, modifyVars) {
466
+
467
+ if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(originalHref)) {
468
+ originalHref = currentFileInfo.currentDirectory + originalHref;
469
+ }
470
+
471
+ // sheet may be set to the stylesheet for the initial load or a collection of properties including
472
+ // some env variables for imports
473
+ var hrefParts = extractUrlParts(originalHref, window.location.href);
474
+ var href = hrefParts.url;
475
+ var newFileInfo = {
476
+ currentDirectory: hrefParts.path,
477
+ filename: href
478
+ };
479
+
480
+ if (currentFileInfo) {
481
+ newFileInfo.entryPath = currentFileInfo.entryPath;
482
+ newFileInfo.rootpath = currentFileInfo.rootpath;
483
+ newFileInfo.rootFilename = currentFileInfo.rootFilename;
484
+ newFileInfo.relativeUrls = currentFileInfo.relativeUrls;
485
+ } else {
486
+ newFileInfo.entryPath = hrefParts.path;
487
+ newFileInfo.rootpath = less.rootpath || hrefParts.path;
488
+ newFileInfo.rootFilename = href;
489
+ newFileInfo.relativeUrls = env.relativeUrls;
490
+ }
491
+
492
+ if (newFileInfo.relativeUrls) {
493
+ if (env.rootpath) {
494
+ newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path;
495
+ } else {
496
+ newFileInfo.rootpath = hrefParts.path;
497
+ }
498
+ }
499
+
500
+ if (env.useFileCache && fileCache[href]) {
501
+ try {
502
+ var lessText = fileCache[href];
503
+ callback(null, lessText, href, newFileInfo, { lastModified: new Date() });
504
+ } catch (e) {
505
+ callback(e, null, href);
506
+ }
507
+ return;
508
+ }
509
+
510
+ doXHR(href, env.mime, function (data, lastModified) {
511
+ // per file cache
512
+ fileCache[href] = data;
513
+
514
+ // Use remote copy (re-parse)
515
+ try {
516
+ callback(null, data, href, newFileInfo, { lastModified: lastModified });
517
+ } catch (e) {
518
+ callback(e, null, href);
519
+ }
520
+ }, function (status, url) {
521
+ callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href);
522
+ });
523
+ }
524
+
525
+ function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
526
+
527
+ var env = new less.tree.parseEnv(less);
528
+ env.mime = sheet.type;
529
+
530
+ if (modifyVars || less.globalVars) {
531
+ env.useFileCache = true;
532
+ }
533
+
534
+ loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) {
535
+
536
+ if (webInfo) {
537
+ webInfo.remaining = remaining;
538
+
539
+ var css = cache && cache.getItem(path),
540
+ timestamp = cache && cache.getItem(path + ':timestamp');
541
+
542
+ if (!reload && timestamp && webInfo.lastModified &&
543
+ (new(Date)(webInfo.lastModified).valueOf() ===
544
+ new(Date)(timestamp).valueOf())) {
545
+ // Use local copy
546
+ createCSS(css, sheet);
547
+ webInfo.local = true;
548
+ callback(null, null, data, sheet, webInfo, path);
549
+ return;
550
+ }
551
+ }
552
+
553
+ //TODO add tests around how this behaves when reloading
554
+ removeError(path);
555
+
556
+ if (data) {
557
+ env.currentFileInfo = newFileInfo;
558
+ new(less.Parser)(env).parse(data, function (e, root) {
559
+ if (e) { return callback(e, null, null, sheet); }
560
+ try {
561
+ callback(e, root, data, sheet, webInfo, path);
562
+ } catch (e) {
563
+ callback(e, null, null, sheet);
564
+ }
565
+ }, {modifyVars: modifyVars, globalVars: less.globalVars});
566
+ } else {
567
+ callback(e, null, null, sheet, webInfo, path);
568
+ }
569
+ }, env, modifyVars);
570
+ }
571
+
572
+ function loadStyleSheets(callback, reload, modifyVars) {
573
+ for (var i = 0; i < less.sheets.length; i++) {
574
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);
575
+ }
576
+ }
577
+
578
+ function initRunningMode(){
579
+ if (less.env === 'development') {
580
+ less.optimization = 0;
581
+ less.watchTimer = setInterval(function () {
582
+ if (less.watchMode) {
583
+ loadStyleSheets(function (e, root, _, sheet, env) {
584
+ if (e) {
585
+ error(e, sheet.href);
586
+ } else if (root) {
587
+ var styles = root.toCSS(less);
588
+ styles = postProcessCSS(styles);
589
+ createCSS(styles, sheet, env.lastModified);
590
+ }
591
+ });
592
+ }
593
+ }, less.poll);
594
+ } else {
595
+ less.optimization = 3;
596
+ }
597
+ }
598
+
599
+
600
+
601
+ //
602
+ // Watch mode
603
+ //
604
+ less.watch = function () {
605
+ if (!less.watchMode ){
606
+ less.env = 'development';
607
+ initRunningMode();
608
+ }
609
+ this.watchMode = true;
610
+ return true;
611
+ };
612
+
613
+ less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };
614
+
615
+ if (/!watch/.test(location.hash)) {
616
+ less.watch();
617
+ }
618
+
619
+ if (less.env != 'development') {
620
+ try {
621
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
622
+ } catch (_) {}
623
+ }
624
+
625
+ //
626
+ // Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
627
+ //
628
+ var links = document.getElementsByTagName('link');
629
+
630
+ less.sheets = [];
631
+
632
+ for (var i = 0; i < links.length; i++) {
633
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
634
+ (links[i].type.match(typePattern)))) {
635
+ less.sheets.push(links[i]);
636
+ }
637
+ }
638
+
639
+ //
640
+ // With this function, it's possible to alter variables and re-render
641
+ // CSS without reloading less-files
642
+ //
643
+ less.modifyVars = function(record) {
644
+ less.refresh(false, record);
645
+ };
646
+
647
+ less.refresh = function (reload, modifyVars) {
648
+ var startTime, endTime;
649
+ startTime = endTime = new Date();
650
+
651
+ loadStyleSheets(function (e, root, _, sheet, env) {
652
+ if (e) {
653
+ return error(e, sheet.href);
654
+ }
655
+ if (env.local) {
656
+ log("loading " + sheet.href + " from cache.", logLevel.info);
657
+ } else {
658
+ log("parsed " + sheet.href + " successfully.", logLevel.debug);
659
+ var styles = root.toCSS(less);
660
+ styles = postProcessCSS(styles);
661
+ createCSS(styles, sheet, env.lastModified);
662
+ }
663
+ log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info);
664
+ if (env.remaining === 0) {
665
+ log("less has finished. css generated in " + (new Date() - startTime) + 'ms', logLevel.info);
666
+ }
667
+ endTime = new Date();
668
+ }, reload, modifyVars);
669
+
670
+ loadStyles(modifyVars);
671
+ };
672
+
673
+ less.refreshStyles = loadStyles;
674
+
675
+ less.Parser.fileLoader = loadFile;
676
+
677
+ less.refresh(less.env === 'development');