less 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +4 -0
  3. data/Gemfile +1 -1
  4. data/less.gemspec +1 -1
  5. data/lib/less/defaults.rb +3 -3
  6. data/lib/less/java_script/v8_context.rb +1 -1
  7. data/lib/less/js/.gitattributes +3 -2
  8. data/lib/less/js/.gitignore +18 -2
  9. data/lib/less/js/.jshintrc +11 -0
  10. data/lib/less/js/CHANGELOG.md +87 -2
  11. data/lib/less/js/CONTRIBUTING.md +4 -3
  12. data/lib/less/js/Gruntfile.js +290 -0
  13. data/lib/less/js/README.md +342 -12
  14. data/lib/less/js/benchmark/benchmark.less +194 -194
  15. data/lib/less/js/benchmark/less-benchmark.js +9 -10
  16. data/lib/less/js/bin/lessc +154 -12
  17. data/lib/less/js/bower.json +18 -0
  18. data/lib/less/js/build.gradle +347 -0
  19. data/lib/less/js/build/README.md +350 -0
  20. data/lib/less/js/build/browser-header.js +4 -0
  21. data/lib/less/js/build/build.yml +160 -0
  22. data/lib/less/js/build/require-rhino.js +7 -2
  23. data/lib/less/js/build/rhino-header.js +4 -0
  24. data/lib/less/js/build/rhino-modules.js +131 -0
  25. data/lib/less/js/build/tasks/.gitkeep +1 -0
  26. data/lib/less/js/dist/less-1.5.0.js +6914 -0
  27. data/lib/less/js/dist/less-1.5.0.min.js +13 -0
  28. data/lib/less/js/dist/less-1.5.1.js +6941 -0
  29. data/lib/less/js/dist/less-1.5.1.min.js +13 -0
  30. data/lib/less/js/dist/less-1.6.0.js +7485 -0
  31. data/lib/less/js/dist/less-1.6.0.min.js +16 -0
  32. data/lib/less/js/dist/less-1.6.1.js +7513 -0
  33. data/lib/less/js/dist/less-1.6.1.min.js +16 -0
  34. data/lib/less/js/dist/less-1.6.2.js +7624 -0
  35. data/lib/less/js/dist/less-1.6.2.min.js +16 -0
  36. data/lib/less/js/dist/less-rhino-1.5.1.js +6831 -0
  37. data/lib/less/js/dist/less-rhino-1.6.2.js +9017 -0
  38. data/lib/less/js/dist/lessc-rhino-1.6.2.js +449 -0
  39. data/lib/less/js/gradle/wrapper/gradle-wrapper.jar +0 -0
  40. data/lib/less/js/gradle/wrapper/gradle-wrapper.properties +6 -0
  41. data/lib/less/js/gradlew +164 -0
  42. data/lib/less/js/gradlew.bat +90 -0
  43. data/lib/less/js/lib/less/browser.js +482 -367
  44. data/lib/less/js/lib/less/colors.js +0 -1
  45. data/lib/less/js/lib/less/encoder.js +4 -0
  46. data/lib/less/js/lib/less/env.js +50 -19
  47. data/lib/less/js/lib/less/extend-visitor.js +66 -41
  48. data/lib/less/js/lib/less/functions.js +309 -104
  49. data/lib/less/js/lib/less/import-visitor.js +21 -10
  50. data/lib/less/js/lib/less/index.js +90 -68
  51. data/lib/less/js/lib/less/join-selector-visitor.js +11 -4
  52. data/lib/less/js/lib/less/lessc_helper.js +56 -45
  53. data/lib/less/js/lib/less/parser.js +830 -460
  54. data/lib/less/js/lib/less/rhino.js +380 -58
  55. data/lib/less/js/lib/less/source-map-output.js +141 -0
  56. data/lib/less/js/lib/less/to-css-visitor.js +215 -0
  57. data/lib/less/js/lib/less/tree.js +57 -5
  58. data/lib/less/js/lib/less/tree/alpha.js +13 -5
  59. data/lib/less/js/lib/less/tree/anonymous.js +11 -5
  60. data/lib/less/js/lib/less/tree/assignment.js +11 -5
  61. data/lib/less/js/lib/less/tree/call.js +19 -8
  62. data/lib/less/js/lib/less/tree/color.js +59 -36
  63. data/lib/less/js/lib/less/tree/comment.js +17 -4
  64. data/lib/less/js/lib/less/tree/condition.js +3 -3
  65. data/lib/less/js/lib/less/tree/dimension.js +161 -153
  66. data/lib/less/js/lib/less/tree/directive.js +39 -18
  67. data/lib/less/js/lib/less/tree/element.js +41 -18
  68. data/lib/less/js/lib/less/tree/expression.js +11 -5
  69. data/lib/less/js/lib/less/tree/extend.js +11 -1
  70. data/lib/less/js/lib/less/tree/import.js +34 -20
  71. data/lib/less/js/lib/less/tree/javascript.js +16 -10
  72. data/lib/less/js/lib/less/tree/keyword.js +5 -2
  73. data/lib/less/js/lib/less/tree/media.js +39 -22
  74. data/lib/less/js/lib/less/tree/mixin.js +135 -56
  75. data/lib/less/js/lib/less/tree/negative.js +4 -2
  76. data/lib/less/js/lib/less/tree/operation.js +17 -12
  77. data/lib/less/js/lib/less/tree/paren.js +5 -2
  78. data/lib/less/js/lib/less/tree/quoted.js +9 -6
  79. data/lib/less/js/lib/less/tree/rule.js +39 -21
  80. data/lib/less/js/lib/less/tree/ruleset.js +229 -145
  81. data/lib/less/js/lib/less/tree/selector.js +101 -34
  82. data/lib/less/js/lib/less/tree/unicode-descriptor.js +4 -3
  83. data/lib/less/js/lib/less/tree/url.js +33 -11
  84. data/lib/less/js/lib/less/tree/value.js +13 -6
  85. data/lib/less/js/lib/less/tree/variable.js +13 -8
  86. data/lib/less/js/lib/less/visitor.js +117 -25
  87. data/lib/less/js/lib/source-map/source-map-0.1.31.js +1933 -0
  88. data/lib/less/js/lib/source-map/source-map-footer.js +4 -0
  89. data/lib/less/js/lib/source-map/source-map-header.js +3 -0
  90. data/lib/less/js/package.json +30 -15
  91. data/lib/less/js/test/browser/common.js +131 -56
  92. data/lib/less/js/test/browser/css/global-vars/simple.css +3 -0
  93. data/lib/less/js/test/browser/css/modify-vars/simple.css +8 -0
  94. data/lib/less/js/test/browser/css/relative-urls/urls.css +8 -9
  95. data/lib/less/js/test/browser/css/rootpath-relative/urls.css +0 -1
  96. data/lib/less/js/test/browser/css/rootpath/urls.css +0 -1
  97. data/lib/less/js/test/browser/css/urls.css +18 -14
  98. data/lib/less/js/test/browser/es5.js +27 -0
  99. data/lib/less/js/test/{less/errors/color-operation-error.less → browser/less/console-errors/test-error.less} +0 -0
  100. data/lib/less/js/test/browser/less/console-errors/test-error.txt +2 -0
  101. data/lib/less/js/test/browser/less/global-vars/simple.less +3 -0
  102. data/lib/less/js/test/browser/less/modify-vars/imports/simple2.less +4 -0
  103. data/lib/less/js/test/browser/less/modify-vars/simple.less +8 -0
  104. data/lib/less/js/test/browser/less/relative-urls/urls.less +1 -1
  105. data/lib/less/js/test/browser/less/rootpath-relative/urls.less +1 -1
  106. data/lib/less/js/test/browser/less/rootpath/urls.less +1 -1
  107. data/lib/less/js/test/browser/less/urls.less +9 -1
  108. data/lib/less/js/test/browser/phantom-runner.js +112 -103
  109. data/lib/less/js/test/browser/runner-browser-options.js +42 -0
  110. data/lib/less/js/test/browser/{runner-browser.js → runner-browser-spec.js} +7 -2
  111. data/lib/less/js/test/browser/runner-console-errors.js +5 -0
  112. data/lib/less/js/test/browser/runner-errors-options.js +5 -0
  113. data/lib/less/js/test/browser/runner-errors-spec.js +4 -0
  114. data/lib/less/js/test/browser/runner-global-vars-options.js +4 -0
  115. data/lib/less/js/test/browser/runner-global-vars-spec.js +3 -0
  116. data/lib/less/js/test/browser/runner-legacy-options.js +4 -0
  117. data/lib/less/js/test/browser/{runner-legacy.js → runner-legacy-spec.js} +1 -4
  118. data/lib/less/js/test/browser/runner-main-options.js +15 -0
  119. data/lib/less/js/test/browser/runner-main-spec.js +3 -0
  120. data/lib/less/js/test/browser/runner-modify-vars-options.js +2 -0
  121. data/lib/less/js/test/browser/runner-modify-vars-spec.js +43 -0
  122. data/lib/less/js/test/browser/runner-no-js-errors-options.js +4 -0
  123. data/lib/less/js/test/browser/runner-no-js-errors-spec.js +4 -0
  124. data/lib/less/js/test/browser/runner-production-options.js +3 -0
  125. data/lib/less/js/test/browser/{runner-production.js → runner-production-spec.js} +1 -3
  126. data/lib/less/js/test/browser/runner-relative-urls-options.js +3 -0
  127. data/lib/less/js/test/browser/{runner-relative-urls.js → runner-relative-urls-spec.js} +1 -2
  128. data/lib/less/js/test/browser/runner-rootpath-options.js +3 -0
  129. data/lib/less/js/test/browser/runner-rootpath-relative-options.js +4 -0
  130. data/lib/less/js/test/browser/{runner-rootpath-relative.js → runner-rootpath-relative-spec.js} +1 -3
  131. data/lib/less/js/test/browser/{runner-rootpath.js → runner-rootpath-spec.js} +1 -2
  132. data/lib/less/js/test/browser/test-runner-template.tmpl +47 -0
  133. data/lib/less/js/test/css/colors.css +7 -0
  134. data/lib/less/js/test/css/comments.css +9 -4
  135. data/lib/less/js/test/css/compression/compression.css +3 -2
  136. data/lib/less/js/test/css/css-3.css +17 -5
  137. data/lib/less/js/test/css/css-guards.css +37 -0
  138. data/lib/less/js/test/css/debug/linenumbers-all.css +6 -0
  139. data/lib/less/js/test/css/debug/linenumbers-comments.css +5 -0
  140. data/lib/less/js/test/css/debug/linenumbers-mediaquery.css +5 -0
  141. data/lib/less/js/test/css/empty.css +0 -0
  142. data/lib/less/js/test/css/extend-chaining.css +9 -0
  143. data/lib/less/js/test/css/extend-selector.css +10 -2
  144. data/lib/less/js/test/css/extract-and-length.css +133 -0
  145. data/lib/less/js/test/css/functions.css +23 -10
  146. data/lib/less/js/test/css/globalVars/extended.css +12 -0
  147. data/lib/less/js/test/css/globalVars/simple.css +6 -0
  148. data/lib/less/js/test/css/import-inline.css +5 -0
  149. data/lib/less/js/test/css/import-once.css +12 -0
  150. data/lib/less/js/test/css/import-reference.css +49 -0
  151. data/lib/less/js/test/css/import.css +0 -2
  152. data/lib/less/js/test/css/media.css +21 -5
  153. data/lib/less/js/test/css/merge.css +26 -0
  154. data/lib/less/js/test/css/mixins-guards-default-func.css +129 -0
  155. data/lib/less/js/test/css/mixins-guards.css +6 -0
  156. data/lib/less/js/test/css/mixins-important.css +7 -0
  157. data/lib/less/js/test/css/mixins-interpolated.css +39 -0
  158. data/lib/less/js/test/css/mixins.css +20 -0
  159. data/lib/less/js/test/css/modifyVars/extended.css +9 -0
  160. data/lib/less/js/test/css/no-output.css +0 -0
  161. data/lib/less/js/test/css/parens.css +3 -0
  162. data/lib/less/js/test/css/property-name-interp.css +20 -0
  163. data/lib/less/js/test/css/selectors.css +12 -0
  164. data/lib/less/js/test/css/static-urls/urls.css +7 -4
  165. data/lib/less/js/test/css/strings.css +3 -0
  166. data/lib/less/js/test/css/url-args/urls.css +56 -0
  167. data/lib/less/js/test/css/urls.css +21 -9
  168. data/lib/less/js/test/index.js +45 -0
  169. data/lib/less/js/test/less-test.js +234 -191
  170. data/lib/less/js/test/less/colors.less +6 -0
  171. data/lib/less/js/test/less/comments.less +7 -1
  172. data/lib/less/js/test/less/compression/compression.less +21 -1
  173. data/lib/less/js/test/less/css-3.less +12 -0
  174. data/lib/less/js/test/less/css-guards.less +99 -0
  175. data/lib/less/js/test/less/debug/linenumbers.less +11 -1
  176. data/lib/less/js/test/less/empty.less +0 -0
  177. data/lib/less/js/test/less/errors/add-mixed-units.txt +4 -2
  178. data/lib/less/js/test/less/errors/add-mixed-units2.txt +4 -2
  179. data/lib/less/js/test/less/errors/color-func-invalid-color.less +3 -0
  180. data/lib/less/js/test/less/errors/color-func-invalid-color.txt +4 -0
  181. data/lib/less/js/test/less/errors/css-guard-default-func.less +4 -0
  182. data/lib/less/js/test/less/errors/css-guard-default-func.txt +4 -0
  183. data/lib/less/js/test/less/errors/import-subfolder2.txt +4 -2
  184. data/lib/less/js/test/less/errors/javascript-undefined-var.less +3 -0
  185. data/lib/less/js/test/less/errors/javascript-undefined-var.txt +4 -0
  186. data/lib/less/js/test/less/errors/mixins-guards-default-func-1.less +9 -0
  187. data/lib/less/js/test/less/errors/mixins-guards-default-func-1.txt +4 -0
  188. data/lib/less/js/test/less/errors/mixins-guards-default-func-2.less +9 -0
  189. data/lib/less/js/test/less/errors/mixins-guards-default-func-2.txt +4 -0
  190. data/lib/less/js/test/less/errors/mixins-guards-default-func-3.less +9 -0
  191. data/lib/less/js/test/less/errors/mixins-guards-default-func-3.txt +4 -0
  192. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors.less +4 -0
  193. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors.txt +4 -0
  194. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors2.less +4 -0
  195. data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors2.txt +4 -0
  196. data/lib/less/js/test/less/errors/parse-error-curly-bracket.less +4 -1
  197. data/lib/less/js/test/less/errors/parse-error-curly-bracket.txt +4 -2
  198. data/lib/less/js/test/less/errors/parse-error-extra-parens.less +5 -0
  199. data/lib/less/js/test/less/errors/parse-error-extra-parens.txt +3 -0
  200. data/lib/less/js/test/less/errors/parse-error-missing-bracket.txt +2 -2
  201. data/lib/less/js/test/less/errors/parse-error-missing-parens.less +5 -0
  202. data/lib/less/js/test/less/errors/parse-error-missing-parens.txt +3 -0
  203. data/lib/less/js/test/less/errors/property-asterisk-only-name.less +3 -0
  204. data/lib/less/js/test/less/errors/property-asterisk-only-name.txt +4 -0
  205. data/lib/less/js/test/less/errors/property-interp-not-defined.less +1 -0
  206. data/lib/less/js/test/less/errors/property-interp-not-defined.txt +2 -0
  207. data/lib/less/js/test/less/errors/svg-gradient1.less +3 -0
  208. data/lib/less/js/test/less/errors/svg-gradient1.txt +4 -0
  209. data/lib/less/js/test/less/errors/svg-gradient2.less +3 -0
  210. data/lib/less/js/test/less/errors/svg-gradient2.txt +4 -0
  211. data/lib/less/js/test/less/errors/svg-gradient3.less +3 -0
  212. data/lib/less/js/test/less/errors/svg-gradient3.txt +4 -0
  213. data/lib/less/js/test/less/errors/unit-function.less +3 -0
  214. data/lib/less/js/test/less/errors/unit-function.txt +4 -0
  215. data/lib/less/js/test/less/extend-chaining.less +12 -0
  216. data/lib/less/js/test/less/extend-selector.less +15 -0
  217. data/lib/less/js/test/less/extract-and-length.less +133 -0
  218. data/lib/less/js/test/less/functions.less +15 -2
  219. data/lib/less/js/test/less/globalVars/extended.json +5 -0
  220. data/lib/less/js/test/less/globalVars/extended.less +10 -0
  221. data/lib/less/js/test/less/globalVars/simple.json +3 -0
  222. data/lib/less/js/test/less/globalVars/simple.less +3 -0
  223. data/lib/less/js/test/less/import-inline.less +2 -0
  224. data/lib/less/js/test/less/import-once.less +2 -0
  225. data/lib/less/js/test/less/import-reference.less +18 -0
  226. data/lib/less/js/test/less/import/import-and-relative-paths-test.less +11 -0
  227. data/lib/less/js/test/less/import/import-reference.less +43 -0
  228. data/lib/less/js/test/less/import/import-test-f.less +5 -0
  229. data/lib/less/js/test/less/import/invalid-css.less +1 -0
  230. data/lib/less/js/test/less/media.less +25 -1
  231. data/lib/less/js/test/less/merge.less +59 -0
  232. data/lib/less/js/test/less/mixins-args.less +10 -0
  233. data/lib/less/js/test/less/mixins-guards-default-func.less +195 -0
  234. data/lib/less/js/test/less/mixins-guards.less +16 -0
  235. data/lib/less/js/test/less/mixins-important.less +4 -1
  236. data/lib/less/js/test/less/mixins-interpolated.less +69 -0
  237. data/lib/less/js/test/less/mixins.less +27 -0
  238. data/lib/less/js/test/less/modifyVars/extended.json +5 -0
  239. data/lib/less/js/test/less/modifyVars/extended.less +11 -0
  240. data/lib/less/js/test/less/no-js-errors/no-js-errors.less +3 -0
  241. data/lib/less/js/test/less/no-js-errors/no-js-errors.txt +4 -0
  242. data/lib/less/js/test/less/no-output.less +2 -0
  243. data/lib/less/js/test/less/parens.less +4 -0
  244. data/lib/less/js/test/less/property-name-interp.less +53 -0
  245. data/lib/less/js/test/less/selectors.less +13 -0
  246. data/lib/less/js/test/less/sourcemaps/basic.json +3 -0
  247. data/lib/less/js/test/less/sourcemaps/basic.less +27 -0
  248. data/lib/less/js/test/less/sourcemaps/imported.css +7 -0
  249. data/lib/less/js/test/less/strings.less +6 -0
  250. data/lib/less/js/test/less/url-args/urls.less +63 -0
  251. data/lib/less/js/test/less/urls.less +15 -0
  252. data/lib/less/js/test/rhino/test-header.js +15 -0
  253. data/lib/less/js/test/sourcemaps/basic.json +1 -0
  254. data/lib/less/js/test/sourcemaps/index.html +17 -0
  255. data/lib/less/loader.rb +48 -40
  256. data/lib/less/version.rb +1 -1
  257. data/spec/less/parser_spec.rb +15 -15
  258. metadata +146 -40
  259. data/lib/less/js/Makefile +0 -102
  260. data/lib/less/js/build/header.js +0 -9
  261. data/lib/less/js/test/browser-test-prepare.js +0 -46
  262. data/lib/less/js/test/browser/runner-errors.js +0 -5
  263. data/lib/less/js/test/browser/runner-main.js +0 -15
  264. data/lib/less/js/test/browser/template.htm +0 -10
  265. data/lib/less/js/test/less/errors/color-operation-error.txt +0 -2
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ##############################################################################
4
+ ##
5
+ ## Gradle start up script for UN*X
6
+ ##
7
+ ##############################################################################
8
+
9
+ # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10
+ DEFAULT_JVM_OPTS=""
11
+
12
+ APP_NAME="Gradle"
13
+ APP_BASE_NAME=`basename "$0"`
14
+
15
+ # Use the maximum available, or set MAX_FD != -1 to use that value.
16
+ MAX_FD="maximum"
17
+
18
+ warn ( ) {
19
+ echo "$*"
20
+ }
21
+
22
+ die ( ) {
23
+ echo
24
+ echo "$*"
25
+ echo
26
+ exit 1
27
+ }
28
+
29
+ # OS specific support (must be 'true' or 'false').
30
+ cygwin=false
31
+ msys=false
32
+ darwin=false
33
+ case "`uname`" in
34
+ CYGWIN* )
35
+ cygwin=true
36
+ ;;
37
+ Darwin* )
38
+ darwin=true
39
+ ;;
40
+ MINGW* )
41
+ msys=true
42
+ ;;
43
+ esac
44
+
45
+ # For Cygwin, ensure paths are in UNIX format before anything is touched.
46
+ if $cygwin ; then
47
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48
+ fi
49
+
50
+ # Attempt to set APP_HOME
51
+ # Resolve links: $0 may be a link
52
+ PRG="$0"
53
+ # Need this for relative symlinks.
54
+ while [ -h "$PRG" ] ; do
55
+ ls=`ls -ld "$PRG"`
56
+ link=`expr "$ls" : '.*-> \(.*\)$'`
57
+ if expr "$link" : '/.*' > /dev/null; then
58
+ PRG="$link"
59
+ else
60
+ PRG=`dirname "$PRG"`"/$link"
61
+ fi
62
+ done
63
+ SAVED="`pwd`"
64
+ cd "`dirname \"$PRG\"`/" >&-
65
+ APP_HOME="`pwd -P`"
66
+ cd "$SAVED" >&-
67
+
68
+ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69
+
70
+ # Determine the Java command to use to start the JVM.
71
+ if [ -n "$JAVA_HOME" ] ; then
72
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73
+ # IBM's JDK on AIX uses strange locations for the executables
74
+ JAVACMD="$JAVA_HOME/jre/sh/java"
75
+ else
76
+ JAVACMD="$JAVA_HOME/bin/java"
77
+ fi
78
+ if [ ! -x "$JAVACMD" ] ; then
79
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80
+
81
+ Please set the JAVA_HOME variable in your environment to match the
82
+ location of your Java installation."
83
+ fi
84
+ else
85
+ JAVACMD="java"
86
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87
+
88
+ Please set the JAVA_HOME variable in your environment to match the
89
+ location of your Java installation."
90
+ fi
91
+
92
+ # Increase the maximum file descriptors if we can.
93
+ if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94
+ MAX_FD_LIMIT=`ulimit -H -n`
95
+ if [ $? -eq 0 ] ; then
96
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97
+ MAX_FD="$MAX_FD_LIMIT"
98
+ fi
99
+ ulimit -n $MAX_FD
100
+ if [ $? -ne 0 ] ; then
101
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
102
+ fi
103
+ else
104
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105
+ fi
106
+ fi
107
+
108
+ # For Darwin, add options to specify how the application appears in the dock
109
+ if $darwin; then
110
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111
+ fi
112
+
113
+ # For Cygwin, switch paths to Windows format before running java
114
+ if $cygwin ; then
115
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117
+
118
+ # We build the pattern for arguments to be converted via cygpath
119
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120
+ SEP=""
121
+ for dir in $ROOTDIRSRAW ; do
122
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
123
+ SEP="|"
124
+ done
125
+ OURCYGPATTERN="(^($ROOTDIRS))"
126
+ # Add a user-defined pattern to the cygpath arguments
127
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129
+ fi
130
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
131
+ i=0
132
+ for arg in "$@" ; do
133
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135
+
136
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138
+ else
139
+ eval `echo args$i`="\"$arg\""
140
+ fi
141
+ i=$((i+1))
142
+ done
143
+ case $i in
144
+ (0) set -- ;;
145
+ (1) set -- "$args0" ;;
146
+ (2) set -- "$args0" "$args1" ;;
147
+ (3) set -- "$args0" "$args1" "$args2" ;;
148
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154
+ esac
155
+ fi
156
+
157
+ # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158
+ function splitJvmOpts() {
159
+ JVM_OPTS=("$@")
160
+ }
161
+ eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162
+ JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163
+
164
+ exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@@ -0,0 +1,90 @@
1
+ @if "%DEBUG%" == "" @echo off
2
+ @rem ##########################################################################
3
+ @rem
4
+ @rem Gradle startup script for Windows
5
+ @rem
6
+ @rem ##########################################################################
7
+
8
+ @rem Set local scope for the variables with windows NT shell
9
+ if "%OS%"=="Windows_NT" setlocal
10
+
11
+ @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12
+ set DEFAULT_JVM_OPTS=
13
+
14
+ set DIRNAME=%~dp0
15
+ if "%DIRNAME%" == "" set DIRNAME=.
16
+ set APP_BASE_NAME=%~n0
17
+ set APP_HOME=%DIRNAME%
18
+
19
+ @rem Find java.exe
20
+ if defined JAVA_HOME goto findJavaFromJavaHome
21
+
22
+ set JAVA_EXE=java.exe
23
+ %JAVA_EXE% -version >NUL 2>&1
24
+ if "%ERRORLEVEL%" == "0" goto init
25
+
26
+ echo.
27
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
+ echo.
29
+ echo Please set the JAVA_HOME variable in your environment to match the
30
+ echo location of your Java installation.
31
+
32
+ goto fail
33
+
34
+ :findJavaFromJavaHome
35
+ set JAVA_HOME=%JAVA_HOME:"=%
36
+ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
+
38
+ if exist "%JAVA_EXE%" goto init
39
+
40
+ echo.
41
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
+ echo.
43
+ echo Please set the JAVA_HOME variable in your environment to match the
44
+ echo location of your Java installation.
45
+
46
+ goto fail
47
+
48
+ :init
49
+ @rem Get command-line arguments, handling Windowz variants
50
+
51
+ if not "%OS%" == "Windows_NT" goto win9xME_args
52
+ if "%@eval[2+2]" == "4" goto 4NT_args
53
+
54
+ :win9xME_args
55
+ @rem Slurp the command line arguments.
56
+ set CMD_LINE_ARGS=
57
+ set _SKIP=2
58
+
59
+ :win9xME_args_slurp
60
+ if "x%~1" == "x" goto execute
61
+
62
+ set CMD_LINE_ARGS=%*
63
+ goto execute
64
+
65
+ :4NT_args
66
+ @rem Get arguments from the 4NT Shell from JP Software
67
+ set CMD_LINE_ARGS=%$
68
+
69
+ :execute
70
+ @rem Setup the command line
71
+
72
+ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73
+
74
+ @rem Execute Gradle
75
+ "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76
+
77
+ :end
78
+ @rem End local scope for the variables with windows NT shell
79
+ if "%ERRORLEVEL%"=="0" goto mainEnd
80
+
81
+ :fail
82
+ rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83
+ rem the _cmd.exe /c_ return code!
84
+ if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85
+ exit /b 1
86
+
87
+ :mainEnd
88
+ if "%OS%"=="Windows_NT" endlocal
89
+
90
+ :omega
@@ -1,16 +1,31 @@
1
1
  //
