From 13470738ccfe5455ba71df09e5691850456134b3 Mon Sep 17 00:00:00 2001 From: Toni Sevener Date: Fri, 5 Jan 2024 13:45:32 -0600 Subject: [PATCH] Add link and image button selection and enabled states, formatter cleanup --- .../Base/WKEditorToolbarButton.swift | 13 +- .../WKEditorToolbarExpandingView.swift | 12 +- .../WKEditorToolbarExpandingView.xib | 8 +- .../WKEditorToolbarHighlightView.swift | 1 + .../WKEditorToolbarPlainView.swift | 1 + .../WKSourceEditorFormatterLink.m | 166 +++++++----------- 6 files changed, 90 insertions(+), 111 deletions(-) diff --git a/Components/Sources/Components/Components/Editors/Common Views/Base/WKEditorToolbarButton.swift b/Components/Sources/Components/Components/Editors/Common Views/Base/WKEditorToolbarButton.swift index 59b10a283f7..cf60cdc87e2 100644 --- a/Components/Sources/Components/Components/Editors/Common Views/Base/WKEditorToolbarButton.swift +++ b/Components/Sources/Components/Components/Editors/Common Views/Base/WKEditorToolbarButton.swift @@ -64,7 +64,18 @@ class WKEditorToolbarButton: WKComponentView { set { button.isSelected = newValue updateColors() - accessibilityTraits = newValue ? [.button, .selected] : [.button] + accessibilityTraits = button.accessibilityTraits + } + } + + var isEnabled: Bool { + get { + return button.isEnabled + } + set { + button.isEnabled = newValue + updateColors() + accessibilityTraits = button.accessibilityTraits } } diff --git a/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.swift b/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.swift index 51b0691c643..69b61463663 100644 --- a/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.swift +++ b/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.swift @@ -46,7 +46,7 @@ class WKEditorToolbarExpandingView: WKEditorToolbarView { @IBOutlet private weak var citationButton: WKEditorToolbarButton! @IBOutlet private weak var linkButton: WKEditorToolbarButton! @IBOutlet private weak var templateButton: WKEditorToolbarButton! - @IBOutlet private weak var mediaButton: WKEditorToolbarButton! + @IBOutlet private weak var imageButton: WKEditorToolbarButton! @IBOutlet private weak var findInPageButton: WKEditorToolbarButton! @IBOutlet private weak var unorderedListButton: WKEditorToolbarButton! @@ -101,9 +101,9 @@ class WKEditorToolbarExpandingView: WKEditorToolbarView { templateButton.addTarget(self, action: #selector(tappedTemplate), for: .touchUpInside) templateButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonTemplate - mediaButton.setImage(WKSFSymbolIcon.for(symbol: .photo), for: .normal) - mediaButton.addTarget(self, action: #selector(tappedMedia), for: .touchUpInside) - mediaButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonMedia + imageButton.setImage(WKSFSymbolIcon.for(symbol: .photo), for: .normal) + imageButton.addTarget(self, action: #selector(tappedMedia), for: .touchUpInside) + imageButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonMedia findInPageButton.setImage(WKSFSymbolIcon.for(symbol: .docTextMagnifyingGlass), for: .normal) findInPageButton.addTarget(self, action: #selector(tappedFindInPage), for: .touchUpInside) @@ -140,6 +140,7 @@ class WKEditorToolbarExpandingView: WKEditorToolbarView { cursorRightButton.setImage(WKIcon.chevronRight, for: .normal) cursorRightButton.addTarget(self, action: #selector(tappedCursorRight), for: .touchUpInside) + cursorRightButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonCursorRight NotificationCenter.default.addObserver(self, selector: #selector(updateButtonSelectionState(_:)), name: Notification.WKSourceEditorSelectionState, object: nil) } @@ -152,7 +153,8 @@ class WKEditorToolbarExpandingView: WKEditorToolbarView { } templateButton.isSelected = selectionState.isHorizontalTemplate - cursorRightButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonCursorRight + linkButton.isSelected = selectionState.isSimpleLink + imageButton.isEnabled = !selectionState.isBold && !selectionState.isItalics && !selectionState.isSimpleLink } // MARK: - Button Actions diff --git a/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.xib b/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.xib index a303c68443c..1a1b1d5af93 100644 --- a/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.xib +++ b/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Expanding/WKEditorToolbarExpandingView.xib @@ -1,9 +1,9 @@ - + - + @@ -281,11 +281,11 @@ + - - + diff --git a/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Highlight/WKEditorToolbarHighlightView.swift b/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Highlight/WKEditorToolbarHighlightView.swift index 92606443801..577e5cb2c8e 100644 --- a/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Highlight/WKEditorToolbarHighlightView.swift +++ b/Components/Sources/Components/Components/Editors/Common Views/Input Accessory Views/Highlight/WKEditorToolbarHighlightView.swift @@ -81,6 +81,7 @@ class WKEditorToolbarHighlightView: WKEditorToolbarView { boldButton.isSelected = selectionState.isBold italicsButton.isSelected = selectionState.isItalics templateButton.isSelected = selectionState.isHorizontalTemplate + linkButton.isSelected = selectionState.isSimpleLink } // MARK: - Button Actions diff --git a/Components/Sources/Components/Components/Editors/Common Views/Input Views/Main/Plain Toolbar Table Item/WKEditorToolbarPlainView.swift b/Components/Sources/Components/Components/Editors/Common Views/Input Views/Main/Plain Toolbar Table Item/WKEditorToolbarPlainView.swift index 0e4ebf054a1..b39cd5a7cbd 100644 --- a/Components/Sources/Components/Components/Editors/Common Views/Input Views/Main/Plain Toolbar Table Item/WKEditorToolbarPlainView.swift +++ b/Components/Sources/Components/Components/Editors/Common Views/Input Views/Main/Plain Toolbar Table Item/WKEditorToolbarPlainView.swift @@ -55,6 +55,7 @@ class WKEditorToolbarPlainView: WKEditorToolbarView { boldButton.isSelected = selectionState.isBold italicsButton.isSelected = selectionState.isItalics templateButton.isSelected = selectionState.isHorizontalTemplate + linkButton.isSelected = selectionState.isSimpleLink } // MARK: Button Actions diff --git a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterLink.m b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterLink.m index 700a64a8460..e3547df8c5e 100644 --- a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterLink.m +++ b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterLink.m @@ -3,9 +3,8 @@ @interface WKSourceEditorFormatterLink () -@property (nonatomic, strong) NSDictionary *simpleLinkMarkupAttributes; -@property (nonatomic, strong) NSDictionary *simpleLinkContentAttributes; -@property (nonatomic, strong) NSDictionary *linkWithNestedLinkMarkupAndContentAttributes; +@property (nonatomic, strong) NSDictionary *simpleLinkAttributes; +@property (nonatomic, strong) NSDictionary *linkWithNestedLinkAttributes; @property (nonatomic, strong) NSRegularExpression *simpleLinkRegex; @property (nonatomic, strong) NSRegularExpression *linkWithNestedLinkRegex; @@ -14,9 +13,8 @@ @interface WKSourceEditorFormatterLink () #pragma mark - Custom Attributed String Keys NSString * const WKSourceEditorCustomKeyColorBlue = @"WKSourceEditorCustomKeyColorBlue"; -NSString * const WKSourceEditorCustomKeyMarkupLink = @"WKSourceEditorCustomKeyMarkupLink"; -NSString * const WKSourceEditorCustomKeyContentLink = @"WKSourceEditorCustomKeyContentLink"; -NSString * const WKSourceEditorCustomKeyMarkupAndContentLinkWithNestedLink = @"WKSourceEditorCustomKeyMarkupAndContentLinkWithNestedLink"; +NSString * const WKSourceEditorCustomKeyLink = @"WKSourceEditorCustomKeyLink"; +NSString * const WKSourceEditorCustomKeyLinkWithNestedLink = @"WKSourceEditorCustomKeyLinkWithNestedLink"; @implementation WKSourceEditorFormatterLink @@ -25,22 +23,16 @@ @implementation WKSourceEditorFormatterLink - (instancetype)initWithColors:(nonnull WKSourceEditorColors *)colors fonts:(nonnull WKSourceEditorFonts *)fonts { self = [super initWithColors:colors fonts:fonts]; if (self) { - _simpleLinkMarkupAttributes = @{ - WKSourceEditorCustomKeyMarkupLink: [NSNumber numberWithBool:YES], - NSForegroundColorAttributeName: colors.blueForegroundColor, - WKSourceEditorCustomKeyColorBlue: [NSNumber numberWithBool:YES] - }; - - _simpleLinkContentAttributes = @{ - WKSourceEditorCustomKeyContentLink: [NSNumber numberWithBool:YES], + _simpleLinkAttributes = @{ + WKSourceEditorCustomKeyLink: [NSNumber numberWithBool:YES], NSForegroundColorAttributeName: colors.blueForegroundColor, WKSourceEditorCustomKeyColorBlue: [NSNumber numberWithBool:YES] }; _simpleLinkRegex = [[NSRegularExpression alloc] initWithPattern:@"(\\[{2})([^\\[\\]\\n]*)(\\]{2})" options:0 error:nil]; - _linkWithNestedLinkMarkupAndContentAttributes = @{ - WKSourceEditorCustomKeyMarkupAndContentLinkWithNestedLink: [NSNumber numberWithBool:YES], + _linkWithNestedLinkAttributes = @{ + WKSourceEditorCustomKeyLinkWithNestedLink: [NSNumber numberWithBool:YES], NSForegroundColorAttributeName: colors.blueForegroundColor, WKSourceEditorCustomKeyColorBlue: [NSNumber numberWithBool:YES] }; @@ -57,8 +49,8 @@ - (void)addSyntaxHighlightingToAttributedString:(nonnull NSMutableAttributedStri // Reset [attributedString removeAttribute:WKSourceEditorCustomKeyColorBlue range:range]; - [attributedString removeAttribute:WKSourceEditorCustomKeyContentLink range:range]; - [attributedString removeAttribute:WKSourceEditorCustomKeyMarkupAndContentLinkWithNestedLink range:range]; + [attributedString removeAttribute:WKSourceEditorCustomKeyLink range:range]; + [attributedString removeAttribute:WKSourceEditorCustomKeyLinkWithNestedLink range:range]; // This section finds and highlights simple links that do NOT contain nested links, e.g. [[Cat]] and [[Dog|puppy]]. [self.simpleLinkRegex enumerateMatchesInString:attributedString.string @@ -71,15 +63,15 @@ - (void)addSyntaxHighlightingToAttributedString:(nonnull NSMutableAttributedStri NSRange closingRange = [result rangeAtIndex:3]; if (openingRange.location != NSNotFound) { - [attributedString addAttributes:self.simpleLinkMarkupAttributes range:openingRange]; + [attributedString addAttributes:self.simpleLinkAttributes range:openingRange]; } if (contentRange.location != NSNotFound) { - [attributedString addAttributes:self.simpleLinkContentAttributes range:contentRange]; + [attributedString addAttributes:self.simpleLinkAttributes range:contentRange]; } if (closingRange.location != NSNotFound) { - [attributedString addAttributes:self.simpleLinkMarkupAttributes range:closingRange]; + [attributedString addAttributes:self.simpleLinkAttributes range:closingRange]; } }]; @@ -99,7 +91,7 @@ - (void)addSyntaxHighlightingToAttributedString:(nonnull NSMutableAttributedStri for (NSValue *value in linkWithNestedLinkRanges) { NSRange range = [value rangeValue]; if (range.location != NSNotFound) { - [attributedString addAttributes:self.linkWithNestedLinkMarkupAndContentAttributes range:range]; + [attributedString addAttributes:self.linkWithNestedLinkAttributes range:range]; } } } @@ -108,17 +100,13 @@ - (void)addSyntaxHighlightingToAttributedString:(nonnull NSMutableAttributedStri - (void)updateColors:(WKSourceEditorColors *)colors inAttributedString:(NSMutableAttributedString *)attributedString inRange:(NSRange)range { - NSMutableDictionary *mutSimpleLinkMarkupAttributes = [[NSMutableDictionary alloc] initWithDictionary:self.simpleLinkMarkupAttributes]; - [mutSimpleLinkMarkupAttributes setObject:colors.blueForegroundColor forKey:NSForegroundColorAttributeName]; - self.simpleLinkMarkupAttributes = [[NSDictionary alloc] initWithDictionary:mutSimpleLinkMarkupAttributes]; - - NSMutableDictionary *mutSimpleLinkContentAttributes = [[NSMutableDictionary alloc] initWithDictionary:self.simpleLinkContentAttributes]; - [mutSimpleLinkContentAttributes setObject:colors.blueForegroundColor forKey:NSForegroundColorAttributeName]; - self.simpleLinkContentAttributes = [[NSDictionary alloc] initWithDictionary:mutSimpleLinkContentAttributes]; + NSMutableDictionary *mutSimpleLinkAttributes = [[NSMutableDictionary alloc] initWithDictionary:self.simpleLinkAttributes]; + [mutSimpleLinkAttributes setObject:colors.blueForegroundColor forKey:NSForegroundColorAttributeName]; + self.simpleLinkAttributes = [[NSDictionary alloc] initWithDictionary:mutSimpleLinkAttributes]; - NSMutableDictionary *mutLinkWithNestedLinkMarkupAndContentAttributes = [[NSMutableDictionary alloc] initWithDictionary:self.linkWithNestedLinkMarkupAndContentAttributes]; - [mutLinkWithNestedLinkMarkupAndContentAttributes setObject:colors.blueForegroundColor forKey:NSForegroundColorAttributeName]; - self.linkWithNestedLinkMarkupAndContentAttributes = [[NSDictionary alloc] initWithDictionary:mutLinkWithNestedLinkMarkupAndContentAttributes]; + NSMutableDictionary *mutLinkWithNestedLinkAttributes = [[NSMutableDictionary alloc] initWithDictionary:self.linkWithNestedLinkAttributes]; + [mutLinkWithNestedLinkAttributes setObject:colors.blueForegroundColor forKey:NSForegroundColorAttributeName]; + self.linkWithNestedLinkAttributes = [[NSDictionary alloc] initWithDictionary:mutLinkWithNestedLinkAttributes]; [attributedString enumerateAttribute:WKSourceEditorCustomKeyColorBlue inRange:range @@ -140,79 +128,12 @@ - (void)updateFonts:(WKSourceEditorFonts *)fonts inAttributedString:(NSMutableAt #pragma mark - Public - (BOOL)attributedString:(NSMutableAttributedString *)attributedString isSimpleLinkInRange:(NSRange)range { - __block BOOL isContentKey = NO; - if (range.length == 0) { - - if (attributedString.length > range.location) { - NSDictionary *attrs = [attributedString attributesAtIndex:range.location effectiveRange:nil]; - - if (attrs[WKSourceEditorCustomKeyContentLink] != nil) { - isContentKey = YES; - } else { - // Edge case, check previous character if we are up against closing markup - if (attrs[WKSourceEditorCustomKeyMarkupLink]) { - attrs = [attributedString attributesAtIndex:range.location - 1 effectiveRange:nil]; - if (attrs[WKSourceEditorCustomKeyContentLink] != nil) { - isContentKey = YES; - } - } - } - } - - } else { - __block NSRange unionRange = NSMakeRange(NSNotFound, 0); - [attributedString enumerateAttributesInRange:range options:nil usingBlock:^(NSDictionary * _Nonnull attrs, NSRange loopRange, BOOL * _Nonnull stop) { - if (attrs[WKSourceEditorCustomKeyContentLink] != nil) { - if (unionRange.location == NSNotFound) { - unionRange = loopRange; - } else { - unionRange = NSUnionRange(unionRange, loopRange); - } - stop = YES; - } - }]; - - if (NSEqualRanges(unionRange, range)) { - isContentKey = YES; - } - } - - return isContentKey; + return [self attributedString:attributedString isKey:WKSourceEditorCustomKeyLink inRange:range]; } - (BOOL)attributedString:(NSMutableAttributedString *)attributedString isLinkWithNestedLinkInRange:(NSRange)range { - __block BOOL isKey = NO; - if (range.length == 0) { - - if (attributedString.length > range.location) { - NSDictionary *attrs = [attributedString attributesAtIndex:range.location effectiveRange:nil]; - - if (attrs[WKSourceEditorCustomKeyMarkupAndContentLinkWithNestedLink] != nil) { - isKey = YES; - } - } - - } else { - __block NSRange unionRange = NSMakeRange(NSNotFound, 0); - [attributedString enumerateAttributesInRange:range options:nil usingBlock:^(NSDictionary * _Nonnull attrs, NSRange loopRange, BOOL * _Nonnull stop) { - if (attrs[WKSourceEditorCustomKeyMarkupAndContentLinkWithNestedLink] != nil) { - if (unionRange.location == NSNotFound) { - unionRange = loopRange; - } else { - unionRange = NSUnionRange(unionRange, loopRange); - } - stop = YES; - } - }]; - - if (NSEqualRanges(unionRange, range)) { - isKey = YES; - } - } - - return isKey; - + return [self attributedString:attributedString isKey:WKSourceEditorCustomKeyLinkWithNestedLink inRange:range]; } #pragma mark - Private @@ -276,4 +197,47 @@ - (NSArray *)linkWithNestedLinkRangesInString: (NSString *)string startingIndex: return [[NSArray alloc] initWithArray:completedLinkWithNestedLinkRanges]; } +- (BOOL)attributedString:(NSMutableAttributedString *)attributedString isKey:(NSString *)key inRange:(NSRange)range { + __block BOOL isKey = NO; + if (range.length == 0) { + + if (attributedString.length > range.location) { + NSDictionary *attrs = [attributedString attributesAtIndex:range.location effectiveRange:nil]; + + if (attrs[key] != nil) { + isKey = YES; + } + + // Edge case, check previous character if we are up against opening markup + if (attrs[WKSourceEditorCustomKeyLink]) { + if (attributedString.length > range.location - 1) { + attrs = [attributedString attributesAtIndex:range.location - 1 effectiveRange:nil]; + if (attrs[key] == nil) { + isKey = NO; + } + } + } + } + + } else { + __block NSRange unionRange = NSMakeRange(NSNotFound, 0); + [attributedString enumerateAttributesInRange:range options:nil usingBlock:^(NSDictionary * _Nonnull attrs, NSRange loopRange, BOOL * _Nonnull stop) { + if (attrs[key] != nil) { + if (unionRange.location == NSNotFound) { + unionRange = loopRange; + } else { + unionRange = NSUnionRange(unionRange, loopRange); + } + stop = YES; + } + }]; + + if (NSEqualRanges(unionRange, range)) { + isKey = YES; + } + } + + return isKey; +} + @end