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
@@ -1429,7 +1429,7 @@ SC.Query.mixin( /** @scope SC.Query */ {
1429
1429
 
1430
1430
  // pass one or more recordTypes.
1431
1431
  if (recordType && recordType.isEnumerable) {
1432
- opts.recordsTypes = recordType;
1432
+ opts.recordTypes = recordType;
1433
1433
  } else opts.recordType = recordType;
1434
1434
 
1435
1435
  // set conditions and params if needed
@@ -551,9 +551,7 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
551
551
  // otherwise, lookup all storeKeys for the named recordType...
552
552
  } else if (recordType = query.get('expandedRecordTypes')) {
553
553
  sourceKeys = SC.IndexSet.create();
554
- recordType.forEach(function(cur) {
555
- sourceKeys.addEach(store.storeKeysFor(recordType));
556
- });
554
+ sourceKeys.addEach(store.storeKeysFor(recordType));
557
555
  }
558
556
 
559
557
  // loop through storeKeys to determine if it belongs in this query or
@@ -635,7 +633,7 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
635
633
  @type Boolean
636
634
  */
637
635
  isError: function() {
638
- return this.get('status') & SC.Record.ERROR;
636
+ return !!(this.get('status') & SC.Record.ERROR);
639
637
  }.property('status').cacheable(),
640
638
 
641
639
  /**
@@ -45,8 +45,8 @@ test("Verify error methods behave correctly", function() {
45
45
  store.dataSourceDidError(storeKey, SC.Record.GENERIC_ERROR);
46
46
  SC.RunLoop.end();
47
47
 
48
- ok(thing1.get('isError'), "isError on thing1 should be YES");
49
- ok(!thing2.get('isError'), "isError on thing2 should be NO");
48
+ ok((thing1.get('isError') === YES), "isError on thing1 should be YES");
49
+ ok((thing2.get('isError') === NO), "isError on thing2 should be NO");
50
50
 
51
51
  equals(thing1.get('errorObject'), SC.Record.GENERIC_ERROR,
52
52
  "get('errorObject') on thing1 should return the correct error object");
@@ -282,3 +282,29 @@ test("isEditable NO should not fire property change observer", function() {
282
282
  rec5.removeObserver('readOnlyRelatedTo', modifierListener);
283
283
  });
284
284
 
285
+ test("adding toOne pointing to non existing class should throw error", function() {
286
+ var message;
287
+ try {
288
+ MyApp.InvalidModel = SC.Record.extend({
289
+ foo: SC.Record.toOne(MyApp.DoesNotExist)
290
+ });
291
+ } catch (x) {
292
+ message = x;
293
+ }
294
+
295
+ same(message, 'Attempted to create toOne attribute with undefined recordType. Did you forget to sc_require a dependency?');
296
+ });
297
+
298
+ test("adding toMany pointing to non existing class should throw error", function() {
299
+ var message;
300
+ try {
301
+ MyApp.InvalidModel = SC.Record.extend({
302
+ foo: SC.Record.toMany(MyApp.DoesNotExist)
303
+ });
304
+ } catch (x) {
305
+ message = x;
306
+ }
307
+
308
+ same(message, 'Attempted to create toMany attribute with undefined recordType. Did you forget to sc_require a dependency?');
309
+ });
310
+
@@ -144,6 +144,13 @@ function performBasicTests(methodName, loc) {
144
144
  equals(q5, q4, 'second call for different conditions should return cache');
145
145
  });
146
146
 
147
+ test("query with record types and conditions hash", function() {
148
+
149
+ var q = invokeWith([TestRecord, TestRecord2], {});
150
+ queryEquals(q, loc, [TestRecord, TestRecord2], null, 'first query');
151
+
152
+ });
153
+
147
154
  test("query with no record type and with conditions", function() {
148
155
  var q1, q2;
149
156
 
@@ -43,7 +43,7 @@ test("Verify error methods behave correctly", function() {
43
43
  store.dataSourceDidErrorQuery(q, SC.Record.GENERIC_ERROR);
44
44
  SC.RunLoop.end();
45
45
 
46
- ok(things.get('isError'), "isError on things array should be YES");
46
+ ok((things.get('isError') === YES), "isError on things array should be YES");
47
47
 
48
48
  equals(things.get('errorObject'), SC.Record.GENERIC_ERROR,
49
49
  "get('errorObject') on things array should return the correct error object");
@@ -975,7 +975,10 @@ SC.DateTime.mixin(SC.Comparable,
975
975
  }
976
976
 
977
977
  if (!SC.none(opts.meridian) && !SC.none(opts.hour)) {
978
- if (opts.meridian === 1) opts.hour = (opts.hour + 12) % 24;
978
+ if ((opts.meridian === 1 && opts.hour !== 12)
979
+ || (opts.meridian === 0 && opts.hour === 12)) {
980
+ opts.hour = (opts.hour + 12) % 24;
981
+ }
979
982
  delete opts.meridian;
980
983
  }
981
984
 
@@ -306,6 +306,12 @@ test('parse', function() {
306
306
  timeShouldBeEqualToHash(
307
307
  SC.DateTime.parse('71-01-01 00:00:00', '%y-%m-%d %H:%M:%S'),
308
308
  { year: 1971, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0 });
309
+ timeShouldBeEqualToHash(
310
+ SC.DateTime.parse('71-01-01 12:00 AM', '%y-%m-%d %i:%M %p'),
311
+ { year: 1971, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0 });
312
+ timeShouldBeEqualToHash(
313
+ SC.DateTime.parse('71-01-01 12:00 PM', '%y-%m-%d %i:%M %p'),
314
+ { year: 1971, month: 1, day: 1, hour: 12, minute: 0, second: 0, millisecond: 0 });
309
315
  });
310
316
 
311
317
  test('parse with time zones',function() {
@@ -39,7 +39,7 @@ sc_require('views/menu_item');
39
39
 
40
40
  var menuItems = [
41
41
  { title: 'Menu Item', keyEquivalent: 'ctrl_shift_n' },
42
- { title: 'Checked Menu Item', isChecked: YES, keyEquivalent: 'ctrl_a' },
42
+ { title: 'Checked Menu Item', checkbox: YES, keyEquivalent: 'ctrl_a' },
43
43
  { title: 'Selected Menu Item', keyEquivalent: ['backspace', 'delete'] },
44
44
  { isSeparator: YES },
45
45
  { title: 'Menu Item with Icon', icon: 'inbox', keyEquivalent: 'ctrl_m' },
@@ -249,7 +249,7 @@ SC.MenuPane = SC.PickerPane.extend(
249
249
 
250
250
  /**
251
251
  Disable context menu.
252
-
252
+
253
253
  @property {Boolean}
254
254
  @default NO
255
255
  */
@@ -465,6 +465,15 @@ SC.MenuPane = SC.PickerPane.extend(
465
465
  */
466
466
  itemLayerIdKey: 'layerId',
467
467
 
468
+ /**
469
+ The name of the property that determines whether a unique exampleView should be created for the item .
470
+
471
+ @type String
472
+ @default "exampleView"
473
+ @commonTask Menu Item Properties
474
+ */
475
+ itemExampleViewKey: 'exampleView',
476
+
468
477
  /**
469
478
  The array of keys used by SC.MenuItemView when inspecting your menu items
470
479
  for display properties.
@@ -588,7 +597,7 @@ SC.MenuPane = SC.PickerPane.extend(
588
597
  },
589
598
 
590
599
  /**
591
- Remove the menu pane status from the pane. This will simply set the
600
+ Remove the menu pane status from the pane. This will simply set the
592
601
  `menuPane` on the `rootResponder` to `null.
593
602
 
594
603
  @returns {SC.Pane} receiver
@@ -627,7 +636,7 @@ SC.MenuPane = SC.PickerPane.extend(
627
636
  */
628
637
  createMenuItemViews: function() {
629
638
  var views = [], items = this.get('displayItems'),
630
- exampleView = this.get('exampleView'), item, view,
639
+ exampleView = this.get('exampleView'), item, itemView, view,
631
640
  height, heightKey, separatorKey, defaultHeight, separatorHeight,
632
641
  menuHeight, menuHeightPadding, keyEquivalentKey, keyEquivalent,
633
642
  keyArray, idx, layerIdKey, propertiesHash,
@@ -636,6 +645,7 @@ SC.MenuPane = SC.PickerPane.extend(
636
645
  if (!items) return views; // return an empty array
637
646
  heightKey = this.get('itemHeightKey');
638
647
  separatorKey = this.get('itemSeparatorKey');
648
+ exampleViewKey = this.get('itemExampleViewKey');
639
649
  defaultHeight = this.get('itemHeight');
640
650
  keyEquivalentKey = this.get('itemKeyEquivalentKey');
641
651
  separatorHeight = this.get('itemSeparatorHeight');
@@ -652,16 +662,27 @@ SC.MenuPane = SC.PickerPane.extend(
652
662
  if (!height) {
653
663
  height = item.get(separatorKey) ? separatorHeight : defaultHeight;
654
664
  }
665
+
655
666
  propertiesHash = {
656
667
  layout: { height: height, top: menuHeight },
657
668
  contentDisplayProperties: keyArray,
658
669
  content: item,
659
670
  parentMenu: this
660
671
  };
672
+
661
673
  if(item.get(layerIdKey)) {
662
674
  propertiesHash.layerId = item.get(layerIdKey);
663
675
  }
664
- view = this._menuView.createChildView(exampleView, propertiesHash);
676
+
677
+ // Item has its own exampleView so use it
678
+ itemExampleView = item.get(exampleViewKey);
679
+ if (itemExampleView) {
680
+ itemView = itemExampleView;
681
+ } else {
682
+ itemView = exampleView;
683
+ }
684
+
685
+ view = this._menuView.createChildView(itemView, propertiesHash);
665
686
  views[idx] = view;
666
687
  menuHeight += height;
667
688
  keyEquivalent = item.get(keyEquivalentKey);
@@ -7,9 +7,9 @@
7
7
 
8
8
  sc_require('panes/palette');
9
9
 
10
- /**
10
+ /**
11
11
  Popular customized picker position rules:
12
- default: initiated just below the anchor.
12
+ default: initiated just below the anchor.
13
13
  shift x, y to optimized picker visibility and make sure top-left corner is always visible.
14
14
  menu : same as default rule +
15
15
  default(1,4,3) or custom offset below the anchor for default location to fine tunned visual alignment +
@@ -51,7 +51,7 @@ SC.PICKER_POINTER = 'pointer';
51
51
  */
52
52
  SC.PICKER_MENU_POINTER = 'menu-pointer';
53
53
 
54
- /**
54
+ /**
55
55
  Pointer layout for perfect right/left/top/bottom.
56
56
 
57
57
  @constant
@@ -61,10 +61,10 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
61
61
 
62
62
  /**
63
63
  @class
64
-
64
+
65
65
  Display a non-modal pane that automatically repositions around a view so as
66
66
  to remain visible.
67
-
67
+
68
68
  An `SC.PickerPane` repositions around the view to which it is anchored as the
69
69
  browser window is resized so as to ensure the pane's content remains visible.
70
70
  A picker pane is useful for displaying supplementary information and does not
@@ -82,11 +82,11 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
82
82
  layout: { width: 400, height: 200 },
83
83
  contentView: SC.View.extend({})
84
84
  }).popup(someView);
85
-
85
+
86
86
  This displays the `SC.PickerPane` anchored to `someView`.
87
87
 
88
88
  ## Positioning
89
-
89
+
90
90
  Picker pane positioning can be classified into two broad categories:
91
91
  offset-based and position-based.
92
92
 
@@ -99,66 +99,66 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
99
99
  value the y offset. The third value can be `0` (right) or `3` (bottom),
100
100
  controlling whether the origin of the pane is further offset by the width
101
101
  (in the case of 0) or the height (in the case of 3) of the anchor.
102
-
102
+
103
103
  ### Position-based
104
-
104
+
105
105
  When `preferType` is `SC.PICKER_POINTER` or `SC.PICKER_MENU_POINTER`, then
106
106
  the `preferMatrix` specifies the sides in the order in which you want the
107
107
  `SC.PickerPane` to try to arrange itself around the view to which it is
108
108
  anchored. The fifth element in the `preferMatrix` specifies which side the
109
109
  `SC.PickerPane` should display on when there isn't enough space around any
110
110
  of the preferred sides.
111
-
111
+
112
112
  Anchor sides are defined by their index in `SC.POINTER_LAYOUT`, where right
113
113
  is `0`, left is `1`, top is `2`, and bottom is `3`.
114
-
114
+
115
115
  For example, the `preferMatrix` of `[3, 0, 1, 2, 2]` says: "Display below the
116
116
  anchor (3); if there isn't enough space then display to the right of the anchor (0).
117
117
  If there isn't enough space either below or to the right of the anchor, then appear
118
118
  to the left (1), unless there is also no space on the left, in which case display
119
119
  above the anchor (2)."
120
-
120
+
121
121
  ## Position Rules
122
-
122
+
123
123
  When invoking `.popup()` you can optionally specify a picker position rule with
124
124
  the `preferType` argument.
125
-
125
+
126
126
  If no `preferType` is specified, the picker pane is displayed just below the anchor.
127
127
  The pane will reposition automatically for optimal visibility, ensuring the top-left
128
128
  corner is visible.
129
-
129
+
130
130
  These position rules have the following behaviors:
131
-
131
+
132
132
  ### `SC.PICKER_MENU`
133
-
133
+
134
134
  Positioning is offset-based, with `preferMatrix` defaulting to `[1, 4, 3]`.
135
135
  Furthermore, a minimum left and right padding to window, of 7px and 8px, respectively,
136
136
  is enforced.
137
-
138
-
137
+
138
+
139
139
  ### `SC.PICKER_FIXED`
140
-
140
+
141
141
  Positioning is offset-based, with `preferMatrix` defaulting to `[1, 4, 3]` and
142
142
  skipping `fitPositionToScreen`.
143
-
144
-
143
+
144
+
145
145
  ### `SC.PICKER_POINTER`
146
-
146
+
147
147
  Positioning is position-based, with `preferMatrix` defaulting to `[0, 1, 2, 3, 2]`,
148
148
  i.e. right > left > top > bottom; fallback to top.
149
-
150
-
149
+
150
+
151
151
  ### `SC.PICKER_MENU_POINTER`
152
-
152
+
153
153
  Positioning is position-based, with `preferMatrix` defaulting to `[3, 0, 1, 2, 3]`,
154
154
  i.e. bottom, right, left, top; fallback to bottom.
155
-
156
-
157
-
155
+
156
+
157
+
158
158
  ## Examples
159
-
159
+
160
160
  Examples for applying popular customized picker position rules:
161
-
161
+
162
162
  ### default:
163
163
 
164
164
  SC.PickerPane.create({
@@ -200,7 +200,7 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
200
200
  layout: { width: 400, height: 200 },
201
201
  contentView: SC.View.extend({})
202
202
  }).popup(anchor, SC.PICKER_POINTER);
203
-
203
+
204
204
  Positioning: right (0) > left (1) > top (2) > bottom (3). Fallback to top (2).
205
205
 
206
206
  ### pointer with custom `preferMatrix` of `[3,0,1,2,2]`:
@@ -218,34 +218,34 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
218
218
  layout: { width: 400, height: 200 },
219
219
  contentView: SC.View.extend({})
220
220
  }).popup(anchor, SC.PICKER_MENU_POINTER);
221
-
221
+
222
222
  Positioning: bottom (3) > right (0) > left (1) > top (2). Fallback to bottom (3).
223
-
223
+
224
224
  @extends SC.PalettePane
225
225
  @since SproutCore 1.0
226
226
  */
227
227
  SC.PickerPane = SC.PalettePane.extend(
228
228
  /** @scope SC.PickerPane.prototype */ {
229
-
229
+
230
230
  /**
231
231
  @type Array
232
232
  @default ['sc-picker']
233
233
  @see SC.View#classNames
234
234
  */
235
235
  classNames: ['sc-picker'],
236
-
236
+
237
237
  /**
238
238
  @type Boolean
239
239
  @default YES
240
240
  */
241
241
  isAnchored: YES,
242
-
242
+
243
243
  /**
244
244
  @type Boolean
245
245
  @default YES
246
246
  */
247
247
  isModal: YES,
248
-
248
+
249
249
  /**
250
250
  @type String
251
251
  @default 'perfectRight'
@@ -263,12 +263,12 @@ SC.PickerPane = SC.PalettePane.extend(
263
263
  @default 0
264
264
  */
265
265
  pointerPosY: 0,
266
-
266
+
267
267
  /**
268
- This property will be set to the element (or view.get('layer')) that
269
- triggered your picker to show. You can use this to properly position your
268
+ This property will be set to the element (or view.get('layer')) that
269
+ triggered your picker to show. You can use this to properly position your
270
270
  picker.
271
-
271
+
272
272
  @type HTMLElement
273
273
  @default null
274
274
  */
@@ -281,18 +281,18 @@ SC.PickerPane = SC.PalettePane.extend(
281
281
  @default null
282
282
  */
283
283
  anchorCached: null,
284
-
284
+
285
285
  /**
286
286
  popular customized picker position rule
287
-
287
+
288
288
  @type String
289
289
  @default null
290
290
  */
291
291
  preferType: null,
292
-
292
+
293
293
  /**
294
294
  default/custom offset or position pref matrix for specific preferType
295
-
295
+
296
296
  @type String
297
297
  @default null
298
298
  */
@@ -313,13 +313,13 @@ SC.PickerPane = SC.PalettePane.extend(
313
313
  @default 0
314
314
  */
315
315
  extraRightOffset: 0,
316
-
316
+
317
317
  /**
318
- The target object to invoke the remove action on when the user clicks off the
318
+ The target object to invoke the remove action on when the user clicks off the
319
319
  picker that is to be removed.
320
320
 
321
321
  If you set this target, the action will be called on the target object
322
- directly when the user clicks off the picker. If you leave this property
322
+ directly when the user clicks off the picker. If you leave this property
323
323
  set to null, then the button will search the responder chain for a view that
324
324
  implements the action when the button is pressed instead.
325
325
 
@@ -327,19 +327,19 @@ SC.PickerPane = SC.PalettePane.extend(
327
327
  @default null
328
328
  */
329
329
  removeTarget: null,
330
-
330
+
331
331
  /**
332
332
  The name of the action you want triggered when the user clicks off the
333
- picker pane that is to be removed.
334
-
333
+ picker pane that is to be removed.
334
+
335
335
  This property is used in conjunction with the removeTarget property to execute
336
- a method when the user clicks off the picker pane.
336
+ a method when the user clicks off the picker pane.
337
337
 
338
338
  If you do not set a target, then clicking off the picker pane will cause the
339
339
  responder chain to search for a view that implements the action you name
340
- here, if one was provided.
341
-
342
- Note that this property is optional. If no explicit value is provided then the
340
+ here, if one was provided.
341
+
342
+ Note that this property is optional. If no explicit value is provided then the
343
343
  picker pane will perform the default action which is to simply remove itself.
344
344
 
345
345
  @type String
@@ -373,25 +373,26 @@ SC.PickerPane = SC.PalettePane.extend(
373
373
  },
374
374
 
375
375
  /** @private
376
- The ideal position for a picker pane is just below the anchor that
377
- triggered it + offset of specific preferType. Find that ideal position,
378
- then call fitPositionToScreen to get final position. If anchor is missing,
376
+ The ideal position for a picker pane is just below the anchor that
377
+ triggered it + offset of specific preferType. Find that ideal position,
378
+ then call fitPositionToScreen to get final position. If anchor is missing,
379
379
  fallback to center.
380
- */
380
+ */
381
381
  positionPane: function(useAnchorCached) {
382
382
  useAnchorCached = useAnchorCached && this.get('anchorCached');
383
-
383
+
384
384
  var anchor = useAnchorCached ? this.get('anchorCached') : this.get('anchorElement'),
385
385
  preferType = this.get('preferType'),
386
386
  preferMatrix = this.get('preferMatrix'),
387
387
  layout = this.get('layout'),
388
388
  origin;
389
-
390
-
391
- // usually an anchorElement will be passed. The ideal position is just
389
+
390
+
391
+ // usually an anchorElement will be passed. The ideal position is just
392
392
  // below the anchor + default or custom offset according to preferType.
393
- // If that is not possible, fitPositionToScreen will take care of that for
393
+ // If that is not possible, fitPositionToScreen will take care of that for
394
394
  // other alternative and fallback position.
395
+
395
396
  if (anchor) {
396
397
  if(!useAnchorCached) {
397
398
  anchor = this.computeAnchorRect(anchor);
@@ -405,19 +406,19 @@ SC.PickerPane = SC.PalettePane.extend(
405
406
  case SC.PICKER_MENU:
406
407
  case SC.PICKER_FIXED:
407
408
  if(!preferMatrix || preferMatrix.length !== 3) {
408
- // default below the anchor with fine-tuned visual alignment
409
+ // default below the anchor with fine-tuned visual alignment
409
410
  // for Menu to appear just below the anchorElement.
410
411
  this.set('preferMatrix', [1, 4, 3]) ;
411
412
  }
412
413
 
413
414
  // fine-tuned visual alignment from preferMatrix
414
415
  origin.x += ((this.preferMatrix[2]===0) ? origin.width : 0) + this.preferMatrix[0] ;
415
- origin.y += ((this.preferMatrix[2]===3) ? origin.height : 0) + this.preferMatrix[1];
416
+ origin.y += ((this.preferMatrix[2]===3) ? origin.height : 0) + this.preferMatrix[1];
416
417
  break;
417
418
  default:
418
419
  origin.y += origin.height ;
419
420
  break;
420
- }
421
+ }
421
422
  } else {
422
423
  origin.y += origin.height ;
423
424
  }
@@ -434,10 +435,10 @@ SC.PickerPane = SC.PalettePane.extend(
434
435
 
435
436
  /** @private
436
437
  This method will return ret (x, y, width, height) from a rectangular element
437
- Notice: temp hack for calculating visiable anchor height by counting height
438
+ Notice: temp hack for calculating visiable anchor height by counting height
438
439
  up to window bottom only. We do have 'clippingFrame' supported from view.
439
440
  But since our anchor can be element, we use this solution for now.
440
- */
441
+ */
441
442
  computeAnchorRect: function(anchor) {
442
443
  var bounding, ret, cq,
443
444
  wsize = SC.RootResponder.responder.computeWindowSize();
@@ -482,14 +483,14 @@ SC.PickerPane = SC.PalettePane.extend(
482
483
 
483
484
  /** @private
484
485
  This method will dispatch to the right re-position rule according to preferType
485
- */
486
+ */
486
487
  fitPositionToScreen: function(preferredPosition, picker, anchor) {
487
488
  // get window rect.
488
489
  //if(this._prefPosX && this._prefPosY)
489
-
490
+
490
491
  var wsize = SC.RootResponder.responder.computeWindowSize(),
491
492
  wret = { x: 0, y: 0, width: wsize.width, height: wsize.height } ;
492
-
493
+
493
494
  picker.x = preferredPosition.x ; picker.y = preferredPosition.y ;
494
495
 
495
496
  if(this.preferType) {
@@ -507,13 +508,13 @@ SC.PickerPane = SC.PalettePane.extend(
507
508
  this.setupPointer(anchor);
508
509
  picker = this.fitPositionToScreenPointer(wret, picker, anchor) ;
509
510
  break;
510
-
511
+
511
512
  case SC.PICKER_FIXED:
512
513
  // skip fitPositionToScreen
513
514
  break;
514
515
  default:
515
516
  break;
516
- }
517
+ }
517
518
  } else {
518
519
  // apply default re-position rule
519
520
  picker = this.fitPositionToScreenDefault(wret, picker, anchor) ;
@@ -523,11 +524,11 @@ SC.PickerPane = SC.PalettePane.extend(
523
524
  },
524
525
 
525
526
  /** @private
526
- re-position rule migrated from old SC.OverlayPaneView.
527
+ re-position rule migrated from old SC.OverlayPaneView.
527
528
  shift x, y to optimized picker visibility and make sure top-left corner is always visible.
528
529
  */
529
530
  fitPositionToScreenDefault: function(w, f, a) {
530
- // make sure the right edge fits on the screen. If not, anchor to
531
+ // make sure the right edge fits on the screen. If not, anchor to
531
532
  // right edge of anchor or right edge of window, whichever is closer.
532
533
  if (SC.maxX(f) > w.width) {
533
534
  var mx = Math.max(SC.maxX(a), f.width) ;
@@ -535,7 +536,7 @@ SC.PickerPane = SC.PalettePane.extend(
535
536
  }
536
537
 
537
538
  // if the left edge is off of the screen, try to position at left edge
538
- // of anchor. If that pushes right edge off screen, shift back until
539
+ // of anchor. If that pushes right edge off screen, shift back until
539
540
  // right is on screen or left = 0
540
541
  if (SC.minX(f) < 0) {
541
542
  f.x = SC.minX(Math.max(a,0)) ;
@@ -559,7 +560,7 @@ SC.PickerPane = SC.PalettePane.extend(
559
560
  mx = Math.min(SC.maxY(a), (w.height - a.height)) ;
560
561
  f.y = Math.max(mx, 0) ;
561
562
  }
562
- return f ;
563
+ return f ;
563
564
  },
564
565
 
565
566
  /** @private
@@ -593,7 +594,7 @@ SC.PickerPane = SC.PalettePane.extend(
593
594
 
594
595
  // Make sure we are at least 7 pixels from the left edge of the screen.
595
596
  if( paneFrame.x < 7 ) paneFrame.x = 7;
596
-
597
+
597
598
  if (paneFrame.y < 7) {
598
599
  paneFrame.height += paneFrame.y;
599
600
  paneFrame.y = 7;
@@ -638,7 +639,7 @@ SC.PickerPane = SC.PalettePane.extend(
638
639
  fitPositionToScreenPointer: function(w, f, a) {
639
640
  var offset = [this.pointerOffset[0], this.pointerOffset[1],
640
641
  this.pointerOffset[2], this.pointerOffset[3]];
641
-
642
+
642
643
  // initiate perfect positions matrix
643
644
  // 4 perfect positions: right > left > top > bottom
644
645
  // 2 coordinates: x, y
@@ -653,7 +654,7 @@ SC.PickerPane = SC.PalettePane.extend(
653
654
  [a.x+parseInt((a.width/2)-(f.width/2),0)+f.width, a.y+offset[2]],
654
655
  [a.x+parseInt((a.width/2)-(f.width/2),0)+f.width, a.y+a.height+f.height+offset[3]]];
655
656
  // cutoff of 4 perfect positioned f: top, right, bottom, left (4x4)
656
- var cutoffPrefP =[[prefP1[0][1]>0 ? 0 : 0-prefP1[0][1], prefP2[0][0]<w.width ? 0 : prefP2[0][0]-w.width, prefP2[0][1]<w.height ? 0 : prefP2[0][1]-w.height, prefP1[0][0]>0 ? 0 : 0-prefP1[0][0]],
657
+ var cutoffPrefP =[[prefP1[0][1]>0 ? 0 : 0-prefP1[0][1], prefP2[0][0]<w.width ? 0 : prefP2[0][0]-w.width, prefP2[0][1]<w.height ? 0 : prefP2[0][1]-w.height, prefP1[0][0]>0 ? 0 : 0-prefP1[0][0]],
657
658
  [prefP1[1][1]>0 ? 0 : 0-prefP1[1][1], prefP2[1][0]<w.width ? 0 : prefP2[1][0]-w.width, prefP2[1][1]<w.height ? 0 : prefP2[1][1]-w.height, prefP1[1][0]>0 ? 0 : 0-prefP1[1][0]],
658
659
  [prefP1[2][1]>0 ? 0 : 0-prefP1[2][1], prefP2[2][0]<w.width ? 0 : prefP2[2][0]-w.width, prefP2[2][1]<w.height ? 0 : prefP2[2][1]-w.height, prefP1[2][0]>0 ? 0 : 0-prefP1[2][0]],
659
660
  [prefP1[3][1]>0 ? 0 : 0-prefP1[3][1], prefP2[3][0]<w.width ? 0 : prefP2[3][0]-w.width, prefP2[3][1]<w.height ? 0 : prefP2[3][1]-w.height, prefP1[3][0]>0 ? 0 : 0-prefP1[3][0]]];
@@ -667,12 +668,12 @@ SC.PickerPane = SC.PalettePane.extend(
667
668
  f.x = a.x+parseInt(a.width/2,0);
668
669
  f.y = a.y+parseInt(a.height/2,0)-parseInt(f.height/2,0);
669
670
  this.set('pointerPos', SC.POINTER_LAYOUT[0]+' fallback');
670
- this.set('pointerPosY', parseInt(f.height/2,0)-40);
671
+ this.set('pointerPosY', parseInt(f.height/2,0)-40);
671
672
  } else {
672
673
  f.x = prefP1[m[4]][0];
673
674
  f.y = prefP1[m[4]][1];
674
675
  this.set('pointerPos', SC.POINTER_LAYOUT[m[4]]);
675
- this.set('pointerPosY', 0);
676
+ this.set('pointerPosY', 0);
676
677
  }
677
678
  this.set('pointerPosX', 0);
678
679
 
@@ -719,9 +720,9 @@ SC.PickerPane = SC.PalettePane.extend(
719
720
  i = SC.POINTER_LAYOUT.length;
720
721
  }
721
722
  }
722
- return f ;
723
+ return f ;
723
724
  },
724
-
725
+
725
726
  /** @private
726
727
  This method will set up pointerOffset and preferMatrix according to type
727
728
  and size if not provided explicitly.
@@ -729,7 +730,7 @@ SC.PickerPane = SC.PalettePane.extend(
729
730
  setupPointer: function(a) {
730
731
  var pointerOffset = this.pointerOffset,
731
732
  K = SC.PickerPane;
732
-
733
+
733
734
  // set up pointerOffset according to type and size if not provided explicitly
734
735
  if (!pointerOffset || pointerOffset.length !== 4) {
735
736
  if (this.get('preferType') == SC.PICKER_MENU_POINTER) {
@@ -783,7 +784,7 @@ SC.PickerPane = SC.PalettePane.extend(
783
784
  this.set('preferMatrix', this.get('preferType') == SC.PICKER_MENU_POINTER ? [3,0,1,2,3] : [0,1,2,3,2]) ;
784
785
  }
785
786
  },
786
-
787
+
787
788
  /**
788
789
  @type Array
789
790
  @default ['preferType','pointerPos','pointerPosY']
@@ -820,30 +821,30 @@ SC.PickerPane = SC.PalettePane.extend(
820
821
  mouseDown: function(evt) {
821
822
  return this.modalPaneDidClick(evt);
822
823
  },
823
-
824
+
824
825
  /** @private
825
- internal method to define the range for clicking inside so the picker
826
- won't be clicked away default is the range of contentView frame.
826
+ internal method to define the range for clicking inside so the picker
827
+ won't be clicked away default is the range of contentView frame.
827
828
  Over-write for adjustments. ex: shadow
828
829
  */
829
830
  clickInside: function(frame, evt) {
830
831
  return SC.pointInRect({ x: evt.pageX, y: evt.pageY }, frame);
831
832
  },
832
833
 
833
- /**
834
+ /**
834
835
  Invoked by the root responder. Re-position picker whenever the window resizes.
835
836
  */
836
837
  windowSizeDidChange: function(oldSize, newSize) {
837
838
  this.positionPane();
838
839
  },
839
-
840
+
840
841
  remove: function(){
841
842
  if(this.get('isVisibleInWindow') && this.get('isPaneAttached')) this._showOverflow();
842
843
  return sc_super();
843
844
  },
844
-
845
+
845
846
  /** @private
846
- Internal method to hide the overflow on the body to make sure we don't
847
+ Internal method to hide the overflow on the body to make sure we don't
847
848
  show scrollbars when the picker has shadows, as it's really anoying.
848
849
  */
849
850
  _hideOverflow: function(){
@@ -877,7 +878,7 @@ SC.PickerPane = SC.PalettePane.extend(
877
878
  Default metrics for the different control sizes.
878
879
  */
879
880
 
880
- // Counter to track how many pickers are open. This help us to now when to
881
+ // Counter to track how many pickers are open. This help us to now when to
881
882
  // show/hide the body overflow.
882
883
  SC.PICKERS_OPEN = 0;
883
884