Giter Club home page Giter Club logo

compose-webview-multiplatform's People

Contributors

alirezat775 avatar datl4g avatar kevinnzou avatar msasikanth avatar shabinder avatar terryglen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

compose-webview-multiplatform's Issues

use <1.7.2> cannot find org.jogamp.gluegen:gluegen-rt:2.5.0!

Execution failed for task ':desktop:run'.

Could not resolve all files for configuration ':desktop:runtimeClasspath'.
Could not find org.jogamp.gluegen:gluegen-rt:2.5.0.
Searched in the following locations:
- https://dl.google.com/dl/android/maven2/org/jogamp/gluegen/gluegen-rt/2.5.0/gluegen-rt-2.5.0.pom
- https://repo.maven.apache.org/maven2/org/jogamp/gluegen/gluegen-rt/2.5.0/gluegen-rt-2.5.0.pom
- https://maven.pkg.jetbrains.space/public/p/compose/dev/org/jogamp/gluegen/gluegen-rt/2.5.0/gluegen-rt-2.5.0.pom
- https://s01.oss.sonatype.org/content/repositories/snapshots/org/jogamp/gluegen/gluegen-rt/2.5.0/gluegen-rt-2.5.0.pom
Required by:
project :desktop > project :shared > io.github.kevinnzou:compose-webview-multiplatform:1.7.2 > io.github.kevinnzou:compose-webview-multiplatform-desktop:1.7.2 > dev.datlag:kcef:2023.10.13 > dev.datlag:jcef:2023.10.13

Authorisation Code Grant flow

Hi I'm working on supporting oAuth flow in 3 platforms.

here is the code base

`@Composable
fun OAuth2WebView(utils: Utils,onAuthorizationCodeReceived: (String) -> Unit) {

val url="${OAuthConfig.AUTH_END_POINT}?response_type=code&client_id=${OAuthConfig.CLIENT_ID}&redirect_uri=${OAuthConfig.REDIRECT_URL}"

val webViewState = rememberWebViewState(url)

LogUtils.logDebug(StringResources.RESPONSE,url)

Column(Modifier.fillMaxSize()) {

    val loadingState = webViewState.loadingState
    if (loadingState is LoadingState.Loading) {
        LinearProgressIndicator(
            progress = loadingState.progress,
            modifier = Modifier.fillMaxWidth()
        )
    }
    WebView(webViewState, onDispose = {
        val currentUrl = webViewState.lastLoadedUrl
        LogUtils.logDebug(StringResources.RESPONSE,currentUrl.toString())
        if (currentUrl?.startsWith(OAuthConfig.REDIRECT_URL) == true) {
            utils.getQueryParameter(currentUrl,"code")?.let {
                LogUtils.logDebug(StringResources.RESPONSE,it)
                onAuthorizationCodeReceived(it)
            }
        }
    })
}

}`

Problem is when auth success we are geting callback with reDirect url and auth code which we are not geting any control.

I tried onDispose which is working when i click back button but ideally not a good solution.. please give me workaround how to get the loading urls at runtime.

Navigator.loadHtml not working on Android

Hi,

I want to update HTML from a UiState. I tested this:

val state = rememberWebViewStateWithHTMLData("initial")

    val navigator = rememberWebViewNavigator()

    LaunchedEffect(Unit) {
        delay(2000)
        navigator.loadHtml("<html><body>New HTML</body></html>")
    }

Which would be expected to first show "initial", then change to New HTML. It doesn't change.

The problem seems to be in WebViewNavigator line 130 which has this code (collecting the flow):

loadHtml(
                            event.baseUrl,
                            event.html,
                            event.mimeType,
                            event.encoding,
                            event.historyUrl,
                        )

But in AndroidWebView.kt (line 25) the arguments are in different order:

override fun loadHtml(
        html: String?,
        baseUrl: String?,
        mimeType: String?,
        encoding: String?,
        historyUrl: String?,
    )