2
2
  // browser.js - client-side engine
3
3
  //
4
+ /*global less, window, document, XMLHttpRequest, location */
4
5
 
5
6
  var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
6
7
 
7
8
  less.env = less.env || (location.hostname == '127.0.0.1' ||
8
9
  location.hostname == '0.0.0.0' ||
9
10
  location.hostname == 'localhost' ||
10
- location.port.length > 0 ||
11
+ (location.port &&
12
+ location.port.length > 0) ||
11
13
  isFileProtocol ? 'development'
12
14
  : 'production');
13
15
 
16
+ var logLevel = {
17
+ info: 2,
18
+ errors: 1,
19
+ none: 0
20
+ };
21
+
22
+ // The amount of logging in the javascript console.
23
+ // 2 - Information and errors
24
+ // 1 - Errors
25
+ // 0 - None
26
+ // Defaults to 2
27
+ less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : logLevel.info;
28
+
14
29
  // Load styles asynchronously (default: false)
15
30
  //
16
31
  // This is set to `false` by default, so that the body
@@ -26,7 +41,9 @@ less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
26
41
  //Setup user functions
27
42
  if (less.functions) {
28
43
  for(var func in less.functions) {
29
- less.tree.functions[func] = less.functions[func];
44
+ if (less.functions.hasOwnProperty(func)) {
45
+ less.tree.functions[func] = less.functions[func];
46
+ }
30
47
  }
31
48
  }
