actionview 7.0.1 → 7.1.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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +281 -202
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/app/assets/javascripts/rails-ujs.esm.js +693 -0
  6. data/app/assets/javascripts/rails-ujs.js +630 -0
  7. data/lib/action_view/base.rb +33 -12
  8. data/lib/action_view/buffers.rb +106 -8
  9. data/lib/action_view/cache_expiry.rb +40 -43
  10. data/lib/action_view/context.rb +1 -1
  11. data/lib/action_view/deprecator.rb +7 -0
  12. data/lib/action_view/digestor.rb +1 -1
  13. data/lib/action_view/gem_version.rb +2 -2
  14. data/lib/action_view/helpers/active_model_helper.rb +1 -1
  15. data/lib/action_view/helpers/asset_tag_helper.rb +133 -48
  16. data/lib/action_view/helpers/asset_url_helper.rb +13 -12
  17. data/lib/action_view/helpers/atom_feed_helper.rb +5 -5
  18. data/lib/action_view/helpers/cache_helper.rb +3 -9
  19. data/lib/action_view/helpers/capture_helper.rb +26 -12
  20. data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
  21. data/lib/action_view/helpers/controller_helper.rb +6 -0
  22. data/lib/action_view/helpers/csp_helper.rb +2 -2
  23. data/lib/action_view/helpers/csrf_helper.rb +3 -3
  24. data/lib/action_view/helpers/date_helper.rb +76 -64
  25. data/lib/action_view/helpers/debug_helper.rb +3 -3
  26. data/lib/action_view/helpers/form_helper.rb +62 -31
  27. data/lib/action_view/helpers/form_options_helper.rb +6 -3
  28. data/lib/action_view/helpers/form_tag_helper.rb +88 -44
  29. data/lib/action_view/helpers/javascript_helper.rb +1 -0
  30. data/lib/action_view/helpers/number_helper.rb +15 -13
  31. data/lib/action_view/helpers/output_safety_helper.rb +4 -4
  32. data/lib/action_view/helpers/rendering_helper.rb +5 -6
  33. data/lib/action_view/helpers/sanitize_helper.rb +34 -15
  34. data/lib/action_view/helpers/tag_helper.rb +27 -16
  35. data/lib/action_view/helpers/tags/base.rb +11 -52
  36. data/lib/action_view/helpers/tags/collection_check_boxes.rb +1 -0
  37. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -0
  38. data/lib/action_view/helpers/tags/collection_select.rb +3 -0
  39. data/lib/action_view/helpers/tags/date_field.rb +1 -1
  40. data/lib/action_view/helpers/tags/date_select.rb +2 -0
  41. data/lib/action_view/helpers/tags/datetime_field.rb +14 -6
  42. data/lib/action_view/helpers/tags/datetime_local_field.rb +11 -2
  43. data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -0
  44. data/lib/action_view/helpers/tags/month_field.rb +1 -1
  45. data/lib/action_view/helpers/tags/select.rb +4 -1
  46. data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
  47. data/lib/action_view/helpers/tags/time_field.rb +1 -1
  48. data/lib/action_view/helpers/tags/time_zone_select.rb +3 -0
  49. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  50. data/lib/action_view/helpers/tags/weekday_select.rb +3 -0
  51. data/lib/action_view/helpers/tags.rb +2 -0
  52. data/lib/action_view/helpers/text_helper.rb +33 -17
  53. data/lib/action_view/helpers/translation_helper.rb +6 -6
  54. data/lib/action_view/helpers/url_helper.rb +90 -65
  55. data/lib/action_view/helpers.rb +2 -0
  56. data/lib/action_view/layouts.rb +13 -8
  57. data/lib/action_view/log_subscriber.rb +49 -32
  58. data/lib/action_view/lookup_context.rb +29 -13
  59. data/lib/action_view/path_registry.rb +57 -0
  60. data/lib/action_view/path_set.rb +13 -14
  61. data/lib/action_view/railtie.rb +26 -3
  62. data/lib/action_view/record_identifier.rb +16 -9
  63. data/lib/action_view/renderer/abstract_renderer.rb +1 -1
  64. data/lib/action_view/renderer/collection_renderer.rb +9 -1
  65. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +21 -3
  66. data/lib/action_view/renderer/partial_renderer.rb +3 -2
  67. data/lib/action_view/renderer/renderer.rb +2 -0
  68. data/lib/action_view/renderer/streaming_template_renderer.rb +3 -2
  69. data/lib/action_view/renderer/template_renderer.rb +3 -2
  70. data/lib/action_view/rendering.rb +24 -6
  71. data/lib/action_view/ripper_ast_parser.rb +6 -6
  72. data/lib/action_view/routing_url_for.rb +7 -4
  73. data/lib/action_view/template/error.rb +14 -1
  74. data/lib/action_view/template/handlers/builder.rb +4 -4
  75. data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
  76. data/lib/action_view/template/handlers/erb.rb +73 -1
  77. data/lib/action_view/template/handlers.rb +1 -1
  78. data/lib/action_view/template/html.rb +1 -1
  79. data/lib/action_view/template/raw_file.rb +1 -1
  80. data/lib/action_view/template/renderable.rb +1 -1
  81. data/lib/action_view/template/resolver.rb +15 -5
  82. data/lib/action_view/template/text.rb +1 -1
  83. data/lib/action_view/template/types.rb +25 -34
  84. data/lib/action_view/template.rb +227 -53
  85. data/lib/action_view/template_path.rb +2 -0
  86. data/lib/action_view/test_case.rb +174 -21
  87. data/lib/action_view/unbound_template.rb +15 -5
  88. data/lib/action_view/version.rb +1 -1
  89. data/lib/action_view/view_paths.rb +19 -28
  90. data/lib/action_view.rb +4 -1
  91. data/lib/assets/compiled/rails-ujs.js +36 -5
  92. metadata +27 -27
