@breakside/jskit 2023.35.0 → 2023.44.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 (66) 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/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/JS/JSHTMLHTTPClient.js +1 -1
  7. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  8. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  9. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  10. package/Info.json +2 -2
  11. package/Node/io.breakside.jskit-bundle.js +2 -2
  12. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  13. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  14. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  15. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  16. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  17. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  18. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  19. package/Root/Frameworks/DOM/Info.yaml +1 -1
  20. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  21. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  22. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  23. package/Root/Frameworks/Foundation/JSHTMLHTTPClient.js +1 -1
  24. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  25. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  26. package/Root/Frameworks/MediaKit/MKAsset+HTML.js +80 -0
  27. package/Root/Frameworks/MediaKit/MKAsset.js +12 -0
  28. package/Root/Frameworks/MediaKit/MKRemoteAsset.js +39 -0
  29. package/Root/Frameworks/MediaKit/MediaKit+HTML.js +2 -1
  30. package/Root/Frameworks/MediaKit/MediaKit.js +17 -1
  31. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTime.js +216 -0
  32. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeAtom.js +157 -0
  33. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeFileType.js +45 -0
  34. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMedia.js +127 -0
  35. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaHandler.js +68 -0
  36. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaHeader.js +50 -0
  37. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaInformation.js +67 -0
  38. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMeta.js +19 -0
  39. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMovie.js +78 -0
  40. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMovieHeader.js +62 -0
  41. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeSampleDescription.js +72 -0
  42. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeSampleTable.js +84 -0
  43. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTimeToSample.js +57 -0
  44. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTrack.js +133 -0
  45. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTrackHeader.js +82 -0
  46. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeUserData.js +19 -0
  47. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  48. package/Root/Frameworks/MediaKitUI/MKVideoView+HTML.js +77 -0
  49. package/Root/Frameworks/MediaKitUI/MKVideoView.js +19 -1
  50. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  51. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  52. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  53. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  54. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  55. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  56. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  57. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  58. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  59. package/Root/Frameworks/UIKit/UIButton.js +29 -10
  60. package/Root/Frameworks/UIKit/UIListView.js +3 -3
  61. package/Root/Frameworks/UIKit/UIMenuView.js +6 -0
  62. package/Root/Frameworks/UIKit/UIPopupButton.js +22 -3
  63. package/Root/Frameworks/UIKit/UISlider.js +4 -2
  64. package/Root/Frameworks/UIKit/UIStackView.js +43 -0
  65. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  66. package/package.json +1 -1
@@ -13,6 +13,7 @@
13
13
  // See the License for the specific language governing permissions and
14
14
  // limitations under the License.
15
15
 
16
+ // #import MediaKit
16
17
  // #import "MKVideoView.js"
17
18
  'use strict';
18
19
 
