dom_routes 1.0.0

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: f167cc007cf2326be1d2256ea21feb8831efda1e
4
+ data.tar.gz: 90e8ef89d35101a067341072c6b5cdc2ca020bc2
5
+ SHA512:
6
+ metadata.gz: 26a799981bc263a0cf8605eaf99d3b9aab819968e4790504f00cded7b11c59d8810973ea0701f66fa024e4d939d562ef64c4f91a4625a523114a6a04ef26636e
7
+ data.tar.gz: 0b9afacb3fa28a6994e79de1a82966e40f7c48d96e43a393320a39d3b062a54224aa5f2804e67dcf1dcde9f8fd3d1c1b6a20682481eb689bac95b3e34c41d327
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dom_routes.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 s12chung
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,141 @@
1
+ # PokeJs
2
+ Auto-magical scaffolding for
3
+ [Paul Irish's DOM-based Routing](http://www.paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/)
4
+ (or Garber-Irish Implementation) way of organizing your javascript.
5
+
6
+ ## Purpose
7
+ Javascript is hard to organize and debugging ajax is a mess. This is one method to organizing your javascript neatly by mirroring the controllers and having all the it outside of your HTML views.
8
+
9
+ ## How it works
10
+ ### Setup your namespace
11
+ ```javascript
12
+ DR.routes = {
13
+ all: {
14
+ html: {
15
+ before: function() {
16
+ }
17
+ }
18
+ },
19
+ demos: {
20
+ html: {
21
+ before: function() {
22
+ },
23
+ demo_action: function() {
24
+ }
25
+ }
26
+ }
27
+ }
28
+ ```
29
+ ### What happens
30
+ After, requests to `demos#demo_action` with format `html` will call the following functions (if they exist):
31
+ * `DR.routes.all.html.before`
32
+ * `DR.routes.demos.html.before`
33
+ * `DR.routes.demos.html.demo_action` (with parameters if given)
34
+ * `DR.routes.demos.html.after`
35
+ * `DR.routes.all.html.after`
36
+
37
+ `js` format is also supported, i.e.:
38
+ * `DR.routes.all.js.before`
39
+ * `DR.routes.demos.js.before`
40
+ * `DR.routes.demos.js.demo_action` (with parameters if given)
41
+ * `DR.routes.demos.js.after`
42
+ * `DR.routes.all.js.after`
43
+
44
+ ## Installation
45
+ Add this line to your application's `Gemfile`:
46
+
47
+ gem 'dom_routes'
48
+
49
+ And then execute:
50
+
51
+ $ bundle
52
+
53
+ Add this to your `app/assets/javascripts/application.js`
54
+
55
+ //= require dom_routes
56
+
57
+ Make sure your `app/views/layouts/application.html.erb` (and all your other layouts) looks like this:
58
+ ```erb
59
+ <html>
60
+ <head>… <%= execute_js_routes %> …</head>
61
+ <body data-controller="<%= js_route.controller_path %>" data-action="<%= js_route.action %>">
62
+
63
+ </body>
64
+ </html>
65
+ ```
66
+
67
+ ## Basic Use
68
+ I like to have a JS file for every route in `app/assets/javascripts/routes`. Like so:
69
+
70
+ `app/assets/javascripts/routes/demos.js`:
71
+ ```javascript
72
+ (function() {
73
+ var demos = DR.define('demos', {
74
+ html: {
75
+ edit: function(params) {
76
+ alert(params.alert_message);
77
+ }
78
+ },
79
+
80
+ js: {
81
+ new: function(params) {
82
+ console.log(params.log_message);
83
+ }
84
+ }
85
+ });
86
+ })();
87
+ ```
88
+
89
+ `DR.define()` extends or creates the namespace `DR.routes.demos`
90
+ and returns it. This allows me to access `DR.routes.demos` through
91
+ the `demos` variable. You can also use the traditional hash
92
+ namespacing shown in the [Setup your namespace](https://github.com/s12chung/dom_routes#setup-your-namespace) section.
93
+
94
+ So if a `html` request is sent to `demos#edit`, `DR.routes.demos.html.edit` is called with the HTML view rendering.
95
+
96
+ For a `js` request sent to `demos#new`, `DR.routes.demos.js.new` is called and nothing else happens.
97
+
98
+ ### Passing parameters
99
+ __Optional__ Parameters are passed from a JSON DSL (such as [jbuilder](https://github.com/rails/jbuilder/)) and is passed as the `params` object to the function. You can pass any JSON object.
100
+
101
+ #### HTML
102
+ `app/views/demos/edit_params.js.jbuilder`:
103
+ ```ruby
104
+ json.alert_message "ploop"
105
+ ```
106
+ so
107
+ ```javascript
108
+ DR.routes.demos.html.edit({ alert_message: "ploop" });
109
+ ```
110
+ is called automatically.
111
+
112
+ #### Javascript
113
+ `app/views/demos/new.js.jbuilder`:
114
+ ```ruby
115
+ json.log_message "loggggggggggggg"
116
+ ```
117
+ so
118
+ ```javascript
119
+ DR.routes.demos.js.new({ log_message: "loggggggggggggg" });
120
+ ```
121
+ is called automatically.
122
+
123
+ ## Advanced Use
124
+ ### Manually execute a route
125
+ Use `#execute_js_route(js_route=self.js_route, format=formats.first)`
126
+
127
+ ### Executing a different route
128
+ Sometimes you want to execute a different route too. For that, you can specify it like so:
129
+ ```ruby
130
+ self.js_route = "demos/edit" # can be "demos#edit", "edit", { controller: "demos", action: "edit" }, or a DomRoutes::Route object
131
+ ```
132
+ When this is done, the original route and the new route will be executed.
133
+
134
+ ### Handling redirects with flash
135
+ Other times you may want to use a route after a redirect, use `#flash_js_route(js_route=nil)` then.
136
+
137
+ ## Credits
138
+ Extracted out of [Placemark](https://www.placemarkhq.com/). Originally called [poke_js](https://github.com/s12chung/poke_js).
139
+
140
+ ## Contribution
141
+ Feel free to fork, post issues or send any pull requests. Thanks.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,71 @@
1
+ DR = {
2
+ namespace_prefix: "DR.routes",
3
+ blank: function(o) {
4
+ return typeof o === "undefined" || o === null;
5
+ },
6
+ namespace_string: function(namespace_string) {
7
+ return DR.namespace_prefix + "." + namespace_string;
8
+ },
9
+ get_or_create: function(namespace_string) {
10
+ var current_namepace = window;
11
+ $.each(namespace_string.split('.'), function(index, level) {
12
+ if (DR.blank(current_namepace[level]))
13
+ current_namepace[level] = {};
14
+ current_namepace = current_namepace[level];
15
+ });
16
+
17
+ return current_namepace;
18
+ },
19
+ define: function(namespace_string, definition) {
20
+ namespace_string = DR.namespace_string(namespace_string);
21
+ return DR.define_namespace(namespace_string, definition);
22
+ },
23
+ define_namespace: function(namespace_string, definition) {
24
+ var found_namespace = DR.get_or_create(namespace_string);
25
+ return $.extend(found_namespace, definition);
26
+ },
27
+
28
+ traverse_namespace: function(namespace, levels) {
29
+ if (!$.isArray(levels)) levels = [levels.controller, levels.format, levels.action];
30
+ levels = DR.formatted_levels(levels);
31
+
32
+ var current_level = namespace;
33
+ var level;
34
+ for (var i=0;i<levels.length;i++) {
35
+ level = levels[i];
36
+ current_level = current_level[level];
37
+ if (typeof current_level === "undefined") return undefined;
38
+ }
39
+ return current_level;
40
+ },
41
+ formatted_levels: function(levels) {
42
+ var formatted_levels = [];
43
+ var level;
44
+ for (var i=0;i<levels.length;i++) {
45
+ level = levels[i];
46
+ formatted_levels = formatted_levels.concat(level.split('/'));
47
+ }
48
+ return formatted_levels;
49
+ },
50
+
51
+ create_namespace: function(namespace) {
52
+ var current_level = window;
53
+ $.each(namespace.split("."), function(index, level) {
54
+ if (!$.isPlainObject(current_level[level])) current_level[level] = {};
55
+ current_level = current_level[level];
56
+ });
57
+ },
58
+
59
+ exec_all: function(params) {
60
+ DR.exec("application", params.format, "before", params);
61
+ DR.exec(params.controller, params.format, "before", params);
62
+ DR.exec("application", params.format, params.action, params);
63
+ DR.exec(params.controller, params.format, params.action, params);
64
+ DR.exec(params.controller, params.format, "after", params);
65
+ DR.exec("application", params.format, "after", params);
66
+ },
67
+ exec: function(controller, format, action, params) {
68
+ var action_namespace = DR.traverse_namespace(DR.routes, [controller, format, action]);
69
+ if ($.isFunction(action_namespace)) action_namespace(params);
70
+ }
71
+ };
@@ -0,0 +1,5 @@
1
+ (function() {
2
+ DR.create_namespace('<%= js_params_namespace %>');
3
+ <%= js_params_namespace %> = <%= js_params_value { yield } %>;
4
+ DR.exec_all(<%= js_params_namespace %>);
5
+ })();
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dom_routes/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dom_routes"
8
+ spec.version = DomRoutes::VERSION
9
+ spec.authors = ["s12chung"]
10
+ spec.email = ["steve@placemarkhq.com"]
11
+ spec.description = %q{ Auto-magical scaffolding for Paul Irish's DOM-based Routing way of organizing your javascript. }
12
+ spec.summary = %q{ Auto-magical scaffolding for Paul Irish's DOM-based Routing way of organizing your javascript. }
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'rails', '>= 3.1'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,12 @@
1
+ require "dom_routes/view_helpers"
2
+ require "dom_routes/controller"
3
+
4
+ module DomRoutes
5
+ if defined?(Rails) && defined?(Rails::Engine)
6
+ class Engine < ::Rails::Engine
7
+ initializer "dom_routes.view_helpers" do
8
+ ActionView::Base.send :include, ViewHelpers
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,71 @@
1
+ module DomRoutes
2
+ class Route
3
+ attr_accessor :controller_path, :action
4
+
5
+ def set(controller_path, action)
6
+ self.controller_path = controller_path
7
+ self.action = action
8
+ end
9
+
10
+ def controller_namespace
11
+ controller_path.gsub("/", ".")
12
+ end
13
+
14
+ def parts
15
+ [controller_path, action]
16
+ end
17
+
18
+ def to_s
19
+ "#{controller_path}/#{action}"
20
+ end
21
+ def ==(route)
22
+ parts == route.parts
23
+ end
24
+ end
25
+
26
+ module Controller
27
+ extend ActiveSupport::Concern
28
+ included do
29
+ helper_method :js_route
30
+ helper_method :js_route=
31
+ helper_method :extract_js_route
32
+ end
33
+
34
+ protected
35
+ def js_route; @js_route || extract_js_route end
36
+ def js_route=(js_route); @js_route = extract_js_route js_route end
37
+ def flash_js_route(js_route=self.js_route)
38
+ flash[:js_route] = extract_js_route(js_route).to_s
39
+ end
40
+
41
+ def extract_js_route(js_route=nil)
42
+ extracted_route = Route.new
43
+ extracted_route.set controller_path, action_name
44
+
45
+ if js_route
46
+ if js_route.class == Route
47
+ extracted_route = js_route
48
+ elsif js_route.class.ancestors.include? Hash
49
+ hash = HashWithIndifferentAccess.new(js_route)
50
+ extracted_route.set hash[:controller], hash[:action]
51
+ else
52
+ js_route = js_route.to_s
53
+ controller = if js_route.index("#")
54
+ split = js_route.split('#')
55
+ [split.first]
56
+ else
57
+ split = js_route.split('/')
58
+ split[0..-2]
59
+ end
60
+ extracted_route.action = split.last
61
+ unless controller.empty?
62
+ extracted_route.controller_path = controller.join('/')
63
+ end
64
+ end
65
+ end
66
+ extracted_route
67
+ end
68
+ end
69
+ end
70
+
71
+ ::ActionController::Base.send :include, DomRoutes::Controller
@@ -0,0 +1,3 @@
1
+ module DomRoutes
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,110 @@
1
+ module DomRoutes
2
+ module ViewHelpers
3
+ #http://stackoverflow.com/questions/339130/how-do-i-render-a-partial-of-a-different-format-in-rails
4
+ def with_format(format, &block)
5
+ old_formats = formats
6
+ self.formats = [format]
7
+ result = block.call
8
+ self.formats = old_formats
9
+ result
10
+ end
11
+
12
+ def with_js_route(js_route)
13
+ old_js_route = self.js_route
14
+ self.js_route = js_route
15
+ result = yield
16
+ self.js_route = old_js_route
17
+ result
18
+ end
19
+
20
+ def js_params_namespace(js_route=self.js_route)
21
+ raw "DR.routes.#{js_route.controller_namespace}.#{formats.first}.#{js_route.action}_params"
22
+ end
23
+
24
+ def js_params_value(js_route=self.js_route)
25
+ controller_path, action = js_route.parts
26
+
27
+ params = { controller: controller_path, action: action, method: request.method, path: request.env['PATH_INFO'], format: formats.first }
28
+ if self.respond_to? :add_params; params.reverse_merge! add_params end
29
+
30
+ javascript = params.to_json
31
+ if block_given?
32
+ generated_params = yield
33
+ if generated_params
34
+ javascript = "$.extend(#{generated_params}, #{javascript});"
35
+ end
36
+ end
37
+ raw javascript
38
+ end
39
+
40
+ def execute_js_routes
41
+ raw "#{execute_flash_js_route}\n#{execute_js_route}"
42
+ end
43
+
44
+ def execute_js_route(js_route=self.js_route, format=formats.first)
45
+ controller_path, action = js_route.parts
46
+ lambda = -> do
47
+ if format == :html
48
+ javascript_tag do
49
+ raw %Q/
50
+ DR.create_namespace('#{js_params_namespace}');
51
+ #{js_params_namespace} = #{ js_params_value do
52
+ with_format :js do
53
+ if lookup_context.template_exists? "#{controller_path}/#{action}_params"
54
+ render(template: "#{controller_path}/#{action}_params")
55
+ end
56
+ end
57
+ end };
58
+ #{
59
+ if is_flash_js_route?
60
+ %Q/$(function() { DR.exec_all(#{js_params_namespace}); });/
61
+ else
62
+ %Q/
63
+ DR.define_namespace('DR.routes', {
64
+ params: #{js_params_namespace},
65
+ init: function() { DR.exec_all(DR.routes.params); },
66
+ });
67
+ $(DR.routes.init);
68
+ /
69
+ end
70
+ }
71
+ /
72
+ end
73
+ elsif format == :js
74
+ with_format :js do
75
+ content_for :head do
76
+ javascript_tag do
77
+ raw "$(function(){#{render template: "#{controller_path}/#{action}", formats: [:js], layout: "layouts/application"}});"
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ if js_route != self.js_route
85
+ with_js_route(js_route) { lambda.call }
86
+ else
87
+ lambda.call
88
+ end
89
+ end
90
+
91
+ def execute_flash_js_route
92
+ flash_js_route = flash[:js_route]
93
+ if flash_js_route
94
+ with_flash_js_route do
95
+ execute_js_route extract_js_route(flash_js_route)
96
+ end
97
+ end
98
+ end
99
+
100
+ def with_flash_js_route
101
+ @is_flash_js_route = true
102
+ result = yield
103
+ @is_flash_js_route = false
104
+ result
105
+ end
106
+ def is_flash_js_route?
107
+ @is_flash_js_route
108
+ end
109
+ end
110
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dom_routes
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - s12chung
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: ' Auto-magical scaffolding for Paul Irish''s DOM-based Routing way of
56
+ organizing your javascript. '
57
+ email:
58
+ - steve@placemarkhq.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - app/assets/javascripts/dom_routes.js
69
+ - app/views/layouts/application.js.erb
70
+ - dom_routes.gemspec
71
+ - lib/dom_routes.rb
72
+ - lib/dom_routes/controller.rb
73
+ - lib/dom_routes/version.rb
74
+ - lib/dom_routes/view_helpers.rb
75
+ homepage: ''
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.0.3
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Auto-magical scaffolding for Paul Irish's DOM-based Routing way of organizing
99
+ your javascript.
100
+ test_files: []