sproutcore 0.9.0
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 +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +269 -0
- data/README.txt +67 -0
- data/Rakefile +4 -0
- data/app_generators/sproutcore/USAGE +5 -0
- data/app_generators/sproutcore/sproutcore_generator.rb +66 -0
- data/app_generators/sproutcore/templates/README +77 -0
- data/app_generators/sproutcore/templates/environment.yml +4 -0
- data/bin/sc-build +145 -0
- data/bin/sc-gen +24 -0
- data/bin/sc-server +63 -0
- data/bin/sproutcore +21 -0
- data/clients/sc_docs/controllers/docs.js +118 -0
- data/clients/sc_docs/core.js +19 -0
- data/clients/sc_docs/english.lproj/body.css +159 -0
- data/clients/sc_docs/english.lproj/body.rhtml +33 -0
- data/clients/sc_docs/english.lproj/controls.css +0 -0
- data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
- data/clients/sc_docs/english.lproj/images/indicator.gif +0 -0
- data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_docs/english.lproj/no_docs.rhtml +7 -0
- data/clients/sc_docs/english.lproj/strings.js +14 -0
- data/clients/sc_docs/english.lproj/warning.rhtml +6 -0
- data/clients/sc_docs/fixtures/doc.js +11 -0
- data/clients/sc_docs/main.js +21 -0
- data/clients/sc_docs/models/doc.js +9 -0
- data/clients/sc_docs/tests/controllers/docs.rhtml +21 -0
- data/clients/sc_docs/tests/models/doc.rhtml +21 -0
- data/clients/sc_docs/tests/views/doc_frame.rhtml +21 -0
- data/clients/sc_docs/tests/views/doc_label_view.rhtml +21 -0
- data/clients/sc_docs/views/doc_frame.js +33 -0
- data/clients/sc_docs/views/doc_label.js +20 -0
- data/clients/sc_test_runner/controllers/runner.js +175 -0
- data/clients/sc_test_runner/core.js +19 -0
- data/clients/sc_test_runner/english.lproj/body.css +151 -0
- data/clients/sc_test_runner/english.lproj/body.rhtml +35 -0
- data/clients/sc_test_runner/english.lproj/controls.css +0 -0
- data/clients/sc_test_runner/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_test_runner/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_test_runner/english.lproj/images/gradients.png +0 -0
- data/clients/sc_test_runner/english.lproj/images/indicator.gif +0 -0
- data/clients/sc_test_runner/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_test_runner/english.lproj/no_tests.rhtml +6 -0
- data/clients/sc_test_runner/english.lproj/strings.js +14 -0
- data/clients/sc_test_runner/english.lproj/warning.rhtml +6 -0
- data/clients/sc_test_runner/fixtures/test.js +12 -0
- data/clients/sc_test_runner/main.js +26 -0
- data/clients/sc_test_runner/models/test.js +11 -0
- data/clients/sc_test_runner/views/runner_frame.js +72 -0
- data/clients/sc_test_runner/views/test_label.js +20 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/environment.yml +9 -0
- data/frameworks/prototype/prototype.js +4186 -0
- data/frameworks/sproutcore/Core.js +378 -0
- data/frameworks/sproutcore/README +3 -0
- data/frameworks/sproutcore/controllers/array.js +236 -0
- data/frameworks/sproutcore/controllers/collection.js +305 -0
- data/frameworks/sproutcore/controllers/controller.js +323 -0
- data/frameworks/sproutcore/controllers/object.js +372 -0
- data/frameworks/sproutcore/drag/drag.js +549 -0
- data/frameworks/sproutcore/drag/drag_data_source.js +32 -0
- data/frameworks/sproutcore/drag/drag_source.js +64 -0
- data/frameworks/sproutcore/drag/drop_target.js +153 -0
- data/frameworks/sproutcore/english.lproj/blank.gif +0 -0
- data/frameworks/sproutcore/english.lproj/buttons.css +589 -0
- data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
- data/frameworks/sproutcore/english.lproj/inline_text_editor.css +21 -0
- data/frameworks/sproutcore/english.lproj/menu.css +121 -0
- data/frameworks/sproutcore/english.lproj/panels/background-fat.jpg +0 -0
- data/frameworks/sproutcore/english.lproj/panels/background-thin.jpg +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-left-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-right-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/left-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/overlay.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/right-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-left-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-right-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panes.css +155 -0
- data/frameworks/sproutcore/english.lproj/picker.css +22 -0
- data/frameworks/sproutcore/english.lproj/strings.js +15 -0
- data/frameworks/sproutcore/english.lproj/tab.css +23 -0
- data/frameworks/sproutcore/english.lproj/tests.css +67 -0
- data/frameworks/sproutcore/english.lproj/theme.css +77 -0
- data/frameworks/sproutcore/foundation/animator.js +670 -0
- data/frameworks/sproutcore/foundation/application.js +199 -0
- data/frameworks/sproutcore/foundation/array.js +348 -0
- data/frameworks/sproutcore/foundation/benchmark.js +211 -0
- data/frameworks/sproutcore/foundation/binding.js +384 -0
- data/frameworks/sproutcore/foundation/date.js +357 -0
- data/frameworks/sproutcore/foundation/error.js +39 -0
- data/frameworks/sproutcore/foundation/input_manager.js +153 -0
- data/frameworks/sproutcore/foundation/json.js +296 -0
- data/frameworks/sproutcore/foundation/mock.js +42 -0
- data/frameworks/sproutcore/foundation/node_descriptor.js +56 -0
- data/frameworks/sproutcore/foundation/object.js +777 -0
- data/frameworks/sproutcore/foundation/observable.js +451 -0
- data/frameworks/sproutcore/foundation/page.js +63 -0
- data/frameworks/sproutcore/foundation/path_module.js +413 -0
- data/frameworks/sproutcore/foundation/responder.js +310 -0
- data/frameworks/sproutcore/foundation/routes.js +371 -0
- data/frameworks/sproutcore/foundation/run_loop.js +21 -0
- data/frameworks/sproutcore/foundation/server.js +491 -0
- data/frameworks/sproutcore/foundation/set.js +96 -0
- data/frameworks/sproutcore/foundation/string.js +149 -0
- data/frameworks/sproutcore/foundation/undo_manager.js +186 -0
- data/frameworks/sproutcore/foundation/unittest.js +622 -0
- data/frameworks/sproutcore/foundation/utils.js +61 -0
- data/frameworks/sproutcore/globals/panels.js +182 -0
- data/frameworks/sproutcore/globals/popups.js +60 -0
- data/frameworks/sproutcore/globals/window.js +381 -0
- data/frameworks/sproutcore/lib/index.rhtml +66 -0
- data/frameworks/sproutcore/models/collection.js +395 -0
- data/frameworks/sproutcore/models/record.js +622 -0
- data/frameworks/sproutcore/models/store.js +295 -0
- data/frameworks/sproutcore/panes/dialog.js +16 -0
- data/frameworks/sproutcore/panes/manager.js +164 -0
- data/frameworks/sproutcore/panes/menu.js +45 -0
- data/frameworks/sproutcore/panes/overlay.js +231 -0
- data/frameworks/sproutcore/panes/pane.js +90 -0
- data/frameworks/sproutcore/panes/panel.js +19 -0
- data/frameworks/sproutcore/panes/picker.js +45 -0
- data/frameworks/sproutcore/tests/controllers/array.rhtml +86 -0
- data/frameworks/sproutcore/tests/controllers/controller.rhtml +273 -0
- data/frameworks/sproutcore/tests/controllers/object.rhtml +327 -0
- data/frameworks/sproutcore/tests/foundation/application.rhtml +125 -0
- data/frameworks/sproutcore/tests/foundation/array.rhtml +221 -0
- data/frameworks/sproutcore/tests/foundation/object.rhtml +69 -0
- data/frameworks/sproutcore/tests/globals/window.rhtml +45 -0
- data/frameworks/sproutcore/tests/panes/pane.rhtml +88 -0
- data/frameworks/sproutcore/tests/views/collection.rhtml +137 -0
- data/frameworks/sproutcore/tests/views/popup_button.rhtml +115 -0
- data/frameworks/sproutcore/tests/views/text_field.rhtml +37 -0
- data/frameworks/sproutcore/validators/credit_card.js +92 -0
- data/frameworks/sproutcore/validators/date.js +36 -0
- data/frameworks/sproutcore/validators/email.js +29 -0
- data/frameworks/sproutcore/validators/not_empty.js +24 -0
- data/frameworks/sproutcore/validators/number.js +55 -0
- data/frameworks/sproutcore/validators/password.js +78 -0
- data/frameworks/sproutcore/validators/validator.js +304 -0
- data/frameworks/sproutcore/views/button.js +425 -0
- data/frameworks/sproutcore/views/checkbox_field.js +30 -0
- data/frameworks/sproutcore/views/collection.js +1521 -0
- data/frameworks/sproutcore/views/container.js +62 -0
- data/frameworks/sproutcore/views/error_explanation.js +45 -0
- data/frameworks/sproutcore/views/field.js +214 -0
- data/frameworks/sproutcore/views/filter_button.js +29 -0
- data/frameworks/sproutcore/views/form.js +591 -0
- data/frameworks/sproutcore/views/image.js +141 -0
- data/frameworks/sproutcore/views/inline_text_editor.js +96 -0
- data/frameworks/sproutcore/views/label.js +176 -0
- data/frameworks/sproutcore/views/menu_item.js +90 -0
- data/frameworks/sproutcore/views/pagination.js +54 -0
- data/frameworks/sproutcore/views/popup_button.js +86 -0
- data/frameworks/sproutcore/views/popup_menu.js +137 -0
- data/frameworks/sproutcore/views/progress.js +100 -0
- data/frameworks/sproutcore/views/radio_field.js +107 -0
- data/frameworks/sproutcore/views/radio_group.js +48 -0
- data/frameworks/sproutcore/views/segmented.js +80 -0
- data/frameworks/sproutcore/views/select_field.js +272 -0
- data/frameworks/sproutcore/views/spinner.js +11 -0
- data/frameworks/sproutcore/views/tab.js +126 -0
- data/frameworks/sproutcore/views/text_field.js +179 -0
- data/frameworks/sproutcore/views/textarea_field.js +14 -0
- data/frameworks/sproutcore/views/toolbar.js +29 -0
- data/frameworks/sproutcore/views/view.js +1389 -0
- data/frameworks/sproutcore/views/workspace.js +170 -0
- data/generators/client/README +3 -0
- data/generators/client/USAGE +12 -0
- data/generators/client/client_generator.rb +53 -0
- data/generators/client/templates/core.js +19 -0
- data/generators/client/templates/english.lproj/body.css +0 -0
- data/generators/client/templates/english.lproj/body.rhtml +3 -0
- data/generators/client/templates/english.lproj/controls.css +0 -0
- data/generators/client/templates/english.lproj/strings.js +14 -0
- data/generators/client/templates/main.js +37 -0
- data/generators/controller/USAGE +16 -0
- data/generators/controller/controller_generator.rb +51 -0
- data/generators/controller/templates/controller.js +21 -0
- data/generators/controller/templates/test.rhtml +21 -0
- data/generators/framework/README +7 -0
- data/generators/framework/USAGE +12 -0
- data/generators/framework/framework_generator.rb +53 -0
- data/generators/framework/templates/core.js +20 -0
- data/generators/framework/templates/english.lproj/body.css +0 -0
- data/generators/framework/templates/english.lproj/body.rhtml +3 -0
- data/generators/framework/templates/english.lproj/controls.css +0 -0
- data/generators/framework/templates/english.lproj/strings.js +14 -0
- data/generators/language/USAGE +16 -0
- data/generators/language/language_generator.rb +47 -0
- data/generators/language/templates/strings.js +10 -0
- data/generators/model/USAGE +24 -0
- data/generators/model/model_generator.rb +55 -0
- data/generators/model/templates/fixture.js +11 -0
- data/generators/model/templates/model.js +20 -0
- data/generators/model/templates/test.rhtml +21 -0
- data/generators/test/USAGE +16 -0
- data/generators/test/templates/test.rhtml +21 -0
- data/generators/test/test_generator.rb +47 -0
- data/generators/view/USAGE +16 -0
- data/generators/view/templates/test.rhtml +21 -0
- data/generators/view/templates/view.js +20 -0
- data/generators/view/view_generator.rb +51 -0
- data/jsdoc/README.txt +119 -0
- data/jsdoc/app/DocFile.js +137 -0
- data/jsdoc/app/DocTag.js +110 -0
- data/jsdoc/app/Doclet.js +63 -0
- data/jsdoc/app/Dumper.js +143 -0
- data/jsdoc/app/JsDoc.js +103 -0
- data/jsdoc/app/JsHilite.js +45 -0
- data/jsdoc/app/JsIO.js +163 -0
- data/jsdoc/app/JsParse.js +385 -0
- data/jsdoc/app/JsPlate.js +130 -0
- data/jsdoc/app/JsTestrun.js +129 -0
- data/jsdoc/app/JsToke.js +564 -0
- data/jsdoc/app/Symbol.js +298 -0
- data/jsdoc/app/Transformer.js +14 -0
- data/jsdoc/app/Util.js +97 -0
- data/jsdoc/app/js.jar +0 -0
- data/jsdoc/app/run.js +144 -0
- data/jsdoc/plugins/min.js +316 -0
- data/jsdoc/plugins/strip.js +20 -0
- data/jsdoc/templates/sproutcore/class.tmpl +438 -0
- data/jsdoc/templates/sproutcore/default.css +241 -0
- data/jsdoc/templates/sproutcore/index.html +13 -0
- data/jsdoc/templates/sproutcore/index.tmpl +21 -0
- data/jsdoc/templates/sproutcore/prototype.js +4186 -0
- data/jsdoc/templates/sproutcore/publish.js +236 -0
- data/jsdoc/templates/sproutcore/splash.html +7 -0
- data/lib/sproutcore/build_tools/html_builder.rb +88 -0
- data/lib/sproutcore/build_tools/resource_builder.rb +194 -0
- data/lib/sproutcore/build_tools.rb +44 -0
- data/lib/sproutcore/bundle.rb +517 -0
- data/lib/sproutcore/bundle_manifest.rb +397 -0
- data/lib/sproutcore/generator_helper.rb +170 -0
- data/lib/sproutcore/helpers/capture_helper.rb +42 -0
- data/lib/sproutcore/helpers/static_helper.rb +80 -0
- data/lib/sproutcore/helpers/tag_helper.rb +110 -0
- data/lib/sproutcore/helpers/text_helper.rb +336 -0
- data/lib/sproutcore/helpers.rb +3 -0
- data/lib/sproutcore/jsdoc.rb +40 -0
- data/lib/sproutcore/jsmin.rb +247 -0
- data/lib/sproutcore/library.rb +258 -0
- data/lib/sproutcore/merb/bundle_controller.rb +179 -0
- data/lib/sproutcore/merb/router.rb +43 -0
- data/lib/sproutcore/merb.rb +27 -0
- data/lib/sproutcore/version.rb +9 -0
- data/lib/sproutcore/view_helpers/button_views.rb +302 -0
- data/lib/sproutcore/view_helpers/core_views.rb +284 -0
- data/lib/sproutcore/view_helpers/form_views.rb +258 -0
- data/lib/sproutcore/view_helpers/menu_views.rb +94 -0
- data/lib/sproutcore/view_helpers.rb +628 -0
- data/lib/sproutcore.rb +30 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/sproutcore_spec.rb +11 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- metadata +365 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('models/record') ;
|
|
7
|
+
require('models/store') ;
|
|
8
|
+
|
|
9
|
+
// A collection holds a set of records matching the specified conditions. You
|
|
10
|
+
// can set the data source used to find the objects matching the conditions
|
|
11
|
+
// to create collections pulled from the local set of objects or pulled
|
|
12
|
+
// from the server.
|
|
13
|
+
//
|
|
14
|
+
// Collection's automatically update their contents based on the conditions
|
|
15
|
+
// settings you provide as the state of loaded records change.
|
|
16
|
+
//
|
|
17
|
+
SC.Collection = SC.Object.extend({
|
|
18
|
+
|
|
19
|
+
// ........................................
|
|
20
|
+
// CONFIGURABLE PROPERTIES
|
|
21
|
+
//
|
|
22
|
+
// Set these properties to control the records that will be in this list.
|
|
23
|
+
|
|
24
|
+
// indicates the keys to use to order the records. If you want the records
|
|
25
|
+
// ordered by descending order, use a string like 'guid DESC'.
|
|
26
|
+
orderBy: ['guid'],
|
|
27
|
+
|
|
28
|
+
// set this to the range of records you are interested in seeing or null if
|
|
29
|
+
// you want to see all records. Note that collection actually retrieves
|
|
30
|
+
// a list of records slightly larger than what you pass here to allow for
|
|
31
|
+
// members to be added and removed.
|
|
32
|
+
offset: 0, limit: 0,
|
|
33
|
+
|
|
34
|
+
// set this to a hash with conditions options. e.g. { active: true }. If you
|
|
35
|
+
// don't set this property, then all records of the given type will be
|
|
36
|
+
// used.
|
|
37
|
+
conditions: {},
|
|
38
|
+
|
|
39
|
+
// this is the actual array of records in the current collection. This
|
|
40
|
+
// property will change anytime the record members change (but not when
|
|
41
|
+
// the member record properties change)
|
|
42
|
+
records: function() {
|
|
43
|
+
if (this._changedRecords) this._flushChangedRecords() ;
|
|
44
|
+
return this._records ;
|
|
45
|
+
}.property(),
|
|
46
|
+
|
|
47
|
+
// the total count of records matching the conditions settings. The contents
|
|
48
|
+
// of the records array will be clipped to the range value.
|
|
49
|
+
count: function(key, value) {
|
|
50
|
+
if (value !== undefined) {
|
|
51
|
+
this._count = value ;
|
|
52
|
+
} else if (this._changedRecords) this._flushChangedRecords() ;
|
|
53
|
+
return this._count || 0 ;
|
|
54
|
+
}.property(),
|
|
55
|
+
|
|
56
|
+
// set to true when the collection is destroyed
|
|
57
|
+
isDeleted: false, // RO
|
|
58
|
+
|
|
59
|
+
// set this to the data source you want to use to get the records. Use
|
|
60
|
+
// either SC.Store or SC.Server. If you use SC.Server, your recordType
|
|
61
|
+
// must have a resourceURL property. // NC
|
|
62
|
+
dataSource: SC.Store,
|
|
63
|
+
|
|
64
|
+
// set this to the type of record you want in the collection. This should
|
|
65
|
+
// be set when the collection is created and not changed later.
|
|
66
|
+
recordType: SC.Record, // NC
|
|
67
|
+
|
|
68
|
+
// set to true while a refresh is in progress.
|
|
69
|
+
isLoading: false, // RO
|
|
70
|
+
|
|
71
|
+
// set to true if records have changed in a way that might leave the records out
|
|
72
|
+
// of date.
|
|
73
|
+
isDirty: false, // RO
|
|
74
|
+
|
|
75
|
+
// ........................................
|
|
76
|
+
// ACTIONS
|
|
77
|
+
//
|
|
78
|
+
|
|
79
|
+
// call this to force the list to refresh. The refresh may not happen
|
|
80
|
+
// right away, depending on the dataSource.
|
|
81
|
+
refresh: function() {
|
|
82
|
+
var recordType = this.get('recordType') || SC.Record ;
|
|
83
|
+
var offset = (this._limit > 0) ? this._offset : 0 ;
|
|
84
|
+
|
|
85
|
+
if (!this._boundRefreshFunc) {
|
|
86
|
+
this._boundRefreshFunc = this._refreshDidComplete.bind(this) ;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// start refresh
|
|
90
|
+
if (!this.dataSource) throw "collection does not have dataSource" ;
|
|
91
|
+
this.beginPropertyChanges();
|
|
92
|
+
if (!this.isLoading) this.set('isLoading',true) ;
|
|
93
|
+
this._refreshing = true ;
|
|
94
|
+
|
|
95
|
+
var order = this.get('orderBy') ;
|
|
96
|
+
if (order && !(order instanceof Array)) order = [order] ;
|
|
97
|
+
this.dataSource.listFor({
|
|
98
|
+
recordType: recordType,
|
|
99
|
+
offset: offset,
|
|
100
|
+
limit: this._limit,
|
|
101
|
+
conditions: this.get('conditions'),
|
|
102
|
+
order: order,
|
|
103
|
+
callback: this._boundRefreshFunc,
|
|
104
|
+
cacheCode: this._cacheCode
|
|
105
|
+
}) ;
|
|
106
|
+
this.endPropertyChanges() ;
|
|
107
|
+
return this;
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
// call this method when you are done with a collection. This will remove
|
|
111
|
+
// it as an observer to changes in the SC.Store so that it can be reclaimed.
|
|
112
|
+
// isDeleted will also be set to true.
|
|
113
|
+
destroy: function() { SC.Store.removeCollection(this); return this; },
|
|
114
|
+
|
|
115
|
+
newRecord: function(settings) {
|
|
116
|
+
if (!settings) settings = {} ;
|
|
117
|
+
settings.newRecord = true ;
|
|
118
|
+
settings.dataSource = this.get('dataSource') ;
|
|
119
|
+
var ret = this.recordType.create(settings);
|
|
120
|
+
SC.Store.addRecord(ret) ; // this will add the record to the collection.
|
|
121
|
+
return ret;
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
// ........................................
|
|
125
|
+
// INTERNAL
|
|
126
|
+
//
|
|
127
|
+
|
|
128
|
+
// this is the real offset, limit, and records used by the collection.
|
|
129
|
+
// this can be a superset of the actual limits seen by outsiders.
|
|
130
|
+
_offset: 0, _limit: 0, _records: null, _members: null, _store: null,
|
|
131
|
+
|
|
132
|
+
init: function() {
|
|
133
|
+
arguments.callee.base.call(this) ;
|
|
134
|
+
SC.Store.addCollection(this) ; // get notified of changes.
|
|
135
|
+
this._computeInteralOffsetAndLimit() ;
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
// This is the callback executed when the data source has found the records
|
|
139
|
+
// matching the passed parameters. The count is the total count of records
|
|
140
|
+
// matching the conditions, ignoring the offset and limit.
|
|
141
|
+
_refreshDidComplete: function(records,count,cacheCode) {
|
|
142
|
+
if (cacheCode) this._cacheCode = cacheCode;
|
|
143
|
+
|
|
144
|
+
if (records) {
|
|
145
|
+
this.beginPropertyChanges() ;
|
|
146
|
+
|
|
147
|
+
// update count
|
|
148
|
+
if (this.get('count') != count) this.set('count',count) ;
|
|
149
|
+
|
|
150
|
+
// update the record store and reslice.
|
|
151
|
+
this.propertyWillChange('records') ;
|
|
152
|
+
records = this._store = records.slice() ;
|
|
153
|
+
this._reslice() ;
|
|
154
|
+
this.propertyDidChange('records') ;
|
|
155
|
+
|
|
156
|
+
this.endPropertyChanges();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
this._refreshing = false ; // only one refresh at a time.
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// called by SC.Store whenever an locally stored record has changed state.
|
|
163
|
+
// This method simply indicates that the records property has changed and saved
|
|
164
|
+
// the record for later processing.
|
|
165
|
+
recordDidChange: function(rec) {
|
|
166
|
+
if (!rec && !rec._guid) return ; // probably an error, but recover anyway.
|
|
167
|
+
if (!this._changedRecords) this._changedRecords = {} ;
|
|
168
|
+
this._changedRecords[rec._guid] = rec ;
|
|
169
|
+
this.propertyWillChange('records') ;
|
|
170
|
+
this.propertyDidChange('records') ;
|
|
171
|
+
this.propertyWillChange('count') ;
|
|
172
|
+
this.propertyDidChange('count') ;
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
// this method gets called just before the records property is returned. If
|
|
176
|
+
// there are any changed records queued up, the record changes will be
|
|
177
|
+
// integrated.
|
|
178
|
+
_flushChangedRecords: function() {
|
|
179
|
+
if (!this._changedRecords) return ; // nothing to do.
|
|
180
|
+
|
|
181
|
+
if (this.dataSource != SC.Store) throw "non-local data source is not supported"
|
|
182
|
+
|
|
183
|
+
var current = this._store || [] ;
|
|
184
|
+
var order = this.get('orderBy') || [this.recordType.primaryKey()] ;
|
|
185
|
+
if (!(order instanceof Array)) order = [order] ;
|
|
186
|
+
var conditions = this.get('conditions') ;
|
|
187
|
+
|
|
188
|
+
// get the sorted set of changed records, both sorted and as a hash.
|
|
189
|
+
var records = [] ;
|
|
190
|
+
var changed = this._changedRecords ;
|
|
191
|
+
for(var guid in changed) {
|
|
192
|
+
if (!changed.hasOwnProperty(guid)) continue ;
|
|
193
|
+
records.push(changed[guid]) ;
|
|
194
|
+
}
|
|
195
|
+
records = records.sort(function(a,b){ return a.compareTo(b,order); }) ;
|
|
196
|
+
this._changedRecords = null ;
|
|
197
|
+
|
|
198
|
+
// step through the current set of records. Interpolate changed records, remove records
|
|
199
|
+
// that don't belong.
|
|
200
|
+
var loc = 0 ;
|
|
201
|
+
while(loc < current.length) {
|
|
202
|
+
var working = current[loc] ;
|
|
203
|
+
var compareToPrev, compareToNext ;
|
|
204
|
+
|
|
205
|
+
// is this record one of the changed?
|
|
206
|
+
// if so, then the record may need to be removed from its current position if it is deleted,
|
|
207
|
+
// no longer belongs to the group, or is out of order.
|
|
208
|
+
if (changed[working._guid]) {
|
|
209
|
+
|
|
210
|
+
var belongs = (!working.get('isDeleted')) && working.matchConditions(conditions) ;
|
|
211
|
+
if (belongs) {
|
|
212
|
+
|
|
213
|
+
// comes after prev?
|
|
214
|
+
if (loc>0) {
|
|
215
|
+
belongs = (working.compareTo(current[loc-1],order) >= 0) ;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// comes before next?
|
|
219
|
+
if (belongs && (loc+1 < current.length)) {
|
|
220
|
+
belongs = (working.compareTo(current[loc+1],order) <= 0) ;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (!belongs) { current.splice(loc,1); continue; }
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// if we get here, then the current record belongs where it is. next see if any of the changed
|
|
227
|
+
// records need to be inserted here.
|
|
228
|
+
var goAgain = true ;
|
|
229
|
+
while ((records.length > 0) && goAgain) {
|
|
230
|
+
var rec = records[0] ;
|
|
231
|
+
if ((rec != working) && !rec.get('isDeleted') && rec.matchConditions(conditions)) {
|
|
232
|
+
if ((rec == working) || (rec.compareTo(working,order) <= 0)) {
|
|
233
|
+
if (rec != working) current.splice(loc,0,rec) ; // insert only if not the same.
|
|
234
|
+
loc++ ;
|
|
235
|
+
} else goAgain = false ;
|
|
236
|
+
}
|
|
237
|
+
if (goAgain) records.shift() ;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// move on to the next record.
|
|
241
|
+
loc++ ;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// if we get to the end and there are changed records left to process,
|
|
245
|
+
// they probably need to be added.
|
|
246
|
+
while(records.length > 0) {
|
|
247
|
+
var rec = records.shift() ;
|
|
248
|
+
if (!rec.get('isDeleted') && rec.matchConditions(conditions)) {
|
|
249
|
+
current.push(rec) ;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// if ((this == window.tphotos) && (current.length != this._count)) debugger ;
|
|
254
|
+
|
|
255
|
+
// update the count as well.
|
|
256
|
+
this._store = current ;
|
|
257
|
+
this._count = current.length ;
|
|
258
|
+
this._reslice() ;
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
/// SAVED FOR POSTERITY
|
|
262
|
+
_oldRecordsDidChange: function() {
|
|
263
|
+
var state = ((!rec.isDeleted) && rec.matchConditions(this.get('conditions'))) ? 'in' : 'out';
|
|
264
|
+
var records = this._records ;
|
|
265
|
+
|
|
266
|
+
// see if this comes before or after
|
|
267
|
+
if ((this._limit > 0) && (state == "in") && records && (records.length > 0)) {
|
|
268
|
+
var order = this.get('orderBy') ;
|
|
269
|
+
if (rec.compareTo(records[0],order) < 0) {
|
|
270
|
+
state = "before" ;
|
|
271
|
+
} else if (rec.compareTo(records[records.length-1],order) > 0) {
|
|
272
|
+
state = "after" ;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// does this currently belong to the collection.
|
|
277
|
+
var belongs = records.include(rec) ;
|
|
278
|
+
var reslice = false ; var refresh = false ;
|
|
279
|
+
|
|
280
|
+
// now adjust appropriately
|
|
281
|
+
switch(state) {
|
|
282
|
+
case 'before':
|
|
283
|
+
// note: this is technically incorrect. If the record comes before
|
|
284
|
+
// that might actually shift everything forward. But there is no
|
|
285
|
+
// way to really tell if the rec is just now being added or not.
|
|
286
|
+
//
|
|
287
|
+
// We let this go since this will only be temporarily wrong as the
|
|
288
|
+
// list will get refreshed.
|
|
289
|
+
//
|
|
290
|
+
if (belongs) { records = records.without(rec) ; reslice = true; }
|
|
291
|
+
refresh = true ;
|
|
292
|
+
break ;
|
|
293
|
+
|
|
294
|
+
case 'after':
|
|
295
|
+
case 'out':
|
|
296
|
+
if (belongs) {
|
|
297
|
+
records = records.without(rec) ;
|
|
298
|
+
reslice = refresh = true ;
|
|
299
|
+
}
|
|
300
|
+
break ;
|
|
301
|
+
|
|
302
|
+
case 'in':
|
|
303
|
+
// resort records
|
|
304
|
+
if (!belongs) {
|
|
305
|
+
records = records.slice();
|
|
306
|
+
records.push(rec) ;
|
|
307
|
+
}
|
|
308
|
+
records = records.sort(function(a,b){ return a.compareTo(b,order); });
|
|
309
|
+
if (!records.isEqual(this._records)) reslice = refresh = true ;
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (reslice) {
|
|
314
|
+
this._records = records ;
|
|
315
|
+
if (this._limit > 0) {
|
|
316
|
+
var start = this.get('offset') - this._offset ;
|
|
317
|
+
var end = start + this.get('limit') ;
|
|
318
|
+
records = records.slice(start,end) ;
|
|
319
|
+
}
|
|
320
|
+
this.set('records',records) ;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
//if (refresh && !this._refreshing) {
|
|
324
|
+
// this._refreshing = true ; var that = this ;
|
|
325
|
+
// setTimeout(function() { that.refresh(); },1) ;
|
|
326
|
+
//}
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
// Anytime the properties used to filter the collection change, reslice if possible
|
|
330
|
+
// then refresh from the data source.
|
|
331
|
+
propertyObserver: function(observing,target,key,value) {
|
|
332
|
+
if (target != this) return ;
|
|
333
|
+
|
|
334
|
+
// update the internal properties then refresh.
|
|
335
|
+
var needsRefresh = false ;
|
|
336
|
+
var nv ;
|
|
337
|
+
value = this.get(key) ;
|
|
338
|
+
switch(key) {
|
|
339
|
+
case 'offset':
|
|
340
|
+
case 'limit':
|
|
341
|
+
var oldOffset = this._offset ;
|
|
342
|
+
var oldLimit = this._limit ;
|
|
343
|
+
this._computeInteralOffsetAndLimit() ;
|
|
344
|
+
if ((this._offset == oldOffset) && (this._limit == oldLimit)) {
|
|
345
|
+
this.propertyWillChange('records') ;
|
|
346
|
+
this._reslice();
|
|
347
|
+
this.propertyDidChange('records') ;
|
|
348
|
+
} else needsRefresh = true ;
|
|
349
|
+
break ;
|
|
350
|
+
|
|
351
|
+
case 'conditions':
|
|
352
|
+
case 'orderBy':
|
|
353
|
+
needsRefresh = true ;
|
|
354
|
+
break ;
|
|
355
|
+
|
|
356
|
+
default:
|
|
357
|
+
break ;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// refresh only once per loop. We don't want to refresh multiple times
|
|
361
|
+
// if the user makes changes to multiple settings.
|
|
362
|
+
if (needsRefresh && !this._refreshing) {
|
|
363
|
+
this._refreshing = true ;
|
|
364
|
+
this._cacheCode = null ;
|
|
365
|
+
this.set('isLoading',true) ;
|
|
366
|
+
setTimeout(this.refresh.bind(this),1);
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
|
|
370
|
+
// using the current offset and limit properties, compute the internal offset and limit used for
|
|
371
|
+
// records.
|
|
372
|
+
_computeInteralOffsetAndLimit: function() {
|
|
373
|
+
if (this.dataSource != SC.Store) {
|
|
374
|
+
var v ;
|
|
375
|
+
this._offset = ((v=this.get('offset')) > this.MARGIN) ? (v-this.MARGIN) : 0 ;
|
|
376
|
+
this._limit = ((v=this.get('limit')) > 0) ? (v + this.MARGIN) : 0 ;
|
|
377
|
+
} else this._offset = this._limit = 0 ;
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
// This method will slice the _store records based on the current offset and limit.
|
|
381
|
+
// Is it used internally and thus does not indicate that the computed records
|
|
382
|
+
// property has changed.
|
|
383
|
+
_reslice: function() {
|
|
384
|
+
var offset = this.get('offset') ;
|
|
385
|
+
var limit = this.get('limit') ;
|
|
386
|
+
if ((offset > 0) || (limit > 0)) {
|
|
387
|
+
var start = offset - this._offset ;
|
|
388
|
+
var end = start + ((limit <= 0) ? (this._store || []).length : limit) ;
|
|
389
|
+
this._records = this._store.slice(start,end) ;
|
|
390
|
+
} else this._records = this._store ;
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
MARGIN: 10
|
|
394
|
+
|
|
395
|
+
}) ;
|