sproutcore 1.6.0.1-java → 1.7.1.beta-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. data/CHANGELOG +21 -0
  2. data/Gemfile +5 -0
  3. data/Rakefile +26 -13
  4. data/VERSION.yml +2 -2
  5. data/lib/Buildfile +43 -4
  6. data/lib/buildtasks/build.rake +10 -0
  7. data/lib/buildtasks/helpers/file_rule.rb +22 -0
  8. data/lib/buildtasks/helpers/file_rule_list.rb +137 -0
  9. data/lib/buildtasks/manifest.rake +133 -122
  10. data/lib/frameworks/sproutcore/CHANGELOG.md +69 -2
  11. data/lib/frameworks/sproutcore/apps/tests/english.lproj/strings.js +1 -0
  12. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +28 -22
  13. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +9 -5
  14. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js +1 -1
  15. data/lib/frameworks/sproutcore/frameworks/core_foundation/controls/button.js +18 -13
  16. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/bind.js +5 -3
  17. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/collection.js +2 -0
  18. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +80 -0
  19. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +84 -116
  20. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +8 -5
  21. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +157 -157
  22. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +5 -3
  23. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +6 -6
  24. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +10 -7
  25. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/action_support.js +106 -0
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/collection.js +18 -0
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +71 -1
  28. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/attribute_bindings_test.js +38 -0
  29. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/class_name_bindings_test.js +47 -0
  30. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutChildViews.js +18 -18
  31. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +42 -10
  32. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +158 -1
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +26 -1
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +14 -8
  35. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +15 -2
  36. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +108 -108
  37. data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +1 -1
  38. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +2 -4
  39. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/error_methods.js +2 -2
  40. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +26 -0
  41. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/builders.js +7 -0
  42. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/error_methods.js +1 -1
  43. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +4 -1
  44. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/tests/system/datetime.js +6 -0
  45. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +26 -5
  46. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +97 -96
  47. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +4 -3
  48. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +17 -4
  49. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +7 -7
  50. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +7 -5
  51. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +12 -3
  52. data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +23 -14
  53. data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +5 -1
  54. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/render_delegates/menu_scroller.js +28 -0
  55. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/tests/menu/scroll.js +235 -0
  56. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroll.js +363 -0
  57. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroller.js +250 -0
  58. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/desktop_scroller.js +92 -0
  59. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/native_scroll.js +25 -0
  60. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/scroll.js +33 -0
  61. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/touch_scroller.js +76 -0
  62. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/integration.js +50 -0
  63. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/methods.js +143 -0
  64. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/ui.js +258 -0
  65. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroll.js +1164 -0
  66. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroller.js +332 -0
  67. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroll.js +236 -0
  68. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroller.js +347 -0
  69. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroll.js +15 -0
  70. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroller.js +10 -0
  71. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroll.js +804 -0
  72. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroller.js +133 -0
  73. data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +3 -3
  74. data/lib/frameworks/sproutcore/frameworks/foundation/validators/number.js +3 -1
  75. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +3 -3
  76. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +2 -1
  77. data/lib/frameworks/sproutcore/frameworks/media/views/controls.js +2 -1
  78. data/lib/frameworks/sproutcore/frameworks/media/views/media_slider.js +2 -4
  79. data/lib/frameworks/sproutcore/frameworks/media/views/mini_controls.js +2 -4
  80. data/lib/frameworks/sproutcore/frameworks/media/views/simple_controls.js +2 -4
  81. data/lib/frameworks/sproutcore/frameworks/media/views/video.js +2 -2
  82. data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +29 -3
  83. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
  84. data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/replace.js +1 -1
  85. data/lib/frameworks/sproutcore/frameworks/runtime/private/property_chain.js +2 -1
  86. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +3 -3
  87. data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +2 -2
  88. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +1 -1
  89. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +2 -2
  90. data/lib/frameworks/sproutcore/themes/legacy_theme/english.lproj/segmented.css +1 -1
  91. data/lib/gen/app/templates/apps/@target_name@/Buildfile +3 -5
  92. data/lib/gen/app/templates/apps/@target_name@/resources/_theme.css +18 -0
  93. data/lib/gen/project/templates/@filename@/Buildfile +2 -2
  94. data/lib/sproutcore.rb +30 -5
  95. data/lib/sproutcore/builders.rb +1 -0
  96. data/lib/sproutcore/builders/chance_file.rb +9 -16
  97. data/lib/sproutcore/builders/html.rb +2 -1
  98. data/lib/sproutcore/builders/minify.rb +4 -35
  99. data/lib/sproutcore/builders/module.rb +38 -1
  100. data/lib/sproutcore/builders/split.rb +63 -0
  101. data/lib/sproutcore/builders/strings.rb +7 -1
  102. data/lib/sproutcore/helpers.rb +1 -1
  103. data/lib/sproutcore/helpers/css_split.rb +190 -0
  104. data/lib/sproutcore/helpers/entry_sorter.rb +2 -0
  105. data/lib/sproutcore/helpers/minifier.rb +40 -16
  106. data/lib/sproutcore/helpers/static_helper.rb +35 -17
  107. data/lib/sproutcore/models/manifest.rb +26 -0
  108. data/lib/sproutcore/models/target.rb +12 -1
  109. data/lib/sproutcore/rack.rb +1 -0
  110. data/lib/sproutcore/rack/proxy.rb +244 -225
  111. data/lib/sproutcore/rack/restrict_ip.rb +67 -0
  112. data/lib/sproutcore/rack/service.rb +8 -2
  113. data/lib/sproutcore/tools.rb +102 -46
  114. data/lib/sproutcore/tools/build.rb +91 -43
  115. data/lib/sproutcore/tools/gen.rb +2 -3
  116. data/lib/sproutcore/tools/manifest.rb +22 -16
  117. data/lib/sproutcore/tools/server.rb +21 -0
  118. data/spec/buildtasks/helpers/accept_list +22 -0
  119. data/spec/buildtasks/helpers/accept_list.rb +128 -0
  120. data/spec/buildtasks/helpers/list.json +11 -0
  121. data/spec/buildtasks/manifest/prepare_build_tasks/chance_2x_spec.rb +1 -39
  122. data/spec/buildtasks/manifest/prepare_build_tasks/chance_spec.rb +0 -38
  123. data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +4 -4
  124. data/spec/buildtasks/manifest/prepare_build_tasks/module_spec.rb +2 -2
  125. data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_indirect_spec.rb +7 -16
  126. data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_spec.rb +7 -17
  127. data/spec/buildtasks/manifest/prepare_build_tasks/packed_spec.rb +11 -6
  128. data/spec/fixtures/builder_tests/Buildfile +2 -1
  129. data/spec/fixtures/builder_tests/apps/module_test/modules/required_module/core.js +0 -0
  130. data/spec/lib/builders/module_spec.rb +1 -1
  131. data/spec/spec_helper.rb +1 -0
  132. data/sproutcore.gemspec +4 -9
  133. data/vendor/chance/lib/chance.rb +25 -6
  134. data/vendor/chance/lib/chance/factory.rb +45 -0
  135. data/vendor/chance/lib/chance/instance.rb +173 -28
  136. data/vendor/chance/lib/chance/instance/data_url.rb +0 -29
  137. data/vendor/chance/lib/chance/instance/slicing.rb +57 -4
  138. data/vendor/chance/lib/chance/instance/spriting.rb +112 -21
  139. data/vendor/chance/lib/chance/parser.rb +80 -52
  140. data/vendor/sproutcore/SCCompiler.jar +0 -0
  141. data/vendor/sproutcore/lib/args4j-2.0.12.jar +0 -0
  142. data/vendor/sproutcore/lib/yuicompressor-2.4.2.jar +0 -0
  143. metadata +84 -25
