fix: enable auto-correct and auto-capitalization on iOS

related to https://github.com/logseq/db-test/issues/623
This commit is contained in:
Tienson Qin
2025-12-01 18:15:05 +08:00
parent 9af63ff9ca
commit 28c397e894
5 changed files with 120 additions and 12 deletions

View File

@@ -1,6 +1,7 @@
import Foundation
import Capacitor
import SwiftUI
import WebKit
@objc(LiquidTabsPlugin)
public class LiquidTabsPlugin: CAPPlugin, CAPBridgedPlugin {
@@ -8,6 +9,8 @@ public class LiquidTabsPlugin: CAPPlugin, CAPBridgedPlugin {
static weak var shared: LiquidTabsPlugin?
private let store = LiquidTabsStore.shared
private var keyboardHackScriptInstalled = false
private let keyboardHackHandlerName = "keyboardHackKey"
public let identifier = "LiquidTabsPlugin"
public let jsName = "LiquidTabsPlugin"
@@ -19,6 +22,7 @@ public class LiquidTabsPlugin: CAPPlugin, CAPBridgedPlugin {
public override func load() {
super.load()
LiquidTabsPlugin.shared = self
installKeyboardHackScript()
}
// MARK: - Methods from JS
@@ -79,4 +83,60 @@ public class LiquidTabsPlugin: CAPPlugin, CAPBridgedPlugin {
func notifySearchChanged(query: String) {
notifyListeners("searchChanged", data: ["query": query])
}
func notifyKeyboardHackKey(key: String) {
notifyListeners("keyboardHackKey", data: ["key": key])
}
private func installKeyboardHackScript() {
guard !keyboardHackScriptInstalled,
let controller = bridge?.webView?.configuration.userContentController else {
return
}
keyboardHackScriptInstalled = true
controller.removeScriptMessageHandler(forName: keyboardHackHandlerName)
controller.add(self, name: keyboardHackHandlerName)
let source = """
(function() {
if (window.__logseqKeyboardHackInstalled) return;
window.__logseqKeyboardHackInstalled = true;
window.addEventListener('keydown', function(e) {
var k = null;
switch (e.key) {
case 'Backspace':
k = 'backspace';
break;
case 'Enter':
case 'Return':
k = 'enter';
break;
default:
if (e.keyCode === 8) k = 'backspace';
else if (e.keyCode === 13) k = 'enter';
break;
}
if (!k) return;
try {
window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.\(keyboardHackHandlerName).postMessage({ key: k });
} catch (_) {}
}, true);
})();
"""
let script = WKUserScript(source: source, injectionTime: .atDocumentStart, forMainFrameOnly: false)
controller.addUserScript(script)
}
}
extension LiquidTabsPlugin: WKScriptMessageHandler {
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard message.name == keyboardHackHandlerName else { return }
if let body = message.body as? [String: Any],
let key = body["key"] as? String {
notifyKeyboardHackKey(key: key)
}
}
}

View File

@@ -10,8 +10,27 @@ import UIKit
struct KeyboardHackField: UIViewRepresentable {
@Binding var shouldShow: Bool
// Capture Backspace/Enter on the hidden field and forward to JS.
class KeyboardHackTextField: UITextField {
var onKeyPress: ((String) -> Void)?
override func deleteBackward() {
super.deleteBackward()
onKeyPress?("backspace")
text = ""
}
override func insertText(_ text: String) {
super.insertText(text)
if text == "\n" {
onKeyPress?("enter")
}
self.text = ""
}
}
class Coordinator {
let textField = UITextField()
let textField = KeyboardHackTextField()
}
func makeCoordinator() -> Coordinator {
@@ -23,6 +42,9 @@ struct KeyboardHackField: UIViewRepresentable {
let tf = context.coordinator.textField
tf.isHidden = true
tf.keyboardType = .default
tf.onKeyPress = { key in
LiquidTabsPlugin.shared?.notifyKeyboardHackKey(key: key)
}
container.addSubview(tf)
return container
}