forked from starifly/NekoBoxForAndroid
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWebviewFragment.kt
More file actions
96 lines (86 loc) · 3.75 KB
/
Copy pathWebviewFragment.kt
File metadata and controls
96 lines (86 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package io.nekohasekai.sagernet.ui
import android.annotation.SuppressLint
import android.os.Bundle
import android.text.InputType
import android.view.MenuItem
import android.view.View
import android.webkit.*
import android.widget.EditText
import androidx.appcompat.widget.Toolbar
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.nekohasekai.sagernet.BuildConfig
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.databinding.LayoutWebviewBinding
import moe.matsuri.nb4a.utils.WebViewUtil
// Fragment must have a no-argument public constructor, otherwise it will crash during data restoration
class WebviewFragment : ToolbarFragment(R.layout.layout_webview), Toolbar.OnMenuItemClickListener {
lateinit var mWebView: WebView
@SuppressLint("SetJavaScriptEnabled")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// layout
toolbar.setTitle(R.string.menu_dashboard)
toolbar.inflateMenu(R.menu.yacd_menu)
toolbar.setOnMenuItemClickListener(this)
val binding = LayoutWebviewBinding.bind(view)
// webview
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG)
mWebView = binding.webview
mWebView.settings.apply {
// The Clash/yacd dashboard is a JS SPA talking to the local Clash API, so JS
// and DOM storage are required. Everything else is locked down: the dashboard
// (a user-editable URL) must never be able to read the device filesystem or
// content providers, escalate from file:// origins, or downgrade to cleartext
// resources on an https page.
javaScriptEnabled = true
domStorageEnabled = true
allowFileAccess = false
allowContentAccess = false
@Suppress("DEPRECATION")
allowFileAccessFromFileURLs = false
@Suppress("DEPRECATION")
allowUniversalAccessFromFileURLs = false
mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW
// No automatic JS-initiated window.open popups.
javaScriptCanOpenWindowsAutomatically = false
setSupportMultipleWindows(false)
}
mWebView.webViewClient = object : WebViewClient() {
override fun onReceivedError(
view: WebView?, request: WebResourceRequest?, error: WebResourceError?
) {
WebViewUtil.onReceivedError(view, request, error)
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
}
}
mWebView.loadUrl(DataStore.yacdURL)
}
@SuppressLint("CheckResult")
override fun onMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_set_url -> {
val view = EditText(context).apply {
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
setText(DataStore.yacdURL)
}
MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.set_panel_url)
.setView(view)
.setPositiveButton(android.R.string.ok) { _, _ ->
DataStore.yacdURL = view.text.toString()
mWebView.loadUrl(DataStore.yacdURL)
}
.setNegativeButton(android.R.string.cancel, null)
.show()
}
R.id.close -> {
mWebView.onPause()
mWebView.removeAllViews()
mWebView.destroy()
}
}
return true
}
}