sass 3.7.4 → 4.0.0.alpha.1

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 (257) hide show
  1. checksums.yaml +13 -5
  2. data/.yardopts +1 -1
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/CONTRIBUTING.md +1 -146
  5. data/MIT-LICENSE +1 -1
  6. data/README.md +25 -39
  7. data/Rakefile +274 -0
  8. data/VERSION +1 -1
  9. data/VERSION_DATE +1 -1
  10. data/lib/sass.rb +3 -3
  11. data/lib/sass/cache_stores/filesystem.rb +2 -2
  12. data/lib/sass/cache_stores/memory.rb +5 -4
  13. data/lib/sass/callbacks.rb +2 -2
  14. data/lib/sass/css.rb +12 -12
  15. data/lib/sass/engine.rb +44 -62
  16. data/lib/sass/environment.rb +7 -35
  17. data/lib/sass/error.rb +14 -14
  18. data/lib/sass/exec/base.rb +14 -3
  19. data/lib/sass/exec/sass_convert.rb +6 -20
  20. data/lib/sass/exec/sass_scss.rb +29 -5
  21. data/lib/sass/features.rb +2 -3
  22. data/lib/sass/importers/filesystem.rb +6 -11
  23. data/lib/sass/logger.rb +3 -8
  24. data/lib/sass/logger/base.rb +2 -19
  25. data/lib/sass/plugin.rb +2 -3
  26. data/lib/sass/plugin/compiler.rb +67 -48
  27. data/lib/sass/plugin/configuration.rb +3 -3
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/rack.rb +3 -3
  30. data/lib/sass/plugin/staleness_checker.rb +3 -3
  31. data/lib/sass/railtie.rb +1 -1
  32. data/lib/sass/script.rb +3 -3
  33. data/lib/sass/script/css_parser.rb +15 -5
  34. data/lib/sass/script/functions.rb +121 -337
  35. data/lib/sass/script/lexer.rb +36 -102
  36. data/lib/sass/script/parser.rb +153 -529
  37. data/lib/sass/script/tree/funcall.rb +34 -42
  38. data/lib/sass/script/tree/interpolation.rb +26 -171
  39. data/lib/sass/script/tree/list_literal.rb +8 -23
  40. data/lib/sass/script/tree/map_literal.rb +2 -2
  41. data/lib/sass/script/tree/node.rb +3 -3
  42. data/lib/sass/script/tree/operation.rb +16 -43
  43. data/lib/sass/script/tree/string_interpolation.rb +43 -64
  44. data/lib/sass/script/tree/variable.rb +1 -1
  45. data/lib/sass/script/value.rb +0 -2
  46. data/lib/sass/script/value/arg_list.rb +1 -1
  47. data/lib/sass/script/value/base.rb +9 -27
  48. data/lib/sass/script/value/color.rb +18 -26
  49. data/lib/sass/script/value/helpers.rb +18 -44
  50. data/lib/sass/script/value/list.rb +14 -35
  51. data/lib/sass/script/value/map.rb +2 -2
  52. data/lib/sass/script/value/number.rb +16 -26
  53. data/lib/sass/script/value/string.rb +1 -30
  54. data/lib/sass/scss.rb +2 -0
  55. data/lib/sass/scss/css_parser.rb +3 -7
  56. data/lib/sass/scss/parser.rb +78 -196
  57. data/lib/sass/scss/rx.rb +14 -7
  58. data/lib/sass/scss/script_lexer.rb +15 -0
  59. data/lib/sass/scss/script_parser.rb +25 -0
  60. data/lib/sass/scss/static_parser.rb +55 -38
  61. data/lib/sass/selector.rb +10 -7
  62. data/lib/sass/selector/abstract_sequence.rb +12 -15
  63. data/lib/sass/selector/comma_sequence.rb +6 -24
  64. data/lib/sass/selector/pseudo.rb +6 -19
  65. data/lib/sass/selector/sequence.rb +16 -14
  66. data/lib/sass/selector/simple.rb +7 -9
  67. data/lib/sass/selector/simple_sequence.rb +12 -16
  68. data/lib/sass/shared.rb +1 -1
  69. data/lib/sass/source/map.rb +9 -7
  70. data/lib/sass/source/position.rb +4 -4
  71. data/lib/sass/stack.rb +3 -23
  72. data/lib/sass/tree/charset_node.rb +1 -1
  73. data/lib/sass/tree/comment_node.rb +1 -1
  74. data/lib/sass/tree/function_node.rb +3 -2
  75. data/lib/sass/tree/node.rb +3 -5
  76. data/lib/sass/tree/prop_node.rb +58 -49
  77. data/lib/sass/tree/rule_node.rb +8 -15
  78. data/lib/sass/tree/visitors/check_nesting.rb +23 -19
  79. data/lib/sass/tree/visitors/convert.rb +13 -15
  80. data/lib/sass/tree/visitors/cssize.rb +15 -4
  81. data/lib/sass/tree/visitors/deep_copy.rb +2 -2
  82. data/lib/sass/tree/visitors/extend.rb +14 -10
  83. data/lib/sass/tree/visitors/perform.rb +18 -29
  84. data/lib/sass/tree/visitors/set_options.rb +2 -2
  85. data/lib/sass/tree/visitors/to_css.rb +47 -77
  86. data/lib/sass/util.rb +311 -98
  87. data/lib/sass/util/cross_platform_random.rb +19 -0
  88. data/lib/sass/util/multibyte_string_scanner.rb +133 -127
  89. data/lib/sass/util/normalized_map.rb +8 -1
  90. data/lib/sass/util/ordered_hash.rb +192 -0
  91. data/lib/sass/version.rb +6 -2
  92. data/test/sass/cache_test.rb +131 -0
  93. data/test/sass/callbacks_test.rb +61 -0
  94. data/test/sass/compiler_test.rb +236 -0
  95. data/test/sass/conversion_test.rb +2171 -0
  96. data/test/sass/css2sass_test.rb +526 -0
  97. data/test/sass/data/hsl-rgb.txt +319 -0
  98. data/test/sass/encoding_test.rb +219 -0
  99. data/test/sass/engine_test.rb +3400 -0
  100. data/test/sass/exec_test.rb +86 -0
  101. data/test/sass/extend_test.rb +1719 -0
  102. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  103. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  104. data/test/sass/functions_test.rb +1984 -0
  105. data/test/sass/importer_test.rb +421 -0
  106. data/test/sass/logger_test.rb +58 -0
  107. data/test/sass/mock_importer.rb +49 -0
  108. data/test/sass/more_results/more1.css +9 -0
  109. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  110. data/test/sass/more_results/more_import.css +29 -0
  111. data/test/sass/more_templates/_more_partial.sass +2 -0
  112. data/test/sass/more_templates/more1.sass +23 -0
  113. data/test/sass/more_templates/more_import.sass +11 -0
  114. data/test/sass/plugin_test.rb +556 -0
  115. data/test/sass/results/alt.css +4 -0
  116. data/test/sass/results/basic.css +9 -0
  117. data/test/sass/results/cached_import_option.css +3 -0
  118. data/test/sass/results/compact.css +5 -0
  119. data/test/sass/results/complex.css +86 -0
  120. data/test/sass/results/compressed.css +1 -0
  121. data/test/sass/results/expanded.css +19 -0
  122. data/test/sass/results/filename_fn.css +3 -0
  123. data/test/sass/results/if.css +3 -0
  124. data/test/sass/results/import.css +31 -0
  125. data/test/sass/results/import_charset.css +5 -0
  126. data/test/sass/results/import_charset_1_8.css +5 -0
  127. data/test/sass/results/import_charset_ibm866.css +5 -0
  128. data/test/sass/results/import_content.css +1 -0
  129. data/test/sass/results/line_numbers.css +49 -0
  130. data/test/sass/results/mixins.css +95 -0
  131. data/test/sass/results/multiline.css +24 -0
  132. data/test/sass/results/nested.css +22 -0
  133. data/test/sass/results/options.css +1 -0
  134. data/test/sass/results/parent_ref.css +13 -0
  135. data/test/sass/results/script.css +16 -0
  136. data/test/sass/results/scss_import.css +31 -0
  137. data/test/sass/results/scss_importee.css +2 -0
  138. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  139. data/test/sass/results/subdir/subdir.css +3 -0
  140. data/test/sass/results/units.css +11 -0
  141. data/test/sass/results/warn.css +0 -0
  142. data/test/sass/results/warn_imported.css +0 -0
  143. data/test/sass/script_conversion_test.rb +306 -0
  144. data/test/sass/script_test.rb +1206 -0
  145. data/test/sass/scss/css_test.rb +1281 -0
  146. data/test/sass/scss/rx_test.rb +160 -0
  147. data/test/sass/scss/scss_test.rb +4147 -0
  148. data/test/sass/scss/test_helper.rb +37 -0
  149. data/test/sass/source_map_test.rb +1055 -0
  150. data/test/sass/superselector_test.rb +210 -0
  151. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  152. data/test/sass/templates/_double_import_loop2.sass +1 -0
  153. data/test/sass/templates/_filename_fn_import.scss +11 -0
  154. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  155. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  156. data/test/sass/templates/_imported_content.sass +3 -0
  157. data/test/sass/templates/_partial.sass +2 -0
  158. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  159. data/test/sass/templates/alt.sass +16 -0
  160. data/test/sass/templates/basic.sass +23 -0
  161. data/test/sass/templates/bork1.sass +2 -0
  162. data/test/sass/templates/bork2.sass +2 -0
  163. data/test/sass/templates/bork3.sass +2 -0
  164. data/test/sass/templates/bork4.sass +2 -0
  165. data/test/sass/templates/bork5.sass +3 -0
  166. data/test/sass/templates/cached_import_option.scss +3 -0
  167. data/test/sass/templates/compact.sass +17 -0
  168. data/test/sass/templates/complex.sass +305 -0
  169. data/test/sass/templates/compressed.sass +15 -0
  170. data/test/sass/templates/double_import_loop1.sass +1 -0
  171. data/test/sass/templates/expanded.sass +17 -0
  172. data/test/sass/templates/filename_fn.scss +18 -0
  173. data/test/sass/templates/if.sass +11 -0
  174. data/test/sass/templates/import.sass +12 -0
  175. data/test/sass/templates/import_charset.sass +9 -0
  176. data/test/sass/templates/import_charset_1_8.sass +6 -0
  177. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  178. data/test/sass/templates/import_content.sass +4 -0
  179. data/test/sass/templates/importee.less +2 -0
  180. data/test/sass/templates/importee.sass +19 -0
  181. data/test/sass/templates/line_numbers.sass +13 -0
  182. data/test/sass/templates/mixin_bork.sass +5 -0
  183. data/test/sass/templates/mixins.sass +76 -0
  184. data/test/sass/templates/multiline.sass +20 -0
  185. data/test/sass/templates/nested.sass +25 -0
  186. data/test/sass/templates/nested_bork1.sass +2 -0
  187. data/test/sass/templates/nested_bork2.sass +2 -0
  188. data/test/sass/templates/nested_bork3.sass +2 -0
  189. data/test/sass/templates/nested_bork4.sass +2 -0
  190. data/test/sass/templates/nested_import.sass +2 -0
  191. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  192. data/test/sass/templates/options.sass +2 -0
  193. data/test/sass/templates/parent_ref.sass +25 -0
  194. data/test/sass/templates/same_name_different_ext.sass +2 -0
  195. data/test/sass/templates/same_name_different_ext.scss +1 -0
  196. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  197. data/test/sass/templates/script.sass +101 -0
  198. data/test/sass/templates/scss_import.scss +12 -0
  199. data/test/sass/templates/scss_importee.scss +1 -0
  200. data/test/sass/templates/single_import_loop.sass +1 -0
  201. data/test/sass/templates/subdir/import_up1.scss +1 -0
  202. data/test/sass/templates/subdir/import_up2.scss +1 -0
  203. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  204. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  205. data/test/sass/templates/subdir/subdir.sass +6 -0
  206. data/test/sass/templates/units.sass +11 -0
  207. data/test/sass/templates/warn.sass +3 -0
  208. data/test/sass/templates/warn_imported.sass +4 -0
  209. data/test/sass/test_helper.rb +8 -0
  210. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  211. data/test/sass/util/normalized_map_test.rb +51 -0
  212. data/test/sass/util/subset_map_test.rb +91 -0
  213. data/test/sass/util_test.rb +438 -0
  214. data/test/sass/value_helpers_test.rb +179 -0
  215. data/test/test_helper.rb +110 -0
  216. data/vendor/listen/CHANGELOG.md +1 -0
  217. data/vendor/listen/CONTRIBUTING.md +38 -0
  218. data/vendor/listen/Gemfile +20 -0
  219. data/vendor/listen/Guardfile +8 -0
  220. data/vendor/listen/LICENSE +20 -0
  221. data/vendor/listen/README.md +349 -0
  222. data/vendor/listen/Rakefile +5 -0
  223. data/vendor/listen/Vagrantfile +96 -0
  224. data/vendor/listen/lib/listen.rb +54 -0
  225. data/vendor/listen/lib/listen/adapter.rb +327 -0
  226. data/vendor/listen/lib/listen/adapters/bsd.rb +75 -0
  227. data/vendor/listen/lib/listen/adapters/darwin.rb +48 -0
  228. data/vendor/listen/lib/listen/adapters/linux.rb +81 -0
  229. data/vendor/listen/lib/listen/adapters/polling.rb +58 -0
  230. data/vendor/listen/lib/listen/adapters/windows.rb +91 -0
  231. data/vendor/listen/lib/listen/directory_record.rb +406 -0
  232. data/vendor/listen/lib/listen/listener.rb +323 -0
  233. data/vendor/listen/lib/listen/turnstile.rb +32 -0
  234. data/vendor/listen/lib/listen/version.rb +3 -0
  235. data/vendor/listen/listen.gemspec +28 -0
  236. data/vendor/listen/spec/listen/adapter_spec.rb +149 -0
  237. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
  238. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
  239. data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
  240. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  241. data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
  242. data/vendor/listen/spec/listen/directory_record_spec.rb +1250 -0
  243. data/vendor/listen/spec/listen/listener_spec.rb +258 -0
  244. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  245. data/vendor/listen/spec/listen_spec.rb +67 -0
  246. data/vendor/listen/spec/spec_helper.rb +25 -0
  247. data/vendor/listen/spec/support/adapter_helper.rb +666 -0
  248. data/vendor/listen/spec/support/directory_record_helper.rb +57 -0
  249. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  250. data/vendor/listen/spec/support/listeners_helper.rb +179 -0
  251. data/vendor/listen/spec/support/platform_helper.rb +15 -0
  252. metadata +217 -76
  253. data/extra/sass-spec-ref.sh +0 -40
  254. data/lib/sass/deprecation.rb +0 -55
  255. data/lib/sass/logger/delayed.rb +0 -50
  256. data/lib/sass/script/value/callable.rb +0 -25
  257. data/lib/sass/script/value/function.rb +0 -19