@@ -9,6 +9,9 @@ require "rails-dom-testing"
9
9
 
10
10
  module ActionView
11
11
  # = Action View Test Case
12
+ #
13
+ # Read more about <tt>ActionView::TestCase</tt> in {Testing Rails Applications}[https://guides.rubyonrails.org/testing.html#testing-view-partials]
14
+ # in the guides.
12
15
  class TestCase < ActiveSupport::TestCase
13
16
  class TestController < ActionController::Base
14
17
  include ActionDispatch::TestProcess
@@ -57,9 +60,96 @@ module ActionView
57
60
  include ActiveSupport::Testing::ConstantLookup
58
61
 
59
62
  delegate :lookup_context, to: :controller
60
- attr_accessor :controller, :output_buffer, :rendered
63
+ attr_accessor :controller, :request, :output_buffer
61
64
 
62
65
  module ClassMethods
66
+ def inherited(descendant) # :nodoc:
67
+ super
68
+
69
+ descendant_content_class = content_class.dup
70
+
71
+ if descendant_content_class.respond_to?(:set_temporary_name)
72
+ descendant_content_class.set_temporary_name("rendered_content")
73
+ end
74
+
75
+ descendant.content_class = descendant_content_class
76
+ end
77
+
78
+ # Register a callable to parse rendered content for a given template
79
+ # format.
80
+ #
81
+ # Each registered parser will also define a +#rendered.[FORMAT]+ helper
82
+ # method, where +[FORMAT]+ corresponds to the value of the
83
+ # +format+ argument.
84
+ #
85
+ # === Arguments
86
+ #
87
+ # <tt>format</tt> - Symbol the name of the format used to render view's content
88
+ # <tt>callable</tt> - Callable to parse the String. Accepts the String.
89
+ # value as its only argument.
90
+ # <tt>block</tt> - Block serves as the parser when the
91
+ # <tt>callable</tt> is omitted.
92
+ #
93
+ # By default, ActionView::TestCase defines a parser for:
94
+ #
95
+ # * :html - returns an instance of Nokogiri::XML::Node
96
+ # * :json - returns an instance of ActiveSupport::HashWithIndifferentAccess
97
+ #
98
+ # Each pre-registered parser also defines a corresponding helper:
99
+ #
100
+ # * :html - defines `rendered.html`
101
+ # * :json - defines `rendered.json`
102
+ #
103
+ # === Examples
104
+ #
105
+ # test "renders HTML" do
106
+ # article = Article.create!(title: "Hello, world")
107
+ #
108
+ # render partial: "articles/article", locals: { article: article }
109
+ #
110
+ # assert_pattern { rendered.html.at("main h1") => { content: "Hello, world" } }
111
+ # end
112
+ #
113
+ # test "renders JSON" do
114
+ # article = Article.create!(title: "Hello, world")
115
+ #
116
+ # render formats: :json, partial: "articles/article", locals: { article: article }
117
+ #
118
+ # assert_pattern { rendered.json => { title: "Hello, world" } }
119
+ # end
120
+ #
121
+ # To parse the rendered content into RSS, register a call to <tt>RSS::Parser.parse</tt>:
122
+ #
123
+ # register_parser :rss, -> rendered { RSS::Parser.parse(rendered) }
124
+ #
125
+ # test "renders RSS" do
126
+ # article = Article.create!(title: "Hello, world")
127
+ #
128
+ # render formats: :rss, partial: article
129
+ #
130
+ # assert_equal "Hello, world", rendered.rss.items.last.title
131
+ # end
132
+ #
133
+ # To parse the rendered content into a Capybara::Simple::Node,
134
+ # re-register an <tt>:html</tt> parser with a call to
135
+ # <tt>Capybara.string</tt>:
136
+ #
137
+ # register_parser :html, -> rendered { Capybara.string(rendered) }
138
+ #
139
+ # test "renders HTML" do
140
+ # article = Article.create!(title: "Hello, world")
141
+ #
142
+ # render partial: article
143
+ #
144
+ # rendered.html.assert_css "h1", text: "Hello, world"
145
+ # end
146
+ def register_parser(format, callable = nil, &block)
147
+ parser = callable || block || :itself.to_proc
148
+ content_class.redefine_method(format) do
149
+ parser.call(to_s)
150
+ end
151
+ end
152
+
63
153
  def tests(helper_class)
