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

Add javaScriptTextInputPanel to RxWKUIDelegate #49

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions Example/JavaScriptTextInputPanelViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// JavaScriptTextInputPanelViewController.swift
// Example
//
// Created by TTOzzi on 2021/05/29.
// Copyright © 2021 RxSwift Community. All rights reserved.
//

import UIKit
import WebKit
import RxWebKit
import RxSwift
import RxCocoa

class JavaScriptTextInputPanelViewController: UIViewController {

let bag = DisposeBag()
let wkWebView = WKWebView()

override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(wkWebView)
wkWebView.load(URLRequest(url: URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_prompt")!))

wkWebView.rx
.javaScriptTextInputPanel
.debug("javaScriptTextInputPanel")
.subscribe(onNext: { [weak self] webView, prompt, defaultText, frame, handler in
guard let self = self else { return }
let alert = UIAlertController(title: "JavaScriptTextInput", message: prompt, preferredStyle: .alert)
alert.addTextField { textField in
textField.text = defaultText
}
alert.addAction(
UIAlertAction(title: "Confirm", style: .default, handler: { _ in
let text = alert.textFields?.first?.text
handler(text)
})
)
alert.addAction(
UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in
handler(nil)
})
)
self.present(alert, animated: true, completion: nil)
})
.disposed(by: bag)
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let originY = UIApplication.shared.statusBarFrame.maxY
wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height)
}
}
4 changes: 4 additions & 0 deletions RxWebKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
42F426D11C6623C5001FED46 /* RxWebKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 42F426D01C6623C5001FED46 /* RxWebKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
42F426D61C6623C5001FED46 /* RxWebKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 42F426CE1C6623C5001FED46 /* RxWebKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
42F426DC1C662CF9001FED46 /* Rx+WebKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F426DB1C662CF9001FED46 /* Rx+WebKit.swift */; };
449905C02661474C00C6E514 /* JavaScriptTextInputPanelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 449905BF2661474C00C6E514 /* JavaScriptTextInputPanelViewController.swift */; };
C4135FFE22875FBE0061933C /* RxWebKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB7D5322874EE700FB8D99 /* RxWebKitTests.swift */; };
C4136011228764840061933C /* Nimble.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C4D323B3228748A0004B05A5 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
C4136012228764840061933C /* Quick.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C4D323B2228748A0004B05A5 /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
Expand Down Expand Up @@ -138,6 +139,7 @@
42F426D01C6623C5001FED46 /* RxWebKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RxWebKit.h; sourceTree = "<group>"; };
42F426D21C6623C5001FED46 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
42F426DB1C662CF9001FED46 /* Rx+WebKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Rx+WebKit.swift"; sourceTree = "<group>"; };
449905BF2661474C00C6E514 /* JavaScriptTextInputPanelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptTextInputPanelViewController.swift; sourceTree = "<group>"; };
C41360162287651B0061933C /* RxRelay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxRelay.framework; path = Carthage/Build/iOS/RxRelay.framework; sourceTree = "<group>"; };
C41360192288135F0061933C /* HasEventsBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HasEventsBehavior.swift; sourceTree = "<group>"; };
C4607FCF1FA0DAC9002DA12F /* RxWKUIDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWKUIDelegateProxy.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -257,6 +259,7 @@
42F426B41C66223E001FED46 /* ViewController.swift */,
C4607FDA1FA0E68F002DA12F /* JavaScriptAlertPanelViewController.swift */,
C4607FDC1FA0F1D3002DA12F /* JavaScriptConfirmPanelViewController.swift */,
449905BF2661474C00C6E514 /* JavaScriptTextInputPanelViewController.swift */,
C4607FE01FA0F549002DA12F /* AuthChallengeViewController.swift */,
C4878CD51FA1066C00B12C60 /* FailedRequestViewController.swift */,
C4878CD71FA117E900B12C60 /* RedirectViewController.swift */,
Expand Down Expand Up @@ -504,6 +507,7 @@
C4607FDD1FA0F1D3002DA12F /* JavaScriptConfirmPanelViewController.swift in Sources */,
C4878CD61FA1066C00B12C60 /* FailedRequestViewController.swift in Sources */,
42F426B61C66223E001FED46 /* AppDelegate.swift in Sources */,
449905C02661474C00C6E514 /* JavaScriptTextInputPanelViewController.swift in Sources */,
C4607FDB1FA0E68F002DA12F /* JavaScriptAlertPanelViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
24 changes: 24 additions & 0 deletions RxWebKit/Sources/RxWKUIDelegateEvents+Rx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import WebKit
extension Reactive where Base: WKWebView {
public typealias JSAlertEvent = (webView: WKWebView, message: String, frame: WKFrameInfo, handler: () -> ())
public typealias JSConfirmEvent = (webView: WKWebView, message: String, frame: WKFrameInfo, handler: (Bool) -> ())
public typealias JSTextInputEvent = (webView: WKWebView, prompt: String, defaultText: String?, frame: WKFrameInfo, handler: (String?) -> ())
#if os(iOS)
public typealias CommitPreviewEvent = (webView: WKWebView, controller: UIViewController)
#endif
Expand Down Expand Up @@ -67,6 +68,28 @@ extension Reactive where Base: WKWebView {
return ControlEvent(events: source)
}

/// Reactive wrapper for `func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Swift.Void)`
public var javaScriptTextInputPanel: ControlEvent<JSTextInputEvent> {
typealias __CompletionHandler = @convention(block) (String?) -> ()
let source:Observable<JSTextInputEvent> = uiDelegate
.methodInvoked(.jsTextInput).map { args in
let view = try castOrThrow(WKWebView.self, args[0])
let prompt = try castOrThrow(String.self, args[1])
let defaultText = try castOrThrow(String?.self, args[2])
let frame = try castOrThrow(WKFrameInfo.self, args[3])
var closureObject: AnyObject? = nil
var mutableArgs = args
mutableArgs.withUnsafeMutableBufferPointer { ptr in
closureObject = ptr[4] as AnyObject
}
let __completionBlockPtr = UnsafeRawPointer(Unmanaged<AnyObject>.passUnretained(closureObject as AnyObject).toOpaque())
let handler = unsafeBitCast(__completionBlockPtr, to: __CompletionHandler.self)
return (view, prompt, defaultText, frame, handler)
}

return ControlEvent(events: source)
}

#if os(iOS)
/// Reactive wrappper for `func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController)`
@available(iOS 10.0, *)
Expand All @@ -87,6 +110,7 @@ extension Reactive where Base: WKWebView {
fileprivate extension Selector {
static let jsAlert = #selector(WKUIDelegate.webView(_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:))
static let jsConfirm = #selector(WKUIDelegate.webView(_:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:))
static let jsTextInput = #selector(WKUIDelegate.webView(_:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:))

#if os(iOS)
@available(iOS 10.0, *)
Expand Down