jquery_on_rails 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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