Skip to content

Commit

Permalink
Merge branch 'main' into native-editor-links-images
Browse files Browse the repository at this point in the history
  • Loading branch information
tonisevener committed Jan 10, 2024
2 parents 8008601 + 32b31ed commit 9a48957
Show file tree
Hide file tree
Showing 25 changed files with 1,713 additions and 211 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ class WKEditorToolbarButton: WKComponentView {
}
}

var isEnabled: Bool {
get {
return button.isEnabled
}
set {
button.isEnabled = newValue
updateColors()
accessibilityTraits = newValue ? [.button, .selected] : [.button, .notEnabled]
}
}

func setImage(_ image: UIImage?, for state: UIControl.State) {
button.setImage(image, for: state)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ protocol WKEditorToolbarExpandingViewDelegate: AnyObject {
func toolbarExpandingViewDidTapTemplate(toolbarView: WKEditorToolbarExpandingView, isSelected: Bool)
func toolbarExpandingViewDidTapLink(toolbarView: WKEditorToolbarExpandingView, isSelected: Bool)
func toolbarExpandingViewDidTapImage(toolbarView: WKEditorToolbarExpandingView)
func toolbarExpandingViewDidTapUnorderedList(toolbarView: WKEditorToolbarExpandingView, isSelected: Bool)
func toolbarExpandingViewDidTapOrderedList(toolbarView: WKEditorToolbarExpandingView, isSelected: Bool)
func toolbarExpandingViewDidTapIncreaseIndent(toolbarView: WKEditorToolbarExpandingView)
func toolbarExpandingViewDidTapDecreaseIndent(toolbarView: WKEditorToolbarExpandingView)
}

class WKEditorToolbarExpandingView: WKEditorToolbarView {
Expand Down Expand Up @@ -114,10 +118,12 @@ class WKEditorToolbarExpandingView: WKEditorToolbarView {
decreaseIndentionButton.setImage(WKSFSymbolIcon.for(symbol: .decreaseIndent), for: .normal)
decreaseIndentionButton.addTarget(self, action: #selector(tappedDecreaseIndentation), for: .touchUpInside)
decreaseIndentionButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonDecreaseIndent
decreaseIndentionButton.isEnabled = false

increaseIndentionButton.setImage(WKSFSymbolIcon.for(symbol: .increaseIndent), for: .normal)
increaseIndentionButton.addTarget(self, action: #selector(tappedIncreaseIndentation), for: .touchUpInside)
increaseIndentionButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonInceaseIndent
increaseIndentionButton.isEnabled = false

cursorUpButton.setImage(WKIcon.chevronUp, for: .normal)
cursorUpButton.addTarget(self, action: #selector(tappedCursorUp), for: .touchUpInside)
Expand Down Expand Up @@ -148,6 +154,28 @@ class WKEditorToolbarExpandingView: WKEditorToolbarView {
templateButton.isSelected = selectionState.isHorizontalTemplate
linkButton.isSelected = selectionState.isSimpleLink
imageButton.isEnabled = !selectionState.isBold && !selectionState.isItalics && !selectionState.isSimpleLink

unorderedListButton.isSelected = selectionState.isBulletSingleList || selectionState.isBulletMultipleList
unorderedListButton.isEnabled = !selectionState.isNumberSingleList && !selectionState.isNumberMultipleList

orderedListButton.isSelected = selectionState.isNumberSingleList || selectionState.isNumberMultipleList
orderedListButton.isEnabled = !selectionState.isBulletSingleList && !selectionState.isBulletMultipleList

decreaseIndentionButton.isEnabled = false
if selectionState.isBulletMultipleList || selectionState.isNumberMultipleList {
decreaseIndentionButton.isEnabled = true
}

if selectionState.isBulletSingleList ||
selectionState.isBulletMultipleList ||
selectionState.isNumberSingleList ||
selectionState.isNumberMultipleList {
increaseIndentionButton.isEnabled = true
} else {
increaseIndentionButton.isEnabled = false
}

cursorRightButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current.accessibilityLabelButtonCursorRight
}

// MARK: - Button Actions
Expand Down Expand Up @@ -204,15 +232,19 @@ class WKEditorToolbarExpandingView: WKEditorToolbarView {
}

@objc private func tappedUnorderedList() {
delegate?.toolbarExpandingViewDidTapUnorderedList(toolbarView: self, isSelected: unorderedListButton.isSelected)
}

@objc private func tappedOrderedList() {
delegate?.toolbarExpandingViewDidTapOrderedList(toolbarView: self, isSelected: orderedListButton.isSelected)
}

@objc private func tappedDecreaseIndentation() {
delegate?.toolbarExpandingViewDidTapDecreaseIndent(toolbarView: self)
}

@objc private func tappedIncreaseIndentation() {
delegate?.toolbarExpandingViewDidTapIncreaseIndent(toolbarView: self)
}

@objc private func tappedCursorUp() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ protocol WKEditorInputViewDelegate: AnyObject {
func didTapBold(isSelected: Bool)
func didTapItalics(isSelected: Bool)
func didTapTemplate(isSelected: Bool)
func didTapBulletList(isSelected: Bool)
func didTapNumberList(isSelected: Bool)
func didTapIncreaseIndent()
func didTapDecreaseIndent()
func didTapHeading(type: WKEditorInputView.HeadingButtonType)
func didTapStrikethrough(isSelected: Bool)
func didTapLink(isSelected: Bool)
}
Expand Down Expand Up @@ -222,6 +227,18 @@ class WKEditorInputView: WKComponentView {
])

updateColors()

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
}

configure(selectionState: selectionState)
}

// MARK: - Overrides
Expand Down Expand Up @@ -284,20 +301,40 @@ class WKEditorInputView: WKComponentView {

switch type {
case .paragraph:
paragraphButton.isSelected.toggle()
paragraphButton.isSelected = true
case .heading:
headerButton.isSelected.toggle()
headerButton.isSelected = true
case .subheading1:
subheader1Button.isSelected.toggle()
subheader1Button.isSelected = true
case .subheading2:
subheader2Button.isSelected.toggle()
subheader2Button.isSelected = true
case .subheading3:
subheader3Button.isSelected.toggle()
subheader3Button.isSelected = true
case .subheading4:
subheader4Button.isSelected.toggle()
subheader4Button.isSelected = true
}

delegate?.didTapHeading(type: type)
})

return UIButton(configuration: configuration, primaryAction: action)
}

func configure(selectionState: WKSourceEditorSelectionState) {
headingButtons.forEach { $0.isSelected = false }

if selectionState.isHeading {
headerButton.isSelected = true
} else if selectionState.isSubheading1 {
subheader1Button.isSelected = true
} else if selectionState.isSubheading2 {
subheader2Button.isSelected = true
} else if selectionState.isSubheading3 {
subheader3Button.isSelected = true
} else if selectionState.isSubheading4 {
subheader4Button.isSelected = true
} else {
paragraphButton.isSelected = true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ class WKEditorToolbarGroupedView: WKEditorToolbarView {
decreaseIndentButton.setImage(WKSFSymbolIcon.for(symbol: .decreaseIndent), for: .normal)
decreaseIndentButton.addTarget(self, action: #selector(tappedDecreaseIndent), for: .touchUpInside)
decreaseIndentButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current?.accessibilityLabelButtonDecreaseIndent
decreaseIndentButton.isEnabled = false

increaseIndentButton.setImage(WKSFSymbolIcon.for(symbol: .increaseIndent), for: .normal)
increaseIndentButton.addTarget(self, action: #selector(tappedIncreaseIndent), for: .touchUpInside)
increaseIndentButton.accessibilityLabel = WKSourceEditorLocalizedStrings.current?.accessibilityLabelButtonInceaseIndent
increaseIndentButton.isEnabled = false

superscriptButton.setImage(WKSFSymbolIcon.for(symbol: .textFormatSuperscript), for: .normal)
superscriptButton.addTarget(self, action: #selector(tappedSuperscript), for: .touchUpInside)
Expand All @@ -56,27 +58,51 @@ class WKEditorToolbarGroupedView: WKEditorToolbarView {
}

// MARK: - Notifications

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

unorderedListButton.isSelected = selectionState.isBulletSingleList || selectionState.isBulletMultipleList
unorderedListButton.isEnabled = !selectionState.isNumberSingleList && !selectionState.isNumberMultipleList

orderedListButton.isSelected = selectionState.isNumberSingleList || selectionState.isNumberMultipleList
orderedListButton.isEnabled = !selectionState.isBulletSingleList && !selectionState.isBulletMultipleList

decreaseIndentButton.isEnabled = false
if selectionState.isBulletMultipleList || selectionState.isNumberMultipleList {
decreaseIndentButton.isEnabled = true
}

if selectionState.isBulletSingleList ||
selectionState.isBulletMultipleList ||
selectionState.isNumberSingleList ||
selectionState.isNumberMultipleList {
increaseIndentButton.isEnabled = true
} else {
increaseIndentButton.isEnabled = false
}

strikethroughButton.isSelected = selectionState.isStrikethrough
}

// MARK: - Button Actions

@objc private func tappedIncreaseIndent() {
delegate?.didTapIncreaseIndent()
}

@objc private func tappedDecreaseIndent() {
delegate?.didTapDecreaseIndent()
}

@objc private func tappedUnorderedList() {
delegate?.didTapBulletList(isSelected: unorderedListButton.isSelected)
}

@objc private func tappedOrderedList() {
delegate?.didTapNumberList(isSelected: orderedListButton.isSelected)
}

@objc private func tappedSuperscript() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ extension WKSourceEditorFormatter {

// MARK: - Nearby formatting string determination

private func selectedRangeIsSurroundedByFormattingString(formattingString: String, in textView: UITextView) -> Bool {
func selectedRangeIsSurroundedByFormattingString(formattingString: String, in textView: UITextView) -> Bool {
selectedRangeIsSurroundedByFormattingStrings(startingFormattingString: formattingString, endingFormattingString: formattingString, in: textView)
}

Expand All @@ -174,7 +174,7 @@ extension WKSourceEditorFormatter {
return startingString == formattingString
}

private func rangeIsFollowedByFormattingString(range: UITextRange?, formattingString: String, in textView: UITextView) -> Bool {
func rangeIsFollowedByFormattingString(range: UITextRange?, formattingString: String, in textView: UITextView) -> Bool {
guard let range = range,
let newEnd = textView.position(from: range.end, offset: formattingString.count) else {
return false
Expand All @@ -190,7 +190,7 @@ extension WKSourceEditorFormatter {

// MARK: Adding and removing text

private func addStringFormattingCharacters(startingFormattingString: String, endingFormattingString: String, in textView: UITextView) {
func addStringFormattingCharacters(startingFormattingString: String, endingFormattingString: String, in textView: UITextView) {

let startingCursorOffset = startingFormattingString.count
let endingCursorOffset = endingFormattingString.count
Expand All @@ -217,7 +217,7 @@ extension WKSourceEditorFormatter {
}
}

private func removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: String, endingFormattingString: String, in textView: UITextView) {
func removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: String, endingFormattingString: String, in textView: UITextView) {

guard let originalSelectedTextRange = textView.selectedTextRange,
let formattingTextStart = textView.position(from: originalSelectedTextRange.start, offset: -startingFormattingString.count),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Foundation
import ComponentsObjC

extension WKSourceEditorFormatterHeading {
func toggleHeadingFormatting(selectedHeading: WKEditorInputView.HeadingButtonType, currentSelectionState: WKSourceEditorSelectionState, textView: UITextView) {

var currentStateIsParagraph = false
if currentSelectionState.isHeading {
expandSelectedRangeUpToNearestFormattingStrings(startingFormattingString: "==", endingFormattingString: "==", in: textView)
removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: "==", endingFormattingString: "==", in: textView)
} else if currentSelectionState.isSubheading1 {
expandSelectedRangeUpToNearestFormattingStrings(startingFormattingString: "===", endingFormattingString: "===", in: textView)
removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: "===", endingFormattingString: "===", in: textView)
} else if currentSelectionState.isSubheading2 {
expandSelectedRangeUpToNearestFormattingStrings(startingFormattingString: "====", endingFormattingString: "====", in: textView)
removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: "====", endingFormattingString: "====", in: textView)
} else if currentSelectionState.isSubheading3 {
expandSelectedRangeUpToNearestFormattingStrings(startingFormattingString: "=====", endingFormattingString: "=====", in: textView)
removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: "=====", endingFormattingString: "=====", in: textView)
} else if currentSelectionState.isSubheading4 {
expandSelectedRangeUpToNearestFormattingStrings(startingFormattingString: "======", endingFormattingString: "======", in: textView)
removeSurroundingFormattingStringsFromSelectedRange(startingFormattingString: "======", endingFormattingString: "======", in: textView)
} else {
currentStateIsParagraph = true
}

let currentlySurroundedByLineBreaks = selectedRangeIsSurroundedByFormattingString(formattingString: "\n", in: textView) || textView.selectedRange.location == 0 && rangeIsFollowedByFormattingString(range: textView.selectedTextRange, formattingString: "\n", in: textView)

let surroundingLineBreak = currentStateIsParagraph && !currentlySurroundedByLineBreaks ? "\n" : ""
let startingFormattingString: String
let endingFormattingString: String
switch selectedHeading {
case .paragraph:
return
case .heading:
startingFormattingString = surroundingLineBreak + "=="
endingFormattingString = "==" + surroundingLineBreak
case .subheading1:
startingFormattingString = surroundingLineBreak + "==="
endingFormattingString = "===" + surroundingLineBreak
case .subheading2:
startingFormattingString = surroundingLineBreak + "===="
endingFormattingString = "====" + surroundingLineBreak
case .subheading3:
startingFormattingString = surroundingLineBreak + "====="
endingFormattingString = "=====" + surroundingLineBreak
case .subheading4:
startingFormattingString = surroundingLineBreak + "======"
endingFormattingString = "======" + surroundingLineBreak
}

addStringFormattingCharacters(startingFormattingString: startingFormattingString, endingFormattingString: endingFormattingString, in: textView)
}
}
Loading

0 comments on commit 9a48957

Please sign in to comment.