sproutit-sproutcore 1.0.20090721145281 → 1.0.20090721145282

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.
Files changed (105) hide show
  1. data/Buildfile +4 -3
  2. data/VERSION.yml +2 -2
  3. data/buildtasks/entry.rake +3 -0
  4. data/buildtasks/manifest.rake +35 -9
  5. data/buildtasks/target.rake +25 -6
  6. data/frameworks/sproutcore/Buildfile +10 -0
  7. data/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +41 -20
  8. data/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +14 -43
  9. data/frameworks/sproutcore/frameworks/datastore/models/record.js +11 -0
  10. data/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +6 -3
  11. data/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +5 -1
  12. data/frameworks/sproutcore/frameworks/datastore/system/query.js +10 -7
  13. data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +19 -20
  14. data/frameworks/sproutcore/frameworks/datastore/system/store.js +126 -93
  15. data/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +9 -3
  16. data/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +6 -1
  17. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/core_methods.js +28 -3
  18. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +13 -5
  19. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/storeDidChangeProperties.js +46 -23
  20. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +29 -5
  21. data/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +13 -4
  22. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/chain.js +109 -0
  23. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +69 -15
  24. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +20 -1
  25. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/dataHashDidChange.js +4 -1
  26. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/find_all.js +56 -6
  27. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +9 -2
  28. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/core_methods.js +45 -2
  29. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/recordDidChange.js +0 -1
  30. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/retrieveRecord.js +53 -6
  31. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/writeDataHash.js +0 -5
  32. data/frameworks/sproutcore/frameworks/desktop/panes/menu.js +47 -27
  33. data/frameworks/sproutcore/frameworks/desktop/system/drag.js +5 -4
  34. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +23 -12
  35. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/render.js +92 -0
  36. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +104 -53
  37. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +2 -0
  38. data/frameworks/sproutcore/frameworks/desktop/views/button.js +4 -3
  39. data/frameworks/sproutcore/frameworks/desktop/views/collection.js +6 -2
  40. data/frameworks/sproutcore/frameworks/desktop/views/list.js +9 -0
  41. data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +2 -2
  42. data/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +3 -3
  43. data/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +9 -1
  44. data/frameworks/sproutcore/frameworks/desktop/views/select_field.js +80 -102
  45. data/frameworks/sproutcore/frameworks/foundation/controllers/array.js +0 -1
  46. data/frameworks/sproutcore/frameworks/foundation/english.lproj/text_field.css +5 -1
  47. data/frameworks/sproutcore/frameworks/foundation/panes/pane.js +8 -1
  48. data/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +0 -1
  49. data/frameworks/sproutcore/frameworks/foundation/system/datetime.js +31 -3
  50. data/frameworks/sproutcore/frameworks/foundation/system/event.js +0 -4
  51. data/frameworks/sproutcore/frameworks/foundation/system/render_context.js +3 -7
  52. data/frameworks/sproutcore/frameworks/foundation/system/request.js +3 -4
  53. data/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +78 -17
  54. data/frameworks/sproutcore/frameworks/foundation/system/utils.js +9 -0
  55. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/single_case.js +2 -2
  56. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_selector.js +2 -2
  57. data/frameworks/sproutcore/frameworks/foundation/tests/system/datetime.js +5 -0
  58. data/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +2 -2
  59. data/frameworks/sproutcore/frameworks/foundation/tests/system/user_defaults.js +1 -4
  60. data/frameworks/sproutcore/frameworks/foundation/tests/validators/validator.js +20 -0
  61. data/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +13 -0
  62. data/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +132 -0
  63. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/isVisibleInWindow.js +6 -3
  64. data/frameworks/sproutcore/frameworks/foundation/validators/validator.js +8 -5
  65. data/frameworks/sproutcore/frameworks/foundation/views/image.js +18 -5
  66. data/frameworks/sproutcore/frameworks/foundation/views/text_field.js +292 -21
  67. data/frameworks/sproutcore/frameworks/foundation/views/view.js +13 -14
  68. data/frameworks/sproutcore/frameworks/mini/license.js +28 -0
  69. data/frameworks/sproutcore/frameworks/runtime/core.js +35 -0
  70. data/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1 -1
  71. data/frameworks/sproutcore/frameworks/runtime/system/sparse_array.js +79 -5
  72. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable.js +6 -6
  73. data/frameworks/sproutcore/frameworks/runtime/tests/system/sparse_array.js +53 -0
  74. data/frameworks/sproutcore/frameworks/testing/system/plan.js +4 -0
  75. data/frameworks/sproutcore/frameworks/testing/system/runner.js +1 -1
  76. data/frameworks/sproutcore/themes/standard_theme/english.lproj/radio.css +4 -0
  77. data/gen/design/Buildfile +23 -0
  78. data/gen/design/README +1 -0
  79. data/gen/design/USAGE +10 -0
  80. data/gen/design/templates/english.lproj/@filename@.js +16 -0
  81. data/gen/page/Buildfile +36 -0
  82. data/gen/page/README +1 -0
  83. data/gen/page/USAGE +15 -0
  84. data/gen/page/templates/pages/@target_name@/Buildfile +16 -0
  85. data/gen/page/templates/pages/@target_name@/core.js +22 -0
  86. data/gen/page/templates/pages/@target_name@/english.lproj/body.css +1 -0
  87. data/gen/page/templates/pages/@target_name@/english.lproj/body.rhtml +7 -0
  88. data/gen/page/templates/pages/@target_name@/english.lproj/strings.js +15 -0
  89. data/gen/view/README +1 -1
  90. data/gen/view/USAGE +5 -5
  91. data/lib/sproutcore/builders/base.rb +13 -2
  92. data/lib/sproutcore/builders/html.rb +28 -1
  93. data/lib/sproutcore/builders/minify.rb +84 -18
  94. data/lib/sproutcore/builders/test.rb +2 -1
  95. data/lib/sproutcore/helpers/entry_sorter.rb +16 -1
  96. data/lib/sproutcore/helpers/static_helper.rb +32 -4
  97. data/lib/sproutcore/helpers/tag_helper.rb +65 -0
  98. data/lib/sproutcore/models/manifest.rb +40 -6
  99. data/lib/sproutcore/models/target.rb +12 -3
  100. data/lib/sproutcore/rack/builder.rb +56 -4
  101. data/lib/sproutcore/tools/manifest.rb +1 -0
  102. data/lib/sproutcore/tools/server.rb +1 -0
  103. data/lib/sproutcore/tools.rb +21 -1
  104. data/lib/sproutcore.rb +13 -0
  105. metadata +16 -1
