From 3c5c308ea590a51f5228cb911c64b88f50a586e9 Mon Sep 17 00:00:00 2001 From: Jorge Leandro Perez Date: Thu, 5 Oct 2017 12:05:02 -0300 Subject: [PATCH 1/4] TextViewTests: New Unit Test --- AztecTests/TextKit/TextViewTests.swift | 35 ++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/AztecTests/TextKit/TextViewTests.swift b/AztecTests/TextKit/TextViewTests.swift index 77b1b6afc..5270e6deb 100644 --- a/AztecTests/TextKit/TextViewTests.swift +++ b/AztecTests/TextKit/TextViewTests.swift @@ -1409,6 +1409,9 @@ class TextViewTests: XCTestCase { XCTAssertEqual(textView.text, Constants.sampleText0 + Constants.sampleText1 + String(.lineFeed) + String(.paragraphSeparator)) } + + // MARK: - Media + func testInsertVideo() { let textView = createEmptyTextView() let _ = textView.replaceWithVideo(at: NSRange(location:0, length:0), sourceURL: URL(string: "video.mp4")!, posterURL: URL(string: "video.jpg"), placeHolderImage: nil) @@ -1447,6 +1450,9 @@ class TextViewTests: XCTestCase { XCTAssertEqual(textView.getHTML(), "

") } + + // MARK: - Comments + /// This test check if the insertion of a Comment Attachment works correctly and the expected tag gets inserted /// func testInsertComment() { @@ -1470,6 +1476,9 @@ class TextViewTests: XCTestCase { XCTAssertEqual(html, "

") } + + // MARK: - HR + /// This test check if the insertion of an horizontal ruler works correctly and the hr tag is inserted /// func testReplaceRangeWithHorizontalRuler() { @@ -1571,6 +1580,9 @@ class TextViewTests: XCTestCase { XCTAssertEqual(textView.getHTML(), "

\"Changed

") } + + // MARK: - Bugfixing + /// This test verifies that the H1 Header does not get lost during the Rich <> Raw transitioning. /// func testToggleHtmlWithTwoEmptyLineBreaksDoesNotLooseHeaderStyle() { @@ -1664,4 +1676,27 @@ class TextViewTests: XCTestCase { let expected = "
      1. First Item
