gon 3.0.5 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of gon might be problematic. Click here for more details.

data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 4.0.0
4
+
5
+ * Added gon.watch functionality (thanks to @brainopia and @kossnocorp)
6
+ * Compatibility with jbuilder paths for partial! method
7
+ * Fixed some bugs
8
+ * Little bit refactoring - Gon now is a class
9
+
3
10
  ## 3.0.3
4
11
 
5
12
  * Include ActionView::Helpers into Gon::JBuilder
data/README.md CHANGED
@@ -7,6 +7,8 @@
7
7
 
8
8
  If you need to send some data to your js files and you don't want to do this with long way through views and parsing - use this force!
9
9
 
10
+ Now you can easily renew data in your variables through ajax with [gon.watch](https://github.com/gazay/gon/wiki/Usage-gon-watch)!
11
+
10
12
  With [Jbuilder](https://github.com/rails/jbuilder) and [Rabl](https://github.com/nesquena/rabl) support!
11
13
 
12
14
  For Sinatra available [gon-sinatra](https://github.com/gazay/gon-sinatra).
@@ -50,67 +52,30 @@ gem line to your Gemfile and do the following:
50
52
 
51
53
  3. profit?
52
54
 
53
- ## Usage
54
-
55
- `app/views/layouts/application.html.erb`
56
-
57
- ``` erb
58
- <head>
59
- <title>some title</title>
60
- <%= include_gon %>
61
- <!-- include your action js code -->
62
- ...
63
- ```
64
-
65
- To camelize your variables in js you can use:
66
-
67
- ``` erb
68
- <head>
69
- <title>some title</title>
70
- <%= include_gon(:camel_case => true) %>
71
- <!-- include your action js code with camelized variables -->
72
- ...
73
- ```
55
+ With `gon.watch` feature you can easily renew data in gon variables!
56
+ Just pass option `:watch => true` to `include_gon` method and call
57
+ `gon.watch` from your js file. It's super useful in modern web
58
+ applications!
74
59
 
75
- You can change the namespace of the variables:
60
+ ## Usage
76
61
 
77
- ``` erb
78
- <head>
79
- <title>some title</title>
80
- <%= include_gon(:namespace => 'serverExports') %>
81
- <!-- include your action js code with 'serverExports' namespace -->
82
- ...
83
- ```
62
+ ### More details about configuration and usage you can find in [gon wiki](https://github.com/gazay/gon/wiki)
84
63
 
85
- You can initialize window.gon = {}; on each request
64
+ Old readme available in [./README_old.md](https://github.com/gazay/gon/blob/master/README_old.md)
86
65
 
87
- ``` erb
88
- <head>
89
- <title>some title</title>
90
- <%= include_gon(:init => true) %>
91
- <!-- include your action js code with 'serverExports' namespace -->
92
- ...
93
- ```
94
66
 
95
- You can initialize script tag with type="text/javascript"
67
+ `app/views/layouts/application.html.erb`
96
68
 
97
69
  ``` erb
98
70
  <head>
99
71
  <title>some title</title>
100
- <%= include_gon(:need_type => true) %>
101
- <!-- include your action js code with 'serverExports' namespace -->
72
+ <%= include_gon %>
73
+ <!-- include your action js code -->
102
74
  ...
103
75
  ```
104
76
 
105
- You can get json without script tag (kudos to @afa):
106
-
107
- ``` erb
108
- <head>
109
- <title>some title</title>
110
- <script><%= include_gon(:need_tag => false) %></script>
111
- <!-- include your action js code with 'serverExports' namespace -->
112
- ...
113
- ```
77
+ You can pass some [options](https://github.com/gazay/gon/wiki/Options)
78
+ to `include_gon` method.
114
79
 
115
80
  You put something like this in the action of your controller:
116
81
 
@@ -139,39 +104,22 @@ alert(gon.your_array)
139
104
  alert(gon.your_hash)
140
105
  ```
141
106
 
142
- With camelize:
107
+ ## gon.watch - renew your data easily!
143
108
 
144
- ``` js
145
- alert(gon.yourInt)
146
- alert(gon.yourOtherInt)
147
- alert(gon.yourArray)
148
- alert(gon.yourHash)
149
- ```
109
+ You can use gon for renewing your data without reloading pages and
110
+ writing long js functions! It's really
111
+ great for some live values.
150
112
 
151
- With custom namespace and camelize:
113
+ Supports `gon.watch.rabl` and `gon.watch.jbuilder` usage.
152
114
 
153
- ``` js
154
- alert(customNamespace.yourInt)
155
- alert(customNamespace.yourOtherInt)
156
- alert(customNamespace.yourArray)
157
- alert(customNamespace.yourHash)
158
- ```
115
+ [Instruction](https://github.com/gazay/gon/wiki/Usage-gon-watch) for
116
+ usage gon.watch.
159
117
 
160
118
  ## Usage with Rabl
161
119
 
162
120
  You can write your variables assign logic to templates with [Rabl](https://github.com/nesquena/rabl).
163
121
  The way of writing Rabl templates is very clearly described in their repo.
164
122
 
165
- Add Rabl to your Gemfile before requiring gon - because gon checks Rabl constant
166
-
167
- `Gemfile`
168
-
169
- ``` ruby
170
- gem 'rabl'
171
- ...
172
- gem 'gon'
173
- ```
174
-
175
123
  Profit of using Rabl with gon:
176
124
 
177
125
  1. You can clean your controllers now!
@@ -180,195 +128,23 @@ Profit of using Rabl with gon:
180
128
  4. You can still be lazy and don't use common way to transfer data in js
181
129
  5. And so on
182
130
 
183
- For using gon with Rabl you need to create new Rabl template and map gon
184
- to it.
185
- For example you have model Post with attributes :title and :body.
186
- You want to get all your posts in your js as an Array.
187
- That's what you need to do:
188
-
189
- 1. Create Rabl template. You can choose spepicific directory but better
190
- use default directory for action.
191
-
192
- `app/views/posts/index.json.rabl`
193
-
194
- ``` rabl
195
- collection @posts => 'posts'
196
- attributes :id, :title, :body
197
- ```
198
-
199
- 2. If you create template in default directory for action, you just write in this action:
200
-
201
- `app/controllers/posts_controller.rb#index`
202
-
203
- ``` ruby
204
- def index
205
- # some controller logic
206
- @posts = Post.all # Rabl works with instance variables of controller
207
-
208
- gon.rabl
209
- # some controller logic
210
- end
211
- ```
212
-
213
- But if you choose some specific category - you need to map this template to gon.
214
-
215
- `app/controllers/posts_controller.rb#index`
216
-
217
- ``` ruby
218
- def index
219
- # some controller logic
220
- @posts = Post.all # Rabl works with instance variables of controller
221
-
222
- gon.rabl :template => 'app/goners/posts/index.rabl'
223
- # some controller logic
224
- end
225
- ```
226
-
227
- Thats it! Now you will get in your js gon.posts variable which is Array of
228
- post objects with attributes :id, :title and :body.
229
-
230
- In javascript file for view of this action write call to your variable:
231
-
232
- ``` js
233
- alert(gon.posts)
234
- alert(gon.posts[0])
235
- alert(gon.posts[0].post.body)
236
- ```
237
-
238
- P.s. If you didn't put include_gon tag in your html head area - it
239
- wouldn't work. You can read about this in common usage above.
240
-
241
- ### Some tips of usage Rabl with gon:
242
-
243
- If you don't use alias in Rabl template:
244
-
245
- ``` rabl
246
- collection @posts
247
- ....
248
- ```
249
-
250
- instead of using that:
251
-
252
- ``` rabl
253
- collection @posts => 'alias'
254
- ....
255
- ```
256
-
257
- Rabl will return you an array and gon by default will put it to variable
258
- gon.rabl
259
-
260
- Two ways how you can change it - using aliases or you can add alias to
261
- gon mapping method:
262
-
263
- ``` ruby
264
- # your controller stuff here
265
-
266
- gon.rabl :as => 'alias'
267
- ```
131
+ [Instruction](https://github.com/gazay/gon/wiki/Usage-with-rabl) for
132
+ usage gon with Rabl.
268
133
 
269
134
  ## Usage with Jbuilder
270
135
 
271
136
  Use gon with [Jbuilder](https://github.com/rails/jbuilder) as with [Rabl](https://guthub.com/nesquena/rabl):
272
137
 
273
- 0. Add jbuilder to your Gemfile (because of it depends on
274
- ActiveSuppurt '~> 3.0.0')
275
-
276
- `Gemfile`
277
-
278
- ``` ruby
279
- gem 'jbuilder'
280
- ```
281
-
282
- 1. Create Jbuilder template.
283
-
284
- `app/views/posts/index.json.jbuilder`
285
-
286
- ``` jbuilder
287
- json.posts @posts, :id, :title, :body
288
- ```
289
-
290
- 2. In your controller you should just call 'gon.jbuilder' - if your template in
291
- default directory for action. In the other case - you still can use :template option.
292
-
293
- ``` ruby
294
- def index
295
- # some controller logic
296
- @posts = Post.all
297
-
298
- gon.jbuilder
299
- # some controller logic
300
- end
301
- ```
302
-
303
- In javascript file for view of this action write call to your variable:
304
-
305
- Now you can use partials in jbuilder:
306
-
307
- `app/views/posts/index.json.jbuilder`
308
-
309
- ``` jbuilder
310
- json.partial! 'app/views/posts/_part.json.jbuilder', :comments => @posts[0].comments
311
- ```
312
-
313
- `app/views/posts/_part.json.jbuilder`
314
-
315
- ``` jbuilder
316
- json.comments comments.map{ |it| 'comment#' + it.id }
317
- ```
318
-
319
- ``` js
320
- alert(gon.posts)
321
- alert(gon.posts[0])
322
- alert(gon.posts[0].post.body)
323
- alert(gon.comments)
324
- alert(gon.comments[0])
325
- ```
326
-
327
- P.s. If you didn't put include_gon tag in your html head area - it
328
- wouldn't work. You can read about this in common usage above.
138
+ [Instruction](https://github.com/gazay/gon/wiki/Usage-with-jbuilder) for
139
+ usage gon with Jbuilder.
329
140
 
330
141
  ## gon.global
331
142
 
332
- Now you can use gon for sending your data to js from anywhere!
333
-
334
- It works just as simple `gon` but you need to write `Gon.global` instead of `gon` in your ruby code,
335
- `gon.global` in javascript and it will not clear self after each request. All other things remain the same.
336
-
337
- For example I want to set start data into gon, which will be there before I clear it.
338
-
339
- Maybe some configuration data or url address which should be present on each page with `include_gon` helper in head.
340
-
341
- Now with Gon.global it's easy!
342
-
343
- `config/initializers/some_initializer.rb or any file where you can reach Gon constant`
344
-
345
- ```ruby
346
- Gon.global.variable = 'Some data'
347
- ```
348
-
349
- `in some js which can reach window.gon variable`
350
-
351
- ```javascript
352
- alert(gon.global.variable)
353
- ```
354
-
355
- Thats it!
356
-
357
- ## Installation
358
-
359
- Puts this line into `Gemfile` then run `$ bundle`:
360
-
361
- ``` ruby
362
- gem 'gon', '3.0.5'
363
- ```
364
-
365
- Or if you are old-school Rails 2 developer put this into `config/environment.rb` and run `$ rake gems:install`:
366
-
367
- ``` ruby
368
- config.gem 'gon', :version => '3.0.5'
369
- ```
143
+ You can use gon for sending your data to js from anywhere! It's really
144
+ great for some init data.
370
145
 
371
- Or manually install gon gem: `$ gem install gon`
146
+ [Instruction](https://github.com/gazay/gon/wiki/Usage-gon-global) for
147
+ usage gon.global.
372
148
 
373
149
  ## Contributors
374
150
 
data/README_old.md ADDED
@@ -0,0 +1,389 @@
1
+ # Gon gem — get your Rails variables in your js
2
+
3
+ ![Gon. You should try this. If you look closer - you will see an elephant.](https://github.com/gazay/gon/raw/master/doc/logo_small.png)
4
+
5
+
6
+ ### Build Status ![http://travis-ci.org/gazay/gon](https://secure.travis-ci.org/gazay/gon.png)
7
+
8
+ If you need to send some data to your js files and you don't want to do this with long way through views and parsing - use this force!
9
+
10
+ With [Jbuilder](https://github.com/rails/jbuilder) and [Rabl](https://github.com/nesquena/rabl) support!
11
+
12
+ For Sinatra available [gon-sinatra](https://github.com/gazay/gon-sinatra).
13
+
14
+ For .Net MVC available port [NGon](https://github.com/brooklynDev/NGon).
15
+
16
+ ## An example of typical use
17
+
18
+ ### Very good and detailed example and reasons to use is considered in [railscast](http://railscasts.com/episodes/324-passing-data-to-javascript) by Ryan Bates
19
+
20
+ When you need to send some start data from your controller to your js
21
+ you might be doing something like this:
22
+
23
+ 1. Write this data in controller(presenter/model) to some variable
24
+ 2. In view for this action you put this variable to some objects by data
25
+ attributes, or write js right in view
26
+ 3. Then there can be two ways in js:
27
+ + if you previously wrote data in data
28
+ attributes - you should parse this attributes and write data to some
29
+ js variable.
30
+ + if you wrote js right in view (many frontenders would shame you for
31
+ that) - you just use data from this js - OK.
32
+ 4. You can use your data in your js
33
+
34
+ And everytime when you need to send some data from action to js you do this.
35
+
36
+ With gon you configure it firstly - just put in layout one tag, and add
37
+ gem line to your Gemfile and do the following:
38
+
39
+ 1. Write variables by
40
+
41
+ ``` ruby
42
+ gon.variable_name = variable_value
43
+ ```
44
+
45
+ 2. In your js you get this by
46
+
47
+ ``` js
48
+ gon.variable_name
49
+ ```
50
+
51
+ 3. profit?
52
+
53
+ ## Usage
54
+
55
+ `app/views/layouts/application.html.erb`
56
+
57
+ ``` erb
58
+ <head>
59
+ <title>some title</title>
60
+ <%= include_gon %>
61
+ <!-- include your action js code -->
62
+ ...
63
+ ```
64
+
65
+ To camelize your variables in js you can use:
66
+
67
+ ``` erb
68
+ <head>
69
+ <title>some title</title>
70
+ <%= include_gon(:camel_case => true) %>
71
+ <!-- include your action js code with camelized variables -->
72
+ ...
73
+ ```
74
+
75
+ You can change the namespace of the variables:
76
+
77
+ ``` erb
78
+ <head>
79
+ <title>some title</title>
80
+ <%= include_gon(:namespace => 'serverExports') %>
81
+ <!-- include your action js code with 'serverExports' namespace -->
82
+ ...
83
+ ```
84
+
85
+ You can initialize window.gon = {}; on each request
86
+
87
+ ``` erb
88
+ <head>
89
+ <title>some title</title>
90
+ <%= include_gon(:init => true) %>
91
+ <!-- include your action js code with 'serverExports' namespace -->
92
+ ...
93
+ ```
94
+
95
+ You can initialize script tag with type="text/javascript"
96
+
97
+ ``` erb
98
+ <head>
99
+ <title>some title</title>
100
+ <%= include_gon(:need_type => true) %>
101
+ <!-- include your action js code with 'serverExports' namespace -->
102
+ ...
103
+ ```
104
+
105
+ You can get json without script tag (kudos to @afa):
106
+
107
+ ``` erb
108
+ <head>
109
+ <title>some title</title>
110
+ <script><%= include_gon(:need_tag => false) %></script>
111
+ <!-- include your action js code with 'serverExports' namespace -->
112
+ ...
113
+ ```
114
+
115
+ You put something like this in the action of your controller:
116
+
117
+ ``` ruby
118
+ @your_int = 123
119
+ @your_array = [1,2]
120
+ @your_hash = {'a' => 1, 'b' => 2}
121
+ gon.your_int = @your_int
122
+ gon.your_other_int = 345 + gon.your_int
123
+ gon.your_array = @your_array
124
+ gon.your_array << gon.your_int
125
+ gon.your_hash = @your_hash
126
+
127
+ gon.all_variables # > {:your_int => 123, :your_other_int => 468, :your_array => [1, 2, 123], :your_hash => {'a' => 1, 'b' => 2}}
128
+ gon.your_array # > [1, 2, 123]
129
+
130
+ gon.clear # gon.all_variables now is {}
131
+ ```
132
+
133
+ Access the varaibles from your JavaScript file:
134
+
135
+ ``` js
136
+ alert(gon.your_int)
137
+ alert(gon.your_other_int)
138
+ alert(gon.your_array)
139
+ alert(gon.your_hash)
140
+ ```
141
+
142
+ With camelize:
143
+
144
+ ``` js
145
+ alert(gon.yourInt)
146
+ alert(gon.yourOtherInt)
147
+ alert(gon.yourArray)
148
+ alert(gon.yourHash)
149
+ ```
150
+
151
+ With custom namespace and camelize:
152
+
153
+ ``` js
154
+ alert(customNamespace.yourInt)
155
+ alert(customNamespace.yourOtherInt)
156
+ alert(customNamespace.yourArray)
157
+ alert(customNamespace.yourHash)
158
+ ```
159
+
160
+ ## Usage with Rabl
161
+
162
+ You can write your variables assign logic to templates with [Rabl](https://github.com/nesquena/rabl).
163
+ The way of writing Rabl templates is very clearly described in their repo.
164
+
165
+ Add Rabl to your Gemfile before requiring gon - because gon checks Rabl constant
166
+
167
+ `Gemfile`
168
+
169
+ ``` ruby
170
+ gem 'rabl'
171
+ ...
172
+ gem 'gon'
173
+ ```
174
+
175
+ Profit of using Rabl with gon:
176
+
177
+ 1. You can clean your controllers now!
178
+ 2. Work with database objects and collections clearly and easyly
179
+ 3. All power of Rabl
180
+ 4. You can still be lazy and don't use common way to transfer data in js
181
+ 5. And so on
182
+
183
+ For using gon with Rabl you need to create new Rabl template and map gon
184
+ to it.
185
+ For example you have model Post with attributes :title and :body.
186
+ You want to get all your posts in your js as an Array.
187
+ That's what you need to do:
188
+
189
+ 1. Create Rabl template. You can choose spepicific directory but better
190
+ use default directory for action.
191
+
192
+ `app/views/posts/index.json.rabl`
193
+
194
+ ``` rabl
195
+ collection @posts => 'posts'
196
+ attributes :id, :title, :body
197
+ ```
198
+
199
+ 2. If you create template in default directory for action, you just write in this action:
200
+
201
+ `app/controllers/posts_controller.rb#index`
202
+
203
+ ``` ruby
204
+ def index
205
+ # some controller logic
206
+ @posts = Post.all # Rabl works with instance variables of controller
207
+
208
+ gon.rabl
209
+ # some controller logic
210
+ end
211
+ ```
212
+
213
+ But if you choose some specific category - you need to map this template to gon.
214
+
215
+ `app/controllers/posts_controller.rb#index`
216
+
217
+ ``` ruby
218
+ def index
219
+ # some controller logic
220
+ @posts = Post.all # Rabl works with instance variables of controller
221
+
222
+ gon.rabl :template => 'app/goners/posts/index.rabl'
223
+ # some controller logic
224
+ end
225
+ ```
226
+
227
+ Thats it! Now you will get in your js gon.posts variable which is Array of
228
+ post objects with attributes :id, :title and :body.
229
+
230
+ In javascript file for view of this action write call to your variable:
231
+
232
+ ``` js
233
+ alert(gon.posts)
234
+ alert(gon.posts[0])
235
+ alert(gon.posts[0].post.body)
236
+ ```
237
+
238
+ P.s. If you didn't put include_gon tag in your html head area - it
239
+ wouldn't work. You can read about this in common usage above.
240
+
241
+ ### Some tips of usage Rabl with gon:
242
+
243
+ If you don't use alias in Rabl template:
244
+
245
+ ``` rabl
246
+ collection @posts
247
+ ....
248
+ ```
249
+
250
+ instead of using that:
251
+
252
+ ``` rabl
253
+ collection @posts => 'alias'
254
+ ....
255
+ ```
256
+
257
+ Rabl will return you an array and gon by default will put it to variable
258
+ gon.rabl
259
+
260
+ Two ways how you can change it - using aliases or you can add alias to
261
+ gon mapping method:
262
+
263
+ ``` ruby
264
+ # your controller stuff here
265
+
266
+ gon.rabl :as => 'alias'
267
+ ```
268
+
269
+ ## Usage with Jbuilder
270
+
271
+ Use gon with [Jbuilder](https://github.com/rails/jbuilder) as with [Rabl](https://guthub.com/nesquena/rabl):
272
+
273
+ 0. Add jbuilder to your Gemfile (because of it depends on
274
+ ActiveSuppurt '~> 3.0.0')
275
+
276
+ `Gemfile`
277
+
278
+ ``` ruby
279
+ gem 'jbuilder'
280
+ ```
281
+
282
+ 1. Create Jbuilder template.
283
+
284
+ `app/views/posts/index.json.jbuilder`
285
+
286
+ ``` jbuilder
287
+ json.posts @posts, :id, :title, :body
288
+ ```
289
+
290
+ 2. In your controller you should just call 'gon.jbuilder' - if your template in
291
+ default directory for action. In the other case - you still can use :template option.
292
+
293
+ ``` ruby
294
+ def index
295
+ # some controller logic
296
+ @posts = Post.all
297
+
298
+ gon.jbuilder
299
+ # some controller logic
300
+ end
301
+ ```
302
+
303
+ In javascript file for view of this action write call to your variable:
304
+
305
+ Now you can use partials in jbuilder:
306
+
307
+ `app/views/posts/index.json.jbuilder`
308
+
309
+ ``` jbuilder
310
+ json.partial! 'app/views/posts/_part.json.jbuilder', :comments => @posts[0].comments
311
+ ```
312
+
313
+ `app/views/posts/_part.json.jbuilder`
314
+
315
+ ``` jbuilder
316
+ json.comments comments.map{ |it| 'comment#' + it.id }
317
+ ```
318
+
319
+ ``` js
320
+ alert(gon.posts)
321
+ alert(gon.posts[0])
322
+ alert(gon.posts[0].post.body)
323
+ alert(gon.comments)
324
+ alert(gon.comments[0])
325
+ ```
326
+
327
+ P.s. If you didn't put include_gon tag in your html head area - it
328
+ wouldn't work. You can read about this in common usage above.
329
+
330
+ ## gon.global
331
+
332
+ Now you can use gon for sending your data to js from anywhere!
333
+
334
+ It works just as simple `gon` but you need to write `Gon.global` instead of `gon` in your ruby code,
335
+ `gon.global` in javascript and it will not clear self after each request. All other things remain the same.
336
+
337
+ For example I want to set start data into gon, which will be there before I clear it.
338
+
339
+ Maybe some configuration data or url address which should be present on each page with `include_gon` helper in head.
340
+
341
+ Now with Gon.global it's easy!
342
+
343
+ `config/initializers/some_initializer.rb or any file where you can reach Gon constant`
344
+
345
+ ```ruby
346
+ Gon.global.variable = 'Some data'
347
+ ```
348
+
349
+ `in some js which can reach window.gon variable`
350
+
351
+ ```javascript
352
+ alert(gon.global.variable)
353
+ ```
354
+
355
+ Thats it!
356
+
357
+ ## Installation
358
+
359
+ Puts this line into `Gemfile` then run `$ bundle`:
360
+
361
+ ``` ruby
362
+ gem 'gon', '3.0.5'
363
+ ```
364
+
365
+ Or if you are old-school Rails 2 developer put this into `config/environment.rb` and run `$ rake gems:install`:
366
+
367
+ ``` ruby
368
+ config.gem 'gon', :version => '3.0.5'
369
+ ```
370
+
371
+ Or manually install gon gem: `$ gem install gon`
372
+
373
+ ## Contributors
374
+
375
+ * @gazay
376
+
377
+ Special thanks to @brainopia, @kossnocorp and @ai.
378
+
379
+ ## License
380
+
381
+ The MIT License
382
+
383
+ Copyright (c) 2011-2012 gazay
384
+
385
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
386
+
387
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
388
+
389
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Binary file
data/lib/gon.rb CHANGED
@@ -5,6 +5,7 @@ require 'action_view'
5
5
  require 'action_controller'
6
6
  require 'gon/base'
7
7
  require 'gon/global'
8
+ require 'gon/watch'
8
9
  require 'gon/request'
9
10
  require 'gon/helpers'
10
11
  require 'gon/escaper'
@@ -15,13 +16,17 @@ if defined?(Jbuilder)
15
16
  require 'gon/jbuilder'
16
17
  end
17
18
 
18
- module Gon
19
+ class Gon
19
20
  class << self
20
21
 
21
22
  def global
22
23
  Gon::Global
23
24
  end
24
25
 
26
+ def watch
27
+ Gon::Watch
28
+ end
29
+
25
30
  def method_missing(method, *args, &block)
26
31
  if ( method.to_s =~ /=$/ )
27
32
  if public_method_name? method
@@ -43,12 +48,18 @@ module Gon
43
48
  end
44
49
 
45
50
  def rabl(*args)
51
+ unless Gon.constants.include?(:Rabl)
52
+ raise "Possible wrong require order problem - try to add `gem 'rabl'` before `gem 'gon'` in your Gemfile"
53
+ end
46
54
  data, options = Gon::Rabl.handler(args)
47
55
 
48
56
  store_builder_data 'rabl', data, options
49
57
  end
50
58
 
51
59
  def jbuilder(*args)
60
+ unless Gon.constants.include?(:Jbuilder)
61
+ raise "Possible wrong require order problem - try to add `gem 'jbuilder'` before `gem 'gon'` in your Gemfile"
62
+ end
52
63
  data, options = Gon::Jbuilder.handler(args)
53
64
 
54
65
  store_builder_data 'jbuilder', data, options
data/lib/gon/base.rb CHANGED
@@ -1,4 +1,4 @@
1
- module Gon
1
+ class Gon
2
2
  module Base
3
3
  class << self
4
4
 
@@ -7,7 +7,7 @@ module Gon
7
7
  if Gon.global.all_variables.present?
8
8
  data[:global] = Gon.global.all_variables
9
9
  end
10
- namespace, tag, cameled = parse_options options
10
+ namespace, tag, cameled, watch = parse_options options
11
11
  start = "#{tag if tag}window.#{namespace} = {};"
12
12
  script = ''
13
13
 
@@ -20,11 +20,12 @@ module Gon
20
20
  end
21
21
 
22
22
  script = start + Gon::Escaper.escape(script)
23
+ script << Gon.watch.render if watch and Gon::Watch.all_variables.present?
23
24
  script << '</script>' if tag
24
25
  script.html_safe
25
26
  end
26
27
 
27
- def get_controller(options)
28
+ def get_controller(options = {})
28
29
  options[:controller] ||
29
30
  Gon::Request.env['action_controller.instance'] ||
30
31
  Gon::Request.env['action_controller.rescue.response'].
@@ -53,9 +54,10 @@ module Gon
53
54
  need_tag = options[:need_tag].nil? || options[:need_tag]
54
55
  need_type = options[:need_type].present? && options[:need_type]
55
56
  cameled = options[:camel_case]
57
+ watch = options[:watch]
56
58
  tag = need_tag && (need_type ? '<script type="text/javascript">' : '<script>')
57
59
 
58
- [namespace, tag, cameled]
60
+ [namespace, tag, cameled, watch]
59
61
  end
60
62
 
61
63
  def right_extension?(extension, template_path)
data/lib/gon/escaper.rb CHANGED
@@ -1,4 +1,4 @@
1
- module Gon
1
+ class Gon
2
2
  module Escaper
3
3
  class << self
4
4
 
data/lib/gon/global.rb CHANGED
@@ -1,66 +1,47 @@
1
- module Gon
2
- module Global
1
+ class Gon
2
+ class Global < Gon
3
3
  class << self
4
4
 
5
5
  def all_variables
6
6
  @global_vars || {}
7
7
  end
8
8
 
9
- def method_missing(method, *args, &block)
10
- @global_vars ||= {}
11
- if ( method.to_s =~ /=$/ )
12
- if public_method_name? method
13
- raise "You can't use Gon public methods for storing data"
14
- end
9
+ def clear
10
+ @global_vars = {}
11
+ end
15
12
 
16
- @global_vars[method.to_s.delete('=')] = args[0]
17
- else
18
- @global_vars[method.to_s]
19
- end
13
+ def inspect
14
+ 'Gon::Global'
20
15
  end
21
16
 
22
17
  def rabl(*args)
18
+ unless Gon.constants.include?(:Rabl)
19
+ raise "Possible wrong require order problem - try to add `gem 'rabl'` before `gem 'gon'` in your Gemfile"
20
+ end
23
21
  data, options = Gon::Rabl.handler(args, true)
24
22
 
25
23
  store_builder_data 'rabl', data, options
26
24
  end
27
25
 
28
26
  def jbuilder(*args)
27
+ unless Gon.constants.include?(:Jbuilder)
28
+ raise "Possible wrong require order problem - try to add `gem 'jbuilder'` before `gem 'gon'` in your Gemfile"
29
+ end
29
30
  data, options = Gon::Jbuilder.handler(args, true)
30
31
 
31
32
  store_builder_data 'jbuilder', data, options
32
33
  end
33
34
 
34
- def clear
35
- @global_vars = {}
36
- end
37
-
38
- def inspect
39
- 'Gon'
40
- end
41
-
42
35
  private
43
36
 
44
- def store_builder_data(builder, data, options)
45
- if options[:as]
46
- @global_vars[options[:as].to_s] = data
47
- elsif data.is_a? Hash
48
- data.each do |key, value|
49
- @global_vars[key] = value
50
- end
51
- else
52
- @global_vars[builder] = data
53
- end
37
+ def get_variable(name)
38
+ @global_vars ||= {}
39
+ @global_vars[name]
54
40
  end
55
41
 
56
- def public_method_name?(method)
57
- public_methods.include?(
58
- if RUBY_VERSION > '1.9'
59
- method.to_s[0..-2].to_sym
60
- else
61
- method.to_s[0..-2]
62
- end
63
- )
42
+ def set_variable(name, value)
43
+ @global_vars ||= {}
44
+ @global_vars[name] = value
64
45
  end
65
46
 
66
47
  end
data/lib/gon/helpers.rb CHANGED
@@ -1,4 +1,4 @@
1
- module Gon
1
+ class Gon
2
2
  module Helpers
3
3
 
4
4
  def self.included base
data/lib/gon/jbuilder.rb CHANGED
@@ -1,4 +1,4 @@
1
- module Gon
1
+ class Gon
2
2
  module Jbuilder
3
3
  class << self
4
4
 
@@ -7,12 +7,14 @@ module Gon
7
7
  if global && !options[:template]
8
8
  raise 'You should provide :template when use rabl with global variables'
9
9
  end
10
+ controller = Gon::Base.get_controller(options)
11
+ @_controller_name = global ? '' : controller.controller_path
10
12
 
11
13
  include_helpers
12
14
 
13
15
  data = parse_jbuilder \
14
16
  Gon::Base.get_template_path(options,'jbuilder'),
15
- Gon::Base.get_controller(options)
17
+ controller
16
18
 
17
19
  [data, options]
18
20
  end
@@ -69,6 +71,7 @@ module Gon
69
71
 
70
72
  def parse_partial(partial_line)
71
73
  path = partial_line.match(/['"]([^'"]*)['"]/)[1]
74
+ path = parse_path path
72
75
  options_hash = partial_line.match(/,(.*)/)[1]
73
76
  if options_hash.present?
74
77
  options = eval '{' + options_hash + '}'
@@ -80,10 +83,40 @@ module Gon
80
83
  find_partials File.readlines(path)
81
84
  end
82
85
 
86
+ def parse_path(path)
87
+ return path if File.exists?(path)
88
+
89
+ splitted = path.split('/')
90
+ if splitted.size == 2
91
+ tmp_path = construct_path(splitted[0], splitted[1])
92
+ return tmp_path if tmp_path
93
+ elsif splitted.size == 1
94
+ tmp_path = construct_path @_controller_name, splitted[0]
95
+ return tmp_path if tmp_path
96
+ end
97
+
98
+ raise 'Something wrong with partial path in your jbuilder templates'
99
+ end
100
+
101
+ def construct_path(part1, part2)
102
+ tmp_path = "app/views/#{part1}/_#{part2}"
103
+ tmp_path = path_with_ext(tmp_path)
104
+ return tmp_path if tmp_path
105
+ tmp_path = "app/views/#{part1}/#{part2}"
106
+ tmp_path = path_with_ext(tmp_path)
107
+ return tmp_path if tmp_path
108
+ end
109
+
110
+ def path_with_ext(path)
111
+ return path if File.exists?(path)
112
+ return "#{path}.jbuilder" if File.exists?("#{path}.jbuilder")
113
+ return "#{path}.json.jbuilder" if File.exists?("#{path}.json.jbuilder")
114
+ end
115
+
83
116
  def find_partials(lines = [])
84
117
  lines.map do |line|
85
118
  if line =~ /partial!/
86
- parse_partial(line)
119
+ parse_partial line
87
120
  else
88
121
  line
89
122
  end
data/lib/gon/rabl.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'action_view'
2
2
  require 'rabl'
3
3
 
4
- module Gon
4
+ class Gon
5
5
  module Rabl
6
6
  class << self
7
7
 
data/lib/gon/request.rb CHANGED
@@ -1,4 +1,4 @@
1
- module Gon
1
+ class Gon
2
2
  module Request
3
3
  class << self
4
4
 
data/lib/gon/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Gon
2
- VERSION = '3.0.5'
1
+ class Gon
2
+ VERSION = '4.0.0'
3
3
  end
data/lib/gon/watch.rb ADDED
@@ -0,0 +1,117 @@
1
+ class Gon
2
+ class Watch < Gon
3
+ class << self
4
+
5
+ JS_FUNCTION = \
6
+ "gon._timers = {};
7
+
8
+ gon.watch = function(name, possibleOptions, possibleCallback) {
9
+ var callback, key, options, performAjax, timer, value, _base, _ref, _ref1;
10
+ if (typeof $ === 'undefined' || $ === null) {
11
+ return;
12
+ }
13
+ if (typeof possibleOptions === 'object') {
14
+ options = {};
15
+ _ref = gon.watchedVariables[name];
16
+ for (key in _ref) {
17
+ value = _ref[key];
18
+ options[key] = value;
19
+ }
20
+ for (key in possibleOptions) {
21
+ value = possibleOptions[key];
22
+ options[key] = value;
23
+ }
24
+ callback = possibleCallback;
25
+ } else {
26
+ options = gon.watchedVariables[name];
27
+ callback = possibleOptions;
28
+ }
29
+ performAjax = function() {
30
+ var xhr;
31
+ xhr = $.ajax({
32
+ type: options.type || 'GET',
33
+ url: options.url,
34
+ data: {
35
+ _method: options.method,
36
+ gon_return_variable: true,
37
+ gon_watched_variable: name
38
+ }
39
+ });
40
+ return xhr.done(callback);
41
+ };
42
+ if (options.interval) {
43
+ timer = setInterval(performAjax, options.interval);
44
+ if ((_ref1 = (_base = gon._timers)[name]) == null) {
45
+ _base[name] = [];
46
+ }
47
+ return gon._timers[name].push({
48
+ timer: timer,
49
+ fn: callback
50
+ });
51
+ } else {
52
+ return performAjax;
53
+ }
54
+ };
55
+
56
+ gon.unwatch = function(name, fn) {
57
+ var index, timer, _i, _len, _ref;
58
+ _ref = gon._timers[name];
59
+ for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
60
+ timer = _ref[index];
61
+ if (timer.fn === fn) {
62
+ clearInterval(timer.timer);
63
+ gon._timers[name].splice(index, 1);
64
+ return;
65
+ }
66
+ }
67
+ };"
68
+
69
+ def render
70
+ JS_FUNCTION + "window.gon.watchedVariables=#{all_variables.to_json};"
71
+ end
72
+
73
+ def all_variables
74
+ @watch_variables || {}
75
+ end
76
+
77
+ def clear
78
+ @watch_variables = {}
79
+ end
80
+
81
+ private
82
+
83
+ def set_variable(name, value)
84
+ if return_variable?(name)
85
+ return_variable value
86
+ else
87
+ variable = {}
88
+ @watch_variables ||= {}
89
+ env = Gon::Request.env
90
+ variable['url'] = env['ORIGINAL_FULLPATH']
91
+ variable['method'] = env['REQUEST_METHOD']
92
+ variable['name'] = name
93
+
94
+ @watch_variables[name] = variable
95
+ super
96
+ end
97
+ end
98
+
99
+ def return_variable?(variable)
100
+ controller = Gon::Base.get_controller
101
+ params = controller.params
102
+ variable = variable.to_s.gsub('=', '')
103
+
104
+ controller.request.xhr? &&
105
+ params[:gon_return_variable] &&
106
+ params[:gon_watched_variable] == variable
107
+ end
108
+
109
+ def return_variable(value)
110
+ controller = Gon::Base.get_controller
111
+
112
+ controller.render :text => value.to_json
113
+ end
114
+
115
+ end
116
+ end
117
+ end
@@ -42,7 +42,7 @@ describe Gon do
42
42
  it 'should raise error if you use gon.jbuilder without requiring jbuilder gem' do
43
43
  Gon.send(:remove_const, :Jbuilder)
44
44
 
45
- expect { Gon.jbuilder 'some_path' }.to raise_error(NameError)
45
+ expect { Gon.jbuilder 'some_path' }.to raise_error
46
46
  load 'jbuilder.rb'
47
47
  load 'gon/jbuilder.rb'
48
48
  end
@@ -0,0 +1,62 @@
1
+ require 'gon'
2
+
3
+ describe Gon::Watch do
4
+
5
+ let(:controller) { ActionController::Base.new }
6
+ let(:request) { ActionDispatch::Request.new({}) }
7
+
8
+ before :each do
9
+ controller.request = request
10
+ controller.params = {}
11
+ env = {}
12
+ env['ORIGINAL_FULLPATH'] = '/foo'
13
+ env['REQUEST_METHOD'] = 'GET'
14
+
15
+ Gon::Watch.clear
16
+ Gon::Request.instance_variable_set(:@request_env, env)
17
+ Gon::Request.env['action_controller.instance'] = controller
18
+ Gon.clear
19
+ end
20
+
21
+ it 'should add variables to Gon#all_variables hash' do
22
+ Gon.a = 1
23
+ Gon.watch.b = 2
24
+ Gon.all_variables.should == { 'a' => 1, 'b' => 2 }
25
+ end
26
+
27
+ describe '#all_variables' do
28
+
29
+ it 'should generate array with current request url, method type and variable names' do
30
+ Gon.watch.a = 1
31
+ Gon.watch.all_variables.should == { 'a' => { 'url' => '/foo', 'method' => 'GET', 'name' => 'a' } }
32
+ end
33
+
34
+ end
35
+
36
+ describe '#render' do
37
+
38
+ it 'should render function with variables in gon namespace' do
39
+ Gon.watch.a = 1
40
+ Gon.watch.render.should =~ /gon\.watch\s=/
41
+ Gon.watch.render.should =~ /gon\.watchedVariables/
42
+ end
43
+
44
+ end
45
+
46
+ it 'should return value of variable if called right request' do
47
+ env = Gon::Request.instance_variable_get :@request_env
48
+ env["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest"
49
+ request = ActionDispatch::Request.new env
50
+ controller.request = request
51
+ params = {}
52
+ params[:gon_return_variable] = true
53
+ params[:gon_watched_variable] = 'a'
54
+ controller.params = params
55
+ Gon::Request.env['action_controller.instance'] = controller
56
+
57
+ controller.should_receive('render').with(:text => '1')
58
+
59
+ Gon.watch.a = 1
60
+ end
61
+
62
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gon
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.5
4
+ version: 4.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-22 00:00:00.000000000 Z
12
+ date: 2012-07-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -120,9 +120,11 @@ files:
120
120
  - CHANGELOG.md
121
121
  - Gemfile
122
122
  - README.md
123
+ - README_old.md
123
124
  - Rakefile
124
125
  - doc/logo.png
125
126
  - doc/logo_small.png
127
+ - doc/top_sample.png
126
128
  - gon.gemspec
127
129
  - lib/gon.rb
128
130
  - lib/gon/base.rb
@@ -133,11 +135,13 @@ files:
133
135
  - lib/gon/rabl.rb
134
136
  - lib/gon/request.rb
135
137
  - lib/gon/version.rb
138
+ - lib/gon/watch.rb
136
139
  - spec/gon/basic_spec.rb
137
140
  - spec/gon/global_spec.rb
138
141
  - spec/gon/jbuilder_spec.rb
139
142
  - spec/gon/rabl_spec.rb
140
143
  - spec/gon/templates_spec.rb
144
+ - spec/gon/watch_spec.rb
141
145
  - spec/test_data/_sample_partial.json.jbuilder
142
146
  - spec/test_data/sample.json.jbuilder
143
147
  - spec/test_data/sample.rabl
@@ -174,6 +178,7 @@ test_files:
174
178
  - spec/gon/jbuilder_spec.rb
175
179
  - spec/gon/rabl_spec.rb
176
180
  - spec/gon/templates_spec.rb
181
+ - spec/gon/watch_spec.rb
177
182
  - spec/test_data/_sample_partial.json.jbuilder
178
183
  - spec/test_data/sample.json.jbuilder
179
184
  - spec/test_data/sample.rabl