haml-edge 2.3.100 → 2.3.148
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.
- data/.yardopts +3 -0
- data/EDGE_GEM_VERSION +1 -1
- data/Rakefile +14 -2
- data/VERSION +1 -1
- data/extra/haml-mode.el +97 -11
- data/extra/sass-mode.el +2 -2
- data/lib/haml/engine.rb +2 -2
- data/lib/haml/exec.rb +121 -25
- data/lib/haml/filters.rb +1 -1
- data/lib/haml/helpers/action_view_mods.rb +2 -1
- data/lib/haml/helpers/xss_mods.rb +43 -13
- data/lib/haml/helpers.rb +38 -17
- data/lib/haml/html.rb +13 -4
- data/lib/haml/precompiler.rb +24 -3
- data/lib/haml/template/plugin.rb +7 -3
- data/lib/haml/template.rb +3 -3
- data/lib/haml/util.rb +40 -0
- data/lib/sass/callbacks.rb +50 -0
- data/lib/sass/css.rb +1 -1
- data/lib/sass/engine.rb +45 -5
- data/lib/sass/error.rb +6 -3
- data/lib/sass/files.rb +8 -1
- data/lib/sass/plugin/rails.rb +2 -2
- data/lib/sass/plugin.rb +260 -28
- data/lib/sass/script/color.rb +216 -30
- data/lib/sass/script/functions.rb +356 -74
- data/lib/sass/script/lexer.rb +7 -4
- data/lib/sass/script/number.rb +2 -0
- data/lib/sass/script/parser.rb +1 -1
- data/lib/sass/script.rb +3 -0
- data/lib/sass/tree/node.rb +1 -1
- data/lib/sass/tree/root_node.rb +6 -0
- data/lib/sass/tree/rule_node.rb +1 -0
- data/lib/sass.rb +4 -0
- data/test/haml/engine_test.rb +25 -0
- data/test/haml/helper_test.rb +81 -1
- data/test/haml/html2haml_test.rb +13 -0
- data/test/haml/spec/README.md +97 -0
- data/test/haml/spec/lua_haml_spec.lua +30 -0
- data/test/haml/spec/ruby_haml_test.rb +19 -0
- data/test/haml/spec/tests.json +534 -0
- data/test/haml/spec_test.rb +0 -0
- data/test/haml/template_test.rb +18 -4
- data/test/haml/util_test.rb +0 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/css2sass_test.rb +1 -0
- data/test/sass/engine_test.rb +70 -14
- data/test/sass/functions_test.rb +223 -3
- data/test/sass/plugin_test.rb +193 -25
- data/test/sass/results/options.css +1 -0
- data/test/sass/script_test.rb +5 -5
- data/test/sass/templates/options.sass +2 -0
- data/test/test_helper.rb +12 -5
- metadata +19 -9
data/lib/haml/html.rb
CHANGED
@@ -85,6 +85,7 @@ end
|
|
85
85
|
|
86
86
|
# Haml monkeypatches various Hpricot classes
|
87
87
|
# to add methods for conversion to Haml.
|
88
|
+
# @private
|
88
89
|
module Hpricot
|
89
90
|
# @see Hpricot
|
90
91
|
module Node
|
@@ -145,9 +146,11 @@ module Haml
|
|
145
146
|
end
|
146
147
|
alias_method :to_haml, :render
|
147
148
|
|
149
|
+
# @private
|
148
150
|
TEXT_REGEXP = /^(\s*).*$/
|
149
151
|
|
150
152
|
# @see Hpricot
|
153
|
+
# @private
|
151
154
|
class ::Hpricot::Doc
|
152
155
|
# @see Haml::HTML::Node#to_haml
|
153
156
|
def to_haml(tabs, options)
|
@@ -156,6 +159,7 @@ module Haml
|
|
156
159
|
end
|
157
160
|
|
158
161
|
# @see Hpricot
|
162
|
+
# @private
|
159
163
|
class ::Hpricot::XMLDecl
|
160
164
|
# @see Haml::HTML::Node#to_haml
|
161
165
|
def to_haml(tabs, options)
|
@@ -164,6 +168,7 @@ module Haml
|
|
164
168
|
end
|
165
169
|
|
166
170
|
# @see Hpricot
|
171
|
+
# @private
|
167
172
|
class ::Hpricot::CData
|
168
173
|
# @see Haml::HTML::Node#to_haml
|
169
174
|
def to_haml(tabs, options)
|
@@ -174,16 +179,18 @@ module Haml
|
|
174
179
|
end
|
175
180
|
|
176
181
|
# @see Hpricot
|
182
|
+
# @private
|
177
183
|
class ::Hpricot::DocType
|
178
184
|
# @see Haml::HTML::Node#to_haml
|
179
185
|
def to_haml(tabs, options)
|
180
|
-
attrs = public_id.
|
186
|
+
attrs = public_id.nil? ? ["", "", ""] :
|
187
|
+
public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0]
|
181
188
|
raise Haml::SyntaxError.new("Invalid doctype") if attrs == nil
|
182
189
|
|
183
190
|
type, version, strictness = attrs.map { |a| a.downcase }
|
184
191
|
if type == "html"
|
185
|
-
version = "
|
186
|
-
strictness = "
|
192
|
+
version = ""
|
193
|
+
strictness = "strict" if strictness == ""
|
187
194
|
end
|
188
195
|
|
189
196
|
if version == "1.0" || version.empty?
|
@@ -194,7 +201,7 @@ module Haml
|
|
194
201
|
strictness = nil
|
195
202
|
end
|
196
203
|
|
197
|
-
version = " #{version}" if version
|
204
|
+
version = " #{version.capitalize}" if version
|
198
205
|
strictness = " #{strictness.capitalize}" if strictness
|
199
206
|
|
200
207
|
"#{tabulate(tabs)}!!!#{version}#{strictness}\n"
|
@@ -202,6 +209,7 @@ module Haml
|
|
202
209
|
end
|
203
210
|
|
204
211
|
# @see Hpricot
|
212
|
+
# @private
|
205
213
|
class ::Hpricot::Comment
|
206
214
|
# @see Haml::HTML::Node#to_haml
|
207
215
|
def to_haml(tabs, options)
|
@@ -220,6 +228,7 @@ module Haml
|
|
220
228
|
end
|
221
229
|
|
222
230
|
# @see Hpricot
|
231
|
+
# @private
|
223
232
|
class ::Hpricot::Elem
|
224
233
|
# @see Haml::HTML::Node#to_haml
|
225
234
|
def to_haml(tabs, options)
|
data/lib/haml/precompiler.rb
CHANGED
@@ -8,46 +8,60 @@ module Haml
|
|
8
8
|
include Haml::Util
|
9
9
|
|
10
10
|
# Designates an XHTML/XML element.
|
11
|
+
# @private
|
11
12
|
ELEMENT = ?%
|
12
13
|
|
13
14
|
# Designates a `<div>` element with the given class.
|
15
|
+
# @private
|
14
16
|
DIV_CLASS = ?.
|
15
17
|
|
16
18
|
# Designates a `<div>` element with the given id.
|
19
|
+
# @private
|
17
20
|
DIV_ID = ?#
|
18
21
|
|
19
22
|
# Designates an XHTML/XML comment.
|
23
|
+
# @private
|
20
24
|
COMMENT = ?/
|
21
25
|
|
22
26
|
# Designates an XHTML doctype or script that is never HTML-escaped.
|
27
|
+
# @private
|
23
28
|
DOCTYPE = ?!
|
24
29
|
|
25
30
|
# Designates script, the result of which is output.
|
31
|
+
# @private
|
26
32
|
SCRIPT = ?=
|
27
33
|
|
28
34
|
# Designates script that is always HTML-escaped.
|
35
|
+
# @private
|
29
36
|
SANITIZE = ?&
|
30
37
|
|
31
38
|
# Designates script, the result of which is flattened and output.
|
39
|
+
# @private
|
32
40
|
FLAT_SCRIPT = ?~
|
33
41
|
|
34
42
|
# Designates script which is run but not output.
|
43
|
+
# @private
|
35
44
|
SILENT_SCRIPT = ?-
|
36
45
|
|
37
46
|
# When following SILENT_SCRIPT, designates a comment that is not output.
|
47
|
+
# @private
|
38
48
|
SILENT_COMMENT = ?#
|
39
49
|
|
40
50
|
# Designates a non-parsed line.
|
51
|
+
# @private
|
41
52
|
ESCAPE = ?\\
|
42
53
|
|
43
54
|
# Designates a block of filtered text.
|
55
|
+
# @private
|
44
56
|
FILTER = ?:
|
45
57
|
|
46
58
|
# Designates a non-parsed line. Not actually a character.
|
59
|
+
# @private
|
47
60
|
PLAIN_TEXT = -1
|
48
61
|
|
49
62
|
# Keeps track of the ASCII values of the characters that begin a
|
50
63
|
# specially-interpreted line.
|
64
|
+
# @private
|
51
65
|
SPECIAL_CHARACTERS = [
|
52
66
|
ELEMENT,
|
53
67
|
DIV_CLASS,
|
@@ -64,6 +78,7 @@ module Haml
|
|
64
78
|
|
65
79
|
# The value of the character that designates that a line is part
|
66
80
|
# of a multiline string.
|
81
|
+
# @private
|
67
82
|
MULTILINE_CHAR_VALUE = ?|
|
68
83
|
|
69
84
|
# Regex to match keywords that appear in the middle of a Ruby block
|
@@ -79,12 +94,15 @@ module Haml
|
|
79
94
|
#
|
80
95
|
# The block is ended after `%p no!`, because `else`
|
81
96
|
# is a member of this array.
|
97
|
+
# @private
|
82
98
|
MID_BLOCK_KEYWORD_REGEX = /^-\s*(#{%w[else elsif rescue ensure when end].join('|')})\b/
|
83
99
|
|
84
100
|
# The Regex that matches a Doctype command.
|
101
|
+
# @private
|
85
102
|
DOCTYPE_REGEX = /(\d(?:\.\d)?)?[\s]*([a-z]*)/i
|
86
103
|
|
87
104
|
# The Regex that matches a literal string or symbol value
|
105
|
+
# @private
|
88
106
|
LITERAL_VALUE_REGEX = /:(\w*)|(["'])((?![\\#]|\2).|\\.)*\2/
|
89
107
|
|
90
108
|
private
|
@@ -124,6 +142,7 @@ END
|
|
124
142
|
end.join(';') + ';'
|
125
143
|
end
|
126
144
|
|
145
|
+
# @private
|
127
146
|
class Line < Struct.new(:text, :unstripped, :full, :index, :precompiler, :eod)
|
128
147
|
alias_method :eod?, :eod
|
129
148
|
|
@@ -480,10 +499,12 @@ END
|
|
480
499
|
@template_tabs -= 1
|
481
500
|
end
|
482
501
|
|
502
|
+
# This is a class method so it can be accessed from {Haml::Helpers}.
|
503
|
+
#
|
483
504
|
# Iterates through the classes and ids supplied through `.`
|
484
505
|
# and `#` syntax, and returns a hash with them as attributes,
|
485
506
|
# that can then be merged with another attributes hash.
|
486
|
-
def parse_class_and_id(list)
|
507
|
+
def self.parse_class_and_id(list)
|
487
508
|
attributes = {}
|
488
509
|
list.scan(/([#.])([-_a-zA-Z0-9]+)/) do |type, property|
|
489
510
|
case type
|
@@ -663,7 +684,7 @@ END
|
|
663
684
|
return name, [:dynamic, var]
|
664
685
|
end
|
665
686
|
|
666
|
-
re = /((?:\\.|\#
|
687
|
+
re = /((?:\\.|\#(?!\{)|[^#{quote}\\#])*)(#{quote}|#\{)/
|
667
688
|
content = []
|
668
689
|
loop do
|
669
690
|
return false unless scanner.scan(re)
|
@@ -733,7 +754,7 @@ END
|
|
733
754
|
|
734
755
|
object_ref = "nil" if object_ref.nil? || @options[:suppress_eval]
|
735
756
|
|
736
|
-
attributes = parse_class_and_id(attributes)
|
757
|
+
attributes = Precompiler.parse_class_and_id(attributes)
|
737
758
|
attributes_hashes.map! do |syntax, attributes_hash|
|
738
759
|
if syntax == :old
|
739
760
|
static_attributes = parse_static_hash(attributes_hash)
|
data/lib/haml/template/plugin.rb
CHANGED
@@ -2,8 +2,11 @@
|
|
2
2
|
# using the > 2.0.1 template handler API.
|
3
3
|
|
4
4
|
module Haml
|
5
|
-
class Plugin <
|
6
|
-
|
5
|
+
class Plugin < Haml::Util.av_template_class(:Handler)
|
6
|
+
if defined?(ActionView::TemplateHandlers::Compilable) ||
|
7
|
+
defined?(ActionView::Template::Handlers::Compilable)
|
8
|
+
include Haml::Util.av_template_class(:Handlers)::Compilable
|
9
|
+
end
|
7
10
|
|
8
11
|
def compile(template)
|
9
12
|
options = Haml::Template.options.dup
|
@@ -38,7 +41,8 @@ end.register_template_handler(:haml, Haml::Plugin)
|
|
38
41
|
# In Rails 2.0.2, ActionView::TemplateError took arguments
|
39
42
|
# that we can't fill in from the Haml::Plugin context.
|
40
43
|
# Thus, we've got to monkeypatch ActionView::Base to catch the error.
|
41
|
-
if ActionView::TemplateError
|
44
|
+
if defined?(ActionView::TemplateError) &&
|
45
|
+
ActionView::TemplateError.instance_method(:initialize).arity == 5
|
42
46
|
class ActionView::Base
|
43
47
|
def compile_template(handler, template, file_name, local_assigns)
|
44
48
|
render_symbol = assign_method_name(handler, template, file_name)
|
data/lib/haml/template.rb
CHANGED
@@ -28,7 +28,7 @@ module Haml
|
|
28
28
|
|
29
29
|
Haml::Precompiler.module_eval do
|
30
30
|
def precompiled_method_return_value_with_haml_xss
|
31
|
-
"(#{precompiled_method_return_value_without_haml_xss})
|
31
|
+
"::Haml::Util.html_safe(#{precompiled_method_return_value_without_haml_xss})"
|
32
32
|
end
|
33
33
|
alias_method :precompiled_method_return_value_without_haml_xss, :precompiled_method_return_value
|
34
34
|
alias_method :precompiled_method_return_value, :precompiled_method_return_value_with_haml_xss
|
@@ -39,14 +39,14 @@ module Haml
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
if
|
42
|
+
if Haml::Util.rails_env == "production"
|
43
43
|
Haml::Template.options[:ugly] = true
|
44
44
|
end
|
45
45
|
|
46
46
|
# Decide how we want to load Haml into Rails.
|
47
47
|
# Patching was necessary for versions <= 2.0.1,
|
48
48
|
# but we can make it a normal handler for higher versions.
|
49
|
-
if defined?(ActionView::TemplateHandler)
|
49
|
+
if defined?(ActionView::TemplateHandler) || defined?(ActionView::Template::Handler)
|
50
50
|
require 'haml/template/plugin'
|
51
51
|
else
|
52
52
|
require 'haml/template/patch'
|
data/lib/haml/util.rb
CHANGED
@@ -168,6 +168,30 @@ module Haml
|
|
168
168
|
return nil
|
169
169
|
end
|
170
170
|
|
171
|
+
# Returns the environment of the Rails application,
|
172
|
+
# if this is running in a Rails context.
|
173
|
+
# Returns `nil` if no such environment is defined.
|
174
|
+
#
|
175
|
+
# @return [String, nil]
|
176
|
+
def rails_env
|
177
|
+
return Rails.env.to_s if defined?(Rails.root)
|
178
|
+
return RAILS_ENV.to_s if defined?(RAILS_ENV)
|
179
|
+
return nil
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns an ActionView::Template* class.
|
183
|
+
# In pre-3.0 versions of Rails, most of these classes
|
184
|
+
# were of the form `ActionView::TemplateFoo`,
|
185
|
+
# while afterwards they were of the form `ActionView;:Template::Foo`.
|
186
|
+
#
|
187
|
+
# @param name [#to_s] The name of the class to get.
|
188
|
+
# For example, `:Error` will return `ActionView::TemplateError`
|
189
|
+
# or `ActionView::Template::Error`.
|
190
|
+
def av_template_class(name)
|
191
|
+
return ActionView.const_get("Template#{name}") if ActionView.const_defined?("Template#{name}")
|
192
|
+
return ActionView::Template.const_get(name.to_s)
|
193
|
+
end
|
194
|
+
|
171
195
|
## Rails XSS Safety
|
172
196
|
|
173
197
|
# Whether or not ActionView's XSS protection is available and enabled,
|
@@ -179,6 +203,17 @@ module Haml
|
|
179
203
|
false
|
180
204
|
end
|
181
205
|
|
206
|
+
# Returns the given text, marked as being HTML-safe.
|
207
|
+
# With older versions of the Rails XSS-safety mechanism,
|
208
|
+
# this destructively modifies the HTML-safety of `text`.
|
209
|
+
#
|
210
|
+
# @param text [String]
|
211
|
+
# @return [String] `text`, marked as HTML-safe
|
212
|
+
def html_safe(text)
|
213
|
+
return text.html_safe if defined?(ActiveSupport::SafeBuffer)
|
214
|
+
text.html_safe!
|
215
|
+
end
|
216
|
+
|
182
217
|
# Assert that a given object (usually a String) is HTML safe
|
183
218
|
# according to Rails' XSS handling, if it's loaded.
|
184
219
|
#
|
@@ -188,6 +223,11 @@ module Haml
|
|
188
223
|
raise Haml::Error.new("Expected #{text.inspect} to be HTML-safe.")
|
189
224
|
end
|
190
225
|
|
226
|
+
def rails_safe_buffer_class
|
227
|
+
return ActionView::SafeBuffer if defined?(ActionView::SafeBuffer)
|
228
|
+
ActiveSupport::SafeBuffer
|
229
|
+
end
|
230
|
+
|
191
231
|
## Cross-Ruby-Version Compatibility
|
192
232
|
|
193
233
|
# Whether or not this is running under Ruby 1.8 or lower.
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# A lightweight infrastructure for defining and running callbacks.
|
2
|
+
# Callbacks are defined using \{#define\_callback\} at the class level,
|
3
|
+
# and called using `run_#{name}` at the instance level.
|
4
|
+
#
|
5
|
+
# Clients can add callbacks by calling the generated `on_#{name}` method,
|
6
|
+
# and passing in a block that's run when the callback is activated.
|
7
|
+
#
|
8
|
+
# @example Define a callback
|
9
|
+
# class Munger
|
10
|
+
# extend Sass::Callbacks
|
11
|
+
# define_callback :string_munged
|
12
|
+
#
|
13
|
+
# def munge(str)
|
14
|
+
# res = str.gsub(/[a-z]/, '\1\1')
|
15
|
+
# run_string_munged str, res
|
16
|
+
# res
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# @example Use a callback
|
21
|
+
# m = Munger.new
|
22
|
+
# m.on_string_munged {|str, res| puts "#{str} was munged into #{res}!"}
|
23
|
+
# m.munge "bar" #=> bar was munged into bbaarr!
|
24
|
+
module Sass::Callbacks
|
25
|
+
protected
|
26
|
+
|
27
|
+
# Define a callback with the given name.
|
28
|
+
# This will define an `on_#{name}` method
|
29
|
+
# that registers a block,
|
30
|
+
# and a `run_#{name}` method that runs that block
|
31
|
+
# (optionall with some arguments).
|
32
|
+
#
|
33
|
+
# @param name [Symbol] The name of the callback
|
34
|
+
# @return [void]
|
35
|
+
def define_callback(name)
|
36
|
+
class_eval <<RUBY
|
37
|
+
def on_#{name}(&block)
|
38
|
+
@_sass_callbacks ||= {}
|
39
|
+
(@_sass_callbacks[#{name.inspect}] ||= []) << block
|
40
|
+
end
|
41
|
+
|
42
|
+
def run_#{name}(*args)
|
43
|
+
return unless @_sass_callbacks
|
44
|
+
return unless @_sass_callbacks[#{name.inspect}]
|
45
|
+
@_sass_callbacks[#{name.inspect}].each {|c| c[*args]}
|
46
|
+
end
|
47
|
+
private :run_#{name}
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
end
|
data/lib/sass/css.rb
CHANGED
data/lib/sass/engine.rb
CHANGED
@@ -77,45 +77,57 @@ module Sass
|
|
77
77
|
end
|
78
78
|
|
79
79
|
# The character that begins a CSS property.
|
80
|
+
# @private
|
80
81
|
PROPERTY_CHAR = ?:
|
81
82
|
|
82
83
|
# The character that designates that
|
83
84
|
# a property should be assigned to a SassScript expression.
|
85
|
+
# @private
|
84
86
|
SCRIPT_CHAR = ?=
|
85
87
|
|
86
88
|
# The character that designates the beginning of a comment,
|
87
89
|
# either Sass or CSS.
|
90
|
+
# @private
|
88
91
|
COMMENT_CHAR = ?/
|
89
92
|
|
90
93
|
# The character that follows the general COMMENT_CHAR and designates a Sass comment,
|
91
94
|
# which is not output as a CSS comment.
|
95
|
+
# @private
|
92
96
|
SASS_COMMENT_CHAR = ?/
|
93
97
|
|
94
98
|
# The character that follows the general COMMENT_CHAR and designates a CSS comment,
|
95
99
|
# which is embedded in the CSS document.
|
100
|
+
# @private
|
96
101
|
CSS_COMMENT_CHAR = ?*
|
97
102
|
|
98
103
|
# The character used to denote a compiler directive.
|
104
|
+
# @private
|
99
105
|
DIRECTIVE_CHAR = ?@
|
100
106
|
|
101
107
|
# Designates a non-parsed rule.
|
108
|
+
# @private
|
102
109
|
ESCAPE_CHAR = ?\\
|
103
110
|
|
104
111
|
# Designates block as mixin definition rather than CSS rules to output
|
112
|
+
# @private
|
105
113
|
MIXIN_DEFINITION_CHAR = ?=
|
106
114
|
|
107
115
|
# Includes named mixin declared using MIXIN_DEFINITION_CHAR
|
116
|
+
# @private
|
108
117
|
MIXIN_INCLUDE_CHAR = ?+
|
109
118
|
|
110
119
|
# The regex that matches properties of the form `name: prop`.
|
120
|
+
# @private
|
111
121
|
PROPERTY_NEW_MATCHER = /^[^\s:"\[]+\s*[=:](\s|$)/
|
112
122
|
|
113
123
|
# The regex that matches and extracts data from
|
114
124
|
# properties of the form `name: prop`.
|
125
|
+
# @private
|
115
126
|
PROPERTY_NEW = /^([^\s=:"]+)(\s*=|:)(?:\s+|$)(.*)/
|
116
127
|
|
117
128
|
# The regex that matches and extracts data from
|
118
129
|
# properties of the form `:name prop`.
|
130
|
+
# @private
|
119
131
|
PROPERTY_OLD = /^:([^\s=:"]+)\s*(=?)(?:\s+|$)(.*)/
|
120
132
|
|
121
133
|
# The default options for Sass::Engine.
|
@@ -130,9 +142,13 @@ module Sass
|
|
130
142
|
# @param options [{Symbol => Object}] An options hash;
|
131
143
|
# see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
|
132
144
|
def initialize(template, options={})
|
133
|
-
@options = DEFAULT_OPTIONS.merge(options)
|
145
|
+
@options = DEFAULT_OPTIONS.merge(options.reject {|k, v| v.nil?})
|
134
146
|
@template = template
|
135
147
|
|
148
|
+
# Support both, because the docs said one and the other actually worked
|
149
|
+
# for quite a long time.
|
150
|
+
@options[:line_comments] ||= @options[:line_numbers]
|
151
|
+
|
136
152
|
# Backwards compatibility
|
137
153
|
@options[:property_syntax] ||= @options[:attribute_syntax]
|
138
154
|
case @options[:property_syntax]
|
@@ -172,6 +188,7 @@ module Sass
|
|
172
188
|
|
173
189
|
def tabulate(string)
|
174
190
|
tab_str = nil
|
191
|
+
comment_tab_str = nil
|
175
192
|
first = true
|
176
193
|
lines = []
|
177
194
|
string.gsub(/\r|\n|\r\n|\r\n/, "\n").scan(/^.*?$/).each_with_index do |line, index|
|
@@ -183,6 +200,12 @@ module Sass
|
|
183
200
|
|
184
201
|
line_tab_str = line[/^\s*/]
|
185
202
|
unless line_tab_str.empty?
|
203
|
+
if tab_str.nil?
|
204
|
+
comment_tab_str ||= line_tab_str
|
205
|
+
next if try_comment(line, lines.last, "", comment_tab_str, index)
|
206
|
+
comment_tab_str = nil
|
207
|
+
end
|
208
|
+
|
186
209
|
tab_str ||= line_tab_str
|
187
210
|
|
188
211
|
raise SyntaxError.new("Indenting at the beginning of the document is illegal.",
|
@@ -197,9 +220,11 @@ module Sass
|
|
197
220
|
next
|
198
221
|
end
|
199
222
|
|
200
|
-
|
201
|
-
|
223
|
+
comment_tab_str ||= line_tab_str
|
224
|
+
if try_comment(line, lines.last, tab_str * (lines.last.tabs + 1), comment_tab_str, index)
|
202
225
|
next
|
226
|
+
else
|
227
|
+
comment_tab_str = nil
|
203
228
|
end
|
204
229
|
|
205
230
|
line_tabs = line_tab_str.scan(tab_str).size
|
@@ -216,6 +241,21 @@ END
|
|
216
241
|
lines
|
217
242
|
end
|
218
243
|
|
244
|
+
def try_comment(line, last, tab_str, comment_tab_str, index)
|
245
|
+
return unless last && last.comment?
|
246
|
+
return unless line =~ /^#{tab_str}/
|
247
|
+
unless line =~ /^(?:#{comment_tab_str})(.*)$/
|
248
|
+
raise SyntaxError.new(<<MSG.strip.gsub("\n", " "), :line => index)
|
249
|
+
Inconsistent indentation:
|
250
|
+
previous line was indented by #{Haml::Shared.human_indentation comment_tab_str},
|
251
|
+
but this line was indented by #{Haml::Shared.human_indentation line[/^\s*/]}.
|
252
|
+
MSG
|
253
|
+
end
|
254
|
+
|
255
|
+
last.text << "\n" << $1
|
256
|
+
true
|
257
|
+
end
|
258
|
+
|
219
259
|
def tree(arr, i = 0)
|
220
260
|
return [], i if arr[i].nil?
|
221
261
|
|
@@ -313,11 +353,11 @@ END
|
|
313
353
|
def check_for_no_children(node)
|
314
354
|
return unless node.is_a?(Tree::RuleNode) && node.children.empty?
|
315
355
|
warning = (node.rules.size == 1) ? <<SHORT : <<LONG
|
316
|
-
WARNING on line #{node.line}:
|
356
|
+
WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
|
317
357
|
Selector #{node.rules.first.inspect} doesn't have any properties and will not be rendered.
|
318
358
|
SHORT
|
319
359
|
|
320
|
-
WARNING on line #{node.line}:
|
360
|
+
WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
|
321
361
|
Selector
|
322
362
|
#{node.rules.join("\n ")}
|
323
363
|
doesn't have any properties and will not be rendered.
|
data/lib/sass/error.rb
CHANGED
@@ -149,10 +149,13 @@ module Sass
|
|
149
149
|
# Returns an error report for an exception in CSS format.
|
150
150
|
#
|
151
151
|
# @param e [Exception]
|
152
|
-
# @param
|
153
|
-
#
|
152
|
+
# @param options [{Symbol => Object}] The options passed to {Sass::Engine#initialize}
|
153
|
+
# @return [String] The error report
|
154
|
+
# @raise [Exception] `e`, if the
|
155
|
+
# {file:SASS_REFERENCE.md#full_exception-option `:full_exception`} option
|
156
|
+
# is set to false.
|
154
157
|
def exception_to_css(e, options)
|
155
|
-
|
158
|
+
raise e unless options[:full_exception]
|
156
159
|
|
157
160
|
header = header_string(e, options)
|
158
161
|
|
data/lib/sass/files.rb
CHANGED
@@ -71,7 +71,14 @@ module Sass
|
|
71
71
|
new_filename = find_full_path("#{filename}.sass", load_paths)
|
72
72
|
|
73
73
|
return new_filename if new_filename
|
74
|
-
|
74
|
+
unless was_sass
|
75
|
+
warn <<END
|
76
|
+
WARNING: #{filename}.sass not found. Using #{filename}.css instead.
|
77
|
+
This behavior is deprecated and will be removed in a future version.
|
78
|
+
If you really need #{filename}.css, import it explicitly.
|
79
|
+
END
|
80
|
+
return filename + '.css'
|
81
|
+
end
|
75
82
|
raise SyntaxError.new("File to import not found or unreadable: #{original_filename}.")
|
76
83
|
end
|
77
84
|
|
data/lib/sass/plugin/rails.rb
CHANGED
@@ -4,8 +4,8 @@ unless defined?(Sass::RAILS_LOADED)
|
|
4
4
|
Sass::Plugin.options.merge!(:template_location => Haml::Util.rails_root + '/public/stylesheets/sass',
|
5
5
|
:css_location => Haml::Util.rails_root + '/public/stylesheets',
|
6
6
|
:cache_location => Haml::Util.rails_root + '/tmp/sass-cache',
|
7
|
-
:always_check =>
|
8
|
-
:full_exception =>
|
7
|
+
:always_check => Haml::Util.rails_env != "production",
|
8
|
+
:full_exception => Haml::Util.rails_env != "production")
|
9
9
|
|
10
10
|
if defined?(Rails.configuration.middleware)
|
11
11
|
# Rails >= 3.0
|