sproutcore 0.9.11 → 0.9.12

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 (88) hide show
  1. data/History.txt +98 -73
  2. data/Manifest.txt +2 -1
  3. data/README.txt +1 -1
  4. data/Rakefile +8 -8
  5. data/app_generators/sproutcore/USAGE +2 -3
  6. data/app_generators/sproutcore/sproutcore_generator.rb +12 -12
  7. data/app_generators/sproutcore/templates/README +26 -23
  8. data/app_generators/sproutcore/templates/{sc-config.rb → sc-config} +32 -17
  9. data/bin/sc-build +17 -17
  10. data/bin/sc-server +1 -1
  11. data/bin/sproutcore +3 -3
  12. data/clients/sc_test_runner/english.lproj/no_tests.rhtml +0 -1
  13. data/config/hoe.rb +9 -9
  14. data/config/requirements.rb +1 -1
  15. data/frameworks/sproutcore/HISTORY +14 -0
  16. data/frameworks/sproutcore/core.js +1 -1
  17. data/frameworks/sproutcore/english.lproj/theme.css +1 -0
  18. data/frameworks/sproutcore/foundation/binding.js +2 -2
  19. data/frameworks/sproutcore/foundation/timer.js +55 -22
  20. data/frameworks/sproutcore/lib/index.rhtml +2 -3
  21. data/frameworks/sproutcore/models/record.js +204 -63
  22. data/frameworks/sproutcore/tests/models/model.rhtml +360 -0
  23. data/frameworks/sproutcore/views/button/button.js +22 -1
  24. data/frameworks/sproutcore/views/collection/collection.js +6 -2
  25. data/frameworks/sproutcore/views/collection/list.js +1 -0
  26. data/frameworks/sproutcore/views/collection/source_list.js +1 -0
  27. data/frameworks/sproutcore/views/field/text_field.js +11 -2
  28. data/frameworks/sproutcore/views/inline_text_field.js +3 -2
  29. data/frameworks/sproutcore/views/menu_item.js +1 -0
  30. data/frameworks/sproutcore/views/pagination.js +1 -0
  31. data/frameworks/sproutcore/views/view.js +4 -1
  32. data/lib/sproutcore/build_tools/html_builder.rb +36 -36
  33. data/lib/sproutcore/build_tools/resource_builder.rb +55 -54
  34. data/lib/sproutcore/build_tools.rb +12 -12
  35. data/lib/sproutcore/bundle.rb +162 -164
  36. data/lib/sproutcore/bundle_manifest.rb +154 -107
  37. data/lib/sproutcore/generator_helper.rb +23 -23
  38. data/lib/sproutcore/helpers/capture_helper.rb +10 -10
  39. data/lib/sproutcore/helpers/static_helper.rb +39 -26
  40. data/lib/sproutcore/helpers/tag_helper.rb +10 -10
  41. data/lib/sproutcore/helpers/text_helper.rb +36 -36
  42. data/lib/sproutcore/helpers.rb +1 -1
  43. data/lib/sproutcore/jsdoc.rb +10 -10
  44. data/lib/sproutcore/jsmin.rb +14 -14
  45. data/lib/sproutcore/library.rb +135 -87
  46. data/lib/sproutcore/merb/bundle_controller.rb +77 -54
  47. data/lib/sproutcore/merb/router.rb +19 -12
  48. data/lib/sproutcore/merb.rb +1 -1
  49. data/lib/sproutcore/version.rb +1 -1
  50. data/lib/sproutcore/view_helpers.rb +121 -121
  51. data/lib/sproutcore.rb +5 -7
  52. data/sc-config.rb +6 -0
  53. data/sc_generators/client/README +1 -1
  54. data/sc_generators/client/USAGE +1 -2
  55. data/sc_generators/client/client_generator.rb +6 -6
  56. data/sc_generators/client/templates/core.js +2 -2
  57. data/sc_generators/client/templates/english.lproj/body.css +79 -81
  58. data/sc_generators/client/templates/english.lproj/strings.js +1 -2
  59. data/sc_generators/client/templates/main.js +6 -8
  60. data/sc_generators/controller/USAGE +1 -2
  61. data/sc_generators/controller/controller_generator.rb +7 -7
  62. data/sc_generators/controller/templates/controller.js +3 -3
  63. data/sc_generators/controller/templates/test.rhtml +1 -1
  64. data/sc_generators/framework/README +1 -2
  65. data/sc_generators/framework/USAGE +2 -3
  66. data/sc_generators/framework/framework_generator.rb +5 -5
  67. data/sc_generators/framework/templates/core.js +3 -3
  68. data/sc_generators/framework/templates/english.lproj/strings.js +1 -2
  69. data/sc_generators/language/USAGE +1 -2
  70. data/sc_generators/language/language_generator.rb +6 -6
  71. data/sc_generators/language/templates/strings.js +1 -2
  72. data/sc_generators/model/USAGE +1 -2
  73. data/sc_generators/model/model_generator.rb +7 -7
  74. data/sc_generators/model/templates/fixture.js +26 -26
  75. data/sc_generators/model/templates/model.js +5 -5
  76. data/sc_generators/model/templates/test.rhtml +2 -2
  77. data/sc_generators/test/USAGE +1 -2
  78. data/sc_generators/test/templates/test.rhtml +2 -2
  79. data/sc_generators/test/test_generator.rb +6 -6
  80. data/sc_generators/view/USAGE +1 -2
  81. data/sc_generators/view/templates/test.rhtml +2 -2
  82. data/sc_generators/view/templates/view.js +3 -3
  83. data/sc_generators/view/view_generator.rb +7 -7
  84. data/spec/spec.opts +1 -1
  85. data/spec/spec_helper.rb +1 -1
  86. data/spec/sproutcore_spec.rb +3 -3
  87. data/tasks/deployment.rake +4 -4
  88. metadata +4 -3
