haml 3.0.25 → 3.1.0.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/.yardopts +1 -1
- data/CONTRIBUTING +0 -1
- data/EDGE_GEM_VERSION +1 -0
- data/MIT-LICENSE +1 -1
- data/README.md +10 -175
- data/Rakefile +56 -84
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/init.rb +1 -1
- data/lib/haml.rb +14 -12
- data/lib/haml/engine.rb +1 -1
- data/lib/haml/exec.rb +19 -316
- data/lib/haml/helpers/action_view_extensions.rb +1 -1
- data/lib/haml/html.rb +69 -76
- data/lib/haml/precompiler.rb +34 -41
- data/lib/haml/railtie.rb +4 -6
- data/lib/haml/template/plugin.rb +6 -16
- data/lib/haml/util.rb +91 -107
- data/lib/haml/version.rb +7 -0
- data/test/benchmark.rb +2 -9
- data/test/haml/engine_test.rb +195 -92
- data/test/haml/html2haml/erb_tests.rb +0 -14
- data/test/haml/util_test.rb +32 -0
- data/test/test_helper.rb +0 -39
- metadata +96 -324
- data/bin/css2sass +0 -13
- data/bin/sass +0 -8
- data/bin/sass-convert +0 -7
- data/extra/haml-mode.el +0 -753
- data/extra/sass-mode.el +0 -207
- data/lib/haml/util/subset_map.rb +0 -101
- data/lib/sass.rb +0 -29
- data/lib/sass/callbacks.rb +0 -52
- data/lib/sass/css.rb +0 -294
- data/lib/sass/engine.rb +0 -720
- data/lib/sass/environment.rb +0 -143
- data/lib/sass/error.rb +0 -198
- data/lib/sass/files.rb +0 -160
- data/lib/sass/less.rb +0 -382
- data/lib/sass/plugin.rb +0 -279
- data/lib/sass/plugin/configuration.rb +0 -221
- data/lib/sass/plugin/generic.rb +0 -15
- data/lib/sass/plugin/merb.rb +0 -37
- data/lib/sass/plugin/rack.rb +0 -47
- data/lib/sass/plugin/rails.rb +0 -32
- data/lib/sass/plugin/staleness_checker.rb +0 -123
- data/lib/sass/repl.rb +0 -58
- data/lib/sass/script.rb +0 -63
- data/lib/sass/script/bool.rb +0 -18
- data/lib/sass/script/color.rb +0 -491
- data/lib/sass/script/css_lexer.rb +0 -29
- data/lib/sass/script/css_parser.rb +0 -31
- data/lib/sass/script/funcall.rb +0 -77
- data/lib/sass/script/functions.rb +0 -861
- data/lib/sass/script/interpolation.rb +0 -70
- data/lib/sass/script/lexer.rb +0 -337
- data/lib/sass/script/literal.rb +0 -236
- data/lib/sass/script/node.rb +0 -112
- data/lib/sass/script/number.rb +0 -423
- data/lib/sass/script/operation.rb +0 -95
- data/lib/sass/script/parser.rb +0 -401
- data/lib/sass/script/string.rb +0 -67
- data/lib/sass/script/string_interpolation.rb +0 -93
- data/lib/sass/script/unary_operation.rb +0 -57
- data/lib/sass/script/variable.rb +0 -48
- data/lib/sass/scss.rb +0 -17
- data/lib/sass/scss/css_parser.rb +0 -46
- data/lib/sass/scss/parser.rb +0 -855
- data/lib/sass/scss/rx.rb +0 -126
- data/lib/sass/scss/sass_parser.rb +0 -11
- data/lib/sass/scss/script_lexer.rb +0 -15
- data/lib/sass/scss/script_parser.rb +0 -25
- data/lib/sass/scss/static_parser.rb +0 -40
- data/lib/sass/selector.rb +0 -361
- data/lib/sass/selector/abstract_sequence.rb +0 -62
- data/lib/sass/selector/comma_sequence.rb +0 -82
- data/lib/sass/selector/sequence.rb +0 -237
- data/lib/sass/selector/simple.rb +0 -113
- data/lib/sass/selector/simple_sequence.rb +0 -136
- data/lib/sass/tree/charset_node.rb +0 -37
- data/lib/sass/tree/comment_node.rb +0 -128
- data/lib/sass/tree/debug_node.rb +0 -36
- data/lib/sass/tree/directive_node.rb +0 -75
- data/lib/sass/tree/extend_node.rb +0 -65
- data/lib/sass/tree/for_node.rb +0 -55
- data/lib/sass/tree/if_node.rb +0 -69
- data/lib/sass/tree/import_node.rb +0 -102
- data/lib/sass/tree/mixin_def_node.rb +0 -48
- data/lib/sass/tree/mixin_node.rb +0 -111
- data/lib/sass/tree/node.rb +0 -464
- data/lib/sass/tree/prop_node.rb +0 -220
- data/lib/sass/tree/root_node.rb +0 -163
- data/lib/sass/tree/rule_node.rb +0 -261
- data/lib/sass/tree/variable_node.rb +0 -39
- data/lib/sass/tree/warn_node.rb +0 -42
- data/lib/sass/tree/while_node.rb +0 -36
- data/test/haml/util/subset_map_test.rb +0 -91
- data/test/sass/callbacks_test.rb +0 -61
- data/test/sass/conversion_test.rb +0 -1218
- data/test/sass/css2sass_test.rb +0 -364
- data/test/sass/data/hsl-rgb.txt +0 -319
- data/test/sass/engine_test.rb +0 -2267
- data/test/sass/extend_test.rb +0 -1348
- data/test/sass/functions_test.rb +0 -556
- data/test/sass/less_conversion_test.rb +0 -653
- data/test/sass/more_results/more1.css +0 -9
- data/test/sass/more_results/more1_with_line_comments.css +0 -26
- data/test/sass/more_results/more_import.css +0 -29
- data/test/sass/more_templates/_more_partial.sass +0 -2
- data/test/sass/more_templates/more1.sass +0 -23
- data/test/sass/more_templates/more_import.sass +0 -11
- data/test/sass/plugin_test.rb +0 -433
- data/test/sass/results/alt.css +0 -4
- data/test/sass/results/basic.css +0 -9
- data/test/sass/results/compact.css +0 -5
- data/test/sass/results/complex.css +0 -86
- data/test/sass/results/compressed.css +0 -1
- data/test/sass/results/expanded.css +0 -19
- data/test/sass/results/import.css +0 -31
- data/test/sass/results/import_charset.css +0 -4
- data/test/sass/results/import_charset_1_8.css +0 -4
- data/test/sass/results/import_charset_ibm866.css +0 -4
- data/test/sass/results/line_numbers.css +0 -49
- data/test/sass/results/mixins.css +0 -95
- data/test/sass/results/multiline.css +0 -24
- data/test/sass/results/nested.css +0 -22
- data/test/sass/results/options.css +0 -1
- data/test/sass/results/parent_ref.css +0 -13
- data/test/sass/results/script.css +0 -16
- data/test/sass/results/scss_import.css +0 -31
- data/test/sass/results/scss_importee.css +0 -2
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
- data/test/sass/results/subdir/subdir.css +0 -3
- data/test/sass/results/units.css +0 -11
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +0 -314
- data/test/sass/script_test.rb +0 -470
- data/test/sass/scss/css_test.rb +0 -916
- data/test/sass/scss/rx_test.rb +0 -156
- data/test/sass/scss/scss_test.rb +0 -1122
- data/test/sass/scss/test_helper.rb +0 -37
- data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
- data/test/sass/templates/_imported_charset_utf8.sass +0 -4
- data/test/sass/templates/_partial.sass +0 -2
- data/test/sass/templates/alt.sass +0 -16
- data/test/sass/templates/basic.sass +0 -23
- data/test/sass/templates/bork1.sass +0 -2
- data/test/sass/templates/bork2.sass +0 -2
- data/test/sass/templates/bork3.sass +0 -2
- data/test/sass/templates/bork4.sass +0 -2
- data/test/sass/templates/compact.sass +0 -17
- data/test/sass/templates/complex.sass +0 -305
- data/test/sass/templates/compressed.sass +0 -15
- data/test/sass/templates/expanded.sass +0 -17
- data/test/sass/templates/import.sass +0 -12
- data/test/sass/templates/import_charset.sass +0 -7
- data/test/sass/templates/import_charset_1_8.sass +0 -4
- data/test/sass/templates/import_charset_ibm866.sass +0 -9
- data/test/sass/templates/importee.less +0 -2
- data/test/sass/templates/importee.sass +0 -19
- data/test/sass/templates/line_numbers.sass +0 -13
- data/test/sass/templates/mixin_bork.sass +0 -5
- data/test/sass/templates/mixins.sass +0 -76
- data/test/sass/templates/multiline.sass +0 -20
- data/test/sass/templates/nested.sass +0 -25
- data/test/sass/templates/nested_bork1.sass +0 -2
- data/test/sass/templates/nested_bork2.sass +0 -2
- data/test/sass/templates/nested_bork3.sass +0 -2
- data/test/sass/templates/nested_bork4.sass +0 -2
- data/test/sass/templates/nested_mixin_bork.sass +0 -6
- data/test/sass/templates/options.sass +0 -2
- data/test/sass/templates/parent_ref.sass +0 -25
- data/test/sass/templates/script.sass +0 -101
- data/test/sass/templates/scss_import.scss +0 -11
- data/test/sass/templates/scss_importee.scss +0 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
- data/test/sass/templates/subdir/subdir.sass +0 -6
- data/test/sass/templates/units.sass +0 -11
- data/test/sass/templates/warn.sass +0 -3
- data/test/sass/templates/warn_imported.sass +0 -4
- data/vendor/fssm/LICENSE +0 -20
- data/vendor/fssm/README.markdown +0 -55
- data/vendor/fssm/Rakefile +0 -59
- data/vendor/fssm/VERSION.yml +0 -5
- data/vendor/fssm/example.rb +0 -9
- data/vendor/fssm/fssm.gemspec +0 -77
- data/vendor/fssm/lib/fssm.rb +0 -33
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
- data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
- data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
- data/vendor/fssm/lib/fssm/monitor.rb +0 -26
- data/vendor/fssm/lib/fssm/path.rb +0 -91
- data/vendor/fssm/lib/fssm/pathname.rb +0 -502
- data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
- data/vendor/fssm/lib/fssm/state/file.rb +0 -24
- data/vendor/fssm/lib/fssm/support.rb +0 -63
- data/vendor/fssm/lib/fssm/tree.rb +0 -176
- data/vendor/fssm/profile/prof-cache.rb +0 -40
- data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
- data/vendor/fssm/profile/prof-pathname.rb +0 -68
- data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
- data/vendor/fssm/profile/prof.html +0 -2379
- data/vendor/fssm/spec/path_spec.rb +0 -75
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +0 -14
data/lib/sass/less.rb
DELETED
@@ -1,382 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'less'
|
4
|
-
|
5
|
-
module Less
|
6
|
-
# This is the class that Treetop defines for parsing Less files.
|
7
|
-
# Since not everything gets parsed into the AST but is instead resolved at parse-time,
|
8
|
-
# we need to override some of it so that it can be converted into Sass.
|
9
|
-
module StyleSheet
|
10
|
-
# Selector mixins that don't have arguments.
|
11
|
-
# This depends only on the syntax at the call site;
|
12
|
-
# if it doesn't use parens, it hits this production,
|
13
|
-
# regardless of whether the mixin being called has arguments or not.
|
14
|
-
module Mixin4
|
15
|
-
def build_with_sass(env)
|
16
|
-
selectors.build(env, :mixin).each do |path|
|
17
|
-
el = path.inject(env.root) do |current, node|
|
18
|
-
current.descend(node.selector, node) or raise MixinNameError, "#{selectors.text_value} in #{env}"
|
19
|
-
end
|
20
|
-
if el.is_a?(Node::Mixin::Def)
|
21
|
-
# Calling a mixin with arguments, which gets compiled to a Sass mixin
|
22
|
-
env << Node::Mixin::Call.new(el, [], env)
|
23
|
-
else
|
24
|
-
# Calling a mixin without arguments, which gets compiled to @extend
|
25
|
-
sel = selector_str(path)
|
26
|
-
base = selector_str(selector_base(path))
|
27
|
-
if base == sel
|
28
|
-
env << Node::SassNode.new(Sass::Tree::ExtendNode.new([sel]))
|
29
|
-
else
|
30
|
-
Haml::Util.haml_warn <<WARNING
|
31
|
-
WARNING: Sass doesn't support mixing in selector sequences.
|
32
|
-
Replacing "#{sel}" with "@extend #{base}"
|
33
|
-
WARNING
|
34
|
-
env << Node::SassNode.new(Sass::Tree::CommentNode.new("// #{sel};", true))
|
35
|
-
env << Node::SassNode.new(Sass::Tree::ExtendNode.new([base]))
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
alias_method :build_without_sass, :build
|
41
|
-
alias_method :build, :build_with_sass
|
42
|
-
|
43
|
-
def selector_base(path)
|
44
|
-
el, i = Haml::Util.enum_with_index(path).to_a.reverse.find {|e, i| e.selector !~ /^:{1,2}$/} ||
|
45
|
-
[path.first, 0]
|
46
|
-
sel = (el.selector =~ /^:{0,2}$/ ? el.selector : "")
|
47
|
-
[Node::Element.new(el.name, sel)] + path[i+1..-1]
|
48
|
-
end
|
49
|
-
|
50
|
-
def selector_str(path)
|
51
|
-
path.map {|e| e.sass_selector_str}.join(' ').gsub(' :', ':')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Property and variable declarations.
|
56
|
-
# We want to keep track of the line number
|
57
|
-
# so we don't space out the variables too much in the generated Sass.
|
58
|
-
module Declaration3
|
59
|
-
def build_with_sass(env)
|
60
|
-
build_without_sass(env)
|
61
|
-
env.rules.last.src_line = input.line_of(interval.first)
|
62
|
-
end
|
63
|
-
alias_method :build_without_sass, :build
|
64
|
-
alias_method :build, :build_with_sass
|
65
|
-
end
|
66
|
-
|
67
|
-
# Comma-separated selectors.
|
68
|
-
# Less breaks these into completely separate nodes.
|
69
|
-
# Since we don't want this duplication in the Sass,
|
70
|
-
# we modify the production to keep track of the original group
|
71
|
-
# so we can reconstruct it later on.
|
72
|
-
module Selectors2
|
73
|
-
def build_with_sass(env, method)
|
74
|
-
arr = build_without_sass(env, method)
|
75
|
-
return arr if method == :mixin
|
76
|
-
rarr = arr.map {|e| e.top(env)}
|
77
|
-
rarr.each {|e| e.group = rarr}
|
78
|
-
arr
|
79
|
-
end
|
80
|
-
alias_method :build_without_sass, :build
|
81
|
-
alias_method :build, :build_with_sass
|
82
|
-
end
|
83
|
-
|
84
|
-
# Attribute accessors.
|
85
|
-
# Sass just flat-out doesn't support these,
|
86
|
-
# so we print a warning to that effect and compile them to comments.
|
87
|
-
module Accessor1
|
88
|
-
def build(env)
|
89
|
-
Haml::Util.haml_warn <<WARNING
|
90
|
-
WARNING: Sass doesn't support attribute accessors.
|
91
|
-
Ignoring #{text_value}
|
92
|
-
WARNING
|
93
|
-
Node::Anonymous.new("/* #{text_value} */")
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# @import statements.
|
98
|
-
# Less handles these during parse-time,
|
99
|
-
# so we want to wrap them up as a node in the tree.
|
100
|
-
# We also include the nodes, though,
|
101
|
-
# since we want to have access to the mixins
|
102
|
-
# so we can tell if they take arguments or not.
|
103
|
-
# The included nodes are hidden so they don't appear in the output.
|
104
|
-
module Import1
|
105
|
-
def build_with_sass(env)
|
106
|
-
line = input.line_of(interval.first)
|
107
|
-
import = Sass::Tree::ImportNode.new(url.value.gsub(/\.less$/, ''))
|
108
|
-
import.line = input.line_of(interval.first)
|
109
|
-
env << Node::SassNode.new(import)
|
110
|
-
old_rules = env.rules.dup
|
111
|
-
build_without_sass env
|
112
|
-
(env.rules - old_rules).each {|r| r.hide_in_sass = true}
|
113
|
-
rescue ImportError => e
|
114
|
-
raise Sass::SyntaxError.new("File to import #{url.text_value} not found or unreadable", :line => line)
|
115
|
-
end
|
116
|
-
alias_method :build_without_sass, :build
|
117
|
-
alias_method :build, :build_with_sass
|
118
|
-
end
|
119
|
-
|
120
|
-
# The IE-specific `alpha(opacity=@var)`.
|
121
|
-
# Less manually resolves the variable here at parse-time.
|
122
|
-
# We want to keep the variable around,
|
123
|
-
# so we compile this to a function.
|
124
|
-
# Less doesn't actually have an `=` operator,
|
125
|
-
# but that's okay since it's just getting compiled to Sass anyway.
|
126
|
-
module Entity::Alpha1
|
127
|
-
def build(env)
|
128
|
-
Node::Function.new("alpha",
|
129
|
-
[Node::Expression.new([
|
130
|
-
Node::Keyword.new("opacity"),
|
131
|
-
Node::Operator.new("="),
|
132
|
-
variable.build])])
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# The Less AST classes for the document,
|
138
|
-
# including both stylesheet-level nodes and expression-level nodes.
|
139
|
-
# The main purpose of overriding these is to add `#to_sass_tree` functions
|
140
|
-
# for converting to Sass.
|
141
|
-
module Node
|
142
|
-
module Entity
|
143
|
-
attr_accessor :hide_in_sass
|
144
|
-
attr_accessor :src_line
|
145
|
-
end
|
146
|
-
|
147
|
-
class Element
|
148
|
-
attr_accessor :group
|
149
|
-
|
150
|
-
def top(env)
|
151
|
-
return self if parent.equal?(env)
|
152
|
-
return parent.top(env)
|
153
|
-
end
|
154
|
-
|
155
|
-
def to_sass_tree
|
156
|
-
if root?
|
157
|
-
root = Sass::Tree::RootNode.new("")
|
158
|
-
rules.each {|r| root << r.to_sass_tree}
|
159
|
-
return root
|
160
|
-
end
|
161
|
-
return if hide_in_sass
|
162
|
-
return if !self.equal?(group.first)
|
163
|
-
|
164
|
-
last_el = nil
|
165
|
-
sel = group.map do |el|
|
166
|
-
comma_sel = []
|
167
|
-
loop do
|
168
|
-
comma_sel << el.sass_selector_str
|
169
|
-
break unless el.rules.size == 1 && el.rules.first.is_a?(Element)
|
170
|
-
el = el.rules.first
|
171
|
-
end
|
172
|
-
last_el = el
|
173
|
-
comma_sel = comma_sel.join(' ').gsub(' :', ':')
|
174
|
-
comma_sel.gsub!(/^:/, '&:') unless parent.root?
|
175
|
-
comma_sel
|
176
|
-
end.join(', ')
|
177
|
-
|
178
|
-
rule = Sass::Tree::RuleNode.new([sel])
|
179
|
-
last_el.rules.each {|r| rule << r.to_sass_tree}
|
180
|
-
return rule
|
181
|
-
end
|
182
|
-
|
183
|
-
def sass_selector_str
|
184
|
-
case @selector
|
185
|
-
when /[+>~]/; "#{@selector} #{@name}"
|
186
|
-
else @selector + @name
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
module Mixin
|
192
|
-
class Call
|
193
|
-
def to_sass_tree
|
194
|
-
return if hide_in_sass
|
195
|
-
Sass::Tree::MixinNode.new(@mixin.name.gsub(/^\./, ''), @params.map {|v| v.to_sass_tree})
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
class Def
|
200
|
-
def to_sass_tree
|
201
|
-
return if hide_in_sass
|
202
|
-
mixin = Sass::Tree::MixinDefNode.new(name, @params.map do |v|
|
203
|
-
v.value.flatten!
|
204
|
-
[Sass::Script::Variable.new(v), v.value.to_sass_tree]
|
205
|
-
end)
|
206
|
-
rules.each {|r| mixin << r.to_sass_tree}
|
207
|
-
mixin
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
class SassNode
|
213
|
-
include Entity
|
214
|
-
|
215
|
-
def initialize(node)
|
216
|
-
@node = node
|
217
|
-
end
|
218
|
-
|
219
|
-
def to_sass_tree
|
220
|
-
return if hide_in_sass
|
221
|
-
@node
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
class Property
|
226
|
-
def to_sass_tree
|
227
|
-
return if hide_in_sass
|
228
|
-
Sass::Tree::PropNode.new([self], @value.to_sass_tree, :new)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
class Expression
|
233
|
-
def to_sass_tree
|
234
|
-
if first.is_a?(Array)
|
235
|
-
val = map {|e| _to_sass_tree(e)}.inject(nil) do |e, i|
|
236
|
-
next i unless e
|
237
|
-
Sass::Script::Operation.new(e, i, :comma)
|
238
|
-
end
|
239
|
-
else
|
240
|
-
val = _to_sass_tree(self)
|
241
|
-
end
|
242
|
-
val.options = {}
|
243
|
-
val
|
244
|
-
end
|
245
|
-
|
246
|
-
private
|
247
|
-
|
248
|
-
LESS_TO_SASS_OPERATORS = {"-" => :minus, "+" => :plus, "*" => :times, "/" => :div, "=" => :single_eq}
|
249
|
-
|
250
|
-
def _to_sass_tree(arr)
|
251
|
-
e, rest = _to_sass_tree_plus_minus_eq(arr)
|
252
|
-
until rest.empty?
|
253
|
-
e2, rest = _to_sass_tree_plus_minus_eq(rest)
|
254
|
-
e = Sass::Script::Operation.new(e, e2, :concat)
|
255
|
-
end
|
256
|
-
return e
|
257
|
-
end
|
258
|
-
|
259
|
-
def _to_sass_tree_plus_minus_eq(arr)
|
260
|
-
e, rest = _to_sass_tree_times_div(arr)
|
261
|
-
while rest[0] && rest[0].is_a?(Operator) && %w[+ - =].include?(rest[0])
|
262
|
-
op = LESS_TO_SASS_OPERATORS[rest[0]]
|
263
|
-
e2, rest = _to_sass_tree_times_div(rest[1..-1])
|
264
|
-
e = Sass::Script::Operation.new(e, e2, op)
|
265
|
-
end
|
266
|
-
return e, rest
|
267
|
-
end
|
268
|
-
|
269
|
-
def _to_sass_tree_times_div(arr)
|
270
|
-
e, rest = _to_sass_tree_unary(arr)
|
271
|
-
while rest[0] && rest[0].is_a?(Operator) && %w[* /].include?(rest[0])
|
272
|
-
op = LESS_TO_SASS_OPERATORS[rest[0]]
|
273
|
-
e2, rest = _to_sass_tree_unary(rest[1..-1])
|
274
|
-
e = Sass::Script::Operation.new(e, e2, op)
|
275
|
-
end
|
276
|
-
return e, rest
|
277
|
-
end
|
278
|
-
|
279
|
-
def _to_sass_tree_unary(arr)
|
280
|
-
if arr[0] == "-"
|
281
|
-
first, rest = _sass_split(arr[1..-1])
|
282
|
-
return Sass::Script::UnaryOperation.new(first, :minus), rest
|
283
|
-
else
|
284
|
-
return _sass_split(arr[0..-1])
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
def _sass_split(arr)
|
289
|
-
return arr[0].to_sass_tree, arr[1..-1] unless arr[0] == "("
|
290
|
-
parens = 1
|
291
|
-
i = arr[1..-1].each_with_index do |e, i|
|
292
|
-
parens += 1 if e == "("
|
293
|
-
parens -= 1 if e == ")"
|
294
|
-
break i if parens == 0
|
295
|
-
end
|
296
|
-
|
297
|
-
return _to_sass_tree(arr[1...i+1]), arr[i+2..-1]
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
class Color
|
302
|
-
def to_sass_tree
|
303
|
-
Sass::Script::Color.new(:red => r, :green => g, :blue => b, :alpha => a)
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
class Number
|
308
|
-
def to_sass_tree
|
309
|
-
Sass::Script::Number.new(self, [self.unit])
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
class Variable
|
314
|
-
def to_sass_tree
|
315
|
-
if @declaration
|
316
|
-
return if hide_in_sass
|
317
|
-
node = Sass::Tree::VariableNode.new(self, @value.to_sass_tree, false)
|
318
|
-
node.line = self.src_line
|
319
|
-
node
|
320
|
-
else
|
321
|
-
Sass::Script::Variable.new(self)
|
322
|
-
end
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
class Function
|
327
|
-
def to_sass_tree
|
328
|
-
Sass::Script::Funcall.new(self, @args.map {|a| a.to_sass_tree})
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
class Keyword
|
333
|
-
def to_sass_tree
|
334
|
-
Sass::Script::String.new(self)
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
class Anonymous
|
339
|
-
def to_sass_tree
|
340
|
-
Sass::Script::String.new(self)
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
class Quoted
|
345
|
-
def to_sass_tree
|
346
|
-
Sass::Script::String.new(self, true)
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
class FontFamily
|
351
|
-
def to_sass_tree
|
352
|
-
@family.map {|f| f.to_sass_tree}.inject(nil) do |e, f|
|
353
|
-
next f unless e
|
354
|
-
Sass::Script::Operation.new(e, f, :comma)
|
355
|
-
end
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
# The entry point to Less.
|
361
|
-
# By default Less doesn't preserve the filename of the file being parsed,
|
362
|
-
# which is unpleasant for error reporting.
|
363
|
-
# Our monkeypatch keeps it around.
|
364
|
-
class Engine
|
365
|
-
def initialize_with_sass(obj, opts = {})
|
366
|
-
initialize_without_sass(obj, opts)
|
367
|
-
@filename = obj.path if obj.is_a?(File)
|
368
|
-
end
|
369
|
-
alias_method :initialize_without_sass, :initialize
|
370
|
-
alias_method :initialize, :initialize_with_sass
|
371
|
-
|
372
|
-
def parse_with_sass
|
373
|
-
parse_without_sass
|
374
|
-
rescue Sass::SyntaxError => e
|
375
|
-
e.modify_backtrace(:filename => @filename)
|
376
|
-
raise e
|
377
|
-
end
|
378
|
-
alias_method :parse_without_sass, :parse
|
379
|
-
alias_method :parse, :parse_with_sass
|
380
|
-
alias_method :to_tree, :parse
|
381
|
-
end
|
382
|
-
end
|
data/lib/sass/plugin.rb
DELETED
@@ -1,279 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
require 'sass'
|
4
|
-
require 'sass/plugin/configuration'
|
5
|
-
require 'sass/plugin/staleness_checker'
|
6
|
-
|
7
|
-
module Sass
|
8
|
-
# This module handles the compilation of Sass/SCSS files.
|
9
|
-
# It provides global options and checks whether CSS files
|
10
|
-
# need to be updated.
|
11
|
-
#
|
12
|
-
# This module is used as the primary interface with Sass
|
13
|
-
# when it's used as a plugin for various frameworks.
|
14
|
-
# All Rack-enabled frameworks are supported out of the box.
|
15
|
-
# The plugin is {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}.
|
16
|
-
# Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
|
17
|
-
#
|
18
|
-
# This module has a large set of callbacks available
|
19
|
-
# to allow users to run code (such as logging) when certain things happen.
|
20
|
-
# All callback methods are of the form `on_#{name}`,
|
21
|
-
# and they all take a block that's called when the given action occurs.
|
22
|
-
#
|
23
|
-
# @example Using a callback
|
24
|
-
# Sass::Plugin.on_updating_stylesheet do |template, css|
|
25
|
-
# puts "Compiling #{template} to #{css}"
|
26
|
-
# end
|
27
|
-
# Sass::Plugin.update_stylesheets
|
28
|
-
# #=> Compiling app/sass/screen.scss to public/stylesheets/screen.css
|
29
|
-
# #=> Compiling app/sass/print.scss to public/stylesheets/print.css
|
30
|
-
# #=> Compiling app/sass/ie.scss to public/stylesheets/ie.css
|
31
|
-
module Plugin
|
32
|
-
include Haml::Util
|
33
|
-
|
34
|
-
@checked_for_updates = false
|
35
|
-
|
36
|
-
# Whether or not Sass has **ever** checked if the stylesheets need to be updated
|
37
|
-
# (in this Ruby instance).
|
38
|
-
#
|
39
|
-
# @return [Boolean]
|
40
|
-
attr_reader :checked_for_updates
|
41
|
-
|
42
|
-
# Same as \{#update\_stylesheets}, but respects \{#checked\_for\_updates}
|
43
|
-
# and the {file:SASS_REFERENCE.md#always_update-option `:always_update`}
|
44
|
-
# and {file:SASS_REFERENCE.md#always_check-option `:always_check`} options.
|
45
|
-
#
|
46
|
-
# @see #update_stylesheets
|
47
|
-
def check_for_updates
|
48
|
-
return unless !Sass::Plugin.checked_for_updates ||
|
49
|
-
Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
|
50
|
-
update_stylesheets
|
51
|
-
end
|
52
|
-
|
53
|
-
# Updates out-of-date stylesheets.
|
54
|
-
#
|
55
|
-
# Checks each Sass/SCSS file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}
|
56
|
-
# to see if it's been modified more recently than the corresponding CSS file
|
57
|
-
# in {file:SASS_REFERENCE.md#css_location-option `:css_location`}.
|
58
|
-
# If it has, it updates the CSS file.
|
59
|
-
#
|
60
|
-
# @param individual_files [Array<(String, String)>]
|
61
|
-
# A list of files to check for updates
|
62
|
-
# **in addition to those specified by the
|
63
|
-
# {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
|
64
|
-
# The first string in each pair is the location of the Sass/SCSS file,
|
65
|
-
# the second is the location of the CSS file that it should be compiled to.
|
66
|
-
def update_stylesheets(individual_files = [])
|
67
|
-
return if options[:never_update]
|
68
|
-
|
69
|
-
run_updating_stylesheets individual_files
|
70
|
-
@checked_for_updates = true
|
71
|
-
staleness_checker = StalenessChecker.new
|
72
|
-
|
73
|
-
individual_files.each do |t, c|
|
74
|
-
if options[:always_update] || staleness_checker.stylesheet_needs_update?(c, t)
|
75
|
-
update_stylesheet(t, c)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
template_location_array.each do |template_location, css_location|
|
80
|
-
|
81
|
-
Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).sort.each do |file|
|
82
|
-
# Get the relative path to the file
|
83
|
-
name = file.sub(template_location.sub(/\/*$/, '/'), "")
|
84
|
-
css = css_filename(name, css_location)
|
85
|
-
|
86
|
-
next if forbid_update?(name)
|
87
|
-
if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
|
88
|
-
update_stylesheet file, css
|
89
|
-
else
|
90
|
-
run_not_updating_stylesheet file, css
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Updates all stylesheets, even those that aren't out-of-date.
|
97
|
-
# Ignores the cache.
|
98
|
-
#
|
99
|
-
# @param individual_files [Array<(String, String)>]
|
100
|
-
# A list of files to check for updates
|
101
|
-
# **in addition to those specified by the
|
102
|
-
# {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
|
103
|
-
# The first string in each pair is the location of the Sass/SCSS file,
|
104
|
-
# the second is the location of the CSS file that it should be compiled to.
|
105
|
-
# @see #update_stylesheets
|
106
|
-
def force_update_stylesheets(individual_files = [])
|
107
|
-
old_options = options
|
108
|
-
self.options = options.dup
|
109
|
-
options[:never_update] = false
|
110
|
-
options[:always_update] = true
|
111
|
-
options[:cache] = false
|
112
|
-
update_stylesheets(individual_files)
|
113
|
-
ensure
|
114
|
-
self.options = old_options
|
115
|
-
end
|
116
|
-
|
117
|
-
# Watches the template directory (or directories)
|
118
|
-
# and updates the CSS files whenever the related Sass/SCSS files change.
|
119
|
-
# `watch` never returns.
|
120
|
-
#
|
121
|
-
# Whenever a change is detected to a Sass/SCSS file in
|
122
|
-
# {file:SASS_REFERENCE.md#template_location-option `:template_location`},
|
123
|
-
# the corresponding CSS file in {file:SASS_REFERENCE.md#css_location-option `:css_location`}
|
124
|
-
# will be recompiled.
|
125
|
-
# The CSS files of any Sass/SCSS files that import the changed file will also be recompiled.
|
126
|
-
#
|
127
|
-
# Before the watching starts in earnest, `watch` calls \{#update\_stylesheets}.
|
128
|
-
#
|
129
|
-
# Note that `watch` uses the [FSSM](http://github.com/ttilley/fssm) library
|
130
|
-
# to monitor the filesystem for changes.
|
131
|
-
# FSSM isn't loaded until `watch` is run.
|
132
|
-
# The version of FSSM distributed with Sass is loaded by default,
|
133
|
-
# but if another version has already been loaded that will be used instead.
|
134
|
-
#
|
135
|
-
# @param individual_files [Array<(String, String)>]
|
136
|
-
# A list of files to watch for updates
|
137
|
-
# **in addition to those specified by the
|
138
|
-
# {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
|
139
|
-
# The first string in each pair is the location of the Sass/SCSS file,
|
140
|
-
# the second is the location of the CSS file that it should be compiled to.
|
141
|
-
def watch(individual_files = [])
|
142
|
-
update_stylesheets(individual_files)
|
143
|
-
|
144
|
-
begin
|
145
|
-
require 'fssm'
|
146
|
-
rescue LoadError => e
|
147
|
-
e.message << "\n" <<
|
148
|
-
if File.exists?(scope(".git"))
|
149
|
-
'Run "git submodule update --init" to get the recommended version.'
|
150
|
-
else
|
151
|
-
'Run "gem install fssm" to get it.'
|
152
|
-
end
|
153
|
-
raise e
|
154
|
-
end
|
155
|
-
|
156
|
-
unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents"
|
157
|
-
# As of FSSM 0.1.4, it doesn't support FSevents on individual files,
|
158
|
-
# but it also isn't smart enough to switch to polling itself.
|
159
|
-
require 'fssm/backends/polling'
|
160
|
-
Haml::Util.silence_warnings do
|
161
|
-
FSSM::Backends.const_set(:Default, FSSM::Backends::Polling)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
# TODO: Keep better track of what depends on what
|
166
|
-
# so we don't have to run a global update every time anything changes.
|
167
|
-
FSSM.monitor do |mon|
|
168
|
-
template_location_array.each do |template_location, css_location|
|
169
|
-
mon.path template_location do |path|
|
170
|
-
path.glob '**/*.s[ac]ss'
|
171
|
-
|
172
|
-
path.update do |base, relative|
|
173
|
-
run_template_modified File.join(base, relative)
|
174
|
-
update_stylesheets(individual_files)
|
175
|
-
end
|
176
|
-
|
177
|
-
path.create do |base, relative|
|
178
|
-
run_template_created File.join(base, relative)
|
179
|
-
update_stylesheets(individual_files)
|
180
|
-
end
|
181
|
-
|
182
|
-
path.delete do |base, relative|
|
183
|
-
run_template_deleted File.join(base, relative)
|
184
|
-
css = File.join(css_location, relative.gsub(/\.s[ac]ss$/, '.css'))
|
185
|
-
try_delete_css css
|
186
|
-
update_stylesheets(individual_files)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
individual_files.each do |template, css|
|
192
|
-
mon.file template do |path|
|
193
|
-
path.update do
|
194
|
-
run_template_modified template
|
195
|
-
update_stylesheets(individual_files)
|
196
|
-
end
|
197
|
-
|
198
|
-
path.create do
|
199
|
-
run_template_created template
|
200
|
-
update_stylesheets(individual_files)
|
201
|
-
end
|
202
|
-
|
203
|
-
path.delete do
|
204
|
-
run_template_deleted template
|
205
|
-
try_delete_css css
|
206
|
-
update_stylesheets(individual_files)
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
private
|
214
|
-
|
215
|
-
def update_stylesheet(filename, css)
|
216
|
-
dir = File.dirname(css)
|
217
|
-
unless File.exists?(dir)
|
218
|
-
run_creating_directory dir
|
219
|
-
FileUtils.mkdir_p dir
|
220
|
-
end
|
221
|
-
|
222
|
-
begin
|
223
|
-
result = Sass::Files.tree_for(filename, engine_options(:css_filename => css, :filename => filename)).render
|
224
|
-
rescue Exception => e
|
225
|
-
run_compilation_error e, filename, css
|
226
|
-
result = Sass::SyntaxError.exception_to_css(e, options)
|
227
|
-
else
|
228
|
-
run_updating_stylesheet filename, css
|
229
|
-
end
|
230
|
-
|
231
|
-
# Finally, write the file
|
232
|
-
flag = 'w'
|
233
|
-
flag = 'wb' if Haml::Util.windows? && options[:unix_newlines]
|
234
|
-
File.open(css, flag) do |file|
|
235
|
-
file.set_encoding(result.encoding) unless Haml::Util.ruby1_8?
|
236
|
-
file.print(result)
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def try_delete_css(css)
|
241
|
-
return unless File.exists?(css)
|
242
|
-
run_deleting_css css
|
243
|
-
File.delete css
|
244
|
-
end
|
245
|
-
|
246
|
-
def load_paths(opts = options)
|
247
|
-
(opts[:load_paths] || []) + template_locations
|
248
|
-
end
|
249
|
-
|
250
|
-
def template_locations
|
251
|
-
template_location_array.to_a.map {|l| l.first}
|
252
|
-
end
|
253
|
-
|
254
|
-
def css_locations
|
255
|
-
template_location_array.to_a.map {|l| l.last}
|
256
|
-
end
|
257
|
-
|
258
|
-
def css_filename(name, path)
|
259
|
-
"#{path}/#{name}".gsub(/\.s[ac]ss$/, '.css')
|
260
|
-
end
|
261
|
-
|
262
|
-
def forbid_update?(name)
|
263
|
-
name.sub(/^.*\//, '')[0] == ?_
|
264
|
-
end
|
265
|
-
|
266
|
-
# Compass expects this to exist
|
267
|
-
def stylesheet_needs_update?(css_file, template_file)
|
268
|
-
StalenessChecker.stylesheet_needs_update?(css_file, template_file)
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
if defined?(ActionController)
|
274
|
-
require 'sass/plugin/rails'
|
275
|
-
elsif defined?(Merb::Plugins)
|
276
|
-
require 'sass/plugin/merb'
|
277
|
-
else
|
278
|
-
require 'sass/plugin/generic'
|
279
|
-
end
|