It seems like baseUrl and html have changed places.

Is that something that can be fixed, or should I send a pull request? Thanks!

Open and display linked PDF files

Hi, thanks for providing this lib, it has worked very well for our project so far.

It would be great if you could add support for loading PDFs that are linked from a page. At the moment, if I click on a link such as

<a href="https://www.foobar.com/randomfile.pdf" title="randomfile.pdf" download="randomfile.pdf" target="_blank">
nothing happens.

According to https://stackoverflow.com/questions/30461392/android-pdf-not-loading-in-browser-and-webview, if this were only on Android, we could override shouldOverrideUrlLoading in the WebViewClient to obtain the behavior we want. However, its not clear if this would actually be the solution, but its worth exploring.

Have you come across this issue before? Many thanks

Webview.dev for desktop

Hi,

I think this project is filling a really important gap, given that most real world applications with a graphical user interface these days has a webview somewhere.

On Desktop: has the use of webview.dev been considered? Bundling 100MB of Chromium is something that would be better to avoid if possible. There have been a couple projects that aim to allow the use of the system WebView (using webview.dev) on Java: https://github.com/Winterreisender/webviewko and a Java version here: https://github.com/webview/webview_java . Webviewko is looking for a new maintainer.

Maybe this has already been considered. If there's any path to avoid the need to bundle Chromium on the desktop that would massively reduce app sizes.

not working on release build

in my windows desktop app, I have no problem making it work for non-release build. However when I'm running using release build I am experiencing an error

I have included modules in build.gradle.kts (includeAllModules = true) as well as followed this readme https://github.com/KevinnZou/compose-webview-multiplatform/blob/main/README.desktop.md

[createContext(...) must not be null] error shows

Exception in thread "AWT-EventQueue-0" java.lang.ClassNotFoundException: org.cef.callback.CefCommandLine_N
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
	at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
	at org.cef.CefApp.N_Initialize(Native Method)
	at org.cef.CefApp.access$400(CefApp.java:25)
	at org.cef.CefApp$3.run(CefApp.java:427)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: onBeforeCommandLineProcessing
	at org.cef.CefApp.N_Initialize(Native Method)
	at org.cef.CefApp.access$400(CefApp.java:25)
	at org.cef.CefApp$3.run(CefApp.java:427)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.ClassNotFoundException: org.cef.callback.CefSchemeRegistrar_N
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
	at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
	at org.cef.CefApp.N_Initialize(Native Method)
	at org.cef.CefApp.access$400(CefApp.java:25)
	at org.cef.CefApp$3.run(CefApp.java:427)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: onRegisterCustomSchemes
	at org.cef.CefApp.N_Initialize(Native Method)
	at org.cef.CefApp.access$400(CefApp.java:25)
	at org.cef.CefApp$3.run(CefApp.java:427)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "Thread-5" java.lang.NoSuchMethodError: onContextInitialized
Exception in thread "DefaultDispatcher-worker-1" java.lang.NoSuchMethodError: getNativeRef
	at org.cef.handler.CefClientHandler.N_CefClientHandler_CTOR(Native Method)
	at org.cef.handler.CefClientHandler.<init>(CefClientHandler.java:39)
	at org.cef.CefClient.<init>(CefClient.java:110)
	at org.cef.CefApp.createClient(CefApp.java:320)
	at com.multiplatform.webview.web.Cef.newClient(Cef.kt:98)
	at com.multiplatform.webview.web.Cef.newClient$default$4bfbdff3(Cef.kt:93)
	at com.multiplatform.webview.web.WebView_desktopKt$DesktopWebView$client$2$1.invokeSuspend(WebView.desktop.kt:51)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:1793)
