sproutcore 0.9.0 → 0.9.1

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 (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
  });