sproutcore 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/Manifest.txt +42 -29
  2. data/README.txt +1 -1
  3. data/Rakefile +5 -0
  4. data/app_generators/sproutcore/sproutcore_generator.rb +4 -4
  5. data/app_generators/sproutcore/templates/sc-config.rb +72 -0
  6. data/bin/sc-build +2 -0
  7. data/clients/sc_docs/controllers/docs.js +1 -0
  8. data/clients/sc_docs/english.lproj/body.rhtml +5 -0
  9. data/clients/sc_docs/views/doc_frame.js +1 -1
  10. data/clients/sc_test_runner/controllers/runner.js +2 -2
  11. data/clients/sc_test_runner/english.lproj/body.rhtml +5 -0
  12. data/clients/sc_test_runner/main.js +12 -12
  13. data/clients/sc_test_runner/models/test.js +3 -0
  14. data/clients/sc_test_runner/views/test_label.js +1 -1
  15. data/config/hoe.rb +2 -0
  16. data/frameworks/sproutcore/controllers/array.js +132 -125
  17. data/frameworks/sproutcore/drag/drag.js +5 -2
  18. data/frameworks/sproutcore/english.lproj/buttons.css +64 -64
  19. data/frameworks/sproutcore/english.lproj/collections.css +82 -0
  20. data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
  21. data/frameworks/sproutcore/english.lproj/images/sproutcore-logo.png +0 -0
  22. data/frameworks/sproutcore/english.lproj/images/sticky-note.png +0 -0
  23. data/frameworks/sproutcore/english.lproj/menu.css +1 -1
  24. data/frameworks/sproutcore/english.lproj/theme.css +13 -4
  25. data/frameworks/sproutcore/foundation/array.js +24 -2
  26. data/frameworks/sproutcore/foundation/benchmark.js +12 -5
  27. data/frameworks/sproutcore/foundation/observable.js +62 -1
  28. data/frameworks/sproutcore/foundation/utils.js +16 -0
  29. data/frameworks/sproutcore/tests/views/label_item.rhtml +21 -0
  30. data/frameworks/sproutcore/tests/views/list.rhtml +21 -0
  31. data/frameworks/sproutcore/tests/views/scroll.rhtml +21 -0
  32. data/frameworks/sproutcore/views/collection.js +401 -73
  33. data/frameworks/sproutcore/views/collection/collection_item.js +36 -0
  34. data/frameworks/sproutcore/views/collection/grid.js +149 -0
  35. data/frameworks/sproutcore/views/collection/image_cell.js +154 -0
  36. data/frameworks/sproutcore/views/collection/list.js +115 -0
  37. data/frameworks/sproutcore/views/collection/text_cell.js +128 -0
  38. data/frameworks/sproutcore/views/image.js +1 -1
  39. data/frameworks/sproutcore/views/label.js +6 -2
  40. data/frameworks/sproutcore/views/scroll.js +34 -0
  41. data/frameworks/sproutcore/views/view.js +12 -4
  42. data/generators/client/client_generator.rb +3 -11
  43. data/generators/client/templates/english.lproj/body.css +75 -0
  44. data/generators/client/templates/english.lproj/body.rhtml +17 -2
  45. data/generators/model/templates/fixture.js +32 -0
  46. data/lib/sproutcore/build_tools/html_builder.rb +29 -11
  47. data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
  48. data/lib/sproutcore/bundle.rb +19 -7
  49. data/lib/sproutcore/library.rb +39 -21
  50. data/lib/sproutcore/merb/bundle_controller.rb +3 -8
  51. data/lib/sproutcore/version.rb +1 -1
  52. data/lib/sproutcore/view_helpers.rb +7 -5
  53. data/lib/sproutcore/view_helpers/core_views.rb +11 -3
  54. data/sc-config.rb +7 -0
  55. data/tasks/deployment.rake +15 -2
  56. metadata +44 -31
  57. data/app_generators/sproutcore/templates/environment.yml +0 -4
  58. data/environment.yml +0 -9
@@ -1,12 +1,7 @@
1
- History.txt
2
- License.txt
3
- Manifest.txt
4
- README.txt
5
- Rakefile
6
- app_generators/sproutcore/USAGE
7
1
  app_generators/sproutcore/sproutcore_generator.rb
8
2
  app_generators/sproutcore/templates/README
9
- app_generators/sproutcore/templates/environment.yml
3
+ app_generators/sproutcore/templates/sc-config.rb
4
+ app_generators/sproutcore/USAGE
10
5
  bin/sc-build
11
6
  bin/sc-gen
12
7
  bin/sc-server
@@ -53,14 +48,12 @@ clients/sc_test_runner/views/runner_frame.js
53
48
  clients/sc_test_runner/views/test_label.js
