Skip to content

Commit

Permalink
Added ability to toggle on preserving new lines around block attachments
Browse files Browse the repository at this point in the history
  • Loading branch information
rajdeep committed Jun 30, 2024
1 parent 31ee1a4 commit bbd29b8
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 2 deletions.
6 changes: 4 additions & 2 deletions Proton/Sources/ObjC/PRTextStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,15 @@ - (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttribut
NSMutableAttributedString *replacementString = [attrString mutableCopy];
NSAttributedString *substring = [self attributedSubstringFromRange:range];

if (range.location > 0
if (self.preserveNewlineBeforeBlock
&& range.location > 0
&& [self attributedStringHasNewline:substring atStart:NO]
&& [self isCharacterAdjacentToRangeAnAttachment:self range:range checkBefore:NO]) {
replacementString = [self appendNewlineToAttributedString:[attrString mutableCopy] atStart:NO];
}

if (range.location > 0
if (self.preserveNewlineAfterBlock
&& range.location > 0
&& [self attributedStringHasNewline:substring atStart:YES]
&& [self isCharacterAdjacentToRangeAnAttachment:self range:range checkBefore:YES]) {
replacementString = [self appendNewlineToAttributedString:[attrString mutableCopy] atStart:YES];
Expand Down
3 changes: 3 additions & 0 deletions Proton/Sources/ObjC/include/PRTextStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ NS_SWIFT_NAME(TextStorageDelegate)
@property (weak, nullable) id<PRDefaultTextFormattingProviding> defaultTextFormattingProvider;
@property (weak, nullable) id<PRTextStorageDelegate> textStorageDelegate;

@property (nonatomic, assign) BOOL preserveNewlineBeforeBlock;
@property (nonatomic, assign) BOOL preserveNewlineAfterBlock;

@property (nonatomic, readonly) UIFont *defaultFont;
@property (nonatomic, readonly) NSParagraphStyle *defaultParagraphStyle;
@property (nonatomic, readonly) UIColor *defaultTextColor;
Expand Down
15 changes: 15 additions & 0 deletions Proton/Sources/Swift/Core/RichTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ class RichTextView: AutogrowingTextView {

private var delegateOverrides = [GestureRecognizerDelegateOverride]()

var preserveBlockAttachmentNewline: PreserveBlockAttachmentNewline = .none {
didSet {
richTextStorage.preserveNewlineBeforeBlock = false
richTextStorage.preserveNewlineAfterBlock = false

if preserveBlockAttachmentNewline.contains(.before) {
richTextStorage.preserveNewlineBeforeBlock = true
}

if preserveBlockAttachmentNewline.contains(.after) {
richTextStorage.preserveNewlineAfterBlock = true
}
}
}

weak var defaultTextFormattingProvider: DefaultTextFormattingProviding?
{
get { richTextStorage.defaultTextFormattingProvider }
Expand Down
19 changes: 19 additions & 0 deletions Proton/Sources/Swift/Editor/EditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ public struct AttachmentContentIdentifier {
}
}

public struct PreserveBlockAttachmentNewline: OptionSet {
public let rawValue: Int

public init(rawValue: Int) {
self.rawValue = rawValue
}

public static let before = PreserveBlockAttachmentNewline(rawValue: 1 << 0)
public static let after = PreserveBlockAttachmentNewline(rawValue: 1 << 1)

public static let none: PreserveBlockAttachmentNewline = []
public static let both: PreserveBlockAttachmentNewline = [.before, .after]
}

/// Defines the height for the Editor
public enum EditorHeight {
/// Default controlled via autolayout.
Expand Down Expand Up @@ -146,6 +160,11 @@ open class EditorView: UIView {
get { editorViewContext.delegate }
}

public var preserveBlockAttachmentNewline: PreserveBlockAttachmentNewline {
get { richTextView.preserveBlockAttachmentNewline }
set { richTextView.preserveBlockAttachmentNewline = newValue }
}

public var scrollView: UIScrollView {
richTextView as UIScrollView
}
Expand Down
62 changes: 62 additions & 0 deletions Proton/Tests/Editor/EditorViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -870,8 +870,70 @@ class EditorViewTests: XCTestCase {
XCTAssertNil(dummyAttachment1.containerEditorView)
XCTAssertNil(dummyAttachment2.containerEditorView)
}

func testPreservesNewlineBeforeAttachmentOnDelete() {
let viewController = EditorTestViewController()
let editor = viewController.editor
editor.preserveBlockAttachmentNewline = .before

let testString = NSAttributedString(string: "test string\n")
editor.replaceCharacters(in: .zero, with: testString)
let attachment = makePanelAttachment()
editor.insertAttachment(in: editor.textEndRange, attachment: attachment)
XCTAssertEqual(editor.text, "test string\n\n")

editor.replaceCharacters(in: NSRange(location: 8, length: 4), with: "")
XCTAssertEqual(editor.attachmentsInRange(editor.attributedText.fullRange).first?.range, NSRange(location: 9, length: 1))

XCTAssertEqual(editor.text, "test str\n\n")
}

func testPreservesNewlineAfterAttachmentOnDelete() {
let viewController = EditorTestViewController()
let editor = viewController.editor
editor.preserveBlockAttachmentNewline = .after

let testString = NSAttributedString(string: "test string\n After attachment")
editor.replaceCharacters(in: .zero, with: testString)
let attachment = makePanelAttachment()
editor.insertAttachment(in: NSRange(location: 13, length: 0), attachment: attachment)

editor.replaceCharacters(in: NSRange(location: 14, length: 7), with: "")

XCTAssertEqual(editor.text, "test string\n\n attachment")
XCTAssertEqual(editor.attachmentsInRange(editor.attributedText.fullRange).first?.range, NSRange(location: 13, length: 1))
}

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

let testString = NSAttributedString(string: "test string\n")
editor.replaceCharacters(in: .zero, with: testString)
let attachment = makePanelAttachment()
editor.insertAttachment(in: editor.textEndRange, attachment: attachment)
XCTAssertEqual(editor.text, "test string\n\n")

editor.replaceCharacters(in: NSRange(location: 8, length: 4), with: "")

XCTAssertEqual(editor.text, "test str\n")
XCTAssertEqual(editor.attachmentsInRange(editor.attributedText.fullRange).first?.range, NSRange(location: 8, length: 1))
}
}


func makePanelAttachment() -> Attachment {
let panel = PanelView()
panel.editor.forceApplyAttributedText = true
panel.backgroundColor = .cyan
panel.layer.borderWidth = 1.0
panel.layer.cornerRadius = 4.0
panel.layer.borderColor = UIColor.black.cgColor

return Attachment(panel, size: .fullWidth)
}


class DummyMultiEditorAttachment: Attachment {
let view: DummyMultiEditorView
init(numberOfEditors: Int) {
Expand Down

0 comments on commit bbd29b8

Please sign in to comment.