honkster-jelly 0.7.7 → 0.8.1
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.yml +2 -2
- data/generators/jelly/templates/javascripts/ajax_with_jelly.js +4 -3
- data/generators/jelly/templates/javascripts/jelly.js +59 -44
- data/jelly.gemspec +2 -2
- data/lib/jelly/jelly_controller.rb +12 -8
- data/spec/controllers/jelly_controller_spec.rb +148 -58
- data/spec/spec_helper.rb +1 -0
- metadata +2 -2
data/VERSION.yml
CHANGED
@@ -19,12 +19,13 @@ if(!window.Jelly) Jelly = new Object();
|
|
19
19
|
authenticity_token: window._token
|
20
20
|
});
|
21
21
|
}
|
22
|
+
var observers = otherParams.observers || Jelly.observers;
|
22
23
|
return $.extend({
|
23
24
|
dataType: 'json',
|
24
25
|
cache: false,
|
25
|
-
success :
|
26
|
+
success : function(callbacks) {
|
27
|
+
Jelly.notifyObservers.call(observers, callbacks);
|
28
|
+
}
|
26
29
|
}, otherParams);
|
27
30
|
};
|
28
|
-
|
29
|
-
$.ajaxWithJelly.onSuccess = Jelly.notifyObservers.bind(Jelly);
|
30
31
|
})(jQuery);
|
@@ -2,7 +2,7 @@
|
|
2
2
|
* Jelly. a sweet unobtrusive javascript framework
|
3
3
|
* for jQuery and Rails
|
4
4
|
*
|
5
|
-
* version 0.
|
5
|
+
* version 0.8.1
|
6
6
|
*
|
7
7
|
* Copyright (c) 2009 Pivotal Labs
|
8
8
|
* Licensed under the MIT license.
|
@@ -21,8 +21,9 @@ if (!Function.prototype.bind) {
|
|
21
21
|
}
|
22
22
|
}
|
23
23
|
Jelly.init = function() {
|
24
|
-
this.components = [];
|
25
24
|
this.observers = [];
|
25
|
+
this.observers.pending = [];
|
26
|
+
this.attach = this.Observers.attach;
|
26
27
|
this.notifyObservers = this.Observers.notify;
|
27
28
|
this.Components.initCalled = false;
|
28
29
|
this.Pages.init();
|
@@ -32,65 +33,79 @@ Jelly.init = function() {
|
|
32
33
|
});
|
33
34
|
};
|
34
35
|
|
35
|
-
Jelly.
|
36
|
-
|
37
|
-
var
|
38
|
-
|
39
|
-
eval(definition.component) :
|
40
|
-
definition.component;
|
41
|
-
var evaluatedDefinition = {
|
42
|
-
component: component,
|
43
|
-
arguments: definition.arguments
|
44
|
-
};
|
45
|
-
this.components.push(evaluatedDefinition);
|
46
|
-
if (Jelly.Components.initCalled) {
|
47
|
-
Jelly.Components.initComponentFromDefinition(evaluatedDefinition);
|
36
|
+
Jelly.Components = {
|
37
|
+
init: function() {
|
38
|
+
for (var i = 0; i < Jelly.observers.pending.length; i++) {
|
39
|
+
Jelly.Observers.initPending.call(Jelly.observers, Jelly.observers.pending[i]);
|
48
40
|
}
|
41
|
+
this.initCalled = true;
|
49
42
|
}
|
50
43
|
};
|
51
44
|
|
52
|
-
Jelly.
|
53
|
-
|
54
|
-
|
55
|
-
|
45
|
+
Jelly.Observers = {
|
46
|
+
attach: function() {
|
47
|
+
if (this == Jelly) {
|
48
|
+
return Jelly.Observers.attach.apply(this.observers, arguments);
|
49
|
+
}
|
50
|
+
this.pending = this.pending || [];
|
51
|
+
for (var i = 0; i < arguments.length; i++) {
|
52
|
+
var definition = arguments[i];
|
53
|
+
var component = (typeof definition.component == "string") ?
|
54
|
+
eval(definition.component) :
|
55
|
+
definition.component;
|
56
|
+
var evaluatedDefinition = {
|
57
|
+
component: component,
|
58
|
+
arguments: definition.arguments
|
59
|
+
};
|
60
|
+
this.pending.push(evaluatedDefinition);
|
61
|
+
if (Jelly.Components.initCalled) {
|
62
|
+
Jelly.Observers.initPending.call(this, evaluatedDefinition);
|
63
|
+
}
|
56
64
|
}
|
57
|
-
this.initCalled = true;
|
58
65
|
},
|
59
|
-
|
66
|
+
|
67
|
+
initPending: function(definition) {
|
60
68
|
var observer;
|
61
69
|
if (definition.component.init) {
|
62
70
|
observer = definition.component.init.apply(definition.component, definition.arguments);
|
63
71
|
}
|
64
|
-
|
65
|
-
}
|
66
|
-
};
|
72
|
+
this.push(observer ? observer : definition.component);
|
73
|
+
},
|
67
74
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
75
|
+
notify: function(callbacks) {
|
76
|
+
if (this == Jelly) {
|
77
|
+
return Jelly.Observers.notify.apply(this.observers, arguments);
|
78
|
+
}
|
79
|
+
if (!$.isArray(callbacks)) {
|
80
|
+
callbacks = [callbacks];
|
81
|
+
}
|
72
82
|
|
73
|
-
|
74
|
-
|
75
|
-
var
|
76
|
-
|
77
|
-
|
83
|
+
var observers = this.slice(0);
|
84
|
+
for (var i = 0; i < callbacks.length; i++) {
|
85
|
+
var callback = callbacks[i];
|
86
|
+
|
87
|
+
// Deprecate 'on' in favor of making each page action a Component.
|
88
|
+
if (callback.on) {
|
89
|
+
var additionalObserver = eval(callback.on);
|
90
|
+
if (observers.indexOf(additionalObserver) == -1) {
|
91
|
+
observers.push(additionalObserver);
|
92
|
+
}
|
78
93
|
}
|
79
|
-
}
|
80
94
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
95
|
+
for (var j = 0; j < observers.length; j++) {
|
96
|
+
var observer = observers[j];
|
97
|
+
if (observer[callback.method]) {
|
98
|
+
if (observer.detach && observer.detach()) {
|
99
|
+
Jelly.Observers.garbageCollectObserver.call(this, observer);
|
100
|
+
} else {
|
101
|
+
observer[callback.method].apply(observer, callback.arguments);
|
102
|
+
}
|
88
103
|
}
|
89
104
|
}
|
90
|
-
}
|
91
105
|
|
92
|
-
|
93
|
-
|
106
|
+
if (callback.attach) {
|
107
|
+
Jelly.Observers.attach.apply(this, callback.attach);
|
108
|
+
}
|
94
109
|
}
|
95
110
|
},
|
96
111
|
|
data/jelly.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{jelly}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.8.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Pivotal Labs, Inc"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-29}
|
13
13
|
s.description = %q{Jelly provides a set of tools and conventions for creating rich ajax/javascript web applications with jQuery and Ruby on Rails.}
|
14
14
|
s.email = %q{opensource@pivotallabs.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -3,6 +3,14 @@ module JellyController
|
|
3
3
|
include Jelly::Common
|
4
4
|
|
5
5
|
def jelly_callback(callback_base_name = @action_name, options = {}, &block)
|
6
|
+
raw_jelly_callback(options) do
|
7
|
+
arguments = block.try(:call) || []
|
8
|
+
jelly_callback_hash("on_#{callback_base_name}", *arguments).merge(options)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def raw_jelly_callback(options={}, &block)
|
13
|
+
options.symbolize_keys!
|
6
14
|
options[:format] ||= if request.xhr?
|
7
15
|
:json
|
8
16
|
elsif params[:callback]
|
@@ -10,14 +18,12 @@ module JellyController
|
|
10
18
|
else
|
11
19
|
:iframe
|
12
20
|
end
|
13
|
-
render :inline => jelly_callback_erb(
|
21
|
+
render :inline => jelly_callback_erb(options, &block)
|
14
22
|
end
|
15
23
|
|
16
|
-
def jelly_callback_erb(
|
24
|
+
def jelly_callback_erb(options={}, &block)
|
17
25
|
options[:format] ||= :json
|
18
|
-
@
|
19
|
-
@options = options
|
20
|
-
@block = block
|
26
|
+
@jelly_block = block
|
21
27
|
case options[:format].to_sym
|
22
28
|
when :iframe
|
23
29
|
"<textarea>#{jelly_callback_erb_template}</textarea>"
|
@@ -32,9 +38,7 @@ module JellyController
|
|
32
38
|
def jelly_callback_erb_template
|
33
39
|
<<-ERB
|
34
40
|
<%= begin
|
35
|
-
|
36
|
-
args = [args] unless args.is_a?(Array)
|
37
|
-
json = {"method" => @callback_name, "arguments" => args}.reverse_merge(@options).to_json
|
41
|
+
json = instance_eval(&@jelly_block).to_json
|
38
42
|
@jsonp_callback ? "\#{@jsonp_callback}(\#{json});" : json
|
39
43
|
end %>
|
40
44
|
ERB
|
@@ -15,6 +15,54 @@ describe ApplicationController do
|
|
15
15
|
@controller.respond_to?(:jelly_callback).should be_true
|
16
16
|
end
|
17
17
|
|
18
|
+
context "when given a format" do
|
19
|
+
describe "json" do
|
20
|
+
it "responds with a json hash, even if the request is not xhr" do
|
21
|
+
stub(request).xhr? {false}
|
22
|
+
|
23
|
+
@controller.send(:jelly_callback, 'foo', {'format' => :json, 'bar' => 'baz'}) do
|
24
|
+
"grape"
|
25
|
+
end
|
26
|
+
callback = JSON.parse(response.body)
|
27
|
+
callback["method"].should == "on_foo"
|
28
|
+
callback["arguments"].should == ["grape"]
|
29
|
+
callback["bar"].should == "baz"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "jsonp" do
|
34
|
+
it "responds with a jsonp callback based on the callback param" do
|
35
|
+
@controller.params[:callback] = "Jelly.notifyObservers"
|
36
|
+
|
37
|
+
@controller.send(:jelly_callback, 'foo', {'format' => :jsonp, 'bar' => 'baz'}) do
|
38
|
+
"grape"
|
39
|
+
end
|
40
|
+
json = Regexp.new('Jelly\.notifyObservers\((.*)\);').match(response.body)[1]
|
41
|
+
callback = JSON.parse(json)
|
42
|
+
callback["method"].should == "on_foo"
|
43
|
+
callback["arguments"].should == ["grape"]
|
44
|
+
callback["bar"].should == "baz"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "iframe" do
|
49
|
+
it "responds with a the json in a textarea tag" do
|
50
|
+
@controller.send(:jelly_callback, 'foo', {'format' => :iframe, 'bar' => 'baz'}) do
|
51
|
+
"grape"
|
52
|
+
end
|
53
|
+
body = response.body
|
54
|
+
body.should =~ /^<textarea>/
|
55
|
+
body.should =~ /<\/textarea>$/
|
56
|
+
doc = Nokogiri::HTML(body)
|
57
|
+
|
58
|
+
callback = JSON.parse(doc.at("textarea").inner_html)
|
59
|
+
callback["method"].should == "on_foo"
|
60
|
+
callback["arguments"].should == ["grape"]
|
61
|
+
callback["bar"].should == "baz"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
18
66
|
context "when the request is XHR" do
|
19
67
|
before do
|
20
68
|
stub(request).xhr? {true}
|
@@ -71,81 +119,123 @@ describe ApplicationController do
|
|
71
119
|
end
|
72
120
|
end
|
73
121
|
end
|
122
|
+
end
|
74
123
|
|
75
|
-
|
76
|
-
|
77
|
-
|
124
|
+
describe "#raw_jelly_callback" do
|
125
|
+
attr_reader :response
|
126
|
+
before do
|
127
|
+
@response = Struct.new(:body).new
|
128
|
+
stub(@controller).render do |params|
|
129
|
+
response.body = ERB.new(params[:inline]).result(@controller.send(:binding))
|
78
130
|
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "have the method included" do
|
134
|
+
@controller.respond_to?(:raw_jelly_callback).should be_true
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when given a format" do
|
138
|
+
describe "json" do
|
139
|
+
it "responds with a json hash, even if the request is not xhr" do
|
140
|
+
stub(request).xhr? {false}
|
79
141
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
JSON.parse(
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
'format' => 'json'
|
88
|
-
}
|
142
|
+
@controller.send(:raw_jelly_callback, :format => :json) do
|
143
|
+
jelly_callback_hash("foo", "grape").merge('bar' => 'baz')
|
144
|
+
end
|
145
|
+
callback = JSON.parse(response.body)
|
146
|
+
callback["method"].should == "foo"
|
147
|
+
callback["arguments"].should == ["grape"]
|
148
|
+
callback["bar"].should == "baz"
|
89
149
|
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "jsonp" do
|
153
|
+
it "responds with a jsonp callback based on the callback param" do
|
154
|
+
@controller.params[:callback] = "Jelly.notifyObservers"
|
90
155
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
156
|
+
@controller.send(:raw_jelly_callback, :format => :jsonp) do
|
157
|
+
jelly_callback_hash("foo", "grape").merge('bar' => 'baz')
|
158
|
+
end
|
159
|
+
json = Regexp.new('Jelly\.notifyObservers\((.*)\);').match(response.body)[1]
|
160
|
+
callback = JSON.parse(json)
|
161
|
+
callback["method"].should == "foo"
|
162
|
+
callback["arguments"].should == ["grape"]
|
163
|
+
callback["bar"].should == "baz"
|
99
164
|
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "iframe" do
|
168
|
+
it "responds with a the json in a textarea tag" do
|
169
|
+
@controller.send(:raw_jelly_callback, :format => :iframe) do
|
170
|
+
jelly_callback_hash("foo", "grape").merge('bar' => 'baz')
|
171
|
+
end
|
172
|
+
body = response.body
|
173
|
+
body.should =~ /^<textarea>/
|
174
|
+
body.should =~ /<\/textarea>$/
|
175
|
+
doc = Nokogiri::HTML(body)
|
100
176
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
'arguments' => [],
|
106
|
-
'bar' => 'baz',
|
107
|
-
'format' => 'json'
|
108
|
-
}
|
177
|
+
callback = JSON.parse(doc.at("textarea").inner_html)
|
178
|
+
callback["method"].should == "foo"
|
179
|
+
callback["arguments"].should == ["grape"]
|
180
|
+
callback["bar"].should == "baz"
|
109
181
|
end
|
110
182
|
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "when the request is XHR" do
|
186
|
+
before do
|
187
|
+
stub(request).xhr? {true}
|
188
|
+
end
|
111
189
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
JSON.parse(ERB.new(erb).result(@controller.send(:binding))).should == {
|
116
|
-
'method' => 'foo',
|
117
|
-
'arguments' => ['grape'],
|
118
|
-
'format' => 'json'
|
119
|
-
}
|
190
|
+
it "responds with a json hash" do
|
191
|
+
@controller.send(:raw_jelly_callback) do
|
192
|
+
jelly_callback_hash("foo", "grape").merge('bar' => 'baz')
|
120
193
|
end
|
194
|
+
callback = JSON.parse(response.body)
|
195
|
+
callback["method"].should == "foo"
|
196
|
+
callback["arguments"].should == ["grape"]
|
197
|
+
callback["bar"].should == "baz"
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
121
201
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
202
|
+
context "when the request is not XHR" do
|
203
|
+
before do
|
204
|
+
stub(request).xhr? {false}
|
205
|
+
end
|
206
|
+
|
207
|
+
context "when there is a callback param" do
|
208
|
+
before do
|
209
|
+
@controller.params[:callback] = "Jelly.notifyObservers"
|
129
210
|
end
|
130
211
|
|
131
|
-
it "
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
212
|
+
it "responds with a call to the given callback method with the json as an argument" do
|
213
|
+
@controller.send(:raw_jelly_callback) do
|
214
|
+
jelly_callback_hash("foo", "grape").merge('bar' => 'baz')
|
215
|
+
end
|
216
|
+
json = Regexp.new('Jelly\.notifyObservers\((.*)\);').match(response.body)[1]
|
217
|
+
callback = JSON.parse(json)
|
218
|
+
callback["method"].should == "foo"
|
219
|
+
callback["arguments"].should == ["grape"]
|
220
|
+
callback["bar"].should == "baz"
|
138
221
|
end
|
139
222
|
end
|
140
223
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
224
|
+
context "when there is not a callback param" do
|
225
|
+
it "wraps the json response in a textarea tag to support File Uploads in an iframe target (see: http://malsup.com/jquery/form/#code-samples)" do
|
226
|
+
@controller.send(:raw_jelly_callback) do
|
227
|
+
jelly_callback_hash("foo", "grape").merge('bar' => 'baz')
|
228
|
+
end
|
229
|
+
body = response.body
|
230
|
+
body.should =~ /^<textarea>/
|
231
|
+
body.should =~ /<\/textarea>$/
|
232
|
+
doc = Nokogiri::HTML(body)
|
233
|
+
|
234
|
+
callback = JSON.parse(doc.at("textarea").inner_html)
|
235
|
+
callback["method"].should == "foo"
|
236
|
+
callback["arguments"].should == ["grape"]
|
237
|
+
callback["bar"].should == "baz"
|
238
|
+
end
|
149
239
|
end
|
150
240
|
end
|
151
241
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: honkster-jelly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pivotal Labs, Inc
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-29 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|