data/Buildfile CHANGED
@@ -17,9 +17,10 @@ mode :all do
17
17
  # REQUIRED CONFIGS
18
18
  # You will not usually need to override these configs, but the code
19
19
  # assumes they will be present, so you must support them.
20
- :build_prefix => 'tmp/build',
20
+ :build_prefix => 'tmp/build',
21
21
  :staging_prefix => 'tmp/staging',
22
- :url_prefix => 'static',
22
+ :cache_prefix => 'tmp/cache',
23
+ :url_prefix => 'static',
23
24
 
24
25
  # Defines the directories that may contain targets, and maps them to a
25
26
  # target type. When a project tries to find all of the targets in a
@@ -27,6 +28,7 @@ mode :all do
27
28
  :target_types => {
28
29
  :apps => :app,
29
30
  :clients => :app,
31
+ :pages => :app, # used for static pages with your site
30
32
  :frameworks => :framework,
31
33
  :themes => :theme
32
34
  },
@@ -111,7 +113,6 @@ mode :debug do
111
113
  # Do not pack javascripts in development mode, we want each file to
112
114
  # load independently.
113
115
  :use_packed => false
114
-
115
116
  end
116
117
 
117
118
 
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :minor: 0
3
- :patch: 20090721145281
4
- :digest: ba83b210ad765939b203da70844f9799493ef006
3
+ :patch: 20090721145282
4
+ :digest: 8d4f830b015e13e58d53e304b9cf421117d5c456
5
5
  :major: 1
@@ -53,6 +53,9 @@ namespace :entry do
53
53
  else
54
54
  ENTRY.staging_path ||= MANIFEST.unique_staging_path(File.join(MANIFEST.staging_root, filename_parts))
55
55
  end
56
+
57
+ ENTRY.cache_path = MANIFEST.unique_cache_path(File.join(MANIFEST.cache_root, filename_parts))
58
+
56
59
  end
57
60
 
58
61
  end
@@ -22,6 +22,10 @@ namespace :manifest do
22
22
  MANIFEST.staging_root = File.join(TARGET.staging_root,
23
23
  MANIFEST.language.to_s, TARGET.build_number.to_s)
24
24
 
25
+ # cache_root is target.cache_root + language + build_number
26
+ MANIFEST.cache_root = File.join(TARGET.cache_root,
27
+ MANIFEST.language.to_s, TARGET.build_number.to_s)
28
+
25
29
  # url_root
26
30
  MANIFEST.url_root =
27
31
  [TARGET.url_root, MANIFEST.language, TARGET.build_number].join('/')
@@ -369,7 +373,7 @@ namespace :manifest do
369
373
  entries.each do |entry|
370
374
  entry.entry_type = :html
