sproutit-sproutcore 1.0.20090721145281 → 1.0.20090721145282
Sign up to get free protection for your applications and to get access to all the features.
- data/Buildfile +4 -3
- data/VERSION.yml +2 -2
- data/buildtasks/entry.rake +3 -0
- data/buildtasks/manifest.rake +35 -9
- data/buildtasks/target.rake +25 -6
- data/frameworks/sproutcore/Buildfile +10 -0
- data/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +41 -20
- data/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +14 -43
- data/frameworks/sproutcore/frameworks/datastore/models/record.js +11 -0
- data/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +6 -3
- data/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +5 -1
- data/frameworks/sproutcore/frameworks/datastore/system/query.js +10 -7
- data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +19 -20
- data/frameworks/sproutcore/frameworks/datastore/system/store.js +126 -93
- data/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +9 -3
- data/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +6 -1
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record/core_methods.js +28 -3
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +13 -5
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record/storeDidChangeProperties.js +46 -23
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +29 -5
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +13 -4
- data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/chain.js +109 -0
- data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +69 -15
- data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +20 -1
- data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/dataHashDidChange.js +4 -1
- data/frameworks/sproutcore/frameworks/datastore/tests/system/query/find_all.js +56 -6
- data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +9 -2
- data/frameworks/sproutcore/frameworks/datastore/tests/system/store/core_methods.js +45 -2
- data/frameworks/sproutcore/frameworks/datastore/tests/system/store/recordDidChange.js +0 -1
- data/frameworks/sproutcore/frameworks/datastore/tests/system/store/retrieveRecord.js +53 -6
- data/frameworks/sproutcore/frameworks/datastore/tests/system/store/writeDataHash.js +0 -5
- data/frameworks/sproutcore/frameworks/desktop/panes/menu.js +47 -27
- data/frameworks/sproutcore/frameworks/desktop/system/drag.js +5 -4
- data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +23 -12
- data/frameworks/sproutcore/frameworks/desktop/tests/views/list/render.js +92 -0
- data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +104 -53
- data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +2 -0
- data/frameworks/sproutcore/frameworks/desktop/views/button.js +4 -3
- data/frameworks/sproutcore/frameworks/desktop/views/collection.js +6 -2
- data/frameworks/sproutcore/frameworks/desktop/views/list.js +9 -0
- data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +2 -2
- data/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +3 -3
- data/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +9 -1
- data/frameworks/sproutcore/frameworks/desktop/views/select_field.js +80 -102
- data/frameworks/sproutcore/frameworks/foundation/controllers/array.js +0 -1
- data/frameworks/sproutcore/frameworks/foundation/english.lproj/text_field.css +5 -1
- data/frameworks/sproutcore/frameworks/foundation/panes/pane.js +8 -1
- data/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +0 -1
- data/frameworks/sproutcore/frameworks/foundation/system/datetime.js +31 -3
- data/frameworks/sproutcore/frameworks/foundation/system/event.js +0 -4
- data/frameworks/sproutcore/frameworks/foundation/system/render_context.js +3 -7
- data/frameworks/sproutcore/frameworks/foundation/system/request.js +3 -4
- data/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +78 -17
- data/frameworks/sproutcore/frameworks/foundation/system/utils.js +9 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/single_case.js +2 -2
- data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_selector.js +2 -2
- data/frameworks/sproutcore/frameworks/foundation/tests/system/datetime.js +5 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +2 -2
- data/frameworks/sproutcore/frameworks/foundation/tests/system/user_defaults.js +1 -4
- data/frameworks/sproutcore/frameworks/foundation/tests/validators/validator.js +20 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +13 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +132 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/views/view/isVisibleInWindow.js +6 -3
- data/frameworks/sproutcore/frameworks/foundation/validators/validator.js +8 -5
- data/frameworks/sproutcore/frameworks/foundation/views/image.js +18 -5
- data/frameworks/sproutcore/frameworks/foundation/views/text_field.js +292 -21
- data/frameworks/sproutcore/frameworks/foundation/views/view.js +13 -14
- data/frameworks/sproutcore/frameworks/mini/license.js +28 -0
- data/frameworks/sproutcore/frameworks/runtime/core.js +35 -0
- data/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1 -1
- data/frameworks/sproutcore/frameworks/runtime/system/sparse_array.js +79 -5
- data/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable.js +6 -6
- data/frameworks/sproutcore/frameworks/runtime/tests/system/sparse_array.js +53 -0
- data/frameworks/sproutcore/frameworks/testing/system/plan.js +4 -0
- data/frameworks/sproutcore/frameworks/testing/system/runner.js +1 -1
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/radio.css +4 -0
- data/gen/design/Buildfile +23 -0
- data/gen/design/README +1 -0
- data/gen/design/USAGE +10 -0
- data/gen/design/templates/english.lproj/@filename@.js +16 -0
- data/gen/page/Buildfile +36 -0
- data/gen/page/README +1 -0
- data/gen/page/USAGE +15 -0
- data/gen/page/templates/pages/@target_name@/Buildfile +16 -0
- data/gen/page/templates/pages/@target_name@/core.js +22 -0
- data/gen/page/templates/pages/@target_name@/english.lproj/body.css +1 -0
- data/gen/page/templates/pages/@target_name@/english.lproj/body.rhtml +7 -0
- data/gen/page/templates/pages/@target_name@/english.lproj/strings.js +15 -0
- data/gen/view/README +1 -1
- data/gen/view/USAGE +5 -5
- data/lib/sproutcore/builders/base.rb +13 -2
- data/lib/sproutcore/builders/html.rb +28 -1
- data/lib/sproutcore/builders/minify.rb +84 -18
- data/lib/sproutcore/builders/test.rb +2 -1
- data/lib/sproutcore/helpers/entry_sorter.rb +16 -1
- data/lib/sproutcore/helpers/static_helper.rb +32 -4
- data/lib/sproutcore/helpers/tag_helper.rb +65 -0
- data/lib/sproutcore/models/manifest.rb +40 -6
- data/lib/sproutcore/models/target.rb +12 -3
- data/lib/sproutcore/rack/builder.rb +56 -4
- data/lib/sproutcore/tools/manifest.rb +1 -0
- data/lib/sproutcore/tools/server.rb +1 -0
- data/lib/sproutcore/tools.rb +21 -1
- data/lib/sproutcore.rb +13 -0
- metadata +16 -1
@@ -262,6 +262,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
|
|
262
262
|
// if the state has changed, update it and notify children
|
263
263
|
if (last !== cur) {
|
264
264
|
this.set('isVisibleInWindow', cur) ;
|
265
|
+
this._needsVisibiltyChange = YES ; // update even if we aren't visible
|
265
266
|
|
266
267
|
var childViews = this.get('childViews'), len = childViews.length, idx;
|
267
268
|
for(idx=0;idx<len;idx++) {
|
@@ -271,20 +272,14 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
|
|
271
272
|
// if we just became visible, update layer + layout if needed...
|
272
273
|
if (cur) {
|
273
274
|
if (this.parentViewDidResize) this.parentViewDidResize();
|
274
|
-
this.set('layerNeedsUpdate', YES);
|
275
|
-
this.invokeOnce(this.updateLayerIfNeeded);
|
276
275
|
|
277
276
|
if (this.get('childViewsNeedLayout')) {
|
278
277
|
this.invokeOnce(this.layoutChildViewsIfNeeded);
|
279
278
|
}
|
280
|
-
|
281
|
-
// if we just became invisible, force an update to hide the layer
|
282
|
-
} else {
|
283
|
-
var that = this;
|
284
|
-
this.set('layerNeedsUpdate', YES);
|
285
|
-
this.invokeOnce(function() { that.updateLayerIfNeeded(YES); });
|
286
279
|
}
|
287
280
|
|
281
|
+
this.set('layerNeedsUpdate', YES) ;
|
282
|
+
|
288
283
|
// if we were firstResponder, resign firstResponder also if no longer
|
289
284
|
// visible.
|
290
285
|
if (!cur && this.get('isFirstResponder')) this.resignFirstResponder();
|
@@ -670,19 +665,19 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
|
|
670
665
|
@returns {SC.View} receiver
|
671
666
|
@test in updateLayer
|
672
667
|
*/
|
673
|
-
updateLayerIfNeeded: function(
|
674
|
-
|
675
|
-
if (
|
668
|
+
updateLayerIfNeeded: function() {
|
669
|
+
var viz = this.get('isVisibleInWindow') ;
|
670
|
+
if ((viz || this._needsVisibiltyChange) && this.get('layerNeedsUpdate')) {
|
671
|
+
this._needsVisibiltyChange = NO ;
|
676
672
|
// only update a layer if it already exists
|
677
673
|
if (this.get('layer')) {
|
678
674
|
this.beginPropertyChanges() ;
|
679
675
|
this.set('layerNeedsUpdate', NO) ;
|
680
676
|
this.updateLayer() ;
|
681
677
|
this.endPropertyChanges() ;
|
682
|
-
|
683
|
-
// clear our layerNeedsUpdate flag so we can respond to changes later
|
684
|
-
} else this.set('layerNeedsUpdate', NO) ;
|
678
|
+
}
|
685
679
|
}
|
680
|
+
else this.set('layerNeedsUpdate', NO) ;
|
686
681
|
return this ;
|
687
682
|
},
|
688
683
|
|
@@ -707,6 +702,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
|
|
707
702
|
var context = this.renderContext(this.get('layer')) ;
|
708
703
|
this.prepareContext(context, NO) ;
|
709
704
|
context.update() ;
|
705
|
+
if (this.didUpdateLayer) this.didUpdateLayer(); // call to update DOM
|
710
706
|
return this ;
|
711
707
|
},
|
712
708
|
|
@@ -870,11 +866,14 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
|
|
870
866
|
cursor = this.get('cursor') ;
|
871
867
|
if (cursor) context.addClass(cursor.get('className')) ;
|
872
868
|
|
869
|
+
this.beginPropertyChanges() ;
|
870
|
+
this.set('layerNeedsUpdate', NO) ;
|
873
871
|
this.render(context, firstTime) ;
|
874
872
|
if (mixins = this.renderMixin) {
|
875
873
|
len = mixins.length;
|
876
874
|
for(idx=0; idx<len; ++idx) mixins[idx].call(this, context, firstTime) ;
|
877
875
|
}
|
876
|
+
this.endPropertyChanges() ;
|
878
877
|
},
|
879
878
|
|
880
879
|
/**
|
@@ -0,0 +1,28 @@
|
|
1
|
+
/*! @license
|
2
|
+
==========================================================================
|
3
|
+
SproutCore -- JavaScript Application Framework
|
4
|
+
copyright 2006-2008, Sprout Systems, Inc. and contributors.
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
7
|
+
copy of this software and associated documentation files (the "Software"),
|
8
|
+
to deal in the Software without restriction, including without limitation
|
9
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
10
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
11
|
+
Software is furnished to do so, subject to the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
14
|
+
all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
22
|
+
DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
For more information about SproutCore, visit http://www.sproutcore.com
|
25
|
+
|
26
|
+
|
27
|
+
==========================================================================
|
28
|
+
@license */
|
@@ -597,6 +597,27 @@ SC.mixin(/** @scope SC */ {
|
|
597
597
|
}
|
598
598
|
|
599
599
|
return root ;
|
600
|
+
},
|
601
|
+
|
602
|
+
|
603
|
+
// ..........................................................
|
604
|
+
// LOCALIZATION SUPPORT
|
605
|
+
//
|
606
|
+
|
607
|
+
/**
|
608
|
+
Known loc strings
|
609
|
+
*/
|
610
|
+
STRINGS: {},
|
611
|
+
|
612
|
+
/**
|
613
|
+
This is a simplified handler for installing a bunch of strings. This
|
614
|
+
ignores the language name and simply applies the passed strings hash.
|
615
|
+
|
616
|
+
@param {String} lang the language the strings are for
|
617
|
+
@param {Hash} strings hash of strings
|
618
|
+
*/
|
619
|
+
stringsFor: function(lang, strings) {
|
620
|
+
SC.mixin(SC.STRINGS, strings);
|
600
621
|
}
|
601
622
|
|
602
623
|
|
@@ -854,3 +875,17 @@ String.prototype.fmt = function() {
|
|
854
875
|
}) ;
|
855
876
|
};
|
856
877
|
|
878
|
+
/**
|
879
|
+
Localizes the string. This will look up the reciever string as a key
|
880
|
+
in the current Strings hash. If the key matches, the loc'd value will be
|
881
|
+
used. The resulting string will also be passed through fmt() to insert
|
882
|
+
any variables.
|
883
|
+
|
884
|
+
@param args {Object...} optional arguments to interpolate also
|
885
|
+
@returns {String} the localized and formatted string.
|
886
|
+
*/
|
887
|
+
String.prototype.loc = function() {
|
888
|
+
var str = SC.STRINGS[this] || this;
|
889
|
+
return str.fmt.apply(str,arguments) ;
|
890
|
+
};
|
891
|
+
|
@@ -834,7 +834,7 @@ SC.Reducers = {
|
|
834
834
|
*/
|
835
835
|
reducedProperty: function(key, value, generateProperty) {
|
836
836
|
|
837
|
-
if (key
|
837
|
+
if (!key || key.charAt(0) !== '@') return undefined ; // not a reduced property
|
838
838
|
|
839
839
|
// get the reducer key and the reducer
|
840
840
|
var matches = key.match(/^@([^(]*)(\(([^)]*)\))?$/) ;
|
@@ -97,6 +97,13 @@ SC.SparseArray = SC.Object.extend(SC.Observable, SC.Enumerable, SC.Array,
|
|
97
97
|
*/
|
98
98
|
rangeWindowSize: 1,
|
99
99
|
|
100
|
+
/*
|
101
|
+
This array contains all the start_indexes of ranges requested. This is to
|
102
|
+
avoid calling sparseArrayDidRequestRange to often. Indexes are removed and
|
103
|
+
added as range requests are completed.
|
104
|
+
*/
|
105
|
+
requestedRangeIndex: [],
|
106
|
+
|
100
107
|
/**
|
101
108
|
Returns the object at the specified index. If the value for the index
|
102
109
|
is currently undefined, invokes the didRequestIndex() method to notify
|
@@ -115,6 +122,37 @@ SC.SparseArray = SC.Object.extend(SC.Observable, SC.Enumerable, SC.Array,
|
|
115
122
|
return ret ;
|
116
123
|
},
|
117
124
|
|
125
|
+
/**
|
126
|
+
Returns the set of indexes that are currently defined on the sparse array.
|
127
|
+
If you pass an optional index set, the search will be limited to only
|
128
|
+
those indexes. Otherwise this method will return an index set containing
|
129
|
+
all of the defined indexes. Currently this can be quite expensive if
|
130
|
+
you have a lot of indexes defined.
|
131
|
+
|
132
|
+
@param {SC.IndexSet} indexes optional from indexes
|
133
|
+
@returns {SC.IndexSet} defined indexes
|
134
|
+
*/
|
135
|
+
definedIndexes: function(indexes) {
|
136
|
+
var ret = SC.IndexSet.create(),
|
137
|
+
content = this._sa_content,
|
138
|
+
idx, len;
|
139
|
+
|
140
|
+
if (!content) return ret.freeze(); // nothing to do
|
141
|
+
|
142
|
+
if (indexes) {
|
143
|
+
indexes.forEach(function(idx) {
|
144
|
+
if (content[idx] !== undefined) ret.add(idx);
|
145
|
+
});
|
146
|
+
} else {
|
147
|
+
len = content.length;
|
148
|
+
for(idx=0;idx<len;idx++) {
|
149
|
+
if (content[idx] !== undefined) ret.add(idx);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
return ret.freeze();
|
154
|
+
},
|
155
|
+
|
118
156
|
_TMP_RANGE: {},
|
119
157
|
|
120
158
|
/**
|
@@ -122,6 +160,8 @@ SC.SparseArray = SC.Object.extend(SC.Observable, SC.Enumerable, SC.Array,
|
|
122
160
|
loaded. This will possibly expand the index into a range and then invoke
|
123
161
|
an appropriate method on the delegate to request the data.
|
124
162
|
|
163
|
+
It will check if the range has been already requested.
|
164
|
+
|
125
165
|
@param {SC.SparseArray} receiver
|
126
166
|
*/
|
127
167
|
requestIndex: function(idx) {
|
@@ -130,17 +170,19 @@ SC.SparseArray = SC.Object.extend(SC.Observable, SC.Enumerable, SC.Array,
|
|
130
170
|
|
131
171
|
// adjust window
|
132
172
|
var len = this.get('rangeWindowSize'), start = idx;
|
133
|
-
if (len > 1) start = Math.floor(start
|
173
|
+
if (len > 1) start = start - Math.floor(start % len);
|
134
174
|
if (len < 1) len = 1 ;
|
135
175
|
|
136
176
|
// invoke appropriate callback
|
137
177
|
this._requestingIndex++;
|
138
178
|
if (del.sparseArrayDidRequestRange) {
|
139
179
|
var range = this._TMP_RANGE;
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
180
|
+
if(this.wasRangeRequested(start)===-1){
|
181
|
+
range.start = start;
|
182
|
+
range.length = len;
|
183
|
+
del.sparseArrayDidRequestRange(this, range);
|
184
|
+
this.requestedRangeIndex.push(start);
|
185
|
+
}
|
144
186
|
} else if (del.sparseArrayDidRequestIndex) {
|
145
187
|
while(--len >= 0) del.sparseArrayDidRequestIndex(this, start + len);
|
146
188
|
}
|
@@ -149,6 +191,38 @@ SC.SparseArray = SC.Object.extend(SC.Observable, SC.Enumerable, SC.Array,
|
|
149
191
|
return this ;
|
150
192
|
},
|
151
193
|
|
194
|
+
/*
|
195
|
+
This method is called by requestIndex to check if the range has already
|
196
|
+
been requested. We assume that rangeWindowSize is not changed often.
|
197
|
+
|
198
|
+
@param {Number} startIndex
|
199
|
+
@return {Number} index in requestRangeIndex
|
200
|
+
*/
|
201
|
+
wasRangeRequested: function(rangeStart) {
|
202
|
+
var i, ilen;
|
203
|
+
for(i=0, ilen=this.requestedRangeIndex.length; i<ilen; i++){
|
204
|
+
if(this.requestedRangeIndex[i]===rangeStart) return i;
|
205
|
+
}
|
206
|
+
return -1;
|
207
|
+
},
|
208
|
+
|
209
|
+
/*
|
210
|
+
This method has to be called after a request for a range has completed.
|
211
|
+
To remove the index from the sparseArray to allow future updates on the
|
212
|
+
range.
|
213
|
+
|
214
|
+
@param {Number} startIndex
|
215
|
+
@return {Number} index in requestRangeIndex
|
216
|
+
*/
|
217
|
+
rangeRequestCompleted: function(start) {
|
218
|
+
var i = this.wasRangeRequested(start);
|
219
|
+
if(i>=0) {
|
220
|
+
this.requestedRangeIndex.removeAt(i,1);
|
221
|
+
return YES;
|
222
|
+
}
|
223
|
+
return NO;
|
224
|
+
},
|
225
|
+
|
152
226
|
/**
|
153
227
|
This method sets the content for the specified to the objects in the
|
154
228
|
passed array. If you change the way SparseArray implements its internal
|
@@ -98,7 +98,7 @@ module("Real Array & DummyEnumerable", {
|
|
98
98
|
},
|
99
99
|
|
100
100
|
teardown: function() {
|
101
|
-
delete enumerables
|
101
|
+
delete enumerables;
|
102
102
|
delete Array.prototype["@max(balance)"] ; // remove cached value
|
103
103
|
delete Array.prototype["@min(balance)"] ;
|
104
104
|
}
|
@@ -153,7 +153,7 @@ test("should run forEach() to go through objects", function() {
|
|
153
153
|
}, this);
|
154
154
|
|
155
155
|
var len = src.get('length') ;
|
156
|
-
for(
|
156
|
+
for(idx=0;idx<len;idx++) {
|
157
157
|
equals(items[idx], src.objectAt(idx)) ;
|
158
158
|
equals(indexes[idx], idx) ;
|
159
159
|
equals(arrays[idx], src) ;
|
@@ -187,7 +187,7 @@ test("should map to values while passing proper params", function() {
|
|
187
187
|
}, this);
|
188
188
|
|
189
189
|
var len = src.get('length') ;
|
190
|
-
for(
|
190
|
+
for(idx=0;idx<len;idx++) {
|
191
191
|
equals(src.objectAt(idx), items[idx], "items") ;
|
192
192
|
equals(idx, indexes[idx], "indexes") ;
|
193
193
|
equals(src, arrays[idx], 'arrays') ;
|
@@ -220,7 +220,7 @@ test("should filter to items that return for callback", function() {
|
|
220
220
|
}, this);
|
221
221
|
|
222
222
|
var len = src.get('length') ;
|
223
|
-
for(
|
223
|
+
for(idx=0;idx<len;idx++) {
|
224
224
|
equals(src.objectAt(idx), items[idx], "items") ;
|
225
225
|
equals(idx, indexes[idx], "indexes") ;
|
226
226
|
equals(src, arrays[idx], 'arrays') ;
|
@@ -254,7 +254,7 @@ test("should return true if function for every() returns true", function() {
|
|
254
254
|
}, this);
|
255
255
|
|
256
256
|
var len = src.get('length') ;
|
257
|
-
for(
|
257
|
+
for(idx=0;idx<len;idx++) {
|
258
258
|
equals(src.objectAt(idx), items[idx], "items") ;
|
259
259
|
equals(idx, indexes[idx], "indexes") ;
|
260
260
|
equals(src, arrays[idx], 'arrays') ;
|
@@ -298,7 +298,7 @@ test("should return false if all functions for some() returns false", function()
|
|
298
298
|
}, this);
|
299
299
|
|
300
300
|
var len = src.get('length') ;
|
301
|
-
for(
|
301
|
+
for(idx=0;idx<len;idx++) {
|
302
302
|
equals(src.objectAt(idx), items[idx], "items") ;
|
303
303
|
equals(idx, indexes[idx], "indexes") ;
|
304
304
|
equals(src, arrays[idx], 'arrays') ;
|
@@ -84,6 +84,59 @@ test("element to be added is at idx > length of array ", function() {
|
|
84
84
|
});
|
85
85
|
|
86
86
|
|
87
|
+
test("Check that requestIndex works with a rangeWindowSize larger than 1", function() {
|
88
|
+
var ary = SC.SparseArray.array(10) ;
|
89
|
+
var didRequestRange=NO;
|
90
|
+
|
91
|
+
var DummyDelegate = SC.Object.extend({
|
92
|
+
content: [], // source array
|
93
|
+
|
94
|
+
sparseArrayDidRequestLength: function(sparseArray) {
|
95
|
+
sparseArray.provideLength(this.content.length);
|
96
|
+
},
|
97
|
+
|
98
|
+
sparseArrayDidRequestIndex: function(sparseArray, index) {
|
99
|
+
sparseArray.provideObjectAtIndex(index, this.content[index]);
|
100
|
+
},
|
101
|
+
|
102
|
+
sparseArrayDidRequestIndexOf: function(sparseArray, object) {
|
103
|
+
return this.content.indexOf(object);
|
104
|
+
},
|
105
|
+
|
106
|
+
sparseArrayShouldReplace: function(sparseArray, idx, amt, objects) {
|
107
|
+
this.content.replace(idx, amt, objects) ; // keep internal up-to-date
|
108
|
+
return YES ; // allow anything
|
109
|
+
},
|
110
|
+
sparseArrayDidRequestRange: function(sparseArray, range) {
|
111
|
+
didRequestRange=YES;
|
112
|
+
}
|
113
|
+
|
114
|
+
});
|
115
|
+
ary.set('delegate', DummyDelegate.create());
|
116
|
+
ary.set('rangeWindowSize', 4);
|
117
|
+
equals(10, ary.get('length'), "length") ;
|
118
|
+
ary.objectAt(7);
|
119
|
+
equals(didRequestRange, YES, "The range was requested") ;
|
120
|
+
});
|
121
|
+
|
122
|
+
|
123
|
+
// ..........................................................
|
124
|
+
// definedIndexes
|
125
|
+
//
|
126
|
+
|
127
|
+
test("definedIndexes", function() {
|
128
|
+
var ary = SC.SparseArray.array(10);
|
129
|
+
ary.provideObjectAtIndex(5, "foo");
|
130
|
+
|
131
|
+
var expected = SC.IndexSet.create().add(5);
|
132
|
+
same(ary.definedIndexes(), expected, 'definedIndexes() should return all defined indexes');
|
133
|
+
|
134
|
+
same(ary.definedIndexes(SC.IndexSet.create().add(2, 10)), expected, 'definedIndexes([2..11]) should return indexes within');
|
135
|
+
|
136
|
+
same(ary.definedIndexes(SC.IndexSet.create().add(2)), SC.IndexSet.EMPTY, 'definedIndexes([2]) should return empty set (since does not overlap with defined index)');
|
137
|
+
|
138
|
+
});
|
139
|
+
|
87
140
|
// ..........................................................
|
88
141
|
// TEST SC.ARRAY COMPLIANCE
|
89
142
|
//
|
@@ -226,6 +226,10 @@ CoreTest.Plan = {
|
|
226
226
|
@returns {CoreTest.Plan} receiver
|
227
227
|
*/
|
228
228
|
module: function(desc, lifecycle) {
|
229
|
+
if (typeof SC !== 'undefined' && SC.filename) {
|
230
|
+
desc = SC.filename.replace(/^.+?\/current\/tests\//,'') + '\n' + desc;
|
231
|
+
}
|
232
|
+
|
229
233
|
this.currentModule = desc;
|
230
234
|
|
231
235
|
if (!lifecycle) lifecycle = {};
|
@@ -141,7 +141,7 @@ CoreTest.Runner = {
|
|
141
141
|
for(idx=0;idx<len;idx++) s[assertions[idx].result]++;
|
142
142
|
if ((s.failed + s.errors + s.warnings) === 0) clean = "clean" ;
|
143
143
|
|
144
|
-
if (module) name = module + " module: " + test ;
|
144
|
+
if (module) name = module.replace(/\n/g, '<br />') + " module: " + test ;
|
145
145
|
name = CoreTest.fmt('%@ - %@msec', name, timings.total_end - timings.total_begin);
|
146
146
|
// place results into a single string to append all at once.
|
147
147
|
var logstr = this.logstr ;
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# ==========================================================================
|
2
|
+
# Generator: Controller
|
3
|
+
# Copyright: ©2006-2009 Sprout Systems, Inc. and contributors
|
4
|
+
# portions copyright ©2009 Apple, Inc.
|
5
|
+
# ==========================================================================
|
6
|
+
|
7
|
+
namespace :generator do
|
8
|
+
|
9
|
+
# - Verify required properties are present
|
10
|
+
# - Accept second argument as base class
|
11
|
+
# - If file name end in "_design" strip it off.
|
12
|
+
# - Make sure filename ends in _page.
|
13
|
+
task :prepare do
|
14
|
+
GENERATOR.requires! :target_project, :target, :namespace, :class_name
|
15
|
+
GENERATOR.base_class_name ||= GENERATOR.arguments[2]
|
16
|
+
|
17
|
+
filename = GENERATOR.filename.sub(/_design$/,'')
|
18
|
+
filename = "#{filename}_page" unless filename =~ /_page$/
|
19
|
+
GENERATOR.filename = filename
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/gen/design/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Your design is now ready to use!
|
data/gen/design/USAGE
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
design - Create a new page design for your SproutCore app.
|
2
|
+
|
3
|
+
USAGE:
|
4
|
+
|
5
|
+
sc-gen design AppName.designName [--filename=FILENAME] [--target=TARGET_NAME]
|
6
|
+
|
7
|
+
DISCUSSION:
|
8
|
+
|
9
|
+
This generator will create a new SproutCore page design, similar to the main_page design that comes with all new apps.
|
10
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: <%= namespace_instance_name %>
|
3
|
+
// Copyright: ©<%= Time.now.year %> My Company, Inc.
|
4
|
+
// ==========================================================================
|
5
|
+
/*globals <%= namespace %> */
|
6
|
+
|
7
|
+
// This page describes a part of the interface for your application.
|
8
|
+
<%= namespace_instance_name %> = SC.Page.design({
|
9
|
+
|
10
|
+
// Add your views here. Ex:
|
11
|
+
|
12
|
+
// mainView: SC.View.design({
|
13
|
+
// layout: { top: 0, left: 0, right: 0, height: 0 }
|
14
|
+
// })
|
15
|
+
|
16
|
+
});
|
data/gen/page/Buildfile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# ==========================================================================
|
2
|
+
# Generator: APP
|
3
|
+
# Copyright: ©2006-2009 Sprout Systems, Inc. and contributors
|
4
|
+
# portions copyright ©2009 Apple, Inc.
|
5
|
+
# ==========================================================================
|
6
|
+
|
7
|
+
namespace :generator do
|
8
|
+
|
9
|
+
# Require a project then make sure the build root is always the project
|
10
|
+
# root.
|
11
|
+
task :prepare do
|
12
|
+
GENERATOR.requires! :target_project
|
13
|
+
|
14
|
+
# if the target name has a slash in it, then we are trying to create a
|
15
|
+
# nested target. extract the final part (since this is the target name)
|
16
|
+
# and then set the build root to the parent target.
|
17
|
+
if GENERATOR.target_name && GENERATOR.target_name =~ /\//
|
18
|
+
parent_target_name = GENERATOR.target_name.split('/')
|
19
|
+
GENERATOR.target_name = parent_target_name.pop
|
20
|
+
|
21
|
+
parent_target_name = parent_target_name * "/"
|
22
|
+
project = GENERATOR.target_project
|
23
|
+
|
24
|
+
GENERATOR.parent_target_name = parent_target_name
|
25
|
+
GENERATOR.parent_target = project.target_for(parent_target_name)
|
26
|
+
GENERATOR.requires! :parent_target, :parent_target_name
|
27
|
+
|
28
|
+
GENERATOR.build_root = GENERATOR.parent_target.source_root
|
29
|
+
|
30
|
+
# otherwise just use project_root
|
31
|
+
else
|
32
|
+
GENERATOR.build_root = GENERATOR.target_project.project_root
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/gen/page/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Your page target is now ready to use!
|
data/gen/page/USAGE
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
page - Create a new SproutCore page target.
|
2
|
+
|
3
|
+
USAGE:
|
4
|
+
|
5
|
+
sc-gen page PageName [--filename=FILENAME] [--target=TARGET_NAME]
|
6
|
+
|
7
|
+
DISCUSSION:
|
8
|
+
|
9
|
+
*IMPORTANT:* This generator does not create a page design (e.g. main_page.js) in an app. Use "sc-gen design" instead.
|
10
|
+
|
11
|
+
This generator will create a new SproutCore page for a particular project. A page is much like an app but you will often place primarily static content here. You should pass as the first parameter your PageName you want to create. For example:
|
12
|
+
|
13
|
+
sc-gen page NotFound
|
14
|
+
|
15
|
+
defines a new page called NotFound in the file pages/not_found/.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# ==========================================================================
|
2
|
+
# Project: <%= namespace %> Buildfile
|
3
|
+
# Copyright: ©<%= Time.now.year %> My Company, Inc.
|
4
|
+
# ==========================================================================
|
5
|
+
|
6
|
+
# You can use to buildfile to add a custom page title, set environment
|
7
|
+
# variables, and require any specific JavaScript or other libraries you want
|
8
|
+
# to use.
|
9
|
+
#
|
10
|
+
# The default configuration just sets the page title and also requires
|
11
|
+
# SproutCore-Mini (a smaller version of SproutCore)
|
12
|
+
#
|
13
|
+
config :<%= target_name %>,
|
14
|
+
:required => ['sproutcore/mini'],
|
15
|
+
:title => '<%= target_name.split('_').map { |x| x.capitalize }.join(" ") %>'
|
16
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: <%= namespace %>
|
3
|
+
// Copyright: ©<%= Time.now.year %> My Company, Inc.
|
4
|
+
// ==========================================================================
|
5
|
+
/*globals <%= namespace %> */
|
6
|
+
|
7
|
+
/** @namespace
|
8
|
+
|
9
|
+
Static page JavaScript
|
10
|
+
|
11
|
+
@extends SC.Object
|
12
|
+
*/
|
13
|
+
<%= namespace %> = SC.Object.create(
|
14
|
+
/** @scope <%= namespace %>.prototype */ {
|
15
|
+
|
16
|
+
NAMESPACE: '<%= namespace %>',
|
17
|
+
VERSION: '0.1.0'
|
18
|
+
|
19
|
+
// TODO: You can place any JavaScript you need on your page here. If you
|
20
|
+
// don't want any JavaScript, just delete this file.
|
21
|
+
|
22
|
+
}) ;
|
@@ -0,0 +1 @@
|
|
1
|
+
/* Add any extra CSS for this page here. You can also add other CSS files if you want */
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: <%= namespace %> Strings
|
3
|
+
// Copyright: ©<%= Time.now.year %> My Company, Inc.
|
4
|
+
// ==========================================================================
|
5
|
+
/*globals <%= namespace %> */
|
6
|
+
|
7
|
+
// Place strings you want to localize here. In your app, use the key and
|
8
|
+
// localize it using "key string".loc(). HINT: For your key names, use the
|
9
|
+
// english string with an underscore in front. This way you can still see
|
10
|
+
// how your UI will look and you'll notice right away when something needs a
|
11
|
+
// localized string added to this file!
|
12
|
+
//
|
13
|
+
SC.stringsFor('English', {
|
14
|
+
// "_String Key": "Localized String"
|
15
|
+
}) ;
|
data/gen/view/README
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Your
|
1
|
+
Your view is now ready to use!
|
data/gen/view/USAGE
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
view - Create a new view class in your SproutCore app.
|
2
2
|
|
3
3
|
USAGE:
|
4
4
|
|
5
|
-
sc-gen
|
5
|
+
sc-gen view AppName.NewView [--filename=FILENAME] [--target=TARGET_NAME]
|
6
6
|
|
7
7
|
DISCUSSION:
|
8
8
|
|
9
|
-
This generator will create a new SproutCore
|
9
|
+
This generator will create a new SproutCore view in your app. You should pass as the first parameter your AppName.NewView combination you want to create. For example:
|
10
10
|
|
11
|
-
sc-gen
|
11
|
+
sc-gen view Todos.TaskView
|
12
12
|
|
13
|
-
defines a new class called Todos.
|
13
|
+
defines a new class called Todos.TaskView in the file apps/todos/views/task.js .
|
@@ -61,9 +61,20 @@ module SC
|
|
61
61
|
|
62
62
|
# Handles occurances of sc_static() or static_url()
|
63
63
|
def replace_static_url(line)
|
64
|
-
line.gsub(/(sc_static|static_url)\(\s*['"](.+)['"]\s*\)/) do | rsrc |
|
64
|
+
line.gsub(/(sc_static|static_url|sc_target)\(\s*['"](.+)['"]\s*\)/) do | rsrc |
|
65
|
+
entry_name = $2
|
66
|
+
entry_name = "#{$2}:index.html" if $1 == 'sc_target'
|
65
67
|
static_entry = entry.manifest.find_entry($2)
|
66
|
-
|
68
|
+
|
69
|
+
if static_entry.nil?
|
70
|
+
url = ''
|
71
|
+
elsif $1 == 'sc_target'
|
72
|
+
url = static_entry.friendly_url || static_entry.cacheable_url
|
73
|
+
else
|
74
|
+
url = static_entry.cacheable_url
|
75
|
+
end
|
76
|
+
|
77
|
+
static_url(url)
|
67
78
|
end
|
68
79
|
end
|
69
80
|
|