diff options
Diffstat (limited to 'actionview')
28 files changed, 151 insertions, 118 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 6bb1efb0ac..2c1ca12043 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,16 @@ +* Fix JavaScript views rendering does not work with Firefox when using + Content Security Policy. + + Fixes #32577. + + *Yuji Yaginuma* + +* Add the `nonce: true` option for `javascript_include_tag` helper to + support automatic nonce generation for Content Security Policy. + Works the same way as `javascript_tag nonce: true` does. + + *Yaroslav Markin* + * Remove `ActionView::Helpers::RecordTagHelper`. *Yoshiyuki Hirano* diff --git a/actionview/Rakefile b/actionview/Rakefile index 9542b626d1..bdfd96c141 100644 --- a/actionview/Rakefile +++ b/actionview/Rakefile @@ -131,7 +131,7 @@ namespace :assets do end task :lines do - load File.join(File.expand_path("..", __dir__), "/tools/line_statistics") + load File.expand_path("../tools/line_statistics", __dir__) files = FileList["lib/**/*.rb"] CodeTools::LineStatistics.new(files).print_loc end diff --git a/actionview/app/assets/javascripts/README.md b/actionview/app/assets/javascripts/README.md index 185dddc7e5..b74fa1afad 100644 --- a/actionview/app/assets/javascripts/README.md +++ b/actionview/app/assets/javascripts/README.md @@ -23,6 +23,8 @@ Note that the `data` attributes this library adds are a feature of HTML5. If you yarn add rails-ujs +Ensure that `.yarnclean` does not include `assets` if you use [yarn autoclean](https://yarnpkg.com/lang/en/docs/cli/autoclean/). + ## Usage ### Asset pipeline diff --git a/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee index cf31c796df..019bda635a 100644 --- a/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee @@ -66,7 +66,7 @@ processResponse = (response, type) -> try response = JSON.parse(response) else if type.match(/\b(?:java|ecma)script\b/) script = document.createElement('script') - script.nonce = cspNonce() + script.setAttribute('nonce', cspNonce()) script.text = response document.head.appendChild(script).parentNode.removeChild(script) else if type.match(/\bxml\b/) diff --git a/actionview/lib/action_view/context.rb b/actionview/lib/action_view/context.rb index 665a9e3171..3c605c3ee3 100644 --- a/actionview/lib/action_view/context.rb +++ b/actionview/lib/action_view/context.rb @@ -10,10 +10,11 @@ module ActionView # Action View contexts are supplied to Action Controller to render a template. # The default Action View context is ActionView::Base. # - # In order to work with ActionController, a Context must just include this module. - # The initialization of the variables used by the context (@output_buffer, @view_flow, - # and @virtual_path) is responsibility of the object that includes this module - # (although you can call _prepare_context defined below). + # In order to work with Action Controller, a Context must just include this + # module. The initialization of the variables used by the context + # (@output_buffer, @view_flow, and @virtual_path) is responsibility of the + # object that includes this module (although you can call _prepare_context + # defined below). module Context include CompiledTemplates attr_accessor :output_buffer, :view_flow diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 45cf48b3e0..39cdecb9e4 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true -require "concurrent/map" require "action_view/dependency_tracker" -require "monitor" module ActionView class Digestor @@ -70,13 +68,11 @@ module ActionView end private - def find_template(finder, *args) + def find_template(finder, name, prefixes, partial, keys) finder.disable_cache do - if format = finder.rendered_format - finder.find_all(*args, formats: [format]).first || finder.find_all(*args).first - else - finder.find_all(*args).first - end + format = finder.rendered_format + result = finder.find_all(name, prefixes, partial, keys, formats: [format]).first if format + result || finder.find_all(name, prefixes, partial, keys).first end end end diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb index 06fa1875fc..14bd8ffa84 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -55,6 +55,8 @@ module ActionView # that path. # * <tt>:skip_pipeline</tt> - This option is used to bypass the asset pipeline # when it is set to true. + # * <tt>:nonce<tt> - When set to true, adds an automatic nonce value if + # you have Content Security Policy enabled. # # ==== Examples # @@ -79,6 +81,9 @@ module ActionView # # javascript_include_tag "http://www.example.com/xmlhr.js" # # => <script src="http://www.example.com/xmlhr.js"></script> + # + # javascript_include_tag "http://www.example.com/xmlhr.js", nonce: true + # # => <script src="http://www.example.com/xmlhr.js" nonce="..."></script> def javascript_include_tag(*sources) options = sources.extract_options!.stringify_keys path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys @@ -90,6 +95,9 @@ module ActionView tag_options = { "src" => href }.merge!(options) + if tag_options["nonce"] == true + tag_options["nonce"] = content_security_policy_nonce + end content_tag("script".freeze, "", tag_options) }.join("\n").html_safe @@ -325,9 +333,9 @@ module ActionView # # image_tag(user.avatar) # # => <img src="/rails/active_storage/blobs/.../tiger.jpg" /> - # image_tag(user.avatar.variant(resize: "100x100")) + # image_tag(user.avatar.variant(resize_to_fit: [100, 100])) # # => <img src="/rails/active_storage/variants/.../tiger.jpg" /> - # image_tag(user.avatar.variant(resize: "100x100"), size: '100') + # image_tag(user.avatar.variant(resize_to_fit: [100, 100]), size: '100') # # => <img width="100" height="100" src="/rails/active_storage/variants/.../tiger.jpg" /> def image_tag(source, options = {}) options = options.symbolize_keys diff --git a/actionview/lib/action_view/helpers/cache_helper.rb b/actionview/lib/action_view/helpers/cache_helper.rb index 3cbb1ed1a7..15d187a9ec 100644 --- a/actionview/lib/action_view/helpers/cache_helper.rb +++ b/actionview/lib/action_view/helpers/cache_helper.rb @@ -201,7 +201,7 @@ module ActionView end # This helper returns the name of a cache key for a given fragment cache - # call. By supplying +skip_digest:+ true to cache, the digestion of cache + # call. By supplying <tt>skip_digest: true</tt> to cache, the digestion of cache # fragments can be manually bypassed. This is useful when cache fragments # cannot be manually expired unless you know the exact key which is the # case when using memcached. diff --git a/actionview/lib/action_view/helpers/rendering_helper.rb b/actionview/lib/action_view/helpers/rendering_helper.rb index 8e505ab054..1e12aa2736 100644 --- a/actionview/lib/action_view/helpers/rendering_helper.rb +++ b/actionview/lib/action_view/helpers/rendering_helper.rb @@ -13,7 +13,6 @@ module ActionView # * <tt>:partial</tt> - See <tt>ActionView::PartialRenderer</tt>. # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those. # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller. - # * <tt>:text</tt> - Renders the text passed in out. # * <tt>:plain</tt> - Renders the text passed in out. Setting the content # type as <tt>text/plain</tt>. # * <tt>:html</tt> - Renders the HTML safe string passed in out, otherwise diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb index b73c4be1ee..d12989ea64 100644 --- a/actionview/lib/action_view/helpers/tag_helper.rb +++ b/actionview/lib/action_view/helpers/tag_helper.rb @@ -88,9 +88,10 @@ module ActionView if value.is_a?(Array) value = escape ? safe_join(value, " ".freeze) : value.join(" ".freeze) else - value = escape ? ERB::Util.unwrapped_html_escape(value) : value.to_s + value = escape ? ERB::Util.unwrapped_html_escape(value) : value.to_s.dup end - %(#{key}="#{value.gsub('"'.freeze, '"'.freeze)}") + value.gsub!('"'.freeze, """.freeze) + %(#{key}="#{value}") end private diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb index 80cb73d683..d3cdab0d2f 100644 --- a/actionview/lib/action_view/helpers/translation_helper.rb +++ b/actionview/lib/action_view/helpers/translation_helper.rb @@ -59,11 +59,9 @@ module ActionView # they can provide HTML values for. def translate(key, options = {}) options = options.dup - has_default = options.has_key?(:default) - remaining_defaults = Array(options.delete(:default)).compact - - if has_default && !remaining_defaults.first.kind_of?(Symbol) - options[:default] = remaining_defaults + if options.has_key?(:default) + remaining_defaults = Array(options.delete(:default)).compact + options[:default] = remaining_defaults unless remaining_defaults.first.kind_of?(Symbol) end # If the user has explicitly decided to NOT raise errors, pass that option to I18n. diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index 5b40af4f2f..d7f97c3b50 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -363,7 +363,7 @@ module ActionView @options = options @block = block - @locals = options[:locals] || {} + @locals = options[:locals] ? options[:locals].symbolize_keys : {} @details = extract_details(options) prepend_formats(options[:formats]) diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb index e059f37d38..3e6b55a87e 100644 --- a/actionview/test/actionpack/controller/render_test.rb +++ b/actionview/test/actionpack/controller/render_test.rb @@ -485,6 +485,10 @@ class TestController < ActionController::Base render partial: "customer", locals: { customer: Customer.new("david") } end + def partial_with_string_locals + render partial: "customer", locals: { "customer" => Customer.new("david") } + end + def partial_with_form_builder render partial: ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {}) end @@ -1170,6 +1174,11 @@ class RenderTest < ActionController::TestCase assert_equal "Hello: david", @response.body end + def test_partial_with_string_locals + get :partial_with_string_locals + assert_equal "Hello: david", @response.body + end + def test_partial_with_form_builder get :partial_with_form_builder assert_equal "<label for=\"post_title\">Title</label>\n", @response.body diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb index 6d98eacfb8..e68f03d1f4 100644 --- a/actionview/test/template/asset_tag_helper_test.rb +++ b/actionview/test/template/asset_tag_helper_test.rb @@ -29,6 +29,10 @@ class AssetTagHelperTest < ActionView::TestCase "http://www.example.com" end + def content_security_policy_nonce + "iyhD0Yc0W+c=" + end + AssetPathToTag = { %(asset_path("")) => %(), %(asset_path(" ")) => %(), @@ -421,6 +425,10 @@ class AssetTagHelperTest < ActionView::TestCase assert_dom_equal %(<script src="//assets.example.com/javascripts/prototype.js"></script>), javascript_include_tag("prototype") end + def test_javascript_include_tag_nonce + assert_dom_equal %(<script src="/javascripts/bank.js" nonce="iyhD0Yc0W+c="></script>), javascript_include_tag("bank", nonce: true) + end + def test_stylesheet_path StylePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end diff --git a/actionview/test/template/capture_helper_test.rb b/actionview/test/template/capture_helper_test.rb index 31c280a91c..131e49327e 100644 --- a/actionview/test/template/capture_helper_test.rb +++ b/actionview/test/template/capture_helper_test.rb @@ -49,21 +49,21 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_multiple_calls - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title, "bar" assert_equal "foobar", content_for(:title) end def test_content_for_with_multiple_calls_and_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title, "bar", flush: true assert_equal "bar", content_for(:title) end def test_content_for_with_block - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do output_buffer << "foo" output_buffer << "bar" @@ -73,7 +73,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_block_and_multiple_calls_with_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do "foo" end @@ -84,7 +84,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_block_and_multiple_calls_with_flush_nil_content - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do "foo" end @@ -95,7 +95,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_block_and_multiple_calls_without_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do "foo" end @@ -106,7 +106,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_whitespace_block - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title do output_buffer << " \n " @@ -117,7 +117,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_whitespace_block_and_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title, flush: true do output_buffer << " \n " @@ -128,7 +128,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_returns_nil_when_writing - assert ! content_for?(:title) + assert_not content_for?(:title) assert_nil content_for(:title, "foo") assert_nil content_for(:title) { output_buffer << "bar"; nil } assert_nil content_for(:title) { output_buffer << " \n "; nil } @@ -144,14 +144,14 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_question_mark - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "title" assert content_for?(:title) - assert ! content_for?(:something_else) + assert_not content_for?(:something_else) end def test_content_for_should_be_html_safe_after_flush_empty - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do content_tag(:p, "title") end @@ -164,7 +164,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_provide - assert !content_for?(:title) + assert_not content_for?(:title) provide :title, "hi" assert content_for?(:title) assert_equal "hi", content_for(:title) diff --git a/actionview/test/template/form_helper/form_with_test.rb b/actionview/test/template/form_helper/form_with_test.rb index 6b65d740eb..ed1683bad2 100644 --- a/actionview/test/template/form_helper/form_with_test.rb +++ b/actionview/test/template/form_helper/form_with_test.rb @@ -2347,13 +2347,4 @@ class FormWithActsLikeFormForTest < FormWithTest ensure I18n.locale = old_locale end - - def with_default_enforce_utf8(value) - old_value = ActionView::Helpers::FormTagHelper.default_enforce_utf8 - ActionView::Helpers::FormTagHelper.default_enforce_utf8 = value - - yield - ensure - ActionView::Helpers::FormTagHelper.default_enforce_utf8 = old_value - end end diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb index beee76f711..38469cbe3d 100644 --- a/actionview/test/template/lookup_context_test.rb +++ b/actionview/test/template/lookup_context_test.rb @@ -195,7 +195,7 @@ class LookupContextTest < ActiveSupport::TestCase assert @lookup_context.cache template = @lookup_context.disable_cache do - assert !@lookup_context.cache + assert_not @lookup_context.cache @lookup_context.find("foo", %w(test), true) end assert @lookup_context.cache diff --git a/actionview/test/template/partial_iteration_test.rb b/actionview/test/template/partial_iteration_test.rb index 06bbdabac0..1c3c566667 100644 --- a/actionview/test/template/partial_iteration_test.rb +++ b/actionview/test/template/partial_iteration_test.rb @@ -18,7 +18,7 @@ class PartialIterationTest < ActiveSupport::TestCase def test_first_is_false_unless_current_is_at_the_first_index iteration = ActionView::PartialIteration.new 3 iteration.iterate! - assert !iteration.first?, "not first when current is 1" + assert_not iteration.first?, "not first when current is 1" end def test_last_is_true_when_current_is_at_the_last_index @@ -30,6 +30,6 @@ class PartialIterationTest < ActiveSupport::TestCase def test_last_is_false_unless_current_is_at_the_last_index iteration = ActionView::PartialIteration.new 3 - assert !iteration.last?, "not last when current is 0" + assert_not iteration.last?, "not last when current is 0" end end diff --git a/actionview/test/template/test_case_test.rb b/actionview/test/template/test_case_test.rb index 05e5f21ce4..d98fd4f9a2 100644 --- a/actionview/test/template/test_case_test.rb +++ b/actionview/test/template/test_case_test.rb @@ -192,7 +192,7 @@ module ActionView helper HelperThatInvokesProtectAgainstForgery test "protect_from_forgery? in any helpers returns false" do - assert !view.help_me + assert_not view.help_me end end diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb index 8bccda481b..08cb5dfea7 100644 --- a/actionview/test/template/url_helper_test.rb +++ b/actionview/test/template/url_helper_test.rb @@ -508,16 +508,16 @@ class UrlHelperTest < ActiveSupport::TestCase def test_current_page_considering_params @request = request_for_url("/?order=desc&page=1") - assert !current_page?(url_hash, check_parameters: true) - assert !current_page?(url_hash.merge(check_parameters: true)) - assert !current_page?(ActionController::Parameters.new(url_hash.merge(check_parameters: true)).permit!) - assert !current_page?("http://www.example.com/", check_parameters: true) + assert_not current_page?(url_hash, check_parameters: true) + assert_not current_page?(url_hash.merge(check_parameters: true)) + assert_not current_page?(ActionController::Parameters.new(url_hash.merge(check_parameters: true)).permit!) + assert_not current_page?("http://www.example.com/", check_parameters: true) end def test_current_page_considering_params_when_options_does_not_respond_to_to_hash @request = request_for_url("/?order=desc&page=1") - assert !current_page?(:back, check_parameters: false) + assert_not current_page?(:back, check_parameters: false) end def test_current_page_with_params_that_match @@ -562,7 +562,7 @@ class UrlHelperTest < ActiveSupport::TestCase def test_current_page_with_not_get_verb @request = request_for_url("/events", method: :post) - assert !current_page?("/events") + assert_not current_page?("/events") end def test_link_unless_current diff --git a/actionview/test/ujs/public/test/call-remote-callbacks.js b/actionview/test/ujs/public/test/call-remote-callbacks.js index 48763f6301..9c0c8cfb4b 100644 --- a/actionview/test/ujs/public/test/call-remote-callbacks.js +++ b/actionview/test/ujs/public/test/call-remote-callbacks.js @@ -75,9 +75,9 @@ asyncTest('setting data("with-credentials",true) with "ajax:before" uses new set asyncTest('stopping the "ajax:beforeSend" event aborts the request', 1, function() { submit(function(form) { - form.bindNative('ajax:beforeSend', function() { + form.bindNative('ajax:beforeSend', function(e) { ok(true, 'aborting request in ajax:beforeSend') - return false + e.preventDefault() }) form.unbind('ajax:send').bindNative('ajax:send', function() { ok(false, 'ajax:send should not run') @@ -148,8 +148,8 @@ function skipIt() { .bind('iframe:loading', function() { ok(false, 'form should not get submitted') }) - .bindNative('ajax:aborted:file', function() { - return false + .bindNative('ajax:aborted:file', function(e) { + e.preventDefault() }) .triggerNative('submit') @@ -162,9 +162,9 @@ function skipIt() { } asyncTest('"ajax:beforeSend" can be observed and stopped with event delegation', 1, function() { - $(document).delegate('form[data-remote]', 'ajax:beforeSend', function() { + $(document).delegate('form[data-remote]', 'ajax:beforeSend', function(e) { ok(true, 'ajax:beforeSend observed with event delegation') - return false + e.preventDefault() }) submit(function(form) { diff --git a/actionview/test/ujs/public/test/call-remote.js b/actionview/test/ujs/public/test/call-remote.js index e5277a2a03..778dc1b09a 100644 --- a/actionview/test/ujs/public/test/call-remote.js +++ b/actionview/test/ujs/public/test/call-remote.js @@ -210,7 +210,7 @@ asyncTest('allow empty form "action"', 1, function() { buildForm({ action: '' }) $('#qunit-fixture').find('form') - .bindNative('ajax:beforeSend', function(e, xhr, settings) { + .bindNative('ajax:beforeSend', function(evt, xhr, settings) { // Get current location (the same way jQuery does) try { currentLocation = location.href @@ -229,7 +229,7 @@ asyncTest('allow empty form "action"', 1, function() { // Prevent the request from actually getting sent to the current page and // causing an error. - return false + evt.preventDefault() }) .triggerNative('submit') @@ -257,7 +257,7 @@ asyncTest('intelligently guesses crossDomain behavior when target URL has a diff equal(settings.crossDomain, true, 'crossDomain should be set to true') // prevent request from actually getting sent off-domain - return false + evt.preventDefault() }) .triggerNative('submit') @@ -276,7 +276,7 @@ asyncTest('intelligently guesses crossDomain behavior when target URL consists o equal(settings.crossDomain, false, 'crossDomain should be set to false') // prevent request from actually getting sent off-domain - return false + evt.preventDefault() }) .triggerNative('submit') diff --git a/actionview/test/ujs/public/test/data-confirm.js b/actionview/test/ujs/public/test/data-confirm.js index 74f373148f..1bd57b69ad 100644 --- a/actionview/test/ujs/public/test/data-confirm.js +++ b/actionview/test/ujs/public/test/data-confirm.js @@ -173,9 +173,9 @@ asyncTest('binding to confirm event of a link and returning false', 1, function( } $('a[data-confirm]') - .bindNative('confirm', function() { + .bindNative('confirm', function(e) { App.assertCallbackInvoked('confirm') - return false + e.preventDefault() }) .bindNative('confirm:complete', function() { App.assertCallbackNotInvoked('confirm:complete') @@ -194,9 +194,9 @@ asyncTest('binding to confirm event of a button and returning false', 1, functio } $('button[data-confirm]') - .bindNative('confirm', function() { + .bindNative('confirm', function(e) { App.assertCallbackInvoked('confirm') - return false + e.preventDefault() }) .bindNative('confirm:complete', function() { App.assertCallbackNotInvoked('confirm:complete') @@ -216,9 +216,9 @@ asyncTest('binding to confirm:complete event of a link and returning false', 2, } $('a[data-confirm]') - .bindNative('confirm:complete', function() { + .bindNative('confirm:complete', function(e) { App.assertCallbackInvoked('confirm:complete') - return false + e.preventDefault() }) .bindNative('ajax:beforeSend', function() { App.assertCallbackNotInvoked('ajax:beforeSend') @@ -238,9 +238,9 @@ asyncTest('binding to confirm:complete event of a button and returning false', 2 } $('button[data-confirm]') - .bindNative('confirm:complete', function() { + .bindNative('confirm:complete', function(e) { App.assertCallbackInvoked('confirm:complete') - return false + e.preventDefault() }) .bindNative('ajax:beforeSend', function() { App.assertCallbackNotInvoked('ajax:beforeSend') diff --git a/actionview/test/ujs/public/test/data-disable-with.js b/actionview/test/ujs/public/test/data-disable-with.js index b29cbbc867..645ad494c3 100644 --- a/actionview/test/ujs/public/test/data-disable-with.js +++ b/actionview/test/ujs/public/test/data-disable-with.js @@ -132,7 +132,8 @@ test('form input[type=submit][data-disable-with] re-enables when `pageshow` even }) asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html() + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), + origFormContents = form.html() form.bindNative('ajax:success', function() { form.html(origFormContents) @@ -146,7 +147,8 @@ asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced i }) asyncTest('form[data-remote] input[data-disable-with] is replaced with disabled field in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), + input = form.find('input[type=submit]'), newDisabledInput = input.clone().attr('disabled', 'disabled') form.bindNative('ajax:success', function() { @@ -238,9 +240,9 @@ asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:before` event App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(link, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') @@ -256,9 +258,9 @@ asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:beforeSend` e App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(link, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') @@ -293,8 +295,9 @@ asyncTest('form[data-remote] input|button|textarea[data-disable-with] does not d submit = $('<input type="submit" data-disable-with="submitting ..." name="submit2" value="Submit" />').appendTo(form) form - .bindNative('ajax:beforeSend', function() { - return false + .bindNative('ajax:beforeSend', function(e) { + e.preventDefault() + e.stopPropagation() }) .triggerNative('submit') @@ -343,9 +346,9 @@ asyncTest('button[data-remote][data-disable-with] re-enables when `ajax:before` App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(button, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') @@ -361,9 +364,9 @@ asyncTest('button[data-remote][data-disable-with] re-enables when `ajax:beforeSe App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(button, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') diff --git a/actionview/test/ujs/public/test/data-disable.js b/actionview/test/ujs/public/test/data-disable.js index ccc38cf9ae..e9919764b6 100644 --- a/actionview/test/ujs/public/test/data-disable.js +++ b/actionview/test/ujs/public/test/data-disable.js @@ -91,7 +91,7 @@ asyncTest('form input[type=submit][data-disable] disables', 6, function() { }) asyncTest('form[data-remote] input[type=submit][data-disable] is replaced in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html() + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html() form.bindNative('ajax:success', function() { form.html(origFormContents) @@ -105,7 +105,7 @@ asyncTest('form[data-remote] input[type=submit][data-disable] is replaced in aja }) asyncTest('form[data-remote] input[data-disable] is replaced with disabled field in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), newDisabledInput = input.clone().attr('disabled', 'disabled') form.bindNative('ajax:success', function() { @@ -168,9 +168,9 @@ asyncTest('a[data-remote][data-disable] re-enables when `ajax:before` event is c App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(link, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') @@ -186,9 +186,9 @@ asyncTest('a[data-remote][data-disable] re-enables when `ajax:beforeSend` event App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(link, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') @@ -223,8 +223,9 @@ asyncTest('form[data-remote] input|button|textarea[data-disable] does not disabl submit = $('<input type="submit" data-disable="submitting ..." name="submit2" value="Submit" />').appendTo(form) form - .bindNative('ajax:beforeSend', function() { - return false + .bindNative('ajax:beforeSend', function(e) { + e.preventDefault() + e.stopPropagation() }) .triggerNative('submit') @@ -273,9 +274,9 @@ asyncTest('button[data-remote][data-disable] re-enables when `ajax:before` event App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(button, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') @@ -291,9 +292,9 @@ asyncTest('button[data-remote][data-disable] re-enables when `ajax:beforeSend` e App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(button, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') diff --git a/actionview/test/ujs/public/test/data-remote.js b/actionview/test/ujs/public/test/data-remote.js index cbbd4e6c92..3503c2cff3 100644 --- a/actionview/test/ujs/public/test/data-remote.js +++ b/actionview/test/ujs/public/test/data-remote.js @@ -272,9 +272,10 @@ asyncTest('returning false in form\'s submit bindings in non-submit-bubbling bro form .append($('<input type="submit" />')) - .bindNative('submit', function() { + .bindNative('submit', function(e) { ok(true, 'binding handler is called') - return false + e.preventDefault() + e.stopPropagation() }) .bindNative('ajax:beforeSend', function() { ok(false, 'form should not be submitted') @@ -296,8 +297,8 @@ asyncTest('clicking on a link with falsy "data-remote" attribute does not fire a .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('click', function() { - return false + .bindNative('click', function(e) { + e.preventDefault() }) .triggerNative('click') @@ -314,8 +315,8 @@ asyncTest('ctrl-clicking on a link with falsy "data-remote" attribute does not f .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('click', function() { - return false + .bindNative('click', function(e) { + e.preventDefault() }) .triggerNative('click', { metaKey: true }) @@ -333,8 +334,8 @@ asyncTest('clicking on a button with falsy "data-remote" attribute', 0, function .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('click', function() { - return false + .bindNative('click', function(e) { + e.preventDefault() }) .triggerNative('click') @@ -347,8 +348,8 @@ asyncTest('submitting a form with falsy "data-remote" attribute', 0, function() .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('submit', function() { - return false + .bindNative('submit', function(e) { + e.preventDefault() }) .triggerNative('submit') @@ -429,7 +430,7 @@ asyncTest('changing a select option without "data-url" attribute still fires aja ajaxLocation = settings.url.replace(settings.data, '').replace(/&$/, '').replace(/\?$/, '') equal(ajaxLocation, currentLocation, 'URL should be current page by default') - return false + e.preventDefault() }) .val('optionValue2') .triggerNative('change') diff --git a/actionview/test/ujs/public/test/override.js b/actionview/test/ujs/public/test/override.js index 299c7018cc..d73276ee4f 100644 --- a/actionview/test/ujs/public/test/override.js +++ b/actionview/test/ujs/public/test/override.js @@ -25,7 +25,7 @@ asyncTest('the getter for an element\'s href is overridable', 1, function() { $('#qunit-fixture a') .bindNative('ajax:beforeSend', function(e, xhr, options) { equal('/data/href', options.url) - return false + e.preventDefault() }) .triggerNative('click') start() @@ -35,7 +35,7 @@ asyncTest('the getter for an element\'s href works normally if not overridden', $('#qunit-fixture a') .bindNative('ajax:beforeSend', function(e, xhr, options) { equal(location.protocol + '//' + location.host + '/real/href', options.url) - return false + e.preventDefault() }) .triggerNative('click') start() diff --git a/actionview/test/ujs/public/test/settings.js b/actionview/test/ujs/public/test/settings.js index 299c71bb00..b1ce3b8c64 100644 --- a/actionview/test/ujs/public/test/settings.js +++ b/actionview/test/ujs/public/test/settings.js @@ -103,14 +103,16 @@ $.fn.extend({ bindNative: function(event, handler) { if (!handler) return this - this.bind(event, function(e) { + var el = this[0] + el.addEventListener(event, function(e) { var args = [] - if (e.originalEvent.detail) { - args = e.originalEvent.detail.slice() + if (e.detail) { + args = e.detail.slice() } args.unshift(e) - return handler.apply(this, args) - }) + return handler.apply(el, args) + }, false) + return this } }) |