sproutcore 0.9.17 → 0.9.18
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/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 %>
|