bowline 0.5.6 → 0.5.7
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/README.txt +2 -2
- data/TODO +9 -2
- data/VERSION +1 -1
- data/assets/animations.css +92 -0
- data/assets/bowline.js +70 -38
- data/assets/bowline.menu.js +81 -0
- data/assets/bowline.state.js +66 -0
- data/assets/bowline.view.js +108 -0
- data/assets/jquery.dataset.js +167 -0
- data/bowline.gemspec +7 -2
- data/examples/example.js +1 -1
- data/examples/twitter.html +1 -1
- data/lib/bowline/binders.rb +2 -4
- data/lib/bowline/desktop/bridge.rb +15 -9
- data/lib/bowline/desktop/window.rb +9 -1
- data/lib/bowline/desktop/window_manager.rb +4 -1
- data/lib/bowline/desktop/window_methods.rb +9 -0
- data/lib/bowline/initializer.rb +29 -6
- data/lib/bowline/library.rb +6 -12
- data/lib/bowline/logging.rb +1 -1
- data/lib/bowline/tasks/app.rake +43 -8
- data/lib/bowline/tasks/libs.rake +11 -18
- data/lib/bowline/version.rb +2 -2
- data/templates/config/environment.rb +0 -3
- data/templates/public/index.html +1 -3
- metadata +7 -2
data/README.txt
CHANGED
@@ -99,7 +99,7 @@ Which will generate code a bit like this:
|
|
99
99
|
|
100
100
|
Now, in the view you can bind HTML to this collection, by
|
101
101
|
using the following javascript:
|
102
|
-
$('#users').
|
102
|
+
$('#users').bowlineBind('UsersBinder');
|
103
103
|
|
104
104
|
You should probably become familiar with Chain.js (which bowline uses for binding): http://wiki.github.com/raid-ox/chain.js/
|
105
105
|
|
@@ -222,7 +222,7 @@ Usage for a collection (of users):
|
|
222
222
|
jQuery(function($){
|
223
223
|
$.bowline.ready(function(){
|
224
224
|
// Bind the element users to UserBinder
|
225
|
-
var users = $('#users').
|
225
|
+
var users = $('#users').bowlineBind('UsersBinder', function(){
|
226
226
|
var self = $(this);
|
227
227
|
self.find('.destroy').click(function(){
|
228
228
|
self.invoke('destroy');
|
data/TODO
CHANGED
@@ -3,7 +3,7 @@ Use new Rails gem packaging system
|
|
3
3
|
Ideas:
|
4
4
|
* bowline-notification gem (Growl)
|
5
5
|
|
6
|
-
Investigate thread safety
|
6
|
+
Investigate thread safety (for Bowline::Desktop::JS)
|
7
7
|
|
8
8
|
Load all required JS through Bowline (so you only have to require one JS file)
|
9
9
|
|
@@ -20,4 +20,11 @@ Tutorials:
|
|
20
20
|
CSS webkit-box (layouts)
|
21
21
|
CSS search box & placeholder
|
22
22
|
|
23
|
-
Don't run initializers during rake tasks
|
23
|
+
- Don't run initializers during rake tasks
|
24
|
+
- Find out why build is taking so long
|
25
|
+
- Add first-run initializers
|
26
|
+
- Add reload keyboard shortcut
|
27
|
+
- Add some sort of production mode
|
28
|
+
|
29
|
+
- strip exe (to make smaller)
|
30
|
+
- remove framework headers
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.7
|
@@ -0,0 +1,92 @@
|
|
1
|
+
.drag {
|
2
|
+
-webkit-user-drag: element;
|
3
|
+
-webkit-user-select: none;
|
4
|
+
}
|
5
|
+
|
6
|
+
.in, .out {
|
7
|
+
-webkit-animation-timing-function: ease-in-out;
|
8
|
+
-webkit-animation-duration: 350ms;
|
9
|
+
}
|
10
|
+
|
11
|
+
.slideup.in {
|
12
|
+
-webkit-animation-name: slideupbottom;
|
13
|
+
z-index: 10;
|
14
|
+
}
|
15
|
+
|
16
|
+
.slideup.out {
|
17
|
+
-webkit-animation-name: slideuptop;
|
18
|
+
z-index: 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.slidedown.in {
|
22
|
+
-webkit-animation-name: slidedowntop;
|
23
|
+
z-index: 10;
|
24
|
+
}
|
25
|
+
|
26
|
+
.slidedown.out {
|
27
|
+
-webkit-animation-name: slidedownbottom;
|
28
|
+
z-index: 0;
|
29
|
+
}
|
30
|
+
|
31
|
+
@-webkit-keyframes dontmove {
|
32
|
+
from { opacity: 1; }
|
33
|
+
to { opacity: 1; }
|
34
|
+
}
|
35
|
+
|
36
|
+
@-webkit-keyframes slideuptop {
|
37
|
+
from { -webkit-transform: translateY(0); }
|
38
|
+
to { -webkit-transform: translateY(-100%); }
|
39
|
+
}
|
40
|
+
|
41
|
+
@-webkit-keyframes slideupbottom {
|
42
|
+
from { -webkit-transform: translateY(100%); }
|
43
|
+
to { -webkit-transform: translateY(0); }
|
44
|
+
}
|
45
|
+
|
46
|
+
@-webkit-keyframes slidedowntop {
|
47
|
+
from { -webkit-transform: translateY(-100%); }
|
48
|
+
to { -webkit-transform: translateY(0); }
|
49
|
+
}
|
50
|
+
|
51
|
+
@-webkit-keyframes slidedownbottom {
|
52
|
+
from { -webkit-transform: translateY(0); }
|
53
|
+
to { -webkit-transform: translateY(100%); }
|
54
|
+
}
|
55
|
+
|
56
|
+
.explode.in {
|
57
|
+
-webkit-animation-name: explodein;
|
58
|
+
}
|
59
|
+
|
60
|
+
.explode.out {
|
61
|
+
-webkit-animation-name: explodeout;
|
62
|
+
}
|
63
|
+
|
64
|
+
@-webkit-keyframes explodein {
|
65
|
+
from { -webkit-transform: scale(1.3); opacity: 0; }
|
66
|
+
to { -webkit-transform: scale(1); opacity: 1; }
|
67
|
+
}
|
68
|
+
|
69
|
+
@-webkit-keyframes explodeout {
|
70
|
+
from { -webkit-transform: scale(1); opacity: 1; }
|
71
|
+
to { -webkit-transform: scale(1.3); opacity: 0; }
|
72
|
+
}
|
73
|
+
|
74
|
+
.fade.in {
|
75
|
+
z-index: 10;
|
76
|
+
-webkit-animation-name: fadein;
|
77
|
+
}
|
78
|
+
|
79
|
+
.fade.out {
|
80
|
+
z-index: 0;
|
81
|
+
-webkit-animation-name: fadeout;
|
82
|
+
}
|
83
|
+
|
84
|
+
@-webkit-keyframes fadein {
|
85
|
+
from { opacity: 0; }
|
86
|
+
to { opacity: 1; }
|
87
|
+
}
|
88
|
+
|
89
|
+
@-webkit-keyframes fadeout {
|
90
|
+
from { opacity: 1; }
|
91
|
+
to { opacity: 0; }
|
92
|
+
}
|
data/assets/bowline.js
CHANGED
@@ -30,11 +30,11 @@
|
|
30
30
|
helper(method, *args)
|
31
31
|
Invoke a method defined in any helper.
|
32
32
|
|
33
|
-
|
33
|
+
bind(element, klass, options = {})
|
34
34
|
Bind a element to a Bowline binder.
|
35
35
|
Usually called via the jQuery helper functions.
|
36
36
|
Usage:
|
37
|
-
Bowline.
|
37
|
+
Bowline.bind('#users', 'UsersBinder');
|
38
38
|
|
39
39
|
The options can either be a template hash:
|
40
40
|
{
|
@@ -82,11 +82,16 @@
|
|
82
82
|
|
83
83
|
These are how you usually bind elements, or invoke a binders class/instance methods.
|
84
84
|
|
85
|
-
$.fn.
|
85
|
+
$.fn.bowlineBind(klass, options)
|
86
86
|
Associate an an element with a Bowline binder.
|
87
87
|
Example:
|
88
|
-
$("#users").
|
89
|
-
|
88
|
+
$("#users").bowlineBind('UsersBinder');
|
89
|
+
|
90
|
+
$.fn.bowlineUnbind(klass)
|
91
|
+
Opposite of bowlineBind.
|
92
|
+
Example:
|
93
|
+
$("#users").bowlineUnbind('UsersBinder');
|
94
|
+
|
90
95
|
$.fn.invoke(method, *args)
|
91
96
|
Invoke a class/instance method on a Bowline binder.
|
92
97
|
|
@@ -118,6 +123,8 @@ var Bowline = {
|
|
118
123
|
uuid: 0,
|
119
124
|
bounds: {},
|
120
125
|
trace: false,
|
126
|
+
// _app is a function defined in Objective C
|
127
|
+
enabled: typeof(_app) != "undefined",
|
121
128
|
|
122
129
|
id: function(){
|
123
130
|
return ++Bowline.uuid;
|
@@ -125,53 +132,53 @@ var Bowline = {
|
|
125
132
|
|
126
133
|
// Usage: invoke(klass, method, *args)
|
127
134
|
invoke: function(){
|
128
|
-
var args =
|
135
|
+
var args = jQuery.makeArray(arguments);
|
129
136
|
var klass = args.shift();
|
130
137
|
var method = args.shift();
|
131
|
-
var id =
|
138
|
+
var id = -1;
|
132
139
|
|
133
140
|
var callback = args.pop();
|
134
141
|
if(typeof(callback) == "function"){
|
142
|
+
id = Bowline.id();
|
135
143
|
Bowline.callbacks[id] = callback;
|
136
144
|
} else if(callback) {
|
137
145
|
args.push(callback);
|
138
146
|
}
|
147
|
+
|
139
148
|
var msg = {
|
140
|
-
klass:klass,
|
141
|
-
method:method,
|
142
|
-
args:args,
|
143
|
-
id:id
|
149
|
+
klass: klass,
|
150
|
+
method: method,
|
151
|
+
args: args,
|
152
|
+
id: id,
|
144
153
|
};
|
145
154
|
|
146
|
-
Bowline.log("New message:")
|
147
|
-
Bowline.log(msg);
|
155
|
+
Bowline.log("New message:", msg);
|
148
156
|
|
149
|
-
|
150
|
-
|
151
|
-
wx.call(JSON.stringify(msg));
|
157
|
+
if(Bowline.enabled)
|
158
|
+
_app.call(JSON.stringify(msg));
|
152
159
|
},
|
153
160
|
|
154
161
|
// Usage: instanceInvoke(klass, id, method, *args)
|
155
162
|
instanceInvoke: function(){
|
156
|
-
var args =
|
163
|
+
var args = jQuery.makeArray(arguments);
|
157
164
|
args.splice(1, 0, "instance_invoke");
|
158
165
|
Bowline.invoke.apply(this, args);
|
159
166
|
},
|
160
167
|
|
161
168
|
// Usage: windowInvoke(method, *args)
|
162
169
|
windowInvoke: function(){
|
163
|
-
var args =
|
170
|
+
var args = jQuery.makeArray(arguments);
|
164
171
|
args.unshift("_window");
|
165
172
|
Bowline.invoke.apply(this, args);
|
166
173
|
},
|
167
174
|
|
168
175
|
helper: function(){
|
169
|
-
var args =
|
176
|
+
var args = jQuery.makeArray(arguments);
|
170
177
|
args.unshift("Helper");
|
171
|
-
Bowline.invoke(args);
|
178
|
+
Bowline.invoke.apply(this, args);
|
172
179
|
},
|
173
180
|
|
174
|
-
|
181
|
+
bind: function(el, klass, options){
|
175
182
|
el = jQuery(el);
|
176
183
|
el.chain(options);
|
177
184
|
el.data('bowline', klass);
|
@@ -179,22 +186,37 @@ var Bowline = {
|
|
179
186
|
Bowline.bounds[klass] = [];
|
180
187
|
Bowline.bounds[klass].push(el);
|
181
188
|
jQuery(function(){
|
182
|
-
Bowline.invoke(klass, "setup")
|
189
|
+
Bowline.invoke(klass, "setup", function(res){
|
190
|
+
Bowline.populate(klass, res);
|
191
|
+
});
|
183
192
|
});
|
184
193
|
},
|
185
194
|
|
195
|
+
unbind: function(el, klass){
|
196
|
+
var array = Bowline.bounds[klass]
|
197
|
+
if(!array) return;
|
198
|
+
array = jQuery.grep(array,
|
199
|
+
function(n){ return n != el }
|
200
|
+
);
|
201
|
+
Bowline.bounds[klass] = array;
|
202
|
+
},
|
203
|
+
|
186
204
|
// Bowline functions
|
187
205
|
|
188
206
|
invokeJS: function(str){
|
189
|
-
Bowline.log("Invoking:
|
207
|
+
Bowline.log("Invoking:", str);
|
190
208
|
return JSON.stringify(eval(str));
|
191
209
|
},
|
192
210
|
|
193
211
|
invokeCallback: function(id, res){
|
194
|
-
Bowline.log("Callback:
|
212
|
+
Bowline.log("Callback:", id, res);
|
195
213
|
if(!Bowline.callbacks[id]) return true;
|
196
|
-
|
197
|
-
|
214
|
+
try {
|
215
|
+
Bowline.callbacks[id](JSON.parse(res));
|
216
|
+
delete Bowline.callbacks[id];
|
217
|
+
} catch(e) {
|
218
|
+
Bowline.log(e)
|
219
|
+
}
|
198
220
|
return true;
|
199
221
|
},
|
200
222
|
|
@@ -256,18 +278,22 @@ var Bowline = {
|
|
256
278
|
|
257
279
|
findItem: function(el, id){
|
258
280
|
var items = jQuery.grep(el.items(true), function(n, i){
|
259
|
-
return
|
281
|
+
return jQuery(n).item().id == id;
|
260
282
|
});
|
261
|
-
return(
|
283
|
+
return(jQuery(items[0]));
|
262
284
|
},
|
263
285
|
|
264
|
-
log: function(
|
265
|
-
if(Bowline.trace)
|
266
|
-
|
286
|
+
log: function(){
|
287
|
+
if( !Bowline.trace ) return;
|
288
|
+
var args = jQuery.makeArray(arguments);
|
289
|
+
args.unshift("(Bowline)");
|
290
|
+
console.log.apply(console, args);
|
267
291
|
},
|
268
292
|
|
269
|
-
warn: function(
|
270
|
-
|
293
|
+
warn: function(){
|
294
|
+
var args = jQuery.makeArray(arguments);
|
295
|
+
args.unshift("(Bowline)");
|
296
|
+
console.warn.apply(console, args);
|
271
297
|
}
|
272
298
|
};
|
273
299
|
|
@@ -279,25 +305,31 @@ var Bowline = {
|
|
279
305
|
// Class method
|
280
306
|
var klass = $(this).data('bowline');
|
281
307
|
args.unshift(klass);
|
282
|
-
Bowline.invoke.apply(
|
308
|
+
Bowline.invoke.apply(Bowline, args);
|
283
309
|
} else {
|
284
310
|
// Instance method
|
285
311
|
var klass = $(this).item('root').data('bowline');
|
286
312
|
var id = $(this).item().id;
|
287
313
|
args.unshift(id);
|
288
314
|
args.unshift(klass);
|
289
|
-
Bowline.instanceInvoke.apply(
|
315
|
+
Bowline.instanceInvoke.apply(Bowline, args);
|
290
316
|
}
|
291
317
|
} else {
|
292
318
|
throw 'Chain not active';
|
293
319
|
}
|
294
320
|
};
|
295
|
-
|
296
|
-
$.fn.
|
321
|
+
|
322
|
+
$.fn.bowlineBind = function(){
|
297
323
|
var args = $.makeArray(arguments);
|
298
324
|
args.unshift(this);
|
299
|
-
Bowline.
|
325
|
+
Bowline.bind.apply(Bowline, args);
|
300
326
|
};
|
327
|
+
|
328
|
+
$.fn.bowlineUnbind = function(){
|
329
|
+
var args = $.makeArray(arguments);
|
330
|
+
args.unshift(this);
|
331
|
+
Bowline.unbind.apply(Bowline, args);
|
332
|
+
}
|
301
333
|
})(jQuery);
|
302
334
|
|
303
335
|
jQuery(function($){
|
@@ -0,0 +1,81 @@
|
|
1
|
+
var BowlineMenu = function(element, options){
|
2
|
+
var defaults = {childSelector: "li", trace: false};
|
3
|
+
this.options = jQuery.extend({}, defaults, options);
|
4
|
+
|
5
|
+
this.element = jQuery(element);
|
6
|
+
|
7
|
+
if(this.options.current) this.change(this.options.current);
|
8
|
+
|
9
|
+
var self = this;
|
10
|
+
this.elements().click(function(){
|
11
|
+
var view = self.viewName(this);
|
12
|
+
self.change(view);
|
13
|
+
});
|
14
|
+
};
|
15
|
+
|
16
|
+
BowlineMenu.fn = BowlineMenu.prototype;
|
17
|
+
|
18
|
+
BowlineMenu.fn.log = function(){
|
19
|
+
if( !this.options.trace ) return;
|
20
|
+
var args = jQuery.makeArray(arguments);
|
21
|
+
args.unshift("(BowlineMenu)");
|
22
|
+
console.log.apply(console, args);
|
23
|
+
};
|
24
|
+
|
25
|
+
BowlineMenu.fn.onChange = function(func){
|
26
|
+
this.element.bind("change.bowline", func);
|
27
|
+
};
|
28
|
+
|
29
|
+
BowlineMenu.fn.triggerChange = function(data){
|
30
|
+
this.element.trigger("change.bowline", data);
|
31
|
+
};
|
32
|
+
|
33
|
+
BowlineMenu.fn.viewName = function(element){
|
34
|
+
return jQuery(element).dataset("view");
|
35
|
+
};
|
36
|
+
|
37
|
+
BowlineMenu.fn.currentName = function(){
|
38
|
+
return this.viewName(this.current);
|
39
|
+
};
|
40
|
+
|
41
|
+
BowlineMenu.fn.elements = function(){
|
42
|
+
return this.element.find(this.options.childSelector);
|
43
|
+
};
|
44
|
+
|
45
|
+
BowlineMenu.fn.elementFor = function(name){
|
46
|
+
return this.element.find(
|
47
|
+
"[data-view='" + name + "']:first"
|
48
|
+
);
|
49
|
+
};
|
50
|
+
|
51
|
+
BowlineMenu.fn.items = function(){
|
52
|
+
var self = this;
|
53
|
+
return jQuery.map(this.elements(), function(n){
|
54
|
+
return self.viewName(n);
|
55
|
+
});
|
56
|
+
};
|
57
|
+
|
58
|
+
BowlineMenu.fn.change = function(name){
|
59
|
+
if(name != false && jQuery.inArray(name, this.items()) == -1) return false;
|
60
|
+
|
61
|
+
var fromView = this.current;
|
62
|
+
var fromViewName = this.viewName(fromView);
|
63
|
+
|
64
|
+
var toView = this.elementFor(name);
|
65
|
+
var toViewName = name;
|
66
|
+
|
67
|
+
this.log("changing:", fromViewName, toViewName);
|
68
|
+
|
69
|
+
this.elements().removeClass("current");
|
70
|
+
if(toView) {
|
71
|
+
this.current = toView;
|
72
|
+
toView.addClass("current");
|
73
|
+
}
|
74
|
+
|
75
|
+
this.triggerChange({
|
76
|
+
toView: toView,
|
77
|
+
toViewName: toViewName,
|
78
|
+
fromView: fromView,
|
79
|
+
fromViewName: fromViewName
|
80
|
+
});
|
81
|
+
};
|
@@ -0,0 +1,66 @@
|
|
1
|
+
function BowlineState(opts){
|
2
|
+
this.options = opts || {};
|
3
|
+
this.states = {}
|
4
|
+
this.events = {}
|
5
|
+
this.current = this.options.initial;
|
6
|
+
}
|
7
|
+
|
8
|
+
BowlineState.fn = BowlineState.prototype;
|
9
|
+
|
10
|
+
BowlineState.fn.log = function(){
|
11
|
+
if( !this.options.trace ) return;
|
12
|
+
var args = jQuery.makeArray(arguments);
|
13
|
+
args.unshift("(BowlineState)");
|
14
|
+
console.log.apply(console, args);
|
15
|
+
};
|
16
|
+
|
17
|
+
BowlineState.fn.newEvent = function(name, opts){
|
18
|
+
if(!name) throw "Must supply name";
|
19
|
+
// Defaults to the same named state
|
20
|
+
if(!opts) opts = {};
|
21
|
+
if(!opts.to) opts.to = name;
|
22
|
+
this.events[name] = opts;
|
23
|
+
}
|
24
|
+
|
25
|
+
BowlineState.fn.newState = function(name, callbacks){
|
26
|
+
if(!name) throw "Must supply name";
|
27
|
+
this.states[name] = callbacks || {};
|
28
|
+
}
|
29
|
+
|
30
|
+
BowlineState.fn.change = function(){
|
31
|
+
var args = $.makeArray(arguments);
|
32
|
+
var name = args.shift();
|
33
|
+
|
34
|
+
var event = this.events[name]
|
35
|
+
if(!event) throw "Unknown event: " + name;
|
36
|
+
// TODO support arrays in event.from
|
37
|
+
if(event.from &&
|
38
|
+
event.from != "all" &&
|
39
|
+
this.current &&
|
40
|
+
event.from != this.current) {
|
41
|
+
this.log("Not changing state to:", event.to);
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
|
45
|
+
if(!this.states.hasOwnProperty(event.to)) {
|
46
|
+
throw "Unknown state: " + event.to;
|
47
|
+
}
|
48
|
+
|
49
|
+
// Already at state
|
50
|
+
if(event.to == this.current) return;
|
51
|
+
|
52
|
+
var oldState = this.current;
|
53
|
+
var oldStateCB = this.states[oldState];
|
54
|
+
var newState = event.to;
|
55
|
+
var newStateCB = this.states[newState];
|
56
|
+
|
57
|
+
this.log("changing:", oldState, newState);
|
58
|
+
|
59
|
+
if(oldStateCB && oldStateCB.beforeExit) oldStateCB.beforeExit();
|
60
|
+
if(newStateCB.beforeEnter) newStateCB.beforeEnter.apply(this, args);
|
61
|
+
|
62
|
+
this.current = newState;
|
63
|
+
|
64
|
+
if(oldStateCB && oldStateCB.afterExit) oldStateCB.afterExit();
|
65
|
+
if(newStateCB.afterEnter) newStateCB.afterEnter();
|
66
|
+
}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
// #view > *:not(.current) {
|
2
|
+
// display: none;
|
3
|
+
// }
|
4
|
+
|
5
|
+
jQuery.support.WebKitAnimationEvent = (typeof WebKitTransitionEvent == "object");
|
6
|
+
|
7
|
+
var BowlineView = function(element, options){
|
8
|
+
var defaults = {trace:false};
|
9
|
+
this.options = jQuery.extend({}, defaults, options);
|
10
|
+
|
11
|
+
if (this.options.preloadImages) {
|
12
|
+
jQuery.each(this.options.preloadImages, function(e){
|
13
|
+
(new Image()).src = e;
|
14
|
+
});
|
15
|
+
}
|
16
|
+
|
17
|
+
this.element = jQuery(element);
|
18
|
+
|
19
|
+
if(this.options.current){
|
20
|
+
this.current = jQuery(this.options.current);
|
21
|
+
this.current.addClass("current");
|
22
|
+
}
|
23
|
+
};
|
24
|
+
|
25
|
+
BowlineView.fn = BowlineView.prototype;
|
26
|
+
|
27
|
+
BowlineView.fn.log = function(){
|
28
|
+
if( !this.options.trace ) return;
|
29
|
+
var args = jQuery.makeArray(arguments);
|
30
|
+
args.unshift("(BowlineView)");
|
31
|
+
console.log.apply(console, args);
|
32
|
+
};
|
33
|
+
|
34
|
+
BowlineView.fn.onChange = function(func){
|
35
|
+
this.element.bind("change.bowline", func);
|
36
|
+
};
|
37
|
+
|
38
|
+
BowlineView.fn.triggerChange = function(data){
|
39
|
+
this.element.trigger("change.bowline", data);
|
40
|
+
};
|
41
|
+
|
42
|
+
BowlineView.fn.elements = function(){
|
43
|
+
return this.element.find(">*");
|
44
|
+
}
|
45
|
+
|
46
|
+
BowlineView.fn.findView = function(name){
|
47
|
+
return this.element.find("[data-view='" + name + "']:first");
|
48
|
+
};
|
49
|
+
|
50
|
+
BowlineView.fn.viewName = function(element){
|
51
|
+
return jQuery(element).dataset("view");
|
52
|
+
};
|
53
|
+
|
54
|
+
BowlineView.fn.change = function(name){
|
55
|
+
var fromView = this.current;
|
56
|
+
var fromViewName = this.viewName(fromView);
|
57
|
+
var toView = this.findView(name);
|
58
|
+
var toViewName = name;
|
59
|
+
|
60
|
+
this.log("changing:", fromViewName, toViewName);
|
61
|
+
|
62
|
+
if(toView.length == 0) throw 'Unknown view: ' + toViewName;
|
63
|
+
|
64
|
+
if(fromViewName == toViewName) return;
|
65
|
+
|
66
|
+
var animation = null;
|
67
|
+
if(this.options.animationCallback){
|
68
|
+
animation = this.options.animationCallback(
|
69
|
+
fromViewName, toViewName
|
70
|
+
);
|
71
|
+
} else {
|
72
|
+
// Could be blank - doesn't matter.
|
73
|
+
animation = this.current.dataset("animation");
|
74
|
+
}
|
75
|
+
|
76
|
+
if(!fromView) {
|
77
|
+
animation = null;
|
78
|
+
}
|
79
|
+
|
80
|
+
var self = this;
|
81
|
+
var callback = function(){
|
82
|
+
if (animation){
|
83
|
+
toView.removeClass("in " + animation);
|
84
|
+
if(fromView) {
|
85
|
+
fromView.removeClass("current out " + animation);
|
86
|
+
}
|
87
|
+
} else {
|
88
|
+
if(fromView) fromView.removeClass("current");
|
89
|
+
}
|
90
|
+
self.current = toView;
|
91
|
+
self.triggerChange({
|
92
|
+
fromView: fromView,
|
93
|
+
fromViewName: fromViewName,
|
94
|
+
toView: toView,
|
95
|
+
toViewName: toViewName
|
96
|
+
});
|
97
|
+
}
|
98
|
+
|
99
|
+
if(jQuery.support.WebKitAnimationEvent && animation){
|
100
|
+
toView.one("webkitAnimationEnd", callback);
|
101
|
+
this.log("using animation:", animation, toViewName);
|
102
|
+
toView.addClass(animation + " in current");
|
103
|
+
if(fromView) fromView.addClass(animation + " out");
|
104
|
+
} else {
|
105
|
+
toView.addClass("current");
|
106
|
+
callback();
|
107
|
+
}
|
108
|
+
};
|
@@ -0,0 +1,167 @@
|
|
1
|
+
/// jquery.dataset v0.1.0 -- HTML5 dataset jQuery plugin
|
2
|
+
/// http://orangesoda.net/jquery.dataset.html
|
3
|
+
|
4
|
+
/// Copyright (c) 2009, Ben Weaver. All rights reserved.
|
5
|
+
/// This software is issued "as is" under a BSD license
|
6
|
+
/// <http://orangesoda.net/license.html>. All warrenties disclaimed.
|
7
|
+
|
8
|
+
/// The HTML5 specification allows elements to have custom data
|
9
|
+
/// attributes that are prefixed with `data-'. They may be
|
10
|
+
/// conveniently accessed through an element's `dataset' property.
|
11
|
+
/// This plugin provides similar functionality.
|
12
|
+
///
|
13
|
+
/// The methods in the plugin are designed to be similar to the
|
14
|
+
/// built-in `attr' and `data' methods. All names are without the
|
15
|
+
/// `data-' prefix.
|
16
|
+
//
|
17
|
+
/// These methods are defined:
|
18
|
+
///
|
19
|
+
/// dataset()
|
20
|
+
/// Return an object with all custom attribute (name, value) items.
|
21
|
+
///
|
22
|
+
/// dataset(name)
|
23
|
+
/// Return the value of the attribute `data-NAME'.
|
24
|
+
///
|
25
|
+
/// dataset(name, value)
|
26
|
+
/// Set the value of attribtue `data-NAME' to VALUE.
|
27
|
+
///
|
28
|
+
/// dataset({...})
|
29
|
+
/// Set many custom attributes at once.
|
30
|
+
///
|
31
|
+
/// removeDataset(name)
|
32
|
+
/// Remove the attribute `data-NAME'.
|
33
|
+
///
|
34
|
+
/// removeDataset([n1, n2, ...])
|
35
|
+
/// Remove the attributes `data-N1', `data-N2', ...
|
36
|
+
|
37
|
+
(function($) {
|
38
|
+
var PREFIX = 'data-',
|
39
|
+
PATTERN = /^data\-(.*)$/;
|
40
|
+
|
41
|
+
function dataset(name, value) {
|
42
|
+
if (value !== undefined) {
|
43
|
+
// dataset(name, value): set the NAME attribute to VALUE.
|
44
|
+
return this.attr(PREFIX + name, value);
|
45
|
+
}
|
46
|
+
|
47
|
+
switch (typeof name) {
|
48
|
+
case 'string':
|
49
|
+
// dataset(name): get the value of the NAME attribute.
|
50
|
+
return this.attr(PREFIX + name);
|
51
|
+
|
52
|
+
case 'object':
|
53
|
+
// dataset(items): set the values of all (name, value) items.
|
54
|
+
return set_items.call(this, name);
|
55
|
+
|
56
|
+
case 'undefined':
|
57
|
+
// dataset(): return a mapping of (name, value) items for the
|
58
|
+
// first element.
|
59
|
+
return get_items.call(this);
|
60
|
+
|
61
|
+
default:
|
62
|
+
throw 'dataset: invalid argument ' + name;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
function get_items() {
|
67
|
+
return this.foldAttr(function(index, attr, result) {
|
68
|
+
var match = PATTERN.exec(this.name);
|
69
|
+
if (match) result[match[1]] = this.value;
|
70
|
+
});
|
71
|
+
}
|
72
|
+
|
73
|
+
function set_items(items) {
|
74
|
+
for (var key in items) {
|
75
|
+
this.attr(PREFIX + key, items[key]);
|
76
|
+
}
|
77
|
+
return this;
|
78
|
+
}
|
79
|
+
|
80
|
+
function remove(name) {
|
81
|
+
if (typeof name == 'string') {
|
82
|
+
// Remove a single attribute;
|
83
|
+
return this.removeAttr(PREFIX + name);
|
84
|
+
}
|
85
|
+
return remove_names(name);
|
86
|
+
}
|
87
|
+
|
88
|
+
function remove_names(obj) {
|
89
|
+
var idx, length = obj && obj.length;
|
90
|
+
|
91
|
+
// For any object, remove attributes named by the keys.
|
92
|
+
if (length === undefined) {
|
93
|
+
for (idx in obj) {
|
94
|
+
this.removeAttr(PREFIX + idx);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
// For an array, remove attributes named by the values.
|
98
|
+
else {
|
99
|
+
for (idx = 0; idx < length; idx++) {
|
100
|
+
this.removeAttr(PREFIX + obj[idx]);
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
return this;
|
105
|
+
}
|
106
|
+
|
107
|
+
$.fn.dataset = dataset;
|
108
|
+
$.fn.removeDataset = remove_names;
|
109
|
+
|
110
|
+
})(jQuery);
|
111
|
+
|
112
|
+
(function($) {
|
113
|
+
|
114
|
+
function each_attr(proc) {
|
115
|
+
if (this.length > 0) {
|
116
|
+
$.each(this[0].attributes, proc);
|
117
|
+
}
|
118
|
+
return this;
|
119
|
+
}
|
120
|
+
|
121
|
+
function fold_attr(proc, acc) {
|
122
|
+
return fold((this.length > 0) && this[0].attributes, proc, acc);
|
123
|
+
}
|
124
|
+
|
125
|
+
/*
|
126
|
+
* A left-fold operator. The behavior is the same as $.each(),
|
127
|
+
* but the callback is called with the accumulator as the third
|
128
|
+
* argument. The default accumulator is an empty object.
|
129
|
+
*/
|
130
|
+
function fold(object, proc, acc) {
|
131
|
+
var length = object && object.length;
|
132
|
+
|
133
|
+
// The default accumulator is an empty object.
|
134
|
+
if (acc === undefined) acc = {};
|
135
|
+
|
136
|
+
// Returning an empty accumulator when OBJECT is "false"
|
137
|
+
// makes FOLD more composable.
|
138
|
+
if (!object) return acc;
|
139
|
+
|
140
|
+
// Check to see if OBJECT is an array.
|
141
|
+
if (length !== undefined) {
|
142
|
+
for (var i = 0, value = object[i];
|
143
|
+
(i < length) && (proc.call(value, i, value, acc) !== false);
|
144
|
+
value = object[++i])
|
145
|
+
{ }
|
146
|
+
}
|
147
|
+
// Object is a map of (name, value) items.
|
148
|
+
else {
|
149
|
+
for (var name in object) {
|
150
|
+
if (proc.call(object[name], name, object[name], acc) === false) break;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
return acc;
|
155
|
+
}
|
156
|
+
|
157
|
+
function fold_jquery(proc, acc) {
|
158
|
+
if (acc === undefined) acc = [];
|
159
|
+
return fold(this, proc, acc);
|
160
|
+
}
|
161
|
+
|
162
|
+
$.fn.eachAttr = each_attr;
|
163
|
+
$.fn.foldAttr = fold_attr;
|
164
|
+
$.fn.fold = fold_jquery;
|
165
|
+
$.fold = fold;
|
166
|
+
|
167
|
+
})(jQuery);
|
data/bowline.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bowline}
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex MacCaw"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-19}
|
13
13
|
s.default_executable = %q{bowline-gen}
|
14
14
|
s.description = %q{Ruby/JS GUI framework}
|
15
15
|
s.email = %q{alex@leadthinking.com}
|
@@ -26,8 +26,13 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Rakefile",
|
27
27
|
"TODO",
|
28
28
|
"VERSION",
|
29
|
+
"assets/animations.css",
|
29
30
|
"assets/bowline.js",
|
31
|
+
"assets/bowline.menu.js",
|
32
|
+
"assets/bowline.state.js",
|
33
|
+
"assets/bowline.view.js",
|
30
34
|
"assets/jquery.chain.js",
|
35
|
+
"assets/jquery.dataset.js",
|
31
36
|
"assets/jquery.js",
|
32
37
|
"assets/json2.js",
|
33
38
|
"assets/osx/Info.plist.erb",
|
data/examples/example.js
CHANGED
data/examples/twitter.html
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
<script src="javascripts/application.js" type="text/javascript" charset="utf-8"></script>
|
12
12
|
<script type="text/javascript" charset="utf-8">
|
13
13
|
jQuery(function($){
|
14
|
-
var tweets = $('#tweets').
|
14
|
+
var tweets = $('#tweets').bowlineBind('TweetsBinder');
|
15
15
|
|
16
16
|
$('#updateSubmit').click(function(){
|
17
17
|
tweets.invoke('update', $('#updateText').val());
|
data/lib/bowline/binders.rb
CHANGED
@@ -68,10 +68,8 @@ module Bowline
|
|
68
68
|
|
69
69
|
def setup(window) #:nodoc:
|
70
70
|
self.windows << window
|
71
|
-
|
72
|
-
|
73
|
-
).call
|
74
|
-
true
|
71
|
+
items = initial
|
72
|
+
items.try(:to_js) || []
|
75
73
|
end
|
76
74
|
|
77
75
|
# Called by a window's JavaScript whenever that window is bound to this Binder.
|
@@ -41,12 +41,16 @@ module Bowline
|
|
41
41
|
attr_reader :window, :id, :klass, :method, :args
|
42
42
|
|
43
43
|
def initialize(window, atts)
|
44
|
-
@window
|
45
|
-
atts
|
46
|
-
@id
|
47
|
-
@klass
|
48
|
-
@method
|
49
|
-
@args
|
44
|
+
@window = window
|
45
|
+
atts = atts.with_indifferent_access
|
46
|
+
@id = atts[:id]
|
47
|
+
@klass = atts[:klass]
|
48
|
+
@method = atts[:method].to_sym
|
49
|
+
@args = atts[:args] || []
|
50
|
+
end
|
51
|
+
|
52
|
+
def callback?
|
53
|
+
@id != -1
|
50
54
|
end
|
51
55
|
|
52
56
|
def invoke
|
@@ -59,9 +63,11 @@ module Bowline
|
|
59
63
|
trace "JS invoking: #{klass}.#{method}(#{args.join(',')})"
|
60
64
|
if object.respond_to?(:js_exposed?) && object.js_exposed?
|
61
65
|
result = object.js_invoke(window, method, *args)
|
62
|
-
|
63
|
-
|
64
|
-
|
66
|
+
if callback?
|
67
|
+
proxy = Proxy.new(window)
|
68
|
+
proxy.Bowline.invokeCallback(id, result.to_js.to_json)
|
69
|
+
window.run_script(proxy.to_s)
|
70
|
+
end
|
65
71
|
else
|
66
72
|
raise "Method not allowed"
|
67
73
|
end
|
@@ -49,7 +49,11 @@ module Bowline
|
|
49
49
|
# window.file = :about
|
50
50
|
# Passing a symbol will load the corrosponding HTML file
|
51
51
|
# in the public directory. In this case, it'll load about.html
|
52
|
-
|
52
|
+
|
53
|
+
##
|
54
|
+
# :singleton-method: url=(address)
|
55
|
+
# Navigate to a HTTP address.
|
56
|
+
|
53
57
|
##
|
54
58
|
# :singleton-method: id
|
55
59
|
# Internal ID for the window.
|
@@ -148,6 +152,10 @@ module Bowline
|
|
148
152
|
##
|
149
153
|
# :singleton-method: shown?
|
150
154
|
# Is this window currently shown?
|
155
|
+
|
156
|
+
##
|
157
|
+
# :singleton-method: show_inspector(console = false)
|
158
|
+
# Show WebInspector
|
151
159
|
end
|
152
160
|
|
153
161
|
class MainWindow #:nodoc:
|
@@ -63,9 +63,12 @@ module Bowline
|
|
63
63
|
else
|
64
64
|
@window = Window.new
|
65
65
|
end
|
66
|
-
|
66
|
+
# Has to be an instance variable since
|
67
|
+
# it is getting GCed (even if I mark it).
|
68
|
+
@script_callback = Proc.new {|str|
|
67
69
|
Bowline::Desktop::Bridge.call(self, str)
|
68
70
|
}
|
71
|
+
@window.script_callback = @script_callback;
|
69
72
|
end
|
70
73
|
|
71
74
|
# Evaluate JavaScript in this window. Pass
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "net/http"
|
2
|
+
|
1
3
|
module Bowline
|
2
4
|
module Desktop
|
3
5
|
module WindowMethods #:nodoc:
|
@@ -26,6 +28,13 @@ module Bowline
|
|
26
28
|
end
|
27
29
|
alias :load_file :file=
|
28
30
|
|
31
|
+
def url=(address)
|
32
|
+
unless address.is_a?(URI)
|
33
|
+
address = URI.parse(path)
|
34
|
+
end
|
35
|
+
self._url = address.to_s
|
36
|
+
end
|
37
|
+
|
29
38
|
def select_dir(options = {})
|
30
39
|
flags = 0
|
31
40
|
flags |= Window::FD_OPEN if options[:open]
|
data/lib/bowline/initializer.rb
CHANGED
@@ -100,6 +100,16 @@ module Bowline
|
|
100
100
|
$LOAD_PATH.uniq!
|
101
101
|
end
|
102
102
|
|
103
|
+
def disable_dependency_loading
|
104
|
+
if configuration.cache_classes && !configuration.dependency_loading
|
105
|
+
ActiveSupport::Dependencies.unhook!
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def initialize_dependency_mechanism
|
110
|
+
ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
|
111
|
+
end
|
112
|
+
|
103
113
|
# Initializes ActiveRecord databases
|
104
114
|
def initialize_database
|
105
115
|
if defined?(ActiveRecord)
|
@@ -286,6 +296,8 @@ module Bowline
|
|
286
296
|
require_frameworks
|
287
297
|
set_autoload_paths
|
288
298
|
add_plugin_load_paths
|
299
|
+
initialize_dependency_mechanism
|
300
|
+
disable_dependency_loading
|
289
301
|
|
290
302
|
initialize_encoding
|
291
303
|
initialize_database
|
@@ -303,14 +315,13 @@ module Bowline
|
|
303
315
|
load_app_config
|
304
316
|
|
305
317
|
load_plugins
|
318
|
+
load_application_classes
|
319
|
+
load_application_helpers
|
306
320
|
|
307
321
|
load_application_initializers
|
308
322
|
|
309
323
|
after_initialize
|
310
|
-
|
311
|
-
load_application_classes
|
312
|
-
load_application_helpers
|
313
|
-
|
324
|
+
|
314
325
|
initialize_js
|
315
326
|
initialize_windows
|
316
327
|
|
@@ -401,6 +412,13 @@ module Bowline
|
|
401
412
|
# You can add gems with the #gem method.
|
402
413
|
attr_accessor :gems
|
403
414
|
|
415
|
+
attr_accessor :dependency_loading
|
416
|
+
|
417
|
+
def threadsafe!
|
418
|
+
self.cache_classes = true
|
419
|
+
self.dependency_loading = false
|
420
|
+
end
|
421
|
+
|
404
422
|
# Adds a single Gem dependency to the Bowline application. By default, it will require
|
405
423
|
# the library with the same name as the gem. Use :lib to specify a different name.
|
406
424
|
#
|
@@ -469,6 +487,7 @@ module Bowline
|
|
469
487
|
self.frameworks = default_frameworks
|
470
488
|
self.load_paths = default_load_paths
|
471
489
|
self.load_once_paths = default_load_once_paths
|
490
|
+
self.dependency_loading = default_dependency_loading
|
472
491
|
self.eager_load_paths = default_eager_load_paths
|
473
492
|
self.log_path = default_log_path
|
474
493
|
self.log_level = default_log_level
|
@@ -568,14 +587,18 @@ module Bowline
|
|
568
587
|
def default_load_once_paths
|
569
588
|
[]
|
570
589
|
end
|
590
|
+
|
591
|
+
def default_dependency_loading
|
592
|
+
true
|
593
|
+
end
|
571
594
|
|
572
595
|
def default_eager_load_paths
|
573
596
|
%w(
|
574
|
-
app/binders
|
575
597
|
app/models
|
576
598
|
app/remote
|
577
|
-
app/helpers
|
578
599
|
app/windows
|
600
|
+
app/binders
|
601
|
+
app/helpers
|
579
602
|
).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
|
580
603
|
end
|
581
604
|
|
data/lib/bowline/library.rb
CHANGED
@@ -2,8 +2,8 @@ module Bowline
|
|
2
2
|
# Provides paths to Bowline's required libraries.
|
3
3
|
module Library
|
4
4
|
PROJECT_URL = "http://bowline.s3.amazonaws.com/#{Platform.type}"
|
5
|
-
DESKTOP_URL = "#{PROJECT_URL}/bowline-desktop"
|
6
|
-
|
5
|
+
DESKTOP_URL = "#{PROJECT_URL}/bowline-desktop.zip"
|
6
|
+
LIBS_URL = "#{PROJECT_URL}/libs.zip"
|
7
7
|
|
8
8
|
# Path to a folder stored under the users
|
9
9
|
# home directory containing the downloaded libraries.
|
@@ -20,22 +20,16 @@ module Bowline
|
|
20
20
|
end
|
21
21
|
module_function :desktop_path
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
File.join(path, "rubylib")
|
23
|
+
def libs_path
|
24
|
+
File.join(path, "libs")
|
26
25
|
end
|
27
|
-
module_function :
|
26
|
+
module_function :libs_path
|
28
27
|
|
29
28
|
def local_bowline_path
|
30
29
|
File.join(APP_ROOT, "vendor", "bowline")
|
31
30
|
end
|
32
31
|
module_function :local_bowline_path
|
33
32
|
|
34
|
-
def local_rubylib_path
|
35
|
-
File.join(APP_ROOT, "vendor", "rubylib")
|
36
|
-
end
|
37
|
-
module_function :local_rubylib_path
|
38
|
-
|
39
33
|
def local_build_path
|
40
34
|
File.join(APP_ROOT, "build")
|
41
35
|
end
|
@@ -44,7 +38,7 @@ module Bowline
|
|
44
38
|
# Returns true if all required libraries exist.
|
45
39
|
def ready?
|
46
40
|
File.exist?(desktop_path) &&
|
47
|
-
File.directory?(
|
41
|
+
File.directory?(libs_path) &&
|
48
42
|
File.directory?(local_bowline_path)
|
49
43
|
end
|
50
44
|
module_function :ready?
|
data/lib/bowline/logging.rb
CHANGED
@@ -15,7 +15,7 @@ module Bowline
|
|
15
15
|
|
16
16
|
# Log an error backtrace if debugging is activated
|
17
17
|
def log_error(e=$!)
|
18
|
-
|
18
|
+
Bowline.logger.error "#{e}\n\t" + e.backtrace.join("\n\t")
|
19
19
|
end
|
20
20
|
module_function :log_error
|
21
21
|
public :log_error
|
data/lib/bowline/tasks/app.rake
CHANGED
@@ -4,6 +4,44 @@ require 'rbconfig'
|
|
4
4
|
|
5
5
|
namespace :app do
|
6
6
|
namespace :build do
|
7
|
+
namespace :osx do
|
8
|
+
desc "Copy WebKit into app's Frameworks"
|
9
|
+
task :webkit_framework => :environment do
|
10
|
+
config = Bowline.configuration
|
11
|
+
build_path = Bowline::Library.local_build_path
|
12
|
+
app_path = File.join(build_path, "#{config.name}.app")
|
13
|
+
contents_path = File.join(app_path, "Contents")
|
14
|
+
|
15
|
+
webkit_path = ENV["WEBKIT_PATH"] || "/Applications/WebKit.app/Contents/Frameworks/10.5"
|
16
|
+
unless File.directory?(webkit_path)
|
17
|
+
raise "Install the WebKit nightly: http://nightly.webkit.org/"
|
18
|
+
end
|
19
|
+
frameworks = ["WebKit", "JavaScriptGlue", "WebCore", "JavaScriptCore"]
|
20
|
+
|
21
|
+
FileUtils.cd(contents_path) do
|
22
|
+
FileUtils.mkdir("Frameworks")
|
23
|
+
|
24
|
+
frameworks.each {|name|
|
25
|
+
name = "#{name}.framework"
|
26
|
+
FileUtils.cp_r(
|
27
|
+
File.join(webkit_path, name),
|
28
|
+
"Frameworks"
|
29
|
+
)
|
30
|
+
}
|
31
|
+
|
32
|
+
`install_name_tool -change \
|
33
|
+
/Volumes/Data/WebKit/52531/10.5/WebKit.framework/Versions/A/WebKit \
|
34
|
+
@executable_path/../Frameworks/WebKit.framework/Versions/A/WebKit \
|
35
|
+
MacOS/#{config.name}`
|
36
|
+
|
37
|
+
`install_name_tool -change \
|
38
|
+
/Volumes/Data/WebKit/52531/10.5/WebCore.framework/Versions/A/WebCore \
|
39
|
+
@executable_path/../Frameworks/WebCore.framework/Versions/A/WebCore \
|
40
|
+
MacOS/#{config.name}`
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
7
45
|
task :osx => :environment do
|
8
46
|
unless Bowline::Library.ready?
|
9
47
|
Rake::Task["libs:setup"].invoke
|
@@ -61,22 +99,19 @@ namespace :app do
|
|
61
99
|
%w{assets pkg examples bin templates .git}.each do |unused|
|
62
100
|
FileUtils.rm_rf(File.join(bowline_path, unused))
|
63
101
|
end
|
64
|
-
|
65
|
-
rubylib_path = "rubylib"
|
66
|
-
FileUtils.rm_rf(rubylib_path)
|
67
|
-
FileUtils.cp_r(
|
68
|
-
Bowline::Library.rubylib_path,
|
69
|
-
rubylib_path
|
70
|
-
)
|
71
102
|
end
|
72
103
|
end
|
73
104
|
|
74
|
-
# Copy Bowline binary
|
105
|
+
# Copy Bowline binary & libs
|
75
106
|
FileUtils.mkdir("MacOS")
|
76
107
|
FileUtils.cp(
|
77
108
|
Bowline::Library.desktop_path,
|
78
109
|
File.join("MacOS", config.name)
|
79
110
|
)
|
111
|
+
FileUtils.cp_r(
|
112
|
+
Bowline::Library.libs_path,
|
113
|
+
File.join("MacOS", "libs")
|
114
|
+
)
|
80
115
|
end
|
81
116
|
FileUtils.chmod_R(0755, app_path)
|
82
117
|
FileUtils.chmod(0644, File.join(contents_path, "Info.plist"))
|
data/lib/bowline/tasks/libs.rake
CHANGED
@@ -5,13 +5,14 @@ require 'progressbar'
|
|
5
5
|
require 'zip/zip'
|
6
6
|
|
7
7
|
def download(url)
|
8
|
+
puts "Retrieving: #{url}"
|
8
9
|
name = url.split("/").last
|
9
10
|
file = Tempfile.new("download_#{name}")
|
10
11
|
url = URI.parse(url)
|
11
12
|
req = Net::HTTP::Get.new(url.path)
|
12
13
|
res = Net::HTTP.start(url.host, url.port) {|http|
|
13
14
|
http.request(req) {|resp|
|
14
|
-
pbar = ProgressBar.new("Downloading
|
15
|
+
pbar = ProgressBar.new("Downloading", resp.content_length || 0)
|
15
16
|
resp.read_body {|seg|
|
16
17
|
pbar.inc(seg.length)
|
17
18
|
file.write(seg)
|
@@ -41,7 +42,7 @@ def sym_or_copy(from, to)
|
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
44
|
-
namespace :libs do
|
45
|
+
namespace :libs do
|
45
46
|
task :unpack => :environment do
|
46
47
|
# Lots of people are using Ruby 1.8 with Bowline.
|
47
48
|
# When bowline-desktop loads, it doesn't know where the
|
@@ -53,33 +54,27 @@ namespace :libs do
|
|
53
54
|
Bowline.lib_path,
|
54
55
|
local_bowline_path
|
55
56
|
) unless File.directory?(local_bowline_path)
|
56
|
-
|
57
|
-
local_rubylib_path = Bowline::Library.local_rubylib_path
|
58
|
-
raise "Run libs:download task first" unless File.directory?(Bowline::Library.rubylib_path)
|
59
|
-
sym_or_copy(
|
60
|
-
Bowline::Library.rubylib_path,
|
61
|
-
local_rubylib_path
|
62
|
-
) unless File.directory?(local_rubylib_path)
|
63
57
|
end
|
64
58
|
|
65
59
|
desc "Download Bowline's binary and pre-compiled libs"
|
66
60
|
task :download => :environment do
|
67
61
|
FileUtils.mkdir_p(Bowline::Library.path)
|
68
62
|
desktop_path = Bowline::Library.desktop_path
|
69
|
-
|
63
|
+
libs_path = Bowline::Library.libs_path
|
70
64
|
|
71
65
|
unless File.exist?(desktop_path)
|
72
66
|
desktop_tmp = download(Bowline::Library::DESKTOP_URL)
|
73
67
|
desktop_tmp.close
|
74
|
-
|
68
|
+
puts "Extracting bowline-desktop.zip"
|
69
|
+
unzip(desktop_tmp.path, Bowline::Library.path)
|
75
70
|
FileUtils.chmod(0755, desktop_path)
|
76
71
|
end
|
77
72
|
|
78
|
-
unless File.directory?(
|
79
|
-
|
80
|
-
|
81
|
-
puts "Extracting
|
82
|
-
unzip(
|
73
|
+
unless File.directory?(libs_path)
|
74
|
+
libs_tmp = download(Bowline::Library::LIBS_URL)
|
75
|
+
libs_tmp.close
|
76
|
+
puts "Extracting libs.zip (this could take some time)"
|
77
|
+
unzip(libs_tmp.path, Bowline::Library.path)
|
83
78
|
end
|
84
79
|
end
|
85
80
|
|
@@ -88,8 +83,6 @@ namespace :libs do
|
|
88
83
|
desc "Update Bowline's binary and pre-compiled libs"
|
89
84
|
task :update => :environment do
|
90
85
|
FileUtils.rm_rf(Bowline::Library.path)
|
91
|
-
FileUtils.rm_rf(Bowline::Library.local_bowline_path)
|
92
|
-
FileUtils.rm_rf(Bowline::Library.local_rubylib_path)
|
93
86
|
Rake::Task["libs:setup"].invoke
|
94
87
|
end
|
95
88
|
end
|
data/lib/bowline/version.rb
CHANGED
@@ -10,8 +10,5 @@ Bowline::Initializer.run do |config|
|
|
10
10
|
|
11
11
|
# config.gem "activerecord"
|
12
12
|
# config.gem "net-mdns", :lib => 'net/dns/mdns'
|
13
|
-
# config.gem "rack"
|
14
13
|
# config.gem "rubyzip", :lib => 'zip/zip'
|
15
|
-
# Bowline Edge:
|
16
|
-
# config.gem "maccman-bowline", :lib => "bowline", :source => "http://gems.github.com"
|
17
14
|
end
|
data/templates/public/index.html
CHANGED
@@ -12,9 +12,7 @@
|
|
12
12
|
<script type="text/javascript" charset="utf-8">
|
13
13
|
// Binder Example:
|
14
14
|
// jQuery(function($){
|
15
|
-
//
|
16
|
-
// $('#tweets').bindto('TweetsBinder');
|
17
|
-
// })
|
15
|
+
// $('#tweets').bowlineBind('TweetsBinder');
|
18
16
|
// });
|
19
17
|
</script>
|
20
18
|
</head>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bowline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex MacCaw
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-19 00:00:00 +00:00
|
13
13
|
default_executable: bowline-gen
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -59,8 +59,13 @@ files:
|
|
59
59
|
- Rakefile
|
60
60
|
- TODO
|
61
61
|
- VERSION
|
62
|
+
- assets/animations.css
|
62
63
|
- assets/bowline.js
|
64
|
+
- assets/bowline.menu.js
|
65
|
+
- assets/bowline.state.js
|
66
|
+
- assets/bowline.view.js
|
63
67
|
- assets/jquery.chain.js
|
68
|
+
- assets/jquery.dataset.js
|
64
69
|
- assets/jquery.js
|
65
70
|
- assets/json2.js
|
66
71
|
- assets/osx/Info.plist.erb
|