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 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
- if @parent
37
- if @parent == '_.Base' || @parent == '_.Model' || @parent == '_.Container'
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
- else
61
+ @js_path = @js_model_path
62
+ @js_req = 'models'
63
+ when '_.View', '_.ViewController', 'DataView'
40
64
  @args = 'el, data'
41
- end
42
- else
43
- # cannot guess the args to a custom class
44
- @args = '/* args */'
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
- path = 'app/assets/javascripts/application'
52
- css_path = 'app/assets/stylesheets/application'
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
- path = "app/assets/javascripts/views/#{@c_name}"
56
- css_path = "app/assets/stylesheets/views/#{@c_name}"
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(path, css_path)
90
+ ensure_cname_dir(js_path, css_path)
61
91
  else
62
- ensure_cname_dir(path)
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', "#{path}/#{@a_name}.js.coffee"
98
+ template 'class.coffee.erb', "#{js_path}/#{@a_name}.js.coffee"
69
99
  else
70
- template 'class.js.erb', "#{path}/#{@a_name}#{js_extension}"
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
- line = js_pre + rest_app
89
- css_line = css_pre + rest_app + "\n"
114
+ req = "require application/#{@a_name}"
90
115
  else
91
- line = js_pre + rest_view
92
- css_line = css_pre + rest_view + "\n"
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
- // optional init method for your new viewController, delete if unused
13
- <%= @path_to_object %>.<%= @a_pascal %>.prototype.init = function init() {};
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
+ });
@@ -26,9 +26,10 @@ Example:
26
26
  javascripts/
27
27
  application/
28
28
  yourNamespace.js
29
- model.js
30
29
  manifests/
31
30
  application.js
31
+ models/
32
+ base.js
32
33
  views/
33
34
  config/
34
35
  sudo_js.yml
@@ -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/application/model.js.coffee'
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/application/model#{js_extension_arg}"
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 jquery_ujs
5
- //= require <%= which_sudo_arg %>
4
+ //= require sudojs/<%= which_sudo_arg %>
6
5
  //= require application/<%= name %>
7
- //= require application/model
6
+ //= require models/base
@@ -1,9 +1,5 @@
1
1
  # Global model is a sudo.Observable
2
- class <%= name %>.Model extends _.Model
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 %>.Model = function(data) {
2
+ <%= name %>.Base = function(data) {
3
3
  this.construct(data);
4
4
  $.extend(this, _.extensions.observable);
5
5
  };
6
6
  // `private`
7
- <%= name %>.Model.prototype = Object.create(_.Model.prototype);
8
- // attach the model to the <%= name %> namespace
9
- <%= name %>.model = new <%= name %>.Model();
7
+ <%= name %>.Base.prototype = Object.create(_.Model.prototype);
@@ -1,3 +1,3 @@
1
1
  module Sudojs
2
- VERSION = '0.3.6'
2
+ VERSION = '0.3.8'
3
3
  end
@@ -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 pushstate URL got here (and here is hashchange)
1049
- if(this.isHashChange && !atRoot) {
1050
- window.location.replace(this.data['root'] + window.location.search + '#' +
1051
- this.data.fragment);
1052
- // return early as browser will redirect
1053
- return true;
1054
- // the converse of the above
1055
- } else if(this.isPushState && atRoot && window.location.hash) {
1056
- tmp = this.getHash().replace(this.leadingStripper, '');
1057
- window.history.replaceState({}, document.title, this.data['root'] +
1058
- tmp + window.location.search);
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
- // Is a passed in fragment different from the currently set one?
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.get('filters')[key] = val;
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.6
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-03-16 00:00:00.000000000 Z
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: -973221170454478308
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: -973221170454478308
91
+ hash: 67341650352489792
91
92
  requirements: []
92
93
  rubyforge_project:
93
94
  rubygems_version: 1.8.25