@@ -13,16 +13,16 @@ import Foundation
13
13
/// If two attachments are overlapping, the one placed further along in the document will be
14
14
/// ignored when laying out attachments.
15
15
public final class TextAttachmentManager {
16
- private var orderedAttachments : [ TextAttachmentBox ] = [ ]
16
+ private var orderedAttachments : [ AnyTextAttachment ] = [ ]
17
17
weak var layoutManager : TextLayoutManager ?
18
18
19
- /// Adds a new attachment box , keeping `orderedAttachments` sorted by range.location.
19
+ /// Adds a new attachment, keeping `orderedAttachments` sorted by range.location.
20
20
/// If two attachments overlap, the layout phase will later ignore the one with the higher start.
21
21
/// - Complexity: `O(n log(n))` due to array insertion. Could be improved with a binary tree.
22
22
public func add( _ attachment: any TextAttachment , for range: NSRange ) {
23
- let box = TextAttachmentBox ( range: range, attachment: attachment)
23
+ let attachment = AnyTextAttachment ( range: range, attachment: attachment)
24
24
let insertIndex = findInsertionIndex ( for: range. location)
25
- orderedAttachments. insert ( box , at: insertIndex)
25
+ orderedAttachments. insert ( attachment , at: insertIndex)
26
26
layoutManager? . lineStorage. linesInRange ( range) . dropFirst ( ) . forEach {
27
27
if $0. height != 0 {
28
28
layoutManager? . lineStorage. update ( atOffset: $0. range. location, delta: 0 , deltaHeight: - $0. height)
@@ -46,20 +46,20 @@ public final class TextAttachmentManager {
46
46
/// Finds attachments starting in the given line range, and returns them as an array.
47
47
/// Returned attachment's ranges will be relative to the _document_, not the line.
48
48
/// - Complexity: `O(n log(n))`, ideally `O(log(n))`
49
- public func get( startingIn range: NSRange ) -> [ TextAttachmentBox ] {
50
- var results : [ TextAttachmentBox ] = [ ]
49
+ public func get( startingIn range: NSRange ) -> [ AnyTextAttachment ] {
50
+ var results : [ AnyTextAttachment ] = [ ]
51
51
var idx = findInsertionIndex ( for: range. location)
52
52
while idx < orderedAttachments. count {
53
- let box = orderedAttachments [ idx]
54
- let loc = box . range. location
53
+ let attachment = orderedAttachments [ idx]
54
+ let loc = attachment . range. location
55
55
if loc >= range. upperBound {
56
56
break
57
57
}
58
58
if range. contains ( loc) {
59
- if let lastResult = results. last, !lastResult. range. contains ( box . range. location) {
60
- results. append ( box )
59
+ if let lastResult = results. last, !lastResult. range. contains ( attachment . range. location) {
60
+ results. append ( attachment )
61
61
} else if results. isEmpty {
62
- results. append ( box )
62
+ results. append ( attachment )
63
63
}
64
64
}
65
65
idx += 1
@@ -70,25 +70,25 @@ public final class TextAttachmentManager {
70
70
/// Returns all attachments whose ranges overlap the given query range.
71
71
///
72
72
/// - Parameter query: The `NSRange` to test for overlap.
73
- /// - Returns: An array of `TextAttachmentBox ` instances whose ranges intersect `query`.
74
- public func get( overlapping query: NSRange ) -> [ TextAttachmentBox ] {
73
+ /// - Returns: An array of `AnyTextAttachment ` instances whose ranges intersect `query`.
74
+ public func get( overlapping query: NSRange ) -> [ AnyTextAttachment ] {
75
75
// Find the first attachment whose end is beyond the start of the query.
76
76
guard let startIdx = firstIndex ( where: { $0. range. upperBound > query. location } ) else {
77
77
return [ ]
78
78
}
79
79
80
- var results : [ TextAttachmentBox ] = [ ]
80
+ var results : [ AnyTextAttachment ] = [ ]
81
81
var idx = startIdx
82
82
83
83
// Collect every subsequent attachment that truly overlaps the query.
84
84
while idx < orderedAttachments. count {
85
- let box = orderedAttachments [ idx]
86
- if box . range. location >= query. upperBound {
85
+ let attachment = orderedAttachments [ idx]
86
+ if attachment . range. location >= query. upperBound {
87
87
break
88
88
}
89
- if NSIntersectionRange ( box . range, query) . length > 0 ,
90
- results. last? . range != box . range {
91
- results. append ( box )
89
+ if NSIntersectionRange ( attachment . range, query) . length > 0 ,
90
+ results. last? . range != attachment . range {
91
+ results. append ( attachment )
92
92
}
93
93
idx += 1
94
94
}
@@ -97,10 +97,10 @@ public final class TextAttachmentManager {
97
97
}
98
98
99
99
package func textUpdated( atOffset: Int , delta: Int ) {
100
- for (idx, box ) in orderedAttachments. enumerated ( ) . reversed ( ) {
101
- if box . range. contains ( atOffset) {
100
+ for (idx, attachment ) in orderedAttachments. enumerated ( ) . reversed ( ) {
101
+ if attachment . range. contains ( atOffset) {
102
102
orderedAttachments. remove ( at: idx)
103
- } else if box . range. location > atOffset {
103
+ } else if attachment . range. location > atOffset {
104
104
orderedAttachments [ idx] . range. location += delta
105
105
}
106
106
}
@@ -115,7 +115,7 @@ private extension TextAttachmentManager {
115
115
/// If it returns `orderedAttachments.count`, no element satisfied
116
116
/// the predicate, but that’s still a valid insertion point.
117
117
func lowerBoundIndex(
118
- where predicate: ( TextAttachmentBox ) -> Bool
118
+ where predicate: ( AnyTextAttachment ) -> Bool
119
119
) -> Int {
120
120
var low = 0
121
121
var high = orderedAttachments. count
@@ -144,7 +144,7 @@ private extension TextAttachmentManager {
144
144
/// - Parameter predicate: the query predicate.
145
145
/// - Returns: the first matching index, or `nil` if none of the
146
146
/// attachments satisfy the predicate.
147
- func firstIndex( where predicate: ( TextAttachmentBox ) -> Bool ) -> Int ? {
147
+ func firstIndex( where predicate: ( AnyTextAttachment ) -> Bool ) -> Int ? {
148
148
let idx = lowerBoundIndex { predicate ( $0) }
149
149
return idx < orderedAttachments. count ? idx : nil
150
150
}
0 commit comments