kunfei 3 лет назад
Родитель
Сommit
c36eb2ca03

+ 0 - 19
app/src/main/java/io/legado/app/help/JsEngine.kt

@@ -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)
-    }
-
-}

+ 11 - 2
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)
+    }
+
     /**
      * 弹窗提示
      */

+ 0 - 40
app/src/main/java/io/legado/app/rhino/RhinoExtensions.kt

@@ -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 = "<Unknown source>",
-    lineno: Int = 1,
-    securityDomain: Any? = null
-): Any? {
-    return evaluateString(scope, source, sourceName, lineno, securityDomain)
-}
-
-fun Context.eval(
-    scope: Scriptable,
-    reader: Reader,
-    sourceName: String = "<Unknown source>",
-    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)
-    }
-}

+ 34 - 3
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<ActivityRssReadBinding, ReadRssViewModel>
 
     override val binding by viewBinding(ActivityRssReadBinding::inflate)
     override val viewModel by viewModels<ReadRssViewModel>()
+
     private var starMenuItem: MenuItem? = null
     private var ttsMenuItem: MenuItem? = null
     private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null
@@ -48,6 +54,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
             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<ActivityRssReadBinding, ReadRssViewModel>
             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<ActivityRssReadBinding, ReadRssViewModel>
 
     }
 
+    @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))
+        }
+
+    }
+
 }

+ 7 - 1
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<Boolean>()
     val upStarMenuData = MutableLiveData<Boolean>()
 
+    override fun getSource(): BaseSource? {
+        return rssSource
+    }
+
     fun initData(intent: Intent) {
         execute {
             val origin = intent.getStringExtra("origin") ?: return@execute

+ 30 - 0
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<String, String>?
+
+    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<String, String>()
+            query.split("&").forEach {
+                val x = it.split("=")
+                map[x[0]] = URLDecoder.decode(x[1], "utf-8")
+            }
+            map
+        }
+    }
+
+
+}

+ 6 - 0
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<Any, Any?>
     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()