@breakside/jskit 2022.22.2 → 2022.22.3
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/DOM.jsframework/sources.json +10 -3
- package/Frameworks/FontKit.jsframework/Info.json +2 -2
- package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
- package/Frameworks/FontKit.jsframework/sources.json +34 -2
- package/Frameworks/Foundation.jsframework/Info.json +2 -2
- package/Frameworks/Foundation.jsframework/JS/JSAttributedString.js +69 -20
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/sources.json +159 -1
- package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
- package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
- package/Frameworks/SecurityKit.jsframework/sources.json +43 -2
- package/Info.json +2 -2
- package/Node/Builder.js +20 -9
- package/Node/FrameworkBuilder.js +22 -2
- package/Node/Project.js +22 -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/JSAttributedString.js +69 -20
- 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/UILabel.js +43 -10
- 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": "2022.22.
|
|
4
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
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": "2022.22.
|
|
6
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
"files": [
|
|
5
5
|
"DOM.js"
|
|
6
6
|
],
|
|
7
|
-
"features": []
|
|
7
|
+
"features": [],
|
|
8
|
+
"globals": []
|
|
8
9
|
},
|
|
9
10
|
"html": {
|
|
10
11
|
"frameworks": [],
|
|
11
12
|
"files": [
|
|
12
13
|
"DOM+HTML.js"
|
|
13
14
|
],
|
|
14
|
-
"features": []
|
|
15
|
+
"features": [],
|
|
16
|
+
"globals": []
|
|
15
17
|
},
|
|
16
18
|
"node": {
|
|
17
19
|
"frameworks": [
|
|
@@ -33,6 +35,11 @@
|
|
|
33
35
|
"XMLSerializer.js",
|
|
34
36
|
"DOM+Node.js"
|
|
35
37
|
],
|
|
36
|
-
"features": []
|
|
38
|
+
"features": [],
|
|
39
|
+
"globals": [
|
|
40
|
+
"DOM",
|
|
41
|
+
"DOMParser",
|
|
42
|
+
"XMLSerializer"
|
|
43
|
+
]
|
|
37
44
|
}
|
|
38
45
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.FontKit",
|
|
4
|
-
"JSBundleVersion": "2022.22.
|
|
4
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
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": "2022.22.
|
|
6
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [],
|
|
16
16
|
"ResourceLookup": {
|
|
@@ -12,7 +12,38 @@
|
|
|
12
12
|
"FNTFontDescriptor.js",
|
|
13
13
|
"FontKit.js"
|
|
14
14
|
],
|
|
15
|
-
"features": []
|
|
15
|
+
"features": [],
|
|
16
|
+
"globals": [
|
|
17
|
+
"FNTOpenTypeFont",
|
|
18
|
+
"FNTOpenTypeFontTable",
|
|
19
|
+
"FNTOpenTypeFontTableHead",
|
|
20
|
+
"FNTOpenTypeFontTableName",
|
|
21
|
+
"FNTOpenTypeFontTableHhea",
|
|
22
|
+
"FNTOpenTypeFontTableHmtx",
|
|
23
|
+
"FNTOpenTypeFontTableCmap",
|
|
24
|
+
"FNTOpenTypeFontTableOS2",
|
|
25
|
+
"FNTOpenTypeFontTableMaxp",
|
|
26
|
+
"FNTOpenTypeFontTablePost",
|
|
27
|
+
"FNTOpenTypeFontTableCFF",
|
|
28
|
+
"FNTOpenTypeFontTableGlyf",
|
|
29
|
+
"FNTOpenTypeFontTableLoca",
|
|
30
|
+
"FNTOpenTypeFontCmap",
|
|
31
|
+
"FNTOpenTypeFontCmapNull",
|
|
32
|
+
"FNTOpenTypeFontCmap0",
|
|
33
|
+
"FNTOpenTypeFontCmap4",
|
|
34
|
+
"FNTOpenTypeFontCmap6",
|
|
35
|
+
"FNTOpenTypeFontCmap10",
|
|
36
|
+
"FNTOpenTypeFontCmap12",
|
|
37
|
+
"FNTOpenTypeFontCmap13",
|
|
38
|
+
"FNTOpenTypeGlyph",
|
|
39
|
+
"FNTOpenTypeSimpleGlyph",
|
|
40
|
+
"FNTOpenTypeCompoundGlyph",
|
|
41
|
+
"FNTOpenTypeConstructor",
|
|
42
|
+
"FNTType1Font",
|
|
43
|
+
"FNTAdobeNamesToUnicode",
|
|
44
|
+
"FNTCompactFontFormat",
|
|
45
|
+
"FNTFontDescriptor"
|
|
46
|
+
]
|
|
16
47
|
},
|
|
17
48
|
"html": {
|
|
18
49
|
"frameworks": [],
|
|
@@ -20,6 +51,7 @@
|
|
|
20
51
|
"FNTFontDescriptor+HTML.js",
|
|
21
52
|
"FontKit+HTML.js"
|
|
22
53
|
],
|
|
23
|
-
"features": []
|
|
54
|
+
"features": [],
|
|
55
|
+
"globals": []
|
|
24
56
|
}
|
|
25
57
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.Foundation",
|
|
4
|
-
"JSBundleVersion": "2022.22.
|
|
4
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
13
13
|
}
|
|
@@ -294,6 +294,44 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
294
294
|
return new JSAttributedStringRunIterator(this, index);
|
|
295
295
|
},
|
|
296
296
|
|
|
297
|
+
longestRangeOfAttributeAtIndex: function(attributeName, index){
|
|
298
|
+
return this.longestRangeOfAttributesAtIndex([attributeName], index);
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
longestRangeOfAttributesAtIndex: function(attributeNames, index){
|
|
302
|
+
var runIndex = this._runIndexForStringIndex(index);
|
|
303
|
+
var run = this._runs[runIndex];
|
|
304
|
+
var range = JSRange(run.range);
|
|
305
|
+
var attributes = {};
|
|
306
|
+
var i, l;
|
|
307
|
+
for (i = 0, l = attributeNames.length; i < l; ++i){
|
|
308
|
+
attributes[attributeNames[i]] = run.attributes[attributeNames[i]];
|
|
309
|
+
}
|
|
310
|
+
i = runIndex - 1;
|
|
311
|
+
while (i >= 0){
|
|
312
|
+
run = this._runs[i];
|
|
313
|
+
if (run.containsEqualAttributes(attributes)){
|
|
314
|
+
range.length = range.end - run.range.location;
|
|
315
|
+
range.location = run.range.location;
|
|
316
|
+
}else{
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
--i;
|
|
320
|
+
}
|
|
321
|
+
i = runIndex + 1;
|
|
322
|
+
l = this._runs.length;
|
|
323
|
+
while (i < l){
|
|
324
|
+
run = this._runs[i];
|
|
325
|
+
if (run.containsEqualAttributes(attributes)){
|
|
326
|
+
range.length = run.range.end - range.location;
|
|
327
|
+
}else{
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
++i;
|
|
331
|
+
}
|
|
332
|
+
return range;
|
|
333
|
+
},
|
|
334
|
+
|
|
297
335
|
// MARK: - Formatting
|
|
298
336
|
|
|
299
337
|
replaceFormat: function(){
|
|
@@ -339,7 +377,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
339
377
|
var runA;
|
|
340
378
|
for (var runIndex = lastRunIndex - 1; runIndex >= expandedRunRange.location; --runIndex){
|
|
341
379
|
runA = this._runs[runIndex];
|
|
342
|
-
if (runA.
|
|
380
|
+
if (runA.onlyContainsEqualAttributes(runB.attributes)){
|
|
343
381
|
this._runs.splice(runIndex, 1);
|
|
344
382
|
runB.range.location = runA.range.location;
|
|
345
383
|
runB.range.length += runA.range.length;
|
|
@@ -358,7 +396,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
358
396
|
}
|
|
359
397
|
var runA = this._runs[runIndex - 1];
|
|
360
398
|
var runB = this._runs[runIndex];
|
|
361
|
-
if (runA.
|
|
399
|
+
if (runA.onlyContainsEqualAttributes(runB.attributes)){
|
|
362
400
|
this._runs.splice(runIndex, 1);
|
|
363
401
|
runA.range.length += runB.range.length;
|
|
364
402
|
}
|
|
@@ -471,35 +509,46 @@ function JSAttributedStringRun(range, attributes){
|
|
|
471
509
|
|
|
472
510
|
JSAttributedStringRun.prototype = {
|
|
473
511
|
|
|
474
|
-
|
|
512
|
+
containsEqualAttributes: function(attributes){
|
|
475
513
|
var attribute;
|
|
476
514
|
var a, b;
|
|
477
|
-
for (attribute in
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
if (
|
|
482
|
-
if (!a.isEqual(b)){
|
|
483
|
-
return false;
|
|
484
|
-
}
|
|
485
|
-
}else if (b.isEqual){
|
|
486
|
-
if (!b.isEqual(a)){
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
}else if (a != b){
|
|
515
|
+
for (attribute in attributes){
|
|
516
|
+
a = attributes[attribute];
|
|
517
|
+
b = this.attributes[attribute];
|
|
518
|
+
if (a === undefined){
|
|
519
|
+
if (!!b){
|
|
490
520
|
return false;
|
|
491
521
|
}
|
|
492
|
-
}else{
|
|
522
|
+
}else if (a === null){
|
|
523
|
+
if (b !== null && b !== undefined){
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
}else if (a.isEqual){
|
|
527
|
+
if (b === null || b === undefined){
|
|
528
|
+
return false;
|
|
529
|
+
}
|
|
530
|
+
if (!a.isEqual(b)){
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
}else if (a != b){
|
|
493
534
|
return false;
|
|
494
535
|
}
|
|
495
536
|
}
|
|
496
|
-
|
|
497
|
-
|
|
537
|
+
return true;
|
|
538
|
+
},
|
|
539
|
+
|
|
540
|
+
onlyContainsEqualAttributes: function(attributes){
|
|
541
|
+
if (!this.containsEqualAttributes(attributes)){
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
var attribute;
|
|
545
|
+
for (attribute in this.attributes){
|
|
546
|
+
if (!(attribute in attributes)){
|
|
498
547
|
return false;
|
|
499
548
|
}
|
|
500
549
|
}
|
|
501
550
|
return true;
|
|
502
|
-
}
|
|
551
|
+
},
|
|
503
552
|
|
|
504
553
|
};
|
|
505
554
|
|
|
@@ -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": "2022.22.
|
|
6
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [
|
|
17
17
|
{
|
|
@@ -122,6 +122,146 @@
|
|
|
122
122
|
"setInterval",
|
|
123
123
|
"ArrayBuffer",
|
|
124
124
|
"Uint8Array"
|
|
125
|
+
],
|
|
126
|
+
"globals": [
|
|
127
|
+
"JSCopy",
|
|
128
|
+
"JSDeepCopy",
|
|
129
|
+
"JSResolveDottedName",
|
|
130
|
+
"JSSetDottedName",
|
|
131
|
+
"JSSize",
|
|
132
|
+
"JSPoint",
|
|
133
|
+
"JSInsets",
|
|
134
|
+
"JSRect",
|
|
135
|
+
"JSAffineTransform",
|
|
136
|
+
"JSRange",
|
|
137
|
+
"JSConstraintBox",
|
|
138
|
+
"JSLineBreakMode",
|
|
139
|
+
"JSTextAlignment",
|
|
140
|
+
"UnicodeProperties",
|
|
141
|
+
"UnicodeChar",
|
|
142
|
+
"JSData",
|
|
143
|
+
"Promise",
|
|
144
|
+
"JSMath",
|
|
145
|
+
"JSCubicBezier",
|
|
146
|
+
"JSBinarySearcher",
|
|
147
|
+
"JSIndexRange",
|
|
148
|
+
"JSIndexSet",
|
|
149
|
+
"JSIndexPath",
|
|
150
|
+
"JSIndexPathRange",
|
|
151
|
+
"JSIndexPathSet",
|
|
152
|
+
"UUID",
|
|
153
|
+
"JSClass",
|
|
154
|
+
"JSCustomProperty",
|
|
155
|
+
"JSDynamicProperty",
|
|
156
|
+
"JSReadOnlyProperty",
|
|
157
|
+
"JSLazyInitProperty",
|
|
158
|
+
"JSOutlet",
|
|
159
|
+
"JSProtocol",
|
|
160
|
+
"JSIsNullValueTransformer",
|
|
161
|
+
"JSIsNotNullValueTransformer",
|
|
162
|
+
"JSIsEmptyValueTransformer",
|
|
163
|
+
"JSIsNotEmptyValueTransformer",
|
|
164
|
+
"JSNegateBooleanValueTransformer",
|
|
165
|
+
"JSCommaSeparatedListValueTransformer",
|
|
166
|
+
"JSObject",
|
|
167
|
+
"JSLog",
|
|
168
|
+
"JSObjectGraphLoading",
|
|
169
|
+
"JSObjectGraph",
|
|
170
|
+
"JSDate",
|
|
171
|
+
"JSTimeZone",
|
|
172
|
+
"JSTimeInterval",
|
|
173
|
+
"JSCalendar",
|
|
174
|
+
"JSGregorianCalendar",
|
|
175
|
+
"JSLocale",
|
|
176
|
+
"JSMediaType",
|
|
177
|
+
"JSFile",
|
|
178
|
+
"JSDataFile",
|
|
179
|
+
"JSBundle",
|
|
180
|
+
"JSBundleResourceFile",
|
|
181
|
+
"JSFormFieldMap",
|
|
182
|
+
"JSFormField",
|
|
183
|
+
"JSURL",
|
|
184
|
+
"JSMIMEHeaderMap",
|
|
185
|
+
"JSMIMEHeader",
|
|
186
|
+
"JSURLRequest",
|
|
187
|
+
"JSURLSession",
|
|
188
|
+
"JSURLResponse",
|
|
189
|
+
"JSURLResponseError",
|
|
190
|
+
"JSXMLParser",
|
|
191
|
+
"JSImage",
|
|
192
|
+
"_JSResourceImage",
|
|
193
|
+
"_JSDataImage",
|
|
194
|
+
"_JSURLImage",
|
|
195
|
+
"JSTextAttachment",
|
|
196
|
+
"JSAttributedString",
|
|
197
|
+
"JSSpec",
|
|
198
|
+
"JSArrayController",
|
|
199
|
+
"JSSparseArrayController",
|
|
200
|
+
"JSColorSpace",
|
|
201
|
+
"JSXYZColorSpace",
|
|
202
|
+
"JSXYZScaledColorSpace",
|
|
203
|
+
"JSLabColorSpace",
|
|
204
|
+
"JSRGBColorSpace",
|
|
205
|
+
"JSGrayColorSpace",
|
|
206
|
+
"JSDerivedColorSpace",
|
|
207
|
+
"JSMappedColorSpace",
|
|
208
|
+
"JSIndexedColorSpace",
|
|
209
|
+
"JSNamedColorSpace",
|
|
210
|
+
"JSColor",
|
|
211
|
+
"JSGradient",
|
|
212
|
+
"HuffmanTree",
|
|
213
|
+
"DeflateStream",
|
|
214
|
+
"Deflate",
|
|
215
|
+
"Adler32",
|
|
216
|
+
"Zlib",
|
|
217
|
+
"ZlibStream",
|
|
218
|
+
"JSFontDescriptor",
|
|
219
|
+
"JSDataFontDescriptor",
|
|
220
|
+
"JSResourceFontDescriptor",
|
|
221
|
+
"JSTestFontDescriptor",
|
|
222
|
+
"JSFont",
|
|
223
|
+
"JSPath",
|
|
224
|
+
"JSContext",
|
|
225
|
+
"JSDateFormatter",
|
|
226
|
+
"JSNumberFormatter",
|
|
227
|
+
"JSTextLayoutManager",
|
|
228
|
+
"JSTextRun",
|
|
229
|
+
"JSTextLine",
|
|
230
|
+
"JSTextTypesetter",
|
|
231
|
+
"JSTextFrame",
|
|
232
|
+
"JSTextFramesetter",
|
|
233
|
+
"JSTextContainer",
|
|
234
|
+
"JSTextLayoutManagerDelegate",
|
|
235
|
+
"JSTextStorage",
|
|
236
|
+
"JSTimer",
|
|
237
|
+
"JSRunLoop",
|
|
238
|
+
"JSIPAddress",
|
|
239
|
+
"JSURLSessionTask",
|
|
240
|
+
"JSURLSessionDataTask",
|
|
241
|
+
"JSURLSessionUploadTask",
|
|
242
|
+
"JSURLSessionStreamTask",
|
|
243
|
+
"JSURLSessionDelegate",
|
|
244
|
+
"JSURLSessionStreamTaskDelegate",
|
|
245
|
+
"JSHTTPResponseParserDelegate",
|
|
246
|
+
"JSHTTPResponseParser",
|
|
247
|
+
"JSHTTPWebSocketParser",
|
|
248
|
+
"JSHTTPWebSocketParserDelegate",
|
|
249
|
+
"JSNotification",
|
|
250
|
+
"JSNotificationCenter",
|
|
251
|
+
"JSFileManager",
|
|
252
|
+
"JSFileEnumerator",
|
|
253
|
+
"JSFileArrayFileEnumerator",
|
|
254
|
+
"JSUserDefaults",
|
|
255
|
+
"JSUndoManager",
|
|
256
|
+
"JSDistributedNotificationCenter",
|
|
257
|
+
"JSSynchronizer",
|
|
258
|
+
"JSCRC32",
|
|
259
|
+
"JSZip",
|
|
260
|
+
"JSIterativeHash",
|
|
261
|
+
"JSSHA1Hash",
|
|
262
|
+
"JSMD5Hash",
|
|
263
|
+
"JSArguments",
|
|
264
|
+
"JSEnvironment"
|
|
125
265
|
]
|
|
126
266
|
},
|
|
127
267
|
"html": {
|
|
@@ -156,6 +296,16 @@
|
|
|
156
296
|
"FileReader",
|
|
157
297
|
"URL.createObjectURL",
|
|
158
298
|
"URL.revokeObjectURL"
|
|
299
|
+
],
|
|
300
|
+
"globals": [
|
|
301
|
+
"JSHTMLHTTPClient",
|
|
302
|
+
"JSHTMLURLSessionDataTask",
|
|
303
|
+
"JSHTMLURLSessionUploadTask",
|
|
304
|
+
"JSHTMLURLSessionStreamTask",
|
|
305
|
+
"JSHTMLFileManager",
|
|
306
|
+
"JSHTMLFile",
|
|
307
|
+
"JSHTMLFileListFileEnumerator",
|
|
308
|
+
"JSHTMLFileSystemEntryFileEnumerator"
|
|
159
309
|
]
|
|
160
310
|
},
|
|
161
311
|
"node": {
|
|
@@ -175,6 +325,14 @@
|
|
|
175
325
|
"JSAMQPNotificationCenter.js",
|
|
176
326
|
"Foundation+Node.js"
|
|
177
327
|
],
|
|
178
|
-
"features": []
|
|
328
|
+
"features": [],
|
|
329
|
+
"globals": [
|
|
330
|
+
"JSNodeFileManager",
|
|
331
|
+
"JSNodeHTTPClient",
|
|
332
|
+
"JSNodeURLSessionDataTask",
|
|
333
|
+
"JSNodeURLSessionUploadTask",
|
|
334
|
+
"JSNodeURLSessionStreamTask",
|
|
335
|
+
"JSAMQPNotificationCenter"
|
|
336
|
+
]
|
|
179
337
|
}
|
|
180
338
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
|
|
4
|
-
"JSBundleVersion": "2022.22.
|
|
4
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
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": "2022.22.
|
|
6
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
|
@@ -23,7 +23,40 @@
|
|
|
23
23
|
"SECCBOR.js",
|
|
24
24
|
"SecurityKit.js"
|
|
25
25
|
],
|
|
26
|
-
"features": []
|
|
26
|
+
"features": [],
|
|
27
|
+
"globals": [
|
|
28
|
+
"SECKey",
|
|
29
|
+
"SECDataKey",
|
|
30
|
+
"SECJSONWebAlgorithms",
|
|
31
|
+
"SECCipher",
|
|
32
|
+
"SECCipherAESCipherBlockChaining",
|
|
33
|
+
"SECCipherAESCounter",
|
|
34
|
+
"SECCipherAESGaloisCounterMode",
|
|
35
|
+
"SECCipherRC4",
|
|
36
|
+
"SECHash",
|
|
37
|
+
"SECVerify",
|
|
38
|
+
"SECKeychain",
|
|
39
|
+
"SECHMAC",
|
|
40
|
+
"SECSign",
|
|
41
|
+
"SECJSONWebToken",
|
|
42
|
+
"SECPassword",
|
|
43
|
+
"SECASN1Value",
|
|
44
|
+
"SECASN1Boolean",
|
|
45
|
+
"SECASN1Integer",
|
|
46
|
+
"SECASN1BitString",
|
|
47
|
+
"SECASN1OctetString",
|
|
48
|
+
"SECASN1ObjectIdentifier",
|
|
49
|
+
"SECASN1Sequence",
|
|
50
|
+
"SECASN1UTF8String",
|
|
51
|
+
"SECASN1Optional",
|
|
52
|
+
"SECASN1Unknown",
|
|
53
|
+
"SECASN1Parser",
|
|
54
|
+
"SECOneTimePassword",
|
|
55
|
+
"SECKeystore",
|
|
56
|
+
"SECDeviceAuthentication",
|
|
57
|
+
"SECCBOR",
|
|
58
|
+
"SECCBORParser"
|
|
59
|
+
]
|
|
27
60
|
},
|
|
28
61
|
"html": {
|
|
29
62
|
"frameworks": [],
|
|
@@ -42,6 +75,11 @@
|
|
|
42
75
|
"features": [
|
|
43
76
|
"window.crypto.subtle",
|
|
44
77
|
"window.crypto.subtle"
|
|
78
|
+
],
|
|
79
|
+
"globals": [
|
|
80
|
+
"SECHTMLKey",
|
|
81
|
+
"SECHTMLDeviceAuthentication",
|
|
82
|
+
"SECHTMLPasswordCredentialKeychain"
|
|
45
83
|
]
|
|
46
84
|
},
|
|
47
85
|
"node": {
|
|
@@ -56,6 +94,9 @@
|
|
|
56
94
|
"SECPassword+Node.js",
|
|
57
95
|
"SecurityKit+Node.js"
|
|
58
96
|
],
|
|
59
|
-
"features": []
|
|
97
|
+
"features": [],
|
|
98
|
+
"globals": [
|
|
99
|
+
"SECNodeKey"
|
|
100
|
+
]
|
|
60
101
|
}
|
|
61
102
|
}
|
package/Info.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "node",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.jskit",
|
|
4
|
-
"JSBundleVersion": "2022.22.
|
|
4
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
12
12
|
}
|
package/Node/Builder.js
CHANGED
|
@@ -174,20 +174,31 @@ JSClass("Builder", JSObject, {
|
|
|
174
174
|
if (!seen.has(name)){
|
|
175
175
|
seen.add(name);
|
|
176
176
|
// If the framework was pre-built, then it can only have
|
|
177
|
-
// dependencies on
|
|
178
|
-
//
|
|
179
|
-
//
|
|
177
|
+
// dependencies on other pre-built frameworks, which
|
|
178
|
+
// are other .jsframework bundles or JSKit frameworks
|
|
179
|
+
//
|
|
180
180
|
// If we built the framework, then we already added its
|
|
181
181
|
// dependencies based on its build reuslts and won't get here.
|
|
182
|
-
let
|
|
183
|
-
let
|
|
184
|
-
|
|
185
|
-
|
|
182
|
+
let includeDirectoryURLs = this.project.includeDirectoryURLs;
|
|
183
|
+
let url = null;
|
|
184
|
+
for (let i = 0, l = includeDirectoryURLs.length; i < l && url === null; ++i){
|
|
185
|
+
let directoryURL = includeDirectoryURLs[i];
|
|
186
|
+
let candidateURL = directoryURL.appendingPathComponent(name + '.jsframework', true);
|
|
187
|
+
let found = await this.fileManager.itemExistsAtURL(candidateURL);
|
|
188
|
+
if (found){
|
|
189
|
+
url = candidateURL;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (url === null){
|
|
193
|
+
url = this.fileManager.urlForPath(JSKitRootDirectoryPath).appendingPathComponents(["Frameworks", name], true);
|
|
194
|
+
let found = await this.fileManager.itemExistsAtURL(url);
|
|
195
|
+
if (!found){
|
|
196
|
+
throw new Error("Cannot find framework %s, (required by %s)".sprintf(name, url.lastPathComponent));
|
|
197
|
+
}
|
|
186
198
|
}
|
|
187
|
-
this.printer.print("\nAdding dependency %s\n".sprintf(name));
|
|
188
199
|
imports.push({
|
|
189
200
|
name: name,
|
|
190
|
-
url:
|
|
201
|
+
url: url
|
|
191
202
|
});
|
|
192
203
|
}
|
|
193
204
|
}
|
package/Node/FrameworkBuilder.js
CHANGED
|
@@ -138,9 +138,10 @@ JSClass("FrameworkBuilder", Builder, {
|
|
|
138
138
|
var genericFrameworks = new Set();
|
|
139
139
|
var genericFiles = new Set();
|
|
140
140
|
var genericFeatures = new Set();
|
|
141
|
+
var genericGlobals = new Set();
|
|
141
142
|
var sources = {};
|
|
142
143
|
for (let env in this.bundleEnvironments){
|
|
143
|
-
sources[env] = {frameworks: [], files: [], features: []};
|
|
144
|
+
sources[env] = {frameworks: [], files: [], features: [], globals: []};
|
|
144
145
|
let imports = this.importsByEnvironment[env];
|
|
145
146
|
for (let i = 0, l = imports.frameworks.length; i < l; ++i){
|
|
146
147
|
let framework = imports.frameworks[i];
|
|
@@ -176,6 +177,15 @@ JSClass("FrameworkBuilder", Builder, {
|
|
|
176
177
|
sources[env].features.push(feature);
|
|
177
178
|
}
|
|
178
179
|
}
|
|
180
|
+
for (let i = 0, l = imports.globals.length; i < l; ++i){
|
|
181
|
+
let name = imports.globals[i];
|
|
182
|
+
if (env == 'generic'){
|
|
183
|
+
genericGlobals.add(name);
|
|
184
|
+
}
|
|
185
|
+
if (env == 'generic' || !genericGlobals.has(name)){
|
|
186
|
+
sources[env].globals.push(name);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
179
189
|
}
|
|
180
190
|
return sources;
|
|
181
191
|
},
|
|
@@ -185,6 +195,7 @@ JSClass("FrameworkBuilder", Builder, {
|
|
|
185
195
|
var genericFrameworks = new Set();
|
|
186
196
|
var genericFiles = new Set();
|
|
187
197
|
var genericFeatures = new Set();
|
|
198
|
+
var genericGlobals = new Set();
|
|
188
199
|
var sources = {};
|
|
189
200
|
var copyright = this.project.getInfoString("JSCopyright", this.resources);
|
|
190
201
|
var licenseString = await this.project.licenseNoticeString();
|
|
@@ -195,7 +206,7 @@ JSClass("FrameworkBuilder", Builder, {
|
|
|
195
206
|
}
|
|
196
207
|
var header = "%s (%s)\n----\n%s%s".sprintf(this.project.info.JSBundleIdentifier, this.project.info.JSBundleVersion, copyright, licenseString);
|
|
197
208
|
for (let env in this.bundleEnvironments){
|
|
198
|
-
sources[env] = {frameworks: [], files: [], features: []};
|
|
209
|
+
sources[env] = {frameworks: [], files: [], features: [], globals: []};
|
|
199
210
|
let filename = this.bundleEnvironments[env];
|
|
200
211
|
let compilation = JavascriptCompilation.initWithName(filename, this.sourcesURL, this.fileManager);
|
|
201
212
|
var fullSourcesURL = this.sourcesURL.appendingPathComponent("_debug", true);
|
|
@@ -238,6 +249,15 @@ JSClass("FrameworkBuilder", Builder, {
|
|
|
238
249
|
sources[env].features.push(feature);
|
|
239
250
|
}
|
|
240
251
|
}
|
|
252
|
+
for (let i = 0, l = imports.globals.length; i < l; ++i){
|
|
253
|
+
let name = imports.globals[i];
|
|
254
|
+
if (env == 'generic'){
|
|
255
|
+
genericGlobals.add(name);
|
|
256
|
+
}
|
|
257
|
+
if (env == 'generic' || !genericGlobals.has(name)){
|
|
258
|
+
sources[env].globals.push(name);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
241
261
|
}
|
|
242
262
|
return sources;
|
|
243
263
|
},
|
package/Node/Project.js
CHANGED
|
@@ -310,7 +310,8 @@ JSClass("Project", JSObject, {
|
|
|
310
310
|
var result = {
|
|
311
311
|
files: [],
|
|
312
312
|
frameworks: [],
|
|
313
|
-
features: []
|
|
313
|
+
features: [],
|
|
314
|
+
globals: []
|
|
314
315
|
};
|
|
315
316
|
var visited = {
|
|
316
317
|
paths: new Set(),
|
|
@@ -359,6 +360,11 @@ JSClass("Project", JSObject, {
|
|
|
359
360
|
result.features.push(feature);
|
|
360
361
|
}
|
|
361
362
|
}
|
|
363
|
+
let globals = js.globals();
|
|
364
|
+
for (let i = 0, l = globals.length; i < l; ++i){
|
|
365
|
+
let name = globals[i];
|
|
366
|
+
result.globals.push(name);
|
|
367
|
+
}
|
|
362
368
|
}
|
|
363
369
|
};
|
|
364
370
|
|
|
@@ -443,7 +449,21 @@ JSClass("Project", JSObject, {
|
|
|
443
449
|
let url = await this.urlForFrameworkName(name, includeDirectoryURLs);
|
|
444
450
|
if (url !== null){
|
|
445
451
|
if (url.fileExtension === '.jsframework'){
|
|
446
|
-
|
|
452
|
+
let sourcesURL = url.appendingPathComponent("sources.json");
|
|
453
|
+
let data = await this.fileManager.contentsAtURL(sourcesURL);
|
|
454
|
+
let sources = JSON.parse(data.stringByDecodingUTF8());
|
|
455
|
+
if (sources.generic.globals){
|
|
456
|
+
for (let name of sources.generic.globals){
|
|
457
|
+
globals.push(name);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
for (let env of envs){
|
|
461
|
+
if ((env in sources) && sources[env].globals){
|
|
462
|
+
for (let name of sources[env].globals){
|
|
463
|
+
globals.push(name);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
447
467
|
}else{
|
|
448
468
|
let frameworkProject = Project.initWithURL(url);
|
|
449
469
|
try{
|
|
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.jskit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "node",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.jskit",
|
|
6
|
-
"JSBundleVersion": "2022.22.
|
|
6
|
+
"JSBundleVersion": "2022.22.3",
|
|
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": "6f0b376edf61fbea02fd94b92f86de9e17d3b716"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [
|
|
16
16
|
{
|
|
@@ -294,6 +294,44 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
294
294
|
return new JSAttributedStringRunIterator(this, index);
|
|
295
295
|
},
|
|
296
296
|
|
|
297
|
+
longestRangeOfAttributeAtIndex: function(attributeName, index){
|
|
298
|
+
return this.longestRangeOfAttributesAtIndex([attributeName], index);
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
longestRangeOfAttributesAtIndex: function(attributeNames, index){
|
|
302
|
+
var runIndex = this._runIndexForStringIndex(index);
|
|
303
|
+
var run = this._runs[runIndex];
|
|
304
|
+
var range = JSRange(run.range);
|
|
305
|
+
var attributes = {};
|
|
306
|
+
var i, l;
|
|
307
|
+
for (i = 0, l = attributeNames.length; i < l; ++i){
|
|
308
|
+
attributes[attributeNames[i]] = run.attributes[attributeNames[i]];
|
|
309
|
+
}
|
|
310
|
+
i = runIndex - 1;
|
|
311
|
+
while (i >= 0){
|
|
312
|
+
run = this._runs[i];
|
|
313
|
+
if (run.containsEqualAttributes(attributes)){
|
|
314
|
+
range.length = range.end - run.range.location;
|
|
315
|
+
range.location = run.range.location;
|
|
316
|
+
}else{
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
--i;
|
|
320
|
+
}
|
|
321
|
+
i = runIndex + 1;
|
|
322
|
+
l = this._runs.length;
|
|
323
|
+
while (i < l){
|
|
324
|
+
run = this._runs[i];
|
|
325
|
+
if (run.containsEqualAttributes(attributes)){
|
|
326
|
+
range.length = run.range.end - range.location;
|
|
327
|
+
}else{
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
++i;
|
|
331
|
+
}
|
|
332
|
+
return range;
|
|
333
|
+
},
|
|
334
|
+
|
|
297
335
|
// MARK: - Formatting
|
|
298
336
|
|
|
299
337
|
replaceFormat: function(){
|
|
@@ -339,7 +377,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
339
377
|
var runA;
|
|
340
378
|
for (var runIndex = lastRunIndex - 1; runIndex >= expandedRunRange.location; --runIndex){
|
|
341
379
|
runA = this._runs[runIndex];
|
|
342
|
-
if (runA.
|
|
380
|
+
if (runA.onlyContainsEqualAttributes(runB.attributes)){
|
|
343
381
|
this._runs.splice(runIndex, 1);
|
|
344
382
|
runB.range.location = runA.range.location;
|
|
345
383
|
runB.range.length += runA.range.length;
|
|
@@ -358,7 +396,7 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
358
396
|
}
|
|
359
397
|
var runA = this._runs[runIndex - 1];
|
|
360
398
|
var runB = this._runs[runIndex];
|
|
361
|
-
if (runA.
|
|
399
|
+
if (runA.onlyContainsEqualAttributes(runB.attributes)){
|
|
362
400
|
this._runs.splice(runIndex, 1);
|
|
363
401
|
runA.range.length += runB.range.length;
|
|
364
402
|
}
|
|
@@ -471,35 +509,46 @@ function JSAttributedStringRun(range, attributes){
|
|
|
471
509
|
|
|
472
510
|
JSAttributedStringRun.prototype = {
|
|
473
511
|
|
|
474
|
-
|
|
512
|
+
containsEqualAttributes: function(attributes){
|
|
475
513
|
var attribute;
|
|
476
514
|
var a, b;
|
|
477
|
-
for (attribute in
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
if (
|
|
482
|
-
if (!a.isEqual(b)){
|
|
483
|
-
return false;
|
|
484
|
-
}
|
|
485
|
-
}else if (b.isEqual){
|
|
486
|
-
if (!b.isEqual(a)){
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
}else if (a != b){
|
|
515
|
+
for (attribute in attributes){
|
|
516
|
+
a = attributes[attribute];
|
|
517
|
+
b = this.attributes[attribute];
|
|
518
|
+
if (a === undefined){
|
|
519
|
+
if (!!b){
|
|
490
520
|
return false;
|
|
491
521
|
}
|
|
492
|
-
}else{
|
|
522
|
+
}else if (a === null){
|
|
523
|
+
if (b !== null && b !== undefined){
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
}else if (a.isEqual){
|
|
527
|
+
if (b === null || b === undefined){
|
|
528
|
+
return false;
|
|
529
|
+
}
|
|
530
|
+
if (!a.isEqual(b)){
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
}else if (a != b){
|
|
493
534
|
return false;
|
|
494
535
|
}
|
|
495
536
|
}
|
|
496
|
-
|
|
497
|
-
|
|
537
|
+
return true;
|
|
538
|
+
},
|
|
539
|
+
|
|
540
|
+
onlyContainsEqualAttributes: function(attributes){
|
|
541
|
+
if (!this.containsEqualAttributes(attributes)){
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
var attribute;
|
|
545
|
+
for (attribute in this.attributes){
|
|
546
|
+
if (!(attribute in attributes)){
|
|
498
547
|
return false;
|
|
499
548
|
}
|
|
500
549
|
}
|
|
501
550
|
return true;
|
|
502
|
-
}
|
|
551
|
+
},
|
|
503
552
|
|
|
504
553
|
};
|
|
505
554
|
|
|
@@ -174,11 +174,14 @@ JSClass('UILabel', UIView, {
|
|
|
174
174
|
var attributes = this.attributedText.attributesAtIndex(index);
|
|
175
175
|
this._didDrag = false;
|
|
176
176
|
if (attributes.link){
|
|
177
|
-
var range = this.attributedText.
|
|
178
|
-
var layer =
|
|
179
|
-
layer.
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
var range = this.attributedText.longestRangeOfAttributeAtIndex("link", index);
|
|
178
|
+
var layer = UILabelLinkLayer.init();
|
|
179
|
+
layer.pathColor = (attributes.textColor || this.textColor).colorWithAlpha(0.2);
|
|
180
|
+
var rects = this.layer.textLayoutManager.rectsForCharacterRange(range);
|
|
181
|
+
var i, l;
|
|
182
|
+
for (i = 0, l = rects.length; i < l; ++i){
|
|
183
|
+
layer.addRect(rects[i]);
|
|
184
|
+
}
|
|
182
185
|
this.layer.addSublayer(layer);
|
|
183
186
|
this._mouseDownAction = {
|
|
184
187
|
link: attributes.link,
|
|
@@ -271,11 +274,14 @@ JSClass('UILabel', UIView, {
|
|
|
271
274
|
var index = this.layer.textLayoutManager.characterIndexAtPoint(location);
|
|
272
275
|
var attributes = this.attributedText.attributesAtIndex(index);
|
|
273
276
|
if (attributes.link){
|
|
274
|
-
var range = this.attributedText.
|
|
275
|
-
var layer =
|
|
276
|
-
layer.
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
var range = this.attributedText.longestRangeOfAttributeAtIndex("link", index);
|
|
278
|
+
var layer = UILabelLinkLayer.init();
|
|
279
|
+
layer.pathColor = (attributes.textColor || this.textColor).colorWithAlpha(0.2);
|
|
280
|
+
var rects = this.layer.textLayoutManager.rectsForCharacterRange(range);
|
|
281
|
+
var i, l;
|
|
282
|
+
for (i = 0, l = rects.length; i < l; ++i){
|
|
283
|
+
layer.addRect(rects[i]);
|
|
284
|
+
}
|
|
279
285
|
this.layer.addSublayer(layer);
|
|
280
286
|
this._touchAction = {
|
|
281
287
|
link: attributes.link,
|
|
@@ -379,4 +385,31 @@ JSClass('UILabel', UIView, {
|
|
|
379
385
|
|
|
380
386
|
});
|
|
381
387
|
|
|
388
|
+
JSClass("UILabelLinkLayer", UILayer, {
|
|
389
|
+
|
|
390
|
+
pathColor: null,
|
|
391
|
+
|
|
392
|
+
init: function(){
|
|
393
|
+
UILabelLinkLayer.$super.init.call(this);
|
|
394
|
+
this.path = JSPath.init();
|
|
395
|
+
this.pathColor = JSColor.black;
|
|
396
|
+
this.setNeedsDisplay();
|
|
397
|
+
},
|
|
398
|
+
|
|
399
|
+
addRect: function(rect){
|
|
400
|
+
this.path.addRoundedRect(rect.rectWithInsets(JSInsets(-1, -2)), 2);
|
|
401
|
+
this.frame = this.path.boundingRect;
|
|
402
|
+
},
|
|
403
|
+
|
|
404
|
+
drawInContext: function(context){
|
|
405
|
+
context.save();
|
|
406
|
+
context.translateBy(-this.path.boundingRect.origin.x, -this.path.boundingRect.origin.y);
|
|
407
|
+
context.setFillColor(this.pathColor);
|
|
408
|
+
context.addPath(this.path);
|
|
409
|
+
context.fillPath();
|
|
410
|
+
context.restore();
|
|
411
|
+
},
|
|
412
|
+
|
|
413
|
+
});
|
|
414
|
+
|
|
382
415
|
UILabel.layerClass = UITextLayer;
|