Exception in thread "DefaultDispatcher-worker-1" java.lang.NoSuchMethodError: setNativeRef
	at org.cef.handler.CefClientHandler.N_CefClientHandler_CTOR(Native Method)
	at org.cef.handler.CefClientHandler.<init>(CefClientHandler.java:39)
	at org.cef.CefClient.<init>(CefClient.java:110)
	at org.cef.CefApp.createClient(CefApp.java:320)
	at com.multiplatform.webview.web.Cef.newClient(Cef.kt:98)
	at com.multiplatform.webview.web.Cef.newClient$default$4bfbdff3(Cef.kt:93)
	at com.multiplatform.webview.web.WebView_desktopKt$DesktopWebView$client$2$1.invokeSuspend(WebView.desktop.kt:51)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:1793)
java.lang.UnsatisfiedLinkError: 'org.cef.browser.CefMessageRouter$CefMessageRouterConfig org.cef.browser.CefMessageRouter$CefMessageRouterConfig.N_CreateContext$106d6c7e(org.cef.handler.CefRequestContextHandler)'
	at org.cef.browser.CefMessageRouter$CefMessageRouterConfig.N_CreateContext$106d6c7e(Native Method)
	at org.cef.browser.CefMessageRouter$CefMessageRouterConfig.createNative$106d6c7e(CefMessageRouter.java:1049)
	at org.cef.browser.CefMessageRouter$CefMessageRouterConfig.createContext$7f59e2ed(CefMessageRouter.java:1039)
	at com.multiplatform.webview.web.CefRequestExtKt.createModifiedRequestContext$140d9ba5(CefRequestExt.kt:29)
	at com.multiplatform.webview.web.WebView_desktopKt.DesktopWebView(WebView.desktop.kt:65)
	at com.multiplatform.webview.web.WebView_desktopKt$DesktopWebView$3.invoke(WebView.desktop.kt:1000)
	at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt)
	at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2469)
	at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:2761)
.....
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: createContext(...) must not be null
	at com.multiplatform.webview.web.CefRequestExtKt.createModifiedRequestContext$140d9ba5(CefRequestExt.kt:29)
	at com.multiplatform.webview.web.WebView_desktopKt.DesktopWebView(WebView.desktop.kt:65)
	at com.multiplatform.webview.web.WebView_desktopKt$DesktopWebView$3.invoke(WebView.desktop.kt:1000)
	at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt)
	at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2469)
	at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:2761)

How to Disable Information in the Command Line

Hi there, could you please tell me how to make the command line not show the information.
I have tested set logSeverity = KLogSeverity.Error in the webSettings, however, the command line still outputs some INFO as shown below.
image
Sometimes there are too much information to crash my IDE.

additionalHeaders not working as expected

The doc of rememberWebViewState states:

param additionalHttpHeaders Optional, additional HTTP headers that are passed to [AccompanistWebView.loadUrl]. Note that these headers are used for all subsequent requests of the WebView.

It seems the bolded part isn't actually true. The headers are passed along via the initial WebContent.Url object, but discarded when navigating inside the webview or using navigator.loadUrl().

I tried it by attaching an Authorization header to a request; the initial request worked, subsequent requests were rejected.

I can see a few options here:

  1. Change the docs and use the headers only for the initial request. But that would leave us with no option to actually provide universal headers.
  2. Keep the headers and apply them to every subsequent navigator.loadUrl() call. That would apply the headers to all requests created via the navigator, but not to requests created by the webview itself.
  3. Apply these headers to all requests. That's probably a bit more work, on Android it would involve overrideUrlLoading, on Cef I don't know.

My personal, related issue: I want to attach an Authorization header to all requests (if possible, only requests to a certain domain). I think at the moment this is impossible.