" XCTAssert(textView.getHTML(prettyPrint: false) == expected) } + + /// This test verifies that the `deleteBackward` call does not result in loosing the Typing Attributes. + /// Precisely, we'll ensure that the Italics style isn't lost after hitting backspace, and retyping the + /// deleted character. + /// + /// Ref. Issue #749: Loosing Style after hitting Backspace + /// + func testDeleteBackwardsDoesNotEndUpLoosingItalicsStyle() { + let textView = createTextView(withHTML: "") + + textView.toggleBoldface(self) + textView.insertText("First Line") + textView.insertText("\n") + + textView.toggleItalics(self) + textView.insertText("Second") + + let expectedHTML = textView.getHTML(prettyPrint: false) + textView.deleteBackward() + textView.insertText("d") + + XCTAssertEqual(textView.getHTML(prettyPrint: false), expectedHTML) + } } From 49e955596136aca931247d0a247977d91249032f Mon Sep 17 00:00:00 2001 From: Jorge Leandro Perez Date: Thu, 5 Oct 2017 12:17:39 -0300 Subject: [PATCH 2/4] TextView: deleteBackward iOS 11 Workaround --- Aztec/Classes/TextKit/TextView.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Aztec/Classes/TextKit/TextView.swift b/Aztec/Classes/TextKit/TextView.swift index 8a7b4b3ab..c93b4b9fd 100644 --- a/Aztec/Classes/TextKit/TextView.swift +++ b/Aztec/Classes/TextKit/TextView.swift @@ -457,8 +457,20 @@ open class TextView: UITextView { ensureRemovalOfParagraphStylesBeforeRemovingCharacter(at: selectedRange) + // WORKAROUND: iOS 11 introduced an issue that's causing UITextView to lose it's typing + // attributes under certain circumstances. This workaround is analog to the one introduced in + /// the `insertText` call. + // + // Issue: https://github.com/wordpress-mobile/AztecEditor-iOS/issues/749 + // + let workaroundTypingAttributes = typingAttributes + super.deleteBackward() + // WORKAROUND: this line is related to the workaround above. + // + typingAttributes = workaroundTypingAttributes + ensureRemovalOfParagraphAttributesWhenPressingBackspaceAndEmptyingTheDocument() ensureCursorRedraw(afterEditing: deletedString.string) delegate?.textViewDidChange?(self) From fb425e715428a1f4adaa9c007316224599c1990b Mon Sep 17 00:00:00 2001 From: Jorge Leandro Perez Date: Thu, 5 Oct 2017 15:16:51 -0300 Subject: [PATCH 3/4] TextView: Updates workaround --- Aztec/Classes/TextKit/TextView.swift | 30 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Aztec/Classes/TextKit/TextView.swift b/Aztec/Classes/TextKit/TextView.swift index c93b4b9fd..903c89081 100644 --- a/Aztec/Classes/TextKit/TextView.swift +++ b/Aztec/Classes/TextKit/TextView.swift @@ -457,20 +457,9 @@ open class TextView: UITextView { ensureRemovalOfParagraphStylesBeforeRemovingCharacter(at: selectedRange) - // WORKAROUND: iOS 11 introduced an issue that's causing UITextView to lose it's typing - // attributes under certain circumstances. This workaround is analog to the one introduced in - /// the `insertText` call. - // - // Issue: https://github.com/wordpress-mobile/AztecEditor-iOS/issues/749 - // - let workaroundTypingAttributes = typingAttributes - super.deleteBackward() - // WORKAROUND: this line is related to the workaround above. - // - typingAttributes = workaroundTypingAttributes - + ensureTypingAttributesAreValid() ensureRemovalOfParagraphAttributesWhenPressingBackspaceAndEmptyingTheDocument() ensureCursorRedraw(afterEditing: deletedString.string) delegate?.textViewDidChange?(self) @@ -979,6 +968,23 @@ open class TextView: UITextView { } + // WORKAROUND: iOS 11 introduced an issue that's causing UITextView to lose it's typing + // attributes under certain circumstances. This method will determine the Typing Attributes based on + /// the TextStorage attributes, whenever possible. + /// + /// Issue: https://github.com/wordpress-mobile/AztecEditor-iOS/issues/749 + /// + private func ensureTypingAttributesAreValid() { + let document = textStorage.string + guard selectedRange.location == document.characters.count else { + return + } + + let previousLocation = max(selectedRange.location - 1, 0) + typingAttributes = textStorage.attributes(at: previousLocation, effectiveRange: nil) + } + + // MARK: - Links /// Adds a link to the designated url on the specified range. From fb9cc6adb8c664728eaf84b11b6e534dba3ab1c1 Mon Sep 17 00:00:00 2001 From: Jorge Leandro Perez Date: Mon, 9 Oct 2017 15:30:22 -0300 Subject: [PATCH 4/4] TextView: Making Diego a happy human --- Aztec/Classes/TextKit/TextView.swift | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Aztec/Classes/TextKit/TextView.swift b/Aztec/Classes/TextKit/TextView.swift index 903c89081..60a532355 100644 --- a/Aztec/Classes/TextKit/TextView.swift +++ b/Aztec/Classes/TextKit/TextView.swift @@ -457,9 +457,10 @@ open class TextView: UITextView { ensureRemovalOfParagraphStylesBeforeRemovingCharacter(at: selectedRange) - super.deleteBackward() + preserveTypingAttributes { + super.deleteBackward() + } - ensureTypingAttributesAreValid() ensureRemovalOfParagraphAttributesWhenPressingBackspaceAndEmptyingTheDocument() ensureCursorRedraw(afterEditing: deletedString.string) delegate?.textViewDidChange?(self) @@ -974,14 +975,19 @@ open class TextView: UITextView { /// /// Issue: https://github.com/wordpress-mobile/AztecEditor-iOS/issues/749 /// - private func ensureTypingAttributesAreValid() { + private func preserveTypingAttributes(beforeDeletion block: () -> Void) { let document = textStorage.string guard selectedRange.location == document.characters.count else { + block() return } let previousLocation = max(selectedRange.location - 1, 0) - typingAttributes = textStorage.attributes(at: previousLocation, effectiveRange: nil) + let previousAttributes = textStorage.attributes(at: previousLocation, effectiveRange: nil) + + block() + + typingAttributes = previousAttributes }