haml 2.2.24 → 3.0.0.beta.1
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 +0 -1
- data/README.md +91 -151
- data/REMEMBER +11 -1
- data/Rakefile +73 -55
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/bin/css2sass +7 -1
- data/bin/sass-convert +7 -0
- data/extra/haml-mode.el +2 -1
- data/lib/haml/buffer.rb +22 -4
- data/lib/haml/engine.rb +5 -1
- data/lib/haml/exec.rb +231 -46
- data/lib/haml/filters.rb +19 -8
- data/lib/haml/helpers.rb +47 -20
- data/lib/haml/helpers/action_view_extensions.rb +2 -4
- data/lib/haml/helpers/action_view_mods.rb +11 -8
- data/lib/haml/helpers/xss_mods.rb +13 -2
- data/lib/haml/html.rb +179 -48
- data/lib/haml/html/erb.rb +141 -0
- data/lib/haml/precompiler.rb +40 -15
- data/lib/haml/railtie.rb +1 -5
- data/lib/haml/root.rb +3 -0
- data/lib/haml/template.rb +4 -14
- data/lib/haml/util.rb +120 -30
- data/lib/haml/version.rb +25 -2
- data/lib/sass.rb +5 -1
- data/lib/sass/callbacks.rb +50 -0
- data/lib/sass/css.rb +40 -191
- data/lib/sass/engine.rb +170 -74
- data/lib/sass/environment.rb +8 -2
- data/lib/sass/error.rb +163 -25
- data/lib/sass/files.rb +31 -28
- data/lib/sass/plugin.rb +268 -87
- data/lib/sass/plugin/rails.rb +9 -4
- data/lib/sass/repl.rb +1 -1
- data/lib/sass/script.rb +31 -29
- data/lib/sass/script/bool.rb +1 -0
- data/lib/sass/script/color.rb +290 -23
- data/lib/sass/script/css_lexer.rb +22 -0
- data/lib/sass/script/css_parser.rb +28 -0
- data/lib/sass/script/funcall.rb +22 -3
- data/lib/sass/script/functions.rb +523 -33
- data/lib/sass/script/interpolation.rb +42 -0
- data/lib/sass/script/lexer.rb +169 -52
- data/lib/sass/script/literal.rb +58 -9
- data/lib/sass/script/node.rb +79 -1
- data/lib/sass/script/number.rb +20 -5
- data/lib/sass/script/operation.rb +49 -3
- data/lib/sass/script/parser.rb +162 -28
- data/lib/sass/script/string.rb +50 -2
- data/lib/sass/script/unary_operation.rb +25 -2
- data/lib/sass/script/variable.rb +21 -4
- data/lib/sass/scss.rb +14 -0
- data/lib/sass/scss/css_parser.rb +39 -0
- data/lib/sass/scss/parser.rb +683 -0
- data/lib/sass/scss/rx.rb +112 -0
- data/lib/sass/scss/script_lexer.rb +13 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/tree/comment_node.rb +69 -27
- data/lib/sass/tree/debug_node.rb +7 -2
- data/lib/sass/tree/directive_node.rb +41 -35
- data/lib/sass/tree/for_node.rb +6 -0
- data/lib/sass/tree/if_node.rb +13 -1
- data/lib/sass/tree/import_node.rb +52 -27
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +41 -6
- data/lib/sass/tree/node.rb +197 -70
- data/lib/sass/tree/prop_node.rb +152 -57
- data/lib/sass/tree/root_node.rb +118 -0
- data/lib/sass/tree/rule_node.rb +193 -96
- data/lib/sass/tree/variable_node.rb +9 -5
- data/lib/sass/tree/while_node.rb +4 -0
- data/test/benchmark.rb +5 -5
- data/test/haml/engine_test.rb +147 -10
- data/test/haml/{rhtml/_av_partial_1.rhtml → erb/_av_partial_1.erb} +1 -1
- data/test/haml/{rhtml/_av_partial_2.rhtml → erb/_av_partial_2.erb} +1 -1
- data/test/haml/{rhtml/action_view.rhtml → erb/action_view.erb} +1 -1
- data/test/haml/{rhtml/standard.rhtml → erb/standard.erb} +0 -0
- data/test/haml/helper_test.rb +91 -24
- data/test/haml/html2haml/erb_tests.rb +410 -0
- data/test/haml/html2haml_test.rb +210 -66
- data/test/haml/results/filters.xhtml +1 -1
- data/test/haml/results/just_stuff.xhtml +2 -0
- data/test/haml/spec_test.rb +44 -0
- data/test/haml/template_test.rb +22 -2
- data/test/haml/templates/helpers.haml +0 -13
- data/test/haml/templates/just_stuff.haml +2 -0
- data/test/haml/util_test.rb +48 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/conversion_test.rb +884 -0
- data/test/sass/css2sass_test.rb +99 -18
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/engine_test.rb +1049 -131
- data/test/sass/functions_test.rb +398 -47
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more_import.sass +3 -3
- data/test/sass/plugin_test.rb +184 -10
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +5 -5
- data/test/sass/results/compressed.css +1 -1
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +3 -1
- data/test/sass/results/mixins.css +12 -12
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/options.css +1 -0
- data/test/sass/results/parent_ref.css +4 -4
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +15 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/script_conversion_test.rb +153 -0
- data/test/sass/script_test.rb +137 -70
- data/test/sass/scss/css_test.rb +811 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +871 -0
- data/test/sass/scss/test_helper.rb +37 -0
- data/test/sass/templates/alt.sass +2 -2
- data/test/sass/templates/bork1.sass +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/bork4.sass +2 -0
- data/test/sass/templates/import.sass +4 -4
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/line_numbers.sass +1 -1
- data/test/sass/templates/mixin_bork.sass +5 -0
- data/test/sass/templates/mixins.sass +2 -2
- data/test/sass/templates/nested_bork1.sass +2 -0
- data/test/sass/templates/nested_bork2.sass +2 -0
- data/test/sass/templates/nested_bork3.sass +2 -0
- data/test/sass/templates/nested_bork4.sass +2 -0
- data/test/sass/templates/nested_mixin_bork.sass +6 -0
- data/test/sass/templates/options.sass +2 -0
- data/test/sass/templates/parent_ref.sass +2 -2
- data/test/sass/templates/script.sass +69 -69
- data/test/sass/templates/scss_import.scss +10 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/units.sass +10 -10
- data/test/test_helper.rb +20 -8
- data/vendor/fssm/LICENSE +20 -0
- data/vendor/fssm/README.markdown +55 -0
- data/vendor/fssm/Rakefile +59 -0
- data/vendor/fssm/VERSION.yml +5 -0
- data/vendor/fssm/example.rb +9 -0
- data/vendor/fssm/fssm.gemspec +77 -0
- data/vendor/fssm/lib/fssm.rb +33 -0
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
- data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
- data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
- data/vendor/fssm/lib/fssm/monitor.rb +26 -0
- data/vendor/fssm/lib/fssm/path.rb +91 -0
- data/vendor/fssm/lib/fssm/pathname.rb +502 -0
- data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
- data/vendor/fssm/lib/fssm/state/file.rb +24 -0
- data/vendor/fssm/lib/fssm/support.rb +63 -0
- data/vendor/fssm/lib/fssm/tree.rb +176 -0
- data/vendor/fssm/profile/prof-cache.rb +40 -0
- data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
- data/vendor/fssm/profile/prof-pathname.rb +68 -0
- data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
- data/vendor/fssm/profile/prof.html +2379 -0
- data/vendor/fssm/spec/path_spec.rb +75 -0
- 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 +14 -0
- metadata +94 -14
- data/test/sass/templates/bork.sass +0 -2
data/lib/sass/scss/rx.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
module Sass
|
2
|
+
module SCSS
|
3
|
+
# A module containing regular expressions used
|
4
|
+
# for lexing tokens in an SCSS document.
|
5
|
+
# Most of these are taken from [the CSS3 spec](http://www.w3.org/TR/css3-syntax/#lexical),
|
6
|
+
# although some have been modified for various reasons.
|
7
|
+
module RX
|
8
|
+
# Takes a string and returns a CSS identifier
|
9
|
+
# that will have the value of the given string.
|
10
|
+
#
|
11
|
+
# @param str [String] The string to escape
|
12
|
+
# @return [String] The escaped string
|
13
|
+
def self.escape_ident(str)
|
14
|
+
return "" if str.empty?
|
15
|
+
return "\\#{str}" if str == '-' || str == '_'
|
16
|
+
out = ""
|
17
|
+
value = str.dup
|
18
|
+
out << value.slice!(0...1) if value =~ /^[-_]/
|
19
|
+
if value[0...1] =~ NMSTART
|
20
|
+
out << value.slice!(0...1)
|
21
|
+
else
|
22
|
+
out << escape_char(value.slice!(0...1))
|
23
|
+
end
|
24
|
+
out << value.gsub(/[^a-zA-Z0-9_-]/) {|c| escape_char c}
|
25
|
+
return out
|
26
|
+
end
|
27
|
+
|
28
|
+
# Escapes a single character for a CSS identifier.
|
29
|
+
#
|
30
|
+
# @param c [String] The character to escape. Should have length 1
|
31
|
+
# @return [String] The escaped character
|
32
|
+
# @private
|
33
|
+
def self.escape_char(c)
|
34
|
+
return "\\%06x" % Haml::Util.ord(c) unless c =~ /[ -\/:-~]/
|
35
|
+
return "\\#{c}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Creates a Regexp from a plain text string,
|
39
|
+
# escaping all significant characters.
|
40
|
+
#
|
41
|
+
# @param str [String] The text of the regexp
|
42
|
+
# @param flags [Fixnum] Flags for the created regular expression
|
43
|
+
# @return [Regexp]
|
44
|
+
# @private
|
45
|
+
def self.quote(str, flags = 0)
|
46
|
+
Regexp.new(Regexp.quote(str), flags)
|
47
|
+
end
|
48
|
+
|
49
|
+
H = /[0-9a-fA-F]/
|
50
|
+
NL = /\n|\r\n|\r|\f/
|
51
|
+
UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/
|
52
|
+
s = if Haml::Util.ruby1_8?
|
53
|
+
'\200-\377'
|
54
|
+
else
|
55
|
+
'\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
|
56
|
+
end
|
57
|
+
NONASCII = /[#{s}]/
|
58
|
+
ESCAPE = /#{UNICODE}|\\[ -~#{s}]/
|
59
|
+
NMSTART = /[a-zA-Z]|#{NONASCII}|#{ESCAPE}/
|
60
|
+
NMCHAR = /[a-zA-Z0-9_-]|#{NONASCII}|#{ESCAPE}/
|
61
|
+
STRING1 = /\"((?:[^\n\r\f\\"]|\\#{NL}|#{ESCAPE})*)\"/
|
62
|
+
STRING2 = /\'((?:[^\n\r\f\\']|\\#{NL}|#{ESCAPE})*)\'/
|
63
|
+
|
64
|
+
IDENT = /[-_]?#{NMSTART}#{NMCHAR}*/
|
65
|
+
NAME = /#{NMCHAR}+/
|
66
|
+
NUM = /[0-9]+|[0-9]*.[0-9]+/
|
67
|
+
STRING = /#{STRING1}|#{STRING2}/
|
68
|
+
URL = /((?:[!#%$&*-~]|#{NONASCII}|#{ESCAPE})*)/
|
69
|
+
W = /[ \t\r\n\f]*/
|
70
|
+
|
71
|
+
# This is more liberal than the spec's definition,
|
72
|
+
# but that definition didn't work well with the greediness rules
|
73
|
+
RANGE = /(?:#{H}|\?){1,6}/
|
74
|
+
|
75
|
+
##
|
76
|
+
|
77
|
+
S = /[ \t\r\n\f]+/
|
78
|
+
|
79
|
+
COMMENT = /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
|
80
|
+
SINGLE_LINE_COMMENT = /\/\/.*(\n[ \t]*\/\/.*)*/
|
81
|
+
|
82
|
+
CDO = quote("<!--")
|
83
|
+
CDC = quote("-->")
|
84
|
+
INCLUDES = quote("~=")
|
85
|
+
DASHMATCH = quote("|=")
|
86
|
+
PREFIXMATCH = quote("^=")
|
87
|
+
SUFFIXMATCH = quote("$=")
|
88
|
+
SUBSTRINGMATCH = quote("*=")
|
89
|
+
|
90
|
+
HASH = /##{NAME}/
|
91
|
+
|
92
|
+
IMPORTANT = /!#{W}important/i
|
93
|
+
DEFAULT = /!#{W}default/i
|
94
|
+
|
95
|
+
NUMBER = /#{NUM}(?:#{IDENT}|%)?/
|
96
|
+
|
97
|
+
URI = /url\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
|
98
|
+
FUNCTION = /#{IDENT}\(/
|
99
|
+
|
100
|
+
UNICODERANGE = /u\+(?:#{H}{1,6}-#{H}{1,6}|#{RANGE})/i
|
101
|
+
|
102
|
+
# Defined in http://www.w3.org/TR/css3-selectors/#lex
|
103
|
+
PLUS = /#{W}\+/
|
104
|
+
GREATER = /#{W}>/
|
105
|
+
TILDE = /#{W}~/
|
106
|
+
NOT = quote(":not(", Regexp::IGNORECASE)
|
107
|
+
|
108
|
+
# Custom
|
109
|
+
HEXCOLOR = /\#[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?/
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Sass
|
2
|
+
module SCSS
|
3
|
+
# A mixin for subclasses of {Sass::Script::Lexer}
|
4
|
+
# that makes them usable by {SCSS::Parser} to parse SassScript.
|
5
|
+
# In particular, the lexer doesn't support `!` for a variable prefix.
|
6
|
+
module ScriptLexer
|
7
|
+
def variable
|
8
|
+
return [:raw, "!important"] if scan(Sass::SCSS::RX::IMPORTANT)
|
9
|
+
_variable(/(\$)(#{Sass::SCSS::RX::IDENT})/)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Sass
|
2
|
+
module SCSS
|
3
|
+
# A mixin for subclasses of {Sass::Script::Parser}
|
4
|
+
# that makes them usable by {SCSS::Parser} to parse SassScript.
|
5
|
+
# In particular, the parser won't raise an error
|
6
|
+
# when there's more content in the lexer once lexing is done.
|
7
|
+
# In addition, the parser doesn't support `!` for a variable prefix.
|
8
|
+
module ScriptParser
|
9
|
+
private
|
10
|
+
|
11
|
+
# @private
|
12
|
+
def lexer_class
|
13
|
+
klass = Class.new(super)
|
14
|
+
klass.send(:include, ScriptLexer)
|
15
|
+
klass
|
16
|
+
end
|
17
|
+
|
18
|
+
# Instead of raising an error when the parser is done,
|
19
|
+
# rewind the StringScanner so that it hasn't consumed the final token.
|
20
|
+
def assert_done
|
21
|
+
@lexer.unpeek!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -5,12 +5,7 @@ module Sass::Tree
|
|
5
5
|
#
|
6
6
|
# @see Sass::Tree
|
7
7
|
class CommentNode < Node
|
8
|
-
# The
|
9
|
-
#
|
10
|
-
# @return [Array<Sass::Engine::Line>]
|
11
|
-
attr_accessor :lines
|
12
|
-
|
13
|
-
# The text on the same line as the comment starter.
|
8
|
+
# The text of the comment, not including `/*` and `*/`.
|
14
9
|
#
|
15
10
|
# @return [String]
|
16
11
|
attr_accessor :value
|
@@ -24,7 +19,7 @@ module Sass::Tree
|
|
24
19
|
# @param silent [Boolean] See \{#silent}
|
25
20
|
def initialize(value, silent)
|
26
21
|
@lines = []
|
27
|
-
@value = value
|
22
|
+
@value = normalize_indentation value
|
28
23
|
@silent = silent
|
29
24
|
super()
|
30
25
|
end
|
@@ -35,9 +30,58 @@ module Sass::Tree
|
|
35
30
|
# @return [Boolean] Whether or not this node and the other object
|
36
31
|
# are the same
|
37
32
|
def ==(other)
|
38
|
-
self.class == other.class && value == other.value && silent == other.silent
|
33
|
+
self.class == other.class && value == other.value && silent == other.silent
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns `true` if this is a silent comment
|
37
|
+
# or the current style doesn't render comments.
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
def invisible?
|
41
|
+
style == :compressed || @silent
|
42
|
+
end
|
43
|
+
|
44
|
+
# @see Node#to_sass
|
45
|
+
def to_sass(tabs, opts = {})
|
46
|
+
content = value.gsub(/\*\/$/, '').rstrip
|
47
|
+
if content =~ /\A[ \t]/
|
48
|
+
# Re-indent SCSS comments like this:
|
49
|
+
# /* foo
|
50
|
+
# bar
|
51
|
+
# baz */
|
52
|
+
content.gsub!(/^/, ' ')
|
53
|
+
content.sub!(/\A([ \t]*)\/\*/, '/*\1')
|
54
|
+
end
|
55
|
+
|
56
|
+
content =
|
57
|
+
unless content.include?("\n")
|
58
|
+
content
|
59
|
+
else
|
60
|
+
content.gsub!(/\n( \*|\/\/)/, "\n ")
|
61
|
+
spaces = content.scan(/\n( *)/).map {|s| s.first.size}.min
|
62
|
+
if spaces >= 2
|
63
|
+
content
|
64
|
+
else
|
65
|
+
content.gsub(/\n#{' ' * spaces}/, "\n ")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
content.gsub!(/^/, ' ' * tabs)
|
70
|
+
content.gsub!(/\A\/\*/, '//') if silent
|
71
|
+
content.rstrip + "\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_scss(tabs, opts = {})
|
75
|
+
spaces = (' ' * [tabs - value[/^ */].size, 0].max)
|
76
|
+
if silent
|
77
|
+
value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
|
78
|
+
else
|
79
|
+
value
|
80
|
+
end.gsub(/^/, spaces) + "\n"
|
39
81
|
end
|
40
82
|
|
83
|
+
protected
|
84
|
+
|
41
85
|
# Computes the CSS for the comment.
|
42
86
|
#
|
43
87
|
# Returns `nil` if this is a silent comment
|
@@ -47,29 +91,15 @@ module Sass::Tree
|
|
47
91
|
# @param tabs [Fixnum] The level of indentation for the CSS
|
48
92
|
# @return [String, nil] The resulting CSS
|
49
93
|
# @see #invisible?
|
50
|
-
def
|
94
|
+
def _to_s(tabs = 0, _ = nil)
|
51
95
|
return if invisible?
|
52
|
-
spaces = ' ' *
|
53
|
-
|
54
|
-
content = (value.split("\n") + lines.map {|l| l.text})
|
55
|
-
return spaces + "/* */" if content.empty?
|
56
|
-
content.map! {|l| (l.empty? ? "" : " ") + l}
|
57
|
-
content.first.gsub!(/^ /, '')
|
58
|
-
content.last.gsub!(%r{ ?\*/ *$}, '')
|
59
|
-
|
60
|
-
spaces + "/* " + content.join(style == :compact ? '' : "\n#{spaces} *") + " */"
|
61
|
-
end
|
96
|
+
spaces = (' ' * [tabs - 1 - value[/^ */].size, 0].max)
|
62
97
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# @return [Boolean]
|
67
|
-
def invisible?
|
68
|
-
style == :compressed || @silent
|
98
|
+
content = value.gsub(/^/, spaces)
|
99
|
+
content.gsub!(/\n +(\* *)?/, ' ') if style == :compact
|
100
|
+
content
|
69
101
|
end
|
70
102
|
|
71
|
-
protected
|
72
|
-
|
73
103
|
# Removes this node from the tree if it's a silent comment.
|
74
104
|
#
|
75
105
|
# @param environment [Sass::Environment] The lexical environment containing
|
@@ -80,5 +110,17 @@ module Sass::Tree
|
|
80
110
|
return [] if @silent
|
81
111
|
self
|
82
112
|
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def normalize_indentation(str)
|
117
|
+
pre = str.split("\n").inject(str[/^[ \t]*/].split("")) do |pre, line|
|
118
|
+
line[/^[ \t]*/].split("").zip(pre).inject([]) do |arr, (a, b)|
|
119
|
+
break arr if a != b
|
120
|
+
arr + [a]
|
121
|
+
end
|
122
|
+
end.join
|
123
|
+
str.gsub(/^#{pre}/, '')
|
124
|
+
end
|
83
125
|
end
|
84
126
|
end
|
data/lib/sass/tree/debug_node.rb
CHANGED
@@ -12,16 +12,21 @@ module Sass
|
|
12
12
|
|
13
13
|
protected
|
14
14
|
|
15
|
+
def to_src(tabs, opts, fmt)
|
16
|
+
"#{' ' * tabs}@debug #{@expr.to_sass}#{semi fmt}\n"
|
17
|
+
end
|
18
|
+
|
15
19
|
# Prints the expression to STDERR.
|
16
20
|
#
|
17
21
|
# @param environment [Sass::Environment] The lexical environment containing
|
18
22
|
# variable and mixin values
|
19
23
|
def _perform(environment)
|
20
24
|
res = @expr.perform(environment)
|
25
|
+
res = res.value if res.is_a?(Sass::Script::String)
|
21
26
|
if filename
|
22
|
-
|
27
|
+
$stderr.puts "#{filename}:#{line} DEBUG: #{res}"
|
23
28
|
else
|
24
|
-
|
29
|
+
$stderr.puts "Line #{line} DEBUG: #{res}"
|
25
30
|
end
|
26
31
|
[]
|
27
32
|
end
|
@@ -20,49 +20,55 @@ module Sass::Tree
|
|
20
20
|
super()
|
21
21
|
end
|
22
22
|
|
23
|
+
protected
|
24
|
+
|
25
|
+
def to_src(tabs, opts, fmt)
|
26
|
+
res = "#{' ' * tabs}#{value}"
|
27
|
+
return res + "#{semi fmt}\n" if children.empty?
|
28
|
+
res + children_to_src(tabs, opts, fmt) + "\n"
|
29
|
+
end
|
30
|
+
|
23
31
|
# Computes the CSS for the directive.
|
24
32
|
#
|
25
33
|
# @param tabs [Fixnum] The level of indentation for the CSS
|
26
34
|
# @return [String] The resulting CSS
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
if
|
41
|
-
|
42
|
-
result << "#{child.to_s(first || was_prop ? 1 : tabs + 1)} "
|
43
|
-
else
|
44
|
-
if was_prop
|
45
|
-
result[-1] = "\n"
|
46
|
-
end
|
47
|
-
rendered = child.to_s(tabs + 1)
|
48
|
-
rendered.lstrip! if first
|
49
|
-
result << rendered
|
50
|
-
end
|
51
|
-
was_prop = child.is_a?(PropNode)
|
52
|
-
first = false
|
53
|
-
elsif style == :compressed
|
54
|
-
result << (was_prop ? ";#{child.to_s(1)}" : child.to_s(1))
|
55
|
-
was_prop = child.is_a?(PropNode)
|
35
|
+
def _to_s(tabs)
|
36
|
+
return value + ";" unless has_children
|
37
|
+
return value + " {}" if children.empty?
|
38
|
+
result = if style == :compressed
|
39
|
+
"#{value}{"
|
40
|
+
else
|
41
|
+
"#{' ' * (tabs - 1)}#{value} {" + (style == :compact ? ' ' : "\n")
|
42
|
+
end
|
43
|
+
was_prop = false
|
44
|
+
first = true
|
45
|
+
children.each do |child|
|
46
|
+
next if child.invisible?
|
47
|
+
if style == :compact
|
48
|
+
if child.is_a?(PropNode)
|
49
|
+
result << "#{child.to_s(first || was_prop ? 1 : tabs + 1)} "
|
56
50
|
else
|
57
|
-
|
51
|
+
if was_prop
|
52
|
+
result[-1] = "\n"
|
53
|
+
end
|
54
|
+
rendered = child.to_s(tabs + 1).dup
|
55
|
+
rendered = rendered.lstrip if first
|
56
|
+
result << rendered.rstrip + "\n"
|
58
57
|
end
|
58
|
+
was_prop = child.is_a?(PropNode)
|
59
|
+
first = false
|
60
|
+
elsif style == :compressed
|
61
|
+
result << (was_prop ? ";#{child.to_s(1)}" : child.to_s(1))
|
62
|
+
was_prop = child.is_a?(PropNode)
|
63
|
+
else
|
64
|
+
result << child.to_s(tabs + 1) + "\n"
|
59
65
|
end
|
60
|
-
result.rstrip + if style == :compressed
|
61
|
-
"}"
|
62
|
-
else
|
63
|
-
(style == :expanded ? "\n" : " ") + "}\n"
|
64
|
-
end
|
65
66
|
end
|
67
|
+
result.rstrip + if style == :compressed
|
68
|
+
"}"
|
69
|
+
else
|
70
|
+
(style == :expanded ? "\n" : " ") + "}\n"
|
71
|
+
end
|
66
72
|
end
|
67
73
|
end
|
68
74
|
end
|
data/lib/sass/tree/for_node.rb
CHANGED
@@ -20,6 +20,12 @@ module Sass::Tree
|
|
20
20
|
|
21
21
|
protected
|
22
22
|
|
23
|
+
def to_src(tabs, opts, fmt)
|
24
|
+
to = @exclusive ? "to" : "through"
|
25
|
+
"#{' ' * tabs}@for $#{@var} from #{@from.to_sass} #{to} #{@to.to_sass}" +
|
26
|
+
children_to_src(tabs, opts, fmt)
|
27
|
+
end
|
28
|
+
|
23
29
|
# Runs the child nodes once for each time through the loop,
|
24
30
|
# varying the variable each time.
|
25
31
|
#
|
data/lib/sass/tree/if_node.rb
CHANGED
@@ -30,7 +30,6 @@ module Sass::Tree
|
|
30
30
|
@last_else = node
|
31
31
|
end
|
32
32
|
|
33
|
-
# @see Node#options=
|
34
33
|
def options=(options)
|
35
34
|
super
|
36
35
|
self.else.options = options if self.else
|
@@ -38,6 +37,19 @@ module Sass::Tree
|
|
38
37
|
|
39
38
|
protected
|
40
39
|
|
40
|
+
def to_src(tabs, opts, fmt, is_else = false)
|
41
|
+
name =
|
42
|
+
if !is_else; "if"
|
43
|
+
elsif @expr; "else if"
|
44
|
+
else; "else"
|
45
|
+
end
|
46
|
+
str = "#{' ' * tabs}@#{name}"
|
47
|
+
str << " #{@expr.to_sass}" if @expr
|
48
|
+
str << children_to_src(tabs, opts, fmt)
|
49
|
+
str << @else.send(:to_src, tabs, opts, fmt, true) if @else
|
50
|
+
str
|
51
|
+
end
|
52
|
+
|
41
53
|
# Runs the child nodes if the conditional expression is true;
|
42
54
|
# otherwise, tries the \{#else} nodes.
|
43
55
|
#
|
@@ -3,38 +3,72 @@ module Sass
|
|
3
3
|
# A static node that wraps the {Sass::Tree} for an `@import`ed file.
|
4
4
|
# It doesn't have a functional purpose other than to add the `@import`ed file
|
5
5
|
# to the backtrace if an error occurs.
|
6
|
-
class ImportNode <
|
6
|
+
class ImportNode < RootNode
|
7
|
+
# The name of the imported file as it appears in the Sass document.
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :imported_filename
|
11
|
+
|
7
12
|
# @param imported_filename [String] The name of the imported file
|
8
13
|
def initialize(imported_filename)
|
9
14
|
@imported_filename = imported_filename
|
10
|
-
super()
|
15
|
+
super(nil)
|
11
16
|
end
|
12
17
|
|
13
|
-
|
18
|
+
def invisible?; to_s.empty?; end
|
19
|
+
|
20
|
+
# Returns the resolved name of the imported file,
|
21
|
+
# as returned by \{Sass::Files#find\_file\_to\_import}.
|
14
22
|
#
|
15
|
-
# @
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
# @return [String] The filename of the imported file.
|
24
|
+
# This is an absolute path if the file is a `".sass"` or `".scss"` file.
|
25
|
+
# @raise [Sass::SyntaxError] if `filename` ends in `".sass"` or `".scss"`
|
26
|
+
# and no corresponding Sass file could be found.
|
27
|
+
def full_filename
|
28
|
+
@full_filename ||= import
|
21
29
|
end
|
22
30
|
|
23
|
-
def
|
31
|
+
def to_sass(tabs = 0, opts = {})
|
32
|
+
"#{' ' * tabs}@import #{@imported_filename}\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_scss(tabs = 0, opts = {})
|
36
|
+
"#{' ' * tabs}@import \"#{@imported_filename}\";\n"
|
37
|
+
end
|
24
38
|
|
25
39
|
protected
|
26
40
|
|
27
|
-
#
|
28
|
-
|
41
|
+
# @see Node#_cssize
|
42
|
+
def _cssize(*args)
|
43
|
+
super.children
|
44
|
+
rescue Sass::SyntaxError => e
|
45
|
+
e.modify_backtrace(:filename => children.first.filename)
|
46
|
+
e.add_backtrace(:filename => @filename, :line => @line)
|
47
|
+
raise e
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a static DirectiveNode if this is importing a CSS file,
|
51
|
+
# or parses and includes the imported Sass file.
|
52
|
+
#
|
53
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
54
|
+
# variable and mixin values
|
55
|
+
def _perform(environment)
|
56
|
+
return DirectiveNode.new("@import url(#{full_filename})") if full_filename =~ /\.css$/
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
# Parses the imported file and runs the dynamic Sass for it.
|
29
61
|
#
|
30
62
|
# @param environment [Sass::Environment] The lexical environment containing
|
31
63
|
# variable and mixin values
|
32
64
|
def perform!(environment)
|
33
|
-
|
34
|
-
|
65
|
+
root = Sass::Files.tree_for(full_filename, @options)
|
66
|
+
@template = root.template
|
67
|
+
self.children = root.children
|
35
68
|
self.children = perform_children(environment)
|
36
69
|
rescue Sass::SyntaxError => e
|
37
|
-
e.
|
70
|
+
e.modify_backtrace(:filename => full_filename)
|
71
|
+
e.add_backtrace(:filename => @filename, :line => @line)
|
38
72
|
raise e
|
39
73
|
end
|
40
74
|
|
@@ -47,18 +81,9 @@ module Sass
|
|
47
81
|
end
|
48
82
|
|
49
83
|
def import
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
raise SyntaxError.new(e.message, self.line)
|
54
|
-
end
|
55
|
-
|
56
|
-
if full_filename =~ /\.css$/
|
57
|
-
@to_s = "@import url(#{full_filename});"
|
58
|
-
return false
|
59
|
-
end
|
60
|
-
|
61
|
-
return full_filename
|
84
|
+
Sass::Files.find_file_to_import(@imported_filename, import_paths)
|
85
|
+
rescue Exception => e
|
86
|
+
raise SyntaxError.new(e.message, :line => self.line, :filename => @filename)
|
62
87
|
end
|
63
88
|
end
|
64
89
|
end
|