radiant 0.6.7 → 0.6.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of radiant might be problematic. Click here for more details.
- data/CHANGELOG +35 -3
- data/CONTRIBUTORS +11 -1
- data/README +5 -3
- data/app/controllers/admin/welcome_controller.rb +7 -0
- data/app/migrate/020_add_session_info_to_users.rb +11 -0
- data/app/models/page.rb +22 -9
- data/app/models/standard_tags.rb +133 -10
- data/app/models/user.rb +9 -1
- data/app/views/admin/page/edit.html.haml +5 -4
- data/app/views/admin/welcome/login.html.haml +42 -24
- data/app/views/layouts/application.html.haml +1 -1
- data/config/environment.rb +4 -2
- data/db/migrate/020_add_session_info_to_users.rb +11 -0
- data/db/migrate/021_remove_session_expire_from_users.rb +9 -0
- data/db/schema.rb +3 -2
- data/lib/generators/instance/instance_generator.rb +2 -1
- data/lib/generators/instance/templates/instance_environment.rb +5 -3
- data/lib/login_system.rb +13 -0
- data/lib/radiant.rb +1 -1
- data/lib/radiant/admin_ui.rb +21 -21
- data/lib/radiant/extension/script.rb +251 -0
- data/lib/radiant/extension_loader.rb +22 -20
- data/lib/radiant/initializer.rb +1 -1
- data/lib/radiant/setup.rb +2 -0
- data/lib/tasks/framework.rake +39 -29
- data/public/500.html +1 -1
- data/public/javascripts/admin/admin.js +11 -9
- data/script/extension +5 -0
- data/spec/controllers/admin/user_controller_spec.rb +1 -1
- data/spec/controllers/admin/welcome_controller_spec.rb +31 -5
- data/spec/controllers/site_controller_spec.rb +15 -2
- data/spec/lib/login_system_spec.rb +106 -60
- data/spec/lib/radiant/extension/script_spec.rb +349 -0
- data/spec/lib/radiant/extension_loader_spec.rb +3 -0
- data/spec/models/page_spec.rb +62 -2
- data/spec/models/standard_tags_spec.rb +150 -3
- data/spec/models/user_spec.rb +28 -0
- data/spec/scenarios/file_not_found_scenario.rb +5 -0
- data/spec/scenarios/pages_scenario.rb +6 -0
- data/spec/scenarios/snippets_scenario.rb +4 -0
- data/test/fixtures/users.yml +11 -6
- data/vendor/plugins/haml/FAQ +138 -0
- data/vendor/plugins/haml/REVISION +1 -0
- data/vendor/plugins/haml/Rakefile +54 -62
- data/vendor/plugins/haml/VERSION +1 -1
- data/vendor/plugins/haml/init.rb +6 -1
- data/vendor/plugins/haml/lib/haml.rb +72 -12
- data/vendor/plugins/haml/lib/haml/buffer.rb +47 -40
- data/vendor/plugins/haml/lib/haml/engine.rb +20 -30
- data/vendor/plugins/haml/lib/haml/error.rb +4 -5
- data/vendor/plugins/haml/lib/haml/exec.rb +4 -2
- data/vendor/plugins/haml/lib/haml/filters.rb +30 -15
- data/vendor/plugins/haml/lib/haml/helpers.rb +47 -28
- data/vendor/plugins/haml/lib/haml/helpers/action_view_mods.rb +74 -25
- data/vendor/plugins/haml/lib/haml/precompiler.rb +92 -51
- data/vendor/plugins/haml/lib/haml/template.rb +11 -3
- data/vendor/plugins/haml/lib/haml/template/patch.rb +1 -1
- data/vendor/plugins/haml/lib/sass.rb +26 -3
- data/vendor/plugins/haml/lib/sass/constant.rb +26 -57
- data/vendor/plugins/haml/lib/sass/constant/literal.rb +1 -0
- data/vendor/plugins/haml/lib/sass/constant/nil.rb +9 -0
- data/vendor/plugins/haml/lib/sass/css.rb +17 -2
- data/vendor/plugins/haml/lib/sass/engine.rb +11 -5
- data/vendor/plugins/haml/test/haml/engine_test.rb +57 -39
- data/vendor/plugins/haml/test/haml/helper_test.rb +20 -4
- data/vendor/plugins/haml/test/haml/html2haml_test.rb +1 -3
- data/vendor/plugins/haml/test/haml/results/content_for_layout.xhtml +1 -2
- data/vendor/plugins/haml/test/haml/results/eval_suppressed.xhtml +2 -4
- data/vendor/plugins/haml/test/haml/results/filters.xhtml +12 -8
- data/vendor/plugins/haml/test/haml/results/helpers.xhtml +2 -5
- data/vendor/plugins/haml/test/haml/results/just_stuff.xhtml +1 -3
- data/vendor/plugins/haml/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
- data/vendor/plugins/haml/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
- data/vendor/plugins/haml/test/haml/results/original_engine.xhtml +2 -4
- data/vendor/plugins/haml/test/haml/results/tag_parsing.xhtml +1 -6
- data/vendor/plugins/haml/test/haml/results/very_basic.xhtml +2 -4
- data/vendor/plugins/haml/test/haml/results/whitespace_handling.xhtml +13 -21
- data/vendor/plugins/haml/test/haml/template_test.rb +31 -48
- data/vendor/plugins/haml/test/haml/templates/filters.haml +13 -0
- data/vendor/plugins/haml/test/haml/templates/helpers.haml +1 -1
- data/vendor/plugins/haml/test/haml/templates/just_stuff.haml +0 -1
- data/vendor/plugins/haml/test/haml/templates/nuke_inner_whitespace.haml +32 -0
- data/vendor/plugins/haml/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/vendor/plugins/haml/test/haml/templates/partials.haml +1 -1
- data/vendor/plugins/haml/test/haml/templates/tag_parsing.haml +0 -3
- data/vendor/plugins/haml/test/haml/templates/whitespace_handling.haml +10 -10
- data/vendor/plugins/haml/test/sass/engine_test.rb +11 -5
- data/vendor/plugins/haml/test/sass/plugin_test.rb +2 -6
- data/vendor/plugins/haml/test/sass/results/constants.css +2 -0
- data/vendor/plugins/haml/test/sass/templates/constants.sass +3 -0
- data/vendor/plugins/haml/test/{haml/test_helper.rb → test_helper.rb} +4 -3
- metadata +21 -11
- data/vendor/plugins/haml/TODO +0 -9
- data/vendor/plugins/haml/extra/haml-mode.el +0 -328
- data/vendor/plugins/haml/extra/sass-mode.el +0 -88
- data/vendor/plugins/haml/test/profile.rb +0 -65
@@ -109,28 +109,15 @@ END
|
|
109
109
|
end.join(';') + ';'
|
110
110
|
end
|
111
111
|
|
112
|
-
Line = Struct.new(
|
112
|
+
Line = Struct.new(:text, :unstripped, :index, :spaces, :tabs)
|
113
113
|
|
114
114
|
def precompile
|
115
|
-
@precompiled = ''
|
116
|
-
@merged_text = ''
|
117
|
-
@tab_change = 0
|
118
|
-
|
119
115
|
old_line = Line.new
|
120
|
-
|
121
|
-
line = Line.new
|
116
|
+
@template.split(/\r\n|\r|\n/).each_with_index do |text, index|
|
117
|
+
@next_line = line = Line.new(text.strip, text.lstrip.chomp, index)
|
122
118
|
line.spaces, line.tabs = count_soft_tabs(text)
|
123
119
|
|
124
|
-
if line.text.empty?
|
125
|
-
process_indent(old_line) if flat? && !old_line.text.empty?
|
126
|
-
|
127
|
-
unless flat?
|
128
|
-
newline
|
129
|
-
next
|
130
|
-
end
|
131
|
-
|
132
|
-
push_flat(old_line)
|
133
|
-
old_line.text, old_line.unstripped, old_line.spaces = '', '', 0
|
120
|
+
if line.text.empty? && !flat?
|
134
121
|
newline
|
135
122
|
next
|
136
123
|
end
|
@@ -154,7 +141,7 @@ END
|
|
154
141
|
end
|
155
142
|
|
156
143
|
if old_line.spaces != old_line.tabs * 2
|
157
|
-
raise SyntaxError.new(<<END.strip,
|
144
|
+
raise SyntaxError.new(<<END.strip, old_line.index)
|
158
145
|
#{old_line.spaces} space#{old_line.spaces == 1 ? ' was' : 's were'} used for indentation. Haml must be indented using two spaces.
|
159
146
|
END
|
160
147
|
end
|
@@ -165,7 +152,7 @@ END
|
|
165
152
|
resolve_newlines
|
166
153
|
|
167
154
|
if !flat? && line.tabs - old_line.tabs > 1
|
168
|
-
raise SyntaxError.new(<<END.strip,
|
155
|
+
raise SyntaxError.new(<<END.strip, line.index)
|
169
156
|
#{line.spaces} spaces were used for indentation. Haml must be indented using two spaces.
|
170
157
|
END
|
171
158
|
end
|
@@ -199,12 +186,12 @@ END
|
|
199
186
|
when ELEMENT; render_tag(text)
|
200
187
|
when COMMENT; render_comment(text[1..-1].strip)
|
201
188
|
when SANITIZE
|
202
|
-
return push_script(unescape_interpolation(text[3..-1].strip), false,
|
203
|
-
return push_script(text[2..-1].strip, false,
|
189
|
+
return push_script(unescape_interpolation(text[3..-1].strip), false, false, false, true) if text[1..2] == "=="
|
190
|
+
return push_script(text[2..-1].strip, false, false, false, true) if text[1] == SCRIPT
|
204
191
|
push_plain text
|
205
192
|
when SCRIPT
|
206
193
|
return push_script(unescape_interpolation(text[2..-1].strip), false) if text[1] == SCRIPT
|
207
|
-
return push_script(text[1..-1], false,
|
194
|
+
return push_script(text[1..-1], false, false, false, true) if options[:escape_html]
|
208
195
|
push_script(text[1..-1], false)
|
209
196
|
when FLAT_SCRIPT; push_flat_script(text[1..-1])
|
210
197
|
when SILENT_SCRIPT
|
@@ -277,8 +264,9 @@ END
|
|
277
264
|
|
278
265
|
# Adds <tt>text</tt> to <tt>@buffer</tt> with appropriate tabulation
|
279
266
|
# without parsing it.
|
280
|
-
def push_merged_text(text, tab_change = 0,
|
281
|
-
@merged_text << (@options[:ugly] ? text : "#{' ' * @output_tabs}#{text}")
|
267
|
+
def push_merged_text(text, tab_change = 0, indent = true)
|
268
|
+
@merged_text << (!indent || @dont_indent_next_line || @options[:ugly] ? text : "#{' ' * @output_tabs}#{text}")
|
269
|
+
@dont_indent_next_line = false
|
282
270
|
@tab_change += tab_change
|
283
271
|
end
|
284
272
|
|
@@ -287,24 +275,29 @@ END
|
|
287
275
|
@merged_text << text
|
288
276
|
end
|
289
277
|
|
290
|
-
def push_text(text, tab_change = 0
|
291
|
-
push_merged_text("#{text}\n", tab_change
|
278
|
+
def push_text(text, tab_change = 0)
|
279
|
+
push_merged_text("#{text}\n", tab_change)
|
292
280
|
end
|
293
281
|
|
294
282
|
def flush_merged_text
|
295
283
|
return if @merged_text.empty?
|
296
284
|
|
297
285
|
@precompiled << "_hamlout.push_text(#{@merged_text.dump}"
|
286
|
+
@precompiled << ", #{@dont_tab_up_next_text.inspect}" if @dont_tab_up_next_text || @tab_change != 0
|
298
287
|
@precompiled << ", #{@tab_change}" if @tab_change != 0
|
299
288
|
@precompiled << ");"
|
300
289
|
@merged_text = ''
|
290
|
+
@dont_tab_up_next_text = false
|
301
291
|
@tab_change = 0
|
302
292
|
end
|
303
293
|
|
304
294
|
# Renders a block of text as plain text.
|
305
295
|
# Also checks for an illegally opened block.
|
306
296
|
def push_plain(text)
|
307
|
-
|
297
|
+
if @block_opened
|
298
|
+
raise SyntaxError.new("Illegal nesting: nesting within plain text is illegal.", @next_line.index)
|
299
|
+
end
|
300
|
+
|
308
301
|
push_text text
|
309
302
|
end
|
310
303
|
|
@@ -324,7 +317,11 @@ END
|
|
324
317
|
#
|
325
318
|
# If <tt>preserve_script</tt> is true, Haml::Helpers#find_and_flatten is run on
|
326
319
|
# the result before it is added to <tt>@buffer</tt>
|
327
|
-
def push_script(text, preserve_script,
|
320
|
+
def push_script(text, preserve_script, in_tag = false, preserve_tag = false,
|
321
|
+
escape_html = false, nuke_inner_whitespace = false)
|
322
|
+
# Prerender tabulation unless we're in a tag
|
323
|
+
push_merged_text '' unless in_tag
|
324
|
+
|
328
325
|
flush_merged_text
|
329
326
|
return if options[:suppress_eval]
|
330
327
|
|
@@ -332,7 +329,9 @@ END
|
|
332
329
|
|
333
330
|
push_silent "haml_temp = #{text}"
|
334
331
|
newline_now
|
335
|
-
|
332
|
+
args = [preserve_script, in_tag, preserve_tag,
|
333
|
+
escape_html, nuke_inner_whitespace].map { |a| a.inspect }.join(', ')
|
334
|
+
out = "haml_temp = _hamlout.push_script(haml_temp, #{args});"
|
336
335
|
if @block_opened
|
337
336
|
push_and_tabulate([:loud, out])
|
338
337
|
else
|
@@ -371,10 +370,14 @@ END
|
|
371
370
|
|
372
371
|
# Puts a line in <tt>@precompiled</tt> that will add the closing tag of
|
373
372
|
# the most recently opened tag.
|
374
|
-
def close_tag(
|
375
|
-
|
373
|
+
def close_tag(value)
|
374
|
+
tag, nuke_outer_whitespace, nuke_inner_whitespace = value
|
375
|
+
@output_tabs -= 1 unless nuke_inner_whitespace
|
376
376
|
@template_tabs -= 1
|
377
|
-
|
377
|
+
rstrip_buffer! if nuke_inner_whitespace
|
378
|
+
push_merged_text("</#{tag}>" + (nuke_outer_whitespace ? "" : "\n"),
|
379
|
+
nuke_inner_whitespace ? 0 : -1, !nuke_inner_whitespace)
|
380
|
+
@dont_indent_next_line = nuke_outer_whitespace
|
378
381
|
end
|
379
382
|
|
380
383
|
# Closes a Ruby block.
|
@@ -502,10 +505,14 @@ END
|
|
502
505
|
if rest
|
503
506
|
object_ref, rest = balance(rest, ?[, ?]) if rest[0] == ?[
|
504
507
|
attributes_hash, rest = parse_attributes(rest) if rest[0] == ?{ && attributes_hash.nil?
|
505
|
-
action, value = rest.scan(/([=\/\~&!]
|
508
|
+
nuke_whitespace, action, value = rest.scan(/(<>|><|[><])?([=\/\~&!])?(.*)?/)[0]
|
509
|
+
nuke_whitespace ||= ''
|
510
|
+
nuke_outer_whitespace = nuke_whitespace.include? '>'
|
511
|
+
nuke_inner_whitespace = nuke_whitespace.include? '<'
|
506
512
|
end
|
507
513
|
value = value.to_s.strip
|
508
|
-
[tag_name, attributes, attributes_hash, object_ref,
|
514
|
+
[tag_name, attributes, attributes_hash, object_ref, nuke_outer_whitespace,
|
515
|
+
nuke_inner_whitespace, action, value]
|
509
516
|
end
|
510
517
|
|
511
518
|
def parse_attributes(line)
|
@@ -518,11 +525,17 @@ END
|
|
518
525
|
# Parses a line that will render as an XHTML tag, and adds the code that will
|
519
526
|
# render that tag to <tt>@precompiled</tt>.
|
520
527
|
def render_tag(line)
|
521
|
-
tag_name, attributes, attributes_hash, object_ref,
|
528
|
+
tag_name, attributes, attributes_hash, object_ref, nuke_outer_whitespace,
|
529
|
+
nuke_inner_whitespace, action, value = parse_tag(line)
|
522
530
|
|
523
531
|
raise SyntaxError.new("Illegal element: classes and ids must have values.") if attributes =~ /[\.#](\.|#|\z)/
|
524
532
|
|
533
|
+
# Get rid of whitespace outside of the tag if we need to
|
534
|
+
rstrip_buffer! if nuke_outer_whitespace
|
535
|
+
|
525
536
|
preserve_tag = options[:preserve].include?(tag_name)
|
537
|
+
nuke_inner_whitespace ||= preserve_tag
|
538
|
+
preserve_tag &&= !options[:ugly]
|
526
539
|
|
527
540
|
case action
|
528
541
|
when '/'; self_closing = xhtml?
|
@@ -551,41 +564,58 @@ END
|
|
551
564
|
attributes = parse_class_and_id(attributes)
|
552
565
|
Buffer.merge_attrs(attributes, static_attributes) if static_attributes
|
553
566
|
|
554
|
-
raise SyntaxError.new("Illegal nesting: nesting within a self-closing tag is illegal.",
|
555
|
-
raise SyntaxError.new("Illegal nesting: content can't be both given on the same line as %#{tag_name} and nested within it.",
|
567
|
+
raise SyntaxError.new("Illegal nesting: nesting within a self-closing tag is illegal.", @next_line.index) if @block_opened && self_closing
|
568
|
+
raise SyntaxError.new("Illegal nesting: content can't be both given on the same line as %#{tag_name} and nested within it.", @next_line.index) if @block_opened && !value.empty?
|
556
569
|
raise SyntaxError.new("There's no Ruby code for #{action} to evaluate.") if parse && value.empty?
|
557
570
|
raise SyntaxError.new("Self-closing tags can't have content.") if self_closing && !value.empty?
|
558
571
|
|
559
572
|
self_closing ||= !!( !@block_opened && value.empty? && @options[:autoclose].include?(tag_name) )
|
560
573
|
|
574
|
+
dont_indent_next_line =
|
575
|
+
(nuke_outer_whitespace && !@block_opened) ||
|
576
|
+
(nuke_inner_whitespace && @block_opened)
|
577
|
+
|
578
|
+
# Check if we can render the tag directly to text and not process it in the buffer
|
561
579
|
if object_ref == "nil" && attributes_hash.nil? && !preserve_script
|
562
|
-
|
563
|
-
tag_closed = !value.empty? && !parse
|
580
|
+
tag_closed = !@block_opened && !self_closing && !parse
|
564
581
|
|
565
582
|
open_tag = prerender_tag(tag_name, self_closing, attributes)
|
566
|
-
|
567
|
-
|
583
|
+
if tag_closed
|
584
|
+
open_tag << "#{value}</#{tag_name}>"
|
585
|
+
open_tag << "\n" unless nuke_outer_whitespace
|
586
|
+
else
|
587
|
+
open_tag << "\n" unless parse || nuke_inner_whitespace || (self_closing && nuke_outer_whitespace)
|
588
|
+
end
|
589
|
+
|
590
|
+
push_merged_text(open_tag, tag_closed || self_closing || nuke_inner_whitespace ? 0 : 1,
|
591
|
+
!nuke_outer_whitespace)
|
568
592
|
|
569
|
-
|
593
|
+
@dont_indent_next_line = dont_indent_next_line
|
570
594
|
return if tag_closed
|
571
595
|
else
|
572
596
|
flush_merged_text
|
573
597
|
content = value.empty? || parse ? 'nil' : value.dump
|
574
598
|
attributes_hash = ', ' + attributes_hash if attributes_hash
|
575
|
-
|
599
|
+
args = [tag_name, self_closing, !@block_opened, preserve_tag, escape_html,
|
600
|
+
attributes, nuke_outer_whitespace, nuke_inner_whitespace
|
601
|
+
].map { |v| v.inspect }.join(', ')
|
602
|
+
push_silent "_hamlout.open_tag(#{args}, #{object_ref}, #{content}#{attributes_hash})"
|
603
|
+
@dont_tab_up_next_text = @dont_indent_next_line = dont_indent_next_line
|
576
604
|
end
|
577
605
|
|
578
606
|
return if self_closing
|
579
607
|
|
580
608
|
if value.empty?
|
581
|
-
push_and_tabulate([:element, tag_name])
|
582
|
-
@output_tabs += 1
|
609
|
+
push_and_tabulate([:element, [tag_name, nuke_outer_whitespace, nuke_inner_whitespace]])
|
610
|
+
@output_tabs += 1 unless nuke_inner_whitespace
|
583
611
|
return
|
584
612
|
end
|
585
613
|
|
586
614
|
if parse
|
587
615
|
flush_merged_text
|
588
|
-
push_script(value, preserve_script,
|
616
|
+
push_script(value, preserve_script, true, preserve_tag, escape_html, nuke_inner_whitespace)
|
617
|
+
@dont_tab_up_next_text = true
|
618
|
+
concat_merged_text("</#{tag_name}>" + (nuke_outer_whitespace ? "" : "\n"))
|
589
619
|
end
|
590
620
|
end
|
591
621
|
|
@@ -602,7 +632,7 @@ END
|
|
602
632
|
conditional << ">" if conditional
|
603
633
|
|
604
634
|
if @block_opened && !line.empty?
|
605
|
-
raise SyntaxError.new('Illegal nesting: nesting within a tag that already has content is illegal.',
|
635
|
+
raise SyntaxError.new('Illegal nesting: nesting within a tag that already has content is illegal.', @next_line.index)
|
606
636
|
end
|
607
637
|
|
608
638
|
open = "<!--#{conditional} "
|
@@ -623,7 +653,7 @@ END
|
|
623
653
|
|
624
654
|
# Renders an XHTML doctype or XML shebang.
|
625
655
|
def render_doctype(line)
|
626
|
-
raise SyntaxError.new("Illegal nesting: nesting within a header command is illegal.",
|
656
|
+
raise SyntaxError.new("Illegal nesting: nesting within a header command is illegal.", @next_line.index) if @block_opened
|
627
657
|
doctype = text_for_doctype(line)
|
628
658
|
push_text doctype if doctype
|
629
659
|
end
|
@@ -666,7 +696,7 @@ END
|
|
666
696
|
def start_filtered(name)
|
667
697
|
raise Error.new("Invalid filter name \":#{name}\".") unless name =~ /^\w+$/
|
668
698
|
|
669
|
-
unless filter =
|
699
|
+
unless filter = Filters.defined[name]
|
670
700
|
if filter == 'redcloth' || filter == 'markdown' || filter == 'textile'
|
671
701
|
raise Error.new("You must have the RedCloth gem installed to use \"#{name}\" filter")
|
672
702
|
end
|
@@ -719,8 +749,8 @@ END
|
|
719
749
|
def count_soft_tabs(line)
|
720
750
|
spaces = line.index(/([^ ]|$)/)
|
721
751
|
if line[spaces] == ?\t
|
722
|
-
return
|
723
|
-
raise SyntaxError.new(<<END.strip,
|
752
|
+
return 0, 0 if line.strip.empty?
|
753
|
+
raise SyntaxError.new(<<END.strip, @next_line.index)
|
724
754
|
A tab character was used for indentation. Haml must be indented using two spaces.
|
725
755
|
Are you sure you have soft tabs enabled in your editor?
|
726
756
|
END
|
@@ -753,5 +783,16 @@ END
|
|
753
783
|
@precompiled << "\n" * @newlines
|
754
784
|
@newlines = 0
|
755
785
|
end
|
786
|
+
|
787
|
+
# Get rid of and whitespace at the end of the buffer
|
788
|
+
# or the merged text
|
789
|
+
def rstrip_buffer!
|
790
|
+
unless @merged_text.empty?
|
791
|
+
@merged_text.rstrip!
|
792
|
+
else
|
793
|
+
push_silent("_erbout.rstrip!", false)
|
794
|
+
@dont_tab_up_next_text = true
|
795
|
+
end
|
796
|
+
end
|
756
797
|
end
|
757
798
|
end
|
@@ -36,8 +36,16 @@ if defined?(RAILS_ROOT)
|
|
36
36
|
# to not need updating.
|
37
37
|
rails_init_file = File.join(RAILS_ROOT, 'vendor', 'plugins', 'haml', 'init.rb')
|
38
38
|
haml_init_file = Haml.scope('init.rb')
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
begin
|
40
|
+
if File.exists?(rails_init_file)
|
41
|
+
require 'fileutils'
|
42
|
+
FileUtils.cp(haml_init_file, rails_init_file) unless FileUtils.cmp(rails_init_file, haml_init_file)
|
43
|
+
end
|
44
|
+
rescue SystemCallError
|
45
|
+
warn <<END
|
46
|
+
HAML WARNING:
|
47
|
+
#{rails_init_file} is out of date and couldn't be automatically updated.
|
48
|
+
Please run `haml --rails #{File.expand_path(RAILS_ROOT)}' to update it.
|
49
|
+
END
|
42
50
|
end
|
43
51
|
end
|
@@ -35,7 +35,7 @@ module ActionView
|
|
35
35
|
options[:filename] = file_name || 'compiled-template'
|
36
36
|
|
37
37
|
begin
|
38
|
-
Haml::Engine.new(template, options).def_method(CompiledTemplates, render_symbol, *
|
38
|
+
Haml::Engine.new(template, options).def_method(CompiledTemplates, render_symbol, *locals_keys)
|
39
39
|
rescue Exception => e
|
40
40
|
if logger
|
41
41
|
logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
|
@@ -253,6 +253,22 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
253
253
|
# font-size: 30em;
|
254
254
|
# font-weight: bold; }
|
255
255
|
#
|
256
|
+
# === Rule Escaping
|
257
|
+
#
|
258
|
+
# In case, for whatever reason, you need to write a rule
|
259
|
+
# that begins with a Sass-meaningful character,
|
260
|
+
# you can escape it with a backslash (<tt>\</tt>).
|
261
|
+
# For example:
|
262
|
+
#
|
263
|
+
# #main
|
264
|
+
# \+div
|
265
|
+
# clear: both
|
266
|
+
#
|
267
|
+
# is compiled to:
|
268
|
+
#
|
269
|
+
# #main +div {
|
270
|
+
# clear: both; }
|
271
|
+
#
|
256
272
|
# == Constants
|
257
273
|
#
|
258
274
|
# Sass has support for setting document-wide constants.
|
@@ -760,9 +776,16 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
760
776
|
#
|
761
777
|
# == Sass Options
|
762
778
|
#
|
763
|
-
# Options can be set by setting the
|
764
|
-
#
|
765
|
-
#
|
779
|
+
# Options can be set by setting the <tt>Sass::Plugin.options</tt> hash
|
780
|
+
# in <tt>environment.rb</tt> in Rails...
|
781
|
+
#
|
782
|
+
# Sass::Plugin.options[:style] = :compact
|
783
|
+
#
|
784
|
+
# ...or by setting the <tt>Merb::Config[:sass]</tt> hash in <tt>init.rb</tt> in Merb...
|
785
|
+
#
|
786
|
+
# Merb::Config[:sass][:style] = :compact
|
787
|
+
#
|
788
|
+
# ...or by passing an options hash to Sass::Engine.new.
|
766
789
|
# Available options are:
|
767
790
|
#
|
768
791
|
# [<tt>:style</tt>] Sets the style of the CSS output.
|
@@ -119,17 +119,10 @@ module Sass
|
|
119
119
|
next
|
120
120
|
end
|
121
121
|
|
122
|
-
# Is this a constant?
|
123
|
-
if beginning_of_token && symbol == :const
|
124
|
-
beginning_of_token = true
|
125
|
-
to_return << :const
|
126
|
-
next
|
127
|
-
end
|
128
|
-
|
129
122
|
# Are we looking at an operator?
|
130
123
|
if symbol && (symbol != :mod || str.empty?)
|
131
124
|
str = reset_str.call
|
132
|
-
beginning_of_token =
|
125
|
+
beginning_of_token = symbol != :close
|
133
126
|
to_return << symbol
|
134
127
|
next
|
135
128
|
end
|
@@ -148,57 +141,30 @@ module Sass
|
|
148
141
|
to_return
|
149
142
|
end
|
150
143
|
|
151
|
-
def parenthesize(value)
|
152
|
-
parenthesize_helper(0, value, value.length)[0]
|
153
|
-
end
|
154
|
-
|
155
|
-
def parenthesize_helper(i, value, value_len, return_after_expr = false)
|
144
|
+
def parenthesize(value, return_after_expr = false)
|
156
145
|
to_return = []
|
157
|
-
|
158
|
-
token = value
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
to_return <<
|
166
|
-
|
167
|
-
if value
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
sub, i = parenthesize_helper(i + 2, value, value_len)
|
173
|
-
beginning = i
|
174
|
-
to_return << [:neg, sub]
|
175
|
-
elsif value[i + 1].is_a?(::Symbol)
|
176
|
-
to_return.push(*value[beginning...i])
|
177
|
-
sub, i = parenthesize_helper(i + 1, value, value_len, true)
|
178
|
-
beginning = i
|
179
|
-
to_return << [:neg, sub]
|
180
|
-
else
|
181
|
-
to_return.push(*value[beginning...i])
|
182
|
-
to_return << [:neg, value[i + 1]]
|
183
|
-
beginning = i = i + 2
|
184
|
-
end
|
185
|
-
return to_return[0], i if return_after_expr
|
186
|
-
elsif token == :const
|
187
|
-
raise Sass::SyntaxError.new("Unterminated constant.") if value[i + 1].nil?
|
188
|
-
raise Sass::SyntaxError.new("Invalid constant.") unless value[i + 1].is_a?(::String)
|
189
|
-
|
190
|
-
to_return.push(*value[beginning...i])
|
191
|
-
to_return << [:const, value[i + 1]]
|
192
|
-
beginning = i = i + 2
|
193
|
-
return to_return[0], i if return_after_expr
|
146
|
+
|
147
|
+
while (token = value.shift) && token != :close
|
148
|
+
case token
|
149
|
+
when :open
|
150
|
+
to_return << parenthesize(value)
|
151
|
+
when :neg
|
152
|
+
# This is never actually reached, but we'll leave it in just in case.
|
153
|
+
raise Sass::SyntaxError.new("Unterminated unary minus.") if value.first.nil?
|
154
|
+
to_return << [:neg, parenthesize(value, true)]
|
155
|
+
when :const
|
156
|
+
raise Sass::SyntaxError.new("Unterminated constant.") if value.first.nil?
|
157
|
+
raise Sass::SyntaxError.new("Invalid constant.") unless value.first.is_a?(::String)
|
158
|
+
|
159
|
+
to_return << [:const, value.first]
|
160
|
+
value.shift
|
194
161
|
else
|
195
|
-
|
162
|
+
to_return << token
|
196
163
|
end
|
197
164
|
|
198
|
-
|
165
|
+
return to_return.first if return_after_expr
|
199
166
|
end
|
200
|
-
to_return
|
201
|
-
return to_return, i + 1
|
167
|
+
return to_return
|
202
168
|
end
|
203
169
|
|
204
170
|
#--
|
@@ -207,7 +173,10 @@ module Sass
|
|
207
173
|
#++
|
208
174
|
def operationalize(value, constants)
|
209
175
|
value = [value] unless value.is_a?(Array)
|
210
|
-
|
176
|
+
case value.length
|
177
|
+
when 0
|
178
|
+
Sass::Constant::Nil.new
|
179
|
+
when 1
|
211
180
|
value = value[0]
|
212
181
|
if value.is_a? Array
|
213
182
|
operationalize(value, constants)
|
@@ -216,7 +185,7 @@ module Sass
|
|
216
185
|
else
|
217
186
|
Literal.parse(value)
|
218
187
|
end
|
219
|
-
|
188
|
+
when 2
|
220
189
|
if value[0] == :neg
|
221
190
|
Operation.new(Sass::Constant::Number.new('0'), operationalize(value[1], constants), :minus)
|
222
191
|
elsif value[0] == :const
|
@@ -224,7 +193,7 @@ module Sass
|
|
224
193
|
else
|
225
194
|
raise SyntaxError.new("Constant arithmetic error")
|
226
195
|
end
|
227
|
-
|
196
|
+
when 3
|
228
197
|
Operation.new(operationalize(value[0], constants), operationalize(value[2], constants), value[1])
|
229
198
|
else
|
230
199
|
if SECOND_ORDER.include?(value[1]) && FIRST_ORDER.include?(value[3])
|