Tested using 1.6.0 and Android, but I think the current master works the same (except that additionalHeaders don't work for desktop at all in 1.6.0).

Thanks for stepping up to build and maintain an KMP webview! 💪

Terrible performance on Android

I ran an example on Google Pixel, which has absolutely no problems in Chrome. WebView is very slow

2023-12-24.00.47.31.mp4

Version: 1.7.8

NullPointerException

in IOSWebView class

wkWebView.loadHTMLString(
string = concat,
baseURL = baseUrl?.let { NSURL(string = it) },
)

please replace above code with below code

wkWebView.loadHTMLString(
string = concat,
baseURL = baseUrl?.let { NSURL.URLWithString(it) },
)

WebView recompositions when navigate from other tab/screen

There are several screens and tabs in my application. On one of the screens in the tab there is a webview. Every time you switch between screens or tablets, webview refreshes the page. I'm not sure if the problem is in the webview or in voyager navigation, or even in my code.
For the accompanist, I found a similar problem where the solution was to use rememberSaveableWebViewState
google/accompanist#1557
However, there is no such class in your library.

Finding way to Communicate with Java script function

My requirement is to communicate with a JavaScript function from native code, similar to what we usually do in the old way by adding ‘addJavascriptInterface’ in WebView. I am exploring this library, but I can’t find any way to communicate with JavaScript code through it.

Failed to load url error in compose desktop

For a compose desktop application i get this error in state.errorsForCurrentRequest using the code sample in the README.desktop.md
ERR_ABORTED), WebViewError(code=-3, description=Failed to load url: https://github.com)

Thanks for your efforts for this great library

Add ability to enable dom storage in WebSettings

`class WebSettings {
var isJavaScriptEnabled = true

var customUserAgentString: String? = null

/**
 * Android platform specific settings
 */
val androidWebSettings = PlatformWebSettings.AndroidWebSettings()

/**
 * Desktop platform specific settings
 */
val desktopWebSettings = PlatformWebSettings.DesktopWebSettings()

/**
 * iOS platform specific settings
 */
val iOSWebSettings = PlatformWebSettings.IOSWebSettings

}
`

As you can see there is no support to enable dom storage
Which causes some web pages to turn blank.
Example url : https://economictimes.indiatimes.com/tech/technology/amazon-launches-first-test-satellites-for-internet-network/articleshow/104223101.cms

Background Color Not Applied When Using Hex Color Codes in Kotlin Multiplatform for Desktop

Description:
There's an issue with the background color not updating to the specified hex color code in a Kotlin Multiplatform for Desktop project. The background remains white, despite the hex code being set correctly in the code. Using named colors like "black" seems to work fine, but hex codes do not.

Steps to Reproduce:

  1. Integrate the following Kotlin code into a Kotlin Multiplatform project for Desktop.
  2. Observe that the WebView component's background color remains white instead of changing to the specified hex color code "#222E3A".

Expected Behavior:
The WebView component's background should display the color corresponding to the hex color code given.

Actual Behavior:
The WebView's background color remains white regardless of the hex color code provided.

Code Snippet:

@Composable
fun BotResponse(
    chatMessage: ChatMessage,
    chatViewModel: ChatViewModel
) {
    chatMessage.botResponse?.let { botResponse ->

        val textColorString = "#FFFFFF"
        val backgroundColorString = "#222E3A"

        val htmlPrefix = "<head><meta name=\"viewport\" content=\"width=device-width, height=device-height, shrink-to-fit=YES\"></head><body style=\"font-family: 'Roboto', sans-serif; color: $textColorString; margin:0px !important; padding:0px!important; background: $backgroundColorString;\"><div id=\"bot-response-container\" style=\"background: $backgroundColorString;\">"
        val htmlSuffix = "</div></body>"
        val contentHtml = htmlPrefix + botResponse + htmlSuffix

        val webViewState = rememberWebViewStateWithHTMLData(
            contentHtml,
            null,
            "utf-8",
            "text/html",
            null
        )

        Column(
            verticalArrangement = Arrangement.Center,
            modifier = Modifier.fillMaxWidth(0.8f)
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically
            ) {
                WebView(
                    state = webViewState,
                    modifier = Modifier.size(320.dp)
                )
            }
        }
    }
}

Environment:

OS: [MacOs 13.4]
Kotlin Version: [1.9.10]
Library Version: [1.6.0]

