@@ -5,7 +5,9 @@ import android.content.pm.PackageManager
55import android.content.res.Configuration
66import android.graphics.Bitmap
77import android.os.Build
8+ import android.view.View
89import android.view.ViewGroup
10+ import android.webkit.ConsoleMessage
911import android.webkit.PermissionRequest
1012import android.webkit.WebChromeClient
1113import android.webkit.WebResourceError
@@ -27,9 +29,11 @@ import androidx.core.graphics.createBitmap
2729import androidx.webkit.WebSettingsCompat
2830import androidx.webkit.WebViewAssetLoader
2931import androidx.webkit.WebViewFeature
32+ import com.multiplatform.webview.jsbridge.ConsoleBridge
3033import com.multiplatform.webview.jsbridge.WebViewJsBridge
3134import com.multiplatform.webview.request.WebRequest
3235import com.multiplatform.webview.request.WebRequestInterceptResult
36+ import com.multiplatform.webview.setting.PlatformWebSettings
3337import com.multiplatform.webview.util.InternalStoragePathHandler
3438import com.multiplatform.webview.util.KLogger
3539
@@ -69,6 +73,7 @@ fun AccompanistWebView(
6973 captureBackPresses : Boolean = true,
7074 navigator : WebViewNavigator = rememberWebViewNavigator(),
7175 webViewJsBridge : WebViewJsBridge ? = null,
76+ consoleBridge : ConsoleBridge ? = null,
7277 onCreated : (WebView ) -> Unit = {},
7378 onDispose : (WebView ) -> Unit = {},
7479 client : AccompanistWebViewClient = remember { AccompanistWebViewClient () },
@@ -105,6 +110,7 @@ fun AccompanistWebView(
105110 captureBackPresses,
106111 navigator,
107112 webViewJsBridge,
113+ consoleBridge,
108114 onCreated,
109115 onDispose,
110116 client,
@@ -147,6 +153,7 @@ fun AccompanistWebView(
147153 captureBackPresses : Boolean = true,
148154 navigator : WebViewNavigator = rememberWebViewNavigator(),
149155 webViewJsBridge : WebViewJsBridge ? = null,
156+ consoleBridge : ConsoleBridge ? = null,
150157 onCreated : (WebView ) -> Unit = {},
151158 onDispose : (WebView ) -> Unit = {},
152159 client : AccompanistWebViewClient = remember { AccompanistWebViewClient () },
@@ -183,8 +190,15 @@ fun AccompanistWebView(
183190 webChromeClient = chromeClient
184191 webViewClient = client
185192
186- // Avoid covering other components
187- this .setLayerType(state.webSettings.androidWebSettings.layerType, null )
193+ // Avoid covering other components - map to Android View constants explicitly
194+ val desiredLayerType =
195+ when (state.webSettings.androidWebSettings.layerType) {
196+ PlatformWebSettings .AndroidWebSettings .LayerType .NONE -> View .LAYER_TYPE_NONE
197+ PlatformWebSettings .AndroidWebSettings .LayerType .SOFTWARE -> View .LAYER_TYPE_SOFTWARE
198+ PlatformWebSettings .AndroidWebSettings .LayerType .HARDWARE -> View .LAYER_TYPE_HARDWARE
199+ else -> View .LAYER_TYPE_HARDWARE
200+ }
201+ this .setLayerType(desiredLayerType, null )
188202
189203 settings.apply {
190204 state.webSettings.let {
@@ -245,7 +259,7 @@ fun AccompanistWebView(
245259 }
246260 }
247261 }.also {
248- val androidWebView = AndroidWebView (it, scope, webViewJsBridge)
262+ val androidWebView = AndroidWebView (it, scope, webViewJsBridge, consoleBridge )
249263 state.webView = androidWebView
250264 webViewJsBridge?.webView = androidWebView
251265 }
@@ -295,6 +309,15 @@ open class AccompanistWebViewClient : WebViewClient() {
295309 val script =
296310 " var meta = document.createElement('meta');meta.setAttribute('name', 'viewport');meta.setAttribute('content', 'width=device-width, initial-scale=${state.webSettings.zoomLevel} , maximum-scale=10.0, minimum-scale=0.1,user-scalable=$supportZoom ');document.getElementsByTagName('head')[0].appendChild(meta);"
297311 navigator.evaluateJavaScript(script)
312+
313+ // Remove tap highlight color
314+ val removeHighlightScript =
315+ """
316+ var style = document.createElement('style');
317+ style.innerHTML = '* { -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; -webkit-user-select: none; }';
318+ document.head.appendChild(style);
319+ """ .trimIndent()
320+ navigator.evaluateJavaScript(removeHighlightScript)
298321 }
299322
300323 override fun shouldInterceptRequest (
@@ -426,6 +449,41 @@ open class AccompanistWebChromeClient : WebChromeClient() {
426449 internal set
427450 private var lastLoadedUrl = " "
428451
452+ override fun onConsoleMessage (consoleMessage : ConsoleMessage ? ): Boolean {
453+ try {
454+ val msg = consoleMessage ? : return super .onConsoleMessage(consoleMessage)
455+ val level =
456+ when (msg.messageLevel()) {
457+ ConsoleMessage .MessageLevel .ERROR -> " error"
458+ ConsoleMessage .MessageLevel .WARNING -> " warn"
459+ ConsoleMessage .MessageLevel .LOG -> " log"
460+ ConsoleMessage .MessageLevel .TIP -> " info"
461+ ConsoleMessage .MessageLevel .DEBUG -> " debug"
462+ else -> " log"
463+ }
464+ val timestamp =
465+ try {
466+ val sdf =
467+ java.text.SimpleDateFormat (" yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" , java.util.Locale .US )
468+ sdf.timeZone = java.util.TimeZone .getTimeZone(" UTC" )
469+ sdf.format(java.util.Date ())
470+ } catch (_: Throwable ) {
471+ System .currentTimeMillis().toString()
472+ }
473+ val iwv = state.webView
474+ val bridge = iwv?.consoleBridge
475+ bridge?.emitFromPlatform(
476+ level = level,
477+ content = msg.message(),
478+ sourceId = msg.sourceId(),
479+ lineNumber = msg.lineNumber(),
480+ timestamp = timestamp,
481+ )
482+ } catch (_: Exception ) {
483+ }
484+ return super .onConsoleMessage(consoleMessage)
485+ }
486+
429487 override fun onReceivedTitle (
430488 view : WebView ,
431489 title : String? ,
0 commit comments