Skip to content

Commit

Permalink
Merge branch 'main' into native-editor-new-input-view
Browse files Browse the repository at this point in the history
  • Loading branch information
mazevedofs authored Jan 9, 2024
2 parents 55dff0b + 2cce0df commit d3a48e4
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 <s>Strikethrough text here</s>
// To:
// Testing <s>Strikethrough </s>text<s> here</s>
// 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 <s>Strikethrough </s>text<s> here</s>
// To:
// Testing <s>Strikethrough text here</s>
// 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)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<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;
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<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
Expand Up @@ -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];
}
Expand Down Expand Up @@ -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
Expand All @@ -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];
}

}];
}

Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit d3a48e4

Please sign in to comment.