@breakside/jskit 2022.9.0 → 2022.22.0

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 (71) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/JS/FNTFontDescriptor.js +9 -6
  5. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  6. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  7. package/Frameworks/Foundation.jsframework/JS/JSEnvironment.js +5 -0
  8. package/Frameworks/Foundation.jsframework/JS/JSHTMLHTTPClient.js +9 -1
  9. package/Frameworks/Foundation.jsframework/JS/JSImage.js +11 -4
  10. package/Frameworks/Foundation.jsframework/JS/JSSynchronizer.js +1 -0
  11. package/Frameworks/Foundation.jsframework/JS/JSURLResponse.js +10 -0
  12. package/Frameworks/Foundation.jsframework/JS/JSUserDefaults.js +14 -1
  13. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  14. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  15. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  16. package/Info.json +2 -2
  17. package/Node/io.breakside.jskit-bundle.js +2 -2
  18. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  19. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  20. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  21. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  22. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  23. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  24. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  25. package/Root/Frameworks/DOM/Info.yaml +1 -1
  26. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  27. package/Root/Frameworks/FontKit/FNTFontDescriptor.js +9 -6
  28. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  29. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  30. package/Root/Frameworks/Foundation/JSEnvironment.js +5 -0
  31. package/Root/Frameworks/Foundation/JSHTMLHTTPClient.js +9 -1
  32. package/Root/Frameworks/Foundation/JSImage.js +11 -4
  33. package/Root/Frameworks/Foundation/JSSynchronizer.js +1 -0
  34. package/Root/Frameworks/Foundation/JSURLResponse.js +10 -0
  35. package/Root/Frameworks/Foundation/JSUserDefaults.js +14 -1
  36. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  37. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  38. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  39. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  40. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  41. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  42. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  43. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  44. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  45. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  46. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  47. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  48. package/Root/Frameworks/UIKit/UIApplication.js +15 -1
  49. package/Root/Frameworks/UIKit/UICollectionReusableView.js +1 -1
  50. package/Root/Frameworks/UIKit/UICollectionView.js +99 -13
  51. package/Root/Frameworks/UIKit/UICollectionViewCell.js +11 -1
  52. package/Root/Frameworks/UIKit/UICollectionViewLayout.js +1 -1
  53. package/Root/Frameworks/UIKit/UIColorPanel.js +4 -1
  54. package/Root/Frameworks/UIKit/UIDraggingSession.js +7 -0
  55. package/Root/Frameworks/UIKit/UIHTMLTextField.js +3 -1
  56. package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +13 -1
  57. package/Root/Frameworks/UIKit/UIMenu.js +12 -5
  58. package/Root/Frameworks/UIKit/UIMenuItem.js +6 -0
  59. package/Root/Frameworks/UIKit/UIMenuView.js +12 -1
  60. package/Root/Frameworks/UIKit/UIPressGestureRecognizer.js +13 -2
  61. package/Root/Frameworks/UIKit/UIScrollView.js +15 -12
  62. package/Root/Frameworks/UIKit/UISegmentedControl.js +15 -0
  63. package/Root/Frameworks/UIKit/UISlider.js +9 -0
  64. package/Root/Frameworks/UIKit/UIStackView.js +16 -0
  65. package/Root/Frameworks/UIKit/UITabView.js +5 -6
  66. package/Root/Frameworks/UIKit/UITextField.js +2 -0
  67. package/Root/Frameworks/UIKit/UIView.js +1 -1
  68. package/Root/Frameworks/UIKit/UIWindow.js +32 -1
  69. package/Root/Frameworks/UIKit/UIWindowServer.js +3 -0
  70. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  71. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SecurityKit
3
- JSBundleVersion: 2022.9.0
3
+ JSBundleVersion: 2022.22.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKit
3
- JSBundleVersion: 2022.9.0
3
+ JSBundleVersion: 2022.22.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKitTesting
3
- JSBundleVersion: 2022.9.0
3
+ JSBundleVersion: 2022.22.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.TestKit
3
- JSBundleVersion: 2022.9.0
3
+ JSBundleVersion: 2022.22.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKit
3
- JSBundleVersion: 2022.9.0
3
+ JSBundleVersion: 2022.22.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -126,7 +126,7 @@ JSClass('UIApplication', UIResponder, {
126
126
  JSFont.Size[size] = Math.round(JSFont.Size[size] * 1.2);
127
127
  }
128
128
  }