64
154
  case helper_class
65
155
  when String, Symbol
@@ -105,14 +195,33 @@ module ActionView
105
195
  end
106
196
  end
107
197
 
198
+ included do
199
+ class_attribute :content_class, instance_accessor: false, default: Content
200
+
201
+ setup :setup_with_controller
202
+
203
+ register_parser :html, -> rendered { Rails::Dom::Testing.html_document.parse(rendered).root }
204
+ register_parser :json, -> rendered { JSON.parse(rendered, object_class: ActiveSupport::HashWithIndifferentAccess) }
205
+
206
+ ActiveSupport.run_load_hooks(:action_view_test_case, self)
207
+
208
+ helper do
209
+ def protect_against_forgery?
210
+ false
211
+ end
212
+
213
+ def _test_case
214
+ controller._test_case
215
+ end
216
+ end
217
+ end
218
+
108
219
  def setup_with_controller
109
220
  controller_class = Class.new(ActionView::TestCase::TestController)
110
221
  @controller = controller_class.new
111
222
  @request = @controller.request
112
223
  @view_flow = ActionView::OutputFlow.new
113
- # empty string ensures buffer has UTF-8 encoding as
114
- # new without arguments returns ASCII-8BIT encoded buffer like String#new
115
- @output_buffer = ActiveSupport::SafeBuffer.new ""
224
+ @output_buffer = ActionView::OutputBuffer.new
116
225
  @rendered = +""
117
226
 
118
227
  test_case_instance = self
