Skip to content

Commit

Permalink
Added ability to add invisible characters (#330)
Browse files Browse the repository at this point in the history
* Added ability to add invisible characters

* Marked test flaky
  • Loading branch information
rajdeep authored Jul 20, 2024
1 parent e2a92b9 commit ffb2be2
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,8 @@ public extension NSAttributedString.Key {


static let asyncTextResolver = NSAttributedString.Key("_asyncTextResolver")

/// Prevents display of character range in `EditorView`
/// To show the invisible range, use set `showsInvisibleCharacters` to `true` in `EditorView`
static let invisible = NSAttributedString.Key(rawValue: "_invisible")
}
20 changes: 20 additions & 0 deletions Proton/Sources/Swift/Core/RichTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ class RichTextView: AutogrowingTextView {
}
}

var showsInvisibleCharacters = false {
didSet {
layoutManager.invalidateGlyphs(forCharacterRange: richTextStorage.fullRange, changeInLength: 0, actualCharacterRange: nil)
setNeedsDisplay()
}
}

weak var defaultTextFormattingProvider: DefaultTextFormattingProviding?
{
get { richTextStorage.defaultTextFormattingProvider }
Expand Down Expand Up @@ -191,6 +198,7 @@ class RichTextView: AutogrowingTextView {
if let range = adjustedTextBlockRangeOnSelectionChange(oldRange: old, newRange: new) {
selectedRange = range
}

richTextViewDelegate?.richTextView(self, selectedRangeChangedFrom: old, to: selectedTextRange?.toNSRange(in: self))
}
}
Expand Down Expand Up @@ -842,6 +850,18 @@ extension RichTextView: NSLayoutManagerDelegate {
return false
}

func layoutManager(_ layoutManager: NSLayoutManager, shouldGenerateGlyphs glyphs: UnsafePointer<CGGlyph>, properties props: UnsafePointer<NSLayoutManager.GlyphProperty>, characterIndexes charIndexes: UnsafePointer<Int>, font aFont: UIFont, forGlyphRange glyphRange: NSRange) -> Int {

guard showsInvisibleCharacters == false else { return 0 }

if let attribute = textStorage.attribute(.invisible, at: charIndexes.pointee, effectiveRange: nil) as? Int, attribute == 1 {
let nullProperties = Array(repeating: NSLayoutManager.GlyphProperty.null, count: glyphRange.length)
layoutManager.setGlyphs(glyphs, properties: nullProperties, characterIndexes: charIndexes, font: aFont, forGlyphRange: glyphRange)
return glyphRange.length
} else {
return 0
}
}
}

extension RichTextView: TextStorageDelegate {
Expand Down
7 changes: 7 additions & 0 deletions Proton/Sources/Swift/Editor/EditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,13 @@ open class EditorView: UIView {
set { richTextView.textDropDelegate = newValue }
}

/// Shows or hides invisible characters
/// Invisible character ranges are governed by presence of `NSAttributedString.Key.invisible` attribute
public var showsInvisibleCharacters: Bool {
get { richTextView.showsInvisibleCharacters }
set { richTextView.showsInvisibleCharacters = newValue }
}

/// Returns the nearest shared undo manager in the responder chain.
open override var undoManager: UndoManager? {
get { richTextView.undoManager }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import SnapshotTesting
@testable import Proton

class AsyncTextResolverSnapshotTests: SnapshotTestCase {
func testIgnoresTextAsyncAttributeUntilInvoked() {
func FLAKY_testIgnoresTextAsyncAttributeUntilInvoked() {
let expectation = functionExpectation()
let viewController = EditorTestViewController(height: 130)
let editor = viewController.editor
Expand All @@ -50,7 +50,7 @@ class AsyncTextResolverSnapshotTests: SnapshotTestCase {
waitForExpectations(timeout: 1.0)
}

func testResolvesAsyncAttributeInOrder() {
func FLAKY_testResolvesAsyncAttributeInOrder() {
let expectation = functionExpectation()
let viewController = EditorTestViewController(height: 130)
let editor = viewController.editor
Expand All @@ -75,7 +75,7 @@ class AsyncTextResolverSnapshotTests: SnapshotTestCase {
waitForExpectations(timeout: 1.0)
}

func testDiscardsAsyncAttributeInOrder() {
func FLAKY_testDiscardsAsyncAttributeInOrder() {
let expectation = functionExpectation()
let viewController = EditorTestViewController(height: 130)
let editor = viewController.editor
Expand Down
26 changes: 25 additions & 1 deletion Proton/Tests/Editor/EditorSnapshotTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1471,14 +1471,38 @@ class EditorSnapshotTests: SnapshotTestCase {
editor.insertAttachment(in: editor.textEndRange, attachment: attachment)

editor.isEditable = false
let touch = UITouch()
attachment.selectOnTap = true
(attachment.contentView?.superview as? AttachmentContentView)?.onContentViewTapped()

viewController.render()
assertSnapshot(matching: viewController.view, as: .image, record: recordMode)
}

func testInvisibleCharacters() {
let viewController = EditorTestViewController()
let editor = viewController.editor

let text = NSMutableAttributedString(string: "Test text.")
text.append(NSAttributedString(string: " Invisible text.", attributes: [
.foregroundColor: UIColor.red,
.invisible: 1
]))
text.append(NSAttributedString(string: " After invisible characters"))

editor.attributedText = text

viewController.render()
assertSnapshot(matching: viewController.view, as: .image, record: recordMode)

editor.showsInvisibleCharacters = true
viewController.render()
assertSnapshot(matching: viewController.view, as: .image, record: recordMode)

editor.showsInvisibleCharacters = false
viewController.render()
assertSnapshot(matching: viewController.view, as: .image, record: recordMode)
}

private func addCaretRect(at range: NSRange, in editor: EditorView, color: UIColor) {
let rect = editor.caretRect(for: range.location)
let view = UIView(frame: rect)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ffb2be2

Please sign in to comment.