129
- this.windowServer.displayServer.registerFontDescriptors(descriptors, function(error){
129
+ this.registerFontDescriptors(descriptors, function(error){
130
130
  completion.call(target, error);
131
131
  }, this);
132
132
  },
@@ -427,9 +427,23 @@ JSClass('UIApplication', UIResponder, {
427
427
  this.windowServer.createMouseEvent(UIEvent.Type.leftMouseUp, event.timestamp, location);
428
428
  },
429
429
 
430
+ // MARK: - Fonts
431
+
432
+ registerFontDescriptor: function(descriptor, completion, target){
433
+ return this.registerFontDescriptors([descriptor], completion, target);
434
+ },
435
+
436
+ registerFontDescriptors: function(descriptors, completion, target){
437
+ return this.windowServer.displayServer.registerFontDescriptors(descriptors, completion, target);
438
+ },
439
+
440
+ // MARK: - URLs
441
+
430
442
  openURL: function(url, options){
431
443
  },
432
444
 
445
+ // MARK: - Environment
446
+
433
447
  getenv: function(name, defaultValue){
434
448
  return this.environment.get(name, defaultValue);
435
449
  },
@@ -69,7 +69,7 @@ JSClass("UICollectionReusableView", UIView, {
69
69
  var view;
70
70
  var i, l;
71
71
  while (stack.length > 0){
72
- view = stack.pop();
72
+ view = stack.shift();
73
73
  if (view.isKindOfClass(UILabel)){
74
74
  return view.text;
75
75
  }
@@ -17,6 +17,7 @@
17
17
  // #import "UIScrollView.js"
18
18
  // #import "UIPlatform.js"
19
19
  // #import "UICollectionViewLayout.js"
20
+ // #import "UIPressGestureRecognizer.js"
20
21
  "use strict";
21
22
 
22
23
  (function(){
@@ -36,7 +37,13 @@ JSProtocol("UICollectionViewDelegate", JSProtocol, {
36
37
  // Dragging cells
37
38
  collectionViewShouldDragCellAtIndexPath: function(collectionView, indexPath){},
38
39
  pasteboardItemsForCollectionViewAtIndexPath: function(collectionView, indexPath){},
39
- collectionViewWillBeginDraggingSession: function(collectionView, session){}
40
+ collectionViewWillBeginDraggingSession: function(collectionView, session){},
41
+
42
+ // Dragging destination
43
+ collectionViewDraggingSessionDidEnter: function(collectionView, sesssion){},
44
+ collectionViewDraggingSessionDidUpdate: function(collectionView, sesssion, indexPath){},
45
+ collectionViewDraggingSessionDidExit: function(collectionView, sesssion){},
46
+ collectionViewPerformDragOperation: function(collectionView, sesssion, operation, indexPath){}
40
47
 
41
48
  });
42
49
 
@@ -288,6 +295,9 @@ JSClass("UICollectionView", UIScrollView, {
288
295
  },
289
296
 
290
297
  reloadCellsAtIndexPaths: function(indexPaths, animator){
298
+ if (this._needsReload){
299
+ return;
300
+ }
291
301
  if (this._visibleElements.length === 0){
292
302
  return;
293
303
  }
@@ -343,6 +353,9 @@ JSClass("UICollectionView", UIScrollView, {
343
353
  deleteCellsAtIndexPaths: function(indexPaths, animation){
344
354
  // TODO:
345
355
  this.reloadData();
356
+ if (this.selectedIndexPaths.length > 0){
357
+ this._setSelectedIndexPaths([], {notifyDelegate: true});
358
+ }
346
359
  },
347
360
 
348
361
  insertSection: function(section, animation){
@@ -361,6 +374,9 @@ JSClass("UICollectionView", UIScrollView, {
361
374
  deleteSections: function(sections, animation){
362
375
  // TODO:
363
376
  this.reloadData();
377
+ if (this.selectedIndexPaths.length > 0){
378
+ this._setSelectedIndexPaths([], {notifyDelegate: true});
379
+ }
364
380
  },
365
381
 
366
382
  // -------------------------------------------------------------------------
@@ -811,6 +827,10 @@ JSClass("UICollectionView", UIScrollView, {
811
827
  if (cell === null){
812
828
  return;
813
829
  }
830
+ this._contextSelectCell(cell, location);
831
+ },
832
+
833
+ _contextSelectCell: function(cell, location){
814
834
  if (this.delegate && this.delegate.menuForCollectionViewCellAtIndexPath){
815
835
  var contextSelectedIndexPaths;
816
836
  if (this._selectionContainsIndexPath(cell.indexPath)){
@@ -834,11 +854,13 @@ JSClass("UICollectionView", UIScrollView, {
834
854
  this._updateVisibleCellStates();
835
855
  },
836
856
 
857
+
837
858
  mouseDragged: function(event){
838
859
  var location = event.locationInView(this);
839
860
  var cell = this._cellHitTest(location);
840
861
  if (this._shouldDrag){
841
862
  var dragItems = [];
863
+ var indexPaths = [];
842
864
  if (cell !== null){
843
865
  var cellItems = [];
844
866
  if (this.allowsMultipleSelection && this._selectionContainsIndexPath(cell.indexPath)){
@@ -850,6 +872,7 @@ JSClass("UICollectionView", UIScrollView, {
850
872
  if (cellItems !== null){
851
873
  dragItems = dragItems.concat(cellItems);
852
874
  }
875
+ indexPaths.push(indexPath);
853
876
  }
854
877
  }
855
878
  }else{
@@ -858,13 +881,14 @@ JSClass("UICollectionView", UIScrollView, {
858
881
  if (cellItems !== null){
859
882
  dragItems = cellItems;
860
883
  }
884
+ indexPaths.push(cell.indexPath);
861
885
  }
862
886
  }
863
887
  }
864
888
  if (dragItems.length > 0){
865
889
  var session = this.beginDraggingSessionWithItems(dragItems, event);
866
890
  if (this.delegate && this.delegate.collectionViewWillBeginDraggingSession){
867
- this.delegate.collectionViewWillBeginDraggingSession(this, session);
891
+ this.delegate.collectionViewWillBeginDraggingSession(this, session, indexPaths, location);
868
892
  }
869
893
  }
870
894
  }else{
@@ -952,7 +976,7 @@ JSClass("UICollectionView", UIScrollView, {
952
976
  this._touch = null;
953
977
  },
954
978
 
955
- _makeTouchActiveCell: function(touch){
979
+ _makeTouchActiveCell: function(touch, waitForLongPress){
956
980
  var location = touch.locationInView(this);
957
981
  var cell = this._cellHitTest(location);
958
982
  if (cell === null){
@@ -964,6 +988,19 @@ JSClass("UICollectionView", UIScrollView, {
964
988
  }
965
989
  cell.active = true;
966
990
  this._touch.cell = cell;
991
+ if (waitForLongPress){
992
+ this._touch.timer = JSTimer.scheduledTimerWithInterval(UIPressGestureRecognizer.PressInterval.long, function(){
993
+ this._touch.timer = null;
994
+ this._longPressCell(location);
995
+ }, this);
996
+ }
997
+ },
998
+
999
+ _longPressCell: function(location){
1000
+ var cell = this._touch.cell;
1001
+ var indexPath = cell.indexPath;
1002
+ this._cancelTouchSelection();
1003
+ this._contextSelectCell(cell, location);
967
1004
  },
968
1005
 
969
1006
  touchesBegan: function(touches, event){
@@ -976,7 +1013,7 @@ JSClass("UICollectionView", UIScrollView, {
976
1013
  cell: null,
977
1014
  timer: JSTimer.scheduledTimerWithInterval(0.05, function(){
978
1015
  this._touch.timer = null;
979
- this._makeTouchActiveCell(touches[0]);
1016
+ this._makeTouchActiveCell(touches[0], true);
980
1017
  }, this)
981
1018
  };
982
1019
  },
@@ -1015,6 +1052,62 @@ JSClass("UICollectionView", UIScrollView, {
1015
1052
  this._cancelTouchSelection();
1016
1053
  },
1017
1054
 
1055
+ // ----------------------------------------------------------------------
1056
+ // MARK: - Drag Destination
1057
+
1058
+ draggingEntered: function(session){
1059
+ if (this.delegate && this.delegate.collectionViewDraggingSessionDidEnter){
1060
+ this.delegate.collectionViewDraggingSessionDidEnter(this, session);
1061
+ }
1062
+ return UIDragOperation.none;
1063
+ },
1064
+
1065
+ draggingUpdated: function(session){
1066
+ var location = this.convertPointFromScreen(session.screenLocation);
1067
+ var indexPath = null;
1068
+ var cell = this._cellHitTest(location);
1069
+ if (cell !== null){
1070
+ indexPath = cell.indexPath;
1071
+ }
1072
+ var operation = UIDragOperation.none;
1073
+ if (this.delegate && this.delegate.collectionViewDraggingSessionDidUpdate){
1074
+ operation = this.delegate.collectionViewDraggingSessionDidUpdate(this, session, indexPath);
1075
+ }
1076
+ if (operation === UIDragOperation.none){
1077
+ this._updateDropTarget(null);
1078
+ }else{
1079
+ this._updateDropTarget(cell);
1080
+ }
1081
+ return operation;
1082
+ },
1083
+
1084
+ draggingExited: function(session){
1085
+ this._updateDropTarget(null);
1086
+ if (this.delegate && this.delegate.collectionViewDraggingSessionDidExit){
1087
+ this.delegate.collectionViewDraggingSessionDidExit(this, session);
1088
+ }
1089
+ },
1090
+
1091
+ performDragOperation: function(session, operation){
1092
+ var location = this.convertPointFromScreen(session.screenLocation);
1093
+ var cell = this._cellHitTest(location);
1094
+ this._updateDropTarget(null);
1095
+ if (cell && this.delegate && this.delegate.collectionViewPerformDragOperation){
1096
+ this.delegate.collectionViewPerformDragOperation(this, session, operation, cell.indexPath);
1097
+ }
1098
+ },
1099
+
1100
+ _updateDropTarget: function(cell){
1101
+ var i, l;
1102
+ var item;
1103
+ for (i = 0, l = this._visibleElements.length; i < l; ++i){
1104
+ item = this._visibleElements[i];
1105
+ if (item.attributes.elementCategory === UICollectionView.ElementCategory.cell){
1106
+ item.view.dropTarget = item.view === cell;
1107
+ }
1108
+ }
1109
+ },
1110
+
1018
1111
  // --------------------------------------------------------------------
1019
1112
  // MARK: - Finding Cells by Location
1020
1113
 
@@ -1114,6 +1207,7 @@ JSClass("UICollectionView", UIScrollView, {
1114
1207
  // MARK: - Scrolling
1115
1208
 
1116
1209
  scrollToCellAtIndexPath: function(indexPath, position){
1210
+ this.layoutIfNeeded();
1117
1211
  if (position === undefined){
1118
1212
  position = UICollectionView.ScrollPosition.auto;
1119
1213
  }
@@ -1222,15 +1316,7 @@ VisibleElement.prototype = Object.create(Function.prototype, {
1222
1316
  indexPath: { value: null, writable: true },
1223
1317
  rect: { value: null, writable: true, configurable: true },
1224
1318
  kind: { value: null, writable: true },
1225
- view: {
1226
- configurable: true,
1227
- set: function(view){
1228
- Object.defineProperty(this, 'view', {value: view});
1229
- },
1230
- get: function(){
1231
- return null;
1232
- }
1233
- },
1319
+ view: { value: null, writable: true },
1234
1320
  state: { value: null, writable: true },
1235
1321
  animation: { value: null, writable: true },
1236
1322
 
@@ -36,6 +36,7 @@ JSClass("UICollectionViewCell", UICollectionReusableView, {
36
36
  active: JSDynamicProperty(null, null, 'isActive'),
37
37
  selected: JSDynamicProperty(null, null, 'isSelected'),
38
38
  contextSelected: JSDynamicProperty(null, null, 'isContextSelected'),
39
+ dropTarget: JSDynamicProperty(null, null, 'isDropTarget'),
39
40
 
40
41
  _updateState: function(newState){
41
42
  if (newState != this._state){
@@ -94,6 +95,14 @@ JSClass("UICollectionViewCell", UICollectionReusableView, {
94
95
  this._toggleState(UICollectionViewCell.State.contextSelected, isContextSelected);
95
96
  },
96
97
 
98
+ isDropTarget: function(){
99
+ return (this._state & UICollectionViewCell.State.dropTarget) === UICollectionViewCell.State.dropTarget;
100
+ },
101
+
102
+ setDropTarget: function(isDropTarget){
103
+ this._toggleState(UICollectionViewCell.State.dropTarget, isDropTarget);
104
+ },
105
+
97
106
  // --------------------------------------------------------------------
98
107
  // MARK: - Accessibility
99
108
 
@@ -117,5 +126,6 @@ UICollectionViewCell.State = {
117
126
  active: 1 << 1,
118
127
  selected: 1 << 2,
119
128
  contextSelected: 1 << 3,
120
- firstUserState: 1 << 4
129
+ dropTarget: 1 << 4,
130
+ firstUserState: 1 << 5
121
131
  };
@@ -35,7 +35,7 @@ JSClass("UICollectionViewLayout", JSObject, {
35
35
  layoutAttributesForCellAtIndexPath: function(indexPath){
36
36
  },
37
37
 
38
- layoutAttributesForSupplimentaryViewAtIndexPath: function(indexPath){
38
+ layoutAttributesForSupplimentaryViewAtIndexPath: function(indexPath, kind){
39
39
  },
40
40
 
41
41
  shouldInvalidateLayoutForBounds: function(bounds){
@@ -257,7 +257,9 @@ JSClass("UIColorPanelViewController", UIViewController, {
257
257
 
258
258
  viewDidAppear: function(animated){
259
259
  UIColorPanelViewController.$super.viewDidAppear.call(this, animated);
260
- this.view.window.firstResponder = this.hexField;
260
+ if (UIDevice.shared !== null && UIDevice.shared.primaryPointerType !== UIUserInterface.PointerType.touch){
261
+ this.view.window.firstResponder = this.hexField;
262
+ }
261
263
  },
262
264
 
263
265
  viewWillDisappear: function(animated){
@@ -656,6 +658,7 @@ JSClass("UIColorPanelViewController", UIViewController, {
656
658
  componentFieldSpacing: 4,
657
659
 
658
660
  contentSizeThatFitsSize: function(maxSize){
661
+ var view = this.view; // force view load
659
662
  var size = JSSize(this.contentInsets.width + 220, this.contentInsets.height);
660
663
  if (size.width > maxSize.width){
661
664
  size.width = maxSize.width;
@@ -83,6 +83,9 @@ JSClass("UIDraggingSession", JSObject, {
83
83
  },
84
84
 
85
85
  cancel: function(){
86
+ if (this.destination){
87
+ this.destination.draggingExited(this);
88
+ }
86
89
  },
87
90
 
88
91
  isValidDestination: function(destination){
@@ -95,6 +98,10 @@ JSClass("UIDraggingSession", JSObject, {
95
98
  this.imageOffset = JSPoint(offset);
96
99
  },
97
100
 
101
+ setImageFromView: function(view, offset){
102
+ this.imageOffset = JSPoint(offset);
103
+ },
104
+
98
105
  centerImageScreenLocation: JSReadOnlyProperty(),
99
106
 
100
107
  getCenterImageScreenLocation: function(){
@@ -239,7 +239,7 @@ JSClass("UIHTMLTextField", UIControl, {
239
239
  this.didChangeValueForBinding('text');
240
240
  this.didChangeValueForBinding('integerValue');
241
241
  this.postAccessibilityNotification(UIAccessibility.Notification.valueChanged);
242
- this.sendActionsForEvents(UIControl.Event.valueChanged);
242
+ this.sendActionsForEvents(UIControl.Event.editingChanged);
243
243
  if (this.delegate && this.delegate.textFieldDidChange){
244
244
  this.delegate.textFieldDidChange(this);
245
245
  }
@@ -904,6 +904,8 @@ UIHTMLTextField.layerClass = UIHTMLElementLayer;
904
904
 
905
905
  UIHTMLTextField.sharedStyleElement = null;
906
906
 
907
+ UIHTMLTextField.Styler = UITextField.Styler;
908
+
907
909
  var htmlInputModeByKeyboardType = {};
908
910
  htmlInputModeByKeyboardType[UITextInput.KeyboardType.default] = "";
909
911
  htmlInputModeByKeyboardType[UITextInput.KeyboardType.url] = "url";
@@ -562,7 +562,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
562
562
  dragend: function(e){
563
563
  // dragend is not cancelable, so no need for preventDefault()
564
564
  if (this._dragImageElement !== null){
565
- if (this._dragImageElement.parentNode !== null){
565
+ if (this._dragImageElement.parentNode !== null && this._createdDragImageElement){
566
566
  this._dragImageElement.parentNode.removeChild(this._dragImageElement);
567
567
  }
568
568
  this._dragImageElement = null;
@@ -839,6 +839,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
839
839
  // MARK: - Drag & Drop Support
840
840
 
841
841
  _dragImageElement: null,
842
+ _createdDragImageElement: false,
842
843
 
843
844
  prerenderDragImage: function(image){
844
845
  // Safari is picky here and requires that the image element be in the document and
@@ -852,6 +853,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
852
853
  imageElement.src = image.htmlURLString();
853
854
  this.rootElement.appendChild(imageElement);
854
855
  this._dragImageElement = imageElement;
856
+ this._createdDragImageElement = true;
855
857
  },
856
858
 
857
859
  createDraggingSessionWithItems: function(items, event, view){
@@ -863,6 +865,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
863
865
  context.element.draggable = true;
864
866
  // Could use a subclass here, but this seems to work too
865
867
  var originalSetImage = session.setImage;
868
+ var originalSetImageFromView = session.setImageFromView;
866
869
  var windowServer = this;
867
870
  Object.defineProperties(session, {
868
871
  setImage: {
@@ -871,6 +874,15 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
871
874
  originalSetImage.call(this, image, imageOffset);
872
875
  windowServer.prerenderDragImage(image);
873
876
  }
877
+ },
878
+ setImageFromView: {
879
+ configurable: true,
880
+ value: function UIHTMLWindowServer_UIDragSession_setImageFromView(view, imageOffset){
881
+ originalSetImageFromView.call(this, view, imageOffset);
882
+ var context = windowServer.displayServer.contextForLayer(view.layer);
883
+ windowServer._dragImageElement = context.element;
884
+ windowServer._createdDragImageElement = false;
885
+ }
874
886
  }
875
887
  });
876
888
  }
@@ -747,10 +747,6 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
747
747
  }
748
748
 
749
749
  // Figure out how much space we have on either side of the target rect
750
- // IMPORTANT: target rect is assumed to leave enough room on at least
751
- // one side. In our two uses cases 1) submenus, and 2) context menus,
752
- // menu must be true because 1) a menu is < 1/3 screen wide, leaving
753
- // at least 1/3 on one side, and 2) context menu rects are Zero size
754
750
  var viewFrame = view.convertRectToScreen(rect);
755
751
 
756
752
  // If our rect if offscreen to the left or right, move it over
@@ -779,6 +775,11 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
779
775
  origin.x = viewFrame.origin.x - size.width;
780
776
  }
781
777
 
778
+ // Adjust our x position if we've overflowed
779
+ if (origin.x < screenMetrics.safeFrame.origin.x){
780
+ origin.x = screenMetrics.safeFrame.origin.x;
781
+ }
782
+
782
783
  // Prefer the y origin at the top of our rect
783
784
  origin.y = viewFrame.origin.y;
784
785
 
@@ -840,9 +841,15 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
840
841
 
841
842
  metricsForScreen: function(screen){
842
843
  var safeFrame = screen.availableFrame.rectWithInsets(4, 7);
844
+ if (screen.traitCollection.horizontalSizeClass === UIUserInterface.SizeClass.compact){
845
+ return {
846
+ safeFrame: safeFrame,
847
+ maximumWidth: Math.floor(safeFrame.size.width * 0.75)
848
+ };
849
+ }
843
850
  return {
844
851
  safeFrame: safeFrame,
845
- maximumWidth: Math.floor(safeFrame.size.width * 0.3)
852
+ maximumWidth: Math.min(450, Math.floor(safeFrame.size.width * 0.5))
846
853
  };
847
854
  },
848
855
 
@@ -101,6 +101,12 @@ JSClass("UIMenuItem", JSObject, {
101
101
  this.target = target || null;
102
102
  },
103
103
 
104
+ initWithView: function(view, action, target){
105
+ this.view = view;
106
+ this.action = action || null;
107
+ this.target = target || null;
108
+ },
109
+
104
110
  initSeparator: function(){
105
111
  this._isSeparator = true;
106
112
  this._isEnabled = false;
@@ -646,9 +646,13 @@ JSClass("UIMenuView", UIView, {
646
646
 
647
647
  addViewForItem: function(item){
648
648
  var view = item.view;
649
+ var separatorInsets = this.menuWindow.itemContentInsets.insetsWithInsets(0, item.menu.showStatusColumn ? (item.menu.font.displayLineHeight + this.menuWindow.itemContentInsets.left) : 0, 0, 0);
650
+ if (UIDevice.shared !== null && UIDevice.shared.primaryPointerType === UIUserInterface.PointerType.touch){
651
+ separatorInsets = JSInsets.Zero;
652
+ }
649
653
  if (view === null){
650
654
  if (item.separator){
651
- view = UIMenuItemSeparatorView.initWithColor(this.menuWindow.separatorColor, this.menuWindow.separatorLineWidth, this.menuWindow.itemContentInsets.insetsWithInsets(0, item.menu.showStatusColumn ? (item.menu.font.displayLineHeight + this.menuWindow.itemContentInsets.left) : 0, 0, 0));
655
+ view = UIMenuItemSeparatorView.initWithColor(this.menuWindow.separatorColor, this.menuWindow.separatorLineWidth, separatorInsets);
652
656
  view.frame = JSRect(0, 0, 1, this.menuWindow.separatorSize);
653
657
  }else{
654
658
  view = UIMenuItemView.init();
@@ -662,6 +666,13 @@ JSClass("UIMenuView", UIView, {
662
666
  view.setItem(item);
663
667
  }
664
668
  }
669
+ if (UIDevice.shared !== null && UIDevice.shared.primaryPointerType === UIUserInterface.PointerType.touch){
670
+ if (!item.separator && this.itemViews.length > 0 && !(this.itemViews[this.itemViews.length - 1] instanceof UIMenuItemSeparatorView)){
671
+ view.borderWidth = 1;
672
+ }
673
+ view.maskedBorders = UIView.Sides.minY;
674
+ view.borderColor = this.menuWindow.separatorColor;
675
+ }
665
676
  view.hidden = item.alternate;
666
677
  this.addSubview(view);
667
678
  this.itemViews.push(view);
@@ -18,14 +18,21 @@
18
18
 
19
19
  JSClass("UIPressGestureRecognizer", UIGestureRecognizer, {
20
20
 
21
+ init: function(){
22
+ UIPressGestureRecognizer.$super.init.call(this);
23
+ this.minimumPressInterval = UIPressGestureRecognizer.PressInterval.long;
24
+ },
25
+
21
26
  initWithSpec: function(spec){
22
27
  UIPressGestureRecognizer.$super.initWithSpec.call(this, spec);
23
28
  if (spec.containsKey("minimumPressInterval")){
24
29
  this.minimumPressInterval = spec.valueForKey("minimumPressInterval");
30
+ }else{
31
+ this.minimumPressInterval = UIPressGestureRecognizer.PressInterval.long;
25
32
  }
26
33
  },
27
34
 
28
- minimumPressInterval: 1.0,
35
+ minimumPressInterval: 0,
29
36
 
30
37
  // MARK: - Events
31
38
 
@@ -106,4 +113,8 @@ JSClass("UIPressGestureRecognizer", UIGestureRecognizer, {
106
113
  this.end(UIGestureRecognizer.State.failed);
107
114
  }
108
115
 
109
- });
116
+ });
117
+
118
+ UIPressGestureRecognizer.PressInterval = {
119
+ long: 1
120
+ };
@@ -37,16 +37,19 @@ JSClass('UIScrollView', UIView, {
37
37
  initWithSpec: function(spec){
38
38
  UIScrollView.$super.initWithSpec.call(this, spec);
39
39
 
40
- // 1. If any subviews were added directly to this view, we'll move them
41
- // to the contentView once it's ready
42
- var contentSubviews = JSCopy(this.subviews);
43
-
44
- // 2. If the content view and scrollers are specified in the spec, create them
45
- // before doing the _commonScrollViewInit, so it won't try to create them itself.
46
- // These properties are optional in the spec, and are typically only provided if
47
- // the user wants to provide specialized customization
40
+ var contentSubviews = [];
41
+
42
+ // If the content view and scrollers are specified in the spec, create them
43
+ // before doing the _commonScrollViewInit, so it won't try to create them itself.
44
+ // These properties are optional in the spec, and are typically only provided if
45
+ // the user wants to provide specialized customization
48
46
  if (spec.containsKey('contentView')){
49
47
  this._contentView = spec.valueForKey("contentView", UIView);
48
+ }else{
49
+ // If any subviews were added directly to this view, and a
50
+ // contentView was not provided, treat the subviews as children
51
+ // of the contentView
52
+ contentSubviews = JSCopy(this.subviews);
50
53
  }
51
54
  if (spec.containsKey('verticalScroller')){
52
55
  this._verticalScroller = spec.valueForKey("verticalScroller", UIScroller);
@@ -59,13 +62,13 @@ JSClass('UIScrollView', UIView, {
59
62
  }
60
63
  this._commonScrollViewInit();
61
64
 
62
- // 3. Finish the work from step #1 after _commonScrollViewInit, when we can be sure that
63
- // a contentView has been created
65
+ // Finish the contentSubvies work after _commonScrollViewInit,
66
+ // when we can be sure that a contentView has been created
64
67
  for (var i = 0, l = contentSubviews.length; i < l; ++i){
65
68
  this._contentView.addSubview(contentSubviews[i]);
66
69
  }
67
70
 
68
- // 4. Handle all the other properties
71
+ // Handle all the other properties
69
72
  if (spec.containsKey('contentInsets')){
70
73
  this.contentInsets = spec.valueForKey("contentInsets", JSInsets);
71
74
  }
@@ -105,7 +108,7 @@ JSClass('UIScrollView', UIView, {
105
108
  this._maxContentOffset = JSPoint.Zero;
106
109
  this._horizontalScroller.addAction("_horizontalScrollerValueChanged", this, UIControl.Event.valueChanged);
107
110
  this._verticalScroller.addAction("_verticalScrollerValueChanged", this, UIControl.Event.valueChanged);
108
- this.addSubview(this._contentView);
111
+ this.insertSubviewAtIndex(this._contentView, 0);
109
112
  this.addSubview(this._verticalScroller);
110
113
  this.addSubview(this._horizontalScroller);
111
114
  this._updateScrollers();
@@ -769,6 +769,21 @@ JSClass("UISegmentedControlDefaultStyler", UISegmentedControlStyler, {
769
769
  }
770
770
  },
771
771
 
772
+ sizeControlToFitSize: function(control, maxSize){
773
+ var intrinsicSize = this.intrinsicSizeOfControl(control);
774
+ var size = JSSize(control.bounds.size);
775
+ if (maxSize.width < Number.MAX_VALUE){
776
+ size.width = maxSize.width;
777
+ }
778
+ if (intrinsicSize.width < maxSize.width){
779
+ size.width = intrinsicSize.width;
780
+ }
781
+ if (intrinsicSize.height < maxSize.height){
782
+ size.height = intrinsicSize.height;
783
+ }
784
+ control.bounds = JSRect(JSPoint.Zero, size);
785
+ },
786
+
772
787
  intrinsicSizeOfControl: function(control){
773
788
  var itemView;
774
789
  var size = JSSize.Zero;