@@ -0,0 +1,360 @@
1
+ <% # ========================================================================
2
+ # Model Unit Test
3
+ # ========================================================================
4
+ %>
5
+ <% content_for('final') do %>
6
+
7
+ <script>
8
+
9
+ //
10
+ // core.js stub
11
+ //
12
+ ModelTest = SC.Object.create({
13
+
14
+ server: SC.Server.create({ prefix: ['ModelTest'] }),
15
+
16
+ FIXTURES: []
17
+
18
+ }) ;
19
+
20
+ //
21
+ // fixtures stub
22
+ //
23
+ ModelTest.FIXTURES = ModelTest.FIXTURES.concat([
24
+
25
+ { guid: 1,
26
+ type: 'Todo',
27
+ name: "Something to do",
28
+ todoList: 1 // the guid of the todo list object this todo is related to
29
+ },
30
+
31
+ { guid: 2,
32
+ type: 'Todo',
33
+ name: "Something else to do",
34
+ todoList: 1
35
+ },
36
+
37
+ { guid: 3,
38
+ type: 'Todo',
39
+ name: "Gee, I'm busy.",
40
+ todoList: 2
41
+ }
42
+
43
+ ]);
44
+
45
+ ModelTest.FIXTURES = ModelTest.FIXTURES.concat([
46
+
47
+ { guid: 1,
48
+ type: 'TodoList',
49
+ name: "My List"
50
+ },
51
+
52
+ { guid: 2,
53
+ type: 'TodoList',
54
+ name: "My List 2"
55
+ }
56
+
57
+ ]);
58
+
59
+ //
60
+ // model classes
61
+ //
62
+ ModelTest.Todo = SC.Record.extend({
63
+
64
+ todoListType: 'ModelTest.TodoList'
65
+
66
+ }) ;
67
+
68
+ ModelTest.TodoList = SC.Record.extend({
69
+
70
+ todos: SC.Record.hasMany('ModelTest.Todo', 'todoList')
71
+
72
+ }) ;
73
+
74
+ //
75
+ // main.js stub
76
+ //
77
+ ModelTest.server.preload(ModelTest.FIXTURES) ;
78
+
79
+ Test.context("Test model comparisons with numeric guids", {
80
+
81
+ setup: function()
82
+ {
83
+ this.todoList1 = ModelTest.TodoList.find(1);
84
+ this.todoList2 = ModelTest.TodoList.find(2);
85
+ this.todo1 = ModelTest.Todo.find(1);
86
+ this.todo2 = ModelTest.Todo.find(2);
87
+ this.todo3 = ModelTest.Todo.find(3);
88
+ },
89
+
90
+ teardown: function()
91
+ {
92
+ delete this.todoList;
93
+ delete this.todo1;
94
+ delete this.todo2;
95
+ },
96
+
97
+ "Objects should exist in Store": function()
98
+ {
99
+ assertNotNull(this.todoList1);
100
+ assertNotNull(this.todoList2);
101
+ assertNotNull(this.todo1);
102
+ assertNotNull(this.todo2);
103
+ assertNotNull(this.todo3);
104
+ },
105
+
106
+ "Todo 1 and 2 should be related to TodoList 1": function()
107
+ {
108
+ assertIdentical(this.todoList1, this.todo1.get('todoList'));
109
+ assertIdentical(this.todoList1, this.todo2.get('todoList'));
110
+ },
111
+
112
+ "Todo 3 should not be related to TodoList 1": function()
113
+ {
114
+ assertNotIdentical(this.todoList1, this.todo3.get('todoList'));
115
+ },
116
+
117
+ "Todo 3 should be related to TodoList 2": function()
118
+ {
119
+ assertIdentical(this.todoList2, this.todo3.get('todoList'));
120
+ },
121
+
122
+ "Todo 1 and 2 should not be related to TodoList 2": function()
123
+ {
124
+ assertNotIdentical(this.todoList2, this.todo1.get('todoList'));
125
+ assertNotIdentical(this.todoList2, this.todo2.get('todoList'));
126
+ },
127
+
128
+ "TodoList 1 should be related to Todo 1 and 2": function()
129
+ {
130
+ var records = this.todoList1.get('todos').get('records');
131
+ var todosWeWanted = SC.Set.create([this.todo1, this.todo2]);
132
+ var todosWeGot = SC.Set.create();
133
+ var loc = records.length;
134
+
135
+ while(--loc >= 0) {
136
+ var obj = records[loc];
137
+
138
+ assert( todosWeGot.add(obj), "should be no duplicates" );
139
+ assert( todosWeWanted.contains(obj), "should be in set of objects we're expecting to get" );
140
+ }
141
+ },
142
+
143
+ "TodoList 2 should be related to Todo 3": function()
144
+ {
145
+ var records = this.todoList2.get('todos').get('records');
146
+ var todosWeWanted = SC.Set.create([this.todo3]);
147
+ var todosWeGot = SC.Set.create();
148
+ var loc = records.length;
149
+
150
+ while(--loc >= 0) {
151
+ var obj = records[loc];
152
+
153
+ assert( todosWeGot.add(obj), "should be no duplicates" );
154
+ assert( todosWeWanted.contains(obj), "should be in set of objects we're expecting to get" );
155
+ }
156
+ },
157
+
158
+ "Todos should be collectable using guids": function()
159
+ {
160
+ var c = SC.Collection.create({ recordType: ModelTest.Todo, conditions: { todoList: 1 } });
161
+ c.refresh();
162
+ var records = c.records();
163
+ var todosWeWanted = SC.Set.create([this.todo1, this.todo2]);
164
+ var todosWeGot = SC.Set.create();
165
+ var loc = records.length;
166
+
167
+ while(--loc >= 0) {
168
+ var obj = records[loc];
169
+
170
+ assert( todosWeGot.add(obj), "should be no duplicates" );
171
+ assert( todosWeWanted.contains(obj), "should be in set of objects we're expecting to get" );
172
+ }
173
+ },
174
+
175
+ "toString() should show model class name": function()
176
+ {
177
+ var re = /^ModelTest.Todo/;
178
+ assert( this.todo1.toString().match(re), "Todo 1 toString() should start with ModelTest.Todo" );
179
+ }
180
+
181
+ });
182
+
183
+ </script>
184
+
185
+ <script>
186
+
187
+ //
188
+ // core.js stub
189
+ //
190
+ ModelTest2 = SC.Object.create({
191
+
192
+ server: SC.Server.create({ prefix: ['ModelTest2'] }),
193
+
194
+ FIXTURES: []
195
+
196
+ }) ;
197
+
198
+ //
199
+ // fixtures stub
200
+ //
201
+ ModelTest2.FIXTURES = ModelTest2.FIXTURES.concat([
202
+
203
+ { guid: '1',
204
+ type: 'Todo',
205
+ name: "Something to do",
206
+ todoList: '1' // the guid of the todo list object this todo is related to
207
+ },
208
+
209
+ { guid: '2',
210
+ type: 'Todo',
211
+ name: "Something else to do",
212
+ todoList: '1'
213
+ },
214
+
215
+ { guid: '3',
216
+ type: 'Todo',
217
+ name: "Gee, I'm busy.",
218
+ todoList: '2'
219
+ }
220
+
221
+ ]);
222
+
223
+ ModelTest2.FIXTURES = ModelTest2.FIXTURES.concat([
224
+
225
+ { guid: '1',
226
+ type: 'TodoList',
227
+ name: "My List"
228
+ },
229
+
230
+ { guid: '2',
231
+ type: 'TodoList',
232
+ name: "My List 2"
233
+ }
234
+
235
+ ]);
236
+
237
+ //
238
+ // model classes
239
+ //
240
+ ModelTest2.Todo = SC.Record.extend({
241
+
242
+ todoListType: 'ModelTest2.TodoList'
243
+
244
+ }) ;
245
+
246
+ ModelTest2.TodoList = SC.Record.extend({
247
+
248
+ todos: SC.Record.hasMany('ModelTest2.Todo', 'todoList')
249
+
250
+ }) ;
251
+
252
+ //
253
+ // main.js stub
254
+ //
255
+ ModelTest2.server.preload(ModelTest2.FIXTURES) ;
256
+
257
+ Test.context("Test model comparisons with string guids", {
258
+
259
+ setup: function()
260
+ {
261
+ this.todoList1 = ModelTest2.TodoList.find(1);
262
+ this.todoList2 = ModelTest2.TodoList.find(2);
263
+ this.todo1 = ModelTest2.Todo.find(1);
264
+ this.todo2 = ModelTest2.Todo.find(2);
265
+ this.todo3 = ModelTest2.Todo.find(3);
266
+ },
267
+
268
+ teardown: function()
269
+ {
270
+ delete this.todoList;
271
+ delete this.todo1;
272
+ delete this.todo2;
273
+ },
274
+
275
+ "Objects should exist in Store": function()
276
+ {
277
+ assertNotNull(this.todoList1);
278
+ assertNotNull(this.todoList2);
279
+ assertNotNull(this.todo1);
280
+ assertNotNull(this.todo2);
281
+ assertNotNull(this.todo3);
282
+ },
283
+
284
+ "Todo 1 and 2 should be related to TodoList 1": function()
285
+ {
286
+ assertIdentical(this.todoList1, this.todo1.get('todoList'));
287
+ assertIdentical(this.todoList1, this.todo2.get('todoList'));
288
+ },
289
+
290
+ "Todo 3 should not be related to TodoList 1": function()
291
+ {
292
+ assertNotIdentical(this.todoList1, this.todo3.get('todoList'));
293
+ },
294
+
295
+ "Todo 3 should be related to TodoList 2": function()
296
+ {
297
+ assertIdentical(this.todoList2, this.todo3.get('todoList'));
298
+ },
299
+
300
+ "Todo 1 and 2 should not be related to TodoList 2": function()
301
+ {
302
+ assertNotIdentical(this.todoList2, this.todo1.get('todoList'));
303
+ assertNotIdentical(this.todoList2, this.todo2.get('todoList'));
304
+ },
305
+
306
+ "TodoList 1 should be related to Todo 1 and 2": function()
307
+ {
308
+ var records = this.todoList1.get('todos').get('records');
309
+ var todosWeWanted = SC.Set.create([this.todo1, this.todo2]);
310
+ var todosWeGot = SC.Set.create();
311
+ var loc = records.length;
312
+
313
+ // assert( todosWeWanted.contains(this.todo1), "verify SC.Set works properly" );
314
+ // assert( todosWeWanted.contains(this.todo2), "verify SC.Set works properly" );
315
+
316
+ while(--loc >= 0) {
317
+ var obj = records[loc];
318
+
319
+ assert( todosWeGot.add(obj), "should be no duplicates" );
320
+ assert( todosWeWanted.contains(obj), "should be in set of objects we're expecting to get" );
321
+ }
322
+ },
323
+
324
+ "TodoList 2 should be related to Todo 3": function()
325
+ {
326
+ var records = this.todoList2.get('todos').get('records');
327
+ var todosWeWanted = SC.Set.create([this.todo3]);
328
+ var todosWeGot = SC.Set.create();
329
+ var loc = records.length;
330
+
331
+ while(--loc >= 0) {
332
+ var obj = records[loc];
333
+
334
+ assert( todosWeGot.add(obj), "should be no duplicates" );
335
+ assert( todosWeWanted.contains(obj), "should be in set of objects we're expecting to get" );
336
+ }
337
+ },
338
+
339
+ "Todos should be collectable using guids": function()
340
+ {
341
+ var c = SC.Collection.create({ recordType: ModelTest2.Todo, conditions: { todoList: '1' } });
342
+ c.refresh();
343
+ var records = c.records();
344
+ var todosWeWanted = SC.Set.create([this.todo1, this.todo2]);
345
+ var todosWeGot = SC.Set.create();
346
+ var loc = records.length;
347
+
348
+ while(--loc >= 0) {
349
+ var obj = records[loc];
350
+
351
+ assert( todosWeGot.add(obj), "should be no duplicates" );
352
+ assert( todosWeWanted.contains(obj), "should be in set of objects we're expecting to get" );
353
+ }
354
+ }
355
+
356
+ });
357
+
358
+ </script>
359
+
360
+ <% end %>
@@ -367,19 +367,40 @@ SC.ButtonView = SC.View.extend(SC.Control,
367
367
 
368
368
  }.observes('isDefault', 'isCancel'),
