diff --git a/Gemfile.lock b/Gemfile.lock index 92b8540..b7cf640 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,85 +2,112 @@ PATH remote: . specs: prototype-rails (4.0.0) - rails (~> 4.0) + rails (>= 4.0) GEM remote: https://rubygems.org/ specs: - actionmailer (4.0.0) - actionpack (= 4.0.0) - mail (~> 2.5.3) - actionpack (4.0.0) - activesupport (= 4.0.0) - builder (~> 3.1.0) - erubis (~> 2.7.0) - rack (~> 1.5.2) - rack-test (~> 0.6.2) - activemodel (4.0.0) - activesupport (= 4.0.0) - builder (~> 3.1.0) - activerecord (4.0.0) - activemodel (= 4.0.0) - activerecord-deprecated_finders (~> 1.0.2) - activesupport (= 4.0.0) - arel (~> 4.0.0) - activerecord-deprecated_finders (1.0.3) - activesupport (4.0.0) - i18n (~> 0.6, >= 0.6.4) - minitest (~> 4.2) - multi_json (~> 1.3) - thread_safe (~> 0.1) - tzinfo (~> 0.3.37) - arel (4.0.0) - atomic (1.1.13) - builder (3.1.4) - erubis (2.7.0) - hike (1.2.3) - i18n (0.6.5) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) + actioncable (5.1.1) + actionpack (= 5.1.1) + nio4r (~> 2.0) + websocket-driver (~> 0.6.1) + actionmailer (5.1.1) + actionpack (= 5.1.1) + actionview (= 5.1.1) + activejob (= 5.1.1) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.1.1) + actionview (= 5.1.1) + activesupport (= 5.1.1) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.1.1) + activesupport (= 5.1.1) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.1.1) + activesupport (= 5.1.1) + globalid (>= 0.3.6) + activemodel (5.1.1) + activesupport (= 5.1.1) + activerecord (5.1.1) + activemodel (= 5.1.1) + activesupport (= 5.1.1) + arel (~> 8.0) + activesupport (5.1.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + arel (8.0.0) + builder (3.2.3) + concurrent-ruby (1.0.5) + erubi (1.6.0) + globalid (0.4.0) + activesupport (>= 4.2.0) + i18n (0.8.1) + loofah (2.0.3) + nokogiri (>= 1.5.9) + mail (2.6.5) + mime-types (>= 1.16, < 4) metaclass (0.0.1) - mime-types (1.24) - minitest (4.7.5) + method_source (0.8.2) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mini_portile2 (2.1.0) + minitest (5.10.2) mocha (0.10.3) metaclass (~> 0.0.1) - multi_json (1.7.9) - polyglot (0.3.3) - rack (1.5.2) - rack-test (0.6.2) + nio4r (2.0.0) + nokogiri (1.7.2) + mini_portile2 (~> 2.1.0) + rack (2.0.3) + rack-test (0.6.3) rack (>= 1.0) - rails (4.0.0) - actionmailer (= 4.0.0) - actionpack (= 4.0.0) - activerecord (= 4.0.0) - activesupport (= 4.0.0) + rails (5.1.1) + actioncable (= 5.1.1) + actionmailer (= 5.1.1) + actionpack (= 5.1.1) + actionview (= 5.1.1) + activejob (= 5.1.1) + activemodel (= 5.1.1) + activerecord (= 5.1.1) + activesupport (= 5.1.1) bundler (>= 1.3.0, < 2.0) - railties (= 4.0.0) - sprockets-rails (~> 2.0.0) - railties (4.0.0) - actionpack (= 4.0.0) - activesupport (= 4.0.0) + railties (= 5.1.1) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + railties (5.1.1) + actionpack (= 5.1.1) + activesupport (= 5.1.1) + method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rake (10.1.0) - sprockets (2.10.0) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.0.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - sprockets (~> 2.8) - thor (0.18.1) - thread_safe (0.1.2) - atomic - tilt (1.4.1) - treetop (1.4.14) - polyglot - polyglot (>= 0.3.1) - tzinfo (0.3.37) + rake (12.0.0) + sprockets (3.7.1) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.0) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.19.4) + thread_safe (0.3.6) + tzinfo (1.2.3) + thread_safe (~> 0.1) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.2) PLATFORMS ruby @@ -88,3 +115,6 @@ PLATFORMS DEPENDENCIES mocha prototype-rails! + +BUNDLED WITH + 1.14.6 diff --git a/lib/action_view/helpers/prototype_helper.rb b/lib/action_view/helpers/prototype_helper.rb index 6e33385..9196c20 100644 --- a/lib/action_view/helpers/prototype_helper.rb +++ b/lib/action_view/helpers/prototype_helper.rb @@ -601,7 +601,7 @@ def method_missing(method, *arguments) # page.hide 'spinner' # end def update_page(&block) - JavaScriptGenerator.new(self, &block).to_s.html_safe + JavaScriptGenerator.new(self, &block).to_s end # Works like update_page but wraps the generated JavaScript in a diff --git a/lib/action_view/template/handlers/rjs.rb b/lib/action_view/template/handlers/rjs.rb index 0855959..aea56bc 100644 --- a/lib/action_view/template/handlers/rjs.rb +++ b/lib/action_view/template/handlers/rjs.rb @@ -3,9 +3,9 @@ module Template::Handlers class RJS # Default format used by RJS. class_attribute :default_format - self.default_format = Mime::JS + self.default_format = Mime[:js] - def call(template) + def call(template, source = template.source) "update_page do |page|;#{template.source}\nend" end end diff --git a/lib/prototype-rails/javascript_helper.rb b/lib/prototype-rails/javascript_helper.rb index 29a71f1..2d57bee 100644 --- a/lib/prototype-rails/javascript_helper.rb +++ b/lib/prototype-rails/javascript_helper.rb @@ -35,7 +35,7 @@ def button_to_function(name, *args, &block) function = block_given? ? update_page(&block) : args[0] || '' onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};" - tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick)) + tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => escape_once(onclick)), false, false) end # link_to_function("Show me more", nil, :id => "more_link") do |page| @@ -62,6 +62,6 @@ def link_to_function(name, *args, &block) onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" href = html_options[:href] || '#' - content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) + content_tag(:a, name, html_options.merge(:href => href, :onclick => escape_once(onclick)), false) end end diff --git a/lib/prototype-rails/on_load_action_view.rb b/lib/prototype-rails/on_load_action_view.rb index 8942274..47109c9 100644 --- a/lib/prototype-rails/on_load_action_view.rb +++ b/lib/prototype-rails/on_load_action_view.rb @@ -15,9 +15,11 @@ end if defined?(Rails.env) && Rails.env.test? - ActionView::TestCase.class_eval do - include ActionView::Helpers::PrototypeHelper - include ActionView::Helpers::ScriptaculousHelper + ActiveSupport::Reloader.to_prepare do + ActionView::TestCase.class_eval do + include ActionView::Helpers::PrototypeHelper + include ActionView::Helpers::ScriptaculousHelper + end end end diff --git a/lib/prototype-rails/renderers.rb b/lib/prototype-rails/renderers.rb index a514adc..e7c6f03 100644 --- a/lib/prototype-rails/renderers.rb +++ b/lib/prototype-rails/renderers.rb @@ -5,7 +5,7 @@ module Renderers add :update do |proc, options| view_context = self.view_context generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc) - self.content_type = Mime::JS + self.content_type = Mime[:js] self.response_body = generator.to_s end end diff --git a/lib/prototype-rails/rendering.rb b/lib/prototype-rails/rendering.rb index e2350d8..8626a10 100644 --- a/lib/prototype-rails/rendering.rb +++ b/lib/prototype-rails/rendering.rb @@ -1,13 +1,14 @@ require 'action_view/helpers/rendering_helper' -ActionView::Helpers::RenderingHelper.module_eval do - def render_with_update(options = {}, locals = {}, &block) - if options == :update - update_page(&block) - else - render_without_update(options, locals, &block) - end +module PrototypeRails + module Rendering + def render(options = {}, locals = {}, &block) + if options == :update + update_page(&block) + else + super(options, locals, &block) + end + end end - - alias_method_chain :render, :update -end \ No newline at end of file +end +ActionView::Helpers::RenderingHelper.send(:prepend, PrototypeRails::Rendering) diff --git a/lib/prototype-rails/selector_assertions.rb b/lib/prototype-rails/selector_assertions.rb index bdbe918..457e682 100644 --- a/lib/prototype-rails/selector_assertions.rb +++ b/lib/prototype-rails/selector_assertions.rb @@ -1,14 +1,14 @@ require 'active_support/core_ext/module/aliasing' -require 'action_view/vendor/html-scanner' require 'action_dispatch/testing/assertions' -require 'action_dispatch/testing/assertions/selector' +require 'rails/dom/testing/assertions/selector_assertions' #-- # Copyright (c) 2006 Assaf Arkin (http://labnotes.org) # Under MIT and/or CC By license. #++ -ActionDispatch::Assertions::SelectorAssertions.module_eval do +module PrototypeRails + module SelectorAssertions # Selects content from the RJS response. # # === Narrowing down @@ -193,7 +193,6 @@ def response_from_page_with_rjs response_from_page_without_rjs end end - alias_method_chain :response_from_page, :rjs # Unescapes a RJS string. def unescape_rjs(rjs_string) @@ -208,3 +207,4 @@ def unescape_rjs(rjs_string) unescaped end end +end diff --git a/prototype-rails.gemspec b/prototype-rails.gemspec index 512ae58..596f1d8 100644 --- a/prototype-rails.gemspec +++ b/prototype-rails.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |spec| spec.files = %w(README.md Rakefile Gemfile MIT-LICENSE) + Dir['lib/**/*', 'vendor/**/*'] - spec.add_dependency('rails', '~> 4.0') + spec.add_dependency('rails', '>= 4.0') spec.add_development_dependency('mocha') spec.license = "MIT" end diff --git a/test/template/prototype_helper_test.rb b/test/template/prototype_helper_test.rb index a6aa848..1991051 100644 --- a/test/template/prototype_helper_test.rb +++ b/test/template/prototype_helper_test.rb @@ -104,6 +104,18 @@ def test_update_page_tag_with_html_options assert_equal javascript_tag(create_generator(&block).to_s, {:defer => 'true'}), update_page_tag({:defer => 'true'}, &block) end + def test_update_page_html_tag + block = Proc.new { |page| page.hide('cancel-commit') } + input_tag = submit_tag('Save', :onclick => 'Element.hide("cancel-commit");') + assert_equal input_tag, submit_tag('Save', :onclick => update_page(&block)) + end + + def test_update_page_link_to_function + block = Proc.new { |page| page.hide('cancel-commit') } + link_tag = link_to_function('Save', 'Element.hide("cancel-commit");') + assert_equal link_tag, link_to_function('Save', update_page(&block)) + end + def test_remote_function res = remote_function(:url => authors_path, :with => "'author[name]='+$F('author_name')+'&author[dob]='+$F('author_dob')") assert_equal "new Ajax.Request('/authors', {asynchronous:true, evalScripts:true, parameters:'author[name]='+$F('author_name')+'&author[dob]='+$F('author_dob')})", res diff --git a/vendor/assets/javascripts/prototype_ujs.js b/vendor/assets/javascripts/prototype_ujs.js index 2cd1220..695ad4a 100644 --- a/vendor/assets/javascripts/prototype_ujs.js +++ b/vendor/assets/javascripts/prototype_ujs.js @@ -1,4 +1,14 @@ (function() { + Ajax.Responders.register({ + onCreate: function(request) { + var token = $$('meta[name=csrf-token]')[0]; + if (token) { + if (!request.options.requestHeaders) request.options.requestHeaders = {}; + request.options.requestHeaders['X-CSRF-Token'] = token.readAttribute('content'); + } + } + }); + // Technique from Juriy Zaytsev // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ function isEventSupported(eventName) { @@ -111,10 +121,11 @@ function handleMethod(element) { var method = element.readAttribute('data-method'), url = element.readAttribute('href'), + target = element.readAttribute('target') || "", csrf_param = $$('meta[name=csrf-param]')[0], csrf_token = $$('meta[name=csrf-token]')[0]; - var form = new Element('form', { method: "POST", action: url, style: "display: none;" }); + var form = new Element('form', { method: "POST", action: url, style: "display: none;", target: target }); $(element.parentNode).insert(form); if (method !== 'post') { @@ -130,11 +141,11 @@ function disableFormElements(form) { form.select('input[type=submit][data-disable-with]').each(function(input) { - input.store('rails:original-value', input.getValue()); + input.store('rails:original-value', input.value); input.setValue(input.readAttribute('data-disable-with')).disable(); }); } - + function enableFormElements(form) { form.select('input[type=submit][data-disable-with]').each(function(input) { input.setValue(input.retrieve('rails:original-value')).enable(); @@ -147,17 +158,19 @@ } document.on('click', 'a[data-confirm], a[data-remote], a[data-method]', function(event, link) { - if (!allowAction(link)) { - event.stop(); - return false; - } + if (Event.isLeftClick(event)) { + if (!allowAction(link)) { + event.stop(); + return false; + } - if (link.readAttribute('data-remote')) { - handleRemote(link); - event.stop(); - } else if (link.readAttribute('data-method')) { - handleMethod(link); - event.stop(); + if (link.readAttribute('data-remote')) { + handleRemote(link); + event.stop(); + } else if (link.readAttribute('data-method')) { + handleMethod(link); + event.stop(); + } } }); @@ -178,14 +191,15 @@ handleRemote(form); event.stop(); } else { - disableFormElements(form); + // Slight timeout so that the submit button gets properly serialized + setTimeout(function() { disableFormElements(form); }, 13); } }); document.on('ajax:create', 'form', function(event, form) { if (form == event.findElement()) disableFormElements(form); }); - + document.on('ajax:complete', 'form', function(event, form) { if (form == event.findElement()) enableFormElements(form); });