eleven / messenger Public

ios: implement window.confirm()/alert() in the Mac app's webview (#104)

WKUIDelegate silently no-ops window.confirm()/alert() unless the host
app implements runJavaScriptConfirmPanelWithMessage/AlertPanelWithMessage.
Without them, chat.js's "Cancel invite" (and every other confirm(): delete
message, remove from group, leave group, sign out) as well as error
alert()s did nothing on Mac. Add both, backed by a non-blocking NSAlert
sheet rather than runModal(), since confirm()/alert() block the page's JS
thread until completionHandler fires.
Co-authored-by: Claude <noreply@anthropic.com>
James Adam 55a33e81a382ae2a4d22b69788431855ff66e34c parent 71ca5d4
1 file changed, +39 −0
  • ios/LChatMac/ChatFeedWebView.swift +39 −0
diff --git a/ios/LChatMac/ChatFeedWebView.swift b/ios/LChatMac/ChatFeedWebView.swift
index dac421a..461dc9d 100644
--- a/ios/LChatMac/ChatFeedWebView.swift
+++ b/ios/LChatMac/ChatFeedWebView.swift
@@ -365,6 +365,45 @@ struct ChatFeedWebView: NSViewRepresentable {
}
}
+ // WKUIDelegate shows nothing for window.confirm()/alert() unless we implement
+ // these — chat.js's "Cancel invite", "Remove from group", "Leave group", "Sign
+ // out", and delete-message confirms all silently no-op without them. Use a
+ // sheet, not NSAlert.runModal(): confirm()/alert() block the page's JS thread
+ // until completionHandler fires, and a nested runModal loop risks the same
+ // webview freeze the notifyError() comment in chat.js warns about.
+ func webView(_ webView: WKWebView,
+ runJavaScriptConfirmPanelWithMessage message: String,
+ initiatedByFrame frame: WKFrameInfo,
+ completionHandler: @escaping (Bool) -> Void) {
+ let alert = NSAlert()
+ alert.messageText = message
+ alert.addButton(withTitle: "OK")
+ alert.addButton(withTitle: "Cancel")
+ if let window = webView.window {
+ alert.beginSheetModal(for: window) { completionHandler($0 == .alertFirstButtonReturn) }
+ } else {
+ completionHandler(alert.runModal() == .alertFirstButtonReturn)
+ }
+ }
+
+ // Same gap as runJavaScriptConfirmPanelWithMessage above, for window.alert() —
+ // on Mac chat.js's `embed` is always nil, so notifyError() and upload-error
+ // messages call plain alert() rather than posting to the native shell.
+ func webView(_ webView: WKWebView,
+ runJavaScriptAlertPanelWithMessage message: String,
+ initiatedByFrame frame: WKFrameInfo,
+ completionHandler: @escaping () -> Void) {
+ let alert = NSAlert()
+ alert.messageText = message
+ alert.addButton(withTitle: "OK")
+ if let window = webView.window {
+ alert.beginSheetModal(for: window) { _ in completionHandler() }
+ } else {
+ alert.runModal()
+ completionHandler()
+ }
+ }
+
// Message links and link-preview cards render as target="_blank" anchors
// (chat.js), which WebKit routes here as a new-window request rather than a
// normal navigation. With no WKUIDelegate handling it, the click did nothing.