bowline 0.5.3 → 0.5.4
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 +1 -0
- data/README.txt +62 -62
- data/Rakefile +10 -0
- data/TODO +3 -1
- data/VERSION +1 -1
- data/assets/bowline.js +118 -3
- data/bowline.gemspec +6 -6
- data/examples/example.js +2 -15
- data/examples/tweet.rb +35 -0
- data/examples/tweets_binder.rb +6 -0
- data/examples/twitter.html +6 -8
- data/examples/users.rb +8 -14
- data/lib/bowline/binders.rb +130 -42
- data/lib/bowline/dependencies/lib/dependencies.rb +2 -1
- data/lib/bowline/dependencies/lib/ext/rubygems.rb +4 -4
- data/lib/bowline/desktop.rb +11 -2
- data/lib/bowline/desktop/app.rb +7 -3
- data/lib/bowline/desktop/bridge.rb +8 -9
- data/lib/bowline/desktop/clipboard.rb +11 -2
- data/lib/bowline/desktop/dialog.rb +19 -0
- data/lib/bowline/desktop/dock.rb +14 -3
- data/lib/bowline/desktop/host.rb +13 -4
- data/lib/bowline/desktop/js.rb +2 -2
- data/lib/bowline/desktop/misc.rb +7 -3
- data/lib/bowline/desktop/network.rb +1 -1
- data/lib/bowline/desktop/proxy.rb +28 -30
- data/lib/bowline/desktop/sound.rb +3 -2
- data/lib/bowline/desktop/window.rb +147 -21
- data/lib/bowline/desktop/window_manager.rb +53 -5
- data/lib/bowline/desktop/window_methods.rb +2 -2
- data/lib/bowline/ext/object.rb +1 -1
- data/lib/bowline/generators.rb +1 -1
- data/lib/bowline/generators/binder.rb +1 -1
- data/lib/bowline/helpers.rb +1 -1
- data/lib/bowline/initializer.rb +37 -4
- data/lib/bowline/library.rb +11 -0
- data/lib/bowline/local_model.rb +45 -19
- data/lib/bowline/logging.rb +1 -1
- data/lib/bowline/platform.rb +8 -6
- data/lib/bowline/tasks/app.rake +4 -3
- data/lib/bowline/version.rb +1 -1
- data/lib/bowline/watcher.rb +18 -8
- data/templates/binder.rb +1 -1
- data/vendor/pathname.rb +0 -4
- metadata +6 -6
- data/examples/account.rb +0 -31
- data/examples/tweets.rb +0 -28
data/examples/tweet.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Tweet < Bowline::LocalModel
|
2
|
+
class << self
|
3
|
+
def poll
|
4
|
+
destroy_all
|
5
|
+
populate(timeline)
|
6
|
+
end
|
7
|
+
|
8
|
+
def timeline
|
9
|
+
twitter.friends_timeline.collect {|t|
|
10
|
+
t.delete('user')
|
11
|
+
t.to_hash
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def update(status)
|
16
|
+
twitter.update(status)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def twitter
|
21
|
+
httpauth = Twitter::HTTPAuth.new(
|
22
|
+
AppConfig.username,
|
23
|
+
AppConfig.password
|
24
|
+
)
|
25
|
+
Twitter::Base.new(httpauth)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Thread.new do
|
31
|
+
loop do
|
32
|
+
Tweet.poll
|
33
|
+
sleep 60
|
34
|
+
end
|
35
|
+
end
|
data/examples/twitter.html
CHANGED
@@ -6,18 +6,16 @@
|
|
6
6
|
<link rel="stylesheet" href="stylesheets/application.css" type="text/css" charset="utf-8">
|
7
7
|
<script src="javascripts/jquery.js" type="text/javascript" charset="utf-8"></script>
|
8
8
|
<script src="javascripts/jquery.chain.js" type="text/javascript" charset="utf-8"></script>
|
9
|
-
|
9
|
+
<script src="javascripts/json2.js" type="text/javascript" charset="utf-8"></script>
|
10
|
+
<script src="javascripts/bowline.js" type="text/javascript" charset="utf-8"></script>
|
10
11
|
<script src="javascripts/application.js" type="text/javascript" charset="utf-8"></script>
|
11
12
|
<script type="text/javascript" charset="utf-8">
|
12
13
|
jQuery(function($){
|
13
|
-
|
14
|
-
var tweets = $('#tweets').bowline('tweets');
|
15
|
-
tweets.invoke('index');
|
14
|
+
var tweets = $('#tweets').bindto('tweets');
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
});
|
16
|
+
$('#updateSubmit').click(function(){
|
17
|
+
tweets.invoke('update', $('#updateText').val());
|
18
|
+
return false;
|
21
19
|
});
|
22
20
|
});
|
23
21
|
</script>
|
data/examples/users.rb
CHANGED
@@ -1,12 +1,7 @@
|
|
1
1
|
module Binders
|
2
|
-
class Users < Bowline::Binders::
|
3
|
-
|
4
|
-
|
5
|
-
# Basically it'll update users on the client side
|
6
|
-
def index
|
7
|
-
self.items = User.all
|
8
|
-
end
|
9
|
-
|
2
|
+
class Users < Bowline::Binders::Base
|
3
|
+
bind User
|
4
|
+
class << self
|
10
5
|
def admins
|
11
6
|
self.items = User.admins.all
|
12
7
|
end
|
@@ -14,23 +9,22 @@ module Binders
|
|
14
9
|
|
15
10
|
def update(attrs)
|
16
11
|
if @item.update_attributes(attrs)
|
17
|
-
flash
|
12
|
+
page.flash("Successfully updated").call
|
18
13
|
else
|
19
|
-
|
14
|
+
page.flash_error("Errors updating users").call
|
20
15
|
end
|
21
16
|
end
|
22
17
|
|
23
18
|
def highlight
|
24
19
|
# Calls $('user_1').highlight()
|
25
|
-
self.element.highlight
|
20
|
+
self.element.highlight.call
|
26
21
|
end
|
27
22
|
|
28
|
-
# Overrides charge on user
|
29
23
|
def charge!
|
30
|
-
# calls charge! on model (i.e. do
|
24
|
+
# calls charge! on model (i.e. do SQL commit )
|
31
25
|
self.item.charge!
|
32
26
|
# Now gui stuff
|
33
|
-
flash
|
27
|
+
page.flash("Charged!")
|
34
28
|
highlight
|
35
29
|
end
|
36
30
|
end
|
data/lib/bowline/binders.rb
CHANGED
@@ -1,23 +1,87 @@
|
|
1
1
|
module Bowline
|
2
2
|
module Binders
|
3
|
+
# Binders are a central part of Bowline. They perform two main functions:
|
4
|
+
# 1) Bind a model to the view, so any changes to the model get automatically
|
5
|
+
# reflected in the view.
|
6
|
+
# 2) View abstraction of the model. You can define view specific class & instance
|
7
|
+
# methods, and easily call them from bound JavaScript objects.
|
8
|
+
#
|
9
|
+
# To use a binder, you first need to bind it to a model using the bind method.
|
10
|
+
# Example:
|
11
|
+
# class UsersBinder < Bowline::Binders::Base
|
12
|
+
# bind User
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Once a class is bound, any updates to the model automatically update any bound HTML.
|
16
|
+
# The class names in the HTML are tied to the model's attribute names.
|
17
|
+
# You can bind HTML using the bowline.js bindup function.
|
18
|
+
# Example:
|
19
|
+
# <div id="users">
|
20
|
+
# <div class="item">
|
21
|
+
# <span class="name"></span>
|
22
|
+
# </div>
|
23
|
+
# </div>
|
24
|
+
# <script>
|
25
|
+
# $("#users").bindup('UsersBinder');
|
26
|
+
# </script>
|
27
|
+
#
|
28
|
+
# =Class methods
|
29
|
+
#
|
30
|
+
# You can define class methods on your binder, and call them using JavaScript
|
31
|
+
# using the invoke function on the bound HTML element.
|
32
|
+
# Example:
|
33
|
+
# <script>
|
34
|
+
# var users = $("#users").bindup('UsersBinder');
|
35
|
+
# users.invoke("method_name", "arg1", "arg2")
|
36
|
+
# </script>
|
37
|
+
#
|
38
|
+
# =Instance methods
|
39
|
+
#
|
40
|
+
# You can call your binders instance method from JavaScript by calling the invoke
|
41
|
+
# function on the generated HTML elements. Your binder's instance methods have access
|
42
|
+
# to an 'element' variable, which is the jQuery element, and a 'item' variable, which
|
43
|
+
# is the bound model's instance record.
|
44
|
+
#
|
45
|
+
# Example:
|
46
|
+
# class UsersBinder < Bowline::Binders::Base
|
47
|
+
# bind User
|
48
|
+
# def charge!
|
49
|
+
# #...
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# <script>
|
54
|
+
# $('#users').items(10).invoke('charge!');
|
55
|
+
# </script>
|
56
|
+
#
|
57
|
+
# For more documentation on Bowline's JavaScript API, see bowline.js
|
3
58
|
class Base
|
4
59
|
extend Bowline::Watcher::Base
|
5
60
|
extend Bowline::Desktop::Bridge::ClassMethods
|
6
61
|
js_expose
|
7
62
|
|
8
63
|
class << self
|
64
|
+
# An array of window currently bound.
|
9
65
|
def windows
|
10
66
|
@windows ||= []
|
11
67
|
end
|
12
68
|
|
13
|
-
# Called by
|
14
|
-
|
69
|
+
# Called by a window's JavaScript whenever that window is bound to this Binder.
|
70
|
+
# This method populates the window's HTML with all bound class' records.
|
71
|
+
# Override this if you don't want to send all the class' records to the window.
|
72
|
+
# Example:
|
73
|
+
# def setup(window)
|
74
|
+
# super(window, last_10_tweets)
|
75
|
+
# end
|
76
|
+
def setup(window, items = all)
|
15
77
|
self.windows << window
|
16
|
-
|
78
|
+
window.bowline.populate(
|
79
|
+
name, items.to_js
|
80
|
+
).call
|
17
81
|
true
|
18
82
|
end
|
19
83
|
|
20
|
-
def js_invoke(window, method, *args)
|
84
|
+
def js_invoke(window, method, *args) #:nodoc:
|
21
85
|
if method == :setup
|
22
86
|
setup(window)
|
23
87
|
else
|
@@ -29,19 +93,28 @@ module Bowline
|
|
29
93
|
self.new(id).send(meth, *args)
|
30
94
|
end
|
31
95
|
|
96
|
+
# Calls .find on the klass sent to the bind method.
|
97
|
+
# This is used internally, to find records when the page
|
98
|
+
# invoke instance methods.
|
32
99
|
def find(id)
|
33
100
|
klass.find(id)
|
34
101
|
end
|
35
|
-
|
102
|
+
|
103
|
+
# Calls .all on the klass sent to the bind method.
|
104
|
+
# This method is called internally by the setup method.
|
36
105
|
def all
|
37
106
|
klass.all
|
38
107
|
end
|
39
108
|
|
40
|
-
|
109
|
+
# Set the binder's items. This will replace all items, and update the HTML.
|
110
|
+
def items=(items)
|
41
111
|
bowline.populate(name, items.to_js).call
|
42
112
|
end
|
43
113
|
|
44
|
-
|
114
|
+
# Add a new item to the binder, updating the HTML.
|
115
|
+
# This method is normally only called internally by
|
116
|
+
# the bound class's after_create callback.
|
117
|
+
def created(item)
|
45
118
|
bowline.created(
|
46
119
|
name,
|
47
120
|
item.id,
|
@@ -49,7 +122,10 @@ module Bowline
|
|
49
122
|
).call
|
50
123
|
end
|
51
124
|
|
52
|
-
|
125
|
+
# Update an item on the binder, updating the HTML.
|
126
|
+
# This method is normally only called internally by
|
127
|
+
# the bound class's after_update callback.
|
128
|
+
def updated(item)
|
53
129
|
bowline.updated(
|
54
130
|
name,
|
55
131
|
item.id,
|
@@ -57,7 +133,10 @@ module Bowline
|
|
57
133
|
).call
|
58
134
|
end
|
59
135
|
|
60
|
-
|
136
|
+
# Remove an item from the binder, updating the HTML.
|
137
|
+
# This method is normally only called internally by
|
138
|
+
# the bound class's after_destroy callback.
|
139
|
+
def removed(item)
|
61
140
|
bowline.removed(
|
62
141
|
name,
|
63
142
|
item.id
|
@@ -65,41 +144,45 @@ module Bowline
|
|
65
144
|
end
|
66
145
|
|
67
146
|
protected
|
68
|
-
# Associate the binder with a model
|
69
|
-
# to
|
70
|
-
#
|
71
|
-
#
|
72
|
-
# expose Post
|
147
|
+
# Associate the binder with a model to setup callbacks so
|
148
|
+
# changes to the model are automatically reflected in the view.
|
149
|
+
# Example:
|
150
|
+
# bind Post
|
73
151
|
#
|
74
|
-
# When the
|
152
|
+
# When the bound class is created/updated/deleted
|
75
153
|
# the binder's callbacks are executed and the view
|
76
154
|
# updated accordingly.
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
# *
|
82
|
-
# *
|
83
|
-
# *
|
155
|
+
#
|
156
|
+
# Classes inheriting fromActiveRecord and Bowline::LocalModel are
|
157
|
+
# automatically compatable, but if you're using your own custom model
|
158
|
+
# you need to make sure it responds to the following methods:
|
159
|
+
# * all - return all records
|
160
|
+
# * find(id) - find record by id
|
161
|
+
# * after_create(method) - after_create callback
|
162
|
+
# * after_update(method) - after_update callback
|
163
|
+
# * after_destroy(method) - after_destroy callback
|
84
164
|
#
|
85
|
-
# klass instance needs to respond to:
|
86
|
-
# * id
|
165
|
+
# The klass' instance needs to respond to:
|
166
|
+
# * id - returns record id
|
167
|
+
# * to_js - return record's attribute hash
|
87
168
|
#
|
88
|
-
# You can override
|
89
|
-
# in order to return specific attributes for the view
|
90
|
-
def
|
169
|
+
# You can override the to_js method on the model instance
|
170
|
+
# in order to return specific attributes for the view.
|
171
|
+
def bind(klass)
|
91
172
|
@klass = klass
|
92
173
|
@klass.after_create(method(:created))
|
93
174
|
@klass.after_update(method(:updated))
|
94
175
|
@klass.after_destroy(method(:removed))
|
95
176
|
end
|
96
177
|
|
97
|
-
# Returns class set by the '
|
178
|
+
# Returns class set by the 'bind' method
|
98
179
|
def klass
|
99
|
-
@klass || raise("klass not set - see
|
180
|
+
@klass || raise("klass not set - see bind method")
|
100
181
|
end
|
101
182
|
|
102
|
-
# JavaScript proxy to the page
|
183
|
+
# JavaScript proxy to the page.
|
184
|
+
# See Bowline::Desktop::Proxy for more information.
|
185
|
+
# Example:
|
103
186
|
# page.myFunc(1,2,3).call
|
104
187
|
def page
|
105
188
|
Bowline::Desktop::Proxy.new(
|
@@ -107,14 +190,18 @@ module Bowline
|
|
107
190
|
)
|
108
191
|
end
|
109
192
|
|
110
|
-
# JavaScript proxy to the Bowline object
|
193
|
+
# JavaScript proxy to the Bowline object.
|
194
|
+
# See Bowline::Desktop::Proxy for more information.
|
195
|
+
# Example:
|
111
196
|
# bowline.log("msg").call
|
112
197
|
def bowline
|
113
198
|
page.Bowline
|
114
199
|
end
|
115
200
|
|
116
|
-
# Javascript proxy to jQuery
|
117
|
-
#
|
201
|
+
# Javascript proxy to jQuery.
|
202
|
+
# See Bowline::Desktop::Proxy for more information.
|
203
|
+
# Example:
|
204
|
+
# jquery.getJSON("http://example.com").call
|
118
205
|
def jquery
|
119
206
|
page.jQuery
|
120
207
|
end
|
@@ -125,7 +212,8 @@ module Bowline
|
|
125
212
|
end
|
126
213
|
|
127
214
|
# Trigger events on all elements
|
128
|
-
# bound to this binder
|
215
|
+
# bound to this binder.
|
216
|
+
# Example:
|
129
217
|
# trigger(:reload, {:key => :value})
|
130
218
|
def trigger(event, data = nil)
|
131
219
|
bowline.trigger(
|
@@ -152,14 +240,13 @@ module Bowline
|
|
152
240
|
name.to_s
|
153
241
|
end
|
154
242
|
end
|
155
|
-
|
243
|
+
|
244
|
+
# jQuery element object
|
156
245
|
attr_reader :element
|
157
|
-
attr_reader :item
|
158
246
|
|
159
|
-
# Instance of
|
160
|
-
|
161
|
-
|
162
|
-
# element.highlight.call
|
247
|
+
# Instance of the bound class' record
|
248
|
+
attr_reader :item
|
249
|
+
|
163
250
|
def initialize(id, *args) #:nodoc:
|
164
251
|
@element = self.class.bowline.element(
|
165
252
|
self.class.name, id
|
@@ -168,7 +255,8 @@ module Bowline
|
|
168
255
|
end
|
169
256
|
|
170
257
|
protected
|
171
|
-
# Trigger jQuery events on this element
|
258
|
+
# Trigger jQuery events on this element.
|
259
|
+
# Example:
|
172
260
|
# trigger(:highlight)
|
173
261
|
def trigger(event, data = nil)
|
174
262
|
element.trigger(
|
@@ -184,7 +272,7 @@ module Bowline
|
|
184
272
|
|
185
273
|
# Shortcut methods
|
186
274
|
|
187
|
-
# See self.class.
|
275
|
+
# See self.class.page
|
188
276
|
def page
|
189
277
|
self.class.page
|
190
278
|
end
|
@@ -22,7 +22,7 @@ Gem.pre_install_hooks.push(proc do |installer|
|
|
22
22
|
end
|
23
23
|
end)
|
24
24
|
|
25
|
-
class ::Gem::Uninstaller
|
25
|
+
class ::Gem::Uninstaller #:nodoc:
|
26
26
|
def self._with_silent_ui
|
27
27
|
|
28
28
|
ui = Gem::DefaultUserInteraction.ui
|
@@ -64,7 +64,7 @@ Gem.post_install_hooks.push(proc do |installer|
|
|
64
64
|
)
|
65
65
|
end)
|
66
66
|
|
67
|
-
class ::Gem::DependencyInstaller
|
67
|
+
class ::Gem::DependencyInstaller #:nodoc:
|
68
68
|
alias old_fg find_gems_with_sources
|
69
69
|
|
70
70
|
def find_gems_with_sources(dep)
|
@@ -78,7 +78,7 @@ class ::Gem::DependencyInstaller
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
class ::Gem::SpecFetcher
|
81
|
+
class ::Gem::SpecFetcher #:nodoc:
|
82
82
|
alias old_fetch fetch
|
83
83
|
def fetch(*args) # in rubygems 1.3.2 fetch takes 4 parameters
|
84
84
|
dependency, all, matching_platform, prerelease = *args
|
@@ -102,7 +102,7 @@ class ::Gem::SpecFetcher
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
class ::Gem::Specification
|
105
|
+
class ::Gem::Specification #:nodoc:
|
106
106
|
def recursive_dependencies(from, index = Gem.source_index)
|
107
107
|
specs = self.runtime_dependencies.map do |dep|
|
108
108
|
spec = index.search(dep).last
|
data/lib/bowline/desktop.rb
CHANGED
@@ -4,19 +4,28 @@ module Bowline
|
|
4
4
|
extend Bowline::Watcher::Base
|
5
5
|
watch :on_tick, :on_idle
|
6
6
|
|
7
|
+
##
|
8
|
+
# :singleton-method: on_tick(method = nil, &block)
|
9
|
+
# A Watcher event method that gets called every few microseconds,
|
10
|
+
# inside the application's main thread.
|
11
|
+
# Example:
|
12
|
+
# on_tick { puts "App tick" }
|
13
|
+
|
14
|
+
# Return true if we're currently
|
15
|
+
# being executed by bowline-desktop.
|
7
16
|
def enabled?
|
8
17
|
$0 == "bowline"
|
9
18
|
end
|
10
19
|
module_function :enabled?
|
11
20
|
|
12
|
-
def idle
|
21
|
+
def idle #:nodoc:
|
13
22
|
watcher.call(:on_idle)
|
14
23
|
rescue => e
|
15
24
|
log_error e
|
16
25
|
end
|
17
26
|
module_function :idle
|
18
27
|
|
19
|
-
def tick
|
28
|
+
def tick #:nodoc:
|
20
29
|
watcher.call(:on_tick)
|
21
30
|
rescue => e
|
22
31
|
log_error e
|