Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #3568: prototype_helper_behavior_methods_patch2.diff

File prototype_helper_behavior_methods_patch2.diff, 5.6 kB (added by devslashnull@gmail.com, 4 years ago)

Patch for the trunk directory, allows multiple selectors per behavior and adds more tests

  • trunk/actionpack/test/template/prototype_helper_test.rb

    old new  
    111111    assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {new Ajax.Request('http://www.example.com/cart_changed', {asynchronous:true, evalScripts:true})})\n//]]>\n</script>), 
    112112      observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" }) 
    113113  end 
    114  
     114   
     115  def test_observe_elements 
     116    assert_equal %(new Behavior("a", {name: "show_href_on_click", callbacks: [function(element) {Event.observe(element, "click", function() {alert(element.href)});}]});), 
     117      observe_elements("a", {:click => "alert(element.href)"}, :name => "show_href_on_click") 
     118    assert_equal %(new Behavior(["a", "p"], {name: "a,p", callbacks: [function(element) {Event.observe(element, "mouseover", function() {Element.addClassName("mousy")});\nEvent.observe(element, "mouseout", function() {Element.removeClassName("mousy")});}]});), 
     119      observe_elements(["a", "p"], {:mouseover => 'Element.addClassName("mousy")', :mouseout => 'Element.removeClassName("mousy")'}) 
     120  end 
     121   
     122  def test_register_behaviors 
     123    assert_equal %(new Behavior("a", {name: "a", callbacks: [function(element) {if (/\\.pdf$/i.test(element.href)) element.target = "_blank";}]});), 
     124      register_behaviors('a' => 'if (/\.pdf$/i.test(element.href)) element.target = "_blank";') 
     125    assert_equal %(new Behavior(["p", "a"], {name: "p,a", callbacks: [function(element) {new Effect.Appear(element)}]});), 
     126      register_behaviors(['p', 'a'] => 'new Effect.Appear(element)') 
     127    assert_equal %(new Behavior(".tabset .tab a", {name: ".tabset .tab a", callbacks: [function(element) {element.pane = $(element.getAttribute("pane") || (element.innerHTML.stripTags().strip().toLowerCase() + "_pane"));}]});), 
     128      register_behaviors('.tabset .tab a' => {:callback => 'element.pane = $(element.getAttribute("pane") || (element.innerHTML.stripTags().strip().toLowerCase() + "_pane"));'}) 
     129    assert_equal %(new Behavior("a", {name: "add-class-to-non-relative-links", callbacks: [function(element) {if (/:/.test(element.getAttribute("href"))) Element.addClass(element, "external");}]});), 
     130      register_behaviors('a' => {:name => 'add-class-to-non-relative-links', :callback => 'if (/:/.test(element.getAttribute("href"))) Element.addClass(element, "external");'}) 
     131  end 
     132   
    115133  def test_update_element_function 
    116134    assert_equal %($('myelement').innerHTML = 'blub';\n), 
    117135      update_element_function('myelement', :content => 'blub') 
  • trunk/actionpack/lib/action_view/helpers/prototype_helper.rb

    old new  
    365365        end 
    366366      end 
    367367       
     368      # Applies callbacks for all elements matching the given CSS selector. For example, 
     369      # to make all +h1+ tags green on mouseover you could do this: 
     370      # 
     371      #   observe_elements 'h1', 
     372      #                    :mouseover => 'Element.setStyle(element, {color: "green"})', 
     373      #                    :mouseout  => 'Element.setStyle(element, {color: null})' 
     374      # 
     375      # Event names may optionally start with 'on'. 
     376      def observe_elements(selector, callbacks, options={}) 
     377        options = { 
     378          :callback => (callbacks || {}).map { |(event,callback)| 
     379            %(Event.observe(element, #{event.to_s.sub(/^on/, '').to_json}, function() {#{callback}});) 
     380          } * "\n", 
     381          :name => [selector].flatten.join(',') 
     382        }.merge(options) 
     383 
     384        register_behaviors(selector => options) 
     385      end 
     386 
     387      # Applies behaviors to elements matching certain CSS selectors. For example, 
     388      # to make all paragraph elements fade in you could do this: 
     389      #  
     390      #   register_behaviors 'p' => visual_effect(:appear) 
     391      # 
     392      # Or to make all links to PDF documents open in a new window: 
     393      # 
     394      #   register_behaviors 'a' => 'if (/\.pdf$/i.test(element.href)) element.target = "_blank";' 
     395      def register_behaviors(rules) 
     396        js = [] 
     397        rules.dup.each do |(selector,options)| 
     398          options = {:callbacks => [options]} if options.is_a?(String) 
     399          options = { 
     400            :name => [selector].flatten.join(','), 
     401            :callbacks => [options[:callback]].flatten 
     402          }.merge(options) 
     403          options[:callbacks].map! { |callback| "function(element) {#{callback}}" } 
     404           
     405          js << "new Behavior(#{selector.to_json}, {name: #{options[:name].to_json}, callbacks: [#{options[:callbacks] * ','}]});" 
     406        end 
     407        js * "\n" 
     408      end 
     409 
    368410      # JavaScriptGenerator generates blocks of JavaScript code that allow you  
    369411      # to change the content and presentation of multiple DOM elements.  Use  
    370412      # this in your Ajax response bodies, either in a <script> tag or as plain 
     
    501543          yield 
    502544          record "}, #{(seconds * 1000).to_i})" 
    503545        end 
    504  
     546         
     547        # Forces existing and new behaviors to be applied. This is required  
     548        # if any new page elements are to exibit existing behaviors or if  
     549        # this request has created any new behaviors. 
     550        def apply_behaviors 
     551          record "Behavior.apply()" 
     552        end 
     553         
    505554      private 
    506555        def method_missing(method, *arguments, &block) 
    507556          record(@context.send(method, *arguments, &block))