@breakside/jskit 2025.37.0 → 2025.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/JS/JSFont.js +0 -3
  7. package/Frameworks/Foundation.jsframework/JS/JSFontDescriptor.js +10 -1
  8. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  9. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  10. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  11. package/Info.json +2 -2
  12. package/Node/Resources.js +5 -3
  13. package/Node/io.breakside.jskit-bundle.js +2 -2
  14. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  15. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  16. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  17. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  18. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  19. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  20. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  21. package/Root/Frameworks/DOM/Info.yaml +1 -1
  22. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  23. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  24. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  25. package/Root/Frameworks/Foundation/JSFont.js +0 -3
  26. package/Root/Frameworks/Foundation/JSFontDescriptor.js +10 -1
  27. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  28. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  29. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  30. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  31. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  32. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  33. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  34. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  35. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  36. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  37. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  38. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  39. package/Root/Frameworks/UIKit/UIContainerView.js +6 -1
  40. package/Root/Frameworks/UIKit/UIMenu.js +6 -0
  41. package/Root/Frameworks/UIKit/UIMenuItem.js +2 -0
  42. package/Root/Frameworks/UIKit/UIMenuView.js +41 -1
  43. package/Root/Frameworks/UIKit/UIScrollView.js +7 -2
  44. package/Root/Frameworks/UIKit/UISplitView.js +2 -2
  45. package/Root/Frameworks/UIKit/UIStackView.js +5 -0
  46. package/Root/Frameworks/UIKit/UITabView.js +15 -3
  47. package/Root/Frameworks/UIKit/UITextEditor.js +3 -0
  48. package/Root/Frameworks/UIKit/UITextField.js +11 -7
  49. package/Root/Frameworks/UIKit/UIToolbar.js +13 -0
  50. package/Root/Frameworks/UIKit/UIView.js +9 -0
  51. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  52. 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.37.0",
4
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
12
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
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.37.0",
6
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
14
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
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.37.0",
4
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
11
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
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.37.0",
6
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
13
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
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.37.0",
4
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
12
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
13
13
  }