@@ -133,10 +242,64 @@ module ActionView
133
242
  @_rendered_views ||= RenderedViewsCollection.new
134
243
  end
135
244
 
245
+ # Returns the content rendered by the last +render+ call.
246
+ #
247
+ # The returned object behaves like a string but also exposes a number of methods
248
+ # that allows you to parse the content string in formats registered using
249
+ # <tt>.register_parser</tt>.
250
+ #
251
+ # By default includes the following parsers:
252
+ #
253
+ # +.html+
254
+ #
255
+ # Parse the <tt>rendered</tt> content String into HTML. By default, this means
256
+ # a <tt>Nokogiri::XML::Node</tt>.
257
+ #
258
+ # test "renders HTML" do
259
+ # article = Article.create!(title: "Hello, world")
260
+ #
261
+ # render partial: "articles/article", locals: { article: article }
262
+ #
263
+ # assert_pattern { rendered.html.at("main h1") => { content: "Hello, world" } }
264
+ # end
265
+ #
266
+ # To parse the rendered content into a <tt>Capybara::Simple::Node</tt>,
267
+ # re-register an <tt>:html</tt> parser with a call to
268
+ # <tt>Capybara.string</tt>:
269
+ #
270
+ # register_parser :html, -> rendered { Capybara.string(rendered) }
271
+ #
272
+ # test "renders HTML" do
273
+ # article = Article.create!(title: "Hello, world")
274
+ #
275
+ # render partial: article
276
+ #
277
+ # rendered.html.assert_css "h1", text: "Hello, world"
278
+ # end
279
+ #
280
+ # +.json+
281
+ #
282
+ # Parse the <tt>rendered</tt> content String into JSON. By default, this means
283
+ # a <tt>ActiveSupport::HashWithIndifferentAccess</tt>.
284
+ #
285
+ # test "renders JSON" do
286
+ # article = Article.create!(title: "Hello, world")
287
+ #
288
+ # render formats: :json, partial: "articles/article", locals: { article: article }
289
+ #
290
+ # assert_pattern { rendered.json => { title: "Hello, world" } }
291
+ # end
292
+ def rendered
293
+ @_rendered ||= self.class.content_class.new(@rendered)
294
+ end
295
+
136
296
  def _routes
137
297
  @controller._routes if @controller.respond_to?(:_routes)
138
298
  end
139
299
 
300
+ class Content < SimpleDelegator
301
+ end
302
+
140
303
  # Need to experiment if this priority is the best one: rendered => output_buffer
141
304
  class RenderedViewsCollection
142
305
  def initialize
@@ -163,25 +326,10 @@ module ActionView
163
326
  end
164
327
  end
165
328
 
166
- included do
167
- setup :setup_with_controller
168
- ActiveSupport.run_load_hooks(:action_view_test_case, self)
169
-
170
- helper do
171
- def protect_against_forgery?
172
- false
173
- end
174
-
175
- def _test_case
176
- controller._test_case
177
- end
178
- end
179
- end
180
-
181
329
  private
182
330
  # Need to experiment if this priority is the best one: rendered => output_buffer
183
331
  def document_root_element
184
- Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
332
+ Rails::Dom::Testing.html_document.parse(@rendered.blank? ? @output_buffer.to_str : @rendered).root
185
333
  end
186
334
 
187
335
  module Locals
@@ -227,6 +375,10 @@ module ActionView
227
375
  :@_result,
228
376
  :@_routes,
229
377
  :@controller,
378
+ :@_controller,
379
+ :@_request,
380
+ :@_config,
381
+ :@_default_form_builder,
230
382
  :@_layouts,
231
383
  :@_files,
232
384
  :@_rendered_views,
@@ -245,7 +397,7 @@ module ActionView
245
397
  :@view_context_class,
246
398
  :@view_flow,
247
399
  :@_subscribers,
248
- :@html_document
400
+ :@html_document,
249
401
  ]
250
402
 
251
403
  def _user_defined_ivars
