sproutcore 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/History.txt +19 -0
  2. data/Manifest.txt +15 -1
  3. data/clients/view_builder/builders/builder.js +339 -0
  4. data/clients/view_builder/builders/button.js +81 -0
  5. data/clients/view_builder/controllers/document.js +21 -0
  6. data/clients/view_builder/core.js +19 -0
  7. data/clients/view_builder/english.lproj/body.css +77 -0
  8. data/clients/view_builder/english.lproj/body.rhtml +39 -0
  9. data/clients/view_builder/english.lproj/controls.css +0 -0
  10. data/clients/view_builder/english.lproj/strings.js +14 -0
  11. data/clients/view_builder/main.js +38 -0
  12. data/clients/view_builder/mixins/design_mode.js +92 -0
  13. data/clients/view_builder/tests/controllers/document.rhtml +20 -0
  14. data/clients/view_builder/tests/views/builder.rhtml +20 -0
  15. data/clients/view_builder/tests/views/palette.rhtml +21 -0
  16. data/clients/view_builder/views/builder.js +26 -0
  17. data/clients/view_builder/views/palette.js +30 -0
  18. data/frameworks/sproutcore/Core.js +6 -4
  19. data/frameworks/sproutcore/README +1 -3
  20. data/frameworks/sproutcore/controllers/array.js +5 -5
  21. data/frameworks/sproutcore/drag/drag.js +2 -0
  22. data/frameworks/sproutcore/english.lproj/panes.css +16 -35
  23. data/frameworks/sproutcore/foundation/application.js +29 -8
  24. data/frameworks/sproutcore/foundation/object.js +5 -1
  25. data/frameworks/sproutcore/foundation/run_loop.js +65 -2
  26. data/frameworks/sproutcore/foundation/timer.js +1 -0
  27. data/frameworks/sproutcore/globals/window.js +23 -18
  28. data/frameworks/sproutcore/mixins/array.js +2 -2
  29. data/frameworks/sproutcore/mixins/observable.js +127 -52
  30. data/frameworks/sproutcore/panes/dialog.js +1 -1
  31. data/frameworks/sproutcore/panes/overlay.js +6 -2
  32. data/frameworks/sproutcore/panes/pane.js +27 -0
  33. data/frameworks/sproutcore/views/collection/collection.js +1 -1
  34. data/frameworks/sproutcore/views/collection/grid.js +3 -15
  35. data/frameworks/sproutcore/views/collection/source_list.js +10 -5
  36. data/frameworks/sproutcore/views/field/select_field.js +11 -2
  37. data/frameworks/sproutcore/views/field/text_field.js +1 -1
  38. data/frameworks/sproutcore/views/label.js +2 -7
  39. data/frameworks/sproutcore/views/view.js +254 -213
  40. data/generators/client/README +2 -2
  41. data/generators/client/USAGE +2 -2
  42. data/lib/sproutcore/build_tools/html_builder.rb +2 -2
  43. data/lib/sproutcore/bundle_manifest.rb +28 -22
  44. data/lib/sproutcore/merb/bundle_controller.rb +4 -3
  45. data/lib/sproutcore/version.rb +1 -1
  46. metadata +17 -3
  47. data/frameworks/sproutcore/animation/animation.js +0 -411
@@ -1,3 +1 @@
1
- SproutCore is a framework for building JavaScript applications. It contains a number of components you can use to enable traditional desktop-like functions using only javascript. SproutCore relies on Prototype and works with Scriptaculous, jQuery or any other toolkit you like to use.
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
- @property
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
- @property
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
- @property
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
- @property
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
- * @property
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
- margin-bottom: 10px;
20
- border-bottom: 1px #aaa dotted;
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
- padding-top: 12px;
27
- margin-top: 10px;
28
- margin-left: -16px;
29
- margin-right: -16px;
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 static_url('panels/background-thin') repeat-x left -1px;
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: 11px 16px;
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
- @version 0.1
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
- * The pane that is currently receiving key events.
23
- * @return {SC.PaneView}
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
- * The primary pane for the application.
40
- * @return {SC.PaneView}
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
- * Starts the application
57
- * @return {void}
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
- // flush any expired timers, possibly cancelling the timout.
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 + 3000; // max time we are allowed to run timers
282
+ var max = now + this.get('maxRunTime'); // max time we are allowed to run timers
220
283
 
221
284
  this._flushing = YES ;
222
285
 
@@ -4,6 +4,7 @@
4
4
  // ========================================================================
5
5
 
6
6
  require('Core') ;
7
+ require('foundation/object');
7
8
 
8
9
  /**
9
10
  @class
@@ -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
- return false;
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
- // find the view to handle the mouseDown. go up the chain till you find
198
- // one that implements didMouseDown or mouseDown && returns true.
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.