Skip to content

Commit

Permalink
Merge pull request wikimedia#4693 from wikimedia/native-editor-templa…
Browse files Browse the repository at this point in the history
…te-selection-fix

Bug fix - Native Editor template selection fix
  • Loading branch information
mazevedofs authored Jan 8, 2024
2 parents dafaa2a + 19d44d3 commit 141ec7f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -278,70 +278,56 @@ - (void)updateFonts:(WKSourceEditorFonts *)fonts inAttributedString:(NSMutableAt
#pragma mark - Public

- (BOOL)attributedString:(NSMutableAttributedString *)attributedString isBoldInRange:(NSRange)range {
__block BOOL isBold = NO;
if (range.length == 0) {

if (attributedString.length > range.location) {
NSDictionary<NSAttributedStringKey,id> *attrs = [attributedString attributesAtIndex:range.location effectiveRange:nil];

if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontBold] != nil) {
isBold = YES;
} else {
// Edge case, check previous character if we are up against a closing bold or italic
if (attrs[WKSourceEditorCustomKeyColorOrange]) {
attrs = [attributedString attributesAtIndex:range.location - 1 effectiveRange:nil];
if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontBold] != nil) {
isBold = YES;
}
}
}
}

} else {
[attributedString enumerateAttributesInRange:range options:nil usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange loopRange, BOOL * _Nonnull stop) {
if ((attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontBold] != nil) &&
(loopRange.location == range.location && loopRange.length == range.length)) {
isBold = YES;
stop = YES;
}
}];
}


return isBold;
return [self attributedString:attributedString isFormattedInRange:range formattingKey:WKSourceEditorCustomKeyFontBold];
}

- (BOOL)attributedString:(NSMutableAttributedString *)attributedString isItalicsInRange:(NSRange)range {
__block BOOL isItalics = NO;
return [self attributedString:attributedString isFormattedInRange:range formattingKey:WKSourceEditorCustomKeyFontItalics];
}

#pragma mark - Private

- (BOOL)attributedString:(NSMutableAttributedString *)attributedString isFormattedInRange:(NSRange)range formattingKey: (NSString *)formattingKey {
__block BOOL isFormatted = NO;

if (range.length == 0) {

if (attributedString.length > range.location) {
NSDictionary<NSAttributedStringKey,id> *attrs = [attributedString attributesAtIndex:range.location effectiveRange:nil];

if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontItalics] != nil) {
isItalics = YES;
isFormatted = YES;
} else {
// Edge case, check previous character if we are up against a closing bold or italic
if (attrs[WKSourceEditorCustomKeyColorOrange]) {
attrs = [attributedString attributesAtIndex:range.location - 1 effectiveRange:nil];
if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontItalics] != nil) {
isItalics = YES;
if (attrs[WKSourceEditorCustomKeyFontBold] != nil || attrs[WKSourceEditorCustomKeyFontItalics] != nil) {
isFormatted = YES;
}
}
}
}

} else {

__block NSRange unionRange = NSMakeRange(NSNotFound, 0);
[attributedString enumerateAttributesInRange:range options:nil usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange loopRange, BOOL * _Nonnull stop) {
if ((attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontItalics] != nil) &&
(loopRange.location == range.location && loopRange.length == range.length)) {
isItalics = YES;
if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[formattingKey] != nil) {
if (unionRange.location == NSNotFound) {
unionRange = loopRange;
} else {
unionRange = NSUnionRange(unionRange, loopRange);
}
stop = YES;
}
}];

if (NSEqualRanges(unionRange, range)) {
isFormatted = YES;
}
}

return isItalics;
return isFormatted;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,21 @@ - (BOOL)attributedString:(NSMutableAttributedString *)attributedString isHorizon
}

} else {
__block NSRange unionRange = NSMakeRange(NSNotFound, 0);
[attributedString enumerateAttributesInRange:range options:nil usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange loopRange, BOOL * _Nonnull stop) {
if ((attrs[WKSourceEditorCustomKeyHorizontalTemplate] != nil) &&
(loopRange.location == range.location && loopRange.length == range.length)) {
isTemplate = YES;
stop = YES;
if (attrs[WKSourceEditorCustomKeyHorizontalTemplate] != nil) {
if (unionRange.location == NSNotFound) {
unionRange = loopRange;
} else {
unionRange = NSUnionRange(unionRange, loopRange);
}
stop = YES;
}
}];

if (NSEqualRanges(unionRange, range)) {
isTemplate = YES;
}
}

return isTemplate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,25 @@ final class WKSourceEditorTextFrameworkMediatorTests: XCTestCase {
XCTAssertFalse(selectionStates9.isItalics)
}

func testSelectionSpanningNonFormattedState1() throws {
let text = "Testing '''bold with {{template}}''' selection that spans nonbold."
mediator.textView.attributedText = NSAttributedString(string: text)

// "bold with {{template}}"
let selectionStates = mediator.selectionState(selectedDocumentRange: NSRange(location: 11, length: 22))
XCTAssertTrue(selectionStates.isBold)
XCTAssertFalse(selectionStates.isHorizontalTemplate)
}

func testSelectionSpanningNonFormattedState2() throws {
let text = "Testing {{template | '''bold'''}} selection that spans nonbold."
mediator.textView.attributedText = NSAttributedString(string: text)

// "template | '''bold'''"
let selectionStates1 = mediator.selectionState(selectedDocumentRange: NSRange(location: 10, length: 21))
XCTAssertFalse(selectionStates1.isBold)
XCTAssertTrue(selectionStates1.isHorizontalTemplate)
}
func testClosingBoldSelectionStateCursor() throws {
let text = "One '''Two''' Three"
mediator.textView.attributedText = NSAttributedString(string: text)
Expand Down Expand Up @@ -138,6 +157,15 @@ final class WKSourceEditorTextFrameworkMediatorTests: XCTestCase {
XCTAssertFalse(selectionStates1.isHorizontalTemplate)
}

func testHorizontalTemplateButtonSelectionStateFormattedRange() throws {
let text = "Testing inner formatted {{cite web | url=https://en.wikipedia.org | title = The '''Free''' Encyclopedia}} template example."
mediator.textView.attributedText = NSAttributedString(string: text)

// "cite web | url=https://en.wikipedia.org | title = The '''Free''' Encyclopedia"
let selectionStates = mediator.selectionState(selectedDocumentRange: NSRange(location: 26, length: 77))
XCTAssertTrue(selectionStates.isHorizontalTemplate)
}

func testStrikethroughSelectionState() throws {
let text = "Testing <s>Strikethrough</s> Testing."
mediator.textView.attributedText = NSAttributedString(string: text)
Expand Down

0 comments on commit 141ec7f

Please sign in to comment.