Wiki Improvement

We have to think of a proper way to document certain thinks.

The current documentation is a bit confusing.
We could either use the Wiki feature by GitHub or maybe something like Decompose did.

P.S. please add the following to the desktop ReadMe

> **Note**
> Make sure to exclude the `installDir` from upstreaming by adding it to the `.gitignore`.
> The downloaded files are platform-specific and therefore differ to each user.

Local file viewing

This looks like a very promising library. No problem viewing URLs.
Is it possible to load local HTML files saved in the Resource directory?
Thank you

Support for scriptMessageHandler on desktop

We have implemented this library in a kotlin cross platform application (for desktop) and we need to communicate back and forth with the web app we are loading in a webview. As I could see in the documentation we already have a way to send script messages to the web app using the evaluateJavaScript of the WebViewNavigator but we don't have a way to implement a scriptMessageHandler to receive messages from the web app to the app we are building.

Any plan to support this soon? Thanks in advance

How to add implement in compose-desktop project

when I add it in build.gradle.kt like

repositories {
    mavenCentral()
    maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
    maven ("https://maven.aliyun.com/nexus/content/groups/public/")
    google()
}

dependencies {
    implementation(compose.desktop.currentOs)
    testImplementation(kotlin("test"))

    val voyagerVersion = "1.0.0-rc07"
    implementation("cafe.adriel.voyager:voyager-navigator:$voyagerVersion")
    implementation("cafe.adriel.voyager:voyager-bottom-sheet-navigator:$voyagerVersion")
    implementation("cafe.adriel.voyager:voyager-tab-navigator:$voyagerVersion")
    implementation("cafe.adriel.voyager:voyager-transitions:$voyagerVersion")
    antlr("org.antlr:antlr4:4.13.1")
}

kotlin {
    sourceSets {
        dependencies {
            // use api since the desktop app need to access the Cef to initialize it.
            api("io.github.kevinnzou:compose-webview-multiplatform:1.5.0")
        }
    }
}

And then launched the Main.kt
It failed to like this

Exception in thread "main" java.lang.UnsatisfiedLinkError: 'void org.jetbrains.skia.CanvasKt._nTranslate(long, float, float)'
	at org.jetbrains.skia.CanvasKt._nTranslate(Native Method)
	at org.jetbrains.skia.CanvasKt.access$_nTranslate(Canvas.kt:1)
	at org.jetbrains.skia.Canvas.translate(Canvas.kt:1091)
	at androidx.compose.ui.graphics.SkiaBackedCanvas.translate(SkiaBackedCanvas.skiko.kt:84)
	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:357)
	at androidx.compose.ui.node.LayoutNode.draw$ui(LayoutNode.kt:922)
	at androidx.compose.ui.platform.SkiaBasedOwner.draw(SkiaBasedOwner.skiko.kt:352)
	at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:463)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:153)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:152)
	at androidx.compose.ui.awt.ComposeBridge.catchExceptions(ComposeBridge.desktop.kt:126)
	at androidx.compose.ui.awt.ComposeBridge.access$catchExceptions(ComposeBridge.desktop.kt:59)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1.onRender(ComposeBridge.desktop.kt:152)
	at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:548)
	at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54)
	at org.jetbrains.skiko.redrawer.Direct3DRedrawer.redrawImmediately(Direct3DRedrawer.kt:73)
	at org.jetbrains.skiko.SkiaLayer.paint(SkiaLayer.awt.kt:388)
	at androidx.compose.ui.awt.WindowComposeBridge$component$1.paint(WindowComposeBridge.desktop.kt:59)
	at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
	at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
	at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
	at androidx.compose.ui.window.Window_desktopKt$Window$12$1.invoke(Window.desktop.kt:430)
	at androidx.compose.ui.window.Window_desktopKt$Window$12$1.invoke(Window.desktop.kt:416)
	at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:82)
	at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:80)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$1.invoke(UpdateEffect.desktop.kt:59)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$1.invoke(UpdateEffect.desktop.kt:55)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke$performUpdate(UpdateEffect.desktop.kt:55)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:64)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:47)
	at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:81)
	at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1137)
	at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:828)
	at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1041)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:219)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

