hanami-assets 1.3.5 → 2.1.0.beta2
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 +22 -0
- data/README.md +92 -314
- data/hanami-assets.gemspec +26 -33
- data/lib/hanami/assets/asset.rb +83 -0
- data/lib/hanami/assets/base_url.rb +64 -0
- data/lib/hanami/assets/config.rb +106 -0
- data/lib/hanami/assets/errors.rb +46 -0
- data/lib/hanami/assets/version.rb +2 -2
- data/lib/hanami/assets.rb +61 -143
- data/lib/hanami-assets.rb +3 -0
- metadata +33 -115
- data/lib/hanami/assets/bundler/asset.rb +0 -100
- data/lib/hanami/assets/bundler/compressor.rb +0 -63
- data/lib/hanami/assets/bundler/manifest_entry.rb +0 -64
- data/lib/hanami/assets/bundler.rb +0 -154
- data/lib/hanami/assets/cache.rb +0 -102
- data/lib/hanami/assets/compiler.rb +0 -287
- data/lib/hanami/assets/compilers/less.rb +0 -31
- data/lib/hanami/assets/compilers/sass.rb +0 -61
- data/lib/hanami/assets/compressors/abstract.rb +0 -119
- data/lib/hanami/assets/compressors/builtin_javascript.rb +0 -36
- data/lib/hanami/assets/compressors/builtin_stylesheet.rb +0 -57
- data/lib/hanami/assets/compressors/closure_javascript.rb +0 -25
- data/lib/hanami/assets/compressors/javascript.rb +0 -77
- data/lib/hanami/assets/compressors/jsmin.rb +0 -284
- data/lib/hanami/assets/compressors/null_compressor.rb +0 -19
- data/lib/hanami/assets/compressors/sass_stylesheet.rb +0 -36
- data/lib/hanami/assets/compressors/stylesheet.rb +0 -77
- data/lib/hanami/assets/compressors/uglifier_javascript.rb +0 -25
- data/lib/hanami/assets/compressors/yui_javascript.rb +0 -25
- data/lib/hanami/assets/compressors/yui_stylesheet.rb +0 -25
- data/lib/hanami/assets/config/global_sources.rb +0 -52
- data/lib/hanami/assets/config/manifest.rb +0 -142
- data/lib/hanami/assets/config/sources.rb +0 -80
- data/lib/hanami/assets/configuration.rb +0 -657
- data/lib/hanami/assets/helpers.rb +0 -945
- data/lib/hanami/assets/precompiler.rb +0 -97
|
@@ -1,945 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "uri"
|
|
4
|
-
require "hanami/helpers/html_helper"
|
|
5
|
-
require "hanami/utils/escape"
|
|
6
|
-
|
|
7
|
-
module Hanami
|
|
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/hanami-helpers/Hanami/Helpers/HtmlHelper
|
|
16
|
-
#
|
|
17
|
-
# rubocop:disable Metrics/ModuleLength
|
|
18
|
-
module Helpers
|
|
19
|
-
# @since 0.1.0
|
|
20
|
-
# @api private
|
|
21
|
-
NEW_LINE_SEPARATOR = "\n"
|
|
22
|
-
|
|
23
|
-
# @since 0.1.0
|
|
24
|
-
# @api private
|
|
25
|
-
WILDCARD_EXT = ".*"
|
|
26
|
-
|
|
27
|
-
# @since 0.1.0
|
|
28
|
-
# @api private
|
|
29
|
-
JAVASCRIPT_EXT = ".js"
|
|
30
|
-
|
|
31
|
-
# @since 0.1.0
|
|
32
|
-
# @api private
|
|
33
|
-
STYLESHEET_EXT = ".css"
|
|
34
|
-
|
|
35
|
-
# @since 0.1.0
|
|
36
|
-
# @api private
|
|
37
|
-
JAVASCRIPT_MIME_TYPE = "text/javascript"
|
|
38
|
-
|
|
39
|
-
# @since 0.1.0
|
|
40
|
-
# @api private
|
|
41
|
-
STYLESHEET_MIME_TYPE = "text/css"
|
|
42
|
-
|
|
43
|
-
# @since 0.1.0
|
|
44
|
-
# @api private
|
|
45
|
-
FAVICON_MIME_TYPE = "image/x-icon"
|
|
46
|
-
|
|
47
|
-
# @since 0.1.0
|
|
48
|
-
# @api private
|
|
49
|
-
STYLESHEET_REL = "stylesheet"
|
|
50
|
-
|
|
51
|
-
# @since 0.1.0
|
|
52
|
-
# @api private
|
|
53
|
-
FAVICON_REL = "shortcut icon"
|
|
54
|
-
|
|
55
|
-
# @since 0.1.0
|
|
56
|
-
# @api private
|
|
57
|
-
DEFAULT_FAVICON = "favicon.ico"
|
|
58
|
-
|
|
59
|
-
# @since 0.3.0
|
|
60
|
-
# @api private
|
|
61
|
-
CROSSORIGIN_ANONYMOUS = "anonymous"
|
|
62
|
-
|
|
63
|
-
# @since 0.3.0
|
|
64
|
-
# @api private
|
|
65
|
-
ABSOLUTE_URL_MATCHER = URI::DEFAULT_PARSER.make_regexp
|
|
66
|
-
|
|
67
|
-
# @since 1.1.0
|
|
68
|
-
# @api private
|
|
69
|
-
QUERY_STRING_MATCHER = /\?/.freeze
|
|
70
|
-
|
|
71
|
-
include Hanami::Helpers::HtmlHelper
|
|
72
|
-
|
|
73
|
-
# Inject helpers into the given class
|
|
74
|
-
#
|
|
75
|
-
# @since 0.1.0
|
|
76
|
-
# @api private
|
|
77
|
-
def self.included(base)
|
|
78
|
-
conf = ::Hanami::Assets::Configuration.for(base)
|
|
79
|
-
base.class_eval do
|
|
80
|
-
include Utils::ClassAttribute
|
|
81
|
-
|
|
82
|
-
class_attribute :assets_configuration
|
|
83
|
-
self.assets_configuration = conf
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Generate <tt>script</tt> tag for given source(s)
|
|
88
|
-
#
|
|
89
|
-
# It accepts one or more strings representing the name of the asset, if it
|
|
90
|
-
# comes from the application or third party gems. It also accepts strings
|
|
91
|
-
# representing absolute URLs in case of public CDN (eg. jQuery CDN).
|
|
92
|
-
#
|
|
93
|
-
# If the "fingerprint mode" is on, <tt>src</tt> is the fingerprinted
|
|
94
|
-
# version of the relative URL.
|
|
95
|
-
#
|
|
96
|
-
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
|
97
|
-
# application CDN.
|
|
98
|
-
#
|
|
99
|
-
# If the "subresource integrity mode" is on, <tt>integriy</tt> is the
|
|
100
|
-
# name of the algorithm, then a hyphen, then the hash value of the file.
|
|
101
|
-
# If more than one algorithm is used, they'll be separated by a space.
|
|
102
|
-
#
|
|
103
|
-
# It makes the script(s) eligible for HTTP/2 Push Promise/Early Hints.
|
|
104
|
-
# You can opt-out with inline option: `push: false`.
|
|
105
|
-
#
|
|
106
|
-
# @param sources [Array<String>] one or more assets by name or absolute URL
|
|
107
|
-
# @param push [TrueClass, FalseClass] HTTP/2 Push Promise/Early Hints flag
|
|
108
|
-
#
|
|
109
|
-
# @return [Hanami::Utils::Escape::SafeString] the markup
|
|
110
|
-
#
|
|
111
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
112
|
-
# `subresource_integrity` modes are on and the javascript file is missing
|
|
113
|
-
# from the manifest
|
|
114
|
-
#
|
|
115
|
-
# @since 0.1.0
|
|
116
|
-
#
|
|
117
|
-
# @see Hanami::Assets::Configuration#fingerprint
|
|
118
|
-
# @see Hanami::Assets::Configuration#cdn
|
|
119
|
-
# @see Hanami::Assets::Helpers#asset_path
|
|
120
|
-
#
|
|
121
|
-
# @example Single Asset
|
|
122
|
-
#
|
|
123
|
-
# <%= javascript 'application' %>
|
|
124
|
-
#
|
|
125
|
-
# # <script src="/assets/application.js" type="text/javascript"></script>
|
|
126
|
-
#
|
|
127
|
-
# @example Multiple Assets
|
|
128
|
-
#
|
|
129
|
-
# <%= javascript 'application', 'dashboard' %>
|
|
130
|
-
#
|
|
131
|
-
# # <script src="/assets/application.js" type="text/javascript"></script>
|
|
132
|
-
# # <script src="/assets/dashboard.js" type="text/javascript"></script>
|
|
133
|
-
#
|
|
134
|
-
# @example Asynchronous Execution
|
|
135
|
-
#
|
|
136
|
-
# <%= javascript 'application', async: true %>
|
|
137
|
-
#
|
|
138
|
-
# # <script src="/assets/application.js" type="text/javascript" async="async"></script>
|
|
139
|
-
#
|
|
140
|
-
# @example Subresource Integrity
|
|
141
|
-
#
|
|
142
|
-
# <%= javascript 'application' %>
|
|
143
|
-
#
|
|
144
|
-
# # <script src="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
145
|
-
# # type="text/javascript" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
146
|
-
#
|
|
147
|
-
# @example Subresource Integrity for 3rd Party Scripts
|
|
148
|
-
#
|
|
149
|
-
# <%= javascript 'https://example.com/assets/example.js', integrity: 'sha384-oqVu...Y8wC' %>
|
|
150
|
-
#
|
|
151
|
-
# # <script src="https://example.com/assets/example.js" type="text/javascript"
|
|
152
|
-
# # integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
153
|
-
#
|
|
154
|
-
# @example Deferred Execution
|
|
155
|
-
#
|
|
156
|
-
# <%= javascript 'application', defer: true %>
|
|
157
|
-
#
|
|
158
|
-
# # <script src="/assets/application.js" type="text/javascript" defer="defer"></script>
|
|
159
|
-
#
|
|
160
|
-
# @example Absolute URL
|
|
161
|
-
#
|
|
162
|
-
# <%= javascript 'https://code.jquery.com/jquery-2.1.4.min.js' %>
|
|
163
|
-
#
|
|
164
|
-
# # <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
|
|
165
|
-
#
|
|
166
|
-
# @example Fingerprint Mode
|
|
167
|
-
#
|
|
168
|
-
# <%= javascript 'application' %>
|
|
169
|
-
#
|
|
170
|
-
# # <script src="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js" type="text/javascript"></script>
|
|
171
|
-
#
|
|
172
|
-
# @example CDN Mode
|
|
173
|
-
#
|
|
174
|
-
# <%= javascript 'application' %>
|
|
175
|
-
#
|
|
176
|
-
# # <script src="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
177
|
-
# # type="text/javascript"></script>
|
|
178
|
-
#
|
|
179
|
-
# @example Disable Push Promise/Early Hints
|
|
180
|
-
#
|
|
181
|
-
# <%= javascript 'application', push: false %>
|
|
182
|
-
# <%= javascript 'http://cdn.example.test/jquery.js', 'dashboard', push: false %>
|
|
183
|
-
def javascript(*sources, push: true, **options)
|
|
184
|
-
options = options.reject { |k, _| k.to_sym == :src }
|
|
185
|
-
|
|
186
|
-
_safe_tags(*sources) do |source|
|
|
187
|
-
attributes = {
|
|
188
|
-
src: _typed_asset_path(source, JAVASCRIPT_EXT, push: push, as: :script),
|
|
189
|
-
type: JAVASCRIPT_MIME_TYPE
|
|
190
|
-
}
|
|
191
|
-
attributes.merge!(options)
|
|
192
|
-
|
|
193
|
-
if _subresource_integrity? || attributes.include?(:integrity)
|
|
194
|
-
attributes[:integrity] ||= _subresource_integrity_value(source, JAVASCRIPT_EXT)
|
|
195
|
-
attributes[:crossorigin] ||= CROSSORIGIN_ANONYMOUS
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
html.script(**attributes).to_s
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
# Generate <tt>link</tt> tag for given source(s)
|
|
203
|
-
#
|
|
204
|
-
# It accepts one or more strings representing the name of the asset, if it
|
|
205
|
-
# comes from the application or third party gems. It also accepts strings
|
|
206
|
-
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
207
|
-
#
|
|
208
|
-
# If the "fingerprint mode" is on, <tt>href</tt> is the fingerprinted
|
|
209
|
-
# version of the relative URL.
|
|
210
|
-
#
|
|
211
|
-
# If the "CDN mode" is on, the <tt>href</tt> is an absolute URL of the
|
|
212
|
-
# application CDN.
|
|
213
|
-
#
|
|
214
|
-
# If the "subresource integrity mode" is on, <tt>integriy</tt> is the
|
|
215
|
-
# name of the algorithm, then a hyphen, then the hashed value of the file.
|
|
216
|
-
# If more than one algorithm is used, they'll be separated by a space.
|
|
217
|
-
#
|
|
218
|
-
# It makes the script(s) eligible for HTTP/2 Push Promise/Early Hints.
|
|
219
|
-
# You can opt-out with inline option: `push: false`.
|
|
220
|
-
#
|
|
221
|
-
# @param sources [Array<String>] one or more assets by name or absolute URL
|
|
222
|
-
# @param push [TrueClass, FalseClass] HTTP/2 Push Promise/Early Hints flag
|
|
223
|
-
#
|
|
224
|
-
# @return [Hanami::Utils::Escape::SafeString] the markup
|
|
225
|
-
#
|
|
226
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
227
|
-
# `subresource_integrity` modes are on and the stylesheet file is missing
|
|
228
|
-
# from the manifest
|
|
229
|
-
#
|
|
230
|
-
# @since 0.1.0
|
|
231
|
-
#
|
|
232
|
-
# @see Hanami::Assets::Configuration#fingerprint
|
|
233
|
-
# @see Hanami::Assets::Configuration#cdn
|
|
234
|
-
# @see Hanami::Assets::Configuration#subresource_integrity
|
|
235
|
-
# @see Hanami::Assets::Helpers#asset_path
|
|
236
|
-
#
|
|
237
|
-
# @example Single Asset
|
|
238
|
-
#
|
|
239
|
-
# <%= stylesheet 'application' %>
|
|
240
|
-
#
|
|
241
|
-
# # <link href="/assets/application.css" type="text/css" rel="stylesheet">
|
|
242
|
-
#
|
|
243
|
-
# @example Multiple Assets
|
|
244
|
-
#
|
|
245
|
-
# <%= stylesheet 'application', 'dashboard' %>
|
|
246
|
-
#
|
|
247
|
-
# # <link href="/assets/application.css" type="text/css" rel="stylesheet">
|
|
248
|
-
# # <link href="/assets/dashboard.css" type="text/css" rel="stylesheet">
|
|
249
|
-
#
|
|
250
|
-
# @example Subresource Integrity
|
|
251
|
-
#
|
|
252
|
-
# <%= stylesheet 'application' %>
|
|
253
|
-
#
|
|
254
|
-
# # <link href="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css"
|
|
255
|
-
# # type="text/css" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
256
|
-
#
|
|
257
|
-
# @example Subresource Integrity for 3rd Party Assets
|
|
258
|
-
#
|
|
259
|
-
# <%= stylesheet 'https://example.com/assets/example.css', integrity: 'sha384-oqVu...Y8wC' %>
|
|
260
|
-
#
|
|
261
|
-
# # <link href="https://example.com/assets/example.css"
|
|
262
|
-
# # type="text/css" rel="stylesheet" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
263
|
-
#
|
|
264
|
-
# @example Absolute URL
|
|
265
|
-
#
|
|
266
|
-
# <%= stylesheet 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' %>
|
|
267
|
-
#
|
|
268
|
-
# # <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
|
|
269
|
-
# # type="text/css" rel="stylesheet">
|
|
270
|
-
#
|
|
271
|
-
# @example Fingerprint Mode
|
|
272
|
-
#
|
|
273
|
-
# <%= stylesheet 'application' %>
|
|
274
|
-
#
|
|
275
|
-
# # <link href="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css" type="text/css" rel="stylesheet">
|
|
276
|
-
#
|
|
277
|
-
# @example CDN Mode
|
|
278
|
-
#
|
|
279
|
-
# <%= stylesheet 'application' %>
|
|
280
|
-
#
|
|
281
|
-
# # <link href="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css"
|
|
282
|
-
# # type="text/css" rel="stylesheet">
|
|
283
|
-
#
|
|
284
|
-
# @example Disable Push Promise/Early Hints
|
|
285
|
-
#
|
|
286
|
-
# <%= stylesheet 'application', push: false %>
|
|
287
|
-
# <%= stylesheet 'http://cdn.example.test/bootstrap.css', 'dashboard', push: false %>
|
|
288
|
-
def stylesheet(*sources, push: true, **options)
|
|
289
|
-
options = options.reject { |k, _| k.to_sym == :href }
|
|
290
|
-
|
|
291
|
-
_safe_tags(*sources) do |source|
|
|
292
|
-
attributes = {
|
|
293
|
-
href: _typed_asset_path(source, STYLESHEET_EXT, push: push, as: :style),
|
|
294
|
-
type: STYLESHEET_MIME_TYPE,
|
|
295
|
-
rel: STYLESHEET_REL
|
|
296
|
-
}
|
|
297
|
-
attributes.merge!(options)
|
|
298
|
-
|
|
299
|
-
if _subresource_integrity? || attributes.include?(:integrity)
|
|
300
|
-
attributes[:integrity] ||= _subresource_integrity_value(source, STYLESHEET_EXT)
|
|
301
|
-
attributes[:crossorigin] ||= CROSSORIGIN_ANONYMOUS
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
html.link(**attributes).to_s
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
# Generate <tt>img</tt> tag for given source
|
|
309
|
-
#
|
|
310
|
-
# It accepts one string representing the name of the asset, if it comes
|
|
311
|
-
# from the application or third party gems. It also accepts string
|
|
312
|
-
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
313
|
-
#
|
|
314
|
-
# <tt>alt</tt> Attribute is auto generated from <tt>src</tt>.
|
|
315
|
-
# You can specify a different value, by passing the <tt>:src</tt> option.
|
|
316
|
-
#
|
|
317
|
-
# If the "fingerprint mode" is on, <tt>src</tt> is the fingerprinted
|
|
318
|
-
# version of the relative URL.
|
|
319
|
-
#
|
|
320
|
-
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
|
321
|
-
# application CDN.
|
|
322
|
-
#
|
|
323
|
-
# @param source [String] asset name or absolute URL
|
|
324
|
-
# @param options [Hash] HTML 5 attributes
|
|
325
|
-
# @option options [TrueClass, FalseClass] :push HTTP/2 Push Promise/Early Hints flag
|
|
326
|
-
#
|
|
327
|
-
# @return [Hanami::Utils::Helpers::HtmlBuilder] the builder
|
|
328
|
-
#
|
|
329
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
330
|
-
# `subresource_integrity` modes are on and the image file is missing
|
|
331
|
-
# from the manifest
|
|
332
|
-
#
|
|
333
|
-
# @since 0.1.0
|
|
334
|
-
#
|
|
335
|
-
# @see Hanami::Assets::Configuration#fingerprint
|
|
336
|
-
# @see Hanami::Assets::Configuration#cdn
|
|
337
|
-
# @see Hanami::Assets::Configuration#subresource_integrity
|
|
338
|
-
# @see Hanami::Assets::Helpers#asset_path
|
|
339
|
-
#
|
|
340
|
-
# @example Basic Usage
|
|
341
|
-
#
|
|
342
|
-
# <%= image 'logo.png' %>
|
|
343
|
-
#
|
|
344
|
-
# # <img src="/assets/logo.png" alt="Logo">
|
|
345
|
-
#
|
|
346
|
-
# @example Custom alt Attribute
|
|
347
|
-
#
|
|
348
|
-
# <%= image 'logo.png', alt: 'Application Logo' %>
|
|
349
|
-
#
|
|
350
|
-
# # <img src="/assets/logo.png" alt="Application Logo">
|
|
351
|
-
#
|
|
352
|
-
# @example Custom HTML Attributes
|
|
353
|
-
#
|
|
354
|
-
# <%= image 'logo.png', id: 'logo', class: 'image' %>
|
|
355
|
-
#
|
|
356
|
-
# # <img src="/assets/logo.png" alt="Logo" id="logo" class="image">
|
|
357
|
-
#
|
|
358
|
-
# @example Absolute URL
|
|
359
|
-
#
|
|
360
|
-
# <%= image 'https://example-cdn.com/images/logo.png' %>
|
|
361
|
-
#
|
|
362
|
-
# # <img src="https://example-cdn.com/images/logo.png" alt="Logo">
|
|
363
|
-
#
|
|
364
|
-
# @example Fingerprint Mode
|
|
365
|
-
#
|
|
366
|
-
# <%= image 'logo.png' %>
|
|
367
|
-
#
|
|
368
|
-
# # <img src="/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
|
|
369
|
-
#
|
|
370
|
-
# @example CDN Mode
|
|
371
|
-
#
|
|
372
|
-
# <%= image 'logo.png' %>
|
|
373
|
-
#
|
|
374
|
-
# # <img src="https://assets.bookshelf.org/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
|
|
375
|
-
#
|
|
376
|
-
# @example Enable Push Promise/Early Hints
|
|
377
|
-
#
|
|
378
|
-
# <%= image 'logo.png', push: true %>
|
|
379
|
-
def image(source, options = {})
|
|
380
|
-
options = options.reject { |k, _| k.to_sym == :src }
|
|
381
|
-
attributes = {
|
|
382
|
-
src: asset_path(source, push: options.delete(:push) || false, as: :image),
|
|
383
|
-
alt: Utils::String.titleize(::File.basename(source, WILDCARD_EXT))
|
|
384
|
-
}
|
|
385
|
-
attributes.merge!(options)
|
|
386
|
-
|
|
387
|
-
html.img(attributes)
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
# Generate <tt>link</tt> tag application favicon.
|
|
391
|
-
#
|
|
392
|
-
# If no argument is given, it assumes <tt>favico.ico</tt> from the application.
|
|
393
|
-
#
|
|
394
|
-
# It accepts one string representing the name of the asset.
|
|
395
|
-
#
|
|
396
|
-
# If the "fingerprint mode" is on, <tt>href</tt> is the fingerprinted version
|
|
397
|
-
# of the relative URL.
|
|
398
|
-
#
|
|
399
|
-
# If the "CDN mode" is on, the <tt>href</tt> is an absolute URL of the
|
|
400
|
-
# application CDN.
|
|
401
|
-
#
|
|
402
|
-
# @param source [String] asset name
|
|
403
|
-
# @param options [Hash] HTML 5 attributes
|
|
404
|
-
# @option options [TrueClass, FalseClass] :push HTTP/2 Push Promise/Early Hints flag
|
|
405
|
-
#
|
|
406
|
-
# @return [Hanami::Utils::Helpers::HtmlBuilder] the builder
|
|
407
|
-
#
|
|
408
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
409
|
-
# `subresource_integrity` modes are on and the favicon is file missing
|
|
410
|
-
# from the manifest
|
|
411
|
-
#
|
|
412
|
-
# @since 0.1.0
|
|
413
|
-
#
|
|
414
|
-
# @see Hanami::Assets::Configuration#fingerprint
|
|
415
|
-
# @see Hanami::Assets::Configuration#cdn
|
|
416
|
-
# @see Hanami::Assets::Helpers#asset_path
|
|
417
|
-
#
|
|
418
|
-
# @example Basic Usage
|
|
419
|
-
#
|
|
420
|
-
# <%= favicon %>
|
|
421
|
-
#
|
|
422
|
-
# # <link href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
|
423
|
-
#
|
|
424
|
-
# @example Custom Path
|
|
425
|
-
#
|
|
426
|
-
# <%= favicon 'fav.ico' %>
|
|
427
|
-
#
|
|
428
|
-
# # <link href="/assets/fav.ico" rel="shortcut icon" type="image/x-icon">
|
|
429
|
-
#
|
|
430
|
-
# @example Custom HTML Attributes
|
|
431
|
-
#
|
|
432
|
-
# <%= favicon "favicon.ico", id: "fav" %>
|
|
433
|
-
#
|
|
434
|
-
# # <link id: "fav" href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
|
435
|
-
#
|
|
436
|
-
# @example Fingerprint Mode
|
|
437
|
-
#
|
|
438
|
-
# <%= favicon %>
|
|
439
|
-
#
|
|
440
|
-
# # <link href="/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico" rel="shortcut icon" type="image/x-icon">
|
|
441
|
-
#
|
|
442
|
-
# @example CDN Mode
|
|
443
|
-
#
|
|
444
|
-
# <%= favicon %>
|
|
445
|
-
#
|
|
446
|
-
# # <link href="https://assets.bookshelf.org/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico"
|
|
447
|
-
# rel="shortcut icon" type="image/x-icon">
|
|
448
|
-
#
|
|
449
|
-
# @example Enable Push Promise/Early Hints
|
|
450
|
-
#
|
|
451
|
-
# <%= favicon 'favicon.ico', push: true %>
|
|
452
|
-
def favicon(source = DEFAULT_FAVICON, options = {})
|
|
453
|
-
options = options.reject { |k, _| k.to_sym == :href }
|
|
454
|
-
|
|
455
|
-
attributes = {
|
|
456
|
-
href: asset_path(source, push: options.delete(:push) || false, as: :image),
|
|
457
|
-
rel: FAVICON_REL,
|
|
458
|
-
type: FAVICON_MIME_TYPE
|
|
459
|
-
}
|
|
460
|
-
attributes.merge!(options)
|
|
461
|
-
|
|
462
|
-
html.link(attributes)
|
|
463
|
-
end
|
|
464
|
-
|
|
465
|
-
# Generate <tt>video</tt> tag for given source
|
|
466
|
-
#
|
|
467
|
-
# It accepts one string representing the name of the asset, if it comes
|
|
468
|
-
# from the application or third party gems. It also accepts string
|
|
469
|
-
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
470
|
-
#
|
|
471
|
-
# Alternatively, it accepts a block that allows to specify one or more
|
|
472
|
-
# sources via the <tt>source</tt> tag.
|
|
473
|
-
#
|
|
474
|
-
# If the "fingerprint mode" is on, <tt>src</tt> is the fingerprinted
|
|
475
|
-
# version of the relative URL.
|
|
476
|
-
#
|
|
477
|
-
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
|
478
|
-
# application CDN.
|
|
479
|
-
#
|
|
480
|
-
# @param source [String] asset name or absolute URL
|
|
481
|
-
# @param options [Hash] HTML 5 attributes
|
|
482
|
-
# @option options [TrueClass, FalseClass] :push HTTP/2 Push Promise/Early Hints flag
|
|
483
|
-
#
|
|
484
|
-
# @return [Hanami::Utils::Helpers::HtmlBuilder] the builder
|
|
485
|
-
#
|
|
486
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
487
|
-
# `subresource_integrity` modes are on and the video file is missing
|
|
488
|
-
# from the manifest
|
|
489
|
-
#
|
|
490
|
-
# @raise [ArgumentError] if source isn't specified both as argument or
|
|
491
|
-
# tag inside the given block
|
|
492
|
-
#
|
|
493
|
-
# @since 0.1.0
|
|
494
|
-
#
|
|
495
|
-
# @see Hanami::Assets::Configuration#fingerprint
|
|
496
|
-
# @see Hanami::Assets::Configuration#cdn
|
|
497
|
-
# @see Hanami::Assets::Helpers#asset_path
|
|
498
|
-
#
|
|
499
|
-
# @example Basic Usage
|
|
500
|
-
#
|
|
501
|
-
# <%= video 'movie.mp4' %>
|
|
502
|
-
#
|
|
503
|
-
# # <video src="/assets/movie.mp4"></video>
|
|
504
|
-
#
|
|
505
|
-
# @example Absolute URL
|
|
506
|
-
#
|
|
507
|
-
# <%= video 'https://example-cdn.com/assets/movie.mp4' %>
|
|
508
|
-
#
|
|
509
|
-
# # <video src="https://example-cdn.com/assets/movie.mp4"></video>
|
|
510
|
-
#
|
|
511
|
-
# @example Custom HTML Attributes
|
|
512
|
-
#
|
|
513
|
-
# <%= video('movie.mp4', autoplay: true, controls: true) %>
|
|
514
|
-
#
|
|
515
|
-
# # <video src="/assets/movie.mp4" autoplay="autoplay" controls="controls"></video>
|
|
516
|
-
#
|
|
517
|
-
# @example Fallback Content
|
|
518
|
-
#
|
|
519
|
-
# <%=
|
|
520
|
-
# video('movie.mp4') do
|
|
521
|
-
# "Your browser does not support the video tag"
|
|
522
|
-
# end
|
|
523
|
-
# %>
|
|
524
|
-
#
|
|
525
|
-
# # <video src="/assets/movie.mp4">
|
|
526
|
-
# # Your browser does not support the video tag
|
|
527
|
-
# # </video>
|
|
528
|
-
#
|
|
529
|
-
# @example Tracks
|
|
530
|
-
#
|
|
531
|
-
# <%=
|
|
532
|
-
# video('movie.mp4') do
|
|
533
|
-
# track(kind: 'captions', src: asset_path('movie.en.vtt'),
|
|
534
|
-
# srclang: 'en', label: 'English')
|
|
535
|
-
# end
|
|
536
|
-
# %>
|
|
537
|
-
#
|
|
538
|
-
# # <video src="/assets/movie.mp4">
|
|
539
|
-
# # <track kind="captions" src="/assets/movie.en.vtt" srclang="en" label="English">
|
|
540
|
-
# # </video>
|
|
541
|
-
#
|
|
542
|
-
# @example Sources
|
|
543
|
-
#
|
|
544
|
-
# <%=
|
|
545
|
-
# video do
|
|
546
|
-
# text "Your browser does not support the video tag"
|
|
547
|
-
# source(src: asset_path('movie.mp4'), type: 'video/mp4')
|
|
548
|
-
# source(src: asset_path('movie.ogg'), type: 'video/ogg')
|
|
549
|
-
# end
|
|
550
|
-
# %>
|
|
551
|
-
#
|
|
552
|
-
# # <video>
|
|
553
|
-
# # Your browser does not support the video tag
|
|
554
|
-
# # <source src="/assets/movie.mp4" type="video/mp4">
|
|
555
|
-
# # <source src="/assets/movie.ogg" type="video/ogg">
|
|
556
|
-
# # </video>
|
|
557
|
-
#
|
|
558
|
-
# @example Without Any Argument
|
|
559
|
-
#
|
|
560
|
-
# <%= video %>
|
|
561
|
-
#
|
|
562
|
-
# # ArgumentError
|
|
563
|
-
#
|
|
564
|
-
# @example Without src And Without Block
|
|
565
|
-
#
|
|
566
|
-
# <%= video(content: true) %>
|
|
567
|
-
#
|
|
568
|
-
# # ArgumentError
|
|
569
|
-
#
|
|
570
|
-
# @example Fingerprint Mode
|
|
571
|
-
#
|
|
572
|
-
# <%= video 'movie.mp4' %>
|
|
573
|
-
#
|
|
574
|
-
# # <video src="/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
|
|
575
|
-
#
|
|
576
|
-
# @example CDN Mode
|
|
577
|
-
#
|
|
578
|
-
# <%= video 'movie.mp4' %>
|
|
579
|
-
#
|
|
580
|
-
# # <video src="https://assets.bookshelf.org/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
|
|
581
|
-
#
|
|
582
|
-
# @example Enable Push Promise/Early Hints
|
|
583
|
-
#
|
|
584
|
-
# <%= video 'movie.mp4', push: true %>
|
|
585
|
-
#
|
|
586
|
-
# <%=
|
|
587
|
-
# video do
|
|
588
|
-
# text "Your browser does not support the video tag"
|
|
589
|
-
# source src: asset_path("movie.mp4", push: :video), type: "video/mp4"
|
|
590
|
-
# source src: asset_path("movie.ogg"), type: "video/ogg"
|
|
591
|
-
# end
|
|
592
|
-
# %>
|
|
593
|
-
def video(source = nil, options = {}, &blk)
|
|
594
|
-
options = _source_options(source, options, as: :video, &blk)
|
|
595
|
-
html.video(blk, options)
|
|
596
|
-
end
|
|
597
|
-
|
|
598
|
-
# Generate <tt>audio</tt> tag for given source
|
|
599
|
-
#
|
|
600
|
-
# It accepts one string representing the name of the asset, if it comes
|
|
601
|
-
# from the application or third party gems. It also accepts string
|
|
602
|
-
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
603
|
-
#
|
|
604
|
-
# Alternatively, it accepts a block that allows to specify one or more
|
|
605
|
-
# sources via the <tt>source</tt> tag.
|
|
606
|
-
#
|
|
607
|
-
# If the "fingerprint mode" is on, <tt>src</tt> is the fingerprinted
|
|
608
|
-
# version of the relative URL.
|
|
609
|
-
#
|
|
610
|
-
# If the "CDN mode" is on, the <tt>src</tt> is an absolute URL of the
|
|
611
|
-
# application CDN.
|
|
612
|
-
#
|
|
613
|
-
# @param source [String] asset name or absolute URL
|
|
614
|
-
# @param options [Hash] HTML 5 attributes
|
|
615
|
-
# @option options [TrueClass, FalseClass] :push HTTP/2 Push Promise/Early Hints flag
|
|
616
|
-
#
|
|
617
|
-
# @return [Hanami::Utils::Helpers::HtmlBuilder] the builder
|
|
618
|
-
#
|
|
619
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
620
|
-
# `subresource_integrity` modes are on and the audio file is missing
|
|
621
|
-
# from the manifest
|
|
622
|
-
#
|
|
623
|
-
# @raise [ArgumentError] if source isn't specified both as argument or
|
|
624
|
-
# tag inside the given block
|
|
625
|
-
#
|
|
626
|
-
# @since 0.1.0
|
|
627
|
-
#
|
|
628
|
-
# @see Hanami::Assets::Configuration#fingerprint
|
|
629
|
-
# @see Hanami::Assets::Configuration#cdn
|
|
630
|
-
# @see Hanami::Assets::Helpers#asset_path
|
|
631
|
-
#
|
|
632
|
-
# @example Basic Usage
|
|
633
|
-
#
|
|
634
|
-
# <%= audio 'song.ogg' %>
|
|
635
|
-
#
|
|
636
|
-
# # <audio src="/assets/song.ogg"></audio>
|
|
637
|
-
#
|
|
638
|
-
# @example Absolute URL
|
|
639
|
-
#
|
|
640
|
-
# <%= audio 'https://example-cdn.com/assets/song.ogg' %>
|
|
641
|
-
#
|
|
642
|
-
# # <audio src="https://example-cdn.com/assets/song.ogg"></audio>
|
|
643
|
-
#
|
|
644
|
-
# @example Custom HTML Attributes
|
|
645
|
-
#
|
|
646
|
-
# <%= audio('song.ogg', autoplay: true, controls: true) %>
|
|
647
|
-
#
|
|
648
|
-
# # <audio src="/assets/song.ogg" autoplay="autoplay" controls="controls"></audio>
|
|
649
|
-
#
|
|
650
|
-
# @example Fallback Content
|
|
651
|
-
#
|
|
652
|
-
# <%=
|
|
653
|
-
# audio('song.ogg') do
|
|
654
|
-
# "Your browser does not support the audio tag"
|
|
655
|
-
# end
|
|
656
|
-
# %>
|
|
657
|
-
#
|
|
658
|
-
# # <audio src="/assets/song.ogg">
|
|
659
|
-
# # Your browser does not support the audio tag
|
|
660
|
-
# # </audio>
|
|
661
|
-
#
|
|
662
|
-
# @example Tracks
|
|
663
|
-
#
|
|
664
|
-
# <%=
|
|
665
|
-
# audio('song.ogg') do
|
|
666
|
-
# track(kind: 'captions', src: asset_path('song.pt-BR.vtt'),
|
|
667
|
-
# srclang: 'pt-BR', label: 'Portuguese')
|
|
668
|
-
# end
|
|
669
|
-
# %>
|
|
670
|
-
#
|
|
671
|
-
# # <audio src="/assets/song.ogg">
|
|
672
|
-
# # <track kind="captions" src="/assets/song.pt-BR.vtt" srclang="pt-BR" label="Portuguese">
|
|
673
|
-
# # </audio>
|
|
674
|
-
#
|
|
675
|
-
# @example Sources
|
|
676
|
-
#
|
|
677
|
-
# <%=
|
|
678
|
-
# audio do
|
|
679
|
-
# text "Your browser does not support the audio tag"
|
|
680
|
-
# source(src: asset_path('song.ogg'), type: 'audio/ogg')
|
|
681
|
-
# source(src: asset_path('song.wav'), type: 'auido/wav')
|
|
682
|
-
# end
|
|
683
|
-
# %>
|
|
684
|
-
#
|
|
685
|
-
# # <audio>
|
|
686
|
-
# # Your browser does not support the audio tag
|
|
687
|
-
# # <source src="/assets/song.ogg" type="audio/ogg">
|
|
688
|
-
# # <source src="/assets/song.wav" type="auido/wav">
|
|
689
|
-
# # </audio>
|
|
690
|
-
#
|
|
691
|
-
# @example Without Any Argument
|
|
692
|
-
#
|
|
693
|
-
# <%= audio %>
|
|
694
|
-
#
|
|
695
|
-
# # ArgumentError
|
|
696
|
-
#
|
|
697
|
-
# @example Without src And Without Block
|
|
698
|
-
#
|
|
699
|
-
# <%= audio(controls: true) %>
|
|
700
|
-
#
|
|
701
|
-
# # ArgumentError
|
|
702
|
-
#
|
|
703
|
-
# @example Fingerprint Mode
|
|
704
|
-
#
|
|
705
|
-
# <%= audio 'song.ogg' %>
|
|
706
|
-
#
|
|
707
|
-
# # <audio src="/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
|
|
708
|
-
#
|
|
709
|
-
# @example CDN Mode
|
|
710
|
-
#
|
|
711
|
-
# <%= audio 'song.ogg' %>
|
|
712
|
-
#
|
|
713
|
-
# # <audio src="https://assets.bookshelf.org/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
|
|
714
|
-
#
|
|
715
|
-
# @example Enable Push Promise/Early Hints
|
|
716
|
-
#
|
|
717
|
-
# <%= audio 'movie.mp4', push: true %>
|
|
718
|
-
#
|
|
719
|
-
# <%=
|
|
720
|
-
# audio do
|
|
721
|
-
# text "Your browser does not support the audio tag"
|
|
722
|
-
# source src: asset_path("song.ogg", push: :audio), type: "audio/ogg"
|
|
723
|
-
# source src: asset_path("song.wav"), type: "audio/wav"
|
|
724
|
-
# end
|
|
725
|
-
# %>
|
|
726
|
-
def audio(source = nil, options = {}, &blk)
|
|
727
|
-
options = _source_options(source, options, as: :audio, &blk)
|
|
728
|
-
html.audio(blk, options)
|
|
729
|
-
end
|
|
730
|
-
|
|
731
|
-
# It generates the relative URL for the given source.
|
|
732
|
-
#
|
|
733
|
-
# It can be the name of the asset, coming from the sources or third party
|
|
734
|
-
# gems.
|
|
735
|
-
#
|
|
736
|
-
# Absolute URLs are returned as they are.
|
|
737
|
-
#
|
|
738
|
-
# If Fingerprint mode is on, it returns the fingerprinted path of the source
|
|
739
|
-
#
|
|
740
|
-
# If CDN mode is on, it returns the absolute URL of the asset.
|
|
741
|
-
#
|
|
742
|
-
# @param source [String] the asset name
|
|
743
|
-
# @param push [TrueClass, FalseClass, Symbol] HTTP/2 Push Promise/Early Hints flag, or type
|
|
744
|
-
# @param as [Symbol] HTTP/2 Push Promise / Early Hints flag type
|
|
745
|
-
#
|
|
746
|
-
# @return [String] the asset path
|
|
747
|
-
#
|
|
748
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
749
|
-
# `subresource_integrity` modes are on and the asset is missing
|
|
750
|
-
# from the manifest
|
|
751
|
-
#
|
|
752
|
-
# @since 0.1.0
|
|
753
|
-
#
|
|
754
|
-
# @example Basic Usage
|
|
755
|
-
#
|
|
756
|
-
# <%= asset_path 'application.js' %>
|
|
757
|
-
#
|
|
758
|
-
# # "/assets/application.js"
|
|
759
|
-
#
|
|
760
|
-
# @example Absolute URL
|
|
761
|
-
#
|
|
762
|
-
# <%= asset_path 'https://code.jquery.com/jquery-2.1.4.min.js' %>
|
|
763
|
-
#
|
|
764
|
-
# # "https://code.jquery.com/jquery-2.1.4.min.js"
|
|
765
|
-
#
|
|
766
|
-
# @example Fingerprint Mode
|
|
767
|
-
#
|
|
768
|
-
# <%= asset_path 'application.js' %>
|
|
769
|
-
#
|
|
770
|
-
# # "/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
771
|
-
#
|
|
772
|
-
# @example CDN Mode
|
|
773
|
-
#
|
|
774
|
-
# <%= asset_path 'application.js' %>
|
|
775
|
-
#
|
|
776
|
-
# # "https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
777
|
-
#
|
|
778
|
-
# @example Enable Push Promise/Early Hints
|
|
779
|
-
#
|
|
780
|
-
# <%= asset_path "application.js", push: :script %>
|
|
781
|
-
def asset_path(source, push: false, as: nil)
|
|
782
|
-
_asset_url(source, push: push, as: as) { _relative_url(source) }
|
|
783
|
-
end
|
|
784
|
-
|
|
785
|
-
# It generates the absolute URL for the given source.
|
|
786
|
-
#
|
|
787
|
-
# It can be the name of the asset, coming from the sources or third party
|
|
788
|
-
# gems.
|
|
789
|
-
#
|
|
790
|
-
# Absolute URLs are returned as they are.
|
|
791
|
-
#
|
|
792
|
-
# If Fingerprint mode is on, it returns the fingerprint URL of the source
|
|
793
|
-
#
|
|
794
|
-
# If CDN mode is on, it returns the absolute URL of the asset.
|
|
795
|
-
#
|
|
796
|
-
# @param source [String] the asset name
|
|
797
|
-
# @param push [TrueClass, FalseClass, Symbol] HTTP/2 Push Promise/Early Hints flag, or type
|
|
798
|
-
# @param as [Symbol] HTTP/2 Push Promise / Early Hints flag type
|
|
799
|
-
#
|
|
800
|
-
# @return [String] the asset URL
|
|
801
|
-
#
|
|
802
|
-
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
803
|
-
# `subresource_integrity` modes are on and the asset is missing
|
|
804
|
-
# from the manifest
|
|
805
|
-
#
|
|
806
|
-
# @since 0.1.0
|
|
807
|
-
#
|
|
808
|
-
# @example Basic Usage
|
|
809
|
-
#
|
|
810
|
-
# <%= asset_url 'application.js' %>
|
|
811
|
-
#
|
|
812
|
-
# # "https://bookshelf.org/assets/application.js"
|
|
813
|
-
#
|
|
814
|
-
# @example Absolute URL
|
|
815
|
-
#
|
|
816
|
-
# <%= asset_url 'https://code.jquery.com/jquery-2.1.4.min.js' %>
|
|
817
|
-
#
|
|
818
|
-
# # "https://code.jquery.com/jquery-2.1.4.min.js"
|
|
819
|
-
#
|
|
820
|
-
# @example Fingerprint Mode
|
|
821
|
-
#
|
|
822
|
-
# <%= asset_url 'application.js' %>
|
|
823
|
-
#
|
|
824
|
-
# # "https://bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
825
|
-
#
|
|
826
|
-
# @example CDN Mode
|
|
827
|
-
#
|
|
828
|
-
# <%= asset_url 'application.js' %>
|
|
829
|
-
#
|
|
830
|
-
# # "https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
831
|
-
#
|
|
832
|
-
# @example Enable Push Promise/Early Hints
|
|
833
|
-
#
|
|
834
|
-
# <%= asset_url "application.js", push: :script %>
|
|
835
|
-
def asset_url(source, push: false, as: nil)
|
|
836
|
-
_asset_url(source, push: push, as: as) { _absolute_url(source) }
|
|
837
|
-
end
|
|
838
|
-
|
|
839
|
-
private
|
|
840
|
-
|
|
841
|
-
# @since 0.1.0
|
|
842
|
-
# @api private
|
|
843
|
-
def _safe_tags(*sources)
|
|
844
|
-
::Hanami::Utils::Escape::SafeString.new(
|
|
845
|
-
sources.map do |source|
|
|
846
|
-
yield source
|
|
847
|
-
end.join(NEW_LINE_SEPARATOR)
|
|
848
|
-
)
|
|
849
|
-
end
|
|
850
|
-
|
|
851
|
-
# @since 0.1.0
|
|
852
|
-
# @api private
|
|
853
|
-
def _asset_url(source, push:, as:)
|
|
854
|
-
url = _absolute_url?(source) ? source : yield
|
|
855
|
-
|
|
856
|
-
case push
|
|
857
|
-
when Symbol
|
|
858
|
-
_push_promise(url, as: push)
|
|
859
|
-
when TrueClass
|
|
860
|
-
_push_promise(url, as: as)
|
|
861
|
-
end
|
|
862
|
-
|
|
863
|
-
url
|
|
864
|
-
end
|
|
865
|
-
|
|
866
|
-
# @since 0.1.0
|
|
867
|
-
# @api private
|
|
868
|
-
def _typed_asset_path(source, ext, push: false, as: nil)
|
|
869
|
-
source = "#{source}#{ext}" if _append_extension?(source, ext)
|
|
870
|
-
asset_path(source, push: push, as: as)
|
|
871
|
-
end
|
|
872
|
-
|
|
873
|
-
# @api private
|
|
874
|
-
def _subresource_integrity?
|
|
875
|
-
!!self.class.assets_configuration.subresource_integrity
|
|
876
|
-
end
|
|
877
|
-
|
|
878
|
-
# @api private
|
|
879
|
-
def _subresource_integrity_value(source, ext)
|
|
880
|
-
source = "#{source}#{ext}" unless source =~ /#{Regexp.escape(ext)}\z/
|
|
881
|
-
self.class.assets_configuration.subresource_integrity_value(source) unless _absolute_url?(source)
|
|
882
|
-
end
|
|
883
|
-
|
|
884
|
-
# @since 0.1.0
|
|
885
|
-
# @api private
|
|
886
|
-
def _absolute_url?(source)
|
|
887
|
-
ABSOLUTE_URL_MATCHER.match(source)
|
|
888
|
-
end
|
|
889
|
-
|
|
890
|
-
# @since 1.2.0
|
|
891
|
-
# @api private
|
|
892
|
-
def _crossorigin?(source)
|
|
893
|
-
return false unless _absolute_url?(source)
|
|
894
|
-
|
|
895
|
-
self.class.assets_configuration.crossorigin?(source)
|
|
896
|
-
end
|
|
897
|
-
|
|
898
|
-
# @since 0.1.0
|
|
899
|
-
# @api private
|
|
900
|
-
def _relative_url(source)
|
|
901
|
-
self.class.assets_configuration.asset_path(source)
|
|
902
|
-
end
|
|
903
|
-
|
|
904
|
-
# @since 0.1.0
|
|
905
|
-
# @api private
|
|
906
|
-
def _absolute_url(source)
|
|
907
|
-
self.class.assets_configuration.asset_url(source)
|
|
908
|
-
end
|
|
909
|
-
|
|
910
|
-
# @since 0.1.0
|
|
911
|
-
# @api private
|
|
912
|
-
def _source_options(src, options, as:, &_blk)
|
|
913
|
-
options ||= {}
|
|
914
|
-
|
|
915
|
-
if src.respond_to?(:to_hash)
|
|
916
|
-
options = src.to_hash
|
|
917
|
-
elsif src
|
|
918
|
-
options[:src] = asset_path(src, push: options.delete(:push) || false, as: as)
|
|
919
|
-
end
|
|
920
|
-
|
|
921
|
-
if !options[:src] && !block_given?
|
|
922
|
-
raise ArgumentError.new("You should provide a source via `src` option or with a `source` HTML tag")
|
|
923
|
-
end
|
|
924
|
-
|
|
925
|
-
options
|
|
926
|
-
end
|
|
927
|
-
|
|
928
|
-
# @since 0.1.0
|
|
929
|
-
# @api private
|
|
930
|
-
def _push_promise(url, as: nil)
|
|
931
|
-
Thread.current[:__hanami_assets] ||= {}
|
|
932
|
-
Thread.current[:__hanami_assets][url.to_s] = {as: as, crossorigin: _crossorigin?(url)}
|
|
933
|
-
|
|
934
|
-
url
|
|
935
|
-
end
|
|
936
|
-
|
|
937
|
-
# @since 1.1.0
|
|
938
|
-
# @api private
|
|
939
|
-
def _append_extension?(source, ext)
|
|
940
|
-
source !~ QUERY_STRING_MATCHER && source !~ /#{Regexp.escape(ext)}\z/
|
|
941
|
-
end
|
|
942
|
-
end
|
|
943
|
-
# rubocop:enable Metrics/ModuleLength
|
|
944
|
-
end
|
|
945
|
-
end
|