@@ -277,6 +429,7 @@ module ActionView
277
429
  super
278
430
  end
279
431
  end
432
+ ruby2_keywords(:method_missing)
280
433
 
281
434
  def respond_to_missing?(name, include_private = false)
282
435
  begin
@@ -18,21 +18,31 @@ module ActionView
18
18
  end
19
19
 
20
20
  def bind_locals(locals)
21
- if template = @templates[locals]
22
- template
23
- else
21
+ unless template = @templates[locals]
24
22
  @write_lock.synchronize do
25
23
  normalized_locals = normalize_locals(locals)
26
24
 
27
25
  # We need ||=, both to dedup on the normalized locals and to check
28
26
  # while holding the lock.
29
- @templates[normalized_locals] ||= build_template(normalized_locals)
27
+ template = (@templates[normalized_locals] ||= build_template(normalized_locals))
30
28
 
31
29
  # This may have already been assigned, but we've already de-dup'd so
32
30
  # reassignment is fine.
33
- @templates[locals.dup] = @templates[normalized_locals]
31
+ @templates[locals.dup] = template
32
+
33
+ if template.strict_locals?
34
+ # Under strict locals, we only need one template.
35
+ # This replaces the @templates Concurrent::Map with a hash which
36
+ # returns this template for every key.
37
+ @templates = Hash.new(template).freeze
38
+ end
34
39
  end
35
40
  end
41
+ template
42
+ end
43
+
44
+ def built_templates # :nodoc:
45
+ @templates.values
36
46
  end
37
47
 
38
48
  private
@@ -3,7 +3,7 @@
3
3
  require_relative "gem_version"
4
4
 
5
5
  module ActionView
6
- # Returns the version of the currently loaded ActionView as a <tt>Gem::Version</tt>
6
+ # Returns the currently loaded version of Action View as a +Gem::Version+.
7
7
  def self.version
8
8
  gem_version
9
9
  end
@@ -5,7 +5,7 @@ module ActionView
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- ViewPaths.set_view_paths(self, ActionView::PathSet.new.freeze)
8
+ ActionView::PathRegistry.set_view_paths(self, ActionView::PathSet.new.freeze)
9
9
  end
10
10
 
11
11
  delegate :template_exists?, :any_templates?, :view_paths, :formats, :formats=,
@@ -13,11 +13,11 @@ module ActionView
13
13
 
14
14
  module ClassMethods
15
15
  def _view_paths
16
- ViewPaths.get_view_paths(self)
16
+ ActionView::PathRegistry.get_view_paths(self)
17
17
  end
18
18
 
19
19
  def _view_paths=(paths)
20
- ViewPaths.set_view_paths(self, paths)
20
+ ActionView::PathRegistry.set_view_paths(self, paths)
21
21
  end
22
22
 
23
23
  def _prefixes # :nodoc:
@@ -28,6 +28,13 @@ module ActionView
28
28
  end
29
29
  end
30
30
 
31
+ def _build_view_paths(paths) # :nodoc:
32
+ return paths if ActionView::PathSet === paths
33
+
34
+ paths = ActionView::PathRegistry.cast_file_system_resolvers(paths)
35
+ ActionView::PathSet.new(paths)
36
+ end
37
+
31
38
  # Append a path to the list of view paths for this controller.
32
39
  #
33
40
  # ==== Parameters
@@ -35,7 +42,7 @@ module ActionView
35
42
  # the default view path. You may also provide a custom view path
36
43
  # (see ActionView::PathSet for more information)
37
44
  def append_view_path(path)
38
- self._view_paths = view_paths + Array(path)
45
+ self._view_paths = view_paths + _build_view_paths(path)
39
46
  end
40
47
 
41
48
  # Prepend a path to the list of view paths for this controller.
@@ -45,7 +52,7 @@ module ActionView
45
52
  # the default view path. You may also provide a custom view path
46
53
  # (see ActionView::PathSet for more information)
47
54
  def prepend_view_path(path)