369
369
 
370
+
371
+ isMouseDown: false,
372
+
370
373
  // on mouse down, set active only if enabled.
371
374
  /** @private */
372
375
  mouseDown: function(evt) {
373
376
  this.setClassName('active',this.get('isEnabled')) ;
377
+ this._isMouseDown = true;
374
378
  return true ;
375
379
  },
376
380
 
381
+ // remove the active class on mouse down as well
382
+ /** @private */
383
+
384
+ mouseOut: function(evt)
385
+ {
386
+ this.setClassName('active', false);
387
+ return true;
388
+ },
389
+
390
+ // add the active class name if the mouse is down
391
+ // this covers a scenario where the user drags out and back on to a button
392
+ mouseOver: function(evt)
393
+ {
394
+ this.setClassName('active', this._isMouseDown) ;
395
+ return true;
396
+ },
397
+
377
398
  // on mouse up, trigger the action only if we are enabled and the mouse
378
399
  // was released inside the view.
379
400
  /** @private */
380
401
  mouseUp: function(evt) {
381
402
  this.setClassName('active', false) ;
382
-
403
+ this._isMouseDown = false;
383
404
  var tgt = Event.element(evt) ;
384
405
  var inside = false ;
385
406
  while(tgt && (tgt != this.rootElement)) tgt = tgt.parentNode;
@@ -634,7 +634,6 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate,
634
634
 
635
635
  */
636
636
  updateChildren: function(fullUpdate) {
637
-
638
637
  var f ;
639
638
 
640
639
  // if the collection is not presently visible in the window, then there is
@@ -670,6 +669,11 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate,
670
669
  // later but the frame has not actually changed, we don't want to run
671
670
  // updateChildren again.
672
671
  var clippingFrame = this._lastClippingFrame = this.get('clippingFrame') ;
672
+
673
+ // this is a workaround for the clippingFrame bug in ie7 clippingFrame is always returning dimensions 0,0
674
+ if(clippingFrame.width==0 && clippingFrame.height==0){
675
+ clippingFrame = this._lastClippingFrame = f;
676
+ }
673
677
 
674
678
  // STEP 2: Calculate the new range of content to display in
675
679
  // the clipping frame. Determine if we need to do a full update or
@@ -1476,7 +1480,7 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate,
1476
1480
  var content = Array.from(this.get('content')) ;
1477
1481
  var contentIndex = content.indexOf(record) ;
1478
1482
  var groupBy = this.get('groupBy');
1479
- itemView = this._insertItemViewFor(itemView, groupBy, contentIndex);
1483
+ itemView = this._insertItemViewFor(record, groupBy, contentIndex);
1480
1484
  }
1481
1485
  if (itemView) this.scrollToItemView(itemView);
1482
1486
  },
