xass 0.1.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 (242) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +11 -0
  3. data/CONTRIBUTING +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +201 -0
  6. data/Rakefile +349 -0
  7. data/VERSION +1 -0
  8. data/VERSION_NAME +1 -0
  9. data/bin/push +13 -0
  10. data/bin/sass +13 -0
  11. data/bin/sass-convert +12 -0
  12. data/bin/scss +13 -0
  13. data/extra/update_watch.rb +13 -0
  14. data/init.rb +18 -0
  15. data/lib/sass/cache_stores/base.rb +88 -0
  16. data/lib/sass/cache_stores/chain.rb +33 -0
  17. data/lib/sass/cache_stores/filesystem.rb +64 -0
  18. data/lib/sass/cache_stores/memory.rb +47 -0
  19. data/lib/sass/cache_stores/null.rb +25 -0
  20. data/lib/sass/cache_stores.rb +15 -0
  21. data/lib/sass/callbacks.rb +66 -0
  22. data/lib/sass/css.rb +409 -0
  23. data/lib/sass/engine.rb +930 -0
  24. data/lib/sass/environment.rb +101 -0
  25. data/lib/sass/error.rb +201 -0
  26. data/lib/sass/exec.rb +707 -0
  27. data/lib/sass/importers/base.rb +139 -0
  28. data/lib/sass/importers/filesystem.rb +186 -0
  29. data/lib/sass/importers.rb +22 -0
  30. data/lib/sass/logger/base.rb +32 -0
  31. data/lib/sass/logger/log_level.rb +49 -0
  32. data/lib/sass/logger.rb +15 -0
  33. data/lib/sass/media.rb +213 -0
  34. data/lib/sass/plugin/compiler.rb +406 -0
  35. data/lib/sass/plugin/configuration.rb +123 -0
  36. data/lib/sass/plugin/generic.rb +15 -0
  37. data/lib/sass/plugin/merb.rb +48 -0
  38. data/lib/sass/plugin/rack.rb +60 -0
  39. data/lib/sass/plugin/rails.rb +47 -0
  40. data/lib/sass/plugin/staleness_checker.rb +199 -0
  41. data/lib/sass/plugin.rb +133 -0
  42. data/lib/sass/railtie.rb +10 -0
  43. data/lib/sass/repl.rb +57 -0
  44. data/lib/sass/root.rb +7 -0
  45. data/lib/sass/script/arg_list.rb +52 -0
  46. data/lib/sass/script/bool.rb +18 -0
  47. data/lib/sass/script/color.rb +606 -0
  48. data/lib/sass/script/css_lexer.rb +29 -0
  49. data/lib/sass/script/css_parser.rb +31 -0
  50. data/lib/sass/script/funcall.rb +245 -0
  51. data/lib/sass/script/functions.rb +1543 -0
  52. data/lib/sass/script/interpolation.rb +79 -0
  53. data/lib/sass/script/lexer.rb +345 -0
  54. data/lib/sass/script/list.rb +85 -0
  55. data/lib/sass/script/literal.rb +221 -0
  56. data/lib/sass/script/node.rb +99 -0
  57. data/lib/sass/script/null.rb +37 -0
  58. data/lib/sass/script/number.rb +453 -0
  59. data/lib/sass/script/operation.rb +110 -0
  60. data/lib/sass/script/parser.rb +502 -0
  61. data/lib/sass/script/string.rb +51 -0
  62. data/lib/sass/script/string_interpolation.rb +103 -0
  63. data/lib/sass/script/unary_operation.rb +69 -0
  64. data/lib/sass/script/variable.rb +58 -0
  65. data/lib/sass/script.rb +39 -0
  66. data/lib/sass/scss/css_parser.rb +36 -0
  67. data/lib/sass/scss/parser.rb +1180 -0
  68. data/lib/sass/scss/rx.rb +133 -0
  69. data/lib/sass/scss/script_lexer.rb +15 -0
  70. data/lib/sass/scss/script_parser.rb +25 -0
  71. data/lib/sass/scss/static_parser.rb +54 -0
  72. data/lib/sass/scss.rb +16 -0
  73. data/lib/sass/selector/abstract_sequence.rb +94 -0
  74. data/lib/sass/selector/comma_sequence.rb +92 -0
  75. data/lib/sass/selector/sequence.rb +507 -0
  76. data/lib/sass/selector/simple.rb +119 -0
  77. data/lib/sass/selector/simple_sequence.rb +215 -0
  78. data/lib/sass/selector.rb +452 -0
  79. data/lib/sass/shared.rb +76 -0
  80. data/lib/sass/supports.rb +229 -0
  81. data/lib/sass/tree/charset_node.rb +22 -0
  82. data/lib/sass/tree/comment_node.rb +82 -0
  83. data/lib/sass/tree/content_node.rb +9 -0
  84. data/lib/sass/tree/css_import_node.rb +60 -0
  85. data/lib/sass/tree/debug_node.rb +18 -0
  86. data/lib/sass/tree/directive_node.rb +42 -0
  87. data/lib/sass/tree/each_node.rb +24 -0
  88. data/lib/sass/tree/extend_node.rb +36 -0
  89. data/lib/sass/tree/for_node.rb +36 -0
  90. data/lib/sass/tree/function_node.rb +34 -0
  91. data/lib/sass/tree/if_node.rb +52 -0
  92. data/lib/sass/tree/import_node.rb +75 -0
  93. data/lib/sass/tree/media_node.rb +58 -0
  94. data/lib/sass/tree/mixin_def_node.rb +38 -0
  95. data/lib/sass/tree/mixin_node.rb +39 -0
  96. data/lib/sass/tree/node.rb +196 -0
  97. data/lib/sass/tree/prop_node.rb +152 -0
  98. data/lib/sass/tree/return_node.rb +18 -0
  99. data/lib/sass/tree/root_node.rb +78 -0
  100. data/lib/sass/tree/rule_node.rb +132 -0
  101. data/lib/sass/tree/supports_node.rb +51 -0
  102. data/lib/sass/tree/trace_node.rb +32 -0
  103. data/lib/sass/tree/variable_node.rb +30 -0
  104. data/lib/sass/tree/visitors/base.rb +75 -0
  105. data/lib/sass/tree/visitors/check_nesting.rb +147 -0
  106. data/lib/sass/tree/visitors/convert.rb +316 -0
  107. data/lib/sass/tree/visitors/cssize.rb +241 -0
  108. data/lib/sass/tree/visitors/deep_copy.rb +102 -0
  109. data/lib/sass/tree/visitors/extend.rb +68 -0
  110. data/lib/sass/tree/visitors/perform.rb +446 -0
  111. data/lib/sass/tree/visitors/set_options.rb +125 -0
  112. data/lib/sass/tree/visitors/to_css.rb +228 -0
  113. data/lib/sass/tree/warn_node.rb +18 -0
  114. data/lib/sass/tree/while_node.rb +18 -0
  115. data/lib/sass/util/multibyte_string_scanner.rb +155 -0
  116. data/lib/sass/util/subset_map.rb +109 -0
  117. data/lib/sass/util/test.rb +10 -0
  118. data/lib/sass/util.rb +948 -0
  119. data/lib/sass/version.rb +126 -0
  120. data/lib/sass.rb +95 -0
  121. data/rails/init.rb +1 -0
  122. data/test/Gemfile +3 -0
  123. data/test/Gemfile.lock +10 -0
  124. data/test/sass/cache_test.rb +89 -0
  125. data/test/sass/callbacks_test.rb +61 -0
  126. data/test/sass/conversion_test.rb +1760 -0
  127. data/test/sass/css2sass_test.rb +458 -0
  128. data/test/sass/data/hsl-rgb.txt +319 -0
  129. data/test/sass/engine_test.rb +3244 -0
  130. data/test/sass/exec_test.rb +86 -0
  131. data/test/sass/extend_test.rb +1482 -0
  132. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  133. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  134. data/test/sass/functions_test.rb +1139 -0
  135. data/test/sass/importer_test.rb +192 -0
  136. data/test/sass/logger_test.rb +58 -0
  137. data/test/sass/mock_importer.rb +49 -0
  138. data/test/sass/more_results/more1.css +9 -0
  139. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  140. data/test/sass/more_results/more_import.css +29 -0
  141. data/test/sass/more_templates/_more_partial.sass +2 -0
  142. data/test/sass/more_templates/more1.sass +23 -0
  143. data/test/sass/more_templates/more_import.sass +11 -0
  144. data/test/sass/plugin_test.rb +564 -0
  145. data/test/sass/results/alt.css +4 -0
  146. data/test/sass/results/basic.css +9 -0
  147. data/test/sass/results/cached_import_option.css +3 -0
  148. data/test/sass/results/compact.css +5 -0
  149. data/test/sass/results/complex.css +86 -0
  150. data/test/sass/results/compressed.css +1 -0
  151. data/test/sass/results/expanded.css +19 -0
  152. data/test/sass/results/filename_fn.css +3 -0
  153. data/test/sass/results/if.css +3 -0
  154. data/test/sass/results/import.css +31 -0
  155. data/test/sass/results/import_charset.css +5 -0
  156. data/test/sass/results/import_charset_1_8.css +5 -0
  157. data/test/sass/results/import_charset_ibm866.css +5 -0
  158. data/test/sass/results/import_content.css +1 -0
  159. data/test/sass/results/line_numbers.css +49 -0
  160. data/test/sass/results/mixins.css +95 -0
  161. data/test/sass/results/multiline.css +24 -0
  162. data/test/sass/results/nested.css +22 -0
  163. data/test/sass/results/options.css +1 -0
  164. data/test/sass/results/parent_ref.css +13 -0
  165. data/test/sass/results/script.css +16 -0
  166. data/test/sass/results/scss_import.css +31 -0
  167. data/test/sass/results/scss_importee.css +2 -0
  168. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  169. data/test/sass/results/subdir/subdir.css +3 -0
  170. data/test/sass/results/units.css +11 -0
  171. data/test/sass/results/warn.css +0 -0
  172. data/test/sass/results/warn_imported.css +0 -0
  173. data/test/sass/script_conversion_test.rb +299 -0
  174. data/test/sass/script_test.rb +622 -0
  175. data/test/sass/scss/css_test.rb +1100 -0
  176. data/test/sass/scss/rx_test.rb +156 -0
  177. data/test/sass/scss/scss_test.rb +2106 -0
  178. data/test/sass/scss/test_helper.rb +37 -0
  179. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  180. data/test/sass/templates/_double_import_loop2.sass +1 -0
  181. data/test/sass/templates/_filename_fn_import.scss +11 -0
  182. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  183. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  184. data/test/sass/templates/_imported_content.sass +3 -0
  185. data/test/sass/templates/_partial.sass +2 -0
  186. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  187. data/test/sass/templates/alt.sass +16 -0
  188. data/test/sass/templates/basic.sass +23 -0
  189. data/test/sass/templates/bork1.sass +2 -0
  190. data/test/sass/templates/bork2.sass +2 -0
  191. data/test/sass/templates/bork3.sass +2 -0
  192. data/test/sass/templates/bork4.sass +2 -0
  193. data/test/sass/templates/bork5.sass +3 -0
  194. data/test/sass/templates/cached_import_option.scss +3 -0
  195. data/test/sass/templates/compact.sass +17 -0
  196. data/test/sass/templates/complex.sass +305 -0
  197. data/test/sass/templates/compressed.sass +15 -0
  198. data/test/sass/templates/double_import_loop1.sass +1 -0
  199. data/test/sass/templates/expanded.sass +17 -0
  200. data/test/sass/templates/filename_fn.scss +18 -0
  201. data/test/sass/templates/if.sass +11 -0
  202. data/test/sass/templates/import.sass +12 -0
  203. data/test/sass/templates/import_charset.sass +9 -0
  204. data/test/sass/templates/import_charset_1_8.sass +6 -0
  205. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  206. data/test/sass/templates/import_content.sass +4 -0
  207. data/test/sass/templates/importee.less +2 -0
  208. data/test/sass/templates/importee.sass +19 -0
  209. data/test/sass/templates/line_numbers.sass +13 -0
  210. data/test/sass/templates/mixin_bork.sass +5 -0
  211. data/test/sass/templates/mixins.sass +76 -0
  212. data/test/sass/templates/multiline.sass +20 -0
  213. data/test/sass/templates/nested.sass +25 -0
  214. data/test/sass/templates/nested_bork1.sass +2 -0
  215. data/test/sass/templates/nested_bork2.sass +2 -0
  216. data/test/sass/templates/nested_bork3.sass +2 -0
  217. data/test/sass/templates/nested_bork4.sass +2 -0
  218. data/test/sass/templates/nested_import.sass +2 -0
  219. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  220. data/test/sass/templates/options.sass +2 -0
  221. data/test/sass/templates/parent_ref.sass +25 -0
  222. data/test/sass/templates/same_name_different_ext.sass +2 -0
  223. data/test/sass/templates/same_name_different_ext.scss +1 -0
  224. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  225. data/test/sass/templates/script.sass +101 -0
  226. data/test/sass/templates/scss_import.scss +11 -0
  227. data/test/sass/templates/scss_importee.scss +1 -0
  228. data/test/sass/templates/single_import_loop.sass +1 -0
  229. data/test/sass/templates/subdir/import_up1.scss +1 -0
  230. data/test/sass/templates/subdir/import_up2.scss +1 -0
  231. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  232. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  233. data/test/sass/templates/subdir/subdir.sass +6 -0
  234. data/test/sass/templates/units.sass +11 -0
  235. data/test/sass/templates/warn.sass +3 -0
  236. data/test/sass/templates/warn_imported.sass +4 -0
  237. data/test/sass/test_helper.rb +8 -0
  238. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  239. data/test/sass/util/subset_map_test.rb +91 -0
  240. data/test/sass/util_test.rb +382 -0
  241. data/test/test_helper.rb +80 -0
  242. metadata +354 -0
