Skip to content

Commit 4cfc74e

Browse files
authored
Merge pull request #182 from coderforlife/factory
Expose several internal fields and add factory functions
2 parents c40e880 + 07502be commit 4cfc74e

10 files changed

Lines changed: 198 additions & 99 deletions

File tree

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ The complete API of this library is as follows:
555555
* navigation from outside the composable.
556556
* @param onCreated Called when the WebView is first created.
557557
* @param onDispose Called when the WebView is destroyed.
558+
* @param factory A function that creates a platform-specific WebView object.
558559
* @sample sample.BasicWebViewSample
559560
*/
560561
@Composable
@@ -563,8 +564,10 @@ fun WebView(
563564
modifier: Modifier = Modifier,
564565
captureBackPresses: Boolean = true,
565566
navigator: WebViewNavigator = rememberWebViewNavigator(),
566-
onCreated: () -> Unit = {},
567-
onDispose: () -> Unit = {},
567+
webViewJsBridge: WebViewJsBridge? = null,
568+
onCreated: (NativeWebView) -> Unit = {},
569+
onDispose: (NativeWebView) -> Unit = {},
570+
factory: ((WebViewFactoryParam) -> NativeWebView)? = null,
568571
)
569572
```
570573

webview/src/androidMain/kotlin/com/multiplatform/webview/web/AndroidWebView.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import kotlinx.serialization.json.Json
1212
* Created By Kevin Zou On 2023/9/5
1313
*/
1414

15+
actual typealias NativeWebView = WebView
16+
1517
/**
1618
* Android implementation of [IWebView]
1719
*/
1820
class AndroidWebView(
19-
private val webView: WebView,
21+
override val webView: WebView,
2022
override val scope: CoroutineScope,
2123
override val webViewJsBridge: WebViewJsBridge?,
2224
) : IWebView {

webview/src/androidMain/kotlin/com/multiplatform/webview/web/WebView.android.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.multiplatform.webview.web
22

3+
import android.content.Context
34
import androidx.compose.runtime.Composable
45
import androidx.compose.ui.Modifier
56
import com.multiplatform.webview.jsbridge.WebViewJsBridge
@@ -14,16 +15,24 @@ actual fun ActualWebView(
1415
captureBackPresses: Boolean,
1516
navigator: WebViewNavigator,
1617
webViewJsBridge: WebViewJsBridge?,
17-
onCreated: () -> Unit,
18-
onDispose: () -> Unit,
18+
onCreated: (NativeWebView) -> Unit,
19+
onDispose: (NativeWebView) -> Unit,
20+
factory: (WebViewFactoryParam) -> NativeWebView,
1921
) {
2022
AccompanistWebView(
2123
state,
2224
modifier,
2325
captureBackPresses,
2426
navigator,
2527
webViewJsBridge,
26-
onCreated = { _ -> onCreated() },
27-
onDispose = { _ -> onDispose() },
28+
onCreated = onCreated,
29+
onDispose = onDispose,
30+
factory = { factory(WebViewFactoryParam(it)) },
2831
)
2932
}
33+
34+
/** Android WebView factory parameters: a context. */
35+
actual data class WebViewFactoryParam(val context: Context)
36+
37+
/** Default WebView factory for Android. */
38+
actual fun defaultWebViewFactory(param: WebViewFactoryParam) = android.webkit.WebView(param.context)

webview/src/commonMain/kotlin/com/multiplatform/webview/web/IWebView.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ import org.jetbrains.compose.resources.ExperimentalResourceApi
1010
* Created By Kevin Zou On 2023/9/5
1111
*/
1212

13+
expect class NativeWebView
14+
1315
/**
1416
* Interface for WebView
1517
*/
1618
interface IWebView {
19+
/**
20+
* The native web view instance. On Android, this is an instance of [android.webkit.WebView].
21+
* On iOS, this is an instance of [WKWebView]. On desktop, this is an instance of [KCEFBrowser].
22+
*/
23+
val webView: NativeWebView
24+
1725
val scope: CoroutineScope
1826

1927
val webViewJsBridge: WebViewJsBridge?

webview/src/commonMain/kotlin/com/multiplatform/webview/web/WebView.kt

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import com.multiplatform.webview.util.KLogger
1010
import com.multiplatform.webview.util.getPlatform
1111
import kotlinx.coroutines.flow.filter
1212
import kotlinx.coroutines.flow.merge
13-
import org.jetbrains.compose.resources.ExperimentalResourceApi
1413

1514
/**
1615
* Created By Kevin Zou On 2023/8/31
1716
*/
1817

1918
/**
20-
*
21-
* A wrapper around the Android View WebView to provide a basic WebView composable.
19+
* Provides a basic WebView composable.
20+
* This version of the function is provided for backwards compatibility by using the older
21+
* onCreated and onDispose callbacks and is missing the factory parameter.
2222
*
2323
* @param state The webview state holder where the Uri to load is defined.
2424
* @param modifier A compose modifier
@@ -30,7 +30,6 @@ import org.jetbrains.compose.resources.ExperimentalResourceApi
3030
* @param onDispose Called when the WebView is destroyed.
3131
* @sample sample.BasicWebViewSample
3232
*/
33-
@OptIn(ExperimentalResourceApi::class)
3433
@Composable
3534
fun WebView(
3635
state: WebViewState,
@@ -40,6 +39,42 @@ fun WebView(
4039
webViewJsBridge: WebViewJsBridge? = null,
4140
onCreated: () -> Unit = {},
4241
onDispose: () -> Unit = {},
42+
) {
43+
WebView(
44+
state = state,
45+
modifier = modifier,
46+
captureBackPresses = captureBackPresses,
47+
navigator = navigator,
48+
webViewJsBridge = webViewJsBridge,
49+
onCreated = { _ -> onCreated() },
50+
onDispose = { _ -> onDispose() },
51+
)
52+
}
53+
54+
/**
55+
* Provides a basic WebView composable.
56+
*
57+
* @param state The webview state holder where the Uri to load is defined.
58+
* @param modifier A compose modifier
59+
* @param captureBackPresses Set to true to have this Composable capture back presses and navigate
60+
* the WebView back.
61+
* @param navigator An optional navigator object that can be used to control the WebView's
62+
* navigation from outside the composable.
63+
* @param onCreated Called when the WebView is first created.
64+
* @param onDispose Called when the WebView is destroyed.
65+
* @param factory A function that creates a platform-specific WebView object.
66+
* @sample sample.BasicWebViewSample
67+
*/
68+
@Composable
69+
fun WebView(
70+
state: WebViewState,
71+
modifier: Modifier = Modifier,
72+
captureBackPresses: Boolean = true,
73+
navigator: WebViewNavigator = rememberWebViewNavigator(),
74+
webViewJsBridge: WebViewJsBridge? = null,
75+
onCreated: (NativeWebView) -> Unit = {},
76+
onDispose: (NativeWebView) -> Unit = {},
77+
factory: ((WebViewFactoryParam) -> NativeWebView)? = null,
4378
) {
4479
val webView = state.webView
4580

@@ -119,6 +154,7 @@ fun WebView(
119154
webViewJsBridge = webViewJsBridge,
120155
onCreated = onCreated,
121156
onDispose = onDispose,
157+
factory = factory ?: ::defaultWebViewFactory,
122158
)
123159

124160
DisposableEffect(Unit) {
@@ -131,6 +167,24 @@ fun WebView(
131167
}
132168
}
133169

170+
/**
171+
* Platform specific parameters given to the WebView factory function. This is a
172+
* data class containing one or more platform-specific values necessary to
173+
* create a platform-specific WebView:
174+
* - On Android, this contains a `Context` object
175+
* - On iOS, this contains a `WKWebViewConfiguration` object created from the
176+
* provided WebSettings
177+
* - On Desktop, this contains the WebViewState, the KCEFClient, and the
178+
* loaded file content (if a file, otherwise, an empty string)
179+
*/
180+
expect class WebViewFactoryParam
181+
182+
/**
183+
* Platform specific default WebView factory function. This can be called from
184+
* a custom factory function for any platforms that don't need to be customized.
185+
*/
186+
expect fun defaultWebViewFactory(param: WebViewFactoryParam): NativeWebView
187+
134188
/**
135189
* Expect API of [WebView] that is implemented in the platform-specific modules.
136190
*/
@@ -141,6 +195,7 @@ expect fun ActualWebView(
141195
captureBackPresses: Boolean = true,
142196
navigator: WebViewNavigator = rememberWebViewNavigator(),
143197
webViewJsBridge: WebViewJsBridge? = null,
144-
onCreated: () -> Unit = {},
145-
onDispose: () -> Unit = {},
198+
onCreated: (NativeWebView) -> Unit = {},
199+
onDispose: (NativeWebView) -> Unit = {},
200+
factory: (WebViewFactoryParam) -> NativeWebView = ::defaultWebViewFactory,
146201
)

webview/src/commonMain/kotlin/com/multiplatform/webview/web/WebViewState.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ class WebViewState(webContent: WebContent) {
7575
*/
7676
internal var webView by mutableStateOf<IWebView?>(null)
7777

78+
/**
79+
* The native web view instance. On Android, this is an instance of [android.webkit.WebView].
80+
* On iOS, this is an instance of [WKWebView]. On desktop, this is an instance of [KCEFBrowser].
81+
*/
82+
val nativeWebView get() = webView?.webView ?: error("WebView is not initialized")
83+
7884
/**
7985
* The saved view state from when the view was destroyed last. To restore state,
8086
* use the navigator and only call loadUrl if the bundle is null.

webview/src/desktopMain/kotlin/com/multiplatform/webview/web/DesktopWebView.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ import org.cef.network.CefPostData
1515
import org.cef.network.CefPostDataElement
1616
import org.cef.network.CefRequest
1717

18+
actual typealias NativeWebView = KCEFBrowser
19+
1820
/**
1921
* Created By Kevin Zou On 2023/9/12
2022
*/
2123
class DesktopWebView(
22-
private val webView: KCEFBrowser,
24+
override val webView: KCEFBrowser,
2325
override val scope: CoroutineScope,
2426
override val webViewJsBridge: WebViewJsBridge?,
2527
) : IWebView {

0 commit comments

Comments
 (0)