padrino-assets 0.2.2 → 0.3.0

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.
@@ -1,379 +1,445 @@
1
- module Padrino
2
- module Assets
3
- module Helpers
4
- ##
5
- # Returns an HTML stylesheet link tag for the specified sources
6
- #
7
- # @overload include_stylesheet(sources, options = {})
8
- # @param [Array<String, Symbol>] sources
9
- # Sources
10
- # @param [Hash] options
11
- # HTML options
12
- # @option options [String] :media ('screen')
13
- # Specifies the type of device the linked document is optimized for
14
- #
15
- # @return [String]
16
- # Stylesheet link tag for +sources+ with specified +options+.
17
- #
18
- # @example
19
- # include_stylesheets :application, :theme
20
- # # => <link href="/assets/application.css" media="screen" rel="stylesheet" type="text/css">
21
- # # => <link href="/assets/theme.css" media="screen" rel="stylesheet" type="text/css">
22
- #
23
- # include_stylesheet :handheld, media: 'handheld'
24
- # # => <link href="/assets/handheld.css" media="handheld" rel="stylesheet" type="text/css">
25
- #
26
- # include_stylesheet 'http://www.example.com/style.css'
27
- # # => <link href="http://www.example.com/style.css" media="screen" rel="stylesheet" type="text/css">
28
- #
29
- # @since 0.1.0
30
- # @api public
31
- def include_stylesheet(*sources)
32
- options = sources.extract_options!.symbolize_keys
33
- options.reverse_merge!(media: 'screen', rel: 'stylesheet', type: 'text/css')
34
- sources.collect do |source|
35
- tag(:link, options.reverse_merge(href: asset_path(source, :css)))
36
- end.join("\n")
37
- end
38
- alias_method :include_stylesheets, :include_stylesheet
39
- alias_method :stylesheet_link_tag, :include_stylesheet
40
-
41
- ##
42
- # Returns an HTML script tag for the specified sources
43
- #
44
- # @overload include_javascript(sources, options)
45
- # @param [Array<String, Symbol>] sources
46
- # Sources
47
- # @param [Hash] options
48
- # HTML options
49
- #
50
- # @return [String]
51
- # Script tag for +sources+ with specified +options+.
52
- #
53
- # @example
54
- # include_javascripts :application, :jquery
55
- # # => <script type="text/javascript" src="/assets/application.js"></script>
56
- # # => <script type="text/javascript" src="/assets/jquery.js"></script>
57
- #
58
- # include_javascript 'http://www.example.com/application.js'
59
- # # => <script type="text/javascript" src="http://www.example.com/application.js"></script>
60
- #
61
- # @since 0.1.0
62
- # @api public
63
- def include_javascript(*sources)
64
- options = sources.extract_options!.symbolize_keys
65
- options.reverse_merge!(type: 'text/javascript')
66
- sources.collect do |source|
67
- content_tag(:script, nil, options.reverse_merge(src: asset_path(source, :js)))
68
- end.join("\n")
69
- end
70
- alias_method :include_javascripts, :include_javascript
71
- alias_method :javascript_include_tag, :include_javascript
72
-
73
- ##
74
- # Returns an HTML image element with given sources and options
75
- #
76
- # @overload image(sources, options={})
77
- # @param [Array<String>] sources
78
- # Sources
79
- # @param [Hash] options
80
- # HTML options
81
- # @option options [String] :id
82
- # Specifies the identifier of the image
83
- # @option options [String] :class
84
- # Specifies the class of the image
85
- # @option options [String] :size
86
- # Specifies the width and height of the image
87
- # @option options [Integer] :width
88
- # Specifies the width of the image
89
- # @option options [Integer] :height
90
- # Specifies the height of the image
91
- # @option options [String] :alt
92
- # Specifies an alternate text for an image
93
- #
94
- # @return [String]
95
- # Image tag with +url+ and specified +options+.
96
- #
97
- # @example
98
- # image 'example.png'
99
- # # => <img src="/assets/example.png" alt="Example">
100
- #
101
- # image 'example.png', size: '40x40'
102
- # # => <img src="/assets/example.png" width="40" height="40" alt="Example">
103
- #
104
- # image 'example.png', width: 40
105
- # # => <img src="/assets/example.png" width="40" alt="Example">
106
- #
107
- # image 'example.png', height: 40
108
- # # => <img src="/assets/example.png" height="40" alt="Example">
109
- #
110
- # image 'example.png', alt: 'My Little Pony'
111
- # # => <img src="/assets/example.png" alt="My Little Pony">
112
- #
113
- # image 'http://www.example.com/example.png'
114
- # # => <img src="http://www.example.com/example.png">
115
- #
116
- # images 'example.png', 'example.jpg'
117
- # # => <img src="/assets/example.png" alt="Example">
118
- # # => <img src="/assets/example.jpg" alt="Example">
119
- #
120
- # @since 0.1.0
121
- # @api public
122
- def image(*sources)
123
- options = sources.extract_options!.symbolize_keys
124
-
125
- if size = options.delete(:size)
126
- options[:width], options[:height] = size.split('x') if size =~ /^[0-9]+x[0-9]+$/
127
- end
128
-
129
- sources.collect do |source|
130
- tag(:img, options.reverse_merge(src: asset_path(source)))
131
- end.join("\n")
132
- end
133
- alias_method :images, :image
134
- alias_method :image_tag, :image
135
-
136
- ##
137
- # Return an HTML video element with given sources and options
138
- #
139
- # @overload video(sources, options={})
140
- # @param [Array<String>] sources
141
- # Sources
142
- # @param [Hash] options
143
- # HTML options
144
- # @option options [String] :id
145
- # Specifies the identifier of the video
146
- # @option options [String] :class
147
- # Specifies the class of the video
148
- # @option options [String] :size
149
- # Specifies the width and height of the video
150
- # @option options [Integer] :width
151
- # Specifies the width of the video
152
- # @option options [Integer] :height
153
- # Specifies the height of the video
154
- # @option options [String] :preload
155
- # Specifies the method the web browser should use to preload the video
156
- # @option options [String] :poster
157
- # Specifies an image to be shown while the video is downloading, or until the user hits the play button
158
- # @option options [Boolean] :controls
159
- # Should the video controls be shown if present
160
- # @option options [Boolean] :muted
161
- # Should the video automatically start off muted
162
- # @option options [Boolean] :autoplay
163
- # Should the video automatically play when it's ready
164
- # @option options [Boolean] :loop
165
- # Should the video automatically loop when it's done
166
- #
167
- # @return [String]
168
- # Video tag with +url+ and specified +options+
169
- #
170
- # @example
171
- # video 'example.webm'
172
- # # => <video src="/assets/example.webm" />
173
- #
174
- # video 'example.webm', controls: true, autoplay: true
175
- # # => <video src="/assets/example.webm" controls="controls" autoplay="autoplay" />
176
- #
177
- # video 'example.webm', loop: true
178
- # # => <video src="/assets/example.webm" loop="loop" />
179
- #
180
- # video 'example.webm', size: '40x40'
181
- # # => <video src="/assets/example.webm" width="40" height="40" />
182
- #
183
- # video 'example.webm', height: 40
184
- # # => <video src="/assets/example.webm" height="40" />
185
- #
186
- # video 'example.webm', width: 40
187
- # # => <video src="/assets/example.webm" width="40" />
188
- #
189
- # video 'http://www.example.com/example.webm'
190
- # # => <video src="http://www.example.com/example.webm" />
191
- #
192
- # videos 'example.webm', 'example.mov'
193
- # # => <video>
194
- # # => <source src="/assets/example.webm" />
195
- # # => <source src="/assets/example.mov" />
196
- # # => </video>
197
- #
198
- # @since 0.1.0
199
- # @api public
200
- def video(*sources)
201
- options = sources.extract_options!.symbolize_keys
202
- sources = sources.first if sources.size == 1
203
-
204
- if options[:poster]
205
- options[:poster] = asset_path(options[:poster])
206
- end
207
-
208
- if size = options.delete(:size)
209
- options[:width], options[:height] = size.split('x') if size =~ /^[0-9]+x[0-9]+$/
210
- end
211
-
212
- if sources.is_a?(Array)
213
- content_tag(:video, options) do
214
- sources.collect { |source| tag(:source, src: asset_path(source)) }.join("\n")
215
- end
216
- else
217
- tag(:video, options.reverse_merge(src: asset_path(sources)))
218
- end
219
- end
220
- alias_method :videos, :video
221
- alias_method :video_tag, :video
222
-
223
- ##
224
- # Returns an HTML audio element with given sources and options
225
- #
226
- # @overload audio(sources, options={})
227
- # @param [Array<String>] sources
228
- # Sources
229
- # @param [Hash] options
230
- # HTML options
231
- # @option options [String] :id
232
- # Specifies the identifier of the audio
233
- # @option options [String] :class
234
- # Specifies the class of the audio
235
- # @option options [String] :preload
236
- # Specifies the method the web browser should use to preload the audio
237
- # @option options [Boolean] :controls
238
- # Should the audio controls be shown if present
239
- # @option options [Boolean] :autoplay
240
- # Should the audio automatically play when it's ready
241
- # @option options [Boolean] :loop
242
- # Should the audio automatically loop when it's done
243
- #
244
- # @return [String]
245
- # Audio tag with +url+ and specified +options+
246
- #
247
- # @example
248
- # audio 'example.ogg'
249
- # # => <audio src="/assets/example.ogg" />
250
- #
251
- # audio 'example.ogg', controls: true, autoplay: true
252
- # # => <audio src="/assets/example.ogg" controls="controls" autoplay="autoplay" />
253
- #
254
- # audio 'example.ogg', loop: true
255
- # # => <audio src="/assets/example.ogg" loop="loop" />
256
- #
257
- # audio 'http://www.example.com/example.ogg'
258
- # # => <audio src="http://www.example.com/example.ogg" />
259
- #
260
- # audios 'example.ogg', 'example.mp4'
261
- # # => <audio>
262
- # # => <source src="/assets/example.ogg" />
263
- # # => <source src="/assets/example.mp4" />
264
- # # => </audio>
265
- #
266
- # @since 0.1.0
267
- # @api public
268
- def audio(*sources)
269
- options = sources.extract_options!.symbolize_keys
270
- sources = sources.first if sources.size == 1
271
-
272
- if sources.is_a?(Array)
273
- content_tag(:audio, options) do
274
- sources.collect { |source| tag(:source, src: asset_path(source)) }.join("\n")
275
- end
276
- else
277
- tag(:audio, options.reverse_merge(src: asset_path(sources)))
278
- end
279
- end
280
- alias_method :audios, :audio
281
- alias_method :audio_tag, :audio
282
-
283
- ##
284
- # Determines whether or not the provided source is a valid URI
285
- #
286
- # @param [String] source
287
- # URI Source
288
- #
289
- # @return [Boolean]
290
- #
291
- # @example
292
- # is_uri?('http://www.example.com')
293
- # # => true
294
- #
295
- # is_uri?('www.example.com')
296
- # # => false
297
- #
298
- # is_uri?('//example.com')
299
- # # => true
300
- #
301
- # is_uri?('/example/example.css')
302
- # # => true
303
- #
304
- # @since 0.1.0
305
- # @api public
306
- def is_uri?(source)
307
- !!(source =~ URI_REGEXP)
308
- end
309
-
310
- URI_REGEXP = %r[^[a-z]+://|^//?]
311
-
312
- ##
313
- # Returns a modified asset source based on the current application settings
314
- #
315
- # @overload asset_path(source, extension = nil)
316
- # @param [String] source
317
- # Source
318
- # @param [Symbol] extension (nil)
319
- # File extension
320
- #
321
- # @return [String]
322
- # Modified source based on application settings
323
- #
324
- # @example
325
- # asset_path('example.webm')
326
- # # => '/assets/example.webm'
327
- #
328
- # asset_path('stylesheet', :css)
329
- # # => '/assets/stylesheet.css'
330
- #
331
- # asset_path('http://www.example.com/stylesheet.css')
332
- # # => 'http://www.example.com/stylesheet.css'
333
- #
334
- # @since 0.1.0
335
- # @api public
336
- def asset_path(source, extension = nil)
337
- return source if is_uri?(source)
338
- source = source.to_s
339
- source = rewrite_extension(source, extension)
340
- source = rewrite_asset(source)
341
- source = rewrite_asset_path(source)
342
- source = rewrite_asset_host(source)
343
- source
344
- end
345
-
346
- private
347
-
348
- # @private
349
- def rewrite_extension(source, extension)
350
- if extension && File.extname(source).empty?
351
- "#{source}.#{extension}"
352
- else
353
- source
354
- end
355
- end
356
-
357
- # @private
358
- def rewrite_asset(source)
359
- if settings.index_assets? && asset = Assets.manifest.assets[source]
360
- source = asset
361
- end
362
- source
363
- end
364
-
365
- # @private
366
- def rewrite_asset_path(source)
367
- source = File.join(settings.assets_prefix, source)
368
- source = "/#{source}" unless source[0] == ?/
369
- source
370
- end
371
-
372
- # @private
373
- def rewrite_asset_host(source)
374
- host = settings.assets_host rescue settings.assets_host(source, request)
375
- host ? host + source : source
376
- end
377
- end
378
- end
379
- end
1
+ # encoding: utf-8
2
+ module Padrino
3
+ module Assets
4
+ module Helpers
5
+ URI_REGEXP = %r(^[a-z]+://|^/)
6
+ ###
7
+ # Returns an HTML stylesheet link tag for the specified sources
8
+ #
9
+ # @overload stylesheet(sources)
10
+ # @param [Array<String, Symbol>] sources
11
+ # Asset sources
12
+ #
13
+ # @overload stylesheet(sources, options)
14
+ # @param [Array<String, Symbol>] sources
15
+ # Asset sources
16
+ # @param [Hash] options
17
+ # The HTML options to include in this stylesheet
18
+ #
19
+ # @option options [String] :media ('screen')
20
+ # Specifies the type of device the linked document is optimized for
21
+ #
22
+ # @return [String]
23
+ # Generated HTML for sources with specified options
24
+ #
25
+ # @example
26
+ # stylesheet(:application)
27
+ # # => <link href="/assets/application.css" media="screen" rel="stylesheet" type="text/css">
28
+ #
29
+ # stylesheets(:application, :theme)
30
+ # # => <link href="/assets/application.css" media="screen" rel="stylesheet" type="text/css">
31
+ # # => <link href="/assets/theme.css" media="screen" rel="stylesheet" type="text/css">
32
+ #
33
+ # stylesheet(:handheld, media: 'handheld')
34
+ # # => <link href="/assets/handheld.css" media="handheld" rel="stylesheet" type="text/css">
35
+ #
36
+ # stylesheet('http://www.example.com/style.css')
37
+ # # => <link href="http://www.example.com/style.css" media="screen" rel="stylesheet" type="text/css">
38
+ #
39
+ # @since 0.1.0
40
+ # @api public
41
+ def stylesheet(*sources)
42
+ options = sources.extract_options!.symbolize_keys
43
+ options.reverse_merge!(media: 'screen', rel: 'stylesheet', type: 'text/css')
44
+ sources.collect do |source|
45
+ tag(:link, options.reverse_merge(href: asset_path(source, :css)))
46
+ end.join("\n")
47
+ end
48
+ alias_method :stylesheets, :stylesheet
49
+ alias_method :include_stylesheet, :stylesheet
50
+ alias_method :include_stylesheets, :stylesheet
51
+ alias_method :stylesheet_link_tag, :stylesheet
52
+
53
+ ###
54
+ # Returns an HTML script tag for the specified sources
55
+ #
56
+ # @overload javascript(sources)
57
+ # @param [Array<String, Symbol>] source
58
+ # Asset sources
59
+ #
60
+ # @overload javascript(sources, options)
61
+ # @param [Array<String, Symbol>] sources
62
+ # Asset sources
63
+ # @param [Hash] options
64
+ # The HTML options to include in this script tag
65
+ #
66
+ # @return [String]
67
+ # Generated HTML for sources with specified options
68
+ #
69
+ # @example
70
+ # javascript(:jquery)
71
+ # # => <script type="text/javascript" src="/assets/jquery.js"></script>
72
+ #
73
+ # javascripts(:jquery, :application)
74
+ # # => <script type="text/javascript" src="/assets/jquery.js"></script>
75
+ # # => <script type="text/javascript" src="/assets/application.js"></script>
76
+ #
77
+ # javascript('http://www.example.com/application.js')
78
+ # # => <script type="text/javascript" src="http://www.example.com/application.js"></script>
79
+ #
80
+ # @since 0.1.0
81
+ # @api public
82
+ def javascript(*sources)
83
+ options = sources.extract_options!.symbolize_keys
84
+ options.reverse_merge!(type: 'text/javascript')
85
+ sources.collect do |source|
86
+ content_tag(:script, nil, options.reverse_merge(src: asset_path(source, :js)))
87
+ end.join("\n")
88
+ end
89
+ alias_method :javascripts, :javascript
90
+ alias_method :include_javascript, :javascript
91
+ alias_method :include_javascripts, :javascript
92
+ alias_method :javascript_include_tag, :javascript
93
+
94
+ ###
95
+ # Returns an HTML image element for the specified sources
96
+ #
97
+ # @overload image(sources)
98
+ # @param [Array<String>] sources
99
+ # Asset sources
100
+ #
101
+ # @overload image(sources, options)
102
+ # @param [Array<String>] sources
103
+ # Asset ources
104
+ # @param [Hash] options
105
+ # The HTML options to include in this image
106
+ #
107
+ # @option options [String] :id
108
+ # Specifies a unique identifier for the image
109
+ # @option options [String] :class
110
+ # Specifies the class of the image
111
+ # @option options [String] :size
112
+ # Specifies the width and height of the image
113
+ # @option options [Integer] :width
114
+ # Specifies the width of the image
115
+ # @option options [Integer] :height
116
+ # Specifies the height of the image
117
+ # @option options [String] :alt
118
+ # Specifies an alternate text for an image
119
+ # @option options [String] :title
120
+ # Specifies the title of the image
121
+ # @option options [Boolean] :draggable
122
+ # Specifies whether or not the image is draggable (true, false, :auto)
123
+ # @option options [Boolean] :hidden
124
+ # Should the image be hidden from view
125
+ #
126
+ # @return [String]
127
+ # Generated HTML for sources with specified options
128
+ #
129
+ # @example
130
+ # image('example.png')
131
+ # # => <img src="/assets/example.png" alt="Example">
132
+ #
133
+ # image('example.png', size: '40x40')
134
+ # # => <img src="/assets/example.png" width="40" height="40" alt="Example">
135
+ #
136
+ # image('example.png', size: [40, 40])
137
+ # # => <img src="/assets/example.png" width="40" height="40" alt="Example">
138
+ #
139
+ # image('example.png', alt: 'My Little Pony')
140
+ # # => <img src="/assets/example.png" alt="My Little Pony">
141
+ #
142
+ # image('http://www.example.com/example.png')
143
+ # # => <img src="http://www.example.com/example.png" alt="Example">
144
+ #
145
+ # images('example.png', 'example.jpg')
146
+ # # => <img src="/assets/example.png" alt="Example">
147
+ # # => <img src="/assets/example.jpg" alt="Example">
148
+ #
149
+ # image('example.jpg', data: { nsfw: true, geo: [34.087, -118.407] })
150
+ # # => <img src="example.jpg" data-nsfw="true" data-geo="34.087 -118.407">
151
+ #
152
+ # @since 0.1.0
153
+ # @api public
154
+ def image(*sources)
155
+ options = sources.extract_options!.symbolize_keys
156
+
157
+ if size = options.delete(:size)
158
+ options[:width], options[:height] = size =~ /^\d+x\d+$/ ? size.split('x') : size
159
+ end
160
+
161
+ sources.collect do |source|
162
+ alternate_text = options.fetch(:alt, alternate_text(source))
163
+ tag(:img, options.reverse_merge(src: asset_path(source), alt: alternate_text))
164
+ end.join("\n")
165
+ end
166
+ alias_method :images, :image
167
+ alias_method :image_tag, :image
168
+
169
+ ###
170
+ # Returns an alternate text based off the specified source
171
+ #
172
+ # @param [String] source
173
+ # Asset Source
174
+ #
175
+ # @return [String]
176
+ # Humanized alternate text
177
+ #
178
+ # @example
179
+ # alternate_text('padrino.jpg')
180
+ # # => 'Padrino'
181
+ #
182
+ # alternate_text('my_pony.jpg')
183
+ # # => 'My pony'
184
+ #
185
+ # @since 0.3.0
186
+ # @api semipublic
187
+ def alternate_text(source)
188
+ File.basename(source, '.*').humanize
189
+ end
190
+
191
+ ###
192
+ # Returns an HTML video element for the specified sources
193
+ #
194
+ # @overload video(sources)
195
+ # @param [Array<String>] source
196
+ # Asset Sources
197
+ #
198
+ # @overload video(sources, options)
199
+ # @param [Array<String>] sources
200
+ # Asset Sources
201
+ # @param [Hash] options
202
+ # The HTML options to include in this video
203
+ #
204
+ # @option options [String] :id
205
+ # Specifies a unique identifier for the video
206
+ # @option options [String] :class
207
+ # Specifies the class of the video
208
+ # @option options [String] :size
209
+ # Specifies the width and height of the video
210
+ # @option options [Integer] :width
211
+ # Specifies the width of the video
212
+ # @option options [Integer] :height
213
+ # Specifies the height of the video
214
+ # @option options [String] :title
215
+ # Specifies the title of the video
216
+ # @option options [Boolean] :draggable
217
+ # Specifies whether or not the video is draggable (true, false, :auto)
218
+ # @option options [Symbol] :preload
219
+ # Specifies the method the web browser should use to preload the video (:auto, :metadata, :none)
220
+ # @option options [String] :poster
221
+ # Specifies an image to be shown while the video is downloading, or until the user hits the play button
222
+ # @option options [Boolean] :hidden
223
+ # Should the video be hidden from view
224
+ # @option options [Boolean] :controls
225
+ # Should the video controls be shown if present
226
+ # @option options [Boolean] :muted
227
+ # Should the video automatically start off muted
228
+ # @option options [Boolean] :autoplay
229
+ # Should the video automatically play when it's ready
230
+ # @option options [Boolean] :loop
231
+ # Should the video automatically loop when it's done
232
+ #
233
+ # @return [String]
234
+ # Generated HTML for sources with specified options
235
+ #
236
+ # @example
237
+ # video('example.webm')
238
+ # # => <video src="/assets/example.webm">
239
+ #
240
+ # video('example.webm', loop: true, autoplay: true)
241
+ # # => <video src="/assets/example.webm" loop="loop" autoplay="autoplay">
242
+ #
243
+ # video('example.webm', size: '40x40')
244
+ # # => <video src="/assets/example.webm" width="40" height="40">
245
+ #
246
+ # video('example.webm', size: [40, 40])
247
+ # # => <video src="/assets/example.webm" width="40" height="40">
248
+ #
249
+ # video('http://www.example.com/example.webm')
250
+ # # => <video src="http://www.example.com/example.webm">
251
+ #
252
+ # videos('example.webm', 'example.mov')
253
+ # # => <video>
254
+ # # => <source src="/assets/example.webm">
255
+ # # => <source src="/assets/example.mov">
256
+ # # => </video>
257
+ #
258
+ # video('example.webm', poster: 'preload.jpg')
259
+ # # => <video src="/assets/example.webm" poster="/assets/preload.jpg">
260
+ #
261
+ # @since 0.1.0
262
+ # @api public
263
+ def video(*sources)
264
+ options = sources.extract_options!.symbolize_keys
265
+ sources = sources.shift if sources.size == 1
266
+
267
+ if options[:poster]
268
+ options[:poster] = asset_path(options[:poster])
269
+ end
270
+
271
+ if size = options.delete(:size)
272
+ options[:width], options[:height] = size =~ /^\d+x\d+$/ ? size.split('x') : size
273
+ end
274
+
275
+ if sources.is_a?(Array)
276
+ content_tag(:video, options) do
277
+ sources.collect { |source| tag(:source, src: asset_path(source)) }.join("\n")
278
+ end
279
+ else
280
+ tag(:video, options.reverse_merge(src: asset_path(sources)))
281
+ end
282
+ end
283
+ alias_method :videos, :video
284
+ alias_method :video_tag, :video
285
+
286
+ ###
287
+ # Returns an HTML audio element for the specified sources
288
+ #
289
+ # @overload audio(sources)
290
+ # @param [Array<String>] sources
291
+ # Asset sources
292
+ #
293
+ # @overload audio(sources, options)
294
+ # @param [Array<String>] sources
295
+ # Asset sources
296
+ # @param [Hash] options
297
+ # The HTML options to include in this audio
298
+ #
299
+ # @option options [String] :id
300
+ # Specifies a unique identifier for the audio
301
+ # @option options [String] :class
302
+ # Specifies the class of the audio
303
+ # @option options [Boolean] :draggable
304
+ # Specifies whether or not the audio is draggable (true, false, :auto)
305
+ # @option options [Symbol] :preload
306
+ # Specifies the method the web browser should use to preload the audio (:auto, :metadata, :none)
307
+ # @option options [Boolean] :hidden
308
+ # Should the audio be hidden from view
309
+ # @option options [Boolean] :controls
310
+ # Should the audio controls be shown if present
311
+ # @option options [Boolean] :autoplay
312
+ # Should the audio automatically play when it's ready
313
+ # @option options [Boolean] :loop
314
+ # Should the audio automatically loop when it's done
315
+ #
316
+ # @return [String]
317
+ # Generated HTML for sources with specified options
318
+ #
319
+ # @example
320
+ # audio('example.ogg')
321
+ # # => <audio src="/assets/example.ogg">
322
+ #
323
+ # audio('example.ogg', loop: true, autoplay: true)
324
+ # # => <audio src="/assets/example.ogg" loop="loop" autoplay="autoplay">
325
+ #
326
+ # audio('http://www.example.com/example.ogg')
327
+ # # => <audio src="http://www.example.com/example.ogg">
328
+ #
329
+ # audios('example.ogg', 'example.mp4')
330
+ # # => <audio>
331
+ # # => <source src="/assets/example.ogg">
332
+ # # => <source src="/assets/example.mp4">
333
+ # # => </audio>
334
+ #
335
+ # @since 0.1.0
336
+ # @api public
337
+ def audio(*sources)
338
+ options = sources.extract_options!.symbolize_keys
339
+ sources = sources.shift if sources.size == 1
340
+
341
+ if sources.is_a?(Array)
342
+ content_tag(:audio, options) do
343
+ sources.collect { |source| tag(:source, src: asset_path(source)) }.join("\n")
344
+ end
345
+ else
346
+ tag(:audio, options.reverse_merge(src: asset_path(sources)))
347
+ end
348
+ end
349
+ alias_method :audios, :audio
350
+ alias_method :audio_tag, :audio
351
+
352
+ ###
353
+ # Returns whether or not the provided source is a valid URI
354
+ #
355
+ # @param [String] source
356
+ # URI source
357
+ #
358
+ # @return [Boolean]
359
+ # *true* if it is a valid, *false* otherwise
360
+ #
361
+ # @example
362
+ # is_uri?('http://www.example.com')
363
+ # # => true
364
+ #
365
+ # is_uri?('www.example.com')
366
+ # # => false
367
+ #
368
+ # is_uri?('//example.com')
369
+ # # => true
370
+ #
371
+ # is_uri?('/example/example.css')
372
+ # # => true
373
+ #
374
+ # is_uri?('example.css')
375
+ # # => false
376
+ #
377
+ # @since 0.1.0
378
+ # @api public
379
+ def is_uri?(source)
380
+ !!(source =~ URI_REGEXP)
381
+ end
382
+
383
+ ###
384
+ # Returns a modified asset source based on the current application settings
385
+ #
386
+ # @param [String] source
387
+ # Asset source
388
+ # @param [Symbol] extension
389
+ # Asset file extension
390
+ #
391
+ # @return [String]
392
+ # Modified source based on application settings
393
+ #
394
+ # @example
395
+ # asset_path('example.webm')
396
+ # # => '/assets/example.webm'
397
+ #
398
+ # asset_path('stylesheet', :css)
399
+ # # => '/assets/stylesheet.css'
400
+ #
401
+ # asset_path('http://www.example.com/stylesheet.css')
402
+ # # => 'http://www.example.com/stylesheet.css'
403
+ #
404
+ # @since 0.1.0
405
+ # @api public
406
+ def asset_path(source, extension = nil)
407
+ return source if is_uri?(source)
408
+ source = source.to_s
409
+ source = rewrite_extension(source, extension)
410
+ source = rewrite_asset(source)
411
+ source = rewrite_asset_path(source)
412
+ source = rewrite_asset_host(source)
413
+ source
414
+ end
415
+
416
+ private
417
+
418
+ def rewrite_extension(source, extension)
419
+ if extension && File.extname(source).empty?
420
+ "#{source}.#{extension}"
421
+ else
422
+ source
423
+ end
424
+ end
425
+
426
+ def rewrite_asset(source)
427
+ if settings.index_assets && asset = Assets.manifest.assets[source]
428
+ source = asset
429
+ end
430
+ source
431
+ end
432
+
433
+ def rewrite_asset_path(source)
434
+ source = File.join(settings.assets_prefix, source)
435
+ source = "/#{source}" unless source[0] == ?/
436
+ source
437
+ end
438
+
439
+ def rewrite_asset_host(source)
440
+ host = settings.assets_host rescue settings.assets_host(source, request)
441
+ host ? host + source : source
442
+ end
443
+ end # Helpers
444
+ end # Assets
445
+ end # Padrino