sproutcore 0.9.17 → 0.9.18
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +45 -2
- data/Manifest.txt +10 -0
- data/Rakefile +1 -1
- data/app_generators/sproutcore/templates/sc-config +8 -2
- data/bin/sc-server +4 -0
- data/clients/sc_docs/english.lproj/body.css +0 -20
- data/clients/sc_docs/english.lproj/body.rhtml +1 -3
- data/clients/sc_docs/english.lproj/strings.js +1 -1
- data/clients/sc_docs/french.lproj/strings.js +14 -0
- data/clients/sc_test_runner/english.lproj/body.css +0 -20
- data/clients/sc_test_runner/english.lproj/body.rhtml +1 -3
- data/config/hoe.rb +1 -1
- data/frameworks/sproutcore/HISTORY +56 -1
- data/frameworks/sproutcore/debug/trace.js +81 -0
- data/frameworks/sproutcore/debug/unittest.js +2 -1
- data/frameworks/sproutcore/english.lproj/buttons.css +5 -2
- data/frameworks/sproutcore/english.lproj/core.css +0 -16
- data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/splitview.css +83 -0
- data/frameworks/sproutcore/english.lproj/theme.css +21 -5
- data/frameworks/sproutcore/foundation/object.js +23 -0
- data/frameworks/sproutcore/foundation/string.js +4 -3
- data/frameworks/sproutcore/lib/core_views.rb +43 -8
- data/frameworks/sproutcore/lib/form_views.rb +2 -2
- data/frameworks/sproutcore/lib/index.rhtml +1 -1
- data/frameworks/sproutcore/mixins/enumerable.js +4 -8
- data/frameworks/sproutcore/mixins/selection_support.js +1 -1
- data/frameworks/sproutcore/models/collection.js +14 -3
- data/frameworks/sproutcore/models/record.js +6 -5
- data/frameworks/sproutcore/models/store.js +3 -3
- data/frameworks/sproutcore/panes/picker.js +1 -0
- data/frameworks/sproutcore/server/rails_server.js +4 -7
- data/frameworks/sproutcore/server/server.js +58 -1
- data/frameworks/sproutcore/tests/controllers/object.rhtml +1 -1
- data/frameworks/sproutcore/tests/models/collection.rhtml +160 -0
- data/frameworks/sproutcore/tests/models/model.rhtml +15 -3
- data/frameworks/sproutcore/tests/views/collection/base.rhtml +120 -47
- data/frameworks/sproutcore/tests/views/collection/source_list_rendering.rhtml +232 -0
- data/frameworks/sproutcore/tests/views/view/frame.rhtml +2 -2
- data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +87 -85
- data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +25 -26
- data/frameworks/sproutcore/views/collection/collection.js +5 -1
- data/frameworks/sproutcore/views/field/select_field.js +1 -1
- data/frameworks/sproutcore/views/radio_group.js +2 -2
- data/frameworks/sproutcore/views/split.js +191 -174
- data/frameworks/sproutcore/views/split_divider.js +71 -68
- data/frameworks/sproutcore/views/view.js +65 -25
- data/lib/sproutcore.rb +4 -1
- data/lib/sproutcore/build_tools/html_builder.rb +50 -46
- data/lib/sproutcore/build_tools/resource_builder.rb +17 -5
- data/lib/sproutcore/bundle_installer.rb +3 -1
- data/lib/sproutcore/bundle_manifest.rb +4 -3
- data/lib/sproutcore/cssmin.rb +195 -0
- data/lib/sproutcore/generator_helper.rb +15 -0
- data/lib/sproutcore/helpers/capture_helper.rb +2 -22
- data/lib/sproutcore/helpers/dom_id_helper.rb +14 -0
- data/lib/sproutcore/helpers/static_helper.rb +6 -2
- data/lib/sproutcore/helpers/text_helper.rb +1 -1
- data/lib/sproutcore/merb.rb +2 -2
- data/lib/sproutcore/renderers/erubis.rb +43 -0
- data/lib/sproutcore/renderers/haml.rb +28 -0
- data/lib/sproutcore/renderers/sass.rb +42 -0
- data/lib/sproutcore/version.rb +1 -1
- data/lib/sproutcore/view_helpers.rb +40 -46
- data/sc_generators/controller/controller_generator.rb +1 -1
- data/sc_generators/language/USAGE +5 -7
- data/sc_generators/language/language_generator.rb +1 -1
- data/sc_generators/language/templates/strings.js +5 -1
- data/sc_generators/model/model_generator.rb +1 -1
- data/sc_generators/test/test_generator.rb +1 -1
- data/sc_generators/view/view_generator.rb +1 -1
- metadata +12 -5
@@ -216,6 +216,7 @@ SC.Record = SC.Object.extend(
|
|
216
216
|
if (ret === undefined) {
|
217
217
|
var attr = this._attributes ;
|
218
218
|
ret = (attr) ? attr[key] : undefined ;
|
219
|
+
ret = ret || this[key] ; // also check properties...
|
219
220
|
if (ret !== undefined) {
|
220
221
|
var recordType = this._getRecordType(key+'Type') ;
|
221
222
|
ret = this._propertyFromAttribute(ret, recordType) ;
|
@@ -248,7 +249,6 @@ SC.Record = SC.Object.extend(
|
|
248
249
|
*/
|
249
250
|
recordDidChange: function() {
|
250
251
|
this.incrementProperty('changeCount') ;
|
251
|
-
if (SC.Store) SC.Store.recordDidChange(this) ;
|
252
252
|
},
|
253
253
|
|
254
254
|
/**
|
@@ -500,7 +500,7 @@ SC.Record = SC.Object.extend(
|
|
500
500
|
|
501
501
|
_matchValue: function(recValue,value) {
|
502
502
|
// if we get here with recValue as a record, we must compare by guid, so grab it
|
503
|
-
if (recValue && recValue.primaryKey) recValue = recValue.get(recValue.primaryKey) ;
|
503
|
+
if (recValue && recValue.primaryKey) recValue = recValue.get(recValue.get('primaryKey')) ;
|
504
504
|
var stringify = (value instanceof RegExp);
|
505
505
|
if (stringify) {
|
506
506
|
if (recValue == null) return false ;
|
@@ -648,7 +648,7 @@ SC.Record = SC.Object.extend(
|
|
648
648
|
_convertValueOut: function(value,typeConverter,recordType) {
|
649
649
|
if (typeConverter) return typeConverter(value,'out') ;
|
650
650
|
if (recordType) {
|
651
|
-
return (value) ? value.get(recordType.primaryKey) : null ;
|
651
|
+
return (value) ? value.get(recordType.primaryKey()) : null ;
|
652
652
|
} else return value ;
|
653
653
|
},
|
654
654
|
|
@@ -742,7 +742,7 @@ SC.Record.mixin(
|
|
742
742
|
var conditions = opts.conditions || {} ;
|
743
743
|
opts.conditions = conditions ;
|
744
744
|
|
745
|
-
var privateKey = '_' + conditionKey ;
|
745
|
+
var privateKey = '_' + conditionKey + SC.generateGuid() ;
|
746
746
|
return function() {
|
747
747
|
if (!this[privateKey]) {
|
748
748
|
var recordType = eval(recordTypeString);
|
@@ -781,7 +781,8 @@ SC.Record.Date = function(value,direction) {
|
|
781
781
|
} else if (typeof(value) == "string") {
|
782
782
|
// try to parse date. trim any decimal numbers at end since Rails sends
|
783
783
|
// this sometimes.
|
784
|
-
var ret = Date.
|
784
|
+
var ret = Date.parseDate(value.replace(/\.\d+$/,'')) ;
|
785
|
+
if (!ret) ret = new Date(value);
|
785
786
|
if (ret) value = ret ;
|
786
787
|
}
|
787
788
|
return value ;
|
@@ -291,9 +291,9 @@ SC.Store = SC.Object.create(
|
|
291
291
|
*/
|
292
292
|
recordDidChange: function(rec) {
|
293
293
|
// add to changed records. This will eventually notify collections.
|
294
|
-
var guid
|
295
|
-
|
296
|
-
|
294
|
+
var guid = rec._storeKey(),
|
295
|
+
changed = this.get('_changedRecords') || {},
|
296
|
+
records = changed[guid] || {} ;
|
297
297
|
records[rec._guid] = rec ;
|
298
298
|
|
299
299
|
changed[guid] = records ;
|
@@ -53,14 +53,11 @@ require('server/rest_server') ;
|
|
53
53
|
map.connect 'auth-token.js', :controller => 'application', :action => 'auth_token'
|
54
54
|
}}}
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
index template add a line to call auth-token.js on your rails server.
|
60
|
-
For example:
|
61
|
-
|
56
|
+
Lastly, add a reference to the script to the :javascript_libs property
|
57
|
+
in your sc-config file, for example:
|
58
|
+
|
62
59
|
{{{
|
63
|
-
|
60
|
+
c[:javascript_libs] = ['/sc/auth-token.js']
|
64
61
|
}}}
|
65
62
|
|
66
63
|
|
@@ -288,7 +288,7 @@ SC.Server = SC.Object.extend({
|
|
288
288
|
var key = r.get(primaryKey);
|
289
289
|
if (key) { ids.push(key); context[key] = r; }
|
290
290
|
});
|
291
|
-
context._recordType = curRecords[0].
|
291
|
+
context._recordType = this._instantiateRecordType(curRecords[0].get('type'), this.prefix, null) ; // default rec type.
|
292
292
|
|
293
293
|
params = {
|
294
294
|
requestContext: context,
|
@@ -503,6 +503,50 @@ SC.Server = SC.Object.extend({
|
|
503
503
|
// ................................
|
504
504
|
// PRIVATE METHODS
|
505
505
|
|
506
|
+
_prepareDataForRecords: function(data, server, defaultType) {
|
507
|
+
if (data === null) {
|
508
|
+
return null;
|
509
|
+
} else if ($type(data) == T_ARRAY) {
|
510
|
+
var that = this;
|
511
|
+
return data.map( function(d) {
|
512
|
+
return that._prepareDataForRecords(d, server, defaultType) ;
|
513
|
+
}) ;
|
514
|
+
} else if ($type(data) == T_HASH) {
|
515
|
+
data = server._camelizeData(data) ; // camelize the keys received back.
|
516
|
+
if (data.id) {
|
517
|
+
// convert the 'id' property to 'guid'
|
518
|
+
data.guid = data.id;
|
519
|
+
delete data.id;
|
520
|
+
}
|
521
|
+
data.recordType = server._instantiateRecordType(data.type, server.prefix, defaultType);
|
522
|
+
if (data.recordType) {
|
523
|
+
return data;
|
524
|
+
} else {
|
525
|
+
console.log("Data RecordType could not be instantiated!: "+data.type) ;
|
526
|
+
return null; // could not process.
|
527
|
+
}
|
528
|
+
} else {
|
529
|
+
console.log("Unknown data type in SC.Server#_prepareDataForRecords. Should be array or hash.") ;
|
530
|
+
return null; // could not process.
|
531
|
+
}
|
532
|
+
},
|
533
|
+
|
534
|
+
_instantiateRecordType: function(recordType, prefix, defaultType) {
|
535
|
+
if (recordType) {
|
536
|
+
var recordName = recordType.capitalize() ;
|
537
|
+
if (prefix) {
|
538
|
+
for (var prefixLoc = 0; prefixLoc < prefix.length; prefixLoc++) {
|
539
|
+
var prefixParts = prefix[prefixLoc].split('.');
|
540
|
+
var namespace = window;
|
541
|
+
for (var prefixPartsLoc = 0; prefixPartsLoc < prefixParts.length; prefixPartsLoc++) {
|
542
|
+
var namespace = namespace[prefixParts[prefixPartsLoc]] ;
|
543
|
+
}
|
544
|
+
if (namespace !== window) return namespace[recordName] ;
|
545
|
+
}
|
546
|
+
} else return window[recordName] ;
|
547
|
+
} else return defaultType;
|
548
|
+
},
|
549
|
+
|
506
550
|
// places records from array into hash, sorted by resourceURL.
|
507
551
|
_recordsByResource: function(records) {
|
508
552
|
var ret = {} ;
|
@@ -590,6 +634,19 @@ SC.Server = SC.Object.extend({
|
|
590
634
|
|
591
635
|
// handle other values
|
592
636
|
} else return [rootKey,params].join('=') ;
|
637
|
+
},
|
638
|
+
|
639
|
+
init: function() {
|
640
|
+
sc_super();
|
641
|
+
SC.Server.addServer(this);
|
593
642
|
}
|
594
643
|
|
595
644
|
}) ;
|
645
|
+
|
646
|
+
SC.Server.servers = [];
|
647
|
+
|
648
|
+
SC.Server.addServer = function(server) {
|
649
|
+
var ary = SC.Server.servers;
|
650
|
+
ary.push(server);
|
651
|
+
SC.Server.servers = ary;
|
652
|
+
};
|
@@ -250,7 +250,7 @@ Test.context("SC.ObjectController", {
|
|
250
250
|
var rcrds = Contact.collection();
|
251
251
|
cc.set('content', rcrds);
|
252
252
|
rcrds.refresh();
|
253
|
-
var single = Contact.
|
253
|
+
var single = Contact.newRecord({'test' : 'NAME1', 'value' : 0});
|
254
254
|
|
255
255
|
rcrds.count().shouldEqual(1);
|
256
256
|
|
@@ -0,0 +1,160 @@
|
|
1
|
+
<% # ========================================================================
|
2
|
+
# Collection Unit Test
|
3
|
+
# ========================================================================
|
4
|
+
%>
|
5
|
+
<% content_for('final') do %>
|
6
|
+
|
7
|
+
<script>
|
8
|
+
|
9
|
+
|
10
|
+
//
|
11
|
+
// core.js stub
|
12
|
+
//
|
13
|
+
CollectionTest = SC.Object.create({
|
14
|
+
|
15
|
+
server: SC.Server.create({ prefix: ['CollectionTest'] }),
|
16
|
+
|
17
|
+
FIXTURES: []
|
18
|
+
|
19
|
+
}) ;
|
20
|
+
|
21
|
+
//
|
22
|
+
// fixtures stub
|
23
|
+
//
|
24
|
+
CollectionTest.FIXTURES = CollectionTest.FIXTURES.concat([
|
25
|
+
|
26
|
+
{ guid: '1',
|
27
|
+
type: 'Employee',
|
28
|
+
name: "Anne",
|
29
|
+
sex: "Female"
|
30
|
+
},
|
31
|
+
|
32
|
+
{ guid: '2',
|
33
|
+
type: 'Employee',
|
34
|
+
name: "Bob",
|
35
|
+
sex: "Male"
|
36
|
+
},
|
37
|
+
|
38
|
+
{ guid: '3',
|
39
|
+
type: 'Employee',
|
40
|
+
name: "Alice",
|
41
|
+
sex: "Female"
|
42
|
+
},
|
43
|
+
|
44
|
+
{ guid: '4',
|
45
|
+
type: 'Employee',
|
46
|
+
name: "Rachel",
|
47
|
+
sex: "Female"
|
48
|
+
},
|
49
|
+
|
50
|
+
{ guid: '5',
|
51
|
+
type: 'Employee',
|
52
|
+
name: "Michael",
|
53
|
+
sex: "Male"
|
54
|
+
},
|
55
|
+
|
56
|
+
{ guid: '6',
|
57
|
+
type: 'Employee',
|
58
|
+
name: "Barbara",
|
59
|
+
sex: "Female"
|
60
|
+
},
|
61
|
+
|
62
|
+
{ guid: '7',
|
63
|
+
type: 'Employee',
|
64
|
+
name: "Richard",
|
65
|
+
sex: "Male"
|
66
|
+
}
|
67
|
+
|
68
|
+
]);
|
69
|
+
|
70
|
+
//
|
71
|
+
// model classes
|
72
|
+
//
|
73
|
+
CollectionTest.Employee = SC.Record.extend({
|
74
|
+
|
75
|
+
}) ;
|
76
|
+
|
77
|
+
//
|
78
|
+
// main.js stub
|
79
|
+
//
|
80
|
+
CollectionTest.server.preload(CollectionTest.FIXTURES) ;
|
81
|
+
|
82
|
+
Test.context("Test basic functions of a collection", {
|
83
|
+
|
84
|
+
setup: function()
|
85
|
+
{
|
86
|
+
this.employees = CollectionTest.Employee.collection()
|
87
|
+
|
88
|
+
this.anne = CollectionTest.Employee.find('1');
|
89
|
+
this.bob = CollectionTest.Employee.find('2');
|
90
|
+
this.alice = CollectionTest.Employee.find('3');
|
91
|
+
this.rachel = CollectionTest.Employee.find('4');
|
92
|
+
this.michael = CollectionTest.Employee.find('5');
|
93
|
+
this.barbara = CollectionTest.Employee.find('6');
|
94
|
+
this.richard = CollectionTest.Employee.find('7');
|
95
|
+
},
|
96
|
+
|
97
|
+
teardown: function()
|
98
|
+
{
|
99
|
+
delete this.employees;
|
100
|
+
delete this.anne;
|
101
|
+
delete this.bob;
|
102
|
+
delete this.alice;
|
103
|
+
delete this.rachel;
|
104
|
+
delete this.michael;
|
105
|
+
delete this.barbara;
|
106
|
+
delete this.richard;
|
107
|
+
},
|
108
|
+
|
109
|
+
"Collection should initially be empty": function() {
|
110
|
+
assertNull(this.employees.get('records'));
|
111
|
+
},
|
112
|
+
|
113
|
+
"Collection should have 7 records upon refresh": function() {
|
114
|
+
this.employees.refresh();
|
115
|
+
this.employees.get('records').length.shouldEqual(7);
|
116
|
+
},
|
117
|
+
|
118
|
+
"Collections should NOT contain records that have NOT been added to the store": function() {
|
119
|
+
this.employees.refresh();
|
120
|
+
var originalLength = this.employees.get('records').length;
|
121
|
+
var newEmployee = CollectionTest.Employee.create({name: "Joe"});
|
122
|
+
this.employees.get('records').length.shouldEqual(originalLength);
|
123
|
+
},
|
124
|
+
|
125
|
+
"Collections should contain records that have been added to the store": function() {
|
126
|
+
this.employees.refresh();
|
127
|
+
var originalLength = this.employees.get('records').length;
|
128
|
+
var newEmployee = CollectionTest.Employee.newRecord({name: "Joe"});
|
129
|
+
this.employees.get('records').length.shouldEqual(originalLength + 1);
|
130
|
+
newEmployee.destroy();
|
131
|
+
},
|
132
|
+
|
133
|
+
"Collections should be properly ordered": function() {
|
134
|
+
var employeesByName = CollectionTest.Employee.collection({orderBy: ['name']});
|
135
|
+
employeesByName.refresh();
|
136
|
+
var names = employeesByName.get('records').map(function(e) { return e.get('name') });
|
137
|
+
assertIdentical(["Alice", "Anne", "Barbara", "Bob", "Michael", "Rachel", "Richard"].join(""), names.join(""));
|
138
|
+
|
139
|
+
var employeesBySex = CollectionTest.Employee.collection({orderBy: ['sex']});
|
140
|
+
employeesBySex.refresh();
|
141
|
+
var sexes = employeesBySex.get('records').map(function(e) { return e.get('sex') });
|
142
|
+
assertIdentical(["Female", "Female", "Female", "Female", "Male", "Male", "Male"].join(""), sexes.join(""));
|
143
|
+
},
|
144
|
+
|
145
|
+
"Collections should remain unchanged if a record is changed in a way that does not affect the order": function() {
|
146
|
+
var employeesBySex = CollectionTest.Employee.collection({orderBy: ['sex']});
|
147
|
+
employeesBySex.refresh();
|
148
|
+
var employeesOriginal = employeesBySex.get('records').map(function(e) { return e.get('guid') }).join(", ");
|
149
|
+
|
150
|
+
this.bob.set('name', 'Robert');
|
151
|
+
var employees = employeesBySex.get('records').map(function(e) { return e.get('guid') }).join(", ");
|
152
|
+
|
153
|
+
assertIdentical(employeesOriginal, employees);
|
154
|
+
}
|
155
|
+
|
156
|
+
});
|
157
|
+
|
158
|
+
</script>
|
159
|
+
|
160
|
+
<% end %>
|
@@ -89,12 +89,14 @@ Test.context("Test model comparisons with numeric guids", {
|
|
89
89
|
|
90
90
|
teardown: function()
|
91
91
|
{
|
92
|
-
delete this.
|
92
|
+
delete this.todoList1;
|
93
|
+
delete this.todoList2;
|
93
94
|
delete this.todo1;
|
94
95
|
delete this.todo2;
|
96
|
+
delete this.todo3;
|
95
97
|
},
|
96
98
|
|
97
|
-
"
|
99
|
+
"Records should exist in Store": function()
|
98
100
|
{
|
99
101
|
assertNotNull(this.todoList1);
|
100
102
|
assertNotNull(this.todoList2);
|
@@ -103,6 +105,15 @@ Test.context("Test model comparisons with numeric guids", {
|
|
103
105
|
assertNotNull(this.todo3);
|
104
106
|
},
|
105
107
|
|
108
|
+
"Records should have correct guid": function()
|
109
|
+
{
|
110
|
+
assertEqual(1, this.todoList1.get('guid'));
|
111
|
+
assertEqual(2, this.todoList2.get('guid'));
|
112
|
+
assertEqual(1, this.todo1.get('guid'));
|
113
|
+
assertEqual(2, this.todo2.get('guid'));
|
114
|
+
assertEqual(3, this.todo3.get('guid'));
|
115
|
+
},
|
116
|
+
|
106
117
|
"Todo 1 and 2 should be related to TodoList 1": function()
|
107
118
|
{
|
108
119
|
assertIdentical(this.todoList1, this.todo1.get('todoList'));
|
@@ -175,7 +186,8 @@ Test.context("Test model comparisons with numeric guids", {
|
|
175
186
|
"toString() should show model class name": function()
|
176
187
|
{
|
177
188
|
var re = /^ModelTest.Todo/;
|
178
|
-
|
189
|
+
var str = this.todo1.toString();
|
190
|
+
assert( str.match(re), "Todo 1 toString() should start with ModelTest.Todo, actually starts with " + str);
|
179
191
|
}
|
180
192
|
|
181
193
|
});
|
@@ -1,34 +1,67 @@
|
|
1
1
|
<% content_for('final') do %>
|
2
2
|
<script>
|
3
3
|
|
4
|
-
|
4
|
+
// create some item data...
|
5
|
+
[
|
6
|
+
{ guid: '1001', name: 'item one' },
|
7
|
+
{ guid: '1002', name: 'item two' },
|
8
|
+
{ guid: '1003', name: 'item three' },
|
9
|
+
{ guid: '1004', name: 'item four' },
|
10
|
+
{ guid: '1005', name: 'item five' },
|
11
|
+
{ guid: '1006', name: 'item six' }
|
12
|
+
].each(function(o){ SC.Store.addRecord(SC.Record.create(o)); });
|
13
|
+
|
14
|
+
// a collection to hold the items...
|
15
|
+
testCollection = SC.Record.collection();
|
16
|
+
testCollection.refresh();
|
17
|
+
|
18
|
+
// a controller for the collection...
|
19
|
+
testController = SC.CollectionController.create();
|
20
|
+
|
21
|
+
Test.context("A SC.CollectionView with it's content set to a SC.CollectionController 1", {
|
5
22
|
|
6
|
-
"Should
|
23
|
+
"Should scroll to the selected item": function()
|
7
24
|
{
|
8
|
-
testCollectionView.get('
|
25
|
+
testCollectionView.get('rootElement').scrollTop.shouldEqual(0);
|
26
|
+
testCollectionView.scrollToContent( testCollection.get('records').last() );
|
27
|
+
testCollectionView.get('itemViews').length.shouldEqual(3);
|
28
|
+
scrollView.get('rootElement').scrollTop.shouldEqual(30);
|
9
29
|
},
|
10
30
|
|
11
|
-
|
31
|
+
setup: function()
|
12
32
|
{
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
33
|
+
// add a scroll view wrapper.
|
34
|
+
scrollView = SC.ScrollView.create() ;
|
35
|
+
scrollView.set('frame', { x: 10, y: 10, width: 100, height: 30 }) ;
|
36
|
+
SC.window.appendChild(scrollView) ;
|
17
37
|
|
18
|
-
|
38
|
+
// create the view...
|
39
|
+
testCollectionView = SC.ListView.create({
|
40
|
+
contentValueKey: 'name',
|
41
|
+
contentBinding: 'testController.arrangedObjects',
|
42
|
+
selectionBinding: 'testController.selection'
|
43
|
+
}) ;
|
44
|
+
scrollView.set('content', testCollectionView) ;
|
19
45
|
|
20
|
-
|
21
|
-
|
22
|
-
valueOfFirstItemView().shouldEqual('0999') ;
|
46
|
+
testController.set('content', testCollection) ;
|
23
47
|
},
|
24
|
-
|
25
|
-
|
48
|
+
|
49
|
+
teardown: function()
|
26
50
|
{
|
27
|
-
|
28
|
-
testCollectionView.
|
29
|
-
scrollView.
|
30
|
-
|
51
|
+
// remove the view from SC.window
|
52
|
+
testCollectionView.removeFromParent() ;
|
53
|
+
scrollView.removeFromParent() ;
|
54
|
+
|
55
|
+
delete testCollectionView ;
|
56
|
+
delete scrollView ;
|
57
|
+
|
58
|
+
testController.set('content', null) ;
|
59
|
+
}
|
60
|
+
|
61
|
+
});
|
31
62
|
|
63
|
+
Test.context("A SC.CollectionView with it's content set to a SC.CollectionController 2", {
|
64
|
+
|
32
65
|
"Should not scroll to the selected item if it's already fully visible": function()
|
33
66
|
{
|
34
67
|
scrollView.get('rootElement').scrollTop.shouldEqual(0);
|
@@ -40,50 +73,89 @@ Test.context("A SC.CollectionView with it's content set to a SC.CollectionContro
|
|
40
73
|
{
|
41
74
|
// add a scroll view wrapper.
|
42
75
|
scrollView = SC.ScrollView.create() ;
|
43
|
-
scrollView.set('frame', { x: 10, y: 10, width: 100, height: 30 });
|
44
|
-
SC.window.appendChild(scrollView);
|
76
|
+
scrollView.set('frame', { x: 10, y: 10, width: 100, height: 30 }) ;
|
77
|
+
SC.window.appendChild(scrollView) ;
|
45
78
|
|
46
79
|
// create the view...
|
47
|
-
testCollectionView = SC.ListView.
|
80
|
+
testCollectionView = SC.ListView.create({
|
48
81
|
contentValueKey: 'name',
|
49
82
|
contentBinding: 'testController.arrangedObjects',
|
50
83
|
selectionBinding: 'testController.selection'
|
51
|
-
})
|
84
|
+
}) ;
|
52
85
|
scrollView.set('content', testCollectionView) ;
|
86
|
+
|
87
|
+
testController.set('content', testCollection) ;
|
88
|
+
},
|
89
|
+
|
90
|
+
teardown: function()
|
91
|
+
{
|
92
|
+
// remove the view from SC.window
|
93
|
+
testCollectionView.removeFromParent() ;
|
94
|
+
scrollView.removeFromParent() ;
|
53
95
|
|
54
|
-
|
55
|
-
|
56
|
-
{ guid: '1001', name: 'item one' },
|
57
|
-
{ guid: '1002', name: 'item two' },
|
58
|
-
{ guid: '1003', name: 'item three' },
|
59
|
-
{ guid: '1004', name: 'item four' },
|
60
|
-
{ guid: '1005', name: 'item five' },
|
61
|
-
{ guid: '1006', name: 'item six' }
|
62
|
-
].each(function(o){ SC.Store.addRecord(SC.Record.create(o)); });
|
96
|
+
delete testCollectionView ;
|
97
|
+
delete scrollView ;
|
63
98
|
|
64
|
-
|
65
|
-
|
66
|
-
|
99
|
+
testController.set('content', null) ;
|
100
|
+
}
|
101
|
+
|
102
|
+
});
|
67
103
|
|
68
|
-
|
69
|
-
|
70
|
-
|
104
|
+
Test.context("A SC.CollectionView with it's content set to a SC.CollectionController 3", {
|
105
|
+
|
106
|
+
"Should contain the same number of visible item views as it's controller has records": function()
|
107
|
+
{
|
108
|
+
testCollectionView.get('itemViews').length.shouldEqual(2);
|
109
|
+
},
|
110
|
+
|
111
|
+
"Should update it's item views as it's controller is updated": function()
|
112
|
+
{
|
113
|
+
var valueOfFirstItemView = function() {
|
114
|
+
var itemView = testCollectionView.get('itemViews').first() ;
|
115
|
+
return (itemView) ? itemView.get('content').get('guid') : null ;
|
116
|
+
} ;
|
117
|
+
|
118
|
+
valueOfFirstItemView().shouldEqual('1001') ;
|
119
|
+
|
120
|
+
var rec = SC.Record.create({ guid: '0999', name: 'item zero' });
|
121
|
+
SC.Store.addRecord( rec );
|
122
|
+
|
123
|
+
valueOfFirstItemView().shouldEqual('0999') ;
|
124
|
+
testCollectionView.get('itemViews').length.shouldEqual(2);
|
125
|
+
|
126
|
+
rec.destroy();
|
127
|
+
SC.Store.removeRecord(rec);
|
128
|
+
delete rec;
|
129
|
+
},
|
130
|
+
|
131
|
+
setup: function()
|
132
|
+
{
|
133
|
+
// add a scroll view wrapper.
|
134
|
+
scrollView = SC.ScrollView.create() ;
|
135
|
+
scrollView.set('frame', { x: 10, y: 10, width: 100, height: 30 }) ;
|
136
|
+
SC.window.appendChild(scrollView) ;
|
71
137
|
|
138
|
+
// create the view...
|
139
|
+
testCollectionView = SC.ListView.create({
|
140
|
+
contentValueKey: 'name',
|
141
|
+
contentBinding: 'testController.arrangedObjects',
|
142
|
+
selectionBinding: 'testController.selection'
|
143
|
+
}) ;
|
144
|
+
scrollView.set('content', testCollectionView) ;
|
145
|
+
|
146
|
+
testController.set('content', testCollection) ;
|
72
147
|
},
|
148
|
+
|
73
149
|
teardown: function()
|
74
150
|
{
|
75
|
-
//
|
76
|
-
|
77
|
-
testCollection.get('records').each(function(r){ SC.Store.removeRecord(r); });
|
78
|
-
|
79
|
-
// remove the view from SC.window... again, no shared fixtures...
|
80
|
-
testCollectionView.removeFromParent();
|
151
|
+
// remove the view from SC.window
|
152
|
+
testCollectionView.removeFromParent() ;
|
81
153
|
scrollView.removeFromParent() ;
|
82
|
-
|
83
|
-
delete testCollectionView;
|
84
|
-
delete testCollection;
|
85
|
-
delete testController;
|
154
|
+
|
155
|
+
delete testCollectionView ;
|
86
156
|
delete scrollView ;
|
157
|
+
|
158
|
+
testController.set('content', null) ;
|
87
159
|
}
|
88
160
|
|
89
161
|
});
|
@@ -135,4 +207,5 @@ Test.context("A SC.CollectionView with it's content set to a SC.ArrayController"
|
|
135
207
|
});
|
136
208
|
|
137
209
|
</script>
|
210
|
+
|
138
211
|
<% end %>
|