diff --git a/Components/Sources/Components/Components/Editors/Source Editor/Formatter Extensions/WKSourceEditorFormatter+ButtonActions.swift b/Components/Sources/Components/Components/Editors/Source Editor/Formatter Extensions/WKSourceEditorFormatter+ButtonActions.swift
index e0e70e9d2f6..2095711d9fa 100644
--- a/Components/Sources/Components/Components/Editors/Source Editor/Formatter Extensions/WKSourceEditorFormatter+ButtonActions.swift
+++ b/Components/Sources/Components/Components/Editors/Source Editor/Formatter Extensions/WKSourceEditorFormatter+ButtonActions.swift
@@ -16,19 +16,63 @@ extension WKSourceEditorFormatter {
func toggleFormatting(startingFormattingString: String, endingFormattingString: String, action: WKSourceEditorFormatterButtonAction, in textView: UITextView) {
- switch action {
- case .remove:
- expandSelectedRangeUpToNearestFormattingStrings(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
-
- if selectedRangeIsSurroundedByFormattingStrings(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView) {
- removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ if textView.selectedRange.length == 0 {
+ switch action {
+ case .remove:
+ expandSelectedRangeUpToNearestFormattingStrings(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+
+ if selectedRangeIsSurroundedByFormattingStrings(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView) {
+ removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ }
+ case .add:
+ if selectedRangeIsSurroundedByFormattingStrings(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView) {
+ removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ } else {
+ addStringFormattingCharacters(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ }
}
- case .add:
- if textView.selectedRange.length == 0 &&
- selectedRangeIsSurroundedByFormattingStrings(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView) {
- removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
- } else {
- addStringFormattingCharacters(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ } else {
+
+ switch action {
+ case .remove:
+
+ if selectedRangeIsSurroundedByFormattingStrings(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView) {
+ removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ } else {
+
+ // Note the flipped formatting string params.
+ // For example, this takes selected 'text' from:
+ // Testing Strikethrough text here
+ // To:
+ // Testing Strikethrough text here
+ // We have to add formatters in reverse order to remove formatting from 'text'
+
+ addStringFormattingCharacters(startingFormattingString: endingFormattingString, endingFormattingString: startingFormattingString, in: textView)
+ }
+
+ case .add:
+
+ // Note: gross workaround to prevent italics misfire from continuing below
+ if startingFormattingString == "''" && endingFormattingString == "''" {
+ if selectedRangeIsSurroundedByFormattingString(formattingString: "''", in: textView) &&
+ selectedRangeIsSurroundedByFormattingString(formattingString: "'''", in: textView) {
+ addStringFormattingCharacters(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ return
+ }
+ }
+
+ // Note the flipped formatting string params.
+ // For example, this takes selected 'text' from:
+ // Testing Strikethrough text here
+ // To:
+ // Testing Strikethrough text here
+ // We have to check and remove formatters in reverse order to add formatting to 'text'
+
+ if selectedRangeIsSurroundedByFormattingStrings(startingFormattingString: endingFormattingString, endingFormattingString: startingFormattingString, in: textView) {
+ removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: endingFormattingString, endingFormattingString: startingFormattingString, in: textView)
+ } else {
+ addStringFormattingCharacters(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
+ }
}
}
}
diff --git a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterBoldItalics.m b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterBoldItalics.m
index f376e5eec50..990d0573a3e 100644
--- a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterBoldItalics.m
+++ b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterBoldItalics.m
@@ -278,70 +278,54 @@ - (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 *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 * _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 *attrs = [attributedString attributesAtIndex:range.location effectiveRange:nil];
-
- if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontItalics] != nil) {
- isItalics = YES;
+ if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[formattingKey] != nil) {
+ 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[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[formattingKey] != nil) {
+ isFormatted = YES;
}
}
}
}
} else {
+
+ __block NSRange unionRange = NSMakeRange(NSNotFound, 0);
[attributedString enumerateAttributesInRange:range options:nil usingBlock:^(NSDictionary * _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
diff --git a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterTemplate.m b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterTemplate.m
index 5d6272f4a8c..b2e5bc1e321 100644
--- a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterTemplate.m
+++ b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterTemplate.m
@@ -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 * _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;
diff --git a/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift b/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift
index 35d8f3b5a64..5fd35883a8c 100644
--- a/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift
+++ b/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift
@@ -42,7 +42,7 @@ final class WKSourceEditorFormatterButtonActionTests: XCTestCase {
XCTAssertEqual(mediator.textView.attributedText.string, "One Two Three Four")
}
- func testSingleBoldRemove() throws {
+ func testCursorBoldRemove() throws {
let text = "One '''Two''' Three Four"
mediator.textView.attributedText = NSAttributedString(string: text)
mediator.textView.selectedRange = NSRange(location: 8, length: 0) // Just a cursor inside Two
@@ -50,7 +50,7 @@ final class WKSourceEditorFormatterButtonActionTests: XCTestCase {
XCTAssertEqual(mediator.textView.attributedText.string, "One Two Three Four")
}
- func testSingleItalicsRemove() throws {
+ func testCursorItalicsRemove() throws {
let text = "One Two '''Three''' Four"
mediator.textView.attributedText = NSAttributedString(string: text)
mediator.textView.selectedRange = NSRange(location: 14, length: 0)
@@ -77,7 +77,7 @@ final class WKSourceEditorFormatterButtonActionTests: XCTestCase {
XCTAssertEqual(mediator.textView.attributedText.string, "One Two Three Four")
}
- func testSingleBoldInsertAndRemove() throws {
+ func testCursorBoldInsertAndRemove() throws {
let text = "One Two Three Four"
mediator.textView.attributedText = NSAttributedString(string: text)
mediator.textView.selectedRange = NSRange(location: 4, length: 0) // Just a cursor before Two
@@ -87,7 +87,7 @@ final class WKSourceEditorFormatterButtonActionTests: XCTestCase {
XCTAssertEqual(mediator.textView.attributedText.string, "One Two Three Four")
}
- func testSingleItalicsInsertAndRemove() throws {
+ func testCursorItalicsInsertAndRemove() throws {
let text = "One Two Three Four"
mediator.textView.attributedText = NSAttributedString(string: text)
mediator.textView.selectedRange = NSRange(location: 4, length: 0) // Just a cursor before Two
@@ -97,6 +97,46 @@ final class WKSourceEditorFormatterButtonActionTests: XCTestCase {
XCTAssertEqual(mediator.textView.attributedText.string, "One Two Three Four")
}
+ func testBoldInnerRemoveAndInsert() throws {
+ let text = "One '''Two Three Four''' Five"
+ mediator.textView.attributedText = NSAttributedString(string: text)
+ mediator.textView.selectedRange = NSRange(location: 11, length: 5) // Selected Three
+ mediator.boldItalicsFormatter?.toggleBoldFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One '''Two '''Three''' Four''' Five")
+ mediator.boldItalicsFormatter?.toggleBoldFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One '''Two Three Four''' Five")
+ }
+
+ func testItalicsInnerRemoveAndInsert() throws {
+ let text = "One ''Two Three Four'' Five"
+ mediator.textView.attributedText = NSAttributedString(string: text)
+ mediator.textView.selectedRange = NSRange(location: 10, length: 5) // Selected Three
+ mediator.boldItalicsFormatter?.toggleItalicsFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One ''Two ''Three'' Four'' Five")
+ mediator.boldItalicsFormatter?.toggleItalicsFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One ''Two Three Four'' Five")
+ }
+
+ func testBoldItalicsInnerRemoveBoldAndInsert() throws {
+ let text = "One '''''Two Three Four''''' Five"
+ mediator.textView.attributedText = NSAttributedString(string: text)
+ mediator.textView.selectedRange = NSRange(location: 13, length: 5) // Selected Three
+ mediator.boldItalicsFormatter?.toggleBoldFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One '''''Two '''Three''' Four''''' Five")
+ mediator.boldItalicsFormatter?.toggleBoldFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One '''''Two Three Four''''' Five")
+ }
+
+ func testBoldItalicsInnerRemoveItalicsAndInsert() throws {
+ let text = "One '''''Two Three Four''''' Five"
+ mediator.textView.attributedText = NSAttributedString(string: text)
+ mediator.textView.selectedRange = NSRange(location: 13, length: 5) // Selected Three
+ mediator.boldItalicsFormatter?.toggleItalicsFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One '''''Two ''Three'' Four''''' Five")
+ mediator.boldItalicsFormatter?.toggleItalicsFormatting(action: .remove, in: mediator.textView)
+ XCTAssertEqual(mediator.textView.attributedText.string, "One '''''Two Three Four''''' Five")
+ }
+
func testTemplateInsert() throws {
let text = "One Two Three Four"
mediator.textView.attributedText = NSAttributedString(string: text)
@@ -113,7 +153,7 @@ final class WKSourceEditorFormatterButtonActionTests: XCTestCase {
XCTAssertEqual(mediator.textView.attributedText.string, "One Two Three Four")
}
- func testSingleTemplateInsertAndRemove() throws {
+ func testCursorTemplateInsertAndRemove() throws {
let text = "One Two Three Four"
mediator.textView.attributedText = NSAttributedString(string: text)
mediator.textView.selectedRange = NSRange(location: 4, length: 0) // Just a cursor before Two
diff --git a/Components/Tests/ComponentsTests/WKSourceEditorFormatterTests.swift b/Components/Tests/ComponentsTests/WKSourceEditorFormatterTests.swift
index a3764296794..499e3bcb247 100644
--- a/Components/Tests/ComponentsTests/WKSourceEditorFormatterTests.swift
+++ b/Components/Tests/ComponentsTests/WKSourceEditorFormatterTests.swift
@@ -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)
diff --git a/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift b/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift
index f9e23050c16..5aa38f420ed 100644
--- a/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift
+++ b/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift
@@ -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 Strikethrough Testing."
mediator.textView.attributedText = NSAttributedString(string: text)