48
- self._view_paths = ActionView::PathSet.new(Array(path) + view_paths)
55
+ self._view_paths = _build_view_paths(path) + view_paths
49
56
  end
50
57
 
51
58
  # A list of all of the default view paths for this controller.
@@ -59,7 +66,7 @@ module ActionView
59
66
  # * <tt>paths</tt> - If a PathSet is provided, use that;
60
67
  # otherwise, process the parameter into a PathSet.
61
68
  def view_paths=(paths)
62
- self._view_paths = ActionView::PathSet.new(Array(paths))
69
+ self._view_paths = _build_view_paths(paths)
63
70
  end
64
71
 
65
72
  private
@@ -70,30 +77,14 @@ module ActionView
70
77
  end
71
78
  end
72
79
 
73
- # :stopdoc:
74
- @all_view_paths = {}
75
-
76
- def self.get_view_paths(klass)
77
- @all_view_paths[klass] || get_view_paths(klass.superclass)
78
- end
79
-
80
- def self.set_view_paths(klass, paths)
81
- @all_view_paths[klass] = paths
82
- end
83
-
84
- def self.all_view_paths
85
- @all_view_paths.values.uniq
86
- end
87
- # :startdoc:
88
-
89
80
  # The prefixes used in render "foo" shortcuts.
90
81
  def _prefixes # :nodoc:
91
82
  self.class._prefixes
92
83
  end
93
84
 
94
- # <tt>LookupContext</tt> is the object responsible for holding all
85
+ # LookupContext is the object responsible for holding all
95
86
  # information required for looking up templates, i.e. view paths and
96
- # details. Check <tt>ActionView::LookupContext</tt> for more information.
87
+ # details. Check ActionView::LookupContext for more information.
97
88
  def lookup_context
98
89
  @_lookup_context ||=
99
90
  ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
@@ -103,24 +94,24 @@ module ActionView
103
94
  {}
104
95
  end
105
96
 
106
- # Append a path to the list of view paths for the current <tt>LookupContext</tt>.
97
+ # Append a path to the list of view paths for the current LookupContext.
107
98
  #
108
99
  # ==== Parameters
109
100
  # * <tt>path</tt> - If a String is provided, it gets converted into
110
101
  # the default view path. You may also provide a custom view path
111
102
  # (see ActionView::PathSet for more information)
112
103
  def append_view_path(path)
113
- lookup_context.view_paths.push(*path)
104
+ lookup_context.append_view_paths(self.class._build_view_paths(path))
114
105
  end
115
106
 
116
- # Prepend a path to the list of view paths for the current <tt>LookupContext</tt>.
107
+ # Prepend a path to the list of view paths for the current LookupContext.
117
108
  #
118
109
  # ==== Parameters
119
110
  # * <tt>path</tt> - If a String is provided, it gets converted into
120
111
  # the default view path. You may also provide a custom view path
121
112
  # (see ActionView::PathSet for more information)
122
113
  def prepend_view_path(path)
123
- lookup_context.view_paths.unshift(*path)
114
+ lookup_context.prepend_view_paths(self.class._build_view_paths(path))
124
115
  end
125
116
  end
126
117
  end
data/lib/action_view.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2022 David Heinemeier Hansson
4
+ # Copyright (c) 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
@@ -26,7 +26,9 @@
26
26
  require "active_support"
27
27
  require "active_support/rails"
28
28
  require "action_view/version"
29
+ require "action_view/deprecator"
29
30
 
31
+ # :include: actionview/README.rdoc
30
32
  module ActionView
31
33
  extend ActiveSupport::Autoload
32
34
 
@@ -39,6 +41,7 @@ module ActionView
39
41
  autoload :Helpers
40
42
  autoload :LookupContext
41
43
  autoload :Layouts
44
+ autoload :PathRegistry
42
45
  autoload :PathSet
43
46
  autoload :RecordIdentifier
44
47
  autoload :Rendering
