@@ -37,27 +37,14 @@ + (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text i
3737
3838 // if the backspace removes the whole content of a paragraph (possibly more but has to start where the paragraph starts), we remove the typing attributes
3939 if (range.location == nonNewlineRange.location && range.length >= nonNewlineRange.length ) {
40- // for lists and quotes we want to remove the characters but keep attribtues so that a zero width space appears here
40+ // for lists, quotes and codeblocks we want to remove the characters but keep the attributes so that a zero width space appears here
4141 // so we do the removing manually and reapply attributes
42- if ([ulStyle detectStyle: nonNewlineRange]) {
43- [TextInsertionUtils replaceText: text at: range additionalAttributes: nullptr input: typedInput withSelection: YES ];
44- [ulStyle addAttributes: NSMakeRange (range.location, 0 )];
45- return YES ;
46- }
47- if ([olStyle detectStyle: nonNewlineRange]) {
48- [TextInsertionUtils replaceText: text at: range additionalAttributes: nullptr input: typedInput withSelection: YES ];
49- [olStyle addAttributes: NSMakeRange (range.location, 0 )];
50- return YES ;
51- }
52- if ([bqStyle detectStyle: nonNewlineRange]) {
53- [TextInsertionUtils replaceText: text at: range additionalAttributes: nullptr input: typedInput withSelection: YES ];
54- [bqStyle addAttributes: NSMakeRange (range.location, 0 )];
55- return YES ;
56- }
57- if ([cbStyle detectStyle: nonNewlineRange]) {
58- [TextInsertionUtils replaceText: text at: range additionalAttributes: nullptr input: typedInput withSelection: YES ];
59- [cbStyle addAttributes: NSMakeRange (range.location, 0 )];
60- return YES ;
42+ NSArray *handledStyles = @[ulStyle, olStyle, bqStyle, cbStyle];
43+ for (id <BaseStyleProtocol> style in handledStyles) {
44+ if ([style detectStyle: nonNewlineRange]) {
45+ [TextInsertionUtils replaceText: text at: range additionalAttributes: nullptr input: typedInput withSelection: YES ];
46+ return YES ;
47+ }
6148 }
6249
6350 // do the replacement manually
@@ -70,6 +57,23 @@ + (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text i
7057 return NO ;
7158}
7259
60+ /* *
61+ * Handles the specific case of backspacing a newline character, which results in merging two paragraphs.
62+ *
63+ * THE PROBLEM:
64+ * When merging a bottom paragraph (Source) into a top paragraph (Destination), the bottom paragraph
65+ * normally brings all its attributes with it. If the top paragraph is a restrictive style (like a CodeBlock),
66+ * and the bottom paragraph contains a conflicting style (like an H1 Header), a standard merge would
67+ * create an invalid state (e.g., a CodeBlock that is also a Header).
68+ *
69+ * THE SOLUTION:
70+ * 1. Identifies the dominant style of the paragraph ABOVE the deleted newline (`leftParagraphStyle`).
71+ * 2. Checks the paragraph BELOW the newline (`rightRange`) for any styles that conflict with or are blocked by the top style.
72+ * 3. Explicitly removes those forbidden styles from the bottom paragraph *before* the merge occurs.
73+ * 4. Performs the merge (deletes the newline).
74+ *
75+ * @return YES if the newline backspace was handled and sanitized; NO otherwise.
76+ */
7377+ (BOOL )handleNewlineBackspaceInRange : (NSRange )range replacementText : (NSString *)text input : (id )input {
7478 EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
7579 if (typedInput == nullptr ) {
0 commit comments