@@ -0,0 +1,19 @@
1
+ module Sass
2
+ module Util
3
+ # Ruby 1.8 doesn't support an actual Random class with a settable seed.
4
+ class CrossPlatformRandom
5
+ def initialize(seed = nil)
6
+ if Sass::Util.ruby1_8?
7
+ srand(seed) if seed
8
+ else
9
+ @random = seed ? ::Random.new(seed) : ::Random.new
10
+ end
11
+ end
12
+
13
+ def rand(*args)
14
+ return @random.rand(*args) if @random
15
+ Kernel.rand(*args)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,151 +1,157 @@
1
1
  require 'strscan'
2
2
 
3
- if Sass::Util.rbx?
4
- # Rubinius's StringScanner class implements some of its methods in terms of
5
- # others, which causes us to double-count bytes in some cases if we do
6
- # straightforward inheritance. To work around this, we use a delegate class.
7
- require 'delegate'
8
- class Sass::Util::MultibyteStringScanner < DelegateClass(StringScanner)
9
- def initialize(str)
10
- super(StringScanner.new(str))
11
- @mb_pos = 0
12
- @mb_matched_size = nil
13
- @mb_last_pos = nil
3
+ if Sass::Util.ruby1_8?
4
+ # rubocop:disable ConstantName
5
+ Sass::Util::MultibyteStringScanner = StringScanner
6
+ # rubocop:enable ConstantName
7
+ else
8
+ if Sass::Util.rbx?
9
+ # Rubinius's StringScanner class implements some of its methods in terms of
10
+ # others, which causes us to double-count bytes in some cases if we do
11
+ # straightforward inheritance. To work around this, we use a delegate class.
12
+ require 'delegate'
13
+ class Sass::Util::MultibyteStringScanner < DelegateClass(StringScanner)
14
+ def initialize(str)
15
+ super(StringScanner.new(str))
16
+ @mb_pos = 0
17
+ @mb_matched_size = nil
18
+ @mb_last_pos = nil
19
+ end
20
+
21
+ def is_a?(klass)
22
+ __getobj__.is_a?(klass) || super
23
+ end
14
24
  end