@@ -0,0 +1,47 @@
1
+ unless defined?(Sass::RAILS_LOADED)
2
+ Sass::RAILS_LOADED = true
3
+
4
+ module Sass::Plugin::Configuration
5
+ # Different default options in a rails envirionment.
6
+ def default_options
7
+ return @default_options if @default_options
8
+ opts = {
9
+ :quiet => Sass::Util.rails_env != "production",
10
+ :full_exception => Sass::Util.rails_env != "production",
11
+ :cache_location => Sass::Util.rails_root + '/tmp/sass-cache'
12
+ }
13
+
14
+ opts.merge!(
15
+ :always_update => false,
16
+ :template_location => Sass::Util.rails_root + '/public/stylesheets/sass',
17
+ :css_location => Sass::Util.rails_root + '/public/stylesheets',
18
+ :always_check => Sass::Util.rails_env == "development")
19
+
20
+ @default_options = opts.freeze
21
+ end
22
+ end
23
+
24
+ Sass::Plugin.options.reverse_merge!(Sass::Plugin.default_options)
25
+
26
+ # Rails 3.1 loads and handles Sass all on its own
27
+ if defined?(ActionController::Metal)
28
+ # 3.1 > Rails >= 3.0
29
+ require 'sass/plugin/rack'
30
+ Rails.configuration.middleware.use(Sass::Plugin::Rack)
31
+ elsif defined?(ActionController::Dispatcher) &&
32
+ defined?(ActionController::Dispatcher.middleware)
33
+ # Rails >= 2.3
34
+ require 'sass/plugin/rack'
35
+ ActionController::Dispatcher.middleware.use(Sass::Plugin::Rack)
36
+ else
37
+ module ActionController
38
+ class Base
39
+ alias_method :sass_old_process, :process
40
+ def process(*args)
41
+ Sass::Plugin.check_for_updates
42
+ sass_old_process(*args)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,199 @@
1
+ require 'thread'
2
+
3
+ module Sass
4
+ module Plugin
5
+ # The class handles `.s[ca]ss` file staleness checks via their mtime timestamps.
6
+ #
7
+ # To speed things up two level of caches are employed:
8
+ #
9
+ # * A class-level dependency cache which stores @import paths for each file.
10
+ # This is a long-lived cache that is reused by every StalenessChecker instance.
11
+ # * Three short-lived instance-level caches, one for file mtimes,
12
+ # one for whether a file is stale during this particular run.
13
+ # and one for the parse tree for a file.
14
+ # These are only used by a single StalenessChecker instance.
15
+ #
16
+ # Usage:
17
+ #
18
+ # * For a one-off staleness check of a single `.s[ca]ss` file,
19
+ # the class-level {stylesheet_needs_update?} method
20
+ # should be used.
21
+ # * For a series of staleness checks (e.g. checking all files for staleness)
22
+ # a StalenessChecker instance should be created,
23
+ # and the instance-level \{#stylesheet\_needs\_update?} method should be used.
24
+ # the caches should make the whole process significantly faster.
25
+ # *WARNING*: It is important not to retain the instance for too long,
26
+ # as its instance-level caches are never explicitly expired.
27
+ class StalenessChecker
28
+ @dependencies_cache = {}
29
+ @dependency_cache_mutex = Mutex.new
30
+
31
+ class << self
32
+ # TODO: attach this to a compiler instance.
33
+ # @private
34
+ attr_accessor :dependencies_cache
35
+ attr_reader :dependency_cache_mutex
36
+ end
37
+
38
+ # Creates a new StalenessChecker
39
+ # for checking the staleness of several stylesheets at once.
40
+ #
41
+ # @param options [{Symbol => Object}]
42
+ # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
43
+ def initialize(options)
44
+ # URIs that are being actively checked for staleness. Protects against
45
+ # import loops.
46
+ @actively_checking = Set.new
47
+
48
+ # Entries in the following instance-level caches are never explicitly expired.
49
+ # Instead they are supposed to automaticaly go out of scope when a series of staleness checks
50
+ # (this instance of StalenessChecker was created for) is finished.
51
+ @mtimes, @dependencies_stale, @parse_trees = {}, {}, {}
52
+ @options = Sass::Engine.normalize_options(options)
53
+ end
54
+
55
+ # Returns whether or not a given CSS file is out of date
56
+ # and needs to be regenerated.
57
+ #
58
+ # @param css_file [String] The location of the CSS file to check.
59
+ # @param template_file [String] The location of the Sass or SCSS template
60
+ # that is compiled to `css_file`.
61
+ # @return [Boolean] Whether the stylesheet needs to be updated.
62
+ def stylesheet_needs_update?(css_file, template_file, importer = nil)
63
+ template_file = File.expand_path(template_file)
64
+ begin
65
+ css_mtime = File.mtime(css_file)
66
+ rescue Errno::ENOENT
67
+ return true
68
+ end
69
+ stylesheet_modified_since?(template_file, css_mtime, importer)
70
+ end
71
+
72
+ # Returns whether a Sass or SCSS stylesheet has been modified since a given time.
73
+ #
74
+ # @param template_file [String] The location of the Sass or SCSS template.
75
+ # @param mtime [Fixnum] The modification time to check against.
76
+ # @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
77
+ # Defaults to the filesystem importer.
78
+ # @return [Boolean] Whether the stylesheet has been modified.
79
+ def stylesheet_modified_since?(template_file, mtime, importer = nil)
80
+ importer ||= @options[:filesystem_importer].new(".")
81
+ dependency_updated?(mtime).call(template_file, importer)
82
+ end
83
+
84
+ # Returns whether or not a given CSS file is out of date
85
+ # and needs to be regenerated.
86
+ #
87
+ # The distinction between this method and the instance-level \{#stylesheet\_needs\_update?}
88
+ # is that the instance method preserves mtime and stale-dependency caches,
89
+ # so it's better to use when checking multiple stylesheets at once.
90
+ #
91
+ # @param css_file [String] The location of the CSS file to check.
92
+ # @param template_file [String] The location of the Sass or SCSS template
93
+ # that is compiled to `css_file`.
94
+ # @return [Boolean] Whether the stylesheet needs to be updated.
95
+ def self.stylesheet_needs_update?(css_file, template_file, importer = nil)
96
+ new(Plugin.engine_options).stylesheet_needs_update?(css_file, template_file, importer)
97
+ end
98
+
99
+ # Returns whether a Sass or SCSS stylesheet has been modified since a given time.
100
+ #
101
+ # The distinction between this method and the instance-level \{#stylesheet\_modified\_since?}
102
+ # is that the instance method preserves mtime and stale-dependency caches,
103
+ # so it's better to use when checking multiple stylesheets at once.
104
+ #
105
+ # @param template_file [String] The location of the Sass or SCSS template.
106
+ # @param mtime [Fixnum] The modification time to check against.
107
+ # @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
108
+ # Defaults to the filesystem importer.
109
+ # @return [Boolean] Whether the stylesheet has been modified.
110
+ def self.stylesheet_modified_since?(template_file, mtime, importer = nil)
111
+ new(Plugin.engine_options).stylesheet_modified_since?(template_file, mtime, importer)
112
+ end
113
+
114
+ private
115
+
116
+ def dependencies_stale?(uri, importer, css_mtime)
117
+ timestamps = @dependencies_stale[[uri, importer]] ||= {}
118
+ timestamps.each_pair do |checked_css_mtime, is_stale|
119
+ if checked_css_mtime <= css_mtime && !is_stale
120
+ return false
121
+ elsif checked_css_mtime > css_mtime && is_stale
122
+ return true
123
+ end
124
+ end
125
+ timestamps[css_mtime] = dependencies(uri, importer).any?(&dependency_updated?(css_mtime))
126
+ rescue Sass::SyntaxError
127
+ # If there's an error finding dependencies, default to recompiling.
128
+ true
129
+ end
130
+
131
+ def mtime(uri, importer)
132
+ @mtimes[[uri, importer]] ||=
133
+ begin
134
+ mtime = importer.mtime(uri, @options)
135
+ if mtime.nil?
136
+ with_dependency_cache {|cache| cache.delete([uri, importer])}
137
+ nil
138
+ else
139
+ mtime
140
+ end
141
+ end
142
+ end
143
+
144
+ def dependencies(uri, importer)
145
+ stored_mtime, dependencies =
146
+ with_dependency_cache {|cache| Sass::Util.destructure(cache[[uri, importer]])}
147
+
148
+ if !stored_mtime || stored_mtime < mtime(uri, importer)
149
+ dependencies = compute_dependencies(uri, importer)
150
+ with_dependency_cache do |cache|
151
+ cache[[uri, importer]] = [mtime(uri, importer), dependencies]
152
+ end
153
+ end
154
+
155
+ dependencies
156
+ end
157
+
158
+ def dependency_updated?(css_mtime)
159
+ Proc.new do |uri, importer|
160
+ next true if @actively_checking.include?(uri)
161
+ begin
162
+ @actively_checking << uri
163
+ sass_mtime = mtime(uri, importer)
164
+ !sass_mtime ||
165
+ sass_mtime > css_mtime ||
166
+ dependencies_stale?(uri, importer, css_mtime)
167
+ ensure
168
+ @actively_checking.delete uri
169
+ end
170
+ end
171
+ end
172
+
173
+ def compute_dependencies(uri, importer)
174
+ tree(uri, importer).grep(Tree::ImportNode) do |n|
175
+ next if n.css_import?
176
+ file = n.imported_file
177
+ key = [file.options[:filename], file.options[:importer]]
178
+ @parse_trees[key] = file.to_tree
179
+ key
180
+ end.compact
181
+ end
182
+
183
+ def tree(uri, importer)
184
+ @parse_trees[[uri, importer]] ||= importer.find(uri, @options).to_tree
185
+ end
186
+
187
+ # Get access to the global dependency cache in a threadsafe manner.
188
+ # Inside the block, no other thread can access the dependency cache.
189
+ #
190
+ # @yieldparam cache [Hash] The hash that is the global dependency cache
191
+ # @return The value returned by the block to which this method yields
192
+ def with_dependency_cache
193
+ StalenessChecker.dependency_cache_mutex.synchronize do
194
+ yield StalenessChecker.dependencies_cache
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,133 @@
1
+ require 'fileutils'
2
+
3
+ require 'sass'
4
+ require 'sass/plugin/compiler'
5
+
6
+ module Sass
7
+ # This module provides a single interface to the compilation of Sass/SCSS files
8
+ # for an application. It provides global options and checks whether CSS files
9
+ # need to be updated.
10
+ #
11
+ # This module is used as the primary interface with Sass
12
+ # when it's used as a plugin for various frameworks.
13
+ # All Rack-enabled frameworks are supported out of the box.
14
+ # The plugin is {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}.
15
+ # Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
16
+ #
17
+ # This module has a large set of callbacks available
18
+ # to allow users to run code (such as logging) when certain things happen.
19
+ # All callback methods are of the form `on_#{name}`,
20
+ # and they all take a block that's called when the given action occurs.
21
+ #
22
+ # Note that this class proxies almost all methods to its {Sass::Plugin::Compiler} instance.
23
+ # See \{#compiler}.
24
+ #
25
+ # @example Using a callback
26
+ # Sass::Plugin.on_updating_stylesheet do |template, css|
27
+ # puts "Compiling #{template} to #{css}"
28
+ # end
29
+ # Sass::Plugin.update_stylesheets
30
+ # #=> Compiling app/sass/screen.scss to public/stylesheets/screen.css
31
+ # #=> Compiling app/sass/print.scss to public/stylesheets/print.css
32
+ # #=> Compiling app/sass/ie.scss to public/stylesheets/ie.css
33
+ # @see Sass::Plugin::Compiler
34
+ module Plugin
35
+ include Sass::Util
36
+ extend self
37
+
38
+ @checked_for_updates = false
39
+
40
+ # Whether or not Sass has **ever** checked if the stylesheets need to be updated
41
+ # (in this Ruby instance).
42
+ #
43
+ # @return [Boolean]
44
+ attr_accessor :checked_for_updates
45
+
46
+ # Same as \{#update\_stylesheets}, but respects \{#checked\_for\_updates}
47
+ # and the {file:SASS_REFERENCE.md#always_update-option `:always_update`}
48
+ # and {file:SASS_REFERENCE.md#always_check-option `:always_check`} options.
49
+ #
50
+ # @see #update_stylesheets
51
+ def check_for_updates
52
+ return unless !Sass::Plugin.checked_for_updates ||
53
+ Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
54
+ update_stylesheets
55
+ end
56
+
57
+ # Returns the singleton compiler instance.
58
+ # This compiler has been pre-configured according
59
+ # to the plugin configuration.
60
+ #
61
+ # @return [Sass::Plugin::Compiler]
62
+ def compiler
63
+ @compiler ||= Compiler.new
64
+ end
65
+
66
+ # Updates out-of-date stylesheets.
67
+ #
68
+ # Checks each Sass/SCSS file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}
69
+ # to see if it's been modified more recently than the corresponding CSS file
70
+ # in {file:SASS_REFERENCE.md#css_location-option `:css_location`}.
71
+ # If it has, it updates the CSS file.
72
+ #
73
+ # @param individual_files [Array<(String, String)>]
74
+ # A list of files to check for updates
75
+ # **in addition to those specified by the
76
+ # {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
77
+ # The first string in each pair is the location of the Sass/SCSS file,
78
+ # the second is the location of the CSS file that it should be compiled to.
79
+ def update_stylesheets(individual_files = [])
80
+ return if options[:never_update]
81
+ compiler.update_stylesheets(individual_files)
82
+ end
83
+
84
+ # Updates all stylesheets, even those that aren't out-of-date.
85
+ # Ignores the cache.
86
+ #
87
+ # @param individual_files [Array<(String, String)>]
88
+ # A list of files to check for updates
89
+ # **in addition to those specified by the
90
+ # {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
91
+ # The first string in each pair is the location of the Sass/SCSS file,
92
+ # the second is the location of the CSS file that it should be compiled to.
93
+ # @see #update_stylesheets
94
+ def force_update_stylesheets(individual_files = [])
95
+ Compiler.new(options.dup.merge(
96
+ :never_update => false,
97
+ :always_update => true,
98
+ :cache => false)).update_stylesheets(individual_files)
99
+ end
100
+
101
+ # All other method invocations are proxied to the \{#compiler}.
102
+ #
103
+ # @see #compiler
104
+ # @see Sass::Plugin::Compiler
105
+ def method_missing(method, *args, &block)
106
+ if compiler.respond_to?(method)
107
+ compiler.send(method, *args, &block)
108
+ else
109
+ super
110
+ end
111
+ end
112
+
113
+ # For parity with method_missing
114
+ def respond_to?(method)
115
+ super || compiler.respond_to?(method)
116
+ end
117
+
118
+ # There's a small speedup by not using method missing for frequently delegated methods.
119
+ def options
120
+ compiler.options
121
+ end
122
+
123
+ end
124
+ end
125
+
126
+ # On Rails 3+ the rails plugin is loaded at the right time in railtie.rb
127
+ if defined?(ActionController) && !Sass::Util.ap_geq_3?
128
+ require 'sass/plugin/rails'
129
+ elsif defined?(Merb::Plugins)
130
+ require 'sass/plugin/merb'
131
+ else
132
+ require 'sass/plugin/generic'
133
+ end
@@ -0,0 +1,10 @@
1
+ # Rails 3.0.0.beta.2+, < 3.1
2
+ if defined?(ActiveSupport) && Sass::Util.has?(:public_method, ActiveSupport, :on_load) &&
3
+ !Sass::Util.ap_geq?('3.1.0.beta')
4
+ require 'sass/plugin/configuration'
5
+ ActiveSupport.on_load(:before_configuration) do
6
+ require 'sass'
7
+ require 'sass/plugin'
8
+ require 'sass/plugin/rails'
9
+ end
10
+ end
data/lib/sass/repl.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'readline'
2
+
3
+ module Sass
4
+ # Runs a SassScript read-eval-print loop.
5
+ # It presents a prompt on the terminal,
6
+ # reads in SassScript expressions,
7
+ # evaluates them,
8
+ # and prints the result.
9
+ class Repl
10
+ # @param options [{Symbol => Object}] An options hash.
11
+ def initialize(options = {})
12
+ @options = options
13
+ end
14
+
15
+ # Starts the read-eval-print loop.
16
+ def run
17
+ environment = Environment.new
18
+ @line = 0
19
+ loop do
20
+ @line += 1
21
+ unless text = Readline.readline('>> ')
22
+ puts
23
+ return
24
+ end
25
+
26
+ Readline::HISTORY << text
27
+ parse_input(environment, text)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def parse_input(environment, text)
34
+ case text
35
+ when Script::MATCH
36
+ name = $1
37
+ guarded = !!$3
38
+ val = Script::Parser.parse($2, @line, text.size - ($3 || '').size - $2.size)
39
+
40
+ unless guarded && environment.var(name)
41
+ environment.set_var(name, val.perform(environment))
42
+ end
43
+
44
+ p environment.var(name)
45
+ else
46
+ p Script::Parser.parse(text, @line, 0).perform(environment)
47
+ end
48
+ rescue Sass::SyntaxError => e
49
+ puts "SyntaxError: #{e.message}"
50
+ if @options[:trace]
51
+ e.backtrace.each do |e|
52
+ puts "\tfrom #{e}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/sass/root.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Sass
2
+ # The root directory of the Sass source tree.
3
+ # This may be overridden by the package manager
4
+ # if the lib directory is separated from the main source tree.
5
+ # @api public
6
+ ROOT_DIR = File.expand_path(File.join(__FILE__, "../../.."))
7
+ end
@@ -0,0 +1,52 @@
1
+ module Sass::Script
2
+ # A SassScript object representing a variable argument list. This works just
3
+ # like a normal list, but can also contain keyword arguments.
4
+ #
5
+ # The keyword arguments attached to this list are unused except when this is
6
+ # passed as a glob argument to a function or mixin.
7
+ class ArgList < List
8
+ # Whether \{#keywords} has been accessed. If so, we assume that all keywords
9
+ # were valid for the function that created this ArgList.
10
+ #
11
+ # @return [Boolean]
12
+ attr_accessor :keywords_accessed
13
+
14
+ # Creates a new argument list.
15
+ #
16
+ # @param value [Array<Literal>] See \{List#value}.
17
+ # @param keywords [Hash<String, Literal>] See \{#keywords}
18
+ # @param separator [String] See \{List#separator}.
19
+ def initialize(value, keywords, separator)
20
+ super(value, separator)
21
+ @keywords = keywords
22
+ end
23
+
24
+ # The keyword arguments attached to this list.
25
+ #
26
+ # @return [Hash<String, Literal>]
27
+ def keywords
28
+ @keywords_accessed = true
29
+ @keywords
30
+ end
31
+
32
+ # @see Node#children
33
+ def children
34
+ super + @keywords.values
35
+ end
36
+
37
+ # @see Node#deep_copy
38
+ def deep_copy
39
+ node = super
40
+ node.instance_variable_set('@keywords',
41
+ Sass::Util.map_hash(@keywords) {|k, v| [k, v.deep_copy]})
42
+ node
43
+ end
44
+
45
+ protected
46
+
47
+ # @see Node#_perform
48
+ def _perform(environment)
49
+ self
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ require 'sass/script/literal'
2
+
3
+ module Sass::Script
4
+ # A SassScript object representing a boolean (true or false) value.
5
+ class Bool < Literal
6
+ # The Ruby value of the boolean.
7
+ #
8
+ # @return [Boolean]
9
+ attr_reader :value
10
+ alias_method :to_bool, :value
11
+
12
+ # @return [String] "true" or "false"
13
+ def to_s(opts = {})
14
+ @value.to_s
15
+ end
16
+ alias_method :to_sass, :to_s
17
+ end
18
+ end