sproutcore 0.9.3 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -28,7 +28,7 @@ SC.OUT_OF_RANGE_EXCEPTION = "Index out of range" ;
28
28
  SC.Array = {
29
29
 
30
30
  /**
31
- @property {Number} length
31
+ @field {Number} length
32
32
 
33
33
  Your array must support the length property. your replace methods should
34
34
  set this property whenever it changes.
@@ -92,7 +92,7 @@ SC.Array = {
92
92
  },
93
93
 
94
94
  /**
95
- @property []
95
+ @field []
96
96
 
97
97
  This is the handler for the special array content property. If you get
98
98
  this property, it will return this. If you set this property it a new
@@ -197,7 +197,7 @@ SC.Observable = {
197
197
  this may be more efficient.
198
198
  */
199
199
  setIfChanged: function(key, value) {
200
- return (this.get(key) != value) ? this.set(key, value) : value ;
200
+ return (this.get(key) !== value) ? this.set(key, value) : value ;
201
201
  },
202
202
 
203
203
  /**
@@ -236,6 +236,9 @@ SC.Observable = {
236
236
 
237
237
  /**
238
238
  Increments the value of a property.
239
+
240
+ @param key {String} property name
241
+ @returns {Number} new value of property
239
242
  */
240
243
  incrementProperty: function(key) {
241
244
  return this.set(key,(this.get(key) || 0)+1);
@@ -243,25 +246,35 @@ SC.Observable = {
243
246
 
244
247
  /**
245
248
  decrements a property
249
+
250
+ @param key {String} property name
251
+ @returns {Number} new value of property
246
252
  */
247
253
  decrementProperty: function(key) {
248
254
  return this.set(key,(this.get(key) || 0) - 1 ) ;
249
255
  },
250
256
 
251
257
  /**
252
- inverts a property. Property should be a bool.
258
+ Inverts a property. Property should be a bool.
259
+
260
+ @param key {String} property name
261
+ @param value {Object} optional parameter for "true" value
262
+ @param alt {Object} optional parameter for "false" value
263
+ @returns {Object} new value
253
264
  */
254
265
  toggleProperty: function(key,value,alt) {
255
266
  if (value === undefined) value = true ;
256
267
  if (alt == undefined) alt = false ;
257
268
  value = (this.get(key) == value) ? alt : value ;
258
- this.set(key,value);
269
+ return this.set(key,value);
259
270
  },
260
271
 
261
272
  /**
262
- This is a generic property handler. If you define it, it will be called
263
- when the named property is not yet set in the object. The default does
264
- nothing.
273
+ Called whenever you try to get or set an undefined property.
274
+
275
+ This is a generic property handler. If you define it, it will be called
276
+ when the named property is not yet set in the object. The default does
277
+ nothing.
265
278
  */
266
279
  unknownProperty: function(key,value) {
267
280
  if (!(value === undefined)) { this[key] = value; }
@@ -269,18 +282,55 @@ SC.Observable = {
269
282
  },
270
283
 
271
284
  /**
272
- Override to receive generic observation notices.
285
+ Generic property observer called whenever a property on the receiver
286
+ changes.
287
+
288
+ If you need to observe a large number of properties on your object, it
289
+ is sometimes more efficient to implement this observer only and then to
290
+ handle requests yourself. Although this observer will be triggered
291
+ more often than an observer registered on a specific property, it also
292
+ does not need to be registered which can make it faster to setup your
293
+ object instance.
294
+
295
+ You will often implement this observer using a switch statement on the
296
+ key parameter, taking appropriate action.
297
+
298
+ @param observer {null} no longer used; usually null
299
+ @param target {Object} the target of the change. usually this
300
+ @param key {String} the name of the property that changed
301
+ @param value {Object} the new value of the property.
302
+ @returns {void}
273
303
  */
274
304
  propertyObserver: function(observer,target,key,value) {},
275
305
 
276
306
  /**
277
- You can wrap property changes with these methods to cause notifications
278
- to be delivered only after groups are closed.
307
+ Begins a grouping of property changes.
308
+
309
+ You can use this method to group property changes so that notifications
310
+ will not be sent until the changes are finished. If you plan to make a
311
+ large number of changes to an object at one time, you should call this
312
+ method at the beginning of the changes to suspend change notifications.
313
+ When you are done making changes, all endPropertyChanges() to allow
314
+ notification to resume.
315
+
316
+ @returns {void}
279
317
  */
280
318
  beginPropertyChanges: function() {
281
319
  this._kvo().changes++ ;
282
320
  },
283
321
 
322
+ /**
323
+ Ends a grouping of property changes.
324
+
325
+ You can use this method to group property changes so that notifications
326
+ will not be sent until the changes are finished. If you plan to make a
327
+ large number of changes to an object at one time, you should call
328
+ beginsPropertyChanges() at the beginning of the changes to suspend change
329
+ notifications. When you are done making changes, call this method to allow
330
+ notification to resume.
331
+
332
+ @returns {void}
333
+ */
284
334
  endPropertyChanges: function() {
285
335
  var kvo = this._kvo() ; kvo.changes--;
286
336
  if (kvo.changes <= 0) this._notifyPropertyObservers() ;
@@ -289,16 +339,18 @@ SC.Observable = {
289
339
  /**
290
340
  Notify the observer system that a property is about to change.
291
341
 
292
- Sometimes you need to change a value directly or indirectly without actually
293
- calling get() or set() on it. In this case, you can use this method and
294
- propertyDidChange() instead. Calling these two methods together will notify all
295
- observers that the property has potentially changed value.
342
+ Sometimes you need to change a value directly or indirectly without
343
+ actually calling get() or set() on it. In this case, you can use this
344
+ method and propertyDidChange() instead. Calling these two methods
345
+ together will notify all observers that the property has potentially
346
+ changed value.
296
347
 
297
- Note that you must always call propertyWillChange and propertyDidChange as a pair.
298
- If you do not, it may get the property change groups out of order and cause
299
- notifications to be delivered more often than you would like.
348
+ Note that you must always call propertyWillChange and propertyDidChange as
349
+ a pair. If you do not, it may get the property change groups out of order
350
+ and cause notifications to be delivered more often than you would like.
300
351
 
301
352
  @param key {String} The property key that is about to change.
353
+ @returns {void}
302
354
  */
303
355
  propertyWillChange: function(key) {
304
356
  this._kvo().changes++ ;
@@ -307,17 +359,19 @@ SC.Observable = {
307
359
  /**
308
360
  Notify the observer system that a property has just changed.
309
361
 
310
- Sometimes you need to change a value directly or indirectly without actually
311
- calling get() or set() on it. In this case, you can use this method and
312
- propertyWillChange() instead. Calling these two methods together will notify all
313
- observers that the property has potentially changed value.
362
+ Sometimes you need to change a value directly or indirectly without
363
+ actually calling get() or set() on it. In this case, you can use this
364
+ method and propertyWillChange() instead. Calling these two methods
365
+ together will notify all observers that the property has potentially
366
+ changed value.
314
367
 
315
- Note that you must always call propertyWillChange and propertyDidChange as a pair.
316
- If you do not, it may get the property change groups out of order and cause
317
- notifications to be delivered more often than you would like.
368
+ Note that you must always call propertyWillChange and propertyDidChange as
369
+ a pair. If you do not, it may get the property change groups out of order
370
+ and cause notifications to be delivered more often than you would like.
318
371
 
319
372
  @param key {String} The property key that has just changed.
320
373
  @param value {Object} The new value of the key. May be null.
374
+ @returns {void}
321
375
  */
322
376
  propertyDidChange: function(key,value) {
323
377
  this._kvo().changed[key] = value ;
@@ -328,9 +382,10 @@ SC.Observable = {
328
382
  /**
329
383
  Convenience method to call propertyWillChange/propertyDidChange.
330
384
 
331
- Sometimes you need to notify observers that a property has changed value without
332
- actually changing this value. In those cases, you can use this method as a
333
- convenience instead of calling propertyWillChange() and propertyDidChange().
385
+ Sometimes you need to notify observers that a property has changed value
386
+ without actually changing this value. In those cases, you can use this
387
+ method as a convenience instead of calling propertyWillChange() and
388
+ propertyDidChange().
334
389
 
335
390
  @param key {String} The property key that has just changed.
336
391
  @param value {Object} The new value of the key. May be null.
@@ -342,16 +397,36 @@ SC.Observable = {
342
397
  },
343
398
 
344
399
  /**
345
- This may be a simpler way to notify of changes if you are making a major
346
- update or don't know exactly which properties have changed. This ignores
347
- property gorups.
400
+ Notifies all of observers of a property changes.
401
+
402
+ Sometimes when you make a major update to your object, it is cheaper to
403
+ simply notify all observers that their property might have changed than
404
+ to figure out specifically which properties actually did change.
405
+
406
+ In those cases, you can simply call this method to notify all property
407
+ observers immediately. Note that this ignores property groups.
408
+
409
+ @returns {void}
348
410
  */
349
411
  allPropertiesDidChange: function() {
350
412
  this._notifyPropertyObservers(true) ;
351
413
  },
352
414
 
353
415
  /**
354
- Add an observer
416
+ Adds an observer on a property.
417
+
418
+ This is the core method used to register an observer for a property.
419
+ The observer can be either a simple function or an object and a method.
420
+
421
+ Once you call this method, anytime the key's value is set, your observer
422
+ will be notified. Note that the observers are triggered anytime the
423
+ value is set, regardless of whether it has actually changed. Your
424
+ observer should be prepared to handle that.
425
+
426
+ @param key {String} the key to observer
427
+ @param target {Object} the object holding the action to call. May benull.
428
+ @param action {String,Function} the action to call.
429
+ @returns {void}
355
430
  */
356
431
  addObserver: function(key,func) {
357
432
  var kvo = this._kvo() ;
@@ -376,6 +451,28 @@ SC.Observable = {
376
451
 
377
452
  },
378
453
 
454
+ removeObserver: function(key,func) {
455
+ var kvo = this._kvo() ;
456
+
457
+ // if the key contains a '.', this is a chained observer.
458
+ key = key.toString() ;
459
+ var parts = key.split('.') ;
460
+ if (parts.length > 1) {
461
+ var chainObservers = kvo.chainObserver[key] || [] ;
462
+ var newObservers = [] ;
463
+ chainObservers.each(function(co) {
464
+ if (co.masterFunc != func) newObservers.push(co) ;
465
+ }) ;
466
+ kvo.chainObservers[key] = newObservers ;
467
+
468
+ // otherwise, just like a normal observer.
469
+ } else {
470
+ var observers = kvo.observers[key] || [] ;
471
+ observers = observers.without(func) ;
472
+ kvo.observers[key] = observers ;
473
+ }
474
+ },
475
+
379
476
  addProbe: function(key) { this.addObserver(key,logChange); },
380
477
  removeProbe: function(key) { this.removeObserver(key,logChange); },
381
478
 
@@ -420,28 +517,6 @@ SC.Observable = {
420
517
  return handler ;
421
518
  },
422
519
 
423
- removeObserver: function(key,func) {
424
- var kvo = this._kvo() ;
425
-
426
- // if the key contains a '.', this is a chained observer.
427
- key = key.toString() ;
428
- var parts = key.split('.') ;
429
- if (parts.length > 1) {
430
- var chainObservers = kvo.chainObserver[key] || [] ;
431
- var newObservers = [] ;
432
- chainObservers.each(function(co) {
433
- if (co.masterFunc != func) newObservers.push(co) ;
434
- }) ;
435
- kvo.chainObservers[key] = newObservers ;
436
-
437
- // otherwise, just like a normal observer.
438
- } else {
439
- var observers = kvo.observers[key] || [] ;
440
- observers = observers.without(func) ;
441
- kvo.observers[key] = observers ;
442
- }
443
- },
444
-
445
520
  /**
446
521
  Use this to indicate that one key changes if other keys it depends on
447
522
  change.
@@ -8,7 +8,7 @@ require('panes/overlay') ;
8
8
  SC.DIALOG_PANE = 'dialog';
9
9
  SC.DialogPaneView = SC.OverlayPaneView.extend({
10
10
 
11
- emptyElement: '<div class="pane dialog-pane"><div class="pane-wrapper"><div class="pane-root"></div></div>',
11
+ emptyElement: '<div class="pane dialog-pane"><div class="shadow pane-wrapper"><div class="pane-root"></div><div class="top-left-edge"></div><div class="top-edge"></div><div class="top-right-edge"></div><div class="right-edge"></div><div class="bottom-right-edge"></div><div class="bottom-edge"></div><div class="bottom-left-edge"></div><div class="left-edge"></div></div></div>',
12
12
 
13
13
  layer: 200
14
14
 
@@ -189,8 +189,12 @@ SC.OverlayPaneView = SC.PaneView.extend({
189
189
  if (content) {
190
190
  content.resizeWithOldParentSize(this.get('size')) ;
191
191
 
192
- // compute padding we need to add.
193
- var padding = this.get('size').width - this.get('innerFrame').width;
192
+ // compute space we need to add for border/padding
193
+ var padding = 0;
194
+ this.getEach('styleBorderLeftWidth', 'styleBorderRightWidth', 'stylePaddingLeft', 'stylePaddingRight').each(function(x) { padding += x || 0; });
195
+ this.recacheFrames() ;
196
+ content.recacheFrames() ;
197
+
194
198
  this.set('size', { width: (content.get('size').width + padding) });
195
199
  this.owner.positionPane() ;
196
200
  this.owner.setStyle({ visibility: 'visible' }) ;
@@ -1,9 +1,36 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
1
6
  require('views/view');
2
7
 
3
8
  SC.KEYVIEW_SELECTING_NONE = 0;
4
9
  SC.KEYVIEW_SELECTING_NEXT = 1;
5
10
  SC.KEYVIEW_SELECTING_PREVIOUS = 2;
6
11
 
12
+ /**
13
+ @class
14
+
15
+ A PaneView provides the root view context for a popup, menu, dialog, sheet,
16
+ widget or a window itself. The responder chain, which is used to route
17
+ keyboard and mouse events, always terminates with a pane view.
18
+
19
+ You can use PaneViews to display various pop-up widgets as well as to
20
+ implement your own behaviors.
21
+
22
+ To use a pane, you typically just create a view and set its paneType
23
+ property to the name of the type of pane view you want it to display in.
24
+ Whenever you set the view's isVisible property to true, it will display
25
+ inside of the pane view automatically.
26
+
27
+ You will rarely use the SC.PaneView directly. Instead, you should use
28
+ one of the subclasses included in SproutCore or create your own.
29
+
30
+ @extends SC.View
31
+ @since SproutCore 1.0
32
+ */
33
+
7
34
  SC.PaneView = SC.View.extend({
8
35
 
9
36
  // panes do not belong to other panes...
@@ -2203,7 +2203,7 @@ SC.CollectionView = SC.View.extend(
2203
2203
  // -- update layout on all item views.
2204
2204
  // -- optional: determine the first item view that does not match.
2205
2205
  //
2206
- _contentPropertyObserver: function(target, key, value, rev) {
2206
+ _contentPropertyObserver: function(target, key, value, rev) {
2207
2207
  if (!this._updatingContent && (!rev || (rev != this._contentPropertyRevision))) {
2208
2208
  this._contentPropertyRevision = rev ;
2209
2209
  this._updatingContent = true ;
@@ -97,21 +97,6 @@ SC.GridView = SC.CollectionView.extend(
97
97
  SC.Benchmark.end('SC.GridView.layoutItemViewsFor') ;
98
98
  },
99
99
 
100
- computeFrame: function() {
101
- var content = this.get('content') ;
102
- var rows = (content) ? content.get('length') : 0 ;
103
- var rowHeight = this.get('rowHeight') || 20 ;
104
-
105
- var parent = this.get('parentNode') ;
106
- var f = (parent) ? parent.get('innerFrame') : { width: 100, height: 100 } ;
107
-
108
- f.x = f.y = 0;
109
- f.height = Math.max(f.height, rows * rowHeight) ;
110
- // console.log('computeFrame(%@)'.fmt($H(f).inspect())) ;
111
- return f ;
112
- },
113
-
114
-
115
100
  /** @private */
116
101
  layoutItemViewsFor: function(parentView, startingView) {
117
102
  SC.Benchmark.start('SC.GridView.layoutItemViewsFor') ;
@@ -165,6 +150,9 @@ SC.GridView = SC.CollectionView.extend(
165
150
 
166
151
  var parent = this.get('parentNode') ;
167
152
  var f = (parent) ? parent.get('innerFrame') : { width: 0, height: 0 };
153
+
154
+ //console.log('computeFrame(%@)'.fmt($I(f))) ;
155
+
168
156
  var itemsPerRow = (columnWidth <= 0) ? 1 : (f.width / columnWidth) ;
169
157
  var rows = Math.ceil(count / itemsPerRow) ;
170
158
 
@@ -264,12 +264,17 @@ SC.SourceListView = SC.CollectionView.extend(
264
264
 
265
265
  var rowHeight = this.get('rowHeight') || 0 ;
266
266
 
267
+
267
268
  // layout relative to top of group. Leave open row for title
268
- var range = this.groupRangeForContentIndex(contentIndex) ;
269
- contentIndex = (contentIndex - range.start) ;
270
-
271
- var groupValue = this.groupValueAtContentIndex(range.start) ;
272
- if (groupValue != null) contentIndex++ ;
269
+ if(this.get("groupBy"))
270
+ {
271
+
272
+ var range = this.groupRangeForContentIndex(contentIndex) ;
273
+ contentIndex = (contentIndex - range.start) ;
274
+
275
+ var groupValue = this.groupValueAtContentIndex(range.start) ;
276
+ if (groupValue != null) contentIndex++ ;
277
+ }
273
278
 
274
279
  var f = {
275
280
  x: 0,
@@ -157,7 +157,10 @@ SC.SelectFieldView = SC.FieldView.extend(
157
157
  var valueKey = this.get('valueKey') ;
158
158
  var objects = this.get('objects') ;
159
159
  var fieldValue = this.get('value') ;
160
-
160
+
161
+ // get the localization flag.
162
+ var shouldLocalize = this.get('localize');
163
+
161
164
  // convert fieldValue to guid, if it is an object.
162
165
  if (!valueKey && fieldValue) fieldValue = fieldValue._guid ;
163
166
  if ((fieldValue == null) || (fieldValue == '')) fieldValue = '***' ;
@@ -169,7 +172,7 @@ SC.SelectFieldView = SC.FieldView.extend(
169
172
 
170
173
  var emptyName = this.get('emptyName') ;
171
174
  if (emptyName) {
172
- if (this.get('localize')) emptyName = emptyName.loc() ;
175
+ if (shouldLocalize) emptyName = emptyName.loc() ;
173
176
  html.push('<option value="***">%@</option>'.fmt(emptyName)) ;
174
177
  html.push('<option disabled="disabled"></option>') ;
175
178
  }
@@ -181,6 +184,12 @@ SC.SelectFieldView = SC.FieldView.extend(
181
184
  // either get the name from the object or convert object to string.
182
185
  var name = (nameKey) ? ((object.get) ? object.get(nameKey) : object[nameKey]) : object.toString() ;
183
186
 
187
+ // localize name if specified.
188
+ if(shouldLocalize)
189
+ {
190
+ name = name.loc();
191
+ }
192
+
184
193
  // get the value using the valueKey or the object if no valueKey.
185
194
  // then convert to a string or use _guid if one of available.
186
195
  var value = (valueKey) ? ((object.get) ? object.get(valueKey) : object[valueKey]) : object ;