@breakside/jskit 2024.15.0 → 2024.20.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 (48) 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/JSTextLayoutManager.js +16 -0
  7. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  8. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  9. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  10. package/Info.json +2 -2
  11. package/Node/io.breakside.jskit-bundle.js +2 -2
  12. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  13. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  14. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  15. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  16. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  17. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  18. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  19. package/Root/Frameworks/DOM/Info.yaml +1 -1
  20. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  21. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  22. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  23. package/Root/Frameworks/Foundation/JSTextLayoutManager.js +16 -0
  24. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  25. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  26. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  27. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  28. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  29. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  30. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  31. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  32. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  33. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  34. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  35. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  36. package/Root/Frameworks/UIKit/UIAccessibility.js +4 -1
  37. package/Root/Frameworks/UIKit/UIApplication.js +14 -1
  38. package/Root/Frameworks/UIKit/UIHTMLDisplayServer.js +6 -0
  39. package/Root/Frameworks/UIKit/UIHTMLDisplayServerCanvasContext.js +12 -2
  40. package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +10 -1
  41. package/Root/Frameworks/UIKit/UIListView.js +2 -2
  42. package/Root/Frameworks/UIKit/UIListViewCell.js +1 -1
  43. package/Root/Frameworks/UIKit/UINavigationBar.js +2 -2
  44. package/Root/Frameworks/UIKit/UIView.js +35 -3
  45. package/Root/Frameworks/UIKit/UIWindow.js +4 -1
  46. package/Root/Frameworks/UIKit/UIWindowServer.js +131 -11
  47. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  48. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.DOM",
4
- "JSBundleVersion": "2024.15.0",
4
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
12
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
6
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
14
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
4
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
11
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
6
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
13
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
4
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
12
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
13
13
  }
