@breakside/jskit 2026.1.0 → 2026.2.1
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/JSBundle+HTML.js +12 -2
- package/Frameworks/Foundation.jsframework/JS/JSFile.js +1 -1
- package/Frameworks/Foundation.jsframework/JS/JSFileManager+HTML.js +3 -0
- package/Frameworks/Foundation.jsframework/JS/JSTextLayoutManager.js +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/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/JSBundle+HTML.js +12 -2
- package/Root/Frameworks/Foundation/JSFile.js +1 -1
- package/Root/Frameworks/Foundation/JSFileManager+HTML.js +3 -0
- package/Root/Frameworks/Foundation/JSTextLayoutManager.js +2 -2
- 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/UIAnimation.js +1 -1
- package/Root/Frameworks/UIKit/UICollectionViewCell.js +10 -1
- package/Root/Frameworks/UIKit/UIHTMLApplication.js +8 -1
- package/Root/Frameworks/UIKit/UIHTMLContentEditableTextInputManager.js +14 -3
- package/Root/Frameworks/UIKit/UIHTMLTextRun.js +9 -5
- package/Root/Frameworks/UIKit/UIMenu.js +55 -0
- package/Root/Frameworks/UIKit/UIMenuView.js +18 -2
- package/Root/Frameworks/UIKit/UIPopupWindow.js +8 -0
- package/Root/Frameworks/UIKit/UIWindowServer.js +3 -0
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/Root/Templates/html/${PROJECT_NAME}/www/HTMLAppBootstrapper.js +3 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
4
|
-
"JSBundleVersion": "2026.1
|
|
4
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
6
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
4
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
6
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
4
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
13
13
|
}
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
// #import "JSURLResponse.js"
|
|
20
20
|
'use strict';
|
|
21
21
|
|
|
22
|
+
(function(){
|
|
23
|
+
|
|
24
|
+
var logger = JSLog("foundation", "bundle");
|
|
25
|
+
|
|
22
26
|
JSBundle.definePropertiesFromExtensions({
|
|
23
27
|
getResourceData: function(metadata, completion, target){
|
|
24
28
|
if (!completion){
|
|
@@ -27,7 +31,11 @@ JSBundle.definePropertiesFromExtensions({
|
|
|
27
31
|
var session = JSURLSession.shared;
|
|
28
32
|
var url = JSURL.initWithString(metadata.htmlURL);
|
|
29
33
|
var task = session.dataTaskWithURL(url, function(error){
|
|
30
|
-
if (error !== null
|
|
34
|
+
if (error !== null){
|
|
35
|
+
logger.error("error getting resource data (%{public}): %{error}", url.encodedString, error);
|
|
36
|
+
completion.call(target, null);
|
|
37
|
+
}else if (task.response.statusClass != JSURLResponse.StatusClass.success){
|
|
38
|
+
logger.error("unable to fetch resource data (%{public}): HTTP %d", url.encodedString, task.response.statusCode);
|
|
31
39
|
completion.call(target, null);
|
|
32
40
|
}else{
|
|
33
41
|
completion.call(target, task.response.data);
|
|
@@ -36,4 +44,6 @@ JSBundle.definePropertiesFromExtensions({
|
|
|
36
44
|
task.resume();
|
|
37
45
|
return completion.promise;
|
|
38
46
|
}
|
|
39
|
-
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
})();
|
|
@@ -73,7 +73,7 @@ JSFile.unregisterContentTypeForFileExtension = function(contentType, fileExtensi
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
JSFile.contentTypeForFileExtension = function(fileExtension){
|
|
76
|
-
return JSFile.contentTypesByFileExtension[fileExtension] || null;
|
|
76
|
+
return JSFile.contentTypesByFileExtension[fileExtension.toLowerCase()] || null;
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
JSClass("JSDataFile", JSFile, {
|
|
@@ -93,6 +93,9 @@ JSClass("JSHTMLFileManager", JSFileManager, {
|
|
|
93
93
|
};
|
|
94
94
|
request.onsuccess = function JSFileManager_open_onsuccess(e){
|
|
95
95
|
manager._db = e.target.result;
|
|
96
|
+
manager._db.onclose = function JSFileManager_db_onclose(e){
|
|
97
|
+
logger.warn("database closed by browser");
|
|
98
|
+
};
|
|
96
99
|
if (oldVersion === 1){
|
|
97
100
|
var v1url = manager._rootURL.appendingPathComponents(["Containers", "io.breakside.JSKit.Foundation.JSFileManager"], true);
|
|
98
101
|
var v2url = manager.persistentContainerURL;
|
|
@@ -490,7 +490,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
|
|
|
490
490
|
line: {
|
|
491
491
|
get: function(){
|
|
492
492
|
var container = this.container;
|
|
493
|
-
if (container !== null){
|
|
493
|
+
if (container !== null && container.textFrame !== null){
|
|
494
494
|
return container.textFrame.lines[this._lineIndex];
|
|
495
495
|
}
|
|
496
496
|
return null;
|
|
@@ -500,7 +500,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
|
|
|
500
500
|
rect: {
|
|
501
501
|
get: function(){
|
|
502
502
|
var container = this.container;
|
|
503
|
-
if (container !== null){
|
|
503
|
+
if (container !== null && container.textFrame !== null){
|
|
504
504
|
var line = container.textFrame.lines[this._lineIndex];
|
|
505
505
|
var rect = JSRect(line.origin, line.size);
|
|
506
506
|
return this._layoutManager.convertRectFromTextContainer(rect, container);
|
|
@@ -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": "2026.1
|
|
6
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
4
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
6
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
4
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
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": "2026.1
|
|
6
|
+
"JSBundleVersion": "2026.2.1",
|
|
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": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [
|
|
16
16
|
{
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
// #import "JSURLResponse.js"
|
|
20
20
|
'use strict';
|
|
21
21
|
|
|
22
|
+
(function(){
|
|
23
|
+
|
|
24
|
+
var logger = JSLog("foundation", "bundle");
|
|
25
|
+
|
|
22
26
|
JSBundle.definePropertiesFromExtensions({
|
|
23
27
|
getResourceData: function(metadata, completion, target){
|
|
24
28
|
if (!completion){
|
|
@@ -27,7 +31,11 @@ JSBundle.definePropertiesFromExtensions({
|
|
|
27
31
|
var session = JSURLSession.shared;
|
|
28
32
|
var url = JSURL.initWithString(metadata.htmlURL);
|
|
29
33
|
var task = session.dataTaskWithURL(url, function(error){
|
|
30
|
-
if (error !== null
|
|
34
|
+
if (error !== null){
|
|
35
|
+
logger.error("error getting resource data (%{public}): %{error}", url.encodedString, error);
|
|
36
|
+
completion.call(target, null);
|
|
37
|
+
}else if (task.response.statusClass != JSURLResponse.StatusClass.success){
|
|
38
|
+
logger.error("unable to fetch resource data (%{public}): HTTP %d", url.encodedString, task.response.statusCode);
|
|
31
39
|
completion.call(target, null);
|
|
32
40
|
}else{
|
|
33
41
|
completion.call(target, task.response.data);
|
|
@@ -36,4 +44,6 @@ JSBundle.definePropertiesFromExtensions({
|
|
|
36
44
|
task.resume();
|
|
37
45
|
return completion.promise;
|
|
38
46
|
}
|
|
39
|
-
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
})();
|
|
@@ -73,7 +73,7 @@ JSFile.unregisterContentTypeForFileExtension = function(contentType, fileExtensi
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
JSFile.contentTypeForFileExtension = function(fileExtension){
|
|
76
|
-
return JSFile.contentTypesByFileExtension[fileExtension] || null;
|
|
76
|
+
return JSFile.contentTypesByFileExtension[fileExtension.toLowerCase()] || null;
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
JSClass("JSDataFile", JSFile, {
|
|
@@ -93,6 +93,9 @@ JSClass("JSHTMLFileManager", JSFileManager, {
|
|
|
93
93
|
};
|
|
94
94
|
request.onsuccess = function JSFileManager_open_onsuccess(e){
|
|
95
95
|
manager._db = e.target.result;
|
|
96
|
+
manager._db.onclose = function JSFileManager_db_onclose(e){
|
|
97
|
+
logger.warn("database closed by browser");
|
|
98
|
+
};
|
|
96
99
|
if (oldVersion === 1){
|
|
97
100
|
var v1url = manager._rootURL.appendingPathComponents(["Containers", "io.breakside.JSKit.Foundation.JSFileManager"], true);
|
|
98
101
|
var v2url = manager.persistentContainerURL;
|
|
@@ -490,7 +490,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
|
|
|
490
490
|
line: {
|
|
491
491
|
get: function(){
|
|
492
492
|
var container = this.container;
|
|
493
|
-
if (container !== null){
|
|
493
|
+
if (container !== null && container.textFrame !== null){
|
|
494
494
|
return container.textFrame.lines[this._lineIndex];
|
|
495
495
|
}
|
|
496
496
|
return null;
|
|
@@ -500,7 +500,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
|
|
|
500
500
|
rect: {
|
|
501
501
|
get: function(){
|
|
502
502
|
var container = this.container;
|
|
503
|
-
if (container !== null){
|
|
503
|
+
if (container !== null && container.textFrame !== null){
|
|
504
504
|
var line = container.textFrame.lines[this._lineIndex];
|
|
505
505
|
var rect = JSRect(line.origin, line.size);
|
|
506
506
|
return this._layoutManager.convertRectFromTextContainer(rect, container);
|
|
@@ -121,7 +121,7 @@ UIAnimation.defaultInterpolationValueToPairWithValue = function(value){
|
|
|
121
121
|
return JSRect.Zero;
|
|
122
122
|
}
|
|
123
123
|
if (value instanceof JSAffineTransform){
|
|
124
|
-
return JSAffineTransform.
|
|
124
|
+
return JSAffineTransform.Identity;
|
|
125
125
|
}
|
|
126
126
|
if (value.isKindOfClass && value.isKindOfClass(JSColor)){
|
|
127
127
|
return value.colorWithAlpha(0);
|
|
@@ -132,7 +132,16 @@ JSClass("UICollectionViewCell", UICollectionReusableView, {
|
|
|
132
132
|
},
|
|
133
133
|
|
|
134
134
|
mouseEntered: function(event){
|
|
135
|
-
|
|
135
|
+
if (!this.collectionView){
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (this.collectionView._needsReload){
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (this.collectionView._edit !== null){
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
var shouldSelect = (!this.collectionView.delegate || !this.collectionView.delegate.collectionViewShouldSelectCellAtIndexPath || this.collectionView.delegate.collectionViewShouldSelectCellAtIndexPath(this.collectionView, this.collectionView.indexPathOfCell(this)));
|
|
136
145
|
if (shouldSelect){
|
|
137
146
|
this.over = true;
|
|
138
147
|
}
|
|
@@ -73,12 +73,19 @@ JSClass("UIHTMLApplication", UIApplication, {
|
|
|
73
73
|
if (options === undefined){
|
|
74
74
|
options = {};
|
|
75
75
|
}
|
|
76
|
-
if (options.replacingApplication
|
|
76
|
+
if (options.replacingApplication){
|
|
77
77
|
var application = this;
|
|
78
78
|
var open = function(){
|
|
79
|
+
application.domWindow.addEventListener("visibilitychange", function(e){
|
|
80
|
+
if (application.domWindow.document.visibilityState === "visible"){
|
|
81
|
+
application.domWindow.location.reload();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
79
84
|
application.domWindow.location.href = url.encodedString;
|
|
80
85
|
};
|
|
81
86
|
this.stop(open);
|
|
87
|
+
}else if (url.scheme === "mailto" || url.scheme === "tel"){
|
|
88
|
+
this.domWindow.location.href = url.encodedString;
|
|
82
89
|
}else{
|
|
83
90
|
try{
|
|
84
91
|
var child = this.domWindow.open(url.encodedString);
|
|
@@ -165,7 +165,14 @@ JSClass('UIHTMLContentEditableTextInputManager', UITextInputManager, {
|
|
|
165
165
|
if (anchor.offset < 0 || focus.offset < 0){
|
|
166
166
|
throw new Error("negative dom offset");
|
|
167
167
|
}
|
|
168
|
-
|
|
168
|
+
try{
|
|
169
|
+
domSelection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
|
|
170
|
+
}catch (e){
|
|
171
|
+
logger.debug("selection: @%d +%d", selection.range.location, selection.range.length);
|
|
172
|
+
logger.debug("anchor: %{public} @%d", anchor.toString(), anchor.offset);
|
|
173
|
+
logger.debug("focus: %{public} @%d", focus.toString(), focus.offset);
|
|
174
|
+
logger.error("failed to update html selection: %{error}", e);
|
|
175
|
+
}
|
|
169
176
|
// logger.debug("setting dom selection: %d->%d", anchor.offset, focus.offset);
|
|
170
177
|
if (domSelection.anchorNode){
|
|
171
178
|
// logger.debug(" selection anchor: %{public} @ %d", domSelection.anchorNode.nodeValue, domSelection.anchorOffset);
|
|
@@ -463,8 +470,12 @@ JSClass('UIHTMLContentEditableTextInputManager', UITextInputManager, {
|
|
|
463
470
|
if (this.shouldPreventSpaceInput || e.data !== " "){
|
|
464
471
|
e.preventDefault();
|
|
465
472
|
}
|
|
466
|
-
|
|
467
|
-
|
|
473
|
+
if (e.data === null){
|
|
474
|
+
logger.warn("received null data for insertText, ignoring");
|
|
475
|
+
}else{
|
|
476
|
+
this.textInputClient.insertText(e.data);
|
|
477
|
+
this.scheduleDocumentSelectionUpdate();
|
|
478
|
+
}
|
|
468
479
|
break;
|
|
469
480
|
case "insertLineBreak":
|
|
470
481
|
e.preventDefault();
|
|
@@ -203,9 +203,9 @@ JSClass("UIHTMLTextRun", JSTextRun, {
|
|
|
203
203
|
var rect;
|
|
204
204
|
var localIndex = index - this.range.location;
|
|
205
205
|
localIndex *= this._maskFactor;
|
|
206
|
-
var iterator =
|
|
207
|
-
sharedDomRange.setStart(
|
|
208
|
-
sharedDomRange.setEnd(
|
|
206
|
+
var iterator = sharedTextNodeForSizing.nodeValue.userPerceivedCharacterIterator(localIndex);
|
|
207
|
+
sharedDomRange.setStart(sharedTextNodeForSizing, iterator.range.location);
|
|
208
|
+
sharedDomRange.setEnd(sharedTextNodeForSizing, iterator.range.end);
|
|
209
209
|
var clientRect = this._pickCorrectClientRectFromRects(sharedDomRange.getClientRects());
|
|
210
210
|
if (clientRect === undefined){
|
|
211
211
|
return JSRect(0, 0, 0, this.size.height);
|
|
@@ -217,7 +217,6 @@ JSClass("UIHTMLTextRun", JSTextRun, {
|
|
|
217
217
|
updateSharedElementForSizing: function(){
|
|
218
218
|
if (sharedElementForSizing === null){
|
|
219
219
|
sharedElementForSizing = this.element.ownerDocument.createElement("span");
|
|
220
|
-
sharedElementForSizing.appendChild(sharedElementForSizing.ownerDocument.createTextNode(""));
|
|
221
220
|
sharedElementForSizing.style.visibility = "hidden";
|
|
222
221
|
sharedElementForSizing.style.position = "absolute";
|
|
223
222
|
sharedElementForSizing.style.zIndex = -100;
|
|
@@ -225,8 +224,12 @@ JSClass("UIHTMLTextRun", JSTextRun, {
|
|
|
225
224
|
sharedElementForSizing.style.whiteSpace = "pre";
|
|
226
225
|
sharedElementForSizing.ownerDocument.body.appendChild(sharedElementForSizing);
|
|
227
226
|
}
|
|
227
|
+
if (sharedTextNodeForSizing === null){
|
|
228
|
+
sharedTextNodeForSizing = sharedElementForSizing.ownerDocument.createTextNode("");
|
|
229
|
+
sharedElementForSizing.appendChild(sharedTextNodeForSizing);
|
|
230
|
+
}
|
|
228
231
|
sharedElementForSizing.style.font = this.element.style.font;
|
|
229
|
-
|
|
232
|
+
sharedTextNodeForSizing.nodeValue = this.textNode.nodeValue;
|
|
230
233
|
},
|
|
231
234
|
|
|
232
235
|
_pickCorrectClientRectFromRects: function(rects){
|
|
@@ -288,5 +291,6 @@ JSClass("UIHTMLTextRun", JSTextRun, {
|
|
|
288
291
|
});
|
|
289
292
|
|
|
290
293
|
var sharedElementForSizing = null;
|
|
294
|
+
var sharedTextNodeForSizing = null;
|
|
291
295
|
|
|
292
296
|
})();
|
|
@@ -143,6 +143,7 @@ JSClass("UIMenu", JSObject, {
|
|
|
143
143
|
for (var i = index + 1, l = this._items.length; i < l; ++i){
|
|
144
144
|
this._items[i].index = i;
|
|
145
145
|
}
|
|
146
|
+
this._styler.invalidateMenuPresentation(this);
|
|
146
147
|
},
|
|
147
148
|
|
|
148
149
|
// MARK: - Removing Items
|
|
@@ -168,11 +169,15 @@ JSClass("UIMenu", JSObject, {
|
|
|
168
169
|
if (item.tag in this._itemsByTag){
|
|
169
170
|
delete this._itemsByTag[item.tag];
|
|
170
171
|
}
|
|
172
|
+
if (item === this._highlightedItem){
|
|
173
|
+
this._highlightedItem = null;
|
|
174
|
+
}
|
|
171
175
|
item.menu = null;
|
|
172
176
|
this._items.splice(index, 1);
|
|
173
177
|
for (var i = index, l = this._items.length; i < l; ++i){
|
|
174
178
|
this._items[i].index = i;
|
|
175
179
|
}
|
|
180
|
+
this._styler.invalidateMenuPresentation(this);
|
|
176
181
|
},
|
|
177
182
|
|
|
178
183
|
removeAllItems: function(){
|
|
@@ -186,6 +191,8 @@ JSClass("UIMenu", JSObject, {
|
|
|
186
191
|
}
|
|
187
192
|
this._itemsByTag = {};
|
|
188
193
|
this._items = [];
|
|
194
|
+
this._highlightedItem = null;
|
|
195
|
+
this._styler.invalidateMenuPresentation(this);
|
|
189
196
|
},
|
|
190
197
|
|
|
191
198
|
// MARK: - Supermenu
|
|
@@ -433,6 +440,9 @@ JSClass("UIMenuStyler", JSObject, {
|
|
|
433
440
|
dismissMenu: function(menu, animated, completion, target){
|
|
434
441
|
},
|
|
435
442
|
|
|
443
|
+
invalidateMenuPresentation: function(menu){
|
|
444
|
+
},
|
|
445
|
+
|
|
436
446
|
getItemTitleOffset: function(menu){
|
|
437
447
|
return JSPoint.Zero;
|
|
438
448
|
},
|
|
@@ -844,6 +854,51 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
|
|
|
844
854
|
}
|
|
845
855
|
},
|
|
846
856
|
|
|
857
|
+
invalidateMenuPresentation: function(menu){
|
|
858
|
+
var window = menu.stylerProperties.window || null;
|
|
859
|
+
if (window !== null && window.screen !== null){
|
|
860
|
+
menu.updateEnabled();
|
|
861
|
+
window.update();
|
|
862
|
+
|
|
863
|
+
var screenMetrics = this.metricsForScreen(window.screen);
|
|
864
|
+
var size = JSSize(window.frame.size);
|
|
865
|
+
|
|
866
|
+
// Ensure we're at least the minimum width
|
|
867
|
+
// (although max width will take precedence)
|
|
868
|
+
if (size.width < menu._minimumWidth){
|
|
869
|
+
size.width = menu._minimumWidth;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// Limit width to the max screen width
|
|
873
|
+
if (size.width > screenMetrics.maximumWidth){
|
|
874
|
+
size.width = screenMetrics.maximumWidth;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// Set our origin so the origin of the target item matches the given location
|
|
878
|
+
var origin = JSPoint(window.frame.origin);
|
|
879
|
+
|
|
880
|
+
// Adjust our x position if we've overflowed
|
|
881
|
+
var over = origin.x + size.width - screenMetrics.safeFrame.origin.x - screenMetrics.safeFrame.size.width;
|
|
882
|
+
if (over > 0){
|
|
883
|
+
origin.x -= over;
|
|
884
|
+
}
|
|
885
|
+
if (origin.x < screenMetrics.safeFrame.origin.x){
|
|
886
|
+
origin.x = screenMetrics.safeFrame.origin.x;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
var offset = JSPoint.Zero;
|
|
890
|
+
|
|
891
|
+
// If we extend beyond the bottom, adjust our height
|
|
892
|
+
over = origin.y + size.height - screenMetrics.safeFrame.origin.y - screenMetrics.safeFrame.size.height;
|
|
893
|
+
if (over > 0){
|
|
894
|
+
size.height -= over;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
window.frame = JSRect(origin, size);
|
|
898
|
+
window.layoutIfNeeded();
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
|
|
847
902
|
metricsForScreen: function(screen){
|
|
848
903
|
var safeFrame = screen.availableFrame.rectWithInsets(4, 7);
|
|
849
904
|
if (screen.traitCollection.horizontalSizeClass === UIUserInterface.SizeClass.compact){
|
|
@@ -132,16 +132,26 @@ JSClass("UIMenuWindow", UIWindow, {
|
|
|
132
132
|
var itemView;
|
|
133
133
|
var menuSize = JSSize.Zero;
|
|
134
134
|
var i, l;
|
|
135
|
+
this._itemIndexesByItemViewId = {};
|
|
136
|
+
this._itemViewIndexesByItemId = {};
|
|
135
137
|
// TODO: optimize by only drawing those views that fill the screen
|
|
136
138
|
// We don't need to know the true height because we aren't showing a
|
|
137
139
|
// scroll bar, only indicators that there is more.
|
|
138
140
|
// Although, a UI that uses very long menus is poorly designed, so this
|
|
139
141
|
// is a low priority
|
|
142
|
+
var itemViewIndex = 0;
|
|
140
143
|
for (i = 0, l = this._menu.items.length; i < l; ++i){
|
|
141
144
|
item = this._menu.items[i];
|
|
142
145
|
if (!item.hidden){
|
|
143
|
-
this._itemViewIndexesByItemId[item.objectID] =
|
|
144
|
-
|
|
146
|
+
this._itemViewIndexesByItemId[item.objectID] = itemViewIndex;
|
|
147
|
+
if (i < this.menuView.itemViews.length){
|
|
148
|
+
itemView = this.menuView.itemViews[i];
|
|
149
|
+
if (itemView instanceof UIMenuItemView){
|
|
150
|
+
itemView.setItem(item);
|
|
151
|
+
}
|
|
152
|
+
}else{
|
|
153
|
+
itemView = this.menuView.addViewForItem(item);
|
|
154
|
+
}
|
|
145
155
|
itemView.sizeToFit();
|
|
146
156
|
if (!item.alternate){
|
|
147
157
|
menuSize.height += itemView.frame.size.height;
|
|
@@ -150,8 +160,14 @@ JSClass("UIMenuWindow", UIWindow, {
|
|
|
150
160
|
menuSize.width = itemView.frame.size.width;
|
|
151
161
|
}
|
|
152
162
|
this._itemIndexesByItemViewId[itemView.objectID] = i;
|
|
163
|
+
++itemViewIndex;
|
|
153
164
|
}
|
|
154
165
|
}
|
|
166
|
+
for (var j = this.menuView.itemViews.length - 1; j >= itemViewIndex; --j){
|
|
167
|
+
itemView = this.menuView.itemViews[j];
|
|
168
|
+
itemView.removeFromSuperview();
|
|
169
|
+
this.menuView.itemViews.pop();
|
|
170
|
+
}
|
|
155
171
|
this.menuView.bounds = JSRect(JSPoint.Zero, menuSize);
|
|
156
172
|
this.menuView.layoutIfNeeded();
|
|
157
173
|
this.layoutIfNeeded();
|
|
@@ -119,6 +119,10 @@ JSClass("UIPopupWindow", UIWindow, {
|
|
|
119
119
|
if (animated === undefined){
|
|
120
120
|
animated = true;
|
|
121
121
|
}
|
|
122
|
+
if (view.window === null || view.window.screen === null){
|
|
123
|
+
JSNotificationCenter.shared.post("UIWindowWillClose", this);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
122
126
|
var sourceBounds = view.bounds;
|
|
123
127
|
if (view.sourceRectForPopupWindow){
|
|
124
128
|
sourceBounds = view.sourceRectForPopupWindow(this);
|
|
@@ -408,6 +412,10 @@ JSClass("UIPopupWindow", UIWindow, {
|
|
|
408
412
|
if (animated === undefined){
|
|
409
413
|
animated = true;
|
|
410
414
|
}
|
|
415
|
+
if (view.window === null || view.window.screen === null){
|
|
416
|
+
JSNotificationCenter.shared.post("UIWindowWillClose", this);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
411
419
|
var sourceFrame = view.convertRectToScreen(view.bounds);
|
|
412
420
|
var safeFrame = view.window.screen.availableFrame.rectWithInsets(20);
|
|
413
421
|
|
|
@@ -860,6 +860,9 @@ JSClass("UIWindowServer", JSObject, {
|
|
|
860
860
|
_windowResizeWidthOutside: 4,
|
|
861
861
|
|
|
862
862
|
windowResizeHitTest: function(window, location){
|
|
863
|
+
if (location === null){
|
|
864
|
+
return UIWindowServer.ResizeOperation.none;
|
|
865
|
+
}
|
|
863
866
|
if (!window._canResizeWidth && !window._canResizeHeight){
|
|
864
867
|
return UIWindowServer.ResizeOperation.none;
|
|
865
868
|
}
|
|
@@ -252,6 +252,9 @@ HTMLAppBootstrapper.prototype = {
|
|
|
252
252
|
script.type = 'text/javascript';
|
|
253
253
|
script.async = async;
|
|
254
254
|
script.addEventListener('load', function HTMLAppBootstrapper_scriptLoad(e){
|
|
255
|
+
if (!bootstrapper.loadingScripts[src]){
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
255
258
|
if (bootstrapper.loadingScripts[src].compileError !== null){
|
|
256
259
|
errorCallback(bootstrapper.loadingScripts[src].compileError);
|
|
257
260
|
delete bootstrapper.loadingScripts[src];
|