Fix WKWebView JavaScript dialogs in browser panel
This commit is contained in:
parent
5ae36fcb91
commit
73cbfce432
2 changed files with 119 additions and 0 deletions
|
|
@ -2245,6 +2245,25 @@ private class BrowserUIDelegate: NSObject, WKUIDelegate {
|
|||
var openInNewTab: ((URL) -> Void)?
|
||||
var requestNavigation: ((URL, BrowserInsecureHTTPNavigationIntent) -> Void)?
|
||||
|
||||
private func javaScriptDialogTitle(for webView: WKWebView) -> String {
|
||||
if let absolute = webView.url?.absoluteString, !absolute.isEmpty {
|
||||
return "The page at \(absolute) says:"
|
||||
}
|
||||
return "This page says:"
|
||||
}
|
||||
|
||||
private func presentDialog(
|
||||
_ alert: NSAlert,
|
||||
for webView: WKWebView,
|
||||
completion: @escaping (NSApplication.ModalResponse) -> Void
|
||||
) {
|
||||
if let window = webView.window {
|
||||
alert.beginSheetModal(for: window, completionHandler: completion)
|
||||
return
|
||||
}
|
||||
completion(alert.runModal())
|
||||
}
|
||||
|
||||
/// Returning nil tells WebKit not to open a new window.
|
||||
/// Cmd+click opens in a new tab; regular target=_blank navigates in-place.
|
||||
func webView(
|
||||
|
|
@ -2282,4 +2301,62 @@ private class BrowserUIDelegate: NSObject, WKUIDelegate {
|
|||
completionHandler(result == .OK ? panel.urls : nil)
|
||||
}
|
||||
}
|
||||
|
||||
func webView(
|
||||
_ webView: WKWebView,
|
||||
runJavaScriptAlertPanelWithMessage message: String,
|
||||
initiatedByFrame frame: WKFrameInfo,
|
||||
completionHandler: @escaping () -> Void
|
||||
) {
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .informational
|
||||
alert.messageText = javaScriptDialogTitle(for: webView)
|
||||
alert.informativeText = message
|
||||
alert.addButton(withTitle: "OK")
|
||||
presentDialog(alert, for: webView) { _ in completionHandler() }
|
||||
}
|
||||
|
||||
func webView(
|
||||
_ webView: WKWebView,
|
||||
runJavaScriptConfirmPanelWithMessage message: String,
|
||||
initiatedByFrame frame: WKFrameInfo,
|
||||
completionHandler: @escaping (Bool) -> Void
|
||||
) {
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .informational
|
||||
alert.messageText = javaScriptDialogTitle(for: webView)
|
||||
alert.informativeText = message
|
||||
alert.addButton(withTitle: "OK")
|
||||
alert.addButton(withTitle: "Cancel")
|
||||
presentDialog(alert, for: webView) { response in
|
||||
completionHandler(response == .alertFirstButtonReturn)
|
||||
}
|
||||
}
|
||||
|
||||
func webView(
|
||||
_ webView: WKWebView,
|
||||
runJavaScriptTextInputPanelWithPrompt prompt: String,
|
||||
defaultText: String?,
|
||||
initiatedByFrame frame: WKFrameInfo,
|
||||
completionHandler: @escaping (String?) -> Void
|
||||
) {
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .informational
|
||||
alert.messageText = javaScriptDialogTitle(for: webView)
|
||||
alert.informativeText = prompt
|
||||
alert.addButton(withTitle: "OK")
|
||||
alert.addButton(withTitle: "Cancel")
|
||||
|
||||
let field = NSTextField(frame: NSRect(x: 0, y: 0, width: 320, height: 24))
|
||||
field.stringValue = defaultText ?? ""
|
||||
alert.accessoryView = field
|
||||
|
||||
presentDialog(alert, for: webView) { response in
|
||||
if response == .alertFirstButtonReturn {
|
||||
completionHandler(field.stringValue)
|
||||
} else {
|
||||
completionHandler(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,6 +216,48 @@ final class BrowserDeveloperToolsConfigurationTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
final class BrowserJavaScriptDialogDelegateTests: XCTestCase {
|
||||
func testBrowserPanelUIDelegateImplementsJavaScriptDialogSelectors() {
|
||||
let panel = BrowserPanel(workspaceId: UUID())
|
||||
guard let uiDelegate = panel.webView.uiDelegate as? NSObject else {
|
||||
XCTFail("Expected BrowserPanel webView.uiDelegate to be an NSObject")
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssertTrue(
|
||||
uiDelegate.responds(
|
||||
to: #selector(
|
||||
WKUIDelegate.webView(
|
||||
_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:
|
||||
)
|
||||
)
|
||||
),
|
||||
"Browser UI delegate must implement JavaScript alert handling"
|
||||
)
|
||||
XCTAssertTrue(
|
||||
uiDelegate.responds(
|
||||
to: #selector(
|
||||
WKUIDelegate.webView(
|
||||
_:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:
|
||||
)
|
||||
)
|
||||
),
|
||||
"Browser UI delegate must implement JavaScript confirm handling"
|
||||
)
|
||||
XCTAssertTrue(
|
||||
uiDelegate.responds(
|
||||
to: #selector(
|
||||
WKUIDelegate.webView(
|
||||
_:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:
|
||||
)
|
||||
)
|
||||
),
|
||||
"Browser UI delegate must implement JavaScript prompt handling"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
final class BrowserDeveloperToolsVisibilityPersistenceTests: XCTestCase {
|
||||
private final class FakeInspector: NSObject {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue