bowline 0.1.6

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.
Files changed (59) hide show
  1. data/.gitignore +1 -0
  2. data/History.txt +4 -0
  3. data/MIT-LICENSE +20 -0
  4. data/Manifest.txt +58 -0
  5. data/README.txt +136 -0
  6. data/Rakefile +25 -0
  7. data/assets/jquery.bowline.js +96 -0
  8. data/assets/jquery.chain.js +2348 -0
  9. data/assets/jquery.js +3549 -0
  10. data/bin/bowline-gen +6 -0
  11. data/bowline.gemspec +45 -0
  12. data/examples/account.rb +31 -0
  13. data/examples/example.js +24 -0
  14. data/examples/tweets.rb +28 -0
  15. data/examples/twitter.html +39 -0
  16. data/examples/users.rb +37 -0
  17. data/lib/bowline.rb +42 -0
  18. data/lib/bowline/binders.rb +177 -0
  19. data/lib/bowline/binders/collection.rb +27 -0
  20. data/lib/bowline/binders/singleton.rb +25 -0
  21. data/lib/bowline/commands/console.rb +27 -0
  22. data/lib/bowline/commands/generate.rb +1 -0
  23. data/lib/bowline/commands/run.rb +11 -0
  24. data/lib/bowline/ext/array.rb +5 -0
  25. data/lib/bowline/ext/class.rb +51 -0
  26. data/lib/bowline/ext/object.rb +12 -0
  27. data/lib/bowline/ext/string.rb +9 -0
  28. data/lib/bowline/gem_dependency.rb +42 -0
  29. data/lib/bowline/generators.rb +59 -0
  30. data/lib/bowline/generators/application.rb +58 -0
  31. data/lib/bowline/generators/binder.rb +25 -0
  32. data/lib/bowline/generators/migration.rb +51 -0
  33. data/lib/bowline/generators/model.rb +20 -0
  34. data/lib/bowline/initializer.rb +596 -0
  35. data/lib/bowline/jquery.rb +31 -0
  36. data/lib/bowline/observer.rb +43 -0
  37. data/lib/bowline/tasks/app.rake +90 -0
  38. data/lib/bowline/tasks/bowline.rb +8 -0
  39. data/lib/bowline/tasks/database.rake +167 -0
  40. data/lib/bowline/tasks/log.rake +9 -0
  41. data/lib/bowline/tasks/misk.rake +3 -0
  42. data/templates/Rakefile +7 -0
  43. data/templates/binder.rb +9 -0
  44. data/templates/config/application.yml +1 -0
  45. data/templates/config/boot.rb +13 -0
  46. data/templates/config/database.yml +4 -0
  47. data/templates/config/environment.rb +12 -0
  48. data/templates/config/manifest +18 -0
  49. data/templates/config/tiapp.xml +24 -0
  50. data/templates/gitignore +15 -0
  51. data/templates/migration.rb +7 -0
  52. data/templates/model.rb +4 -0
  53. data/templates/public/index.html +25 -0
  54. data/templates/public/javascripts/application.js +0 -0
  55. data/templates/public/stylesheets/application.css +0 -0
  56. data/templates/script/console +3 -0
  57. data/templates/script/init +18 -0
  58. data/templates/script/run +3 -0
  59. metadata +155 -0