54
49
  config/hoe.rb
55
50
  config/requirements.rb
56
- environment.yml
57
51
  frameworks/prototype/prototype.js
58
- frameworks/sproutcore/Core.js
59
- frameworks/sproutcore/README
60
52
  frameworks/sproutcore/controllers/array.js
61
53
  frameworks/sproutcore/controllers/collection.js
62
54
  frameworks/sproutcore/controllers/controller.js
63
55
  frameworks/sproutcore/controllers/object.js
56
+ frameworks/sproutcore/Core.js
64
57
  frameworks/sproutcore/drag/drag.js
65
58
  frameworks/sproutcore/drag/drag_data_source.js
66
59
  frameworks/sproutcore/drag/drag_source.js
@@ -68,6 +61,10 @@ frameworks/sproutcore/drag/drop_target.js
68
61
  frameworks/sproutcore/english.lproj/blank.gif
69
62
  frameworks/sproutcore/english.lproj/buttons.css
70
63
  frameworks/sproutcore/english.lproj/buttons.png
64
+ frameworks/sproutcore/english.lproj/collections.css
65
+ frameworks/sproutcore/english.lproj/images/buttons-sprite.png
66
+ frameworks/sproutcore/english.lproj/images/sproutcore-logo.png
67
+ frameworks/sproutcore/english.lproj/images/sticky-note.png
71
68
  frameworks/sproutcore/english.lproj/inline_text_editor.css
72
69
  frameworks/sproutcore/english.lproj/menu.css
73
70
  frameworks/sproutcore/english.lproj/panels/background-fat.jpg
@@ -125,6 +122,7 @@ frameworks/sproutcore/panes/overlay.js
125
122
  frameworks/sproutcore/panes/pane.js
126
123
  frameworks/sproutcore/panes/panel.js
127
124
  frameworks/sproutcore/panes/picker.js
125
+ frameworks/sproutcore/README
128
126
  frameworks/sproutcore/tests/controllers/array.rhtml
129
127
  frameworks/sproutcore/tests/controllers/controller.rhtml
130
128
  frameworks/sproutcore/tests/controllers/object.rhtml
@@ -134,7 +132,10 @@ frameworks/sproutcore/tests/foundation/object.rhtml
134
132
  frameworks/sproutcore/tests/globals/window.rhtml
135
133
  frameworks/sproutcore/tests/panes/pane.rhtml
136
134
  frameworks/sproutcore/tests/views/collection.rhtml
135
+ frameworks/sproutcore/tests/views/label_item.rhtml
136
+ frameworks/sproutcore/tests/views/list.rhtml
137
137
  frameworks/sproutcore/tests/views/popup_button.rhtml
138
+ frameworks/sproutcore/tests/views/scroll.rhtml
138
139
  frameworks/sproutcore/tests/views/text_field.rhtml
139
140
  frameworks/sproutcore/validators/credit_card.js
140
141
  frameworks/sproutcore/validators/date.js
@@ -145,6 +146,11 @@ frameworks/sproutcore/validators/password.js
145
146
  frameworks/sproutcore/validators/validator.js
146
147
  frameworks/sproutcore/views/button.js
147
148
  frameworks/sproutcore/views/checkbox_field.js
149
+ frameworks/sproutcore/views/collection/collection_item.js
150
+ frameworks/sproutcore/views/collection/grid.js
151
+ frameworks/sproutcore/views/collection/image_cell.js
152
+ frameworks/sproutcore/views/collection/list.js
153
+ frameworks/sproutcore/views/collection/text_cell.js
148
154
  frameworks/sproutcore/views/collection.js
149
155
  frameworks/sproutcore/views/container.js
150
156
  frameworks/sproutcore/views/error_explanation.js
@@ -161,6 +167,7 @@ frameworks/sproutcore/views/popup_menu.js
161
167
  frameworks/sproutcore/views/progress.js
162
168
  frameworks/sproutcore/views/radio_field.js
163
169
  frameworks/sproutcore/views/radio_group.js
170
+ frameworks/sproutcore/views/scroll.js
164
171
  frameworks/sproutcore/views/segmented.js
165
172
  frameworks/sproutcore/views/select_field.js
166
173
  frameworks/sproutcore/views/spinner.js
@@ -170,47 +177,48 @@ frameworks/sproutcore/views/textarea_field.js
170
177
  frameworks/sproutcore/views/toolbar.js
171
178
  frameworks/sproutcore/views/view.js
172
179
  frameworks/sproutcore/views/workspace.js
173
- generators/client/README
174
- generators/client/USAGE
175
180
  generators/client/client_generator.rb
181
+ generators/client/README
176
182
  generators/client/templates/core.js
177
183
  generators/client/templates/english.lproj/body.css
