rails-js 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 931d5dbd625d0ce4bd1edd2b08aa70e36f75af58
4
+ data.tar.gz: 09fb2738423fbbb26754ec6c2b7292ae150a2d5d
5
+ SHA512:
6
+ metadata.gz: 6246edb935192928bbbfc916b96ba532238cda5e0676e3a37b37b79ad26018b2b184a97b68614ebe500de7712b886386aced11b1a47a9667e6b360f7140e7797
7
+ data.tar.gz: 75ec23dccf39596a86512a3e4cc5c44881043a1bcea8ea297d2ba3eb0a1fc592ed8af51df367a37296ba5aa7fe24f455e8743fcb8dfb119b77057e97bf879809
@@ -0,0 +1 @@
1
+ *.gem
@@ -0,0 +1,4 @@
1
+ rails.js
2
+ ========
3
+
4
+ A new approach to structure your javascript in non single-page Rails apps
@@ -0,0 +1,304 @@
1
+ (function(window, document) {
2
+
3
+ /*
4
+ * All the global stuff (helpers, data, hooks) is stored
5
+ * locally in this closure so we cannot do anything wrong
6
+ */
7
+ var controllers = {},
8
+ globalHelpers = {},
9
+ namespaceHooks = {},
10
+ data = {};
11
+
12
+ /*
13
+ * Singleton that stores functions to create your apps' structure
14
+ */
15
+ Rails = window.Rails || {};
16
+
17
+ /*
18
+ * Creates a Rails application (the javascript part!)
19
+ *
20
+ * Pass global helper and initial data as params
21
+ */
22
+ Rails.app = function(helpers, initialData, beforeAll) {
23
+
24
+ /*
25
+ * Store everything in our local variables
26
+ */
27
+ globalHelpers = helpers;
28
+ data = initialData;
29
+
30
+ /*
31
+ * Set event listener to execute controllers' javascript
32
+ *
33
+ * There might be cases where we do not want to execute
34
+ * DOM-related js (e.g. javascript unit-tests).
35
+ * Set Rails.config.test to disable action execution.
36
+ */
37
+ document.addEventListener("DOMContentLoaded", function(event) {
38
+
39
+ if(Rails.config && Rails.config.test) {
40
+ return;
41
+ }
42
+
43
+ /*
44
+ * Also execute beforeAll() hook if defined
45
+ */
46
+ if(beforeAll && typeof(beforeAll) == 'function') {
47
+ beforeAll();
48
+ }
49
+
50
+ Rails.execute();
51
+ });
52
+ };
53
+
54
+ /*
55
+ * Adds a controller.
56
+ * Controllers are used to apply javascript in rails routes.
57
+ * Example:
58
+ *
59
+ * Rails.controller('users', {
60
+ *
61
+ * new: function() {
62
+ * // Executed on users/new
63
+ * }
64
+ * });
65
+ */
66
+ Rails.controller = function(name, actions, helpers) {
67
+
68
+ /*
69
+ * Should not be able to define controller (and helpers) twice
70
+ */
71
+ if(controllers[name]) {
72
+ throw ['Controller \'', name,
73
+ '\' is already defined! Please use a namespace'].join('');
74
+ }
75
+
76
+ /*
77
+ * Store controller & helpers in our local closure
78
+ */
79
+ controllers[name] = actions;
80
+ controllers[name].helpers = helpers;
81
+ },
82
+
83
+ /*
84
+ * Execute the actual controller action.
85
+ * e.g. will execute controller.users.index()
86
+ * when on #users/index
87
+ */
88
+ Rails.execute = function() {
89
+
90
+ /*
91
+ * Make sure rails.js has been properly added to the layout
92
+ */
93
+ if(!(this.config && this.config.controller && this.config.action)) {
94
+
95
+ throw ['No action or controller given.',
96
+ 'It seems like you forgot to add rails.js to your layouts\' header.'].join(' ');
97
+ }
98
+
99
+ var controller,
100
+ namespaceHook,
101
+ controllerName = this.config.controller;
102
+
103
+ /*
104
+ * Take care of namespace (e.g. admin/users)
105
+ */
106
+ if(this.config.namespace) {
107
+ controllerName = this.config.namespace + '/' + controllerName;
108
+
109
+ /*
110
+ * Execute namespace hook if we defined one
111
+ */
112
+ namespaceHook = namespaceHooks[this.config.namespace];
113
+ if(namespaceHook && typeof(namespaceHook) == 'function') {
114
+ namespaceHook();
115
+ }
116
+ }
117
+
118
+ /*
119
+ * Find controller and execute method
120
+ */
121
+ var controller = controllers[controllerName];
122
+ if(controller && controller[this.config.action] &&
123
+ typeof(controller[this.config.action]) == 'function') {
124
+
125
+ controller[this.config.action](controller.helpers);
126
+ }
127
+ };
128
+
129
+ /*
130
+ * Defines a namespace hook which will be executed when
131
+ * we are in the namespace of that hook.
132
+ *
133
+ * For example:
134
+ * When we define a namespace for 'admin'
135
+ * the function will be executed on all controllers in that namespace.
136
+ * (e.g. Admin::UsersController, Admin::SettingsController, etc...)
137
+ */
138
+ Rails.namespace = function(name, block) {
139
+
140
+ /*
141
+ * Should not be able to define controller (and helpers) twice
142
+ */
143
+ if(namespaceHooks[name]) {
144
+ throw ['Namespace \'', name, '\' is already defined!'].join('');
145
+ }
146
+
147
+ namespaceHooks[name] = block;
148
+ };
149
+
150
+
151
+ /*
152
+ * Global Singleton to store variables and functions
153
+ * that you need all over your javascript codebase.
154
+ *
155
+ * Also contains global helpers, so to prevent conflicts
156
+ * we save global variables by using this singleton as a function.
157
+ *
158
+ * R('foo'); // Gets window.R.data.foo
159
+ * R('foo', 'bar'); // Sets window.R.data.foo
160
+ */
161
+ R = function(key, val) {
162
+
163
+ /*
164
+ * It's possible to go multiple layers with one call, e.g.
165
+ * R('foo.bar.baz');
166
+ *
167
+ * Or you can set things at paths which are not there:
168
+ * // foo and bar will be created as empty objects
169
+ * R('foo.bar.baz', 'foo');
170
+ *
171
+ */
172
+ var steps = key.split('.'),
173
+ step = data;
174
+
175
+ if(val) {
176
+ for(var i = 0; i < steps.length-1; i++) {
177
+ if(!step[steps[i]]) {
178
+ step[steps[i]] = {};
179
+ }
180
+
181
+ step = step[steps[i]];
182
+ }
183
+
184
+ step[steps[steps.length -1]] = val;
185
+
186
+ } else {
187
+ for(var i = 0; i < steps.length; i++) {
188
+ step = step[steps[i]];
189
+ if(!step) {
190
+ break;
191
+ }
192
+
193
+ }
194
+ return step;
195
+ }
196
+ };
197
+
198
+ /*
199
+ * Execute a helper of a foreign controller
200
+ *
201
+ * e.g.
202
+ * Rails.helper('admin/users', 'method', [arg1, arg2, arg3]);
203
+ * or
204
+ * Rails.helper('entities', 'method', arg1, arg2, arg3);
205
+ */
206
+ R.helper = function(controllerName, helperName) {
207
+
208
+ var controller,
209
+ helper,
210
+ context,
211
+ args = Array.prototype.slice.call(arguments, 2);
212
+
213
+ /*
214
+ * Treat 3rd argument as arguments for helper if it is an Array
215
+ */
216
+ if(args.length == 1 && args[0] instanceof Array) {
217
+ args = args[0];
218
+ }
219
+
220
+ /*
221
+ * Choose global helper if controllerName is not given
222
+ */
223
+ if(controllerName) {
224
+ controller = controllers[controllerName];
225
+ helper = controller.helpers[helperName];
226
+ } else {
227
+ helper = globalHelpers[helperName];
228
+ }
229
+
230
+ /*
231
+ * Make sure our helper exists
232
+ */
233
+ if(!(helper && typeof(helper) == 'function')) {
234
+ if(controllerName) {
235
+ throw ['Helper \'', helperName, '\' not defined for controller \'',
236
+ controllerName, '\''].join('');
237
+ } else {
238
+ throw ['Global helper \'', helperName, '\' not defined'].join('');
239
+ }
240
+ }
241
+
242
+ /*
243
+ * Choose context, either some controllers' helpers or
244
+ * the globalHelpers object
245
+ */
246
+ context = controller ? controller.helpers : globalHelpers;
247
+
248
+ /*
249
+ * Execute helper in context with arguments
250
+ */
251
+ return helper.apply(context, args);
252
+ };
253
+
254
+ /*
255
+ * Execute a global helper
256
+ *
257
+ * Global helpers are defined when the Rails.app is created
258
+ */
259
+ R.global = function(helperName) {
260
+ return this.helper(undefined, helperName, Array.prototype.slice.call(arguments, 1));
261
+ };
262
+
263
+ /*
264
+ * Executes a controller action
265
+ * (to execute the same javascript in a different controller)
266
+ */
267
+ R.action = function(action) {
268
+
269
+ /*
270
+ * Arguments are either controller and action or the
271
+ * familliar rails syntax:
272
+ *
273
+ * R.action('users', 'index');
274
+ * R.action('users#index');
275
+ */
276
+ var controller,
277
+ controllerName = arguments[0],
278
+ actionName = arguments[1];
279
+
280
+ if(action.indexOf('#') !== -1) {
281
+ controllerName = action.split('#')[0];
282
+ actionName = action.split('#')[1];
283
+ }
284
+
285
+ /*
286
+ * Make sure controller and action exist
287
+ */
288
+ controller = controllers[controllerName];
289
+
290
+ if(!controller) {
291
+ throw ['Attempting to call action \'', controllerName, '#', actionName,
292
+ '\', but Controller \'', controllerName, '\' is not defined!'].join('');
293
+ } else if(!controller[actionName] || !(typeof(controller[actionName]) == 'function')) {
294
+ throw ['Attempting to call action \'', controllerName, '#', actionName,
295
+ '\', but Action \'', actionName, '\' is not defined!'].join('');
296
+ }
297
+
298
+ /*
299
+ * Execute controller action with helpers as argument
300
+ */
301
+ controller[actionName](controller.helper);
302
+ };
303
+
304
+ })(window, window.document);
@@ -0,0 +1,8 @@
1
+ module Rails
2
+ module JS
3
+ if defined?(::Rails)
4
+ require_relative 'js/view_helpers'
5
+ require_relative 'js/engine'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module Rails
2
+ module JS
3
+ class Engine < ::Rails::Engine
4
+ initializer "rails-js.view_helpers" do |app|
5
+ # include view helpers
6
+ ActionView::Base.send :include, ViewHelpers
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ module Rails
2
+ module JS
3
+ module ViewHelpers
4
+ def rails_js
5
+
6
+ namespace = controller_path.split('/').reject do |el|
7
+ el == controller_name
8
+ end.join
9
+
10
+ raw [
11
+ '<script type="text/javascript">',
12
+ 'window.Rails = window.Rails || {};',
13
+ 'Rails.config = {',
14
+ " controller: '#{controller_name}',",
15
+ " namespace: '#{namespace}',",
16
+ " action: '#{action_name}'",
17
+ '};',
18
+ '</script>'
19
+ ].join("\n")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'rails-js'
3
+ s.version = '0.0.1'
4
+ s.date = '2014-10-11'
5
+ s.summary = "A new approach to structure your javascript in non single-page Rails apps"
6
+ s.description = "Divide your javascript like you divide your ruby code. Put it in controllers and actions and write clean, scalable code."
7
+ s.authors = ["Finn-Lenanrt Heemeyer"]
8
+ s.email = 'finn@heemeyer.net'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.require_paths = ['lib']
11
+ s.homepage = 'http://rubygems.org/gems/rails-js'
12
+ s.license = 'MIT'
13
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-js
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Finn-Lenanrt Heemeyer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Divide your javascript like you divide your ruby code. Put it in controllers
14
+ and actions and write clean, scalable code.
15
+ email: finn@heemeyer.net
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - .gitignore
21
+ - README.md
22
+ - app/assets/javascripts/rails.js
23
+ - lib/rails/js.rb
24
+ - lib/rails/js/engine.rb
25
+ - lib/rails/js/view_helpers.rb
26
+ - rails-js.gemspec
27
+ homepage: http://rubygems.org/gems/rails-js
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.3.0
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: A new approach to structure your javascript in non single-page Rails apps
51
+ test_files: []