data/bin/bowline-gen ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__), *%w[.. lib bowline])
4
+ require 'bowline/generators'
5
+
6
+ Bowline::Generators.run_cli(Dir.pwd, 'bowline', Bowline::VERSION, ARGV)
data/bowline.gemspec ADDED
@@ -0,0 +1,45 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bowline}
5
+ s.version = "0.1.6"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Alex MacCaw"]
9
+ s.date = %q{2009-04-24}
10
+ s.default_executable = %q{bowline-gen}
11
+ s.description = %q{Ruby desktop application framework}
12
+ s.email = ["info@eribium.org"]
13
+ s.executables = ["bowline-gen"]
14
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
15
+ s.files = [".gitignore", "History.txt", "MIT-LICENSE", "Manifest.txt", "README.txt", "Rakefile", "assets/jquery.bowline.js", "assets/jquery.chain.js", "assets/jquery.js", "bin/bowline-gen", "bowline.gemspec", "examples/account.rb", "examples/example.js", "examples/twitter.html", "examples/tweets.rb", "examples/users.rb", "lib/bowline.rb", "lib/bowline/binders.rb", "lib/bowline/binders/collection.rb", "lib/bowline/binders/singleton.rb", "lib/bowline/commands/console.rb", "lib/bowline/commands/generate.rb", "lib/bowline/commands/run.rb", "lib/bowline/ext/array.rb", "lib/bowline/ext/class.rb", "lib/bowline/ext/object.rb", "lib/bowline/ext/string.rb", "lib/bowline/gem_dependency.rb", "lib/bowline/generators.rb", "lib/bowline/generators/application.rb", "lib/bowline/generators/binder.rb", "lib/bowline/generators/migration.rb", "lib/bowline/generators/model.rb", "lib/bowline/initializer.rb", "lib/bowline/jquery.rb", "lib/bowline/observer.rb", "lib/bowline/tasks/app.rake", "lib/bowline/tasks/bowline.rb", "lib/bowline/tasks/database.rake", "lib/bowline/tasks/log.rake", "lib/bowline/tasks/misk.rake", "templates/Rakefile", "templates/binder.rb", "templates/config/application.yml", "templates/config/boot.rb", "templates/config/database.yml", "templates/config/environment.rb", "templates/config/manifest", "templates/config/tiapp.xml", "templates/gitignore", "templates/migration.rb", "templates/model.rb", "templates/public/index.html", "templates/public/javascripts/application.js", "templates/public/stylesheets/application.css", "templates/script/console", "templates/script/init", "templates/script/run"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/maccman/bowline}
18
+ s.rdoc_options = ["--main", "README.txt"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{maccman}
21
+ s.rubygems_version = %q{1.3.2}
22
+ s.summary = %q{Ruby desktop application framework}
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 3
27
+
28
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
+ s.add_runtime_dependency(%q<templater>, [">= 0.3.2"])
30
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.2"])
31
+ s.add_development_dependency(%q<newgem>, [">= 1.3.0"])
32
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
33
+ else
34
+ s.add_dependency(%q<templater>, [">= 0.3.2"])
35
+ s.add_dependency(%q<activesupport>, [">= 2.3.2"])
36
+ s.add_dependency(%q<newgem>, [">= 1.3.0"])
37
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
38
+ end
39
+ else
40
+ s.add_dependency(%q<templater>, [">= 0.3.2"])
41
+ s.add_dependency(%q<activesupport>, [">= 2.3.2"])
42
+ s.add_dependency(%q<newgem>, [">= 1.3.0"])
43
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ module Binders
2
+ class Account < Bowline::Binders::Singleton
3
+ class << self
4
+ # self.collection is a special method
5
+ # Basically it'll update users on the client side
6
+ def index
7
+ self.item = current_account
8
+ end
9
+
10
+ def destroy
11
+ current_account.destroy
12
+ self.item = nil
13
+ end
14
+ end
15
+
16
+ # Everything has a js_id which is basically the lowercase classname + _ + self.id
17
+ def highlight
18
+ # Calls $(element).highlight()
19
+ self.element.highlight
20
+ end
21
+
22
+ # Overrides charge on user
23
+ def charge!
24
+ # calls charge on model (i.e. do sql commit )
25
+ self.item.charge!
26
+ # Now gui stuff
27
+ flash[:notice] = "Successfully charged"
28
+ highlight
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ $('#users').bowline('users_binder');
2
+
3
+ var user = $('#users').items(10);
4
+ user.update({name: 'Alex'}); // will automatiinvokey
5
+ user.item().errors //=> []
6
+
7
+ // Deletes item from DOM too
8
+ item.destroy()
9
+
10
+ // invoke collection method
11
+ // This will invoke UserBinder.admins and fill #users with admins
12
+ $('#users').invoke('admins');
13
+
14
+ // invoke singleton method
15
+ $('#users').items(10).invoke('charge!');
16
+
17
+ // invoke charge! on every user
18
+ $('#users').items().invoke('charge!')
19
+
20
+ // // For binding over a http connection - an async invoke
21
+ // // last argument is a function
22
+ // $('#users').items(10).invoke('charge!', function(){
23
+ //
24
+ // })
@@ -0,0 +1,28 @@
1
+ module Binders
2
+ class Tweets < Bowline::Binders::Collection
3
+ class << self
4
+ def index
5
+ self.items = timeline
6
+ end
7
+
8
+ def update(status)
9
+ twitter.update(status)
10
+ index # update timeline
11
+ end
12
+
13
+ protected
14
+ def twitter
15
+ httpauth = Twitter::HTTPAuth.new('user', 'pass')
16
+ Twitter::Base.new(httpauth)
17
+ end
18
+
19
+ def timeline
20
+ twitter.friends_timeline.collect {|t|
21
+ t.delete('user')
22
+ t.to_hash
23
+ }
24
+ end
25
+ end
26
+
27
+ end
28
+ end # Binders
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
2
+ "http://www.w3.org/TR/html4/strict.dtd">
3
+
4
+ <html lang="en">
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
7
+ <title>Twitter</title>
8
+ <!--
9
+ <script src="http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js" type="text/javascript"></script>
10
+ -->
11
+ <script src="javascripts/jquery.js" type="text/javascript" charset="utf-8"></script>
12
+ <script src="javascripts/jquery.chain.js" type="text/javascript" charset="utf-8"></script>
13
+ <script src="javascripts/jquery.bowline.js" type="text/javascript" charset="utf-8"></script>
14
+ <script src="../script/init" type="text/ruby" charset="utf-8"></script>
15
+ <script src="javascripts/application.js" type="text/javascript" charset="utf-8"></script>
16
+ <link rel="stylesheet" href="stylesheets/application.css" type="text/css" charset="utf-8">
17
+ <script type="text/javascript" charset="utf-8">
18
+ jQuery(function($){
19
+ var tweets = $('#tweets').bowline('tweets');
20
+ tweets.invoke('index');
21
+
22
+ $('#updateSubmit').click(function(){
23
+ tweets.invoke('update', $('#updateText').val());
24
+ return false;
25
+ })
26
+ });
27
+ </script>
28
+ </head>
29
+ <body>
30
+ <div id="tweets">
31
+ <div class="item">
32
+ <span class="text"></span>
33
+ </div>
34
+ </div>
35
+
36
+ <input type="text" id="updateText">
37
+ <input type="submit" value="Update &rarr;" id="updateSubmit">
38
+ </body>
39
+ </html>
data/examples/users.rb ADDED
@@ -0,0 +1,37 @@
1
+ module Binders
2
+ class Users < Bowline::Binders::Collection
3
+ class << self
4
+ # self.items is a special method
5
+ # Basically it'll update users on the client side
6
+ def index
7
+ self.items = User.all
8
+ end
9
+
10
+ def admins
11
+ self.items = User.admins.all
12
+ end
13
+ end
14
+
15
+ def update(attrs)
16
+ if @item.update_attributes(attrs)
17
+ flash[:notice] = "Successfully updated"
18
+ else
19
+ flash[:notice] = "Errors updating users"
20
+ end
21
+ end
22
+
23
+ def highlight
24
+ # Calls $('user_1').highlight()
25
+ self.element.highlight
26
+ end
27
+
28
+ # Overrides charge on user
29
+ def charge!
30
+ # calls charge! on model (i.e. do sql commit )
31
+ self.item.charge!
32
+ # Now gui stuff
33
+ flash[:notice] = "Successfully charged"
34
+ highlight
35
+ end
36
+ end
37
+ end
data/lib/bowline.rb ADDED
@@ -0,0 +1,42 @@
1
+ module Bowline
2
+ VERSION = '0.1.6'
3
+
4
+ # The raw JavaScript window object
5
+ def self.js
6
+ if defined?($app_window)
7
+ $app_window
8
+ else
9
+ Class.new {
10
+ def self.method_missing(*a)
11
+ Bowline.logger.info "Sending to Window: #{a.inspect}"
12
+ self
13
+ end
14
+ }
15
+ end
16
+ end
17
+
18
+ # Change which page we're on
19
+ def self.show_view(name)
20
+ js.window.location = "app://public/#{name}.html"
21
+ end
22
+
23
+ class Base
24
+ end
25
+ end
26
+
27
+ $LOAD_PATH << File.dirname(__FILE__)
28
+
29
+ require 'bowline/ext/object'
30
+ require 'bowline/ext/array'
31
+ require 'bowline/ext/class'
32
+ require 'bowline/ext/string'
33
+
34
+ require 'bowline/gem_dependency'
35
+ require 'bowline/initializer'
36
+
37
+ require 'bowline/jquery'
38
+ require 'bowline/observer'
39
+
40
+ require 'bowline/binders'
41
+ require 'bowline/binders/collection'
42
+ require 'bowline/binders/singleton'
@@ -0,0 +1,177 @@
1
+ module Bowline
2
+ module Binders
3
+ class Base
4
+ cattr_accessor :params
5
+
6
+ class << self
7
+ # See Bowline::js
8
+ def js
9
+ Bowline::js
10
+ end
11
+
12
+ # Equivalent of the 'jQuery' function
13
+ def jquery
14
+ @@jquery ||= JQuery.new
15
+ end
16
+
17
+ # See the Observer class
18
+ def observer
19
+ @@observer ||= Observer.new
20
+ end
21
+
22
+ # See Bowline::logger
23
+ def logger
24
+ Bowline::logger
25
+ end
26
+
27
+ # See Bowline::show_view
28
+ def show_view(*args)
29
+ Bowline::show_view(*args)
30
+ end
31
+
32
+ def params=(p)
33
+ case p
34
+ when String
35
+ # Params comes in a string (since it's a
36
+ # serialized form) - we need to make it into
37
+ # a nestled hash.
38
+ # Stolen from Ramaze
39
+ m = proc {|_,o,n|o.merge(n,&m)}
40
+ @@params = params.inject({}) do |hash, (key, value)|
41
+ parts = key.split(/[\]\[]+/)
42
+ hash.merge(parts.reverse.inject(value) { |x, i| {i => x} }, &m)
43
+ end
44
+ else
45
+ @@params = p
46
+ end
47
+ end
48
+
49
+ def setup(d)
50
+ @@elements ||= []
51
+ @@elements << d
52
+ self.item_sync!
53
+ end
54
+
55
+ def instance(el)
56
+ self.new(el).method(:send)
57
+ end
58
+
59
+ # todo - flash?
60
+
61
+ def inherited(child)
62
+ return if self == Bowline::Binders::Base
63
+ return if child == Bowline::Binders::Singleton
64
+ return if child == Bowline::Binders::Collection
65
+ name = child.name.underscore
66
+ name = name.split('/').last
67
+ js.send("bowline_#{name}_setup=", child.method(:setup))
68
+ js.send("bowline_#{name}_instance=", child.method(:instance))
69
+ js.send("bowline_#{name}=", child.method(:send))
70
+ end
71
+ end
72
+
73
+ attr_reader :element
74
+ attr_reader :item
75
+
76
+ # Todo
77
+ # We want initialize method to take
78
+ # no argument, and for every item in items
79
+ # to have initialize called on startup,
80
+ # so they can set up event handlers etc
81
+ def self.new(element, *args) #:nodoc:
82
+ allocate.instance_eval do
83
+ # jQuery element
84
+ @element = element
85
+ # Calling chain.js 'item' function
86
+ @item = element.item()
87
+ if @item
88
+ @item.with_indifferent_access
89
+ # If possible, find Ruby object
90
+ if @item[:id] && respond_to?(:find)
91
+ @item = find(@item[:id])
92
+ end
93
+ end
94
+
95
+ initialize(*args)
96
+ self
97
+ end
98
+ end
99
+
100
+ # Trigger jQuery events on this element
101
+ def trigger(event, data = nil)
102
+ self.element.trigger(event, data)
103
+ end
104
+
105
+ # Bind event to element:
106
+ # bind(:click) { puts "element clicked" }
107
+ # todo - two events with the same item/event overwrite each other
108
+ # todo - need initalize method on class - so we can set events there
109
+ def bind(event, method_name, &block)
110
+ event_name = [event, item_id].join(":")
111
+ callback = block
112
+ callback ||= begin
113
+ method_name.is_a?(Method) ?
114
+ method_name : method(method_name)
115
+ end
116
+ self.observer.append(event_name, callback)
117
+ self.element.bind(
118
+ event.to_s,
119
+ event_name,
120
+ self.observer.method(:call)
121
+ )
122
+ end
123
+
124
+ def click(method_name = nil, &block)
125
+ bind(:click, method, &block)
126
+ end
127
+
128
+ # Raw DOM element
129
+ def dom
130
+ self.element[0]
131
+ end
132
+
133
+ # Shortcut methods
134
+
135
+ # See self.class.show_view
136
+ def show_view(*args)
137
+ self.class.show_view(*args)
138
+ end
139
+
140
+ # See self.class.js
141
+ def js
142
+ self.class.js
143
+ end
144
+ alias :page :js
145
+
146
+ # See self.class.jquery
147
+ def jquery
148
+ self.class.jquery
149
+ end
150
+
151
+ # See self.class.observer
152
+ def observer
153
+ self.class.observer
154
+ end
155
+
156
+ # See self.class.logger
157
+ def logger
158
+ self.class.logger
159
+ end
160
+
161
+ private
162
+ # This is just a unique identifier
163
+ # for the item - and isn't
164
+ # used in the dom
165
+ def item_id
166
+ if item.respond_to?(:dom_id)
167
+ item.dom_id
168
+ else
169
+ [
170
+ item.id,
171
+ self.class.name.underscore
172
+ ].join("_")
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,27 @@
1
+ module Bowline
2
+ module Binders
3
+ class Collection < Base
4
+ cattr_accessor :items
5
+ class << self
6
+ def items=(args)
7
+ @@items = args
8
+ self.item_sync!
9
+ @@items
10
+ end
11
+
12
+ def item_sync!
13
+ return unless @@items && @@elements
14
+ @@elements.each {|i|
15
+ i.updateCollection(@@items.to_js)
16
+ }
17
+ end
18
+
19
+ def find(id)
20
+ @@items.find {|item|
21
+ item.id == id if item.respond_to?(:id)
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end