Skip to content

Commit

Permalink
Merge branch 'main' into native-editor-inner-formatting-action-fix
Browse files Browse the repository at this point in the history
mazevedofs authored Jan 8, 2024
2 parents 641ccbe + 3371bb9 commit 5fc651a
Showing 4 changed files with 141 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -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
37 changes: 24 additions & 13 deletions Components/Sources/ComponentsObjC/WKSourceEditorFormatterTemplate.m
Original file line number Diff line number Diff line change
@@ -33,8 +33,8 @@ - (instancetype)initWithColors:(WKSourceEditorColors *)colors fonts:(WKSourceEdi
WKSourceEditorCustomKeyVerticalTemplate: [NSNumber numberWithBool:YES]
};

_horizontalTemplateRegex = [[NSRegularExpression alloc] initWithPattern:@"\\{{2}[^\\{\\}\\n]*\\}{2}" options:0 error:nil];
_verticalStartTemplateRegex = [[NSRegularExpression alloc] initWithPattern:@"^\\{{2}[^\\{\\}\\n]*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
_horizontalTemplateRegex = [[NSRegularExpression alloc] initWithPattern:@"\\{{2}[^\\{\\}\\n]*(?:\\{{2}[^\\{\\}\\n]*\\}{2})*[^\\{\\}\\n]*\\}{2}" options:0 error:nil];
_verticalStartTemplateRegex = [[NSRegularExpression alloc] initWithPattern:@"^(?:.*)(\\{{2}[^\\{\\}\\n]*)$" options:NSRegularExpressionAnchorsMatchLines error:nil];
_verticalParameterTemplateRegex = [[NSRegularExpression alloc] initWithPattern:@"^\\s*\\|.*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
_verticalEndTemplateRegex = [[NSRegularExpression alloc] initWithPattern:@"^([^\\{\\}\n]*\\}{2})(?:.)*$" options:NSRegularExpressionAnchorsMatchLines error:nil];
}
@@ -64,11 +64,12 @@ - (void)addSyntaxHighlightingToAttributedString:(nonnull NSMutableAttributedStri
options:0
range:range
usingBlock:^(NSTextCheckingResult *_Nullable result, NSMatchingFlags flags, BOOL *_Nonnull stop) {
NSRange matchRange = [result rangeAtIndex:0];
NSRange fullMatch = [result rangeAtIndex:0];
NSRange openingTemplateRange = [result rangeAtIndex:1];

if (matchRange.location != NSNotFound) {
[attributedString addAttributes:self.verticalTemplateAttributes range:matchRange];
}
if (fullMatch.location != NSNotFound && openingTemplateRange.location != NSNotFound) {
[attributedString addAttributes:self.verticalTemplateAttributes range:openingTemplateRange];
}
}];

[self.verticalParameterTemplateRegex enumerateMatchesInString:attributedString.string
@@ -86,12 +87,14 @@ - (void)addSyntaxHighlightingToAttributedString:(nonnull NSMutableAttributedStri
options:0
range:range
usingBlock:^(NSTextCheckingResult *_Nullable result, NSMatchingFlags flags, BOOL *_Nonnull stop) {

NSRange fullMatch = [result rangeAtIndex:0];
NSRange closingTemplateRange = [result rangeAtIndex:1];

if (fullMatch.location != NSNotFound && closingTemplateRange.location != NSNotFound) {
[attributedString addAttributes:self.verticalTemplateAttributes range:closingTemplateRange];
}
if (fullMatch.location != NSNotFound && closingTemplateRange.location != NSNotFound) {
[attributedString addAttributes:self.verticalTemplateAttributes range:closingTemplateRange];
}

}];
}

@@ -149,13 +152,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;
Original file line number Diff line number Diff line change
@@ -633,7 +633,43 @@ final class WKSourceEditorFormatterTests: XCTestCase {
XCTAssertEqual(refClosingAttributes[.foregroundColor] as! UIColor, colors.baseForegroundColor, "Incorrect ref formatting")
}

func testVerticalStartTemplate() {
func testHorizontalNestedTemplate() {
let string = "Ford Island ({{lang-haw|Poka {{okina}}Ailana}}) is an"
let mutAttributedString = NSMutableAttributedString(string: string)

for formatter in formatters {
formatter.addSyntaxHighlighting(to: mutAttributedString, in: NSRange(location: 0, length: string.count))
}

var base1Range = NSRange(location: 0, length: 0)
let base1Attributes = mutAttributedString.attributes(at: 0, effectiveRange: &base1Range)

var templateRange = NSRange(location: 0, length: 0)
let templateAttributes = mutAttributedString.attributes(at: 13, effectiveRange: &templateRange)

var base2Range = NSRange(location: 0, length: 0)
let base2Attributes = mutAttributedString.attributes(at: 46, effectiveRange: &base2Range)

// "Ford Island ("
XCTAssertEqual(base1Range.location, 0, "Incorrect base formatting")
XCTAssertEqual(base1Range.length, 13, "Incorrect base formatting")
XCTAssertEqual(base1Attributes[.font] as! UIFont, fonts.baseFont, "Incorrect base formatting")
XCTAssertEqual(base1Attributes[.foregroundColor] as! UIColor, colors.baseForegroundColor, "Incorrect base formatting")

// "{{lang-haw|Poka {{okina}}Ailana}}"
XCTAssertEqual(templateRange.location, 13, "Incorrect template formatting")
XCTAssertEqual(templateRange.length, 33, "Incorrect template formatting")
XCTAssertEqual(templateAttributes[.font] as! UIFont, fonts.baseFont, "Incorrect template formatting")
XCTAssertEqual(templateAttributes[.foregroundColor] as! UIColor, colors.purpleForegroundColor, "Incorrect template formatting")

// ") is an"
XCTAssertEqual(base2Range.location, 46, "Incorrect base formatting")
XCTAssertEqual(base2Range.length, 7, "Incorrect base formatting")
XCTAssertEqual(base2Attributes[.font] as! UIFont, fonts.baseFont, "Incorrect base formatting")
XCTAssertEqual(base2Attributes[.foregroundColor] as! UIColor, colors.baseForegroundColor, "Incorrect base formatting")
}

func testVerticalStartTemplate1() {
let string = "{{Infobox officeholder"
let mutAttributedString = NSMutableAttributedString(string: string)

@@ -651,6 +687,33 @@ final class WKSourceEditorFormatterTests: XCTestCase {
XCTAssertEqual(templateAttributes[.foregroundColor] as! UIColor, colors.purpleForegroundColor, "Incorrect template formatting")
}

func testVerticalStartTemplate2() {
let string = "ending of previous sentence. {{cite web"
let mutAttributedString = NSMutableAttributedString(string: string)

for formatter in formatters {
formatter.addSyntaxHighlighting(to: mutAttributedString, in: NSRange(location: 0, length: string.count))
}

var baseRange = NSRange(location: 0, length: 0)
let baseAttributes = mutAttributedString.attributes(at: 0, effectiveRange: &baseRange)

var templateRange = NSRange(location: 0, length: 0)
let templateAttributes = mutAttributedString.attributes(at: 29, effectiveRange: &templateRange)

// "ending of previous sentence. "
XCTAssertEqual(baseRange.location, 0, "Incorrect base formatting")
XCTAssertEqual(baseRange.length, 29, "Incorrect base formatting")
XCTAssertEqual(baseAttributes[.font] as! UIFont, fonts.baseFont, "Incorrect base formatting")
XCTAssertEqual(baseAttributes[.foregroundColor] as! UIColor, colors.baseForegroundColor, "Incorrect base formatting")

// "ending of previous sentence. "
XCTAssertEqual(templateRange.location, 29, "Incorrect template formatting")
XCTAssertEqual(templateRange.length, 10, "Incorrect template formatting")
XCTAssertEqual(templateAttributes[.font] as! UIFont, fonts.baseFont, "Incorrect template formatting")
XCTAssertEqual(templateAttributes[.foregroundColor] as! UIColor, colors.purpleForegroundColor, "Incorrect base formatting")
}

func testVerticalParameterTemplate() {
let string = "| genus = Felis"
let mutAttributedString = NSMutableAttributedString(string: string)
Original file line number Diff line number Diff line change
@@ -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)
@@ -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)

0 comments on commit 5fc651a

Please sign in to comment.