进程已结束,退出代码为 1

Use in the Desktop rememberWebViewStateWithHTMLData not loaded correctly

Hello, I have integrated your component into my sample application, but now I'm encountering an issue. When I use 'rememberWebViewStateWithHTMLData' to load data in Desktop, it prompts me with the following error message:
image

Additionally, the content is blank, without any data.

image

I'm running on Mac and have added the following.

Screen

    val html = """
            <html>
                <head>
                    <title>Custom Title</title>
                </head>
                <body>
                    <h1>Custom HTML</h1>
                    <p>This is a custom HTML page.</p>
                </body>
            </html>
    """.trimIndent()
    val webViewState = rememberWebViewStateWithHTMLData(
        html
    )
    Column(
        modifier = Modifier.fillMaxSize()
    ) {
        LedgerTitle(title = state.title, onBack = {
            onEvent(AgreementEvent.GoBack)
        })
        WebView(
            modifier = Modifier.fillMaxSize(),
            state = webViewState
        )
    }

Gradle

afterEvaluate {
    tasks.withType<JavaExec> {
        jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
        jvmArgs("--add-opens", "java.desktop/java.awt.peer=ALL-UNNAMED")

        if (System.getProperty("os.name").contains("Mac")) {
            jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.lwawt=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.lwawt.macosx=ALL-UNNAMED")
        }
    }
}

Flickering effect when showing new Window on top of WebView

I was able to load a url in the webview (inside a Window) and implement js bridge using the SNAPSHOT version. Now I'm facing a different issue. When I got a message from the web app I need to show a popup view with a button for the user to authorize some actions.

I first tried showing the AUTHORIZE view on top of the webview in the same window, and then I tried showing it in a new window. On both cases the webview starts to flicker as shown in the video.

Any ideas what might be causing this?

Screen.Recording.2023-12-26.at.13.10.31.mov

Access the Android WebView Settings

First of all thanks for providing this library.

I need to access the android WebView settings, could you please provide an option to do this.
Maybe a method/value that returns a generic in common, then we can parse it ourself in the specific targets.
I have to change some attributes and apply the settings to the webview again.

Additional information for Desktop

People need to add the JavaFx modules themself, because your lib doesn't provide native packages.
Maybe you can extend the build.gradle.kts usage guide.

I did it like this, (a bit overkill but I need this configuration for something else) just strip it down or something:

val javafx = CompileOptions.jvmTarget // jvmTarget set for the whole project
val javafxModules = listOf(
    "javafx.base",
    "javafx.graphics", // depends on base
    "javafx.controls", // depends on base & graphics
    "javafx.media", // depends on base & graphics
    "javafx.swing", // depends on base & graphics
    "javafx.web", // depends on base & graphics & controls & media
)

kotlin {
	...
	jvm("desktop")
	
	sourceSets {
		...
		val desktopMain by getting {
			dependencies {
				...
				val javaFxSuffix = getJavaFxSuffix()
                javafxModules.forEach { artifact ->
                    implementation(javaFxLib(artifact, javafx, javaFxSuffix))
                }
			}
		}
	}
}

fun getHost(): Host {
    return when (osdetector.os) {
        "linux" -> Host.Linux
        "osx" -> Host.MAC
        "windows" -> Host.Windows
        else -> {
            val hostOs = System.getProperty("os.name")
            val isMingwX64 = hostOs.startsWith("Windows")

            when {
                hostOs == "Linux" -> Host.Linux
                hostOs == "Mac OS X" -> Host.MAC
                isMingwX64 -> Host.Windows
                else -> throw IllegalStateException("Unknown OS: ${osdetector.classifier}")
            }
        }
    }
}

