@breakside/jskit 2022.23.0 → 2022.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/JS/JSAttributedString.js +139 -10
  7. package/Frameworks/Foundation.jsframework/JS/JSParagraphStyle.js +71 -0
  8. package/Frameworks/Foundation.jsframework/JS/JSTextAttachment.js +1 -1
  9. package/Frameworks/Foundation.jsframework/JS/JSTextContainer.js +56 -29
  10. package/Frameworks/Foundation.jsframework/JS/JSTextFrame.js +2 -32
  11. package/Frameworks/Foundation.jsframework/JS/JSTextFramesetter.js +125 -22
  12. package/Frameworks/Foundation.jsframework/JS/JSTextLayoutManager.js +11 -3
  13. package/Frameworks/Foundation.jsframework/JS/JSTextLine.js +4 -3
  14. package/Frameworks/Foundation.jsframework/JS/JSTextRun.js +5 -3
  15. package/Frameworks/Foundation.jsframework/JS/JSTextTypesetter.js +41 -25
  16. package/Frameworks/Foundation.jsframework/JS/String+JS.js +35 -0
  17. package/Frameworks/Foundation.jsframework/JS/UnicodeChar.js +8 -0
  18. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  19. package/Frameworks/Foundation.jsframework/sources.json +3 -0
  20. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  21. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  22. package/Info.json +2 -2
  23. package/Node/io.breakside.jskit-bundle.js +2 -2
  24. package/Node/jskit +1 -0
  25. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  26. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  27. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  28. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  29. package/Root/Frameworks/ChartKit/CHAxis.js +5 -5
  30. package/Root/Frameworks/ChartKit/CHPieChart.js +1 -1
  31. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  32. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  33. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  34. package/Root/Frameworks/DOM/Info.yaml +1 -1
  35. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  36. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  37. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  38. package/Root/Frameworks/Foundation/JSAttributedString.js +139 -10
  39. package/Root/Frameworks/Foundation/JSParagraphStyle.js +71 -0
  40. package/Root/Frameworks/Foundation/JSTextAttachment.js +1 -1
  41. package/Root/Frameworks/Foundation/JSTextContainer.js +56 -29
  42. package/Root/Frameworks/Foundation/JSTextFrame.js +2 -32
  43. package/Root/Frameworks/Foundation/JSTextFramesetter.js +125 -22
  44. package/Root/Frameworks/Foundation/JSTextLayoutManager.js +11 -3
  45. package/Root/Frameworks/Foundation/JSTextLine.js +4 -3
  46. package/Root/Frameworks/Foundation/JSTextRun.js +5 -3
  47. package/Root/Frameworks/Foundation/JSTextTypesetter.js +41 -25
  48. package/Root/Frameworks/Foundation/String+JS.js +35 -0
  49. package/Root/Frameworks/Foundation/UnicodeChar.js +8 -0
  50. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  51. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  52. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  53. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  54. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  55. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  56. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  57. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  58. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  59. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  60. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  61. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  62. package/Root/Frameworks/UIKit/UIHTMLContentEditableTextInputManager.js +36 -0
  63. package/Root/Frameworks/UIKit/UIHTMLDisplayServer.js +1 -1
  64. package/Root/Frameworks/UIKit/UIHTMLTextField.js +1 -1
  65. package/Root/Frameworks/UIKit/UIHTMLTextFrame.js +19 -91
  66. package/Root/Frameworks/UIKit/UIHTMLTextFramesetter.js +52 -9
  67. package/Root/Frameworks/UIKit/UIHTMLTextLine.js +95 -30
  68. package/Root/Frameworks/UIKit/UIHTMLTextRun.js +22 -9
  69. package/Root/Frameworks/UIKit/UIHTMLTextTypesetter.js +334 -459
  70. package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +16 -0
  71. package/Root/Frameworks/UIKit/UIScrollView.js +12 -0
  72. package/Root/Frameworks/UIKit/UISegmentedControl.js +6 -6
  73. package/Root/Frameworks/UIKit/UITextAttachmentView.js +1 -1
  74. package/Root/Frameworks/UIKit/UITextEditor.js +210 -25
  75. package/Root/Frameworks/UIKit/UITextField.js +58 -31
  76. package/Root/Frameworks/UIKit/UITextInput.js +3 -1
  77. package/Root/Frameworks/UIKit/UITextInputManager.js +2 -2
  78. package/Root/Frameworks/UIKit/UITextLayer.js +39 -26
  79. package/Root/Frameworks/UIKit/UITokenField.js +4 -4
  80. package/Root/Frameworks/UIKit/UIView.js +3 -1
  81. package/Root/Frameworks/UIKit/UIWindow.js +16 -3
  82. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  83. 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.23.0",
