sproutcore 1.10.0.rc.2 → 1.10.0.rc.3
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.
- checksums.yaml +8 -8
- data/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +14 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +9 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane_statechart.js +7 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/array/array_case.js +14 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layout.js +103 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutChildViews.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutDidChange.js +4 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/viewDidResize.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +17 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/statechart.js +62 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +14 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +26 -5
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/integration/many_array.js +9 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/data_store.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/split_child.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/render.js +56 -54
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/methods.js +221 -171
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/methods.js +261 -315
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/split_child.js +137 -122
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +10 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +5 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_display.js +14 -14
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +123 -98
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/content_display.js +18 -6
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/api.js +9 -11
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/transition_test.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/views/container.js +15 -16
- data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +11 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +170 -153
- data/lib/frameworks/sproutcore/frameworks/table/views/table.js +105 -101
- data/lib/frameworks/sproutcore/frameworks/table/views/table_head.js +0 -7
- data/lib/frameworks/sproutcore/frameworks/table/views/table_header.js +46 -56
- data/lib/frameworks/sproutcore/frameworks/table/views/table_row.js +0 -6
- data/lib/frameworks/sproutcore/frameworks/template_view/tests/views/template/collection.js +12 -4
- data/lib/frameworks/sproutcore/frameworks/template_view/views/bindable_span.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/template_view/views/template_collection.js +11 -8
- data/lib/frameworks/sproutcore/tests/phantomjs_runner.phantomjs +0 -1
- metadata +3 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +0 -235
@@ -33,21 +33,30 @@ SC.ContentValueSupport = {
|
|
33
33
|
hasContentValueSupport: YES,
|
34
34
|
|
35
35
|
/** @private */
|
36
|
-
initMixin: function() {
|
36
|
+
initMixin: function () {
|
37
37
|
// setup content observing if needed.
|
38
38
|
this._control_contentKeysDidChange();
|
39
39
|
},
|
40
|
-
|
40
|
+
|
41
|
+
/** @private */
|
42
|
+
destroyMixin: function () {
|
43
|
+
// Remove old observers on self.
|
44
|
+
this._cleanup_old_observers();
|
45
|
+
|
46
|
+
// Remove old observers on content.
|
47
|
+
this._cleanup_old_content_observers();
|
48
|
+
},
|
49
|
+
|
41
50
|
/**
|
42
51
|
The value represented by this control.
|
43
|
-
|
52
|
+
|
44
53
|
Most controls represent a value of some type, such as a number, string
|
45
54
|
or image URL. This property should hold that value. It is bindable
|
46
55
|
and observable. Changing this value will immediately change the
|
47
|
-
appearance of the control. Likewise, editing the control
|
56
|
+
appearance of the control. Likewise, editing the control
|
48
57
|
will immediately change this value.
|
49
|
-
|
50
|
-
If instead of setting a single value on a control, you would like to
|
58
|
+
|
59
|
+
If instead of setting a single value on a control, you would like to
|
51
60
|
set a content object and have the control display a single property
|
52
61
|
of that control, then you should use the content property instead.
|
53
62
|
|
@@ -55,23 +64,23 @@ SC.ContentValueSupport = {
|
|
55
64
|
@default null
|
56
65
|
*/
|
57
66
|
value: null,
|
58
|
-
|
67
|
+
|
59
68
|
/**
|
60
69
|
The content object represented by this control.
|
61
|
-
|
62
|
-
Often you need to use a control to display some single aspect of an
|
70
|
+
|
71
|
+
Often you need to use a control to display some single aspect of an
|
63
72
|
object, especially if you are using the control as an item view in a
|
64
73
|
collection view.
|
65
|
-
|
74
|
+
|
66
75
|
In those cases, you can set the content and contentValueKey for the
|
67
76
|
control. This will cause the control to observe the content object for
|
68
|
-
changes to the value property and then set the value of that property
|
77
|
+
changes to the value property and then set the value of that property
|
69
78
|
on the "value" property of this object.
|
70
|
-
|
71
|
-
Note that unless you are using this control as part of a form or
|
79
|
+
|
80
|
+
Note that unless you are using this control as part of a form or
|
72
81
|
collection view, then it would be better to instead bind the value of
|
73
82
|
the control directly to a controller property.
|
74
|
-
|
83
|
+
|
75
84
|
@type SC.Object
|
76
85
|
@default null
|
77
86
|
*/
|
@@ -92,42 +101,42 @@ SC.ContentValueSupport = {
|
|
92
101
|
_default_contentKeys: {
|
93
102
|
contentValueKey: 'value'
|
94
103
|
},
|
95
|
-
|
104
|
+
|
96
105
|
/**
|
97
|
-
The property on the content object that would want to represent the
|
106
|
+
The property on the content object that would want to represent the
|
98
107
|
value of this control. This property should only be set before the
|
99
108
|
content object is first set. If you have a displayDelegate, then
|
100
109
|
you can also use the contentValueKey of the displayDelegate.
|
101
|
-
|
110
|
+
|
102
111
|
@type String
|
103
112
|
@default null
|
104
113
|
*/
|
105
114
|
contentValueKey: null,
|
106
|
-
|
115
|
+
|
107
116
|
/**
|
108
|
-
Invoked whenever any property on the content object changes.
|
109
|
-
|
117
|
+
Invoked whenever any property on the content object changes.
|
118
|
+
|
110
119
|
The default implementation will update the value property of the view
|
111
120
|
if the contentValueKey property has changed. You can override this
|
112
121
|
method to implement whatever additional changes you would like.
|
113
|
-
|
114
|
-
The key will typically contain the name of the property that changed or
|
122
|
+
|
123
|
+
The key will typically contain the name of the property that changed or
|
115
124
|
'*' if the content object itself has changed. You should generally do
|
116
125
|
a total reset if '*' is changed.
|
117
|
-
|
126
|
+
|
118
127
|
@param {Object} target the content object
|
119
128
|
@param {String} key the property that changes
|
120
129
|
@returns {void}
|
121
130
|
@test in content
|
122
131
|
*/
|
123
|
-
contentPropertyDidChange: function(target, key) {
|
132
|
+
contentPropertyDidChange: function (target, key) {
|
124
133
|
var contentKeys = this.get('contentKeys');
|
125
134
|
|
126
|
-
if(contentKeys) {
|
135
|
+
if (contentKeys) {
|
127
136
|
var contentKey;
|
128
137
|
|
129
|
-
for(contentKey in contentKeys) {
|
130
|
-
if(key === '*' || key === this.getDelegateProperty(contentKey, this, this.get('displayDelegate'), contentKeys)) return this.updatePropertyFromContent(contentKeys[contentKey], key, contentKey, target);
|
138
|
+
for (contentKey in contentKeys) {
|
139
|
+
if (key === '*' || key === this.getDelegateProperty(contentKey, this, this.get('displayDelegate'), contentKeys)) return this.updatePropertyFromContent(contentKeys[contentKey], key, contentKey, target);
|
131
140
|
}
|
132
141
|
}
|
133
142
|
|
@@ -137,65 +146,65 @@ SC.ContentValueSupport = {
|
|
137
146
|
},
|
138
147
|
|
139
148
|
/**
|
140
|
-
Helper method you can use from your own implementation of
|
149
|
+
Helper method you can use from your own implementation of
|
141
150
|
contentPropertyDidChange(). This method will look up the content key to
|
142
151
|
extract a property and then update the property if needed. If you do
|
143
|
-
not pass the content key or the content object, they will be computed
|
152
|
+
not pass the content key or the content object, they will be computed
|
144
153
|
for you. It is more efficient, however, for you to compute these values
|
145
154
|
yourself if you expect this method to be called frequently.
|
146
|
-
|
155
|
+
|
147
156
|
@param {String} prop local property to update
|
148
157
|
@param {String} key the contentproperty that changed
|
149
158
|
@param {String} contentKey the local property that contains the key
|
150
159
|
@param {Object} content
|
151
160
|
@returns {SC.Control} receiver
|
152
161
|
*/
|
153
|
-
updatePropertyFromContent: function(prop, key, contentKey, content) {
|
162
|
+
updatePropertyFromContent: function (prop, key, contentKey, content) {
|
154
163
|
var del, v;
|
155
164
|
|
156
|
-
if (contentKey === undefined) contentKey = "content"+prop.capitalize()+"Key";
|
157
|
-
|
165
|
+
if (contentKey === undefined) contentKey = "content" + prop.capitalize() + "Key";
|
166
|
+
|
158
167
|
// prefer our own definition of contentKey
|
159
|
-
if(this[contentKey]) contentKey = this.get(contentKey);
|
168
|
+
if (this[contentKey]) contentKey = this.get(contentKey);
|
160
169
|
// if we don't have one defined check the delegate
|
161
|
-
else if((del = this.get('displayDelegate')) && (v = del[contentKey])) contentKey = del.get ? del.get(contentKey) : v;
|
170
|
+
else if ((del = this.get('displayDelegate')) && (v = del[contentKey])) contentKey = del.get ? del.get(contentKey) : v;
|
162
171
|
// if we have no key we can't do anything so just short circuit out
|
163
172
|
else return this;
|
164
173
|
|
165
174
|
// only bother setting value if the observer triggered for the correct key
|
166
175
|
if (key === '*' || key === contentKey) {
|
167
176
|
if (content === undefined) content = this.get('content');
|
168
|
-
|
169
|
-
if(content) v = content.get ? content.get(contentKey) : content[contentKey];
|
177
|
+
|
178
|
+
if (content) v = content.get ? content.get(contentKey) : content[contentKey];
|
170
179
|
else v = null;
|
171
180
|
|
172
|
-
this.setIfChanged(prop, v)
|
181
|
+
this.setIfChanged(prop, v);
|
173
182
|
}
|
174
|
-
|
175
|
-
return this
|
183
|
+
|
184
|
+
return this;
|
176
185
|
},
|
177
|
-
|
186
|
+
|
178
187
|
/**
|
179
188
|
Relays changes to the value back to the content object if you are using
|
180
189
|
a content object.
|
181
|
-
|
190
|
+
|
182
191
|
This observer is triggered whenever the value changes. It will only do
|
183
192
|
something if it finds you are using the content property and
|
184
193
|
contentValueKey and the new value does not match the old value of the
|
185
|
-
content object.
|
186
|
-
|
194
|
+
content object.
|
195
|
+
|
187
196
|
If you are using contentValueKey in some other way than typically
|
188
197
|
implemented by this mixin, then you may want to override this method as
|
189
198
|
well.
|
190
|
-
|
199
|
+
|
191
200
|
@returns {void}
|
192
201
|
*/
|
193
|
-
updateContentWithValueObserver: function(target, key) {
|
202
|
+
updateContentWithValueObserver: function (target, key) {
|
194
203
|
var reverseContentKeys = this._reverseContentKeys;
|
195
204
|
|
196
205
|
// if everything changed, iterate through and update them all
|
197
|
-
if(!key || key === '*') {
|
198
|
-
for(key in reverseContentKeys) {
|
206
|
+
if (!key || key === '*') {
|
207
|
+
for (key in reverseContentKeys) {
|
199
208
|
this.updateContentWithValueObserver(this, key);
|
200
209
|
}
|
201
210
|
}
|
@@ -217,7 +226,7 @@ SC.ContentValueSupport = {
|
|
217
226
|
|
218
227
|
// avoid re-writing inherited props
|
219
228
|
else if (content[contentKey] !== value) {
|
220
|
-
content[contentKey] = value
|
229
|
+
content[contentKey] = value;
|
221
230
|
}
|
222
231
|
},
|
223
232
|
|
@@ -230,56 +239,34 @@ SC.ContentValueSupport = {
|
|
230
239
|
_old_contentKeys: null,
|
231
240
|
|
232
241
|
/** @private
|
233
|
-
Observes when a content object has changed and handles notifying
|
242
|
+
Observes when a content object has changed and handles notifying
|
234
243
|
changes to the value of the content object.
|
235
244
|
|
236
245
|
Optimized for the default case of only observing contentValueKey. If you use
|
237
246
|
a custom value for contentKeys it will switch to using a CoreSet to track
|
238
247
|
observed keys.
|
239
248
|
*/
|
240
|
-
_control_contentDidChange: function(target, key) {
|
249
|
+
_control_contentDidChange: function (target, key) {
|
241
250
|
var content = this.get('content'),
|
242
251
|
contentKeys = this.get('contentKeys'), contentKey,
|
243
|
-
old = this._control_content,
|
244
252
|
oldKeys = this._old_contentValueKeys,
|
245
|
-
oldType = SC.typeOf(oldKeys),
|
246
253
|
f = this.contentPropertyDidChange;
|
247
254
|
|
248
255
|
// remove an observer from the old content if necessary
|
249
|
-
|
250
|
-
// default case
|
251
|
-
if(oldType === SC.T_STRING) {
|
252
|
-
old.removeObserver(oldKeys, this, f);
|
253
|
-
|
254
|
-
oldKeys = null;
|
255
|
-
}
|
256
|
-
|
257
|
-
// set case
|
258
|
-
else {
|
259
|
-
var i, len = oldKeys.get('length');
|
260
|
-
|
261
|
-
for(i = 0; i < len; i++) {
|
262
|
-
contentKey = oldKeys[i];
|
263
|
-
|
264
|
-
old.removeObserver(contentKey, this, f);
|
265
|
-
}
|
266
|
-
|
267
|
-
oldKeys.clear();
|
268
|
-
}
|
269
|
-
}
|
256
|
+
this._cleanup_old_content_observers();
|
270
257
|
|
271
258
|
// add observer to new content if necessary.
|
272
259
|
if (content && content.addObserver) {
|
273
260
|
// set case
|
274
|
-
if(contentKeys) {
|
261
|
+
if (contentKeys) {
|
275
262
|
// lazily create the key set
|
276
|
-
if(!oldKeys) oldKeys = SC.CoreSet.create();
|
263
|
+
if (!oldKeys) oldKeys = SC.CoreSet.create();
|
277
264
|
|
278
265
|
// add observers to each key
|
279
|
-
for(contentKey in contentKeys) {
|
266
|
+
for (contentKey in contentKeys) {
|
280
267
|
contentKey = this.getDelegateProperty(contentKey, this, this.get('displayDelegate'));
|
281
268
|
|
282
|
-
if(contentKey) {
|
269
|
+
if (contentKey) {
|
283
270
|
content.addObserver(contentKey, this, f);
|
284
271
|
|
285
272
|
oldKeys.add(contentKey);
|
@@ -291,11 +278,11 @@ SC.ContentValueSupport = {
|
|
291
278
|
else {
|
292
279
|
contentKey = this.getDelegateProperty('contentValueKey', this, this.get('displayDelegate'));
|
293
280
|
|
294
|
-
if(contentKey) {
|
281
|
+
if (contentKey) {
|
295
282
|
content.addObserver(contentKey, this, f);
|
296
283
|
|
297
284
|
// if we had a set before, continue using it
|
298
|
-
if(oldKeys) oldKeys.add(contentKey);
|
285
|
+
if (oldKeys) oldKeys.add(contentKey);
|
299
286
|
// otherwise just use a string
|
300
287
|
else oldKeys = contentKey;
|
301
288
|
}
|
@@ -303,40 +290,31 @@ SC.ContentValueSupport = {
|
|
303
290
|
}
|
304
291
|
|
305
292
|
// update previous values
|
306
|
-
this._control_content = content
|
293
|
+
this._control_content = content;
|
307
294
|
this._old_contentValueKeys = oldKeys;
|
308
295
|
|
309
296
|
// notify that value did change.
|
310
297
|
key = (!key || key === 'content') ? '*' : this.get(key);
|
311
|
-
if(key) this.contentPropertyDidChange(content, key)
|
298
|
+
if (key) this.contentPropertyDidChange(content, key);
|
312
299
|
}.observes('content'),
|
313
300
|
|
314
|
-
// holds the previous value of contentKeys
|
315
|
-
_old_contentKeys: null,
|
316
|
-
|
317
301
|
/** @private
|
318
302
|
Observes changes to contentKeys and sets up observers on the local keys to
|
319
303
|
update the observers on the content object.
|
320
304
|
*/
|
321
|
-
_control_contentKeysDidChange: function() {
|
305
|
+
_control_contentKeysDidChange: function () {
|
322
306
|
var key, reverse = {},
|
323
307
|
// if no hash is present, use the default contentValueKey -> value
|
324
|
-
contentKeys = this.get('contentKeys') || this._default_contentKeys,
|
325
|
-
|
308
|
+
contentKeys = this.get('contentKeys') || this._default_contentKeys,
|
309
|
+
contentKey,
|
326
310
|
f = this._control_contentDidChange,
|
327
311
|
reverseF = this.updateContentWithValueObserver;
|
328
312
|
|
329
|
-
//
|
330
|
-
|
331
|
-
contentKey = oldContentKeys[key];
|
332
|
-
|
333
|
-
this.removeObserver(contentKey, this, reverseF);
|
334
|
-
|
335
|
-
this.removeObserver(key, this, f);
|
336
|
-
}
|
313
|
+
// Remove old observers.
|
314
|
+
this._cleanup_old_observers();
|
337
315
|
|
338
316
|
// add new observers
|
339
|
-
for(key in contentKeys) {
|
317
|
+
for (key in contentKeys) {
|
340
318
|
contentKey = contentKeys[key];
|
341
319
|
|
342
320
|
// build reverse mapping to update content with value
|
@@ -356,6 +334,53 @@ SC.ContentValueSupport = {
|
|
356
334
|
|
357
335
|
// call the other observer now to update all the observers
|
358
336
|
this._control_contentDidChange();
|
359
|
-
}.observes('contentKeys')
|
337
|
+
}.observes('contentKeys'),
|
338
|
+
|
339
|
+
/** @private */
|
340
|
+
_cleanup_old_content_observers: function () {
|
341
|
+
var old = this._control_content,
|
342
|
+
oldKeys = this._old_contentValueKeys,
|
343
|
+
oldType = SC.typeOf(oldKeys),
|
344
|
+
f = this.contentPropertyDidChange,
|
345
|
+
contentKey;
|
346
|
+
|
347
|
+
if (old && old.removeObserver && oldKeys) {
|
348
|
+
// default case
|
349
|
+
if (oldType === SC.T_STRING) {
|
350
|
+
old.removeObserver(oldKeys, this, f);
|
351
|
+
|
352
|
+
oldKeys = null;
|
353
|
+
}
|
354
|
+
|
355
|
+
// set case
|
356
|
+
else {
|
357
|
+
var i, len = oldKeys.get('length');
|
358
|
+
|
359
|
+
for (i = 0; i < len; i++) {
|
360
|
+
contentKey = oldKeys[i];
|
361
|
+
|
362
|
+
old.removeObserver(contentKey, this, f);
|
363
|
+
}
|
364
|
+
|
365
|
+
oldKeys.clear();
|
366
|
+
}
|
367
|
+
}
|
368
|
+
},
|
369
|
+
|
370
|
+
/** @private */
|
371
|
+
_cleanup_old_observers: function () {
|
372
|
+
var oldContentKeys = this._old_contentKeys,
|
373
|
+
f = this._control_contentDidChange,
|
374
|
+
reverseF = this.updateContentWithValueObserver,
|
375
|
+
contentKey, key;
|
376
|
+
|
377
|
+
// remove old observers
|
378
|
+
for (key in oldContentKeys) {
|
379
|
+
contentKey = oldContentKeys[key];
|
380
|
+
|
381
|
+
this.removeObserver(contentKey, this, reverseF);
|
382
|
+
this.removeObserver(key, this, f);
|
383
|
+
}
|
384
|
+
}
|
360
385
|
};
|
361
386
|
|
@@ -4,10 +4,10 @@
|
|
4
4
|
// ©2008-2011 Apple Inc. All rights reserved.
|
5
5
|
// License: Licensed under MIT license (see license.js)
|
6
6
|
// ==========================================================================
|
7
|
-
var view, contentA, contentB;
|
7
|
+
var view, pane, contentA, contentB;
|
8
8
|
|
9
9
|
module('ContentDisplay', {
|
10
|
-
setup: function() {
|
10
|
+
setup: function () {
|
11
11
|
contentA = SC.Object.create({
|
12
12
|
foo: 'foo.A',
|
13
13
|
bar: 'bar.A'
|
@@ -18,32 +18,43 @@ module('ContentDisplay', {
|
|
18
18
|
bar: 'bar.B'
|
19
19
|
});
|
20
20
|
|
21
|
+
pane = SC.Pane.create();
|
21
22
|
view = SC.View.create(SC.ContentDisplay, {
|
22
23
|
contentDisplayProperties: ['foo', 'bar'],
|
23
24
|
content: contentA
|
24
25
|
});
|
26
|
+
pane.appendChild(view);
|
27
|
+
pane.append();
|
28
|
+
},
|
25
29
|
|
26
|
-
|
30
|
+
teardown: function () {
|
31
|
+
pane.destroy();
|
32
|
+
contentA.destroy();
|
33
|
+
contentB.destroy();
|
34
|
+
pane = view = contentA = contentB = null;
|
27
35
|
}
|
28
36
|
});
|
29
37
|
|
30
38
|
test('should dirty layer when content changes', function () {
|
31
39
|
SC.run(function () {
|
32
40
|
view.set('content', contentB);
|
41
|
+
|
42
|
+
ok(view.get('layerNeedsUpdate'), "The view's layerNeedsUpdate should be true.");
|
33
43
|
});
|
34
|
-
ok(view.get('layerNeedsUpdate'));
|
35
44
|
});
|
36
45
|
|
37
46
|
test('should dirty layer when any of contentDisplayProperties change', function () {
|
38
47
|
SC.run(function () {
|
39
48
|
contentA.set('foo', 'newFoo');
|
49
|
+
|
50
|
+
ok(view.get('layerNeedsUpdate'), "The view's layerNeedsUpdate should be true.");
|
40
51
|
});
|
41
|
-
ok(view.get('layerNeedsUpdate'));
|
42
52
|
});
|
43
53
|
|
44
54
|
test('should stop observing old content when content changes', function () {
|
45
55
|
ok(contentA.hasObserverFor('*'));
|
46
56
|
view.set('content', contentB);
|
57
|
+
|
47
58
|
ok(!contentA.hasObserverFor('*'));
|
48
59
|
});
|
49
60
|
|
@@ -52,8 +63,9 @@ test('should begin observing new content when content changes', function () {
|
|
52
63
|
view.set('layerNeedsUpdate', NO);
|
53
64
|
SC.run(function () {
|
54
65
|
contentB.set('bar', 'newBar');
|
66
|
+
|
67
|
+
ok(view.get('layerNeedsUpdate'), "The view's layerNeedsUpdate should be true.");
|
55
68
|
});
|
56
|
-
ok(view.get('layerNeedsUpdate'));
|
57
69
|
});
|
58
70
|
|
59
71
|
test('should stop observing content when destroyed', function () {
|
@@ -7,18 +7,19 @@
|
|
7
7
|
|
8
8
|
/*global module test htmlbody ok equals same stop start Q$ */
|
9
9
|
|
10
|
-
var field;
|
10
|
+
var field, view;
|
11
11
|
|
12
12
|
/**
|
13
13
|
Track the public functions and properties of the class. This will serve as an early warning
|
14
14
|
when functions that people may depend on disappear between versions to ensure that we don't
|
15
15
|
break promised support without proper deprecations.
|
16
|
-
|
16
|
+
|
17
17
|
tylerkeating: This is probably redundant since each of these functions and properties should
|
18
18
|
be individually tested elsewhere.
|
19
19
|
*/
|
20
20
|
module("Test the public functions and properties of SC.InlineTextFieldView", {
|
21
21
|
setup: function() {
|
22
|
+
view = SC.View.create(SC.InlineEditable, {});
|
22
23
|
field = SC.InlineTextFieldView.create({});
|
23
24
|
},
|
24
25
|
|
@@ -27,15 +28,6 @@ module("Test the public functions and properties of SC.InlineTextFieldView", {
|
|
27
28
|
}
|
28
29
|
});
|
29
30
|
|
30
|
-
|
31
|
-
test("contains all public class functions",
|
32
|
-
function() {
|
33
|
-
ok(SC.typeOf(SC.InlineTextFieldView['beginEditing']) === SC.T_FUNCTION, "should respond to beginEditing()");
|
34
|
-
ok(SC.typeOf(SC.InlineTextFieldView['commitEditing']) === SC.T_FUNCTION, "should respond to commitEditing()");
|
35
|
-
ok(SC.typeOf(SC.InlineTextFieldView['discardEditing']) === SC.T_FUNCTION, "should respond to discardEditing()");
|
36
|
-
});
|
37
|
-
|
38
|
-
|
39
31
|
test("contains all public functions",
|
40
32
|
function() {
|
41
33
|
ok(field.respondsTo('beginEditing'), "should respond to beginEditing()");
|
@@ -45,6 +37,12 @@ function() {
|
|
45
37
|
ok(field.respondsTo('cancel'), "should respond to cancel()");
|
46
38
|
});
|
47
39
|
|
40
|
+
test("a view with SC.InlineEditable mixin contains all public functions",
|
41
|
+
function() {
|
42
|
+
ok(view.respondsTo('beginEditing'), "should respond to beginEditing()");
|
43
|
+
ok(view.respondsTo('commitEditing'), "should respond to commitEditing()");
|
44
|
+
ok(view.respondsTo('discardEditing'), "should respond to discardEditing()");
|
45
|
+
});
|
48
46
|
|
49
47
|
test("contains all public properties",
|
50
48
|
function() {
|
data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/transition_test.js
CHANGED
@@ -62,7 +62,7 @@ test("Test that the isTransitioning property of container view updates according
|
|
62
62
|
window.stop(2000);
|
63
63
|
|
64
64
|
SC.run(function () {
|
65
|
-
containerView.set('
|
65
|
+
containerView.set('transitionSwap', SC.ContainerView.PUSH);
|
66
66
|
containerView.set('nowShowing', view2);
|
67
67
|
});
|
68
68
|
|
@@ -112,7 +112,7 @@ test("Test that the container view calls the proper transition plugin methods.",
|
|
112
112
|
didBuildOutFromView: function () { didBuildOutFromViewCalled++; }
|
113
113
|
};
|
114
114
|
|
115
|
-
containerView.set('
|
115
|
+
containerView.set('transitionSwap', plugin);
|
116
116
|
containerView.set('nowShowing', view2);
|
117
117
|
equals(willBuildInToViewCalled, 1, "willBuildInToViewCalled() should have been called this many times");
|
118
118
|
equals(willBuildOutFromViewCalled, 1, "willBuildOutFromViewCalled() should have been called this many times");
|
@@ -169,15 +169,25 @@ SC.ContainerView = SC.View.extend(
|
|
169
169
|
// Methods
|
170
170
|
//
|
171
171
|
|
172
|
-
/** @private
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
awake: function () {
|
172
|
+
/** @private */
|
173
|
+
init: function () {
|
174
|
+
var view;
|
175
|
+
|
177
176
|
sc_super();
|
178
177
|
|
179
178
|
if (this.get('nowShowing')) {
|
179
|
+
// If nowShowing is directly set, invoke the instantiation of
|
180
|
+
// it as well.
|
180
181
|
this.nowShowingDidChange();
|
182
|
+
} else {
|
183
|
+
// If contentView is directly set, then swap it into nowShowing so that it
|
184
|
+
// is properly instantiated and ready for swapping.
|
185
|
+
// Fixes: https://github.com/sproutcore/sproutcore/issues/1069
|
186
|
+
view = this.get('contentView');
|
187
|
+
|
188
|
+
if (view) {
|
189
|
+
this.set('nowShowing', view);
|
190
|
+
}
|
181
191
|
}
|
182
192
|
},
|
183
193
|
|
@@ -208,17 +218,6 @@ SC.ContainerView = SC.View.extend(
|
|
208
218
|
return ret;
|
209
219
|
}.property('parentView', 'frame').cacheable(),
|
210
220
|
|
211
|
-
/** @private */
|
212
|
-
createChildViews: function () {
|
213
|
-
// if contentView is defined, then create the content
|
214
|
-
var view = this.get('contentView');
|
215
|
-
|
216
|
-
if (view) {
|
217
|
-
view = this.contentView = this.createChildView(view);
|
218
|
-
this.childViews = [view];
|
219
|
-
}
|
220
|
-
},
|
221
|
-
|
222
221
|
/** @private
|
223
222
|
Invoked whenever the content property changes. This method will simply
|
224
223
|
call replaceContent. Override replaceContent to change how the view is
|
@@ -96,6 +96,17 @@ SC.InlineTextFieldView = SC.TextFieldView.extend(SC.InlineEditor,
|
|
96
96
|
*/
|
97
97
|
_topOffsetForFirefoxCursorFix: 0,
|
98
98
|
|
99
|
+
/**
|
100
|
+
The default size of the inline text field is 0 x 0 so that when it is
|
101
|
+
appended, but before it is positioned it doesn't fill the parent view
|
102
|
+
entirely.
|
103
|
+
|
104
|
+
This is important, because if the parent view layer allows overflow,
|
105
|
+
we could inadvertently alter the scrollTop or scrollLeft properties
|
106
|
+
of the layer.
|
107
|
+
*/
|
108
|
+
layout: { height: 0, width: 0 },
|
109
|
+
|
99
110
|
/*
|
100
111
|
* @private
|
101
112
|
* @method
|
@@ -838,7 +838,7 @@ SC.Reducers = /** @scope SC.Reducers.prototype */ {
|
|
838
838
|
// or lastObject properties changed, thus making them independently observable.
|
839
839
|
if (!SC.none(start)) {
|
840
840
|
if (start === 0) this.notifyPropertyChange('firstObject');
|
841
|
-
if (!SC.none(length) && start + length
|
841
|
+
if (!SC.none(length) && start + length >= this.get('length') - 1) this.notifyPropertyChange('lastObject');
|
842
842
|
}
|
843
843
|
|
844
844
|
this.notifyPropertyChange('[]');
|
@@ -598,7 +598,7 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
598
598
|
while ((queue = this._connectQueue).length > 0) {
|
599
599
|
this._connectQueue = this._alternateConnectQueue;
|
600
600
|
this._alternateConnectQueue = queue;
|
601
|
-
while (binding = queue.pop()) binding._connect();
|
601
|
+
while ((binding = queue.pop())) { binding._connect(); }
|
602
602
|
}
|
603
603
|
|
604
604
|
// loop through the changed queue...
|
@@ -617,7 +617,7 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
617
617
|
// next, apply any bindings in the current queue. This may cause
|
618
618
|
// additional bindings to trigger, which will end up in the new active
|
619
619
|
// queue.
|
620
|
-
while (binding = queue.pop()) binding.applyBindingValue();
|
620
|
+
while ((binding = queue.pop())) { binding.applyBindingValue(); }
|
621
621
|
|
622
622
|
// now loop back and see if there are additional changes pending in the
|
623
623
|
// active queue. Repeat this until all bindings that need to trigger
|
@@ -821,7 +821,7 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
821
821
|
var t = binding._transforms;
|
822
822
|
|
823
823
|
// clone the transform array if this comes from the parent
|
824
|
-
if (t && (t === binding.parentBinding.
|
824
|
+
if (t && (t === binding.parentBinding._transforms)) {
|
825
825
|
t = binding._transforms = t.slice();
|
826
826
|
}
|
827
827
|
|