@@ -4,6 +4,7 @@
4
4
 
5
5
  require('views/collection/collection') ;
6
6
  require('views/label');
7
+ require('views/list_item') ;
7
8
 
8
9
  /** @class
9
10
 
@@ -5,6 +5,7 @@
5
5
  require('views/collection/collection') ;
6
6
  require('views/button/disclosure');
7
7
  require('views/source_list_group');
8
+ require('views/list_item') ;
8
9
 
9
10
  SC.BENCHMARK_SOURCE_LIST_VIEW = NO ;
10
11
 
@@ -192,8 +192,17 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
192
192
  _focusOnVisible: function() {
193
193
  if (this.get('isVisibleInWindow') && this._isFocused) {
194
194
  this.rootElement.focus() ;
195
- this.rootElement.select.bind(this.rootElement).delay(0.05);
196
- }
195
+
196
+ if(SC.isIE()){
197
+ var selector = function() {
198
+ Element.select(arguments.callee.it);
199
+ };
200
+ selector.it = this.rootElement;
201
+ setTimeout(selector,0.05);
202
+ } else{
203
+ this.rootElement.select.bind(this.rootElement).delay(0.05);
204
+ }
205
+ }
197
206
  }.observes('isVisibleInWindow'),
198
207
 
199
208
  // THESE ARE DUMMY IMPLEMENTATIONS OF THE REPONDER METHODS FOR KEYBOARD
@@ -6,6 +6,7 @@
6
6
  require('views/view') ;
7
7
  require('mixins/delegate_support') ;
8
8
  require('views/field/text_field') ;
9
+ require('views/field/textarea_field') ;
9
10
  require('mixins/inline_editor_delegate');
10
11
 
11
12
  /**
@@ -289,7 +290,7 @@ SC.InlineTextFieldView = SC.View.extend(SC.DelegateSupport, SC.InlineEditorDeleg
289
290
  /**
290
291
  The actual text field view used for editing.
291
292
  */
