@nativescript-community/text 1.5.17 → 1.5.19
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/index-common.d.ts +1 -0
- package/index-common.js +39 -106
- package/index-common.js.map +1 -1
- package/index.android.d.ts +1 -1
- package/index.android.js +140 -160
- package/index.android.js.map +1 -1
- package/index.ios.d.ts +1 -0
- package/index.ios.js +14 -21
- package/index.ios.js.map +1 -1
- package/package.json +2 -2
- package/platforms/android/include.gradle +3 -0
- package/platforms/android/java/com/nativescript/text/Font.java +22 -9
- package/platforms/android/java/com/nativescript/text/HtmlToSpannedConverter.java +7 -4
- package/platforms/android/java/com/nativescript/text/TextView.java +28 -0
- package/platforms/android/java/com/nativescript/text/URLSpanClickListener.java +7 -0
- package/platforms/android/java/com/nativescript/text/URLSpanNoUnderline.java +21 -6
- package/platforms/android/native-api-usage.json +3 -1
- package/platforms/ios/src/NSTextUtils.swift +297 -0
- package/typings/android.d.ts +24 -2
- package/typings/ios.d.ts +14 -0
- package/platforms/ios/src/Info.plist +0 -0
- package/platforms/ios/src/NSTextModule.h +0 -1
- package/platforms/ios/src/NSTextUtils.h +0 -4
- package/platforms/ios/src/NSTextUtils.mm +0 -203
- package/platforms/ios/src/module.modulemap +0 -5
@@ -0,0 +1,297 @@
|
|
1
|
+
import CoreFoundation
|
2
|
+
import UIKit
|
3
|
+
import CoreGraphics
|
4
|
+
|
5
|
+
@objcMembers
|
6
|
+
@objc(NSTextUtils)
|
7
|
+
class NSTextUtils: NSObject {
|
8
|
+
class func setTextDecorationAndTransformOn(view:UIView!, text:String!, textDecoration:String!, letterSpacing:CGFloat, lineHeight:CGFloat, color:UIColor!) {
|
9
|
+
let attrDict:NSMutableDictionary! = NSMutableDictionary()
|
10
|
+
var paragraphStyle:NSMutableParagraphStyle! = nil
|
11
|
+
let isTextType:Bool = (view is UITextField) || (view is UITextView) || (view is UILabel) || (view is UIButton)
|
12
|
+
let isTextView:Bool = (view is UITextView)
|
13
|
+
|
14
|
+
if textDecoration.contains("underline") {
|
15
|
+
attrDict[NSAttributedString.Key.underlineStyle] = (NSUnderlineStyle.single)
|
16
|
+
}
|
17
|
+
|
18
|
+
if textDecoration.contains("line-through") {
|
19
|
+
attrDict[NSAttributedString.Key.strikethroughStyle] = (NSUnderlineStyle.single)
|
20
|
+
}
|
21
|
+
|
22
|
+
if letterSpacing != 0 && isTextType && (view as! UILabel).font != nil {
|
23
|
+
let kern:NSNumber! = NSNumber.init(value: letterSpacing * (view as! UILabel).font.pointSize)
|
24
|
+
attrDict[NSAttributedString.Key.kern] = kern
|
25
|
+
}
|
26
|
+
var fLineHeight = lineHeight
|
27
|
+
if fLineHeight >= 0 {
|
28
|
+
if fLineHeight == 0 {
|
29
|
+
fLineHeight = 0.00001
|
30
|
+
}
|
31
|
+
if paragraphStyle == nil {
|
32
|
+
paragraphStyle = NSMutableParagraphStyle()
|
33
|
+
}
|
34
|
+
paragraphStyle.minimumLineHeight = fLineHeight
|
35
|
+
paragraphStyle.maximumLineHeight = fLineHeight
|
36
|
+
// make sure a possible previously set text alignment setting is not lost when line height is specified
|
37
|
+
|
38
|
+
|
39
|
+
}
|
40
|
+
if (paragraphStyle != nil) {
|
41
|
+
if (view is UIButton) {
|
42
|
+
paragraphStyle.alignment = (view as! UIButton).titleLabel!.textAlignment
|
43
|
+
} else {
|
44
|
+
paragraphStyle.alignment = (view as! UILabel).textAlignment
|
45
|
+
}
|
46
|
+
if (view is UILabel) {
|
47
|
+
// make sure a possible previously set line break mode is not lost when line height is specified
|
48
|
+
paragraphStyle.lineBreakMode = (view as! UILabel).lineBreakMode
|
49
|
+
}
|
50
|
+
attrDict[NSAttributedString.Key.paragraphStyle] = paragraphStyle
|
51
|
+
}
|
52
|
+
|
53
|
+
if attrDict.count > 0 {
|
54
|
+
if isTextView && ((view as! UITextView).font != nil) {
|
55
|
+
// UITextView's font seems to change inside.
|
56
|
+
attrDict[NSAttributedString.Key.font] = (view as! UITextView).font
|
57
|
+
}
|
58
|
+
|
59
|
+
if color != nil {
|
60
|
+
attrDict[NSAttributedString.Key.foregroundColor] = color
|
61
|
+
}
|
62
|
+
|
63
|
+
let result:NSMutableAttributedString! = NSMutableAttributedString(string:text)
|
64
|
+
result.setAttributes((attrDict as! [NSAttributedString.Key : Any]), range:NSRange(location: 0, length: text.count))
|
65
|
+
|
66
|
+
if (view is UIButton) {
|
67
|
+
(view as! UIButton).setAttributedTitle(result, for:UIControl.State.normal)
|
68
|
+
}
|
69
|
+
else if(view is UILabel) {
|
70
|
+
(view as! UILabel).attributedText = result
|
71
|
+
} else if(view is UITextView) {
|
72
|
+
(view as! UITextView).attributedText = result
|
73
|
+
}
|
74
|
+
} else {
|
75
|
+
if (view is UIButton) {
|
76
|
+
// Clear attributedText or title won't be affected.
|
77
|
+
(view as! UIButton).setAttributedTitle(nil, for:UIControl.State.normal)
|
78
|
+
(view as! UIButton).setTitle(text, for:UIControl.State.normal)
|
79
|
+
} else if(view is UILabel) {
|
80
|
+
// Clear attributedText or text won't be affected.
|
81
|
+
(view as! UILabel).attributedText = nil
|
82
|
+
(view as! UILabel).text = text
|
83
|
+
} else if(view is UITextView) {
|
84
|
+
// Clear attributedText or text won't be affected.
|
85
|
+
(view as! UITextView).attributedText = nil
|
86
|
+
(view as! UITextView).text = text
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
class func computeBaseLineOffset(align:String!, fontAscent:Float, fontDescent:Float, fontBottom:Float, fontTop:Float, fontSize:Float, maxFontSize:Float) -> Float {
|
91
|
+
var result:Float = 0
|
92
|
+
if (align == "top") {
|
93
|
+
result = -maxFontSize - fontBottom - fontTop
|
94
|
+
} else if (align == "bottom") {
|
95
|
+
result = fontBottom
|
96
|
+
} else if (align == "text-top") {
|
97
|
+
result = -maxFontSize - fontDescent - fontAscent
|
98
|
+
} else if (align == "text-bottom") {
|
99
|
+
result = fontBottom - fontDescent
|
100
|
+
} else if (align == "middle") || (align == "center") {
|
101
|
+
result = (fontAscent - fontDescent) / 2 - fontAscent - maxFontSize / 2
|
102
|
+
} else if (align == "super") {
|
103
|
+
result = -(maxFontSize - fontSize)
|
104
|
+
} else if (align == "sub") {
|
105
|
+
result = 0
|
106
|
+
}
|
107
|
+
return result
|
108
|
+
}
|
109
|
+
|
110
|
+
class func createNativeHTMLAttributedString(_ data:NSDictionary!) -> NSMutableAttributedString! {
|
111
|
+
do {
|
112
|
+
// if (!attributedString) {
|
113
|
+
// NSData* data = [nsString dataUsingEncoding: NSUnicodeStringEncoding allowLossyConversion: YES];
|
114
|
+
// attributedString = [[NSMutableAttributedString alloc] initWithHTML:data
|
115
|
+
// }
|
116
|
+
let htmlString:String! = data.object(forKey: "htmlString") as? String
|
117
|
+
let dic:NSDictionary! = [NSAttributedString.DocumentAttributeKey.documentType: NSAttributedString.DocumentType.html,
|
118
|
+
NSAttributedString.DocumentReadingOptionKey.characterEncoding: NSUTF8StringEncoding]
|
119
|
+
let attrText:NSMutableAttributedString! = try NSMutableAttributedString(data:htmlString.data(using: String.Encoding(rawValue: NSUTF8StringEncoding), allowLossyConversion: false)!, options:dic as! [NSAttributedString.DocumentReadingOptionKey : Any], documentAttributes:nil)
|
120
|
+
|
121
|
+
let fullRange:NSRange = NSRange(location: 0, length: attrText.length)
|
122
|
+
let linkColor:UIColor! = data.object(forKey:"linkColor") as? UIColor
|
123
|
+
let useCustomLinkTag:NSNumber! = data.object(forKey:"useCustomLinkTag") as? NSNumber
|
124
|
+
if (linkColor != nil) || useCustomLinkTag.boolValue {
|
125
|
+
// if linkColor is used for non UITextView we cant use NSLinkAttributeName
|
126
|
+
// as it will force the rendered color
|
127
|
+
attrText.enumerateAttribute(NSAttributedString.Key.link, in: fullRange) { value, range, stop in
|
128
|
+
if (value != nil) {
|
129
|
+
let attributes:NSMutableDictionary! = NSMutableDictionary(dictionary:attrText.attributes(at: range.location, longestEffectiveRange:nil, in:range))
|
130
|
+
var sValue:String! = nil
|
131
|
+
if (value is NSURL) {
|
132
|
+
sValue = (value as! NSURL).absoluteString
|
133
|
+
} else {
|
134
|
+
sValue = value as? String
|
135
|
+
}
|
136
|
+
if sValue.hasPrefix("applewebdata://") {
|
137
|
+
let index = sValue.lastIndex(of: "/")
|
138
|
+
attributes.setObject(sValue[index!...], forKey:"CustomLinkAttribute" as NSCopying)
|
139
|
+
|
140
|
+
} else {
|
141
|
+
attributes.setObject(sValue, forKey:"CustomLinkAttribute" as NSCopying)
|
142
|
+
}
|
143
|
+
attributes.removeObject(forKey: NSAttributedString.Key.link)
|
144
|
+
attrText.setAttributes(attributes as? [NSAttributedString.Key : Any], range:range)
|
145
|
+
}
|
146
|
+
}
|
147
|
+
}
|
148
|
+
// }
|
149
|
+
let autoFontSizeEnabled:NSNumber! = data.object(forKey:"autoFontSizeEnabled") as? NSNumber
|
150
|
+
if autoFontSizeEnabled.boolValue {
|
151
|
+
attrText.enumerateAttribute(NSAttributedString.Key.font, in:fullRange ){ value, range, stop in
|
152
|
+
if ((value) != nil){
|
153
|
+
let fontValue: UIFont = value as! UIFont;
|
154
|
+
attrText.addAttribute(NSAttributedString.Key(rawValue: "OriginalFontSize") , value:fontValue.pointSize, range:range)
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
let letterSpacing:NSNumber! = data.object(forKey:"letterSpacing") as? NSNumber
|
160
|
+
let fontSize:NSNumber! = data.object(forKey:"fontSize") as? NSNumber
|
161
|
+
if (letterSpacing != nil) && letterSpacing.floatValue != 0 {
|
162
|
+
attrText.addAttribute(NSAttributedString.Key.kern, value:letterSpacing.floatValue * fontSize.floatValue, range:fullRange)
|
163
|
+
}
|
164
|
+
var paragraphStyle:NSMutableParagraphStyle! = nil
|
165
|
+
let textAlignment:NSNumber! = data.object(forKey:"textAlignment") as? NSNumber
|
166
|
+
let createParagraphStyle:()->Void = {
|
167
|
+
if (paragraphStyle == nil) {
|
168
|
+
paragraphStyle = NSMutableParagraphStyle()
|
169
|
+
if (textAlignment != nil) {
|
170
|
+
paragraphStyle.alignment = NSTextAlignment(rawValue: textAlignment.intValue)!
|
171
|
+
|
172
|
+
}
|
173
|
+
}
|
174
|
+
}
|
175
|
+
if (textAlignment != nil) {
|
176
|
+
createParagraphStyle()
|
177
|
+
}
|
178
|
+
let lineBreak:NSNumber! = data.object(forKey:"lineBreak") as? NSNumber
|
179
|
+
if (lineBreak != nil) {
|
180
|
+
|
181
|
+
createParagraphStyle()
|
182
|
+
// make sure a possible previously set line break mode is not lost when line height is specified
|
183
|
+
paragraphStyle.lineBreakMode = NSLineBreakMode(rawValue: lineBreak.intValue)!
|
184
|
+
}
|
185
|
+
let lineHeight:NSNumber! = data.object(forKey:"lineHeight") as? NSNumber
|
186
|
+
if (lineHeight != nil) {
|
187
|
+
createParagraphStyle()
|
188
|
+
var fLineHeight:Float = lineHeight.floatValue
|
189
|
+
if fLineHeight == 0.0 {
|
190
|
+
fLineHeight = 0.00001
|
191
|
+
}
|
192
|
+
paragraphStyle.minimumLineHeight = CGFloat(fLineHeight)
|
193
|
+
paragraphStyle.maximumLineHeight = CGFloat(fLineHeight)
|
194
|
+
// make sure a possible previously set text alignment setting is not lost when line height is specified
|
195
|
+
// if (this.nativeTextViewProtected instanceof UILabel) {
|
196
|
+
// paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode;
|
197
|
+
// }
|
198
|
+
}
|
199
|
+
if (paragraphStyle != nil) {
|
200
|
+
attrText.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:fullRange)
|
201
|
+
}
|
202
|
+
return attrText
|
203
|
+
} catch {
|
204
|
+
return nil;
|
205
|
+
}
|
206
|
+
|
207
|
+
}
|
208
|
+
|
209
|
+
class func createNativeAttributedString(_ data:NSDictionary!) -> NSMutableAttributedString! {
|
210
|
+
let result:NSMutableAttributedString! = NSMutableAttributedString()
|
211
|
+
let details: [NSDictionary] = (data.object(forKey: "details") as! NSArray) as! [NSDictionary]
|
212
|
+
for spanDetails: NSDictionary in details {
|
213
|
+
let text = spanDetails.object(forKey: "text")
|
214
|
+
if text == nil {
|
215
|
+
continue
|
216
|
+
}
|
217
|
+
let attributes:NSMutableDictionary! = NSMutableDictionary()
|
218
|
+
let iosFont:UIFont! = spanDetails.object(forKey: "iosFont") as? UIFont
|
219
|
+
if (iosFont != nil) {
|
220
|
+
attributes.setObject(iosFont, forKey:NSAttributedString.Key.font as NSCopying)
|
221
|
+
}
|
222
|
+
let autoFontSizeEnabled:NSNumber! = spanDetails.object(forKey: "autoFontSizeEnabled") as? NSNumber
|
223
|
+
if autoFontSizeEnabled.boolValue {
|
224
|
+
attributes.setObject(spanDetails.object(forKey: "realFontSize")!, forKey:"OriginalFontSize" as NSCopying)
|
225
|
+
|
226
|
+
}
|
227
|
+
let verticalTextAlignment:String! = spanDetails.object(forKey: "verticalTextAlignment") as? String
|
228
|
+
if (verticalTextAlignment != nil) && (iosFont != nil) && !(verticalTextAlignment == "initial") && !(verticalTextAlignment == "stretch") {
|
229
|
+
let fontSize:NSNumber! = spanDetails.object(forKey: "fontSize") as? NSNumber
|
230
|
+
let ctFont:CTFont = iosFont
|
231
|
+
let ascent:CGFloat = CTFontGetAscent(ctFont)
|
232
|
+
let descent:CGFloat = CTFontGetDescent(ctFont)
|
233
|
+
let realMaxFontSize:NSNumber! = spanDetails.object(forKey: "realMaxFontSize") as? NSNumber
|
234
|
+
attributes.setObject(-computeBaseLineOffset(align: verticalTextAlignment, fontAscent: -Float(ascent), fontDescent: Float(descent), fontBottom: -Float(iosFont.descender), fontTop: -Float(iosFont.ascender), fontSize: (fontSize.floatValue), maxFontSize: (realMaxFontSize.floatValue)), forKey:NSAttributedString.Key.baselineOffset as NSCopying)
|
235
|
+
}
|
236
|
+
let color:UIColor! = spanDetails.object(forKey: "color") as? UIColor
|
237
|
+
if (color != nil) {
|
238
|
+
attributes.setObject(color, forKey:NSAttributedString.Key.foregroundColor as NSCopying)
|
239
|
+
|
240
|
+
}
|
241
|
+
let backgroundColor:UIColor! = spanDetails.object(forKey: "backgroundColor") as? UIColor
|
242
|
+
if (backgroundColor != nil) {
|
243
|
+
attributes.setObject(backgroundColor, forKey:NSAttributedString.Key.backgroundColor as NSCopying)
|
244
|
+
}
|
245
|
+
let letterSpacing:NSNumber! = spanDetails.object(forKey: "letterSpacing") as? NSNumber
|
246
|
+
if (iosFont != nil) && (letterSpacing != nil) {
|
247
|
+
attributes.setObject((letterSpacing.floatValue * Float(iosFont.pointSize)), forKey:NSAttributedString.Key.kern as NSCopying)
|
248
|
+
}
|
249
|
+
|
250
|
+
let tapIndex:NSNumber! = spanDetails.object(forKey: "tapIndex") as? NSNumber
|
251
|
+
if (tapIndex != nil) {
|
252
|
+
attributes.setObject(tapIndex, forKey:"CustomLinkAttribute" as NSCopying)
|
253
|
+
}
|
254
|
+
let lineHeight:NSNumber! = spanDetails.object(forKey: "lineHeight") as? NSNumber
|
255
|
+
let textAlignment:String! = spanDetails.object(forKey: "textAlignment") as? String
|
256
|
+
if (lineHeight != nil) || (textAlignment != nil) {
|
257
|
+
let paragraphStyle:NSMutableParagraphStyle! = NSMutableParagraphStyle()
|
258
|
+
if (textAlignment == "middle") || (textAlignment == "center") {
|
259
|
+
paragraphStyle.alignment = NSTextAlignment.center
|
260
|
+
} else if (textAlignment == "right") {
|
261
|
+
paragraphStyle.alignment = NSTextAlignment.right
|
262
|
+
} else {
|
263
|
+
paragraphStyle.alignment = NSTextAlignment.left
|
264
|
+
}
|
265
|
+
if (lineHeight != nil) {
|
266
|
+
var fLineHeight:CGFloat = CGFloat(lineHeight.floatValue)
|
267
|
+
if fLineHeight == 0.0 {
|
268
|
+
fLineHeight = 0.00001
|
269
|
+
}
|
270
|
+
paragraphStyle.maximumLineHeight = fLineHeight
|
271
|
+
paragraphStyle.minimumLineHeight = fLineHeight
|
272
|
+
}
|
273
|
+
attributes.setObject(paragraphStyle, forKey:NSAttributedString.Key.paragraphStyle as NSCopying as NSCopying)
|
274
|
+
}
|
275
|
+
let textDecoration:String! = spanDetails.object(forKey: "textDecoration") as? String
|
276
|
+
if (textDecoration != nil) {
|
277
|
+
let underline:Bool = textDecoration.contains("underline")
|
278
|
+
if underline {
|
279
|
+
attributes.setObject(underline, forKey:NSAttributedString.Key.underlineStyle as NSCopying)
|
280
|
+
}
|
281
|
+
let strikethrough:Bool = textDecoration.contains("line-through")
|
282
|
+
if strikethrough {
|
283
|
+
attributes.setObject(strikethrough, forKey:NSAttributedString.Key.strikethroughStyle as NSCopying)
|
284
|
+
}
|
285
|
+
}
|
286
|
+
if text is NSAttributedString {
|
287
|
+
let resultSpan:NSMutableAttributedString! = NSMutableAttributedString(attributedString:text as! NSAttributedString)
|
288
|
+
resultSpan.setAttributes(attributes as? [NSAttributedString.Key : Any], range:NSRange(location: 0, length: (text as! NSAttributedString).length)); result.append(resultSpan)
|
289
|
+
}
|
290
|
+
else if text is String {
|
291
|
+
result.append(NSMutableAttributedString(string:text as! String, attributes:attributes as? [NSAttributedString.Key : Any]))
|
292
|
+
|
293
|
+
}
|
294
|
+
}
|
295
|
+
return result
|
296
|
+
}
|
297
|
+
}
|
package/typings/android.d.ts
CHANGED
@@ -18,8 +18,21 @@ declare namespace com {
|
|
18
18
|
}
|
19
19
|
|
20
20
|
export class Font {
|
21
|
-
static stringBuilderFromHtmlString(
|
22
|
-
|
21
|
+
static stringBuilderFromHtmlString(
|
22
|
+
context: globalAndroid.content.Context,
|
23
|
+
fontPath: string,
|
24
|
+
parentFontFamily: string,
|
25
|
+
text: string,
|
26
|
+
disableLinkUnderline: boolean,
|
27
|
+
linkColor: android.graphics.Color
|
28
|
+
): globalAndroid.text.SpannableStringBuilder;
|
29
|
+
static stringBuilderFromFormattedString(
|
30
|
+
context: globalAndroid.content.Context,
|
31
|
+
fontPath: string,
|
32
|
+
parentFontFamily: string,
|
33
|
+
nativeString: string,
|
34
|
+
ssp: globalAndroid.text.SpannableStringBuilder
|
35
|
+
): any;
|
23
36
|
static createTypeface(
|
24
37
|
context: globalAndroid.content.Context,
|
25
38
|
fontFolder: string,
|
@@ -29,6 +42,15 @@ declare namespace com {
|
|
29
42
|
isItalic: boolean
|
30
43
|
): globalAndroid.graphics.Typeface;
|
31
44
|
}
|
45
|
+
export class URLSpanClickListener {
|
46
|
+
constructor(impl?: { onClick(span: android.text.style.URLSpan) });
|
47
|
+
onClick(span: android.text.style.URLSpan);
|
48
|
+
}
|
49
|
+
|
50
|
+
export class TextView extends androidx.appcompat.widget.AppCompatTextView {
|
51
|
+
urlSpanClickListener: URLSpanClickListener;
|
52
|
+
static attributedStringHasSpan(attributeString: android.text.Spannable, spanClass: sjava.lang.Class<any>): boolean;
|
53
|
+
}
|
32
54
|
}
|
33
55
|
}
|
34
56
|
}
|
package/typings/ios.d.ts
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
declare class NSTextUtils extends NSObject {
|
2
|
+
|
3
|
+
static alloc(): NSTextUtils; // inherited from NSObject
|
4
|
+
|
5
|
+
static computeBaseLineOffsetWithAlignFontAscentFontDescentFontBottomFontTopFontSizeMaxFontSize(align: string, fontAscent: number, fontDescent: number, fontBottom: number, fontTop: number, fontSize: number, maxFontSize: number): number;
|
6
|
+
|
7
|
+
static createNativeAttributedStringWithData(data: NSDictionary<any, any>): NSMutableAttributedString;
|
8
|
+
|
9
|
+
static createNativeHTMLAttributedStringWithData(data: NSDictionary<any, any>): NSMutableAttributedString;
|
10
|
+
|
11
|
+
static new(): NSTextUtils; // inherited from NSObject
|
12
|
+
|
13
|
+
static setTextDecorationAndTransformOnViewTextTextDecorationLetterSpacingLineHeightColor(view: UIView, text: string, textDecoration: string, letterSpacing: number, lineHeight: number, color: UIColor): void;
|
14
|
+
}
|
Binary file
|
@@ -1 +0,0 @@
|
|
1
|
-
#import "NSTextUtils.h"
|
@@ -1,203 +0,0 @@
|
|
1
|
-
#import "NSTextUtils.h"
|
2
|
-
#import <CoreText/CoreText.h>
|
3
|
-
|
4
|
-
@implementation NSTextUtils
|
5
|
-
CGFloat computeBaseLineOffset(NSString *align, CGFloat fontAscent, CGFloat fontDescent, CGFloat fontBottom, CGFloat fontTop, CGFloat fontSize, CGFloat maxFontSize) {
|
6
|
-
CGFloat result = 0;
|
7
|
-
if ([align isEqualToString:@"top"]) {
|
8
|
-
result = -maxFontSize - fontBottom - fontTop;
|
9
|
-
} else if ([align isEqualToString:@"bottom"]) {
|
10
|
-
result = fontBottom;
|
11
|
-
} else if ([align isEqualToString:@"text-top"]) {
|
12
|
-
result = -maxFontSize - fontDescent - fontAscent;
|
13
|
-
} else if ([align isEqualToString:@"text-bottom"]) {
|
14
|
-
result = fontBottom - fontDescent;
|
15
|
-
} else if ([align isEqualToString:@"middle"] || [align isEqualToString:@"center"]) {
|
16
|
-
result = (fontAscent - fontDescent) / 2 - fontAscent - maxFontSize / 2;
|
17
|
-
} else if ([align isEqualToString:@"super"]) {
|
18
|
-
result = -(maxFontSize - fontSize);
|
19
|
-
} else if ([align isEqualToString:@"sub"]) {
|
20
|
-
result = 0;
|
21
|
-
}
|
22
|
-
return result;
|
23
|
-
}
|
24
|
-
|
25
|
-
+(NSMutableAttributedString*)createNativeHTMLAttributedString:(NSDictionary*)data {
|
26
|
-
// if (!attributedString) {
|
27
|
-
// NSData* data = [nsString dataUsingEncoding: NSUnicodeStringEncoding allowLossyConversion: YES];
|
28
|
-
// attributedString = [[NSMutableAttributedString alloc] initWithHTML:data
|
29
|
-
// }
|
30
|
-
NSString* htmlString = [data objectForKey:@"htmlString"];
|
31
|
-
NSDictionary *dic = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
|
32
|
-
NSCharacterEncodingDocumentOption: @(NSUTF8StringEncoding)};
|
33
|
-
NSMutableAttributedString* attrText = [[NSMutableAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:dic documentAttributes:nil error:nil];
|
34
|
-
|
35
|
-
NSRange fullRange = NSMakeRange(0, [attrText length]);
|
36
|
-
UIColor* linkColor = [data objectForKey:@"linkColor"];
|
37
|
-
NSNumber* useCustomLinkTag = [data objectForKey:@"useCustomLinkTag"];
|
38
|
-
if (linkColor || [useCustomLinkTag boolValue]) {
|
39
|
-
// if linkColor is used for non UITextView we cant use NSLinkAttributeName
|
40
|
-
// as it will force the rendered color
|
41
|
-
[attrText enumerateAttribute:NSLinkAttributeName inRange:fullRange options:0 usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
42
|
-
if (value) {
|
43
|
-
NSMutableDictionary* attributes = [[NSMutableDictionary alloc] initWithDictionary:[attrText attributesAtIndex:range.location longestEffectiveRange:nil inRange:range ]];
|
44
|
-
NSString* sValue = nil;
|
45
|
-
if ([value isKindOfClass:[NSURL class]]) {
|
46
|
-
sValue = [(NSURL*)value absoluteString];
|
47
|
-
} else {
|
48
|
-
sValue = value;
|
49
|
-
}
|
50
|
-
if ([sValue hasPrefix:@"applewebdata://"]) {
|
51
|
-
NSRange range = [sValue rangeOfString:@"/" options:NSBackwardsSearch];
|
52
|
-
[attributes setObject:[sValue substringFromIndex:range.location+1] forKey:@"CustomLinkAttribute"];
|
53
|
-
|
54
|
-
} else {
|
55
|
-
[attributes setObject:sValue forKey:@"CustomLinkAttribute"];
|
56
|
-
}
|
57
|
-
[attributes removeObjectForKey:NSLinkAttributeName];
|
58
|
-
[attrText setAttributes:attributes range:range];
|
59
|
-
}
|
60
|
-
}];
|
61
|
-
}
|
62
|
-
// }
|
63
|
-
NSNumber* autoFontSizeEnabled = [data objectForKey:@"autoFontSizeEnabled"];
|
64
|
-
if ([autoFontSizeEnabled boolValue]) {
|
65
|
-
[attrText enumerateAttribute:NSFontAttributeName inRange:fullRange options:0 usingBlock:^(UIFont* _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
66
|
-
if (value) {
|
67
|
-
[attrText addAttribute:@"OriginalFontSize" value:[NSNumber numberWithFloat:[value pointSize]] range:range];
|
68
|
-
}
|
69
|
-
}];
|
70
|
-
}
|
71
|
-
|
72
|
-
NSNumber* letterSpacing = [data objectForKey:@"letterSpacing"];
|
73
|
-
NSNumber* fontSize = [data objectForKey:@"fontSize"];
|
74
|
-
if (letterSpacing && letterSpacing.floatValue != 0) {
|
75
|
-
[attrText addAttribute:NSKernAttributeName value:[NSNumber numberWithFloat:letterSpacing.floatValue * fontSize.floatValue] range:fullRange];
|
76
|
-
}
|
77
|
-
__block NSMutableParagraphStyle* paragraphStyle = nil;
|
78
|
-
NSNumber* textAlignment = [data objectForKey:@"textAlignment"];
|
79
|
-
void (^createParagraphStyle)(void) = ^{
|
80
|
-
if (!paragraphStyle) {
|
81
|
-
paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
82
|
-
if (textAlignment) {
|
83
|
-
paragraphStyle.alignment = (NSTextAlignment)textAlignment.integerValue;
|
84
|
-
|
85
|
-
}
|
86
|
-
}
|
87
|
-
};
|
88
|
-
if (textAlignment) {
|
89
|
-
createParagraphStyle();
|
90
|
-
}
|
91
|
-
NSNumber* lineBreak = [data objectForKey:@"lineBreak"];
|
92
|
-
if (lineBreak) {
|
93
|
-
|
94
|
-
createParagraphStyle();
|
95
|
-
// make sure a possible previously set line break mode is not lost when line height is specified
|
96
|
-
paragraphStyle.lineBreakMode = (NSLineBreakMode)lineBreak.integerValue;
|
97
|
-
}
|
98
|
-
NSNumber* lineHeight = [data objectForKey:@"lineHeight"];
|
99
|
-
if (lineHeight) {
|
100
|
-
createParagraphStyle();
|
101
|
-
CGFloat fLineHeight = [lineHeight floatValue];
|
102
|
-
if (fLineHeight == 0.0) {
|
103
|
-
fLineHeight = 0.00001;
|
104
|
-
}
|
105
|
-
paragraphStyle.minimumLineHeight = fLineHeight;
|
106
|
-
paragraphStyle.maximumLineHeight = fLineHeight;
|
107
|
-
// make sure a possible previously set text alignment setting is not lost when line height is specified
|
108
|
-
// if (this.nativeTextViewProtected instanceof UILabel) {
|
109
|
-
// paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode;
|
110
|
-
// }
|
111
|
-
}
|
112
|
-
if (paragraphStyle) {
|
113
|
-
[attrText addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:fullRange];
|
114
|
-
}
|
115
|
-
return attrText;
|
116
|
-
}
|
117
|
-
|
118
|
-
+(NSMutableAttributedString*)createNativeAttributedString:(NSDictionary*)data {
|
119
|
-
NSMutableAttributedString* result = [[NSMutableAttributedString alloc] init];
|
120
|
-
for (id spanDetails in [data objectForKey:@"details"]){
|
121
|
-
NSMutableDictionary* attributes = [[NSMutableDictionary alloc] init];
|
122
|
-
UIFont* iosFont = [spanDetails objectForKey:@"iosFont"];
|
123
|
-
if (iosFont) {
|
124
|
-
[attributes setObject:iosFont forKey:NSFontAttributeName];
|
125
|
-
}
|
126
|
-
NSNumber* autoFontSizeEnabled = [spanDetails objectForKey:@"autoFontSizeEnabled"];
|
127
|
-
if ([autoFontSizeEnabled boolValue]) {
|
128
|
-
[attributes setObject:[spanDetails objectForKey:@"realFontSize"] forKey:@"OriginalFontSize"];
|
129
|
-
|
130
|
-
}
|
131
|
-
NSString* verticalTextAlignment = [spanDetails objectForKey:@"verticalTextAlignment"];
|
132
|
-
if (verticalTextAlignment && iosFont && ![verticalTextAlignment isEqualToString:@"initial"] && ![verticalTextAlignment isEqualToString:@"stretch"]) {
|
133
|
-
NSNumber* fontSize = [spanDetails objectForKey:@"fontSize"];
|
134
|
-
CTFontRef ctFont = (__bridge CTFontRef)iosFont;
|
135
|
-
CGFloat ascent = CTFontGetAscent(ctFont);
|
136
|
-
CGFloat descent = CTFontGetDescent(ctFont);
|
137
|
-
NSNumber* realMaxFontSize = [spanDetails objectForKey:@"realMaxFontSize"];
|
138
|
-
[attributes setObject:[NSNumber numberWithFloat:-computeBaseLineOffset(verticalTextAlignment, -ascent, descent, -iosFont.descender, -iosFont.ascender, [fontSize floatValue], [realMaxFontSize floatValue])] forKey:NSBaselineOffsetAttributeName];
|
139
|
-
}
|
140
|
-
UIColor* color = [spanDetails objectForKey:@"color"];
|
141
|
-
if (color) {
|
142
|
-
[attributes setObject:color forKey:NSForegroundColorAttributeName];
|
143
|
-
|
144
|
-
}
|
145
|
-
UIColor* backgroundColor = [spanDetails objectForKey:@"backgroundColor"];
|
146
|
-
if (backgroundColor) {
|
147
|
-
[attributes setObject:backgroundColor forKey:NSBackgroundColorAttributeName];
|
148
|
-
}
|
149
|
-
NSNumber* letterSpacing = [spanDetails objectForKey:@"letterSpacing"];
|
150
|
-
if (iosFont && letterSpacing) {
|
151
|
-
[attributes setObject:[NSNumber numberWithFloat:(letterSpacing.floatValue * iosFont.pointSize)] forKey:NSKernAttributeName];
|
152
|
-
}
|
153
|
-
|
154
|
-
NSNumber* tapIndex = [spanDetails objectForKey:@"tapIndex"];
|
155
|
-
if (tapIndex) {
|
156
|
-
[attributes setObject:tapIndex forKey:@"CustomLinkAttribute"];
|
157
|
-
}
|
158
|
-
NSNumber* lineHeight = [spanDetails objectForKey:@"lineHeight"];
|
159
|
-
NSString* textAlignment = [spanDetails objectForKey:@"textAlignment"];
|
160
|
-
if (lineHeight || textAlignment) {
|
161
|
-
NSMutableParagraphStyle* paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
162
|
-
if ([textAlignment isEqualToString:@"middle"] || [textAlignment isEqualToString:@"center"]) {
|
163
|
-
paragraphStyle.alignment = NSTextAlignmentCenter;
|
164
|
-
} else if ([textAlignment isEqualToString:@"right"]) {
|
165
|
-
paragraphStyle.alignment = NSTextAlignmentRight;
|
166
|
-
} else {
|
167
|
-
paragraphStyle.alignment = NSTextAlignmentLeft;
|
168
|
-
}
|
169
|
-
if (lineHeight) {
|
170
|
-
CGFloat fLineHeight = [lineHeight floatValue];
|
171
|
-
if (fLineHeight == 0.0) {
|
172
|
-
fLineHeight = 0.00001;
|
173
|
-
}
|
174
|
-
paragraphStyle.maximumLineHeight = fLineHeight;
|
175
|
-
paragraphStyle.minimumLineHeight = fLineHeight;
|
176
|
-
}
|
177
|
-
[attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
|
178
|
-
}
|
179
|
-
NSString* textDecoration = [spanDetails objectForKey:@"textDecoration"];
|
180
|
-
if (textDecoration) {
|
181
|
-
BOOL underline = [textDecoration containsString:@"underline" ];
|
182
|
-
if (underline) {
|
183
|
-
[attributes setObject:[NSNumber numberWithBool:underline] forKey:NSUnderlineStyleAttributeName];
|
184
|
-
}
|
185
|
-
BOOL strikethrough = [textDecoration containsString:@"line-through" ];
|
186
|
-
if (strikethrough) {
|
187
|
-
[attributes setObject:[NSNumber numberWithBool:strikethrough] forKey:NSStrikethroughStyleAttributeName];
|
188
|
-
}
|
189
|
-
}
|
190
|
-
id text = [spanDetails objectForKey:@"text"];
|
191
|
-
if (!([text isKindOfClass:[NSAttributedString class]])) {
|
192
|
-
[result appendAttributedString:[[NSMutableAttributedString alloc] initWithString:text attributes:attributes]];
|
193
|
-
}
|
194
|
-
else {
|
195
|
-
NSMutableAttributedString* resultSpan = [[NSMutableAttributedString alloc] initWithAttributedString:text];
|
196
|
-
[resultSpan setAttributes:attributes range:NSMakeRange(0, [text length])];
|
197
|
-
[result appendAttributedString:resultSpan];
|
198
|
-
|
199
|
-
}
|
200
|
-
}
|
201
|
-
return result;
|
202
|
-
}
|
203
|
-
@end
|