1import Foundation
2import Capacitor
3import SwiftUI
4import WebKit
5
6@objc(LiquidTabsPlugin)
7public class LiquidTabsPlugin: CAPPlugin, CAPBridgedPlugin {
8 // So SwiftUI can notify JS
9 static weak var shared: LiquidTabsPlugin?
10
11 private let store = LiquidTabsStore.shared
12 private var keyboardHackScriptInstalled = false
13 private let keyboardHackHandlerName = "keyboardHackKey"
14
15 public let identifier = "LiquidTabsPlugin"
16 public let jsName = "LiquidTabsPlugin"
17 public let pluginMethods: [CAPPluginMethod] = [
18 CAPPluginMethod(name: "configureTabs", returnType: CAPPluginReturnPromise),
19 CAPPluginMethod(name: "selectTab", returnType: CAPPluginReturnPromise)
20 ]
21
22 public override func load() {
23 super.load()
24 LiquidTabsPlugin.shared = self
25 installKeyboardHackScript()
26 }
27
28 // MARK: - Methods from JS
29
30 /// Configure tabs from JS.
31 /// Expected args:
…lines 32–80 unchanged (49 lines)
81 }
82
83 func notifySearchChanged(query: String) {
84 notifyListeners("searchChanged", data: ["query": query])
85 }
86
87 func notifyKeyboardHackKey(key: String) {
88 notifyListeners("keyboardHackKey", data: ["key": key])
89 }
90
91 private func installKeyboardHackScript() {
92 guard !keyboardHackScriptInstalled,
93 let controller = bridge?.webView?.configuration.userContentController else {
94 return
95 }
96
97 keyboardHackScriptInstalled = true
98 controller.removeScriptMessageHandler(forName: keyboardHackHandlerName)
99 controller.add(self, name: keyboardHackHandlerName)
100
101 let source = """
102 (function() {
103 if (window.__logseqKeyboardHackInstalled) return;
104 window.__logseqKeyboardHackInstalled = true;
105 window.addEventListener('keydown', function(e) {
106 var k = null;
107 switch (e.key) {
108 case 'Backspace':
109 k = 'backspace';
110 break;
111 case 'Enter':
112 case 'Return':
113 k = 'enter';
114 break;
115 default:
116 if (e.keyCode === 8) k = 'backspace';
117 else if (e.keyCode === 13) k = 'enter';
118 break;
119 }
120 if (!k) return;
121 try {
122 window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.\(keyboardHackHandlerName).postMessage({ key: k });
123 } catch (_) {}
124 }, true);
125 })();
126 """
127
128 let script = WKUserScript(source: source, injectionTime: .atDocumentStart, forMainFrameOnly: false)
129 controller.addUserScript(script)
130 }
131}
132
133extension LiquidTabsPlugin: WKScriptMessageHandler {
134 public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
135 guard message.name == keyboardHackHandlerName else { return }
136
137 if let body = message.body as? [String: Any],
138 let key = body["key"] as? String {
139 notifyKeyboardHackKey(key: key)
140 }
141 }
142}
143