@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.
- package/Frameworks/DOM.jsframework/Info.json +2 -2
- package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
- package/Frameworks/FontKit.jsframework/Info.json +2 -2
- package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/Info.json +2 -2
- package/Frameworks/Foundation.jsframework/JS/JSCalendar.js +93 -0
- package/Frameworks/Foundation.jsframework/JS/JSDateFormatter.js +1 -3
- package/Frameworks/Foundation.jsframework/JS/JSLocale.js +13 -1
- package/Frameworks/Foundation.jsframework/JS/JSSynchronizer.js +19 -0
- package/Frameworks/Foundation.jsframework/JS/JSTimeZone.js +72 -3
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/sources.json +6 -6
- package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
- package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
- package/Info.json +2 -2
- package/Node/io.breakside.jskit-bundle.js +2 -2
- package/Node/jskit +2 -2
- package/Root/Frameworks/APIKit/Info.yaml +1 -1
- package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/AuthKit/Info.yaml +1 -1
- package/Root/Frameworks/CSSOM/Info.yaml +1 -1
- package/Root/Frameworks/ChartKit/Info.yaml +1 -1
- package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
- package/Root/Frameworks/DBKit/Info.yaml +1 -1
- package/Root/Frameworks/DOM/Info.yaml +1 -1
- package/Root/Frameworks/Dispatch/Info.yaml +1 -1
- package/Root/Frameworks/FontKit/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/JSCalendar.js +93 -0
- package/Root/Frameworks/Foundation/JSDateFormatter.js +1 -3
- package/Root/Frameworks/Foundation/JSLocale.js +13 -1
- package/Root/Frameworks/Foundation/JSSynchronizer.js +19 -0
- package/Root/Frameworks/Foundation/JSTimeZone.js +72 -3
- package/Root/Frameworks/ImageKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/MKAsset+HTML.js +38 -9
- package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
- package/Root/Frameworks/MediaKitUI/MKVideoView+HTML.js +1 -0
- package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
- package/Root/Frameworks/NotificationKit/NKHTMLUserNotificationCenter.js +5 -5
- package/Root/Frameworks/PDFKit/Info.yaml +1 -1
- package/Root/Frameworks/QRKit/Info.yaml +1 -1
- package/Root/Frameworks/SearchKit/Info.yaml +1 -1
- package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
- package/Root/Frameworks/ServerKit/Info.yaml +1 -1
- package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/TestKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/UIApplication.js +16 -0
- package/Root/Frameworks/UIKit/UISplitViewController.js +31 -8
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/UIKitTesting/UIMockApplication.js +2 -0
- package/package.json +1 -1
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
538
|
-
|
|
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.
|
|
673
|
+
JSTimeZone.changeLocalTimeZoneToSystem();
|
|
605
674
|
};
|
|
606
675
|
|
|
607
676
|
JSTimeZone.rulesFromPOSIXString = function(str){
|
|
@@ -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
|
-
|
|
35
|
-
|
|
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
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
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
|
|
|
@@ -90,23 +90,23 @@ JSClass("NKHTMLUserNotificationCenter", NKUserNotificationCenter, {
|
|
|
90
90
|
|
|
91
91
|
unregisterForRemoteNotifications: function(completion, target){
|
|
92
92
|
if (!completion){
|
|
93
|
-
completion = Promise.completion(Promise.
|
|
93
|
+
completion = Promise.completion(Promise.resolveNull);
|
|
94
94
|
}
|
|
95
95
|
if (this.serviceWorkerContainer === null){
|
|
96
|
-
JSRunLoop.main.schedule(completion, target,
|
|
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,
|
|
100
|
+
completion.call(target, null);
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
103
|
if (!serviceWorkerRegistration.pushManager){
|
|
104
|
-
completion.call(target,
|
|
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);
|
|
@@ -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){
|