actionview 4.1.0.beta2 → 4.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionview might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f9b23cbe6e5836943ca74bf7087aca78ff64e3c9
4
- data.tar.gz: e97748e630afc36a648c8160bfff20b8cba563c4
3
+ metadata.gz: 07c7cfb02baa85d1be095df9bdf486932bae786d
4
+ data.tar.gz: 43b83b9ee0eb0a2ac07f0a654c6e622bbe71861a
5
5
  SHA512:
6
- metadata.gz: 9394df9f9b71741dfa33bb7229abbe56c4915eb7a69905c7171c09c059f9ab826c580113f6ecac9e881c06c034e4da1174d6ab4c64567e2e958e771c00125817
7
- data.tar.gz: 46f8811a41621bdfbc7af6e9ec5fb79ada9ffcf1f8d96ce673c2945634fb020da611a29a73babe2ac7ef96c6853e52c4e2c31629646442ad8bd1b75617e43e98
6
+ metadata.gz: bf072d8647e35ca744a19267a9478ed110fa637c1eded7faea8159b6376de476ad9621b857667a7469d152c69994f751b73bdd5541480e09c8d48da4162760d7
7
+ data.tar.gz: b7e058105db2d0ab080608f1922b3d02ed686fa632e7f5dc8df495250e7896286d3562801dec4f93a3602f6189fcc0d0e6453f7acebdfe38b5f4441e37b47172
@@ -1,3 +1,50 @@
1
+ * Added `:plain`, `:html` and `:body` option for `render` method. Please see
2
+ Action Pack's release note for more detail.
3
+
4
+ *Prem Sichanugrist*
5
+
6
+ * Date select helpers accept a format string for the months selector via the
7
+ new option `:month_format_string`.
8
+
9
+ When rendered, the format string gets passed keys `:number` (integer), and
10
+ `:name` (string), in order to be able to interpolate them as in
11
+
12
+ '%{name} (%<number>02d)'
13
+
14
+ for example.
15
+
16
+ This option is motivated by #13618.
17
+
18
+ *Xavier Noria*
19
+
20
+ * Added `config.action_view.raise_on_missing_translations` to define whether an
21
+ error should be raised for missing translations.
22
+
23
+ Fixes #13196.
24
+
25
+ *Kassio Borges*
26
+
27
+ * Improved ERB dependency detection. New argument types and formattings for the `render`
28
+ calls can be matched.
29
+
30
+ Fixes #13074, #13116.
31
+
32
+ *João Britto*
33
+
34
+ * Use `display:none` instead of `display:inline` for hidden fields.
35
+
36
+ Fixes #6403.
37
+
38
+ *Gaelian Ditchburn*
39
+
40
+ * The `video_tag` helper accepts a number as `:size`.
41
+
42
+ The `:size` option of the `video_tag` helper now can be specified
43
+ with a stringified number. The `width` and `height` attributes of
44
+ the generated tag will be the same.
45
+
46
+ *Kuldeep Aggarwal*
47
+
1
48
  * Escape format, negative_format and units options of number helpers
2
49
 
3
50
  Fixes: CVE-2014-0081
@@ -58,11 +105,11 @@
58
105
 
59
106
  *Yves Senn*
60
107
 
61
- * Use `set_backtrace` instead of instance variable `@backtrace` in ActionView exceptions
108
+ * Use `set_backtrace` instead of instance variable `@backtrace` in ActionView exceptions.
62
109
 
63
110
  *Shimpei Makimoto*
64
111
 
65
- * Fix `simple_format` escapes own output when passing `sanitize: true`
112
+ * Fix `simple_format` escapes own output when passing `sanitize: true`.
66
113
 
67
114
  *Paul Seidemann*
68
115
 
@@ -80,7 +127,9 @@
80
127
 
81
128
  *Bogdan Gusiev*
82
129
 
83
- * Ability to pass block to `select` helper
130
+ * Ability to pass a block to the `select` helper.
131
+
132
+ Example:
84
133
 
85
134
  <%= select(report, "campaign_ids") do %>
86
135
  <% available_campaigns.each do |c| -%>
@@ -160,7 +209,7 @@
160
209
  * Fix default rendered format problem when calling `render` without :content_type option.
161
210
  It should return :html. Fix #11393.
162
211
 
163
- *Gleb Mazovetskiy* *Oleg* *kennyj*
212
+ *Gleb Mazovetskiy*, *Oleg*, *kennyj*
164
213
 
