Skip to content

Commit 4f24327

Browse files
committed
refactor(ios): extract attribute builders to NitroTextImpl+Attributes.swift\n\n- Move makeAttributes/makeParagraphStyle/resolveColor/transform into an extension file\n- Relax access controls so extensions can read state (alignment, transform, container)\n- Keep NitroTextImpl.swift focused on core logic
1 parent 5373ed3 commit 4f24327

2 files changed

Lines changed: 90 additions & 80 deletions

File tree

ios/NitroTextImpl+Attributes.swift

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//
2+
// NitroTextImpl+Attributes.swift
3+
// Pods
4+
//
5+
// Attribute-building helpers for NitroTextImpl (colors, paragraph style, transforms).
6+
//
7+
8+
import UIKit
9+
10+
extension NitroTextImpl {
11+
func makeAttributes(
12+
for fragment: Fragment,
13+
defaultColor: UIColor
14+
) -> [NSAttributedString.Key: Any] {
15+
var attrs: [NSAttributedString.Key: Any] = [:]
16+
17+
let font = makeFont(for: fragment, defaultPointSize: nitroTextView?.font?.pointSize)
18+
attrs[.font] = font.value
19+
if font.isItalic { attrs[.obliqueness] = 0.2 }
20+
21+
let para = makeParagraphStyle(for: fragment)
22+
attrs[.paragraphStyle] = para
23+
24+
let color = resolveColor(for: fragment, defaultColor: defaultColor)
25+
attrs[.foregroundColor] = color
26+
27+
return attrs
28+
}
29+
30+
func makeParagraphStyle(for fragment: Fragment) -> NSMutableParagraphStyle {
31+
let para = NSMutableParagraphStyle()
32+
33+
if let lineHeight = fragment.lineHeight, lineHeight > 0 {
34+
para.minimumLineHeight = lineHeight
35+
para.maximumLineHeight = lineHeight
36+
}
37+
38+
if let align = fragment.textAlign {
39+
switch align {
40+
case .center: para.alignment = .center
41+
case .right: para.alignment = .right
42+
case .justify: para.alignment = .justified
43+
case .left: para.alignment = .left
44+
case .auto: para.alignment = .natural
45+
}
46+
} else {
47+
para.alignment = currentTextAlignment
48+
}
49+
50+
if let n = nitroTextView?.textContainer.maximumNumberOfLines {
51+
para.lineBreakMode = effectiveLineBreakMode(forLines: n)
52+
}
53+
return para
54+
}
55+
56+
func resolveColor(for fragment: Fragment, defaultColor: UIColor) -> UIColor {
57+
if let value = fragment.fontColor, let parsed = ColorParser.parse(value) {
58+
return parsed
59+
}
60+
return defaultColor
61+
}
62+
63+
func transform(_ text: String, with fragment: Fragment) -> String {
64+
let effective: TextTransform = {
65+
if let ft = fragment.textTransform {
66+
switch ft {
67+
case .uppercase: return .uppercase
68+
case .lowercase: return .lowercase
69+
case .capitalize: return .capitalize
70+
case .none: return .none
71+
}
72+
}
73+
return currentTransform
74+
}()
75+
76+
switch effective {
77+
case .uppercase: return text.uppercased()
78+
case .lowercase: return text.lowercased()
79+
case .capitalize: return text.capitalized
80+
case .none: return text
81+
}
82+
}
83+
}
84+

ios/NitroTextImpl.swift

Lines changed: 6 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
import UIKit
99

1010
final class NitroTextImpl {
11-
private weak var nitroTextView : NitroTextView?
12-
private var currentTextAlignment: NSTextAlignment = .natural
13-
private var currentTransform: TextTransform = .none
14-
private var currentEllipsize: NSLineBreakMode = .byTruncatingTail
11+
weak var nitroTextView : NitroTextView?
12+
var currentTextAlignment: NSTextAlignment = .natural
13+
var currentTransform: TextTransform = .none
14+
var currentEllipsize: NSLineBreakMode = .byTruncatingTail
1515

1616
init(_ nitroTextView: NitroTextView) {
1717
self.nitroTextView = nitroTextView
@@ -40,7 +40,7 @@ final class NitroTextImpl {
4040
nitroTextView?.textContainer.lineBreakMode = effectiveLineBreakMode(forLines: n)
4141
}
4242

43-
private func effectiveLineBreakMode(forLines n: Int) -> NSLineBreakMode {
43+
func effectiveLineBreakMode(forLines n: Int) -> NSLineBreakMode {
4444
guard n > 0 else { return .byWordWrapping }
4545
if n == 1 { return currentEllipsize }
4646
// Multi-line behavior: allow wrapping, then apply final-line behavior.
@@ -113,81 +113,7 @@ final class NitroTextImpl {
113113
setText(result)
114114
}
115115

116-
// MARK: - Attribute helpers
117-
118-
private func makeAttributes(
119-
for fragment: Fragment,
120-
defaultColor: UIColor
121-
) -> [NSAttributedString.Key: Any] {
122-
var attrs: [NSAttributedString.Key: Any] = [:]
123-
124-
let font = makeFont(for: fragment, defaultPointSize: nitroTextView?.font?.pointSize)
125-
attrs[.font] = font.value
126-
if font.isItalic { attrs[.obliqueness] = 0.2 }
127-
128-
let para = makeParagraphStyle(for: fragment)
129-
attrs[.paragraphStyle] = para
130-
131-
let color = resolveColor(for: fragment, defaultColor: defaultColor)
132-
attrs[.foregroundColor] = color
133-
134-
return attrs
135-
}
136-
137-
// makeFont moved to NitroTextImpl+Font.swift
138-
139-
private func makeParagraphStyle(for fragment: Fragment) -> NSMutableParagraphStyle {
140-
let para = NSMutableParagraphStyle()
141-
142-
if let lineHeight = fragment.lineHeight, lineHeight > 0 {
143-
para.minimumLineHeight = lineHeight
144-
para.maximumLineHeight = lineHeight
145-
}
146-
147-
if let align = fragment.textAlign {
148-
switch align {
149-
case .center: para.alignment = .center
150-
case .right: para.alignment = .right
151-
case .justify: para.alignment = .justified
152-
case .left: para.alignment = .left
153-
case .auto: para.alignment = .natural
154-
}
155-
} else {
156-
para.alignment = currentTextAlignment
157-
}
158-
159-
guard let n = nitroTextView?.textContainer.maximumNumberOfLines else { return para }
160-
para.lineBreakMode = effectiveLineBreakMode(forLines: n)
161-
return para
162-
}
163-
164-
private func resolveColor(for fragment: Fragment, defaultColor: UIColor) -> UIColor {
165-
if let value = fragment.fontColor, let parsed = ColorParser.parse(value) {
166-
return parsed
167-
}
168-
return defaultColor
169-
}
170-
171-
private func transform(_ text: String, with fragment: Fragment) -> String {
172-
let effective: TextTransform = {
173-
if let ft = fragment.textTransform {
174-
switch ft {
175-
case .uppercase: return .uppercase
176-
case .lowercase: return .lowercase
177-
case .capitalize: return .capitalize
178-
case .none: return .none
179-
}
180-
}
181-
return currentTransform
182-
}()
183-
184-
switch effective {
185-
case .uppercase: return text.uppercased()
186-
case .lowercase: return text.lowercased()
187-
case .capitalize: return text.capitalized
188-
case .none: return text
189-
}
190-
}
116+
// Attribute helpers moved to NitroTextImpl+Attributes.swift
191117
}
192118

193119

0 commit comments

Comments
 (0)