15
-
16
- def is_a?(klass)
17
- __getobj__.is_a?(klass) || super
25
+ else
26
+ class Sass::Util::MultibyteStringScanner < StringScanner
27
+ def initialize(str)
28
+ super
29
+ @mb_pos = 0
30
+ @mb_matched_size = nil
31
+ @mb_last_pos = nil
32
+ end
18
33
  end
19
34
  end
20
- else
21
- class Sass::Util::MultibyteStringScanner < StringScanner
22
- def initialize(str)
35
+
36
+ # A wrapper of the native StringScanner class that works correctly with
37
+ # multibyte character encodings. The native class deals only in bytes, not
38
+ # characters, for methods like [#pos] and [#matched_size]. This class deals
39
+ # only in characters, instead.
40
+ class Sass::Util::MultibyteStringScanner
41
+ def self.new(str)
42
+ return StringScanner.new(str) if str.ascii_only?
23
43
  super
24
- @mb_pos = 0
25
- @mb_matched_size = nil
26
- @mb_last_pos = nil
27
44
  end
28
- end
29
- end
30
45
 
31
- # A wrapper of the native StringScanner class that works correctly with
32
- # multibyte character encodings. The native class deals only in bytes, not
33
- # characters, for methods like [#pos] and [#matched_size]. This class deals
34
- # only in characters, instead.
35
- class Sass::Util::MultibyteStringScanner
36
- def self.new(str)
37
- return StringScanner.new(str) if str.ascii_only?
38
- super
39
- end
46
+ alias_method :byte_pos, :pos
47
+ alias_method :byte_matched_size, :matched_size
48
+
49
+ def check(pattern); _match super; end
50
+ def check_until(pattern); _matched super; end
51
+ def getch; _forward _match super; end
52
+ def match?(pattern); _size check(pattern); end
53
+ def matched_size; @mb_matched_size; end
54
+ def peek(len); string[@mb_pos, len]; end
55
+ alias_method :peep, :peek
56
+ def pos; @mb_pos; end
57
+ alias_method :pointer, :pos
58
+ def rest_size; rest.size; end
59
+ def scan(pattern); _forward _match super; end
60
+ def scan_until(pattern); _forward _matched super; end
61
+ def skip(pattern); _size scan(pattern); end
62
+ def skip_until(pattern); _matched _size scan_until(pattern); end
63
+
64
+ def get_byte
65
+ raise "MultibyteStringScanner doesn't support #get_byte."
66
+ end
40
67
 