32
49
 
@@ -35,162 +52,275 @@ if (dumpLineNumbers) {
35
52
  less.dumpLineNumbers = dumpLineNumbers[1];
36
53
  }
37
54
 
38
- //
39
- // Watch mode
40
- //
41
- less.watch = function () {
42
- if (!less.watchMode ){
43
- less.env = 'development';
44
- initRunningMode();
45
- }
46
- return this.watchMode = true
47
- };
48
-
49
- less.unwatch = function () {clearInterval(less.watchTimer); return this.watchMode = false; };
55
+ var typePattern = /^text\/(x-)?less$/;
56
+ var cache = null;
57
+ var fileCache = {};
50
58
 
51
- function initRunningMode(){
52
- if (less.env === 'development') {
53
- less.optimization = 0;
54
- less.watchTimer = setInterval(function () {
55
- if (less.watchMode) {
56
- loadStyleSheets(function (e, root, _, sheet, env) {
57
- if (e) {
58
- error(e, sheet.href);
59
- } else if (root) {
60
- createCSS(root.toCSS(less), sheet, env.lastModified);
61
- }
62
- });
63
- }
64
- }, less.poll);
65
- } else {
66
- less.optimization = 3;
59
+ function log(str, level) {
60
+ if (less.env == 'development' && typeof(console) !== 'undefined' && less.logLevel >= level) {
61
+ console.log('less: ' + str);
67
62
  }
68
63
  }
69
64
 
70
- if (/!watch/.test(location.hash)) {
71
- less.watch();
65
+ function extractId(href) {
66
+ return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain
67
+ .replace(/^\//, '' ) // Remove root /
68
+ .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension
69
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
70
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
72
71
  }
73
72
 
74
- var cache = null;
73
+ function errorConsole(e, rootHref) {
74
+ var template = '{line} {content}';
75
+ var filename = e.filename || rootHref;
76
+ var errors = [];
77
+ var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
78
+ " in " + filename + " ";
75
79
 
76
- if (less.env != 'development') {
77
- try {
78
- cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
79
- } catch (_) {}
80
+ var errorline = function (e, i, classname) {
81
+ if (e.extract[i] !== undefined) {
82
+ errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
83
+ .replace(/\{class\}/, classname)
84
+ .replace(/\{content\}/, e.extract[i]));
85
+ }
86
+ };
87
+
88
+ if (e.extract) {
89
+ errorline(e, 0, '');
90
+ errorline(e, 1, 'line');
91
+ errorline(e, 2, '');
92
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' +
93
+ errors.join('\n');
94
+ } else if (e.stack) {
95
+ content += e.stack;
96
+ }
97
+ log(content, logLevel.errors);
80
98
  }
81
99
 
82
- //
83
- // Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
84
- //
85
- var links = document.getElementsByTagName('link');
86
- var typePattern = /^text\/(x-)?less$/;
100
+ function createCSS(styles, sheet, lastModified) {
101
+ // Strip the query-string
102
+ var href = sheet.href || '';
87
103
 
88
- less.sheets = [];
104
+ // If there is no title set, use the filename, minus the extension
105
+ var id = 'less:' + (sheet.title || extractId(href));
89
106
 
90
- for (var i = 0; i < links.length; i++) {
91
- if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
92
- (links[i].type.match(typePattern)))) {
93
- less.sheets.push(links[i]);
107
+ // If this has already been inserted into the DOM, we may need to replace it
108
+ var oldCss = document.getElementById(id);
109
+ var keepOldCss = false;
110
+
111
+ // Create a new stylesheet node for insertion or (if necessary) replacement
112
+ var css = document.createElement('style');
113
+ css.setAttribute('type', 'text/css');
114
+ if (sheet.media) {
115
+ css.setAttribute('media', sheet.media);
94
116
  }
95
- }
117
+ css.id = id;
96
118
 
97
- //
98
- // With this function, it's possible to alter variables and re-render
99
- // CSS without reloading less-files
100
- //
101
- var session_cache = '';
102
- less.modifyVars = function(record) {
103
- var str = session_cache;
104
- for (var name in record) {
105
- str += ((name.slice(0,1) === '@')? '' : '@') + name +': '+
106
- ((record[name].slice(-1) === ';')? record[name] : record[name] +';');
119
+ if (css.styleSheet) { // IE
120
+ try {
121
+ css.styleSheet.cssText = styles;
122
+ } catch (e) {
123
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
124
+ }
125
+ } else {
126
+ css.appendChild(document.createTextNode(styles));
127
+
128
+ // If new contents match contents of oldCss, don't replace oldCss
129
+ keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 &&
130
+ oldCss.firstChild.nodeValue === css.firstChild.nodeValue);
107
131
  }
108
- new(less.Parser)(new less.tree.parseEnv(less)).parse(str, function (e, root) {
109
- if (e) {
110
- error(e, "session_cache");
132
+
133
+ var head = document.getElementsByTagName('head')[0];
134
+
135
+ // If there is no oldCss, just append; otherwise, only append if we need
136
+ // to replace oldCss with an updated stylesheet
137
+ if (oldCss === null || keepOldCss === false) {
138
+ var nextEl = sheet && sheet.nextSibling || null;
139
+ if (nextEl) {
140
+ nextEl.parentNode.insertBefore(css, nextEl);
111
141
  } else {
112
- createCSS(root.toCSS(less), less.sheets[less.sheets.length - 1]);
142
+ head.appendChild(css);
113
143
  }
114
- });
115
- };
116
-
117
- less.refresh = function (reload) {
118
- var startTime, endTime;
119
- startTime = endTime = new(Date);
144
+ }
145
+ if (oldCss && keepOldCss === false) {
146
+ oldCss.parentNode.removeChild(oldCss);
147
+ }
120
148
 
121
- loadStyleSheets(function (e, root, _, sheet, env) {
122
- if (e) {
123
- return error(e, sheet.href);
149
+ // Don't update the local store if the file wasn't modified
150
+ if (lastModified && cache) {
151
+ log('saving ' + href + ' to cache.', logLevel.info);
152
+ try {
153
+ cache.setItem(href, styles);
154
+ cache.setItem(href + ':timestamp', lastModified);
155
+ } catch(e) {
156
+ //TODO - could do with adding more robust error handling
157
+ log('failed to save', logLevel.errors);
124
158
  }
125
- if (env.local) {
126
- log("loading " + sheet.href + " from cache.");
127
- } else {
128
- log("parsed " + sheet.href + " successfully.");
129
- createCSS(root.toCSS(less), sheet, env.lastModified);
159
+ }
160
+ }
161
+
162
+ function errorHTML(e, rootHref) {
163
+ var id = 'less-error-message:' + extractId(rootHref || "");
164
+ var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
165
+ var elem = document.createElement('div'), timer, content, errors = [];
166
+ var filename = e.filename || rootHref;
167
+ var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
168
+
169
+ elem.id = id;
170
+ elem.className = "less-error-message";
171
+
172
+ content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
173
+ '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
174
+
175
+ var errorline = function (e, i, classname) {
176
+ if (e.extract[i] !== undefined) {
177
+ errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
178
+ .replace(/\{class\}/, classname)
179
+ .replace(/\{content\}/, e.extract[i]));
130
180
  }
131
- log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
132
- (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
133
- endTime = new(Date);
134
- }, reload);
181
+ };
135
182
 
136
- loadStyles();
137
- };
138
- less.refreshStyles = loadStyles;
183
+ if (e.extract) {
184
+ errorline(e, 0, '');
185
+ errorline(e, 1, 'line');
186
+ errorline(e, 2, '');
187
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
188
+ '<ul>' + errors.join('') + '</ul>';
189
+ } else if (e.stack) {
190
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
191
+ }
192
+ elem.innerHTML = content;
139
193
 
140
- less.refresh(less.env === 'development');
194
+ // CSS for error messages
195
+ createCSS([
196
+ '.less-error-message ul, .less-error-message li {',
197
+ 'list-style-type: none;',
198
+ 'margin-right: 15px;',
199
+ 'padding: 4px 0;',
200
+ 'margin: 0;',
201
+ '}',
202
+ '.less-error-message label {',
203
+ 'font-size: 12px;',
204
+ 'margin-right: 15px;',
205
+ 'padding: 4px 0;',
206
+ 'color: #cc7777;',
207
+ '}',
208
+ '.less-error-message pre {',
209
+ 'color: #dd6666;',
210
+ 'padding: 4px 0;',
211
+ 'margin: 0;',
212
+ 'display: inline-block;',
213
+ '}',
214
+ '.less-error-message pre.line {',
215
+ 'color: #ff0000;',
216
+ '}',
217
+ '.less-error-message h3 {',
218
+ 'font-size: 20px;',
219
+ 'font-weight: bold;',
220
+ 'padding: 15px 0 5px 0;',
221
+ 'margin: 0;',
222
+ '}',
223
+ '.less-error-message a {',
224
+ 'color: #10a',
225
+ '}',
226
+ '.less-error-message .error {',
227
+ 'color: red;',
228
+ 'font-weight: bold;',
229
+ 'padding-bottom: 2px;',
230
+ 'border-bottom: 1px dashed red;',
231
+ '}'
232
+ ].join('\n'), { title: 'error-message' });
141
233
 
142
- function loadStyles() {
143
- var styles = document.getElementsByTagName('style');
144
- for (var i = 0; i < styles.length; i++) {
145
- if (styles[i].type.match(typePattern)) {
146
- var env = new less.tree.parseEnv(less);
147
- env.filename = document.location.href.replace(/#.*$/, '');
234
+ elem.style.cssText = [
235
+ "font-family: Arial, sans-serif",
236
+ "border: 1px solid #e00",
237
+ "background-color: #eee",
238
+ "border-radius: 5px",
239
+ "-webkit-border-radius: 5px",
240
+ "-moz-border-radius: 5px",
241
+ "color: #e00",
242
+ "padding: 15px",
243
+ "margin-bottom: 15px"
244
+ ].join(';');
148
245
 
149
- new(less.Parser)(env).parse(styles[i].innerHTML || '', function (e, cssAST) {
150
- if (e) {
151
- return error(e, "inline");
152
- }
153
- var css = cssAST.toCSS(less);
154
- var style = styles[i];
155
- style.type = 'text/css';
156
- if (style.styleSheet) {
157
- style.styleSheet.cssText = css;
246
+ if (less.env == 'development') {
247
+ timer = setInterval(function () {
248
+ if (document.body) {
249
+ if (document.getElementById(id)) {
250
+ document.body.replaceChild(elem, document.getElementById(id));
158
251
  } else {
159
- style.innerHTML = css;
252
+ document.body.insertBefore(elem, document.body.firstChild);
160
253
  }
161
- });
162
- }
254
+ clearInterval(timer);
255
+ }
256
+ }, 10);
163
257
  }
164
258
  }
165
259
 
166
- function loadStyleSheets(callback, reload) {
167
- for (var i = 0; i < less.sheets.length; i++) {
168
- loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
260
+ function error(e, rootHref) {
261
+ if (!less.errorReporting || less.errorReporting === "html") {
262
+ errorHTML(e, rootHref);
263
+ } else if (less.errorReporting === "console") {
264
+ errorConsole(e, rootHref);
265
+ } else if (typeof less.errorReporting === 'function') {
266
+ less.errorReporting("add", e, rootHref);
169
267
  }
170
268
  }
171
269
 
172
- function pathDiff(url, baseUrl) {
173
- // diff between two paths to create a relative path
174
-
175
- var urlParts = extractUrlParts(url),
176
- baseUrlParts = extractUrlParts(baseUrl),
177
- i, max, urlDirectories, baseUrlDirectories, diff = "";
178
- if (urlParts.hostPart !== baseUrlParts.hostPart) {
179
- return "";
270
+ function removeErrorHTML(path) {
271
+ var node = document.getElementById('less-error-message:' + extractId(path));
272
+ if (node) {
273
+ node.parentNode.removeChild(node);
180
274
  }
181
- max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
182
- for(i = 0; i < max; i++) {
183
- if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
184
- }
185
- baseUrlDirectories = baseUrlParts.directories.slice(i);
186
- urlDirectories = urlParts.directories.slice(i);
187
- for(i = 0; i < baseUrlDirectories.length-1; i++) {
188
- diff += "../";
275
+ }
276
+
277
+ function removeErrorConsole(path) {
278
+ //no action
279
+ }
280
+
281
+ function removeError(path) {
282
+ if (!less.errorReporting || less.errorReporting === "html") {
283
+ removeErrorHTML(path);
284
+ } else if (less.errorReporting === "console") {
285
+ removeErrorConsole(path);
286
+ } else if (typeof less.errorReporting === 'function') {
287
+ less.errorReporting("remove", path);
189
288
  }
190
- for(i = 0; i < urlDirectories.length-1; i++) {
191
- diff += urlDirectories[i] + "/";
289
+ }
290
+
291
+ function loadStyles(modifyVars) {
292
+ var styles = document.getElementsByTagName('style'),
293
+ style;
294
+ for (var i = 0; i < styles.length; i++) {
295
+ style = styles[i];
296
+ if (style.type.match(typePattern)) {
297
+ var env = new less.tree.parseEnv(less),
298
+ lessText = style.innerHTML || '';
299
+ env.filename = document.location.href.replace(/#.*$/, '');
300
+
301
+ if (modifyVars || less.globalVars) {
302
+ env.useFileCache = true;
303
+ }
304
+
305
+ /*jshint loopfunc:true */
306
+ // use closure to store current value of i
307
+ var callback = (function(style) {
308
+ return function (e, cssAST) {
309
+ if (e) {
310
+ return error(e, "inline");
311
+ }
312
+ var css = cssAST.toCSS(less);
313
+ style.type = 'text/css';
314
+ if (style.styleSheet) {
315
+ style.styleSheet.cssText = css;
316
+ } else {
317
+ style.innerHTML = css;
318
+ }
319
+ };
320
+ })(style);
321
+ new(less.Parser)(env).parse(lessText, callback, {globalVars: less.globalVars, modifyVars: modifyVars});
322
+ }
192
323
  }
193
- return diff;
194
324
  }
195
325
 
196
326
  function extractUrlParts(url, baseUrl) {
@@ -208,7 +338,7 @@ function extractUrlParts(url, baseUrl) {
208
338
  throw new Error("Could not parse sheet href - '"+url+"'");
209
339
  }
210
340
 
211
- // Stylesheets in IE don't always return the full path
341
+ // Stylesheets in IE don't always return the full path
212
342
  if (!urlParts[1] || urlParts[2]) {
213
343
  baseUrlParts = baseUrl.match(urlPartsRegex);
214
344
  if (!baseUrlParts) {
@@ -219,7 +349,7 @@ function extractUrlParts(url, baseUrl) {
219
349
  urlParts[3] = baseUrlParts[3] + urlParts[3];
220
350
  }
221
351
  }
222
-
352
+
223
353
  if (urlParts[3]) {
224
354
  directories = urlParts[3].replace(/\\/g, "/").split("/");
225
355
 
@@ -247,162 +377,65 @@ function extractUrlParts(url, baseUrl) {
247
377
  return returner;
248
378
  }
249
379
 
250
- function loadStyleSheet(sheet, callback, reload, remaining) {
251
-
252
- // sheet may be set to the stylesheet for the initial load or a collection of properties including
253
- // some env variables for imports
254
- var hrefParts = extractUrlParts(sheet.href, window.location.href);
255
- var href = hrefParts.url;
256
- var css = cache && cache.getItem(href);
257
- var timestamp = cache && cache.getItem(href + ':timestamp');
258
- var styles = { css: css, timestamp: timestamp };
259
- var env;
260
- var newFileInfo = {
261
- relativeUrls: less.relativeUrls,
262
- currentDirectory: hrefParts.path,
263
- filename: href
264
- };
380
+ function pathDiff(url, baseUrl) {
381
+ // diff between two paths to create a relative path
265
382
 
266
- if (sheet instanceof less.tree.parseEnv) {
267
- env = new less.tree.parseEnv(sheet);
268
- newFileInfo.entryPath = env.currentFileInfo.entryPath;
269
- newFileInfo.rootpath = env.currentFileInfo.rootpath;
270
- newFileInfo.rootFilename = env.currentFileInfo.rootFilename;
271
- } else {
272
- env = new less.tree.parseEnv(less);
273
- env.mime = sheet.type;
274
- newFileInfo.entryPath = hrefParts.path;
275
- newFileInfo.rootpath = less.rootpath || hrefParts.path;
276
- newFileInfo.rootFilename = href;
383
+ var urlParts = extractUrlParts(url),
384
+ baseUrlParts = extractUrlParts(baseUrl),
385
+ i, max, urlDirectories, baseUrlDirectories, diff = "";
386
+ if (urlParts.hostPart !== baseUrlParts.hostPart) {
387
+ return "";
277
388
  }
278
-
279
- if (env.relativeUrls) {
280
- //todo - this relies on option being set on less object rather than being passed in as an option
281
- // - need an originalRootpath
282
- if (less.rootpath) {
283
- newFileInfo.rootpath = extractUrlParts(less.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path;
284
- } else {
285
- newFileInfo.rootpath = hrefParts.path;
286
- }
389
+ max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
390
+ for(i = 0; i < max; i++) {
391
+ if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
287
392
  }
288
-
289
- xhr(href, sheet.type, function (data, lastModified) {
290
- // Store data this session
291
- session_cache += data.replace(/@import .+?;/ig, '');
292
-
293
- if (!reload && styles && lastModified &&
294
- (new(Date)(lastModified).valueOf() ===
295
- new(Date)(styles.timestamp).valueOf())) {
296
- // Use local copy
297
- createCSS(styles.css, sheet);
298
- callback(null, null, data, sheet, { local: true, remaining: remaining }, href);
299
- } else {
300
- // Use remote copy (re-parse)
301
- try {
302
- env.contents[href] = data; // Updating content cache
303
- env.paths = [hrefParts.path];
304
- env.currentFileInfo = newFileInfo;
305
-
306
- new(less.Parser)(env).parse(data, function (e, root) {
307
- if (e) { return callback(e, null, null, sheet); }
308
- try {
309
- callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining }, href);
310
- //TODO - there must be a better way? A generic less-to-css function that can both call error
311
- //and removeNode where appropriate
312
- //should also add tests
313
- if (env.currentFileInfo.rootFilename === href) {
314
- removeNode(document.getElementById('less-error-message:' + extractId(href)));
315
- }
316
- } catch (e) {
317
- callback(e, null, null, sheet);
318
- }
319
- });
320
- } catch (e) {
321
- callback(e, null, null, sheet);
322
- }
323
- }
324
- }, function (status, url) {
325
- callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, null, sheet);
326
- });
327
- }
328
-
329
- function extractId(href) {
330
- return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain
331
- .replace(/^\//, '' ) // Remove root /
332
- .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension
333
- .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
334
- .replace(/\./g, ':'); // Replace dots with colons(for valid id)
335
- }
336
-
337
- function createCSS(styles, sheet, lastModified) {
338
- // Strip the query-string
339
- var href = sheet.href || '';
340
-
341
- // If there is no title set, use the filename, minus the extension
342
- var id = 'less:' + (sheet.title || extractId(href));
343
-
344
- // If this has already been inserted into the DOM, we may need to replace it
345
- var oldCss = document.getElementById(id);
346
- var keepOldCss = false;
347
-
348
- // Create a new stylesheet node for insertion or (if necessary) replacement
349
- var css = document.createElement('style');
350
- css.setAttribute('type', 'text/css');
351
- if (sheet.media) {
352
- css.setAttribute('media', sheet.media);
353
- }
354
- css.id = id;
355
-
356
- if (css.styleSheet) { // IE
357
- try {
358
- css.styleSheet.cssText = styles;
359
- } catch (e) {
360
- throw new(Error)("Couldn't reassign styleSheet.cssText.");
361
- }
362
- } else {
363
- css.appendChild(document.createTextNode(styles));
364
-
365
- // If new contents match contents of oldCss, don't replace oldCss
366
- keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 &&
367
- oldCss.firstChild.nodeValue === css.firstChild.nodeValue);
368
- }
369
-
370
- var head = document.getElementsByTagName('head')[0];
371
-
372
- // If there is no oldCss, just append; otherwise, only append if we need
373
- // to replace oldCss with an updated stylesheet
374
- if (oldCss == null || keepOldCss === false) {
375
- var nextEl = sheet && sheet.nextSibling || null;
376
- (nextEl || document.getElementsByTagName('head')[0]).parentNode.insertBefore(css, nextEl);
393
+ baseUrlDirectories = baseUrlParts.directories.slice(i);
394
+ urlDirectories = urlParts.directories.slice(i);
395
+ for(i = 0; i < baseUrlDirectories.length-1; i++) {
396
+ diff += "../";
377
397
  }
378
- if (oldCss && keepOldCss === false) {
379
- head.removeChild(oldCss);
398
+ for(i = 0; i < urlDirectories.length-1; i++) {
399
+ diff += urlDirectories[i] + "/";
380
400
  }
401
+ return diff;
402
+ }
381
403
 
382
- // Don't update the local store if the file wasn't modified
383
- if (lastModified && cache) {
384
- log('saving ' + href + ' to cache.');
404
+ function getXMLHttpRequest() {
405
+ if (window.XMLHttpRequest) {
406
+ return new XMLHttpRequest();
407
+ } else {
385
408
  try {
386
- cache.setItem(href, styles);
387
- cache.setItem(href + ':timestamp', lastModified);
388
- } catch(e) {
389
- //TODO - could do with adding more robust error handling
390
- log('failed to save');
409
+ /*global ActiveXObject */
410
+ return new ActiveXObject("MSXML2.XMLHTTP.3.0");
411
+ } catch (e) {
412
+ log("browser doesn't support AJAX.", logLevel.errors);
413
+ return null;
391
414
  }
392
415
  }
393
416
  }
394
417
 
395
- function xhr(url, type, callback, errback) {
418
+ function doXHR(url, type, callback, errback) {
396
419
  var xhr = getXMLHttpRequest();
397
420
  var async = isFileProtocol ? less.fileAsync : less.async;
398
421
 
399
422
  if (typeof(xhr.overrideMimeType) === 'function') {
400
423
  xhr.overrideMimeType('text/css');
401
424
  }
425
+ log("XHR: Getting '" + url + "'", logLevel.info);
402
426
  xhr.open('GET', url, async);
403
427
  xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
404
428
  xhr.send(null);
405
429
 
430
+ function handleResponse(xhr, callback, errback) {
431
+ if (xhr.status >= 200 && xhr.status < 300) {
432
+ callback(xhr.responseText,
433
+ xhr.getResponseHeader("Last-Modified"));
434
+ } else if (typeof(errback) === 'function') {
435
+ errback(xhr.status, url);
436
+ }
437
+ }
438
+
406
439
  if (isFileProtocol && !less.fileAsync) {
407
440
  if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
408
441
  callback(xhr.responseText);
@@ -418,132 +451,214 @@ function xhr(url, type, callback, errback) {
418
451
  } else {
419
452
  handleResponse(xhr, callback, errback);
420
453
  }
454
+ }
421
455
 
422
- function handleResponse(xhr, callback, errback) {
423
- if (xhr.status >= 200 && xhr.status < 300) {
424
- callback(xhr.responseText,
425
- xhr.getResponseHeader("Last-Modified"));
426
- } else if (typeof(errback) === 'function') {
427
- errback(xhr.status, url);
428
- }
456
+ function loadFile(originalHref, currentFileInfo, callback, env, modifyVars) {
457
+
458
+ if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(originalHref)) {
459
+ originalHref = currentFileInfo.currentDirectory + originalHref;
429
460
  }
430
- }
431
461
 
432
- function getXMLHttpRequest() {
433
- if (window.XMLHttpRequest) {
434
- return new(XMLHttpRequest);
462
+ // sheet may be set to the stylesheet for the initial load or a collection of properties including
463
+ // some env variables for imports
464
+ var hrefParts = extractUrlParts(originalHref, window.location.href);
465
+ var href = hrefParts.url;
466
+ var newFileInfo = {
467
+ currentDirectory: hrefParts.path,
468
+ filename: href
469
+ };
470
+
471
+ if (currentFileInfo) {
472
+ newFileInfo.entryPath = currentFileInfo.entryPath;
473
+ newFileInfo.rootpath = currentFileInfo.rootpath;
474
+ newFileInfo.rootFilename = currentFileInfo.rootFilename;
475
+ newFileInfo.relativeUrls = currentFileInfo.relativeUrls;
435
476
  } else {
477
+ newFileInfo.entryPath = hrefParts.path;
478
+ newFileInfo.rootpath = less.rootpath || hrefParts.path;
479
+ newFileInfo.rootFilename = href;
480
+ newFileInfo.relativeUrls = env.relativeUrls;
481
+ }
482
+
483
+ if (newFileInfo.relativeUrls) {
484
+ if (env.rootpath) {
485
+ newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path;
486
+ } else {
487
+ newFileInfo.rootpath = hrefParts.path;
488
+ }
489
+ }
490
+
491
+ if (env.useFileCache && fileCache[href]) {
436
492
  try {
437
- return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
493
+ var lessText = fileCache[href];
494
+ callback(null, lessText, href, newFileInfo, { lastModified: new Date() });
438
495
  } catch (e) {
439
- log("browser doesn't support AJAX.");
440
- return null;
496
+ callback(e, null, href);
441
497
  }
498
+ return;
442
499
  }
443
- }
444
500
 
445
- function removeNode(node) {
446
- return node && node.parentNode.removeChild(node);
447
- }
501
+ doXHR(href, env.mime, function (data, lastModified) {
502
+ // per file cache
503
+ fileCache[href] = data;
448
504
 
449
- function log(str) {
450
- if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
505
+ // Use remote copy (re-parse)
506
+ try {
507
+ callback(null, data, href, newFileInfo, { lastModified: lastModified });
508
+ } catch (e) {
509
+ callback(e, null, href);
510
+ }
511
+ }, function (status, url) {
512
+ callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href);
513
+ });
451
514
  }
452
515
 
453
- function error(e, rootHref) {
454
- var id = 'less-error-message:' + extractId(rootHref || "");
455
- var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
456
- var elem = document.createElement('div'), timer, content, error = [];
457
- var filename = e.filename || rootHref;
458
- var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
516
+ function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
459
517
 
460
- elem.id = id;
461
- elem.className = "less-error-message";
518
+ var env = new less.tree.parseEnv(less);
519
+ env.mime = sheet.type;
462
520
 
463
- content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
464
- '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
521
+ if (modifyVars || less.globalVars) {
522
+ env.useFileCache = true;
523
+ }
465
524
 
466
- var errorline = function (e, i, classname) {
467
- if (e.extract[i] != undefined) {
468
- error.push(template.replace(/\{line\}/, (parseInt(e.line) || 0) + (i - 1))
469
- .replace(/\{class\}/, classname)
470
- .replace(/\{content\}/, e.extract[i]));
471
- }
472
- };
525
+ loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) {
473
526
 
474
- if (e.extract) {
475
- errorline(e, 0, '');
476
- errorline(e, 1, 'line');
477
- errorline(e, 2, '');
478
- content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
479
- '<ul>' + error.join('') + '</ul>';
480
- } else if (e.stack) {
481
- content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
482
- }
483
- elem.innerHTML = content;
527
+ if (webInfo) {
528
+ webInfo.remaining = remaining;
484
529
 
485
- // CSS for error messages
486
- createCSS([
487
- '.less-error-message ul, .less-error-message li {',
488
- 'list-style-type: none;',
489
- 'margin-right: 15px;',
490
- 'padding: 4px 0;',
491
- 'margin: 0;',
492
- '}',
493
- '.less-error-message label {',
494
- 'font-size: 12px;',
495
- 'margin-right: 15px;',
496
- 'padding: 4px 0;',
497
- 'color: #cc7777;',
498
- '}',
499
- '.less-error-message pre {',
500
- 'color: #dd6666;',
501
- 'padding: 4px 0;',
502
- 'margin: 0;',
503
- 'display: inline-block;',
504
- '}',
505
- '.less-error-message pre.line {',
506
- 'color: #ff0000;',
507
- '}',
508
- '.less-error-message h3 {',
509
- 'font-size: 20px;',
510
- 'font-weight: bold;',
511
- 'padding: 15px 0 5px 0;',
512
- 'margin: 0;',
513
- '}',
514
- '.less-error-message a {',
515
- 'color: #10a',
516
- '}',
517
- '.less-error-message .error {',
518
- 'color: red;',
519
- 'font-weight: bold;',
520
- 'padding-bottom: 2px;',
521
- 'border-bottom: 1px dashed red;',
522
- '}'
523
- ].join('\n'), { title: 'error-message' });
530
+ var css = cache && cache.getItem(path),
531
+ timestamp = cache && cache.getItem(path + ':timestamp');
524
532
 
525
- elem.style.cssText = [
526
- "font-family: Arial, sans-serif",
527
- "border: 1px solid #e00",
528
- "background-color: #eee",
529
- "border-radius: 5px",
530
- "-webkit-border-radius: 5px",
531
- "-moz-border-radius: 5px",
532
- "color: #e00",
533
- "padding: 15px",
534
- "margin-bottom: 15px"
535
- ].join(';');
533
+ if (!reload && timestamp && webInfo.lastModified &&
534
+ (new(Date)(webInfo.lastModified).valueOf() ===
535
+ new(Date)(timestamp).valueOf())) {
536
+ // Use local copy
537
+ createCSS(css, sheet);
538
+ webInfo.local = true;
539
+ callback(null, null, data, sheet, webInfo, path);
540
+ return;
541
+ }
542
+ }
536
543
 
537
- if (less.env == 'development') {
538
- timer = setInterval(function () {
539
- if (document.body) {
540
- if (document.getElementById(id)) {
541
- document.body.replaceChild(elem, document.getElementById(id));
542
- } else {
543
- document.body.insertBefore(elem, document.body.firstChild);
544
+ //TODO add tests around how this behaves when reloading
545
+ removeError(path);
546
+
547
+ if (data) {
548
+ env.currentFileInfo = newFileInfo;
549
+ new(less.Parser)(env).parse(data, function (e, root) {
550
+ if (e) { return callback(e, null, null, sheet); }
551
+ try {
552
+ callback(e, root, data, sheet, webInfo, path);
553
+ } catch (e) {
554
+ callback(e, null, null, sheet);
544
555
  }
545
- clearInterval(timer);
556
+ }, {modifyVars: modifyVars, globalVars: less.globalVars});
557
+ } else {
558
+ callback(e, null, null, sheet, webInfo, path);
559
+ }
560
+ }, env, modifyVars);
561
+ }
562
+
563
+ function loadStyleSheets(callback, reload, modifyVars) {
564
+ for (var i = 0; i < less.sheets.length; i++) {
565
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);
566
+ }
567
+ }
568
+
569
+ function initRunningMode(){
570
+ if (less.env === 'development') {
571
+ less.optimization = 0;
572
+ less.watchTimer = setInterval(function () {
573
+ if (less.watchMode) {
574
+ loadStyleSheets(function (e, root, _, sheet, env) {
575
+ if (e) {
576
+ error(e, sheet.href);
577
+ } else if (root) {
578
+ createCSS(root.toCSS(less), sheet, env.lastModified);
579
+ }
580
+ });
546
581
  }
547
- }, 10);
582
+ }, less.poll);
583
+ } else {
584
+ less.optimization = 3;
585
+ }
586
+ }
587
+
588
+
589
+
590
+ //
591
+ // Watch mode
592
+ //
593
+ less.watch = function () {
594
+ if (!less.watchMode ){
595
+ less.env = 'development';
596
+ initRunningMode();
597
+ }
598
+ this.watchMode = true;
599
+ return true;
600
+ };
601
+
602
+ less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };
603
+
604
+ if (/!watch/.test(location.hash)) {
605
+ less.watch();
606
+ }
607
+
608
+ if (less.env != 'development') {
609
+ try {
610
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
611
+ } catch (_) {}
612
+ }
613
+
614
+ //
615
+ // Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
616
+ //
617
+ var links = document.getElementsByTagName('link');
618
+
619
+ less.sheets = [];
620
+
621
+ for (var i = 0; i < links.length; i++) {
622
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
623
+ (links[i].type.match(typePattern)))) {
624
+ less.sheets.push(links[i]);
548
625
  }
549
626
  }
627
+
628
+ //
629
+ // With this function, it's possible to alter variables and re-render
630
+ // CSS without reloading less-files
631
+ //
632
+ less.modifyVars = function(record) {
633
+ less.refresh(false, record);
634
+ };
635
+
636
+ less.refresh = function (reload, modifyVars) {
637
+ var startTime, endTime;
638
+ startTime = endTime = new Date();
639
+
640
+ loadStyleSheets(function (e, root, _, sheet, env) {
641
+ if (e) {
642
+ return error(e, sheet.href);
643
+ }
644
+ if (env.local) {
645
+ log("loading " + sheet.href + " from cache.", logLevel.info);
646
+ } else {
647
+ log("parsed " + sheet.href + " successfully.", logLevel.info);
648
+ createCSS(root.toCSS(less), sheet, env.lastModified);
649
+ }
650
+ log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info);
651
+ if (env.remaining === 0) {
652
+ log("css generated in " + (new Date() - startTime) + 'ms', logLevel.info);
653
+ }
654
+ endTime = new Date();
655
+ }, reload, modifyVars);
656
+
657
+ loadStyles(modifyVars);
658
+ };
659
+
660
+ less.refreshStyles = loadStyles;
661
+
662
+ less.Parser.fileLoader = loadFile;
663
+
664
+ less.refresh(less.env === 'development');