sproutcore 1.9.0 → 1.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
});
|