less 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
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');