sproutcore 1.10.2 → 1.10.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG +11 -0
  3. data/VERSION.yml +1 -1
  4. data/lib/frameworks/sproutcore/CHANGELOG.md +34 -0
  5. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/horizontal_stack_layout.js +3 -1
  6. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/vertical_stack_layout.js +3 -1
  7. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +79 -80
  8. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +115 -22
  9. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +54 -17
  10. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/statechart.js +76 -34
  11. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/methods.js +18 -5
  12. data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +14 -5
  13. data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +42 -18
  14. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +41 -41
  15. data/lib/frameworks/sproutcore/frameworks/foundation/tests/transitions/view_transitions_test.js +235 -0
  16. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/bounce_transition.js +8 -4
  17. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/fade_transition.js +6 -2
  18. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/pop_transition.js +8 -4
  19. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/scale_transition.js +6 -2
  20. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/slide_transition.js +6 -2
  21. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/spring_transition.js +8 -4
  22. data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +5 -4
  23. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +1 -1
  24. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +2 -2
  25. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +124 -80
  26. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +134 -0
  27. data/lib/sproutcore.rb +1 -1
  28. data/lib/sproutcore/models/manifest.rb +12 -6
  29. data/lib/sproutcore/rack/builder.rb +20 -12
  30. data/lib/sproutcore/tools.rb +3 -3
  31. data/lib/sproutcore/tools/build.rb +22 -22
  32. data/sproutcore.gemspec +2 -5
  33. data/vendor/sproutcore/lib/yuicompressor-2.4.8.jar +0 -0
  34. metadata +10 -23
  35. data/vendor/sproutcore/lib/yuicompressor-2.4.6.jar +0 -0