178
184
  generators/client/templates/english.lproj/body.rhtml
179
185
  generators/client/templates/english.lproj/controls.css
180
186
  generators/client/templates/english.lproj/strings.js
181
187
  generators/client/templates/main.js
182
- generators/controller/USAGE
188
+ generators/client/USAGE
183
189
  generators/controller/controller_generator.rb
184
190
  generators/controller/templates/controller.js
185
191
  generators/controller/templates/test.rhtml
186
- generators/framework/README
187
- generators/framework/USAGE
192
+ generators/controller/USAGE
188
193
  generators/framework/framework_generator.rb
194
+ generators/framework/README
189
195
  generators/framework/templates/core.js
190
196
  generators/framework/templates/english.lproj/body.css
191
197
  generators/framework/templates/english.lproj/body.rhtml
192
198
  generators/framework/templates/english.lproj/controls.css
193
199
  generators/framework/templates/english.lproj/strings.js
194
- generators/language/USAGE
200
+ generators/framework/USAGE
195
201
  generators/language/language_generator.rb
196
202
  generators/language/templates/strings.js
197
- generators/model/USAGE
203
+ generators/language/USAGE
198
204
  generators/model/model_generator.rb
199
205
  generators/model/templates/fixture.js
200
206
  generators/model/templates/model.js
201
207
  generators/model/templates/test.rhtml
202
- generators/test/USAGE
208
+ generators/model/USAGE
203
209
  generators/test/templates/test.rhtml
204
210
  generators/test/test_generator.rb
205
- generators/view/USAGE
211
+ generators/test/USAGE
206
212
  generators/view/templates/test.rhtml
207
213
  generators/view/templates/view.js
214
+ generators/view/USAGE
208
215
  generators/view/view_generator.rb
209
- jsdoc/README.txt
216
+ History.txt
210
217
  jsdoc/app/DocFile.js
211
- jsdoc/app/DocTag.js
212
218
  jsdoc/app/Doclet.js
219
+ jsdoc/app/DocTag.js
213
220
  jsdoc/app/Dumper.js
221
+ jsdoc/app/js.jar
214
222
  jsdoc/app/JsDoc.js
215
223
  jsdoc/app/JsHilite.js
216
224
  jsdoc/app/JsIO.js
@@ -218,13 +226,13 @@ jsdoc/app/JsParse.js
218
226
  jsdoc/app/JsPlate.js
219
227
  jsdoc/app/JsTestrun.js
220
228
  jsdoc/app/JsToke.js
229
+ jsdoc/app/run.js
221
230
  jsdoc/app/Symbol.js
222
231
  jsdoc/app/Transformer.js
223
232
  jsdoc/app/Util.js
224
- jsdoc/app/js.jar
225
- jsdoc/app/run.js
226
233
  jsdoc/plugins/min.js
227
234
  jsdoc/plugins/strip.js
235
+ jsdoc/README.txt
228
236
  jsdoc/templates/sproutcore/class.tmpl
229
237
  jsdoc/templates/sproutcore/default.css
230
238
  jsdoc/templates/sproutcore/index.html
@@ -232,30 +240,35 @@ jsdoc/templates/sproutcore/index.tmpl
232
240
  jsdoc/templates/sproutcore/prototype.js
233
241
  jsdoc/templates/sproutcore/publish.js
234
242
  jsdoc/templates/sproutcore/splash.html
235
- lib/sproutcore.rb
236
- lib/sproutcore/build_tools.rb
237
243
  lib/sproutcore/build_tools/html_builder.rb
238
244
  lib/sproutcore/build_tools/resource_builder.rb
245
+ lib/sproutcore/build_tools.rb
239
246
  lib/sproutcore/bundle.rb
240
247
  lib/sproutcore/bundle_manifest.rb
241
248
  lib/sproutcore/generator_helper.rb
242
- lib/sproutcore/helpers.rb
243
249
  lib/sproutcore/helpers/capture_helper.rb
244
250
  lib/sproutcore/helpers/static_helper.rb
245
251
  lib/sproutcore/helpers/tag_helper.rb
246
252
  lib/sproutcore/helpers/text_helper.rb
253
+ lib/sproutcore/helpers.rb
247
254
  lib/sproutcore/jsdoc.rb
248
255
  lib/sproutcore/jsmin.rb
249
256
  lib/sproutcore/library.rb
250
- lib/sproutcore/merb.rb
251
257
  lib/sproutcore/merb/bundle_controller.rb
252
258
  lib/sproutcore/merb/router.rb
259
+ lib/sproutcore/merb.rb
253
260
  lib/sproutcore/version.rb
254
- lib/sproutcore/view_helpers.rb
255
261
  lib/sproutcore/view_helpers/button_views.rb