41
- alias_method :byte_pos, :pos
42
- alias_method :byte_matched_size, :matched_size
43
-
44
- def check(pattern); _match super; end
45
- def check_until(pattern); _matched super; end
46
- def getch; _forward _match super; end
47
- def match?(pattern); _size check(pattern); end
48
- def matched_size; @mb_matched_size; end
49
- def peek(len); string[@mb_pos, len]; end
50
- alias_method :peep, :peek
51
- def pos; @mb_pos; end
52
- alias_method :pointer, :pos
53
- def rest_size; rest.size; end
54
- def scan(pattern); _forward _match super; end
55
- def scan_until(pattern); _forward _matched super; end
56
- def skip(pattern); _size scan(pattern); end
57
- def skip_until(pattern); _matched _size scan_until(pattern); end
58
-
59
- def get_byte
60
- raise "MultibyteStringScanner doesn't support #get_byte."
61
- end
68
+ def getbyte
69
+ raise "MultibyteStringScanner doesn't support #getbyte."
70
+ end
62
71
 
63
- def getbyte
64
- raise "MultibyteStringScanner doesn't support #getbyte."
65
- end
72
+ def pos=(n)
73
+ @mb_last_pos = nil
66
74
 
67
- def pos=(n)
68
- @mb_last_pos = nil
69
-
70
- # We set position kind of a lot during parsing, so we want it to be as
71
- # efficient as possible. This is complicated by the fact that UTF-8 is a
72
- # variable-length encoding, so it's difficult to find the byte length that
73
- # corresponds to a given character length.
74
- #
75
- # Our heuristic here is to try to count the fewest possible characters. So
76
- # if the new position is close to the current one, just count the
77
- # characters between the two; if the new position is closer to the
78
- # beginning of the string, just count the characters from there.
79
- if @mb_pos - n < @mb_pos / 2
80
- # New position is close to old position
81
- byte_delta = @mb_pos > n ? -string[n...@mb_pos].bytesize : string[@mb_pos...n].bytesize
82
- super(byte_pos + byte_delta)
83
- else
84
- # New position is close to BOS
85
- super(string[0...n].bytesize)
86
- end
87
- @mb_pos = n
88
- end
75
+ # We set position kind of a lot during parsing, so we want it to be as
76
+ # efficient as possible. This is complicated by the fact that UTF-8 is a
77
+ # variable-length encoding, so it's difficult to find the byte length that
78
+ # corresponds to a given character length.
79
+ #
80
+ # Our heuristic here is to try to count the fewest possible characters. So
81
+ # if the new position is close to the current one, just count the
82
+ # characters between the two; if the new position is closer to the
83
+ # beginning of the string, just count the characters from there.
84
+ if @mb_pos - n < @mb_pos / 2
85
+ # New position is close to old position
86
+ byte_delta = @mb_pos > n ? -string[n...@mb_pos].bytesize : string[@mb_pos...n].bytesize
87
+ super(byte_pos + byte_delta)
88
+ else
89
+ # New position is close to BOS
90
+ super(string[0...n].bytesize)
91
+ end
92
+ @mb_pos = n
93
+ end
89
94
 
