Skip to content

Commit

Permalink
Merge branch 'main' into native-editor-template-syntax-highlight-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tonisevener authored Jan 8, 2024
2 parents 91eac86 + dafaa2a commit a171594
Show file tree
Hide file tree
Showing 96 changed files with 2,007 additions and 127 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@ class WKEditorToolbarGroupedCell: UITableViewCell {

// MARK: - Properties

private lazy var componentView: UIView = {
let view = UINib(nibName: String(describing: WKEditorToolbarGroupedView.self), bundle: Bundle.module).instantiate(withOwner: nil).first as! UIView
private lazy var componentView: WKEditorToolbarGroupedView = {
let view = UINib(nibName: String(describing: WKEditorToolbarGroupedView.self), bundle: Bundle.module).instantiate(withOwner: nil).first as! WKEditorToolbarGroupedView

return view
}()

var delegate: WKEditorInputViewDelegate? {
get {
return componentView.delegate
}
set {
componentView.delegate = newValue
}
}

// MARK: - Lifecycle

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class WKEditorToolbarGroupedView: WKEditorToolbarView {
@IBOutlet private weak var underlineButton: WKEditorToolbarButton!
@IBOutlet private weak var strikethroughButton: WKEditorToolbarButton!

weak var delegate: WKEditorInputViewDelegate?

// MARK: - Lifecycle

override func awakeFromNib() {
Expand Down Expand Up @@ -49,6 +51,18 @@ class WKEditorToolbarGroupedView: WKEditorToolbarView {
strikethroughButton.setImage(WKSFSymbolIcon.for(symbol: .strikethrough), for: .normal)
strikethroughButton.addTarget(self, action: #selector(tappedStrikethrough), for: .touchUpInside)
strikethroughButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current?.accessibilityLabelButtonStrikethrough

NotificationCenter.default.addObserver(self, selector: #selector(updateButtonSelectionState(_:)), name: Notification.WKSourceEditorSelectionState, object: nil)
}

// MARK: - Notifications

@objc private func updateButtonSelectionState(_ notification: NSNotification) {
guard let selectionState = notification.userInfo?[Notification.WKSourceEditorSelectionStateKey] as? WKSourceEditorSelectionState else {
return
}

strikethroughButton.isSelected = selectionState.isStrikethrough
}

// MARK: - Button Actions
Expand All @@ -75,6 +89,7 @@ class WKEditorToolbarGroupedView: WKEditorToolbarView {
}

@objc private func tappedStrikethrough() {
delegate?.didTapStrikethrough(isSelected: strikethroughButton.isSelected)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ extension WKEditorInputMainViewController: UITableViewDataSource {
cell.selectionStyle = .none
case 1:
cell = tableView.dequeueReusableCell(withIdentifier: groupedReuseIdentifier, for: indexPath)

if let groupedCell = cell as? WKEditorToolbarGroupedCell {
groupedCell.delegate = delegate
}

cell.selectionStyle = .none
case 2:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ protocol WKEditorInputViewDelegate: AnyObject {
func didTapBold(isSelected: Bool)
func didTapItalics(isSelected: Bool)
func didTapTemplate(isSelected: Bool)
func didTapStrikethrough(isSelected: Bool)
}

class WKEditorInputViewController: WKComponentViewController {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation
import ComponentsObjC

extension WKSourceEditorFormatterStrikethrough {
func toggleStrikethroughFormatting(action: WKSourceEditorFormatterButtonAction, in textView: UITextView) {
toggleFormatting(startingFormattingString: "<s>", endingFormattingString: "</s>", action: action, in: textView)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ fileprivate var needsTextKit2: Bool {
let isBold: Bool
let isItalics: Bool
let isHorizontalTemplate: Bool
let isStrikethrough: Bool

init(isBold: Bool, isItalics: Bool, isHorizontalTemplate: Bool) {
init(isBold: Bool, isItalics: Bool, isHorizontalTemplate: Bool, isStrikethrough: Bool) {
self.isBold = isBold
self.isItalics = isItalics
self.isHorizontalTemplate = isHorizontalTemplate
self.isStrikethrough = isStrikethrough
}
}

Expand All @@ -35,6 +37,7 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {
private(set) var formatters: [WKSourceEditorFormatter] = []
private(set) var boldItalicsFormatter: WKSourceEditorFormatterBoldItalics?
private(set) var templateFormatter: WKSourceEditorFormatterTemplate?
private(set) var strikethroughFormatter: WKSourceEditorFormatterStrikethrough?

var isSyntaxHighlightingEnabled: Bool = true {
didSet {
Expand Down Expand Up @@ -103,11 +106,15 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {

let boldItalicsFormatter = WKSourceEditorFormatterBoldItalics(colors: colors, fonts: fonts)
let templateFormatter = WKSourceEditorFormatterTemplate(colors: colors, fonts: fonts)
let strikethroughFormatter = WKSourceEditorFormatterStrikethrough(colors: colors, fonts: fonts)

self.formatters = [WKSourceEditorFormatterBase(colors: colors, fonts: fonts, textAlignment: viewModel.textAlignment),
templateFormatter,
boldItalicsFormatter]
boldItalicsFormatter,
strikethroughFormatter]
self.boldItalicsFormatter = boldItalicsFormatter
self.templateFormatter = templateFormatter
self.strikethroughFormatter = strikethroughFormatter

if needsTextKit2 {
if #available(iOS 16.0, *) {
Expand Down Expand Up @@ -147,24 +154,26 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {

if needsTextKit2 {
guard let textKit2Data = textkit2SelectionData(selectedDocumentRange: selectedDocumentRange) else {
return WKSourceEditorSelectionState(isBold: false, isItalics: false, isHorizontalTemplate: false)
return WKSourceEditorSelectionState(isBold: false, isItalics: false, isHorizontalTemplate: false, isStrikethrough: false)
}

let isBold = boldItalicsFormatter?.attributedString(textKit2Data.paragraphAttributedString, isBoldIn: textKit2Data.paragraphSelectedRange) ?? false
let isItalics = boldItalicsFormatter?.attributedString(textKit2Data.paragraphAttributedString, isItalicsIn: textKit2Data.paragraphSelectedRange) ?? false
let isHorizontalTemplate = templateFormatter?.attributedString(textKit2Data.paragraphAttributedString, isHorizontalTemplateIn: textKit2Data.paragraphSelectedRange) ?? false
let isStrikethrough = strikethroughFormatter?.attributedString(textKit2Data.paragraphAttributedString, isStrikethroughIn: textKit2Data.paragraphSelectedRange) ?? false

return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate)
return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate, isStrikethrough: isStrikethrough)
} else {
guard let textKit1Storage else {
return WKSourceEditorSelectionState(isBold: false, isItalics: false, isHorizontalTemplate: false)
return WKSourceEditorSelectionState(isBold: false, isItalics: false, isHorizontalTemplate: false, isStrikethrough: false)
}

let isBold = boldItalicsFormatter?.attributedString(textKit1Storage, isBoldIn: selectedDocumentRange) ?? false
let isItalics = boldItalicsFormatter?.attributedString(textKit1Storage, isItalicsIn: selectedDocumentRange) ?? false
let isHorizontalTemplate = templateFormatter?.attributedString(textKit1Storage, isHorizontalTemplateIn: selectedDocumentRange) ?? false
let isStrikethrough = strikethroughFormatter?.attributedString(textKit1Storage, isStrikethroughIn: selectedDocumentRange) ?? false

return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate)
return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate, isStrikethrough: isStrikethrough)
}
}

Expand Down Expand Up @@ -201,6 +210,7 @@ extension WKSourceEditorTextFrameworkMediator: WKSourceEditorStorageDelegate {
colors.baseForegroundColor = WKAppEnvironment.current.theme.text
colors.orangeForegroundColor = isSyntaxHighlightingEnabled ? WKAppEnvironment.current.theme.editorOrange : WKAppEnvironment.current.theme.text
colors.purpleForegroundColor = isSyntaxHighlightingEnabled ? WKAppEnvironment.current.theme.editorPurple : WKAppEnvironment.current.theme.text
colors.greenForegroundColor = isSyntaxHighlightingEnabled ? WKAppEnvironment.current.theme.editorGreen : WKAppEnvironment.current.theme.text
return colors
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ extension WKSourceEditorViewController: WKEditorInputViewDelegate {
textFrameworkMediator.templateFormatter?.toggleTemplateFormatting(action: action, in: textView)
}

func didTapStrikethrough(isSelected: Bool) {
let action: WKSourceEditorFormatterButtonAction = isSelected ? .remove : .add
textFrameworkMediator.strikethroughFormatter?.toggleStrikethroughFormatting(action: action, in: textView)
}

func didTapClose() {
inputViewType = nil
let isRangeSelected = textView.selectedRange.length > 0
Expand Down
13 changes: 9 additions & 4 deletions Components/Sources/Components/Style/WKTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public struct WKTheme: Equatable {
public let diffCompareAccent: UIColor
public let editorOrange: UIColor
public let editorPurple: UIColor
public let editorGreen: UIColor

public static let light = WKTheme(
name: "Light",
Expand All @@ -50,7 +51,8 @@ public struct WKTheme: Equatable {
keyboardBarSearchFieldBackground: WKColor.gray200,
diffCompareAccent: WKColor.orange600,
editorOrange: WKColor.orange600,
editorPurple: WKColor.purple600
editorPurple: WKColor.purple600,
editorGreen: WKColor.green600
)

public static let sepia = WKTheme(
Expand All @@ -76,7 +78,8 @@ public struct WKTheme: Equatable {
keyboardBarSearchFieldBackground: WKColor.gray200,
diffCompareAccent: WKColor.orange600,
editorOrange: WKColor.orange600,
editorPurple: WKColor.purple600
editorPurple: WKColor.purple600,
editorGreen: WKColor.green600
)

public static let dark = WKTheme(
Expand All @@ -102,7 +105,8 @@ public struct WKTheme: Equatable {
keyboardBarSearchFieldBackground: WKColor.gray650,
diffCompareAccent: WKColor.orange600,
editorOrange: WKColor.yellow600,
editorPurple: WKColor.red100
editorPurple: WKColor.red100,
editorGreen: WKColor.green600
)

public static let black = WKTheme(
Expand All @@ -128,7 +132,8 @@ public struct WKTheme: Equatable {
keyboardBarSearchFieldBackground: WKColor.gray650,
diffCompareAccent: WKColor.orange600,
editorOrange: WKColor.yellow600,
editorPurple: WKColor.red100
editorPurple: WKColor.red100,
editorGreen: WKColor.green600
)

}
1 change: 1 addition & 0 deletions Components/Sources/ComponentsObjC/WKSourceEditorColors.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) UIColor *baseForegroundColor;
@property (nonatomic, strong) UIColor *orangeForegroundColor;
@property (nonatomic, strong) UIColor *purpleForegroundColor;
@property (nonatomic, strong) UIColor *greenForegroundColor;
@end

NS_ASSUME_NONNULL_END
3 changes: 3 additions & 0 deletions Components/Sources/ComponentsObjC/WKSourceEditorFormatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
NS_ASSUME_NONNULL_BEGIN

@interface WKSourceEditorFormatter : NSObject

extern NSString *const WKSourceEditorCustomKeyColorGreen;

- (instancetype)initWithColors:(nonnull WKSourceEditorColors *)colors fonts:(nonnull WKSourceEditorFonts *)fonts;
- (void)addSyntaxHighlightingToAttributedString:(NSMutableAttributedString *)attributedString inRange:(NSRange)range;

Expand Down
5 changes: 5 additions & 0 deletions Components/Sources/ComponentsObjC/WKSourceEditorFormatter.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#import "WKSourceEditorFonts.h"

@implementation WKSourceEditorFormatter

#pragma mark - Common Custom Attributed String Keys

NSString * const WKSourceEditorCustomKeyColorGreen = @"WKSourceEditorKeyColorGreen";

- (nonnull instancetype)initWithColors:(nonnull WKSourceEditorColors *)colors fonts:(nonnull WKSourceEditorFonts *)fonts {
self = [super init];
return self;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ - (instancetype)initWithColors:(nonnull WKSourceEditorColors *)colors fonts:(non

- (void)addSyntaxHighlightingToAttributedString:(NSMutableAttributedString *)attributedString inRange:(NSRange)range {

// reset old attributes
// reset base attributes
[attributedString removeAttribute:NSFontAttributeName range:range];
[attributedString removeAttribute:NSForegroundColorAttributeName range:range];

// reset shared custom attributes
[attributedString removeAttribute:WKSourceEditorCustomKeyColorGreen range:range];

[attributedString addAttributes:self.attributes range:range];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,14 @@ - (BOOL)attributedString:(NSMutableAttributedString *)attributedString isBoldInR

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;
}
}
}
}

Expand All @@ -312,6 +320,14 @@ - (BOOL)attributedString:(NSMutableAttributedString *)attributedString isItalics

if (attrs[WKSourceEditorCustomKeyFontBoldItalics] != nil || attrs[WKSourceEditorCustomKeyFontItalics] != nil) {
isItalics = 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;
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#import "WKSourceEditorFormatter.h"

NS_ASSUME_NONNULL_BEGIN

@interface WKSourceEditorFormatterStrikethrough : WKSourceEditorFormatter

- (BOOL)attributedString:(NSMutableAttributedString *)attributedString isStrikethroughInRange:(NSRange)range;

@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit a171594

Please sign in to comment.