@@ -136,9 +136,6 @@ JSClass("JSFont", JSObject, {
136
136
 
137
137
  bolderFont: function(){
138
138
  var descriptor = this.descriptor.bolderDescriptor();
139
- if (descriptor === null){
140
- descriptor = this.descriptor.fontWithWeight(JSFont.Weight.bold);
141
- }
142
139
  return JSFont.initWithDescriptor(descriptor, this.pointSize);
143
140
  },
144
141
 
@@ -45,7 +45,16 @@ JSClass("JSFontDescriptor", JSObject, {
45
45
 
46
46
  bolderDescriptor: function(){
47
47
  var weight = this._weight + 300;
48
- return this.descriptorWithWeight(weight);
48
+ var descriptor = JSFontDescriptor.descriptorWithFamily(this.family, weight, this.style);
49
+ if (descriptor === null){
50
+ weight = this._weight + 200;
51
+ descriptor = JSFontDescriptor.descriptorWithFamily(this.family, weight, this.style);
52
+ if (descriptor === null){
53
+ weight = this._weight + 100;
54
+ descriptor = JSFontDescriptor.descriptorWithFamily(this.family, weight, this.style);
55
+ }
56
+ }
57
+ return descriptor || this;
49
58
  },
50
59
 
51
60
  descriptorWithStyle: function(style){
@@ -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.37.0",
6
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
14
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
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.37.0",
4
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
12
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
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.37.0",
6
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
14
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
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.37.0",
4
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
11
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
12
12
  }
package/Node/Resources.js CHANGED
@@ -50,7 +50,7 @@ JSClass("Resources", JSObject, {
50
50
 
51
51
  getImportPaths: async function(importDirectoryURLs){
52
52
  var fileManager = this.fileManager;
53
- var addImportsFromObject = async function(obj){
53
+ var addImportsFromObject = async function(obj, debugPath){
54
54
  if (typeof(obj) == "object"){
55
55
  if ('class' in obj){
56
56
  let path = obj['class'] + '.js';
@@ -97,7 +97,9 @@ JSClass("Resources", JSObject, {
97
97
  }
98
98
  for (let k in obj){
99
99
  if (k == 'class' || k == 'include') continue;
100
- await addImportsFromObject(obj[k]);
100
+ if (obj[k] !== null){
101
+ await addImportsFromObject(obj[k], debugPath.concat([k]));
102
+ }
101
103
  }
102
104
  }
103
105
  };
@@ -119,7 +121,7 @@ JSClass("Resources", JSObject, {
119
121
  for (let i = 0, l = this.metadata.length; i < l; ++i){
120
122
  let metadata = this.metadata[i];
121
123
  if (metadata.spec){
122
- await addImportsFromObject(metadata.value);
124
+ await addImportsFromObject(metadata.value, [metadata.path]);
123
125
  }
124
126
  }
125
127
  return Array.from(paths.values());
@@ -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.37.0",
6
+ "JSBundleVersion": "2025.41.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": "9291bb0c17f6a29b383c667bbee690664f9fb896"
13
+ "GitRevision": "33135f87071fd20f7ab28e4ab55dc741edd834bb"
14
14
  },
15
15
  "Resources": [
16
16
  {
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSIncludeDirectories:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKitTesting
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.AuthKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.CSSOM
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ChartKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  # JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ConferenceKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DBKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DOM
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Dispatch
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSCopyright: Copyright © 2020 Breakside Inc.
5
5
  JSBundleEnvironments:
6
6
  html: Dispatch+HTML.js
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.FontKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Foundation
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -136,9 +136,6 @@ JSClass("JSFont", JSObject, {
136
136
 
137
137
  bolderFont: function(){
138
138
  var descriptor = this.descriptor.bolderDescriptor();
139
- if (descriptor === null){
140
- descriptor = this.descriptor.fontWithWeight(JSFont.Weight.bold);
141
- }
142
139
  return JSFont.initWithDescriptor(descriptor, this.pointSize);
143
140
  },
144
141
 
@@ -45,7 +45,16 @@ JSClass("JSFontDescriptor", JSObject, {
45
45
 
46
46
  bolderDescriptor: function(){
47
47
  var weight = this._weight + 300;
48
- return this.descriptorWithWeight(weight);
48
+ var descriptor = JSFontDescriptor.descriptorWithFamily(this.family, weight, this.style);
49
+ if (descriptor === null){
50
+ weight = this._weight + 200;
51
+ descriptor = JSFontDescriptor.descriptorWithFamily(this.family, weight, this.style);
52
+ if (descriptor === null){
53
+ weight = this._weight + 100;
54
+ descriptor = JSFontDescriptor.descriptorWithFamily(this.family, weight, this.style);
55
+ }
56
+ }
57
+ return descriptor || this;
49
58
  },
50
59
 
51
60
  descriptorWithStyle: function(style){
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKitUI
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.NotificationKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.PDFKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.QRKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SearchKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SecurityKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKitTesting
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.TestKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKit
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -105,6 +105,11 @@ JSClass("UIContainerView", UIView, {
105
105
  );
106
106
  },
107
107
 
108
+ subviewDidInvalidateSize: function(subview){
109
+ this.setNeedsLayout();
110
+ this.invalidateSize();
111
+ },
112
+
108
113
  sizeToFitSize: function(maxSize){
109
114
  if (this._contentView === null){
110
115
  UIContainerView.$super.sizeToFitSize.call(this, maxSize);
@@ -128,7 +133,7 @@ JSClass("UIContainerView", UIView, {
128
133
  var rect = this.bounds.rectWithInsets(this._contentInsets);
129
134
  if (this._contentView !== null){
130
135
  if (this._alignment === UIContainerView.Alignment.full){
131
- this._contentView.frame = rect;
136
+ this._contentView.untransformedFrame = rect;
132
137
  }else if (this._alignment === UIContainerView.Alignment.center){
133
138
  var maxSize = JSSize(rect.size);
134
139
  if (this._maximumContentSize.width > 0 && this._maximumContentSize.width < maxSize.width){
@@ -446,6 +446,7 @@ JSClass("UIMenuStyler", JSObject, {
446
446
  });
447
447
 
448
448
  var defaultTextColor = JSColor.text;
449
+ var defaultSecondaryTextColor = JSColor.secondaryText;
449
450
  var defaultHighlightTextColor = JSColor.highlightedText;
450
451
  var defaultDisabledTextColor = JSColor.text.colorWithAlpha(0.2);
451
452
  var defaultHighlightColor = JSColor.highlight;
@@ -457,6 +458,7 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
457
458
  cornerRadius: JSDynamicProperty('_cornerRadius', 6),
458
459
  capSize: JSDynamicProperty('_capSize', 5),
459
460
  textColor: JSDynamicProperty('_textColor', defaultTextColor),
461
+ secondaryTextColor: JSDynamicProperty('_secondaryTextColor', defaultSecondaryTextColor),
460
462
  disabledTextColor: JSDynamicProperty('_disabledTextColor', defaultDisabledTextColor),
461
463
  highlightedTextColor: JSDynamicProperty('_highlightedTextColor', defaultHighlightTextColor),
462
464
  highlightColor: JSDynamicProperty('_highlightColor', defaultHighlightColor),
@@ -493,6 +495,9 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
493
495
  if (spec.containsKey('textColor')){
494
496
  this._textColor = spec.valueForKey("textColor", JSColor);
495
497
  }
498
+ if (spec.containsKey('secondaryTextColor')){
499
+ this._secondaryTextColor = spec.valueForKey("secondaryTextColor", JSColor);
500
+ }
496
501
  if (spec.containsKey('disabledTextColor')){
497
502
  this._disabledTextColor = spec.valueForKey("disabledTextColor", JSColor);
498
503
  }
@@ -876,6 +881,7 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
876
881
  window.indentationSize = this.indentationSize;
877
882
  window.highlightColor = this.highlightColor;
878
883
  window.textColor = this.textColor;
884
+ window.secondaryTextColor = this.secondaryTextColor;
879
885
  window.highlightedTextColor = this.highlightedTextColor;
880
886
  window.disabledTextColor = this.disabledTextColor;
881
887
  window.update();
@@ -43,6 +43,8 @@ JSClass("UIMenuItem", JSObject, {
43
43
  target: null,
44
44
  action: null,
45
45
  view: null,
46
+ detailText: null,
47
+ numberOfDetailTextLines: 0,
46
48
  accessoryView: null,
47
49
  accessorySize: null,
48
50
 
@@ -54,6 +54,7 @@ JSClass("UIMenuWindow", UIWindow, {
54
54
  indentationSize: 10,
55
55
  highlightColor: null,
56
56
  textColor: null,
57
+ secondaryTextColor: null,
57
58
  highlightedTextColor: null,
58
59
  disabledTextColor: null,
59
60
  _lastMoveLocation: null,
@@ -130,12 +131,13 @@ JSClass("UIMenuWindow", UIWindow, {
130
131
  var item;
131
132
  var itemView;
132
133
  var menuSize = JSSize.Zero;
134
+ var i, l;
133
135
  // TODO: optimize by only drawing those views that fill the screen
134
136
  // We don't need to know the true height because we aren't showing a
135
137
  // scroll bar, only indicators that there is more.
136
138
  // Although, a UI that uses very long menus is poorly designed, so this
137
139
  // is a low priority
138
- for (var i = 0, l = this._menu.items.length; i < l; ++i){
140
+ for (i = 0, l = this._menu.items.length; i < l; ++i){
139
141
  item = this._menu.items[i];
140
142
  if (!item.hidden){
141
143
  this._itemViewIndexesByItemId[item.objectID] = this.menuView.itemViews.length;
@@ -765,6 +767,7 @@ JSClass("UIMenuView", UIView, {
765
767
  view.contentInsets = this.menuWindow.itemContentInsets;
766
768
  view.indentationSize = this.menuWindow.indentationSize;
767
769
  view.textColor = this.menuWindow.textColor;
770
+ view.secondaryTextColor = this.menuWindow.secondaryTextColor;
768
771
  view.highlightedTextColor = this.menuWindow.highlightedTextColor;
769
772
  view.disabledTextColor = this.menuWindow.disabledTextColor;
770
773
  view.highlightColor = this.menuWindow.highlightColor;
@@ -865,7 +868,9 @@ JSClass("UIMenuItemSeparatorView", UIView, {
865
868
  JSClass("UIMenuItemView", UIView, {
866
869
 
867
870
  titleLabel: null,
871
+ detailLabel: null,
868
872
  textColor: null,
873
+ secondaryTextColor: null,
869
874
  highlightedTextColor: null,
870
875
  disabledTextColor: null,
871
876
  highlightColor: null,
@@ -927,6 +932,19 @@ JSClass("UIMenuItemView", UIView, {
927
932
  setItem: function(item){
928
933
  this._item = item;
929
934
  this.titleLabel.text = item.title;
935
+ if (item.detailText !== null){
936
+ if (this.detailLabel === null){
937
+ this.detailLabel = UILabel.init();
938
+ this.detailLabel.font = JSFont.detail;
939
+ this.detailLabel.text = item.detailText;
940
+ this.insertSubviewBelowSibling(this.detailLabel, this.titleLabel);
941
+ }
942
+ }else{
943
+ if (this.detailLabel !== null){
944
+ this.detailLabel.removeFromSuperview();
945
+ this.detailLabel = null;
946
+ }
947
+ }
930
948
  if (item.image !== null){
931
949
  this.imageView.image = item.image;
932
950
  }else if (this._imageView !== null){
@@ -969,6 +987,10 @@ JSClass("UIMenuItemView", UIView, {
969
987
  var textColor = this.getTextColorForItem(item);
970
988
  this.titleLabel.font = item.menu.font;
971
989
  this.titleLabel.textColor = textColor;
990
+ if (this.detailLabel !== null){
991
+ this.detailLabel.textColor = this.getDetailTextColorForItem(item);
992
+ this.detailLabel.maximumNumberOfLines = item.numberOfDetailTextLines;
993
+ }
972
994
  if (this._imageView !== null){
973
995
  this._imageView.templateColor = textColor;
974
996
  if (!item.enabled && this._imageView.image !== null && this._imageView.image.renderMode === JSImage.RenderMode.original){
@@ -1019,6 +1041,16 @@ JSClass("UIMenuItemView", UIView, {
1019
1041
  return this.disabledTextColor;
1020
1042
  },
1021
1043
 
1044
+ getDetailTextColorForItem: function(item){
1045
+ if (item.enabled){
1046
+ if (item.highlighted){
1047
+ return this.highlightedTextColor;
1048
+ }
1049
+ return this.secondaryTextColor;
1050
+ }
1051
+ return this.disabledTextColor;
1052
+ },
1053
+
1022
1054
  updateItemView: function(view, item){
1023
1055
  },
1024
1056
 
@@ -1086,6 +1118,11 @@ JSClass("UIMenuItemView", UIView, {
1086
1118
  left = right;
1087
1119
  }
1088
1120
  this.titleLabel.frame = JSRect(left, this.contentInsets.top, right - left, lineHeight);
1121
+ if (this.detailLabel !== null){
1122
+ right = this.bounds.size.width - this.contentInsets.right;
1123
+ var y = this.contentInsets.top + lineHeight;
1124
+ this.detailLabel.frame = JSRect(left, y, right - left, this.bounds.size.height - this.contentInsets.bottom - y);
1125
+ }
1089
1126
  },
1090
1127
 
1091
1128
  sizeToFit: function(){
@@ -1127,6 +1164,9 @@ JSClass("UIMenuItemView", UIView, {
1127
1164
  size.height = lineHeight + this.contentInsets.top + this.contentInsets.bottom;
1128
1165
  size.width = Math.ceil(size.width);
1129
1166
  size.height = Math.ceil(size.height);
1167
+ if (this.detailLabel !== null && item.numberOfDetailTextLines > 0){
1168
+ size.height += this.detailLabel.font.displayLineHeight * item.numberOfDetailTextLines;
1169
+ }
1130
1170
  this.bounds = JSRect(JSPoint.Zero, size);
1131
1171
  },
1132
1172
 
@@ -44,7 +44,7 @@ JSClass('UIScrollView', UIView, {
44
44
  // These properties are optional in the spec, and are typically only provided if
45
45
  // the user wants to provide specialized customization
46
46
  if (spec.containsKey('contentView')){
47
- this._contentView = spec.valueForKey("contentView", UIView);
47
+ this._contentView = spec.valueForKey("contentView", this.contentViewClass);
48
48
  }else{
49
49
  // If any subviews were added directly to this view, and a
50
50
  // contentView was not provided, treat the subviews as children
@@ -84,15 +84,20 @@ JSClass('UIScrollView', UIView, {
84
84
  if (spec.containsKey('delaysContentTouches')){
85
85
  this._delaysContentTouches = spec.valueForKey("delaysContentTouches");
86
86
  }
87
+ if (spec.containsKey('delegate')){
88
+ this.delegate = spec.valueForKey('delegate');
89
+ }
87
90
  },
88
91
 
92
+ contentViewClass: UIView,
93
+
89
94
  _commonScrollViewInit: function(){
90
95
  this.clipsToBounds = true;
91
96
 
92
97
  // Only create the content view and scrollers if the haven't already been created
93
98
  // by a specialized init function like initWithSpec.
94
99
  if (this._contentView === null){
95
- this._contentView = UIView.initWithFrame(this.bounds);
100
+ this._contentView = this.contentViewClass.initWithFrame(this.bounds);
96
101
  }
97
102
  if (this._horizontalScroller === null){
98
103
  this._horizontalScroller = UIScroller.initWithDirection(UIScroller.Direction.horizontal, this._scrollStyler);
@@ -487,7 +487,7 @@ JSClass("UISplitView", UIView, {
487
487
  }
488
488
  if (divider === this._leadingDividerView){
489
489
  var maximumLeadingSize = boundsSize - this._minimumMainSize;
490
- if (this._trailingViewOpen){
490
+ if (this._trailingViewOpen && this._trailingView !== null){
491
491
  maximumLeadingSize -= this._trailingSize;
492
492
  }
493
493
  if (this._maximumLeadingSize < maximumLeadingSize){
@@ -517,7 +517,7 @@ JSClass("UISplitView", UIView, {
517
517
  }
518
518
  }else if (divider === this._trailingDividerView){
519
519
  var maximumTrailingSize = boundsSize - this._minimumMainSize;
520
- if (this._leadingViewOpen){
520
+ if (this._leadingViewOpen && this._leadingView !== null){
521
521
  maximumTrailingSize -= this._leadingSize;
522
522
  }
523
523
  if (this._maximumTrailingSize < maximumTrailingSize){
@@ -217,6 +217,11 @@ JSClass("UIStackView", UIView, {
217
217
  this.setNeedsLayout();
218
218
  },
219
219
 
220
+ subviewDidInvalidateSize: function(subview){
221
+ this.setNeedsLayout();
222
+ this.invalidateSize();
223
+ },
224
+
220
225
  getFirstBaselineOffsetFromTop: function(){
221
226
  var top = this._contentInsets.top;
222
227
  if (this._arrangedSubviews.length > 0){
@@ -421,7 +421,19 @@ JSClass("UITabViewItemView", UIView, {
421
421
 
422
422
  canBecomeFirstResponder: function(){
423
423
  return this.fullKeyboardAccessEnabled;
424
- }
424
+ },
425
+
426
+ mouseEntered: function(event){
427
+ var tabView = this.superview.tabView;
428
+ tabView.items[this.index].over = true;
429
+ tabView._styler.updateTabViewItemAtIndex(tabView, this.index);
430
+ },
431
+
432
+ mouseExited: function(event){
433
+ var tabView = this.superview.tabView;
434
+ tabView.items[this.index].over = false;
435
+ tabView._styler.updateTabViewItemAtIndex(tabView, this.index);
436
+ },
425
437
 
426
438
  });
427
439
 
@@ -717,8 +729,8 @@ JSClass("UITabViewDefaultStyler", UITabViewStyler, {
717
729
  if (spec.containsKey("itemContentInsets")){
718
730
  this.itemContentInsets = spec.valueForKey("itemContentInsets", JSInsets);
719
731
  }
720
- if (spec.containsKey("itemInsets")){
721
- this.itemInsets = spec.valueForKey("itemInsets", JSInsets);
732
+ if (spec.containsKey("itemsInsets")){
733
+ this.itemsInsets = spec.valueForKey("itemsInsets", JSInsets);
722
734
  }
723
735
  if (spec.containsKey("dividerColor")){
724
736
  this.dividerColor = spec.valueForKey("dividerColor", JSColor);
@@ -760,7 +760,9 @@ JSClass("UITextEditor", JSObject, {
760
760
  }
761
761
  this.undoManager.registerUndo(this, this._replaceTextStorageRangeAllowingUndo, textStorage, JSRange(range.location, insertedLength), replacedString);
762
762
  this._isHandlingSelectionAdjustments = true;
763
+ this._isHandlingUserAction = true;
763
764
  textStorage.replaceCharactersInRangeWithAttributedString(range, attributedString);
765
+ this._isHandlingUserAction = false;
764
766
  this._isHandlingSelectionAdjustments = false;
765
767
  },
766
768
 
@@ -817,6 +819,7 @@ JSClass("UITextEditor", JSObject, {
817
819
  },
818
820
 
819
821
  _isHandlingSelectionAdjustments: false,
822
+ _isHandlingUserAction: false,
820
823
 
821
824
  textStorageDidReplaceCharactersInRange: function(range, insertedLength){
822
825
  if (!this._isHandlingSelectionAdjustments){
@@ -799,13 +799,17 @@ JSClass("UITextField", UIControl, {
799
799
  }else if (!this._isEmpty && insertedLength === 0 && !this._textLayer.hasText()){
800
800
  this._updateIsEmpty(true);
801
801
  }
802
- this.didChangeValueForBinding('text');
803
- this.didChangeValueForBinding('attributedText');
804
- this.didChangeValueForBinding('integerValue');
805
- this.postAccessibilityNotification(UIAccessibility.Notification.valueChanged);
806
- this.sendActionsForEvents(UIControl.Event.editingChanged);
807
- if (this.delegate && this.delegate.textFieldDidChange){
808
- this.delegate.textFieldDidChange(this);
802
+ if (textEditor._isHandlingUserAction){
803
+ this.didChangeValueForBinding('text');
804
+ this.didChangeValueForBinding('attributedText');
805
+ this.didChangeValueForBinding('integerValue');
806
+ this.postAccessibilityNotification(UIAccessibility.Notification.valueChanged);
807
+ this.sendActionsForEvents(UIControl.Event.editingChanged);
808
+ if (this.delegate && this.delegate.textFieldDidChange){
809
+ this.delegate.textFieldDidChange(this);
810
+ }
811
+ }else{
812
+ this.postAccessibilityNotification(UIAccessibility.Notification.valueChanged);
809
813
  }
810
814
  this._didChange = true;
811
815
  if (this._textLayer.textAlignment !== JSTextAlignment.left){
@@ -158,6 +158,19 @@ JSClass("UIToolbar", UIView, {
158
158
  return this._styler.intrinsicSizeOfToolbar(this);
159
159
  },
160
160
 
161
+ sizeToFitSize: function(maxSize){
162
+ var size = JSSize(this.intrinsicSize);
163
+ if (size.width === UIView.noIntrinsicSize){
164
+ size.width = maxSize.width;
165
+ }else if (size.width > maxSize.width){
166
+ size.width = maxSize.width;
167
+ }
168
+ if (size.height > maxSize.height){
169
+ size.height = maxSize.height;
170
+ }
171
+ this.bounds = JSRect(JSPoint.Zero, size);
172
+ },
173
+
161
174
  // --------------------------------------------------------------------
162
175
  // MARK: - Accessibility
163
176
 
@@ -583,6 +583,15 @@ JSClass('UIView', UIResponder, {
583
583
  this._needsIntrinsicSizeConstraintUpdate = true;
584
584
  },
585
585
 
586
+ invalidateSize: function(){
587
+ if (this.superview !== null){
588
+ this.superview.subviewDidInvalidateSize(this);
589
+ }
590
+ },
591
+
592
+ subviewDidInvalidateSize: function(subview){
593
+ },
594
+
586
595
  layerDidChangeSize: function(layer){
587
596
  if (layer === this.layer){
588
597
  this.invalidateFocusRingPath();
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKitTesting
3
- JSBundleVersion: 2025.37.0
3
+ JSBundleVersion: 2025.41.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "node": ">=10.10.0"
10
10
  },
11
11
  "name": "@breakside/jskit",
12
- "version": "2025.37.0",
12
+ "version": "2025.41.0",
13
13
  "license": "SEE LICENSE IN LICENSE.txt",
14
14
  "files": [
15
15
  "*"