订阅添加url跳转拦截(js, 返回true拦截,js变量url,可以通过js打开url,比如调用阅读搜索,添加书架等,简化规则写法,不用webView js注入)

This commit is contained in:
kunfei
2023-07-28 09:15:52 +08:00
parent ee33893c0e
commit d8789f9821
5 changed files with 1940 additions and 4 deletions
File diff suppressed because it is too large Load Diff
@@ -25,7 +25,7 @@ val appDb by lazy {
} }
@Database( @Database(
version = 69, version = 70,
exportSchema = true, exportSchema = true,
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class, entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
@@ -58,7 +58,8 @@ val appDb by lazy {
AutoMigration(from = 65, to = 66), AutoMigration(from = 65, to = 66),
AutoMigration(from = 66, to = 67), AutoMigration(from = 66, to = 67),
AutoMigration(from = 67, to = 68), AutoMigration(from = 67, to = 68),
AutoMigration(from = 68, to = 69) AutoMigration(from = 68, to = 69),
AutoMigration(from = 69, to = 70)
] ]
) )
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
@@ -73,6 +73,11 @@ data class RssSource(
var contentWhitelist: String? = null, var contentWhitelist: String? = null,
/**正文url黑名单**/ /**正文url黑名单**/
var contentBlacklist: String? = null, var contentBlacklist: String? = null,
/**
* 跳转url拦截,
* js, 返回true拦截,js变量url,可以通过js打开url,比如调用阅读搜索,添加书架等,简化规则写法,不用webView js注入
* **/
var shouldOverrideUrlLoading: String? = null,
/**webView样式**/ /**webView样式**/
var style: String? = null, var style: String? = null,
@ColumnInfo(defaultValue = "1") @ColumnInfo(defaultValue = "1")
@@ -398,6 +398,16 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
} }
private fun shouldOverrideUrlLoading(url: Uri): Boolean { private fun shouldOverrideUrlLoading(url: Uri): Boolean {
val source = viewModel.rssSource
val js = source?.shouldOverrideUrlLoading
if (!js.isNullOrBlank()) {
val result = source.evalJS(js) {
put("url", url.toString())
}.toString()
if (result.isTrue()) {
return true
}
}
when (url.scheme) { when (url.scheme) {
"http", "https", "jsbridge" -> { "http", "https", "jsbridge" -> {
return false return false
@@ -27,7 +27,16 @@ import io.legado.app.ui.widget.dialog.UrlOptionDialog
import io.legado.app.ui.widget.dialog.VariableDialog import io.legado.app.ui.widget.dialog.VariableDialog
import io.legado.app.ui.widget.keyboard.KeyboardToolPop import io.legado.app.ui.widget.keyboard.KeyboardToolPop
import io.legado.app.ui.widget.text.EditEntity import io.legado.app.ui.widget.text.EditEntity
import io.legado.app.utils.* import io.legado.app.utils.GSON
import io.legado.app.utils.isContentScheme
import io.legado.app.utils.isTrue
import io.legado.app.utils.launch
import io.legado.app.utils.sendToClip
import io.legado.app.utils.setEdgeEffectColor
import io.legado.app.utils.share
import io.legado.app.utils.shareWithQr
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.startActivity
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -116,17 +125,20 @@ class RssSourceEditActivity :
setResult(Activity.RESULT_OK) setResult(Activity.RESULT_OK)
finish() finish()
} }
R.id.menu_debug_source -> viewModel.save(getRssSource()) { source -> R.id.menu_debug_source -> viewModel.save(getRssSource()) { source ->
startActivity<RssSourceDebugActivity> { startActivity<RssSourceDebugActivity> {
putExtra("key", source.sourceUrl) putExtra("key", source.sourceUrl)
} }
} }
R.id.menu_login -> viewModel.save(getRssSource()) { R.id.menu_login -> viewModel.save(getRssSource()) {
startActivity<SourceLoginActivity> { startActivity<SourceLoginActivity> {
putExtra("type", "rssSource") putExtra("type", "rssSource")
putExtra("key", it.sourceUrl) putExtra("key", it.sourceUrl)
} }
} }
R.id.menu_set_source_variable -> setSourceVariable() R.id.menu_set_source_variable -> setSourceVariable()
R.id.menu_clear_cookie -> viewModel.clearCookie(getRssSource().sourceUrl) R.id.menu_clear_cookie -> viewModel.clearCookie(getRssSource().sourceUrl)
R.id.menu_auto_complete -> viewModel.autoComplete = !viewModel.autoComplete R.id.menu_auto_complete -> viewModel.autoComplete = !viewModel.autoComplete
@@ -139,6 +151,7 @@ class RssSourceEditActivity :
getString(R.string.share_rss_source), getString(R.string.share_rss_source),
ErrorCorrectionLevel.L ErrorCorrectionLevel.L
) )
R.id.menu_help -> showHelp("ruleHelp") R.id.menu_help -> showHelp("ruleHelp")
} }
return super.onCompatOptionsItemSelected(item) return super.onCompatOptionsItemSelected(item)
@@ -239,6 +252,13 @@ class RssSourceEditActivity :
add(EditEntity("injectJs", rs.injectJs, R.string.r_inject_js)) add(EditEntity("injectJs", rs.injectJs, R.string.r_inject_js))
add(EditEntity("contentWhitelist", rs.contentWhitelist, R.string.c_whitelist)) add(EditEntity("contentWhitelist", rs.contentWhitelist, R.string.c_whitelist))
add(EditEntity("contentBlacklist", rs.contentBlacklist, R.string.c_blacklist)) add(EditEntity("contentBlacklist", rs.contentBlacklist, R.string.c_blacklist))
add(
EditEntity(
"shouldOverrideUrlLoading",
rs.shouldOverrideUrlLoading,
"url跳转拦截(js, 返回true拦截,js变量url,可以通过js打开url,比如调用阅读搜索,添加书架等,简化规则写法,不用webView js注入)"
)
)
} }
binding.tabLayout.selectTab(binding.tabLayout.getTabAt(0)) binding.tabLayout.selectTab(binding.tabLayout.getTabAt(0))
setEditEntities(0) setEditEntities(0)
@@ -272,14 +292,19 @@ class RssSourceEditActivity :
"ruleArticles" -> source.ruleArticles = it.value "ruleArticles" -> source.ruleArticles = it.value
"ruleNextPage" -> source.ruleNextPage = "ruleNextPage" -> source.ruleNextPage =
viewModel.ruleComplete(it.value, source.ruleArticles, 2) viewModel.ruleComplete(it.value, source.ruleArticles, 2)
"ruleTitle" -> source.ruleTitle = "ruleTitle" -> source.ruleTitle =
viewModel.ruleComplete(it.value, source.ruleArticles) viewModel.ruleComplete(it.value, source.ruleArticles)
"rulePubDate" -> source.rulePubDate = "rulePubDate" -> source.rulePubDate =
viewModel.ruleComplete(it.value, source.ruleArticles) viewModel.ruleComplete(it.value, source.ruleArticles)
"ruleDescription" -> source.ruleDescription = "ruleDescription" -> source.ruleDescription =
viewModel.ruleComplete(it.value, source.ruleArticles) viewModel.ruleComplete(it.value, source.ruleArticles)
"ruleImage" -> source.ruleImage = "ruleImage" -> source.ruleImage =
viewModel.ruleComplete(it.value, source.ruleArticles, 3) viewModel.ruleComplete(it.value, source.ruleArticles, 3)
"ruleLink" -> source.ruleLink = "ruleLink" -> source.ruleLink =
viewModel.ruleComplete(it.value, source.ruleArticles) viewModel.ruleComplete(it.value, source.ruleArticles)
} }
@@ -290,10 +315,12 @@ class RssSourceEditActivity :
"loadWithBaseUrl" -> source.loadWithBaseUrl = it.value.isTrue() "loadWithBaseUrl" -> source.loadWithBaseUrl = it.value.isTrue()
"ruleContent" -> source.ruleContent = "ruleContent" -> source.ruleContent =
viewModel.ruleComplete(it.value, source.ruleArticles) viewModel.ruleComplete(it.value, source.ruleArticles)
"style" -> source.style = it.value "style" -> source.style = it.value
"injectJs" -> source.injectJs = it.value "injectJs" -> source.injectJs = it.value
"contentWhitelist" -> source.contentWhitelist = it.value "contentWhitelist" -> source.contentWhitelist = it.value
"contentBlacklist" -> source.contentBlacklist = it.value "contentBlacklist" -> source.contentBlacklist = it.value
"shouldOverrideUrlLoading" -> source.shouldOverrideUrlLoading = it.value
} }
} }
return source return source
@@ -302,7 +329,8 @@ class RssSourceEditActivity :
private fun setSourceVariable() { private fun setSourceVariable() {
viewModel.save(getRssSource()) { source -> viewModel.save(getRssSource()) { source ->
launch { launch {
val comment = source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") val comment =
source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取")
val variable = withContext(Dispatchers.IO) { source.getVariable() } val variable = withContext(Dispatchers.IO) { source.getVariable() }
showDialogFragment( showDialogFragment(
VariableDialog( VariableDialog(
@@ -335,6 +363,7 @@ class RssSourceEditActivity :
"urlOption" -> UrlOptionDialog(this) { "urlOption" -> UrlOptionDialog(this) {
sendText(it) sendText(it)
}.show() }.show()
"ruleHelp" -> showHelp("ruleHelp") "ruleHelp" -> showHelp("ruleHelp")
"jsHelp" -> showHelp("jsHelp") "jsHelp" -> showHelp("jsHelp")
"regexHelp" -> showHelp("regexHelp") "regexHelp" -> showHelp("regexHelp")