### Simple Browser Setup in Compose Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/00-README.md Demonstrates the basic setup for a WebView within a Compose UI. Requires rememberWebViewNavigator and rememberWebViewState. ```kotlin val navigator = rememberWebViewNavigator() val state = rememberWebViewState("https://example.com") Column { Row { /* nav buttons */ } WebView(state, navigator = navigator) } ``` -------------------------------- ### Basic WebView Setup Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/12-usage-patterns.md Minimal setup for a WebView component, loading a URL and displaying reactive state like the last loaded URL and loading progress. ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material.LinearProgressIndicator import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.kaspersky.components.componenativewebview.webview.WebView import com.kaspersky.components.componenativewebview.webview.rememberWebViewState @Composable fun SimpleBrowser() { val state = rememberWebViewState("https://example.com") Column(Modifier.fillMaxSize()) { // Header showing current URL TopAppBar( title = { Text(state.lastLoadedUrl ?: "Loading...") } ) // WebView WebView( state = state, modifier = Modifier .fillMaxWidth() .weight(1f) ) // Loading indicator if (state.isLoading) { LinearProgressIndicator(Modifier.fillMaxWidth()) } } } ``` -------------------------------- ### Basic Request Interceptor Setup Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/09-request-interception.md Demonstrates how to create and pass a basic request interceptor to the WebViewNavigator. ```kotlin val interceptor = object : RequestInterceptor { override fun onInterceptUrlRequest( request: WebRequest, navigator: WebViewNavigator, ): WebRequestInterceptResult { // Intercept logic here return WebRequestInterceptResult.Allow } } val navigator = rememberWebViewNavigator(requestInterceptor = interceptor) ``` ```kotlin val state = rememberWebViewState("https://example.com") WebView(state, navigator = navigator) ``` -------------------------------- ### WebViewState Constructor Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/02-webview-state.md Creates a new WebView state with the given initial content. Use this to initialize the WebView with a specific URL. ```kotlin val state = WebViewState(WebContent.Url("https://example.com")) ``` -------------------------------- ### Get Cookies Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/06-cookie-manager.md Shows how to retrieve all cookies associated with a given URL. The results are printed to the console. Requires a coroutine scope. ```kotlin scope.launch { val cookies = state.cookieManager.getCookies("https://example.com") println("Found ${cookies.size} cookies") cookies.forEach { cookie -> println("${cookie.name} = ${cookie.value}") } } ``` -------------------------------- ### Basic WebView Usage Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/04-webview-composable.md Demonstrates how to use the WebView composable with a given state and lifecycle callbacks. Ensure the WebViewState is properly initialized with a URL. ```kotlin ```kotlin @Composable fun MyPage() { val state = rememberWebViewState("https://example.com") WebView( state = state, modifier = Modifier.fillMaxSize(), onCreated = { println("WebView created") }, onDispose = { println("WebView disposed") } ) } ``` ``` -------------------------------- ### Basic WebView Usage in Compose Source: https://github.com/kdroidfilter/composenativewebview/blob/main/README.md Demonstrates the basic setup for displaying a WebView in a Compose application. Requires remembering the WebView state. ```kotlin @Composable fun App() { val state = rememberWebViewState("https://example.com") WebView(state, Modifier.fillMaxSize()) } ``` -------------------------------- ### Configure WasmJSWebSettings Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/08-settings.md Example of how to apply WasmJS specific settings when creating a WebView state, such as enabling a border and sandbox. ```kotlin val state = rememberWebViewState("https://example.com") { wasmJSWebSettings.apply { showBorder = true borderStyle = "2px dashed blue" enableSandbox = true } } ``` -------------------------------- ### Create and Set a Cookie Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/05-types.md Example demonstrating how to create a Cookie object with specific attributes and set it for a given URL using the cookie manager. ```kotlin val cookie = Cookie( name = "sessionId", value = "abc123", domain = "example.com", path = "/", isSecure = true, isHttpOnly = true, sameSite = Cookie.HTTPCookieSameSitePolicy.LAX ) scope.launch { state.cookieManager.setCookie("https://example.com", cookie) } ``` -------------------------------- ### Basic WebView Setup Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/01-overview.md Use this snippet to initialize and display a basic WebView with a given URL. Ensure the WebView composable is placed within a layout that provides constraints, such as `Modifier.fillMaxSize()`. ```kotlin val state = rememberWebViewState("https://example.com") WebView(state, Modifier.fillMaxSize()) ``` -------------------------------- ### Example RequestInterceptor Implementation Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/09-request-interception.md Demonstrates how to block specific URLs, handle custom protocols by redirecting, or allow all other navigations. Ensure to handle the navigator appropriately for custom protocol routing. ```kotlin val interceptor = object : RequestInterceptor { override fun onInterceptUrlRequest( request: WebRequest, navigator: WebViewNavigator, ): WebRequestInterceptResult { println("Intercepting: ${request.url}") return when { request.url.contains("ads.example.com") -> { WebRequestInterceptResult.Reject } request.url.startsWith("myapp://") -> { // Handle custom protocol in app navigator.loadUrl("https://example.com/page") WebRequestInterceptResult.Reject } else -> WebRequestInterceptResult.Allow } } } ``` -------------------------------- ### Set Cookie Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/06-cookie-manager.md Demonstrates how to set a cookie for a specific URL using the CookieManager. Requires a coroutine scope and a WebView state. ```kotlin val scope = rememberCoroutineScope() val state = rememberWebViewState("https://example.com") Button(onClick = { scope.launch { state.cookieManager.setCookie( "https://example.com", Cookie( name = "auth_token", value = "abc123", isSecure = true, isHttpOnly = true ) ) } }) { Text("Set Cookie") } ``` -------------------------------- ### Log Info Message Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/11-logging.md Logs a message at the Info severity level. Use this for general information about the application's flow. ```kotlin KLogger.i(tag = "Cookie") { "Setting cookie: ${cookie.name}" } ``` -------------------------------- ### Remove All Cookies Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/06-cookie-manager.md Demonstrates the removal of all cookies stored in the WebView. This is a destructive operation. ```kotlin scope.launch { state.cookieManager.removeAllCookies() println("All cookies cleared") } ``` -------------------------------- ### Usage Examples for WebContent Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/05-types.md Demonstrates how to set the WebContent for a WebView state. Supports loading URLs, raw HTML data with optional base URLs and MIME types, or local files from resources. ```kotlin val state = rememberWebViewState("https://example.com") state.content = WebContent.Url("https://other.com") ``` ```kotlin state.content = WebContent.Data("...", baseUrl = "https://example.com") ``` ```kotlin state.content = WebContent.File("pages/index.html", WebViewFileReadType.ASSET_RESOURCES) ``` -------------------------------- ### Load HTML File with WebViewFileReadType Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/05-types.md Example of loading an HTML file into the WebView using a specified read type. COMPOSE_RESOURCE_FILES is recommended. ```kotlin navigator.loadHtmlFile("index.html", WebViewFileReadType.COMPOSE_RESOURCE_FILES) ``` -------------------------------- ### Example WebViewNavigator with Request Interceptor Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/03-webview-navigator.md Demonstrates how to create a WebViewNavigator with a custom RequestInterceptor. This interceptor can be used to block or allow specific URL requests based on defined criteria. ```kotlin val navigator = rememberWebViewNavigator( requestInterceptor = object : RequestInterceptor { override fun onInterceptUrlRequest( request: WebRequest, navigator: WebViewNavigator, ): WebRequestInterceptResult { return if (request.url.contains("blocked.com")) { WebRequestInterceptResult.Reject } else { WebRequestInterceptResult.Allow } } } ) ``` -------------------------------- ### Custom Logger Implementation Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/11-logging.md Implement the KLogger interface to integrate with your own logging framework. This example shows how to format messages and route them to different severity levels of a hypothetical MyLogger. ```kotlin class MyCustomLogger : KLogger { override fun setMinSeverity(severity: KLogSeverity) { // Update your logger's severity } override fun log(severity: KLogSeverity, tag: String?, t: Throwable?, msg: () -> String) { val message = msg() val prefix = buildString { append("[ComposeWebView]") if (!tag.isNullOrBlank()) append("[$tag]") } when (severity) { KLogSeverity.Debug -> MyLogger.debug("$prefix $message") KLogSeverity.Info -> MyLogger.info("$prefix $message") KLogSeverity.Warn -> MyLogger.warn("$prefix $message") KLogSeverity.Error -> { MyLogger.error("$prefix $message", t) } else -> { } } } } ``` -------------------------------- ### Log Error Message with Exception Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/11-logging.md Logs an error message along with an optional Throwable. This is useful for capturing details about exceptions that occur during operation. ```kotlin try { // something } catch (e: Exception) { KLogger.e(t = e, tag = "Navigation") { "Load failed" } } ``` -------------------------------- ### Accessing Native WebView in Composable Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/04-webview-composable.md Example of using the advanced WebView overload to access the native WebView instance. The onCreated callback is used to print the native WebView object and can be used for platform-specific operations. ```kotlin @Composable fun MyPageWithNativeAccess() { val state = rememberWebViewState("https://example.com") WebView( state = state, onCreated = { nativeWebView -> println("Native WebView: $nativeWebView") // Access platform-specific methods on Desktop, for example } ) } ``` -------------------------------- ### Call Native Method with Object Parameters and Callback Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/07-js-bridge.md Example of calling a native method named 'echo' from JavaScript. Parameters are provided as a JavaScript object, which is automatically serialized to JSON. A callback function is included to handle the response. ```javascript // Call with object (auto-serialized to JSON) window.kmpJsBridge.callNative("echo", { text: "Hello" }, function(result) { console.log("Got: " + result); }); ``` -------------------------------- ### Handling Web Request Interception Results Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/05-types.md Demonstrates how to use a when statement to determine the appropriate WebRequestInterceptResult based on URL and modification needs. This example shows rejecting blocked URLs, modifying requests with authorization headers, or allowing others. ```kotlin return when { isBlocked(request.url) -> WebRequestInterceptResult.Reject needsModification(request.url) -> WebRequestInterceptResult.Modify(request.apply { headers["Authorization"] = "Bearer token" }) else -> WebRequestInterceptResult.Allow } ``` -------------------------------- ### Intercepting and Modifying a Web Request Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/05-types.md Example of implementing a RequestInterceptor to modify request headers for GET requests to the main frame. The interceptor can add custom headers. ```kotlin val interceptor = object : RequestInterceptor { override fun onInterceptUrlRequest( request: WebRequest, navigator: WebViewNavigator, ): WebRequestInterceptResult { if (request.method == "GET" && request.isForMainFrame) { request.headers["X-Custom-Header"] = "value" return WebRequestInterceptResult.Modify(request) } return WebRequestInterceptResult.Allow } } ``` -------------------------------- ### Modifying Requests Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/09-request-interception.md Example of how to intercept a web request, modify its headers, and return a Modify result. ```APIDOC ### Modifying Requests The `headers` map is mutable and can be modified by the interceptor: ```kotlin override fun onInterceptUrlRequest( request: WebRequest, navigator: WebViewNavigator, ): WebRequestInterceptResult { if (request.url.startsWith("https://api.example.com")) { request.headers["Authorization"] = "Bearer ${getToken()}" request.headers["X-Client-Version"] = "1.0" return WebRequestInterceptResult.Modify(request) } return WebRequestInterceptResult.Allow } ``` ``` -------------------------------- ### Basic WebView Usage Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/04-webview-composable.md Demonstrates the simplest way to display a WebView with a given URL. Requires remembering the WebView state. ```kotlin @Composable fun SimpleBrowser() { val state = rememberWebViewState("https://example.com") WebView(state, Modifier.fillMaxSize()) } ``` -------------------------------- ### WebView with Navigation and Settings Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/04-webview-composable.md Shows how to implement basic navigation controls (back, reload) and configure custom user agent and logging. Requires remembering a WebView navigator and state. ```kotlin @Composable fun AdvancedBrowser() { val navigator = rememberWebViewNavigator() val state = rememberWebViewState("https://example.com") { customUserAgentString = "MyApp/1.0" logSeverity = KLogSeverity.Debug } Column(Modifier.fillMaxSize()) { Row(Modifier.fillMaxWidth().padding(8.dp)) { Button(onClick = { navigator.navigateBack() }, enabled = navigator.canGoBack) { Text("Back") } Button(onClick = { navigator.reload() }) { Text("Reload") } } WebView(state, navigator = navigator, modifier = Modifier.weight(1f)) Text("URL: ${state.lastLoadedUrl ?: "Loading..."}") } } ``` -------------------------------- ### Conditionally Set a Cookie Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/06-cookie-manager.md Sets a cookie only if it does not already exist. Useful for user preferences or initial setup. ```kotlin scope.launch { val existing = state.cookieManager.getCookies("https://example.com") if (existing.none { it.name == "userPrefs" }) { val prefCookie = Cookie( name = "userPrefs", value = "dark_mode=true", domain = "example.com" ) state.cookieManager.setCookie("https://example.com", prefCookie) } } ``` -------------------------------- ### Run Desktop Demo App Source: https://github.com/kdroidfilter/composenativewebview/blob/main/AGENTS.md Executes the desktop demonstration application. Useful for verifying UI changes. ```bash ./gradlew :demo:run ``` -------------------------------- ### Get All Cookies Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Retrieves all cookies associated with the web view. Requires a valid web view ID. ```rust #[uniffi::export] pub fn get_cookies(id: u64) -> Result, WebViewError> ``` -------------------------------- ### Get Current URL Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Retrieves the current URL of the web view. Requires a valid web view ID. ```rust #[uniffi::export] pub fn get_url(id: u64) -> Result ``` -------------------------------- ### Remove Cookies by URL Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/06-cookie-manager.md Illustrates how to remove cookies specifically for a given URL domain. Requires a coroutine scope. ```kotlin scope.launch { state.cookieManager.removeCookies("https://example.com") } ``` -------------------------------- ### Initialize WebView with Custom Settings Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/13-platform-notes.md Create a WebView state with a specific URL and apply custom desktop WebView settings, including a custom data directory and an initialization script. This is useful for managing cookies, cache, and injecting custom JavaScript on page load. ```kotlin val state = rememberWebViewState("https://example.com") { desktopWebSettings.dataDirectory = "/path/to/webview-data" desktopWebSettings.initScript = """ console.log('Page loading...'); window.customVar = 42; """.trimIndent() } ``` -------------------------------- ### Handle JavaScript Message with JSON Response Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/07-js-bridge.md Example of handling a JavaScript message and sending a JSON-formatted response back using `dataToJsonString`. ```kotlin @Serializable data class Result(val success: Boolean, val message: String) override fun handle(message: JsMessage, navigator: WebViewNavigator?, callback: (String) -> Unit) { val result = Result(true, "OK") callback(dataToJsonString(result)) } ``` -------------------------------- ### WebView with Custom Factory Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/04-webview-composable.md Shows how to provide a custom factory for creating the WebView instance. This is an advanced option rarely needed in practice. ```kotlin @Composable fun CustomWebView() { val state = rememberWebViewState("https://example.com") WebView( state = state, modifier = Modifier.fillMaxSize(), factory = { param -> // Custom factory logic here // This is rarely needed in practice defaultWebViewFactory(param) } ) } ``` -------------------------------- ### Log Debug Message Example Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/11-logging.md Logs a message at the Debug severity level. Use this for detailed diagnostics that are not typically needed in production. ```kotlin KLogger.d(tag = "WebView") { "Page loaded: ${state.lastLoadedUrl}" } ``` -------------------------------- ### Create WebViewState with Custom User-Agent Source: https://github.com/kdroidfilter/composenativewebview/blob/main/README.md Initialize a WebViewState with a specific URL and optionally configure custom settings like the User-Agent string. Setting the User-Agent early is recommended as changes may recreate the WebView. ```kotlin val state = rememberWebViewState( url = "https://example.com" ) { customUserAgentString = "MyApp/1.0" } ``` -------------------------------- ### Build All Modules Source: https://github.com/kdroidfilter/composenativewebview/blob/main/AGENTS.md Builds all modules in the project, including Kotlin and Rust components. Requires a working Rust toolchain. ```bash ./gradlew build ``` -------------------------------- ### WebViewState Constructor Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/02-webview-state.md Initializes a new WebViewState with the specified web content. This is the primary way to create and configure the state for a WebView. ```APIDOC ## WebViewState Constructor ### Description Creates a new WebView state with the given initial content. ### Parameters #### Path Parameters - **webContent** (WebContent) - Required - Initial page content (URL, HTML data, file, or navigator-only) ### Request Example ```kotlin val state = WebViewState(WebContent.Url("https://example.com")) ``` ``` -------------------------------- ### WebView with Native Access (Desktop) Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/04-webview-composable.md Demonstrates accessing the native WebView instance, particularly useful on desktop platforms for platform-specific interactions. The `onCreated` callback provides the native WebView object. ```kotlin @Composable fun BrowserWithNativeAccess() { val state = rememberWebViewState("https://example.com") WebView( state = state, modifier = Modifier.fillMaxSize(), onCreated = { nativeWebView -> println("WebView created: $nativeWebView") // On Desktop, nativeWebView is a WryWebView instance // Can call platform-specific methods if needed } ) } ``` -------------------------------- ### WebView Creation Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Creates a new WebView instance with specified properties and an optional navigation handler. ```APIDOC ## create_webview() ### Description Creates a new WebView as a child of the given window. ### Method `create_webview` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **parent_handle** (u64) - Required - Parent window handle (platform-specific) * **width** (i32) - Required - Initial width in pixels * **height** (i32) - Required - Initial height in pixels * **url** (String) - Required - Initial URL to load * **user_agent** (Option) - Optional - Custom User-Agent string * **data_directory** (Option) - Optional - Directory for cookies/cache/local storage * **zoom** (bool) - Optional - Enable hotkey zoom (Ctrl+/Ctrl-) * **transparent** (bool) - Optional - Transparent background * **background_color** (Rgba) - Optional - Background color * **init_script** (Option) - Optional - JavaScript to inject at page load * **clipboard** (bool) - Optional - Enable clipboard access * **dev_tools** (bool) - Optional - Enable DevTools (F12) * **navigation_gestures** (bool) - Optional - Enable back/forward gestures * **incognito** (bool) - Optional - Private mode (no persistence) * **autoplay** (bool) - Optional - Allow auto-play video/audio * **focused** (bool) - Optional - Focus on creation * **nav_handler** (Option>) - Optional - Optional navigation interceptor ### Returns `Result` - WebView ID or error. ### Platform-Specific Notes * **Linux**: Must be called from the GTK thread (marshalled internally). * **macOS**: Must be called from the main thread. * **Windows**: Called from the message loop. ``` -------------------------------- ### JavaScript to Kotlin Bridge Call (Get Cookies) Source: https://github.com/kdroidfilter/composenativewebview/blob/main/demo-shared/src/commonMain/composeResources/files/bridge_playground.html Use this to retrieve cookies from the WebView. It expects a callback to handle the cookie data. ```javascript callNative('getCookies', (res) => { console.log('Cookies:', res) }) ``` -------------------------------- ### Get Cookies for Specific URL Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Retrieves cookies for a specific URL domain. Requires a valid web view ID and the target URL. ```rust #[uniffi::export] pub fn get_cookies_for_url(id: u64, url: String) -> Result, WebViewError> ``` -------------------------------- ### Full-Featured Browser Implementation Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/12-usage-patterns.md Implement a complete browser experience with navigation controls, URL input, settings panel, progress indicator, and status bar. This pattern is useful for applications requiring extensive web browsing capabilities. ```kotlin import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowForward import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.Button import androidx.compose.material3.Card import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.github.g0dkar.compose.native.webview.KLogSeverity import io.github.g0dkar.compose.native.webview.WebView import io.github.g0dkar.compose.native.webview.rememberWebViewNavigator import io.github.g0dkar.compose.native.webview.rememberWebViewState import io.github.g0dkar.compose.native.webview.rememberWebViewJsBridge import kotlinx.coroutines.launch @Composable fun FullBrowser() { val navigator = rememberWebViewNavigator() val state = rememberWebViewState("https://example.com") { logSeverity = KLogSeverity.Info } val jsBridge = rememberWebViewJsBridge(navigator) val scope = rememberCoroutineScope() var urlInput by remember { mutableStateOf("https://example.com") } var showSettings by remember { mutableStateOf(false) } Column(Modifier.fillMaxSize()) { // Top bar Row( Modifier .fillMaxWidth() .padding(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically ) { IconButton( onClick = { navigator.navigateBack() }, enabled = navigator.canGoBack ) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") } IconButton( onClick = { navigator.navigateForward() }, enabled = navigator.canGoForward ) { Icon(Icons.AutoMirrored.Filled.ArrowForward, contentDescription = "Forward") } TextField( value = urlInput, onValueChange = { urlInput = it }, modifier = Modifier .weight(1f) .height(40.dp), singleLine = true, keyboardActions = KeyboardActions( onDone = { navigator.loadUrl(urlInput) } ) ) IconButton(onClick = { showSettings = !showSettings }) { Icon(Icons.Filled.Settings, contentDescription = "Settings") } } // Settings panel if (showSettings) { Card(Modifier.fillMaxWidth().padding(8.dp)) { Column(Modifier.padding(8.dp)) { Row(Modifier.fillMaxWidth()) { Text("Zoom:", modifier = Modifier.align(Alignment.CenterVertically)) Slider( value = state.webSettings.zoomLevel.toFloat(), onValueChange = { state.webSettings.zoomLevel = it.toDouble() }, valueRange = 0.5f..2.0f, modifier = Modifier .weight(1f) .padding(8.dp) ) } Row { Button(onClick = { scope.launch { state.cookieManager.removeAllCookies() } }) { Text("Clear Cookies") } Button(onClick = { navigator.reload() }) { Text("Reload") } } } } } // Progress if (state.isLoading) { LinearProgressIndicator(Modifier.fillMaxWidth()) } // WebView WebView( state = state, navigator = navigator, webViewJsBridge = jsBridge, modifier = Modifier.weight(1f) ) // Status bar Text( "Ready | " + (state.pageTitle ?: state.lastLoadedUrl ?: ""), fontSize = 10.sp, modifier = Modifier .fillMaxWidth() .padding(4.dp) ) } } ``` -------------------------------- ### Get Current Page Title Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Retrieves the current title of the web view's page. Requires a valid web view ID. ```rust #[uniffi::export] pub fn get_title(id: u64) -> Result ``` -------------------------------- ### Configure WebView Settings on Creation Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/08-settings.md Use `rememberWebViewState` to set initial web view properties like custom user agent, JavaScript enablement, and log severity. Platform-specific settings can also be applied here. ```kotlin val state = rememberWebViewState( "https://example.com", extraSettings = { // Applied at creation time customUserAgentString = "MyApp/1.0" isJavaScriptEnabled = true logSeverity = KLogSeverity.Info // Platform-specific desktopWebSettings.enableDevtools = BuildConfig.DEBUG androidWebSettings.textZoom = 110 iOSWebSettings.isInspectable = BuildConfig.DEBUG } ) WebView(state, modifier = Modifier.fillMaxSize()) ``` -------------------------------- ### Intercepting and Modifying WebRequests Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/09-request-interception.md Example of an interceptor that adds authorization and client version headers to requests targeting 'api.example.com'. It returns WebRequestInterceptResult.Modify to apply the changes. ```kotlin override fun onInterceptUrlRequest( request: WebRequest, navigator: WebViewNavigator, ): WebRequestInterceptResult { if (request.url.startsWith("https://api.example.com")) { request.headers["Authorization"] = "Bearer ${getToken()}" request.headers["X-Client-Version"] = "1.0" return WebRequestInterceptResult.Modify(request) } return WebRequestInterceptResult.Allow } ``` -------------------------------- ### Handle LoadingState in UI Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/05-types.md Demonstrates how to use the LoadingState to update the UI, showing progress indicators or status messages. It also shows a simpler check for the isLoading property. ```kotlin val state = rememberWebViewState("https://example.com") when (state.loadingState) { is LoadingState.Initializing -> Text("Starting...") is LoadingState.Loading -> { val progress = (state.loadingState as LoadingState.Loading).progress LinearProgressIndicator(progress = progress) } is LoadingState.Finished -> Text("Loaded") } // Or simply: if (state.isLoading) { LinearProgressIndicator() } ``` -------------------------------- ### Manage WebView Cookies Source: https://github.com/kdroidfilter/composenativewebview/blob/main/README.md Provides methods to interact with the WebView's cookie manager, including setting, getting, and removing cookies for a given URL. ```kotlin state.cookieManager.setCookie(...) state.cookieManager.getCookies(url) state.cookieManager.removeCookies(url) state.cookieManager.removeAllCookies() ``` -------------------------------- ### Intercept WebView Requests Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/00-README.md Provides an example of implementing a RequestInterceptor to control network requests made by the WebView. Allows rejecting specific URLs like advertisements. ```kotlin val interceptor = object : RequestInterceptor { override fun onInterceptUrlRequest( request: WebRequest, navigator: WebViewNavigator, ) = when { request.url.contains("ads") -> WebRequestInterceptResult.Reject else -> WebRequestInterceptResult.Allow } } val navigator = rememberWebViewNavigator(requestInterceptor = interceptor) ``` -------------------------------- ### Configure Desktop JVM Arguments Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/13-platform-notes.md Adds JVM arguments to enable native access for desktop applications. Use when native access is required. ```kotlin compose.desktop { application { jvmArgs += "--enable-native-access=ALL-UNNAMED" } } ``` -------------------------------- ### Bypass CORS Issues with a Proxy Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/13-platform-notes.md Example of using a CORS proxy to load content from a different origin. This is a workaround for CORS limitations when embedding external websites. ```kotlin navigator.loadUrl("https://api.allorigins.win/raw?url=https://example.com") ``` -------------------------------- ### Create WebView Function Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Creates a new WebView instance. Ensure platform-specific threading requirements are met. ```rust #[uniffi::export] pub fn create_webview( parent_handle: u64, width: i32, height: i32, url: String, user_agent: Option, data_directory: Option, zoom: bool, transparent: bool, background_color: Rgba, init_script: Option, clipboard: bool, dev_tools: bool, navigation_gestures: bool, incognito: bool, autoplay: bool, focused: bool, nav_handler: Option> ) -> Result ``` -------------------------------- ### Configure iOS Framework Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/13-platform-notes.md Sets the base name and static property for the iOS framework. Use to customize the generated iOS binary. ```kotlin iosTarget.binaries.framework { baseName = "composewebview" isStatic = true } ``` -------------------------------- ### drain_ipc_messages Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Retrieves and clears queued IPC messages from the JavaScript bridge. This function is used to get JSON strings sent from JavaScript's `postMessage()` calls. ```APIDOC ## drain_ipc_messages(id: u64) ### Description Get and clear queued IPC messages from the JS bridge. ### Signature ```rust pub fn drain_ipc_messages(id: u64) -> Result, WebViewError> ``` ### Parameters #### Path Parameters - **id** (u64) - Required - Identifier for the WebView. ### Returns - **Vec** - A vector of JSON strings from JavaScript `postMessage()` calls. - **WebViewError** - An error if the operation fails. ``` -------------------------------- ### rememberWebViewStateWithHTMLFile() Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/02-webview-state.md Creates and remembers a WebViewState initialized with an HTML file from resources. Allows specifying the file name and read type (asset or compose resource). ```APIDOC ## rememberWebViewStateWithHTMLFile() ### Description Creates and remembers a WebViewState initialized with an HTML file from resources. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **fileName** (String) - Required - Filename to load (relative path in assets or resources) - **readType** (WebViewFileReadType) - Required - Where to find the file: `ASSET_RESOURCES` or `COMPOSE_RESOURCE_FILES` ### Request Example ```kotlin val state = rememberWebViewStateWithHTMLFile( fileName = "index.html", readType = WebViewFileReadType.ASSET_RESOURCES ) ``` ### Response #### Success Response (200) - **WebViewState** - The remembered WebViewState object. #### Response Example None provided in source. ``` -------------------------------- ### Dynamically Change WebView Zoom Level Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/08-settings.md Shows how to adjust the WebView's zoom level to 125% after its creation. This is an example of a dynamic setting that takes effect immediately. ```kotlin val state = rememberWebViewState("https://example.com") Button(onClick = { // Also safe state.webSettings.zoomLevel = 1.25 }) { Text("Zoom to 125%") } ``` -------------------------------- ### Logging Convenience Methods Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/11-logging.md Convenience methods are provided for common logging levels: `d()` for debug, `i()` for info, `w()` for warnings, and `e()` for errors. The `e()` method also supports logging an associated exception. ```APIDOC ### `d()` - Debug ```kotlin fun d(tag: String? = null, msg: () -> String) = log(KLogSeverity.Debug, tag, null, msg) ``` Log a debug message. **Example:** ```kotlin KLogger.d(tag = "WebView") { "Page loaded: ${state.lastLoadedUrl}" } ``` ``` ```APIDOC ### `i()` - Info ```kotlin fun i(tag: String? = null, msg: () -> String) = log(KLogSeverity.Info, tag, null, msg) ``` Log an info message. **Example:** ```kotlin KLogger.i(tag = "Cookie") { "Setting cookie: ${cookie.name}" } ``` ``` ```APIDOC ### `w()` - Warn ```kotlin fun w(tag: String? = null, msg: () -> String) = log(KLogSeverity.Warn, tag, null, msg) ``` Log a warning. ``` ```APIDOC ### `e()` - Error ```kotlin fun e(t: Throwable? = null, tag: String? = null, msg: () -> String) = log(KLogSeverity.Error, tag, t, msg) ``` Log an error with optional exception. **Example:** ```kotlin try { // something } catch (e: Exception) { KLogger.e(t = e, tag = "Navigation") { "Load failed" } } ``` ``` -------------------------------- ### Calling Native from JavaScript Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/07-js-bridge.md Demonstrates how to call a native method ('greet') from JavaScript using the injected `window.kmpJsBridge`. It passes parameters and handles the response asynchronously via a callback function. Ensure the parameters match the expected structure of the native handler. ```html ``` -------------------------------- ### Handle JavaScript Message with Deserialized Parameters Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/07-js-bridge.md Example of handling a JavaScript message by first deserializing its parameters into a Kotlin data class using `processParams` and then using the extracted data. ```kotlin @Serializable data class EchoParams(val text: String) override fun handle(message: JsMessage, navigator: WebViewNavigator?, callback: (String) -> Unit) { val params = processParams(message) callback(params.text) } ``` -------------------------------- ### Configure Desktop WebView Settings Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/13-platform-notes.md Apply various settings to the desktop WebView, such as enabling transparency, setting data directories, and controlling JavaScript clipboard access. Use this to customize the WebView's behavior and appearance. ```kotlin desktopWebSettings.apply { transparent = true // Transparent background dataDirectory = null // Cookie/cache directory initScript = null // Script injected at load enableClipboard = true // JavaScript clipboard access enableDevtools = false // F12 to open DevTools enableNavigationGestures = true // Back/forward gestures incognito = false // Private mode autoplayWithoutUserInteraction = false // Auto-play audio/video focused = true // Focused on creation } ``` -------------------------------- ### Compile Android Implementation Source: https://github.com/kdroidfilter/composenativewebview/blob/main/AGENTS.md Compiles the Android-specific implementation of the WebView. Requires the Android SDK to be set up. ```bash ./gradlew :wrywebview-compose:compileDebugKotlinAndroid ``` -------------------------------- ### JavaScript Call to Kotlin Handler Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/05-types.md Example of how to invoke a native Kotlin handler from JavaScript using the `kmpJsBridge`. This includes specifying the method name, parameters, and a callback function to receive the result. ```javascript window.kmpJsBridge.callNative("echo", { text: "Hello" }, function(result) { console.log("Got: " + result); }); ``` -------------------------------- ### Load HTML Content in WebView Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/12-usage-patterns.md Demonstrates how to load different types of content into the WebView, including URLs, HTML strings, and local HTML files. Use `rememberWebViewState` for URLs, `rememberWebViewStateWithHTMLData` for HTML strings, and `rememberWebViewStateWithHTMLFile` for local files. ```kotlin import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.kaspersky.components.composesupport.webview.core.model.WebContent import com.kaspersky.components.composesupport.webview.core.model.WebViewFileReadType import com.kaspersky.components.composesupport.webview.core.model.WebViewNavigator import com.kaspersky.components.composesupport.webview.core.model.rememberWebViewNavigator import com.kaspersky.components.composesupport.webview.core.model.rememberWebViewState import com.kaspersky.components.composesupport.webview.core.model.rememberWebViewStateWithHTMLData import com.kaspersky.components.composesupport.webview.core.model.rememberWebViewStateWithHTMLFile import com.kaspersky.components.composesupport.webview.core.view.WebView @Composable fun HtmlContentBrowser() { val navigator = rememberWebViewNavigator() var contentMode by remember { mutableStateOf(null) } val urlState = rememberWebViewState("about:blank") val htmlState = rememberWebViewStateWithHTMLData( data = "