90
- def reset
91
- @mb_pos = 0
92
- @mb_matched_size = nil
93
- @mb_last_pos = nil
94
- super
95
- end
95
+ def reset
96
+ @mb_pos = 0
97
+ @mb_matched_size = nil
98
+ @mb_last_pos = nil
99
+ super
100
+ end
96
101
 
97
- def scan_full(pattern, advance_pointer_p, return_string_p)
98
- res = _match super(pattern, advance_pointer_p, true)
99
- _forward res if advance_pointer_p
100
- return res if return_string_p
101
- end
102
+ def scan_full(pattern, advance_pointer_p, return_string_p)
103
+ res = _match super(pattern, advance_pointer_p, true)
104
+ _forward res if advance_pointer_p
105
+ return res if return_string_p
106
+ end
102
107
 
103
- def search_full(pattern, advance_pointer_p, return_string_p)
104
- res = super(pattern, advance_pointer_p, true)
105
- _forward res if advance_pointer_p
106
- _matched((res if return_string_p))
107
- end
108
+ def search_full(pattern, advance_pointer_p, return_string_p)
109
+ res = super(pattern, advance_pointer_p, true)
110
+ _forward res if advance_pointer_p
111
+ _matched((res if return_string_p))
112
+ end
108
113
 
109
- def string=(str)
110
- @mb_pos = 0
111
- @mb_matched_size = nil
112
- @mb_last_pos = nil
113
- super
114
- end
114
+ def string=(str)
115
+ @mb_pos = 0
116
+ @mb_matched_size = nil
117
+ @mb_last_pos = nil
118
+ super
119
+ end
115
120
 