165
214
  * Fix `link_to` with block and url hashes.
166
215
 
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2013 David Heinemeier Hansson
1
+ Copyright (c) 2004-2014 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2004-2013 David Heinemeier Hansson
2
+ # Copyright (c) 2004-2014 David Heinemeier Hansson
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -23,10 +23,13 @@
23
23
 
24
24
  require 'active_support'
25
25
  require 'active_support/rails'
26
+ require 'action_view/version'
26
27
 
27
28
  module ActionView
28
29
  extend ActiveSupport::Autoload
29
30
 
31
+ ENCODING_FLAG = '#.*coding[:=]\s*(\S+)[ \t]*'
32
+
30
33
  eager_autoload do
31
34
  autoload :Base
32
35
  autoload :Context
@@ -53,7 +56,6 @@ module ActionView
53
56
  autoload_at "action_view/template/resolver" do
54
57
  autoload :Resolver
55
58
  autoload :PathResolver
56
- autoload :FileSystemResolver
57
59
  autoload :OptimizedFileSystemResolver
58
60
  autoload :FallbackFileSystemResolver
59
61
  end
@@ -80,8 +82,6 @@ module ActionView
80
82
 
81
83
  autoload :TestCase
82
84
 
83
- ENCODING_FLAG = '#.*coding[:=]\s*(\S+)[ \t]*'
84
-
85
85
  def self.eager_load!
86
86
  super
87
87
  ActionView::Helpers.eager_load!
@@ -153,6 +153,10 @@ module ActionView #:nodoc:
153
153
  # Specify default_formats that can be rendered.
154
154
  cattr_accessor :default_formats
155
155
 
156
+ # Specify whether an error should be raised for missing translations
157
+ cattr_accessor :raise_on_missing_translations
158
+ @@raise_on_missing_translations = false
159
+
156
160
  class_attribute :_routes
157
161
  class_attribute :logger
158
162
 
@@ -1,7 +1,7 @@
1
1
  require 'thread_safe'
2
2
 
3
3
  module ActionView
4
- class DependencyTracker
4
+ class DependencyTracker # :nodoc:
5
5
  @trackers = ThreadSafe::Cache.new
6
6
 
7
7
  def self.find_dependencies(name, template)
@@ -23,24 +23,52 @@ module ActionView
23
23
  @trackers.delete(handler)
24
24
  end
25
25
 
26
- class ERBTracker
26
+ class ERBTracker # :nodoc:
27
27
  EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/
28
28
 
