@breakside/jskit 2025.34.0 → 2025.36.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/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/HTMLBuilder.js +42 -2
- package/Node/HTMLProjectServer.js +209 -0
- package/Node/io.breakside.jskit-bundle.js +2 -2
- package/Node/jskit +1 -0
- 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/ImageKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKitUI/Info.yaml +1 -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/UIContainerView.js +17 -1
- 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": "2025.
|
|
4
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
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": "2025.
|
|
6
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
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": "2025.
|
|
4
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
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": "2025.
|
|
6
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
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": "2025.
|
|
4
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
13
13
|
}
|
|
@@ -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": "2025.
|
|
6
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
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": "2025.
|
|
4
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
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": "2025.
|
|
6
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
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": "2025.
|
|
4
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
12
12
|
}
|
package/Node/HTMLBuilder.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// #import "Builder.js"
|
|
18
18
|
// #import "Resources.js"
|
|
19
19
|
// #import "JavascriptCompilation.js"
|
|
20
|
+
// #import "HTMLProjectServer.js"
|
|
20
21
|
'use strict';
|
|
21
22
|
|
|
22
23
|
// buildURL
|
|
@@ -48,7 +49,8 @@ JSClass("HTMLBuilder", Builder, {
|
|
|
48
49
|
'env': {default: null, help: "A file with environmental variables for this build"},
|
|
49
50
|
'tls-cert': {default: null, help: "The SSL cert to use for the debug build"},
|
|
50
51
|
'tls-key': {default: null, help: "The SSL key to use for the debug build"},
|
|
51
|
-
'zoneinfo': {default: null, help: "The build host path to timezone data files"}
|
|
52
|
+
'zoneinfo': {default: null, help: "The build host path to timezone data files"},
|
|
53
|
+
'server': {kind: "flag", help: "Run an http server (required --debug) (implies --no-docker)"}
|
|
52
54
|
},
|
|
53
55
|
|
|
54
56
|
needsDockerBuild: true,
|
|
@@ -81,6 +83,11 @@ JSClass("HTMLBuilder", Builder, {
|
|
|
81
83
|
this.arguments['http-port'] = this.project.info.HTTPPort || 80;
|
|
82
84
|
}
|
|
83
85
|
}
|
|
86
|
+
if (this.arguments.server){
|
|
87
|
+
if (!this.debug){
|
|
88
|
+
throw new Error("--server requires --debug");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
84
91
|
this.wwwJavascriptPaths = [];
|
|
85
92
|
this.wwwResourcePaths = [];
|
|
86
93
|
this.preflightFeatures = new Set();
|
|
@@ -135,6 +142,7 @@ JSClass("HTMLBuilder", Builder, {
|
|
|
135
142
|
await this.bundleInfo();
|
|
136
143
|
await this.buildDocker();
|
|
137
144
|
await this.finish();
|
|
145
|
+
await this.runServer();
|
|
138
146
|
},
|
|
139
147
|
|
|
140
148
|
findImports: async function(){
|
|
@@ -1099,7 +1107,7 @@ JSClass("HTMLBuilder", Builder, {
|
|
|
1099
1107
|
var url = this.buildURL.appendingPathComponent("Dockerfile");
|
|
1100
1108
|
await this.fileManager.createFileAtURL(url, dockerfile);
|
|
1101
1109
|
|
|
1102
|
-
if (this.arguments['no-docker']){
|
|
1110
|
+
if (this.arguments['no-docker'] || this.arguments.server){
|
|
1103
1111
|
return;
|
|
1104
1112
|
}
|
|
1105
1113
|
|
|
@@ -1167,6 +1175,38 @@ JSClass("HTMLBuilder", Builder, {
|
|
|
1167
1175
|
});
|
|
1168
1176
|
},
|
|
1169
1177
|
|
|
1178
|
+
// -----------------------------------------------------------------------
|
|
1179
|
+
// MARK: - Server
|
|
1180
|
+
|
|
1181
|
+
httpServer: null,
|
|
1182
|
+
|
|
1183
|
+
runServer: async function(){
|
|
1184
|
+
if (!this.debug){
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
if (!this.arguments.server){
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
if (this.options.server){
|
|
1191
|
+
if (this.httpServer === null){
|
|
1192
|
+
this.httpServer = HTMLProjectServer.initWithProject(this.project, this.wwwURL, this.fileManager, this.printer);
|
|
1193
|
+
this.httpServer.port = this.arguments['http-port'];
|
|
1194
|
+
if (this.arguments['tls-cert']){
|
|
1195
|
+
this.httpServer.tlsCertificateFileURL = JSURL.initWithString(this.arguments['tls-cert'], this.workingDirectoryURL);
|
|
1196
|
+
if (this.arguments['tls-key']){
|
|
1197
|
+
this.httpServer.tlsKeyFileURL = JSURL.initWithString(this.arguments['tls-key'], this.workingDirectoryURL);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
this.httpServer.run();
|
|
1201
|
+
}
|
|
1202
|
+
}else{
|
|
1203
|
+
if (this.httpServer !== null){
|
|
1204
|
+
await this.httpServer.stop();
|
|
1205
|
+
this.httpServer = null;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1170
1210
|
});
|
|
1171
1211
|
|
|
1172
1212
|
var getenv = function(name, defaultValue){
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// #import Foundation
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const http = require("http");
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
|
|
9
|
+
const logger = JSLog("jskit", "http");
|
|
10
|
+
|
|
11
|
+
JSClass("HTMLProjectServer", JSObject, {
|
|
12
|
+
|
|
13
|
+
initWithProject: function(project, wwwURL, fileManager, printer){
|
|
14
|
+
this.project = project;
|
|
15
|
+
this.wwwURL = wwwURL;
|
|
16
|
+
this.fileManager = fileManager;
|
|
17
|
+
this.printer = printer;
|
|
18
|
+
this.contentTypesByExtension = {
|
|
19
|
+
".html": "text/html",
|
|
20
|
+
".css": "text/css",
|
|
21
|
+
".js": "application/javascript",
|
|
22
|
+
".json": "application/json",
|
|
23
|
+
".xml": "text/xml",
|
|
24
|
+
".txt": "text/plain",
|
|
25
|
+
".gif": "image/gif",
|
|
26
|
+
".jpeg": "image/jpeg",
|
|
27
|
+
".jpg": "image/jpeg",
|
|
28
|
+
".png": "image/png",
|
|
29
|
+
".svg": "image/svg+xml",
|
|
30
|
+
".svgz": "image/svg+xml",
|
|
31
|
+
".pdf": "application/pdf",
|
|
32
|
+
".woff": "application/font-woff",
|
|
33
|
+
".ttf": "application/x-font-ttf",
|
|
34
|
+
".webmanifest": "application/manifest+json",
|
|
35
|
+
".appcache": "text/cache-manifest",
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
project: null,
|
|
40
|
+
wwwURL: null,
|
|
41
|
+
fileManager: null,
|
|
42
|
+
printer: null,
|
|
43
|
+
|
|
44
|
+
port: null,
|
|
45
|
+
tlsCertificateFileURL: null,
|
|
46
|
+
tlsKeyFileURL: null,
|
|
47
|
+
contentTypesByExtension: null,
|
|
48
|
+
|
|
49
|
+
_nodeHttpServer: null,
|
|
50
|
+
|
|
51
|
+
run: async function(){
|
|
52
|
+
var scheme = "http";
|
|
53
|
+
if (this.tlsCertificateFileURL !== null && this.tlsKeyFileURL !== null){
|
|
54
|
+
scheme = "https";
|
|
55
|
+
var options = {
|
|
56
|
+
cert: await this.fileManager.contentsAtURL(this.tlsCertificateFileURL),
|
|
57
|
+
key: await this.fileManager.contentsAtURL(this.tlsKeyFileURL)
|
|
58
|
+
};
|
|
59
|
+
this._nodeHttpServer = https.createServer(options, this._handleNodeRequest.bind(this));
|
|
60
|
+
if (this.port === null){
|
|
61
|
+
this.port = 443;
|
|
62
|
+
}
|
|
63
|
+
}else{
|
|
64
|
+
this._nodeHttpServer = http.createServer(this._handleNodeRequest.bind(this));
|
|
65
|
+
if (this.port === null){
|
|
66
|
+
this.port = 80;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
this._nodeHttpServer.listen(this.port);
|
|
70
|
+
var networkInterfaces = os.networkInterfaces();
|
|
71
|
+
var networkInterface;
|
|
72
|
+
var address;
|
|
73
|
+
for (var name in networkInterfaces){
|
|
74
|
+
networkInterface = networkInterfaces[name];
|
|
75
|
+
for (var i = 0, l = networkInterface.length; i < l; ++i){
|
|
76
|
+
address = networkInterface[i];
|
|
77
|
+
if (address.family == "IPv4"){
|
|
78
|
+
this.printer.print(String.initWithFormat("HTTP server listening on %s://%s:%d", scheme, address.address, this.port), true, true);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
stop: function(completion, target){
|
|
85
|
+
if (!completion){
|
|
86
|
+
completion = Promise.completion();
|
|
87
|
+
}
|
|
88
|
+
if (this._nodeHttpServer === null){
|
|
89
|
+
completion.call(target);
|
|
90
|
+
}else{
|
|
91
|
+
this.printer.print("HTTP server closing, waiting for outstanding requests to close", true, true);
|
|
92
|
+
var server = this;
|
|
93
|
+
this._nodeHttpServer.close(function(){
|
|
94
|
+
this.printer.print("HTTP server closed", true, true);
|
|
95
|
+
completion.call(target);
|
|
96
|
+
server._nodeHttpServer = null;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return completion.promise;
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
alwaysExpires: JSLazyInitProperty(() => "Thu, 01 Jan 1970 00:00:01 GMT"),
|
|
103
|
+
neverExpires: JSLazyInitProperty(() => "Thu, 31 Dec 2037 23:55:55 GMT"),
|
|
104
|
+
|
|
105
|
+
_handleNodeRequest: async function(nodeRequest, nodeResponse){
|
|
106
|
+
let statusCode = null;
|
|
107
|
+
let headers = {};
|
|
108
|
+
let filePath = null;
|
|
109
|
+
try{
|
|
110
|
+
let url = JSURL.initWithString(nodeRequest.url);
|
|
111
|
+
if (url !== null){
|
|
112
|
+
url.standardize();
|
|
113
|
+
if (url.pathComponents.length === 0){
|
|
114
|
+
url.path = "/";
|
|
115
|
+
}
|
|
116
|
+
let method = nodeRequest.method.toUpperCase();
|
|
117
|
+
if (method === "GET"){
|
|
118
|
+
if (url.pathComponents[0] === "/"){
|
|
119
|
+
if (url.pathComponents.length === 1){
|
|
120
|
+
url.appendPathComponent("index.html");
|
|
121
|
+
}
|
|
122
|
+
let statePaths = this.project.info.UIHTMLStatePaths || [];
|
|
123
|
+
for (let path of statePaths){
|
|
124
|
+
path = path.trim();
|
|
125
|
+
if (path.endsWith("/")){
|
|
126
|
+
if (url.path.startsWith(path)){
|
|
127
|
+
statusCode = 302;
|
|
128
|
+
headers.Location = "/#" + url.path;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}else{
|
|
132
|
+
if (url.path === path){
|
|
133
|
+
statusCode = 302;
|
|
134
|
+
headers.Location = "/#" + url.path;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (statusCode === null){
|
|
140
|
+
if (url.pathComponents.length === 2){
|
|
141
|
+
if (url.pathComponents[1] === "index.html"){
|
|
142
|
+
headers.Expires = this.alwaysExpires;
|
|
143
|
+
headers["Cache-Control"] = "no-cache";
|
|
144
|
+
}else if (url.pathComponents[1] === "manifest.appcache"){
|
|
145
|
+
headers.Expires = this.alwaysExpires;
|
|
146
|
+
headers["Cache-Control"] = "no-cache";
|
|
147
|
+
}else if (url.pathComponents[1] === "service-worker.js"){
|
|
148
|
+
headers.Expires = this.alwaysExpires;
|
|
149
|
+
headers["Cache-Control"] = "no-cache";
|
|
150
|
+
}else if (url.pathComponents[1] === "HTMLAppBootstrapper.js"){
|
|
151
|
+
headers.Expires = this.alwaysExpires;
|
|
152
|
+
headers["Cache-Control"] = "no-cache";
|
|
153
|
+
}
|
|
154
|
+
}else if (url.pathComponents[1] === "Resources"){
|
|
155
|
+
headers.Expires = this.neverExpires;
|
|
156
|
+
headers["Cache-Control"] = "max-age=315360000"; // ~10 years
|
|
157
|
+
headers.Etag = url.lastPathComponent;
|
|
158
|
+
}
|
|
159
|
+
let fileURL = this.wwwURL.appendingPathComponents(url.pathComponents.slice(1));
|
|
160
|
+
let exists = await this.fileManager.itemExistsAtURL(fileURL);
|
|
161
|
+
if (exists){
|
|
162
|
+
let attributes = await this.fileManager.attributesOfItemAtURL(fileURL);
|
|
163
|
+
headers["Content-Type"] = this.contentTypesByExtension[url.fileExtension] || "application/octet-stream";
|
|
164
|
+
headers["Content-Length"] = attributes.size;
|
|
165
|
+
filePath = this.fileManager.pathForURL(fileURL);
|
|
166
|
+
statusCode = 200;
|
|
167
|
+
}else{
|
|
168
|
+
statusCode = 404;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}else{
|
|
172
|
+
statusCode = 404;
|
|
173
|
+
}
|
|
174
|
+
}else{
|
|
175
|
+
statusCode = 405;
|
|
176
|
+
}
|
|
177
|
+
}else{
|
|
178
|
+
statusCode = 404;
|
|
179
|
+
}
|
|
180
|
+
}catch (e){
|
|
181
|
+
logger.error("Error handling request: %{error}", e);
|
|
182
|
+
statusCode = 500;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
try{
|
|
186
|
+
try{
|
|
187
|
+
nodeResponse.writeHead(statusCode, headers);
|
|
188
|
+
}catch (e){
|
|
189
|
+
logger.error("Error sending response headers: %{error}", e);
|
|
190
|
+
nodeResponse.writeHead(500);
|
|
191
|
+
}
|
|
192
|
+
nodeResponse.flushHeaders();
|
|
193
|
+
|
|
194
|
+
if (statusCode === 200 && filePath !== null){
|
|
195
|
+
let fp = fs.createReadStream(filePath);
|
|
196
|
+
fp.pipe(nodeResponse); // pipe will call this._nodeResponse.end(), which is the same as calling complete()
|
|
197
|
+
}else{
|
|
198
|
+
nodeResponse.end();
|
|
199
|
+
}
|
|
200
|
+
if (statusCode >= 400){
|
|
201
|
+
logger.warn("%d %{public} %{public}", statusCode, nodeRequest.method, nodeRequest.url);
|
|
202
|
+
}
|
|
203
|
+
}catch (e){
|
|
204
|
+
nodeRequest.socket.destroy();
|
|
205
|
+
logger.error("Error sending response: %{error}", e);
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
});
|
|
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.jskit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "node",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.jskit",
|
|
6
|
-
"JSBundleVersion": "2025.
|
|
6
|
+
"JSBundleVersion": "2025.36.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": "542d9c51b5664a6f0e1a92bdb945534a06c433ea"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [
|
|
16
16
|
{
|
package/Node/jskit
CHANGED
|
@@ -188,6 +188,7 @@ require("./Builder.js");
|
|
|
188
188
|
require("./JavascriptCompilation.js");
|
|
189
189
|
require("./FrameworkBuilder.js");
|
|
190
190
|
require("./NodeBuilder.js");
|
|
191
|
+
require("./HTMLProjectServer.js");
|
|
191
192
|
require("./HTMLBuilder.js");
|
|
192
193
|
require("./APIBuilder.js");
|
|
193
194
|
require("./TestBuilder.js");
|
|
@@ -85,7 +85,17 @@ JSClass("UIContainerView", UIView, {
|
|
|
85
85
|
getIntrinsicSize: function(){
|
|
86
86
|
var contentSize;
|
|
87
87
|
if (this._contentView !== null){
|
|
88
|
-
contentSize = this._contentView.intrinsicSize;
|
|
88
|
+
contentSize = JSSize(this._contentView.intrinsicSize);
|
|
89
|
+
if (contentSize.width !== UIView.noIntrinsicSize){
|
|
90
|
+
if (this._maximumContentSize.width > 0 && this._maximumContentSize.width < contentSize.width){
|
|
91
|
+
contentSize.width = this._maximumContentSize.width;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (contentSize.height !== UIView.noIntrinsicSize){
|
|
95
|
+
if (this._maximumContentSize.height > 0 && this._maximumContentSize.height < contentSize.height){
|
|
96
|
+
contentSize.height = this._maximumContentSize.height;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
89
99
|
}else{
|
|
90
100
|
contentSize = JSSize(UIView.noIntrinsicSize, UIView.noIntrinsicSize);
|
|
91
101
|
}
|
|
@@ -103,6 +113,12 @@ JSClass("UIContainerView", UIView, {
|
|
|
103
113
|
maxSize.width < Number.MAX_VALUE ? maxSize.width - this._contentInsets.width : Number.MAX_VALUE,
|
|
104
114
|
maxSize.height < Number.MAX_VALUE ? maxSize.height - this._contentInsets.height : Number.MAX_VALUE
|
|
105
115
|
);
|
|
116
|
+
if (this._maximumContentSize.width > 0 && this._maximumContentSize.width < maxContentSize.width){
|
|
117
|
+
maxContentSize.width = this._maximumContentSize.width - this.contentInsets.width;
|
|
118
|
+
}
|
|
119
|
+
if (this._maximumContentSize.height > 0 && this._maximumContentSize.height < maxContentSize.height){
|
|
120
|
+
maxContentSize.height = this._maximumContentSize.height - this.contentInsets.height;
|
|
121
|
+
}
|
|
106
122
|
this._contentView.sizeToFitSize(maxContentSize);
|
|
107
123
|
this.bounds = JSRect(0, 0, this._contentView.bounds.size.width + this._contentInsets.width, this._contentView.bounds.size.height + this._contentInsets.height);
|
|
108
124
|
}
|