piko-lite-box 0.0.1
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 +7 -0
- data/hanami-3.0.1/CHANGELOG.md +1701 -0
- data/hanami-3.0.1/LICENSE +20 -0
- data/hanami-3.0.1/README.md +89 -0
- data/hanami-3.0.1/hanami.gemspec +49 -0
- data/hanami-3.0.1/lib/hanami/app.rb +197 -0
- data/hanami-3.0.1/lib/hanami/boot.rb +5 -0
- data/hanami-3.0.1/lib/hanami/config/actions/content_security_policy.rb +140 -0
- data/hanami-3.0.1/lib/hanami/config/actions/cookies.rb +57 -0
- data/hanami-3.0.1/lib/hanami/config/actions/sessions.rb +83 -0
- data/hanami-3.0.1/lib/hanami/config/actions.rb +189 -0
- data/hanami-3.0.1/lib/hanami/config/assets.rb +84 -0
- data/hanami-3.0.1/lib/hanami/config/console.rb +79 -0
- data/hanami-3.0.1/lib/hanami/config/db.rb +35 -0
- data/hanami-3.0.1/lib/hanami/config/i18n.rb +138 -0
- data/hanami-3.0.1/lib/hanami/config/logger.rb +207 -0
- data/hanami-3.0.1/lib/hanami/config/null_config.rb +17 -0
- data/hanami-3.0.1/lib/hanami/config/router.rb +48 -0
- data/hanami-3.0.1/lib/hanami/config/views.rb +103 -0
- data/hanami-3.0.1/lib/hanami/config.rb +564 -0
- data/hanami-3.0.1/lib/hanami/constants.rb +62 -0
- data/hanami-3.0.1/lib/hanami/env.rb +52 -0
- data/hanami-3.0.1/lib/hanami/errors.rb +41 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/i18n_helper.rb +64 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/name_inferrer.rb +34 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/slice_configured_action.rb +190 -0
- data/hanami-3.0.1/lib/hanami/extensions/action.rb +147 -0
- data/hanami-3.0.1/lib/hanami/extensions/db/repo.rb +108 -0
- data/hanami-3.0.1/lib/hanami/extensions/mailer/slice_configured_mailer.rb +134 -0
- data/hanami-3.0.1/lib/hanami/extensions/mailer.rb +28 -0
- data/hanami-3.0.1/lib/hanami/extensions/operation/slice_configured_db_operation.rb +90 -0
- data/hanami-3.0.1/lib/hanami/extensions/operation.rb +33 -0
- data/hanami-3.0.1/lib/hanami/extensions/router/errors.rb +58 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/context.rb +298 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/part.rb +92 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/scope.rb +36 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_context.rb +73 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_helpers.rb +55 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_part.rb +73 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_view.rb +243 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/standard_helpers.rb +26 -0
- data/hanami-3.0.1/lib/hanami/extensions/view.rb +38 -0
- data/hanami-3.0.1/lib/hanami/extensions.rb +30 -0
- data/hanami-3.0.1/lib/hanami/helpers/assets_helper.rb +804 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper/form_builder.rb +1389 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper/values.rb +75 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper.rb +213 -0
- data/hanami-3.0.1/lib/hanami/helpers/i18n_helper.rb +241 -0
- data/hanami-3.0.1/lib/hanami/logger/rack_formatter.rb +73 -0
- data/hanami-3.0.1/lib/hanami/logger/sql_formatter.rb +80 -0
- data/hanami-3.0.1/lib/hanami/logger/sql_logger.rb +48 -0
- data/hanami-3.0.1/lib/hanami/middleware/assets.rb +21 -0
- data/hanami-3.0.1/lib/hanami/middleware/content_security_policy_nonce.rb +53 -0
- data/hanami-3.0.1/lib/hanami/middleware/public_errors_app.rb +75 -0
- data/hanami-3.0.1/lib/hanami/middleware/render_errors.rb +90 -0
- data/hanami-3.0.1/lib/hanami/port.rb +45 -0
- data/hanami-3.0.1/lib/hanami/prepare.rb +5 -0
- data/hanami-3.0.1/lib/hanami/provider/source.rb +16 -0
- data/hanami-3.0.1/lib/hanami/provider_registrar.rb +28 -0
- data/hanami-3.0.1/lib/hanami/providers/assets.rb +28 -0
- data/hanami-3.0.1/lib/hanami/providers/db/adapter.rb +75 -0
- data/hanami-3.0.1/lib/hanami/providers/db/adapters.rb +66 -0
- data/hanami-3.0.1/lib/hanami/providers/db/config.rb +44 -0
- data/hanami-3.0.1/lib/hanami/providers/db/gateway.rb +87 -0
- data/hanami-3.0.1/lib/hanami/providers/db/sql_adapter.rb +100 -0
- data/hanami-3.0.1/lib/hanami/providers/db.rb +325 -0
- data/hanami-3.0.1/lib/hanami/providers/db_logging.rb +19 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n/backend.rb +373 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n/locale/en.yml +57 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n.rb +114 -0
- data/hanami-3.0.1/lib/hanami/providers/inflector.rb +17 -0
- data/hanami-3.0.1/lib/hanami/providers/logger.rb +41 -0
- data/hanami-3.0.1/lib/hanami/providers/mailers.rb +101 -0
- data/hanami-3.0.1/lib/hanami/providers/rack.rb +47 -0
- data/hanami-3.0.1/lib/hanami/providers/relations.rb +31 -0
- data/hanami-3.0.1/lib/hanami/providers/routes.rb +29 -0
- data/hanami-3.0.1/lib/hanami/rake_tasks.rb +54 -0
- data/hanami-3.0.1/lib/hanami/routes.rb +146 -0
- data/hanami-3.0.1/lib/hanami/settings/composite_store.rb +53 -0
- data/hanami-3.0.1/lib/hanami/settings/env_store.rb +32 -0
- data/hanami-3.0.1/lib/hanami/settings.rb +234 -0
- data/hanami-3.0.1/lib/hanami/setup.rb +6 -0
- data/hanami-3.0.1/lib/hanami/slice/router.rb +280 -0
- data/hanami-3.0.1/lib/hanami/slice/routes_helper.rb +37 -0
- data/hanami-3.0.1/lib/hanami/slice/routing/middleware/stack.rb +216 -0
- data/hanami-3.0.1/lib/hanami/slice/routing/resolver.rb +88 -0
- data/hanami-3.0.1/lib/hanami/slice/view_name_inferrer.rb +63 -0
- data/hanami-3.0.1/lib/hanami/slice.rb +1239 -0
- data/hanami-3.0.1/lib/hanami/slice_configurable.rb +72 -0
- data/hanami-3.0.1/lib/hanami/slice_name.rb +111 -0
- data/hanami-3.0.1/lib/hanami/slice_registrar.rb +215 -0
- data/hanami-3.0.1/lib/hanami/universal_logger.rb +250 -0
- data/hanami-3.0.1/lib/hanami/version.rb +45 -0
- data/hanami-3.0.1/lib/hanami/web/rack_logger.rb +126 -0
- data/hanami-3.0.1/lib/hanami/web/welcome.html.erb +584 -0
- data/hanami-3.0.1/lib/hanami/web/welcome.rb +46 -0
- data/hanami-3.0.1/lib/hanami.rb +276 -0
- data/piko-lite-box.gemspec +11 -0
- metadata +137 -0
|
@@ -0,0 +1,804 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
require "hanami/view"
|
|
5
|
+
require_relative "../constants"
|
|
6
|
+
|
|
7
|
+
module Hanami
|
|
8
|
+
module Helpers
|
|
9
|
+
# HTML assets helpers
|
|
10
|
+
#
|
|
11
|
+
# Inject these helpers in a view
|
|
12
|
+
#
|
|
13
|
+
# @since 2.1.0
|
|
14
|
+
#
|
|
15
|
+
# @see http://www.rubydoc.info/gems/hanami-helpers/Hanami/Helpers/HtmlHelper
|
|
16
|
+
module AssetsHelper
|
|
17
|
+
# @since 2.1.0
|
|
18
|
+
# @api private
|
|
19
|
+
NEW_LINE_SEPARATOR = "\n"
|
|
20
|
+
|
|
21
|
+
# @since 2.1.0
|
|
22
|
+
# @api private
|
|
23
|
+
WILDCARD_EXT = ".*"
|
|
24
|
+
|
|
25
|
+
# @since 2.1.0
|
|
26
|
+
# @api private
|
|
27
|
+
JAVASCRIPT_EXT = ".js"
|
|
28
|
+
|
|
29
|
+
# @since 2.1.0
|
|
30
|
+
# @api private
|
|
31
|
+
STYLESHEET_EXT = ".css"
|
|
32
|
+
|
|
33
|
+
# @since 2.1.0
|
|
34
|
+
# @api private
|
|
35
|
+
JAVASCRIPT_MIME_TYPE = "text/javascript"
|
|
36
|
+
|
|
37
|
+
# @since 2.1.0
|
|
38
|
+
# @api private
|
|
39
|
+
STYLESHEET_MIME_TYPE = "text/css"
|
|
40
|
+
|
|
41
|
+
# @since 2.1.0
|
|
42
|
+
# @api private
|
|
43
|
+
FAVICON_MIME_TYPE = "image/x-icon"
|
|
44
|
+
|
|
45
|
+
# @since 2.1.0
|
|
46
|
+
# @api private
|
|
47
|
+
STYLESHEET_REL = "stylesheet"
|
|
48
|
+
|
|
49
|
+
# @since 2.1.0
|
|
50
|
+
# @api private
|
|
51
|
+
FAVICON_REL = "shortcut icon"
|
|
52
|
+
|
|
53
|
+
# @since 2.1.0
|
|
54
|
+
# @api private
|
|
55
|
+
DEFAULT_FAVICON = "favicon.ico"
|
|
56
|
+
|
|
57
|
+
# @since 0.3.0
|
|
58
|
+
# @api private
|
|
59
|
+
CROSSORIGIN_ANONYMOUS = "anonymous"
|
|
60
|
+
|
|
61
|
+
# @since 0.3.0
|
|
62
|
+
# @api private
|
|
63
|
+
# TODO: we can drop the defined?-check and fallback once Ruby 3.3 becomes our minimum required version
|
|
64
|
+
ABSOLUTE_URL_MATCHER = (
|
|
65
|
+
defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER
|
|
66
|
+
).make_regexp
|
|
67
|
+
|
|
68
|
+
# @since 1.1.0
|
|
69
|
+
# @api private
|
|
70
|
+
QUERY_STRING_MATCHER = /\?/
|
|
71
|
+
|
|
72
|
+
include Hanami::View::Helpers::TagHelper
|
|
73
|
+
|
|
74
|
+
# Generate `script` tag for given source(s)
|
|
75
|
+
#
|
|
76
|
+
# It accepts one or more strings representing the name of the asset, if it
|
|
77
|
+
# comes from the application or third party gems. It also accepts strings
|
|
78
|
+
# representing absolute URLs in case of public CDN (eg. jQuery CDN).
|
|
79
|
+
#
|
|
80
|
+
# If the "fingerprint mode" is on, `src` is the fingerprinted
|
|
81
|
+
# version of the relative URL.
|
|
82
|
+
#
|
|
83
|
+
# If the "CDN mode" is on, the `src` is an absolute URL of the
|
|
84
|
+
# application CDN.
|
|
85
|
+
#
|
|
86
|
+
# If the "subresource integrity mode" is on, `integrity` is the
|
|
87
|
+
# name of the algorithm, then a hyphen, then the hash value of the file.
|
|
88
|
+
# If more than one algorithm is used, they"ll be separated by a space.
|
|
89
|
+
#
|
|
90
|
+
# If the Content Security Policy uses 'nonce' and the source is not
|
|
91
|
+
# absolute, the nonce value of the current request is automatically added
|
|
92
|
+
# as an attribute. You can override this with the `nonce: false` option.
|
|
93
|
+
# See {#content_security_policy_nonce} for more.
|
|
94
|
+
#
|
|
95
|
+
# @param sources [Array<String, #url>] one or more assets by name or absolute URL
|
|
96
|
+
#
|
|
97
|
+
# @return [Hanami::View::HTML::SafeString] the markup
|
|
98
|
+
#
|
|
99
|
+
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
100
|
+
# `subresource_integrity` modes are on and the javascript file is missing
|
|
101
|
+
# from the manifest
|
|
102
|
+
#
|
|
103
|
+
# @since 2.1.0
|
|
104
|
+
#
|
|
105
|
+
# @see Hanami::Assets::Helpers#path
|
|
106
|
+
#
|
|
107
|
+
# @example Single Asset
|
|
108
|
+
#
|
|
109
|
+
# <%= javascript_tag "application" %>
|
|
110
|
+
#
|
|
111
|
+
# # <script src="/assets/application.js" type="text/javascript"></script>
|
|
112
|
+
#
|
|
113
|
+
# @example Multiple Assets
|
|
114
|
+
#
|
|
115
|
+
# <%= javascript_tag "application", "dashboard" %>
|
|
116
|
+
#
|
|
117
|
+
# # <script src="/assets/application.js" type="text/javascript"></script>
|
|
118
|
+
# # <script src="/assets/dashboard.js" type="text/javascript"></script>
|
|
119
|
+
#
|
|
120
|
+
# @example Asynchronous Execution
|
|
121
|
+
#
|
|
122
|
+
# <%= javascript_tag "application", async: true %>
|
|
123
|
+
#
|
|
124
|
+
# # <script src="/assets/application.js" type="text/javascript" async="async"></script>
|
|
125
|
+
#
|
|
126
|
+
# @example Subresource Integrity
|
|
127
|
+
#
|
|
128
|
+
# <%= javascript_tag "application" %>
|
|
129
|
+
#
|
|
130
|
+
# # <script src="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
131
|
+
# # type="text/javascript" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
132
|
+
#
|
|
133
|
+
# @example Subresource Integrity for 3rd Party Scripts
|
|
134
|
+
#
|
|
135
|
+
# <%= javascript_tag "https://example.com/assets/example.js", integrity: "sha384-oqVu...Y8wC" %>
|
|
136
|
+
#
|
|
137
|
+
# # <script src="https://example.com/assets/example.js" type="text/javascript"
|
|
138
|
+
# # integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
139
|
+
#
|
|
140
|
+
# @example Deferred Execution
|
|
141
|
+
#
|
|
142
|
+
# <%= javascript_tag "application", defer: true %>
|
|
143
|
+
#
|
|
144
|
+
# # <script src="/assets/application.js" type="text/javascript" defer="defer"></script>
|
|
145
|
+
#
|
|
146
|
+
# @example Disable nonce
|
|
147
|
+
#
|
|
148
|
+
# <%= javascript_tag "application", nonce: false %>
|
|
149
|
+
#
|
|
150
|
+
# @example Absolute URL
|
|
151
|
+
#
|
|
152
|
+
# <%= javascript_tag "https://code.jquery.com/jquery-2.1.4.min.js" %>
|
|
153
|
+
#
|
|
154
|
+
# # <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
|
|
155
|
+
#
|
|
156
|
+
# @example Fingerprint Mode
|
|
157
|
+
#
|
|
158
|
+
# <%= javascript_tag "application" %>
|
|
159
|
+
#
|
|
160
|
+
# # <script src="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js" type="text/javascript"></script>
|
|
161
|
+
#
|
|
162
|
+
# @example CDN Mode
|
|
163
|
+
#
|
|
164
|
+
# <%= javascript_tag "application" %>
|
|
165
|
+
#
|
|
166
|
+
# # <script src="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
167
|
+
# # type="text/javascript"></script>
|
|
168
|
+
def javascript_tag(*sources, **options)
|
|
169
|
+
options = options.reject { |k, _| k.to_sym == :src }
|
|
170
|
+
nonce_option = options.delete(:nonce)
|
|
171
|
+
|
|
172
|
+
_safe_tags(*sources) do |source|
|
|
173
|
+
attributes = {
|
|
174
|
+
src: _typed_url(source, JAVASCRIPT_EXT),
|
|
175
|
+
type: JAVASCRIPT_MIME_TYPE,
|
|
176
|
+
nonce: _nonce(source, nonce_option)
|
|
177
|
+
}
|
|
178
|
+
attributes.merge!(options)
|
|
179
|
+
|
|
180
|
+
if _context.assets.subresource_integrity? || attributes.include?(:integrity)
|
|
181
|
+
attributes[:integrity] ||= _subresource_integrity_value(source, JAVASCRIPT_EXT)
|
|
182
|
+
attributes[:crossorigin] ||= CROSSORIGIN_ANONYMOUS
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
tag.script(**attributes).to_s
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Generate `link` tag for given source(s)
|
|
190
|
+
#
|
|
191
|
+
# It accepts one or more strings representing the name of the asset, if it
|
|
192
|
+
# comes from the application or third party gems. It also accepts strings
|
|
193
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
194
|
+
#
|
|
195
|
+
# If the "fingerprint mode" is on, `href` is the fingerprinted
|
|
196
|
+
# version of the relative URL.
|
|
197
|
+
#
|
|
198
|
+
# If the "CDN mode" is on, the `href` is an absolute URL of the
|
|
199
|
+
# application CDN.
|
|
200
|
+
#
|
|
201
|
+
# If the "subresource integrity mode" is on, `integrity` is the
|
|
202
|
+
# name of the algorithm, then a hyphen, then the hashed value of the file.
|
|
203
|
+
# If more than one algorithm is used, they"ll be separated by a space.
|
|
204
|
+
#
|
|
205
|
+
# If the Content Security Policy uses 'nonce' and the source is not
|
|
206
|
+
# absolute, the nonce value of the current request is automatically added
|
|
207
|
+
# as an attribute. You can override this with the `nonce: false` option.
|
|
208
|
+
# See {#content_security_policy_nonce} for more.
|
|
209
|
+
#
|
|
210
|
+
# @param sources [Array<String, #url>] one or more assets by name or absolute URL
|
|
211
|
+
#
|
|
212
|
+
# @return [Hanami::View::HTML::SafeString] the markup
|
|
213
|
+
#
|
|
214
|
+
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
215
|
+
# `subresource_integrity` modes are on and the stylesheet file is missing
|
|
216
|
+
# from the manifest
|
|
217
|
+
#
|
|
218
|
+
# @since 2.1.0
|
|
219
|
+
#
|
|
220
|
+
# @see Hanami::Assets::Helpers#path
|
|
221
|
+
#
|
|
222
|
+
# @example Single Asset
|
|
223
|
+
#
|
|
224
|
+
# <%= stylesheet_tag "application" %>
|
|
225
|
+
#
|
|
226
|
+
# # <link href="/assets/application.css" type="text/css" rel="stylesheet">
|
|
227
|
+
#
|
|
228
|
+
# @example Multiple Assets
|
|
229
|
+
#
|
|
230
|
+
# <%= stylesheet_tag "application", "dashboard" %>
|
|
231
|
+
#
|
|
232
|
+
# # <link href="/assets/application.css" type="text/css" rel="stylesheet">
|
|
233
|
+
# # <link href="/assets/dashboard.css" type="text/css" rel="stylesheet">
|
|
234
|
+
#
|
|
235
|
+
# @example Disable nonce
|
|
236
|
+
#
|
|
237
|
+
# <%= stylesheet_tag "application", nonce: false %>
|
|
238
|
+
#
|
|
239
|
+
# @example Subresource Integrity
|
|
240
|
+
#
|
|
241
|
+
# <%= stylesheet_tag "application" %>
|
|
242
|
+
#
|
|
243
|
+
# # <link href="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css"
|
|
244
|
+
# # type="text/css" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
245
|
+
#
|
|
246
|
+
# @example Subresource Integrity for 3rd Party Assets
|
|
247
|
+
#
|
|
248
|
+
# <%= stylesheet_tag "https://example.com/assets/example.css", integrity: "sha384-oqVu...Y8wC" %>
|
|
249
|
+
#
|
|
250
|
+
# # <link href="https://example.com/assets/example.css"
|
|
251
|
+
# # type="text/css" rel="stylesheet" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
|
|
252
|
+
#
|
|
253
|
+
# @example Absolute URL
|
|
254
|
+
#
|
|
255
|
+
# <%= stylesheet_tag "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" %>
|
|
256
|
+
#
|
|
257
|
+
# # <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
|
|
258
|
+
# # type="text/css" rel="stylesheet">
|
|
259
|
+
#
|
|
260
|
+
# @example Fingerprint Mode
|
|
261
|
+
#
|
|
262
|
+
# <%= stylesheet_tag "application" %>
|
|
263
|
+
#
|
|
264
|
+
# # <link href="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css" type="text/css" rel="stylesheet">
|
|
265
|
+
#
|
|
266
|
+
# @example CDN Mode
|
|
267
|
+
#
|
|
268
|
+
# <%= stylesheet_tag "application" %>
|
|
269
|
+
#
|
|
270
|
+
# # <link href="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css"
|
|
271
|
+
# # type="text/css" rel="stylesheet">
|
|
272
|
+
def stylesheet_tag(*sources, **options)
|
|
273
|
+
options = options.reject { |k, _| k.to_sym == :href }
|
|
274
|
+
nonce_option = options.delete(:nonce)
|
|
275
|
+
|
|
276
|
+
_safe_tags(*sources) do |source|
|
|
277
|
+
attributes = {
|
|
278
|
+
href: _typed_url(source, STYLESHEET_EXT),
|
|
279
|
+
type: STYLESHEET_MIME_TYPE,
|
|
280
|
+
rel: STYLESHEET_REL,
|
|
281
|
+
nonce: _nonce(source, nonce_option)
|
|
282
|
+
}
|
|
283
|
+
attributes.merge!(options)
|
|
284
|
+
|
|
285
|
+
if _context.assets.subresource_integrity? || attributes.include?(:integrity)
|
|
286
|
+
attributes[:integrity] ||= _subresource_integrity_value(source, STYLESHEET_EXT)
|
|
287
|
+
attributes[:crossorigin] ||= CROSSORIGIN_ANONYMOUS
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
tag.link(**attributes).to_s
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Generate `img` tag for given source
|
|
295
|
+
#
|
|
296
|
+
# It accepts one string representing the name of the asset, if it comes
|
|
297
|
+
# from the application or third party gems. It also accepts strings
|
|
298
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
299
|
+
#
|
|
300
|
+
# `alt` Attribute is auto generated from `src`.
|
|
301
|
+
# You can specify a different value, by passing the `:src` option.
|
|
302
|
+
#
|
|
303
|
+
# If the "fingerprint mode" is on, `src` is the fingerprinted
|
|
304
|
+
# version of the relative URL.
|
|
305
|
+
#
|
|
306
|
+
# If the "CDN mode" is on, the `src` is an absolute URL of the
|
|
307
|
+
# application CDN.
|
|
308
|
+
#
|
|
309
|
+
# @param source [String, #url] asset name, absolute URL, or asset object
|
|
310
|
+
# @param options [Hash] HTML 5 attributes
|
|
311
|
+
#
|
|
312
|
+
# @return [Hanami::View::HTML::SafeString] the markup
|
|
313
|
+
#
|
|
314
|
+
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
315
|
+
# `subresource_integrity` modes are on and the image file is missing
|
|
316
|
+
# from the manifest
|
|
317
|
+
#
|
|
318
|
+
# @since 2.1.0
|
|
319
|
+
#
|
|
320
|
+
# @see Hanami::Assets::Helpers#path
|
|
321
|
+
#
|
|
322
|
+
# @example Basic Usage
|
|
323
|
+
#
|
|
324
|
+
# <%= image_tag "logo.png" %>
|
|
325
|
+
#
|
|
326
|
+
# # <img src="/assets/logo.png" alt="Logo">
|
|
327
|
+
#
|
|
328
|
+
# @example Custom alt Attribute
|
|
329
|
+
#
|
|
330
|
+
# <%= image_tag "logo.png", alt: "Application Logo" %>
|
|
331
|
+
#
|
|
332
|
+
# # <img src="/assets/logo.png" alt="Application Logo">
|
|
333
|
+
#
|
|
334
|
+
# @example Custom HTML Attributes
|
|
335
|
+
#
|
|
336
|
+
# <%= image_tag "logo.png", id: "logo", class: "image" %>
|
|
337
|
+
#
|
|
338
|
+
# # <img src="/assets/logo.png" alt="Logo" id="logo" class="image">
|
|
339
|
+
#
|
|
340
|
+
# @example Absolute URL
|
|
341
|
+
#
|
|
342
|
+
# <%= image_tag "https://example-cdn.com/images/logo.png" %>
|
|
343
|
+
#
|
|
344
|
+
# # <img src="https://example-cdn.com/images/logo.png" alt="Logo">
|
|
345
|
+
#
|
|
346
|
+
# @example Fingerprint Mode
|
|
347
|
+
#
|
|
348
|
+
# <%= image_tag "logo.png" %>
|
|
349
|
+
#
|
|
350
|
+
# # <img src="/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
|
|
351
|
+
#
|
|
352
|
+
# @example CDN Mode
|
|
353
|
+
#
|
|
354
|
+
# <%= image_tag "logo.png" %>
|
|
355
|
+
#
|
|
356
|
+
# # <img src="https://assets.bookshelf.org/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
|
|
357
|
+
def image_tag(source, options = {})
|
|
358
|
+
options = options.reject { |k, _| k.to_sym == :src }
|
|
359
|
+
attributes = {
|
|
360
|
+
src: asset_url(source),
|
|
361
|
+
alt: _context.inflector.humanize(::File.basename(source, WILDCARD_EXT))
|
|
362
|
+
}
|
|
363
|
+
attributes.merge!(options)
|
|
364
|
+
|
|
365
|
+
tag.img(**attributes)
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# Generate `link` tag application favicon.
|
|
369
|
+
#
|
|
370
|
+
# If no argument is given, it assumes `favico.ico` from the application.
|
|
371
|
+
#
|
|
372
|
+
# It accepts one string representing the name of the asset.
|
|
373
|
+
#
|
|
374
|
+
# If the "fingerprint mode" is on, `href` is the fingerprinted version
|
|
375
|
+
# of the relative URL.
|
|
376
|
+
#
|
|
377
|
+
# If the "CDN mode" is on, the `href` is an absolute URL of the
|
|
378
|
+
# application CDN.
|
|
379
|
+
#
|
|
380
|
+
# @param source [String, #url] asset name or asset object
|
|
381
|
+
# @param options [Hash] HTML 5 attributes
|
|
382
|
+
#
|
|
383
|
+
# @return [Hanami::View::HTML::SafeString] the markup
|
|
384
|
+
#
|
|
385
|
+
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
386
|
+
# `subresource_integrity` modes are on and the favicon is file missing
|
|
387
|
+
# from the manifest
|
|
388
|
+
#
|
|
389
|
+
# @since 2.1.0
|
|
390
|
+
#
|
|
391
|
+
# @see Hanami::Assets::Helpers#path
|
|
392
|
+
#
|
|
393
|
+
# @example Basic Usage
|
|
394
|
+
#
|
|
395
|
+
# <%= favicon_tag %>
|
|
396
|
+
#
|
|
397
|
+
# # <link href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
|
398
|
+
#
|
|
399
|
+
# @example Custom Path
|
|
400
|
+
#
|
|
401
|
+
# <%= favicon_tag "fav.ico" %>
|
|
402
|
+
#
|
|
403
|
+
# # <link href="/assets/fav.ico" rel="shortcut icon" type="image/x-icon">
|
|
404
|
+
#
|
|
405
|
+
# @example Custom HTML Attributes
|
|
406
|
+
#
|
|
407
|
+
# <%= favicon_tag "favicon.ico", id: "fav" %>
|
|
408
|
+
#
|
|
409
|
+
# # <link id="fav" href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
|
410
|
+
#
|
|
411
|
+
# @example Fingerprint Mode
|
|
412
|
+
#
|
|
413
|
+
# <%= favicon_tag %>
|
|
414
|
+
#
|
|
415
|
+
# # <link href="/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico" rel="shortcut icon" type="image/x-icon">
|
|
416
|
+
#
|
|
417
|
+
# @example CDN Mode
|
|
418
|
+
#
|
|
419
|
+
# <%= favicon_tag %>
|
|
420
|
+
#
|
|
421
|
+
# # <link href="https://assets.bookshelf.org/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico"
|
|
422
|
+
# rel="shortcut icon" type="image/x-icon">
|
|
423
|
+
def favicon_tag(source = DEFAULT_FAVICON, options = {})
|
|
424
|
+
options = options.reject { |k, _| k.to_sym == :href }
|
|
425
|
+
|
|
426
|
+
attributes = {
|
|
427
|
+
href: asset_url(source),
|
|
428
|
+
rel: FAVICON_REL,
|
|
429
|
+
type: FAVICON_MIME_TYPE
|
|
430
|
+
}
|
|
431
|
+
attributes.merge!(options)
|
|
432
|
+
|
|
433
|
+
tag.link(**attributes)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# Generate `video` tag for given source
|
|
437
|
+
#
|
|
438
|
+
# It accepts one string representing the name of the asset, if it comes
|
|
439
|
+
# from the application or third party gems. It also accepts strings
|
|
440
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
441
|
+
#
|
|
442
|
+
# Alternatively, it accepts a block that allows to specify one or more
|
|
443
|
+
# sources via the `source` tag.
|
|
444
|
+
#
|
|
445
|
+
# If the "fingerprint mode" is on, `src` is the fingerprinted
|
|
446
|
+
# version of the relative URL.
|
|
447
|
+
#
|
|
448
|
+
# If the "CDN mode" is on, the `src` is an absolute URL of the
|
|
449
|
+
# application CDN.
|
|
450
|
+
#
|
|
451
|
+
# @param source [String, #url] asset name, absolute URL or asset object
|
|
452
|
+
# @param options [Hash] HTML 5 attributes
|
|
453
|
+
#
|
|
454
|
+
# @return [Hanami::View::HTML::SafeString] the markup
|
|
455
|
+
#
|
|
456
|
+
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
457
|
+
# `subresource_integrity` modes are on and the video file is missing
|
|
458
|
+
# from the manifest
|
|
459
|
+
#
|
|
460
|
+
# @raise [ArgumentError] if source isn"t specified both as argument or
|
|
461
|
+
# tag inside the given block
|
|
462
|
+
#
|
|
463
|
+
# @since 2.1.0
|
|
464
|
+
#
|
|
465
|
+
# @see Hanami::Assets::Helpers#path
|
|
466
|
+
#
|
|
467
|
+
# @example Basic Usage
|
|
468
|
+
#
|
|
469
|
+
# <%= video_tag "movie.mp4" %>
|
|
470
|
+
#
|
|
471
|
+
# # <video src="/assets/movie.mp4"></video>
|
|
472
|
+
#
|
|
473
|
+
# @example Absolute URL
|
|
474
|
+
#
|
|
475
|
+
# <%= video_tag "https://example-cdn.com/assets/movie.mp4" %>
|
|
476
|
+
#
|
|
477
|
+
# # <video src="https://example-cdn.com/assets/movie.mp4"></video>
|
|
478
|
+
#
|
|
479
|
+
# @example Custom HTML Attributes
|
|
480
|
+
#
|
|
481
|
+
# <%= video_tag("movie.mp4", autoplay: true, controls: true) %>
|
|
482
|
+
#
|
|
483
|
+
# # <video src="/assets/movie.mp4" autoplay="autoplay" controls="controls"></video>
|
|
484
|
+
#
|
|
485
|
+
# @example Fallback Content
|
|
486
|
+
#
|
|
487
|
+
# <%=
|
|
488
|
+
# video("movie.mp4") do
|
|
489
|
+
# "Your browser does not support the video tag"
|
|
490
|
+
# end
|
|
491
|
+
# %>
|
|
492
|
+
#
|
|
493
|
+
# # <video src="/assets/movie.mp4">
|
|
494
|
+
# # Your browser does not support the video tag
|
|
495
|
+
# # </video>
|
|
496
|
+
#
|
|
497
|
+
# @example Tracks
|
|
498
|
+
#
|
|
499
|
+
# <%=
|
|
500
|
+
# video("movie.mp4") do
|
|
501
|
+
# tag.track(kind: "captions", src: asset_url("movie.en.vtt"),
|
|
502
|
+
# srclang: "en", label: "English")
|
|
503
|
+
# end
|
|
504
|
+
# %>
|
|
505
|
+
#
|
|
506
|
+
# # <video src="/assets/movie.mp4">
|
|
507
|
+
# # <track kind="captions" src="/assets/movie.en.vtt" srclang="en" label="English">
|
|
508
|
+
# # </video>
|
|
509
|
+
#
|
|
510
|
+
# @example Without Any Argument
|
|
511
|
+
#
|
|
512
|
+
# <%= video_tag %>
|
|
513
|
+
#
|
|
514
|
+
# # ArgumentError
|
|
515
|
+
#
|
|
516
|
+
# @example Without src And Without Block
|
|
517
|
+
#
|
|
518
|
+
# <%= video_tag(content: true) %>
|
|
519
|
+
#
|
|
520
|
+
# # ArgumentError
|
|
521
|
+
#
|
|
522
|
+
# @example Fingerprint Mode
|
|
523
|
+
#
|
|
524
|
+
# <%= video_tag "movie.mp4" %>
|
|
525
|
+
#
|
|
526
|
+
# # <video src="/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
|
|
527
|
+
#
|
|
528
|
+
# @example CDN Mode
|
|
529
|
+
#
|
|
530
|
+
# <%= video_tag "movie.mp4" %>
|
|
531
|
+
#
|
|
532
|
+
# # <video src="https://assets.bookshelf.org/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
|
|
533
|
+
def video_tag(source = nil, options = {}, &blk)
|
|
534
|
+
options = _source_options(source, options, &blk)
|
|
535
|
+
tag.video(**options, &blk)
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
# Generate `audio` tag for given source
|
|
539
|
+
#
|
|
540
|
+
# It accepts one string representing the name of the asset, if it comes
|
|
541
|
+
# from the application or third party gems. It also accepts strings
|
|
542
|
+
# representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
|
|
543
|
+
#
|
|
544
|
+
# Alternatively, it accepts a block that allows to specify one or more
|
|
545
|
+
# sources via the `source` tag.
|
|
546
|
+
#
|
|
547
|
+
# If the "fingerprint mode" is on, `src` is the fingerprinted
|
|
548
|
+
# version of the relative URL.
|
|
549
|
+
#
|
|
550
|
+
# If the "CDN mode" is on, the `src` is an absolute URL of the
|
|
551
|
+
# application CDN.
|
|
552
|
+
#
|
|
553
|
+
# @param source [String, #url] asset name, absolute URL or asset object
|
|
554
|
+
# @param options [Hash] HTML 5 attributes
|
|
555
|
+
#
|
|
556
|
+
# @return [Hanami::View::HTML::SafeString] the markup
|
|
557
|
+
#
|
|
558
|
+
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
559
|
+
# `subresource_integrity` modes are on and the audio file is missing
|
|
560
|
+
# from the manifest
|
|
561
|
+
#
|
|
562
|
+
# @raise [ArgumentError] if source isn"t specified both as argument or
|
|
563
|
+
# tag inside the given block
|
|
564
|
+
#
|
|
565
|
+
# @since 2.1.0
|
|
566
|
+
#
|
|
567
|
+
# @see Hanami::Assets::Helpers#path
|
|
568
|
+
#
|
|
569
|
+
# @example Basic Usage
|
|
570
|
+
#
|
|
571
|
+
# <%= audio_tag "song.ogg" %>
|
|
572
|
+
#
|
|
573
|
+
# # <audio src="/assets/song.ogg"></audio>
|
|
574
|
+
#
|
|
575
|
+
# @example Absolute URL
|
|
576
|
+
#
|
|
577
|
+
# <%= audio_tag "https://example-cdn.com/assets/song.ogg" %>
|
|
578
|
+
#
|
|
579
|
+
# # <audio src="https://example-cdn.com/assets/song.ogg"></audio>
|
|
580
|
+
#
|
|
581
|
+
# @example Custom HTML Attributes
|
|
582
|
+
#
|
|
583
|
+
# <%= audio_tag("song.ogg", autoplay: true, controls: true) %>
|
|
584
|
+
#
|
|
585
|
+
# # <audio src="/assets/song.ogg" autoplay="autoplay" controls="controls"></audio>
|
|
586
|
+
#
|
|
587
|
+
# @example Fallback Content
|
|
588
|
+
#
|
|
589
|
+
# <%=
|
|
590
|
+
# audio("song.ogg") do
|
|
591
|
+
# "Your browser does not support the audio tag"
|
|
592
|
+
# end
|
|
593
|
+
# %>
|
|
594
|
+
#
|
|
595
|
+
# # <audio src="/assets/song.ogg">
|
|
596
|
+
# # Your browser does not support the audio tag
|
|
597
|
+
# # </audio>
|
|
598
|
+
#
|
|
599
|
+
# @example Tracks
|
|
600
|
+
#
|
|
601
|
+
# <%=
|
|
602
|
+
# audio("song.ogg") do
|
|
603
|
+
# tag.track(kind: "captions", src: asset_url("song.pt-BR.vtt"),
|
|
604
|
+
# srclang: "pt-BR", label: "Portuguese")
|
|
605
|
+
# end
|
|
606
|
+
# %>
|
|
607
|
+
#
|
|
608
|
+
# # <audio src="/assets/song.ogg">
|
|
609
|
+
# # <track kind="captions" src="/assets/song.pt-BR.vtt" srclang="pt-BR" label="Portuguese">
|
|
610
|
+
# # </audio>
|
|
611
|
+
#
|
|
612
|
+
# @example Without Any Argument
|
|
613
|
+
#
|
|
614
|
+
# <%= audio_tag %>
|
|
615
|
+
#
|
|
616
|
+
# # ArgumentError
|
|
617
|
+
#
|
|
618
|
+
# @example Without src And Without Block
|
|
619
|
+
#
|
|
620
|
+
# <%= audio_tag(controls: true) %>
|
|
621
|
+
#
|
|
622
|
+
# # ArgumentError
|
|
623
|
+
#
|
|
624
|
+
# @example Fingerprint Mode
|
|
625
|
+
#
|
|
626
|
+
# <%= audio_tag "song.ogg" %>
|
|
627
|
+
#
|
|
628
|
+
# # <audio src="/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
|
|
629
|
+
#
|
|
630
|
+
# @example CDN Mode
|
|
631
|
+
#
|
|
632
|
+
# <%= audio_tag "song.ogg" %>
|
|
633
|
+
#
|
|
634
|
+
# # <audio src="https://assets.bookshelf.org/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
|
|
635
|
+
def audio_tag(source = nil, options = {}, &blk)
|
|
636
|
+
options = _source_options(source, options, &blk)
|
|
637
|
+
tag.audio(**options, &blk)
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
# It generates the relative or absolute URL for the given asset.
|
|
641
|
+
# It automatically decides if it has to use the relative or absolute
|
|
642
|
+
# depending on the configuration and current environment.
|
|
643
|
+
#
|
|
644
|
+
# Absolute URLs are returned as they are.
|
|
645
|
+
#
|
|
646
|
+
# It can be the name of the asset, coming from the sources or third party
|
|
647
|
+
# gems.
|
|
648
|
+
#
|
|
649
|
+
# If Fingerprint mode is on, it returns the fingerprinted path of the source
|
|
650
|
+
#
|
|
651
|
+
# If CDN mode is on, it returns the absolute URL of the asset.
|
|
652
|
+
#
|
|
653
|
+
# @param source [String, #url] the asset name or asset object
|
|
654
|
+
#
|
|
655
|
+
# @return [String] the asset path
|
|
656
|
+
#
|
|
657
|
+
# @raise [Hanami::Assets::MissingManifestAssetError] if `fingerprint` or
|
|
658
|
+
# `subresource_integrity` modes are on and the asset is missing
|
|
659
|
+
# from the manifest
|
|
660
|
+
#
|
|
661
|
+
# @since 2.1.0
|
|
662
|
+
#
|
|
663
|
+
# @example Basic Usage
|
|
664
|
+
#
|
|
665
|
+
# <%= asset_url "application.js" %>
|
|
666
|
+
#
|
|
667
|
+
# # "/assets/application.js"
|
|
668
|
+
#
|
|
669
|
+
# @example Alias
|
|
670
|
+
#
|
|
671
|
+
# <%= asset_url "application.js" %>
|
|
672
|
+
#
|
|
673
|
+
# # "/assets/application.js"
|
|
674
|
+
#
|
|
675
|
+
# @example Absolute URL
|
|
676
|
+
#
|
|
677
|
+
# <%= asset_url "https://code.jquery.com/jquery-2.1.4.min.js" %>
|
|
678
|
+
#
|
|
679
|
+
# # "https://code.jquery.com/jquery-2.1.4.min.js"
|
|
680
|
+
#
|
|
681
|
+
# @example Fingerprint Mode
|
|
682
|
+
#
|
|
683
|
+
# <%= asset_url "application.js" %>
|
|
684
|
+
#
|
|
685
|
+
# # "/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
686
|
+
#
|
|
687
|
+
# @example CDN Mode
|
|
688
|
+
#
|
|
689
|
+
# <%= asset_url "application.js" %>
|
|
690
|
+
#
|
|
691
|
+
# # "https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
|
|
692
|
+
def asset_url(source)
|
|
693
|
+
return source.url if source.respond_to?(:url)
|
|
694
|
+
return source if _absolute_url?(source)
|
|
695
|
+
|
|
696
|
+
_context.assets[source].url
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
# Random per request nonce value for Content Security Policy (CSP) rules.
|
|
700
|
+
#
|
|
701
|
+
# If the `Hanami::Middleware::ContentSecurityPolicyNonce` middleware is
|
|
702
|
+
# in use, this helper returns the nonce value for the current request
|
|
703
|
+
# or `nil` otherwise.
|
|
704
|
+
#
|
|
705
|
+
# For this policy to work in the browser, you have to add the `'nonce'`
|
|
706
|
+
# placeholder to the script and/or style source policy rule. It will be
|
|
707
|
+
# substituted by the current nonce value like `'nonce-A12OggyZ'.
|
|
708
|
+
#
|
|
709
|
+
# @return [String, nil] nonce value of the current request
|
|
710
|
+
#
|
|
711
|
+
# @since 2.3.0
|
|
712
|
+
#
|
|
713
|
+
# @example App configuration
|
|
714
|
+
#
|
|
715
|
+
# config.middleware.use Hanami::Middleware::ContentSecurityPolicyNonce
|
|
716
|
+
# config.actions.content_security_policy[:script_src] = "'self' 'nonce'"
|
|
717
|
+
# config.actions.content_security_policy[:style_src] = "'self' 'nonce'"
|
|
718
|
+
#
|
|
719
|
+
# @example View helper
|
|
720
|
+
#
|
|
721
|
+
# <script nonce="<%= content_security_policy_nonce %>">
|
|
722
|
+
def content_security_policy_nonce
|
|
723
|
+
return unless _context.request?
|
|
724
|
+
|
|
725
|
+
_context.request.env[CONTENT_SECURITY_POLICY_NONCE_REQUEST_KEY]
|
|
726
|
+
end
|
|
727
|
+
|
|
728
|
+
private
|
|
729
|
+
|
|
730
|
+
# @since 2.1.0
|
|
731
|
+
# @api private
|
|
732
|
+
def _safe_tags(*sources, &blk)
|
|
733
|
+
::Hanami::View::HTML::SafeString.new(
|
|
734
|
+
sources.map(&blk).join(NEW_LINE_SEPARATOR)
|
|
735
|
+
)
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
# @since 2.1.0
|
|
739
|
+
# @api private
|
|
740
|
+
def _typed_url(source, ext)
|
|
741
|
+
source = "#{source}#{ext}" if source.is_a?(String) && _append_extension?(source, ext)
|
|
742
|
+
asset_url(source)
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
# @api private
|
|
746
|
+
def _subresource_integrity_value(source, ext)
|
|
747
|
+
return if _absolute_url?(source)
|
|
748
|
+
|
|
749
|
+
source = "#{source}#{ext}" unless /#{Regexp.escape(ext)}\z/.match?(source)
|
|
750
|
+
_context.assets[source].sri
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
# @since 2.1.0
|
|
754
|
+
# @api private
|
|
755
|
+
def _absolute_url?(source)
|
|
756
|
+
ABSOLUTE_URL_MATCHER.match?(source.respond_to?(:url) ? source.url : source)
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
# @since 1.2.0
|
|
760
|
+
# @api private
|
|
761
|
+
def _crossorigin?(source)
|
|
762
|
+
return false unless _absolute_url?(source)
|
|
763
|
+
|
|
764
|
+
_context.assets.crossorigin?(source)
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
# @since 2.3.0
|
|
768
|
+
# @api private
|
|
769
|
+
def _nonce(source, nonce_option)
|
|
770
|
+
if nonce_option == false
|
|
771
|
+
nil
|
|
772
|
+
elsif nonce_option == true || (nonce_option.nil? && !_absolute_url?(source))
|
|
773
|
+
content_security_policy_nonce
|
|
774
|
+
else
|
|
775
|
+
nonce_option
|
|
776
|
+
end
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
# @since 2.1.0
|
|
780
|
+
# @api private
|
|
781
|
+
def _source_options(src, options, &blk)
|
|
782
|
+
options ||= {}
|
|
783
|
+
|
|
784
|
+
if src.respond_to?(:to_hash)
|
|
785
|
+
options = src.to_hash
|
|
786
|
+
elsif src
|
|
787
|
+
options[:src] = asset_url(src)
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
if !options[:src] && !blk
|
|
791
|
+
raise ArgumentError.new("You should provide a source via `src` option or with a `source` HTML tag")
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
options
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
# @since 1.1.0
|
|
798
|
+
# @api private
|
|
799
|
+
def _append_extension?(source, ext)
|
|
800
|
+
source !~ QUERY_STRING_MATCHER && source !~ /#{Regexp.escape(ext)}\z/
|
|
801
|
+
end
|
|
802
|
+
end
|
|
803
|
+
end
|
|
804
|
+
end
|