256
262
  lib/sproutcore/view_helpers/core_views.rb
257
263
  lib/sproutcore/view_helpers/form_views.rb
258
264
  lib/sproutcore/view_helpers/menu_views.rb
265
+ lib/sproutcore/view_helpers.rb
266
+ lib/sproutcore.rb
267
+ License.txt
268
+ Manifest.txt
269
+ Rakefile
270
+ README.txt
271
+ sc-config.rb
259
272
  script/destroy
260
273
  script/generate
261
274
  script/txt2html
@@ -266,4 +279,4 @@ spec/sproutcore_spec.rb
266
279
  tasks/deployment.rake
267
280
  tasks/environment.rake
268
281
  tasks/rspec.rake
269
- tasks/website.rake
282
+ tasks/website.rake
data/README.txt CHANGED
@@ -8,7 +8,7 @@ This package includes both the raw SproutCore source as well as a complete build
8
8
 
9
9
  SproutCore comes loaded with a lot of features you would normally find in a full MVC desktop framework including:
10
10
 
11
- 2. "Bindings" that can automatically relay changes in a property from your model objects to your views.
11
+ 1. "Bindings" that can automatically relay changes in a property from your model objects to your views.
12
12
 
13
13
  2. A simple in-memory database for storing your models.
14
14
 
data/Rakefile CHANGED
@@ -1,4 +1,9 @@
1
1
  require 'config/requirements'
2
2
  require 'config/hoe' # setup Hoe + all gem configuration
3
3
 
4
+ APP_ROOT = File.expand_path(File.dirname(__FILE__))
5
+
6
+ # Set directories you want ignored in the manifest.
7
+ IGNORE_DIRS = ['assets', 'pkg', 'samples', 'doc']
8
+
4
9
  Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -22,12 +22,12 @@ class SproutcoreGenerator < RubiGen::Base
22
22
  BASEDIRS.each { |path| m.directory path }
23
23
 
24
24
  # Create stubs
25
- m.template_copy_each %w(README environment.yml)
26
- m.dependency "install_rubigen_scripts", [destination_root, 'sproutcore'],
27
- :shebang => options[:shebang], :collision => :force
25
+ m.template_copy_each %w(README sc-config.rb)
26
+ # m.dependency "install_rubigen_scripts", [destination_root, 'sproutcore'],
27
+ # :shebang => options[:shebang], :collision => :force
28
28
 
29
29
  # Create initial client
30
- m.dependency "client", [destination_root, @name],
30
+ m.dependency "client", [@name, "--library=#{@destination_root}"],
31
31
  :shebang => options[:shebang], :collision => :force
32
32
 
33
33
  end