@@ -171,6 +171,22 @@ JSClass("JSTextLayoutManager", JSObject, {
171
171
  this.setNeedsLayout();
172
172
  },
173
173
 
174
+ temporaryAttributesAtIndex: function(index){
175
+ return this._temporaryAttributedString.attributesAtIndex(index);
176
+ },
177
+
178
+ temporaryAttributeAtIndex: function(attributeName, index){
179
+ return this._temporaryAttributedString.attributeAtIndex(attributeName, index);
180
+ },
181
+
182
+ longestRangeOfTemporaryAttributeAtIndex: function(attributeName, index){
183
+ return this._temporaryAttributedString.longestRangeOfAttributeAtIndex(attributeName, index);
184
+ },
185
+
186
+ longestRangeOfTemporaryAttributesAtIndex: function(attributeNames, index){
187
+ return this._temporaryAttributedString.longestRangeOfAttributesAtIndex(attributeNames, index);
188
+ },
189
+
174
190
  // MARK: - Layout
175
191
 
176
192
  setNeedsLayout: function(){
@@ -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": "2024.15.0",
6
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
14
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
4
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
12
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
6
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
14
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
4
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
11
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
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": "2024.15.0",
6
+ "JSBundleVersion": "2024.20.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": "fe0cad01e494854b98abafb2e8cbd4da7eede6b5"
13
+ "GitRevision": "db73dee805a2ddf357407e46018c1a74ccdd9310"
14
14
  },
15
15
  "Resources": [
16
16
  {
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKit
3
- JSBundleVersion: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -171,6 +171,22 @@ JSClass("JSTextLayoutManager", JSObject, {
171
171
  this.setNeedsLayout();
172
172
  },
173
173
 
174
+ temporaryAttributesAtIndex: function(index){
175
+ return this._temporaryAttributedString.attributesAtIndex(index);
176
+ },
177
+
178
+ temporaryAttributeAtIndex: function(attributeName, index){
179
+ return this._temporaryAttributedString.attributeAtIndex(attributeName, index);
180
+ },
181
+
182
+ longestRangeOfTemporaryAttributeAtIndex: function(attributeName, index){
183
+ return this._temporaryAttributedString.longestRangeOfAttributeAtIndex(attributeName, index);
184
+ },
185
+
186
+ longestRangeOfTemporaryAttributesAtIndex: function(attributeNames, index){
187
+ return this._temporaryAttributedString.longestRangeOfAttributesAtIndex(attributeNames, index);
188
+ },
189
+
174
190
  // MARK: - Layout
175
191
 
176
192
  setNeedsLayout: function(){
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.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: 2024.15.0
3
+ JSBundleVersion: 2024.20.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -181,7 +181,9 @@ UIAccessibility.Subrole = {
181
181
  tooltip: "tooltip",
182
182
  alert: "alert",
183
183
  menuItemRadio: "menuItemRadio",
184
- menuItemCheckbox: "menuItemCheckbox"
184
+ menuItemCheckbox: "menuItemCheckbox",
185
+ navigation: "navigation",
186
+ region: "region"
185
187
  };
186
188
 
187
189
  UIAccessibility.Orientation = {
@@ -234,6 +236,7 @@ UIAccessibility.Notification = {
234
236
  rowCollapsed: "UIAccessibility.Notification.rowCollapsed",
235
237
  selectedChildrenChanged: "UIAccessibility.Notification.selectedChildrenChanged",
236
238
  selectedTextChanged: "UIAccessibility.Notification.selectedTextChanged",
239
+ identifierChanged: "UIAccessibility.Notification.identifierChanged",
237
240
  labelChanged: "UIAccessibility.Notification.labelChanged",
238
241
  titleChanged: "UIAccessibility.Notification.labelChanged",
239
242
  valueChanged: "UIAccessibility.Notification.valueChanged",
@@ -423,6 +423,10 @@ JSClass('UIApplication', UIResponder, {
423
423
  return null;
424
424
  },
425
425
 
426
+ keyDown: function(event){
427
+ this.windowServer.textInputManager.sendActionsForEvent(event);
428
+ },
429
+
426
430
  // MARK: - Touch Event Conversion
427
431
 
428
432
  convertsTouchesToMouseEvents: false,
@@ -502,7 +506,7 @@ JSClass('UIApplication', UIResponder, {
502
506
  accessibilitySubrole: null,
503
507
 
504
508
  // Label
505
- accessibilityIdentifier: null,
509
+ accessibilityIdentifier: JSDynamicProperty("_accessibilityIdentifier"),
506
510
  accessibilityLabel: JSReadOnlyProperty(),
507
511
  accessibilityHint: null,
508
512
 
@@ -524,6 +528,15 @@ JSClass('UIApplication', UIResponder, {
524
528
  accessibilityParent: null,
525
529
  accessibilityElements: JSReadOnlyProperty(),
526
530
 
531
+ getAccessibilityIdentifier: function(){
532
+ return this._accessibilityIdentifier;
533
+ },
534
+
535
+ setAccessibilityIdentifier: function(accessibilityIdentifier){
536
+ this._accessibilityIdentifier = accessibilityIdentifier;
537
+ this.windowServer.postNotificationForAccessibilityElement(UIAccessibility.Notification.identifierChanged, this);
538
+ },
539
+
527
540
  getAccessibilityFrame: function(){
528
541
  return this.windowServer.screen.frame;
529
542
  },
@@ -483,6 +483,12 @@ JSClass("UIHTMLDisplayServer", UIDisplayServer, {
483
483
  }
484
484
  }
485
485
  },
486
+
487
+ // MARK: - Accessibility
488
+
489
+ elementIDForAccessibility: function(accessibility){
490
+ return accessibility.accessibilityIdentifier || "accessibility-%d".sprintf(accessibility.objectID);
491
+ },
486
492
 
487
493
  // MARK: - Debugging
488
494
 
@@ -928,7 +928,6 @@ JSClass("UIHTMLDisplayServerCanvasContext", UIHTMLDisplayServerContext, {
928
928
  }else{
929
929
  this.element.removeAttribute("aria-roledescription");
930
930
  }
931
- this.element.id = "accessibility-%d".sprintf(accessibility.objectID);
932
931
  switch (ariaRole){
933
932
  case "button":
934
933
  case "tab":
@@ -961,6 +960,7 @@ JSClass("UIHTMLDisplayServerCanvasContext", UIHTMLDisplayServerContext, {
961
960
  this.element.addEventListener("mousedown", this.accessibilityMousedownListener);
962
961
  break;
963
962
  }
963
+ this.updateAccessibilityIdentifier(accessibility);
964
964
  this.updateAccessibilityLabel(accessibility);
965
965
  this.updateAccessibilityValue(accessibility);
966
966
  this.updateAccessibilitySelected(accessibility);
@@ -1002,6 +1002,10 @@ JSClass("UIHTMLDisplayServerCanvasContext", UIHTMLDisplayServerContext, {
1002
1002
  this.updateAccessibilityColumnCount(accessibility);
1003
1003
  },
1004
1004
 
1005
+ updateAccessibilityIdentifier: function(accessibility){
1006
+ this.element.id = this.displayServer.elementIDForAccessibility(accessibility);
1007
+ },
1008
+
1005
1009
  updateAccessibilityLabel: function(accessibility){
1006
1010
  // FIXME: Once browsers support aria-description (slated for ARIA-1.3),
1007
1011
  // hint should go there
@@ -1126,7 +1130,7 @@ JSClass("UIHTMLDisplayServerCanvasContext", UIHTMLDisplayServerContext, {
1126
1130
  // if (focusedAccessibility === null || focusedAccessibility === undefined){
1127
1131
  // this.element.removeAttribute("aria-activedescendant");
1128
1132
  // }else{
1129
- // this.element.setAttribute("aria-activedescendant", "accessibility-%d".sprintf(focusedAccessibility.objectID));
1133
+ // this.element.setAttribute("aria-activedescendant", this.displayServer.elementIDForAccessibility(focusedAccessibility));
1130
1134
  // }
1131
1135
  },
1132
1136
 
@@ -1283,6 +1287,12 @@ var ariaRoleForAccessibility = function(accessibility){
1283
1287
  case UIAccessibility.Role.outline:
1284
1288
  return "treegrid";
1285
1289
  case UIAccessibility.Role.group:
1290
+ switch (accessibility.accessibilitySubrole){
1291
+ case UIAccessibility.Subrole.navigation:
1292
+ return "navigation";
1293
+ case UIAccessibility.Subrole.region:
1294
+ return "region";
1295
+ }
1286
1296
  return "group";
1287
1297
  case UIAccessibility.Role.window:
1288
1298
  switch (accessibility.accessibilitySubrole){
@@ -1040,6 +1040,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
1040
1040
  this.accessibilityObservers = {};
1041
1041
  this.accessibilityObservers.elementCreated = this.accessibilityNotificationCenter.addObserver(UIAccessibility.Notification.elementCreated, null, this.handleAccessibilityElementCreated, this);
1042
1042
  this.accessibilityObservers.elementChanged = this.accessibilityNotificationCenter.addObserver(UIAccessibility.Notification.elementChanged, null, this.handleAccessibilityElementChanged, this);
1043
+ this.accessibilityObservers.identifierChanged = this.accessibilityNotificationCenter.addObserver(UIAccessibility.Notification.identifierChanged, null, this.handleAccessibilityIdentifierChanged, this);
1043
1044
  this.accessibilityObservers.labelChanged = this.accessibilityNotificationCenter.addObserver(UIAccessibility.Notification.labelChanged, null, this.handleAccessibilityLabelChanged, this);
1044
1045
  this.accessibilityObservers.valueChanged = this.accessibilityNotificationCenter.addObserver(UIAccessibility.Notification.valueChanged, null, this.handleAccessibilityValueChanged, this);
1045
1046
  this.accessibilityObservers.visibilityChanged = this.accessibilityNotificationCenter.addObserver(UIAccessibility.Notification.visibilityChanged, null, this.handleAccessibilityVisibilityChanged, this);
@@ -1082,7 +1083,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
1082
1083
  if (element.accessibilityRole === UIAccessibility.Role.scrollBar){
1083
1084
  var parent = element.accessibilityParent;
1084
1085
  if (parent !== null && parent.accessibilityRole === UIAccessibility.Role.scrollArea){
1085
- context.element.setAttribute("aria-controls", "accessibility-%d" + parent.objectID);
1086
+ context.element.setAttribute("aria-controls", this.displayServer.elementIDForAccessibility(parent));
1086
1087
  }
1087
1088
  }
1088
1089
  }
@@ -1096,6 +1097,14 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
1096
1097
  }
1097
1098
  },
1098
1099
 
1100
+ handleAccessibilityIdentifierChanged: function(notification){
1101
+ var element = notification.sender;
1102
+ var context = this.contextForAccessibilityElement(element);
1103
+ if (context !== null){
1104
+ context.updateAccessibilityIdentifier(element);
1105
+ }
1106
+ },
1107
+
1099
1108
  handleAccessibilityLabelChanged: function(notification){
1100
1109
  var element = notification.sender;
1101
1110
  var context = this.contextForAccessibilityElement(element);
@@ -917,7 +917,7 @@ JSClass("UIListView", UIScrollView, {
917
917
  }
918
918
  this._listHeaderView = listHeaderView;
919
919
  if (this._listHeaderView){
920
- this.contentView.addSubview(this._listHeaderView);
920
+ this.contentView.insertSubviewAtIndex(this._listHeaderView, 0);
921
921
  }
922
922
  this.setNeedsLayout();
923
923
  },
@@ -2713,7 +2713,7 @@ JSClass("UIListView", UIScrollView, {
2713
2713
  showsFocusRing: false,
2714
2714
 
2715
2715
  getFocusRingPath: function(){
2716
- if (this.showsFocusRing){
2716
+ if (this.showsFocusRing || this.fullKeyboardAccessEnabled){
2717
2717
  return UIListView.$super.getFocusRingPath.call(this);
2718
2718
  }
2719
2719
  return null;
@@ -63,7 +63,7 @@ JSClass("UIListViewCell", UIView, {
63
63
 
64
64
  _createTitleLabel: function(){
65
65
  var label = UILabel.init();
66
- label.accessibilityHidden = false;
66
+ // label.accessibilityHidden = false;
67
67
  this.contentView.addSubview(label);
68
68
  return label;
69
69
  },
@@ -442,8 +442,8 @@ JSClass("UINavigationBarDefaultStyler", UINavigationBarStyler, {
442
442
 
443
443
  createTitleLabel: function(){
444
444
  var label = UILabel.init();
445
- label.accessibilityHidden = false;
446
- label.accessibilityRole = UIAccessibility.Role.header;
445
+ // label.accessibilityHidden = false;
446
+ // label.accessibilityRole = UIAccessibility.Role.header;
447
447
  label.font = this.titleFont;
448
448
  label.textColor = this.titleColor;
449
449
  return label;
@@ -126,8 +126,16 @@ JSClass('UIView', UIResponder, {
126
126
  if (spec.containsKey("transform")){
127
127
  this.transform = spec.valueForKey("transform", JSAffineTransform);
128
128
  }
129
+ if (spec.containsKey("accessibilityRole")){
130
+ this.accessibilityRole = spec.valueForKey("accessibilityRole");
131
+ this.isAccessibilityElement = this.accessibilityRole !== null;
132
+ }
133
+ if (spec.containsKey("accessibilitySubrole")){
134
+ this.accessibilitySubrole = spec.valueForKey("accessibilitySubrole");
135
+ this.isAccessibilityElement = this.accessibilitySubrole !== null;
136
+ }
129
137
  if (spec.containsKey("accessibilityIdentifier")){
130
- this.accessibilityIdentifier = spec.valueForKey("accessibilityIdentifier");
138
+ this._accessibilityIdentifier = spec.valueForKey("accessibilityIdentifier");
131
139
  }
132
140
  if (spec.containsKey("accessibilityLabel")){
133
141
  this._accessibilityLabel = spec.valueForKey("accessibilityLabel");
@@ -135,6 +143,9 @@ JSClass('UIView', UIResponder, {
135
143
  if (spec.containsKey("accessibilityHint")){
136
144
  this.accessibilityHint = spec.valueForKey("accessibilityHint");
137
145
  }
146
+ if (spec.containsKey("accessibilityHidden")){
147
+ this.accessibilityHidden = spec.valueForKey("accessibilityHidden");
148
+ }
138
149
  if (spec.containsKey("tag")){
139
150
  this.tag = spec.valueForKey("tag");
140
151
  }
@@ -1104,7 +1115,7 @@ JSClass('UIView', UIResponder, {
1104
1115
  accessibilityResponder: JSReadOnlyProperty(),
1105
1116
 
1106
1117
  // Label
1107
- accessibilityIdentifier: null,
1118
+ accessibilityIdentifier: JSDynamicProperty("_accessibilityIdentifier", null),
1108
1119
  accessibilityLabel: JSDynamicProperty("_accessibilityLabel", null),
1109
1120
  accessibilityHint: null,
1110
1121
 
@@ -1128,7 +1139,7 @@ JSClass('UIView', UIResponder, {
1128
1139
  accessibilityMultiline: null,
1129
1140
 
1130
1141
  // Children
1131
- accessibilityParent: null,
1142
+ accessibilityParent: JSReadOnlyProperty(),
1132
1143
  accessibilityElements: JSReadOnlyProperty(),
1133
1144
 
1134
1145
  getAccessibilityParent: function(){
@@ -1155,16 +1166,34 @@ JSClass('UIView', UIResponder, {
1155
1166
  return this;
1156
1167
  },
1157
1168
 
1169
+ getAccessibilityIdentifier: function(){
1170
+ return this._accessibilityIdentifier;
1171
+ },
1172
+
1173
+ setAccessibilityIdentifier: function(accessibilityIdentifier){
1174
+ if (accessibilityIdentifier === this._accessibilityIdentifier){
1175
+ return;
1176
+ }
1177
+ this._accessibilityIdentifier = accessibilityIdentifier;
1178
+ this.postAccessibilityNotification(UIAccessibility.Notification.identifierChanged);
1179
+ },
1180
+
1158
1181
  getAccessibilityLabel: function(){
1159
1182
  return this._accessibilityLabel;
1160
1183
  },
1161
1184
 
1162
1185
  setAccessibilityLabel: function(accessibilityLabel){
1186
+ if (accessibilityLabel === this._accessibilityLabel){
1187
+ return;
1188
+ }
1163
1189
  this._accessibilityLabel = accessibilityLabel;
1164
1190
  this.postAccessibilityNotification(UIAccessibility.Notification.labelChanged);
1165
1191
  },
1166
1192
 
1167
1193
  setAccessibilityHidden: function(accessibilityHidden){
1194
+ if (accessibilityHidden === this._accessibilityHidden){
1195
+ return;
1196
+ }
1168
1197
  this._accessibilityHidden = accessibilityHidden;
1169
1198
  this.postAccessibilityNotification(UIAccessibility.Notification.visibilityChanged);
1170
1199
  },
@@ -1177,6 +1206,9 @@ JSClass('UIView', UIResponder, {
1177
1206
  if (this._windowServer === null){
1178
1207
  return;
1179
1208
  }
1209
+ if (!this.isAccessibilityElement){
1210
+ return;
1211
+ }
1180
1212
  this._windowServer.postNotificationForAccessibilityElement(notificationName, this);
1181
1213
  },
1182
1214
 
@@ -464,7 +464,10 @@ JSClass('UIWindow', UIView, {
464
464
  _isVisible: false,
465
465
 
466
466
  didBecomeVisible: function(){
467
- this._application._windows.push(this);
467
+ var index = this._application._windows.indexOf(this);
468
+ if (index < 0){
469
+ this._application._windows.push(this);
470
+ }
468
471
  this._isVisible = true;
469
472
  if (this._shouldCallDidAppear){
470
473
  this._shouldCallDidAppear = false;
@@ -284,7 +284,9 @@ JSClass("UIWindowServer", JSObject, {
284
284
  },
285
285
 
286
286
  layoutWindow: function(window){
287
- if (window instanceof UIRootWindow){
287
+ if (window === this._accessibilityHighlightWindow){
288
+ window.frame = window._screen.frame;
289
+ }else if (window instanceof UIRootWindow){
288
290
  window.frame = window._screen.frame;
289
291
  var insets = JSInsets.Zero;
290
292
  if (this._menuBar !== null && this._menuBar.isOpaque){
@@ -455,13 +457,26 @@ JSClass("UIWindowServer", JSObject, {
455
457
  // MARK: - Keyboard Events
456
458
 
457
459
  createKeyEvent: function(type, timestamp, key, keyCode, modifiers){
460
+ if (this._accessibilityHighlightWindow !== null){
461
+ if (type === UIEvent.Type.keyDown){
462
+ if (key === UIEvent.Key.up){
463
+ this._accessibilityHighlightWindow.contentView.level += 1;
464
+ return;
465
+ }
466
+ if (key === UIEvent.Key.down){
467
+ if (this._accessibilityHighlightWindow.contentView.level > 0){
468
+ this._accessibilityHighlightWindow.contentView.level -= 1;
469
+ }
470
+ return;
471
+ }
472
+ }
473
+ }
458
474
  var keyWindow = this.windowForKeyEvent();
459
475
  if (keyWindow !== null){
460
476
  var event = UIEvent.initKeyEventWithType(type, timestamp, keyWindow, key, keyCode, modifiers);
461
477
  if (this.shouldDraggingSessionHandleKey(event)){
462
478
  this.handleDraggingKeyEvent(event);
463
479
  }else{
464
- this.textInputManager.sendActionsForEvent(event);
465
480
  this._sendEventToApplication(event, keyWindow.application);
466
481
  }
467
482
  }
@@ -475,9 +490,11 @@ JSClass("UIWindowServer", JSObject, {
475
490
  var locationInWindow;
476
491
  for (var i = this.windowStack.length - 1; i >= 0; --i){
477
492
  _window = this.windowStack[i];
478
- locationInWindow = _window.convertPointFromScreen(location);
479
- if (_window.containsPoint(locationInWindow)){
480
- return _window;
493
+ if (!_window.hidden){
494
+ locationInWindow = _window.convertPointFromScreen(location);
495
+ if (_window.containsPoint(locationInWindow)){
496
+ return _window;
497
+ }
481
498
  }
482
499
  }
483
500
  return null;
@@ -488,12 +505,14 @@ JSClass("UIWindowServer", JSObject, {
488
505
  var window;
489
506
  for (var i = this.windowStack.length - 1; i >= 0; --i){
490
507
  window = this.windowStack[i];
491
- if (window.receivesAllEvents){
492
- return window;
493
- }
494
- locationInWindow = window.convertPointFromScreen(location);
495
- if (window.userInteractionEnabled && window.containsPoint(locationInWindow)){
496
- return window;
508
+ if (!window.hidden){
509
+ if (window.receivesAllEvents){
510
+ return window;
511
+ }
512
+ locationInWindow = window.convertPointFromScreen(location);
513
+ if (window.userInteractionEnabled && window.containsPoint(locationInWindow)){
514
+ return window;
515
+ }
497
516
  }
498
517
  }
499
518
  return null;
@@ -702,6 +721,10 @@ JSClass("UIWindowServer", JSObject, {
702
721
  }
703
722
  }
704
723
  }
724
+ if (this._accessibilityHighlightWindow !== null){
725
+ this._accessibilityHighlightWindow.contentView.level = 0;
726
+ this._accessibilityHighlightWindow.contentView.setNeedsDisplay();
727
+ }
705
728
  },
706
729
 
707
730
  _mouseDidIdle: function(){
@@ -980,6 +1003,30 @@ JSClass("UIWindowServer", JSObject, {
980
1003
  }
981
1004
  },
982
1005
 
1006
+ accessibilityHighlightEnabled: JSDynamicProperty("_accessibilityHighlightEnabled", false),
1007
+
1008
+ setAccessibilityHighlightEnabled: function(enabled){
1009
+ this._accessibilityHighlightEnabled = enabled;
1010
+ if (enabled){
1011
+ if (this._accessibilityHighlightWindow === null){
1012
+ this._accessibilityHighlightWindow = UIWindow.initWithStyler(UIWindow.Styler.custom);
1013
+ this._accessibilityHighlightWindow.backgroundColor = null;
1014
+ this._accessibilityHighlightWindow.contentView = UIWindowServerAccessibilityHighlightView.init();
1015
+ this._accessibilityHighlightWindow.userInteractionEnabled = false;
1016
+ this._accessibilityHighlightWindow.level = UIWindow.Level.front;
1017
+ this._accessibilityHighlightWindow.frame = this.screen.frame;
1018
+ this._accessibilityHighlightWindow.orderFront();
1019
+ }
1020
+ }else{
1021
+ if (this._accessibilityHighlightWindow !== null){
1022
+ this._accessibilityHighlightWindow.close();
1023
+ this._accessibilityHighlightWindow = null;
1024
+ }
1025
+ }
1026
+ },
1027
+
1028
+ _accessibilityHighlightWindow: null,
1029
+
983
1030
  // -----------------------------------------------------------------------
984
1031
  // MARK: - Traits
985
1032
 
@@ -1034,4 +1081,77 @@ JSClass("UIWindowServer", JSObject, {
1034
1081
 
1035
1082
  });
1036
1083
 
1084
+ JSClass("UIWindowServerAccessibilityHighlightView", UIView, {
1085
+
1086
+ framesetter: JSLazyInitProperty(function(){
1087
+ var framesetter = JSTextFramesetter.init();
1088
+ return framesetter;
1089
+ }),
1090
+
1091
+ font: JSLazyInitProperty(function(){
1092
+ return JSFont.systemFontOfSize(JSFont.Size.detail);
1093
+ }),
1094
+
1095
+ level: JSDynamicProperty("_level", 0),
1096
+
1097
+ setLevel: function(level){
1098
+ this._level = level;
1099
+ this.setNeedsDisplay();
1100
+ },
1101
+
1102
+ drawLayerInContext: function(layer, context){
1103
+ if (this._windowServer === null){
1104
+ return;
1105
+ }
1106
+ var location = this._windowServer.mouseLocation;
1107
+ var window = this._windowServer.windowForEventAtLocation(location);
1108
+ if (window === null){
1109
+ return;
1110
+ }
1111
+ var view = window.hitTest(location);
1112
+ while (view !== null && (!view.isAccessibilityElement || view.accessibilityHidden)){
1113
+ view = view.superview;
1114
+ }
1115
+ var level = 0;
1116
+ while (view !== null && level < this._level){
1117
+ view = view.superview;
1118
+ while (view !== null && (!view.isAccessibilityElement || view.accessibilityHidden)){
1119
+ view = view.superview;
1120
+ }
1121
+ ++level;
1122
+ }
1123
+ if (view === null){
1124
+ return;
1125
+ }
1126
+ var color = JSColor.highlight;
1127
+ var textColor = JSColor.highlightedText;
1128
+ var width = 2;
1129
+ var halfWidth = width / 2;
1130
+ var rect = view.convertRectToScreen(view.bounds);
1131
+ var maxRect = this.bounds.rectWithInsets(halfWidth);
1132
+ var outlineRect = rect.rectWithInsets(-halfWidth).intersectingRect(maxRect);
1133
+ var text = view.accessibilityIdentifier;
1134
+ context.save();
1135
+ context.setStrokeColor(color);
1136
+ context.setLineWidth(width);
1137
+ context.setLineJoin(JSContext.LineJoin.round);
1138
+ context.beginPath();
1139
+ context.addRect(outlineRect);
1140
+ context.strokePath();
1141
+ context.restore();
1142
+ if (text){
1143
+ this.framesetter.attributedString = JSAttributedString.initWithString("#" + text, {font: this.font});
1144
+ var textFrame = this.framesetter.createFrame(JSSize(0, 0), JSRange(0, this.framesetter.attributedString.string.length), 1);
1145
+ var textRect = JSRect(rect.origin, textFrame.size);
1146
+ context.save();
1147
+ context.setFillColor(color);
1148
+ context.fillRect(textRect);
1149
+ context.setFillColor(textColor);
1150
+ textFrame.drawInContextAtPoint(context, textRect.origin);
1151
+ context.restore();
1152
+ }
1153
+ },
1154
+
1155
+ });
1156
+
1037
1157
  })();
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKitTesting
3
- JSBundleVersion: 2024.15.0
3
+ JSBundleVersion: 2024.20.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": "2024.15.0",
12
+ "version": "2024.20.0",
13
13
  "license": "SEE LICENSE IN LICENSE.txt",
14
14
  "files": [
15
15
  "*"