116
- def terminate
117
- @mb_pos = string.size
118
- @mb_matched_size = nil
119
- @mb_last_pos = nil
120
- super
121
- end
122
- alias_method :clear, :terminate
121
+ def terminate
122
+ @mb_pos = string.size
123
+ @mb_matched_size = nil
124
+ @mb_last_pos = nil
125
+ super
126
+ end
127
+ alias_method :clear, :terminate
123
128
 
124
- def unscan
125
- super
126
- @mb_pos = @mb_last_pos
127
- @mb_last_pos = @mb_matched_size = nil
128
- end
129
+ def unscan
130
+ super
131
+ @mb_pos = @mb_last_pos
132
+ @mb_last_pos = @mb_matched_size = nil
133
+ end
129
134
 
130
- private
135
+ private
131
136
 
132
- def _size(str)
133
- str && str.size
134
- end
137
+ def _size(str)
138
+ str && str.size
139
+ end
135
140
 
136
- def _match(str)
137
- @mb_matched_size = str && str.size
138
- str
139
- end
141
+ def _match(str)
142
+ @mb_matched_size = str && str.size
143
+ str
144
+ end
140
145
 
141
- def _matched(res)
142
- _match matched
143
- res
144
- end
146
+ def _matched(res)
147
+ _match matched
148
+ res
149
+ end
145
150
 
