Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions ios/EnrichedTextInputView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -980,8 +980,8 @@ - (void)manageSelectionBasedChanges {
}

// typing attributes for empty lines selection reset
NSString *currentString = [[textView.textStorage.string copy] stringByReplacingOccurrencesOfString:@"\u200B" withString:@""];
if(textView.selectedRange.length == 0 && [_recentlyEmittedString isEqualToString: currentString] ) {
NSString *currentString = [textView.textStorage.string copy];
if(textView.selectedRange.length == 0 && [_recentlyEmittedString isEqualToString:currentString]) {
// no string change means only a selection changed with no character changes
NSRange paragraphRange = [textView.textStorage.string paragraphRangeForRange:textView.selectedRange];
if(
Expand Down Expand Up @@ -1012,15 +1012,15 @@ - (void)anyTextMayHaveBeenModified {
return;
}

// zero width space adding or removal
[ZeroWidthSpaceUtils handleZeroWidthSpacesInInput:self];

// emptying input typing attributes management
if(textView.textStorage.string.length == 0 && _recentlyEmittedString.length > 0) {
// reset typing attribtues
textView.typingAttributes = defaultTypingAttributes;
}

// zero width space removal
[ZeroWidthSpaceUtils handleZeroWidthSpacesInInput:self];

// inline code on newlines fix
InlineCodeStyle *codeStyle = stylesDict[@([InlineCodeStyle getStyleType])];
if(codeStyle != nullptr) {
Expand Down
35 changes: 12 additions & 23 deletions ios/styles/BlockQuoteStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -119,30 +119,19 @@ - (void)removeTypingAttributes {
}

- (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
if(
[self detectStyle:_input->textView.selectedRange] &&
NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0)) &&
[text isEqualToString:@""]
) {
// removing first quote line by backspacing doesn't remove typing attributes because it doesn't run textViewDidChange
// so we try guessing that a line should be deleted here
if([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
// backspace while the style is active

NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:_input->textView.selectedRange];
[self removeAttributes:paragraphRange];
return YES;
} else if(
[self detectStyle:_input->textView.selectedRange] &&
[text isEqualToString:@""]
) {
// other case; make sure removing all the (non newline) text from a quto line also removes the line itself
NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:range];
NSValue *nonNewlineVal = [ParagraphsUtils getNonNewlineRangesIn:_input->textView range:paragraphRange].firstObject;
if(nonNewlineVal == nullptr) {
return NO;
}
NSRange nonNewlineRange = [nonNewlineVal rangeValue];
if(NSEqualRanges(range, nonNewlineRange)) {
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:_input withSelection:YES];
[self removeAttributes:NSMakeRange(range.location, 0)];

if(NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
// a backspace on the very first input's line quote
// it doesn't run textVieDidChange so we need to manually remove attributes
[self removeAttributes:paragraphRange];
return YES;
} else if(range.location == paragraphRange.location - 1) {
// same case in other lines; here, the removed range location will be exactly 1 less than paragraph range location
[self removeAttributes:paragraphRange];
return YES;
}
}
Expand Down
35 changes: 12 additions & 23 deletions ios/styles/OrderedListStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -131,30 +131,19 @@ - (void)removeTypingAttributes {
}

- (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
if(
[self detectStyle:_input->textView.selectedRange] &&
NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0)) &&
[text isEqualToString:@""]
) {
// removing first list point by backspacing doesn't remove typing attributes because it doesn't run textViewDidChange
// so we try guessing that a point should be deleted here
if([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
// backspace while the style is active

NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:_input->textView.selectedRange];
[self removeAttributes:paragraphRange];
return YES;
} else if(
[self detectStyle:_input->textView.selectedRange] &&
[text isEqualToString:@""]
) {
// other case; make sure removing all the (non newline) text from a list item also removes the item itself
NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:range];
NSValue *nonNewlineVal = [ParagraphsUtils getNonNewlineRangesIn:_input->textView range:paragraphRange].firstObject;
if(nonNewlineVal == nullptr) {
return NO;
}
NSRange nonNewlineRange = [nonNewlineVal rangeValue];
if(NSEqualRanges(range, nonNewlineRange)) {
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:_input withSelection:YES];
[self removeAttributes:NSMakeRange(range.location, 0)];

if(NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
// a backspace on the very first input's line list point
// it doesn't run textVieDidChange so we need to manually remove attributes
[self removeAttributes:paragraphRange];
return YES;
} else if(range.location == paragraphRange.location - 1) {
// same case in other lines; here, the removed range location will be exactly 1 less than paragraph range location
[self removeAttributes:paragraphRange];
return YES;
}
}
Expand Down
35 changes: 12 additions & 23 deletions ios/styles/UnorderedListStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -131,30 +131,19 @@ - (void)removeTypingAttributes {
}

- (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
if(
[self detectStyle:_input->textView.selectedRange] &&
NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0)) &&
[text isEqualToString:@""]
) {
// removing first list point by backspacing doesn't remove typing attributes because it doesn't run textViewDidChange
// so we try guessing that a point should be deleted here
if([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
// backspace while the style is active

NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:_input->textView.selectedRange];
[self removeAttributes:paragraphRange];
return YES;
} else if(
[self detectStyle:_input->textView.selectedRange] &&
[text isEqualToString:@""]
) {
// other case; make sure removing all the (non newline) text from a list item also removes the item itself
NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:range];
NSValue *nonNewlineVal = [ParagraphsUtils getNonNewlineRangesIn:_input->textView range:paragraphRange].firstObject;
if(nonNewlineVal == nullptr) {
return NO;
}
NSRange nonNewlineRange = [nonNewlineVal rangeValue];
if(NSEqualRanges(range, nonNewlineRange)) {
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:_input withSelection:YES];
[self removeAttributes:NSMakeRange(range.location, 0)];

if(NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
// a backspace on the very first input's line list point
// it doesn't run textVieDidChange so we need to manually remove attributes
[self removeAttributes:paragraphRange];
return YES;
} else if(range.location == paragraphRange.location - 1) {
// same case in other lines; here, the removed range location will be exactly 1 less than paragraph range location
[self removeAttributes:paragraphRange];
return YES;
}
}
Expand Down
2 changes: 1 addition & 1 deletion ios/utils/OccurenceUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ + (BOOL)detect
NSRange attrRange = NSMakeRange(0, 0);
attrValue = [input->textView.textStorage attribute:key atIndex:index effectiveRange:&attrRange];
}
return condition(attrValue, NSMakeRange(index, 0));
return condition(attrValue, detectionRange);
}

