@breakside/jskit 2023.35.0 → 2023.40.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/JSHTMLHTTPClient.js +1 -1
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- 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/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/JSHTMLHTTPClient.js +1 -1
- package/Root/Frameworks/ImageKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/MKAsset+HTML.js +80 -0
- package/Root/Frameworks/MediaKit/MKAsset.js +12 -0
- package/Root/Frameworks/MediaKit/MKRemoteAsset.js +39 -0
- package/Root/Frameworks/MediaKit/MediaKit+HTML.js +2 -1
- package/Root/Frameworks/MediaKit/MediaKit.js +2 -1
- package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
- package/Root/Frameworks/MediaKitUI/MKVideoView+HTML.js +77 -0
- package/Root/Frameworks/MediaKitUI/MKVideoView.js +19 -1
- package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
- 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/UIListView.js +3 -3
- package/Root/Frameworks/UIKit/UIPopupButton.js +21 -2
- package/Root/Frameworks/UIKit/UISlider.js +4 -2
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
4
|
-
"JSBundleVersion": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.40.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "DOM+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
13
13
|
}
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
6
|
-
"JSBundleVersion": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.40.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
|
|
|
11
11
|
"node": "DOM+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.FontKit",
|
|
4
|
-
"JSBundleVersion": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.40.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
8
8
|
"html": "FontKit+HTML.js"
|
|
9
9
|
},
|
|
10
10
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
11
|
-
"GitRevision": "
|
|
11
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
12
12
|
}
|
|
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.JSKit.FontKit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.FontKit",
|
|
6
|
-
"JSBundleVersion": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.40.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
10
10
|
"html": "FontKit+HTML.js"
|
|
11
11
|
},
|
|
12
12
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
13
|
-
"GitRevision": "
|
|
13
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [],
|
|
16
16
|
"ResourceLookup": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.Foundation",
|
|
4
|
-
"JSBundleVersion": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.40.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "Foundation+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
13
13
|
}
|
|
@@ -68,7 +68,7 @@ JSClass("JSHTMLHTTPClient", JSObject, {
|
|
|
68
68
|
}
|
|
69
69
|
if (callbacks.uploadProgress){
|
|
70
70
|
xmlRequest.upload.addEventListener('progress', function(e){
|
|
71
|
-
callbacks.
|
|
71
|
+
callbacks.uploadProgress.call(target, e.loaded, e.lengthComputable ? e.total : undefined);
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.Foundation",
|
|
6
|
-
"JSBundleVersion": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.40.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
|
|
|
11
11
|
"node": "Foundation+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [
|
|
17
17
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
|
|
4
|
-
"JSBundleVersion": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.40.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "SecurityKit+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
13
13
|
}
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
|
|
6
|
-
"JSBundleVersion": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.40.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
|
|
|
11
11
|
"node": "SecurityKit+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
package/Info.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "node",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.jskit",
|
|
4
|
-
"JSBundleVersion": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.40.0",
|
|
5
5
|
"JSExecutableName": "jskit",
|
|
6
6
|
"NPMOrganization": "breakside",
|
|
7
7
|
"JSResources": [
|
|
8
8
|
"Tests/HTMLTestRunner.js",
|
|
9
9
|
"Tests/NodeTestRunner.js"
|
|
10
10
|
],
|
|
11
|
-
"GitRevision": "
|
|
11
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
12
12
|
}
|
|
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.jskit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "node",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.jskit",
|
|
6
|
-
"JSBundleVersion": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.40.0",
|
|
7
7
|
"JSExecutableName": "jskit",
|
|
8
8
|
"NPMOrganization": "breakside",
|
|
9
9
|
"JSResources": [
|
|
10
10
|
"Tests/HTMLTestRunner.js",
|
|
11
11
|
"Tests/NodeTestRunner.js"
|
|
12
12
|
],
|
|
13
|
-
"GitRevision": "
|
|
13
|
+
"GitRevision": "7a5657f2af17a4f47b589fd84ac50fd7f40e0294"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [
|
|
16
16
|
{
|
|
@@ -68,7 +68,7 @@ JSClass("JSHTMLHTTPClient", JSObject, {
|
|
|
68
68
|
}
|
|
69
69
|
if (callbacks.uploadProgress){
|
|
70
70
|
xmlRequest.upload.addEventListener('progress', function(e){
|
|
71
|
-
callbacks.
|
|
71
|
+
callbacks.uploadProgress.call(target, e.loaded, e.lengthComputable ? e.total : undefined);
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Copyright 2020 Breakside Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Breakside Public License, Version 1.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// If a copy of the License was not distributed with this file, you may
|
|
6
|
+
// obtain a copy at
|
|
7
|
+
//
|
|
8
|
+
// http://breakside.io/licenses/LICENSE-1.0.txt
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
|
|
16
|
+
// #import "MKAsset.js"
|
|
17
|
+
// #import "MKRemoteAsset.js"
|
|
18
|
+
// #import "MKHTMLStream.js"
|
|
19
|
+
/* global document */
|
|
20
|
+
'use strict';
|
|
21
|
+
|
|
22
|
+
(function(){
|
|
23
|
+
|
|
24
|
+
var logger = JSLog("medikit", "asset");
|
|
25
|
+
|
|
26
|
+
MKAsset.definePropertiesFromExtensions({
|
|
27
|
+
|
|
28
|
+
imageAtPlaybackTime: function(playbackTime, completion, target){
|
|
29
|
+
if (completion === undefined){
|
|
30
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
31
|
+
}
|
|
32
|
+
var video = document.createElement("video");
|
|
33
|
+
video.playsInline = true;
|
|
34
|
+
var loadmetadata = function(){
|
|
35
|
+
video.currentTime = playbackTime;
|
|
36
|
+
};
|
|
37
|
+
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);
|
|
41
|
+
};
|
|
42
|
+
var capture = function(){
|
|
43
|
+
var canvas = document.createElement("canvas");
|
|
44
|
+
canvas.width = video.videoWidth;
|
|
45
|
+
canvas.height = video.videoHeight;
|
|
46
|
+
var context = canvas.getContext("2d");
|
|
47
|
+
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
|
48
|
+
canvas.toBlob(function(blob){
|
|
49
|
+
var reader = new FileReader();
|
|
50
|
+
reader.addEventListener("loadend", function(){
|
|
51
|
+
video.removeEventListener("loadmetadata", loadmetadata);
|
|
52
|
+
video.removeEventListener("canplay", canplay);
|
|
53
|
+
if (reader.error){
|
|
54
|
+
logger.error("Error reading blob: %{error}", reader.error);
|
|
55
|
+
completion.call(target, null);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
var data = JSData.initWithBuffer(reader.result);
|
|
59
|
+
var image = JSImage.initWithData(data);
|
|
60
|
+
completion.call(target, image);
|
|
61
|
+
});
|
|
62
|
+
reader.readAsArrayBuffer(blob);
|
|
63
|
+
}, "image/jpeg");
|
|
64
|
+
};
|
|
65
|
+
video.addEventListener("loadmetadata", loadmetadata);
|
|
66
|
+
video.addEventListener("canplay", canplay);
|
|
67
|
+
if (this.isKindOfClass(MKHTMLStream)){
|
|
68
|
+
video.srcObject = this.htmlMediaStream;
|
|
69
|
+
}else if (this.isKindOfClass(MKRemoteAsset)){
|
|
70
|
+
video.src = this.url.encodedString;
|
|
71
|
+
}else{
|
|
72
|
+
logger.warning("unsupported asset class: %{public}", this.$class.className);
|
|
73
|
+
JSRunLoop.main.schedule(completion, target, null);
|
|
74
|
+
}
|
|
75
|
+
return completion.promise;
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
})();
|
|
@@ -18,4 +18,16 @@
|
|
|
18
18
|
|
|
19
19
|
JSClass("MKAsset", JSObject, {
|
|
20
20
|
|
|
21
|
+
isEqual: function(other){
|
|
22
|
+
return false;
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
imageAtPlaybackTime: function(playbackTime, completion, target){
|
|
26
|
+
if (completion === undefined){
|
|
27
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
28
|
+
}
|
|
29
|
+
JSRunLoop.main.schedule(completion, target, null);
|
|
30
|
+
return completion.promise;
|
|
31
|
+
}
|
|
32
|
+
|
|
21
33
|
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Copyright 2023 Breakside Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Breakside Public License, Version 1.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// If a copy of the License was not distributed with this file, you may
|
|
6
|
+
// obtain a copy at
|
|
7
|
+
//
|
|
8
|
+
// http://breakside.io/licenses/LICENSE-1.0.txt
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
|
|
16
|
+
// #import "MKAsset.js"
|
|
17
|
+
'use strict';
|
|
18
|
+
|
|
19
|
+
JSClass("MKRemoteAsset", MKAsset, {
|
|
20
|
+
|
|
21
|
+
url: null,
|
|
22
|
+
contentType: null,
|
|
23
|
+
|
|
24
|
+
initWithURL: function(url, contentType){
|
|
25
|
+
this.url = url;
|
|
26
|
+
this.contentType = contentType;
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
isEqual: function(other){
|
|
30
|
+
if (other === null || other === undefined){
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
if (!other.isKindOfClass(MKRemoteAsset)){
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return this.url.isEqual(other.url);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
});
|
|
@@ -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
|
-
|
|
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
|
|
|
@@ -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
|
}
|
|
@@ -779,6 +779,7 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
|
|
|
779
779
|
normalColor: null,
|
|
780
780
|
disabledColor: null,
|
|
781
781
|
activeColor: null,
|
|
782
|
+
normalBackgroundColor: null,
|
|
782
783
|
activeBackgroundColor: null,
|
|
783
784
|
overBackgroundColor: null,
|
|
784
785
|
cornerRadius: 0,
|
|
@@ -794,6 +795,13 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
|
|
|
794
795
|
this._fillInMissingColors();
|
|
795
796
|
},
|
|
796
797
|
|
|
798
|
+
initWithBackgroundColor: function(backgroundColor, color){
|
|
799
|
+
UIPopupButtonCustomStyler.$super.init.call(this);
|
|
800
|
+
this.normalBackgroundColor = backgroundColor;
|
|
801
|
+
this.normalColor = color;
|
|
802
|
+
this._fillInMissingColors();
|
|
803
|
+
},
|
|
804
|
+
|
|
797
805
|
initWithSpec: function(spec){
|
|
798
806
|
UIPopupButtonCustomStyler.$super.initWithSpec.call(this, spec);
|
|
799
807
|
if (spec.containsKey("normalColor")){
|
|
@@ -805,6 +813,9 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
|
|
|
805
813
|
if (spec.containsKey("activeColor")){
|
|
806
814
|
this.activeColor = spec.valueForKey("activeColor", JSColor);
|
|
807
815
|
}
|
|
816
|
+
if (spec.containsKey('normalBackgroundColor')){
|
|
817
|
+
this.normalBackgroundColor = spec.valueForKey("normalBackgroundColor", JSColor);
|
|
818
|
+
}
|
|
808
819
|
if (spec.containsKey("activeBackgroundColor")){
|
|
809
820
|
this.activeBackgroundColor = spec.valueForKey("activeBackgroundColor", JSColor);
|
|
810
821
|
}
|
|
@@ -831,6 +842,14 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
|
|
|
831
842
|
if (this.titleInsets === null){
|
|
832
843
|
this.titleInsets = JSInsets.Zero;
|
|
833
844
|
}
|
|
845
|
+
if (this.normalBackgroundColor !== null){
|
|
846
|
+
if (this.activeBackgroundColor === null){
|
|
847
|
+
this.activeBackgroundColor = this.normalBackgroundColor.colorDarkenedByPercentage(0.2);
|
|
848
|
+
}
|
|
849
|
+
if (this.disabledBackgroundColor === null){
|
|
850
|
+
this.disabledBackgroundColor = this.normalBackgroundColor.colorWithAlpha(0.5);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
834
853
|
},
|
|
835
854
|
|
|
836
855
|
initializeControl: function(button){
|
|
@@ -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 =
|
|
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 =
|
|
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
|
},
|