@breakside/jskit 2024.11.1 → 2024.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Frameworks/DOM.jsframework/Info.json +2 -2
- package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
- package/Frameworks/FontKit.jsframework/Info.json +2 -2
- package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/Info.json +2 -2
- package/Frameworks/Foundation.jsframework/JS/JSNumberFormatter.js +4 -3
- package/Frameworks/Foundation.jsframework/JS/JSTextLayoutManager.js +16 -0
- 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/JSNumberFormatter.js +4 -3
- package/Root/Frameworks/Foundation/JSTextLayoutManager.js +16 -0
- 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/UIAccessibility.js +4 -1
- package/Root/Frameworks/UIKit/UIApplication.js +10 -1
- package/Root/Frameworks/UIKit/UIHTMLDisplayServer.js +6 -0
- package/Root/Frameworks/UIKit/UIHTMLDisplayServerCanvasContext.js +12 -2
- package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +10 -1
- package/Root/Frameworks/UIKit/UIListView.js +2 -2
- package/Root/Frameworks/UIKit/UIListViewCell.js +1 -1
- package/Root/Frameworks/UIKit/UINavigationBar.js +2 -2
- package/Root/Frameworks/UIKit/UINavigationController.js +2 -0
- package/Root/Frameworks/UIKit/UIView.js +35 -3
- package/Root/Frameworks/UIKit/UIWindowServer.js +118 -1
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
4
|
-
"JSBundleVersion": "2024.
|
|
4
|
+
"JSBundleVersion": "2024.16.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "DOM+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
6
|
+
"JSBundleVersion": "2024.16.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
|
|
|
11
11
|
"node": "DOM+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
4
|
+
"JSBundleVersion": "2024.16.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
8
8
|
"html": "FontKit+HTML.js"
|
|
9
9
|
},
|
|
10
10
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
11
|
-
"GitRevision": "
|
|
11
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
6
|
+
"JSBundleVersion": "2024.16.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
10
10
|
"html": "FontKit+HTML.js"
|
|
11
11
|
},
|
|
12
12
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
13
|
-
"GitRevision": "
|
|
13
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
4
|
+
"JSBundleVersion": "2024.16.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "Foundation+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
13
13
|
}
|
|
@@ -493,8 +493,11 @@ JSClass("JSNumberFormatter", JSObject, {
|
|
|
493
493
|
// Integer
|
|
494
494
|
var integer = Math.floor(n);
|
|
495
495
|
var fraction = n - integer;
|
|
496
|
-
|
|
496
|
+
var maximumFraction = Math.pow(10, this._maximumFractionDigits);
|
|
497
|
+
fraction = Math.round(fraction * maximumFraction);
|
|
498
|
+
if (fraction >= maximumFraction){
|
|
497
499
|
integer += 1;
|
|
500
|
+
fraction = 0;
|
|
498
501
|
}
|
|
499
502
|
var str = integer.toString();
|
|
500
503
|
var zeroFillCount = this._minimumIntegerDigits - str.length;
|
|
@@ -524,8 +527,6 @@ JSClass("JSNumberFormatter", JSObject, {
|
|
|
524
527
|
// Decimal
|
|
525
528
|
if (this._maximumFractionDigits > 0){
|
|
526
529
|
if (this._minimumFractionDigits > 0 || fraction !== 0){
|
|
527
|
-
fraction *= Math.pow(10, this._maximumFractionDigits);
|
|
528
|
-
fraction = Math.round(fraction);
|
|
529
530
|
if (this._minimumFractionDigits > 0 || fraction !== 0){
|
|
530
531
|
str += ".";
|
|
531
532
|
var fractionString = fraction.toString();
|
|
@@ -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.
|
|
6
|
+
"JSBundleVersion": "2024.16.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
|
|
|
11
11
|
"node": "Foundation+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
4
|
+
"JSBundleVersion": "2024.16.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "SecurityKit+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
6
|
+
"JSBundleVersion": "2024.16.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
|
|
|
11
11
|
"node": "SecurityKit+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
4
|
+
"JSBundleVersion": "2024.16.0",
|
|
5
5
|
"JSExecutableName": "jskit",
|
|
6
6
|
"NPMOrganization": "breakside",
|
|
7
7
|
"JSResources": [
|
|
8
8
|
"Tests/HTMLTestRunner.js",
|
|
9
9
|
"Tests/NodeTestRunner.js"
|
|
10
10
|
],
|
|
11
|
-
"GitRevision": "
|
|
11
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
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.
|
|
6
|
+
"JSBundleVersion": "2024.16.0",
|
|
7
7
|
"JSExecutableName": "jskit",
|
|
8
8
|
"NPMOrganization": "breakside",
|
|
9
9
|
"JSResources": [
|
|
10
10
|
"Tests/HTMLTestRunner.js",
|
|
11
11
|
"Tests/NodeTestRunner.js"
|
|
12
12
|
],
|
|
13
|
-
"GitRevision": "
|
|
13
|
+
"GitRevision": "463df029aece1135d6a1d574f8ded927d6bd953b"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [
|
|
16
16
|
{
|
|
@@ -493,8 +493,11 @@ JSClass("JSNumberFormatter", JSObject, {
|
|
|
493
493
|
// Integer
|
|
494
494
|
var integer = Math.floor(n);
|
|
495
495
|
var fraction = n - integer;
|
|
496
|
-
|
|
496
|
+
var maximumFraction = Math.pow(10, this._maximumFractionDigits);
|
|
497
|
+
fraction = Math.round(fraction * maximumFraction);
|
|
498
|
+
if (fraction >= maximumFraction){
|
|
497
499
|
integer += 1;
|
|
500
|
+
fraction = 0;
|
|
498
501
|
}
|
|
499
502
|
var str = integer.toString();
|
|
500
503
|
var zeroFillCount = this._minimumIntegerDigits - str.length;
|
|
@@ -524,8 +527,6 @@ JSClass("JSNumberFormatter", JSObject, {
|
|
|
524
527
|
// Decimal
|
|
525
528
|
if (this._maximumFractionDigits > 0){
|
|
526
529
|
if (this._minimumFractionDigits > 0 || fraction !== 0){
|
|
527
|
-
fraction *= Math.pow(10, this._maximumFractionDigits);
|
|
528
|
-
fraction = Math.round(fraction);
|
|
529
530
|
if (this._minimumFractionDigits > 0 || fraction !== 0){
|
|
530
531
|
str += ".";
|
|
531
532
|
var fractionString = fraction.toString();
|
|
@@ -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(){
|
|
@@ -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",
|
|
@@ -502,7 +502,7 @@ JSClass('UIApplication', UIResponder, {
|
|
|
502
502
|
accessibilitySubrole: null,
|
|
503
503
|
|
|
504
504
|
// Label
|
|
505
|
-
accessibilityIdentifier:
|
|
505
|
+
accessibilityIdentifier: JSDynamicProperty("_accessibilityIdentifier"),
|
|
506
506
|
accessibilityLabel: JSReadOnlyProperty(),
|
|
507
507
|
accessibilityHint: null,
|
|
508
508
|
|
|
@@ -524,6 +524,15 @@ JSClass('UIApplication', UIResponder, {
|
|
|
524
524
|
accessibilityParent: null,
|
|
525
525
|
accessibilityElements: JSReadOnlyProperty(),
|
|
526
526
|
|
|
527
|
+
getAccessibilityIdentifier: function(){
|
|
528
|
+
return this._accessibilityIdentifier;
|
|
529
|
+
},
|
|
530
|
+
|
|
531
|
+
setAccessibilityIdentifier: function(accessibilityIdentifier){
|
|
532
|
+
this._accessibilityIdentifier = accessibilityIdentifier;
|
|
533
|
+
this.windowServer.postNotificationForAccessibilityElement(UIAccessibility.Notification.identifierChanged, this);
|
|
534
|
+
},
|
|
535
|
+
|
|
527
536
|
getAccessibilityFrame: function(){
|
|
528
537
|
return this.windowServer.screen.frame;
|
|
529
538
|
},
|
|
@@ -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",
|
|
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",
|
|
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.
|
|
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;
|
|
@@ -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;
|
|
@@ -85,8 +85,10 @@ JSClass("UINavigationController", UIViewController, {
|
|
|
85
85
|
var topView = this.topViewController.view;
|
|
86
86
|
if (this.topViewController.navigationItem.hidesNavigationBar){
|
|
87
87
|
this.view.addSubview(topView);
|
|
88
|
+
this.navigationBar.hidden = true;
|
|
88
89
|
}else{
|
|
89
90
|
this.view.insertSubviewBelowSibling(topView, this._navigationBar);
|
|
91
|
+
this.navigationBar.hidden = false;
|
|
90
92
|
}
|
|
91
93
|
this.view.setNeedsLayout();
|
|
92
94
|
},
|
|
@@ -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.
|
|
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:
|
|
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
|
|
|
@@ -284,7 +284,9 @@ JSClass("UIWindowServer", JSObject, {
|
|
|
284
284
|
},
|
|
285
285
|
|
|
286
286
|
layoutWindow: function(window){
|
|
287
|
-
if (window
|
|
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,6 +457,20 @@ 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);
|
|
@@ -702,6 +718,10 @@ JSClass("UIWindowServer", JSObject, {
|
|
|
702
718
|
}
|
|
703
719
|
}
|
|
704
720
|
}
|
|
721
|
+
if (this._accessibilityHighlightWindow !== null){
|
|
722
|
+
this._accessibilityHighlightWindow.contentView.level = 0;
|
|
723
|
+
this._accessibilityHighlightWindow.contentView.setNeedsDisplay();
|
|
724
|
+
}
|
|
705
725
|
},
|
|
706
726
|
|
|
707
727
|
_mouseDidIdle: function(){
|
|
@@ -980,6 +1000,30 @@ JSClass("UIWindowServer", JSObject, {
|
|
|
980
1000
|
}
|
|
981
1001
|
},
|
|
982
1002
|
|
|
1003
|
+
accessibilityHighlightEnabled: JSDynamicProperty("_accessibilityHighlightEnabled", false),
|
|
1004
|
+
|
|
1005
|
+
setAccessibilityHighlightEnabled: function(enabled){
|
|
1006
|
+
this._accessibilityHighlightEnabled = enabled;
|
|
1007
|
+
if (enabled){
|
|
1008
|
+
if (this._accessibilityHighlightWindow === null){
|
|
1009
|
+
this._accessibilityHighlightWindow = UIWindow.initWithStyler(UIWindow.Styler.custom);
|
|
1010
|
+
this._accessibilityHighlightWindow.backgroundColor = null;
|
|
1011
|
+
this._accessibilityHighlightWindow.contentView = UIWindowServerAccessibilityHighlightView.init();
|
|
1012
|
+
this._accessibilityHighlightWindow.userInteractionEnabled = false;
|
|
1013
|
+
this._accessibilityHighlightWindow.level = UIWindow.Level.front;
|
|
1014
|
+
this._accessibilityHighlightWindow.frame = this.screen.frame;
|
|
1015
|
+
this._accessibilityHighlightWindow.orderFront();
|
|
1016
|
+
}
|
|
1017
|
+
}else{
|
|
1018
|
+
if (this._accessibilityHighlightWindow !== null){
|
|
1019
|
+
this._accessibilityHighlightWindow.close();
|
|
1020
|
+
this._accessibilityHighlightWindow = null;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
},
|
|
1024
|
+
|
|
1025
|
+
_accessibilityHighlightWindow: null,
|
|
1026
|
+
|
|
983
1027
|
// -----------------------------------------------------------------------
|
|
984
1028
|
// MARK: - Traits
|
|
985
1029
|
|
|
@@ -1034,4 +1078,77 @@ JSClass("UIWindowServer", JSObject, {
|
|
|
1034
1078
|
|
|
1035
1079
|
});
|
|
1036
1080
|
|
|
1081
|
+
JSClass("UIWindowServerAccessibilityHighlightView", UIView, {
|
|
1082
|
+
|
|
1083
|
+
framesetter: JSLazyInitProperty(function(){
|
|
1084
|
+
var framesetter = JSTextFramesetter.init();
|
|
1085
|
+
return framesetter;
|
|
1086
|
+
}),
|
|
1087
|
+
|
|
1088
|
+
font: JSLazyInitProperty(function(){
|
|
1089
|
+
return JSFont.systemFontOfSize(JSFont.Size.detail);
|
|
1090
|
+
}),
|
|
1091
|
+
|
|
1092
|
+
level: JSDynamicProperty("_level", 0),
|
|
1093
|
+
|
|
1094
|
+
setLevel: function(level){
|
|
1095
|
+
this._level = level;
|
|
1096
|
+
this.setNeedsDisplay();
|
|
1097
|
+
},
|
|
1098
|
+
|
|
1099
|
+
drawLayerInContext: function(layer, context){
|
|
1100
|
+
if (this._windowServer === null){
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
var location = this._windowServer.mouseLocation;
|
|
1104
|
+
var window = this._windowServer.windowForEventAtLocation(location);
|
|
1105
|
+
if (window === null){
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
var view = window.hitTest(location);
|
|
1109
|
+
while (view !== null && (!view.isAccessibilityElement || view.accessibilityHidden)){
|
|
1110
|
+
view = view.superview;
|
|
1111
|
+
}
|
|
1112
|
+
var level = 0;
|
|
1113
|
+
while (view !== null && level < this._level){
|
|
1114
|
+
view = view.superview;
|
|
1115
|
+
while (view !== null && (!view.isAccessibilityElement || view.accessibilityHidden)){
|
|
1116
|
+
view = view.superview;
|
|
1117
|
+
}
|
|
1118
|
+
++level;
|
|
1119
|
+
}
|
|
1120
|
+
if (view === null){
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
var color = JSColor.highlight;
|
|
1124
|
+
var textColor = JSColor.highlightedText;
|
|
1125
|
+
var width = 2;
|
|
1126
|
+
var halfWidth = width / 2;
|
|
1127
|
+
var rect = view.convertRectToScreen(view.bounds);
|
|
1128
|
+
var maxRect = this.bounds.rectWithInsets(halfWidth);
|
|
1129
|
+
var outlineRect = rect.rectWithInsets(-halfWidth).intersectingRect(maxRect);
|
|
1130
|
+
var text = view.accessibilityIdentifier;
|
|
1131
|
+
context.save();
|
|
1132
|
+
context.setStrokeColor(color);
|
|
1133
|
+
context.setLineWidth(width);
|
|
1134
|
+
context.setLineJoin(JSContext.LineJoin.round);
|
|
1135
|
+
context.beginPath();
|
|
1136
|
+
context.addRect(outlineRect);
|
|
1137
|
+
context.strokePath();
|
|
1138
|
+
context.restore();
|
|
1139
|
+
if (text){
|
|
1140
|
+
this.framesetter.attributedString = JSAttributedString.initWithString("#" + text, {font: this.font});
|
|
1141
|
+
var textFrame = this.framesetter.createFrame(JSSize(0, 0), JSRange(0, this.framesetter.attributedString.string.length), 1);
|
|
1142
|
+
var textRect = JSRect(rect.origin, textFrame.size);
|
|
1143
|
+
context.save();
|
|
1144
|
+
context.setFillColor(color);
|
|
1145
|
+
context.fillRect(textRect);
|
|
1146
|
+
context.setFillColor(textColor);
|
|
1147
|
+
textFrame.drawInContextAtPoint(context, textRect.origin);
|
|
1148
|
+
context.restore();
|
|
1149
|
+
}
|
|
1150
|
+
},
|
|
1151
|
+
|
|
1152
|
+
});
|
|
1153
|
+
|
|
1037
1154
|
})();
|