Skip to content

Commit

Permalink
Merge branch 'main' into native-editor-paragraph-header-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
tonisevener committed Jan 8, 2024
2 parents bc00a5a + dafaa2a commit 3a0a7af
Show file tree
Hide file tree
Showing 96 changed files with 1,998 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 @@ -7,6 +7,7 @@ protocol WKEditorInputViewDelegate: AnyObject {
func didTapItalics(isSelected: Bool)
func didTapTemplate(isSelected: Bool)
func didTapHeading(selectedHeading: WKEditorHeaderSelectViewModel.Configuration)
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 @@ -22,8 +22,9 @@ fileprivate var needsTextKit2: Bool {
let isSubheading2: Bool
let isSubheading3: Bool
let isSubheading4: Bool
let isStrikethrough: Bool

init(isBold: Bool, isItalics: Bool, isHorizontalTemplate: Bool, isHeading: Bool, isSubheading1: Bool, isSubheading2: Bool, isSubheading3: Bool, isSubheading4: Bool) {
init(isBold: Bool, isItalics: Bool, isHorizontalTemplate: Bool, isHeading: Bool, isSubheading1: Bool, isSubheading2: Bool, isSubheading3: Bool, isSubheading4: Bool, isStrikethrough: Bool) {
self.isBold = isBold
self.isItalics = isItalics
self.isHorizontalTemplate = isHorizontalTemplate
Expand All @@ -32,7 +33,7 @@ fileprivate var needsTextKit2: Bool {
self.isSubheading2 = isSubheading2
self.isSubheading3 = isSubheading3
self.isSubheading4 = isSubheading4

self.isStrikethrough = isStrikethrough
}
}

Expand All @@ -47,6 +48,7 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {
private(set) var boldItalicsFormatter: WKSourceEditorFormatterBoldItalics?
private(set) var templateFormatter: WKSourceEditorFormatterTemplate?
private(set) var headingFormatter: WKSourceEditorFormatterHeading?
private(set) var strikethroughFormatter: WKSourceEditorFormatterStrikethrough?

var isSyntaxHighlightingEnabled: Bool = true {
didSet {
Expand Down Expand Up @@ -116,13 +118,16 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {
let boldItalicsFormatter = WKSourceEditorFormatterBoldItalics(colors: colors, fonts: fonts)
let templateFormatter = WKSourceEditorFormatterTemplate(colors: colors, fonts: fonts)
let headingFormatter = WKSourceEditorFormatterHeading(colors: colors, fonts: fonts)
let strikethroughFormatter = WKSourceEditorFormatterStrikethrough(colors: colors, fonts: fonts)
self.formatters = [WKSourceEditorFormatterBase(colors: colors, fonts: fonts, textAlignment: viewModel.textAlignment),
templateFormatter,
boldItalicsFormatter,
headingFormatter]
headingFormatter,
strikethroughFormatter]
self.boldItalicsFormatter = boldItalicsFormatter
self.templateFormatter = templateFormatter
self.headingFormatter = headingFormatter
self.strikethroughFormatter = strikethroughFormatter

if needsTextKit2 {
if #available(iOS 16.0, *) {
Expand Down Expand Up @@ -162,7 +167,7 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {

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

let isBold = boldItalicsFormatter?.attributedString(textKit2Data.paragraphAttributedString, isBoldIn: textKit2Data.paragraphSelectedRange) ?? false
Expand All @@ -173,11 +178,12 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {
let isSubheading2 = headingFormatter?.attributedString(textKit2Data.paragraphAttributedString, isSubheading2In: textKit2Data.paragraphSelectedRange) ?? false
let isSubheading3 = headingFormatter?.attributedString(textKit2Data.paragraphAttributedString, isSubheading3In: textKit2Data.paragraphSelectedRange) ?? false
let isSubheading4 = headingFormatter?.attributedString(textKit2Data.paragraphAttributedString, isSubheading4In: textKit2Data.paragraphSelectedRange) ?? false
let isStrikethrough = strikethroughFormatter?.attributedString(textKit2Data.paragraphAttributedString, isStrikethroughIn: textKit2Data.paragraphSelectedRange) ?? false

return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate, isHeading: isHeading, isSubheading1: isSubheading1, isSubheading2: isSubheading2, isSubheading3: isSubheading3, isSubheading4: isSubheading4)
return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate, isHeading: isHeading, isSubheading1: isSubheading1, isSubheading2: isSubheading2, isSubheading3: isSubheading3, isSubheading4: isSubheading4, isStrikethrough: isStrikethrough)
} else {
guard let textKit1Storage else {
return WKSourceEditorSelectionState(isBold: false, isItalics: false, isHorizontalTemplate: false, isHeading: false, isSubheading1: false, isSubheading2: false, isSubheading3: false, isSubheading4: false)
return WKSourceEditorSelectionState(isBold: false, isItalics: false, isHorizontalTemplate: false, isHeading: false, isSubheading1: false, isSubheading2: false, isSubheading3: false, isSubheading4: false, isStrikethrough: false)
}

let isBold = boldItalicsFormatter?.attributedString(textKit1Storage, isBoldIn: selectedDocumentRange) ?? false
Expand All @@ -188,8 +194,9 @@ final class WKSourceEditorTextFrameworkMediator: NSObject {
let isSubheading2 = headingFormatter?.attributedString(textKit1Storage, isSubheading2In: selectedDocumentRange) ?? false
let isSubheading3 = headingFormatter?.attributedString(textKit1Storage, isSubheading3In: selectedDocumentRange) ?? false
let isSubheading4 = headingFormatter?.attributedString(textKit1Storage, isSubheading4In: selectedDocumentRange) ?? false
let isStrikethrough = strikethroughFormatter?.attributedString(textKit1Storage, isStrikethroughIn: selectedDocumentRange) ?? false

return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate, isHeading: isHeading, isSubheading1: isSubheading1, isSubheading2: isSubheading2, isSubheading3: isSubheading3, isSubheading4: isSubheading4)
return WKSourceEditorSelectionState(isBold: isBold, isItalics: isItalics, isHorizontalTemplate: isHorizontalTemplate, isHeading: isHeading, isSubheading1: isSubheading1, isSubheading2: isSubheading2, isSubheading3: isSubheading3, isSubheading4: isSubheading4, isStrikethrough: isStrikethrough)
}
}

Expand Down Expand Up @@ -226,6 +233,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 @@ -365,6 +365,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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface WKSourceEditorFormatter : NSObject

extern NSString *const WKSourceEditorCustomKeyColorOrange;
extern NSString *const WKSourceEditorCustomKeyColorGreen;

- (instancetype)initWithColors:(nonnull WKSourceEditorColors *)colors fonts:(nonnull WKSourceEditorFonts *)fonts;
- (void)addSyntaxHighlightingToAttributedString:(NSMutableAttributedString *)attributedString inRange:(NSRange)range;
Expand Down
2 changes: 2 additions & 0 deletions Components/Sources/ComponentsObjC/WKSourceEditorFormatter.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
@implementation WKSourceEditorFormatter

#pragma mark - Common Custom Attributed String Keys

// Font and Color custom attributes allow us to easily target already-formatted ranges. This is handy for speedy updates upon theme and text size change, as well as determining keyboard button selection states.
NSString * const WKSourceEditorCustomKeyColorOrange = @"WKSourceEditorKeyColorOrange";
NSString * const WKSourceEditorCustomKeyColorGreen = @"WKSourceEditorKeyColorGreen";

- (nonnull instancetype)initWithColors:(nonnull WKSourceEditorColors *)colors fonts:(nonnull WKSourceEditorFonts *)fonts {
self = [super init];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ - (void)addSyntaxHighlightingToAttributedString:(NSMutableAttributedString *)att

// reset shared custom attributes
[attributedString removeAttribute:WKSourceEditorCustomKeyColorOrange range:range];
[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 @@ -282,6 +282,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 @@ -308,6 +316,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 3a0a7af

Please sign in to comment.