lotus-assets 0.0.0 → 0.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/{LICENSE.txt → LICENSE.md} +1 -1
- data/README.md +429 -7
- data/bin/lotus-assets +22 -0
- data/lib/lotus/assets.rb +153 -2
- data/lib/lotus/assets/bundler.rb +173 -0
- data/lib/lotus/assets/cache.rb +58 -0
- data/lib/lotus/assets/compiler.rb +212 -0
- data/lib/lotus/assets/compressors/abstract.rb +119 -0
- data/lib/lotus/assets/compressors/builtin_javascript.rb +36 -0
- data/lib/lotus/assets/compressors/builtin_stylesheet.rb +57 -0
- data/lib/lotus/assets/compressors/closure_javascript.rb +25 -0
- data/lib/lotus/assets/compressors/javascript.rb +77 -0
- data/lib/lotus/assets/compressors/jsmin.rb +283 -0
- data/lib/lotus/assets/compressors/null_compressor.rb +19 -0
- data/lib/lotus/assets/compressors/sass_stylesheet.rb +38 -0
- data/lib/lotus/assets/compressors/stylesheet.rb +77 -0
- data/lib/lotus/assets/compressors/uglifier_javascript.rb +25 -0
- data/lib/lotus/assets/compressors/yui_javascript.rb +25 -0
- data/lib/lotus/assets/compressors/yui_stylesheet.rb +25 -0
- data/lib/lotus/assets/config/global_sources.rb +50 -0
- data/lib/lotus/assets/config/manifest.rb +112 -0
- data/lib/lotus/assets/config/sources.rb +77 -0
- data/lib/lotus/assets/configuration.rb +539 -0
- data/lib/lotus/assets/helpers.rb +733 -0
- data/lib/lotus/assets/precompiler.rb +67 -0
- data/lib/lotus/assets/version.rb +4 -1
- data/lotus-assets.gemspec +25 -11
- metadata +192 -15
- data/.gitignore +0 -22
- data/Gemfile +0 -4
- data/Rakefile +0 -2
@@ -0,0 +1,733 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'set'
|
3
|
+
require 'thread'
|
4
|
+
require 'lotus/helpers/html_helper'
|
5
|
+
require 'lotus/utils/escape'
|
6
|
+
|
7
|
+
module Lotus
|
8
|
+
module Assets
|
9
|
+
# HTML assets helpers
|
10
|
+
#
|
11
|
+
# Include this helper in a view
|
12
|
+
#
|
13
|
+
# @since 0.1.0
|
14
|
+
#
|
15
|
+
# @see http://www.rubydoc.info/gems/lotus-helpers/Lotus/Helpers/HtmlHelper
|
16
|
+
module Helpers
|
17
|
+
# @since 0.1.0
|
18
|
+
# @api private
|
19
|
+
NEW_LINE_SEPARATOR = "\n".freeze
|
20
|
+
|
21
|
+
# @since 0.1.0
|
22
|
+
# @api private
|
23
|
+
WILDCARD_EXT = '.*'.freeze
|
24
|
+
|
25
|
+
# @since 0.1.0
|
26
|
+
# @api private
|
27
|
+
JAVASCRIPT_EXT = '.js'.freeze
|
28
|
+
|
29
|
+
# @since 0.1.0
|
30
|
+
# @api private
|
31
|
+
STYLESHEET_EXT = '.css'.freeze
|
32
|
+
|
33
|
+
# @since 0.1.0
|
34
|
+
# @api private
|
35
|
+
JAVASCRIPT_MIME_TYPE = 'text/javascript'.freeze
|
36
|
+
|
37
|
+
# @since 0.1.0
|
38
|
+
# @api private
|
39
|
+
STYLESHEET_MIME_TYPE = 'text/css'.freeze
|
40
|
+
|
41
|
+
# @since 0.1.0
|
42
|
+
# @api private
|
43
|
+
FAVICON_MIME_TYPE = 'image/x-icon'.freeze
|
44
|
+
|
45
|
+
# @since 0.1.0
|
46
|
+
# @api private
|
47
|
+
STYLESHEET_REL = 'stylesheet'.freeze
|
48
|
+
|
49
|
+
# @since 0.1.0
|
50
|
+
# @api private
|
51
|
+
FAVICON_REL = 'shortcut icon'.freeze
|
52
|
+
|
53
|
+
# @since 0.1.0
|
54
|
+
# @api private
|
55
|
+
DEFAULT_FAVICON = 'favicon.ico'.freeze
|
56
|
+
|
57
|
+
include Lotus::Helpers::HtmlHelper
|
58
|
+
|
59
|
+
# Inject helpers into the given class
|
60
|
+
#
|
61
|
+
# @since 0.1.0
|
62
|
+
# @api private
|
63
|
+
def self.included(base)
|
64
|
+
conf = ::Lotus::Assets::Configuration.for(base)
|
65
|
+
base.class_eval do
|
66
|
+
include Utils::ClassAttribute
|
67
|
+
|
68
|
+
class_attribute :assets_configuration
|
69
|
+
self.assets_configuration = conf
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Generate <tt>script</tt> tag for given source(s)
|
74
|
+
#
|
75
|
+
# It accepts one or more strings representing the name of the asset, if it
|
76
|
+
# comes from the application or third party gems. It also accepts strings
|
77
|
+
# representing absolute URLs in case of public CDN (eg. jQuery CDN).
|
78
|
+
#
|
79
|
+
# If the "digest mode" is on, <tt>src</tt> is the digest version of the
|
80
|
+
# relative URL.
|
81
|
+
#
|
82
|
+
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
83
|
+
# application CDN.
|
84
|
+
#
|
85
|
+
# @param sources [Array<String>] one or more assets by name or absolute URL
|
86
|
+
#
|
87
|
+
# @return [Lotus::Utils::Escape::SafeString] the markup
|
88
|
+
#
|
89
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
90
|
+
# at least one of the given sources is missing from the manifest
|
91
|
+
#
|
92
|
+
# @since 0.1.0
|
93
|
+
#
|
94
|
+
# @see Lotus::Assets::Configuration#digest
|
95
|
+
# @see Lotus::Assets::Configuration#cdn
|
96
|
+
# @see Lotus::Assets::Helpers#asset_path
|
97
|
+
#
|
98
|
+
# @example Single Asset
|
99
|
+
#
|
100
|
+
# <%= javascript 'application' %>
|
101
|
+
#
|
102
|
+
# # <script src="/assets/application.js" type="text/javascript"></script>
|
103
|
+
#
|
104
|
+
# @example Multiple Assets
|
105
|
+
#
|
106
|
+
# <%= javascript 'application', 'dashboard' %>
|
107
|
+
#
|
108
|
+
# # <script src="/assets/application.js" type="text/javascript"></script>
|
109
|
+
# # <script src="/assets/dashboard.js" type="text/javascript"></script>
|
110
|
+
#
|
111
|
+
# @example Absolute URL
|
112
|
+
#
|
113
|
+
# <%= javascript 'https://code.jquery.com/jquery-2.1.4.min.js' %>
|
114
|
+
#
|
115
|
+
# # <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
|
116
|
+
#
|
117
|
+
# @example Digest Mode
|
118
|
+
#
|
119
|
+
# <%= javascript 'application' %>
|
120
|
+
#
|
121
|
+
# # <script src="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js" type="text/javascript"></script>
|
122
|
+
#
|
123
|
+
# @example CDN Mode
|
124
|
+
#
|
125
|
+
# <%= javascript 'application' %>
|
126
|
+
#
|
127
|
+
# # <script src="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js" type="text/javascript"></script>
|
128
|
+
def javascript(*sources)
|
129
|
+
_safe_tags(*sources) do |source|
|
130
|
+
html.script(src: _typed_asset_path(source, JAVASCRIPT_EXT), type: JAVASCRIPT_MIME_TYPE).to_s
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Generate <tt>link</tt> tag for given source(s)
|
135
|
+
#
|
136
|
+
# It accepts one or more strings representing the name of the asset, if it
|
137
|
+
# comes from the application or third party gems. It also accepts strings
|
138
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
139
|
+
#
|
140
|
+
# If the "digest mode" is on, <tt>href</tt> is the digest version of the
|
141
|
+
# relative URL.
|
142
|
+
#
|
143
|
+
# If the "CDN mode" is on, the <tt>href</tt> is an absolute URL of the
|
144
|
+
# application CDN.
|
145
|
+
#
|
146
|
+
# @param sources [Array<String>] one or more assets by name or absolute URL
|
147
|
+
#
|
148
|
+
# @return [Lotus::Utils::Escape::SafeString] the markup
|
149
|
+
#
|
150
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
151
|
+
# at least one of the given sources is missing from the manifest
|
152
|
+
#
|
153
|
+
# @since 0.1.0
|
154
|
+
#
|
155
|
+
# @see Lotus::Assets::Configuration#digest
|
156
|
+
# @see Lotus::Assets::Configuration#cdn
|
157
|
+
# @see Lotus::Assets::Helpers#asset_path
|
158
|
+
#
|
159
|
+
# @example Single Asset
|
160
|
+
#
|
161
|
+
# <%= stylesheet 'application' %>
|
162
|
+
#
|
163
|
+
# # <link href="/assets/application.css" type="text/css" rel="stylesheet">
|
164
|
+
#
|
165
|
+
# @example Multiple Assets
|
166
|
+
#
|
167
|
+
# <%= stylesheet 'application', 'dashboard' %>
|
168
|
+
#
|
169
|
+
# # <link href="/assets/application.css" type="text/css" rel="stylesheet">
|
170
|
+
# # <link href="/assets/dashboard.css" type="text/css" rel="stylesheet">
|
171
|
+
#
|
172
|
+
# @example Absolute URL
|
173
|
+
#
|
174
|
+
# <%= stylesheet 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' %>
|
175
|
+
#
|
176
|
+
# # <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css" rel="stylesheet">
|
177
|
+
#
|
178
|
+
# @example Digest Mode
|
179
|
+
#
|
180
|
+
# <%= stylesheet 'application' %>
|
181
|
+
#
|
182
|
+
# # <link href="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css" type="text/css" rel="stylesheet">
|
183
|
+
#
|
184
|
+
# @example CDN Mode
|
185
|
+
#
|
186
|
+
# <%= stylesheet 'application' %>
|
187
|
+
#
|
188
|
+
# # <link href="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css" type="text/css" rel="stylesheet">
|
189
|
+
def stylesheet(*sources)
|
190
|
+
_safe_tags(*sources) do |source|
|
191
|
+
html.link(href: _typed_asset_path(source, STYLESHEET_EXT), type: STYLESHEET_MIME_TYPE, rel: STYLESHEET_REL).to_s
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Generate <tt>img</tt> tag for given source
|
196
|
+
#
|
197
|
+
# It accepts one string representing the name of the asset, if it comes
|
198
|
+
# from the application or third party gems. It also accepts string
|
199
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
200
|
+
#
|
201
|
+
# <tt>alt</tt> Attribute is auto generated from <tt>src</tt>.
|
202
|
+
# You can specify a different value, by passing the <tt>:src</tt> option.
|
203
|
+
#
|
204
|
+
# If the "digest mode" is on, <tt>src</tt> is the digest version of the
|
205
|
+
# relative URL.
|
206
|
+
#
|
207
|
+
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
208
|
+
# application CDN.
|
209
|
+
#
|
210
|
+
# @param source [String] asset name or absolute URL
|
211
|
+
#
|
212
|
+
# @return [Lotus::Utils::Helpers::HtmlBuilder] the builder
|
213
|
+
#
|
214
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
215
|
+
# the image is missing from the manifest
|
216
|
+
#
|
217
|
+
# @since 0.1.0
|
218
|
+
#
|
219
|
+
# @see Lotus::Assets::Configuration#digest
|
220
|
+
# @see Lotus::Assets::Configuration#cdn
|
221
|
+
# @see Lotus::Assets::Helpers#asset_path
|
222
|
+
#
|
223
|
+
# @example Basic Usage
|
224
|
+
#
|
225
|
+
# <%= image 'logo.png' %>
|
226
|
+
#
|
227
|
+
# # <img src="/assets/logo.png" alt="Logo">
|
228
|
+
#
|
229
|
+
# @example Custom alt Attribute
|
230
|
+
#
|
231
|
+
# <%= image 'logo.png', alt: 'Application Logo' %>
|
232
|
+
#
|
233
|
+
# # <img src="/assets/logo.png" alt="Application Logo">
|
234
|
+
#
|
235
|
+
# @example Custom HTML Attributes
|
236
|
+
#
|
237
|
+
# <%= image 'logo.png', id: 'logo', class: 'image' %>
|
238
|
+
#
|
239
|
+
# # <img src="/assets/logo.png" alt="Logo" id="logo" class="image">
|
240
|
+
#
|
241
|
+
# @example Absolute URL
|
242
|
+
#
|
243
|
+
# <%= image 'https://example-cdn.com/images/logo.png' %>
|
244
|
+
#
|
245
|
+
# # <img src="https://example-cdn.com/images/logo.png" alt="Logo">
|
246
|
+
#
|
247
|
+
# @example Digest Mode
|
248
|
+
#
|
249
|
+
# <%= image 'logo.png' %>
|
250
|
+
#
|
251
|
+
# # <img src="/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
|
252
|
+
#
|
253
|
+
# @example CDN Mode
|
254
|
+
#
|
255
|
+
# <%= image 'logo.png' %>
|
256
|
+
#
|
257
|
+
# # <img src="https://assets.bookshelf.org/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
|
258
|
+
def image(source, options = {})
|
259
|
+
options[:src] = asset_path(source)
|
260
|
+
options[:alt] ||= Utils::String.new(::File.basename(source, WILDCARD_EXT)).titleize
|
261
|
+
|
262
|
+
html.img(options)
|
263
|
+
end
|
264
|
+
|
265
|
+
# Generate <tt>link</tt> tag application favicon.
|
266
|
+
#
|
267
|
+
# If no argument is given, it assumes <tt>favico.ico</tt> from the application.
|
268
|
+
#
|
269
|
+
# It accepts one string representing the name of the asset.
|
270
|
+
#
|
271
|
+
# If the "digest mode" is on, <tt>href</tt> is the digest version of the
|
272
|
+
# relative URL.
|
273
|
+
#
|
274
|
+
# If the "CDN mode" is on, the <tt>href</tt> is an absolute URL of the
|
275
|
+
# application CDN.
|
276
|
+
#
|
277
|
+
# @param source [String] asset name
|
278
|
+
#
|
279
|
+
# @return [Lotus::Utils::Helpers::HtmlBuilder] the builder
|
280
|
+
#
|
281
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
282
|
+
# the favicon is missing from the manifest
|
283
|
+
#
|
284
|
+
# @since 0.1.0
|
285
|
+
#
|
286
|
+
# @see Lotus::Assets::Configuration#digest
|
287
|
+
# @see Lotus::Assets::Configuration#cdn
|
288
|
+
# @see Lotus::Assets::Helpers#asset_path
|
289
|
+
#
|
290
|
+
# @example Basic Usage
|
291
|
+
#
|
292
|
+
# <%= favicon %>
|
293
|
+
#
|
294
|
+
# # <link href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
295
|
+
#
|
296
|
+
# @example Custom Path
|
297
|
+
#
|
298
|
+
# <%= favicon 'fav.ico' %>
|
299
|
+
#
|
300
|
+
# # <link href="/assets/fav.ico" rel="shortcut icon" type="image/x-icon">
|
301
|
+
#
|
302
|
+
# @example Custom HTML Attributes
|
303
|
+
#
|
304
|
+
# <%= favicon id: 'fav' %>
|
305
|
+
#
|
306
|
+
# # <link id: "fav" href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
307
|
+
#
|
308
|
+
# @example Digest Mode
|
309
|
+
#
|
310
|
+
# <%= favicon %>
|
311
|
+
#
|
312
|
+
# # <link href="/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico" rel="shortcut icon" type="image/x-icon">
|
313
|
+
#
|
314
|
+
# @example CDN Mode
|
315
|
+
#
|
316
|
+
# <%= favicon %>
|
317
|
+
#
|
318
|
+
# # <link href="https://assets.bookshelf.org/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico" rel="shortcut icon" type="image/x-icon">
|
319
|
+
def favicon(source = DEFAULT_FAVICON, options = {})
|
320
|
+
options[:href] = asset_path(source)
|
321
|
+
options[:rel] ||= FAVICON_REL
|
322
|
+
options[:type] ||= FAVICON_MIME_TYPE
|
323
|
+
|
324
|
+
html.link(options)
|
325
|
+
end
|
326
|
+
|
327
|
+
# Generate <tt>video</tt> tag for given source
|
328
|
+
#
|
329
|
+
# It accepts one string representing the name of the asset, if it comes
|
330
|
+
# from the application or third party gems. It also accepts string
|
331
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
332
|
+
#
|
333
|
+
# Alternatively, it accepts a block that allows to specify one or more
|
334
|
+
# sources via the <tt>source</tt> tag.
|
335
|
+
#
|
336
|
+
# If the "digest mode" is on, <tt>src</tt> is the digest version of the
|
337
|
+
# relative URL.
|
338
|
+
#
|
339
|
+
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
340
|
+
# application CDN.
|
341
|
+
#
|
342
|
+
# @param source [String] asset name or absolute URL
|
343
|
+
#
|
344
|
+
# @return [Lotus::Utils::Helpers::HtmlBuilder] the builder
|
345
|
+
#
|
346
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
347
|
+
# the image is missing from the manifest
|
348
|
+
#
|
349
|
+
# @raise [ArgumentError] if source isn't specified both as argument or
|
350
|
+
# tag inside the given block
|
351
|
+
#
|
352
|
+
# @since 0.1.0
|
353
|
+
#
|
354
|
+
# @see Lotus::Assets::Configuration#digest
|
355
|
+
# @see Lotus::Assets::Configuration#cdn
|
356
|
+
# @see Lotus::Assets::Helpers#asset_path
|
357
|
+
#
|
358
|
+
# @example Basic Usage
|
359
|
+
#
|
360
|
+
# <%= video 'movie.mp4' %>
|
361
|
+
#
|
362
|
+
# # <video src="/assets/movie.mp4"></video>
|
363
|
+
#
|
364
|
+
# @example Absolute URL
|
365
|
+
#
|
366
|
+
# <%= video 'https://example-cdn.com/assets/movie.mp4' %>
|
367
|
+
#
|
368
|
+
# # <video src="https://example-cdn.com/assets/movie.mp4"></video>
|
369
|
+
#
|
370
|
+
# @example Custom HTML Attributes
|
371
|
+
#
|
372
|
+
# <%= video('movie.mp4', autoplay: true, controls: true) %>
|
373
|
+
#
|
374
|
+
# # <video src="/assets/movie.mp4" autoplay="autoplay" controls="controls"></video>
|
375
|
+
#
|
376
|
+
# @example Fallback Content
|
377
|
+
#
|
378
|
+
# <%=
|
379
|
+
# video('movie.mp4') do
|
380
|
+
# "Your browser does not support the video tag"
|
381
|
+
# end
|
382
|
+
# %>
|
383
|
+
#
|
384
|
+
# # <video src="/assets/movie.mp4">
|
385
|
+
# # Your browser does not support the video tag
|
386
|
+
# # </video>
|
387
|
+
#
|
388
|
+
# @example Tracks
|
389
|
+
#
|
390
|
+
# <%=
|
391
|
+
# video('movie.mp4') do
|
392
|
+
# track(kind: 'captions', src: asset_path('movie.en.vtt'),
|
393
|
+
# srclang: 'en', label: 'English')
|
394
|
+
# end
|
395
|
+
# %>
|
396
|
+
#
|
397
|
+
# # <video src="/assets/movie.mp4">
|
398
|
+
# # <track kind="captions" src="/assets/movie.en.vtt" srclang="en" label="English">
|
399
|
+
# # </video>
|
400
|
+
#
|
401
|
+
# @example Sources
|
402
|
+
#
|
403
|
+
# <%=
|
404
|
+
# video do
|
405
|
+
# text "Your browser does not support the video tag"
|
406
|
+
# source(src: asset_path('movie.mp4'), type: 'video/mp4')
|
407
|
+
# source(src: asset_path('movie.ogg'), type: 'video/ogg')
|
408
|
+
# end
|
409
|
+
# %>
|
410
|
+
#
|
411
|
+
# # <video>
|
412
|
+
# # Your browser does not support the video tag
|
413
|
+
# # <source src="/assets/movie.mp4" type="video/mp4">
|
414
|
+
# # <source src="/assets/movie.ogg" type="video/ogg">
|
415
|
+
# # </video>
|
416
|
+
#
|
417
|
+
# @example Without Any Argument
|
418
|
+
#
|
419
|
+
# <%= video %>
|
420
|
+
#
|
421
|
+
# # ArgumentError
|
422
|
+
#
|
423
|
+
# @example Without src And Without Block
|
424
|
+
#
|
425
|
+
# <%= video(content: true) %>
|
426
|
+
#
|
427
|
+
# # ArgumentError
|
428
|
+
#
|
429
|
+
# @example Digest Mode
|
430
|
+
#
|
431
|
+
# <%= video 'movie.mp4' %>
|
432
|
+
#
|
433
|
+
# # <video src="/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
|
434
|
+
#
|
435
|
+
# @example CDN Mode
|
436
|
+
#
|
437
|
+
# <%= video 'movie.mp4' %>
|
438
|
+
#
|
439
|
+
# # <video src="https://assets.bookshelf.org/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
|
440
|
+
def video(source = nil, options = {}, &blk)
|
441
|
+
options = _source_options(source, options, &blk)
|
442
|
+
html.video(blk, options)
|
443
|
+
end
|
444
|
+
|
445
|
+
# Generate <tt>audio</tt> tag for given source
|
446
|
+
#
|
447
|
+
# It accepts one string representing the name of the asset, if it comes
|
448
|
+
# from the application or third party gems. It also accepts string
|
449
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
450
|
+
#
|
451
|
+
# Alternatively, it accepts a block that allows to specify one or more
|
452
|
+
# sources via the <tt>source</tt> tag.
|
453
|
+
#
|
454
|
+
# If the "digest mode" is on, <tt>src</tt> is the digest version of the
|
455
|
+
# relative URL.
|
456
|
+
#
|
457
|
+
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
458
|
+
# application CDN.
|
459
|
+
#
|
460
|
+
# @param source [String] asset name or absolute URL
|
461
|
+
#
|
462
|
+
# @return [Lotus::Utils::Helpers::HtmlBuilder] the builder
|
463
|
+
#
|
464
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
465
|
+
# the image is missing from the manifest
|
466
|
+
#
|
467
|
+
# @raise [ArgumentError] if source isn't specified both as argument or
|
468
|
+
# tag inside the given block
|
469
|
+
#
|
470
|
+
# @since 0.1.0
|
471
|
+
#
|
472
|
+
# @see Lotus::Assets::Configuration#digest
|
473
|
+
# @see Lotus::Assets::Configuration#cdn
|
474
|
+
# @see Lotus::Assets::Helpers#asset_path
|
475
|
+
#
|
476
|
+
# @example Basic Usage
|
477
|
+
#
|
478
|
+
# <%= audio 'song.ogg' %>
|
479
|
+
#
|
480
|
+
# # <audio src="/assets/song.ogg"></audio>
|
481
|
+
#
|
482
|
+
# @example Absolute URL
|
483
|
+
#
|
484
|
+
# <%= audio 'https://example-cdn.com/assets/song.ogg' %>
|
485
|
+
#
|
486
|
+
# # <audio src="https://example-cdn.com/assets/song.ogg"></audio>
|
487
|
+
#
|
488
|
+
# @example Custom HTML Attributes
|
489
|
+
#
|
490
|
+
# <%= audio('song.ogg', autoplay: true, controls: true) %>
|
491
|
+
#
|
492
|
+
# # <audio src="/assets/song.ogg" autoplay="autoplay" controls="controls"></audio>
|
493
|
+
#
|
494
|
+
# @example Fallback Content
|
495
|
+
#
|
496
|
+
# <%=
|
497
|
+
# audio('song.ogg') do
|
498
|
+
# "Your browser does not support the audio tag"
|
499
|
+
# end
|
500
|
+
# %>
|
501
|
+
#
|
502
|
+
# # <audio src="/assets/song.ogg">
|
503
|
+
# # Your browser does not support the audio tag
|
504
|
+
# # </audio>
|
505
|
+
#
|
506
|
+
# @example Tracks
|
507
|
+
#
|
508
|
+
# <%=
|
509
|
+
# audio('song.ogg') do
|
510
|
+
# track(kind: 'captions', src: asset_path('song.pt-BR.vtt'),
|
511
|
+
# srclang: 'pt-BR', label: 'Portuguese')
|
512
|
+
# end
|
513
|
+
# %>
|
514
|
+
#
|
515
|
+
# # <audio src="/assets/song.ogg">
|
516
|
+
# # <track kind="captions" src="/assets/song.pt-BR.vtt" srclang="pt-BR" label="Portuguese">
|
517
|
+
# # </audio>
|
518
|
+
#
|
519
|
+
# @example Sources
|
520
|
+
#
|
521
|
+
# <%=
|
522
|
+
# audio do
|
523
|
+
# text "Your browser does not support the audio tag"
|
524
|
+
# source(src: asset_path('song.ogg'), type: 'audio/ogg')
|
525
|
+
# source(src: asset_path('song.wav'), type: 'auido/wav')
|
526
|
+
# end
|
527
|
+
# %>
|
528
|
+
#
|
529
|
+
# # <audio>
|
530
|
+
# # Your browser does not support the audio tag
|
531
|
+
# # <source src="/assets/song.ogg" type="audio/ogg">
|
532
|
+
# # <source src="/assets/song.wav" type="auido/wav">
|
533
|
+
# # </audio>
|
534
|
+
#
|
535
|
+
# @example Without Any Argument
|
536
|
+
#
|
537
|
+
# <%= audio %>
|
538
|
+
#
|
539
|
+
# # ArgumentError
|
540
|
+
#
|
541
|
+
# @example Without src And Without Block
|
542
|
+
#
|
543
|
+
# <%= audio(controls: true) %>
|
544
|
+
#
|
545
|
+
# # ArgumentError
|
546
|
+
#
|
547
|
+
# @example Digest Mode
|
548
|
+
#
|
549
|
+
# <%= audio 'song.ogg' %>
|
550
|
+
#
|
551
|
+
# # <audio src="/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
|
552
|
+
#
|
553
|
+
# @example CDN Mode
|
554
|
+
#
|
555
|
+
# <%= audio 'song.ogg' %>
|
556
|
+
#
|
557
|
+
# # <audio src="https://assets.bookshelf.org/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
|
558
|
+
def audio(source = nil, options = {}, &blk)
|
559
|
+
options = _source_options(source, options, &blk)
|
560
|
+
html.audio(blk, options)
|
561
|
+
end
|
562
|
+
|
563
|
+
# It generates the relative URL for the given source.
|
564
|
+
#
|
565
|
+
# It can be the name of the asset, coming from the sources or third party
|
566
|
+
# gems.
|
567
|
+
#
|
568
|
+
# Absolute URLs are returned as they are.
|
569
|
+
#
|
570
|
+
# If Digest mode is on, it returns the digest path of the source
|
571
|
+
#
|
572
|
+
# If CDN mode is on, it returns the absolute URL of the asset.
|
573
|
+
#
|
574
|
+
# @param source [String] the asset name
|
575
|
+
#
|
576
|
+
# @return [String] the asset path
|
577
|
+
#
|
578
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
579
|
+
# the asset is missing from the manifest
|
580
|
+
#
|
581
|
+
# @since 0.1.0
|
582
|
+
#
|
583
|
+
# @example Basic Usage
|
584
|
+
#
|
585
|
+
# <%= asset_path 'application.js' %>
|
586
|
+
#
|
587
|
+
# # "/assets/application.js"
|
588
|
+
#
|
589
|
+
# @example Absolute URL
|
590
|
+
#
|
591
|
+
# <%= asset_path 'https://code.jquery.com/jquery-2.1.4.min.js' %>
|
592
|
+
#
|
593
|
+
# # "https://code.jquery.com/jquery-2.1.4.min.js"
|
594
|
+
#
|
595
|
+
# @example Digest Mode
|
596
|
+
#
|
597
|
+
# <%= asset_path 'application.js' %>
|
598
|
+
#
|
599
|
+
# # "/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
600
|
+
#
|
601
|
+
# @example CDN Mode
|
602
|
+
#
|
603
|
+
# <%= asset_path 'application.js' %>
|
604
|
+
#
|
605
|
+
# # "https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
606
|
+
def asset_path(source)
|
607
|
+
_asset_url(source) { _relative_url(source) }
|
608
|
+
end
|
609
|
+
|
610
|
+
# It generates the absolute URL for the given source.
|
611
|
+
#
|
612
|
+
# It can be the name of the asset, coming from the sources or third party
|
613
|
+
# gems.
|
614
|
+
#
|
615
|
+
# Absolute URLs are returned as they are.
|
616
|
+
#
|
617
|
+
# If Digest mode is on, it returns the digest URL of the source
|
618
|
+
#
|
619
|
+
# If CDN mode is on, it returns the absolute URL of the asset.
|
620
|
+
#
|
621
|
+
# @param source [String] the asset name
|
622
|
+
#
|
623
|
+
# @return [String] the asset URL
|
624
|
+
#
|
625
|
+
# @raise [Lotus::Assets::MissingDigestAssetError] if digest mode is on and
|
626
|
+
# the asset is missing from the manifest
|
627
|
+
#
|
628
|
+
# @since 0.1.0
|
629
|
+
#
|
630
|
+
# @example Basic Usage
|
631
|
+
#
|
632
|
+
# <%= asset_url 'application.js' %>
|
633
|
+
#
|
634
|
+
# # "https://bookshelf.org/assets/application.js"
|
635
|
+
#
|
636
|
+
# @example Absolute URL
|
637
|
+
#
|
638
|
+
# <%= asset_url 'https://code.jquery.com/jquery-2.1.4.min.js' %>
|
639
|
+
#
|
640
|
+
# # "https://code.jquery.com/jquery-2.1.4.min.js"
|
641
|
+
#
|
642
|
+
# @example Digest Mode
|
643
|
+
#
|
644
|
+
# <%= asset_url 'application.js' %>
|
645
|
+
#
|
646
|
+
# # "https://bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
647
|
+
#
|
648
|
+
# @example CDN Mode
|
649
|
+
#
|
650
|
+
# <%= asset_url 'application.js' %>
|
651
|
+
#
|
652
|
+
# # "https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
653
|
+
def asset_url(source)
|
654
|
+
_asset_url(source) { _absolute_url(source) }
|
655
|
+
end
|
656
|
+
|
657
|
+
private
|
658
|
+
|
659
|
+
# @since 0.1.0
|
660
|
+
# @api private
|
661
|
+
def _safe_tags(*sources)
|
662
|
+
::Lotus::Utils::Escape::SafeString.new(
|
663
|
+
sources.map do |source|
|
664
|
+
yield source
|
665
|
+
end.join(NEW_LINE_SEPARATOR)
|
666
|
+
)
|
667
|
+
end
|
668
|
+
|
669
|
+
# @since 0.1.0
|
670
|
+
# @api private
|
671
|
+
def _asset_url(source)
|
672
|
+
_push_promise(
|
673
|
+
_absolute_url?(source) ?
|
674
|
+
source : yield
|
675
|
+
)
|
676
|
+
end
|
677
|
+
|
678
|
+
# @since 0.1.0
|
679
|
+
# @api private
|
680
|
+
def _typed_asset_path(source, ext)
|
681
|
+
source = "#{ source }#{ ext }" unless source.match(/#{ Regexp.escape(ext) }\z/)
|
682
|
+
asset_path(source)
|
683
|
+
end
|
684
|
+
|
685
|
+
# @since 0.1.0
|
686
|
+
# @api private
|
687
|
+
def _absolute_url?(source)
|
688
|
+
URI.regexp.match(source)
|
689
|
+
end
|
690
|
+
|
691
|
+
# @since 0.1.0
|
692
|
+
# @api private
|
693
|
+
def _relative_url(source)
|
694
|
+
self.class.assets_configuration.asset_path(source)
|
695
|
+
end
|
696
|
+
|
697
|
+
# @since 0.1.0
|
698
|
+
# @api private
|
699
|
+
def _absolute_url(source)
|
700
|
+
self.class.assets_configuration.asset_url(source)
|
701
|
+
end
|
702
|
+
|
703
|
+
# @since 0.1.0
|
704
|
+
# @api private
|
705
|
+
def _source_options(src, options, &blk)
|
706
|
+
options ||= {}
|
707
|
+
|
708
|
+
if src.respond_to?(:to_hash)
|
709
|
+
options = src.to_hash
|
710
|
+
elsif src
|
711
|
+
options[:src] = asset_path(src)
|
712
|
+
end
|
713
|
+
|
714
|
+
if !options[:src] && !block_given?
|
715
|
+
raise ArgumentError.new('You should provide a source via `src` option or with a `source` HTML tag')
|
716
|
+
end
|
717
|
+
|
718
|
+
options
|
719
|
+
end
|
720
|
+
|
721
|
+
# @since 0.1.0
|
722
|
+
# @api private
|
723
|
+
def _push_promise(url)
|
724
|
+
Mutex.new.synchronize do
|
725
|
+
Thread.current[:__lotus_assets] ||= Set.new
|
726
|
+
Thread.current[:__lotus_assets].add(url.to_s)
|
727
|
+
end
|
728
|
+
|
729
|
+
url
|
730
|
+
end
|
731
|
+
end
|
732
|
+
end
|
733
|
+
end
|