146
- def _forward(str)
147
- @mb_last_pos = @mb_pos
148
- @mb_pos += str.size if str
149
- str
151
+ def _forward(str)
152
+ @mb_last_pos = @mb_pos
153
+ @mb_pos += str.size if str
154
+ str
155
+ end
150
156
  end
151
157
  end
@@ -5,11 +5,12 @@ module Sass
5
5
  # A hash that normalizes its string keys while still allowing you to get back
6
6
  # to the original keys that were stored. If several different values normalize
7
7
  # to the same value, whichever is stored last wins.
8
+ require 'sass/util/ordered_hash' if ruby1_8?
8
9
  class NormalizedMap
9
10
  # Create a normalized map
10
11
  def initialize(map = nil)
11
12
  @key_strings = {}
12
- @map = {}
13
+ @map = Util.ruby1_8? ? OrderedHash.new : {}
13
14
 
14
15
  map.each {|key, value| self[key] = value} if map
15
16
  end
@@ -114,6 +115,12 @@ module Sass
114
115
  @map.send(method, *args, &block)
115
116
  end
116
117
 
118
+ if Sass::Util.ruby1_8?
119
+ def respond_to?(method, include_private = false)
120
+ super || @map.respond_to?(method, include_private)
121
+ end
122
+ end
123
+
117
124
  def respond_to_missing?(method, include_private = false)
118
125
  @map.respond_to?(method, include_private)
119
126
  end
