jquery_on_rails 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{jquery_on_rails}
8
- s.version = "0.1.2"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joe Khoobyar"]
12
- s.date = %q{2010-05-22}
12
+ s.date = %q{2010-05-23}
13
13
  s.description = %q{A complete replacement for Rails 3 javascript helpers and unobstrusive javacript (ujs) using JQuery instead of prototype/scriptaculous}
14
14
  s.email = %q{joe@ankhcraft.com}
15
15
  s.extra_rdoc_files = [
@@ -55,7 +55,7 @@ module JQueryOnRails
55
55
  function
56
56
  end
57
57
 
58
- # Mostly copied from PrototypeHelper
58
+ # Mostly copied from Rails 3 PrototypeHelper
59
59
  class JavaScriptGenerator #:nodoc:
60
60
  def initialize(context, &block) #:nodoc:
61
61
  @context, @lines = context, []
@@ -71,6 +71,7 @@ module JQueryOnRails
71
71
  extend GeneratorMethods
72
72
  end
73
73
 
74
+ # Mostly copied from Rails 3 PrototypeHelper
74
75
  module GeneratorMethods
75
76
  def to_s #:nodoc:
76
77
  returning javascript = @lines * $/ do
@@ -84,10 +85,10 @@ module JQueryOnRails
84
85
 
85
86
  def [](id)
86
87
  case id
87
- when String, Symbol, NilClass
88
- JavaScriptElementProxy.new(self, id)
89
- else
90
- JavaScriptElementProxy.new(self, ActionController::RecordIdentifier.dom_id(id))
88
+ when String, Symbol, NilClass
89
+ JavaScriptElementProxy.new(self, id)
90
+ else
91
+ JavaScriptElementProxy.new(self, ActionController::RecordIdentifier.dom_id(id))
91
92
  end
92
93
  end
93
94
 
@@ -101,18 +102,18 @@ module JQueryOnRails
101
102
 
102
103
  def insert_html(position, id, *options_for_render)
103
104
  content = javascript_object_for(render(*options_for_render))
104
- position = INSERTION_POSITIONS[position.to_sym] || position.to_s.downcase
105
- record "jQuery('##{id}').#{position}(#{content});"
105
+ position = INSERT_POSITIONS[position.to_sym] || position.to_s.downcase
106
+ record "jQuery(\"##{id}\").#{position}(#{content});"
106
107
  end
107
108
 
108
109
  def replace_html(id, *options_for_render)
109
110
  content = javascript_object_for(render(*options_for_render))
110
- record "jQuery('##{id}').html(#{content});"
111
+ record "jQuery(\"##{id}\").html(#{content});"
111
112
  end
112
113
 
113
114
  def replace(id, *options_for_render)
114
115
  content = javascript_object_for(render(*options_for_render))
115
- record "jQuery('##{id}').replaceWith(#{content});"
116
+ record "jQuery(\"##{id}\").replaceWith(#{content});"
116
117
  end
117
118
 
118
119
  def remove(*ids)
@@ -157,14 +158,14 @@ module JQueryOnRails
157
158
  end
158
159
 
159
160
  def delay(seconds = 1)
160
- record "setTimeout(function() {\n\n"
161
+ record "setTimeout(function(){\n\n"
161
162
  yield
162
163
  record "}, #{(seconds * 1000).to_i})"
163
164
  end
164
165
 
165
166
  private
166
167
  def loop_on_multiple_ids(method, ids)
167
- record "jQuery('##{ids.join(', #')}').#{method} ();"
168
+ record "jQuery(\"##{ids.join(', #')}\").#{method}();"
168
169
  end
169
170
 
170
171
  def page
@@ -210,6 +211,19 @@ module JQueryOnRails
210
211
  JavaScriptProxy.new(self, method.to_s.camelize)
211
212
  end
212
213
  end
214
+
215
+ module CompatibilityMethods
216
+ def [](id)
217
+ case id
218
+ when String, Symbol, NilClass
219
+ proxy = JavaScriptElementProxy.new(self, id)
220
+ else
221
+ proxy = JavaScriptElementProxy.new(self, ActionController::RecordIdentifier.dom_id(id))
222
+ end
223
+ Object.instance_method(:extend).bind(proxy).call JavaScriptElementCompatibility
224
+ proxy
225
+ end
226
+ end
213
227
  end
214
228
 
215
229
  def update_page(&block)
@@ -314,15 +328,18 @@ module JQueryOnRails
314
328
  class JavaScriptVariableProxy < ActionView::Helpers::JavaScriptVariableProxy
315
329
  end
316
330
 
317
- # Adapted from Rails 3
331
+ # Adapted from Rails 3 ActionView::Helpers::JavaScriptProxy
318
332
  class JavaScriptElementProxy < JavaScriptProxy
333
+
319
334
  def initialize(generator, id)
320
335
  @id = id
321
- super(generator, "$(#{::ActiveSupport::JSON.encode('#'+id)})")
336
+ super(generator, "jQuery(#{::ActiveSupport::JSON.encode('#'+id.to_s)})")
322
337
  end
323
338
 
324
339
  def [](attribute)
325
- append_to_function_chain!(attribute)
340
+ if Fixnum === attribute then array_access(attribute) else
341
+ append_to_function_chain!(attribute)
342
+ end
326
343
  self
327
344
  end
328
345
 
@@ -341,6 +358,42 @@ module JQueryOnRails
341
358
  def reload(options_for_replace = {})
342
359
  replace(options_for_replace.merge({ :partial => @id.to_s }))
343
360
  end
361
+
362
+ private
363
+
364
+ def array_access(index)
365
+ function_chain[-1].chomp!(';')
366
+ function_chain[-1] += "[#{index}];"
367
+ end
368
+
369
+ end
370
+
371
+ # Compatibility methods that can be mixed into JavaScriptElementProxy
372
+ # to provide at least some level of compatibility for code that tries
373
+ # to access or set properties directly onto the element object.
374
+ module JavaScriptElementCompatibility
375
+
376
+ def [](attribute)
377
+ refer_to_native_element!
378
+ super
379
+ end
380
+
381
+ private
382
+
383
+ def assign(variable, value)
384
+ refer_to_native_element!
385
+ super
386
+ end
387
+
388
+ def call(function, *arguments, &block)
389
+ singleton_class.class_eval{ def refer_to_native_element!; end}
390
+ super
391
+ end
392
+
393
+ def refer_to_native_element!
394
+ array_access(0)
395
+ singleton_class.class_eval{ def refer_to_native_element!; end}
396
+ end
344
397
  end
345
398
 
346
399
  end
@@ -1,14 +1,29 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  require 'dummy_controller'
4
+ require 'active_model'
5
+ require 'active_model/naming'
6
+ require 'active_model/conversion'
7
+
8
+ class Ovechkin < Struct.new(:Ovechkin, :id)
9
+ extend ActiveModel::Naming
10
+ include ActiveModel::Conversion
11
+ def to_key() id ? [id] : nil end
12
+ end
4
13
 
5
14
  describe JQueryOnRails::Helpers::JQueryHelper do
15
+ before(:all) do
16
+ ActiveSupport::JSON::Encoding.escape_html_entities_in_json = true
17
+ end
6
18
  before(:each) do
7
19
  @t = DummyController.new.tap do |c|
8
20
  c.request = ActionDispatch::Request.new Rack::MockRequest.env_for('/dummy')
9
21
  end.view_context
10
22
  end
11
23
 
24
+ it "is automatically mixed into the template class" do
25
+ @t.class.included_modules.should be_include(JQueryOnRails::Helpers::JQueryHelper)
26
+ end
12
27
  it "overrides all instance methods ActionView::Helpers::PrototypeHelper" do
13
28
  (ActionView::Helpers::PrototypeHelper.instance_methods -
14
29
  JQueryOnRails::Helpers::JQueryHelper.instance_methods).should == []
@@ -59,6 +74,7 @@ describe JQueryOnRails::Helpers::JQueryHelper do
59
74
  @t.remote_function(:url=>'/foo', :form=>true).should_not =~ @regex
60
75
  end
61
76
  end
77
+
62
78
  describe ':url' do
63
79
  it "accepts a string" do
64
80
  @t.remote_function(:url=>'/foo').should =~ /url: *'\/foo'/
@@ -67,6 +83,7 @@ describe JQueryOnRails::Helpers::JQueryHelper do
67
83
  @t.remote_function(:url=>{:controller=>'dummy', :action=>'index'}).should =~ /url: *'\/dummy'/
68
84
  end
69
85
  end
86
+
70
87
  describe ':method' do
71
88
  it "defaults to GET" do
72
89
  @t.remote_function(:url=>'/foo').should =~ /method: *'GET'/
@@ -76,4 +93,185 @@ describe JQueryOnRails::Helpers::JQueryHelper do
76
93
  end
77
94
  end
78
95
  end
96
+
97
+ describe "javascript generation" do
98
+ before(:each) do
99
+ @block = proc{|page| page.replace_html 'foo', 'bar'}
100
+ end
101
+
102
+ def create_generator
103
+ block = Proc.new{|*args| yield *args if block_given?}
104
+ @t.class::JavaScriptGenerator.new @t, &block
105
+ end
106
+
107
+ describe 'JavaScriptGenerator' do
108
+ before(:each) do
109
+ @g = create_generator
110
+ end
111
+ it "replaces the PrototypeHelper's generator" do
112
+ @t.class::JavaScriptGenerator.should == JQueryOnRails::Helpers::JQueryHelper::JavaScriptGenerator
113
+ JQueryOnRails::Helpers::JQueryHelper::JavaScriptGenerator.should === @g
114
+ end
115
+ it "#insert_html" do
116
+ @g.insert_html(:top, 'element', '<p>This is a test</p>').should ==
117
+ 'jQuery("#element").prepend("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");'
118
+ @g.insert_html(:bottom, 'element', '<p>This is a test</p>').should ==
119
+ 'jQuery("#element").append("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");'
120
+ @g.insert_html(:before, 'element', '<p>This is a test</p>').should ==
121
+ 'jQuery("#element").before("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");'
122
+ @g.insert_html(:after, 'element', '<p>This is a test</p>').should ==
123
+ 'jQuery("#element").after("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");'
124
+ end
125
+ it "#replace_html" do
126
+ @g.replace_html('element', '<p>This is a test</p>').should ==
127
+ 'jQuery("#element").html("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");'
128
+ end
129
+ it "#replace" do
130
+ @g.replace('element', '<div id="element"><p>This is a test</p></div>').should ==
131
+ 'jQuery("#element").replaceWith("\\u003Cdiv id=\"element\"\\u003E\\u003Cp\\u003EThis is a test\\u003C/p\\u003E\\u003C/div\\u003E");'
132
+ end
133
+ it "#remove" do
134
+ @g.remove('foo').should == 'jQuery("#foo").remove();'
135
+ @g.remove('foo', 'bar', 'baz').should == 'jQuery("#foo, #bar, #baz").remove();'
136
+ end
137
+ it "#show" do
138
+ @g.show('foo').should == 'jQuery("#foo").show();'
139
+ @g.show('foo', 'bar', 'baz').should == 'jQuery("#foo, #bar, #baz").show();'
140
+ end
141
+ it "#hide" do
142
+ @g.hide('foo').should == 'jQuery("#foo").hide();'
143
+ @g.hide('foo', 'bar', 'baz').should == 'jQuery("#foo, #bar, #baz").hide();'
144
+ end
145
+ it "#toggle" do
146
+ @g.toggle('foo').should == 'jQuery("#foo").toggle();'
147
+ @g.toggle('foo', 'bar', 'baz').should == 'jQuery("#foo, #bar, #baz").toggle();'
148
+ end
149
+ it "#alert" do
150
+ @g.alert('hello').should == 'alert("hello");'
151
+ end
152
+ it "#redirect_to" do
153
+ @g.redirect_to(:controller=>'dummy', :action=>'index').should ==
154
+ 'window.location.href = "/dummy";'
155
+ @g.redirect_to("http://www.example.com/welcome?a=b&c=d").should ==
156
+ 'window.location.href = "http://www.example.com/welcome?a=b&c=d";'
157
+ end
158
+ it "#reload" do
159
+ @g.reload.should == 'window.location.reload();'
160
+ end
161
+ it "#delay" do
162
+ @g.delay(20){@g.hide('foo')}
163
+ @g.to_s.should == "setTimeout(function(){\n;\njQuery(\"#foo\").hide();\n}, 20000);"
164
+ end
165
+ it "#to_s" do
166
+ @g.insert_html(:top, 'element', '<p>This is a test</p>')
167
+ @g.insert_html(:bottom, 'element', '<p>This is a test</p>')
168
+ @g.remove('foo', 'bar')
169
+ @g.replace_html('baz', '<p>This is a test</p>')
170
+
171
+ @g.to_s.should == <<-EOS.chomp
172
+ jQuery("#element").prepend("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");
173
+ jQuery("#element").append("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");
174
+ jQuery("#foo, #bar").remove();
175
+ jQuery("#baz").html("\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");
176
+ EOS
177
+ end
178
+ it "#literal" do
179
+ ActiveSupport::JSON.encode(@g.literal("function() {}")).should == "function() {}"
180
+ @g.to_s.should == ""
181
+ end
182
+ it "proxies to class methods" do
183
+ @g.form.focus('my_field')
184
+ @g.to_s.should == "Form.focus(\"my_field\");"
185
+ end
186
+ it "proxies to class methods with blocks" do
187
+ @g.my_object.my_method do |p|
188
+ p[:one].show
189
+ p[:two].hide
190
+ end
191
+ @g.to_s.should == "MyObject.myMethod(function() { jQuery(\"#one\").show();\njQuery(\"#two\").hide(); });"
192
+ end
193
+ it "calls with or without blocks" do
194
+ @g.call(:before)
195
+ @g.call(:my_method) do |p|
196
+ p[:one].show
197
+ p[:two].hide
198
+ end
199
+ @g.call(:in_between)
200
+ @g.call(:my_method_with_arguments, true, "hello") do |p|
201
+ p[:three].toggle
202
+ end
203
+ @g.to_s.should == "before();\nmy_method(function() { jQuery(\"#one\").show();\njQuery(\"#two\").hide(); });\nin_between();\nmy_method_with_arguments(true, \"hello\", function() { jQuery(\"#three\").toggle(); });"
204
+ end
205
+
206
+ describe "element proxy compatibility" do
207
+ before(:each) do
208
+ @g.extend @g.class::CompatibilityMethods
209
+ end
210
+ it "gets properties" do
211
+ @g['hello']['style']
212
+ @g.to_s.should == 'jQuery("#hello")[0].style;'
213
+ end
214
+ it "gets nested properties" do
215
+ @g['hello']['style']['color']
216
+ @g.to_s.should == 'jQuery("#hello")[0].style.color;'
217
+ end
218
+ it "sets properties" do
219
+ @g['hello'].width = 400;
220
+ @g.to_s.should == 'jQuery("#hello")[0].width = 400;'
221
+ end
222
+ it "sets nested properties" do
223
+ @g['hello']['style']['color'] = 'red';
224
+ @g.to_s.should == 'jQuery("#hello")[0].style.color = "red";'
225
+ end
226
+ end
227
+ describe "element proxy" do
228
+ it "refers by element ID" do
229
+ @g['hello'].should == 'jQuery("#hello");'
230
+ end
231
+ it "refers via ActiveModel::Naming" do
232
+ @g[Ovechkin.new(:id=>5)].should == 'jQuery("#bunny_5");'
233
+ @g[Ovechkin.new].should == 'jQuery("#new_bunny");'
234
+ end
235
+ it "refers indirectly" do
236
+ @g['hello'].hide('first').show
237
+ @g.to_s.should == 'jQuery("#hello").hide("first").show();'
238
+ end
239
+ it "calls methods" do
240
+ @g['hello'].hide
241
+ @g.to_s.should == 'jQuery("#hello").hide();'
242
+ end
243
+ it "gets properties" do
244
+ @g['hello'][0]['style']
245
+ @g.to_s.should == 'jQuery("#hello")[0].style;'
246
+ end
247
+ it "gets nested properties" do
248
+ @g['hello'][0]['style']['color']
249
+ @g.to_s.should == 'jQuery("#hello")[0].style.color;'
250
+ end
251
+ it "sets properties" do
252
+ @g['hello'][0].width = 400;
253
+ @g.to_s.should == 'jQuery("#hello")[0].width = 400;'
254
+ end
255
+ it "sets nested properties" do
256
+ @g['hello'][0]['style']['color'] = 'red';
257
+ @g.to_s.should == 'jQuery("#hello")[0].style.color = "red";'
258
+ end
259
+ end
260
+ end
261
+
262
+ describe '#update_page' do
263
+ it 'matches output from #create_generator' do
264
+ @t.update_page(&@block).should == create_generator(&@block).to_s
265
+ end
266
+ end
267
+
268
+ describe '#update_page_tag' do
269
+ it 'matches output from #create_generator wrapped in a script tag' do
270
+ @t.update_page_tag(&@block).should == @t.javascript_tag(create_generator(&@block).to_s)
271
+ end
272
+ it 'outputs html attributes' do
273
+ @t.update_page_tag(:defer=>true, &@block).should == @t.javascript_tag(create_generator(&@block).to_s, :defer=>true)
274
+ end
275
+ end
276
+ end
79
277
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
7
  - 2
9
- version: 0.1.2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joe Khoobyar
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-22 00:00:00 -04:00
17
+ date: 2010-05-23 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency