Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native Editor - Add basic undo / redo support #4719

Merged
merged 5 commits into from Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -2,10 +2,12 @@ import Foundation
import UIKit

public protocol WKSourceEditorViewControllerDelegate: AnyObject {
func sourceEditorViewControllerDidTapFind(sourceEditorViewController: WKSourceEditorViewController)
func sourceEditorViewControllerDidRemoveFindInputAccessoryView(sourceEditorViewController: WKSourceEditorViewController)
func sourceEditorViewControllerDidTapFind(_ sourceEditorViewController: WKSourceEditorViewController)
func sourceEditorViewControllerDidRemoveFindInputAccessoryView(_ sourceEditorViewController: WKSourceEditorViewController)
func sourceEditorViewControllerDidTapLink(parameters: WKSourceEditorFormatterLinkWizardParameters)
func sourceEditorViewControllerDidTapImage()
func sourceEditorDidChangeUndoState(_ sourceEditorViewController: WKSourceEditorViewController, canUndo: Bool, canRedo: Bool)
func sourceEditorDidChangeText(_ sourceEditorViewController: WKSourceEditorViewController, didChangeText: Bool)
}

// MARK: NSNotification Names
Expand Down Expand Up @@ -106,7 +108,7 @@ public class WKSourceEditorViewController: WKComponentViewController {
}

if oldValue == .find && inputAccessoryViewType != .find {
delegate?.sourceEditorViewControllerDidRemoveFindInputAccessoryView(sourceEditorViewController: self)
delegate?.sourceEditorViewControllerDidRemoveFindInputAccessoryView(self)
}

switch inputAccessoryViewType {
Expand Down Expand Up @@ -253,6 +255,14 @@ public class WKSourceEditorViewController: WKComponentViewController {
public func insertImage(wikitext: String) {
textFrameworkMediator.linkFormatter?.insertImage(wikitext: wikitext, in: textView)
}

public func undo() {
textView.undoManager?.undo()
}

public func redo() {
textView.undoManager?.redo()
}
}

// MARK: - Private
Expand Down Expand Up @@ -401,6 +411,15 @@ extension WKSourceEditorViewController: UITextViewDelegate {
postUpdateButtonSelectionStatesNotification(withDelay: false)
}

public func textViewDidChange(_ textView: UITextView) {

DispatchQueue.main.async {
self.delegate?.sourceEditorDidChangeUndoState(self, canUndo: textView.undoManager?.canUndo ?? false, canRedo: textView.undoManager?.canRedo ?? false)
}

delegate?.sourceEditorDidChangeText(self, didChangeText: textView.attributedText.string != viewModel.initialText)
}

public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
// Don't allow emdash text changes. This throws off find & replace.
if text == "—" {
Expand All @@ -417,7 +436,7 @@ extension WKSourceEditorViewController: WKEditorToolbarExpandingViewDelegate {

func toolbarExpandingViewDidTapFind(toolbarView: WKEditorToolbarExpandingView) {
inputAccessoryViewType = .find
delegate?.sourceEditorViewControllerDidTapFind(sourceEditorViewController: self)
delegate?.sourceEditorViewControllerDidTapFind(self)

if let visibleRange = textView.visibleRange {
textView.selectedRange = NSRange(location: visibleRange.location, length: 0)
Expand Down
11 changes: 9 additions & 2 deletions Components/Tests/ComponentsTests/WKSourceEditorTests.swift
Expand Up @@ -34,12 +34,19 @@ final class WKSourceEditorTests: XCTestCase {
}

extension WKSourceEditorTests: WKSourceEditorViewControllerDelegate {
func sourceEditorDidChangeUndoState(_ sourceEditorViewController: Components.WKSourceEditorViewController, canUndo: Bool, canRedo: Bool) {

}

func sourceEditorDidChangeText(_ sourceEditorViewController: Components.WKSourceEditorViewController, didChangeText: Bool) {

}

func sourceEditorViewControllerDidRemoveFindInputAccessoryView(sourceEditorViewController: Components.WKSourceEditorViewController) {
func sourceEditorViewControllerDidRemoveFindInputAccessoryView(_ sourceEditorViewController: Components.WKSourceEditorViewController) {

}

func sourceEditorViewControllerDidTapFind(sourceEditorViewController: Components.WKSourceEditorViewController) {
func sourceEditorViewControllerDidTapFind(_ sourceEditorViewController: Components.WKSourceEditorViewController) {

}

Expand Down
22 changes: 19 additions & 3 deletions Wikipedia/Code/PageEditorViewController.swift
Expand Up @@ -56,6 +56,7 @@ final class PageEditorViewController: UIViewController {

setTextSizeInAppEnvironment()
setupFocusNavigationView()
setupNavigationItemController()
loadWikitext()

apply(theme: theme)
Expand Down Expand Up @@ -85,6 +86,12 @@ final class PageEditorViewController: UIViewController {
NSLayoutConstraint.activate([leadingConstraint, trailingConstraint, topConstraint])
}

private func setupNavigationItemController() {
navigationItemController.progressButton.isEnabled = false
navigationItemController.undoButton.isEnabled = false
navigationItemController.redoButton.isEnabled = false
}

private func loadWikitext() {
fetcher.fetchSection(with: sectionID, articleURL: pageURL) { [weak self] (result) in
DispatchQueue.main.async { [weak self] in
Expand Down Expand Up @@ -231,16 +238,23 @@ extension PageEditorViewController: Themeable {
// MARK: - WKSourceEditorViewControllerDelegate

extension PageEditorViewController: WKSourceEditorViewControllerDelegate {
func sourceEditorDidChangeUndoState(_ sourceEditorViewController: Components.WKSourceEditorViewController, canUndo: Bool, canRedo: Bool) {
navigationItemController.undoButton.isEnabled = canUndo
navigationItemController.redoButton.isEnabled = canRedo
}

func sourceEditorViewControllerDidTapFind(sourceEditorViewController: WKSourceEditorViewController) {
func sourceEditorDidChangeText(_ sourceEditorViewController: Components.WKSourceEditorViewController, didChangeText: Bool) {
navigationItemController.progressButton.isEnabled = didChangeText
}

func sourceEditorViewControllerDidTapFind(_ sourceEditorViewController: WKSourceEditorViewController) {
showFocusNavigationView()
}

func sourceEditorViewControllerDidRemoveFindInputAccessoryView(sourceEditorViewController: Components.WKSourceEditorViewController) {
func sourceEditorViewControllerDidRemoveFindInputAccessoryView(_ sourceEditorViewController: Components.WKSourceEditorViewController) {
hideFocusNavigationView()
}


func sourceEditorViewControllerDidTapLink(parameters: WKSourceEditorFormatterLinkWizardParameters) {
guard let siteURL = pageURL.wmf_site else {
return
Expand Down Expand Up @@ -294,9 +308,11 @@ extension PageEditorViewController: SectionEditorNavigationItemControllerDelegat
}

func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapUndoButton undoButton: UIBarButtonItem) {
sourceEditor.undo()
}

func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapRedoButton redoButton: UIBarButtonItem) {
sourceEditor.redo()
}

func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapReadingThemesControlsButton readingThemesControlsButton: UIBarButtonItem) {
Expand Down
2 changes: 1 addition & 1 deletion Wikipedia/Code/SectionEditorNavigationItemController.swift
Expand Up @@ -67,7 +67,7 @@ class SectionEditorNavigationItemController: NSObject, Themeable {
return BarButtonItem(title: CommonStrings.nextTitle, style: .done, target: self, action: #selector(progress(_:)), tintColorKeyPath: \Theme.colors.link)
}()

private lazy var redoButton: BarButtonItem = {
private(set) lazy var redoButton: BarButtonItem = {
return BarButtonItem(image: #imageLiteral(resourceName: "redo"), style: .plain, target: self, action: #selector(redo(_ :)), tintColorKeyPath: \Theme.colors.inputAccessoryButtonTint, accessibilityLabel: CommonStrings.redo)
}()

Expand Down
12 changes: 10 additions & 2 deletions WikipediaUITests/UITestHelperViewController.swift
Expand Up @@ -150,6 +150,14 @@ public class UITestHelperViewController: WKCanvasViewController {


extension UITestHelperViewController: WKSourceEditorViewControllerDelegate {
public func sourceEditorDidChangeUndoState(_ sourceEditorViewController: Components.WKSourceEditorViewController, canUndo: Bool, canRedo: Bool) {

}

public func sourceEditorDidChangeText(_ sourceEditorViewController: Components.WKSourceEditorViewController, didChangeText: Bool) {

}

public func sourceEditorViewControllerDidTapImage() {

}
Expand All @@ -158,11 +166,11 @@ extension UITestHelperViewController: WKSourceEditorViewControllerDelegate {

}

public func sourceEditorViewControllerDidRemoveFindInputAccessoryView(sourceEditorViewController: Components.WKSourceEditorViewController) {
public func sourceEditorViewControllerDidRemoveFindInputAccessoryView(_ sourceEditorViewController: Components.WKSourceEditorViewController) {

}

public func sourceEditorViewControllerDidTapFind(sourceEditorViewController: Components.WKSourceEditorViewController) {
public func sourceEditorViewControllerDidTapFind(_ sourceEditorViewController: Components.WKSourceEditorViewController) {

}

Expand Down