dom_routes 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []