sproutcore 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +19 -0
- data/Manifest.txt +15 -1
- data/clients/view_builder/builders/builder.js +339 -0
- data/clients/view_builder/builders/button.js +81 -0
- data/clients/view_builder/controllers/document.js +21 -0
- data/clients/view_builder/core.js +19 -0
- data/clients/view_builder/english.lproj/body.css +77 -0
- data/clients/view_builder/english.lproj/body.rhtml +39 -0
- data/clients/view_builder/english.lproj/controls.css +0 -0
- data/clients/view_builder/english.lproj/strings.js +14 -0
- data/clients/view_builder/main.js +38 -0
- data/clients/view_builder/mixins/design_mode.js +92 -0
- data/clients/view_builder/tests/controllers/document.rhtml +20 -0
- data/clients/view_builder/tests/views/builder.rhtml +20 -0
- data/clients/view_builder/tests/views/palette.rhtml +21 -0
- data/clients/view_builder/views/builder.js +26 -0
- data/clients/view_builder/views/palette.js +30 -0
- data/frameworks/sproutcore/Core.js +6 -4
- data/frameworks/sproutcore/README +1 -3
- data/frameworks/sproutcore/controllers/array.js +5 -5
- data/frameworks/sproutcore/drag/drag.js +2 -0
- data/frameworks/sproutcore/english.lproj/panes.css +16 -35
- data/frameworks/sproutcore/foundation/application.js +29 -8
- data/frameworks/sproutcore/foundation/object.js +5 -1
- data/frameworks/sproutcore/foundation/run_loop.js +65 -2
- data/frameworks/sproutcore/foundation/timer.js +1 -0
- data/frameworks/sproutcore/globals/window.js +23 -18
- data/frameworks/sproutcore/mixins/array.js +2 -2
- data/frameworks/sproutcore/mixins/observable.js +127 -52
- data/frameworks/sproutcore/panes/dialog.js +1 -1
- data/frameworks/sproutcore/panes/overlay.js +6 -2
- data/frameworks/sproutcore/panes/pane.js +27 -0
- data/frameworks/sproutcore/views/collection/collection.js +1 -1
- data/frameworks/sproutcore/views/collection/grid.js +3 -15
- data/frameworks/sproutcore/views/collection/source_list.js +10 -5
- data/frameworks/sproutcore/views/field/select_field.js +11 -2
- data/frameworks/sproutcore/views/field/text_field.js +1 -1
- data/frameworks/sproutcore/views/label.js +2 -7
- data/frameworks/sproutcore/views/view.js +254 -213
- data/generators/client/README +2 -2
- data/generators/client/USAGE +2 -2
- data/lib/sproutcore/build_tools/html_builder.rb +2 -2
- data/lib/sproutcore/bundle_manifest.rb +28 -22
- data/lib/sproutcore/merb/bundle_controller.rb +4 -3
- data/lib/sproutcore/version.rb +1 -1
- metadata +17 -3
- data/frameworks/sproutcore/animation/animation.js +0 -411
@@ -1,3 +1 @@
|
|
1
|
-
SproutCore is a framework for building JavaScript
|
2
|
-
|
3
|
-
|
1
|
+
SproutCore is a framework for building applications in JavaScript. It eliminates much of the glue code you would often write to build applications on the web so you can focus on building features. To get started using SproutCore, visit the website at http://www.sproutcore.com, where you can find documentation and tutorials.
|
@@ -24,14 +24,14 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
|
|
24
24
|
{
|
25
25
|
/**
|
26
26
|
Provides compatibility with CollectionControllers.
|
27
|
-
@
|
27
|
+
@field
|
28
28
|
@type {SC.ArrayController}
|
29
29
|
*/
|
30
30
|
arrangedObjects: function() { return this; }.property('content'),
|
31
31
|
|
32
32
|
/**
|
33
33
|
The array content that is being managed by the controller.
|
34
|
-
@
|
34
|
+
@field
|
35
35
|
@type {Array}
|
36
36
|
*/
|
37
37
|
content: null,
|
@@ -42,7 +42,7 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
|
|
42
42
|
deleted. This is a convenient way to manage lists of items owned
|
43
43
|
by a parent record object.
|
44
44
|
|
45
|
-
@
|
45
|
+
@field
|
46
46
|
@type {Boolean}
|
47
47
|
*/
|
48
48
|
destroyOnRemoval: false,
|
@@ -65,7 +65,7 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
|
|
65
65
|
The array content that (when committed) will be merged back into the content property.
|
66
66
|
All array methods will take place on this object.
|
67
67
|
|
68
|
-
@
|
68
|
+
@field
|
69
69
|
@type {SC.Array}
|
70
70
|
*/
|
71
71
|
contentClone: null,
|
@@ -144,7 +144,7 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
|
|
144
144
|
},
|
145
145
|
/**
|
146
146
|
* SC.Array interface implimentation.
|
147
|
-
* @
|
147
|
+
* @field
|
148
148
|
* @type {integer}
|
149
149
|
*/
|
150
150
|
length: function( key, value ) {
|
@@ -344,6 +344,8 @@ SC.Drag = SC.Object.extend(
|
|
344
344
|
|
345
345
|
if (target && target.prepareForDragOperation(op, this)) {
|
346
346
|
op = target.performDragOperation(op, this) ;
|
347
|
+
} else {
|
348
|
+
op = SC.DRAG_NONE;
|
347
349
|
}
|
348
350
|
|
349
351
|
// create cleanupFunc. This function will be called at the end of this
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
/* @override http://localhost:4020/static/sproutcore/en/_cache/panes-1206750928.css */
|
2
2
|
|
3
3
|
/* @group Core */
|
4
4
|
|
@@ -16,25 +16,25 @@
|
|
16
16
|
.sc-theme #panes .pane-wrapper h1 {
|
17
17
|
font-size: 16px;
|
18
18
|
margin: 0;
|
19
|
-
|
20
|
-
|
19
|
+
padding: 0;
|
20
|
+
}
|
21
|
+
|
22
|
+
.sc-theme #panes .pane-wrapper p {
|
23
|
+
margin: 8px 0;
|
21
24
|
}
|
22
25
|
|
23
26
|
.sc-theme #panes .pane-wrapper .buttons {
|
24
|
-
border-top: 1px #aaa dotted;
|
25
27
|
text-align: right ;
|
26
|
-
|
27
|
-
margin-
|
28
|
-
|
29
|
-
|
30
|
-
padding-right: 16px;
|
31
|
-
padding-left: 16px;
|
28
|
+
margin-left: -20px;
|
29
|
+
margin-right: -20px;
|
30
|
+
padding-right: 20px;
|
31
|
+
padding-left: 20px;
|
32
32
|
}
|
33
33
|
|
34
34
|
.sc-theme .pane .shadow {
|
35
35
|
position: relative ;
|
36
36
|
border: none ;
|
37
|
-
background: #e8e8e8
|
37
|
+
background: #e8e8e8 url('/static/sproutcore/_src/english.lproj/panels/background-thin.png') repeat-x left -1px;
|
38
38
|
border-top: 1px #ddd solid;
|
39
39
|
}
|
40
40
|
|
@@ -113,7 +113,8 @@
|
|
113
113
|
|
114
114
|
/* @group Panels */
|
115
115
|
|
116
|
-
.sc-theme .panel-pane
|
116
|
+
.sc-theme .panel-pane,
|
117
|
+
.sc-theme .dialog-pane {
|
117
118
|
position: absolute ;
|
118
119
|
top: 0;
|
119
120
|
left: 0;
|
@@ -122,34 +123,14 @@
|
|
122
123
|
background: static_url('panels/overlay') repeat;
|
123
124
|
}
|
124
125
|
|
125
|
-
.sc-theme .panel-pane .pane-wrapper
|
126
|
+
.sc-theme .panel-pane .pane-wrapper,
|
127
|
+
.sc-theme .dialog-pane .pane-wrapper {
|
126
128
|
top: 50px;
|
127
129
|
margin-left: auto;
|
128
130
|
margin-right: auto;
|
129
|
-
padding:
|
131
|
+
padding: 16px 24px;
|
130
132
|
}
|
131
133
|
|
132
134
|
/* @end */
|
133
135
|
|
134
|
-
/* @group Dialogs */
|
135
|
-
|
136
|
-
.sc-theme .dialog-pane {
|
137
|
-
position: absolute ;
|
138
|
-
top: 0;
|
139
|
-
left: 0;
|
140
|
-
width: 100%;
|
141
|
-
height: 100%;
|
142
|
-
background-color: rgba(255,255,255,0.63);
|
143
|
-
}
|
144
|
-
|
145
|
-
.sc-theme .dialog-pane .pane-wrapper {
|
146
|
-
margin-left: auto ;
|
147
|
-
margin-right: auto ;
|
148
|
-
border: 6px #888 solid ;
|
149
|
-
background: #e8e8e8 static_url('panels/background-thin') repeat-x left -1px;
|
150
|
-
padding: 10px 14px;
|
151
|
-
position: relative ;
|
152
|
-
top: 75px;
|
153
|
-
}
|
154
136
|
|
155
|
-
/* @end */
|
@@ -1,3 +1,8 @@
|
|
1
|
+
// ========================================================================
|
2
|
+
// SproutCore
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
|
+
// ========================================================================
|
5
|
+
|
1
6
|
require('Core');
|
2
7
|
require('foundation/responder');
|
3
8
|
|
@@ -13,14 +18,19 @@ require('foundation/responder');
|
|
13
18
|
@extends SC.Responder
|
14
19
|
@author Skip Baney
|
15
20
|
@copyright 2006-2008, Sprout Systems, Inc. and contributors.
|
16
|
-
@
|
21
|
+
@since SproutCore 1.0
|
17
22
|
*/
|
18
23
|
SC.Application = SC.Responder.extend(
|
19
24
|
/** @scope SC.Application.prototype */ {
|
20
|
-
|
25
|
+
|
21
26
|
/**
|
22
|
-
|
23
|
-
|
27
|
+
The pane that is currently receiving key events.
|
28
|
+
|
29
|
+
This is most often the SC.window object but if you display a popup or
|
30
|
+
some other such element, you may set this to some other value.
|
31
|
+
|
32
|
+
@field
|
33
|
+
@type {SC.View}
|
24
34
|
*/
|
25
35
|
keyPane: function( key, value )
|
26
36
|
{
|
@@ -36,8 +46,14 @@ SC.Application = SC.Responder.extend(
|
|
36
46
|
}.property(),
|
37
47
|
|
38
48
|
/**
|
39
|
-
|
40
|
-
|
49
|
+
The main pane for the application.
|
50
|
+
|
51
|
+
The main pane is usually the primary pane you expect users to work in.
|
52
|
+
It receives keyboard equivalent events and other operations even when
|
53
|
+
another key pane is positioned over it.
|
54
|
+
|
55
|
+
@field
|
56
|
+
@type {SC.View}
|
41
57
|
*/
|
42
58
|
mainPane: function( key, value )
|
43
59
|
{
|
@@ -53,8 +69,13 @@ SC.Application = SC.Responder.extend(
|
|
53
69
|
}.property(),
|
54
70
|
|
55
71
|
/**
|
56
|
-
|
57
|
-
|
72
|
+
Starts the SproutCore application.
|
73
|
+
|
74
|
+
Typically this will simply setup the SC.window object so that it starts
|
75
|
+
to receive keyboard and mouse events and then makes the window both
|
76
|
+
main and key pane.
|
77
|
+
|
78
|
+
@returns {void}
|
58
79
|
*/
|
59
80
|
run: function()
|
60
81
|
{
|
@@ -302,6 +302,7 @@ Object.extend(SC.Object,
|
|
302
302
|
var bindings = (ext._bindings) ? null : (base._bindings || []).slice() ;
|
303
303
|
var observers = (ext._observers) ? null : (base._observers || []).slice();
|
304
304
|
var properties = (ext._properties) ? null : (base._properties || []).slice() ;
|
305
|
+
var outlets = (ext.outlets) ? null : (base.outlets || []).slice() ;
|
305
306
|
|
306
307
|
// now copy properties, add superclass to func.
|
307
308
|
for(var key in ext) {
|
@@ -320,12 +321,14 @@ Object.extend(SC.Object,
|
|
320
321
|
if (bindings && (key.slice(keyLen-7,keyLen) == "Binding")) {
|
321
322
|
bindings.push(key) ;
|
322
323
|
|
323
|
-
// Also add observers and properties for functions...
|
324
|
+
// Also add observers, outlets, and properties for functions...
|
324
325
|
} else if (value && (value instanceof Function)) {
|
325
326
|
if (observers && value.propertyPaths) {
|
326
327
|
observers.push(key) ;
|
327
328
|
} else if (properties && value.dependentKeys) {
|
328
329
|
properties.push(key) ;
|
330
|
+
} else if (outlets && value.autoconfiguredOutlet) {
|
331
|
+
outlets.push(key) ;
|
329
332
|
}
|
330
333
|
}
|
331
334
|
|
@@ -337,6 +340,7 @@ Object.extend(SC.Object,
|
|
337
340
|
if (bindings) base._bindings = bindings;
|
338
341
|
if (observers) base._observers = observers ;
|
339
342
|
if (properties) base._properties = properties ;
|
343
|
+
if (outlets && outlets.length > 0) base.outlets = outlets ;
|
340
344
|
|
341
345
|
//console.log('bindings: %@ -- observers: %@ -- properties: %@'.format(base._bindings,base._observers,base._properties)) ;
|
342
346
|
|
@@ -59,6 +59,66 @@ require('Core') ;
|
|
59
59
|
*/
|
60
60
|
SC.runLoop = SC.Object.create({
|
61
61
|
|
62
|
+
/**
|
63
|
+
Maximum time we allow things to run before taking a break.
|
64
|
+
*/
|
65
|
+
maxRunTime: 3000,
|
66
|
+
|
67
|
+
/**
|
68
|
+
Called by an observable object to schedule an observer to be notified.
|
69
|
+
|
70
|
+
@param target {Object} the target object
|
71
|
+
@param action {Function} the method to call
|
72
|
+
@param args {Array} array of arguments to pass on
|
73
|
+
@returns {void}
|
74
|
+
*/
|
75
|
+
notifyObserver: function(target, action, args) {
|
76
|
+
if (!this._notifications) this._notifications = [] ;
|
77
|
+
this._notifications.push({ target: target, action: action, args: args });
|
78
|
+
},
|
79
|
+
|
80
|
+
/**
|
81
|
+
Tries to flush observer notifications. The idea is that this will
|
82
|
+
continue to remove observers until all of the notifications have flushed
|
83
|
+
or until the max execution time has passed. Called automatically from
|
84
|
+
endRunLoop().
|
85
|
+
|
86
|
+
The way this works, it does not unshift pending notifications but
|
87
|
+
instead just sets them to null until the entire queue is flushed. Then
|
88
|
+
it will reset the queue to a new array. This is faster than shifting().
|
89
|
+
|
90
|
+
@returns {void}
|
91
|
+
*/
|
92
|
+
deliverNotifications: function() {
|
93
|
+
if (!this._notifications || this._notifications.length <=0) return;
|
94
|
+
if (this._notifying) return ; // do not allow recursion
|
95
|
+
this._notifying = YES ;
|
96
|
+
|
97
|
+
var start = this.get('startTime') ;
|
98
|
+
var max = start + this.get('maxRunTime') ;
|
99
|
+
var loc = 0;
|
100
|
+
while((Date.now() < max) && (loc < this._notifications.length)) {
|
101
|
+
var notify = this._notifications[loc] ;
|
102
|
+
this._notifications[loc] = null;
|
103
|
+
loc++ ; // IMPORTANT: Make sure you increment so that we always go on.
|
104
|
+
|
105
|
+
if (notify) {
|
106
|
+
var args = notify.args;
|
107
|
+
notify.action.call(notify.target, args[0], args[1], args[2], args[3]);
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
// if we made it through and the queue is empty, reset it
|
112
|
+
// otherwise, leave the queue in place and schedule another runloop.
|
113
|
+
if (loc >= this._notifications.length) {
|
114
|
+
this._notifications = [];
|
115
|
+
} else {
|
116
|
+
this.invokeLater(this.deliverNotifications) ;
|
117
|
+
}
|
118
|
+
|
119
|
+
this._notifying = NO ;
|
120
|
+
},
|
121
|
+
|
62
122
|
/**
|
63
123
|
Call this method whenver you begin executing code.
|
64
124
|
|
@@ -82,7 +142,10 @@ SC.runLoop = SC.Object.create({
|
|
82
142
|
@returns {void}
|
83
143
|
*/
|
84
144
|
endRunLoop: function() {
|
85
|
-
//
|
145
|
+
// send any pending notifications.
|
146
|
+
//this.deliverNotifications() ;
|
147
|
+
|
148
|
+
// flush any expired timers, possibly cancelling the timeout.
|
86
149
|
this._flushExpiredTimers() ;
|
87
150
|
this._start = null ;
|
88
151
|
},
|
@@ -216,7 +279,7 @@ SC.runLoop = SC.Object.create({
|
|
216
279
|
_flushExpiredTimers: function() {
|
217
280
|
if (!this._timers) this._timers = {} ;
|
218
281
|
var now = this.get('startTime') ;
|
219
|
-
var max = now +
|
282
|
+
var max = now + this.get('maxRunTime'); // max time we are allowed to run timers
|
220
283
|
|
221
284
|
this._flushing = YES ;
|
222
285
|
|
@@ -71,12 +71,16 @@ SC.window = SC.PaneView.extend({
|
|
71
71
|
autoresizesChildViews: true,
|
72
72
|
|
73
73
|
_onresize: function(evt) {
|
74
|
+
SC.runLoop.beginRunLoop();
|
75
|
+
|
74
76
|
var oldSize = Object.clone(this.get('size')) ;
|
75
77
|
this._size = null ;
|
76
78
|
var newSize = this.get('size') ;
|
77
79
|
if ((newSize.width != oldSize.width) || (newSize.height != oldSize.height)) {
|
78
80
|
this.resizeChildrenWithOldSize(oldSize) ;
|
79
81
|
}
|
82
|
+
|
83
|
+
SC.runLoop.endRunLoop() ;
|
80
84
|
},
|
81
85
|
|
82
86
|
// ........................................................................
|
@@ -133,17 +137,21 @@ SC.window = SC.PaneView.extend({
|
|
133
137
|
|
134
138
|
_sendEvent: function( sctype, evt )
|
135
139
|
{
|
140
|
+
SC.runLoop.beginRunLoop();
|
141
|
+
|
136
142
|
evt._type = sctype;
|
137
143
|
evt._stopWhenHandled = (evt._stopWhenHandled !== undefined) ? evt._stopWhenHandled : true;
|
138
144
|
|
139
145
|
var handler = SC.app.sendEvent( evt );
|
140
146
|
|
147
|
+
var ret = true;
|
141
148
|
if (handler && evt._stopWhenHandled) {
|
142
149
|
Event.stop(evt);
|
143
|
-
|
144
|
-
} else {
|
145
|
-
return true;
|
150
|
+
ret = false;
|
146
151
|
}
|
152
|
+
|
153
|
+
SC.runLoop.endRunLoop();
|
154
|
+
return ret ;
|
147
155
|
},
|
148
156
|
|
149
157
|
// util code factored out of keypress and keydown handlers
|
@@ -173,6 +181,8 @@ SC.window = SC.PaneView.extend({
|
|
173
181
|
|
174
182
|
_onmousedown: function(evt)
|
175
183
|
{
|
184
|
+
SC.runLoop.beginRunLoop();
|
185
|
+
|
176
186
|
// make sure the view gets focus no matter what. FF is inconsistant
|
177
187
|
// about this.
|
178
188
|
this._onfocus();
|
@@ -189,26 +199,15 @@ SC.window = SC.PaneView.extend({
|
|
189
199
|
evt._stopWhenHandled = (evt._stopWhenHandled !== undefined) ? evt._stopWhenHandled : true;
|
190
200
|
|
191
201
|
this._mouseDownView = SC.app.sendEvent( evt );
|
202
|
+
var ret = true ;
|
192
203
|
if (this._mouseDownView && evt._stopWhenHandled)
|
193
204
|
{
|
194
205
|
Event.stop(evt);
|
206
|
+
ret = false ;
|
195
207
|
}
|
196
208
|
|
197
|
-
|
198
|
-
|
199
|
-
/* var view = this.firstViewForEvent(evt) ;
|
200
|
-
var handled = false ;
|
201
|
-
while(view && (view != this) && !handled) {
|
202
|
-
var func = view.mouseDown || view.didMouseDown;
|
203
|
-
if (func) handled = func.call(view, evt) ;
|
204
|
-
|
205
|
-
if (!handled) view = view.get('nextResponder');
|
206
|
-
}
|
207
|
-
if (view == this) view = null;
|
208
|
-
this._mouseDownView = view ;
|
209
|
-
|
210
|
-
if (handled) Event.stop(evt) ;
|
211
|
-
*/
|
209
|
+
SC.runLoop.endRunLoop();
|
210
|
+
return ret ;
|
212
211
|
},
|
213
212
|
|
214
213
|
// mouseUp only gets delivered to the view that handled the mouseDown evt.
|
@@ -218,6 +217,7 @@ SC.window = SC.PaneView.extend({
|
|
218
217
|
// send.
|
219
218
|
_onmouseup: function(evt)
|
220
219
|
{
|
220
|
+
SC.runLoop.beginRunLoop();
|
221
221
|
var handler = null;
|
222
222
|
|
223
223
|
this._lastMouseUpAt = Date.now();
|
@@ -246,6 +246,7 @@ SC.window = SC.PaneView.extend({
|
|
246
246
|
}
|
247
247
|
|
248
248
|
this._mouseDownView = null;
|
249
|
+
SC.runLoop.endRunLoop() ;
|
249
250
|
},
|
250
251
|
|
251
252
|
_lastHovered: null,
|
@@ -260,6 +261,8 @@ SC.window = SC.PaneView.extend({
|
|
260
261
|
//
|
261
262
|
_onmousemove: function(evt) {
|
262
263
|
|
264
|
+
SC.runLoop.beginRunLoop();
|
265
|
+
|
263
266
|
// make sure the view gets focus no matter what. FF is inconsistant
|
264
267
|
// about this.
|
265
268
|
this._onfocus();
|
@@ -300,6 +303,8 @@ SC.window = SC.PaneView.extend({
|
|
300
303
|
if (this._mouseDownView && this._mouseDownView.mouseDragged) {
|
301
304
|
this._mouseDownView.mouseDragged(evt) ;
|
302
305
|
}
|
306
|
+
|
307
|
+
SC.runLoop.endRunLoop();
|
303
308
|
},
|
304
309
|
|
305
310
|
// remove event observers.
|