@@ -73,6 +73,22 @@ Released under the MIT license
73
73
  return element[expando][key] = value;
74
74
  };
75
75
 
76
+ Rails.isContentEditable = function(element) {
77
+ var isEditable;
78
+ isEditable = false;
79
+ while (true) {
80
+ if (element.isContentEditable) {
81
+ isEditable = true;
82
+ break;
83
+ }
84
+ element = element.parentElement;
85
+ if (!element) {
86
+ break;
87
+ }
88
+ }
89
+ return isEditable;
90
+ };
91
+
76
92
  Rails.$ = function(selector) {
77
93
  return Array.prototype.slice.call(document.querySelectorAll(selector));
78
94
  };
@@ -395,9 +411,9 @@ Released under the MIT license
395
411
 
396
412
  }).call(this);
397
413
  (function() {
398
- var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isXhrRedirect, matches, setData, stopEverything;
414
+ var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isContentEditable, isXhrRedirect, matches, setData, stopEverything;
399
415
 
400
- matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;
416
+ matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements, isContentEditable = Rails.isContentEditable;
401
417
 
402
418
  Rails.handleDisabledElement = function(e) {
403
419
  var element;
@@ -417,6 +433,9 @@ Released under the MIT license
417
433
  } else {
418
434
  element = e;
419
435
  }
436
+ if (isContentEditable(element)) {
437
+ return;
438
+ }
420
439
  if (matches(element, Rails.linkDisableSelector)) {
421
440
  return enableLinkElement(element);
422
441
  } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {
@@ -429,6 +448,9 @@ Released under the MIT license
429
448
  Rails.disableElement = function(e) {
430
449
  var element;
431
450
  element = e instanceof Event ? e.target : e;
451
+ if (isContentEditable(element)) {
452
+ return;
453
+ }
432
454
  if (matches(element, Rails.linkDisableSelector)) {
433
455
  return disableLinkElement(element);
434
456
  } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) {
@@ -513,10 +535,12 @@ Released under the MIT license
513
535
 
514
536
  }).call(this);
515
537
  (function() {
516
- var stopEverything;
538
+ var isContentEditable, stopEverything;
517
539
 
518
540
  stopEverything = Rails.stopEverything;
519
541
 
542
+ isContentEditable = Rails.isContentEditable;
543
+
520
544
  Rails.handleMethod = function(e) {
521
545
  var csrfParam, csrfToken, form, formContent, href, link, method;
522
546
  link = this;
@@ -524,6 +548,9 @@ Released under the MIT license
524
548
  if (!method) {
525
549
  return;
526
550
  }
551
+ if (isContentEditable(this)) {
552
+ return;
553
+ }
527
554
  href = Rails.href(link);
528
555
  csrfToken = Rails.csrfToken();
529
556
  csrfParam = Rails.csrfParam();
@@ -545,10 +572,10 @@ Released under the MIT license
545
572
 
546
573
  }).call(this);
547
574
  (function() {
548
- var ajax, fire, getData, isCrossDomain, isRemote, matches, serializeElement, setData, stopEverything,
575
+ var ajax, fire, getData, isContentEditable, isCrossDomain, isRemote, matches, serializeElement, setData, stopEverything,
549
576
  slice = [].slice;
550
577
 
551
- matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement;
578
+ matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement, isContentEditable = Rails.isContentEditable;
552
579
 
553
580
  isRemote = function(element) {
554
581
  var value;
@@ -566,6 +593,10 @@ Released under the MIT license
566
593
  fire(element, 'ajax:stopped');
567
594
  return false;
568
595
  }
596
+ if (isContentEditable(element)) {
597
+ fire(element, 'ajax:stopped');
598
+ return false;
599
+ }
569
600
  withCredentials = element.getAttribute('data-with-credentials');
570
601
  dataType = element.getAttribute('data-type') || 'script';
571
602
  if (matches(element, Rails.formSubmitSelector)) {