actionview 5.2.8.1 → 6.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionview might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +106 -162
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/action_view/buffers.rb +15 -0
- data/lib/action_view/context.rb +5 -4
- data/lib/action_view/digestor.rb +7 -6
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +4 -27
- data/lib/action_view/helpers/asset_url_helper.rb +4 -3
- data/lib/action_view/helpers/cache_helper.rb +18 -10
- data/lib/action_view/helpers/capture_helper.rb +4 -0
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +69 -25
- data/lib/action_view/helpers/form_helper.rb +240 -8
- data/lib/action_view/helpers/form_options_helper.rb +23 -15
- data/lib/action_view/helpers/form_tag_helper.rb +9 -9
- data/lib/action_view/helpers/javascript_helper.rb +10 -11
- data/lib/action_view/helpers/number_helper.rb +5 -0
- data/lib/action_view/helpers/sanitize_helper.rb +3 -3
- data/lib/action_view/helpers/tag_helper.rb +13 -43
- data/lib/action_view/helpers/tags/base.rb +8 -4
- data/lib/action_view/helpers/tags/color_field.rb +1 -1
- data/lib/action_view/helpers/tags/translator.rb +1 -6
- data/lib/action_view/helpers/text_helper.rb +3 -3
- data/lib/action_view/helpers/translation_helper.rb +11 -18
- data/lib/action_view/helpers/url_helper.rb +14 -14
- data/lib/action_view/helpers.rb +0 -2
- data/lib/action_view/log_subscriber.rb +6 -6
- data/lib/action_view/lookup_context.rb +4 -4
- data/lib/action_view/railtie.rb +18 -0
- data/lib/action_view/record_identifier.rb +2 -2
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +40 -1
- data/lib/action_view/renderer/partial_renderer.rb +2 -2
- data/lib/action_view/renderer/streaming_template_renderer.rb +1 -1
- data/lib/action_view/rendering.rb +5 -4
- data/lib/action_view/routing_url_for.rb +12 -11
- data/lib/action_view/template/handlers/erb.rb +12 -2
- data/lib/action_view/template/resolver.rb +56 -16
- data/lib/action_view/template.rb +25 -8
- data/lib/action_view/test_case.rb +1 -1
- data/lib/action_view/testing/resolvers.rb +1 -1
- data/lib/action_view.rb +1 -1
- data/lib/assets/compiled/rails-ujs.js +39 -22
- metadata +17 -18
- data/lib/action_view/helpers/record_tag_helper.rb +0 -23
@@ -14,15 +14,35 @@ module ActionView
|
|
14
14
|
def cache_collection_render(instrumentation_payload)
|
15
15
|
return yield unless @options[:cached]
|
16
16
|
|
17
|
+
# Result is a hash with the key represents the
|
18
|
+
# key used for cache lookup and the value is the item
|
19
|
+
# on which the partial is being rendered
|
17
20
|
keyed_collection = collection_by_cache_keys
|
21
|
+
|
22
|
+
# Pull all partials from cache
|
23
|
+
# Result is a hash, key matches the entry in
|
24
|
+
# `keyed_collection` where the cache was retrieved and the
|
25
|
+
# value is the value that was present in the cache
|
18
26
|
cached_partials = collection_cache.read_multi(*keyed_collection.keys)
|
19
27
|
instrumentation_payload[:cache_hits] = cached_partials.size
|
20
28
|
|
29
|
+
# Extract the items for the keys that are not found
|
30
|
+
# Set the uncached values to instance variable @collection
|
31
|
+
# which is used by the caller
|
21
32
|
@collection = keyed_collection.reject { |key, _| cached_partials.key?(key) }.values
|
33
|
+
|
34
|
+
# If all elements are already in cache then
|
35
|
+
# rendered partials will be an empty array
|
36
|
+
#
|
37
|
+
# If the cache is missing elements then
|
38
|
+
# the block will be called against the remaining items
|
39
|
+
# in the @collection.
|
22
40
|
rendered_partials = @collection.empty? ? [] : yield
|
23
41
|
|
24
42
|
index = 0
|
25
43
|
fetch_or_cache_partial(cached_partials, order_by: keyed_collection.each_key) do
|
44
|
+
# This block is called once
|
45
|
+
# for every cache miss while preserving order.
|
26
46
|
rendered_partials[index].tap { index += 1 }
|
27
47
|
end
|
28
48
|
end
|
@@ -40,10 +60,29 @@ module ActionView
|
|
40
60
|
end
|
41
61
|
|
42
62
|
def expanded_cache_key(key)
|
43
|
-
key = @view.combined_fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path))
|
63
|
+
key = @view.combined_fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path, digest_path: digest_path))
|
44
64
|
key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0.
|
45
65
|
end
|
46
66
|
|
67
|
+
def digest_path
|
68
|
+
@digest_path ||= @view.digest_path_from_virtual(@template.virtual_path)
|
69
|
+
end
|
70
|
+
|
71
|
+
# `order_by` is an enumerable object containing keys of the cache,
|
72
|
+
# all keys are passed in whether found already or not.
|
73
|
+
#
|
74
|
+
# `cached_partials` is a hash. If the value exists
|
75
|
+
# it represents the rendered partial from the cache
|
76
|
+
# otherwise `Hash#fetch` will take the value of its block.
|
77
|
+
#
|
78
|
+
# This method expects a block that will return the rendered
|
79
|
+
# partial. An example is to render all results
|
80
|
+
# for each element that was not found in the cache and store it as an array.
|
81
|
+
# Order it so that the first empty cache element in `cached_partials`
|
82
|
+
# corresponds to the first element in `rendered_partials`.
|
83
|
+
#
|
84
|
+
# If the partial is not already cached it will also be
|
85
|
+
# written back to the underlying cache store.
|
47
86
|
def fetch_or_cache_partial(cached_partials, order_by:)
|
48
87
|
order_by.map do |cache_key|
|
49
88
|
cached_partials.fetch(cache_key) do
|
@@ -363,7 +363,7 @@ module ActionView
|
|
363
363
|
@options = options
|
364
364
|
@block = block
|
365
365
|
|
366
|
-
@locals = options[:locals]
|
366
|
+
@locals = options[:locals] ? options[:locals].symbolize_keys : {}
|
367
367
|
@details = extract_details(options)
|
368
368
|
|
369
369
|
prepend_formats(options[:formats])
|
@@ -523,7 +523,7 @@ module ActionView
|
|
523
523
|
|
524
524
|
def retrieve_variable(path, as)
|
525
525
|
variable = as || begin
|
526
|
-
base = path[-1] == "/"
|
526
|
+
base = path[-1] == "/" ? "" : File.basename(path)
|
527
527
|
raise_invalid_identifier(path) unless base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
528
528
|
$1.to_sym
|
529
529
|
end
|
@@ -33,7 +33,7 @@ module ActionView
|
|
33
33
|
logger = ActionView::Base.logger
|
34
34
|
return unless logger
|
35
35
|
|
36
|
-
message = "\n#{exception.class} (#{exception.message}):\n"
|
36
|
+
message = +"\n#{exception.class} (#{exception.message}):\n"
|
37
37
|
message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
|
38
38
|
message << " " << exception.backtrace.join("\n ")
|
39
39
|
logger.fatal("#{message}\n\n")
|
@@ -64,10 +64,11 @@ module ActionView
|
|
64
64
|
# An instance of a view class. The default view class is ActionView::Base.
|
65
65
|
#
|
66
66
|
# The view class must have the following methods:
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
67
|
+
#
|
68
|
+
# * <tt>View.new(lookup_context, assigns, controller)</tt> — Create a new
|
69
|
+
# ActionView instance for a controller and we can also pass the arguments.
|
70
|
+
#
|
71
|
+
# * <tt>View#render(option)</tt> — Returns String with the rendered template.
|
71
72
|
#
|
72
73
|
# Override this method in a module to change the default behavior.
|
73
74
|
def view_context
|
@@ -84,25 +84,24 @@ module ActionView
|
|
84
84
|
super(only_path: _generate_paths_by_default)
|
85
85
|
when Hash
|
86
86
|
options = options.symbolize_keys
|
87
|
-
|
88
|
-
options[:only_path] = only_path?(options[:host])
|
89
|
-
end
|
87
|
+
ensure_only_path_option(options)
|
90
88
|
|
91
89
|
super(options)
|
92
90
|
when ActionController::Parameters
|
93
|
-
|
94
|
-
options[:only_path] = only_path?(options[:host])
|
95
|
-
end
|
91
|
+
ensure_only_path_option(options)
|
96
92
|
|
97
93
|
super(options)
|
98
94
|
when :back
|
99
95
|
_back_url
|
100
96
|
when Array
|
101
97
|
components = options.dup
|
102
|
-
|
103
|
-
|
98
|
+
options = components.extract_options!
|
99
|
+
ensure_only_path_option(options)
|
100
|
+
|
101
|
+
if options[:only_path]
|
102
|
+
polymorphic_path(components, options)
|
104
103
|
else
|
105
|
-
polymorphic_url(components,
|
104
|
+
polymorphic_url(components, options)
|
106
105
|
end
|
107
106
|
else
|
108
107
|
method = _generate_paths_by_default ? :path : :url
|
@@ -138,8 +137,10 @@ module ActionView
|
|
138
137
|
true
|
139
138
|
end
|
140
139
|
|
141
|
-
def
|
142
|
-
|
140
|
+
def ensure_only_path_option(options)
|
141
|
+
unless options.key?(:only_path)
|
142
|
+
options[:only_path] = _generate_paths_by_default unless options[:host]
|
143
|
+
end
|
143
144
|
end
|
144
145
|
end
|
145
146
|
end
|
@@ -14,7 +14,17 @@ module ActionView
|
|
14
14
|
class_attribute :erb_implementation, default: Erubi
|
15
15
|
|
16
16
|
# Do not escape templates of these mime types.
|
17
|
-
class_attribute :
|
17
|
+
class_attribute :escape_ignore_list, default: ["text/plain"]
|
18
|
+
|
19
|
+
[self, singleton_class].each do |base|
|
20
|
+
base.alias_method :escape_whitelist, :escape_ignore_list
|
21
|
+
base.alias_method :escape_whitelist=, :escape_ignore_list=
|
22
|
+
|
23
|
+
base.deprecate(
|
24
|
+
escape_whitelist: "use #escape_ignore_list instead",
|
25
|
+
:escape_whitelist= => "use #escape_ignore_list= instead"
|
26
|
+
)
|
27
|
+
end
|
18
28
|
|
19
29
|
ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
|
20
30
|
|
@@ -47,7 +57,7 @@ module ActionView
|
|
47
57
|
|
48
58
|
self.class.erb_implementation.new(
|
49
59
|
erb,
|
50
|
-
escape: (self.class.
|
60
|
+
escape: (self.class.escape_ignore_list.include? template.type),
|
51
61
|
trim: (self.class.erb_trim_mode == "-")
|
52
62
|
).src
|
53
63
|
end
|
@@ -16,7 +16,7 @@ module ActionView
|
|
16
16
|
alias_method :partial?, :partial
|
17
17
|
|
18
18
|
def self.build(name, prefix, partial)
|
19
|
-
virtual = ""
|
19
|
+
virtual = +""
|
20
20
|
virtual << "#{prefix}/" unless prefix.empty?
|
21
21
|
virtual << (partial ? "_#{name}" : name)
|
22
22
|
new name, prefix, partial, virtual
|
@@ -221,9 +221,7 @@ module ActionView
|
|
221
221
|
end
|
222
222
|
|
223
223
|
def query(path, details, formats, outside_app_allowed)
|
224
|
-
|
225
|
-
|
226
|
-
template_paths = find_template_paths(query)
|
224
|
+
template_paths = find_template_paths_from_details(path, details)
|
227
225
|
template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed
|
228
226
|
|
229
227
|
template_paths.map do |template|
|
@@ -243,6 +241,11 @@ module ActionView
|
|
243
241
|
files.reject { |filename| !inside_path?(@path, filename) }
|
244
242
|
end
|
245
243
|
|
244
|
+
def find_template_paths_from_details(path, details)
|
245
|
+
query = build_query(path, details)
|
246
|
+
find_template_paths(query)
|
247
|
+
end
|
248
|
+
|
246
249
|
def find_template_paths(query)
|
247
250
|
Dir[query].uniq.reject do |filename|
|
248
251
|
File.directory?(filename) ||
|
@@ -279,7 +282,7 @@ module ActionView
|
|
279
282
|
end
|
280
283
|
|
281
284
|
def escape_entry(entry)
|
282
|
-
entry.gsub(/[*?{}\[\]]/, '\\\\\\&'
|
285
|
+
entry.gsub(/[*?{}\[\]]/, '\\\\\\&')
|
283
286
|
end
|
284
287
|
|
285
288
|
# Returns the file mtime from the filesystem.
|
@@ -291,7 +294,7 @@ module ActionView
|
|
291
294
|
# from the path, or the handler, we should return the array of formats given
|
292
295
|
# to the resolver.
|
293
296
|
def extract_handler_and_format_and_variant(path)
|
294
|
-
pieces = File.basename(path).split("."
|
297
|
+
pieces = File.basename(path).split(".")
|
295
298
|
pieces.shift
|
296
299
|
|
297
300
|
extension = pieces.pop
|
@@ -362,19 +365,56 @@ module ActionView
|
|
362
365
|
|
363
366
|
# An Optimized resolver for Rails' most common case.
|
364
367
|
class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
|
365
|
-
|
366
|
-
query = escape_entry(File.join(@path, path))
|
368
|
+
private
|
367
369
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
370
|
+
def find_template_paths_from_details(path, details)
|
371
|
+
# Instead of checking for every possible path, as our other globs would
|
372
|
+
# do, scan the directory for files with the right prefix.
|
373
|
+
query = "#{escape_entry(File.join(@path, path))}*"
|
374
|
+
|
375
|
+
regex = build_regex(path, details)
|
376
|
+
|
377
|
+
Dir[query].uniq.reject do |filename|
|
378
|
+
# This regex match does double duty of finding only files which match
|
379
|
+
# details (instead of just matching the prefix) and also filtering for
|
380
|
+
# case-insensitive file systems.
|
381
|
+
!regex.match?(filename) ||
|
382
|
+
File.directory?(filename)
|
383
|
+
end.sort_by do |filename|
|
384
|
+
# Because we scanned the directory, instead of checking for files
|
385
|
+
# one-by-one, they will be returned in an arbitrary order.
|
386
|
+
# We can use the matches found by the regex and sort by their index in
|
387
|
+
# details.
|
388
|
+
match = filename.match(regex)
|
389
|
+
EXTENSIONS.keys.reverse.map do |ext|
|
390
|
+
if ext == :variants && details[ext] == :any
|
391
|
+
match[ext].nil? ? 0 : 1
|
392
|
+
elsif match[ext].nil?
|
393
|
+
# No match should be last
|
394
|
+
details[ext].length
|
395
|
+
else
|
396
|
+
found = match[ext].to_sym
|
397
|
+
details[ext].index(found)
|
398
|
+
end
|
399
|
+
end
|
373
400
|
end
|
374
|
-
end
|
401
|
+
end
|
375
402
|
|
376
|
-
|
377
|
-
|
403
|
+
def build_regex(path, details)
|
404
|
+
query = escape_entry(File.join(@path, path))
|
405
|
+
exts = EXTENSIONS.map do |ext, prefix|
|
406
|
+
match =
|
407
|
+
if ext == :variants && details[ext] == :any
|
408
|
+
".*?"
|
409
|
+
else
|
410
|
+
details[ext].compact.uniq.map { |e| Regexp.escape(e) }.join("|")
|
411
|
+
end
|
412
|
+
prefix = Regexp.escape(prefix)
|
413
|
+
"(#{prefix}(?<#{ext}>#{match}))?"
|
414
|
+
end.join
|
415
|
+
|
416
|
+
%r{\A#{query}#{exts}\z}
|
417
|
+
end
|
378
418
|
end
|
379
419
|
|
380
420
|
# The same as FileSystemResolver but does not allow templates to store
|
data/lib/action_view/template.rb
CHANGED
@@ -9,6 +9,8 @@ module ActionView
|
|
9
9
|
class Template
|
10
10
|
extend ActiveSupport::Autoload
|
11
11
|
|
12
|
+
mattr_accessor :finalize_compiled_template_methods, default: true
|
13
|
+
|
12
14
|
# === Encodings in ActionView::Template
|
13
15
|
#
|
14
16
|
# ActionView::Template is one of a few sources of potential
|
@@ -186,7 +188,7 @@ module ActionView
|
|
186
188
|
end
|
187
189
|
|
188
190
|
def inspect
|
189
|
-
@inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", ""
|
191
|
+
@inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "") : identifier
|
190
192
|
end
|
191
193
|
|
192
194
|
# This method is responsible for properly setting the encoding of the
|
@@ -233,6 +235,19 @@ module ActionView
|
|
233
235
|
end
|
234
236
|
end
|
235
237
|
|
238
|
+
|
239
|
+
# Exceptions are marshalled when using the parallel test runner with DRb, so we need
|
240
|
+
# to ensure that references to the template object can be marshalled as well. This means forgoing
|
241
|
+
# the marshalling of the compiler mutex and instantiating that again on unmarshalling.
|
242
|
+
def marshal_dump # :nodoc:
|
243
|
+
[ @source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @formats, @variants ]
|
244
|
+
end
|
245
|
+
|
246
|
+
def marshal_load(array) # :nodoc:
|
247
|
+
@source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @formats, @variants = *array
|
248
|
+
@compile_mutex = Mutex.new
|
249
|
+
end
|
250
|
+
|
236
251
|
private
|
237
252
|
|
238
253
|
# Compile a template. This method ensures a template is compiled
|
@@ -284,7 +299,7 @@ module ActionView
|
|
284
299
|
|
285
300
|
# Make sure that the resulting String to be eval'd is in the
|
286
301
|
# encoding of the code
|
287
|
-
source =
|
302
|
+
source = +<<-end_src
|
288
303
|
def #{method_name}(local_assigns, output_buffer)
|
289
304
|
_old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
|
290
305
|
ensure
|
@@ -307,7 +322,9 @@ module ActionView
|
|
307
322
|
end
|
308
323
|
|
309
324
|
mod.module_eval(source, identifier, 0)
|
310
|
-
|
325
|
+
if finalize_compiled_template_methods
|
326
|
+
ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
|
327
|
+
end
|
311
328
|
end
|
312
329
|
|
313
330
|
def handle_render_error(view, e)
|
@@ -331,19 +348,19 @@ module ActionView
|
|
331
348
|
locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
|
332
349
|
|
333
350
|
# Assign for the same variable is to suppress unused variable warning
|
334
|
-
locals.each_with_object(""
|
351
|
+
locals.each_with_object(+"") { |key, code| code << "#{key} = local_assigns[:#{key}]; #{key} = #{key};" }
|
335
352
|
end
|
336
353
|
|
337
354
|
def method_name
|
338
355
|
@method_name ||= begin
|
339
|
-
m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
340
|
-
m.tr!("-"
|
356
|
+
m = +"_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
357
|
+
m.tr!("-", "_")
|
341
358
|
m
|
342
359
|
end
|
343
360
|
end
|
344
361
|
|
345
362
|
def identifier_method_name
|
346
|
-
inspect.tr("^a-z_"
|
363
|
+
inspect.tr("^a-z_", "_")
|
347
364
|
end
|
348
365
|
|
349
366
|
def instrument(action, &block) # :doc:
|
@@ -351,7 +368,7 @@ module ActionView
|
|
351
368
|
end
|
352
369
|
|
353
370
|
def instrument_render_template(&block)
|
354
|
-
ActiveSupport::Notifications.instrument("!render_template.action_view"
|
371
|
+
ActiveSupport::Notifications.instrument("!render_template.action_view", instrument_payload, &block)
|
355
372
|
end
|
356
373
|
|
357
374
|
def instrument_payload
|
@@ -107,7 +107,7 @@ module ActionView
|
|
107
107
|
# empty string ensures buffer has UTF-8 encoding as
|
108
108
|
# new without arguments returns ASCII-8BIT encoded buffer like String#new
|
109
109
|
@output_buffer = ActiveSupport::SafeBuffer.new ""
|
110
|
-
@rendered = ""
|
110
|
+
@rendered = +""
|
111
111
|
|
112
112
|
make_test_case_available_to_view!
|
113
113
|
say_no_to_protect_against_forgery!
|
data/lib/action_view.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2019 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Unobtrusive JavaScript
|
3
3
|
https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts
|
4
4
|
Released under the MIT license
|
5
|
-
|
5
|
+
*/
|
6
6
|
|
7
7
|
(function() {
|
8
8
|
var context = this;
|
@@ -32,17 +32,12 @@ Released under the MIT license
|
|
32
32
|
|
33
33
|
(function() {
|
34
34
|
(function() {
|
35
|
-
var
|
35
|
+
var cspNonce;
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
return nonce = (ref = document.querySelector("meta[name=csp-nonce]")) != null ? ref.content : void 0;
|
42
|
-
};
|
43
|
-
|
44
|
-
Rails.cspNonce = function() {
|
45
|
-
return nonce != null ? nonce : Rails.loadCSPNonce();
|
37
|
+
cspNonce = Rails.cspNonce = function() {
|
38
|
+
var meta;
|
39
|
+
meta = document.querySelector('meta[name=csp-nonce]');
|
40
|
+
return meta && meta.content;
|
46
41
|
};
|
47
42
|
|
48
43
|
}).call(this);
|
@@ -247,8 +242,8 @@ Released under the MIT license
|
|
247
242
|
}
|
248
243
|
if (!options.crossDomain) {
|
249
244
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
250
|
-
CSRFProtection(xhr);
|
251
245
|
}
|
246
|
+
CSRFProtection(xhr);
|
252
247
|
xhr.withCredentials = !!options.withCredentials;
|
253
248
|
xhr.onreadystatechange = function() {
|
254
249
|
if (xhr.readyState === XMLHttpRequest.DONE) {
|
@@ -270,7 +265,7 @@ Released under the MIT license
|
|
270
265
|
script.setAttribute('nonce', cspNonce());
|
271
266
|
script.text = response;
|
272
267
|
document.head.appendChild(script).parentNode.removeChild(script);
|
273
|
-
} else if (type.match(/\
|
268
|
+
} else if (type.match(/\bxml\b/)) {
|
274
269
|
parser = new DOMParser();
|
275
270
|
type = type.replace(/;.+/, '');
|
276
271
|
try {
|
@@ -370,6 +365,10 @@ Released under the MIT license
|
|
370
365
|
}
|
371
366
|
};
|
372
367
|
|
368
|
+
Rails.confirm = function(message, element) {
|
369
|
+
return confirm(message);
|
370
|
+
};
|
371
|
+
|
373
372
|
allowAction = function(element) {
|
374
373
|
var answer, callback, message;
|
375
374
|
message = element.getAttribute('data-confirm');
|
@@ -379,7 +378,7 @@ Released under the MIT license
|
|
379
378
|
answer = false;
|
380
379
|
if (fire(element, 'confirm')) {
|
381
380
|
try {
|
382
|
-
answer = confirm(message);
|
381
|
+
answer = Rails.confirm(message, element);
|
383
382
|
} catch (error) {}
|
384
383
|
callback = fire(element, 'confirm:complete', [answer]);
|
385
384
|
}
|
@@ -388,7 +387,7 @@ Released under the MIT license
|
|
388
387
|
|
389
388
|
}).call(this);
|
390
389
|
(function() {
|
391
|
-
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, matches, setData, stopEverything;
|
390
|
+
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isXhrRedirect, matches, setData, stopEverything;
|
392
391
|
|
393
392
|
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;
|
394
393
|
|
@@ -402,7 +401,14 @@ Released under the MIT license
|
|
402
401
|
|
403
402
|
Rails.enableElement = function(e) {
|
404
403
|
var element;
|
405
|
-
|
404
|
+
if (e instanceof Event) {
|
405
|
+
if (isXhrRedirect(e)) {
|
406
|
+
return;
|
407
|
+
}
|
408
|
+
element = e.target;
|
409
|
+
} else {
|
410
|
+
element = e;
|
411
|
+
}
|
406
412
|
if (matches(element, Rails.linkDisableSelector)) {
|
407
413
|
return enableLinkElement(element);
|
408
414
|
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {
|
@@ -426,6 +432,9 @@ Released under the MIT license
|
|
426
432
|
|
427
433
|
disableLinkElement = function(element) {
|
428
434
|
var replacement;
|
435
|
+
if (getData(element, 'ujs:disabled')) {
|
436
|
+
return;
|
437
|
+
}
|
429
438
|
replacement = element.getAttribute('data-disable-with');
|
430
439
|
if (replacement != null) {
|
431
440
|
setData(element, 'ujs:enable-with', element.innerHTML);
|
@@ -452,6 +461,9 @@ Released under the MIT license
|
|
452
461
|
|
453
462
|
disableFormElement = function(element) {
|
454
463
|
var replacement;
|
464
|
+
if (getData(element, 'ujs:disabled')) {
|
465
|
+
return;
|
466
|
+
}
|
455
467
|
replacement = element.getAttribute('data-disable-with');
|
456
468
|
if (replacement != null) {
|
457
469
|
if (matches(element, 'button')) {
|
@@ -485,6 +497,12 @@ Released under the MIT license
|
|
485
497
|
return setData(element, 'ujs:disabled', null);
|
486
498
|
};
|
487
499
|
|
500
|
+
isXhrRedirect = function(event) {
|
501
|
+
var ref, xhr;
|
502
|
+
xhr = (ref = event.detail) != null ? ref[0] : void 0;
|
503
|
+
return (xhr != null ? xhr.getResponseHeader("X-Xhr-Redirect") : void 0) != null;
|
504
|
+
};
|
505
|
+
|
488
506
|
}).call(this);
|
489
507
|
(function() {
|
490
508
|
var stopEverything;
|
@@ -622,23 +640,23 @@ Released under the MIT license
|
|
622
640
|
};
|
623
641
|
|
624
642
|
Rails.preventInsignificantClick = function(e) {
|
625
|
-
var data, insignificantMetaClick, link, metaClick, method,
|
643
|
+
var data, insignificantMetaClick, link, metaClick, method, primaryMouseKey;
|
626
644
|
link = this;
|
627
645
|
method = (link.getAttribute('data-method') || 'GET').toUpperCase();
|
628
646
|
data = link.getAttribute('data-params');
|
629
647
|
metaClick = e.metaKey || e.ctrlKey;
|
630
648
|
insignificantMetaClick = metaClick && method === 'GET' && !data;
|
631
|
-
|
632
|
-
if (
|
649
|
+
primaryMouseKey = e.button === 0;
|
650
|
+
if (!primaryMouseKey || insignificantMetaClick) {
|
633
651
|
return e.stopImmediatePropagation();
|
634
652
|
}
|
635
653
|
};
|
636
654
|
|
637
655
|
}).call(this);
|
638
656
|
(function() {
|
639
|
-
var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMethod, handleRemote,
|
657
|
+
var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMethod, handleRemote, preventInsignificantClick, refreshCSRFTokens;
|
640
658
|
|
641
|
-
fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection,
|
659
|
+
fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, preventInsignificantClick = Rails.preventInsignificantClick, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMethod = Rails.handleMethod;
|
642
660
|
|
643
661
|
if ((typeof jQuery !== "undefined" && jQuery !== null) && (jQuery.ajax != null)) {
|
644
662
|
if (jQuery.rails) {
|
@@ -701,7 +719,6 @@ Released under the MIT license
|
|
701
719
|
delegate(document, Rails.formInputClickSelector, 'click', handleConfirm);
|
702
720
|
delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick);
|
703
721
|
document.addEventListener('DOMContentLoaded', refreshCSRFTokens);
|
704
|
-
document.addEventListener('DOMContentLoaded', loadCSPNonce);
|
705
722
|
return window._rails_loaded = true;
|
706
723
|
};
|
707
724
|
|