@breakside/jskit 2024.5.0 → 2024.8.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 (53) 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/JSCalendar.js +93 -0
  7. package/Frameworks/Foundation.jsframework/JS/JSDateFormatter.js +1 -3
  8. package/Frameworks/Foundation.jsframework/JS/JSLocale.js +13 -1
  9. package/Frameworks/Foundation.jsframework/JS/JSSynchronizer.js +19 -0
  10. package/Frameworks/Foundation.jsframework/JS/JSTimeZone.js +72 -3
  11. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  12. package/Frameworks/Foundation.jsframework/sources.json +6 -6
  13. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  14. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  15. package/Info.json +2 -2
  16. package/Node/io.breakside.jskit-bundle.js +2 -2
  17. package/Node/jskit +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/Info.yaml +1 -1
  28. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  29. package/Root/Frameworks/Foundation/JSCalendar.js +93 -0
  30. package/Root/Frameworks/Foundation/JSDateFormatter.js +1 -3
  31. package/Root/Frameworks/Foundation/JSLocale.js +13 -1
  32. package/Root/Frameworks/Foundation/JSSynchronizer.js +19 -0
  33. package/Root/Frameworks/Foundation/JSTimeZone.js +72 -3
  34. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  35. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  36. package/Root/Frameworks/MediaKit/MKAsset+HTML.js +38 -9
  37. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  38. package/Root/Frameworks/MediaKitUI/MKVideoView+HTML.js +1 -0
  39. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  40. package/Root/Frameworks/NotificationKit/NKHTMLUserNotificationCenter.js +5 -5
  41. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  42. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  43. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  44. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  45. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  46. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  47. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  48. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  49. package/Root/Frameworks/UIKit/UIApplication.js +16 -0
  50. package/Root/Frameworks/UIKit/UISplitViewController.js +31 -8
  51. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  52. package/Root/Frameworks/UIKitTesting/UIMockApplication.js +2 -0
  53. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Foundation
3
- JSBundleVersion: 2024.5.0
3
+ JSBundleVersion: 2024.8.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -40,6 +40,11 @@ JSClass("JSCalendar", JSObject, {
40
40
  return JSTimeZone.local;
41
41
  },
42
42
 
43
+ setTimezone: function(timezone){
44
+ this._timezone = timezone;
45
+ this.timeZoneChanged();
46
+ },
47
+
43
48
  componentsFromDate: function(units, date, timezone){
44
49
  },
45
50
 
@@ -50,6 +55,93 @@ JSClass("JSCalendar", JSObject, {
50
55
  },
51
56
 
52
57
  dateByAddingComponents: function(addedComponents, toDate){
58
+ },
59
+
60
+ dateChangeTimer: null,
61
+ notificationCenters: null,
62
+ notificationObservers: null,
63
+
64
+ stopSendingNotifications: function(notificationCenter){
65
+ if (this.notificationCenters === null){
66
+ return;
67
+ }
68
+ var i = this.notificationCenters.indexOf(notificationCenter);
69
+ if (i >= 0){
70
+ var observers = this.notificationObservers[i];
71
+ for (var name in observers){
72
+ notificationCenter.removeObserver(name, observers[name]);
73
+ }
74
+ this.notificationCenters.splice(i, 1);
75
+ this.notificationObservers.splice(i, 1);
76
+ }
77
+ if (this.notificationCenters.length === 0){
78
+ this.cancelDayChangeTimer();
79
+ }
80
+ },
81
+
82
+ startSendingNotifications: function(notificationCenter){
83
+ if (this.notificationCenters === null){
84
+ this.notificationCenters = [];
85
+ this.notificationObservers = [];
86
+ }
87
+ var i = this.notificationCenters.indexOf(notificationCenter);
88
+ if (i < 0){
89
+ this.notificationCenters.push(notificationCenter);
90
+ this.notificationObservers.push({
91
+ JSLocalTimeZoneChanged: notificationCenter.addObserver("JSLocalTimeZoneChanged", null, this.timeZoneChanged, this)
92
+ });
93
+ if (this.notificationCenters.length === 1){
94
+ this.scheduleDayChangeTimer();
95
+ }
96
+ }
97
+ },
98
+
99
+ dayChangeTimer: null,
100
+ lastKnownDayComponents: null,
101
+
102
+ cancelDayChangeTimer: function(){
103
+ if (this.dayChangeTimer !== null){
104
+ this.dayChangeTimer.invalidate();
105
+ this.dayChangeTimer = null;
106
+ }
107
+ },
108
+
109
+ scheduleDayChangeTimer: function(){
110
+ this.cancelDayChangeTimer();
111
+ var now = JSDate.now;
112
+ var todayComponents = this.componentsFromDate(JSCalendar.Unit.date, now);
113
+ if (this.lastKnownDayComponents !== null){
114
+ if (todayComponents.year !== this.lastKnownDayComponents.year || todayComponents.month !== this.lastKnownDayComponents.month || todayComponents.day !== this.lastKnownDayComponents.day){
115
+ if (this.notificationCenters !== null){
116
+ var i, l;
117
+ for (i = 0, l = this.notificationCenters.length; i < l; ++i){
118
+ this.notificationCenters[i].post("JSCalendarDayChanged", null, {calendar: this, dayComponents: JSCopy(todayComponents)});
119
+ }
120
+ }
121
+ }
122
+ }
123
+ var tomorrowComponents = this.componentsFromDate(JSCalendar.Unit.date, this.dateByAddingComponents({day: 1}, now));
124
+ var tomorrow = this.dateFromComponents(tomorrowComponents);
125
+ var interval = now.timeIntervalUntilDate(tomorrow);
126
+ this.lastKnownDayComponents = todayComponents;
127
+ this.dateChangeTimer = JSTimer.scheduledTimerWithInterval(interval + 1, this.scheduleDayChangeTimer, this);
128
+ },
129
+
130
+ timeZoneChanged: function(){
131
+ if (this.notificationCenters !== null && this.notificationCenters.length > 0){
132
+ this.scheduleDayChangeTimer();
133
+ }
134
+ },
135
+
136
+ componentsFromComponents: function(units, otherComponents){
137
+ var otherCalendar = otherComponents.calendar || this;
138
+ if (otherCalendar.identifier === this.identifier){
139
+ if (otherCalendar.timezone.identifier === this.identifier){
140
+ return otherComponents;
141
+ }
142
+ }
143
+ var date = otherCalendar.dateFromComponents(otherComponents);
144
+ return this.componentsFromDate(units, date);
53
145
  }
54
146
 
55
147
  });