Hello

", baseUrl = "https://example.com" ) val fileState = rememberWebViewStateWithHTMLFile( fileName = "index.html", readType = WebViewFileReadType.COMPOSE_RESOURCE_FILES ) val state = when (contentMode) { is WebContent.Url -> urlState is WebContent.Data -> htmlState is WebContent.File -> fileState else -> urlState } Column(Modifier.fillMaxSize()) { Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) { Button(onClick = { contentMode = WebContent.Url("https://example.com") }) { Text("URL") } Button(onClick = { contentMode = WebContent.Data("

Test

") }) { Text("HTML") } Button(onClick = { contentMode = WebContent.File("index.html", WebViewFileReadType.COMPOSE_RESOURCE_FILES) }) { Text("File") } } WebView(state, navigator = navigator, modifier = Modifier.weight(1f)) } } ``` -------------------------------- ### WebView with Navigation Controls Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/12-usage-patterns.md A full browser implementation with back, forward, and reload buttons, along with a URL input field for navigation. ```kotlin import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.KeyboardActions import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowForward import androidx.compose.material.icons.filled.Refresh import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.kaspersky.components.componenativewebview.webview.WebView import com.kaspersky.components.componenativewebview.webview.rememberWebViewNavigator import com.kaspersky.components.componenativewebview.webview.rememberWebViewState @Composable fun BrowserWithNavigation() { val navigator = rememberWebViewNavigator() val state = rememberWebViewState("https://example.com") var urlInput by remember { mutableStateOf("https://example.com") } Column(Modifier.fillMaxSize()) { // Toolbar Row( Modifier .fillMaxWidth() .padding(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically ) { IconButton( onClick = { navigator.navigateBack() }, enabled = navigator.canGoBack ) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") } IconButton( onClick = { navigator.navigateForward() }, enabled = navigator.canGoForward ) { Icon(Icons.AutoMirrored.Filled.ArrowForward, contentDescription = "Forward") } IconButton(onClick = { navigator.reload() }) { Icon(Icons.Filled.Refresh, contentDescription = "Reload") } TextField( value = urlInput, onValueChange = { urlInput = it }, modifier = Modifier .weight(1f) .height(40.dp), singleLine = true, keyboardActions = KeyboardActions( onDone = { navigator.loadUrl(urlInput) } ) ) } // WebView WebView( state = state, navigator = navigator, modifier = Modifier.weight(1f) ) } } ``` -------------------------------- ### Call Native Method Without Callback Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/07-js-bridge.md Example of calling a native method named 'log' from JavaScript without providing a callback function. This is useful for methods that do not need to return a value or for fire-and-forget operations. ```javascript // Call without callback window.kmpJsBridge.callNative("log", { message: "User clicked" }); ``` -------------------------------- ### Configure Custom Browser Settings Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/12-usage-patterns.md Set common and platform-specific settings for the WebView, such as user agent, JavaScript enablement, logging, and text zoom. Ensure necessary build configurations are in place for platform-specific settings. ```kotlin import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.kaspersky.components.composesupport.webview.core.model.KLogSeverity import com.kaspersky.components.composesupport.webview.core.model.WebViewState import com.kaspersky.components.composesupport.webview.core.model.rememberWebViewState import com.kaspersky.components.composesupport.webview.core.view.WebView import com.kaspersky.components.composesupport.webview.core.settings.desktopWebSettings import com.kaspersky.components.composesupport.webview.core.settings.iOSWebSettings import com.kaspersky.components.composesupport.webview.core.settings.wasmJSWebSettings import com.kaspersky.components.composesupport.webview.core.settings.androidWebSettings import androidx.compose.ui.graphics.Color @Composable fun CustomSettingsBrowser() { val state = rememberWebViewState("https://example.com") { // Common settings customUserAgentString = "MyApp/1.0" isJavaScriptEnabled = true logSeverity = KLogSeverity.Debug backgroundColor = Color.White // Platform-specific androidWebSettings.textZoom = 110 desktopWebSettings.apply { enableDevtools = BuildConfig.DEBUG transparent = false enableClipboard = true } iOSWebSettings.apply { isInspectable = true } wasmJSWebSettings.apply { showBorder = true } } WebView(state, Modifier.fillMaxSize()) } ``` -------------------------------- ### Event Listeners for Bridge Calls Source: https://github.com/kdroidfilter/composenativewebview/blob/main/demo-shared/src/commonMain/composeResources/files/bridge_playground.html Attaches event listeners to various buttons to trigger specific native bridge calls. These examples demonstrate calling 'echo', 'appInfo', 'navigate', 'setCookie', 'getCookies', and a custom method. ```javascript document.getElementById('btnEcho').addEventListener('click', () => { call('echo', { text: document.getElementById('echoInput').value }, true); }); document.getElementById('btnAppInfo').addEventListener('click', () => { call('appInfo', { requestedAt: Date.now() }, true); }); document.getElementById('btnNavigate').addEventListener('click', () => { call('navigate', { url: document.getElementById('urlInput').value }, false); }); document.getElementById('btnSetCookie').addEventListener('click', () => { call('setCookie', { url: document.getElementById('urlInput').value, name: document.getElementById('cookieName').value, value: document.getElementById('cookieValue').value }, true); }); document.getElementById('btnGetCookies').addEventListener('click', () => { call('getCookies', { url: document.getElementById('urlInput').value }, true); }); document.getElementById('btnCustom').addEventListener('click', () => { let obj = {}; try { obj = JSON.parse(document.getElementById('customParams').value || '{}'); } catch (e) { obj = { parseError: String(e) }; } call('custom', obj, true); }); ``` -------------------------------- ### Evaluate JavaScript and Get Result Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/03-webview-navigator.md Execute JavaScript code within the WebView's context and optionally receive the stringified result via a callback. Useful for interacting with the loaded page's DOM or state. ```kotlin navigator.evaluateJavaScript("document.title") { title -> println("Page title: $title") } ``` -------------------------------- ### Load URL in WebView Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Navigates the WebView to a specified URL. ```rust #[uniffi::export] pub fn load_url(id: u64, url: String) -> Result<(), WebViewError> ``` -------------------------------- ### Remember WebView State with HTML File Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/02-webview-state.md Creates and remembers a WebViewState initialized with an HTML file from resources. Specify the file name and the read type (ASSET_RESOURCES or COMPOSE_RESOURCE_FILES). ```kotlin @Composable fun rememberWebViewStateWithHTMLFile( fileName: String, readType: WebViewFileReadType, ): WebViewState ``` ```kotlin val state = rememberWebViewStateWithHTMLFile( fileName = "index.html", readType = WebViewFileReadType.ASSET_RESOURCES ) ``` -------------------------------- ### Open DevTools Source: https://github.com/kdroidfilter/composenativewebview/blob/main/_autodocs/10-wry-bindings.md Opens the browser's developer tools for the web view. This requires `enableDevtools = true` to have been set during creation. ```rust #[uniffi::export] pub fn open_dev_tools(id: u64) -> Result<(), WebViewError> ```