sproutcore 1.9.0 → 1.9.1
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.
- data/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +123 -1
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +13 -9
- data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/request.js +68 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +59 -60
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/selection_set.js +6 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/locale.js +48 -29
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/selection_set/remove.js +53 -17
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/destroy.js +34 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/destroyLayer.js +47 -11
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/viewDidResize.js +31 -36
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +10 -10
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +55 -23
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +5 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +105 -105
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +131 -30
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/string.js +9 -5
- data/lib/sproutcore/helpers/minifier.rb +0 -2
- data/lib/sproutcore/rack/filesystem.rb +5 -5
- metadata +3 -2
@@ -457,7 +457,7 @@ SC.SelectionSet = SC.Object.extend(SC.Enumerable, SC.Freezable, SC.Copyable,
|
|
457
457
|
@param {Object} source the source to limit
|
458
458
|
@returns {SC.SelectionSet} receiver
|
459
459
|
*/
|
460
|
-
constrain: function(source) {
|
460
|
+
constrain: function (source) {
|
461
461
|
var set, len, max, objects;
|
462
462
|
|
463
463
|
this.beginPropertyChanges();
|
@@ -477,9 +477,11 @@ SC.SelectionSet = SC.Object.extend(SC.Enumerable, SC.Freezable, SC.Copyable,
|
|
477
477
|
|
478
478
|
// remove objects not in source
|
479
479
|
if (objects = this._objects) {
|
480
|
-
|
481
|
-
|
482
|
-
|
480
|
+
var i, cur;
|
481
|
+
for (i = objects.length - 1; i >= 0; i--) {
|
482
|
+
cur = objects[i];
|
483
|
+
if (source.indexOf(cur) < 0) this.removeObject(cur);
|
484
|
+
}
|
483
485
|
}
|
484
486
|
|
485
487
|
this.endPropertyChanges();
|
@@ -6,15 +6,15 @@
|
|
6
6
|
// ==========================================================================
|
7
7
|
|
8
8
|
var LocaleObject;
|
9
|
-
module("object.SC.Locale()", {
|
9
|
+
module("object.SC.Locale()", {
|
10
10
|
setup: function() {
|
11
|
-
|
11
|
+
|
12
12
|
LocaleObject = SC.Locale.create({
|
13
13
|
init: function(){
|
14
14
|
sc_super();
|
15
15
|
//hash of new languages
|
16
16
|
var newLocales = { deflang: 'dl', empty: '' };
|
17
|
-
|
17
|
+
|
18
18
|
//Added the new languages to the existing list of locales
|
19
19
|
SC.Locale.addStrings(newLocales);
|
20
20
|
}
|
@@ -22,12 +22,12 @@ module("object.SC.Locale()", {
|
|
22
22
|
|
23
23
|
}
|
24
24
|
});
|
25
|
-
|
25
|
+
|
26
26
|
test("Locale.init() : Should return a flag if the language has been set during the locale initialization", function() {
|
27
27
|
// As the locale is added during initialization the value of hasString is true
|
28
28
|
equals(LocaleObject.hasStrings, true) ;
|
29
|
-
|
30
|
-
//check the string values.
|
29
|
+
|
30
|
+
//check the string values.
|
31
31
|
equals(LocaleObject.strings.deflang, 'dl') ;
|
32
32
|
});
|
33
33
|
|
@@ -44,51 +44,70 @@ test("Locale.locWithDefault() : localized version of the string even if localize
|
|
44
44
|
equals(LocaleObject.locWithDefault("empty", "Empty"), "");
|
45
45
|
});
|
46
46
|
|
47
|
-
test("Locale.addStrings() : Should be able to add the passed hash of strings to the locale's strings table", function() {
|
48
|
-
|
47
|
+
test("Locale.addStrings() : Should be able to add the passed hash of strings to the locale's strings table", function() {
|
48
|
+
|
49
49
|
//Check for the new languages. This should be false as these are not added to the list of locales
|
50
50
|
equals(false, SC.Locale.options().strings.chinese === 'zh' && SC.Locale.options().strings.dutch === 'nl') ;
|
51
|
-
|
51
|
+
|
52
52
|
//hash of new languages
|
53
53
|
var newLocales = { chinese: 'zh', czech: 'cs', dutch: 'nl'};
|
54
|
-
|
54
|
+
|
55
55
|
//Added the new languages to the existing list of locales
|
56
56
|
SC.Locale.addStrings(newLocales);
|
57
|
-
|
57
|
+
|
58
58
|
//Result should be true as the new locales added to the list of default locales
|
59
59
|
equals(true, SC.Locale.options().strings.chinese === 'zh' && SC.Locale.options().strings.dutch === 'nl') ;
|
60
60
|
});
|
61
61
|
|
62
|
+
/**
|
63
|
+
There was a bug in SC.Locale where the `strings` object was cloned for each
|
64
|
+
subclass but then the original `strings` object was used to mix in new strings
|
65
|
+
and applied back. This meant that each subclass ended up sharing the
|
66
|
+
`strings` object and only one set of localizations (the last one) would exist.
|
67
|
+
*/
|
68
|
+
test("Locale.extend.addStrings() : Subclasses should not share the strings object.", function() {
|
69
|
+
var strings;
|
70
|
+
|
71
|
+
strings = { 'hello': 'Hello' };
|
72
|
+
SC.Locale.locales.en.addStrings(strings);
|
73
|
+
|
74
|
+
strings = { 'hello': 'Bonjour' };
|
75
|
+
SC.Locale.locales.fr.addStrings(strings);
|
76
|
+
|
77
|
+
//Result should be true as the new locales added to the list of default locales
|
78
|
+
ok(SC.Locale.locales.en.prototype.strings !== SC.Locale.locales.fr.prototype.strings, "The strings object should not be shared between subclasses.");
|
79
|
+
});
|
80
|
+
|
62
81
|
test("Locale.options() : Should provide the registered locales that have not been instantiated", function() {
|
63
|
-
|
82
|
+
|
64
83
|
//hash of new languages
|
65
84
|
var newLocales = { jamaican: 'ji', korean: 'ko'};
|
66
85
|
|
67
86
|
//Added the new languages to the existing list of locales
|
68
87
|
SC.Locale.addStrings(newLocales);
|
69
|
-
|
88
|
+
|
70
89
|
//Options should return the list of registered locales, so checking if the returned object has strings.
|
71
90
|
equals(SC.Locale.options().hasStrings, true) ;
|
72
|
-
|
91
|
+
|
73
92
|
//Checking the strings with default locales.
|
74
93
|
equals(true, SC.Locale.options().strings.jamaican === 'ji' && SC.Locale.options().strings.korean === 'ko') ;
|
75
94
|
});
|
76
|
-
|
95
|
+
|
77
96
|
test("Locale.normalizeLanguage() : Should provide the two character language code for the passed locale", function() {
|
78
97
|
//If nothing is passed this will return the default code as 'en'
|
79
98
|
equals(SC.Locale.normalizeLanguage(), 'en') ;
|
80
|
-
|
99
|
+
|
81
100
|
//If the language is passed as 'English' this will return the code as 'en'
|
82
101
|
equals(SC.Locale.normalizeLanguage('English'), 'en') ;
|
83
|
-
|
102
|
+
|
84
103
|
//For any other code passed which is not in the default code it should return as it was passed
|
85
|
-
equals(SC.Locale.normalizeLanguage('ab'), 'ab') ;
|
104
|
+
equals(SC.Locale.normalizeLanguage('ab'), 'ab') ;
|
86
105
|
});
|
87
106
|
|
88
107
|
test("Locale.toString() : Should return the current language set with the guid value", function() {
|
89
108
|
// Creating the new locale by extending an existing Locale object
|
90
109
|
SC.Locale.locales['mx'] = SC.Locale.extend({ _deprecatedLanguageCodes: ['mexican'] }) ;
|
91
|
-
|
110
|
+
|
92
111
|
//Result should return the chinese object
|
93
112
|
equals(SC.Locale.locales.mx.currentLocale.isObject, true) ;
|
94
113
|
|
@@ -96,23 +115,23 @@ test("Locale.toString() : Should return the current language set with the guid v
|
|
96
115
|
|
97
116
|
test("Locale.createCurrentLocale() : Should create the Locale Object for the language selected", function() {
|
98
117
|
//This will match the browser language with the SC language and create the object accordingly
|
99
|
-
// This test will pass only for the default languages i.e en, fr, de, ja, es, it.
|
118
|
+
// This test will pass only for the default languages i.e en, fr, de, ja, es, it.
|
100
119
|
equals(true, SC.Locale.createCurrentLocale().language === SC.browser.language) ;
|
101
|
-
|
120
|
+
|
102
121
|
//Resetting the default browser language
|
103
122
|
SC.browser.language='kn';
|
104
|
-
|
123
|
+
|
105
124
|
//This is false as currentLocale will be created as 'en'
|
106
125
|
equals(false, SC.Locale.createCurrentLocale().language===SC.browser.language) ;
|
107
|
-
});
|
126
|
+
});
|
108
127
|
|
109
128
|
test("Locale.localeClassFor() : Should find the locale class for the names language code or creates on based on its most likely parent", function() {
|
110
129
|
// Local Class for any language other than default languages will be 'en'. Therefore this condition is false
|
111
130
|
equals(false, SC.Locale.localeClassFor('nl').create().language === "nl") ;
|
112
|
-
|
131
|
+
|
113
132
|
// This adds the new language with the parent language to the default list
|
114
133
|
SC.Locale.locales['nl'] = SC.Locale.extend({ _deprecatedLanguageCodes: ['Dutch'] }) ;
|
115
|
-
|
134
|
+
|
116
135
|
//This condition is true as the local class now exists for 'nl'
|
117
136
|
equals(true, SC.Locale.localeClassFor('nl').create().language==="nl") ;
|
118
137
|
});
|
@@ -122,19 +141,19 @@ test("Locale.define() : Should be able to define a particular type of locale", f
|
|
122
141
|
longNames: 'Charles John Romonoski Gregory William'.split(' '),
|
123
142
|
shortNames: ['C','A','Y','N']
|
124
143
|
});
|
125
|
-
|
144
|
+
|
126
145
|
//Result should return the new locale object
|
127
146
|
equals(SC.Locale.locales.xy.isClass, true) ;
|
128
147
|
});
|
129
148
|
|
130
149
|
test("Locale.extend() : Should make sure important properties of Locale object are copied to a new class", function() {
|
131
150
|
SC.Locale.locales['mn'] = SC.Locale.extend({ _deprecatedLanguageCodes: ['newlang'] }) ;
|
132
|
-
|
151
|
+
|
133
152
|
//hash of new languages
|
134
153
|
var testLocales = { test: 'te', newtest: 'nt'};
|
135
154
|
//Added the new languages to the existing list of locales through the new locale object
|
136
155
|
SC.Locale.locales.mn.addStrings(testLocales);
|
137
|
-
|
156
|
+
|
138
157
|
//Result should be true as the new locales added to the list of default locales
|
139
158
|
equals(SC.Locale.locales.mn.options().strings.test,'te') ;
|
140
|
-
});
|
159
|
+
});
|
data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/selection_set/remove.js
CHANGED
@@ -10,7 +10,7 @@ module("SC.SelectionSet#remove", {
|
|
10
10
|
set = SC.SelectionSet.create();
|
11
11
|
array = '0 1 2 3 4 5 6 7 8 9'.w();
|
12
12
|
array2 = 'a b c d e f g h i k l m'.w();
|
13
|
-
|
13
|
+
|
14
14
|
expected = SC.IndexSet.create(4,3);
|
15
15
|
expected2 = SC.IndexSet.create(1);
|
16
16
|
expected.source = array;
|
@@ -18,7 +18,7 @@ module("SC.SelectionSet#remove", {
|
|
18
18
|
}
|
19
19
|
});
|
20
20
|
|
21
|
-
/*
|
21
|
+
/*
|
22
22
|
validates that the selection set has the expected content. pass index sets
|
23
23
|
with sources set appropriately. The order of the array is not important.
|
24
24
|
*/
|
@@ -26,12 +26,12 @@ function validate(set, expected, defaultSource) {
|
|
26
26
|
var sources = set.get('sources'),
|
27
27
|
len = expected.length,
|
28
28
|
idx, cur, actual ;
|
29
|
-
|
30
|
-
equals(sources.length, expected.length, 'should have same number of sources (actual sources: %@)'.fmt(sources));
|
31
|
-
|
29
|
+
|
30
|
+
equals(sources.length, expected.length, 'should have same number of sources (actual sources: %@)'.fmt(sources));
|
31
|
+
|
32
32
|
for(idx=0;idx<len;idx++) {
|
33
33
|
cur = expected[idx];
|
34
|
-
if (!cur.source) cur.source =defaultSource;
|
34
|
+
if (!cur.source) cur.source =defaultSource;
|
35
35
|
actual = set.indexSetForSource(cur.source, NO);
|
36
36
|
ok(actual, 'should have indexSet for source: %@'.fmt(cur.source));
|
37
37
|
equals(actual.source, cur.source, 'indexSet.source should match source');
|
@@ -40,7 +40,7 @@ function validate(set, expected, defaultSource) {
|
|
40
40
|
}
|
41
41
|
// ..........................................................
|
42
42
|
// BASIC REMOVES
|
43
|
-
//
|
43
|
+
//
|
44
44
|
|
45
45
|
test("Removed indexes for single source", function() {
|
46
46
|
set.add(array, 4, 3);
|
@@ -51,7 +51,7 @@ test("Removed indexes for single source", function() {
|
|
51
51
|
});
|
52
52
|
|
53
53
|
test("Removed multiple sources", function() {
|
54
|
-
|
54
|
+
|
55
55
|
set.add(array, 4, 3).add(array2, 1);
|
56
56
|
validate(set, [expected, expected2]); // precondition
|
57
57
|
|
@@ -71,13 +71,13 @@ test("Remove IndexSet with source", function() {
|
|
71
71
|
});
|
72
72
|
|
73
73
|
test("Adding another SelectionSet", function() {
|
74
|
-
|
74
|
+
|
75
75
|
set.add(array, 4, 3).add(array2, 1);
|
76
76
|
validate(set, [expected, expected2]); // precondition
|
77
77
|
|
78
78
|
var x = SC.SelectionSet.create().add(array, 4,1).add(array2, 1);
|
79
79
|
set.remove(x);
|
80
|
-
|
80
|
+
|
81
81
|
expected.remove(4,1);
|
82
82
|
validate(set, [SC.IndexSet.create(5,2)], array);
|
83
83
|
});
|
@@ -85,27 +85,63 @@ test("Adding another SelectionSet", function() {
|
|
85
85
|
|
86
86
|
// ..........................................................
|
87
87
|
// SPECIAL CASES
|
88
|
-
//
|
88
|
+
//
|
89
89
|
|
90
90
|
test("removing index set should also remove individually added objects", function() {
|
91
91
|
var objToRemove = array[3]; // item from one array...
|
92
92
|
var objToNotRemove = array2[3]; // item from array we won't remove..
|
93
|
-
|
93
|
+
|
94
94
|
// add both objects.
|
95
95
|
set.addObject(objToRemove).addObject(objToNotRemove);
|
96
96
|
set.add(array, 4, 3);
|
97
|
-
|
97
|
+
|
98
98
|
ok(set.contains(objToRemove), 'set should contain objToRemove');
|
99
99
|
ok(set.contains(objToNotRemove), 'set should contain objToNotRemove');
|
100
100
|
equals(set.get('length'), 5, 'set.length should == two objects + index.length');
|
101
|
-
|
101
|
+
|
102
102
|
// now remove from array set
|
103
|
-
set.remove(array, 2, 4);
|
104
|
-
|
103
|
+
set.remove(array, 2, 4);
|
104
|
+
|
105
105
|
SC.stopIt = NO ;
|
106
|
-
|
106
|
+
|
107
107
|
ok(!set.contains(objToRemove), 'set should NOT contain objToRemove');
|
108
108
|
ok(set.contains(objToNotRemove), 'set should contain objToNotRemove');
|
109
109
|
equals(set.get('length'), 2, 'set.length should == 1 object + index.length');
|
110
110
|
});
|
111
111
|
|
112
|
+
|
113
|
+
module("SC.SelectionSet#constrain", {
|
114
|
+
setup: function() {
|
115
|
+
set = SC.SelectionSet.create();
|
116
|
+
array = '0 1 2 3 4 5 6 7 8 9'.w();
|
117
|
+
array2 = 'a b c d e f g h i k l m'.w();
|
118
|
+
|
119
|
+
expected = SC.IndexSet.create(4,3);
|
120
|
+
expected2 = SC.IndexSet.create(1);
|
121
|
+
expected.source = array;
|
122
|
+
expected2.source = array2;
|
123
|
+
}
|
124
|
+
});
|
125
|
+
|
126
|
+
/**
|
127
|
+
After cleaning up a memory leak in SC.Set, it was discovered that the constrain
|
128
|
+
method of SC.SelectionSet doesn't work properly. It was naively using forEach
|
129
|
+
to iterate through the objects while mutating the array so that the last
|
130
|
+
object would never be constrained.
|
131
|
+
|
132
|
+
This test shows that you can constrain more than one object using the method.
|
133
|
+
*/
|
134
|
+
test("Tests constrain helper method.", function () {
|
135
|
+
var objToRemove1 = 'a',
|
136
|
+
objToRemove2 = 'b';
|
137
|
+
|
138
|
+
set.add(array, 4, 3);
|
139
|
+
set.addObject(objToRemove1);
|
140
|
+
set.addObject(objToRemove2);
|
141
|
+
ok(set.contains(objToRemove1), 'Set should contain objToRemove1');
|
142
|
+
ok(set.contains(objToRemove2), 'Set should contain objToRemove2');
|
143
|
+
set.constrain(array);
|
144
|
+
ok(!set.contains(objToRemove1), 'Set should not contain objToRemove1');
|
145
|
+
ok(!set.contains(objToRemove2), 'Set should not contain objToRemove2');
|
146
|
+
});
|
147
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: SproutCore - JavaScript Application Framework
|
3
|
+
// Copyright: ©2006-2011 Apple Inc. and contributors.
|
4
|
+
// License: Licensed under MIT license (see license.js)
|
5
|
+
// ==========================================================================
|
6
|
+
|
7
|
+
/* global module test equals context ok same */
|
8
|
+
|
9
|
+
module("SC.View#destroy");
|
10
|
+
|
11
|
+
test('isDestroyed works.', function() {
|
12
|
+
var v = SC.View.create();
|
13
|
+
ok(!v.get('isDestroyed'), 'undestroyed view\'s isDestroyed property is false.');
|
14
|
+
v.destroy();
|
15
|
+
ok(v.get('isDestroyed'), 'destroyed view\'s isDestroyed property is true.');
|
16
|
+
});
|
17
|
+
|
18
|
+
test('childViews specified as classes are also destroyed.', function() {
|
19
|
+
var v = SC.View.create({ childViews: [ SC.View ] }),
|
20
|
+
v2 = v.childViews[0];
|
21
|
+
v.destroy();
|
22
|
+
ok(v2.get('isDestroyed'), 'destroying a parent also destroys a child, mwaha.');
|
23
|
+
ok(!v2.get('parentView'), 'destroying a parent removes the parentView reference from the child.');
|
24
|
+
ok(v2.get('owner') === null, 'destroying a parent removes the owner reference from the child.');
|
25
|
+
});
|
26
|
+
|
27
|
+
test('childViews specified as instances are also destroyed.', function() {
|
28
|
+
var v2 = SC.View.create(),
|
29
|
+
v = SC.View.create({ childViews: [v2] });
|
30
|
+
v.destroy();
|
31
|
+
ok(v2.get('isDestroyed'), 'destroying a parent also destroys a child, mwaha.');
|
32
|
+
ok(!v2.get('parentView'), 'destroying a parent removes the parentView reference from the child.');
|
33
|
+
ok(v2.get('owner') === null, 'destroying a parent removes the owner reference from the child.');
|
34
|
+
});
|
@@ -3,25 +3,25 @@
|
|
3
3
|
// Copyright: ©2006-2011 Apple Inc. and contributors.
|
4
4
|
// License: Licensed under MIT license (see license.js)
|
5
5
|
// ==========================================================================
|
6
|
+
/*globals module, test, equals, context, ok, same, Q$ */
|
6
7
|
|
7
|
-
/*global module test equals context ok same Q$ */
|
8
8
|
|
9
9
|
module("SC.View#destroyLayer");
|
10
10
|
|
11
11
|
test("it if has no layer, does nothing", function() {
|
12
12
|
var callCount = 0;
|
13
|
-
var view = SC.View.create({
|
13
|
+
var view = SC.View.create({
|
14
14
|
willDestroyLayer: function() { callCount++; }
|
15
15
|
});
|
16
16
|
ok(!view.get('layer'), 'precond - does NOT have layer');
|
17
|
-
|
17
|
+
|
18
18
|
view.destroyLayer();
|
19
19
|
equals(callCount, 0, 'did not invoke callback');
|
20
20
|
});
|
21
21
|
|
22
22
|
test("if it has a layer, calls willDestroyLayer on receiver and child views then deletes the layer", function() {
|
23
23
|
var callCount = 0;
|
24
|
-
|
24
|
+
|
25
25
|
var view = SC.View.create({
|
26
26
|
willDestroyLayer: function() { callCount++; },
|
27
27
|
childViews: [SC.View.extend({
|
@@ -33,9 +33,9 @@ test("if it has a layer, calls willDestroyLayer on receiver and child views then
|
|
33
33
|
});
|
34
34
|
view.createLayer();
|
35
35
|
ok(view.get('layer'), 'precond - view has layer');
|
36
|
-
|
36
|
+
|
37
37
|
view.destroyLayer();
|
38
|
-
equals(callCount, 2, 'invoked destroy layer');
|
38
|
+
equals(callCount, 2, 'invoked destroy layer');
|
39
39
|
ok(!view.get('layer'), 'view no longer has layer');
|
40
40
|
});
|
41
41
|
|
@@ -46,11 +46,11 @@ test("if it has a layer, calls willDestroyLayerMixin on receiver and child views
|
|
46
46
|
var mixinA = {
|
47
47
|
willDestroyLayerMixin: function() { callCount++; }
|
48
48
|
};
|
49
|
-
|
49
|
+
|
50
50
|
var mixinB = {
|
51
51
|
willDestroyLayerMixin: function() { callCount++; }
|
52
52
|
};
|
53
|
-
|
53
|
+
|
54
54
|
var view = SC.View.create(mixinA, mixinB, {
|
55
55
|
childViews: [SC.View.extend(mixinA, mixinB, {
|
56
56
|
childViews: [SC.View.extend(mixinA)]
|
@@ -58,7 +58,7 @@ test("if it has a layer, calls willDestroyLayerMixin on receiver and child views
|
|
58
58
|
});
|
59
59
|
view.createLayer();
|
60
60
|
view.destroyLayer();
|
61
|
-
equals(callCount, 5, 'invoked willDestroyLayerMixin on all mixins');
|
61
|
+
equals(callCount, 5, 'invoked willDestroyLayerMixin on all mixins');
|
62
62
|
});
|
63
63
|
|
64
64
|
test("returns receiver", function() {
|
@@ -69,10 +69,10 @@ test("returns receiver", function() {
|
|
69
69
|
test("removes layer from parentNode if in DOM", function() {
|
70
70
|
var view = SC.View.create();
|
71
71
|
var layer = view.createLayer().get('layer');
|
72
|
-
|
72
|
+
|
73
73
|
ok(layer, 'precond - has layer');
|
74
74
|
document.body.appendChild(layer); // add to document body
|
75
|
-
|
75
|
+
|
76
76
|
view.destroyLayer();
|
77
77
|
|
78
78
|
if(layer.parentNode) equals(layer.parentNode.nodeType, 11, 'layer no longer in parent node');
|
@@ -80,4 +80,40 @@ test("removes layer from parentNode if in DOM", function() {
|
|
80
80
|
layer = null; // cleanup
|
81
81
|
});
|
82
82
|
|
83
|
+
/**
|
84
|
+
There is a bug that if childView layers are rendered when the parentView's
|
85
|
+
layer is created, the `layer` property on the childView will not be
|
86
|
+
cached. What occurs is that if the childView is removed from the parent
|
87
|
+
view without ever having its `layer` requested, then when it comes time
|
88
|
+
to destroy the layer of the childView, it will get('layer'), which had a
|
89
|
+
bug that only returned a layer if the view has a parent view. However,
|
90
|
+
since the child was removed from the parent first and then destroyed, it
|
91
|
+
no longer has a parent view and would return undefined for its `layer`.
|
83
92
|
|
93
|
+
This left elements in the DOM.
|
94
|
+
*/
|
95
|
+
test("Tests that if the childView's layer was never cached and the childView is removed, it should still destroy the childView's layer", function() {
|
96
|
+
var childView,
|
97
|
+
layerId,
|
98
|
+
pane,
|
99
|
+
view;
|
100
|
+
|
101
|
+
childView = SC.View.create({});
|
102
|
+
|
103
|
+
layerId = childView.get('layerId');
|
104
|
+
|
105
|
+
view = SC.View.create({
|
106
|
+
childViews: [childView]
|
107
|
+
});
|
108
|
+
|
109
|
+
pane = SC.Pane.create({
|
110
|
+
childViews: [view]
|
111
|
+
}).append();
|
112
|
+
|
113
|
+
ok(document.getElementById(layerId), 'child layer should be in the DOM');
|
114
|
+
ok(!childView._view_layer, 'child view should not have cached its layer');
|
115
|
+
view.removeChild(childView);
|
116
|
+
ok(document.getElementById(layerId), 'child layer should be in the DOM');
|
117
|
+
childView.destroy();
|
118
|
+
ok(!document.getElementById(layerId), 'child layer should not be in the DOM');
|
119
|
+
});
|