371
375
  entry.resource = 'index'
372
-
376
+
373
377
  entry.render_task = case entry.ext
374
378
  when 'rhtml':
375
379
  'render:erubis'
@@ -379,13 +383,21 @@ namespace :manifest do
379
383
  'render:haml'
380
384
  end
381
385
 
382
- # use a custom scan method since discover_build_directives! is too
383
- # general...
384
-
385
- entry.scan_source(/<%\s*sc_resource\(?\s*['"](.+)['"]\s*\)?/) do |m|
386
- entry.resource = m[0].ext ''
386
+ # items beginning with an underscore are partials. do not build
387
+ if entry.filename =~ /^_/
388
+ entry.hide!
389
+ entry.is_partial = true
390
+
391
+ # not a partial
392
+ else
393
+ # use a custom scan method since discover_build_directives! is too
394
+ # general...
395
+ entry.scan_source(/<%\s*sc_resource\(?\s*['"](.+)['"]\s*\)?/) do |m|
396
+ entry.resource = m[0].ext ''
397
+ end
398
+ (entries_by_resource[entry.resource] ||= []) << entry
387
399
  end
388
- (entries_by_resource[entry.resource] ||= []) << entry
400
+
389
401
  end
390
402
 
391
403
  # even if no resource was found for the index.html, add one anyway if
@@ -398,13 +410,27 @@ namespace :manifest do
398
410
  entries_by_resource.each do |resource_name, entries|
399
411
  resource_name = resource_name.ext('html')
400
412
  is_index = resource_name == 'index.html'
413
+
414
+ # compute the friendly_url assuming normal install process
415
+ friendly_url = [TARGET.index_root]
416
+ m_language = MANIFEST.language.to_sym
417
+ t_preferred = (TARGET.config.preferred_language || :en).to_sym
418
+ if is_index
419
+ friendly_url << m_language.to_s unless t_preferred == m_language
420
+ else
421
+ friendly_url << m_language.to_s
422
+ friendly_url << resource_name
423
+ end
424
+ friendly_url = friendly_url.join('/')
425
+
401
426
  MANIFEST.add_composite resource_name,
402
427
  :entry_type => :html,
403
428
  :combined => true,
404
429
  :build_task => 'build:html',
405
430
  :source_entries => entries,
406
431
  :hidden => !TARGET.loadable? && is_index,
407
- :include_required_targets => TARGET.loadable? && is_index
432
+ :include_required_targets => TARGET.loadable? && is_index,
433
+ :friendly_url => friendly_url
408
434
  end
409
435
  end
410
436
 
@@ -444,7 +470,7 @@ namespace :manifest do
444
470
  desc "adds a loc strings entry that generates a yaml file server-side functions can use"
445
471
  task :strings => %w(setup javascript) do
446
472
  # find the lproj/strings.js file...
447
- if entry = MANIFEST.entry_for('source/lproj/strings.js')
473
+ if entry = (MANIFEST.entry_for('source/lproj/strings.js') || MANIFEST.entry_for('source/lproj/strings.js', :hidden => true))
448
474
  MANIFEST.add_transform entry,
449
475
  :filename => 'strings.yaml',
450
476
  :build_path => File.join(MANIFEST.build_root, 'strings.yaml'),
@@ -13,24 +13,43 @@ namespace :target do
13
13
  task :prepare do
14
14
 
15
15
  # use url_root config or merge url_prefix + target_name
16
- TARGET.url_root = CONFIG.url_root ||
17
- [nil, CONFIG.url_prefix, TARGET.target_name].join('/').gsub(/\/+/,'/')
16
+ if (TARGET.url_root = CONFIG.url_root).nil?
17
+ url = [nil, CONFIG.url_prefix, TARGET.target_name].join('/')
18
+ url = url.gsub(/([^:])\/+/,'\1/').gsub(/^\/+/,'/') # remove extra //
19
+ url = url[1..-1] if url.match(/^\/[^\/]+:\/\//) # look for protocol
20
+ TARGET.url_root = url
21
+ end
22
+
18
23
 
19
24
  # use index_root config or merge index_prefix + target_name
20
- TARGET.index_root = CONFIG.index_root ||
21
- [nil, CONFIG.index_prefix, TARGET.target_name].join('/').gsub(/\/+/, '/')
25
+ if (TARGET.index_root = CONFIG.index_root).nil?
26
+ url = [nil, CONFIG.index_prefix, TARGET.target_name].join('/')
27
+ url = url.gsub(/([^:])\/+/,'\1/').gsub(/^\/+/,'/') # remove extra //
28
+ url = url[1..-1] if url.match(/^\/[^\/]+:\/\//) # look for protocol
29
+ TARGET.index_root = url
30
+ end
22
31
 
32
+ url_prefix = CONFIG.url_prefix
33
+ url_prefix = url_prefix.gsub(/^[^\/]+:\/\/[^\/]+\//,'') if url_prefix
34
+
23
35
  # Split all of these paths in case we are on windows...
24
36
  TARGET.build_root = File.expand_path(CONFIG.build_root ||
25
37
  File.join(PROJECT.project_root.to_s,
26
38
  (CONFIG.build_prefix || '').to_s.split('/'),
27
- (CONFIG.url_prefix || '').to_s.split('/'),
39
+ (url_prefix || '').to_s.split('/'),
28
40
  TARGET.target_name.to_s.split('/')))
29
41
 
30
42
  TARGET.staging_root = File.expand_path(CONFIG.staging_root ||
31
43
  File.join(PROJECT.project_root.to_s,
32
44
  (CONFIG.staging_prefix || '').to_s.split('/'),
33
- (CONFIG.url_prefix || '').to_s.split('/'),
45
+ (url_prefix || '').to_s.split('/'),
46
+ TARGET.target_name.to_s))
47
+
48
+ # cache is used to store intermediate files
49
+ TARGET.cache_root = File.expand_path(CONFIG.cache_root ||
50
+ File.join(PROJECT.project_root.to_s,
51
+ (CONFIG.cache_prefix || '').to_s.split('/'),
52
+ (url_prefix || '').to_s.split('/'),
34
53
  TARGET.target_name.to_s))
35
54
 
36
55
  TARGET.build_number = TARGET.compute_build_number
@@ -14,6 +14,15 @@ config :all,
14
14
  :test_required => ['sproutcore/testing', 'sproutcore/empty_theme'],
15
15
  :debug_required => ['sproutcore/debug', 'sproutcore/testing']
16
16
 
17
+ # in debug mode, combine the JS for SC by default. This will improve perf
18
+ # while working with apps. If you are hacking SC itself, you can turn this
19
+ # off in your project buildfile by referencing sproutcore specifically
20
+ mode :debug do
21
+ config :all,
22
+ :combine_javascript => true,
23
+ :combine_stylesheet => true
24
+ end
25
+
17
26
  # CORE FRAMEWORKS
18
27
  config :runtime, :required => []
19
28
  config :foundation, :required => [:runtime]
@@ -30,6 +39,7 @@ config :mobile,
30
39
 
31
40
  # WRAPPER FRAMEWORKS
32
41
  config :sproutcore, :required => :desktop
42
+ config :mini, :required => [:runtime, :datastore]
33
43
 
34
44
  # SPECIAL FRAMEWORKS AND THEMES
35
45
  # These do not require any of the built-in SproutCore frameworks
@@ -56,7 +56,8 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
56
56
  SC.Record or SC.Record.STORE_KEYS if invoked from store.retrieveRecords.
57
57
  Could also be an SC.Query if that was passed in to findAll()
58
58
  @param {Hash} params optional additonal fetch params. storeKeys if invoked
59
- from store.retrieveRecords
59
+ from store.retrieveRecords. this originated from the commitRecords()
60
+ call on the store
60
61
  @returns {SC.Array} result set with storeKeys. In case of SC.Array
61
62
  it may be sparse.
62
63
  */
@@ -70,11 +71,13 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
70
71
  @param {SC.Store} store the requesting store
71
72
  @param {Array} storeKeys
72
73
  @param {Array} ids - optional
74
+ @param {Hash} params to be passed down to data source. originated
75
+ from the commitRecords() call on the store
73
76
  @returns
74
77
  */
75
78
 
76
- retrieveRecords: function(store, storeKeys, ids) {
77
- return this._handleEach(store, storeKeys, this.retrieveRecord, ids);
79
+ retrieveRecords: function(store, storeKeys, ids, params) {
80
+ return this._handleEach(store, storeKeys, this.retrieveRecord, ids, params);
78
81
  },
79
82
 
80
83
  /**
@@ -102,13 +105,15 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
102
105
  @param {Array} createStoreKeys keys to create
103
106
  @param {Array} updateStoreKeys keys to update
104
107
  @param {Array} destroyStoreKeys keys to destroy
108
+ @param {Hash} params to be passed down to data source. originated
109
+ from the commitRecords() call on the store
105
110
  @returns {Boolean} YES if data source can handle keys
106
111
  */
107
- commitRecords: function(store, createStoreKeys, updateStoreKeys, destroyStoreKeys) {
112
+ commitRecords: function(store, createStoreKeys, updateStoreKeys, destroyStoreKeys, params) {
108
113
  var cret, uret, dret;
109
- if(createStoreKeys.length>0) cret = this.createRecords.call(this, store, createStoreKeys);
110
- if(updateStoreKeys.length>0) uret = this.updateRecords.call(this, store, updateStoreKeys);
111
- if(destroyStoreKeys.length>0) dret = this.destroyRecords.call(this, store, destroyStoreKeys);
114
+ if(createStoreKeys.length>0) cret = this.createRecords.call(this, store, createStoreKeys, params);
115
+ if(updateStoreKeys.length>0) uret = this.updateRecords.call(this, store, updateStoreKeys, params);
116
+ if(destroyStoreKeys.length>0) dret = this.destroyRecords.call(this, store, destroyStoreKeys, params);
112
117
  return (cret === uret === dret) ? (cret || uret || dret) : SC.MIXED_STATE ;
113
118
  },
114
119
 
@@ -149,9 +154,11 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
149
154
 
150
155
  @param {SC.Store} store the requesting store
151
156
  @param {Array} storeKeys keys to update
157
+ @param {Hash} params to be passed down to data source. originated
158
+ from the commitRecords() call on the store
152
159
  */
153
- updateRecords: function(store, storeKeys) {
154
- return this._handleEach(store, storeKeys, this.updateRecord);
160
+ updateRecords: function(store, storeKeys, params) {
161
+ return this._handleEach(store, storeKeys, this.updateRecord, null, params);
155
162
  },
156
163
 
157
164
  /**
@@ -166,9 +173,11 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
166
173
 
167
174
  @param {SC.Store} store the requesting store
168
175
  @param {Array} storeKeys keys to update
176
+ @param {Hash} params to be passed down to data source. originated
177
+ from the commitRecords() call on the store
169
178
  */
170
- createRecords: function(store, storeKeys) {
171
- return this._handleEach(store, storeKeys, this.createRecord);
179
+ createRecords: function(store, storeKeys, params) {
180
+ return this._handleEach(store, storeKeys, this.createRecord, null, params);
172
181
  },
173
182
 
174
183
  /**
@@ -183,20 +192,24 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
183
192
 
184
193
  @param {SC.Store} store the requesting store
185
194
  @param {Array} storeKeys keys to update
195
+ @param {Hash} params to be passed down to data source. originated
196
+ from the commitRecords() call on the store
186
197
  */
187
- destroyRecords: function(store, storeKeys) {
188
- return this._handleEach(store, storeKeys, this.destroyRecord);
198
+ destroyRecords: function(store, storeKeys, params) {
199
+ return this._handleEach(store, storeKeys, this.destroyRecord, null, params);
189
200
  },
190
201
 
191
202
  /** @private
192
203
  invokes the named action for each store key. returns proper value
193
204
  */
194
- _handleEach: function(store, storeKeys, action, ids) {
195
- var len = storeKeys.length, idx, ret, cur;
205
+ _handleEach: function(store, storeKeys, action, ids, params) {
206
+ var len = storeKeys.length, idx, ret, cur, lastArg;
196
207
  if(!ids) ids = [];
197
208
 
198
209
  for(idx=0;idx<len;idx++) {
199
- cur = action.call(this, store, storeKeys[idx], ids[idx]);
210
+ lastArg = ids[idx] ? ids[idx] : params;
211
+
212
+ cur = action.call(this, store, storeKeys[idx], lastArg, params);
200
213
  if (ret === undefined) {
201
214
  ret = cur ;
202
215
  } else if (ret === YES) {
@@ -222,9 +235,11 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
222
235
 
223
236
  @param {SC.Store} store the requesting store
224
237
  @param {Array} storeKey key to update
238
+ @param {Hash} params to be passed down to data source. originated
239
+ from the commitRecords() call on the store
225
240
  @returns {Boolean} YES if handled
226
241
  */
227
- updateRecord: function(store, storeKey) {
242
+ updateRecord: function(store, storeKey, params) {
228
243
  return NO ;
229
244
  },
230
245
 
@@ -234,9 +249,11 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
234
249
  @param {SC.Store} store the requesting store
235
250
  @param {Array} storeKey key to retrieve
236
251
  @param {String} id the id to retrieve
252
+ @param {Hash} params to be passed down to data source. originated
253
+ from the commitRecords() call on the store
237
254
  @returns {Boolean} YES if handled
238
255
  */
239
- retrieveRecord: function(store, storeKey, id) {
256
+ retrieveRecord: function(store, storeKey, id, params) {
240
257
  return NO ;
241
258
  },
242
259
 
@@ -249,9 +266,11 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
249
266
 
250
267
  @param {SC.Store} store the requesting store
251
268
  @param {Array} storeKey key to update
269
+ @param {Hash} params to be passed down to data source. originated
270
+ from the commitRecords() call on the store
252
271
  @returns {Boolean} YES if handled
253
272
  */
254
- createRecord: function(store, storeKey) {
273
+ createRecord: function(store, storeKey, params) {
255
274
  return NO ;
256
275
  },
257
276
 
@@ -264,9 +283,11 @@ SC.DataSource = SC.Object.extend( /** SC.DataSource.prototype */ {
264
283
 
265
284
  @param {SC.Store} store the requesting store
266
285
  @param {Array} storeKey key to update
286
+ @param {Hash} params to be passed down to data source. originated
287
+ from the commitRecords() call on the store
267
288
  @returns {Boolean} YES if handled
268
289
  */
269
- destroyRecord: function(store, storeKey) {
290
+ destroyRecord: function(store, storeKey, params) {
270
291
  return NO ;
271
292
  }
272
293
 
@@ -86,52 +86,17 @@ SC.FixturesDataSource = SC.DataSource.extend( {
86
86
 
87
87
  },
88
88
 
89
- /**
90
- Load fixtures for a given fetchKey into the store
91
- and push it to the ret array.
92
-
93
- @param {SC.Store} store
94
- @param {SC.Record} fetchKey
95
- @param {SC.Array} ret
96
- */
97
- loadFixturesFor: function(store, fetchKey, ret) {
98
- var dataHashes, i, storeKey, hashes = [];
99
- dataHashes = this.fixturesFor(fetchKey);
100
- for(i in dataHashes){
101
- storeKey = fetchKey.storeKeyFor(i);
102
- hashes.push(dataHashes[i]);
103
- ret.push(storeKey);
104
- }
105
- store.loadRecords(fetchKey, hashes);
106
- },
107
-
108
- /**
109
- Load fixtures for a given fetchKey into the store
110
- and push it to the ret array.
111
-
112
- @param {SC.Store} store
113
- @param {SC.Record} fetchKey
114
- @param {SC.Array} ret
115
- */
116
- loadFixturesFor: function(store, fetchKey, ret) {
117
- var dataHashes, i, storeKey, hashes = [];
118
- dataHashes = this.fixturesFor(fetchKey);
119
- for(i in dataHashes){
120
- storeKey = fetchKey.storeKeyFor(i);
121
- hashes.push(dataHashes[i]);
122
- ret.push(storeKey);
123
- }
124
- store.loadRecords(fetchKey, hashes);
125
- },
126
-
127
89
  /**
128
90
  Retrieve a record from fixtures.
129
91
 
130
92
  @param {SC.Store} store
131
93
  @param {Number} storeKey
132
94
  @param {SC.Array} ret
95
+ @param {Hash} params to be passed down to data source. originated
96
+ from the commitRecords() call on the store
97
+ @returns {Array} storeKeys
133
98
  */
134
- retrieveRecord: function(store, storeKey) {
99
+ retrieveRecord: function(store, storeKey, params) {
135
100
  var ret = [], recordType = SC.Store.recordTypeFor(storeKey),
136
101
  id = store.idFor(storeKey),
137
102
  hash = this.fixtureForStoreKey(store, storeKey);
@@ -157,9 +122,11 @@ SC.FixturesDataSource = SC.DataSource.extend( {
157
122
 
158
123
  @param {SC.Store} store
159
124
  @param {Number} storeKey
125
+ @param {Hash} params to be passed down to data source. originated
126
+ from the commitRecords() call on the store
160
127
  @returns {Boolean} YES if handled
161
128
  */
162
- updateRecord: function(store, storeKey) {
129
+ updateRecord: function(store, storeKey, params) {
163
130
  this.setFixtureForStoreKey(store, storeKey, store.readDataHash(storeKey));
164
131
  store.dataSourceDidComplete(storeKey);
165
132
  return YES ;
@@ -171,9 +138,11 @@ SC.FixturesDataSource = SC.DataSource.extend( {
171
138
 
172
139
  @param {SC.Store} store the store
173
140
  @param {Number} storeKey the store key
141
+ @param {Hash} params to be passed down to data source. originated
142
+ from the commitRecords() call on the store
174
143
  @returns {Boolean} YES if successful
175
144
  */
176
- createRecord: function(store, storeKey) {
145
+ createRecord: function(store, storeKey, params) {
177
146
  var id = store.idFor(storeKey),
178
147
  recordType = store.recordTypeFor(storeKey),
179
148
  dataHash = store.readDataHash(storeKey),
@@ -192,9 +161,11 @@ SC.FixturesDataSource = SC.DataSource.extend( {
192
161
 
193
162
  @param {SC.Store} store the store
194
163
  @param {Number} storeKey the store key
164
+ @param {Hash} params to be passed down to data source. originated
165
+ from the commitRecords() call on the store
195
166
  @returns {Boolean} YES if successful
196
167
  */
197
- destroyRecord: function(store, storeKey) {
168
+ destroyRecord: function(store, storeKey, params) {
198
169
  var id = store.idFor(storeKey),
199
170
  recordType = store.recordTypeFor(storeKey),
200
171
  fixtures = this.fixturesFor(recordType);
@@ -301,7 +272,7 @@ SC.FixturesDataSource = SC.DataSource.extend( {
301
272
  */
302
273
  _invalidateCachesFor: function(recordType, storeKey, id) {
303
274
  var cache = this._storeKeyCache;
304
- if (cache) delete cache[SC.guidFor(recordType)]
275
+ if (cache) delete cache[SC.guidFor(recordType)];
305
276
  return this ;
306
277
  }
307
278
 
@@ -341,6 +341,17 @@ SC.Record = SC.Object.extend(
341
341
  return this.readAttribute(key);
342
342
  },
343
343
 
344
+ /**
345
+ Lets you commit this specific record to the store which will trigger
346
+ the appropriate methods in the data source for you.
347
+
348
+ @param {Hash} params optional additonal params that will passed down
349
+ to the data source
350
+ */
351
+ commitRecord: function(params) {
352
+ this.get('store').commitRecord(undefined, undefined, this.get('storeKey'), params);
353
+ },
354
+
344
355
  // ...............................
345
356
  // PRIVATE
346
357
  //
@@ -185,11 +185,14 @@ SC.RecordAttribute = SC.Object.extend(
185
185
  @returns {Object} property value
186
186
  */
187
187
  call: function(record, key, value) {
188
- var attrKey = this.get('key') || key;
188
+ var attrKey = this.get('key') || key, nvalue;
189
189
 
190
190
  if (value !== undefined) {
191
- value = this.fromType(record, key, value) ; // convert to attribute.
192
- record.writeAttribute(attrKey, value);
191
+
192
+ // careful: don't overwrite value here. we want the return value to
193
+ // cache.
194
+ nvalue = this.fromType(record, key, value) ; // convert to attribute.
195
+ record.writeAttribute(attrKey, nvalue);
193
196
  } else {
194
197
  value = record.readAttribute(attrKey);
195
198
  if (SC.none(value) && (value = this.get('defaultValue'))) {
@@ -136,8 +136,10 @@ SC.NestedStore = SC.Store.extend(
136
136
  if (this.get('hasChanges')) {
137
137
  var pstore = this.get('parentStore');
138
138
  pstore.commitChangesFromNestedStore(this, this.chainedChanges, force);
139
- this.reset(); // clear out custom changes
140
139
  }
140
+
141
+ // clear out custom changes - even if there is nothing to commit.
142
+ this.reset();
141
143
  return this ;
142
144
  },
143
145
 
@@ -166,6 +168,7 @@ SC.NestedStore = SC.Store.extend(
166
168
  }
167
169
 
168
170
  this.reset();
171
+ this.flush();
169
172
  return this ;
170
173
  },
171
174
 
@@ -380,6 +383,7 @@ SC.NestedStore = SC.Store.extend(
380
383
 
381
384
  // Finally, mark store as dirty if we have changes
382
385
  this.setIfChanged('hasChanges', myChanges.get('length')>0);
386
+ this.flush();
383
387
 
384
388
  return this ;
385
389
  },
@@ -548,13 +548,15 @@ SC.Query = SC.Object.extend({
548
548
 
549
549
  if (!inputString) return [];
550
550
 
551
- for (var i=0; i < inputString.length; i++) {
551
+ var iStLength = inputString.length;
552
+
553
+ for (var i=0; i < iStLength; i++) {
552
554
 
553
555
  // end reached?
554
- endOfString = (i==inputString.length-1);
556
+ endOfString = (i===iStLength-1);
555
557
 
556
558
  // current character
557
- c = inputString[i];
559
+ c = inputString.charAt(i);
558
560
 
559
561
  // set true after end of delimeted token so that
560
562
  // final delimeter is not catched again
@@ -567,7 +569,7 @@ SC.Query = SC.Object.extend({
567
569
 
568
570
  // some helpers
569
571
  t = grammar[currentToken];
570
- endOfToken = t.delimeted ? c==currentDelimeter : t.notAllowed.test(c);
572
+ endOfToken = t.delimeted ? c===currentDelimeter : t.notAllowed.test(c);
571
573
 
572
574
  // if still in token
573
575
  if ( !endOfToken ) currentTokenValue += c;
@@ -859,10 +861,11 @@ SC.Query.mixin( /** @scope SC.Query */ {
859
861
 
860
862
  for(idx=0,len=storeKeys.length;idx<len;idx++) {
861
863
  rec = store.materializeRecord(storeKeys[idx]);
862
- status = rec.get('status');
864
+ if (rec) status = rec.get('status');
865
+
863
866
  // do not include EMPTY or DESTROYED records
864
- if(rec && !(status & K.EMPTY) && !(status & K.DESTROYED) && query.contains(rec)) {
865
- ret.push(storeKeys[idx]);
867
+ if (rec && !(status & K.EMPTY) && !(status & K.DESTROYED)) {
868
+ if (query.contains(rec)) ret.push(storeKeys[idx]);
866
869
  }
867
870
  }
868
871
 
@@ -151,6 +151,7 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
151
151
  // clear existing storeKeys, start over by applying all storekeys for
152
152
  // this recordType
153
153
  this.storeKeys = [];
154
+ query.parseQuery();
154
155
  this.applyQuery(storeKeys, recordTypes);
155
156
  }
156
157
 
@@ -163,13 +164,12 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
163
164
 
164
165
  @param {Array} storeKeys to evaluate against the query
165
166
  @param {SC.Set} recordTypes set of record types that changed
166
- @param {Boolean} notify to send length notifyPropertyChange()
167
167
  */
168
- applyQuery: function(changedStoreKeys, recordTypes, notify) {
169
- var newStoreKeys = this.get('storeKeys'), inChangedStoreKeys,
168
+ applyQuery: function(changedStoreKeys, recordTypes) {
169
+ var newStoreKeys = SC.clone(this.get('storeKeys')), inChangedStoreKeys,
170
170
  inMatchingStoreKeys, idx, len, storeKey, queryKey = this.get('queryKey'),
171
171
  store = this.get('store');
172
-
172
+
173
173
  // first check if these changes include any of the record types
174
174
  if(recordTypes && queryKey.recordType && !recordTypes.contains(queryKey.recordType)) return;
175
175
 
@@ -184,7 +184,7 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
184
184
  inMatchingStoreKeys = (matchingStoreKeys &&
185
185
  matchingStoreKeys.indexOf(storeKey)!==-1) ? YES: NO;
186
186
  var inRecArray = this.storeKeys.indexOf(storeKey)!==-1 ? YES : NO;
187
-
187
+
188
188
  if(inMatchingStoreKeys && !inRecArray) {
189
189
  newStoreKeys.push(storeKey);
190
190
  }
@@ -195,11 +195,7 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
195
195
  }
196
196
 
197
197
  SC.Query.orderStoreKeys(newStoreKeys, queryKey, store);
198
- // clear cache
199
- this._records = null;
200
-
201
- this.storeKeys = newStoreKeys.addObserver('[]', this, this._storeKeysContentDidChange);
202
- if(notify) this.notifyPropertyChange('length');
198
+ this.set('storeKeys', newStoreKeys);
203
199
  },
204
200
 
205
201
  /**
@@ -223,7 +219,6 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
223
219
  Invoked whenever the storeKeys array changes. Observes changes.
224
220
  */
225
221
  _storeKeysDidChange: function() {
226
-
227
222
  var storeKeys = this.get('storeKeys');
228
223
 
229
224
  var prev = this._prevStoreKeys,
@@ -263,13 +258,6 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
263
258
  */
264
259
  _storeKeysContentDidChange: function(target, key, value, rev) {
265
260
  this._records = null ; // clear cache
266
- // if this record array is based on a queryKey reapply the
267
- // the query before setting the storeKeys to ensure it always conforms
268
-
269
- if(SC.instanceOf(this.queryKey, SC.Query)) {
270
- this.storeKeys = SC.Query.containsStoreKeys(this.queryKey, value, this.store);
271
- this.notifyPropertyChange('length');
272
- }
273
261
 
274
262
  this.beginPropertyChanges()
275
263
  .notifyPropertyChange('length')
@@ -279,9 +267,20 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
279
267
 
280
268
  init: function() {
281
269
  sc_super();
282
- this._storeKeysDidChange();
270
+
271
+ // if this record array is based on a queryKey apply the
272
+ // the query before setting the storeKeys to ensure it always conforms
273
+ if(SC.instanceOf(this.queryKey, SC.Query)) {
274
+ var queryKey = this.get('queryKey'), recordTypes = SC.Set.create();
275
+ recordTypes.push(queryKey.get('recordType'));
276
+
277
+ this.applyQuery(this.get('storeKeys'), recordTypes);
278
+ }
279
+ else {
280
+ this._storeKeysDidChange();
281
+ }
282
+
283
283
  }
284
284
 
285
-
286
285
  });
287
286