actionview 5.0.7.2 → 5.1.0.beta1
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 +5 -5
- data/CHANGELOG.md +92 -384
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/action_view.rb +5 -5
- data/lib/action_view/base.rb +19 -19
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +1 -1
- data/lib/action_view/dependency_tracker.rb +4 -5
- data/lib/action_view/digestor.rb +6 -7
- data/lib/action_view/flows.rb +5 -6
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers.rb +1 -1
- data/lib/action_view/helpers/active_model_helper.rb +8 -8
- data/lib/action_view/helpers/asset_tag_helper.rb +62 -36
- data/lib/action_view/helpers/asset_url_helper.rb +111 -49
- data/lib/action_view/helpers/atom_feed_helper.rb +12 -13
- data/lib/action_view/helpers/cache_helper.rb +34 -20
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +3 -11
- data/lib/action_view/helpers/csrf_helper.rb +3 -3
- data/lib/action_view/helpers/date_helper.rb +109 -107
- data/lib/action_view/helpers/debug_helper.rb +2 -3
- data/lib/action_view/helpers/form_helper.rb +406 -31
- data/lib/action_view/helpers/form_options_helper.rb +12 -12
- data/lib/action_view/helpers/form_tag_helper.rb +19 -18
- data/lib/action_view/helpers/javascript_helper.rb +6 -6
- data/lib/action_view/helpers/number_helper.rb +48 -46
- data/lib/action_view/helpers/output_safety_helper.rb +8 -8
- data/lib/action_view/helpers/rendering_helper.rb +2 -2
- data/lib/action_view/helpers/sanitize_helper.rb +6 -8
- data/lib/action_view/helpers/tag_helper.rb +194 -77
- data/lib/action_view/helpers/tags/base.rb +121 -102
- data/lib/action_view/helpers/tags/check_box.rb +17 -17
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +8 -8
- data/lib/action_view/helpers/tags/collection_helpers.rb +60 -60
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +2 -2
- data/lib/action_view/helpers/tags/collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/date_select.rb +36 -36
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/label.rb +4 -0
- data/lib/action_view/helpers/tags/password_field.rb +1 -1
- data/lib/action_view/helpers/tags/radio_button.rb +4 -4
- data/lib/action_view/helpers/tags/select.rb +9 -9
- data/lib/action_view/helpers/tags/text_area.rb +1 -1
- data/lib/action_view/helpers/tags/text_field.rb +5 -5
- data/lib/action_view/helpers/tags/translator.rb +14 -12
- data/lib/action_view/helpers/text_helper.rb +20 -19
- data/lib/action_view/helpers/translation_helper.rb +6 -6
- data/lib/action_view/helpers/url_helper.rb +42 -38
- data/lib/action_view/layouts.rb +51 -47
- data/lib/action_view/log_subscriber.rb +24 -9
- data/lib/action_view/lookup_context.rb +19 -25
- data/lib/action_view/path_set.rb +19 -19
- data/lib/action_view/railtie.rb +3 -3
- data/lib/action_view/record_identifier.rb +6 -6
- data/lib/action_view/renderer/abstract_renderer.rb +17 -17
- data/lib/action_view/renderer/partial_renderer.rb +188 -187
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +7 -1
- data/lib/action_view/renderer/streaming_template_renderer.rb +45 -47
- data/lib/action_view/renderer/template_renderer.rb +64 -66
- data/lib/action_view/rendering.rb +4 -5
- data/lib/action_view/routing_url_for.rb +9 -13
- data/lib/action_view/tasks/cache_digests.rake +7 -7
- data/lib/action_view/template.rb +26 -27
- data/lib/action_view/template/error.rb +5 -15
- data/lib/action_view/template/handlers.rb +4 -4
- data/lib/action_view/template/handlers/builder.rb +7 -7
- data/lib/action_view/template/handlers/erb.rb +9 -76
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +9 -0
- data/lib/action_view/template/handlers/erb/erubi.rb +81 -0
- data/lib/action_view/template/handlers/erb/erubis.rb +81 -0
- data/lib/action_view/template/html.rb +2 -4
- data/lib/action_view/template/resolver.rb +107 -90
- data/lib/action_view/template/text.rb +5 -8
- data/lib/action_view/template/types.rb +1 -1
- data/lib/action_view/test_case.rb +20 -21
- data/lib/action_view/testing/resolvers.rb +29 -30
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +20 -8
- data/lib/assets/compiled/rails-ujs.js +648 -0
- metadata +19 -14
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -13,7 +13,7 @@ The latest version of Action View can be installed with RubyGems:
|
|
13
13
|
|
14
14
|
Source code can be downloaded as part of the Rails project on GitHub
|
15
15
|
|
16
|
-
* https://github.com/rails/rails/tree/
|
16
|
+
* https://github.com/rails/rails/tree/master/actionview
|
17
17
|
|
18
18
|
|
19
19
|
== License
|
data/lib/action_view.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2004-
|
2
|
+
# Copyright (c) 2004-2017 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
|
@@ -21,9 +21,9 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
23
|
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
24
|
+
require "active_support"
|
25
|
+
require "active_support/rails"
|
26
|
+
require "action_view/version"
|
27
27
|
|
28
28
|
module ActionView
|
29
29
|
extend ActiveSupport::Autoload
|
@@ -89,7 +89,7 @@ module ActionView
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
require
|
92
|
+
require "active_support/core_ext/string/output_safety"
|
93
93
|
|
94
94
|
ActiveSupport.on_load(:i18n) do
|
95
95
|
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
|
data/lib/action_view/base.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
1
|
+
require "active_support/core_ext/module/attr_internal"
|
2
|
+
require "active_support/core_ext/module/attribute_accessors"
|
3
|
+
require "active_support/ordered_options"
|
4
|
+
require "action_view/log_subscriber"
|
5
|
+
require "action_view/helpers"
|
6
|
+
require "action_view/context"
|
7
|
+
require "action_view/template"
|
8
|
+
require "action_view/lookup_context"
|
9
9
|
|
10
10
|
module ActionView #:nodoc:
|
11
11
|
# = Action View Base
|
12
12
|
#
|
13
13
|
# Action View templates can be written in several ways.
|
14
|
-
# If the template file has a <tt>.erb</tt> extension, then it uses the
|
14
|
+
# If the template file has a <tt>.erb</tt> extension, then it uses the erubi[https://rubygems.org/gems/erubi]
|
15
15
|
# template system which can embed Ruby into an HTML document.
|
16
16
|
# If the template file has a <tt>.builder</tt> extension, then Jim Weirich's Builder::XmlMarkup library is used.
|
17
17
|
#
|
18
18
|
# == ERB
|
19
19
|
#
|
20
|
-
# You trigger ERB by using embeddings such as
|
20
|
+
# You trigger ERB by using embeddings such as <tt><% %></tt>, <tt><% -%></tt>, and <tt><%= %></tt>. The <tt><%= %></tt> tag set is used when you want output. Consider the
|
21
21
|
# following loop for names:
|
22
22
|
#
|
23
23
|
# <b>Names of all the people</b>
|
@@ -25,7 +25,7 @@ module ActionView #:nodoc:
|
|
25
25
|
# Name: <%= person.name %><br/>
|
26
26
|
# <% end %>
|
27
27
|
#
|
28
|
-
# The loop is setup in regular embedding tags
|
28
|
+
# The loop is setup in regular embedding tags <tt><% %></tt>, and the name is written using the output embedding tag <tt><%= %></tt>. Note that this
|
29
29
|
# is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong:
|
30
30
|
#
|
31
31
|
# <%# WRONG %>
|
@@ -33,9 +33,9 @@ module ActionView #:nodoc:
|
|
33
33
|
#
|
34
34
|
# If you absolutely must write from within a function use +concat+.
|
35
35
|
#
|
36
|
-
# When on a line that only contains whitespaces except for the tag,
|
37
|
-
# including the trailing newline.
|
38
|
-
# Note however that
|
36
|
+
# When on a line that only contains whitespaces except for the tag, <tt><% %></tt> suppresses leading and trailing whitespace,
|
37
|
+
# including the trailing newline. <tt><% %></tt> and <tt><%- -%></tt> are the same.
|
38
|
+
# Note however that <tt><%= %></tt> and <tt><%= -%></tt> are different: only the latter removes trailing whitespaces.
|
39
39
|
#
|
40
40
|
# === Using sub templates
|
41
41
|
#
|
@@ -110,7 +110,7 @@ module ActionView #:nodoc:
|
|
110
110
|
# <p>A product of Danish Design during the Winter of '79...</p>
|
111
111
|
# </div>
|
112
112
|
#
|
113
|
-
#
|
113
|
+
# Here is a full-length RSS example actually used on Basecamp:
|
114
114
|
#
|
115
115
|
# xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
|
116
116
|
# xml.channel do
|
@@ -141,7 +141,7 @@ module ActionView #:nodoc:
|
|
141
141
|
|
142
142
|
# Specify the proc used to decorate input tags that refer to attributes with errors.
|
143
143
|
cattr_accessor :field_error_proc
|
144
|
-
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
|
144
|
+
@@field_error_proc = Proc.new { |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
|
145
145
|
|
146
146
|
# How to complete the streaming when an exception occurs.
|
147
147
|
# This is our best guess: first try to close the attribute, then the tag.
|
@@ -169,7 +169,7 @@ module ActionView #:nodoc:
|
|
169
169
|
class_attribute :logger
|
170
170
|
|
171
171
|
class << self
|
172
|
-
delegate :erb_trim_mode=, :
|
172
|
+
delegate :erb_trim_mode=, to: "ActionView::Template::Handlers::ERB"
|
173
173
|
|
174
174
|
def cache_template_loading
|
175
175
|
ActionView::Resolver.caching?
|
@@ -187,8 +187,8 @@ module ActionView #:nodoc:
|
|
187
187
|
attr_accessor :view_renderer
|
188
188
|
attr_internal :config, :assigns
|
189
189
|
|
190
|
-
delegate :lookup_context, :
|
191
|
-
delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :
|
190
|
+
delegate :lookup_context, to: :view_renderer
|
191
|
+
delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, to: :lookup_context
|
192
192
|
|
193
193
|
def assign(new_assigns) # :nodoc:
|
194
194
|
@_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) }
|
data/lib/action_view/buffers.rb
CHANGED
data/lib/action_view/context.rb
CHANGED
@@ -28,7 +28,7 @@ module ActionView
|
|
28
28
|
# returns the correct buffer on +yield+. This is usually
|
29
29
|
# overwritten by helpers to add more behavior.
|
30
30
|
# :api: plugin
|
31
|
-
def _layout_for(name=nil)
|
31
|
+
def _layout_for(name = nil)
|
32
32
|
name ||= :layout
|
33
33
|
view_flow.get(name).html_safe
|
34
34
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "concurrent/map"
|
2
|
+
require "action_view/path_set"
|
3
3
|
|
4
4
|
module ActionView
|
5
5
|
class DependencyTracker # :nodoc:
|
@@ -105,7 +105,6 @@ module ActionView
|
|
105
105
|
attr_reader :name, :template
|
106
106
|
private :name, :template
|
107
107
|
|
108
|
-
|
109
108
|
private
|
110
109
|
def source
|
111
110
|
template.source
|
@@ -142,7 +141,7 @@ module ActionView
|
|
142
141
|
|
143
142
|
def add_static_dependency(dependencies, dependency)
|
144
143
|
if dependency
|
145
|
-
if dependency.include?(
|
144
|
+
if dependency.include?("/")
|
146
145
|
dependencies << dependency
|
147
146
|
else
|
148
147
|
dependencies << "#{directory}/#{dependency}"
|
@@ -163,7 +162,7 @@ module ActionView
|
|
163
162
|
def explicit_dependencies
|
164
163
|
dependencies = source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
|
165
164
|
|
166
|
-
wildcards, explicits = dependencies.partition { |dependency| dependency[-1] ==
|
165
|
+
wildcards, explicits = dependencies.partition { |dependency| dependency[-1] == "*" }
|
167
166
|
|
168
167
|
(explicits + resolve_directories(wildcards)).uniq
|
169
168
|
end
|
data/lib/action_view/digestor.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "concurrent/map"
|
2
|
+
require "action_view/dependency_tracker"
|
3
|
+
require "monitor"
|
4
4
|
|
5
5
|
module ActionView
|
6
6
|
class Digestor
|
7
|
-
@@digest_mutex
|
7
|
+
@@digest_mutex = Mutex.new
|
8
8
|
|
9
9
|
module PerExecutionDigestCacheExpiry
|
10
10
|
def self.before(target)
|
@@ -18,10 +18,9 @@ module ActionView
|
|
18
18
|
# * <tt>name</tt> - Template name
|
19
19
|
# * <tt>finder</tt> - An instance of <tt>ActionView::LookupContext</tt>
|
20
20
|
# * <tt>dependencies</tt> - An array of dependent views
|
21
|
-
# * <tt>partial</tt> - Specifies whether the template is a partial
|
22
21
|
def digest(name:, finder:, dependencies: [])
|
23
22
|
dependencies ||= []
|
24
|
-
cache_key = [ name, finder.rendered_format, dependencies ].flatten.compact.join(
|
23
|
+
cache_key = [ name, finder.rendered_format, dependencies ].flatten.compact.join(".")
|
25
24
|
|
26
25
|
# this is a correctly done double-checked locking idiom
|
27
26
|
# (Concurrent::Map's lookups have volatile semantics)
|
@@ -110,7 +109,7 @@ module ActionView
|
|
110
109
|
class Partial < Node; end
|
111
110
|
|
112
111
|
class Missing < Node
|
113
|
-
def digest(finder, _ = [])
|
112
|
+
def digest(finder, _ = []) "" end
|
114
113
|
end
|
115
114
|
|
116
115
|
class Injected < Node
|
data/lib/action_view/flows.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/core_ext/string/output_safety"
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
class OutputFlow #:nodoc:
|
5
5
|
attr_reader :content
|
6
6
|
|
7
7
|
def initialize
|
8
|
-
@content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
|
8
|
+
@content = Hash.new { |h, k| h[k] = ActiveSupport::SafeBuffer.new }
|
9
9
|
end
|
10
10
|
|
11
11
|
# Called by _layout_for to read stored values.
|
@@ -23,7 +23,6 @@ module ActionView
|
|
23
23
|
@content[key] << value
|
24
24
|
end
|
25
25
|
alias_method :append!, :append
|
26
|
-
|
27
26
|
end
|
28
27
|
|
29
28
|
class StreamingFlow < OutputFlow #:nodoc:
|
@@ -68,8 +67,8 @@ module ActionView
|
|
68
67
|
|
69
68
|
private
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
def inside_fiber?
|
71
|
+
Fiber.current.object_id != @root
|
72
|
+
end
|
74
73
|
end
|
75
74
|
end
|
data/lib/action_view/helpers.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
2
|
+
require "active_support/core_ext/enumerable"
|
3
3
|
|
4
4
|
module ActionView
|
5
5
|
# = Active Model Helpers
|
@@ -37,13 +37,13 @@ module ActionView
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def object_has_errors?
|
41
|
+
object.respond_to?(:errors) && object.errors.respond_to?(:[]) && error_message.present?
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
def tag_generate_errors?(options)
|
45
|
+
options["type"] != "hidden"
|
46
|
+
end
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "active_support/core_ext/array/extract_options"
|
2
|
+
require "active_support/core_ext/hash/keys"
|
3
|
+
require "action_view/helpers/asset_url_helper"
|
4
|
+
require "action_view/helpers/tag_helper"
|
5
5
|
|
6
6
|
module ActionView
|
7
7
|
# = Action View Asset Tag Helpers
|
@@ -35,18 +35,37 @@ module ActionView
|
|
35
35
|
# When the Asset Pipeline is enabled, you can pass the name of your manifest as
|
36
36
|
# source, and include other JavaScript or CoffeeScript files inside the manifest.
|
37
37
|
#
|
38
|
+
# ==== Options
|
39
|
+
#
|
40
|
+
# When the last parameter is a hash you can add HTML attributes using that
|
41
|
+
# parameter. The following options are supported:
|
42
|
+
#
|
43
|
+
# * <tt>:extname</tt> - Append an extension to the generated url unless the extension
|
44
|
+
# already exists. This only applies for relative urls.
|
45
|
+
# * <tt>:protocol</tt> - Sets the protocol of the generated url, this option only
|
46
|
+
# applies when a relative url and +host+ options are provided.
|
47
|
+
# * <tt>:host</tt> - When a relative url is provided the host is added to the
|
48
|
+
# that path.
|
49
|
+
# * <tt>:skip_pipeline</tt> - This option is used to bypass the asset pipeline
|
50
|
+
# when it is set to true.
|
51
|
+
#
|
52
|
+
# ==== Examples
|
53
|
+
#
|
38
54
|
# javascript_include_tag "xmlhr"
|
39
|
-
# # => <script src="/assets/xmlhr.js
|
55
|
+
# # => <script src="/assets/xmlhr.debug-1284139606.js"></script>
|
56
|
+
#
|
57
|
+
# javascript_include_tag "xmlhr", host: "localhost", protocol: "https"
|
58
|
+
# # => <script src="https://localhost/assets/xmlhr.debug-1284139606.js"></script>
|
40
59
|
#
|
41
60
|
# javascript_include_tag "template.jst", extname: false
|
42
|
-
# # => <script src="/assets/template.jst
|
61
|
+
# # => <script src="/assets/template.debug-1284139606.jst"></script>
|
43
62
|
#
|
44
63
|
# javascript_include_tag "xmlhr.js"
|
45
|
-
# # => <script src="/assets/xmlhr.js
|
64
|
+
# # => <script src="/assets/xmlhr.debug-1284139606.js"></script>
|
46
65
|
#
|
47
66
|
# javascript_include_tag "common.javascript", "/elsewhere/cools"
|
48
|
-
# # => <script src="/assets/common.javascript
|
49
|
-
# # <script src="/elsewhere/cools.js
|
67
|
+
# # => <script src="/assets/common.javascript.debug-1284139606.js"></script>
|
68
|
+
# # <script src="/elsewhere/cools.debug-1284139606.js"></script>
|
50
69
|
#
|
51
70
|
# javascript_include_tag "http://www.example.com/xmlhr"
|
52
71
|
# # => <script src="http://www.example.com/xmlhr"></script>
|
@@ -55,7 +74,7 @@ module ActionView
|
|
55
74
|
# # => <script src="http://www.example.com/xmlhr.js"></script>
|
56
75
|
def javascript_include_tag(*sources)
|
57
76
|
options = sources.extract_options!.stringify_keys
|
58
|
-
path_options = options.extract!(
|
77
|
+
path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
|
59
78
|
sources.uniq.map { |source|
|
60
79
|
tag_options = {
|
61
80
|
"src" => path_to_javascript(source, path_options)
|
@@ -91,8 +110,7 @@ module ActionView
|
|
91
110
|
# # <link href="/css/stylish.css" media="screen" rel="stylesheet" />
|
92
111
|
def stylesheet_link_tag(*sources)
|
93
112
|
options = sources.extract_options!.stringify_keys
|
94
|
-
path_options = options.extract!(
|
95
|
-
|
113
|
+
path_options = options.extract!("protocol", "host", "skip_pipeline").symbolize_keys
|
96
114
|
sources.uniq.map { |source|
|
97
115
|
tag_options = {
|
98
116
|
"rel" => "stylesheet",
|
@@ -138,7 +156,7 @@ module ActionView
|
|
138
156
|
"rel" => tag_options[:rel] || "alternate",
|
139
157
|
"type" => tag_options[:type] || Template::Types[type].to_s,
|
140
158
|
"title" => tag_options[:title] || type.to_s.upcase,
|
141
|
-
"href" => url_options.is_a?(Hash) ? url_for(url_options.merge(:
|
159
|
+
"href" => url_options.is_a?(Hash) ? url_for(url_options.merge(only_path: false)) : url_options
|
142
160
|
)
|
143
161
|
end
|
144
162
|
|
@@ -169,11 +187,11 @@ module ActionView
|
|
169
187
|
#
|
170
188
|
# favicon_link_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
|
171
189
|
# # => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" />
|
172
|
-
def favicon_link_tag(source=
|
173
|
-
tag(
|
174
|
-
:
|
175
|
-
:
|
176
|
-
:
|
190
|
+
def favicon_link_tag(source = "favicon.ico", options = {})
|
191
|
+
tag("link", {
|
192
|
+
rel: "shortcut icon",
|
193
|
+
type: "image/x-icon",
|
194
|
+
href: path_to_image(source, skip_pipeline: options.delete(:skip_pipeline))
|
177
195
|
}.merge!(options.symbolize_keys))
|
178
196
|
end
|
179
197
|
|
@@ -207,14 +225,14 @@ module ActionView
|
|
207
225
|
# # => <img alt="Icon" class="menu_icon" src="/icons/icon.gif" />
|
208
226
|
# image_tag("/icons/icon.gif", data: { title: 'Rails Application' })
|
209
227
|
# # => <img data-title="Rails Application" src="/icons/icon.gif" />
|
210
|
-
def image_tag(source, options={})
|
228
|
+
def image_tag(source, options = {})
|
211
229
|
options = options.symbolize_keys
|
212
230
|
check_for_image_tag_errors(options)
|
213
231
|
|
214
|
-
src = options[:src] = path_to_image(source)
|
232
|
+
src = options[:src] = path_to_image(source, skip_pipeline: options.delete(:skip_pipeline))
|
215
233
|
|
216
|
-
unless src
|
217
|
-
options[:alt] = options.fetch(:alt){ image_alt(src) }
|
234
|
+
unless src.start_with?("cid:") || src.start_with?("data:") || src.blank?
|
235
|
+
options[:alt] = options.fetch(:alt) { image_alt(src) }
|
218
236
|
end
|
219
237
|
|
220
238
|
options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
|
@@ -239,7 +257,7 @@ module ActionView
|
|
239
257
|
# image_alt('underscored_file_name.png')
|
240
258
|
# # => Underscored file name
|
241
259
|
def image_alt(src)
|
242
|
-
File.basename(src,
|
260
|
+
File.basename(src, ".*".freeze).sub(/-[[:xdigit:]]{32,64}\z/, "".freeze).tr("-_".freeze, " ".freeze).capitalize
|
243
261
|
end
|
244
262
|
|
245
263
|
# Returns an HTML video tag for the +sources+. If +sources+ is a string,
|
@@ -257,6 +275,8 @@ module ActionView
|
|
257
275
|
# * <tt>:size</tt> - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes
|
258
276
|
# width="30" and height="45", and "50" becomes width="50" and height="50".
|
259
277
|
# <tt>:size</tt> will be ignored if the value is not in the correct format.
|
278
|
+
# * <tt>:poster_skip_pipeline</tt> will bypass the asset pipeline when using
|
279
|
+
# the <tt>:poster</tt> option instead using an asset in the public folder.
|
260
280
|
#
|
261
281
|
# ==== Examples
|
262
282
|
#
|
@@ -264,10 +284,12 @@ module ActionView
|
|
264
284
|
# # => <video src="/videos/trailer"></video>
|
265
285
|
# video_tag("trailer.ogg")
|
266
286
|
# # => <video src="/videos/trailer.ogg"></video>
|
267
|
-
# video_tag("trailer.ogg", controls: true,
|
268
|
-
# # => <video
|
287
|
+
# video_tag("trailer.ogg", controls: true, preload: 'none')
|
288
|
+
# # => <video preload="none" controls="controls" src="/videos/trailer.ogg" ></video>
|
269
289
|
# video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png")
|
270
290
|
# # => <video src="/videos/trailer.m4v" width="16" height="10" poster="/assets/screenshot.png"></video>
|
291
|
+
# video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png", poster_skip_pipeline: true)
|
292
|
+
# # => <video src="/videos/trailer.m4v" width="16" height="10" poster="screenshot.png"></video>
|
271
293
|
# video_tag("/trailers/hd.avi", size: "16x16")
|
272
294
|
# # => <video src="/trailers/hd.avi" width="16" height="16"></video>
|
273
295
|
# video_tag("/trailers/hd.avi", size: "16")
|
@@ -281,9 +303,12 @@ module ActionView
|
|
281
303
|
# video_tag(["trailer.ogg", "trailer.flv"], size: "160x120")
|
282
304
|
# # => <video height="120" width="160"><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
|
283
305
|
def video_tag(*sources)
|
284
|
-
|
285
|
-
|
286
|
-
|
306
|
+
options = sources.extract_options!.symbolize_keys
|
307
|
+
public_poster_folder = options.delete(:poster_skip_pipeline)
|
308
|
+
sources << options
|
309
|
+
multiple_sources_tag_builder("video", sources) do |tag_options|
|
310
|
+
tag_options[:poster] = path_to_image(tag_options[:poster], skip_pipeline: public_poster_folder) if tag_options[:poster]
|
311
|
+
tag_options[:width], tag_options[:height] = extract_dimensions(tag_options.delete(:size)) if tag_options[:size]
|
287
312
|
end
|
288
313
|
end
|
289
314
|
|
@@ -300,31 +325,32 @@ module ActionView
|
|
300
325
|
# audio_tag("sound.wav", "sound.mid")
|
301
326
|
# # => <audio><source src="/audios/sound.wav" /><source src="/audios/sound.mid" /></audio>
|
302
327
|
def audio_tag(*sources)
|
303
|
-
|
328
|
+
multiple_sources_tag_builder("audio", sources)
|
304
329
|
end
|
305
330
|
|
306
331
|
private
|
307
|
-
def
|
308
|
-
options
|
332
|
+
def multiple_sources_tag_builder(type, sources)
|
333
|
+
options = sources.extract_options!.symbolize_keys
|
334
|
+
skip_pipeline = options.delete(:skip_pipeline)
|
309
335
|
sources.flatten!
|
310
336
|
|
311
337
|
yield options if block_given?
|
312
338
|
|
313
339
|
if sources.size > 1
|
314
340
|
content_tag(type, options) do
|
315
|
-
safe_join sources.map { |source| tag("source", :
|
341
|
+
safe_join sources.map { |source| tag("source", src: send("path_to_#{type}", source, skip_pipeline: skip_pipeline)) }
|
316
342
|
end
|
317
343
|
else
|
318
|
-
options[:src] = send("path_to_#{type}", sources.first)
|
344
|
+
options[:src] = send("path_to_#{type}", sources.first, skip_pipeline: skip_pipeline)
|
319
345
|
content_tag(type, nil, options)
|
320
346
|
end
|
321
347
|
end
|
322
348
|
|
323
349
|
def extract_dimensions(size)
|
324
350
|
size = size.to_s
|
325
|
-
if
|
326
|
-
size.split(
|
327
|
-
elsif
|
351
|
+
if /\A\d+x\d+\z/.match?(size)
|
352
|
+
size.split("x")
|
353
|
+
elsif /\A\d+\z/.match?(size)
|
328
354
|
[size, size]
|
329
355
|
end
|
330
356
|
end
|