1
1
package org.ooni.probe.ui.shared
2
2
3
3
import androidx.compose.runtime.Composable
4
- import androidx.compose.runtime.DisposableEffect
5
- import androidx.compose.runtime.getValue
6
- import androidx.compose.runtime.rememberUpdatedState
7
4
import androidx.compose.ui.Modifier
8
5
import androidx.compose.ui.awt.SwingPanel
9
6
import javafx.application.Platform
@@ -13,24 +10,29 @@ import javafx.scene.Scene
13
10
import javafx.scene.layout.StackPane
14
11
import javafx.scene.web.WebView
15
12
import java.net.URL
13
+ import kotlin.io.encoding.Base64
16
14
17
15
@Composable
18
16
actual fun OoniWebView (
19
17
controller : OoniWebViewController ,
20
18
modifier : Modifier ,
21
19
allowedDomains : List <String >,
22
20
) {
23
- val onCreated = {}
24
- val onDispose = {}
25
- val currentOnDispose by rememberUpdatedState(onDispose)
26
21
val event = controller.rememberNextEvent()
27
22
28
23
SwingPanel (
29
24
factory = {
25
+ controller.state = OoniWebViewController .State .Initializing
26
+
27
+ println (" webview: factory" )
30
28
JFXPanel ().apply {
29
+ Platform .setImplicitExit(false ) // Otherwise, webView will not show the second time
31
30
Platform .runLater {
31
+ println (" webview: factory runLater" )
32
+
32
33
val webView = WebView ().apply {
33
34
isVisible = true
35
+ @Suppress(" SetJavaScriptEnabled" )
34
36
engine.isJavaScriptEnabled = true
35
37
36
38
// Set up load listeners
@@ -39,18 +41,23 @@ actual fun OoniWebView(
39
41
Worker .State .SCHEDULED -> {
40
42
controller.state = OoniWebViewController .State .Loading (0f )
41
43
}
44
+
42
45
Worker .State .RUNNING -> {
43
46
val progress = engine.loadWorker.progress
44
- controller.state = OoniWebViewController .State .Loading (progress.toFloat())
47
+ controller.state =
48
+ OoniWebViewController .State .Loading (progress.toFloat())
45
49
}
50
+
46
51
Worker .State .SUCCEEDED -> {
47
52
controller.state = OoniWebViewController .State .Successful
48
53
controller.canGoBack = engine.history.currentIndex > 0
49
54
}
55
+
50
56
Worker .State .FAILED -> {
51
57
controller.state = OoniWebViewController .State .Failure
52
58
controller.canGoBack = engine.history.currentIndex > 0
53
59
}
60
+
54
61
else -> {}
55
62
}
56
63
}
@@ -71,45 +78,59 @@ actual fun OoniWebView(
71
78
}
72
79
controller.canGoBack = engine.history.currentIndex > 0
73
80
}
81
+
82
+ val css = """
83
+ body {
84
+ -ms-overflow-style: none; /* Internet Explorer 10+ */
85
+ scrollbar-width: none; /* Firefox */
86
+ }
87
+ body::-webkit-scrollbar {
88
+ display: none; /* Safari and Chrome */
89
+ }
90
+ """ .trimIndent()
91
+ val cssData = Base64 .encode(css.encodeToByteArray())
92
+ engine.userStyleSheetLocation =
93
+ " data:text/css;charset=utf-8;base64,$cssData "
74
94
}
75
95
76
96
val root = StackPane ()
77
97
root.children.add(webView)
78
98
this .scene = Scene (root)
79
- onCreated()
80
99
}
81
100
}
82
101
},
83
102
modifier = modifier,
84
103
update = { jfxPanel ->
104
+ println (" webview: update" )
85
105
Platform .runLater {
86
- val scene = jfxPanel.scene
87
- val root = scene?.root as ? StackPane
88
- val webView = root?.children?.get(0 ) as ? WebView
89
- webView?. let {
90
- when (event) {
91
- is OoniWebViewController . Event . Load -> {
92
- webView.engine.load(event.url)
106
+ println ( " webview: update runLater " )
107
+ val root = jfxPanel. scene?.root as ? StackPane
108
+ val webView = ( root?.children?.get(0 ) as ? WebView ) ? : return @runLater
109
+ when (event) {
110
+ is OoniWebViewController . Event . Load -> {
111
+ val headers = event.additionalHttpHeaders.entries.joinToString {
112
+ " \n ${it.key} : it.value "
93
113
}
94
- OoniWebViewController .Event .Reload -> {
95
- webView.engine.reload()
96
- }
97
- OoniWebViewController .Event .Back -> {
98
- if (webView.engine.history.currentIndex > 0 ) {
99
- webView.engine.history.go(- 1 )
100
- }
114
+ // Hack to send HTTP headers by taking advantage of userAgent
115
+ webView.engine.userAgent = " ooni$headers "
116
+ println (" webview: Loading: ${event.url} " )
117
+ webView.engine.load(event.url)
118
+ }
119
+
120
+ OoniWebViewController .Event .Reload -> {
121
+ webView.engine.reload()
122
+ }
123
+
124
+ OoniWebViewController .Event .Back -> {
125
+ if (webView.engine.history.currentIndex > 0 ) {
126
+ webView.engine.history.go(- 1 )
101
127
}
102
- null -> Unit
103
128
}
129
+
130
+ null -> Unit
104
131
}
132
+ event?.let (controller::onEventHandled)
105
133
}
106
- event?.let (controller::onEventHandled)
107
134
},
108
135
)
109
-
110
- DisposableEffect (Unit ) {
111
- onDispose {
112
- currentOnDispose()
113
- }
114
- }
115
136
}
0 commit comments