sproutcore 1.10.0.rc.2 → 1.10.0.rc.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|