Ticket #3876: prototype_helpers.fixed.diff
| File prototype_helpers.fixed.diff, 16.5 kB (added by rick, 3 years ago) |
|---|
-
activesupport/test/json.rb
old new 9 9 end 10 10 11 11 class TestJSONEmitters < Test::Unit::TestCase 12 TrueTests = [[ true, %(true) ]]13 FalseTests = [[ false, %(false) ]]14 NilTests = [[ nil, %(null) ]]15 NumericTests = [[ 1, %(1) ],16 [ 2.5, %(2.5) ]]12 TrueTests = [[ true, %(true) ]] 13 FalseTests = [[ false, %(false) ]] 14 NilTests = [[ nil, %(null) ]] 15 NumericTests = [[ 1, %(1) ], 16 [ 2.5, %(2.5) ]] 17 17 18 StringTests = [[ 'this is the string', %("this is the string") ],19 [ 'a "string" with quotes', %("a \\"string\\" with quotes") ]]18 StringTests = [[ 'this is the string', %("this is the string") ], 19 [ 'a "string" with quotes', %("a \\"string\\" with quotes") ]] 20 20 21 ArrayTests = [[ ['a', 'b', 'c'], %([\"a\", \"b\", \"c\"]) ],22 [ [1, 'a', :b, nil, false], %([1, \"a\", \"b\", null, false]) ]]21 ArrayTests = [[ ['a', 'b', 'c'], %([\"a\", \"b\", \"c\"]) ], 22 [ [1, 'a', :b, nil, false], %([1, \"a\", \"b\", null, false]) ]] 23 23 24 HashTests = [[ {:a => :b, :c => :d}, %({\"c\": \"d\", \"a\": \"b\"}) ]]24 HashTests = [[ {:a => :b, :c => :d}, %({\"c\": \"d\", \"a\": \"b\"}) ]] 25 25 26 SymbolTests = [[ :a, %("a") ],27 [ :this, %("this") ],28 [ :"a b", %("a b") ]]26 SymbolTests = [[ :a, %("a") ], 27 [ :this, %("this") ], 28 [ :"a b", %("a b") ]] 29 29 30 ObjectTests = [[ Foo.new(1, 2), %({\"a\": 1, \"b\": 2}) ]] 31 30 ObjectTests = [[ Foo.new(1, 2), %({\"a\": 1, \"b\": 2}) ]] 31 32 VariableTests = [[ ActiveSupport::JSON::Variable.new('foo'), 'foo'], 33 [ ActiveSupport::JSON::Variable.new('alert("foo")'), 'alert("foo")']] 34 RegexpTests = [[ /^a/, '/^a/' ], /^\w{1,2}[a-z]+/ix, '/^\\w{1,2}[a-z]+/ix'] 35 32 36 constants.grep(/Tests$/).each do |class_tests| 33 37 define_method("test_#{class_tests[0..-6].downcase}") do 34 38 self.class.const_get(class_tests).each do |pair| -
activesupport/lib/active_support/json/encoders/core.rb
old new 56 56 result << '}' 57 57 end 58 58 end 59 60 define_encoder Regexp do |regexp| 61 regexp.inspect 62 end 59 63 end 60 64 end 61 65 end -
activesupport/lib/active_support/json.rb
old new 3 3 module ActiveSupport 4 4 module JSON #:nodoc: 5 5 class CircularReferenceError < StandardError; end 6 6 # returns the literal string as its JSON encoded form. Useful for passing javascript variables into functions. 7 # 8 # page.call 'Element.show', ActiveSupport::JSON::Variable.new("$$(#items li)") 9 class Variable < String 10 def to_json 11 self 12 end 13 end 14 7 15 class << self 8 16 REFERENCE_STACK_VARIABLE = :json_reference_stack 9 17 -
actionpack/test/template/prototype_helper_test.rb
old new 3 3 module BaseTest 4 4 include ActionView::Helpers::JavaScriptHelper 5 5 include ActionView::Helpers::PrototypeHelper 6 include ActionView::Helpers::ScriptaculousHelper 6 7 7 8 include ActionView::Helpers::UrlHelper 8 9 include ActionView::Helpers::TagHelper … … 147 148 end 148 149 end 149 150 151 ActionView::Helpers::JavaScriptCollectionProxy.send :public, :enumerate 152 150 153 class JavaScriptGeneratorTest < Test::Unit::TestCase 151 154 include BaseTest 152 155 … … 234 237 235 238 def test_element_proxy_one_deep 236 239 @generator['hello'].hide 237 assert_equal %( $('hello').hide();), @generator.to_s240 assert_equal %(Element.hide("hello");), @generator.to_s 238 241 end 239 242 240 243 def test_element_proxy_assignment … … 243 246 end 244 247 245 248 def test_element_proxy_two_deep 246 @generator['hello'].hide("first"). display247 assert_equal %( $('hello').hide("first").display();), @generator.to_s249 @generator['hello'].hide("first").visual_effect(:highlight) 250 assert_equal %(Element.hide("hello", "first");\nnew Effect.Highlight('hello',{});), @generator.to_s 248 251 end 249 252 253 def test_element_proxy_visual_effect 254 @generator['hello'].visual_effect :highlight 255 assert_equal %(new Effect.Highlight('hello',{});), @generator.to_s 256 end 257 258 def test_element_proxy_visual_effect_with_options 259 @generator['hello'].visual_effect :highlight, :duration => 0.4 260 assert_equal %(new Effect.Highlight('hello',{duration:0.4});), @generator.to_s 261 end 262 250 263 def test_select_access 251 264 assert_equal %($$('div.hello');), @generator.select('div.hello') 252 265 end 253 266 254 267 def test_select_proxy_one_deep 255 268 @generator.select('p.welcome b').first.hide 256 assert_equal %( $$('p.welcome b').first().hide();), @generator.to_s269 assert_equal %(Element.hide($$('p.welcome b').first());), @generator.to_s 257 270 end 271 272 def test_select_proxy_two_deep 273 @generator.select('p.welcome b').first('a').hide.show 274 assert_equal %(a = $$('p.welcome b').first();\nElement.hide(a);\nElement.show(a);), @generator.to_s 275 end 276 277 def test_collection_proxy_with_each 278 @generator.select('p.welcome b').each do |page, value| 279 value.remove_class_name 'selected' 280 end 281 @generator.select('p.welcome b').each do |page, value, index| 282 page.call 'alert', index 283 page.call 'alert', value, 'selected' 284 end 285 assert_equal <<-EOS.strip, @generator.to_s 286 $$('p.welcome b').each(function(value, index) { 287 Element.removeClassName(value, "selected"); 288 }); 289 $$('p.welcome b').each(function(value, index) { 290 alert(index); 291 alert(value, "selected"); 292 }); 293 EOS 294 end 295 296 def test_collection_proxy_on_enumerables_with_return_and_index 297 iterator = Proc.new { |page, value| page << '(value.className == "welcome")' } 298 iterator_with_index = Proc.new { |page, value, index| page.call 'alert', index ; page << '(value.className == "welcome")' } 299 ActionView::Helpers::JavaScriptCollectionProxy::ENUMERABLE_METHODS_WITH_RETURN.each do |enum| 300 @generator.select('p').enumerate(enum, 'a', &iterator) 301 @generator.select('p').enumerate(enum, 'b', &iterator_with_index) 302 303 assert_equal <<-EOS.strip, @generator.to_s 304 a = $$('p').#{enum}(function(value, index) { 305 return (value.className == "welcome"); 306 }); 307 b = $$('p').#{enum}(function(value, index) { 308 alert(index); 309 return (value.className == "welcome"); 310 }); 311 EOS 312 @generator = create_generator 313 end 314 end 315 316 def test_collection_proxy_with_grep 317 @generator.select('p').grep 'a', /^a/ do |page, value| 318 page << '(value.className == "welcome")' 319 end 320 @generator.select('p').grep 'b', /b$/ do |page, value, index| 321 page.call 'alert', value 322 page << '(value.className == "welcome")' 323 end 324 325 assert_equal <<-EOS.strip, @generator.to_s 326 a = $$('p').grep(/^a/, function(value, index) { 327 return (value.className == "welcome"); 328 }); 329 b = $$('p').grep(/b$/, function(value, index) { 330 alert(value); 331 return (value.className == "welcome"); 332 }); 333 EOS 334 end 335 336 def test_collection_proxy_with_inject 337 @generator.select('p').inject 'a', [] do |page, memo, value| 338 page << '(value.className == "welcome")' 339 end 340 @generator.select('p').inject 'b', nil do |page, memo, value, index| 341 memo.hide.show 342 page << '(value.className == "welcome")' 343 end 344 345 assert_equal <<-EOS.strip, @generator.to_s 346 a = $$('p').inject([], function(memo, value, index) { 347 return (value.className == "welcome"); 348 }); 349 b = $$('p').inject(null, function(memo, value, index) { 350 Element.hide(memo); 351 Element.show(memo); 352 return (value.className == "welcome"); 353 }); 354 EOS 355 end 356 357 def test_collection_proxy_with_pluck 358 @generator.select('p').pluck('a', 'className') 359 assert_equal %(a = $$('p').pluck("className");), @generator.to_s 360 end 361 362 def test_collection_proxy_with_zip 363 ActionView::Helpers::JavaScriptCollectionProxy.new(@generator, '[1, 2, 3]').zip('a', [4, 5, 6], [7, 8, 9]) 364 ActionView::Helpers::JavaScriptCollectionProxy.new(@generator, '[1, 2, 3]').zip('b', [4, 5, 6], [7, 8, 9]) do |page, array| 365 page.call 'array.reverse' 366 end 367 368 assert_equal <<-EOS.strip, @generator.to_s 369 a = [1, 2, 3].zip([4, 5, 6], [7, 8, 9]); 370 b = [1, 2, 3].zip([4, 5, 6], [7, 8, 9], function(array) { 371 return array.reverse(); 372 }); 373 EOS 374 end 258 375 end -
actionpack/lib/action_view/helpers/prototype_helper.rb
old new 421 421 # used for further method calls. Examples: 422 422 # 423 423 # page['blank_slate'] # => $('blank_slate'); 424 # page['blank_slate'].show # => $('blank_slate').show();425 # page['blank_slate'].show('first').up # => $('blank_slate').show('first').up();424 # page['blank_slate'].show # => Element.show("blank_slate"); 425 # page['blank_slate'].show('first').up # => Element.show("blank_slate", "first"); Element.up("blank_slate"); 426 426 def [](id) 427 427 JavaScriptElementProxy.new(self, id) 428 428 end … … 430 430 # Returns a collection reference by finding it through a CSS +pattern+ in the DOM. This collection can then be 431 431 # used for further method calls. Examples: 432 432 # 433 # page.select('p') # => $$('p'); 434 # page.select('p.welcome b').first # => $$('p.welcome b').first(); 435 # page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide(); 433 # page.select('p') # => $$('p'); 434 # page.select('p.welcome b').first # => $$('p.welcome b').first(); 435 # page.select('p.welcome b').first.hide # => Element.hide($$('p.welcome b').first()); 436 # page.select('p.welcome b').first('a').hide.show # => a = $$('p.welcome b').first(); Element.hide(a); Element.show(a); 436 437 def select(pattern) 437 JavaScript CollectionProxy.new(self, pattern)438 JavaScriptElementCollectionProxy.new(self, pattern) 438 439 end 439 440 440 441 # Inserts HTML at the specified +position+ relative to the DOM element … … 595 596 end 596 597 597 598 def javascript_object_for(object) 598 object. respond_to?(:to_json) ? object.to_json :object.inspect599 object.to_json rescue object.inspect 599 600 end 600 601 601 602 def arguments_for_call(arguments) … … 667 668 668 669 # Converts chained method calls on DOM proxy elements into JavaScript chains 669 670 class JavaScriptProxy < Builder::BlankSlate #:nodoc: 670 def initialize(generator, root )671 def initialize(generator, root = nil) 671 672 @generator = generator 672 @generator << root 673 @generator << root if root 673 674 end 674 675 675 676 private … … 687 688 end 688 689 689 690 def assign(variable, value) 690 append_to_function_chain! "#{variable} = #{@generator.send(:javascript_object_for, value)}"691 append_to_function_chain!("#{variable} = #{@generator.send(:javascript_object_for, value)}") 691 692 end 692 693 693 694 def function_chain … … 695 696 end 696 697 697 698 def append_to_function_chain!(call) 698 function_chain[-1] = function_chain[-1][0..-2] if function_chain[-1][-1..-1] == ";" # strip last ; 699 function_chain[-1] += ".#{call};" 699 if function_chain.any? 700 function_chain[-1].chomp!(";") # strip last ; 701 function_chain[-1] += ".#{call};" 702 else 703 function_chain.push("#{call};") 704 end 700 705 end 701 706 end 702 707 703 708 class JavaScriptElementProxy < JavaScriptProxy #:nodoc: 704 709 def initialize(generator, id) 705 710 @id = id 706 super(generator , "$('#{id}')")711 super(generator) 707 712 end 708 713 709 714 def replace_html(*options_for_render) 710 715 call 'update', @generator.send(:render, *options_for_render) 711 716 end … … 717 722 def reload 718 723 replace :partial => @id.to_s 719 724 end 725 726 def to_json 727 @id.to_json 728 end 729 730 def visual_effect(name, options = {}) 731 @generator << @generator.visual_effect(name, @id, options) 732 self 733 end 734 735 private 736 def method_missing(method, *arguments) 737 if method.to_s =~ /(.*)=$/ 738 @generator << "$('#{@id}')" 739 super 740 else 741 @generator.call "Element.#{method.to_s.first}#{method.to_s.classify[1..-1]}", @id, *arguments 742 self 743 end 744 end 720 745 end 721 746 722 747 class JavaScriptCollectionProxy < JavaScriptProxy #:nodoc: 748 ENUMERABLE_METHODS_WITH_RETURN = [:all, :any, :collect, :map, :detect, :find, :findAll, :select, :max, :min, :partition, :reject, :sortBy] 749 723 750 def initialize(generator, pattern) 724 @pattern = pattern 725 super(generator, "$$('#{pattern}')") 751 super(generator, @pattern = pattern) 726 752 end 727 753 728 # TODO: Implement funky stuff like .each 754 def grep(variable, pattern, &block) 755 enumerable_method("grep(#{pattern.to_json}, function(value, index) {", variable, %w(value index), &block) 756 end 757 758 def inject(variable, memo, &block) 759 enumerable_method("inject(#{memo.to_json}, function(memo, value, index) {", variable, %w(memo value index), &block) 760 end 761 762 def pluck(variable, property) 763 add_variable_assignment!(variable) 764 append_enumerable_function!("pluck(#{property.to_json});") 765 end 766 767 def zip(variable, *arguments, &block) 768 add_variable_assignment!(variable) 769 append_enumerable_function!("zip(#{arguments.collect { |a| a.to_json } * ', '}") 770 if block 771 function_chain[-1] += ", function(array) {" 772 yield @generator, ActiveSupport::JSON::Variable.new('array') 773 add_return_statement! 774 @generator << '});' 775 else 776 function_chain[-1] += ');' 777 end 778 end 779 780 def each(&block) 781 enumerate('each', nil, &block) 782 end 783 784 ENUMERABLE_METHODS_WITH_RETURN.each do |meth_name| 785 define_method(meth_name) do 786 enumerate(meth_name, true, &block) 787 end 788 end 789 790 [:first, :last].each do |meth_name| 791 define_method(meth_name) do |*variables| 792 variable = variables.first 793 call(meth_name) 794 add_variable_assignment!(variable) if variable 795 JavaScriptElementProxy.new(@generator, ActiveSupport::JSON::Variable.new(variable || function_chain.pop.chomp(';'))) 796 end 797 end 798 799 private 800 def enumerate(enumerable, variable = nil, &block) 801 enumerable_method("#{enumerable}(function(value, index) {", variable, %w(value index), &block) 802 end 803 804 def enumerable_method(enumerable, variable, yield_params, &block) 805 add_variable_assignment!(variable) if variable 806 append_enumerable_function!(enumerable) 807 yield *([@generator] + yield_params.collect { |p| JavaScriptElementProxy.new(@generator, ActiveSupport::JSON::Variable.new(p)) }) 808 add_return_statement! if variable 809 @generator << '});' 810 end 811 812 def add_variable_assignment!(variable) 813 function_chain.push("#{variable} = #{function_chain.pop}") 814 end 815 816 def add_return_statement! 817 unless function_chain.last =~ /return/ 818 function_chain.push("return #{function_chain.pop.chomp(';')};") 819 end 820 end 821 822 def append_enumerable_function!(call) 823 append_to_function_chain!(call) 824 function_chain[-1].chomp!(";") # strip last ; 825 end 729 826 end 827 828 class JavaScriptElementCollectionProxy < JavaScriptCollectionProxy #:nodoc:\ 829 def initialize(generator, pattern) 830 super(generator, "$$('#{pattern}')") 831 end 832 end 730 833 end 731 834 end