react-native-enriched 0.4.0 → 0.4.1
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.
|
@@ -108,6 +108,9 @@ class ParagraphStyles(
|
|
|
108
108
|
spannable.setSpan(span, safeStart, safeEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
// Removes spans of the given type in the specified range.
|
|
112
|
+
// If the removed span intersects with the range, it will be split and the remaining part will be re-applied after the removal
|
|
113
|
+
// Returns true if any spans were removed, false otherwise
|
|
111
114
|
private fun <T> removeSpansForRange(
|
|
112
115
|
spannable: Spannable,
|
|
113
116
|
start: Int,
|
|
@@ -115,21 +118,24 @@ class ParagraphStyles(
|
|
|
115
118
|
clazz: Class<T>,
|
|
116
119
|
): Boolean {
|
|
117
120
|
val ssb = spannable as SpannableStringBuilder
|
|
118
|
-
var finalStart = start
|
|
119
|
-
var finalEnd = end
|
|
120
|
-
|
|
121
121
|
val spans = ssb.getSpans(start, end, clazz)
|
|
122
122
|
if (spans.isEmpty()) return false
|
|
123
123
|
|
|
124
124
|
for (span in spans) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
val spanStart = ssb.getSpanStart(span)
|
|
126
|
+
val spanEnd = ssb.getSpanEnd(span)
|
|
128
127
|
ssb.removeSpan(span)
|
|
129
|
-
}
|
|
130
128
|
|
|
131
|
-
|
|
129
|
+
if (spanStart < start) {
|
|
130
|
+
setSpan(ssb, clazz, spanStart, start - 1)
|
|
131
|
+
}
|
|
132
132
|
|
|
133
|
+
if (spanEnd > end) {
|
|
134
|
+
setSpan(ssb, clazz, end + 1, spanEnd)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
ssb.removeZWS(start, end)
|
|
133
139
|
return true
|
|
134
140
|
}
|
|
135
141
|
|
|
@@ -215,11 +221,7 @@ class ParagraphStyles(
|
|
|
215
221
|
}
|
|
216
222
|
|
|
217
223
|
val currSpan = currParagraphSpans[0]
|
|
218
|
-
val nextSpan = getNextParagraphSpan(s, end, type)
|
|
219
|
-
|
|
220
|
-
if (nextSpan == null) {
|
|
221
|
-
return
|
|
222
|
-
}
|
|
224
|
+
val nextSpan = getNextParagraphSpan(s, end, type) ?: return
|
|
223
225
|
|
|
224
226
|
val newStart = s.getSpanStart(currSpan)
|
|
225
227
|
val newEnd = s.getSpanEnd(nextSpan)
|
|
@@ -341,9 +343,12 @@ class ParagraphStyles(
|
|
|
341
343
|
continue
|
|
342
344
|
}
|
|
343
345
|
|
|
346
|
+
// If removing text at the beginning of the line, we want to remove the span for the whole paragraph
|
|
344
347
|
if (isBackspace) {
|
|
345
|
-
|
|
348
|
+
val currentParagraphBounds = s.getParagraphBounds(endCursorPosition)
|
|
349
|
+
removeSpansForRange(s, currentParagraphBounds.first, currentParagraphBounds.second, config.clazz)
|
|
346
350
|
spanState.setStart(style, null)
|
|
351
|
+
continue
|
|
347
352
|
} else {
|
|
348
353
|
s.insert(endCursorPosition, EnrichedConstants.ZWS_STRING)
|
|
349
354
|
endCursorPosition += 1
|
|
@@ -1884,6 +1884,14 @@ Class<RCTComponentViewProtocol> EnrichedTextInputViewCls(void) {
|
|
|
1884
1884
|
return NO;
|
|
1885
1885
|
}
|
|
1886
1886
|
|
|
1887
|
+
// Tapping near a link causes iOS to re-derive typingAttributes from
|
|
1888
|
+
// character attributes after textViewDidChangeSelection returns, undoing
|
|
1889
|
+
// the cleanup in manageSelectionBasedChanges. Strip them again here, right
|
|
1890
|
+
// before insertion, so new text never inherits link styling.
|
|
1891
|
+
if (linkStyle != nullptr) {
|
|
1892
|
+
[linkStyle manageLinkTypingAttributes];
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1887
1895
|
return YES;
|
|
1888
1896
|
}
|
|
1889
1897
|
|
|
@@ -19,6 +19,35 @@
|
|
|
19
19
|
return self;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer
|
|
23
|
+
proposedLineFragment:(CGRect)lineFrag
|
|
24
|
+
glyphPosition:(CGPoint)position
|
|
25
|
+
characterIndex:(NSUInteger)charIndex {
|
|
26
|
+
CGRect baseBounds = self.bounds;
|
|
27
|
+
|
|
28
|
+
if (!textContainer.layoutManager.textStorage ||
|
|
29
|
+
charIndex >= textContainer.layoutManager.textStorage.length) {
|
|
30
|
+
return baseBounds;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
UIFont *font =
|
|
34
|
+
[textContainer.layoutManager.textStorage attribute:NSFontAttributeName
|
|
35
|
+
atIndex:charIndex
|
|
36
|
+
effectiveRange:NULL];
|
|
37
|
+
if (!font) {
|
|
38
|
+
return baseBounds;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Extend the layout bounds below the baseline by the font's descender.
|
|
42
|
+
// Without this, a line containing only the attachment has no descender space
|
|
43
|
+
// below the baseline, but adding a text character introduces it — causing
|
|
44
|
+
// the line height to jump. By reserving descender space upfront the line
|
|
45
|
+
// height stays consistent regardless of whether text is present.
|
|
46
|
+
CGFloat descender = font.descender;
|
|
47
|
+
return CGRectMake(baseBounds.origin.x, descender, baseBounds.size.width,
|
|
48
|
+
baseBounds.size.height - descender);
|
|
49
|
+
}
|
|
50
|
+
|
|
22
51
|
- (void)loadAsync {
|
|
23
52
|
NSURL *url = [NSURL URLWithString:self.uri];
|
|
24
53
|
if (!url) {
|