4
+ "JSBundleVersion": "2022.24.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": "e2a77335b26d1a321448e73eb7b733cdd0714cc8"
12
+ "GitRevision": "384e6ac71d317262e4518508066ab61322409ba2"
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.23.0",
6
+ "JSBundleVersion": "2022.24.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": "e2a77335b26d1a321448e73eb7b733cdd0714cc8"
14
+ "GitRevision": "384e6ac71d317262e4518508066ab61322409ba2"
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": "2022.23.0",
4
+ "JSBundleVersion": "2022.24.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": "e2a77335b26d1a321448e73eb7b733cdd0714cc8"
11
+ "GitRevision": "384e6ac71d317262e4518508066ab61322409ba2"
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.23.0",
6
+ "JSBundleVersion": "2022.24.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": "e2a77335b26d1a321448e73eb7b733cdd0714cc8"
13
+ "GitRevision": "384e6ac71d317262e4518508066ab61322409ba2"
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": "2022.23.0",
4
+ "JSBundleVersion": "2022.24.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": "e2a77335b26d1a321448e73eb7b733cdd0714cc8"
12
+ "GitRevision": "384e6ac71d317262e4518508066ab61322409ba2"
13
13
  }
@@ -68,19 +68,26 @@ JSClass("JSAttributedString", JSObject, {
68
68
  // TODO:
69
69
  return JSAttributedString.AttributeDecoder.skip(value);
70
70
  case JSAttributedString.Attribute.maskCharacter:
71
+ case JSAttributedString.Attribute.paragraphStyleName:
71
72
  return JSAttributedString.AttributeDecoder.string(value);
72
73
  case JSAttributedString.Attribute.bold:
73
74
  case JSAttributedString.Attribute.italic:
74
75
  case JSAttributedString.Attribute.underline:
75
76
  case JSAttributedString.Attribute.strike:
76
77
  return JSAttributedString.AttributeDecoder.boolean(value);
77
- case JSAttributedString.Attribute.lineHeight:
78
+ case JSAttributedString.Attribute.lineHeightMultiple:
78
79
  case JSAttributedString.Attribute.lineSpacing:
80
+ case JSAttributedString.Attribute.paragraphSpacing:
81
+ case JSAttributedString.Attribute.beforeParagraphSpacing:
82
+ case JSAttributedString.Attribute.firstLineHeadIndent:
83
+ case JSAttributedString.Attribute.headIndent:
84
+ case JSAttributedString.Attribute.tailIndent:
85
+ case JSAttributedString.Attribute.minimumLineHeight:
79
86
  return JSAttributedString.AttributeDecoder.number(value);
80
87
  case JSAttributedString.Attribute.textAlignment:
81
- // TODO: validate
88
+ return JSAttributedString.AttributeDecoder.enumValue(JSTextAlignment)(value);
82
89
  case JSAttributedString.Attribute.lineBreakMode:
83
- // TODO: validate
90
+ return JSAttributedString.AttributeDecoder.enumName(JSLineBreakMode)(value);
84
91
  default:
85
92
  return value;
86
93
  }
@@ -136,11 +143,18 @@ JSClass("JSAttributedString", JSObject, {
136
143
  case JSAttributedString.Attribute.italic:
137
144
  case JSAttributedString.Attribute.underline:
138
145
  case JSAttributedString.Attribute.strike:
139
- case JSAttributedString.Attribute.lineHeight:
146
+ case JSAttributedString.Attribute.lineHeightMultiple:
147
+ case JSAttributedString.Attribute.minimumLineHeight:
140
148
  case JSAttributedString.Attribute.lineSpacing:
149
+ case JSAttributedString.Attribute.paragraphSpacing:
150
+ case JSAttributedString.Attribute.beforeParagraphSpacing:
151
+ case JSAttributedString.Attribute.firstLineHeadIndent:
152
+ case JSAttributedString.Attribute.headIndent:
153
+ case JSAttributedString.Attribute.tailIndent:
141
154
  case JSAttributedString.Attribute.textAlignment:
142
155
  case JSAttributedString.Attribute.lineBreakMode:
143
156
  case JSAttributedString.Attribute.maskCharacter:
157
+ case JSAttributedString.Attribute.paragraphStyleName:
144
158
  default:
145
159
  return value;
146
160
  }
@@ -332,6 +346,8 @@ JSClass("JSAttributedString", JSObject, {
332
346
  }
333
347
  this._fixRunsAtIndex(runIndex);
334
348
  this._fixRunsAtIndex(runRange.location);
349
+ this._fixParagraphAttributesAtIndex(range.location);
350
+ this._fixParagraphAttributesAtIndex(range.location + attributedString.string.length);
335
351
  },
336
352
 
337
353
  // MARK: - Attribute mutations
@@ -521,6 +537,44 @@ JSClass("JSAttributedString", JSObject, {
521
537
  }
522
538
  },
523
539
 
540
+ _fixParagraphAttributesAtIndex: function(index){
541
+ if (index >= this._string.length){
542
+ return;
543
+ }
544
+ var paragraphRange = this._string.rangeForParagraphAtIndex(index);
545
+ var runIndex = this._runIndexForStringIndex(paragraphRange.location);
546
+ var run = this._runs[runIndex];
547
+ var paragraphAttributes = run.attributes;
548
+ var copy;
549
+ var i, l;
550
+ var attribute;
551
+ var value;
552
+ while (run.range.end < paragraphRange.end && runIndex < this._runs.length){
553
+ run = this._runs[runIndex];
554
+ if (!run.containsEqualParagraphAttributes(paragraphAttributes)){
555
+ if (run.range.end > paragraphRange.end){
556
+ copy = JSAttributedStringRun(JSRange(paragraphRange.end, run.range.end - paragraphRange.end), run.attributes);
557
+ this._runs.splice(runIndex + 1, 0, copy);
558
+ run.range.length -= copy.range.length;
559
+ }
560
+ for (i = 0, l = JSAttributedString.paragraphAttributes.length; i < l; ++i){
561
+ attribute = JSAttributedString.paragraphAttributes[i];
562
+ if (attribute in paragraphAttributes){
563
+ run.attributes[attribute] = paragraphAttributes[attribute];
564
+ }else{
565
+ delete run.attributes[attribute];
566
+ }
567
+ }
568
+ if (this._runs[runIndex - 1].onlyContainsEqualAttributes(run.attributes)){
569
+ this._runs[runIndex - 1].range.length += run.range.length;
570
+ this._runs.splice(runIndex, 1);
571
+ --runIndex;
572
+ }
573
+ }
574
+ ++runIndex;
575
+ }
576
+ },
577
+
524
578
  _rangeOfRunsPreparedForChangeInStringRange: function(range){
525
579
  var firstRunIndex = this._splitRunAtIndex(range.location);
526
580
  if (range.length > 0){
@@ -591,15 +645,38 @@ JSAttributedString.Attribute = {
591
645
  underline: "underline",
592
646
  strike: "strike",
593
647
  attachment: "attachment",
594
- lineHeight: "lineHeight",
595
- lineSpacing: "lineSpacing",
596
- textAlignment: "textAlignment",
597
- lineBreakMode: "lineBreakMode",
598
648
  maskCharacter: "maskCharacter",
599
649
  cursor: "cursor",
600
- link: "link"
650
+ link: "link",
651
+
652
+ // Paragraph
653
+ paragraphStyleName: "paragraphStyleName",
654
+ textAlignment: "textAlignment",
655
+ lineBreakMode: "lineBreakMode",
656
+ minimumLineHeight: "minimumLineHeight",
657
+ lineHeightMultiple: "lineHeightMultiple",
658
+ lineSpacing: "lineSpacing",
659
+ paragraphSpacing: "paragraphSpacing",
660
+ beforeParagraphSpacing: "beforeParagraphSpacing",
661
+ firstLineHeadIndent: "firstLineHeadIndent",
662
+ headIndent: "headIndent",
663
+ tailIndent: "tailIndent",
601
664
  };
602
665
 
666
+ JSAttributedString.paragraphAttributes = [
667
+ JSAttributedString.Attribute.paragraphStyleName,
668
+ JSAttributedString.Attribute.textAlignment,
669
+ JSAttributedString.Attribute.lineBreakMode,
670
+ JSAttributedString.Attribute.minimumLineHeight,
671
+ JSAttributedString.Attribute.lineHeightMultiple,
672
+ JSAttributedString.Attribute.lineSpacing,
673
+ JSAttributedString.Attribute.paragraphSpacing,
674
+ JSAttributedString.Attribute.beforeParagraphSpacing,
675
+ JSAttributedString.Attribute.firstLineHeadIndent,
676
+ JSAttributedString.Attribute.headIndent,
677
+ JSAttributedString.Attribute.tailIndent
678
+ ];
679
+
603
680
  JSAttributedString.AttributeEncoder = {
604
681
  skip: function(value){ return undefined; },
605
682
  identity: function(value){ return value; },
@@ -609,6 +686,15 @@ JSAttributedString.AttributeEncoder = {
609
686
  url: function(value){ return value.encodedString; },
610
687
  font: function(value){ return value.dictionaryRepresentation(); },
611
688
  color: function(value){ return value.dictionaryRepresentation(); },
689
+ enumName: function(obj){
690
+ return function(value){
691
+ for (var name in obj){
692
+ if (obj[name] === value){
693
+ return name;
694
+ }
695
+ }
696
+ };
697
+ }
612
698
  };
613
699
 
614
700
  JSAttributedString.AttributeDecoder = {
@@ -623,6 +709,20 @@ JSAttributedString.AttributeDecoder = {
623
709
  boolean: function(value){ return typeof(value) === "boolean" ? value : undefined; },
624
710
  number: function(value){ return typeof(value) === "number" ? value : undefined; },
625
711
  string: function(value){ return typeof(value) === "string" ? value : undefined; },
712
+ enumName: function(obj){
713
+ return function(value){
714
+ return obj[value];
715
+ };
716
+ },
717
+ enumValue: function(obj){
718
+ return function(value){
719
+ for (var name in obj){
720
+ if (obj[name] === value){
721
+ return value;
722
+ }
723
+ }
724
+ };
725
+ }
626
726
  };
627
727
 
628
728
  JSAttributedString.SpecialCharacter = {
@@ -694,6 +794,35 @@ JSAttributedStringRun.prototype = {
694
794
  return true;
695
795
  },
696
796
 
797
+ containsEqualParagraphAttributes: function(attributes){
798
+ var attribute;
799
+ var a, b;
800
+ for (var i = 0, l = JSAttributedString.paragraphAttributes.length; i < l; ++i){
801
+ attribute = JSAttributedString.paragraphAttributes[i];
802
+ a = attributes[attribute];
803
+ b = this.attributes[attribute];
804
+ if (a === undefined){
805
+ if (!!b){
806
+ return false;
807
+ }
808
+ }else if (a === null){
809
+ if (b !== null && b !== undefined){
810
+ return false;
811
+ }
812
+ }else if (a.isEqual){
813
+ if (b === null || b === undefined){
814
+ return false;
815
+ }
816
+ if (!a.isEqual(b)){
817
+ return false;
818
+ }
819
+ }else if (a != b){
820
+ return false;
821
+ }
822
+ }
823
+ return true;
824
+ }
825
+
697
826
  };
698
827
 
699
828
  var JSAttributedStringRunIterator = function(attributedString, startIndex){
@@ -764,7 +893,7 @@ Object.defineProperties(JSAttributedStringRunIterator.prototype, {
764
893
  return null;
765
894
  }
766
895
  var run = this._attributedString._runs[this._runIndex];
767
- if (run.range.length === 1 && this._attributedString.charCodeAt(run.range.location) === JSAttributedString.SpecialCharacter.attachment){
896
+ if (run.range.length === 1 && this._attributedString.string.charCodeAt(run.range.location) === JSAttributedString.SpecialCharacter.attachment){
768
897
  return run.attributes[JSAttributedString.Attribute.attachment];
769
898
  }
770
899
  return null;
@@ -0,0 +1,71 @@
1
+ // #import "JSObject.js"
2
+ // #import "CoreTypes.js"
3
+ "use strict";
4
+
5
+ JSClass("JSParagraphStyle", JSObject, {
6
+
7
+ textAlignment: JSTextAlignment.left,
8
+ lineBreakMode: JSLineBreakMode.truncateTail,
9
+ lineSpacing: 0,
10
+ minimumLineHeight: 0,
11
+ lineHeightMultiple: 0,
12
+ paragraphSpacing: 0,
13
+ beforeParagraphSpacing: 0,
14
+ firstLineHeadIndent: 0,
15
+ headIndent: 0,
16
+ tailIndent: 0,
17
+
18
+ init: function(){
19
+ },
20
+
21
+ styleWithAttributes: function(attributes){
22
+ var style = this.copy();
23
+ if (attributes.textAlignment !== undefined){
24
+ style.textAlignment = attributes.textAlignment;
25
+ }
26
+ if (attributes.lineBreakMode !== undefined){
27
+ style.lineBreakMode = attributes.lineBreakMode;
28
+ }
29
+ if (attributes.lineSpacing !== undefined){
30
+ style.lineSpacing = attributes.lineSpacing;
31
+ }
32
+ if (attributes.minimumLineHeight !== undefined){
33
+ style.minimumLineHeight = attributes.minimumLineHeight;
34
+ }
35
+ if (attributes.lineHeightMultiple !== undefined){
36
+ style.lineHeightMultiple = attributes.lineHeightMultiple;
37
+ }
38
+ if (attributes.paragraphSpacing !== undefined){
39
+ style.paragraphSpacing = attributes.paragraphSpacing;
40
+ }
41
+ if (attributes.beforeParagraphSpacing !== undefined){
42
+ style.beforeParagraphSpacing = attributes.beforeParagraphSpacing;
43
+ }
44
+ if (attributes.firstLineHeadIndent !== undefined){
45
+ style.firstLineHeadIndent = attributes.firstLineHeadIndent;
46
+ }
47
+ if (attributes.headIndent !== undefined){
48
+ style.headIndent = attributes.headIndent;
49
+ }
50
+ if (attributes.tailIndent !== undefined){
51
+ style.tailIndent = attributes.tailIndent;
52
+ }
53
+ return style;
54
+ },
55
+
56
+ copy: function(){
57
+ var style = JSParagraphStyle.init();
58
+ style.textAlignment = this.textAlignment;
59
+ style.lineBreakMode = this.lineBreakMode;
60
+ style.lineSpacing = this.lineSpacing;
61
+ style.minimumLineHeight = this.minimumLineHeight;
62
+ style.lineHeightMultiple = this.lineHeightMultiple;
63
+ style.paragraphSpacing = this.paragraphSpacing;
64
+ style.beforeParagraphSpacing = this.beforeParagraphSpacing;
65
+ style.firstLineHeadIndent = this.firstLineHeadIndent;
66
+ style.headIndent = this.headIndent;
67
+ style.tailIndent = this.tailIndent;
68
+ return style;
69
+ }
70
+
71
+ });
@@ -32,7 +32,7 @@ JSClass("JSTextAttachment", JSObject, {
32
32
  this._image = image;
33
33
  var ratio = image.size.width / image.size.height;
34
34
  this._size = JSSize(ratio * font.displayLineHeight, font.displayLineHeight);
35
- this.baselineAdjustment = font.displayDescender;
35
+ this.baselineAdjustment = -font.displayDescender;
36
36
  },
37
37
 
38
38
  initWithImage: function(image, size){
@@ -21,37 +21,13 @@
21
21
 
22
22
  (function(){
23
23
 
24
- var JSTextContainerAttributeProperty = function(){
25
- if (this === undefined){
26
- return new JSTextContainerAttributeProperty();
27
- }
28
- };
29
-
30
- JSTextContainerAttributeProperty.prototype = Object.create(JSCustomProperty.prototype);
31
-
32
- JSTextContainerAttributeProperty.prototype.define = function(C, key, extensions){
33
- Object.defineProperty(C.prototype, key, {
34
- configurable: false,
35
- enumerable: false,
36
- set: function JSTextContainer_setAttributeProperty(value){
37
- this.framesetter.attributes[key] = value;
38
- this._notifyLayoutManager();
39
- },
40
- get: function JSTextContainer_getAttributeProperty(){
41
- return this.framesetter.attributes[key];
42
- }
43
- });
44
- };
24
+ var logger = JSLog("foundation", "text");
45
25
 
46
26
  JSClass("JSTextContainer", JSObject, {
47
27
 
48
28
  origin: JSDynamicProperty('_origin', JSPoint.Zero),
49
29
  size: JSDynamicProperty('_size', null),
50
30
  range: JSReadOnlyProperty(),
51
- lineBreakMode: JSTextContainerAttributeProperty(),
52
- textAlignment: JSTextContainerAttributeProperty(),
53
- lineSpacing: JSTextContainerAttributeProperty(),
54
- minimumLineHeight: JSTextContainerAttributeProperty(),
55
31
  textLayoutManager: JSDynamicProperty('_textLayoutManager', null),
56
32
  maximumNumberOfLines: JSDynamicProperty('_maximumNumberOfLines', 0),
57
33
  framesetter: null,
@@ -83,10 +59,10 @@ JSClass("JSTextContainer", JSObject, {
83
59
  // If we are a single line label and we have all of the string, we *may not* need to do a new layout
84
60
  if (this._maximumNumberOfLines == 1 && this._textFrame.range.location === 0 && this._textFrame.range.length >= this._textLayoutManager.textStorage.string.length){
85
61
  // If the new size can still fit the entire layout, then no need to do a new layout manager layout
86
- if (size.width >= this._textFrame.usedSize.width && size.height >= this._textFrame.usedSize.height){
62
+ if (size.width < Number.MAX_VALUE && size.height < Number.MAX_VALUE && size.width >= this._textFrame.usedSize.width && size.height >= this._textFrame.usedSize.height){
87
63
  // Text frame can do a shortcut update by trimming excess size without affecting truncation
88
64
  shouldNotify = false;
89
- this._textFrame.adjustSize(size);
65
+ this.framesetter._resizeFrame(this._textFrame, size);
90
66
  }
91
67
  }
92
68
  if (shouldNotify){
@@ -110,6 +86,7 @@ JSClass("JSTextContainer", JSObject, {
110
86
 
111
87
  createTextFrame: function(attributedString, range){
112
88
  this.framesetter.attributedString = attributedString;
89
+ this.framesetter.defaultParagraphStyle = this._textLayoutManager.defaultParagraphStyle;
113
90
  this._textFrame = this.framesetter.createFrame(this.size, range, this._maximumNumberOfLines);
114
91
  },
115
92
 
@@ -125,7 +102,7 @@ JSClass("JSTextContainer", JSObject, {
125
102
  rectForCharacterAtIndex: function(index, useLineHeight){
126
103
  var line = this.lineForCharacterAtIndex(index);
127
104
  if (line !== null){
128
- var rect = line.rectForCharacterAtIndex(index - (line.range.location - this._textFrame.range.location));
105
+ var rect = line.rectForCharacterAtIndex(index);
129
106
  if (useLineHeight){
130
107
  rect.origin.y = line.origin.y;
131
108
  rect.size.height = line.size.height;
@@ -167,7 +144,57 @@ JSClass("JSTextContainer", JSObject, {
167
144
  if (this._textLayoutManager !== null){
168
145
  this._textLayoutManager.setNeedsLayout();
169
146
  }
170
- }
147
+ },
148
+
149
+ // MARK: - Deprecated
150
+
151
+ lineBreakMode: JSDynamicProperty(),
152
+
153
+ getLineBreakMode: function(){
154
+ logger.warn("JSTextContainer.lineBreakMode is deprecated");
155
+ return this._textLayoutManager.defaultParagraphStyle.lineBreakMode;
156
+ },
157
+
158
+ setLineBreakMode: function(lineBreakMode){
159
+ logger.warn("JSTextContainer.lineBreakMode is deprecated");
160
+ this._textLayoutManager.defaultParagraphStyle = this._textLayoutManager.defaultParagraphStyle.styleWithAttributes({lineBreakMode: lineBreakMode});
161
+ },
162
+
163
+ textAlignment: JSDynamicProperty(),
164
+
165
+ getTextAlignment: function(){
166
+ logger.warn("JSTextContainer.textAlignment is deprecated");
167
+ return this._textLayoutManager.defaultParagraphStyle.textAlignment;
168
+ },
169
+
170
+ setTextAlignment: function(textAlignment){
171
+ logger.warn("JSTextContainer.textAlignment is deprecated");
172
+ this._textLayoutManager.defaultParagraphStyle = this._textLayoutManager.defaultParagraphStyle.styleWithAttributes({textAlignment: textAlignment});
173
+ },
174
+
175
+ lineSpacing: JSDynamicProperty(),
176
+
177
+ getLineSpacing: function(){
178
+ logger.warn("JSTextContainer.lineSpacing is deprecated");
179
+ return this._textLayoutManager.defaultParagraphStyle.lineSpacing;
180
+ },
181
+
182
+ setLineSpacing: function(lineSpacing){
183
+ logger.warn("JSTextContainer.lineSpacing is deprecated");
184
+ this._textLayoutManager.defaultParagraphStyle = this._textLayoutManager.defaultParagraphStyle.styleWithAttributes({lineSpacing: lineSpacing});
185
+ },
186
+
187
+ minimumLineHeight: JSDynamicProperty(),
188
+
189
+ getMinimumLineHeight: function(){
190
+ logger.warn("JSTextContainer.minimumLineHeight is deprecated");
191
+ return this._textLayoutManager.defaultParagraphStyle.minimumLineHeight;
192
+ },
193
+
194
+ setMinimumLineHeight: function(minimumLineHeight){
195
+ logger.warn("JSTextContainer.minimumLineHeight is deprecated");
196
+ this._textLayoutManager.defaultParagraphStyle = this._textLayoutManager.defaultParagraphStyle.styleWithAttributes({minimumLineHeight: minimumLineHeight});
197
+ },
171
198
 
172
199
  });
173
200
 
@@ -25,9 +25,8 @@ JSClass("JSTextFrame", JSObject, {
25
25
  usedSize: JSReadOnlyProperty('_usedSize', null),
26
26
  range: JSReadOnlyProperty('_range', null),
27
27
  lines: JSReadOnlyProperty('_lines', null),
28
- _alignment: JSTextAlignment.left,
29
28
 
30
- initWithLines: function(lines, size, attributes){
29
+ initWithLines: function(lines, size){
31
30
  if (lines.length > 0){
32
31
  this._range = JSRange(lines[0].range.location, lines[lines.length - 1].range.end - lines[0].range.location);
33
32
  }else{
@@ -52,35 +51,6 @@ JSClass("JSTextFrame", JSObject, {
52
51
  if (this._size.height === 0 || this._size.height === Number.MAX_VALUE){
53
52
  this._size.height = y;
54
53
  }
55
- this._alignment = attributes.textAlignment;
56
- this._alignLines();
57
- },
58
-
59
- adjustSize: function(newSize){
60
- if (newSize.width < this._usedSize.width || newSize.height < this._usedSize.height){
61
- throw new Error("Cannot adjust text frame to smaller than its used size");
62
- }
63
- this._size = JSSize(newSize);
64
- this._alignLines();
65
- },
66
-
67
- _alignLines: function(){
68
- var i, l;
69
- var line;
70
- switch (this._alignment){
71
- case JSTextAlignment.center:
72
- for (i = 0, l = this.lines.length; i < l; ++i){
73
- line = this.lines[i];
74
- line.origin.x = (this._size.width - line.size.width + line.trailingWhitespaceWidth) / 2.0;
75
- }
76
- break;
77
- case JSTextAlignment.right:
78
- for (i = 0, l = this.lines.length; i < l; ++i){
79
- line = this.lines[i];
80
- line.origin.x = (this._size.width - line.size.width + line.trailingWhitespaceWidth);
81
- }
82
- break;
83
- }
84
54
  },
85
55
 
86
56
  drawInContextAtPoint: function(context, point){
@@ -107,7 +77,7 @@ JSClass("JSTextFrame", JSObject, {
107
77
  while (min < max){
108
78
  mid = Math.floor(min + (max - min) / 2);
109
79
  line = this._lines[mid];
110
- i = line.range.location - this.range.location;
80
+ i = line.range.location;
111
81
  l = line.range.length;
112
82
  if (index < i){
113
83
  max = mid;