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 +1 -1
- data/jquery_on_rails.gemspec +2 -2
- data/lib/jquery_on_rails/helpers/jquery_helper.rb +67 -14
- data/spec/jquery_helper_spec.rb +198 -0
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/jquery_on_rails.gemspec
CHANGED
@@ -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.
|
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-
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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 =
|
105
|
-
record "jQuery(
|
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(
|
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(
|
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()
|
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(
|
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, "
|
336
|
+
super(generator, "jQuery(#{::ActiveSupport::JSON.encode('#'+id.to_s)})")
|
322
337
|
end
|
323
338
|
|
324
339
|
def [](attribute)
|
325
|
-
|
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
|
data/spec/jquery_helper_spec.rb
CHANGED
@@ -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
|
-
|
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-
|
17
|
+
date: 2010-05-23 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|