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.

@@ -0,0 +1,11 @@
1
+ # CHANGELOG
2
+
3
+ ## 3.0.0
4
+
5
+ * Almost all code refactored
6
+ * Added Gon.global for using gon everywhere
7
+ * Included ActionView::Helpers into Rabl::Engine
8
+
9
+ ## 2.3.0
10
+
11
+ * Don't really remember what was before this version
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
- Now with [Jbuilder](https://github.com/rails/jbuilder) and [Rabl](https://github.com/nesquena/rabl) support!
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
- Now you can write your variables assign logic to templates with [Rabl](https://github.com/nesquena/rabl).
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 'app/views/posts/index.json.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', '2.2.2'
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 => '2.2.2'
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 all_variables
19
- @request_env['gon']
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(m, *args, &block)
46
- if ( m.to_s =~ /=$/ )
47
- if public_methods.include?(RUBY_VERSION > '1.9' ? m.to_s[0..-2].to_sym : m.to_s[0..-2])
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
- set_variable(m.to_s.delete('='), args[0])
30
+
31
+ set_variable(method.to_s.delete('='), args[0])
51
32
  else
52
- get_variable(m.to_s)
33
+ get_variable(method.to_s)
53
34
  end
54
35
  end
55
36
 
56
- def get_variable(name)
57
- @request_env['gon'][name]
37
+ def all_variables
38
+ Request.gon
58
39
  end
59
40
 
60
- def set_variable(name, value)
61
- @request_env['gon'][name] = value
41
+ def clear
42
+ Request.clear
62
43
  end
63
44
 
64
- %w(rabl jbuilder).each do |builder_name|
65
- define_method builder_name do |*options|
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
- builder_module = get_builder(builder_name)
48
+ store_builder_data 'rabl', data, options
49
+ end
74
50
 
75
- data = builder_module.send("parse_#{builder_name}", get_template_path(options, builder_name), get_controller(options))
51
+ def jbuilder(*args)
52
+ data, options = Gon::Jbuilder.handler(args)
76
53
 
77
- if options[:as]
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 jbuilder(*options)
91
- orig_jbuilder(*options)
57
+ def inspect
58
+ 'Gon'
92
59
  end
93
60
 
94
61
  private
95
62
 
96
- def get_builder(builder_name)
97
- begin
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 get_controller(options)
105
- options[:controller] ||
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 get_template_path(options, extension)
113
- if options[:template]
114
- File.extname(options[:template]) == ".#{extension}" ? options[:template] : "#{options[:template]}.#{extension}"
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
- "app/views/#{get_controller(options).controller_path}/#{get_controller(options).action_name}.json.#{extension}"
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
@@ -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
@@ -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
@@ -8,27 +8,24 @@ module Gon
8
8
  module InstanceMethods
9
9
 
10
10
  def include_gon(options = {})
11
- if Gon.request_env && Gon.all_variables.present? && Gon.request == request.object_id
12
- data = Gon.all_variables
13
- namespace = options[:namespace] || 'gon'
14
- start = '<script>window.' + namespace + ' = {};'
15
- script = ''
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 !Gon.request_env || Gon.request != request.object_id
45
- Gon.request = request.object_id
46
- Gon.request_env = request.env
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
@@ -2,21 +2,61 @@ module Gon
2
2
  module Jbuilder
3
3
  class << self
4
4
 
5
- def parse_source(source, controller)
6
- output = ::JbuilderTemplate.encode(controller) do |json|
7
- eval source
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
- JSON.parse(output)
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(name, controller.instance_variable_get(name))
45
+ self.instance_variable_set \
46
+ name,
47
+ controller.instance_variable_get(name)
15
48
  end
16
- lines = find_partials(File.readlines(jbuilder_path))
49
+ lines = find_partials File.readlines(jbuilder_path)
17
50
  source = lines.join('')
18
51
 
19
- output = parse_source(source, controller)
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(File.readlines(path))
72
+ find_partials File.readlines(path)
33
73
  end
34
74
 
35
75
  def find_partials(lines = [])