gon 2.3.0 → 3.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 +11 -0
- data/README.md +29 -5
- data/lib/gon.rb +46 -73
- data/lib/gon/base.rb +58 -0
- data/lib/gon/global.rb +68 -0
- data/lib/gon/helpers.rb +23 -19
- data/lib/gon/jbuilder.rb +48 -8
- data/lib/gon/rabl.rb +49 -0
- data/lib/gon/request.rb +32 -0
- data/lib/gon/version.rb +1 -1
- data/spec/gon/basic_spec.rb +79 -0
- data/spec/gon/global_spec.rb +120 -0
- data/spec/gon/jbuilder_spec.rb +52 -0
- data/spec/gon/rabl_spec.rb +86 -0
- data/spec/gon/templates_spec.rb +52 -0
- data/spec/test_data/sample_with_helpers.rabl +3 -0
- metadata +86 -109
- data/spec/gon/gon_spec.rb +0 -215
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
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
|
-
|
10
|
+
With [Jbuilder](https://github.com/rails/jbuilder) and [Rabl](https://github.com/nesquena/rabl) support!
|
11
11
|
|
12
12
|
For Sinatra available [gon-sinatra](https://github.com/gazay/gon-sinatra).
|
13
13
|
|
@@ -129,7 +129,7 @@ alert(customNamespace.yourHash)
|
|
129
129
|
|
130
130
|
## Usage with Rabl
|
131
131
|
|
132
|
-
|
132
|
+
You can write your variables assign logic to templates with [Rabl](https://github.com/nesquena/rabl).
|
133
133
|
The way of writing Rabl templates is very clearly described in their repo.
|
134
134
|
|
135
135
|
Add Rabl to your Gemfile before requiring gon - because gon checks Rabl constant
|
@@ -265,7 +265,7 @@ Use gon with [Jbuilder](https://github.com/rails/jbuilder) as with [Rabl](https:
|
|
265
265
|
# some controller logic
|
266
266
|
@posts = Post.all
|
267
267
|
|
268
|
-
gon.jbuilder
|
268
|
+
gon.jbuilder
|
269
269
|
# some controller logic
|
270
270
|
end
|
271
271
|
```
|
@@ -297,18 +297,42 @@ alert(gon.comments[0])
|
|
297
297
|
P.s. If you didn't put include_gon tag in your html head area - it
|
298
298
|
wouldn't work. You can read about this in common usage above.
|
299
299
|
|
300
|
+
## gon.global
|
301
|
+
|
302
|
+
Now you can use gon for sending your data to js from anywhere!
|
303
|
+
|
304
|
+
It works just as simple `gon` but you need to write `Gon.global` instead of `gon` in your ruby code,
|
305
|
+
`gon.global` in javascript and it will not clear self after each request. All other things the same.
|
306
|
+
|
307
|
+
For example I want to tell anybody my application session secret token :) Now with Gon.global it's easy!
|
308
|
+
|
309
|
+
`config/initializers/secret_token.rb`
|
310
|
+
|
311
|
+
```ruby
|
312
|
+
GonTest::Application.config.secret_token = 'You can't see my token'
|
313
|
+
Gon.global.session = 'You can't see it I said'
|
314
|
+
```
|
315
|
+
|
316
|
+
`in some js which can reach window.gon variable`
|
317
|
+
|
318
|
+
```javascript
|
319
|
+
alert(gon.global.session)
|
320
|
+
```
|
321
|
+
|
322
|
+
Thats it!
|
323
|
+
|
300
324
|
## Installation
|
301
325
|
|
302
326
|
Puts this line into `Gemfile` then run `$ bundle`:
|
303
327
|
|
304
328
|
``` ruby
|
305
|
-
gem 'gon', '
|
329
|
+
gem 'gon', '3.0.0'
|
306
330
|
```
|
307
331
|
|
308
332
|
Or if you are old-school Rails 2 developer put this into `config/environment.rb` and run `$ rake gems:install`:
|
309
333
|
|
310
334
|
``` ruby
|
311
|
-
config.gem 'gon', :version => '
|
335
|
+
config.gem 'gon', :version => '3.0.0'
|
312
336
|
```
|
313
337
|
|
314
338
|
Or manually install gon gem: `$ gem install gon`
|
data/lib/gon.rb
CHANGED
@@ -3,6 +3,9 @@ if defined?(Jbuilder)
|
|
3
3
|
end
|
4
4
|
require 'action_view'
|
5
5
|
require 'action_controller'
|
6
|
+
require 'gon/base'
|
7
|
+
require 'gon/global'
|
8
|
+
require 'gon/request'
|
6
9
|
require 'gon/helpers'
|
7
10
|
require 'gon/escaper'
|
8
11
|
if defined?(Rabl)
|
@@ -15,107 +18,77 @@ end
|
|
15
18
|
module Gon
|
16
19
|
class << self
|
17
20
|
|
18
|
-
def
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
def clear
|
23
|
-
@request_env['gon'] = {}
|
24
|
-
end
|
25
|
-
|
26
|
-
def request_env=(environment)
|
27
|
-
@request_env = environment
|
28
|
-
@request_env['gon'] ||= {}
|
29
|
-
end
|
30
|
-
|
31
|
-
def request_env
|
32
|
-
if defined?(@request_env)
|
33
|
-
return @request_env
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def request
|
38
|
-
@request_id if defined? @request_id
|
39
|
-
end
|
40
|
-
|
41
|
-
def request=(request_id)
|
42
|
-
@request_id = request_id
|
21
|
+
def global
|
22
|
+
Gon::Global
|
43
23
|
end
|
44
24
|
|
45
|
-
def method_missing(
|
46
|
-
if (
|
47
|
-
if
|
25
|
+
def method_missing(method, *args, &block)
|
26
|
+
if ( method.to_s =~ /=$/ )
|
27
|
+
if public_method_name? method
|
48
28
|
raise "You can't use Gon public methods for storing data"
|
49
29
|
end
|
50
|
-
|
30
|
+
|
31
|
+
set_variable(method.to_s.delete('='), args[0])
|
51
32
|
else
|
52
|
-
get_variable(
|
33
|
+
get_variable(method.to_s)
|
53
34
|
end
|
54
35
|
end
|
55
36
|
|
56
|
-
def
|
57
|
-
|
37
|
+
def all_variables
|
38
|
+
Request.gon
|
58
39
|
end
|
59
40
|
|
60
|
-
def
|
61
|
-
|
41
|
+
def clear
|
42
|
+
Request.clear
|
62
43
|
end
|
63
44
|
|
64
|
-
|
65
|
-
|
66
|
-
if options.first.is_a? String
|
67
|
-
warn "[DEPRECATION] view_path argument is now optional. If you need to specify it please use #{builder}(:template => 'path')"
|
68
|
-
options = options.extract_options!.merge(:template => options[0])
|
69
|
-
else
|
70
|
-
options = (options && options.first.is_a?(Hash)) ? options.first : { }
|
71
|
-
end
|
45
|
+
def rabl(*args)
|
46
|
+
data, options = Gon::Rabl.handler(args)
|
72
47
|
|
73
|
-
|
48
|
+
store_builder_data 'rabl', data, options
|
49
|
+
end
|
74
50
|
|
75
|
-
|
51
|
+
def jbuilder(*args)
|
52
|
+
data, options = Gon::Jbuilder.handler(args)
|
76
53
|
|
77
|
-
|
78
|
-
set_variable(options[:as].to_s, data)
|
79
|
-
elsif data.is_a? Hash
|
80
|
-
data.each do |key, value|
|
81
|
-
set_variable(key, value)
|
82
|
-
end
|
83
|
-
else
|
84
|
-
set_variable(builder_name, data)
|
85
|
-
end
|
86
|
-
end
|
54
|
+
store_builder_data 'jbuilder', data, options
|
87
55
|
end
|
88
|
-
alias_method :orig_jbuilder, :jbuilder
|
89
56
|
|
90
|
-
def
|
91
|
-
|
57
|
+
def inspect
|
58
|
+
'Gon'
|
92
59
|
end
|
93
60
|
|
94
61
|
private
|
95
62
|
|
96
|
-
def
|
97
|
-
|
98
|
-
"Gon::#{builder_name.classify}".constantize
|
99
|
-
rescue
|
100
|
-
raise NoMethodError.new("You should define #{builder_name.classify} in your Gemfile")
|
101
|
-
end
|
63
|
+
def get_variable(name)
|
64
|
+
Request.gon[name]
|
102
65
|
end
|
103
66
|
|
104
|
-
def
|
105
|
-
|
106
|
-
@request_env['action_controller.instance'] ||
|
107
|
-
@request_env['action_controller.rescue.response'].
|
108
|
-
instance_variable_get('@template').
|
109
|
-
instance_variable_get('@controller')
|
67
|
+
def set_variable(name, value)
|
68
|
+
Request.gon[name] = value
|
110
69
|
end
|
111
70
|
|
112
|
-
def
|
113
|
-
if options[:
|
114
|
-
|
71
|
+
def store_builder_data(builder, data, options)
|
72
|
+
if options[:as]
|
73
|
+
set_variable(options[:as].to_s, data)
|
74
|
+
elsif data.is_a? Hash
|
75
|
+
data.each do |key, value|
|
76
|
+
set_variable(key, value)
|
77
|
+
end
|
115
78
|
else
|
116
|
-
|
79
|
+
set_variable(builder, data)
|
117
80
|
end
|
118
81
|
end
|
119
82
|
|
83
|
+
def public_method_name?(method)
|
84
|
+
public_methods.include?(
|
85
|
+
if RUBY_VERSION > '1.9'
|
86
|
+
method.to_s[0..-2].to_sym
|
87
|
+
else
|
88
|
+
method.to_s[0..-2]
|
89
|
+
end
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
120
93
|
end
|
121
94
|
end
|
data/lib/gon/base.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Gon
|
2
|
+
module Base
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def render_data(options)
|
6
|
+
if Gon.global.all_variables.present?
|
7
|
+
Gon::Request.gon['global'] = Gon.global.all_variables
|
8
|
+
end
|
9
|
+
data = Gon.all_variables
|
10
|
+
namespace = options[:namespace] || 'gon'
|
11
|
+
start = '<script>window.' + namespace + ' = {};'
|
12
|
+
script = ''
|
13
|
+
|
14
|
+
if options[:camel_case]
|
15
|
+
data.each do |key, val|
|
16
|
+
script << "#{namespace}.#{key.to_s.camelize(:lower)}=#{val.to_json};"
|
17
|
+
end
|
18
|
+
else
|
19
|
+
data.each do |key, val|
|
20
|
+
script << "#{namespace}.#{key.to_s}=#{val.to_json};"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
script = start + Gon::Escaper.escape(script) + '</script>'
|
25
|
+
script.html_safe
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_controller(options)
|
29
|
+
options[:controller] ||
|
30
|
+
Gon::Request.env['action_controller.instance'] ||
|
31
|
+
Gon::Request.env['action_controller.rescue.response'].
|
32
|
+
instance_variable_get('@template').
|
33
|
+
instance_variable_get('@controller')
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_template_path(options, extension)
|
37
|
+
if options[:template]
|
38
|
+
if right_extension?(extension, options[:template])
|
39
|
+
options[:template]
|
40
|
+
else
|
41
|
+
[options[:template], extension].join('.')
|
42
|
+
end
|
43
|
+
else
|
44
|
+
controller = get_controller(options).controller_path
|
45
|
+
action = get_controller(options).action_name
|
46
|
+
"app/views/#{controller}/#{action}.json.#{extension}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def right_extension?(extension, template_path)
|
53
|
+
File.extname(template_path) == ".#{extension}"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/gon/global.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module Gon
|
2
|
+
module Global
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def all_variables
|
6
|
+
@global_vars || {}
|
7
|
+
end
|
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
|
15
|
+
|
16
|
+
@global_vars[method.to_s.delete('=')] = args[0]
|
17
|
+
else
|
18
|
+
@global_vars[method.to_s]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def rabl(*args)
|
23
|
+
data, options = Gon::Rabl.handler(args, true)
|
24
|
+
|
25
|
+
store_builder_data 'rabl', data, options
|
26
|
+
end
|
27
|
+
|
28
|
+
def jbuilder(*args)
|
29
|
+
data, options = Gon::Jbuilder.handler(args, true)
|
30
|
+
|
31
|
+
store_builder_data 'jbuilder', data, options
|
32
|
+
end
|
33
|
+
|
34
|
+
def clear
|
35
|
+
@global_vars = {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect
|
39
|
+
'Gon'
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
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
|
54
|
+
end
|
55
|
+
|
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
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/gon/helpers.rb
CHANGED
@@ -8,27 +8,24 @@ module Gon
|
|
8
8
|
module InstanceMethods
|
9
9
|
|
10
10
|
def include_gon(options = {})
|
11
|
-
if
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
if options[:camel_case]
|
17
|
-
data.each do |key, val|
|
18
|
-
script << namespace + '.' + key.to_s.camelize(:lower) + '=' + val.to_json + ';'
|
19
|
-
end
|
20
|
-
else
|
21
|
-
data.each do |key, val|
|
22
|
-
script << namespace + '.' + key.to_s + '=' + val.to_json + ';'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
script = start + Gon::Escaper.escape(script) + '</script>'
|
26
|
-
script.html_safe
|
11
|
+
if variables_for_request_present?
|
12
|
+
Gon::Base.render_data(options)
|
13
|
+
elsif Gon.global.all_variables.present?
|
14
|
+
Gon.clear
|
15
|
+
Gon::Base.render_data(options)
|
27
16
|
else
|
28
17
|
""
|
29
18
|
end
|
30
19
|
end
|
31
20
|
|
21
|
+
private
|
22
|
+
|
23
|
+
def variables_for_request_present?
|
24
|
+
Gon::Request.env &&
|
25
|
+
Gon::Request.id == request.object_id &&
|
26
|
+
Gon.all_variables.present?
|
27
|
+
end
|
28
|
+
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
@@ -41,13 +38,20 @@ module Gon
|
|
41
38
|
module InstanceMethods
|
42
39
|
|
43
40
|
def gon
|
44
|
-
if
|
45
|
-
Gon.
|
46
|
-
Gon.
|
41
|
+
if wrong_gon_request?
|
42
|
+
Gon::Request.id = request.object_id
|
43
|
+
Gon::Request.env = request.env
|
47
44
|
end
|
48
45
|
Gon
|
49
46
|
end
|
50
47
|
|
48
|
+
private
|
49
|
+
|
50
|
+
def wrong_gon_request?
|
51
|
+
Gon::Request.env.blank? ||
|
52
|
+
Gon::Request.id != request.object_id
|
53
|
+
end
|
54
|
+
|
51
55
|
end
|
52
56
|
|
53
57
|
end
|
data/lib/gon/jbuilder.rb
CHANGED
@@ -2,21 +2,61 @@ module Gon
|
|
2
2
|
module Jbuilder
|
3
3
|
class << self
|
4
4
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
5
|
+
def handler(args, global = false)
|
6
|
+
options = parse_options_from args
|
7
|
+
if global && !options[:template]
|
8
|
+
raise 'You should provide :template when use rabl with global variables'
|
9
|
+
end
|
10
|
+
|
11
|
+
data = parse_jbuilder \
|
12
|
+
Gon::Base.get_template_path(options,'jbuilder'),
|
13
|
+
Gon::Base.get_controller(options)
|
14
|
+
|
15
|
+
[data, options]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def parse_options_from(args)
|
21
|
+
if old_api? args
|
22
|
+
text = "[DEPRECATION] view_path argument is now optional. "
|
23
|
+
text << "If you need to specify it, "
|
24
|
+
text << "please use gon.rabl(:template => 'path')"
|
25
|
+
warn text
|
26
|
+
|
27
|
+
args.extract_options!.merge(:template => args[0])
|
28
|
+
elsif new_api? args
|
29
|
+
args.first
|
30
|
+
else
|
31
|
+
{}
|
8
32
|
end
|
9
|
-
|
33
|
+
end
|
34
|
+
|
35
|
+
def old_api?(args)
|
36
|
+
args.first.is_a? String
|
37
|
+
end
|
38
|
+
|
39
|
+
def new_api?(args)
|
40
|
+
args.first.is_a? Hash
|
10
41
|
end
|
11
42
|
|
12
43
|
def parse_jbuilder(jbuilder_path, controller)
|
13
44
|
controller.instance_variables.each do |name|
|
14
|
-
self.instance_variable_set
|
45
|
+
self.instance_variable_set \
|
46
|
+
name,
|
47
|
+
controller.instance_variable_get(name)
|
15
48
|
end
|
16
|
-
lines = find_partials
|
49
|
+
lines = find_partials File.readlines(jbuilder_path)
|
17
50
|
source = lines.join('')
|
18
51
|
|
19
|
-
output = parse_source
|
52
|
+
output = parse_source source, controller
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_source(source, controller)
|
56
|
+
output = ::JbuilderTemplate.encode(controller) do |json|
|
57
|
+
eval source
|
58
|
+
end
|
59
|
+
JSON.parse(output)
|
20
60
|
end
|
21
61
|
|
22
62
|
def parse_partial(partial_line)
|
@@ -29,7 +69,7 @@ module Gon
|
|
29
69
|
eval "def #{name}; self.instance_variable_get('@' + '#{name.to_s}'); end"
|
30
70
|
end
|
31
71
|
end
|
32
|
-
find_partials
|
72
|
+
find_partials File.readlines(path)
|
33
73
|
end
|
34
74
|
|
35
75
|
def find_partials(lines = [])
|