File: base.rb

package info (click to toggle)
ruby-gon 5.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 496 kB
  • ctags: 145
  • sloc: ruby: 1,416; makefile: 5
file content (147 lines) | stat: -rw-r--r-- 4,859 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class Gon
  module Base
    ENV_CONTROLLER_KEY = 'action_controller.instance'

    class << self

      def render_data(options)
        namespace, tag, cameled, camel_depth, watch, type, cdata, global_root, namespace_check = parse_options(options)
        script = namespace_check ? "window.#{namespace}=window.#{namespace}||{};" : "window.#{namespace}={};"

        script << formatted_data(namespace, cameled, camel_depth, watch, global_root)
        script = Gon::Escaper.escape_unicode(script)
        script = Gon::Escaper.javascript_tag(script, type, cdata) if tag

        script.html_safe
      end

      def render_data_amd(options)
        namespace, tag, cameled, camel_depth, watch, type, cdata, global_root = parse_options(options)

        script = "define('#{namespace}',[],function(){" 
        script << amd_formatted_data(namespace, cameled, camel_depth, watch, global_root)
        script << 'return gon;});'

        script = Gon::Escaper.escape_unicode(script)
        script = Gon::Escaper.javascript_tag(script, type, cdata) if tag

        script.html_safe
      end

      def get_controller(options = {})
        options[:controller] ||
          (
            current_gon &&
            current_gon.env[Gon::Base::ENV_CONTROLLER_KEY] ||
            current_gon.env['action_controller.rescue.response'].
              instance_variable_get('@template').
              instance_variable_get('@controller')
          )
      end

      def get_template_path(options, extension)
        if options[:template]
          if right_extension?(extension, options[:template])
            options[:template]
          else
            [options[:template], extension].join('.')
          end
        else
          controller = get_controller(options).controller_path
          action = get_controller(options).action_name
          "app/views/#{controller}/#{action}.json.#{extension}"
        end
      end

      private

      def current_gon
        RequestStore.store[:gon]
      end

      def parse_options(options)
        namespace   = options[:namespace] || 'gon'
        need_tag    = options[:need_tag].nil? || options[:need_tag]
        cameled     = options[:camel_case]
        camel_depth = options[:camel_depth] || 1
        watch       = options[:watch] || !Gon.watch.all_variables.empty?
        tag         = need_tag
        type        = options[:type].nil? || options[:type]
        cdata       = options[:cdata].nil? || options[:cdata]
        global_root = options.has_key?(:global_root) ? options[:global_root] : 'global'
        namespace_check = options.has_key?(:namespace_check) ? options[:namespace_check] : false

        [namespace, tag, cameled, camel_depth, watch, type, cdata, global_root, namespace_check]
      end

      def formatted_data(namespace, keys_cameled, camel_depth, watch, global_root)
        script = ''

        gon_variables(global_root).each do |key, val|
          js_key = keys_cameled ? key.to_s.camelize(:lower) : key.to_s
          script << "#{namespace}.#{js_key}=#{to_json(val, camel_depth)};"
        end

        if watch and Gon::Watch.all_variables.present?
          script << Gon.watch.render
        end

        script
      end

      def amd_formatted_data(namespace, keys_cameled, camel_depth, watch, global_root)
        script = 'var gon={};'

        gon_variables(global_root).each do |key, val|
          js_key = keys_cameled ? key.to_s.camelize(:lower) : key.to_s
          script << "gon['#{js_key}']=#{to_json(val, camel_depth)};"
        end

        if watch and Gon::Watch.all_variables.present?
          script << Gon.watch.render_amd
        end

        script
      end

      def to_json(value, camel_depth)
        # starts at 2 because 1 is the root key which is converted in the formatted_data method
        Gon::JsonDumper.dump convert_hash_keys(value, 2, camel_depth)
      end

      def convert_hash_keys(value, current_depth, max_depth)
        return value if current_depth > (max_depth.is_a?(Symbol) ? 1000 : max_depth)

        case value
          when Hash
            Hash[value.map { |k, v|
              [ k.to_s.camelize(:lower), convert_hash_keys(v, current_depth + 1, max_depth) ]
            }]
          when Enumerable
            value.map { |v| convert_hash_keys(v, current_depth + 1, max_depth) }
          else
            value
        end
      end

      def gon_variables(global_root)
        data = {}

        if Gon.global.all_variables.present?
          if global_root.blank?
            data = Gon.global.all_variables
          else
            data[global_root.to_sym] = Gon.global.all_variables
          end
        end

        data.merge(Gon.all_variables)
      end

      def right_extension?(extension, template_path)
        File.extname(template_path) == ".#{extension}"
      end

    end
  end
end