@@ -392,8 +392,8 @@ SC.SelectView = SC.ButtonView.extend(
392
392
  */
393
393
  itemsDidChange: function() {
394
394
  var escapeHTML, items, len, nameKey, iconKey, valueKey, separatorKey, showCheckbox,
395
- currentSelectedVal, shouldLocalize, isSeparator, itemList, isChecked,
396
- idx, name, icon, value, item, itemEnabled, isEnabledKey, emptyName, isSameRecord;
395
+ currentSelectedVal, shouldLocalize, isSeparator, itemList, isChecked,
396
+ idx, name, icon, value, item, itemEnabled, isEnabledKey, emptyName, isSameRecord;
397
397
 
398
398
  items = this.get('items') || [];
399
399
  items = this.sortObjects(items);
@@ -468,7 +468,12 @@ SC.SelectView = SC.ButtonView.extend(
468
468
  // get the separator
469
469
  isSeparator = separatorKey ? (object.get ? object.get(separatorKey) : object[separatorKey]) : NO;
470
470
 
471
- if (!isSeparator) {
471
+ if (isSeparator) {
472
+ item = SC.Object.create({
473
+ isSeparator: true,
474
+ value: '_sc_separator_item'
475
+ });
476
+ } else {
472
477
  //Get the name value. If value key is not specified convert obj
473
478
  //to string
474
479
  name = nameKey ? (object.get ?
@@ -514,8 +519,7 @@ SC.SelectView = SC.ButtonView.extend(
514
519
  //set the _itemIdx - To change the prefMatrix accordingly.
515
520
  this.set('_itemIdx', idx);
516
521
  isChecked = !showCheckbox ? NO : YES;
517
- }
518
- else {
522
+ } else {
519
523
  isChecked = NO;
520
524
  }
521
525
 
@@ -530,18 +534,17 @@ SC.SelectView = SC.ButtonView.extend(
530
534
  this._defaultTitle = name;
531
535
  this._defaultIcon = icon;
532
536
  }
533
- }
534
537
 
535
- item = SC.Object.create({
536
- isSeparator: isSeparator,
537
- title: name,
538
- icon: icon,
539
- value: value,
540
- isEnabled: itemEnabled,
541
- checkbox: isChecked,
542
- target: this,
543
- action: 'displaySelectedItem'
544
- });
538
+ item = SC.Object.create({
539
+ action: 'displaySelectedItem',
540
+ title: name,
541
+ icon: icon,
542
+ value: value,
543
+ isEnabled: itemEnabled,
544
+ checkbox: isChecked,
545
+ target: this
546
+ });
547
+ }
545
548
 
546
549
  //Set the items in the itemList array
547
550
  itemList.push(item);
@@ -718,10 +721,31 @@ SC.SelectView = SC.ButtonView.extend(
718
721
  var currentItem = menuView.get("selectedItem");
719
722
 
720
723
  this.set("value", currentItem.get("value"));
721
- this.set("title", currentItem.get("title"));
722
- this.set("_itemIdx", currentItem.get("contentIndex"));
723
724
  },
724
725
 
726
+ /** @private Each time the value changes, update each item's checkbox property and update our display properties. */
727
+ valueDidChange: function () {
728
+ var itemList = this._itemList,
729
+ showCheckbox = this.get('showCheckbox'),
730
+ value = this.get('value');
731
+
732
+ // Find the newly selected item (if any).
733
+ for (var i = 0, len = itemList.length; i < len; i++) {
734
+ var item = itemList[i],
735
+ isChecked = false;
736
+
737
+ if (value === item.get('value')) {
738
+ isChecked = showCheckbox;
739
+ this.set("title", item.get("title"));
740
+ this.set("icon", item.get("icon"));
741
+ this.set("_itemIdx", item.get("contentIndex"));
742
+ }
743
+
744
+ item.set('checkbox', isChecked);
745
+ }
746
+
747
+ }.observes('value'),
748
+
725
749
  /** @private
726
750
  Set the "top" attribute in the prefer matrix property which will
727
751
  position menu such that the selected item in the menu will be
@@ -8,145 +8,145 @@
8
8
  /**
9
9
  @namespace
10
10
 
11
- The Editable mixin is a standard protocol used to activate keyboard editing
11
+ The Editable mixin is a standard protocol used to activate keyboard editing
12
12
  on views that are editable such as text fields, label views and item views.
13
-
13
+
14
14
  You should apply this mixin, or implement the methods, if you are
15
15
  designing an item view for a collection and you want to automatically
16
16
  trigger editing.
17
-
17
+
18
18
  ## Using Editable Views
19
-
19
+
20
20
  To use a view that includes the Editable mixin, you simply call three
21
21
  methods on the view:
22
-
22
+
23
23
  - To begin editing, call beginEditing(). This will make the view first responder and allow the user to make changes to it. If the view cannot begin editing for some reason, it will return NO.
24
24
  - If you want to cancel editing, you should try calling discardEditing(). This will cause the editor to discard its changed value and resign first responder. Some editors do not support cancelling editing and will return NO. If this is the case, you may optionally try calling commitEditing() instead to force the view to resign first responder, even though this will commit the changes.
25
25
  - If you want to end editing, while saving any changes that were made, try calling commitEditing(). This will cause the editor to validate and apply its changed value and resign first responder. If the editor cannot validate its contents for some reason, it will return NO. In this case you may optionally try calling discardEditing() instead to force the view to resign first responder, even though this will discard the changes.
26
-
26
+
27
27
  ## Implementing an Editable View
28
-
28
+
29
29
  To implement a new view that is editable, you should implement the three
30
30
  methods defined below: beginEditing(), discardEditing(), and
31
31
  commitEditing(). If you already allow editing when your view becomes first
32
32
  responder and commit your changes when the view loses first responder status
33
33
  then you can simply apply this mixin and not override any methods.
34
-
35
-
34
+
35
+
36
36
  @since SproutCore 1.0
37
37
  */
38
38
  SC.Editable = {
39
39
 
40
40
  /**
41
- Indicates whether a view is editable or not. You can optionally
41
+ Indicates whether a view is editable or not. You can optionally
42
42
  implement the methods in this mixin to disallow editing is isEditable is
43
43
  NO.
44
-
44
+
45
45
  @type Boolean
46
46
  @default NO
47
47
  */
48
48
  isEditable: NO,
49
-
49
+
50
50
  /**
51
51
  Indicates whether editing is currently in progress. The methods you
52
- implement should generally up this property as appropriate when you
52
+ implement should generally up this property as appropriate when you
53
53
  begin and end editing.
54
-
54
+
55
55
  @type Boolean
56
56
  @default NO
57
57
  */
58
58
  isEditing: NO,
59
-
59
+
60
60
  /**
61
61
  Begins editing on the view.
62
-
62
+
63
63
  This method is called by other views when they want you to begin editing.
64
- You should write this method to become first responder, perform any
64
+ You should write this method to become first responder, perform any
65
65
  additional setup needed to begin editing and then return YES.
66
-
66
+
67
67
  If for some reason you do not want to allow editing right now, you can
68
68
  also return NO. If your view is already editing, then you should not
69
69
  restart editing again but just return YES.
70
70
 
71
71
  The default implementation checks to see if editing is allowed, then
72
72
  becomes first responder and updates the isEditing property if appropriate.
73
- Generally you will want to replace this method with your own
73
+ Generally you will want to replace this method with your own
74
74
  implementation and not call the default.
75
-
75
+
76
76
  @returns {Boolean} YES if editing began or is in progress, NO otherwise
77
77
  */
78
78
  beginEditing: function() {
79
79
  if (!this.get('isEditable')) return NO ;
80
80
  if (this.get('isEditing')) return YES ;
81
-
81
+
82
82
  // begin editing
83
83
  this.beginPropertyChanges();
84
84
  this.set('isEditing', YES) ;
85
85
  this.becomeFirstResponder();
86
86
  this.endPropertyChanges();
87
-
87
+
88
88
  return YES ;
89
89
  },
90
-
90
+
91
91
  /**
92
92
  Ends editing on the view, discarding any changes that were made to the
93
93
  view value in the meantime.
94
-
94
+
95
95
  This method is called by other views when they want to cancel editing
96
96
  that began earlier. When this method is called you should resign first
97
97
  responder, restore the original value of the view and return YES.
98
-
98
+
99
99
  If your view cannot revert back to its original state before editing began
100
100
  then you can implement this method to simply return NO. A properly
101
101
  implemented client may try to call commitEditing() instead to force your
102
102
  view to end editing anyway.
103
-
103
+
104
104
  If this method is called on a view that is not currently editing, you
105
105
  should always just return YES.
106
-
106
+
107
107
  The default implementation does not support discarding changes and always
108
108
  returns NO.
109
-
109
+
110
110
  @returns {Boolean} YES if changes were discarded and editing ended.
111
111
  */
112
112
  discardEditing: function() {
113
113
  // if we are not editing, return YES, otherwise NO.
114
-
114
+
115
115
  return !this.get('isEditing') ;
116
116
  },
117
-
117
+
118
118
  /**
119
- Ends editing on the view, committing any changes that were made to the
119
+ Ends editing on the view, committing any changes that were made to the
120
120
  view value in the meantime.
121
-
122
- This method is called by other views when they want to end editing,
121
+
122
+ This method is called by other views when they want to end editing,
123
123
  saving any changes that were made to the view in the meantime. When this
124
124
  method is called you should resign first responder, save the latest
125
125
  value of the view and return YES.
126
-
127
- If your view cannot save the current state of the view for some reason
126
+
127
+ If your view cannot save the current state of the view for some reason
128
128
  (for example if validation fails), then you should return NO. Properly
129
129
  implemented clients may then try to call discardEditing() to force your
130
130
  view to resign first responder anyway.
131
-
131
+
132
132
  Some views apply changes to their value immediately during an edit instead
133
133
  of waiting for the view to end editing. If this is the case, you should
134
- still implement commitEditing but you simply may not save any value
134
+ still implement commitEditing but you simply may not save any value
135
135
  changes.
136
-
136
+
137
137
  If this method is called on a view that is not currently editing, you
138
138
  should always just return YES.
139
-
139
+
140
140
  The default implementation sets isEditing to NO, resigns first responder
141
141
  and returns YES.
142
-
142
+
143
143
  @returns {Boolean} YES if changes were discarded and editing ended.
144
144
  */
145
145
  commitEditing: function() {
146
146
  if (!this.get('isEditing')) return YES;
147
147
  this.set('isEditing', NO) ;
148
148
  this.resignFirstResponder();
149
-
149
+
150
150
  return YES ;
151
151
  }
152
152
 
@@ -0,0 +1,235 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2013 7x7 Software, Inc.
4
+ // License: Licensed under MIT license (see license.js)
5
+ // ==========================================================================
6
+
7
+ /*global module, test, equals, ok, start, stop */
8
+
9
+ var view,
10
+ pane;
11
+
12
+ /** Test the SC.View states. */
13
+ module("SC.View Transition States", {
14
+
15
+ setup: function () {
16
+ view = SC.View.create();
17
+ pane = SC.Pane.create({
18
+ layout: { width: 400, height: 400 }
19
+ });
20
+ },
21
+
22
+ teardown: function () {
23
+ view.destroy();
24
+ pane.destroy();
25
+ view = pane = null;
26
+ }
27
+
28
+ });
29
+
30
+ /** */
31
+ // test("Reversing SHOWING to HIDDEN: FADE_IN", function () {
32
+ // stop(2000);
33
+
34
+ // view.set('isVisible', false);
35
+ // SC.run(function () {
36
+ // pane.appendChild(view);
37
+ // pane.append();
38
+ // });
39
+
40
+ // // Test assumption.
41
+ // equals(view.get('isVisible'), false, "The isVisible property of the view is");
42
+ // ok(view.$().hasClass('sc-hidden'), "The view has sc-hidden class name.");
43
+ // equals(view.$().css('opacity'), '1', "The view's opacity is");
44
+
45
+ // view.set('transitionShow', SC.View.FADE_IN);
46
+ // SC.run(function () {
47
+ // view.set('isVisible', true);
48
+ // });
49
+ // equals(view.$().css('opacity'), '0', "The view's opacity is");
50
+
51
+ // setTimeout(function () {
52
+ // var jqEl = view.$();
53
+
54
+ // // Test assumption.
55
+ // equals(view.get('isVisible'), true, "The isVisible property of the view is");
56
+ // ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
57
+ // ok(jqEl.css('opacity') > 0, "The view's opacity is not 0.");
58
+ // ok(jqEl.css('opacity') < 1, "The view's opacity is not 1.");
59
+
60
+ // SC.run(function () {
61
+ // view.set('isVisible', false);
62
+ // });
63
+
64
+ // jqEl = view.$();
65
+ // equals(view.get('isVisible'), false, "The isVisible property of the view is");
66
+ // ok(jqEl.hasClass('sc-hidden'), "The view has sc-hidden class name.");
67
+ // equals(jqEl.css('opacity'), '1', "The view's opacity is");
68
+
69
+ // start();
70
+ // }, 200);
71
+ // });
72
+
73
+ /** */
74
+ test("Reversing SHOWING to HIDING: FADE_IN & FADE_OUT", function () {
75
+ stop(2000);
76
+
77
+ view.set('isVisible', false);
78
+ SC.run(function () {
79
+ pane.appendChild(view);
80
+ pane.append();
81
+ });
82
+
83
+ // Test assumption.
84
+ equals(view.get('isVisible'), false, "The isVisible property of the view is");
85
+ ok(view.$().hasClass('sc-hidden'), "The view has sc-hidden class name.");
86
+ equals(view.$().css('opacity'), '1', "The view's opacity is");
87
+
88
+ view.set('transitionShow', SC.View.FADE_IN);
89
+ view.set('transitionHide', SC.View.FADE_OUT);
90
+ SC.run(function () {
91
+ view.set('isVisible', true);
92
+ });
93
+ equals(view.$().css('opacity'), '0', "The view's opacity is");
94
+
95
+ setTimeout(function () {
96
+ var jqEl = view.$();
97
+
98
+ // Test assumption.
99
+ equals(view.get('isVisible'), true, "The isVisible property of the view is");
100
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
101
+ ok(jqEl.css('opacity') > 0, "The view's opacity is not 0.");
102
+ ok(jqEl.css('opacity') < 1, "The view's opacity is not 1.");
103
+
104
+ SC.run(function () {
105
+ view.set('isVisible', false);
106
+ });
107
+
108
+ jqEl = view.$();
109
+ equals(view.get('isVisible'), false, "The isVisible property of the view is");
110
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
111
+ ok(jqEl.css('opacity') > 0, "The view's opacity is not 0 still.");
112
+ equals(view.$().css('opacity'), '1', "The view's opacity is");
113
+ }, 200);
114
+
115
+ setTimeout(function () {
116
+ var jqEl = view.$();
117
+
118
+ // Test assumption.
119
+ equals(view.get('isVisible'), false, "The isVisible property of the view is");
120
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
121
+ ok(jqEl.css('opacity') > 0, "The view's opacity is not 0.");
122
+ ok(jqEl.css('opacity') < 1, "The view's opacity is not 1.");
123
+ }, 400);
124
+
125
+ setTimeout(function () {
126
+ var jqEl = view.$();
127
+
128
+ SC.RunLoop.begin().end();
129
+ // Test assumption.
130
+ equals(view.get('isVisible'), false, "The isVisible property of the view is");
131
+ ok(jqEl.hasClass('sc-hidden'), "The view has sc-hidden class name.");
132
+ ok(view._layoutStyleNeedsUpdate, "The view's layout needs update");
133
+
134
+ start();
135
+ }, 1500);
136
+ });
137
+
138
+
139
+ /** */
140
+ test("Reversing HIDING to SHOWN: FADE_OUT", function () {
141
+ stop(2000);
142
+
143
+ SC.run(function () {
144
+ pane.appendChild(view);
145
+ pane.append();
146
+ });
147
+
148
+ // Test assumption.
149
+ equals(view.get('isVisible'), true, "The isVisible property of the view is");
150
+ ok(!view.$().hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
151
+ equals(view.$().css('opacity'), '1', "The view's opacity is");
152
+
153
+ view.set('transitionHide', SC.View.FADE_OUT);
154
+ SC.run(function () {
155
+ view.set('isVisible', false);
156
+ });
157
+ equals(view.$().css('opacity'), '1', "The view's opacity is");
158
+
159
+ // Fading out.
160
+ setTimeout(function () {
161
+ var jqEl = view.$();
162
+
163
+ // Test assumption.
164
+ equals(view.get('isVisible'), false, "The isVisible property of the view is");
165
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
166
+ ok(jqEl.css('opacity') > 0, "The view's opacity is not 0.");
167
+ ok(jqEl.css('opacity') < 1, "The view's opacity is not 1.");
168
+
169
+ // Cancel fading out.
170
+ SC.run(function () {
171
+ view.set('isVisible', true);
172
+ });
173
+
174
+ jqEl = view.$();
175
+ equals(view.get('isVisible'), true, "The isVisible property of the view is");
176
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
177
+ equals(jqEl.css('opacity'), '1', "The view's opacity is now");
178
+
179
+ start();
180
+ }, 200);
181
+ });
182
+
183
+
184
+ /** */
185
+ test("Reversing HIDING to SHOWING: FADE_IN & FADE_OUT", function () {
186
+ stop(2000);
187
+
188
+ SC.run(function () {
189
+ pane.appendChild(view);
190
+ pane.append();
191
+ });
192
+
193
+ // Test assumption.
194
+ equals(view.get('isVisible'), true, "The isVisible property of the view is");
195
+ ok(!view.$().hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
196
+ equals(view.$().css('opacity'), '1', "The view's opacity is");
197
+
198
+ view.set('transitionShow', SC.View.FADE_IN);
199
+ view.set('transitionHide', SC.View.FADE_OUT);
200
+ SC.run(function () {
201
+ view.set('isVisible', false);
202
+ });
203
+ equals(view.$().css('opacity'), '1', "The view's opacity is");
204
+
205
+ setTimeout(function () {
206
+ var jqEl = view.$();
207
+
208
+ // Test assumption.
209
+ equals(view.get('isVisible'), false, "The isVisible property of the view is");
210
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
211
+ ok(jqEl.css('opacity') > 0, "The view's opacity is not 0.");
212
+ ok(jqEl.css('opacity') < 1, "The view's opacity is not 1.");
213
+
214
+ // Cancel fading out.
215
+ SC.run(function () {
216
+ view.set('isVisible', true);
217
+ });
218
+
219
+ jqEl = view.$();
220
+ equals(view.get('isVisible'), true, "The isVisible property of the view is");
221
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
222
+ equals(view.$().css('opacity'), '0', "The view's opacity is");
223
+ }, 200);
224
+
225
+ setTimeout(function () {
226
+ var jqEl = view.$();
227
+
228
+ // Test assumption.
229
+ equals(view.get('isVisible'), true, "The isVisible property of the view is");
230
+ ok(!jqEl.hasClass('sc-hidden'), "The view doesn't have sc-hidden class name.");
231
+ equals(jqEl.css('opacity'), '1', "The view's opacity is now");
232
+
233
+ start();
234
+ }, 1000);
235
+ });