Skip to content

Commit

Permalink
TextStorageEventRouter
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed Nov 20, 2023
1 parent db7645f commit 17e4c76
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions Sources/TextStory/TextStorageEventRouter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import Foundation

public protocol TextStorageMonitor {
func textStorage(_ textStorage: TSYTextStorage, willReplaceCharactersIn range: NSRange, with string: String)
func textStorage(_ textStorage: TSYTextStorage, didReplaceCharactersIn range: NSRange, with string: String)
func textStorageWillCompleteProcessingEdit(_ textStorage: TSYTextStorage)
func textStorageDidCompleteProcessingEdit(_ textStorage: TSYTextStorage)
}

public extension TextStorageMonitor {
func textStorage(_ textStorage: TSYTextStorage, willReplaceCharactersIn range: NSRange, with string: String) {}
func textStorageWillCompleteProcessingEdit(_ textStorage: TSYTextStorage) {}
func textStorageDidCompleteProcessingEdit(_ textStorage: TSYTextStorage) {}
}

/// Routes `TSYTextStorageDelegate` calls to multiple `TextStorageMonitor` instances.
///
/// This class can except all the `TSYTextStorageDelegate` calls and forward them to multiple `TextStorageMonitor` instances. It can be directly assigned as the `storageDelegate` of `TSYTextStorageDelegate`.
public final class TextStorageEventRouter: NSObject {
public typealias DoubleClickWordRangeProvider = (Int) -> NSRange
public typealias WordBoundaryProvider = (Int, Bool) -> Int

public var monitors = [TextStorageMonitor]()
public var doubleClickWordRangeProvider: DoubleClickWordRangeProvider?
public var workBoundaryProvider: WordBoundaryProvider?

public override init() {
}
}

extension TextStorageEventRouter: TSYTextStorageDelegate {
public func textStorage(_ textStorage: TSYTextStorage, willReplaceCharactersIn range: NSRange, with string: String) {
for monitor in monitors {
monitor.textStorage(textStorage, willReplaceCharactersIn: range, with: string)
}
}

public func textStorage(_ textStorage: TSYTextStorage, didReplaceCharactersIn range: NSRange, with string: String) {
for monitor in monitors {
monitor.textStorage(textStorage, didReplaceCharactersIn: range, with: string)
}
}

public func textStorageWillCompleteProcessingEdit(_ textStorage: TSYTextStorage) {
for monitor in monitors {
monitor.textStorageWillCompleteProcessingEdit(textStorage)
}
}

public func textStorageDidCompleteProcessingEdit(_ textStorage: TSYTextStorage) {
for monitor in monitors {
monitor.textStorageDidCompleteProcessingEdit(textStorage)
}
}

public func textStorage(_ textStorage: TSYTextStorage, doubleClickRangeForLocation location: UInt) -> NSRange {
if let provider = doubleClickWordRangeProvider {
return provider(Int(location))
}

return textStorage.internalStorage.doubleClick(at: Int(location))

Check failure on line 61 in Sources/TextStory/TextStorageEventRouter.swift

View workflow job for this annotation

GitHub Actions / Test (platform=tvOS Simulator,name=Apple TV)

value of type 'NSTextStorage' has no member 'doubleClick'
}

public func textStorage(_ textStorage: TSYTextStorage, nextWordIndexFromLocation location: UInt, direction forward: Bool) -> UInt {
if let provider = workBoundaryProvider {
return UInt(provider(Int(location), forward))
}

return UInt(textStorage.internalStorage.nextWord(from: Int(location), forward: forward))

Check failure on line 69 in Sources/TextStory/TextStorageEventRouter.swift

View workflow job for this annotation

GitHub Actions / Test (platform=tvOS Simulator,name=Apple TV)

value of type 'NSTextStorage' has no member 'nextWord'
}
}

0 comments on commit 17e4c76

Please sign in to comment.