+ (BOOL)detectMultiple
Expand Down
44 changes: 43 additions & 1 deletion ios/utils/ParagraphAttributesUtils.mm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import "ParagraphAttributesUtils.h"
#import "EnrichedTextInputView.h"
#import "StyleHeaders.h"
#import "ParagraphsUtils.h"
#import "TextInsertionUtils.h"

Expand All @@ -10,6 +11,10 @@ @implementation ParagraphAttributesUtils
// hence the solution - reset typing attributes
+ (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text input:(id)input {
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
UnorderedListStyle *ulStyle = typedInput->stylesDict[@([UnorderedListStyle getStyleType])];
OrderedListStyle *olStyle = typedInput->stylesDict[@([OrderedListStyle getStyleType])];
BlockQuoteStyle *bqStyle = typedInput->stylesDict[@([BlockQuoteStyle getStyleType])];

if(typedInput == nullptr) {
return NO;
}
Expand All @@ -21,15 +26,52 @@ + (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text i

// find a non-newline range of the paragraph
NSRange paragraphRange = [typedInput->textView.textStorage.string paragraphRangeForRange:range];

NSArray *paragraphs = [ParagraphsUtils getNonNewlineRangesIn:typedInput->textView range:paragraphRange];
if(paragraphs.count == 0) {
return NO;
}

NSRange nonNewlineRange = [(NSValue *)paragraphs.firstObject rangeValue];

// if the backspace removes the whole content of a paragraph - do the thing
// if the backspace removes the whole content of a paragraph, we remove the typing attributes
if(NSEqualRanges(nonNewlineRange, range)) {

// edge case with lists and blockquotes:
// for some reason, removing all characters from a list point that is: both the first point of a list and is the last thing in the input, doesn't preserve typing attributes
// so we manually remove the characters and reapply attribtues for zero width space to appear there
// otherwise (there still is list or quote) we don't want no actions because attributes are properly preserved and zero width space appears
if([ulStyle detectStyle:paragraphRange]) {
if(NSMaxRange(nonNewlineRange) == typedInput->textView.textStorage.string.length) {
// manually remove the characters
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:typedInput withSelection:YES];
// add atributes again
[ulStyle addAttributes:NSMakeRange(range.location, 0)];
return YES;
}
return NO;
}
if([olStyle detectStyle:paragraphRange]) {
if(NSMaxRange(nonNewlineRange) == typedInput->textView.textStorage.string.length) {
// manually remove the characters
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:typedInput withSelection:YES];
// add atributes again
[olStyle addAttributes:NSMakeRange(range.location, 0)];
return YES;
}
return NO;
}
if([bqStyle detectStyle:paragraphRange]) {
if(NSMaxRange(nonNewlineRange) == typedInput->textView.textStorage.string.length) {
// manually remove the characters
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:typedInput withSelection:YES];
// add atributes again
[bqStyle addAttributes:NSMakeRange(range.location, 0)];
return YES;
}
return NO;
}

// do the replacement manually
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:typedInput withSelection:YES];
// reset typing attribtues
Expand Down
Loading