@@ -0,0 +1,192 @@
1
+ # Copyright (c) 2005-2013 David Heinemeier Hansson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ # This class was copied from an old version of ActiveSupport.
23
+ class OrderedHash < ::Hash
24
+ # In MRI the Hash class is core and written in C. In particular, methods are
25
+ # programmed with explicit C function calls and polymorphism is not honored.
26
+ #
27
+ # For example, []= is crucial in this implementation to maintain the @keys
28
+ # array but hash.c invokes rb_hash_aset() originally. This prevents method
29
+ # reuse through inheritance and forces us to reimplement stuff.
30
+ #
31
+ # For instance, we cannot use the inherited #merge! because albeit the algorithm
32
+ # itself would work, our []= is not being called at all by the C code.
33
+
34
+ def initialize(*args)
35
+ super
36
+ @keys = []
37
+ end
38
+
39
+ def self.[](*args)
40
+ ordered_hash = new
41
+
42
+ if args.length == 1 && args.first.is_a?(Array)
43
+ args.first.each do |key_value_pair|
44
+ next unless key_value_pair.is_a?(Array)
45
+ ordered_hash[key_value_pair[0]] = key_value_pair[1]
46
+ end
47
+
48
+ return ordered_hash
49
+ end
50
+
51
+ unless args.size.even?
52
+ raise ArgumentError.new("odd number of arguments for Hash")
53
+ end
54
+
55
+ args.each_with_index do |val, ind|
56
+ next if ind.odd?
57
+ ordered_hash[val] = args[ind + 1]
58
+ end
59
+
60
+ ordered_hash
61
+ end
62
+
63
+ def initialize_copy(other)
64
+ super
65
+ # make a deep copy of keys
66
+ @keys = other.keys
67
+ end
68
+
69
+ def []=(key, value)
70
+ @keys << key unless has_key?(key)
71
+ super
72
+ end
73
+
74
+ def delete(key)
75
+ if has_key? key
76
+ index = @keys.index(key)
77
+ @keys.delete_at index
78
+ end
79
+ super
80
+ end
81
+
82
+ def delete_if
83
+ super
84
+ sync_keys!
85
+ self
86
+ end
87
+
88
+ def reject!
89
+ super
90
+ sync_keys!
91
+ self
92
+ end
93
+
94
+ def reject
95
+ dup.reject! {|h, k| yield h, k}
96
+ end
97
+
98
+ def keys
99
+ @keys.dup
100
+ end
101
+
102
+ def values
103
+ @keys.map {|key| self[key]}
104
+ end
105
+
106
+ def to_hash
107
+ self
108
+ end
109
+
110
+ def to_a
111
+ @keys.map {|key| [key, self[key]]}
112
+ end
113
+
114
+ def each_key
115
+ return to_enum(:each_key) unless block_given?
116
+ @keys.each {|key| yield key}
117
+ self
118
+ end
119
+
120
+ def each_value
121
+ return to_enum(:each_value) unless block_given?
122
+ @keys.each {|key| yield self[key]}
123
+ self
124
+ end
125
+
126
+ def each
127
+ return to_enum(:each) unless block_given?
128
+ @keys.each {|key| yield [key, self[key]]}
129
+ self
130
+ end
131
+
132
+ def each_pair
133
+ return to_enum(:each_pair) unless block_given?
134
+ @keys.each {|key| yield key, self[key]}
135
+ self
136
+ end
137
+
138
+ alias_method :select, :find_all
139
+
140
+ def clear
141
+ super
142
+ @keys.clear
143
+ self
144
+ end
145
+
146
+ def shift
147
+ k = @keys.first
148
+ v = delete(k)
149
+ [k, v]
150
+ end
151
+
152
+ def merge!(other_hash)
153
+ if block_given?
154
+ other_hash.each {|k, v| self[k] = key?(k) ? yield(k, self[k], v) : v}
155
+ else
156
+ other_hash.each {|k, v| self[k] = v}
157
+ end
158
+ self
159
+ end
160
+
161
+ alias_method :update, :merge!
162
+
163
+ def merge(other_hash)
164
+ if block_given?
165
+ dup.merge!(other_hash) {|k, v1, v2| yield k, v1, v2}
166
+ else
167
+ dup.merge!(other_hash)
168
+ end
169
+ end
170
+
171
+ # When replacing with another hash, the initial order of our keys must come from the other hash --
172
+ # ordered or not.
173
+ def replace(other)
174
+ super
175
+ @keys = other.keys
176
+ self
177
+ end
178
+
179
+ def invert
180
+ OrderedHash[to_a.map! {|key_value_pair| key_value_pair.reverse}]
181
+ end
182
+
183
+ def inspect
184
+ "#<OrderedHash #{super}>"
185
+ end
186
+
187
+ private
188
+
189
+ def sync_keys!
190
+ @keys.delete_if {|k| !has_key?(k)}
191
+ end
192
+ end