@@ -0,0 +1,72 @@
1
+ # SPROUTCORE CONFIGURATION FILE
2
+ # Use this file to customize the URLs, source and output paths and and other
3
+ # options used by the SproutCore build system to create the output for your
4
+ # SproutCore applications.
5
+
6
+ # If you want to use the libraries provided by other gems, require those gems
7
+ # here. SproutCore will automatically locate and load any bundles found in
8
+ # your load path. The sproutcore gem is automatically loaded for you.
9
+ #
10
+ # require 'sproutcore'
11
+
12
+ # This configuration section will be applied to all bundles used by your
13
+ # application, even bundles that come from other gems.
14
+ config :all do |c|
15
+
16
+ # Name any other frameworks your bundles depend upon. The stylesheets and
17
+ # JavaScript for required bundles will be loaded before your bundle on your
18
+ # page.
19
+ c[:required] = [:sproutcore]
20
+
21
+ # This string will be prepended before any URLs that reference JavaScript,
22
+ # CSS or images in your files.
23
+ c[:resources_at] = 'static'
24
+
25
+ # This string will be prepended before any index.html urls that actually
26
+ # load your clients. Setting this to an empty string will mount all
27
+ # of your clients at the root URL level.
28
+ c[:index_at] = ''
29
+
30
+ # If you also need to load external stylesheets not managed by the bundle
31
+ # system, name the URLs you want to reference here.
32
+ # c[:stylesheet_libs] = ['/stylesheets/public.css']
33
+
34
+ # If you also need to load external javascripts not managed by the bundle
35
+ # system, name hte URLs you want to reference here. These will be loaded
36
+ # automatically.
37
+ # c[:javascript_libs] = ['/javascript/scriptaculous.js']
38
+
39
+ # This is the preferred language. When the user visits the root URL of
40
+ # your client, this is the language they will get. When looking for a
41
+ # resources (such as an image or stylesheet), SproutCore will also try
42
+ # your preferred language .lproj if it cannot find the resource in the
43
+ # current language.
44
+ # c[:preferred_language] = :fr
45
+
46
+ # If you want to use a default root layout template other than the default
47
+ # provided by SproutCore, you can specifiy the path name to the index.html
48
+ # here. If you provide a relative path, SproutCore will assume the file
49
+ # is relative to the root of this project.
50
+ # c[:layout] = 'lib/index.rhtml'
51
+
52
+ # This is the fully qualified path to the directory you want all of your
53
+ # static files stored in. You can place any files not managed by the build
54
+ # system here. SproutCore will also save its cached resources here.
55
+ # c[:public_root] = File.join(File.dirname(__FILE__), 'public')
56
+
57
+ # The default build mode. Normally you can specify this on the command
58
+ # line as well using the -e option, but you can override the default
59
+ # using this config as well.
60
+ #c[:build_mode] = :production
61
+
62
+ end
63
+
64
+ # Add configurations for specific bundles here as well. Any options you
65
+ # provide here will override the defaults provided by the bundles themselves
66
+ # as well as any options you place in the :all category above.
67
+ #
68
+ # config :contacts do |c|
69
+ # c[:required] = [:sproutcore, :shared]
70
+ # end
71
+ #
72
+
@@ -98,6 +98,8 @@ library = SC.library_for(library_root, :public_root => build_root, :url_prefix =
98
98
  ## FIND BUNDLES TO BUILD
99
99
  ##
100
100
 
101
+ puts "build_root = #{build_root}"
102
+
101
103
  # Find the bundles to build.
102
104
  if bundle_name
103
105
  # Get bundle
@@ -39,6 +39,7 @@ Docs.docsController = SC.Object.create({
39
39
  // current client.
40
40
  var clientName = this.get('clientName') ;
41
41
  var clientRoot = this.get('clientRoot') ;
42
+ clientRoot = clientRoot.replace(new RegExp("^%@/?".fmt(window.indexPrefix)), window.urlPrefix + '/');
42
43
  console.log('clientName: '+ clientRoot) ;
43
44
  Docs.server.request(clientRoot, ['data','classes.js'].join('/'), null, {
44
45
  onSuccess: this._reloadSuccess.bind(this),
@@ -30,4 +30,9 @@
30
30
  <% end %>
31
31
  <% end %>
32
32
 
33
+ <script>
34
+ window.urlPrefix = "<%= bundle.url_prefix %>";
35
+ window.indexPrefix = "<%= bundle.index_prefix %>";
36
+ </script>
37
+
33
38
  <% end %>
@@ -13,7 +13,7 @@ Docs.DocFrameView = SC.View.extend({
13
13
  var doc = this.get('doc') ;
14
14
  var url = (doc) ? doc.get('url') : '' ;
15
15
  if (url.length > 0) {
16
- url = "/%@/%@/%@".fmt('sc_docs', Docs.docsController.get('clientName'), url) ;
16
+ url = "/%@/%@/-docs/data/%@".fmt(window.urlPrefix,Docs.docsController.get('clientName'), url) ;
17
17
  }
18
18
 
19
19
  // make sure we clear out the old document settings if needed.
@@ -61,8 +61,8 @@ TestRunner.runnerController = SC.Object.create({
61
61
 
62
62
  // Use Ajax to ask the server for the latest set of tests for the
63
63
  // current client.
64
- var ids = [this.get('clientName')] ;
65
- TestRunner.server.request('sc_test_runner', 'list', ids, {
64
+ var urlRoot = this.get('urlRoot') ;
65
+ TestRunner.server.request(urlRoot, 'index.js', null, {
66
66
  onSuccess: this._reloadSuccess.bind(this),
67
67
  onFailure: this._reloadFailure.bind(this)
68
68
  }) ;
@@ -32,4 +32,9 @@
32
32
 
33
33
  <% end %>
34
34
 
35
+ <script>
36
+ window.urlPrefix = "<%= bundle.url_prefix %>";
37
+ window.indexPrefix = "<%= bundle.index_prefix %>";
38
+ </script>
39
+
35
40
  <% end %>
@@ -6,21 +6,21 @@ function main() {
6
6
  //TestRunner.server.preload(TestRunner.FIXTURES) ;
7
7
  SC.page.awake() ;
8
8
  //TestRunner.runnerController.reloadTests() ;
9
+
10
+ console.log('main') ;
11
+ var indexRoot = window.location.pathname.toString().replace(/-tests\/.*/,'-tests').substr(1,window.location.pathname.length);
12
+ var clientName = indexRoot.match(/([^\/]+)\/-tests/)[1];
13
+ var urlRoot = indexRoot.replace(new RegExp("^%@/?".fmt(window.indexPrefix)), window.urlPrefix + '/');
14
+ console.log('indexRoot: %@ clientName: %@ urlRoot: %@'.fmt( indexRoot, clientName, urlRoot));
15
+ TestRunner.hidePanels() ;
16
+ TestRunner.runnerController.set('selection',[]) ;
17
+ TestRunner.runnerController.set('urlRoot', urlRoot) ;
18
+ TestRunner.runnerController.set('indexRoot', indexRoot) ;
19
+ TestRunner.runnerController.set('clientName', clientName) ;
20
+ TestRunner.runnerController.reloadTests() ;
9
21
  } ;
10
22
 
11
23
  TestRunner.hidePanels = function() {
12
24
  SC.page.get('warningPanel').set('isVisible', false) ;
13
25
  SC.page.get('noTestsPanel').set('isVisible',false) ;
14
26
  } ;
15
-
16
- SC.Routes.addRoute('', function() {
17
- TestRunner.hidePanels() ;
18
- SC.page.get('warningPanel').set('isVisible', true) ;
19
- }) ;
20
-
21
- SC.Routes.addRoute(':client', function(params) {
22
- TestRunner.hidePanels() ;
23
- TestRunner.runnerController.set('selection',[]) ;
24
- TestRunner.runnerController.set('clientName', params.client) ;
25
- TestRunner.runnerController.reloadTests() ;
26
- }) ;
@@ -7,5 +7,8 @@ require('core');
7
7
  TestRunner.Test = SC.Record.extend({
8
8
 
9
9
  // TODO: Add your own code here.
10
+ title: function() {
11
+ return this.get('name').replace(/\.rhtml$/,'');
12
+ }.property('name')
10
13
 
11
14
  }) ;
@@ -10,7 +10,7 @@ TestRunner.TestLabelView = SC.ButtonView.extend({
10
10
 
11
11
  contentObserver: function() {
12
12
  var c = this.get('content') ;
13
- this.set('labelText', (c) ? c.get('name') : '(NONE)') ;
13
+ this.set('labelText', (c) ? c.get('title') : '(NONE)') ;
14
14
  }.observes('content'),
15
15
 
16
16
  labelSelector: 'span',
@@ -8,6 +8,8 @@ RUBYFORGE_PROJECT = 'sproutcore' # The unix name for your project
8
8
  HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
9
  DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
10
 
11
+ ENV['NODOT'] = "nodot" # avoid generating diagrams
12
+
11
13
  @config_file = "~/.rubyforge/user-config.yml"
12
14
  @config = nil
13
15
  RUBYFORGE_USERNAME = "okito"
@@ -5,6 +5,7 @@
5
5
 
6
6
  require('controllers/controller') ;
7
7
  require('foundation/array') ;
8
+ require('foundation/binding') ;
8
9
 
9
10
  /** @class
10
11
 
@@ -21,121 +22,102 @@ SC.ArrayController = SC.Controller.extend(SC.Array,
21
22
  /** @scope SC.ArrayController.prototype */
22
23
  {
23
24
  /**
24
- * The array content that is being managed by the controller.
25
- * @property
26
- * @type {Array}
25
+ Provides compatibility with CollectionControllers.
26
+ @property
27
+ @type {SC.ArrayController}
27
28
  */
28
- content: function( key, value )
29
- {
30
- if (!this._content) this._content = [];
31
- if (value !== undefined)
32
- {
33
- // only allow arrays... or array-like objects...
34
- this._content = ($type(value) == T_ARRAY) || (value && value.objectAt) ? value : [];
35
- }
36
- return this._content;
37
- }.property(),
38
-
29
+ arrangedObjects: function() { return this; }.property(),
30
+
39
31
  /**
40
- * Watches changes to the content property updates the contentClone.
41
- * @private
42
- * @observes content
43
- **/
44
- _contentObserver: function()
45
- {
46
- this.contentCloneReset();
47
- }.observes('content'),
32
+ The array content that is being managed by the controller.
33
+ @property
34
+ @type {Array}
35
+ */
36
+ content: null,
37
+ contentBindingDefault: SC.Binding.Multiple,
48
38
 
49
-
50
39
  /**
51
- * A log of calls to the replace method that will be played back to the content property on commit.
52
- * @private
53
- * @property
54
- * @type {SC.Array}
40
+ Set to true if you want objects removed from the array to also be
41
+ deleted. This is a convenient way to manage lists of items owned
42
+ by a parent record object.
43
+
44
+ @property
45
+ @type {Boolean}
55
46
  */
56
- changelog: function( key, value )
57
- {
58
- if (!this._changelog) this._changelog = [];
59
- if (value !== undefined) this._changelog = value;
60
- return this._changelog;
61
- }.property(),
62
-
47
+ destroyOnRemoval: false,
48
+
63
49
  /**
64
- * A collection of all the objects that have been removed using removeObject.
65
- * On commit, they are deleted.
66
- * @private
67
- * @property
68
- * @type {SC.Array}
50
+ Watches changes to the content property updates the contentClone.
51
+ @private
52
+ @observes content
69
53
  */
70
- deletions: function( key, value )
71
- {
72
- if (!this._deletions) this._deletions = [];
73
- if (value !== undefined) this._deletions = value;
74
- return this._deletions;
75
- }.property(),
54
+ _contentObserver: function() {
55
+ this.contentCloneReset();
56
+ this.arrayContentDidChange() ;
57
+ }.observes('content'),
76
58
 
77
59
  /**
78
- * The array content that (when committed) will be merged back into the content property.
79
- * All array methods will take place on this object.
80
- * @private
81
- * @property
82
- * @type {SC.Array}
60
+ The array content that (when committed) will be merged back into the content property.
61
+ All array methods will take place on this object.
62
+
63
+ @property
64
+ @type {SC.Array}
83
65
  */
84
- contentClone: function( key, value )
85
- {
86
- if (value !== undefined)
87
- {
88
- this._contentClone = value;
89
- this.arrayContentDidChange();
90
- }
91
- return this._contentClone;
92
- }.property(),
66
+ contentClone: null,
93
67
 
94
68
  /**
95
69
  * Clones the content property into the contentClone property.
96
70
  * @private
97
71
  **/
98
- contentCloneReset: function()
99
- {
100
- this.set('changelog', []);
101
- this.set('deletions', []);
72
+ contentCloneReset: function() {
73
+ this._changelog = [];
102
74
  this.set('contentClone', null);
103
75
  },
104
76
 
105
77
  /**
106
- * SC.Array interface implimentation.
107
- *
108
- * @param {Number} idx
109
- * Starting index in the array to replace. If idx >= length, then append to
110
- * the end of the array.
111
- *
112
- * @param {Number} amt
113
- * Number of elements that should be removed from the array, starting at
114
- * *idx*.
115
- *
116
- * @param {Array} objects
117
- * An array of zero or more objects that should be inserted into the array at
118
- * *idx*
78
+ SC.Array interface implimentation.
79
+
80
+ @param {Number} idx
81
+ Starting index in the array to replace. If idx >= length, then append to
82
+ the end of the array.
83
+
84
+ @param {Number} amt
85
+ Number of elements that should be removed from the array, starting at
86
+ *idx*.
87
+
88
+ @param {Array} objects
89
+ An array of zero or more objects that should be inserted into the array at
90
+ *idx*
119
91
  */
120
- replace: function(idx, amt, objects)
121
- {
122
- if (this.get('contentClone') == undefined) this.set('contentClone', this.get('content').clone());
92
+ replace: function(idx, amt, objects) {
123
93
 
124
- for (var i=0; i < amt; i++)
125
- {
126
- this.get('deletions').push( this._getSourceContent().objectAt(idx + i) );
127
- }
94
+ var content = this.get('content') ;
128
95
 
129
- this.get('changelog').push({ idx: idx, amt: amt, objects: objects });
130
- this.get('contentClone').replace(idx, amt, objects);
96
+ // in case the passed objects are controllers, convert to source objects.
97
+ var copyIdx = objects.length ;
98
+ var sourceObjects = [] ;
99
+ while(--copyIdx >= 0) sourceObjects[copyIdx] = this._sourceObjectFor(objects[copyIdx]) ;
131
100
 
132
- for (var i=idx, n=idx+amt; i < n; i++)
133
- {
134
- if ( this._objControllers && this._objControllers[i] )
135
- {
136
- this._objControllers[i] = null;
101
+ // create clone of content array if needed
102
+ var contentClone = this.get('contentClone') ;
103
+ if (!contentClone) {
104
+ contentClone = this.set('contentClone', content.clone());
105
+ }
106
+
107
+ // now, record the removed objects. This may be used later.
108
+ if (this.get('destroyOnRemoval')) {
109
+ if (!this._deletions) this._deletions = [] ;
110
+ for (var i=0; i < amt; i++) {
111
+ this._deletions.push(content.objectAt(idx + i));
137
112
  }
138
113
  }
114
+
115
+ // and record additions
116
+ if (!this._changelog) this._changelog = [];
117
+ this._changelog.push({ idx: idx, amt: amt, objects: objects });
118
+
119
+ // then actually perform the edit on the contentClone
120
+ contentClone.replace(idx, amt, objects);
139
121
 
140
122
  this.editorDidChange() ;
141
123
  this.arrayContentDidChange();
@@ -149,36 +131,31 @@ SC.ArrayController = SC.Controller.extend(SC.Array,
149
131
  * The index of the item to return. If idx exceeds the current length,
150
132
  * return null.
151
133
  */
152
- objectAt: function(idx)
153
- {
134
+ objectAt: function(idx) {
154
135
  var obj = this._getSourceContent().objectAt(idx);
155
-
156
- if ( !this._objControllers ) this._objControllers = [];
157
- if ( !this._objControllers[idx] ) this._objControllers[idx] = this.controllerForValue(obj);
158
-
159
- return this._objControllers[idx];
136
+ return this._objectControllerFor(obj) ;
160
137
  },
161
138
  /**
162
139
  * SC.Array interface implimentation.
163
140
  * @property
164
141
  * @type {integer}
165
142
  */
166
- length: function( key, value )
167
- {
143
+ length: function( key, value ) {
168
144
  return this._getSourceContent().get('length');
169
145
  }.property(),
170
146
 
171
- indexOf: function( obj )
172
- {
173
- return this._getSourceContent().indexOf(obj);
147
+ /**
148
+ Returns the index in the array of the specified object.
149
+
150
+ This can handle both controller wrapper objects and source content objects.
151
+ */
152
+ indexOf: function( obj ) {
153
+ return this._getSourceContent().indexOf(this._sourceObjectFor(obj)) ;
174
154
  },
175
- _getSourceContent: function()
176
- {
177
- return this.get('contentClone') || this.get('content');
155
+
156
+ _getSourceContent: function() {
157
+ return this.get('contentClone') || this.get('content') || [];
178
158
  },
179
-
180
-
181
-
182
159
 
183
160
  /**
184
161
  * @private
@@ -189,8 +166,7 @@ SC.ArrayController = SC.Controller.extend(SC.Array,
189
166
  var ret = true;
190
167
 
191
168
  // cannot commit changes to null content. Return an error.
192
- if (!content)
193
- {
169
+ if (!content) {
194
170
  return $error("No Content");
195
171
  }
196
172
 
@@ -198,25 +174,33 @@ SC.ArrayController = SC.Controller.extend(SC.Array,
198
174
 
199
175
 
200
176
  // apply all the changes made to the clone
201
- this.get('changelog').each(function(change)
202
- {
203
- content.replace( change.idx, change.amt, change.objects );
204
- });
205
- this.get('deletions').each(function(obj)
206
- {
207
- if (obj.instanceOf(SC.ObjectController)) obj = obj.get('content');
208
- if (obj && obj.destroy)
209
- {
210
- obj.destroy();
177
+ var changelog = this._changelog || [] ;
178
+ for(var idx=0;idx<changelog.length;idx++) {
179
+ var change = changelog[idx];
180
+ content.replace(change.idx, change.amt, change.objects) ;
181
+ }
182
+
183
+ // done, flush the changelog
184
+ this._changelog = [] ;
185
+
186
+ // finally, destroy any removed objects if necessary. Make
187
+ // sure the objects have not been re-added before doing this.
188
+ if (this.get('destroyOnRemoval') && this._deletions && this._deletions.length>0) {
189
+ var idx = this._deletions.length;
190
+ while(--idx >= 0) {
191
+ var obj = this._deletions[idx] ;
192
+ if (obj && obj.destroy && (content.indexOf(obj) < 0)) {
193
+ obj.destroy() ;
194
+ }
211
195
  }
212
- });
213
-
214
-
196
+ this._deletions = [] ; // clear array
197
+ }
198
+
199
+ // finish commiting changes.
215
200
  if (content.endPropertyChanges) content.endPropertyChanges();
216
201
  if (content.commitChanges) ret = content.commitChanges();
217
202
 
218
- if ($ok(ret))
219
- {
203
+ if ($ok(ret)) {
220
204
  this.contentCloneReset();
221
205
  this.editorDidClearChanges();
222
206
  }
@@ -231,6 +215,29 @@ SC.ArrayController = SC.Controller.extend(SC.Array,
231
215
  this.contentCloneReset();
232
216
  this.editorDidClearChanges();
233
217
  return true;
218
+ },
219
+
220
+ /** @private
221
+ Returns the object controller for a source value.
222
+ */
223
+ _objectControllerFor: function(obj) {
224
+ var controllers = this._objControllers = this._objControllers || {} ;
225
+ var guid = SC.getGUID(obj) ;
226
+ var ret = controllers[guid] ;
227
+ if (!ret) {
228
+ ret = controllers[guid] = this.controllerForValue(obj) ;
229
+ if (ret) ret.__isArrayController = true ;
230
+ }
231
+ return ret ;
232
+ },
233
+
234
+ /** @private
235
+ Returns the source object for the passed value. If the passed value is a
236
+ controller, this will map back to the sourceo object. Otherwise the object itself
237
+ will be returned.
238
+ */
239
+ _sourceObjectFor: function(obj) {
240
+ return (obj && obj.__isArrayController) ? obj.get('content') : obj ;
234
241
  }
235
242
 
236
243
  });