sudojs-rails 0.3.6 → 0.3.8

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/.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