@@ -279,7 +279,7 @@ SC.Drag = SC.Object.extend(
279
279
  // if all else fails, check to see if the source object is a data source.
280
280
  } else {
281
281
  var source = this.get('source') ;
282
- if (source && SC.typeOf(source.dragDataForType) == SC.T_FUNCTION) {
282
+ if (source && SC.typeOf(source.dragDataForType) === SC.T_FUNCTION) {
283
283
  return source.dragDataForType(this, dataType) ;
284
284
 
285
285
  // no data source found. :(
@@ -701,7 +701,8 @@ SC.Drag = SC.Object.extend(
701
701
  if (!ret) {
702
702
  ret = 1 ;
703
703
  while (x = x.get('parentView')) {
704
- if (dropTargets[SC.guidFor(x)] !== undefined) ret++ ;
704
+ if (dropTargets[SC.guidFor(x)] !== undefined) ret = ret+1 ;
705
+ if(x.isPane && x.isMainPane) ret = ret+10000; // Arbitrary value always have the main pain on top
705
706
  }
706
707
  depth[guid] = ret ;
707
708
  }
@@ -902,7 +903,7 @@ SC.Drag = SC.Object.extend(
902
903
  ret = ret.sort(function(a,b) {
903
904
  var view = a;
904
905
  while (view = view.get('parentView')) {
905
- if (b == view) return -1 ;
906
+ if (b === view) return -1 ;
906
907
  }
907
908
  return 1;
908
909
  }) ;
@@ -17,7 +17,11 @@ var items = [
17
17
  { separator: YES },
18
18
  { title: 'Selected Menu Item…', isChecked: YES, keyEquivalent: 'ctrl_shift_o' },
19
19
  { title: 'Item with Submenu', subMenu: [{ title: 'Submenu item 1' }, { title: 'Submenu item 2'}] },
20
- { title: 'Disabled Menu Item', isEnabled: NO }//,
20
+ { title: 'Disabled Menu Item', isEnabled: NO },
21
+ { separator: YES },
22
+ { title: 'Unique Menu Item Class Per Item', exampleView: SC.MenuItemView.extend({
23
+ classNames: 'custom-menu-item'.w()
24
+ }) }
21
25
  // { isSeparator: YES },
22
26
  // { groupTitle: 'Menu Label', items: [{ title: 'Nested Item' }, { title: 'Nested Item' }] }
23
27
  ];
@@ -166,6 +170,15 @@ test('Custom MenuItemView Class', function() {
166
170
  menu2.remove();
167
171
  });
168
172
 
173
+
174
+ test('Custom MenuItemView Class on an item using itemExampleViewKey', function() {
175
+ equals(menu.get('exampleView'), SC.MenuItemView, 'SC.MenuPane should generate SC.MenuItemViews by default');
176
+ menu.popup();
177
+ ok(menu.$('.custom-menu-item').length === 1, 'SC.MenuPane should generate one instance of a custom class if the item has an exampleView property');
178
+ ok($($('.sc-menu-item')[11]).hasClass('custom-menu-item'), 'The last menu item should have a custom class');
179
+ menu.remove();
180
+ });
181
+
169
182
  test('Basic Submenus', function() {
170
183
  var smallMenu = SC.MenuPane.create({
171
184
  controlSize: SC.SMALL_CONTROL_SIZE,
@@ -227,13 +240,13 @@ test('Automatic Closing', function() {
227
240
 
228
241
  test('keyEquivalents', function() {
229
242
  var keyEquivalents = menu._keyEquivalents;
230
-
231
- // verify that keyEquivalents were mapped correctly and that multiple
243
+
244
+ // verify that keyEquivalents were mapped correctly and that multiple
232
245
  // keyEquivalents work
233
246
  menu.items.forEach(function(item) {
234
247
  var keyEq = item.keyEquivalent, idx, len;
235
248
  if(!keyEq) return;
236
-
249
+
237
250
  if(SC.typeOf(keyEq)===SC.T_ARRAY) {
238
251
  for(idx=0,len=keyEq.length;idx<len;idx++) {
239
252
  ok(keyEquivalents[keyEq[idx]], "keyEquivalent should map to " + keyEq[idx]);
@@ -2158,13 +2158,6 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate, SC.CollectionConte
2158
2158
 
2159
2159
  if(!this.get('isSelectable')) return NO;
2160
2160
 
2161
- info = this.mouseDownInfo = {
2162
- event: ev,
2163
- itemView: itemView,
2164
- contentIndex: contentIndex,
2165
- at: Date.now()
2166
- };
2167
-
2168
2161
  // become first responder if possible.
2169
2162
  this.becomeFirstResponder() ;
2170
2163
 
@@ -2207,6 +2200,13 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate, SC.CollectionConte
2207
2200
  sel = this.get('selection');
2208
2201
  if (sel) sel = sel.indexSetForSource(content);
2209
2202
 
2203
+ info = this.mouseDownInfo = {
2204
+ event: ev,
2205
+ itemView: itemView,
2206
+ contentIndex: contentIndex,
2207
+ at: Date.now()
2208
+ };
2209
+
2210
2210
  isSelected = sel ? sel.contains(contentIndex) : NO;
2211
2211
  info.modifierKeyPressed = modifierKeyPressed = ev.ctrlKey || ev.metaKey ;
2212
2212
 
@@ -54,7 +54,7 @@ SC.MenuItemView = SC.View.extend(SC.ContentDisplay,
54
54
  @default YES
55
55
  */
56
56
  acceptsFirstResponder: YES,
57
-
57
+
58
58
  /**
59
59
  IE only attribute to block bluring of other controls
60
60
 
@@ -140,7 +140,8 @@ SC.MenuItemView = SC.View.extend(SC.ContentDisplay,
140
140
  isModal: NO,
141
141
  isSubMenu: YES,
142
142
  parentMenu: parentMenu,
143
- controlSize: parentMenu.get('controlSize')
143
+ controlSize: parentMenu.get('controlSize'),
144
+ exampleView: parentMenu.get('exampleView')
144
145
  });
145
146
  }
146
147
  }
@@ -302,7 +303,7 @@ SC.MenuItemView = SC.View.extend(SC.ContentDisplay,
302
303
 
303
304
  /**
304
305
  The title from the content property.
305
-
306
+
306
307
  @field
307
308
  @type String
308
309
  @observes content.title
@@ -470,9 +471,10 @@ SC.MenuItemView = SC.View.extend(SC.ContentDisplay,
470
471
  }
471
472
 
472
473
  if(this.get('hasSubMenu')) {
473
- this._subMenuTimer = this.invokeLater(this.showSubMenu,100) ;
474
+ this._subMenuTimer = this.invokeLater(this.showSubMenu, 100) ;
474
475
  }
475
- return YES ;
476
+
477
+ return YES;
476
478
  },
477
479
 
478
480
  /** @private
@@ -1095,7 +1095,16 @@ SC.ScrollView = SC.View.extend({
1095
1095
  if (gen !== this.touchGeneration) return;
1096
1096
 
1097
1097
  var touch = this.touch, itemView;
1098
- if (touch && this.tracking && !this.dragging && !touch.touch.scrollHasEnded) {
1098
+
1099
+ // NOTE! On iPad it is possible that the timer set in touchStart() will not have yet fired and that touchEnd() will
1100
+ // come in in the same Run Loop as the one that started with the call to touchStart(). The bad thing that happens is that
1101
+ // even though we cleared this.touch, occasionally if touchEnd() comes in right at the end of the Run Loop and
1102
+ // then the timer expires and starts a new Run Loop to call beginTouchesInContent(), that this.touch will STILL exist
1103
+ // here. There's no explanation for it, and it's not 100% reproducible, but what happens is that if we try to capture
1104
+ // the touch that has already ended, assignTouch() in RootResponder will check touch.hasEnded and throw an exception.
1105
+
1106
+ // Therefore, don't capture a touch if the touch still exists and hasEnded
1107
+ if (touch && this.tracking && !this.dragging && !touch.touch.scrollHasEnded && !touch.touch.hasEnded) {
1099
1108
  // try to capture the touch
1100
1109
  touch.touch.captureTouch(this, YES);
1101
1110
 
@@ -1270,8 +1279,8 @@ SC.ScrollView = SC.View.extend({
1270
1279
  positionInContentY = ((this._scroll_verticalScrollOffset||0) + touchYInFrame) / this._scale;
1271
1280
 
1272
1281
  // calculate deltas
1273
- var deltaX = positionInContentX - touch.startTouchOffset.x,
1274
- deltaY = positionInContentY - touch.startTouchOffset.y;
1282
+ var deltaX = positionInContentX - touch.startTouchOffsetInContent.x,
1283
+ deltaY = positionInContentY - touch.startTouchOffsetInContent.y;
1275
1284
 
1276
1285
  var isDragging = touch.dragging;
1277
1286
  if (!touch.scrolling.x && Math.abs(deltaX) > touch.scrollTolerance.x && touch.enableScrolling.x) {
@@ -7,8 +7,8 @@
7
7
 
8
8
  /** @class
9
9
 
10
- Used to display an iframe. The source, (specified by the value property) of
11
- the iFrame should be from the same domain. (i.e. the src / value should be
10
+ Used to display an iframe. The source, (specified by the value property) of
11
+ the iFrame should be from the same domain. (i.e. the src / value should be
12
12
  from the same domain) if you want to access the contents of the iframe.
13
13
 
14
14
  @extends SC.View
@@ -17,7 +17,7 @@
17
17
  */
18
18
  SC.WebView = SC.View.extend(SC.Control, {/** @scope SC.WebView.prototype */
19
19
  classNames: 'sc-web-view',
20
-
20
+
21
21
  /**
22
22
  @type Array
23
23
  @default ['value', 'shouldAutoResize']
@@ -27,7 +27,7 @@ SC.WebView = SC.View.extend(SC.Control, {/** @scope SC.WebView.prototype */
27
27
 
28
28
  /**
29
29
  The content of the iframe can be bigger than the size specifed when creating
30
- the view. If you want the view to be auto-resized to the dimensions of the
30
+ the view. If you want the view to be auto-resized to the dimensions of the
31
31
  iframe, then set the value of this property to YES.
32
32
  The web view can be auto resized only if the contents are from the same
33
33
  domain as the parent domain.
@@ -43,23 +43,23 @@ SC.WebView = SC.View.extend(SC.Control, {/** @scope SC.WebView.prototype */
43
43
  */
44
44
  render: function(context, firstTime) {
45
45
  var src = this.get('value'), iframe;
46
-
46
+
47
47
  if (firstTime) {
48
- context.push('<iframe src="' + src +
48
+ context.push('<iframe src="' + src +
49
49
  '" style="position: absolute; width: 100%; height: 100%; border: 0px; margin: 0px; padding: 0px;"></iframe>');
50
- }
50
+ }
51
51
  else if(src!==this._lastSrc) {
52
52
  iframe = this.$('iframe');
53
53
  // clear out the previous src, to force a reload
54
54
  iframe.attr('src', 'javascript:;');
55
55
  iframe.attr('src', src);
56
56
  }
57
-
57
+
58
58
  this._lastSrc = src;
59
59
  },
60
60
 
61
61
  /**
62
- Called when the layer gets created.
62
+ Called when the layer gets created.
63
63
  */
64
64
  didCreateLayer: function() {
65
65
  var f = this.$('iframe');
@@ -67,16 +67,25 @@ SC.WebView = SC.View.extend(SC.Control, {/** @scope SC.WebView.prototype */
67
67
  SC.Event.add(f, 'load', this, this.iframeDidLoad);
68
68
  },
69
69
 
70
+ /**
71
+ Called before the layer gets destroyed.
72
+ */
73
+ willDestroyLayer: function() {
74
+ var f = this.$('iframe');
75
+ // Remove the onload event so that the iframe can be released
76
+ SC.Event.remove(f, 'load', this, this.iframeDidLoad);
77
+ },
70
78
 
71
79
  /** @private
72
80
  Called when iframe onload event is fired.
73
- 1. Resizes the view to fit the contents of the iframe using the
81
+ 1. Resizes the view to fit the contents of the iframe using the
74
82
  scroll width and scroll height of the contents of the iframe
75
-
83
+
76
84
  The iframe contents can be accessed only when the src is from the same
77
85
  domain as the parent document
78
86
  */
79
87
  iframeDidLoad: function() {
88
+
80
89
  //fit the iframe to size of the contents.
81
90
  if (this.get('shouldAutoResize') === YES) {
82
91
  var contentWindow;
@@ -85,13 +94,13 @@ SC.WebView = SC.View.extend(SC.Control, {/** @scope SC.WebView.prototype */
85
94
  contentWindow = iframeElt.contentWindow;
86
95
  if(contentWindow && contentWindow.document && contentWindow.document.documentElement){
87
96
  var docElement = contentWindow.document.documentElement;
88
- // setting the width before the height gives more accurate results..
97
+ // setting the width before the height gives more accurate results..
89
98
  // atleast for the test iframe content i'm using.
90
99
  //TODO: try out document flows other than top to bottom.
91
100
  if (!SC.browser.isIE) {
92
101
  this.$().width(docElement.scrollWidth);
93
- this.$().height(docElement.scrollHeight);
94
- }
102
+ this.$().height(docElement.scrollHeight);
103
+ }
95
104
  else {
96
105
  this.$().width(docElement.scrollWidth + 12);
97
106
  this.$().height(docElement.scrollHeight + 5);
@@ -2,9 +2,13 @@ config :designer, :required => [:runtime, :foundation, :desktop]
2
2
 
3
3
  config :forms, :required => :desktop
4
4
 
5
+ config :scroll_view, :required => [:runtime, :foundation, :desktop]
6
+
7
+ config :menu, :required => [:'experimental/scroll_view']
8
+
5
9
  config :greenhouse,
6
10
  :required => [:sproutcore, :designer, :statechart],
7
11
  :theme => :ace,
8
12
  :css_theme => 'ace.greenhouse'
9
13
 
10
- config :polymorphism, :required => :datastore
14
+ config :polymorphism, :required => :datastore
@@ -0,0 +1,28 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2006-2011 Strobe Inc. and contributors.
4
+ // Portions ©2008-2011 Apple Inc. All rights reserved.
5
+ // License: Licensed under MIT license (see license.js)
6
+ // ==========================================================================
7
+
8
+
9
+ SC.BaseTheme.menuScrollerRenderDelegate = SC.RenderDelegate.create({
10
+ className: 'menu-scroller',
11
+
12
+ render: function (dataSource, context) {
13
+ this.addSizeClassName(dataSource, context);
14
+ context.addClass({
15
+ 'sc-vertical': YES,
16
+ disabled: !dataSource.get('isEnabled')
17
+ });
18
+ context.push('<span class="scrollArrow ' + (dataSource.get('scrollDown') ? 'arrowDown' : 'arrowUp') + '">&nbsp;</span>');
19
+ },
20
+
21
+ update: function (dataSource, context) {
22
+ this.addSizeClassName(dataSource, context);
23
+ context.addClass({
24
+ 'sc-vertical': YES,
25
+ disabled: !dataSource.get('isEnabled')
26
+ });
27
+ }
28
+ });
@@ -0,0 +1,235 @@
1
+ // ==========================================================================
2
+ // Project: SC.MenuScrollView Unit Test
3
+ // Copyright: ©2006-2011 Strobe Inc. and contributors.
4
+ // License: Licensed under MIT license (see license.js)
5
+ // ==========================================================================
6
+ /*globals SC module test ok equals same stop start */
7
+
8
+ var view, pane;
9
+ module("Menu Scroll View", {
10
+ setup: function () {
11
+ SC.RunLoop.begin();
12
+
13
+ var content = ['Dogfish Head',
14
+ 'Delerium',
15
+ 'Smuttynose',
16
+ 'Harpoon',
17
+ 'Bitburger',
18
+ 'Goose Island',
19
+ 'Old Speckled Hen',
20
+ 'Fuller\'s',
21
+ 'Anchor',
22
+ 'Brooklyn',
23
+ 'Lagunitas',
24
+ 'Coney Island'];
25
+
26
+ view = SC.MenuScrollView.create({
27
+ layout: { top: 100, left: 20, height: 100, width: 100 },
28
+ contentView: SC.SourceListView.design({
29
+ content: content
30
+ })
31
+ });
32
+
33
+ pane = SC.MainPane.create();
34
+ pane.appendChild(view);
35
+ pane.append();
36
+
37
+ SC.RunLoop.end();
38
+ },
39
+
40
+ teardown: function () {
41
+ SC.RunLoop.begin();
42
+ pane.remove();
43
+ pane.destroy();
44
+ SC.RunLoop.end();
45
+ }
46
+ });
47
+
48
+ test("menu scroll views cannot scroll horizontally", function () {
49
+ ok(!view.get('hasHorizontalScroller'),
50
+ "the horizontal scroller doesn't exist");
51
+ ok(!view.get('isHorizontalScrollerVisible'),
52
+ "the horizontal scroller shouldn't be visible");
53
+ });
54
+
55
+ test("vertical scroll views cannot scroll horizontally", function () {
56
+ ok(view.get('hasVerticalScroller'),
57
+ "the vertical scroller should exist");
58
+ });
59
+
60
+ test("menu scrollers not visible when content doesn't fill the container", function () {
61
+ SC.RunLoop.begin();
62
+ view.setPath('contentView.content', []);
63
+ SC.RunLoop.end();
64
+
65
+ equals(view.getPath('verticalScrollerView.isVisible'), NO,
66
+ "the top vertical scroller shouldn't be visible");
67
+ equals(view.getPath('verticalScrollerView2.isVisible'), NO,
68
+ "the bottom vertical scroller shouldn't be visible");
69
+ });
70
+
71
+ test("initially, only the bottom menu scroller should be visible", function () {
72
+ equals(view.getPath('verticalScrollerView.isVisible'), NO,
73
+ "the top scroller shouldn't be visible");
74
+ equals(view.getPath('verticalScrollerView2.isVisible'), YES,
75
+ "the bottom scroller should be visible");
76
+ });
77
+
78
+ // ..........................................................
79
+ // autohidesVerticalScrollers => YES
80
+ //
81
+
82
+ // Top scroller visibility
83
+ test("when setting `verticalScrollOffset` to anywhere before the scroller thickness, the top scroller will become invisible", function () {
84
+ view.scrollTo(0, 50);
85
+
86
+ ok(view.getPath('verticalScrollerView.isVisible'),
87
+ "top scroller should be visible");
88
+
89
+ view.scrollTo(0, view.getPath('verticalScrollerView.scrollerThickness'));
90
+ equals(view.get('verticalScrollOffset'), 0,
91
+ "view should be at 0px scroll offset");
92
+ ok(!view.getPath('verticalScrollerView.isVisible'),
93
+ "top scroller should NOT be visible");
94
+
95
+ view.scrollTo(0, 50);
96
+ ok(view.getPath('verticalScrollerView.isVisible'),
97
+ "top scroller should be visible");
98
+
99
+ view.scrollTo(0, view.getPath('verticalScrollerView.scrollerThickness') + 1);
100
+ ok(view.getPath('verticalScrollerView.isVisible'),
101
+ "top scroller should be visible");
102
+
103
+ view.scrollTo(0, 50);
104
+ ok(view.getPath('verticalScrollerView.isVisible'),
105
+ "top scroller should be visible");
106
+
107
+ view.scrollTo(0, view.getPath('verticalScrollerView.scrollerThickness') - 1);
108
+ ok(!view.getPath('verticalScrollerView.isVisible'),
109
+ "top scroller should NOT be visible");
110
+ });
111
+
112
+ // Bottom scroller visibility
113
+ test("when setting `verticalScrollOffset` to anywhere before the scroller thickness, the bottom scroller will become invisible", function () {
114
+ var max = view.get('maximumVerticalScrollOffset');
115
+ ok(view.getPath('verticalScrollerView2.isVisible'),
116
+ "bottom scroller should be visible");
117
+
118
+ // @ bottom
119
+ view.scrollTo(0, max);
120
+ ok(!view.getPath('verticalScrollerView2.isVisible'),
121
+ "bottom scroller should NOT be visible");
122
+
123
+ view.scrollTo(0, 0);
124
+ ok(view.getPath('verticalScrollerView2.isVisible'),
125
+ "bottom scroller should be visible");
126
+
127
+ // just enough so bottom is invisible
128
+ view.scrollTo(0, max - view.getPath('verticalScrollerView2.scrollerThickness') - 1);
129
+ ok(view.getPath('verticalScrollerView2.isVisible'),
130
+ "bottom scroller should be visible");
131
+
132
+ view.scrollTo(0, 0);
133
+ ok(view.getPath('verticalScrollerView2.isVisible'),
134
+ "bottom scroller should be visible");
135
+
136
+ // exactly enough for bottom to be invisible
137
+ view.scrollTo(0, max - view.getPath('verticalScrollerView2.scrollerThickness'));
138
+ ok(!view.getPath('verticalScrollerView2.isVisible'),
139
+ "bottom scroller should NOT be visible");
140
+
141
+ view.scrollTo(0, 0);
142
+ ok(view.getPath('verticalScrollerView2.isVisible'),
143
+ "bottom scroller should be visible");
144
+
145
+ // more than enough for bottom to be invisible
146
+ view.scrollTo(0, max - view.getPath('verticalScrollerView2.scrollerThickness') + 1);
147
+ ok(!view.getPath('verticalScrollerView2.isVisible'),
148
+ "bottom scroller should NOT be visible");
149
+ });
150
+
151
+ test("when the top scroller becomes visible, the vertical scroll offset is adjusted by the scroller thickness", function () {
152
+ view.scrollBy(0, 1);
153
+
154
+ var thickness = view.getPath('verticalScrollerView.scrollerThickness');
155
+
156
+ // check for adjustment
157
+ equals(view.get('verticalScrollOffset'),
158
+ 1 + thickness,
159
+ "the offset should be the scroller thickness + 1");
160
+
161
+ // shouldn't adjust this time
162
+ view.scrollBy(0, 1);
163
+ equals(view.get('verticalScrollOffset'),
164
+ 2 + thickness,
165
+ "the offset should be the scroller thickness + 2");
166
+
167
+ // shouldn't adjust this time
168
+ view.scrollBy(0, -1);
169
+ equals(view.get('verticalScrollOffset'),
170
+ 1 + thickness,
171
+ "the offset should be the scroller thickness + 1");
172
+
173
+ // check for adjustment
174
+ view.scrollBy(0, -1);
175
+ equals(view.get('verticalScrollOffset'), 0,
176
+ "the offset should be 0px");
177
+ });
178
+
179
+ // ..........................................................
180
+ // autohidesVerticalScrollers => NO
181
+ //
182
+
183
+ test("when `autohidesVerticalScrollers` is NO, it will hide both when the content doesn't fill the container", function () {
184
+ view.set('autohidesVerticalScrollers', NO);
185
+ view.tile();
186
+
187
+ SC.RunLoop.begin();
188
+ view.setPath('contentView.content', []);
189
+ SC.RunLoop.end();
190
+
191
+ equals(view.getPath('verticalScrollerView.isVisible'), NO,
192
+ "the top vertical scroller shouldn't be visible");
193
+ equals(view.getPath('verticalScrollerView2.isVisible'), NO,
194
+ "the bottom vertical scroller shouldn't be visible");
195
+ });
196
+
197
+ test("when `autohidesVerticalScrollers` is NO, both scrollers will be shown when the content overflows", function () {
198
+ view.set('autohidesVerticalScrollers', NO);
199
+ view.tile();
200
+
201
+ equals(view.getPath('verticalScrollerView.isVisible'), YES,
202
+ "the top vertical scroller shouldn't be visible");
203
+ equals(view.getPath('verticalScrollerView2.isVisible'), YES,
204
+ "the bottom vertical scroller shouldn't be visible");
205
+ });
206
+
207
+ // ..........................................................
208
+ // autohidesVerticalScroller => NO AND
209
+ // autohidesVerticalScrollers => NO
210
+ //
211
+
212
+ test("when `autohidesVerticalScroller` is NO, it will NOT hide both when the content doesn't fill the container", function () {
213
+ view.set('autohidesVerticalScroller', NO);
214
+ view.set('autohidesVerticalScrollers', NO);
215
+
216
+ SC.RunLoop.begin();
217
+ view.setPath('contentView.content', []);
218
+ SC.RunLoop.end();
219
+
220
+ equals(view.getPath('verticalScrollerView.isVisible'), YES,
221
+ "the top vertical scroller shouldn't be visible");
222
+ equals(view.getPath('verticalScrollerView2.isVisible'), YES,
223
+ "the bottom vertical scroller shouldn't be visible");
224
+ });
225
+
226
+ test("when `autohidesVerticalScroller` is NO, both scrollers will be shown when the content overflows", function () {
227
+ view.set('autohidesVerticalScroller', NO);
228
+ view.set('autohidesVerticalScrollers', NO);
229
+ view.tile();
230
+
231
+ equals(view.getPath('verticalScrollerView.isVisible'), YES,
232
+ "the top vertical scroller shouldn't be visible");
233
+ equals(view.getPath('verticalScrollerView2.isVisible'), YES,
234
+ "the bottom vertical scroller shouldn't be visible");
235
+ });