292
- field: SC.TextFieldView.extend({
293
+ field: SC.TextareaFieldView.extend({
293
294
 
294
295
  // handle mouseDown event if we are currently editing so that events
295
296
  // don't go any further?
@@ -331,7 +332,7 @@ SC.InlineTextFieldView = SC.View.extend(SC.DelegateSupport, SC.InlineEditorDeleg
331
332
  // then allow the newine to proceed. Otherwise, try to commit the
332
333
  // edit.
333
334
  insertNewline: function(evt) {
334
- if (this.owner_multiline) {
335
+ if (this.owner._multiline) {
335
336
  return arguments.callee.base.call(this, evt) ;
336
337
  } else {
337
338
  this.owner.commitEditing() ;
@@ -76,6 +76,7 @@ SC.MenuItemView = SC.ButtonView.extend({
76
76
  mouseOut: function(evt)
77
77
  {
78
78
  this.set('isDefault', false);
79
+ this.setClassName('active', false);
79
80
  },
80
81
 
81
82
  mouseUp: function(evt)
@@ -5,6 +5,7 @@
5
5
 
6
6
  require('views/view') ;
7
7
  require('controllers/collection') ;
8
+ require('views/button/button') ;
8
9
 
9
10
  /**
10
11
 
@@ -1442,7 +1442,10 @@ SC.View = SC.Responder.extend(SC.PathModule, SC.DelegateSupport,
1442
1442
  if (!isVisibleInWindow) {
1443
1443
  if (pnParent) {
1444
1444
  pnParent.insertBefore(pn, pnSib) ;
1445
- } else SC.window.rootElement.removeChild(pn) ;
1445
+ } else {
1446
+ if(pn.parentNode)
1447
+ SC.window.rootElement.removeChild(pn) ;
1448
+ }
1446
1449
  }
1447
1450
 
1448
1451
  return ret;
@@ -3,68 +3,68 @@ require 'sproutcore/helpers'
3
3
  require 'sproutcore/view_helpers'
4
4
 
5
5
  module SproutCore
6
-
6
+
7
7
  module BuildTools
8
8
 
9
- # Whenever you build an HTML file for a SproutCore client, an instance of
10
- # this class is created to actually process and build the HTML using
11
- # Erubus. If you want to add more methods to use in your HTML files, just
9
+ # Whenever you build an HTML file for a SproutCore client, an instance of
10
+ # this class is created to actually process and build the HTML using
11
+ # Erubus. If you want to add more methods to use in your HTML files, just
12
12
  # include them in HtmlContext.
13
13
  #
14
- class HtmlContext
14
+ class HtmlContext
15
15
 
16
16
  include SproutCore::Helpers::TagHelper
17
17
  include SproutCore::Helpers::TextHelper
18
18
  include SproutCore::Helpers::CaptureHelper
19
19
  include SproutCore::Helpers::StaticHelper
20
20
  include SproutCore::ViewHelpers
21
-
21
+
22
22
  attr_reader :entry, :bundle, :entries, :filename, :language, :library
23
-
23
+
24
24
  def initialize(entry, bundle, deep=true)
25
25
  @entry = nil
26
26
  @language = entry.language
27
27
  @bundle = bundle
28
28
  @library = bundle.library
29
29
 
30
- # Find all of the entries that need to be included. If deep is true,
31
- # the include required bundles. Example composite entries to include
30
+ # Find all of the entries that need to be included. If deep is true,
31
+ # the include required bundles. Example composite entries to include
32
32
  # their members.
33
33
  if deep
34
- @entries = bundle.all_required_bundles.map do |cur_bundle|
34
+ @entries = bundle.all_required_bundles.map do |cur_bundle|
35
35
  ret = (cur_bundle == bundle) ? [entry] : cur_bundle.entries_for(:html, :language => language, :hidden => :include)
36
36
  ret.map do |e|
37
- e.composite? ? e.composite.map { |c| cur_bundle.entry_for(c, :hidden => :include) } : [e]
37
+ e.composite? ? e.composite : [e]
38
38
  end
39
39
  end
40
40
  @entries = @entries.flatten.compact.uniq
41
41
  else
42
- @entries = entry.composite? ? entry.composite.map { |c| x.entry_for(c) } : [entry]
42
+ @entries = entry.composite? ? entry.composite : [entry]
43
43
  end
44
-
45
- # Clean out any composites we might have collected. They have already
44
+
45
+ # Clean out any composites we might have collected. They have already
46
46
  # been expanded. Also clean out any non-localized rhtml files.
47
47
  @entries.reject! { |entry| entry.composite? || (entry.type == :html && !entry.localized?) }
48
-
48
+
49
49
  # Load any helpers before we continue
50
50
  bundle.all_required_bundles.each do |cur_bundle|
51
51
  require_helpers(nil, cur_bundle)
52
52
  end
53
-
53
+
54
54
  end
55
55
 
56
- # Actually builds the HTML file from the entry (actually from any
56
+ # Actually builds the HTML file from the entry (actually from any
57
57
  # composite entries)
58
58
  def build
59
59
 
60
60
  @layout_path = bundle.layout_path
61
-
62
- # Render each filename. By default, the output goes to the resources
61
+
62
+ # Render each filename. By default, the output goes to the resources
63
63
  # string
64
64
  @content_for_resources = ''
65
65
  entries.each { |fn| _render_one(fn) }
66
-
67
- # Finally, render the layout. This should produce the final output to
66
+
67
+ # Finally, render the layout. This should produce the final output to
68
68
  # return
69
69
  input = File.read(@layout_path)
70
70
  return eval(Erubis::Eruby.new.convert(input))
@@ -77,29 +77,29 @@ module SproutCore
77
77
 
78
78
  # avoid double render of layout path
79
79
  return if @entry.source_path == @layout_path
80
-
80
+
81
81
  # render. Result goes into @content_for_resources
82
82
  input = File.read(@entry.source_path)
83
83
  @content_for_resources += eval(Erubis::Eruby.new.convert(input))
84
-
84
+
85
85
  @filename =nil
86
86
  @entry = nil
87
87
  end
88
-
89
-
90
- # Returns the current bundle name. Often useful for generating titles,
88
+
89
+
90
+ # Returns the current bundle name. Often useful for generating titles,
91
91
  # etc.
92
92
  def bundle_name; bundle.bundle_name; end
93
93
 
94
- #### For Rails Compatibility. render() does not do anything useful
95
- # since the new build system is nice about putting things into the right
94
+ #### For Rails Compatibility. render() does not do anything useful
95
+ # since the new build system is nice about putting things into the right
96
96
  # place for output.
97
97
  def render; ''; end
98
-
98
+
99
99
  end
100
-
101
- # Builds an html file for the specified entry. If deep is true, then this
102
- # will also find all of the html entries for any required bundles and
100
+
101
+ # Builds an html file for the specified entry. If deep is true, then this
102
+ # will also find all of the html entries for any required bundles and
103
103
  # include them in the built html file.
104
104
  def self.build_html(entry, bundle, deep=true)
105
105
  context = HtmlContext.new(entry, bundle, deep)
@@ -109,12 +109,12 @@ module SproutCore
109
109
  f = File.open(entry.build_path, 'w')
110
110
  f.write(output)
111
111
  f.close
112
-
112
+
113
113
  end
114
-
114
+
115
115
  # Building a test is just like building a single page except that we do not include
116
116
  # all the other html templates in the project
117
117
  def self.build_test(entry, bundle); build_html(entry, bundle, false); end
118
-
118
+
119
119
  end
120
- end
120
+ end