29
+ # A valid ruby identifier - suitable for class, method and specially variable names
30
+ IDENTIFIER = /
31
+ [[:alpha:]_] # at least one uppercase letter, lowercase letter or underscore
32
+ [[:word:]]* # followed by optional letters, numbers or underscores
33
+ /x
34
+
35
+ # Any kind of variable name. e.g. @instance, @@class, $global or local.
36
+ # Possibly following a method call chain
37
+ VARIABLE_OR_METHOD_CHAIN = /
38
+ (?:\$|@{1,2})? # optional global, instance or class variable indicator
39
+ (?:#{IDENTIFIER}\.)* # followed by an optional chain of zero-argument method calls
40
+ (?<dynamic>#{IDENTIFIER}) # and a final valid identifier, captured as DYNAMIC
41
+ /x
42
+
43
+ # A simple string literal. e.g. "School's out!"
44
+ STRING = /
45
+ (?<quote>['"]) # an opening quote
46
+ (?<static>.*?) # with anything inside, captured as STATIC
47
+ \k<quote> # and a matching closing quote
48
+ /x
49
+
50
+ # Part of any hash containing the :partial key
51
+ PARTIAL_HASH_KEY = /
52
+ (?:\bpartial:|:partial\s*=>) # partial key in either old or new style hash syntax
53
+ \s* # followed by optional spaces
54
+ /x
55
+
29
56
  # Matches:
30
- # render partial: "comments/comment", collection: commentable.comments
31
- # render "comments/comments"
32
- # render 'comments/comments'
33
- # render('comments/comments')
57
+ # partial: "comments/comment", collection: @all_comments => "comments/comment"
58
+ # (object: @single_comment, partial: "comments/comment") => "comments/comment"
34
59
  #
35
- # render(@topic) => render("topics/topic")
36
- # render(topics) => render("topics/topic")
37
- # render(message.topics) => render("topics/topic")
38
- RENDER_DEPENDENCY = /
39
- render\s* # render, followed by optional whitespace
40
- \(? # start an optional parenthesis for the render call
41
- (partial:|:partial\s+=>)?\s* # naming the partial, used with collection -- 1st capture
42
- ([@a-z"'][@\w\/\."']+) # the template name itself -- 2nd capture
43
- /x
60
+ # "comments/comments"
61
+ # 'comments/comments'
62
+ # ('comments/comments')
63
+ #
64
+ # (@topic) => "topics/topic"
65
+ # topics => "topics/topic"
66
+ # (message.topics) => "topics/topic"
67
+ RENDER_ARGUMENTS = /\A
68
+ (?:\s*\(?\s*) # optional opening paren surrounded by spaces
69
+ (?:.*?#{PARTIAL_HASH_KEY})? # optional hash, up to the partial key declaration
70
+ (?:#{STRING}|#{VARIABLE_OR_METHOD_CHAIN}) # finally, the dependency name of interest
71
+ /xm
44
72
 
45
73
  def self.call(name, template)
46
74
  new(name, template).dependencies
@@ -68,19 +96,33 @@ module ActionView
68
96
  end
69
97
 
70
98
  def render_dependencies
71
- source.scan(RENDER_DEPENDENCY).
72
- collect(&:second).uniq.
99
+ render_dependencies = []
100
+ render_calls = source.split(/\brender\b/).drop(1)
73
101
 
74
- # render(@topic) => render("topics/topic")
75
- # render(topics) => render("topics/topic")
76
- # render(message.topics) => render("topics/topic")
77
- collect { |name| name.sub(/\A@?([a-z_]+\.)*([a-z_]+)\z/) { "#{$2.pluralize}/#{$2.singularize}" } }.
102
+ render_calls.each do |arguments|
103
+ arguments.scan(RENDER_ARGUMENTS) do
104
+ add_dynamic_dependency(render_dependencies, Regexp.last_match[:dynamic])
105
+ add_static_dependency(render_dependencies, Regexp.last_match[:static])
106
+ end
107
+ end
78
108
 
79
- # render("headline") => render("message/headline")
80
- collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }.
109
+ render_dependencies.uniq
110
+ end
111
+
112
+ def add_dynamic_dependency(dependencies, dependency)
113
+ if dependency
114
+ dependencies << "#{dependency.pluralize}/#{dependency.singularize}"
115
+ end
116
+ end
81
117
 
82
- # replace quotes from string renders
83
- collect { |name| name.gsub(/["']/, "") }
118
+ def add_static_dependency(dependencies, dependency)
119
+ if dependency
120
+ if dependency.include?('/')
121
+ dependencies << dependency
122
+ else
123
+ dependencies << "#{directory}/#{dependency}"
124
+ end
125
+ end
84
126
  end
85
127
 
86
128
  def explicit_dependencies
@@ -176,7 +176,7 @@ module ActionView
176
176
  # ==== Options
177
177
  #
178
178
  # You can add HTML attributes using the +options+. The +options+ supports
179
- # three additional keys for convenience and conformance:
179
+ # two additional keys for convenience and conformance:
180
180
  #
181
181
  # * <tt>:alt</tt> - If no alt text is given, the file name part of the
182
182
  # +source+ is used (capitalized and without the extension)
@@ -207,14 +207,7 @@ module ActionView
207
207
  options[:alt] = options.fetch(:alt){ image_alt(src) }
208
208
  end
209
209
 
210
- if size = options.delete(:size)
211
- if size =~ %r{\A\d+x\d+\z}
212
- options[:width], options[:height] = size.split('x')
213
- elsif size =~ %r{\A\d+\z}
214
- options[:width] = options[:height] = size
215
- end
216
- end
217
-
210
+ options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
218
211
  tag("img", options)
219
212
  end
220
213
 
@@ -251,9 +244,9 @@ module ActionView
251
244
  #
252
245
  # * <tt>:poster</tt> - Set an image (like a screenshot) to be shown
253
246
  # before the video loads. The path is calculated like the +src+ of +image_tag+.
254
- # * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes
255
- # width="30" and height="45". <tt>:size</tt> will be ignored if the
256
- # value is not in the correct format.
247
+ # * <tt>:size</tt> - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes
248
+ # width="30" and height="45", and "50" becomes width="50" and height="50".
249
+ # <tt>:size</tt> will be ignored if the value is not in the correct format.
257
250
  #
258
251
  # ==== Examples
259
252
  #
@@ -267,6 +260,8 @@ module ActionView
267
260
  # # => <video src="/videos/trailer.m4v" width="16" height="10" poster="/assets/screenshot.png" />
268
261
  # video_tag("/trailers/hd.avi", size: "16x16")
269
262
  # # => <video src="/trailers/hd.avi" width="16" height="16" />
263
+ # video_tag("/trailers/hd.avi", size: "16")
264
+ # # => <video height="16" src="/trailers/hd.avi" width="16" />
270
265
  # video_tag("/trailers/hd.avi", height: '32', width: '32')
271
266
  # # => <video height="32" src="/trailers/hd.avi" width="32" />
272
267
  # video_tag("trailer.ogg", "trailer.flv")
@@ -278,10 +273,7 @@ module ActionView
278
273
  def video_tag(*sources)
279
274
  multiple_sources_tag('video', sources) do |options|
280
275
  options[:poster] = path_to_image(options[:poster]) if options[:poster]
281
-
282
- if size = options.delete(:size)
283
- options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
284
- end
276
+ options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
285
277
  end
286
278
  end
287
279
 
@@ -317,6 +309,14 @@ module ActionView
317
309
  content_tag(type, nil, options)
318
310
  end
319
311
  end
312
+
313
+ def extract_dimensions(size)
314
+ if size =~ %r{\A\d+x\d+\z}
315
+ size.split('x')
316
+ elsif size =~ %r{\A\d+\z}
317
+ [size, size]
318
+ end
319
+ end
320
320
  end
321
321
  end
322
322
  end
@@ -12,8 +12,11 @@ module ActionView
12
12
  # These are used to generate the dynamic forms that implement non-remote links with
13
13
  # <tt>:method</tt>.
14
14
  #
15
- # Note that regular forms generate hidden fields, and that Ajax calls are whitelisted,
16
- # so they do not use these tags.
15
+ # You don't need to use these tags for regular forms as they generate their own hidden fields.
16
+ #
17
+ # For AJAX requests other than GETs, extract the "csrf-token" from the meta-tag and send as the
18
+ # "X-CSRF-Token" HTTP header. If you are using jQuery with jquery-rails this happens automatically.
19
+ #
17
20
  def csrf_meta_tags
18
21
  if protect_against_forgery?
19
22
  [
@@ -169,9 +169,16 @@ module ActionView
169
169
  # "2 - February" instead of "February").
170
170
  # * <tt>:use_month_names</tt> - Set to an array with 12 month names if you want to customize month names.
171
171
  # Note: You can also use Rails' i18n functionality for this.
172
+ # * <tt>:month_format_string</tt> - Set to a format string. The string gets passed keys +:number+ (integer)
173
+ # and +:name+ (string). A format string would be something like "%{name} (%<number>02d)" for example.
174
+ # See <tt>Kernel.sprintf</tt> for documentation on format sequences.
172
175
  # * <tt>:date_separator</tt> - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
173
- # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Time.now.year - 5</tt>.
174
- # * <tt>:end_year</tt> - Set the end year for the year select. Default is <tt>Time.now.year + 5</tt>.
176
+ # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Date.today.year - 5</tt>if
177
+ # you are creating new record. While editing existing record, <tt>:start_year</tt> defaults to
178
+ # the current selected year minus 5.
179
+ # * <tt>:end_year</tt> - Set the end year for the year select. Default is <tt>Date.today.year + 5</tt> if
180
+ # you are creating new record. While editing existing record, <tt>:end_year</tt> defaults to
181
+ # the current selected year plus 5.
175
182
  # * <tt>:discard_day</tt> - Set to true if you don't want to show a day select. This includes the day
176
183
  # as a hidden field instead of showing a select field. Also note that this implicitly sets the day to be the
177
184
  # first of the given month in order to not create invalid dates like 31 February.
@@ -846,24 +853,36 @@ module ActionView
846
853
  I18n.translate(key, :locale => @options[:locale])
847
854
  end
848
855
 
849
- # Lookup month name for number.
850
- # month_name(1) => "January"
856
+ # Looks up month names by number (1-based):
851
857
  #
852
- # If <tt>:use_month_numbers</tt> option is passed
853
- # month_name(1) => 1
858
+ # month_name(1) # => "January"
854
859
  #
855
- # If <tt>:use_two_month_numbers</tt> option is passed
856
- # month_name(1) => '01'
860
+ # If the <tt>:use_month_numbers</tt> option is passed:
857
861
  #
858
- # If <tt>:add_month_numbers</tt> option is passed
859
- # month_name(1) => "1 - January"
862
+ # month_name(1) # => 1
863
+ #
864
+ # If the <tt>:use_two_month_numbers</tt> option is passed:
865
+ #
866
+ # month_name(1) # => '01'
867
+ #
868
+ # If the <tt>:add_month_numbers</tt> option is passed:
869
+ #
870
+ # month_name(1) # => "1 - January"
871
+ #
872
+ # If the <tt>:month_format_string</tt> option is passed:
873
+ #
874
+ # month_name(1) # => "January (01)"
875
+ #
876
+ # depending on the format string.
860
877
  def month_name(number)
861
878
  if @options[:use_month_numbers]
862
879
  number
863
880
  elsif @options[:use_two_digit_numbers]
864
- sprintf "%02d", number
881
+ '%02d' % number
865
882
  elsif @options[:add_month_numbers]
866
883
  "#{number} - #{month_names[number]}"
884
+ elsif format_string = @options[:month_format_string]
885
+ format_string % {number: number, name: month_names[number]}
867
886
  else
868
887
  month_names[number]
869
888
  end
@@ -1062,7 +1081,7 @@ module ActionView
1062
1081
  # Wraps ActionView::Helpers::DateHelper#datetime_select for form builders:
1063
1082
  #
1064
1083
  # <%= form_for @person do |f| %>
1065
- # <%= f.time_select :last_request_at %>
1084
+ # <%= f.datetime_select :last_request_at %>
1066
1085
  # <%= f.submit %>
1067
1086
  # <% end %>
1068
1087
  #
@@ -51,7 +51,7 @@ module ActionView
51
51
  # The HTML generated for this would be (modulus formatting):
52
52
  #
53
53
  # <form action="/people" class="new_person" id="new_person" method="post">
54
- # <div style="margin:0;padding:0;display:inline">
54
+ # <div style="display:none">
55
55
  # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
56
56
  # </div>
57
57
  # <label for="person_first_name">First name</label>:
@@ -81,7 +81,7 @@ module ActionView
81
81
  # the code above as is would yield instead:
82
82
  #
83
83
  # <form action="/people/256" class="edit_person" id="edit_person_256" method="post">
84
- # <div style="margin:0;padding:0;display:inline">
84
+ # <div style="display:none">
85
85
  # <input name="_method" type="hidden" value="patch" />
86
86
  # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
87
87
  # </div>
@@ -315,7 +315,7 @@ module ActionView
315
315
  # The HTML generated for this would be:
316
316
  #
317
317
  # <form action='http://www.example.com' method='post' data-remote='true'>
318
- # <div style='margin:0;padding:0;display:inline'>
318
+ # <div style='display:none'>
319
319
  # <input name='_method' type='hidden' value='patch' />
320
320
  # </div>
321
321
  # ...
@@ -333,7 +333,7 @@ module ActionView
333
333
  # The HTML generated for this would be:
334
334
  #
335
335
  # <form action='http://www.example.com' method='post' data-behavior='autosave' name='go'>
336
- # <div style='margin:0;padding:0;display:inline'>
336
+ # <div style='display:none'>
337
337
  # <input name='_method' type='hidden' value='patch' />
338
338
  # </div>
339
339
  # ...
@@ -762,8 +762,8 @@ module ActionView
762
762
  # text_field(:post, :title, class: "create_input")
763
763
  # # => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" class="create_input" />
764
764
  #
765
- # text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }")
766
- # # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }"/>
765
+ # text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
766
+ # # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/>
767
767
  #
768
768
  # text_field(:snippet, :code, size: 20, class: 'code_input')
769
769
  # # => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
@@ -722,7 +722,7 @@ module ActionView
722
722
 
723
723
  enforce_utf8 = html_options.delete("enforce_utf8") { true }
724
724
  tags = (enforce_utf8 ? utf8_enforcer_tag : ''.html_safe) << method_tag
725
- content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
725
+ content_tag(:div, tags, :style => 'display:none')
726
726
  end
727
727
 
728
728
  def form_tag_html(html_options)
@@ -12,6 +12,13 @@ module ActionView
12
12
  # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
13
13
  # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
14
14
  # * <tt>:text</tt> - Renders the text passed in out.
15
+ # * <tt>:plain</tt> - Renders the text passed in out. Setting the content
16
+ # type as <tt>text/plain</tt>.
17
+ # * <tt>:html</tt> - Renders the html safe string passed in out, otherwise
18
+ # performs html escape on the string first. Setting the content type as
19
+ # <tt>text/html</tt>.
20
+ # * <tt>:body</tt> - Renders the text passed in, and does not set content
21
+ # type in the response.
15
22
  #
16
23
  # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
17
24
  # as the locals hash.
@@ -82,6 +82,9 @@ module ActionView
82
82
  # # => "And they f... (continued)"
83
83
  #
84
84
  # truncate("<p>Once upon a time in a world far far away</p>")
85
+ # # => "&lt;p&gt;Once upon a time in a wo..."
86
+ #
87
+ # truncate("<p>Once upon a time in a world far far away</p>", escape: false)
85
88
  # # => "<p>Once upon a time in a wo..."
86
89
  #
87
90
  # truncate("Once upon a time in a world far far away") { link_to "Continue", "#" }
@@ -38,10 +38,10 @@ module ActionView
38
38
 
39
39
  # If the user has specified rescue_format then pass it all through, otherwise use
40
40
  # raise and do the work ourselves
41
- if options.key?(:raise) || options.key?(:rescue_format)
42
- raise_error = options[:raise] || options[:rescue_format]
43
- else
44
- raise_error = false
41
+ options[:raise] ||= ActionView::Base.raise_on_missing_translations
42
+
43
+ raise_error = options[:raise] || options.key?(:rescue_format)
44
+ unless raise_error
45
45
  options[:raise] = true
46
46
  end
47
47
 
@@ -232,6 +232,11 @@ module ActionView
232
232
  # # <div><input value="New" type="submit" /></div>
233
233
  # # </form>"
234
234
  #
235
+ # <%= button_to "New", new_articles_path %>
236
+ # # => "<form method="post" action="/articles/new" class="button_to">
237
+ # # <div><input value="New" type="submit" /></div>
238
+ # # </form>"
239
+ #
235
240
  # <%= button_to [:make_happy, @user] do %>
236
241
  # Make happy <strong><%= @user.name %></strong>
237
242
  # <% end %>
@@ -420,7 +420,7 @@ module ActionView
420
420
  end
421
421
 
422
422
  def _include_layout?(options)
423
- (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout)
423
+ (options.keys & [:body, :text, :plain, :html, :inline, :partial]).empty? || options.key?(:layout)
424
424
  end
425
425
  end
426
426
  end
@@ -1,6 +1,7 @@
1
1
  require 'thread_safe'
2
2
  require 'active_support/core_ext/module/remove_method'
3
3
  require 'active_support/core_ext/module/attribute_accessors'
4
+ require 'action_view/template/resolver'
4
5
 
5
6
  module ActionView
6
7
  # = Action View Lookup Context
@@ -21,8 +21,14 @@ module ActionView
21
21
  def determine_template(options) #:nodoc:
22
22
  keys = options.fetch(:locals, {}).keys
23
23
 
24
- if options.key?(:text)
24
+ if options.key?(:body)
25
+ Template::Text.new(options[:body])
26
+ elsif options.key?(:text)
25
27
  Template::Text.new(options[:text], formats.first)
28
+ elsif options.key?(:plain)
29
+ Template::Text.new(options[:plain])
30
+ elsif options.key?(:html)
31
+ Template::HTML.new(options[:html], formats.first)
26
32
  elsif options.key?(:file)
27
33
  with_fallbacks { find_template(options[:file], nil, false, keys, @details) }
28
34
  elsif options.key?(:inline)
@@ -35,7 +41,7 @@ module ActionView
35
41
  find_template(options[:template], options[:prefixes], false, keys, @details)
36
42
  end
37
43
  else
38
- raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file or :text option."
44
+ raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :text or :body option."
39
45
  end
40
46
  end
41
47
 
@@ -94,14 +94,19 @@ module ActionView
94
94
  variant = options[:variant]
95
95
 
96
96
  lookup_context.rendered_format = nil if options[:formats]
97
- lookup_context.variants = [variant] if variant
97
+ lookup_context.variants = variant if variant
98
98
 
99
99
  view_renderer.render(view_context, options)
100
100
  end
101
101
 
102
102
  # Assign the rendered format to lookup context.
103
- def _process_format(format) #:nodoc:
103
+ def _process_format(format, options = {}) #:nodoc:
104
104
  super
105
+
106
+ if options[:body]
107
+ self.no_content_type = true
108
+ end
109
+
105
110
  lookup_context.formats = [format.to_sym]
106
111
  lookup_context.rendered_format = lookup_context.formats.first
107
112
  end
@@ -90,6 +90,7 @@ module ActionView
90
90
  eager_autoload do
91
91
  autoload :Error
92
92
  autoload :Handlers
93
+ autoload :HTML
93
94
  autoload :Text
94
95
  autoload :Types
95
96
  end
@@ -0,0 +1,34 @@
1
+ module ActionView #:nodoc:
2
+ # = Action View HTML Template
3
+ class Template
4
+ class HTML #:nodoc:
5
+ attr_accessor :type
6
+
7
+ def initialize(string, type = nil)
8
+ @string = string.to_s
9
+ @type = Types[type] || type if type
10
+ @type ||= Types[:html]
11
+ end
12
+
13
+ def identifier
14
+ 'html template'
15
+ end
16
+
17
+ def inspect
18
+ 'html template'
19
+ end
20
+
21
+ def to_str
22
+ ERB::Util.h(@string)
23
+ end
24
+
25
+ def render(*args)
26
+ to_str
27
+ end
28
+
29
+ def formats
30
+ [@type.respond_to?(:ref) ? @type.ref : @type.to_s]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -27,7 +27,7 @@ module ActionView #:nodoc:
27
27
  end
28
28
 
29
29
  def formats
30
- [@type.to_sym]
30
+ [@type.respond_to?(:ref) ? @type.ref : @type.to_s]
31
31
  end
32
32
  end
33
33
  end
@@ -71,12 +71,12 @@ module HTML #:nodoc:
71
71
  @line, @position = line, pos
72
72
  end
73
73
 
74
- # Return a textual representation of the node.
74
+ # Returns a textual representation of the node.
75
75
  def to_s
76
76
  @children.join()
77
77
  end
78
78
 
79
- # Return false (subclasses must override this to provide specific matching
79
+ # Returns false (subclasses must override this to provide specific matching
80
80
  # behavior.) +conditions+ may be of any type.
81
81
  def match(conditions)
82
82
  false
@@ -488,7 +488,7 @@ module HTML
488
488
  end
489
489
 
490
490
 
491
- # Return the next element after this one. Skips sibling text nodes.
491
+ # Returns the next element after this one. Skips sibling text nodes.
492
492
  #
493
493
  # With the +name+ argument, returns the next element with that name,
494
494
  # skipping other sibling elements.
@@ -30,7 +30,7 @@ module HTML #:nodoc:
30
30
  @current_line = 1
31
31
  end
32
32
 
33
- # Return the next token in the sequence, or +nil+ if there are no more tokens in
33
+ # Returns the next token in the sequence, or +nil+ if there are no more tokens in
34
34
  # the stream.
35
35
  def next
36
36
  return nil if @scanner.eos?
@@ -1,7 +1,7 @@
1
1
  module ActionView
2
2
  # Returns the version of the currently loaded ActionView as a Gem::Version
3
3
  def self.version
4
- Gem::Version.new "4.1.0.beta2"
4
+ Gem::Version.new "4.1.0.rc1"
5
5
  end
6
6
 
7
7
  module VERSION #:nodoc:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionview
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0.beta2
4
+ version: 4.1.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 4.1.0.beta2
19
+ version: 4.1.0.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 4.1.0.beta2
26
+ version: 4.1.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: builder
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 4.1.0.beta2
61
+ version: 4.1.0.rc1
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 4.1.0.beta2
68
+ version: 4.1.0.rc1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activemodel
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 4.1.0.beta2
75
+ version: 4.1.0.rc1
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 4.1.0.beta2
82
+ version: 4.1.0.rc1
83
83
  description: Simple, battle-tested conventions and helpers for building web pages.
84
84
  email: david@loudthinking.com
85
85
  executables: []
@@ -176,6 +176,7 @@ files:
176
176
  - lib/action_view/template/handlers/builder.rb
177
177
  - lib/action_view/template/handlers/erb.rb
178
178
  - lib/action_view/template/handlers/raw.rb
179
+ - lib/action_view/template/html.rb
179
180
  - lib/action_view/template/resolver.rb
180
181
  - lib/action_view/template/text.rb
181
182
  - lib/action_view/template/types.rb