@breakside/jskit 2023.22.0 → 2023.32.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/JS/DOMElement.js +8 -0
- package/Frameworks/DOM.jsframework/JS/XMLSerializer.js +29 -3
- 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/JSAttributedString.js +1 -1
- package/Frameworks/Foundation.jsframework/JS/JSTextLayoutManager.js +3 -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/CHPieChart.js +3 -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/DOMElement.js +8 -0
- package/Root/Frameworks/DOM/Info.yaml +1 -1
- package/Root/Frameworks/DOM/XMLSerializer.js +29 -3
- 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/JSAttributedString.js +1 -1
- package/Root/Frameworks/Foundation/JSTextLayoutManager.js +3 -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/TestKit/TKMock.js +4 -0
- package/Root/Frameworks/UIKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/UIApplication.js +9 -1
- package/Root/Frameworks/UIKit/UIButton.js +1 -1
- package/Root/Frameworks/UIKit/UIHTMLApplication.js +14 -0
- package/Root/Frameworks/UIKit/UIHTMLContentEditableTextInputManager.js +3 -3
- package/Root/Frameworks/UIKit/UIHTMLDisplayServerCanvasContext.js +1 -1
- package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +52 -0
- package/Root/Frameworks/UIKit/UIKeyboard.js +13 -0
- package/Root/Frameworks/UIKit/UIPopupWindow.js +1 -0
- package/Root/Frameworks/UIKit/UITextEditor.js +15 -7
- package/Root/Frameworks/UIKit/UITextField.js +15 -4
- package/Root/Frameworks/UIKit/UITextLayer.js +4 -2
- package/Root/Frameworks/UIKit/UITokenField.js +1 -0
- 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": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
13
13
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// limitations under the License.
|
|
15
15
|
|
|
16
16
|
// #import "DOMNode.js"
|
|
17
|
+
/* global XMLSerializer */
|
|
17
18
|
'use strict';
|
|
18
19
|
|
|
19
20
|
DOM.Element.prototype = Object.create(DOM.Node.prototype, {
|
|
@@ -107,6 +108,13 @@ DOM.Element.prototype = Object.create(DOM.Node.prototype, {
|
|
|
107
108
|
delete this._attributeMap[':global:'][name];
|
|
108
109
|
}
|
|
109
110
|
}
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
innerHTML: {
|
|
114
|
+
get: function DOMElement_innerHTML(){
|
|
115
|
+
var serializer = new XMLSerializer();
|
|
116
|
+
return serializer._serializeToString(this, true);
|
|
117
|
+
}
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
});
|
|
@@ -21,7 +21,12 @@ JSGlobalObject.XMLSerializer = function XMLSerializer(){
|
|
|
21
21
|
|
|
22
22
|
XMLSerializer.prototype = {
|
|
23
23
|
|
|
24
|
-
serializeToString: function(
|
|
24
|
+
serializeToString: function(node){
|
|
25
|
+
return this._serializeToString(node, false);
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
_serializeToString: function(node, childrenOnly){
|
|
29
|
+
var document = node.ownerDocument || node;
|
|
25
30
|
var doctype = document.doctype;
|
|
26
31
|
var isHTML = doctype && doctype.name == "html";
|
|
27
32
|
var str = "";
|
|
@@ -127,10 +132,31 @@ XMLSerializer.prototype = {
|
|
|
127
132
|
}
|
|
128
133
|
};
|
|
129
134
|
|
|
130
|
-
if (!isHTML){
|
|
135
|
+
if (!isHTML && !childrenOnly){
|
|
131
136
|
str += '<?xml version="1.0" encoding="utf-8"?>\n';
|
|
132
137
|
}
|
|
133
|
-
|
|
138
|
+
if (childrenOnly){
|
|
139
|
+
var namespaces = {':global:': null};
|
|
140
|
+
if (node.nodeType === DOM.Node.ELEMENT_NODE){
|
|
141
|
+
if (node.namespaceURI !== null){
|
|
142
|
+
if (node.prefix !== null){
|
|
143
|
+
if (namespaces[node.prefix] != node.namespaceURI){
|
|
144
|
+
namespaces[node.prefix] = node.namespaceURI;
|
|
145
|
+
}
|
|
146
|
+
}else{
|
|
147
|
+
if (namespaces[':global:'] !== node.namespaceURI){
|
|
148
|
+
namespaces[':global:'] = node.namespaceURI;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
var i, l;
|
|
154
|
+
for (i = 0, l = node.childNodes.length; i < l; ++i){
|
|
155
|
+
writeNode(node.childNodes[i], namespaces);
|
|
156
|
+
}
|
|
157
|
+
}else{
|
|
158
|
+
writeNode(node, {':global:': null});
|
|
159
|
+
}
|
|
134
160
|
|
|
135
161
|
return str;
|
|
136
162
|
}
|
|
@@ -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": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
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": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
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": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
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": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
13
13
|
}
|
|
@@ -360,7 +360,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
360
360
|
var run = this._runs[runRange.location];
|
|
361
361
|
run.attributes = JSCopy(attributes);
|
|
362
362
|
if (runRange.length > 1){
|
|
363
|
-
run.range.length = this._runs[runRange.end - 1].end - run.range.location;
|
|
363
|
+
run.range.length = this._runs[runRange.end - 1].range.end - run.range.location;
|
|
364
364
|
this._runs.splice(runRange.location + 1, runRange.length - 1);
|
|
365
365
|
}
|
|
366
366
|
this._fixRunsInRunRange(JSRange(runRange.location, 1));
|
|
@@ -72,6 +72,9 @@ JSClass("JSTextLayoutManager", JSObject, {
|
|
|
72
72
|
|
|
73
73
|
replaceTextStorage: function(storage){
|
|
74
74
|
var originalStorage = this._textStorage;
|
|
75
|
+
if (storage === originalStorage){
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
75
78
|
if (originalStorage !== null){
|
|
76
79
|
var managers = originalStorage.layoutManagers;
|
|
77
80
|
originalStorage.removeAllLayoutManagers();
|
|
@@ -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": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
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": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
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": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
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": "2023.
|
|
4
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
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": "2023.
|
|
6
|
+
"JSBundleVersion": "2023.32.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": "ac9770622bb71dffd8ec514219c86c56afecbae8"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [
|
|
16
16
|
{
|
|
@@ -107,10 +107,12 @@ JSClass("CHPieChart", CHChart, {
|
|
|
107
107
|
}
|
|
108
108
|
this.legend.drawInContext(context, legendRect);
|
|
109
109
|
}
|
|
110
|
-
this.drawPieInContext(context, pieRect);
|
|
111
110
|
},
|
|
112
111
|
|
|
113
112
|
drawPieInContext: function(context, rect){
|
|
113
|
+
if (rect.size.width <= 0 || rect.size.height <= 0){
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
114
116
|
if (this.series.length < 1){
|
|
115
117
|
return;
|
|
116
118
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// limitations under the License.
|
|
15
15
|
|
|
16
16
|
// #import "DOMNode.js"
|
|
17
|
+
/* global XMLSerializer */
|
|
17
18
|
'use strict';
|
|
18
19
|
|
|
19
20
|
DOM.Element.prototype = Object.create(DOM.Node.prototype, {
|
|
@@ -107,6 +108,13 @@ DOM.Element.prototype = Object.create(DOM.Node.prototype, {
|
|
|
107
108
|
delete this._attributeMap[':global:'][name];
|
|
108
109
|
}
|
|
109
110
|
}
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
innerHTML: {
|
|
114
|
+
get: function DOMElement_innerHTML(){
|
|
115
|
+
var serializer = new XMLSerializer();
|
|
116
|
+
return serializer._serializeToString(this, true);
|
|
117
|
+
}
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
});
|
|
@@ -21,7 +21,12 @@ JSGlobalObject.XMLSerializer = function XMLSerializer(){
|
|
|
21
21
|
|
|
22
22
|
XMLSerializer.prototype = {
|
|
23
23
|
|
|
24
|
-
serializeToString: function(
|
|
24
|
+
serializeToString: function(node){
|
|
25
|
+
return this._serializeToString(node, false);
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
_serializeToString: function(node, childrenOnly){
|
|
29
|
+
var document = node.ownerDocument || node;
|
|
25
30
|
var doctype = document.doctype;
|
|
26
31
|
var isHTML = doctype && doctype.name == "html";
|
|
27
32
|
var str = "";
|
|
@@ -127,10 +132,31 @@ XMLSerializer.prototype = {
|
|
|
127
132
|
}
|
|
128
133
|
};
|
|
129
134
|
|
|
130
|
-
if (!isHTML){
|
|
135
|
+
if (!isHTML && !childrenOnly){
|
|
131
136
|
str += '<?xml version="1.0" encoding="utf-8"?>\n';
|
|
132
137
|
}
|
|
133
|
-
|
|
138
|
+
if (childrenOnly){
|
|
139
|
+
var namespaces = {':global:': null};
|
|
140
|
+
if (node.nodeType === DOM.Node.ELEMENT_NODE){
|
|
141
|
+
if (node.namespaceURI !== null){
|
|
142
|
+
if (node.prefix !== null){
|
|
143
|
+
if (namespaces[node.prefix] != node.namespaceURI){
|
|
144
|
+
namespaces[node.prefix] = node.namespaceURI;
|
|
145
|
+
}
|
|
146
|
+
}else{
|
|
147
|
+
if (namespaces[':global:'] !== node.namespaceURI){
|
|
148
|
+
namespaces[':global:'] = node.namespaceURI;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
var i, l;
|
|
154
|
+
for (i = 0, l = node.childNodes.length; i < l; ++i){
|
|
155
|
+
writeNode(node.childNodes[i], namespaces);
|
|
156
|
+
}
|
|
157
|
+
}else{
|
|
158
|
+
writeNode(node, {':global:': null});
|
|
159
|
+
}
|
|
134
160
|
|
|
135
161
|
return str;
|
|
136
162
|
}
|
|
@@ -360,7 +360,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
360
360
|
var run = this._runs[runRange.location];
|
|
361
361
|
run.attributes = JSCopy(attributes);
|
|
362
362
|
if (runRange.length > 1){
|
|
363
|
-
run.range.length = this._runs[runRange.end - 1].end - run.range.location;
|
|
363
|
+
run.range.length = this._runs[runRange.end - 1].range.end - run.range.location;
|
|
364
364
|
this._runs.splice(runRange.location + 1, runRange.length - 1);
|
|
365
365
|
}
|
|
366
366
|
this._fixRunsInRunRange(JSRange(runRange.location, 1));
|
|
@@ -72,6 +72,9 @@ JSClass("JSTextLayoutManager", JSObject, {
|
|
|
72
72
|
|
|
73
73
|
replaceTextStorage: function(storage){
|
|
74
74
|
var originalStorage = this._textStorage;
|
|
75
|
+
if (storage === originalStorage){
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
75
78
|
if (originalStorage !== null){
|
|
76
79
|
var managers = originalStorage.layoutManagers;
|
|
77
80
|
originalStorage.removeAllLayoutManagers();
|
|
@@ -75,6 +75,10 @@ JSGlobalObject.TKMock = function(methods){
|
|
|
75
75
|
}
|
|
76
76
|
mockMethod.results.push({callback: {args: args, argIndex: argIndex, targeted: true}});
|
|
77
77
|
};
|
|
78
|
+
mockMethod.reset = function(){
|
|
79
|
+
mockMethod.calls = [];
|
|
80
|
+
mockMethod.results = [];
|
|
81
|
+
};
|
|
78
82
|
return mockMethod;
|
|
79
83
|
};
|
|
80
84
|
for (var name in methods){
|
|
@@ -229,13 +229,21 @@ JSClass('UIApplication', UIResponder, {
|
|
|
229
229
|
}else{
|
|
230
230
|
this._stopCalled = true;
|
|
231
231
|
logger.info("Stopping application");
|
|
232
|
+
var closed = false;
|
|
232
233
|
var _close = function(){
|
|
234
|
+
if (closed){
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
closed = true;
|
|
233
238
|
JSUserDefaults.shared.close(function(){
|
|
234
239
|
completion.call(target);
|
|
235
240
|
});
|
|
236
241
|
};
|
|
237
242
|
if (this.delegate && this.delegate.applicationWillTerminate){
|
|
238
|
-
this.delegate.applicationWillTerminate(_close);
|
|
243
|
+
var promise = this.delegate.applicationWillTerminate(_close);
|
|
244
|
+
if (promise instanceof Promise){
|
|
245
|
+
promise.finally(_close);
|
|
246
|
+
}
|
|
239
247
|
}else{
|
|
240
248
|
_close();
|
|
241
249
|
}
|
|
@@ -214,7 +214,7 @@ JSClass("UIButton", UIControl, {
|
|
|
214
214
|
this.active = false;
|
|
215
215
|
}
|
|
216
216
|
var location = event.locationInView(this);
|
|
217
|
-
this.over = this.window !== null && this.containsPoint(location);
|
|
217
|
+
this.over = this.enabled && this.window !== null && this.containsPoint(location);
|
|
218
218
|
return;
|
|
219
219
|
}
|
|
220
220
|
UIButton.$super.mouseUp.call(this, event);
|
|
@@ -134,6 +134,7 @@ JSClass("UIHTMLApplication", UIApplication, {
|
|
|
134
134
|
this.domWindow.addEventListener("hashchange", this);
|
|
135
135
|
this.domWindow.addEventListener("popstate", this);
|
|
136
136
|
this.domWindow.addEventListener("pageshow", this);
|
|
137
|
+
this.domWindow.addEventListener("visibilitychange", this);
|
|
137
138
|
},
|
|
138
139
|
|
|
139
140
|
removeEventListeners: function(){
|
|
@@ -143,6 +144,7 @@ JSClass("UIHTMLApplication", UIApplication, {
|
|
|
143
144
|
this.domWindow.removeEventListener("hashchange", this);
|
|
144
145
|
this.domWindow.removeEventListener("popstate", this);
|
|
145
146
|
this.domWindow.removeEventListener("pageshow", this);
|
|
147
|
+
this.domWindow.removeEventListener("visibilitychange", this);
|
|
146
148
|
},
|
|
147
149
|
|
|
148
150
|
handleEvent: function(e){
|
|
@@ -244,6 +246,18 @@ JSClass("UIHTMLApplication", UIApplication, {
|
|
|
244
246
|
}
|
|
245
247
|
},
|
|
246
248
|
|
|
249
|
+
_event_visibilitychange: function(e){
|
|
250
|
+
if (this.domWindow.document.visibilityState === "hidden"){
|
|
251
|
+
if (this.delegate && this.delegate.applicationDidEnterBackground){
|
|
252
|
+
this.delegate.applicationDidEnterBackground(this);
|
|
253
|
+
}
|
|
254
|
+
}else if (this.domWindow.document.visibilityState === "visible"){
|
|
255
|
+
if (this.delegate && this.delegate.applicationDidEnterForeground){
|
|
256
|
+
this.delegate.applicationDidEnterForeground(this);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
|
|
247
261
|
_crash: function(error){
|
|
248
262
|
this.removeEventListeners();
|
|
249
263
|
if (this.delegate && this.delegate.applicationDidCrash){
|
|
@@ -83,7 +83,7 @@ JSClass('UIHTMLContentEditableTextInputManager', UITextInputManager, {
|
|
|
83
83
|
setEditableElement: function(editableElement){
|
|
84
84
|
if (editableElement === this._editableElement){
|
|
85
85
|
if (this._editableElement !== null){
|
|
86
|
-
this._editableElement.focus();
|
|
86
|
+
this._editableElement.focus({preventScroll: true});
|
|
87
87
|
this.scheduleDocumentSelectionUpdate();
|
|
88
88
|
}
|
|
89
89
|
return;
|
|
@@ -95,7 +95,7 @@ JSClass('UIHTMLContentEditableTextInputManager', UITextInputManager, {
|
|
|
95
95
|
this._editableElement = editableElement;
|
|
96
96
|
if (this._editableElement !== null){
|
|
97
97
|
this.setupEditableElement();
|
|
98
|
-
this._editableElement.focus();
|
|
98
|
+
this._editableElement.focus({preventScroll: true});
|
|
99
99
|
}
|
|
100
100
|
this.scheduleDocumentSelectionUpdate();
|
|
101
101
|
},
|
|
@@ -749,7 +749,7 @@ JSClass('UIHTMLContentEditableTextInputManager', UITextInputManager, {
|
|
|
749
749
|
|
|
750
750
|
_ensureCorrectFocus: function(){
|
|
751
751
|
if (this._editableElement !== null){
|
|
752
|
-
this._editableElement.focus();
|
|
752
|
+
this._editableElement.focus({preventScroll: true});
|
|
753
753
|
this.updateDocumentSelection();
|
|
754
754
|
}
|
|
755
755
|
},
|
|
@@ -1116,7 +1116,7 @@ JSClass("UIHTMLDisplayServerCanvasContext", UIHTMLDisplayServerContext, {
|
|
|
1116
1116
|
|
|
1117
1117
|
updateAccessibilityFocus: function(accessibility){
|
|
1118
1118
|
var ariaRole = ariaRoleForAccessibility(accessibility);
|
|
1119
|
-
this.element.focus();
|
|
1119
|
+
this.element.focus({preventScroll: true});
|
|
1120
1120
|
// if (focusedAccessibility === null || focusedAccessibility === undefined){
|
|
1121
1121
|
// this.element.removeAttribute("aria-activedescendant");
|
|
1122
1122
|
// }else{
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
// #import "UIHTMLContentEditableTextInputManager.js"
|
|
23
23
|
// #import "UIPlatform.js"
|
|
24
24
|
// #import "UIOpenPanel.js"
|
|
25
|
+
// #import "UIKeyboard.js"
|
|
25
26
|
// #feature Element.prototype.addEventListener
|
|
26
27
|
// #feature 'key' in KeyboardEvent.prototype
|
|
27
28
|
// #feature File
|
|
@@ -166,6 +167,9 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
166
167
|
this.rootElement.addEventListener('touchend', this, {passive: false, capture: false});
|
|
167
168
|
this.rootElement.addEventListener('touchcancel', this, {passive: false, capture: false});
|
|
168
169
|
this.rootElement.addEventListener('touchmove', this, {passive: false, capture: false});
|
|
170
|
+
if (this.domWindow.visualViewport !== null){
|
|
171
|
+
this.domWindow.visualViewport.addEventListener('resize', this, false);
|
|
172
|
+
}
|
|
169
173
|
},
|
|
170
174
|
|
|
171
175
|
removeEventListeners: function(){
|
|
@@ -200,6 +204,9 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
200
204
|
this.rootElement.removeEventListener('touchend', this, {passive: false, capture: false});
|
|
201
205
|
this.rootElement.removeEventListener('touchcancel', this, {passive: false, capture: false});
|
|
202
206
|
this.rootElement.removeEventListener('touchmove', this, {passive: false, capture: false});
|
|
207
|
+
if (this.domWindow.visualViewport !== null){
|
|
208
|
+
this.domWindow.visualViewport.removeEventListener('resize', this, false);
|
|
209
|
+
}
|
|
203
210
|
},
|
|
204
211
|
|
|
205
212
|
handleEvent: function(e){
|
|
@@ -721,6 +728,10 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
721
728
|
// --------------------------------------------------------------------
|
|
722
729
|
// MARK: - Window Events
|
|
723
730
|
|
|
731
|
+
virtualKeyboard: JSLazyInitProperty(function(){
|
|
732
|
+
return UIKeyboard.init();
|
|
733
|
+
}),
|
|
734
|
+
|
|
724
735
|
resize: function(e){
|
|
725
736
|
// resize event is not cancelable, so no need for preventDefault
|
|
726
737
|
if (e.currentTarget === this.domWindow){
|
|
@@ -728,6 +739,47 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
728
739
|
this.screen.frame = JSRect(JSPoint.Zero, this.rootElementSize());
|
|
729
740
|
this.screenDidChangeFrame(oldFrame);
|
|
730
741
|
this.displayServer.setScreenSize(this.screen.frame.size);
|
|
742
|
+
}else if (e.currentTarget === this.domWindow.visualViewport){
|
|
743
|
+
// using touch screen as proxy for "has virtual keyboard"
|
|
744
|
+
// not a perfect match, but good enough for now
|
|
745
|
+
if (UIDevice.shared.primaryPointerType === UIUserInterface.PointerType.touch){
|
|
746
|
+
var viewportFrame = JSRect(
|
|
747
|
+
Math.floor(this.domWindow.visualViewport.offsetLeft),
|
|
748
|
+
Math.floor(this.domWindow.visualViewport.offsetTop),
|
|
749
|
+
Math.floor(this.domWindow.visualViewport.width),
|
|
750
|
+
Math.floor(this.domWindow.visualViewport.height)
|
|
751
|
+
);
|
|
752
|
+
if (viewportFrame.origin.x === this.screen.frame.origin.x && viewportFrame.origin.y === this.screen.frame.origin.y && viewportFrame.size.width === this.screen.frame.size.width){
|
|
753
|
+
// A keyboard may not be the only thing that obstructs the bottom of the screen, but
|
|
754
|
+
// we'll assume that a large-ish obstruction is a keyboard
|
|
755
|
+
var obstructedHeight = this.screen.frame.size.height - viewportFrame.size.height;
|
|
756
|
+
var obstructedFrame = JSRect(0, this.screen.frame.origin.x + this.screen.frame.size.height - obstructedHeight, this.screen.frame.size.width, obstructedHeight);
|
|
757
|
+
if (!this.virtualKeyboard.frame.isEqual(obstructedFrame)){
|
|
758
|
+
var wasVisible = this.virtualKeyboard.visible;
|
|
759
|
+
this.virtualKeyboard.frame = obstructedFrame;
|
|
760
|
+
this.virtualKeyboard.visible = this.virtualKeyboard.frame.size.height > 50;
|
|
761
|
+
if (wasVisible){
|
|
762
|
+
if (this.virtualKeyboard.visible){
|
|
763
|
+
JSNotificationCenter.shared.post("UIKeyboardDidShow", this, {frame: this.virtualKeyboard.frame});
|
|
764
|
+
}else{
|
|
765
|
+
JSNotificationCenter.shared.post("UIKeyboardDidHide", this);
|
|
766
|
+
// This should only come into play on Android, where hiding the keyboard
|
|
767
|
+
// does NOT cause a blur event. We want to go ahead and remove first responder
|
|
768
|
+
// status when the keyboard is hidden.
|
|
769
|
+
if (this.textInputManager.textInputClient instanceof UIView){
|
|
770
|
+
if (this.textInputManager.textInputClient.window.firstResponder === this.textInputManager.textInputClient){
|
|
771
|
+
this.textInputManager.textInputClient.window.firstResponder = null;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}else{
|
|
776
|
+
if (this.virtualKeyboard.visible){
|
|
777
|
+
JSNotificationCenter.shared.post("UIKeyboardDidShow", this, {frame: this.virtualKeyboard.frame});
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
731
783
|
}
|
|
732
784
|
},
|
|
733
785
|
|
|
@@ -394,6 +394,7 @@ JSClass("UIPopupWindowStyler", UIWindowStyler, {
|
|
|
394
394
|
},
|
|
395
395
|
|
|
396
396
|
layoutWindow: function(window){
|
|
397
|
+
UIPopupWindowStyler.$super.layoutWindow.call(this, window);
|
|
397
398
|
var contentInsets = JSInsets(window.contentInsets);
|
|
398
399
|
if (window._showsSourceArrow){
|
|
399
400
|
var popupBacking = window.stylerProperties.popupBacking;
|
|
@@ -475,7 +475,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
475
475
|
var selections = this._selectionsCopy();
|
|
476
476
|
for (i = 0, l = selections.length; i < l; ++i){
|
|
477
477
|
selection = selections[i];
|
|
478
|
-
this._setAttributeValueForSelection(name, value, selection);
|
|
478
|
+
this._setAttributeValueForSelection(name, value, selection, false);
|
|
479
479
|
}
|
|
480
480
|
this._setSelectionsAllowingUndo(selections);
|
|
481
481
|
this.undoManager.endUndoGrouping();
|
|
@@ -585,7 +585,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
585
585
|
var selections = this._selectionsCopy();
|
|
586
586
|
for (i = 0, l = selections.length; i < l; ++i){
|
|
587
587
|
selection = selections[i];
|
|
588
|
-
this._setAttributeValueForSelection(name, !currentValue, selection);
|
|
588
|
+
this._setAttributeValueForSelection(name, !currentValue, selection, true);
|
|
589
589
|
}
|
|
590
590
|
this._setSelectionsAllowingUndo(selections);
|
|
591
591
|
this.undoManager.endUndoGrouping();
|
|
@@ -593,17 +593,25 @@ JSClass("UITextEditor", JSObject, {
|
|
|
593
593
|
this._resetSelectionAffinity();
|
|
594
594
|
},
|
|
595
595
|
|
|
596
|
-
_setAttributeValueForSelection: function(name, value, selection){
|
|
596
|
+
_setAttributeValueForSelection: function(name, value, selection, expandingSelection){
|
|
597
597
|
var textStorage = this.textLayoutManager.textStorage;
|
|
598
|
+
var str = textStorage.string;
|
|
599
|
+
var range = selection.range;
|
|
600
|
+
if (expandingSelection && selection.range.length === 0){
|
|
601
|
+
range = str.rangeForWordAtIndex(selection.range.location);
|
|
602
|
+
if (selection.range.location === range.location || selection.range.location === range.end){
|
|
603
|
+
range = selection.range;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
598
606
|
var replacementString;
|
|
599
|
-
if (
|
|
600
|
-
replacementString = textStorage.attributedSubstringInRange(
|
|
607
|
+
if (range.length > 0){
|
|
608
|
+
replacementString = textStorage.attributedSubstringInRange(range);
|
|
601
609
|
if (value !== null && value !== undefined){
|
|
602
610
|
replacementString.addAttributeInRange(name, value, JSRange(0, replacementString.string.length));
|
|
603
611
|
}else{
|
|
604
612
|
replacementString.removeAttributeInRange(name, JSRange(0, replacementString.string.length));
|
|
605
613
|
}
|
|
606
|
-
this._replaceTextStorageRangeAllowingUndo(textStorage,
|
|
614
|
+
this._replaceTextStorageRangeAllowingUndo(textStorage, range, replacementString);
|
|
607
615
|
}else{
|
|
608
616
|
selection.attributes = this._insertAttributesForSelection(selection);
|
|
609
617
|
var currentValue = selection.attributes[name];
|
|
@@ -612,7 +620,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
612
620
|
}else{
|
|
613
621
|
delete selection.attributes[name];
|
|
614
622
|
}
|
|
615
|
-
this.undoManager.registerUndo(this, this._setAttributeValueForSelection, name, currentValue, selection);
|
|
623
|
+
this.undoManager.registerUndo(this, this._setAttributeValueForSelection, name, currentValue, selection, expandingSelection);
|
|
616
624
|
}
|
|
617
625
|
},
|
|
618
626
|
|
|
@@ -1008,10 +1008,12 @@ JSClass("UITextField", UIControl, {
|
|
|
1008
1008
|
this._localEditor.handleTouchesEnded(touches, event);
|
|
1009
1009
|
return;
|
|
1010
1010
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
this.
|
|
1014
|
-
|
|
1011
|
+
if (this._touchOrigin !== null){
|
|
1012
|
+
var origin = this.convertPointToView(this.bounds.origin, this.window);
|
|
1013
|
+
if (this.containsPoint(location) && this._touchOrigin.distanceToPoint(origin) < 2){
|
|
1014
|
+
this.window.firstResponder = this;
|
|
1015
|
+
this._localEditor.handleTouchesEndedAtLocation(this.layer.convertPointToLayer(location, this._textLayer), touches, event);
|
|
1016
|
+
}
|
|
1015
1017
|
}
|
|
1016
1018
|
}
|
|
1017
1019
|
UITextField.$super.touchesEnded.call(this, touches, event);
|
|
@@ -1407,6 +1409,7 @@ JSClass("UITextFieldCustomStyler", UITextFieldStyler, {
|
|
|
1407
1409
|
disabledBorderColor: null,
|
|
1408
1410
|
borderWidth: 0,
|
|
1409
1411
|
textColor: null,
|
|
1412
|
+
disabledTextColor: null,
|
|
1410
1413
|
placeholderColor: null,
|
|
1411
1414
|
cornerRadius: 0,
|
|
1412
1415
|
textInsets: null,
|
|
@@ -1442,6 +1445,11 @@ JSClass("UITextFieldCustomStyler", UITextFieldStyler, {
|
|
|
1442
1445
|
}else{
|
|
1443
1446
|
this.textColor = JSColor.text;
|
|
1444
1447
|
}
|
|
1448
|
+
if (spec.containsKey("disabledTextColor")){
|
|
1449
|
+
this.disabledTextColor = spec.valueForKey("disabledTextColor", JSColor);
|
|
1450
|
+
}else{
|
|
1451
|
+
this.disabledTextColor = this.textColor;
|
|
1452
|
+
}
|
|
1445
1453
|
if (spec.containsKey("placeholderColor")){
|
|
1446
1454
|
this.placeholderColor = spec.valueForKey("placeholderColor", JSColor);
|
|
1447
1455
|
}
|
|
@@ -1486,6 +1494,7 @@ JSClass("UITextFieldCustomStyler", UITextFieldStyler, {
|
|
|
1486
1494
|
if (textField.active){
|
|
1487
1495
|
textField.backgroundColor = this.activeBackgroundColor || this.backgroundColor;
|
|
1488
1496
|
textField.borderColor = this.activeBorderColor || this.borderColor;
|
|
1497
|
+
textField.textColor = this.textColor;
|
|
1489
1498
|
}else if (textField.enabled){
|
|
1490
1499
|
if (textField.over){
|
|
1491
1500
|
textField.backgroundColor = this.overBackgroundColor || this.backgroundColor;
|
|
@@ -1494,9 +1503,11 @@ JSClass("UITextFieldCustomStyler", UITextFieldStyler, {
|
|
|
1494
1503
|
textField.backgroundColor = this.backgroundColor;
|
|
1495
1504
|
textField.borderColor = this.borderColor;
|
|
1496
1505
|
}
|
|
1506
|
+
textField.textColor = this.textColor;
|
|
1497
1507
|
}else{
|
|
1498
1508
|
textField.backgroundColor = this.disabledBackgroundColor || this.backgroundColor;
|
|
1499
1509
|
textField.borderColor = this.disabledBorderColor || this.borderColor;
|
|
1510
|
+
textField.textColor = this.disabledTextColor;
|
|
1500
1511
|
}
|
|
1501
1512
|
},
|
|
1502
1513
|
|
|
@@ -167,8 +167,10 @@ JSClass("UITextLayer", UILayer, {
|
|
|
167
167
|
if (!text.isKindOfClass(JSTextStorage)){
|
|
168
168
|
text = JSTextStorage.initWithAttributedString(text);
|
|
169
169
|
}
|
|
170
|
-
this._textStorage
|
|
171
|
-
|
|
170
|
+
if (text !== this._textStorage){
|
|
171
|
+
this._textStorage = text;
|
|
172
|
+
this._textLayoutManager.replaceTextStorage(this._textStorage);
|
|
173
|
+
}
|
|
172
174
|
this.setNeedsDisplay();
|
|
173
175
|
this._displayQueued = true;
|
|
174
176
|
},
|
|
@@ -143,6 +143,7 @@ JSClass("UITokenField", UITextField, {
|
|
|
143
143
|
this.attributedText.replaceCharactersInRangeWithAttributedString(JSRange(range.location + indexAdjustment, range.length), attachmentString);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
|
+
this.sendActionsForEvents(UIControl.Event.primaryAction | UIControl.Event.valueChanged);
|
|
146
147
|
},
|
|
147
148
|
|
|
148
149
|
_convertStringToRepresentedObject: function(string, range){
|