@@ -25,6 +26,12 @@ MKVideoView.definePropertiesFromExtensions({
25
26
  asset: JSDynamicProperty('_asset', null),
26
27
 
27
28
  setAsset: function(asset){
29
+ if (this._asset === null && asset === null){
30
+ return;
31
+ }
32
+ if (this._asset !== null && this._asset.isEqual(asset)){
33
+ return;
34
+ }
28
35
  this._asset = asset;
29
36
  this._updateVideoSource();
30
37
  },
@@ -72,10 +79,16 @@ MKVideoView.definePropertiesFromExtensions({
72
79
  }
73
80
  if (this._asset === null){
74
81
  this.videoElement.srcObject = null;
82
+ this.videoElement.src = null;
75
83
  }else if (this._asset.isKindOfClass(MKHTMLStream)){
76
84
  this.videoElement.srcObject = this._asset.htmlMediaStream;
85
+ this.videoElement.src = null;
86
+ }else if (this._asset.isKindOfClass(MKRemoteAsset)){
87
+ this.videoElement.srcObject = null;
88
+ this.videoElement.src = this._asset.url.encodedString;
77
89
  }else{
78
90
  this.videoElement.srcObject = null;
91
+ this.videoElement.src = null;
79
92
  }
80
93
  },
81
94
 
@@ -94,10 +107,22 @@ MKVideoView.definePropertiesFromExtensions({
94
107
  this._isWaitingForPlay = true;
95
108
  this.videoElement.play().then(function(){
96
109
  view._isWaitingForPlay = false;
110
+ if (view.delegate && view.delegate.videoViewPlaybackStarted){
111
+ view.delegate.videoViewPlaybackStarted(view);
112
+ }
113
+ if (view._playbackState === MKVideoView.PlaybackState.paused){
114
+ view.videoElement.pause();
115
+ if (view.delegate && view.delegate.videoViewPlaybackPaused){
116
+ view.delegate.videoViewPlaybackPaused(view);
117
+ }
118
+ }
97
119
  }, function(error){
98
120
  logger.error("play() failed: %{error}", error);
99
121
  view._isWaitingForPlay = false;
100
122
  view._playbackState = MKVideoView.PlaybackState.notPlaying;
123
+ if (view.delegate && view.delegate.videoViewPlaybackFailed){
124
+ view.delegate.videoViewPlaybackFailed(view);
125
+ }
101
126
  });
102
127
  }else{
103
128
  logger.warn("play() requested while still waiting for an earlier play()");
@@ -106,6 +131,9 @@ MKVideoView.definePropertiesFromExtensions({
106
131
  case MKVideoView.PlaybackState.paused:
107
132
  if (!this._isWaitingForPlay){
108
133
  this.videoElement.pause();
134
+ if (view.delegate && view.delegate.videoViewPlaybackPaused){
135
+ view.delegate.videoViewPlaybackPaused(view);
136
+ }
109
137
  }else{
110
138
  logger.warn("pause() requested while still waiting for play()");
111
139
  }
@@ -120,6 +148,30 @@ MKVideoView.definePropertiesFromExtensions({
120
148
  this.videoElement.muted = this.muted;
121
149
  },
122
150
 
151
+ playbackTime: JSDynamicProperty(),
152
+ duration: JSReadOnlyProperty(),
153
+
154
+ getPlaybackTime: function(){
155
+ if (this.videoElement !== null){
156
+ return this.videoElement.currentTime;
157
+ }
158
+ return 0;
159
+ },
160
+
161
+ setPlaybackTime: function(playbackTime){
162
+ if (this.videoElement === null){
163
+ return;
164
+ }
165
+ this.videoElement.currentTime = playbackTime;
166
+ },
167
+
168
+ getDuration: function(){
169
+ if (this.videoElement !== null){
170
+ return this.videoElement.duration;
171
+ }
172
+ return 0;
173
+ },
174
+
123
175
  // MARK: - Events
124
176
 
125
177
  handleEvent: function(e){
@@ -129,11 +181,17 @@ MKVideoView.definePropertiesFromExtensions({
129
181
  addEventListeners: function(){
130
182
  this.videoElement.addEventListener("loadmetadata", this);
131
183
  this.videoElement.addEventListener("resize", this);
184
+ this.videoElement.addEventListener("canplaythrough", this);
185
+ this.videoElement.addEventListener("ended", this);
186
+ this.videoElement.addEventListener("timeupdate", this);
132
187
  },
133
188
 
134
189
  removeEventListeners: function(){
135
190
  this.videoElement.removeEventListener("loadmetadata", this);
136
191
  this.videoElement.removeEventListener("resize", this);
192
+ this.videoElement.removeEventListener("canplaythrough", this);
193
+ this.videoElement.removeEventListener("ended", this);
194
+ this.videoElement.removeEventListener("timeupdate", this);
137
195
  },
138
196
 
139
197
  _event_loadmetadata: function(){
@@ -150,6 +208,25 @@ MKVideoView.definePropertiesFromExtensions({
150
208
  }
151
209
  },
152
210
 
211
+ _event_canplaythrough: function(e){
212
+ if (this.delegate && this.delegate.videoViewCanStartPlayback){
213
+ this.delegate.videoViewCanStartPlayback(this);
214
+ }
215
+ },
216
+
217
+ _event_ended: function(e){
218
+ if (this.delegate && this.delegate.videoViewPlaybackPaused){
219
+ this.delegate.videoViewPlaybackPaused(this);
220
+ }
221
+ this._playbackState = MKVideoView.PlaybackState.paused;
222
+ },
223
+
224
+ _event_timeupdate: function(e){
225
+ if (this.delegate && this.delegate.videoViewPlaybackTimeUpdated){
226
+ this.delegate.videoViewPlaybackTimeUpdated(this);
227
+ }
228
+ },
229
+
153
230
  });
154
231
 
155
232
  MKVideoView.layerClass = UIHTMLElementLayer;
@@ -17,12 +17,30 @@
17
17
  'use strict';
18
18
 
19
19
  JSProtocol("MKVideoViewDelegate", JSProtocol, {
20
- videoViewDidChangeResolution: function(videoView){}
20
+ videoViewCanStartPlayback: function(videoView){},
21
+ videoViewDidChangeResolution: function(videoView){},
22
+ videoViewPlaybackStarted: function(videoView){},
23
+ videoViewPlaybackTimeUpdated: function(videoView){},
24
+ videoViewPlaybackPaused: function(videoView){},
25
+ videoViewPlaybackFailed: function(videoView){},
21
26
  });
22
27
 
23
28
  JSClass("MKVideoView", UIView, {
24
29
 
25
30
  playbackState: JSReadOnlyProperty('_playbackState', 0),
31
+ playbackTime: JSDynamicProperty(),
32
+ duration: JSReadOnlyProperty(),
33
+
34
+ getPlaybackTime: function(){
35
+ return 0;
36
+ },
37
+
38
+ setPlaybackTime: function(){
39
+ },
40
+
41
+ getDuration: function(){
42
+ return 0;
43
+ },
26
44
 
27
45
  delegate: null,
28
46
 
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.NotificationKit
3
- JSBundleVersion: 2023.35.0
3
+ JSBundleVersion: 2023.44.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.PDFKit
3
- JSBundleVersion: 2023.35.0
3
+ JSBundleVersion: 2023.44.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.QRKit
3
- JSBundleVersion: 2023.35.0
3
+ JSBundleVersion: 2023.44.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.SearchKit
3
- JSBundleVersion: 2023.35.0
3
+ JSBundleVersion: 2023.44.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.SecurityKit
3
- JSBundleVersion: 2023.35.0
3
+ JSBundleVersion: 2023.44.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: 2023.35.0
3
+ JSBundleVersion: 2023.44.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: 2023.35.0
3
+ JSBundleVersion: 2023.44.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: 2023.35.0
3
+ JSBundleVersion: 2023.44.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: 2023.35.0
3
+ JSBundleVersion: 2023.44.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -350,10 +350,16 @@ UIButton.Styler = Object.create({}, {
350
350
  }
351
351
  });
352
352
 
353
+ UIButton.ImagePlacement = {
354
+ leading: 0,
355
+ trailing: 1,
356
+ };
357
+
353
358
  JSClass("UIButtonStyler", UIControlStyler, {
354
359
 
355
360
  titleInsets: null,
356
361
  titleImageSpacing: 4,
362
+ imagePlacement: UIButton.ImagePlacement.leading,
357
363
  font: null,
358
364
 
359
365
  init: function(){
@@ -369,6 +375,9 @@ JSClass("UIButtonStyler", UIControlStyler, {
369
375
  if (spec.containsKey('titleImageSpacing')){
370
376
  this.titleImageSpacing = spec.valueForKey("titleImageSpacing", Number);
371
377
  }
378
+ if (spec.containsKey('imagePlacement')){
379
+ this.imagePlacement = spec.valueForKey("imagePlacement", UIButton.ImagePlacement);
380
+ }
372
381
  if (spec.containsKey('font')){
373
382
  this.font = spec.valueForKey("font", JSFont);
374
383
  }else{
@@ -441,19 +450,29 @@ JSClass("UIButtonStyler", UIControlStyler, {
441
450
  var contentRect = button.bounds.rectWithInsets(button._titleInsets);
442
451
  if (button._titleLabel !== null){
443
452
  var titleSize = button._titleLabel.intrinsicSize;
444
- var x, y;
453
+ var titleFrame = JSRect(
454
+ contentRect.origin.x,
455
+ contentRect.origin.y + (contentRect.size.height - titleSize.height) / 2,
456
+ contentRect.size.width,
457
+ titleSize.height
458
+ );
445
459
  if (image !== null){
446
460
  var imageScale = contentRect.size.height / image.size.height;
447
- var imageSize = JSSize(image.size.width * imageScale, contentRect.size.height);
448
- button._imageView.frame = JSRect(contentRect.origin, imageSize);
449
- x = contentRect.origin.x + imageSize.width + this.titleImageSpacing;
450
- y = (contentRect.size.height - titleSize.height) / 2;
451
- }else{
452
- x = contentRect.origin.x;
453
- y = (contentRect.size.height - titleSize.height) / 2;
461
+ var imageFrame = JSRect(
462
+ contentRect.origin.x,
463
+ contentRect.origin.y,
464
+ image.size.width * imageScale,
465
+ contentRect.size.height
466
+ );
467
+ titleFrame.size.width = Math.max(0, titleFrame.size.width - imageFrame.size.width - this.titleImageSpacing);
468
+ if (this.imagePlacement === UIButton.ImagePlacement.leading){
469
+ titleFrame.origin.x += imageFrame.size.width + this.titleImageSpacing;
470
+ }else{
471
+ imageFrame.origin.x = Math.max(0, contentRect.origin.x + contentRect.size.width - imageFrame.size.width);
472
+ }
473
+ button._imageView.frame = imageFrame;
454
474
  }
455
- var w = Math.max(0, contentRect.origin.x + contentRect.size.width - x);
456
- button._titleLabel.frame = JSRect(x, contentRect.origin.y + y, w, titleSize.height);
475
+ button._titleLabel.frame = titleFrame;
457
476
  }else if (image !== null){
458
477
  button._imageView.frame = contentRect;
459
478
  }
@@ -3389,8 +3389,8 @@ JSClass("UIListViewDefaultStyler", UIListViewStyler, {
3389
3389
  cell._accessoryView.frame = JSRect(cell._contentView.bounds.size.width - cell._accessoryInsets.right - accessorySize.width, (cell._contentView.bounds.size.height - accessorySize.height) / 2, accessorySize.width, accessorySize.height);
3390
3390
  size.width -= accessorySize.width + cell._accessoryInsets.width;
3391
3391
  }
3392
- if (cell._titleLabel !== null){
3393
- if (cell._detailLabel !== null){
3392
+ if (cell._titleLabel !== null && !cell._titleLabel.hidden){
3393
+ if (cell._detailLabel !== null && !cell._detailLabel.hidden){
3394
3394
  size.height = cell._titleLabel.font.displayLineHeight * (cell._titleLabel.maximumNumberOfLines || 1) + cell._detailLabel.font.displayLineHeight * (cell._detailLabel.maximumNumberOfLines || 1);
3395
3395
  origin.y = Math.floor((cell._contentView.bounds.size.height - size.height) / 2.0);
3396
3396
  size.height = cell._titleLabel.font.displayLineHeight * (cell._titleLabel.maximumNumberOfLines || 1);
@@ -3403,7 +3403,7 @@ JSClass("UIListViewDefaultStyler", UIListViewStyler, {
3403
3403
  origin.y = Math.floor((cell._contentView.bounds.size.height - size.height) / 2.0);
3404
3404
  cell._titleLabel.frame = JSRect(origin, size);
3405
3405
  }
3406
- }else if (cell._detailLabel !== null){
3406
+ }else if (cell._detailLabel !== null && !cell._detailLabel.hidden){
3407
3407
  size.height = cell._detailLabel.font.displayLineHeight * (cell._detailLabel.maximumNumberOfLines || 1);
3408
3408
  cell._detailLabel.frame = JSRect(JSPoint(cell._titleInsets.left, Math.floor((cell._contentView.bounds.size.height - size.height) / 2.0)), size);
3409
3409
  }
@@ -877,6 +877,7 @@ JSClass("UIMenuItemView", UIView, {
877
877
 
878
878
  _createImageView: function(){
879
879
  this._imageView = UIImageView.init();
880
+ this._imageView.scaleMode = UIImageView.ScaleMode.aspectFit;
880
881
  this.insertSubviewBelowSibling(this._imageView, this.titleLabel);
881
882
  return this._imageView;
882
883
  },
@@ -952,6 +953,11 @@ JSClass("UIMenuItemView", UIView, {
952
953
  this.titleLabel.textColor = textColor;
953
954
  if (this._imageView !== null){
954
955
  this._imageView.templateColor = textColor;
956
+ if (!item.enabled && this._imageView.image !== null && this._imageView.image.renderMode === JSImage.RenderMode.original){
957
+ this._imageView.alpha = 0.4;
958
+ }else{
959
+ this._imageView.alpha = 1;
960
+ }
955
961
  }
956
962
  if (this._submenuImageView !== null){
957
963
  this.submenuImageView.templateColor = textColor;
@@ -74,6 +74,7 @@ JSClass("UIPopupButton", UIControl, {
74
74
  UIPopupButton.$super.commonUIControlInit.call(this);
75
75
  this._imageView = UIImageView.init();
76
76
  this._imageView.hidden = true;
77
+ this._imageView.scaleMode = UIImageView.ScaleMode.aspectFit;
77
78
  this._titleLabel = UILabel.init();
78
79
  this._titleLabel.backgroundColor = JSColor.clear;
79
80
  this._titleLabel.font = JSFont.systemFontOfSize(JSFont.Size.normal).fontWithWeight(JSFont.Weight.regular);
@@ -779,6 +780,7 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
779
780
  normalColor: null,
780
781
  disabledColor: null,
781
782
  activeColor: null,
783
+ normalBackgroundColor: null,
782
784
  activeBackgroundColor: null,
783
785
  overBackgroundColor: null,
784
786
  cornerRadius: 0,
@@ -794,6 +796,13 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
794
796
  this._fillInMissingColors();
795
797
  },
796
798
 
799
+ initWithBackgroundColor: function(backgroundColor, color){
800
+ UIPopupButtonCustomStyler.$super.init.call(this);
801
+ this.normalBackgroundColor = backgroundColor;
802
+ this.normalColor = color;
803
+ this._fillInMissingColors();
804
+ },
805
+
797
806
  initWithSpec: function(spec){
798
807
  UIPopupButtonCustomStyler.$super.initWithSpec.call(this, spec);
799
808
  if (spec.containsKey("normalColor")){
@@ -805,6 +814,9 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
805
814
  if (spec.containsKey("activeColor")){
806
815
  this.activeColor = spec.valueForKey("activeColor", JSColor);
807
816
  }
817
+ if (spec.containsKey('normalBackgroundColor')){
818
+ this.normalBackgroundColor = spec.valueForKey("normalBackgroundColor", JSColor);
819
+ }
808
820
  if (spec.containsKey("activeBackgroundColor")){
809
821
  this.activeBackgroundColor = spec.valueForKey("activeBackgroundColor", JSColor);
810
822
  }
@@ -831,11 +843,18 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
831
843
  if (this.titleInsets === null){
832
844
  this.titleInsets = JSInsets.Zero;
833
845
  }
846
+ if (this.normalBackgroundColor !== null){
847
+ if (this.activeBackgroundColor === null){
848
+ this.activeBackgroundColor = this.normalBackgroundColor.colorDarkenedByPercentage(0.2);
849
+ }
850
+ if (this.disabledBackgroundColor === null){
851
+ this.disabledBackgroundColor = this.normalBackgroundColor.colorWithAlpha(0.5);
852
+ }
853
+ }
834
854
  },
835
855
 
836
856
  initializeControl: function(button){
837
857
  button._imageView.automaticRenderMode = JSImage.RenderMode.template;
838
- button._imageView.scaleMode = UIImageView.ScaleMode.center;
839
858
  button._titleLabel.hidden = true;
840
859
  button._indicatorView.hidden = true;
841
860
  button._titleLabel.frame = JSRect.Zero;
@@ -849,7 +868,7 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
849
868
  updateControl: function(button){
850
869
  if (!button.enabled){
851
870
  button._imageView.templateColor = this.disabledColor;
852
- button.backgroundColor = null;
871
+ button.backgroundColor = this.normalBackgroundColor;
853
872
  }else if (button.active){
854
873
  button._imageView.templateColor = this.activeColor;
855
874
  button.backgroundColor = this.activeBackgroundColor;
@@ -858,7 +877,7 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
858
877
  if (this.showsOverState && button.over){
859
878
  button.backgroundColor = this.overBackgroundColor;
860
879
  }else{
861
- button.backgroundColor = null;
880
+ button.backgroundColor = this.normalBackgroundColor;
862
881
  }
863
882
  }
864
883
  },
@@ -87,10 +87,11 @@ JSClass("UISlider", UIControl, {
87
87
  initialOffset: JSPoint.Zero,
88
88
  };
89
89
  this.active = true;
90
+ this.sendActionsForEvents(UIControl.Event.editingDidBegin, event);
90
91
  if (!isOnKnob){
91
92
  this.value = this.valueForPoint(location);
92
93
  this.didChangeValueForBinding('value');
93
- this.sendActionsForEvents(UIControl.Event.valueChanged | UIControl.Event.primaryAction, event);
94
+ this.sendActionsForEvents(UIControl.Event.valueChanged | UIControl.Event.primaryAction | UIControl.Event.editingChanged, event);
94
95
  }else{
95
96
  var valueLocation = this.pointForValue(this._value);
96
97
  this._drag.initialOffset = location.subtracting(valueLocation);
@@ -103,13 +104,14 @@ JSClass("UISlider", UIControl, {
103
104
  if (value !== this._value){
104
105
  this.value = value;
105
106
  this.didChangeValueForBinding('value');
106
- this.sendActionsForEvents(UIControl.Event.valueChanged | UIControl.Event.primaryAction, event);
107
+ this.sendActionsForEvents(UIControl.Event.valueChanged | UIControl.Event.editingChanged | UIControl.Event.primaryAction, event);
107
108
  }
108
109
  },
109
110
 
110
111
  _endSlide: function(event){
111
112
  if (this.active){
112
113
  this.active = false;
114
+ this.sendActionsForEvents(UIControl.Event.editingDidEnd, event);
113
115
  }
114
116
  this._drag = null;
115
117
  },
@@ -502,18 +502,57 @@ JSClass("UIStackViewHorizontalLayoutManager", UIStackViewLayoutManager, {
502
502
 
503
503
  JSClass("UIStackViewHorizontalNoDistributionLayoutManager", UIStackViewHorizontalLayoutManager, {
504
504
 
505
+ sizeView: function(view, maxSize, shrinkToIntrinsicHeight){
506
+ if (view.isKindOfClass(UIStackViewFlexibleSpace)){
507
+ return JSSize(0, 0);
508
+ }
509
+ return UIStackViewHorizontalNoDistributionLayoutManager.$super.sizeView.call(this, view, maxSize, shrinkToIntrinsicHeight);
510
+ },
511
+
505
512
  layoutStackView: function(stackView){
506
513
  var origin = JSPoint(stackView._contentInsets.left, stackView._contentInsets.top);
507
514
  var size;
508
515
  var i, l;
509
516
  var view;
510
517
  var maxViewSize = JSSize(Number.MAX_VALUE, stackView.bounds.size.height - stackView._contentInsets.height);
518
+ var numberOfFlexibleViews = 0;
511
519
  for (i = 0, l = stackView._arrangedSubviews.length; i < l; ++i){
512
520
  view = stackView._arrangedSubviews[i];
513
521
  size = this.sizeView(view, maxViewSize, stackView._alignment !== UIStackView.Alignment.full);
514
522
  view.frame = JSRect(origin, size);
515
523
  if (!view.hidden){
516
524
  origin.x += size.width + stackView._viewSpacing;
525
+ if (view.isKindOfClass(UIStackViewFlexibleSpace)){
526
+ ++numberOfFlexibleViews;
527
+ }
528
+ }
529
+ }
530
+ if (numberOfFlexibleViews > 0){
531
+ var flexibleWidth = stackView.bounds.origin.x + stackView.bounds.size.width - stackView._contentInsets.right - origin.x + stackView._viewSpacing;
532
+ if (flexibleWidth > 0){
533
+ var flexibleViewWidth = Math.floor(flexibleWidth / numberOfFlexibleViews);
534
+ var finalFlexibleViewWidth = flexibleWidth - flexibleViewWidth * (numberOfFlexibleViews - 1);
535
+ var offset = 0;
536
+ var frame;
537
+ var flexibleViewIndex = 0;
538
+ for (i = 0, l = stackView._arrangedSubviews.length; i < l; ++i){
539
+ view = stackView._arrangedSubviews[i];
540
+ frame = JSRect(view.frame);
541
+ frame.origin.x += offset;
542
+ if (!view.hidden){
543
+ if (view.isKindOfClass(UIStackViewFlexibleSpace)){
544
+ ++flexibleViewIndex;
545
+ if (flexibleViewIndex === numberOfFlexibleViews){
546
+ offset += finalFlexibleViewWidth;
547
+ frame.size.width = finalFlexibleViewWidth;
548
+ }else{
549
+ offset += flexibleViewWidth;
550
+ frame.size.width = flexibleViewWidth;
551
+ }
552
+ }
553
+ }
554
+ view.frame = frame;
555
+ }
517
556
  }
518
557
  }
519
558
  this.alignStackView(stackView);
@@ -604,4 +643,8 @@ JSClass("UIStackViewHorizontalEqualDistributionLayoutManager", UIStackViewHorizo
604
643
  stackView.bounds = JSRect(JSPoint.Zero, stackSize);
605
644
  }
606
645
 
646
+ });
647
+
648
+ JSClass("UIStackViewFlexibleSpace", UIView, {
649
+
607
650
  });
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKitTesting
3
- JSBundleVersion: 2023.35.0
3
+ JSBundleVersion: 2023.44.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "node": ">=10.10.0"
10
10
  },
11
11
  "name": "@breakside/jskit",
12
- "version": "2023.35.0",
12
+ "version": "2023.44.0",
13
13
  "license": "SEE LICENSE IN LICENSE.txt",
14
14
  "files": [
15
15
  "*"