diff --git a/app/src/main/java/io/legado/app/help/JsEngine.kt b/app/src/main/java/io/legado/app/help/JsEngine.kt deleted file mode 100644 index 0a2447ffd..000000000 --- a/app/src/main/java/io/legado/app/help/JsEngine.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.legado.app.help - -import com.script.SimpleBindings -import com.script.rhino.RhinoScriptEngine -import io.legado.app.data.entities.BaseSource - -object JsEngine : JsExtensions { - - override fun getSource(): BaseSource? { - return null - } - - fun eval(js: String): Any? { - val bindings = SimpleBindings() - bindings["java"] = this - return RhinoScriptEngine.eval(js, bindings) - } - -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 7366712ff..79a6ab5eb 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -539,9 +539,9 @@ interface JsExtensions : JsEncodeUtils { /** * 删除本地文件 */ - fun deleteFile(path: String) { + fun deleteFile(path: String): Boolean { val file = getFile(path) - FileUtils.delete(file, true) + return FileUtils.delete(file, true) } /** @@ -825,6 +825,15 @@ interface JsExtensions : JsEncodeUtils { return s } + + fun toURL(urlStr: String): JsURL { + return JsURL(urlStr) + } + + fun toURL(url: String, baseUrl: String? = null): JsURL { + return JsURL(url, baseUrl) + } + /** * 弹窗提示 */ diff --git a/app/src/main/java/io/legado/app/rhino/RhinoExtensions.kt b/app/src/main/java/io/legado/app/rhino/RhinoExtensions.kt deleted file mode 100644 index 213ec9b1d..000000000 --- a/app/src/main/java/io/legado/app/rhino/RhinoExtensions.kt +++ /dev/null @@ -1,40 +0,0 @@ -@file:Suppress("unused") - -package io.legado.app.rhino - -import com.script.Bindings -import org.mozilla.javascript.Context -import org.mozilla.javascript.Scriptable -import org.mozilla.javascript.ScriptableObject -import java.io.Reader - -fun Context.eval( - scope: Scriptable, - source: String, - sourceName: String = "", - lineno: Int = 1, - securityDomain: Any? = null -): Any? { - return evaluateString(scope, source, sourceName, lineno, securityDomain) -} - -fun Context.eval( - scope: Scriptable, - reader: Reader, - sourceName: String = "", - lineno: Int = 1, - securityDomain: Any? = null -): Any? { - return evaluateReader(scope, reader, sourceName, lineno, securityDomain) -} - -fun Scriptable.putBinding(key: String, value: Any?) { - val wrappedOut = Context.javaToJS(value, this) - ScriptableObject.putProperty(this, key, wrappedOut) -} - -fun Scriptable.putBindings(bindings: Bindings) { - bindings.forEach { (t, u) -> - putBinding(t, u) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt index bc0372c35..b431325ea 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt @@ -10,18 +10,23 @@ import android.view.* import android.webkit.* import androidx.activity.viewModels import androidx.core.view.size +import com.script.rhino.RhinoScriptEngine import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst.imagePathKey +import io.legado.app.data.entities.BaseSource import io.legado.app.databinding.ActivityRssReadBinding +import io.legado.app.help.JsExtensions import io.legado.app.help.config.AppConfig import io.legado.app.lib.dialogs.SelectItem import io.legado.app.lib.dialogs.selector import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.primaryTextColor import io.legado.app.model.Download +import io.legado.app.ui.association.AddToBookshelfDialog import io.legado.app.ui.association.OnLineImportActivity +import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.file.HandleFileContract import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.utils.* @@ -39,6 +44,7 @@ class ReadRssActivity : VMBaseActivity override val binding by viewBinding(ActivityRssReadBinding::inflate) override val viewModel by viewModels() + private var starMenuItem: MenuItem? = null private var ttsMenuItem: MenuItem? = null private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null @@ -48,6 +54,7 @@ class ReadRssActivity : VMBaseActivity viewModel.saveImage(it.value, uri) } } + private val rssJsExtensions by lazy { RssJsExtensions() } override fun onActivityCreated(savedInstanceState: Bundle?) { viewModel.upStarMenuData.observe(this) { upStarMenu() } @@ -401,9 +408,14 @@ class ReadRssActivity : VMBaseActivity val source = viewModel.rssSource val js = source?.shouldOverrideUrlLoading if (!js.isNullOrBlank()) { - val result = source.evalJS(js) { - put("url", url.toString()) - }.toString() + val result = RhinoScriptEngine.runCatching { + eval(js) { + put("java", rssJsExtensions) + put("url", url.toString()) + }.toString() + }.onFailure { + it.printOnDebug() + }.getOrNull() if (result.isTrue()) { return true } @@ -440,4 +452,23 @@ class ReadRssActivity : VMBaseActivity } + @Suppress("unused") + private inner class RssJsExtensions : JsExtensions { + + override fun getSource(): BaseSource? { + return viewModel.rssSource + } + + fun searchBook(key: String) { + launch { + SearchActivity.start(this@ReadRssActivity, key) + } + } + + fun addBook(bookUrl: String) { + showDialogFragment(AddToBookshelfDialog(bookUrl)) + } + + } + } diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt index 072e11e1f..64bd51c3d 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt @@ -10,10 +10,12 @@ import androidx.lifecycle.viewModelScope import io.legado.app.base.BaseViewModel import io.legado.app.constant.AppConst import io.legado.app.data.appDb +import io.legado.app.data.entities.BaseSource import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssStar import io.legado.app.exception.NoStackTraceException +import io.legado.app.help.JsExtensions import io.legado.app.help.TTS import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient @@ -26,7 +28,7 @@ import splitties.init.appCtx import java.util.Date -class ReadRssViewModel(application: Application) : BaseViewModel(application) { +class ReadRssViewModel(application: Application) : BaseViewModel(application), JsExtensions { var rssSource: RssSource? = null var rssArticle: RssArticle? = null var tts: TTS? = null @@ -36,6 +38,10 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) { val upTtsMenuData = MutableLiveData() val upStarMenuData = MutableLiveData() + override fun getSource(): BaseSource? { + return rssSource + } + fun initData(intent: Intent) { execute { val origin = intent.getStringExtra("origin") ?: return@execute diff --git a/app/src/main/java/io/legado/app/utils/JsURL.kt b/app/src/main/java/io/legado/app/utils/JsURL.kt new file mode 100644 index 000000000..28c65b747 --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/JsURL.kt @@ -0,0 +1,30 @@ +package io.legado.app.utils + +import java.net.URL +import java.net.URLDecoder + +@Suppress("MemberVisibilityCanBePrivate") +class JsURL(url: String, baseUrl: String? = null) { + + val searchParams: Map? + + init { + val mUrl = if (!baseUrl.isNullOrEmpty()) { + val base = URL(baseUrl) + URL(base, url) + } else { + URL(url) + } + val query = mUrl.query + searchParams = query?.let { query -> + val map = hashMapOf() + query.split("&").forEach { + val x = it.split("=") + map[x[0]] = URLDecoder.decode(x[1], "utf-8") + } + map + } + } + + +} \ No newline at end of file diff --git a/modules/rhino1.7.3/src/main/java/com/script/rhino/RhinoScriptEngine.kt b/modules/rhino1.7.3/src/main/java/com/script/rhino/RhinoScriptEngine.kt index ae0759c3b..8d0f487bb 100644 --- a/modules/rhino1.7.3/src/main/java/com/script/rhino/RhinoScriptEngine.kt +++ b/modules/rhino1.7.3/src/main/java/com/script/rhino/RhinoScriptEngine.kt @@ -48,6 +48,12 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable { private val indexedProps: MutableMap private val implementor: InterfaceImplementor + fun eval(js: String, bindingsConfig: SimpleBindings.() -> Unit = {}): Any? { + val bindings = SimpleBindings() + bindings.apply(bindingsConfig) + return eval(js, bindings) + } + @Throws(ScriptException::class) override fun eval(reader: Reader, scope: Scriptable): Any? { val cx = Context.enter()