padrino-assets 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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