@@ -709,6 +801,7 @@ JSCalendar.Unit.difference =
709
801
  JSCalendar.Unit.second |
710
802
  JSCalendar.Unit.millisecond;
711
803
 
804
+ JSCalendar.Unit.date = JSCalendar.Unit.year | JSCalendar.Unit.month | JSCalendar.Unit.day;
712
805
 
713
806
  var monthsPerYear = 12;
714
807
  var minutesPerHour = 60;
@@ -80,17 +80,15 @@ JSClass("JSDateFormatter", JSObject, {
80
80
 
81
81
  setLocale: function(locale){
82
82
  this._locale = locale;
83
- this._localeCalendar = JSCalendar.initWithIdentifier(locale.calendarIdentifier);
84
83
  },
85
84
 
86
85
  calendar: JSDynamicProperty('_calendar', null),
87
- _localeCalendar: null,
88
86
 
89
87
  getCalendar: function(){
90
88
  if (this._calendar !== null){
91
89
  return this._calendar;
92
90
  }
93
- return this._localeCalendar;
91
+ return this._locale.calendar;
94
92
  },
95
93
 
96
94
  timezone: JSDynamicProperty('_timezone', null),
@@ -373,6 +373,10 @@ JSClass("JSLocale", JSObject, {
373
373
 
374
374
  calendarIdentifier: JSReadOnlyProperty('_calendarIdentifier', JSCalendar.Identifier.gregorian),
375
375
 
376
+ calendar: JSLazyInitProperty(function(){
377
+ return JSCalendar.initWithIdentifier(this.calendarIdentifier);
378
+ }),
379
+
376
380
  dateFormatForTemplate: function(template){
377
381
  return this._dateFormatsByTemplate[template] || null;
378
382
  },
@@ -410,6 +414,7 @@ JSClass("JSLocale", JSObject, {
410
414
  this._dateFormatsByTemplate.MMMMd = "MMMM d";
411
415
  this._dateFormatsByTemplate.hms = "h:mm:ss a";
412
416
  this._dateFormatsByTemplate.hm = "h:mm a";
417
+ this._dateFormatsByTemplate.hmz = "h:mm a z";
413
418
  this._dateFormatsByTemplate.Hms = "HH:mm:ss";
414
419
  this._dateFormatsByTemplate.Hm = "HH:mm";
415
420
  return;
@@ -556,7 +561,13 @@ JSClass("JSLocale", JSObject, {
556
561
  }else if (part.type === "dayPeriod"){
557
562
  format += "a";
558
563
  }else if (part.type === "timeZoneName"){
559
- if (part.value.length > 4){
564
+ if (part.value.startsWith("GMT-") || part.value.startsWith("GMT+")){
565
+ if (part.value.indexOf(":") >= 0){
566
+ format += "OOOO";
567
+ }else{
568
+ format += "O";
569
+ }
570
+ }else if (part.value.length > 4){
560
571
  format += "zzzz";
561
572
  }else{
562
573
  format += "z";
@@ -606,6 +617,7 @@ JSClass("JSLocale", JSObject, {
606
617
  "MMMMd": unicodeFormatForOptions({month: "long", day: "numeric"}),
607
618
  "hms": unicodeFormatForOptions({hour: "numeric", minute: "numeric", second: "numeric"}),
608
619
  "hm": unicodeFormatForOptions({hour: "numeric", minute: "numeric"}),
620
+ "hmz": unicodeFormatForOptions({hour: "numeric", minute: "numeric", timeZoneName: "short"}),
609
621
  "Hms": unicodeFormatForOptions({hour: "numeric", minute: "numeric", second: "numeric", hour12: false}),
610
622
  "Hm": unicodeFormatForOptions({hour: "numeric", minute: "numeric", hour12: false}),
611
623
  };
@@ -45,6 +45,21 @@ JSClass("JSSynchronizer", JSObject, {
45
45
  return this._scheduleSync(0, completion, target);
46
46
  },
47
47
 
48
+ _isPaused: false,
49
+ _syncOnResume: false,
50
+
51
+ pause: function(){
52
+ this._isPaused = true;
53
+ },
54
+
55
+ resume: function(){
56
+ this._isPaused = false;
57
+ if (this._syncOnResume){
58
+ this._syncOnResume = true;
59
+ this._scheduleSync(0, function(){});
60
+ }
61
+ },
62
+
48
63
  cancel: function(){
49
64
  if (this._pendingTimer !== null){
50
65
  this._pendingTimer.invalidate();
@@ -76,6 +91,10 @@ JSClass("JSSynchronizer", JSObject, {
76
91
  },
77
92
 
78
93
  _sync: function(){
94
+ if (this._isPaused){
95
+ this._syncOnResume = true;
96
+ return;
97
+ }
79
98
  this._pendingTimer = null;
80
99
  var controller = this;
81
100
  var started = false;
@@ -16,6 +16,8 @@
16
16
  // #import "JSObject.js"
17
17
  // #import "JSDate.js"
18
18
  // #import "JSBinarySearcher.js"
19
+ // #import "JSTimer.js"
20
+ // #import "JSTimeInterval.js"
19
21
  // #feature Intl
20
22
  /* global JSGregorianCalendar, Intl, DataView */
21
23
  'use strict';
@@ -533,11 +535,77 @@ JSClass("JSTimeZone", JSObject, {
533
535
 
534
536
  });
535
537
 
538
+ JSTimeZone.changeLocalTimeZoneToSystem = function(){
539
+ if (JSTimeZone.localFollowsSystem){
540
+ return;
541
+ }
542
+ JSTimeZone.localFollowsSystem = true;
543
+ JSTimeZone._changeLocalTimeZone(JSTimeZone.systemTimeZoneIdentifier);
544
+ if (JSTimeZone.notificationCenters.length > 0){
545
+ JSTimeZone.scheduleSystemIdentifierWatchTimer();
546
+ }
547
+ };
548
+
536
549
  JSTimeZone.changeLocalTimeZone = function(identifier){
537
- localIdentifier = identifier;
538
- Object.defineProperty(JSTimeZone, 'local', defaultLocalProperty);
550
+ JSTimeZone.cancelSystemIdentifierWatchTimer();
551
+ JSTimeZone.localFollowsSystem = false;
552
+ JSTimeZone._changeLocalTimeZone(identifier);
539
553
  };
540
554
 
555
+ JSTimeZone._changeLocalTimeZone = function(identifier){
556
+ if (identifier !== localIdentifier){
557
+ localIdentifier = identifier;
558
+ Object.defineProperty(JSTimeZone, 'local', defaultLocalProperty);
559
+ var i, l;
560
+ for (i = 0, l = JSTimeZone.notificationCenters.length; i < l; ++i){
561
+ JSTimeZone.notificationCenters[i].post("JSLocalTimeZoneChanged", null);
562
+ }
563
+ }
564
+ };
565
+
566
+ JSTimeZone.startSendingNotifications = function(notificationCenter){
567
+ var i = JSTimeZone.notificationCenters.indexOf(notificationCenter);
568
+ if (i < 0){
569
+ JSTimeZone.notificationCenters.push(notificationCenter);
570
+ }
571
+ if (JSTimeZone.localFollowsSystem){
572
+ JSTimeZone.scheduleSystemIdentifierWatchTimer();
573
+ }
574
+ };
575
+
576
+ JSTimeZone.scheduleSystemIdentifierWatchTimer = function(){
577
+ if (JSTimeZone.systemIdentifierWatchTimer === null){
578
+ var previousSystemTimeZoneIdentifier = JSTimeZone.systemTimeZoneIdentifier;
579
+ JSTimeZone.systemIdentifierWatchTimer = JSTimer.scheduledRepeatingTimerWithInterval(JSTimeInterval.minutes(1), function(){
580
+ if (JSTimeZone.systemTimeZoneIdentifier !== previousSystemTimeZoneIdentifier){
581
+ previousSystemTimeZoneIdentifier = JSTimeZone.systemTimeZoneIdentifier;
582
+ JSTimeZone._changeLocalTimeZone(JSTimeZone.systemTimeZoneIdentifier);
583
+ }
584
+ });
585
+ }
586
+ };
587
+
588
+ JSTimeZone.cancelSystemIdentifierWatchTimer = function(){
589
+ if (JSTimeZone.systemIdentifierWatchTimer !== null){
590
+ JSTimeZone.systemIdentifierWatchTimer.invalidate();
591
+ JSTimeZone.systemIdentifierWatchTimer = null;
592
+ }
593
+ };
594
+
595
+ JSTimeZone.stopSendingNotifications = function(notificationCenter){
596
+ var i = JSTimeZone.notificationCenters.indexOf(notificationCenter);
597
+ if (i >= 0){
598
+ JSTimeZone.notificationCenters.splice(i, 1);
599
+ }
600
+ if (JSTimeZone.notificationCenters.length === 0){
601
+ JSTimeZone.cancelSystemIdentifierWatchTimer();
602
+ }
603
+ };
604
+
605
+ JSTimeZone.localFollowsSystem = true;
606
+ JSTimeZone.systemIdentifierWatchTimer = null;
607
+ JSTimeZone.notificationCenters = [];
608
+
541
609
  var defaultLocalProperty = {
542
610
  configurable: true,
543
611
  get: function JSTimeZone_getLocal(){
@@ -578,6 +646,7 @@ Object.defineProperties(JSTimeZone, {
578
646
  configurable: true,
579
647
  get: function JSTimeZone_getUTC(){
580
648
  var timezone = JSTimeZone.initWithTimeIntervalFromUTC(0, 'UTC');
649
+ timezone._identifier = "UTC";
581
650
  Object.defineProperty(JSTimeZone, 'utc', {configurable: false, value: timezone});
582
651
  return timezone;
583
652
  }
@@ -601,7 +670,7 @@ JSTimeZone.importZoneInfo = function(info){
601
670
  JSTimeZone.clearZoneInfo = function(info){
602
671
  zoneinfo = emptyZoneInfo;
603
672
  Object.defineProperty(JSTimeZone, 'knownTimeZoneIdentifiers', defaultKnownIdentifiersProperty);
604
- JSTimeZone.changeLocalTimeZone(JSTimeZone.systemTimeZoneIdentifier);
673
+ JSTimeZone.changeLocalTimeZoneToSystem();
605
674
  };
606
675
 
607
676
  JSTimeZone.rulesFromPOSIXString = function(str){
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2024.5.0
3
+ JSBundleVersion: 2024.8.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.MediaKit
3
- JSBundleVersion: 2024.5.0
3
+ JSBundleVersion: 2024.8.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -16,7 +16,7 @@
16
16
  // #import "MKAsset.js"
17
17
  // #import "MKRemoteAsset.js"
18
18
  // #import "MKHTMLStream.js"
19
- /* global document */
19
+ /* global document, window */
20
20
  'use strict';
21
21
 
22
22
  (function(){
@@ -31,25 +31,51 @@ MKAsset.definePropertiesFromExtensions({
31
31
  }
32
32
  var video = document.createElement("video");
33
33
  video.playsInline = true;
34
- var loadmetadata = function(){
35
- video.currentTime = playbackTime;
34
+ video.crossOrigin = "anonymous";
35
+ var loadedmetadata = function(){
36
+ // logger.debug("loadedmetadata %f", video.currentTime);
37
+ video.removeEventListener("loadedmetadata", loadedmetadata);
38
+ };
39
+ var loadeddata = function(){
40
+ // logger.debug("loadeddata %f", video.currentTime);
41
+ video.removeEventListener("loadeddata", loadeddata);
36
42
  };
37
43
  var canplay = function(){
38
- // FIXME: would be nice to not have an arbitrary delay of 30ms, and
39
- // instead key off of an event when we know the poster can be captured
40
- JSTimer.scheduledTimerWithInterval(JSTimeInterval.milliseconds(30), capture);
44
+ // logger.debug("canplay %f", video.currentTime);
45
+ video.removeEventListener("canplay", canplay);
46
+ // logger.debug("setting time to %f", playbackTime);
47
+ video.currentTime = playbackTime;
48
+ video.addEventListener("timeupdate", timeupdate);
49
+ };
50
+ var timeupdate = function(){
51
+ // logger.debug("timeupdate %f", video.currentTime);
52
+ if (Math.abs(video.currentTime - playbackTime) > 0.02){
53
+ // logger.debug("correcting time to %f", playbackTime);
54
+ video.currentTime = playbackTime;
55
+ }else{
56
+ video.removeEventListener("timeupdate", timeupdate);
57
+ video.addEventListener("seeked", seeked);
58
+ }
59
+ };
60
+ var seeked = function(){
61
+ // logger.debug("seeked %f", video.currentTime);
62
+ video.removeEventListener("seeked", seeked);
63
+ // logger.debug("capture requested");
64
+ window.requestAnimationFrame(capture);
41
65
  };
42
66
  var capture = function(){
67
+ // logger.debug("capture");
43
68
  var canvas = document.createElement("canvas");
44
69
  canvas.width = video.videoWidth;
45
70
  canvas.height = video.videoHeight;
46
71
  var context = canvas.getContext("2d");
47
72
  context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
73
+ // logger.debug("drawn");
48
74
  canvas.toBlob(function(blob){
75
+ // logger.debug("blob");
49
76
  var reader = new FileReader();
50
77
  reader.addEventListener("loadend", function(){
51
- video.removeEventListener("loadmetadata", loadmetadata);
52
- video.removeEventListener("canplay", canplay);
78
+ // logger.debug("read");
53
79
  if (reader.error){
54
80
  logger.error("Error reading blob: %{error}", reader.error);
55
81
  completion.call(target, null);
@@ -57,13 +83,15 @@ MKAsset.definePropertiesFromExtensions({
57
83
  }
58
84
  var data = JSData.initWithBuffer(reader.result);
59
85
  var image = JSImage.initWithData(data);
86
+ // logger.debug("completion");
60
87
  completion.call(target, image);
61
88
  });
62
89
  reader.readAsArrayBuffer(blob);
63
90
  }, "image/jpeg");
64
91
  };
65
- video.addEventListener("loadmetadata", loadmetadata);
66
92
  video.addEventListener("canplay", canplay);
93
+ video.addEventListener("loadeddata", loadeddata);
94
+ video.addEventListener("loadedmetadata", loadedmetadata);
67
95
  if (this.isKindOfClass(MKHTMLStream)){
68
96
  video.srcObject = this.htmlMediaStream;
69
97
  }else if (this.isKindOfClass(MKRemoteAsset)){
@@ -72,6 +100,7 @@ MKAsset.definePropertiesFromExtensions({
72
100
  logger.warning("unsupported asset class: %{public}", this.$class.className);
73
101
  JSRunLoop.main.schedule(completion, target, null);
74
102
  }
103
+ video.load();
75
104
  return completion.promise;
76
105
  },
77
106
 
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKitUI
3
- JSBundleVersion: 2024.5.0
3
+ JSBundleVersion: 2024.8.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -90,6 +90,7 @@ MKVideoView.definePropertiesFromExtensions({
90
90
  this.videoElement.srcObject = null;
91
91
  this.videoElement.src = null;
92
92
  }
93
+ this.videoElement.load();
93
94
  },
94
95
 
95
96
  _isWaitingForPlay: false,
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.NotificationKit
3
- JSBundleVersion: 2024.5.0
3
+ JSBundleVersion: 2024.8.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -90,23 +90,23 @@ JSClass("NKHTMLUserNotificationCenter", NKUserNotificationCenter, {
90
90
 
91
91
  unregisterForRemoteNotifications: function(completion, target){
92
92
  if (!completion){
93
- completion = Promise.completion(Promise.rejectNonNullFirstArgument);
93
+ completion = Promise.completion(Promise.resolveNull);
94
94
  }
95
95
  if (this.serviceWorkerContainer === null){
96
- JSRunLoop.main.schedule(completion, target, new Error("Remote notifications not supported on this device (no service workers)"));
96
+ JSRunLoop.main.schedule(completion, target, null);
97
97
  }else{
98
98
  this.serviceWorkerContainer.getRegistration().then(function(serviceWorkerRegistration){
99
99
  if (!serviceWorkerRegistration){
100
- completion.call(target, new Error("Missing service worker registration"));
100
+ completion.call(target, null);
101
101
  return;
102
102
  }
103
103
  if (!serviceWorkerRegistration.pushManager){
104
- completion.call(target, new Error("Remote notifications not supported on this device (no push manager)"));
104
+ completion.call(target, null);
105
105
  return;
106
106
  }
107
107
  serviceWorkerRegistration.pushManager.getSubscription().then(function(subscription){
108
108
  if (subscription){
109
- subscription.unsubscribe(function(){
109
+ subscription.unsubscribe().then(function(){
110
110
  completion.call(target, null);
111
111
  }, function(error){
112
112
  completion.call(target, error);
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.PDFKit
3
- JSBundleVersion: 2024.5.0
3
+ JSBundleVersion: 2024.8.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: 2024.5.0
3
+ JSBundleVersion: 2024.8.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: 2024.5.0
3
+ JSBundleVersion: 2024.8.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: 2024.5.0
3
+ JSBundleVersion: 2024.8.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: 2024.5.0
3
+ JSBundleVersion: 2024.8.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: 2024.5.0
3
+ JSBundleVersion: 2024.8.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: 2024.5.0
3
+ JSBundleVersion: 2024.8.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: 2024.5.0
3
+ JSBundleVersion: 2024.8.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -73,6 +73,7 @@ JSClass('UIApplication', UIResponder, {
73
73
  }catch (e){
74
74
  error = e;
75
75
  }
76
+ this.startSystemNotifications();
76
77
  }
77
78
  completion.call(target, error);
78
79
  }, this);
@@ -89,6 +90,20 @@ JSClass('UIApplication', UIResponder, {
89
90
  }
90
91
  },
91
92
 
93
+ postsSystemNotifications: true,
94
+
95
+ startSystemNotifications: function(){
96
+ if (this.postsSystemNotifications){
97
+ JSTimeZone.startSendingNotifications(JSNotificationCenter.shared);
98
+ JSLocale.current.calendar.startSendingNotifications(JSNotificationCenter.shared);
99
+ }
100
+ },
101
+
102
+ stopSystemNotifications: function(){
103
+ JSLocale.current.calendar.stopSendingNotifications(JSNotificationCenter.shared);
104
+ JSTimeZone.stopSendingNotifications(JSNotificationCenter.shared);
105
+ },
106
+
92
107
  setupTimeZones: function(completion, target){
93
108
  var subdirectory = (this.bundle.info.JSTimeZoneInfo || "tz") + ".zoneinfo";
94
109
  var metadata = this.bundle.metadataForResourceName("Contents", "json", subdirectory);
@@ -229,6 +244,7 @@ JSClass('UIApplication', UIResponder, {
229
244
  }else{
230
245
  this._stopCalled = true;
231
246
  logger.info("Stopping application");
247
+ this.stopSystemNotifications();
232
248
  var closed = false;
233
249
  var _close = function(){
234
250
  if (closed){