fun getJavaFxSuffix(): String {
    return when (osdetector.classifier) {
        "linux-x86_64" -> "linux"
        "linux-aarch_64" -> "linux-aarch64"
        "windows-x86_64" -> "win"
        "osx-x86_64" -> "mac"
        "osx-aarch_64" -> "mac-aarch64"
        else -> getHost().label
    }
}

fun javaFxLib(artifactId: String, version: String, suffix: String): String {
    return "org.openjfx:${artifactId.replace('.', '-')}:${version}:${suffix}"
}

enum class Host(val label: String) {
    Linux("linux"),
    Windows("win"),
    MAC("mac");
}

addargs to webview on desktop platform not working

I want to pass some command line arguments into desktop webview, I tried the following code but it has no effect

                KCEF.init(builder = {
                    addArgs("--disable-web-security","--user-data-dir=~/chromeTemp")
                    installDir(File("kcef-bundle"))
                    progress {
                        onDownloading {
                            downloading = max(it, 0F)
                        }
                        onInitialized {
                            initialized = true
                        }
                    }
                    settings {
                        cachePath = File("cache").absolutePath
                    }
                }

I read the documentation and learned that the Desktop platform uses KCEF, and KCEF is a wrapper of JCEF. JCEF supports passing command arguments to CEFApp. Am I using it the wrong way? Or KCEF does not support this now?

btw, I just want to disable CORS restrictions in the webview, is there a better way to do it?

Thanks in advance to all the contributors to this project, it helped me a lot, thank you very much!

In iOS webview height is not becoming wrap content,

Hi There, we used this library in one of our KMM projects, in Android it works perfectly fine, but the issue in iOS it shows scrollable content, instead of making it wrap content

Android Screen shot without scrollabar
Screenshot 2023-12-28 at 12 51 31 PM

iOS Screen shot with scrollbar, how to make it auto adjust according to the height of content
Screenshot 2023-12-28 at 11 31 46 AM

iOS video

Screen.Recording.2023-12-28.at.12.55.54.PM.mov

Task :composeApp:compileKotlinIosSimulatorArm64 FAILED

After adding this library into commonMain, getting Task :composeApp:compileKotlinIosSimulatorArm64 FAILED error while running on iosApp.

Error Detail

> Task :composeApp:compileKotlinIosSimulatorArm64 FAILED
error: Could not find "org.jetbrains.kotlin.native.platform.Symbols" in [/Users/shoaib/Downloads/Kart, /Users/shoaib/.konan/klib, /Users/shoaib/.konan/kotlin-native-prebuilt-macos-aarch64-1.9.10/klib/common, /Users/shoaib/.konan/kotlin-native-prebuilt-macos-aarch64-1.9.10/klib/platform/ios_simulator_arm64]
error: Compilation finished with errors

OpenGL crash

Not sure if it's related with the library but after implementing it I started to get reports from users experiencing a crash with the following error message:

void org.jetbrains.skiko.OpenGLLibraryKt.loadOpenGLLibraryWindows()

Any help will be appreciated. Thanks in advance

desktop 无法使用

java.lang.IllegalAccessError: class org.cef.browser.platform.CefBrowserWindowPlatform (in unnamed module @0x22eab566) cannot access class sun.awt.AWTAccessor (in module java.desktop) because module java.desktop does not export sun.awt to unnamed module @0x22eab566
at org.cef.browser.platform.CefBrowserWindowPlatform.getWindowHandle(CefBrowserWindowPlatform.java:28)
at org.cef.browser.CefBrowserWr.getWindowHandle(CefBrowserWr.java:434)
at org.cef.browser.CefBrowserWr.getWindowHandle(CefBrowserWr.java:426)
at org.cef.browser.CefBrowserWr.createBrowserIfRequired(CefBrowserWr.java:495)
at org.cef.browser.CefBrowserWr$1$1.run(CefBrowserWr.java:65)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

iOS WebView + Dialog dim not working.

I just use M3 Scaffold and androidx.compose.ui.window.Dialog but dim not working in ios

  • Android is ok
@Composable
internal fun WebViewScreen(
    modifier: Modifier = Modifier,
    onNavigateUp: () -> Unit,
) {
    val uiState = remember { mutableStateOf<WebViewUiState>(WebViewUiState.Url("https://www.naver.com")) }
    val webViewDialogVisibleState = remember { mutableStateOf(false) }

    Scaffold(
        modifier = modifier,
        topBar = {
            TopBar(
                onNavigateUp = onNavigateUp,
                onNavigation = { webViewDialogVisibleState.value = true },
            )
        },
    ) {
        WebView(
            modifier = Modifier.fillMaxSize()
                .padding(it),
            uiState = uiState.value,
        )
    }

    WebViewDialog(
        uiState = uiState,
        visibleState = webViewDialogVisibleState,
    )
}

@Composable
private fun WebViewDialog(
    uiState: MutableState<WebViewUiState>,
    visibleState: MutableState<Boolean>,
) {
    if (visibleState.value) {
        Dialog(
            onDismissRequest = { visibleState.value = false },
        ) {
            DialogContent(
                modifier = Modifier.fillMaxWidth(),
                uiState = uiState,
                visibleState = visibleState,
            )
        }
    }
}

image

Set Zoom Level for WebView to Maintain Aspect Ratio on Small Laptop Devices (Desktop)

The current implementation of WebView in our application does not maintain the correct aspect ratio when viewed on small laptop devices. This leads to a distorted user interface, affecting the usability and overall user experience.

On laptops with smaller screens, the WebView content appears compressed, leading to layout issues and potential loss of UI functionality.

If we have the option to set the zoom level, we can adjust the correct zoom level on small laptop devices.

Thank you in advance

[Desktop] Webview is always on top of other components

It's not possible to render composables on top of the WebView on desktop (using JCEF or KCEF. Android/iOS are unaffected). Any composable, even popups or context menus, will be clipped by it.

This isn't a bug with this library but with Compose's Swing interop.

This issue is to keep track of this bug, and to help others who come looking in search of answers.

在Mac OS 上无法获取页面html内容

目前只试了下Mac os,windows未尝试。
在安卓和ios上一切正常。

以下是步骤:

  1. 加载一个链接
  2. 网页加载完成后,调用evaluateJavaScript()函数执行一段js代码
  3. 获取js代码执行后返回的内容

在页面加载完成时做的事情:

    val webViewLoadingState = rememberWebViewState(curPageUrl)
    if (webViewLoadingState.loadingState == LoadingState.Finished) {
        LaunchedEffect(repeatCount) {
            // 去执行了 evaluateJavaScript() 
        }
    }

js代码:

evaluateJavaScript(
        """(function() {
                    var htmlText = document.documentElement.outerHTML;
                    return htmlText;
              })();"""
    ) { html ->
    // 判断页面内容的代码
}

最终我在回掉中得到的结果是:
image

这不是我想要的内容。
我写了个定时循环,如果返回的内容不正确,则间隔0.3s会再次执行这段js,但返回的内容一直是上面的结果

API exposed for Cookie Management ?

Is there any exposed api for setting and getting cookies from current session ?
couldnt find in readme.

If not there yet, this would be great to have.

Listener Support

There should be listener support,
where one could listen to events like onLoadStop etc

desktop上无法使用

image
这是我的使用方式,它在android上一切正常,但是在desktop上出了问题,我没有看到任何错误信息,我不知道该如何查找错误。

Logging Interceptor

We should disable the current logging as it displays unnecessary info for the user and add a interceptor instead.

So the user can decide himself wether it should be enabled or not

CookieManager return empty array on iOS

I need to get auth cookie when page is loaded.
I try it like this cookies = state.cookieManager.getCookies("https://myurl/")

It works fine on Android, but on iOS I get just []

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.