sudojs-rails 0.1.7
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +28 -0
- data/lib/generators/sudojs/class/USAGE +47 -0
- data/lib/generators/sudojs/class/class_generator.rb +107 -0
- data/lib/generators/sudojs/class/templates/class.coffee.erb +13 -0
- data/lib/generators/sudojs/class/templates/class.js.erb +14 -0
- data/lib/generators/sudojs/class/templates/manifest.js.erb +5 -0
- data/lib/generators/sudojs/helpers.rb +44 -0
- data/lib/generators/sudojs/install/USAGE +27 -0
- data/lib/generators/sudojs/install/install_generator.rb +34 -0
- data/lib/generators/sudojs/install/templates/app_manifest.js.erb +4 -0
- data/lib/generators/sudojs/install/templates/model.coffee.erb +9 -0
- data/lib/generators/sudojs/install/templates/model.js.erb +9 -0
- data/lib/generators/sudojs/install/templates/namespace.coffee.erb +8 -0
- data/lib/generators/sudojs/install/templates/namespace.js.erb +8 -0
- data/lib/generators/sudojs/install/templates/sudo_js.erb.yml +11 -0
- data/lib/sudojs/engine.rb +4 -0
- data/lib/sudojs/version.rb +3 -0
- data/lib/sudojs-rails.rb +2 -0
- data/sudojs-rails.gemspec +22 -0
- data/vendor/assets/javascripts/README.md +3 -0
- data/vendor/assets/javascripts/sudo-x.js +1344 -0
- data/vendor/assets/javascripts/sudo.js +778 -0
- metadata +94 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 robrobbins
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Sudojs::Rails
|
2
|
+
|
3
|
+
More than just making the currently released versions of sudo.js and sudo-x.js
|
4
|
+
available to your application, sudojs-rails is about a development pattern. A pattern that is
|
5
|
+
enforced, and made covenient, through the use of generators.
|
6
|
+
|
7
|
+
This highly opinionated workflow creates a global-level namespace for your code, a convenient
|
8
|
+
namespace-level observable model, and expects that you want new javascript class objects placed
|
9
|
+
into either the `app/assets/javascripts/application/` directory or, preferably, into an
|
10
|
+
`app/assets/javascripts/views/<controller_name>/` directory (more below).
|
11
|
+
|
12
|
+
Along with this, it is expected you will want a 'manifest' file created (or appended to if existing)
|
13
|
+
for the newly created Class Object. Manifests will named for controller actions (or the global `application`)
|
14
|
+
and should be loaded either globally (in the `application` case) or per controller (more on this below). This
|
15
|
+
allows for a degree of freedom when differentiating assets.
|
16
|
+
|
17
|
+
New Class Objects that you create can inherit from sudo.js defined types, or your own custom classes, and
|
18
|
+
be written in .js or .coffee
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
gem 'sudojs-rails'
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
|
32
|
+
$ gem install sudojs-rails
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
### Prepare Your Project
|
37
|
+
|
38
|
+
Before use, a few steps need to be followed to prepare your project for our preferred workflow.
|
39
|
+
|
40
|
+
+ We place manifest files into an `app/assets/javascripts/manifests` directory. This means that your
|
41
|
+
`app/views/layouts/application.html.*` file needs to be adjusted to account for this:
|
42
|
+
|
43
|
+
<%= javascript_include_tag 'manifests/application.js' %>
|
44
|
+
|
45
|
+
Preferably, you will **not** place this in your `head` tag
|
46
|
+
|
47
|
+
+ We assume that any Class Object not used more than once (i.e. is unique to a particular controller#action)
|
48
|
+
will not go into `application.js` but be placed into its own manifest for that controller. For this to function,
|
49
|
+
a helper method can be constructed:
|
50
|
+
|
51
|
+
# in app/helpers/application_helper.rb
|
52
|
+
def controller_javascript
|
53
|
+
controller_manifest = File.join('manifests', "#{self.controller_name}.js")
|
54
|
+
return '' if Rails.application.assets.find_asset(controller_manifest).nil?
|
55
|
+
|
56
|
+
return javascript_include_tag(controller_manifest)
|
57
|
+
end
|
58
|
+
|
59
|
+
This allows the following, combined with the previous include tag:
|
60
|
+
|
61
|
+
<%= javascript_include_tag 'manifests/application.js' %>
|
62
|
+
<%= controller_javascript %>
|
63
|
+
|
64
|
+
+ When concatonating for `staging` and `production` environments the following code needs to have been inserted
|
65
|
+
into your `config/environments/staging` and `config/environments/production` .rb files:
|
66
|
+
|
67
|
+
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
68
|
+
config.assets.precompile += %w( manifests/* )
|
69
|
+
|
70
|
+
### In Practice
|
71
|
+
|
72
|
+
running the command `rails g` would reveal that a single `sudojs:install` command can be made. Execute the command
|
73
|
+
`rails g sudojs:install -h` to see the USAGE directives. Running `rails g sudojs:install Spam` will install the correct files
|
74
|
+
and directories (with your shiny new `Spam` namespace).
|
75
|
+
|
76
|
+
After installing a second generator becomes available, run `rails g` again and `sudojs:class` should now be an option.
|
77
|
+
The reason for this is that `:class` depends on a yaml file to be placed in `config/` to function. Execute the command
|
78
|
+
`rails g sudojs:class -h` for the directives there.
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
1. Fork it
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'bundler/gem_tasks'
|
9
|
+
|
10
|
+
namespace :sudojs do
|
11
|
+
desc "Download the latest released versions sudo.js"
|
12
|
+
task :download_latest do
|
13
|
+
files = {
|
14
|
+
'sudo.js'=>'https://raw.github.com/robrobbins/sudo-js/jquery/build/debug/sudo.js',
|
15
|
+
'sudo-x.js' => 'https://raw.github.com/robrobbins/sudo-js/jquery/build/debug/sudo-x.js'
|
16
|
+
}
|
17
|
+
|
18
|
+
vendor_dir = "vendor/assets/javascripts"
|
19
|
+
|
20
|
+
require 'open-uri'
|
21
|
+
files.each do |local,remote|
|
22
|
+
puts "Downloading #{local}"
|
23
|
+
File.open "#{vendor_dir}/#{local}", 'w' do |f|
|
24
|
+
f.write open(remote).read
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
Description:
|
2
|
+
Create a skeletal sudo.js Class and place the files correctly for a given controller#name.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
`rails g sudojs:class View foo#baz`
|
6
|
+
|
7
|
+
Where `View` is a Class Object that this new Object will inherit from. Sudo.js itself
|
8
|
+
will recognize 5 types:
|
9
|
+
|
10
|
+
1. 'Base'
|
11
|
+
2. 'Container'
|
12
|
+
3. 'View'
|
13
|
+
4. 'ViewController'
|
14
|
+
5. 'Dataview'
|
15
|
+
|
16
|
+
The inheritance for any of these will be set as `_.<Name>` as we assume sudo has taken the
|
17
|
+
global `_` char as an alias. If the argument is any other string we assume you are inheriting
|
18
|
+
from a custom class and pass it through as is.
|
19
|
+
|
20
|
+
|
21
|
+
Where `foo#baz` *can* match a controller#action (like `home#show`) it does not
|
22
|
+
have to. The controller argument (`foo`) allows the generator to place the file correctly and
|
23
|
+
create/modify the correct manifest file. The name argument will be the proper name of the
|
24
|
+
Class Object itself
|
25
|
+
|
26
|
+
If a corresponding views/controller/name.html.* is found, a skeletal instantiation of the newly
|
27
|
+
created View will be placed there
|
28
|
+
|
29
|
+
This will create:
|
30
|
+
app/
|
31
|
+
assests/
|
32
|
+
javascripts/
|
33
|
+
manifests/
|
34
|
+
foo.js
|
35
|
+
views/
|
36
|
+
foo/
|
37
|
+
baz.js
|
38
|
+
|
39
|
+
And modify (if found):
|
40
|
+
app/
|
41
|
+
views/
|
42
|
+
foo/
|
43
|
+
baz.html.*
|
44
|
+
|
45
|
+
Note:
|
46
|
+
If the `route` is application level (application#baz) the file will be placed
|
47
|
+
in the application level directory and the manifests/application file will be modified
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'generators/sudojs/helpers.rb'
|
2
|
+
|
3
|
+
module Sudojs
|
4
|
+
module Generators
|
5
|
+
class ClassGenerator < Rails::Generators::NamedBase
|
6
|
+
include Sudojs::Generators::Helpers
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
8
|
+
|
9
|
+
# not really a route but passed in the form controller#name
|
10
|
+
argument :route, :type =>:string, :default => 'foo#bar'
|
11
|
+
|
12
|
+
def set_vars
|
13
|
+
# recognized sudo.js class objects. unrecognized names will
|
14
|
+
# be considered 'custom' classes
|
15
|
+
@class_names = {
|
16
|
+
'Base' => '_.Base',
|
17
|
+
'Container' => '_.Container',
|
18
|
+
'DataView' => '_.DataView',
|
19
|
+
'View' => '_.View',
|
20
|
+
'ViewController' => '_.ViewController'
|
21
|
+
}
|
22
|
+
ary = route.split('#')
|
23
|
+
@c_name = ary[0]
|
24
|
+
@c_camel = camelize(@c_name)
|
25
|
+
# is this an application level object?
|
26
|
+
@is_application = @c_name == 'application'
|
27
|
+
# 'action' name not always applicable but thats ok
|
28
|
+
@a_name = ary[1]
|
29
|
+
@a_camel = camelize(@a_name)
|
30
|
+
# class invocations with `new` should always use a proper name
|
31
|
+
@a_pascal = @a_camel.capitalize
|
32
|
+
# either inherits from a sudo.js class or a custom one
|
33
|
+
@parent = @class_names[name] || name
|
34
|
+
# the arguments vary in the templates for class types
|
35
|
+
if @parent
|
36
|
+
if @parent == '_.Base' || @parent == '_.Container'
|
37
|
+
@args = 'data'
|
38
|
+
else
|
39
|
+
@args = 'el, data'
|
40
|
+
end
|
41
|
+
else
|
42
|
+
# cannot guess the args to a custom class
|
43
|
+
@args = '/* args */'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# expand the template to <destination>
|
48
|
+
def copy_class_template
|
49
|
+
if @is_application
|
50
|
+
path = "app/assets/javascripts/application"
|
51
|
+
@path_to_object = namespace
|
52
|
+
else
|
53
|
+
path = "app/assets/javascripts/views/#{@c_name}"
|
54
|
+
@path_to_object = [namespace, '.', @c_camel].join('')
|
55
|
+
# make sure the directory is present (create if not)
|
56
|
+
ensure_cname_dir(path)
|
57
|
+
end
|
58
|
+
|
59
|
+
if use_coffee?
|
60
|
+
template 'class.coffee.erb', "#{path}/#{@a_name}.js.coffee"
|
61
|
+
else
|
62
|
+
template 'class.js.erb', "#{path}/#{@a_name}.js"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_or_modify_manifest
|
67
|
+
filename = "app/assets/javascripts/manifests/#{@c_name}.js"
|
68
|
+
if @is_application
|
69
|
+
line = "//= require application/#{@a_name}"
|
70
|
+
else
|
71
|
+
line = "//= require views/#{@c_name}/#{@a_name}"
|
72
|
+
end
|
73
|
+
|
74
|
+
if File.exist? filename
|
75
|
+
# inject_into_file not needed here unless you were using a require tree
|
76
|
+
append_to_file filename, line
|
77
|
+
else
|
78
|
+
template 'manifest.js.erb', filename
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def modify_view_if_exists
|
83
|
+
filename = "app/views/#{@c_name}/#{@a_name}.html.#{which_markup}"
|
84
|
+
if File.exist? filename
|
85
|
+
if use_coffee?
|
86
|
+
comment = '#'
|
87
|
+
else
|
88
|
+
comment = '//'
|
89
|
+
end
|
90
|
+
note = "#{comment} Optional invocation of your new Class.\n#{comment} Place this into a jQuery document ready block."
|
91
|
+
content = "\n#{note}\n#{comment} #{@path_to_object}.#{@a_camel} = new #{@path_to_object}.#{@a_pascal}(#{@args});"
|
92
|
+
append_to_file filename, content
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def ensure_cname_dir(path)
|
99
|
+
# if exists we will assume a directory
|
100
|
+
unless File.exist? path
|
101
|
+
empty_directory(path)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
_.namespace '<%= @path_to_object %>'
|
2
|
+
|
3
|
+
class <%= @path_to_object %>.<%= @a_pascal %> extends <%= @parent %>
|
4
|
+
# the constructor can be deleted if not used (most actions can be done in the init)
|
5
|
+
# an obvious choice is when you need to do something `pre-constructor`
|
6
|
+
constructor: (<%= @args %>) ->
|
7
|
+
# perform any actions needed `pre-super` here
|
8
|
+
super <%= @args %>
|
9
|
+
|
10
|
+
# optional init for your new viewController, delete if unused
|
11
|
+
init: ->
|
12
|
+
# do stuff
|
13
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
_.namespace('<%= @path_to_object %>');
|
2
|
+
|
3
|
+
<%= @path_to_object %>.<%= @a_pascal %> = function(<%= @args %>) {
|
4
|
+
// perform any actions needed `pre-super` here
|
5
|
+
this.construct(<%= @args %>);
|
6
|
+
// perform any `post-super` actions here
|
7
|
+
// remember `init` will also be called `post-super` if present
|
8
|
+
};
|
9
|
+
|
10
|
+
<%= @path_to_object %>.<%= @a_pascal %>.prototype = Object.create(<%= @parent %>.prototype);
|
11
|
+
|
12
|
+
// optional init method for your new viewController, delete if unused
|
13
|
+
<%= @path_to_object %>.<%= @a_pascal %>.prototype.init = function init() {};
|
14
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Sudojs
|
4
|
+
module Generators
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
CFG = YAML.load_file('config/sudo_js.yml') unless defined? CFG
|
8
|
+
|
9
|
+
def namespace
|
10
|
+
CFG['js_namespace']
|
11
|
+
end
|
12
|
+
|
13
|
+
def which_sudo
|
14
|
+
CFG['which_sudo']
|
15
|
+
end
|
16
|
+
|
17
|
+
def which_markup
|
18
|
+
CFG['which_markup']
|
19
|
+
end
|
20
|
+
|
21
|
+
def use_coffee?
|
22
|
+
CFG['use_coffee']
|
23
|
+
end
|
24
|
+
|
25
|
+
def camelize(what)
|
26
|
+
if what.include? '_'
|
27
|
+
ary = what.split '_'
|
28
|
+
ary.each_with_index {|val, i|
|
29
|
+
val.capitalize! if i > 0
|
30
|
+
}
|
31
|
+
ary.join('')
|
32
|
+
else
|
33
|
+
what
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def pascalize(what)
|
38
|
+
n = camelize(what)
|
39
|
+
n.capitalize
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Description:
|
2
|
+
Install sudo.js along with it's particular directory hierarchy.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails g sudojs:install namespace [which_sudo] [which_markup] [use_coffee]
|
6
|
+
|
7
|
+
The only mandatory argument is the initial `namespace`.
|
8
|
+
|
9
|
+
The install generator uses these optional arguments to expand the values in the sudo_js.yml file:
|
10
|
+
1. `which_sudo` => which version of sudo.js are you loading? As sudo.js can be rebuilt into any number
|
11
|
+
of custom configurations, indicate here what name should be placed into the application manifest.
|
12
|
+
Defaults to 'sudo-x' if omitted.
|
13
|
+
2. `which_markup` => defaults to `erb`.
|
14
|
+
3. `use_coffee` => defaults to `false` pass `true` if you are of the coffee persuasion.
|
15
|
+
|
16
|
+
This will create:
|
17
|
+
app/
|
18
|
+
assets/
|
19
|
+
javascripts/
|
20
|
+
application/
|
21
|
+
yourNamespace.js
|
22
|
+
model.js
|
23
|
+
manifests/
|
24
|
+
application.js
|
25
|
+
views/
|
26
|
+
config/
|
27
|
+
sudo_js.yml
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Sudojs
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::NamedBase
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
argument :which_sudo_arg, :type => :string, :default => 'sudo-x'
|
7
|
+
argument :which_markup_arg, :type => :string, :default => 'erb'
|
8
|
+
argument :use_coffee_arg, :type => :string, :default => 'false'
|
9
|
+
|
10
|
+
def create_yaml
|
11
|
+
template 'sudo_js.erb.yml', 'config/sudo_js.yml'
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_dir_structure
|
15
|
+
%W{application manifests views}.each do |dir|
|
16
|
+
empty_directory "app/assets/javascripts/#{dir}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def place_install_files
|
21
|
+
template 'app_manifest.js.erb', 'app/assets/javascripts/manifests/application.js'
|
22
|
+
|
23
|
+
unless use_coffee_arg == 'false'
|
24
|
+
template 'namespace.coffee.erb', "app/assets/javascripts/application/#{name}.js.coffee"
|
25
|
+
template 'model.coffee.erb', 'app/assets/javascripts/application/model.js.coffee'
|
26
|
+
else
|
27
|
+
template 'namespace.js.erb', "app/assets/javascripts/application/#{name}.js"
|
28
|
+
template 'model.js.erb', 'app/assets/javascripts/application/model.js'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|