bowline 0.5.6 → 0.5.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|