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
@@ -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 ;