js-routes-zigexn 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ <%# encoding: UTF-8 %>
2
+ <%= JsRoutes.assert_usable_configuration! && JsRoutes.generate %>
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 3.2.22.5"
6
+ gem "tzinfo"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 4.0.13"
6
+ gem "sprockets", "< 3"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 4.0.13"
6
+ gem "sprockets", "~> 3.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 4.1.16"
6
+ gem "sprockets", "< 3"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 4.1.16"
6
+ gem "sprockets", "~> 3.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 4.2.8"
6
+ gem "sprockets", "< 3"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 4.2.8"
6
+ gem "sprockets", "~> 3.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 5.0.2"
6
+ gem "sprockets", "< 3"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "railties", "~> 5.0.2"
6
+ gem "sprockets", "~> 3.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'js_routes/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{js-routes-zigexn}
8
+ s.version = JsRoutes::VERSION
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["VietTH"]
12
+ s.description = %q{Generates javascript file that defines all Rails named routes as javascript helpers}
13
+ s.email = %q{vietth@zigexn.vn}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE.txt"
16
+ ]
17
+ s.files = `git ls-files`.split("\n")
18
+ s.homepage = %q{https://github.com/vietthventura/js-routes}
19
+ s.licenses = ["MIT"]
20
+ s.require_paths = ["lib"]
21
+ s.summary = %q{Brings Rails named routes to javascript}
22
+
23
+ s.add_runtime_dependency(%q<railties>, [">= 3.2"])
24
+ s.add_runtime_dependency(%q<sprockets-rails>)
25
+ s.add_development_dependency(%q<rspec>, [">= 3.0.0"])
26
+ s.add_development_dependency(%q<bundler>, [">= 1.1.0"])
27
+ s.add_development_dependency(%q<coffee-script>, [">= 0"])
28
+ s.add_development_dependency(%q<appraisal>, [">= 0.5.2"])
29
+ if defined?(JRUBY_VERSION)
30
+ s.add_development_dependency(%q<therubyrhino>, [">= 2.0.4"])
31
+ else
32
+ s.add_development_dependency(%q<byebug>)
33
+ s.add_development_dependency(%q<pry-byebug>)
34
+ s.add_development_dependency(%q<therubyracer>, [">= 0.12.3"])
35
+ end
36
+ end
data/lib/js-routes.rb ADDED
@@ -0,0 +1 @@
1
+ require 'js_routes'
@@ -0,0 +1,73 @@
1
+ class JsRoutesSprocketsExtension
2
+ def initialize(filename, &block)
3
+ @filename = filename
4
+ @source = block.call
5
+ end
6
+
7
+ def render(context, empty_hash_wtf)
8
+ self.class.run(@filename, @source, context)
9
+ end
10
+
11
+ def self.run(filename, source, context)
12
+ if context.logical_path == 'js-routes'
13
+ routes = Rails.root.join('config', 'routes.rb').to_s
14
+ context.depend_on(routes)
15
+ end
16
+ source
17
+ end
18
+
19
+ def self.call(input)
20
+ filename = input[:filename]
21
+ source = input[:data]
22
+ context = input[:environment].context_class.new(input)
23
+
24
+ result = run(filename, source, context)
25
+ context.metadata.merge(data: result)
26
+ end
27
+ end
28
+
29
+
30
+ class Engine < ::Rails::Engine
31
+ require 'sprockets/version'
32
+ v2 = Gem::Dependency.new('', ' ~> 2')
33
+ vgte3 = Gem::Dependency.new('', ' >= 3')
34
+ sprockets_version = Gem::Version.new(::Sprockets::VERSION).release
35
+ initializer_args = case sprockets_version
36
+ when -> (v) { v2.match?('', v) }
37
+ { after: "sprockets.environment" }
38
+ when -> (v) { vgte3.match?('', v) }
39
+ { after: :engines_blank_point, before: :finisher_hook }
40
+ else
41
+ raise StandardError, "Sprockets version #{sprockets_version} is not supported"
42
+ end
43
+
44
+ is_running_rails = defined?(Rails) && Rails.respond_to?(:version)
45
+ is_running_rails_32 = is_running_rails && Rails.version.match(/3\.2/)
46
+
47
+ initializer 'js-routes.dependent_on_routes', initializer_args do
48
+ case sprockets_version
49
+ when -> (v) { v2.match?('', v) },
50
+ -> (v) { vgte3.match?('', v) }
51
+
52
+ # It seems rails 3.2 is not working if
53
+ # `Rails.application.config.assets.configure` is used for
54
+ # registering preprocessor
55
+ if is_running_rails_32
56
+ Rails.application.assets.register_preprocessor(
57
+ "application/javascript",
58
+ JsRoutesSprocketsExtension,
59
+ )
60
+ else
61
+ # Other rails version, assumed newer
62
+ Rails.application.config.assets.configure do |config|
63
+ config.register_preprocessor(
64
+ "application/javascript",
65
+ JsRoutesSprocketsExtension,
66
+ )
67
+ end
68
+ end
69
+ else
70
+ raise StandardError, "Sprockets version #{sprockets_version} is not supported"
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ class JsRoutes
2
+ VERSION = "1.3.3"
3
+ end
data/lib/js_routes.rb ADDED
@@ -0,0 +1,293 @@
1
+ require 'uri'
2
+ require 'js_routes/engine' if defined?(Rails)
3
+ require 'js_routes/version'
4
+
5
+ class JsRoutes
6
+
7
+ #
8
+ # OPTIONS
9
+ #
10
+
11
+ DEFAULT_PATH = File.join('app','assets','javascripts','routes.js')
12
+
13
+ DEFAULTS = {
14
+ namespace: "Routes",
15
+ exclude: [],
16
+ include: //,
17
+ file: DEFAULT_PATH,
18
+ prefix: -> { Rails.application.config.relative_url_root || "" },
19
+ url_links: false,
20
+ camel_case: false,
21
+ default_url_options: {},
22
+ compact: false,
23
+ serializer: nil,
24
+ special_options_key: "_options",
25
+ application: -> { Rails.application }
26
+ }
27
+
28
+ NODE_TYPES = {
29
+ GROUP: 1,
30
+ CAT: 2,
31
+ SYMBOL: 3,
32
+ OR: 4,
33
+ STAR: 5,
34
+ LITERAL: 6,
35
+ SLASH: 7,
36
+ DOT: 8
37
+ }
38
+
39
+ LAST_OPTIONS_KEY = "options".freeze
40
+ FILTERED_DEFAULT_PARTS = [:controller, :action, :subdomain]
41
+ URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
42
+
43
+ class Configuration < Struct.new(*DEFAULTS.keys)
44
+ def initialize(attributes = nil)
45
+ assign(DEFAULTS)
46
+ return unless attributes
47
+ assign(attributes)
48
+ end
49
+
50
+ def assign(attributes)
51
+ attributes.each do |attribute, value|
52
+ value = value.call if value.is_a?(Proc)
53
+ send(:"#{attribute}=", value)
54
+ end
55
+ self
56
+ end
57
+
58
+ def [](attribute)
59
+ send(attribute)
60
+ end
61
+
62
+ def merge(attributes)
63
+ clone.assign(attributes)
64
+ end
65
+
66
+ def to_hash
67
+ Hash[*members.zip(values).flatten(1)].symbolize_keys
68
+ end
69
+ end
70
+
71
+ #
72
+ # API
73
+ #
74
+
75
+ class << self
76
+ def setup(&block)
77
+ configuration.tap(&block) if block
78
+ end
79
+
80
+ def options
81
+ ActiveSupport::Deprecation.warn('JsRoutes.options method is deprecated use JsRoutes.configuration instead')
82
+ configuration
83
+ end
84
+
85
+ def configuration
86
+ @configuration ||= Configuration.new
87
+ end
88
+
89
+ def generate(opts = {})
90
+ new(opts).generate
91
+ end
92
+
93
+ def generate!(file_name=nil, opts = {})
94
+ if file_name.is_a?(Hash)
95
+ opts = file_name
96
+ file_name = opts[:file]
97
+ end
98
+ new(opts).generate!(file_name)
99
+ end
100
+
101
+ # Under rails 3.1.1 and higher, perform a check to ensure that the
102
+ # full environment will be available during asset compilation.
103
+ # This is required to ensure routes are loaded.
104
+ def assert_usable_configuration!
105
+ if 3 == Rails::VERSION::MAJOR && !Rails.application.config.assets.initialize_on_precompile
106
+ raise("Cannot precompile js-routes unless environment is initialized. Please set config.assets.initialize_on_precompile to true.")
107
+ end
108
+ true
109
+ end
110
+
111
+ def json(string)
112
+ ActiveSupport::JSON.encode(string)
113
+ end
114
+ end
115
+
116
+ #
117
+ # Implementation
118
+ #
119
+
120
+ def initialize(options = {})
121
+ @configuration = self.class.configuration.merge(options)
122
+ end
123
+
124
+ def generate
125
+ # Ensure routes are loaded. If they're not, load them.
126
+ if named_routes.to_a.empty? && application.respond_to?(:reload_routes!)
127
+ application.reload_routes!
128
+ end
129
+
130
+ {
131
+ "GEM_VERSION" => JsRoutes::VERSION,
132
+ "ROUTES" => js_routes,
133
+ "DEPRECATED_BEHAVIOR" => Rails.version < "4",
134
+ "NODE_TYPES" => json(NODE_TYPES),
135
+
136
+ "APP_CLASS" => application.class.to_s,
137
+ "NAMESPACE" => json(@configuration.namespace),
138
+ "DEFAULT_URL_OPTIONS" => json(@configuration.default_url_options),
139
+ "PREFIX" => json(@configuration.prefix),
140
+ "SPECIAL_OPTIONS_KEY" => json(@configuration.special_options_key),
141
+ "SERIALIZER" => @configuration.serializer || json(nil),
142
+ }.inject(File.read(File.dirname(__FILE__) + "/routes.js")) do |js, (key, value)|
143
+ js.gsub!(key, value.to_s)
144
+ end
145
+ end
146
+
147
+ def generate!(file_name = nil)
148
+ # Some libraries like Devise do not yet loaded their routes so we will wait
149
+ # until initialization process finish
150
+ # https://github.com/railsware/js-routes/issues/7
151
+ Rails.configuration.after_initialize do
152
+ file_name ||= self.class.configuration['file']
153
+ File.open(Rails.root.join(file_name), 'w') do |f|
154
+ f.write generate
155
+ end
156
+ end
157
+ end
158
+
159
+ protected
160
+
161
+ def application
162
+ @configuration.application
163
+ end
164
+
165
+ def named_routes
166
+ application.routes.named_routes.to_a
167
+ end
168
+
169
+ def js_routes
170
+ js_routes = named_routes.sort_by(&:first).flat_map do |_, route|
171
+ [build_route_if_match(route)] + mounted_app_routes(route)
172
+ end.compact
173
+ "{\n" + js_routes.join(",\n") + "}\n"
174
+ end
175
+
176
+ def mounted_app_routes(route)
177
+ rails_engine_app = get_app_from_route(route)
178
+ if rails_engine_app.respond_to?(:superclass) && rails_engine_app.superclass == Rails::Engine && !route.path.anchored
179
+ rails_engine_app.routes.named_routes.map do |_, engine_route|
180
+ build_route_if_match(engine_route, route)
181
+ end
182
+ else
183
+ []
184
+ end
185
+ end
186
+
187
+ def get_app_from_route(route)
188
+ # rails engine in Rails 4.2 use additional ActionDispatch::Routing::Mapper::Constraints, which contain app
189
+ if route.app.respond_to?(:app) && route.app.respond_to?(:constraints)
190
+ route.app.app
191
+ else
192
+ route.app
193
+ end
194
+ end
195
+
196
+ def build_route_if_match(route, parent_route=nil)
197
+ if any_match?(route, parent_route, @configuration[:exclude]) || !any_match?(route, parent_route, @configuration[:include])
198
+ nil
199
+ else
200
+ build_js(route, parent_route)
201
+ end
202
+ end
203
+
204
+ def any_match?(route, parent_route, matchers)
205
+ full_route = [parent_route.try(:name), route.name].compact.join('_')
206
+
207
+ matchers = Array(matchers)
208
+ matchers.any? {|regex| full_route =~ regex}
209
+ end
210
+
211
+ def build_js(route, parent_route)
212
+ name = [parent_route.try(:name), route.name].compact
213
+ route_name = generate_route_name(name, (:path unless @configuration[:compact]))
214
+ parent_spec = parent_route.try(:path).try(:spec)
215
+ route_arguments = route_js_arguments(route, parent_spec)
216
+ url_link = generate_url_link(name, route_name, route_arguments, route)
217
+ _ = <<-JS.strip!
218
+ // #{name.join('.')} => #{parent_spec}#{route.path.spec}
219
+ // function(#{build_params(route.required_parts)})
220
+ #{route_name}: Utils.route(#{route_arguments})#{",\n" + url_link if url_link.length > 0}
221
+ JS
222
+ end
223
+
224
+ def route_js_arguments(route, parent_spec)
225
+ required_parts = route.required_parts
226
+ parts_table = route.parts.each_with_object({}) do |part, hash|
227
+ hash[part] = required_parts.include?(part)
228
+ end
229
+ default_options = route.defaults.select do |part, _|
230
+ FILTERED_DEFAULT_PARTS.exclude?(part) && URL_OPTIONS.include?(part) || parts_table[part]
231
+ end
232
+ [
233
+ # JS objects don't preserve the order of properties which is crucial,
234
+ # so array is a better choice.
235
+ parts_table.to_a,
236
+ default_options,
237
+ serialize(route.path.spec, parent_spec)
238
+ ].map do |argument|
239
+ json(argument)
240
+ end.join(", ")
241
+ end
242
+
243
+ def generate_url_link(name, route_name, route_arguments, route)
244
+ return "" unless @configuration[:url_links]
245
+ <<-JS.strip!
246
+ #{generate_route_name(name, :url)}: Utils.route(#{route_arguments}, true)
247
+ JS
248
+ end
249
+
250
+ def generate_route_name(name, suffix)
251
+ route_name = name.join('_')
252
+ route_name << "_#{ suffix }" if suffix
253
+ @configuration[:camel_case] ? route_name.camelize(:lower) : route_name
254
+ end
255
+
256
+ def json(string)
257
+ self.class.json(string)
258
+ end
259
+
260
+ def build_params(required_parts)
261
+ params = required_parts + [LAST_OPTIONS_KEY]
262
+ params.join(", ")
263
+ end
264
+
265
+ # This function serializes Journey route into JSON structure
266
+ # We do not use Hash for human readable serialization
267
+ # And preffer Array serialization because it is shorter.
268
+ # Routes.js file will be smaller.
269
+ def serialize(spec, parent_spec=nil)
270
+ return nil unless spec
271
+ return spec.tr(':', '') if spec.is_a?(String)
272
+ result = serialize_spec(spec, parent_spec)
273
+ if parent_spec && result[1].is_a?(String)
274
+ result = [
275
+ # We encode node symbols as integer
276
+ # to reduce the routes.js file size
277
+ NODE_TYPES[:CAT],
278
+ serialize_spec(parent_spec),
279
+ result
280
+ ]
281
+ end
282
+ result
283
+ end
284
+
285
+ def serialize_spec(spec, parent_spec=nil)
286
+ [
287
+ NODE_TYPES[spec.type],
288
+ serialize(spec.left, parent_spec),
289
+ spec.respond_to?(:right) && serialize(spec.right)
290
+ ]
291
+ end
292
+ end
293
+