sudojs-rails 0.3.6 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/lib/generators/sudojs/class/USAGE +4 -0
- data/lib/generators/sudojs/class/class_generator.rb +53 -23
- data/lib/generators/sudojs/class/templates/class.js.erb +4 -5
- data/lib/generators/sudojs/install/USAGE +2 -1
- data/lib/generators/sudojs/install/install_generator.rb +4 -4
- data/lib/generators/sudojs/install/templates/app_manifest.js.erb +2 -3
- data/lib/generators/sudojs/install/templates/model.coffee.erb +1 -5
- data/lib/generators/sudojs/install/templates/model.js.erb +2 -4
- data/lib/sudojs/version.rb +1 -1
- data/vendor/assets/javascripts/sudojs/sudo-x.js +64 -19
- metadata +5 -4
data/.DS_Store
ADDED
Binary file
|
@@ -51,3 +51,7 @@ Example:
|
|
51
51
|
Note:
|
52
52
|
If the `route` is application level (application#baz) the file will be placed
|
53
53
|
in the application level directory and the manifests/application file will be modified
|
54
|
+
|
55
|
+
Also a custom path may be passed to allow Javascript files to be placed in arbitrary locations.
|
56
|
+
--js-dr=views/foo for example would force any newly created file into the '/foo' subdirectory of the
|
57
|
+
views folder
|
@@ -9,6 +9,9 @@ module Sudojs
|
|
9
9
|
# not really a route but passed in the form controller#name
|
10
10
|
argument :route, :type =>:string, :default => 'foo#bar'
|
11
11
|
|
12
|
+
class_option :js_dir, :type => :string, :aliases => "--js-dir", :default => '',
|
13
|
+
:desc => 'Specify the application, models, views or a custom directory'
|
14
|
+
|
12
15
|
def set_vars
|
13
16
|
# recognized sudo.js class objects. unrecognized names will
|
14
17
|
# be considered 'custom' classes
|
@@ -20,6 +23,20 @@ module Sudojs
|
|
20
23
|
'View' => '_.View',
|
21
24
|
'ViewController' => '_.ViewController'
|
22
25
|
}
|
26
|
+
|
27
|
+
@js_app_path = 'app/assets/javascripts/application'
|
28
|
+
@css_app_path = 'app/assets/stylesheets/application'
|
29
|
+
@js_model_path = 'app/assets/javascripts/models'
|
30
|
+
@js_views_path = 'app/assets/javascripts/views'
|
31
|
+
@css_views_path = 'app/assets/stylesheets/views'
|
32
|
+
|
33
|
+
# was the js_dir option passed
|
34
|
+
if options[:js_dir] != ''
|
35
|
+
@js_dir = "app/assets/javascripts/#{options[:js_dir]}"
|
36
|
+
else
|
37
|
+
@js_dir = nil
|
38
|
+
end
|
39
|
+
|
23
40
|
ary = route.split('#')
|
24
41
|
@c_name = ary[0]
|
25
42
|
@c_camel = camelize(@c_name)
|
@@ -33,41 +50,54 @@ module Sudojs
|
|
33
50
|
# either inherits from a sudo.js class or a custom one
|
34
51
|
@parent = @class_names[name] || name
|
35
52
|
# the arguments vary in the templates for class types
|
36
|
-
|
37
|
-
|
53
|
+
# also we can make some assumptions about paths
|
54
|
+
case @parent
|
55
|
+
when '_.Base', '_.Container'
|
56
|
+
@args = 'data'
|
57
|
+
@js_path = @js_views_path
|
58
|
+
@js_req = 'views'
|
59
|
+
when '_.Model'
|
38
60
|
@args = 'data'
|
39
|
-
|
61
|
+
@js_path = @js_model_path
|
62
|
+
@js_req = 'models'
|
63
|
+
when '_.View', '_.ViewController', 'DataView'
|
40
64
|
@args = 'el, data'
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
65
|
+
@js_path = @js_views_path
|
66
|
+
@js_req = 'views'
|
67
|
+
else
|
68
|
+
#default to unknown args and views path
|
69
|
+
@args = '/* args */'
|
70
|
+
@js_path = @js_views_path
|
71
|
+
@js_req = 'views'
|
45
72
|
end
|
73
|
+
|
46
74
|
end
|
47
75
|
|
48
76
|
# expand the template to <destination>
|
49
77
|
def copy_class_template
|
50
78
|
if @is_application
|
51
|
-
|
52
|
-
|
79
|
+
# a more definitive indicator
|
80
|
+
js_path = @js_app_path
|
81
|
+
css_path = @css_app_path
|
53
82
|
@path_to_object = namespace
|
54
83
|
else
|
55
|
-
|
56
|
-
|
84
|
+
# the user passed option takes precedence
|
85
|
+
js_path = "#{@js_dir || @js_path}/#{@c_name}"
|
86
|
+
css_path = "#{@css_views_path}/#{@c_name}"
|
57
87
|
@path_to_object = [namespace, '.', @c_camel].join('')
|
58
88
|
# make sure the directory is present (create if not)
|
59
89
|
unless skip_css?
|
60
|
-
ensure_cname_dir(
|
90
|
+
ensure_cname_dir(js_path, css_path)
|
61
91
|
else
|
62
|
-
ensure_cname_dir(
|
92
|
+
ensure_cname_dir(js_path)
|
63
93
|
end
|
64
94
|
end
|
65
95
|
|
66
96
|
# js
|
67
97
|
if js_extension == '.js.coffee'
|
68
|
-
template 'class.coffee.erb', "#{
|
98
|
+
template 'class.coffee.erb', "#{js_path}/#{@a_name}.js.coffee"
|
69
99
|
else
|
70
|
-
template 'class.js.erb', "#{
|
100
|
+
template 'class.js.erb', "#{js_path}/#{@a_name}#{js_extension}"
|
71
101
|
end
|
72
102
|
|
73
103
|
# css
|
@@ -80,17 +110,17 @@ module Sudojs
|
|
80
110
|
def create_or_modify_manifest
|
81
111
|
js_pre = '//= '
|
82
112
|
css_pre = ' *= '
|
83
|
-
rest_app = "require application/#{@a_name}"
|
84
|
-
rest_view = "require views/#{@c_name}/#{@a_name}"
|
85
|
-
filename = "app/assets/javascripts/manifests/#{@c_name}.js"
|
86
|
-
css_filename = "app/assets/stylesheets/manifests/#{@c_name}.css"
|
87
113
|
if @is_application
|
88
|
-
|
89
|
-
css_line = css_pre + rest_app + "\n"
|
114
|
+
req = "require application/#{@a_name}"
|
90
115
|
else
|
91
|
-
|
92
|
-
|
116
|
+
# user passed option can take precedence
|
117
|
+
req = "require #{@js_dir || @js_path}/#{@c_name}/#{@a_name}"
|
93
118
|
end
|
119
|
+
filename = "app/assets/javascripts/manifests/#{@c_name}.js"
|
120
|
+
css_filename = "app/assets/stylesheets/manifests/#{@c_name}.css"
|
121
|
+
|
122
|
+
line = js_pre + req
|
123
|
+
css_line = css_pre + req + "\n"
|
94
124
|
|
95
125
|
# js
|
96
126
|
if File.exist? filename
|
@@ -7,8 +7,7 @@ _.namespace('<%= @path_to_object %>');
|
|
7
7
|
// remember `init` will also be called `post-super` if present
|
8
8
|
};
|
9
9
|
|
10
|
-
<%= @path_to_object %>.<%= @a_pascal %>.prototype = Object.create(<%= @parent %>.prototype)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
<%= @path_to_object %>.<%= @a_pascal %>.prototype = $.extend(Object.create(<%= @parent %>.prototype), {
|
11
|
+
// optional init method for your new viewController, delete if unused
|
12
|
+
init: function init() {};
|
13
|
+
});
|
@@ -21,14 +21,14 @@ module Sudojs
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def create_dir_structure
|
24
|
-
%W{application manifests views}.each do |dir|
|
24
|
+
%W{application manifests models views}.each do |dir|
|
25
25
|
directory = "app/assets/javascripts/#{dir}"
|
26
26
|
css_directory = "app/assets/stylesheets/#{dir}"
|
27
27
|
unless File.directory? directory
|
28
28
|
empty_directory directory
|
29
29
|
end
|
30
30
|
|
31
|
-
unless options[:skip_css]
|
31
|
+
unless options[:skip_css] || dir == 'models'
|
32
32
|
unless File.directory? css_directory
|
33
33
|
empty_directory css_directory
|
34
34
|
end
|
@@ -45,11 +45,11 @@ module Sudojs
|
|
45
45
|
# TODO templates for other javascript pre-processors
|
46
46
|
if js_extension_arg == '.js.coffee'
|
47
47
|
template 'namespace.coffee.erb', "app/assets/javascripts/application/#{name}.js.coffee"
|
48
|
-
template 'model.coffee.erb', 'app/assets/javascripts/
|
48
|
+
template 'model.coffee.erb', 'app/assets/javascripts/models/base.js.coffee'
|
49
49
|
else
|
50
50
|
# for now any other js flavor gets the baseline .js
|
51
51
|
template 'namespace.js.erb', "app/assets/javascripts/application/#{name}#{js_extension_arg}"
|
52
|
-
template 'model.js.erb', "app/assets/javascripts/
|
52
|
+
template 'model.js.erb', "app/assets/javascripts/models/base#{js_extension_arg}"
|
53
53
|
end
|
54
54
|
|
55
55
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
2
|
// listed below.
|
3
3
|
//
|
4
|
-
//= require
|
5
|
-
//= require <%= which_sudo_arg %>
|
4
|
+
//= require sudojs/<%= which_sudo_arg %>
|
6
5
|
//= require application/<%= name %>
|
7
|
-
//= require
|
6
|
+
//= require models/base
|
@@ -1,9 +1,5 @@
|
|
1
1
|
# Global model is a sudo.Observable
|
2
|
-
class <%= name %>.
|
2
|
+
class <%= name %>.Base extends _.Model
|
3
3
|
constructor: (data) ->
|
4
4
|
super data
|
5
5
|
$.extend @, _.extensions.observable
|
6
|
-
|
7
|
-
# attach the model to the <%= name %> namespace
|
8
|
-
<%= name %>.model = new <%= name %>.Model()
|
9
|
-
|
@@ -1,9 +1,7 @@
|
|
1
1
|
// Global model is a sudo.Observable
|
2
|
-
<%= name %>.
|
2
|
+
<%= name %>.Base = function(data) {
|
3
3
|
this.construct(data);
|
4
4
|
$.extend(this, _.extensions.observable);
|
5
5
|
};
|
6
6
|
// `private`
|
7
|
-
<%= name %>.
|
8
|
-
// attach the model to the <%= name %> namespace
|
9
|
-
<%= name %>.model = new <%= name %>.Model();
|
7
|
+
<%= name %>.Base.prototype = Object.create(_.Model.prototype);
|
data/lib/sudojs/version.rb
CHANGED
@@ -423,6 +423,18 @@ sudo.Container.prototype.removeChild = function removeChild(arg) {
|
|
423
423
|
this._indexChildren_(i);
|
424
424
|
return this;
|
425
425
|
};
|
426
|
+
|
427
|
+
// ###removeChildren
|
428
|
+
// Remove all children, removing the name references and index
|
429
|
+
// This method calls removeFromParent on each child. If it's a DataView also removes the child's DOM.
|
430
|
+
// `returns` {Object} `this`
|
431
|
+
sudo.Container.prototype.removeChildren = function removeChildren(arg) {
|
432
|
+
while(this.children.length) {
|
433
|
+
this.children.shift().removeFromParent();
|
434
|
+
}
|
435
|
+
return this;
|
436
|
+
};
|
437
|
+
|
426
438
|
// ###removeFromParent
|
427
439
|
// Remove this object from its parents list of children.
|
428
440
|
// Does not alter the dom - do that yourself by overriding this method
|
@@ -1021,7 +1033,7 @@ sudo.Navigator.prototype.setData = function setData() {
|
|
1021
1033
|
// Gather the necessary information about the current environment and
|
1022
1034
|
// bind to either (push|pop)state or hashchange.
|
1023
1035
|
// Also, if given an imcorrect URL for the current environment (hashchange
|
1024
|
-
// vs pushState) normalize it and set accordingly.
|
1036
|
+
// vs pushState) normalize it and set accordingly (or don't).
|
1025
1037
|
//
|
1026
1038
|
// `returns` {object} `this`
|
1027
1039
|
sudo.Navigator.prototype.start = function start() {
|
@@ -1043,26 +1055,31 @@ sudo.Navigator.prototype.start = function start() {
|
|
1043
1055
|
} else if (this.isHashChange) {
|
1044
1056
|
$(window).on('hashchange', this.handleChange.bind(this));
|
1045
1057
|
} else return;
|
1046
|
-
// Does the current URL need to changed? (hashchange vs popstate)
|
1047
1058
|
atRoot = window.location.pathname.replace(/[^\/]$/, '$&/') === this.data['root'];
|
1048
|
-
// somehow a
|
1049
|
-
if(this.
|
1050
|
-
|
1051
|
-
this.data.
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
+
// somehow a URL got here not in my 'format', unless explicitly told not too, correct this
|
1060
|
+
if(!this.data.stay) {
|
1061
|
+
if(this.isHashChange && !atRoot) {
|
1062
|
+
window.location.replace(this.data['root'] + window.location.search + '#' +
|
1063
|
+
this.data.fragment);
|
1064
|
+
// return early as browser will redirect
|
1065
|
+
return true;
|
1066
|
+
// the converse of the above
|
1067
|
+
} else if(this.isPushState && atRoot && window.location.hash) {
|
1068
|
+
tmp = this.getHash().replace(this.leadingStripper, '');
|
1069
|
+
window.history.replaceState({}, document.title, this.data['root'] +
|
1070
|
+
tmp + window.location.search);
|
1071
|
+
}
|
1059
1072
|
}
|
1060
1073
|
// TODO provide option to `go` from inital `start` state?
|
1061
1074
|
return this;
|
1062
1075
|
};
|
1063
|
-
//
|
1076
|
+
// ###urlChanged
|
1077
|
+
// Is a passed in fragment different from the one currently set at `this.get('fragment')`?
|
1078
|
+
// If so set the fragment to the passed fragment passed in (as well as any 'query' data), else
|
1079
|
+
// simply return false
|
1064
1080
|
//
|
1065
1081
|
// `param` {String} `fragment`
|
1082
|
+
// `returns` {bool}
|
1066
1083
|
sudo.Navigator.prototype.urlChanged = function urlChanged(fragment) {
|
1067
1084
|
var current = this.getFragment(fragment);
|
1068
1085
|
// nothing has changed
|
@@ -1569,7 +1586,7 @@ sudo.extensions.persistable = {
|
|
1569
1586
|
//
|
1570
1587
|
// `returns` {object} A normalized params object for the XHR call
|
1571
1588
|
_normalizeParams_: function _normalizeParams_(meth, opts, params) {
|
1572
|
-
opts || (opts = this.data.ajax);
|
1589
|
+
opts || (opts = $.extend({}, this.data.ajax));
|
1573
1590
|
opts.url || (opts.url = this.url(opts.baseUrl));
|
1574
1591
|
opts.type || (opts.type = meth);
|
1575
1592
|
opts.dataType || (opts.dataType = 'json');
|
@@ -1612,7 +1629,7 @@ sudo.extensions.persistable = {
|
|
1612
1629
|
//
|
1613
1630
|
// `returns` {object} jqXhr
|
1614
1631
|
_sendData_: function _sendData_(meth, params) {
|
1615
|
-
opts = this.data.ajax;
|
1632
|
+
opts = $.extend({}, this.data.ajax);
|
1616
1633
|
opts.contentType || (opts.contentType = 'application/json');
|
1617
1634
|
opts.data || (opts.data = this.data);
|
1618
1635
|
// non GET requests do not 'processData'
|
@@ -1672,9 +1689,9 @@ sudo.delegates.Change.prototype = Object.create(sudo.Model.prototype);
|
|
1672
1689
|
// `param` {string} `val`
|
1673
1690
|
// `returns` {object} this
|
1674
1691
|
sudo.delegates.Change.prototype.addFilter = function addFilter(key, val) {
|
1675
|
-
this.
|
1692
|
+
this.data.filters[key] = val;
|
1676
1693
|
return this;
|
1677
|
-
}
|
1694
|
+
};
|
1678
1695
|
// ###filter
|
1679
1696
|
// Change records are delivered here and filtered, calling any matching
|
1680
1697
|
// methods specified in `this.get('filters').
|
@@ -1702,6 +1719,15 @@ sudo.delegates.Change.prototype.filter = function filter(change) {
|
|
1702
1719
|
return this.delegator[filters[name]].call(this.delegator, obj);
|
1703
1720
|
}
|
1704
1721
|
};
|
1722
|
+
// ###removeFilter
|
1723
|
+
// Remove an entry from this object's hash of filters
|
1724
|
+
//
|
1725
|
+
// `param` {string} `key`
|
1726
|
+
// `returns` {object} this
|
1727
|
+
sudo.delegates.Change.prototype.removeFilter = function removeFilter(key) {
|
1728
|
+
delete this.data.filters[key];
|
1729
|
+
return this;
|
1730
|
+
};
|
1705
1731
|
// `private`
|
1706
1732
|
sudo.delegates.Change.prototype.role = 'change';
|
1707
1733
|
//##Data Delegate
|
@@ -1719,6 +1745,16 @@ sudo.delegates.Data = function(data) {
|
|
1719
1745
|
};
|
1720
1746
|
// inherits from Model
|
1721
1747
|
sudo.delegates.Data.prototype = Object.create(sudo.Model.prototype);
|
1748
|
+
// ###addFilter
|
1749
|
+
// Place an entry into this object's hash of filters
|
1750
|
+
//
|
1751
|
+
// `param` {string} `key`
|
1752
|
+
// `param` {string} `val`
|
1753
|
+
// `returns` {object} this
|
1754
|
+
sudo.delegates.Data.prototype.addFilter = function addFilter(key, val) {
|
1755
|
+
this.data.filters[key] = val;
|
1756
|
+
return this;
|
1757
|
+
};
|
1722
1758
|
// ###filter
|
1723
1759
|
// iterates over a given object literal and returns a value (if present)
|
1724
1760
|
// located at a given key or path
|
@@ -1743,10 +1779,19 @@ sudo.delegates.Data.prototype.filter = function(obj) {
|
|
1743
1779
|
}
|
1744
1780
|
}
|
1745
1781
|
};
|
1782
|
+
// ###removeFilter
|
1783
|
+
// Remove an entry from this object's hash of filters
|
1784
|
+
//
|
1785
|
+
// `param` {string} `key`
|
1786
|
+
// `returns` {object} this
|
1787
|
+
sudo.delegates.Data.prototype.removeFilter = function removeFilter(key) {
|
1788
|
+
delete this.data.filters[key];
|
1789
|
+
return this;
|
1790
|
+
};
|
1746
1791
|
// `private`
|
1747
1792
|
sudo.delegates.Data.prototype.role = 'data';
|
1748
1793
|
|
1749
1794
|
sudo.version = "0.9.4";
|
1750
1795
|
window.sudo = sudo;
|
1751
1796
|
if(typeof window._ === "undefined") window._ = sudo;
|
1752
|
-
}).call(this, this);
|
1797
|
+
}).call(this, this);
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sudojs-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -35,6 +35,7 @@ executables: []
|
|
35
35
|
extensions: []
|
36
36
|
extra_rdoc_files: []
|
37
37
|
files:
|
38
|
+
- .DS_Store
|
38
39
|
- .gitignore
|
39
40
|
- Gemfile
|
40
41
|
- LICENSE.txt
|
@@ -78,7 +79,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
79
|
version: '0'
|
79
80
|
segments:
|
80
81
|
- 0
|
81
|
-
hash:
|
82
|
+
hash: 67341650352489792
|
82
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
84
|
none: false
|
84
85
|
requirements:
|
@@ -87,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
88
|
version: '0'
|
88
89
|
segments:
|
89
90
|
- 0
|
90
|
-
hash:
|
91
|
+
hash: 67341650352489792
|
91
92
|
requirements: []
|
92
93
|
rubyforge_project:
|
93
94
|
rubygems_version: 1.8.25
|