KevinnZou / compose-webview-multiplatform

WebView for JetBrains Compose Multiplatform
https://kevinnzou.github.io/compose-webview-multiplatform/
Apache License 2.0
532 stars 69 forks source link

Make native `webView` values public instead of private, add `factory()` functions #181

Closed coderforlife closed 5 months ago

coderforlife commented 5 months ago

It would be nice for extending purposes if the IWebView interface had a public webView field.

In IOSWebView, AndroidWebView, and DesktopWebView the native webView variable (although in iOS it is named wkWebView but could easily be renamed) are private. This limits external extensibility (such as setting additional settings not exposed in your library or for things like setAcceptThirdPartyCookies() which requires access to that variable).

As an additional nice feature, if the following was done it would increase the apparent similarities:

expect class NativeWebView;
actual typealias NativeWebView = WebView; // Android
actual typealias NativeWebView = WKWebView; // iOS
actual typealias NativeWebView = KCEFBrowser; // desktop

It could then be made as a field in IWebView interface. I know that it still would only be interactable from actual code, but it would still help in extensibility. Additionally, make the webView field of WebViewState publicly accessible (but not publicly settable).

An additional nice feature would be allowing custom factory() functions (like the accompanist library allows for). This function would have to return a NativeWebView object (and likely ultimately have to be based on an expect/actual function).

This would allow me to create a subclass of WebView on Android that properly scrolls within a ModalBottomSheet. There are other issues posted for this library that mention the issue (none about a ModalBottomSheet but definitely a common issue). One fix is to use the following:

/** WebView subclass that forces touch event on it to be consumed by it. */
private class WebViewForceScrolling(context: Context): WebView(context) {
    init { ViewCompat.setNestedScrollingEnabled(this, true) }
    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        requestDisallowInterceptTouchEvent(event.pointerCount == 1)
        return super.onTouchEvent(event)
    }
}

One issue with the factory() would be gaining access to context on Android (while the other platforms don't need it. But this is solvable in a variety of ways not involving your library at all.

KevinnZou commented 5 months ago

@coderforlife Thanks for your suggestion! I will add it to our feature plan. Feel free to submit a PR for it as well!