优化
This commit is contained in:
@@ -2,6 +2,7 @@ package io.legado.app.data.entities
|
|||||||
|
|
||||||
import cn.hutool.crypto.symmetric.AES
|
import cn.hutool.crypto.symmetric.AES
|
||||||
import com.script.ScriptBindings
|
import com.script.ScriptBindings
|
||||||
|
import com.script.buildScriptBindings
|
||||||
import com.script.rhino.RhinoScriptEngine
|
import com.script.rhino.RhinoScriptEngine
|
||||||
import io.legado.app.constant.AppConst
|
import io.legado.app.constant.AppConst
|
||||||
import io.legado.app.constant.AppLog
|
import io.legado.app.constant.AppLog
|
||||||
@@ -232,13 +233,14 @@ interface BaseSource : JsExtensions {
|
|||||||
*/
|
*/
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun evalJS(jsStr: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? {
|
fun evalJS(jsStr: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? {
|
||||||
val bindings = ScriptBindings()
|
val bindings = buildScriptBindings { bindings ->
|
||||||
bindings.apply(bindingsConfig)
|
bindings.apply(bindingsConfig)
|
||||||
bindings["java"] = this
|
bindings["java"] = this
|
||||||
bindings["source"] = this
|
bindings["source"] = this
|
||||||
bindings["baseUrl"] = getKey()
|
bindings["baseUrl"] = getKey()
|
||||||
bindings["cookie"] = CookieStore
|
bindings["cookie"] = CookieStore
|
||||||
bindings["cache"] = CacheManager
|
bindings["cache"] = CacheManager
|
||||||
|
}
|
||||||
val scope = RhinoScriptEngine.getRuntimeScope(bindings)
|
val scope = RhinoScriptEngine.getRuntimeScope(bindings)
|
||||||
getShareScope()?.let {
|
getShareScope()?.let {
|
||||||
scope.prototype = it
|
scope.prototype = it
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
package io.legado.app.help.book
|
package io.legado.app.help.book
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.script.ScriptBindings
|
import com.script.buildScriptBindings
|
||||||
import com.script.rhino.RhinoScriptEngine
|
import com.script.rhino.RhinoScriptEngine
|
||||||
import io.legado.app.constant.AppLog
|
import io.legado.app.constant.AppLog
|
||||||
import io.legado.app.constant.BookSourceType
|
import io.legado.app.constant.BookSourceType
|
||||||
@@ -273,10 +273,11 @@ fun Book.getExportFileName(suffix: String): String {
|
|||||||
if (jsStr.isNullOrBlank()) {
|
if (jsStr.isNullOrBlank()) {
|
||||||
return "$name 作者:${getRealAuthor()}.$suffix"
|
return "$name 作者:${getRealAuthor()}.$suffix"
|
||||||
}
|
}
|
||||||
val bindings = ScriptBindings()
|
val bindings = buildScriptBindings { bindings ->
|
||||||
bindings["epubIndex"] = ""// 兼容老版本,修复可能存在的错误
|
bindings["epubIndex"] = ""// 兼容老版本,修复可能存在的错误
|
||||||
bindings["name"] = name
|
bindings["name"] = name
|
||||||
bindings["author"] = getRealAuthor()
|
bindings["author"] = getRealAuthor()
|
||||||
|
}
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
|
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
@@ -297,10 +298,11 @@ fun Book.getExportFileName(
|
|||||||
if (jsStr.isNullOrBlank()) {
|
if (jsStr.isNullOrBlank()) {
|
||||||
return default
|
return default
|
||||||
}
|
}
|
||||||
val bindings = ScriptBindings()
|
val bindings = buildScriptBindings { bindings ->
|
||||||
bindings["name"] = name
|
bindings["name"] = name
|
||||||
bindings["author"] = getRealAuthor()
|
bindings["author"] = getRealAuthor()
|
||||||
bindings["epubIndex"] = epubIndex
|
bindings["epubIndex"] = epubIndex
|
||||||
|
}
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
|
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
@@ -327,10 +329,11 @@ fun Book.readSimulating(): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun tryParesExportFileName(jsStr: String): Boolean {
|
fun tryParesExportFileName(jsStr: String): Boolean {
|
||||||
val bindings = ScriptBindings()
|
val bindings = buildScriptBindings { bindings ->
|
||||||
bindings["name"] = "name"
|
bindings["name"] = "name"
|
||||||
bindings["author"] = "author"
|
bindings["author"] = "author"
|
||||||
bindings["epubIndex"] = "epubIndex"
|
bindings["epubIndex"] = "epubIndex"
|
||||||
|
}
|
||||||
return runCatching {
|
return runCatching {
|
||||||
RhinoScriptEngine.eval(jsStr, bindings)
|
RhinoScriptEngine.eval(jsStr, bindings)
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.legado.app.model.analyzeRule
|
|||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.script.ScriptBindings
|
import com.script.ScriptBindings
|
||||||
|
import com.script.buildScriptBindings
|
||||||
import com.script.rhino.RhinoScriptEngine
|
import com.script.rhino.RhinoScriptEngine
|
||||||
import io.legado.app.constant.AppPattern.JS_PATTERN
|
import io.legado.app.constant.AppPattern.JS_PATTERN
|
||||||
import io.legado.app.data.entities.BaseBook
|
import io.legado.app.data.entities.BaseBook
|
||||||
@@ -745,18 +746,19 @@ class AnalyzeRule(
|
|||||||
* 执行JS
|
* 执行JS
|
||||||
*/
|
*/
|
||||||
fun evalJS(jsStr: String, result: Any? = null): Any? {
|
fun evalJS(jsStr: String, result: Any? = null): Any? {
|
||||||
val bindings = ScriptBindings()
|
val bindings = buildScriptBindings { bindings ->
|
||||||
bindings["java"] = this
|
bindings["java"] = this
|
||||||
bindings["cookie"] = CookieStore
|
bindings["cookie"] = CookieStore
|
||||||
bindings["cache"] = CacheManager
|
bindings["cache"] = CacheManager
|
||||||
bindings["source"] = source
|
bindings["source"] = source
|
||||||
bindings["book"] = book
|
bindings["book"] = book
|
||||||
bindings["result"] = result
|
bindings["result"] = result
|
||||||
bindings["baseUrl"] = baseUrl
|
bindings["baseUrl"] = baseUrl
|
||||||
bindings["chapter"] = chapter
|
bindings["chapter"] = chapter
|
||||||
bindings["title"] = chapter?.title
|
bindings["title"] = chapter?.title
|
||||||
bindings["src"] = content
|
bindings["src"] = content
|
||||||
bindings["nextChapterUrl"] = nextChapterUrl
|
bindings["nextChapterUrl"] = nextChapterUrl
|
||||||
|
}
|
||||||
val scope = RhinoScriptEngine.getRuntimeScope(bindings)
|
val scope = RhinoScriptEngine.getRuntimeScope(bindings)
|
||||||
source?.getShareScope()?.let {
|
source?.getShareScope()?.let {
|
||||||
scope.prototype = it
|
scope.prototype = it
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import androidx.annotation.Keep
|
|||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import cn.hutool.core.util.HexUtil
|
import cn.hutool.core.util.HexUtil
|
||||||
import com.bumptech.glide.load.model.GlideUrl
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
import com.script.ScriptBindings
|
import com.script.buildScriptBindings
|
||||||
import com.script.rhino.RhinoScriptEngine
|
import com.script.rhino.RhinoScriptEngine
|
||||||
import io.legado.app.constant.AppConst.UA_NAME
|
import io.legado.app.constant.AppConst.UA_NAME
|
||||||
import io.legado.app.constant.AppPattern
|
import io.legado.app.constant.AppPattern
|
||||||
@@ -266,18 +266,19 @@ class AnalyzeUrl(
|
|||||||
* 执行JS
|
* 执行JS
|
||||||
*/
|
*/
|
||||||
fun evalJS(jsStr: String, result: Any? = null): Any? {
|
fun evalJS(jsStr: String, result: Any? = null): Any? {
|
||||||
val bindings = ScriptBindings()
|
val bindings = buildScriptBindings { bindings ->
|
||||||
bindings["java"] = this
|
bindings["java"] = this
|
||||||
bindings["baseUrl"] = baseUrl
|
bindings["baseUrl"] = baseUrl
|
||||||
bindings["cookie"] = CookieStore
|
bindings["cookie"] = CookieStore
|
||||||
bindings["cache"] = CacheManager
|
bindings["cache"] = CacheManager
|
||||||
bindings["page"] = page
|
bindings["page"] = page
|
||||||
bindings["key"] = key
|
bindings["key"] = key
|
||||||
bindings["speakText"] = speakText
|
bindings["speakText"] = speakText
|
||||||
bindings["speakSpeed"] = speakSpeed
|
bindings["speakSpeed"] = speakSpeed
|
||||||
bindings["book"] = ruleData as? Book
|
bindings["book"] = ruleData as? Book
|
||||||
bindings["source"] = source
|
bindings["source"] = source
|
||||||
bindings["result"] = result
|
bindings["result"] = result
|
||||||
|
}
|
||||||
val scope = RhinoScriptEngine.getRuntimeScope(bindings)
|
val scope = RhinoScriptEngine.getRuntimeScope(bindings)
|
||||||
source?.getShareScope()?.let {
|
source?.getShareScope()?.let {
|
||||||
scope.prototype = it
|
scope.prototype = it
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import io.legado.app.utils.isTrue
|
|||||||
import io.legado.app.utils.mapAsync
|
import io.legado.app.utils.mapAsync
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import org.mozilla.javascript.Context
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
import kotlin.coroutines.coroutineContext
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
@@ -126,21 +127,25 @@ object BookChapterList {
|
|||||||
}
|
}
|
||||||
Debug.log(book.origin, "◇目录总数:${list.size}")
|
Debug.log(book.origin, "◇目录总数:${list.size}")
|
||||||
coroutineContext.ensureActive()
|
coroutineContext.ensureActive()
|
||||||
val formatJs = tocRule.formatJs
|
|
||||||
val bindings = ScriptBindings()
|
|
||||||
bindings["gInt"] = 0
|
|
||||||
list.forEachIndexed { index, bookChapter ->
|
list.forEachIndexed { index, bookChapter ->
|
||||||
bookChapter.index = index
|
bookChapter.index = index
|
||||||
if (!formatJs.isNullOrBlank()) {
|
}
|
||||||
bindings["index"] = index + 1
|
val formatJs = tocRule.formatJs
|
||||||
bindings["chapter"] = bookChapter
|
if (!formatJs.isNullOrBlank()) {
|
||||||
bindings["title"] = bookChapter.title
|
Context.enter().use {
|
||||||
RhinoScriptEngine.runCatching {
|
val bindings = ScriptBindings()
|
||||||
eval(formatJs, bindings)?.toString()?.let {
|
bindings["gInt"] = 0
|
||||||
bookChapter.title = it
|
list.forEachIndexed { index, bookChapter ->
|
||||||
|
bindings["index"] = index + 1
|
||||||
|
bindings["chapter"] = bookChapter
|
||||||
|
bindings["title"] = bookChapter.title
|
||||||
|
RhinoScriptEngine.runCatching {
|
||||||
|
eval(formatJs, bindings)?.toString()?.let {
|
||||||
|
bookChapter.title = it
|
||||||
|
}
|
||||||
|
}.onFailure {
|
||||||
|
Debug.log(book.origin, "格式化标题出错, ${it.localizedMessage}")
|
||||||
}
|
}
|
||||||
}.onFailure {
|
|
||||||
Debug.log(book.origin, "格式化标题出错, ${it.localizedMessage}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ protobuf-javalite = { module = "com.google.protobuf:protobuf-javalite", version.
|
|||||||
|
|
||||||
quick-chinese-transfer-core = { module = "com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core", version.ref = "quickChineseTransfer" }
|
quick-chinese-transfer-core = { module = "com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core", version.ref = "quickChineseTransfer" }
|
||||||
|
|
||||||
|
|
||||||
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
||||||
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
||||||
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
|
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
|
||||||
|
|||||||
@@ -39,4 +39,8 @@ class ScriptBindings : NativeObject() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun put(key: String, value: Any?) {
|
||||||
|
set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.script
|
||||||
|
|
||||||
|
import org.mozilla.javascript.Context
|
||||||
|
|
||||||
|
inline fun buildScriptBindings(block: (bindings: ScriptBindings) -> Unit): ScriptBindings {
|
||||||
|
val bindings = ScriptBindings()
|
||||||
|
Context.enter()
|
||||||
|
try {
|
||||||
|
block(bindings)
|
||||||
|
} finally {
|
||||||
|
Context.exit()
|
||||||
|
}
|
||||||
|
return bindings
|
||||||
|
}
|
||||||
@@ -55,7 +55,12 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
|
|
||||||
fun eval(js: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? {
|
fun eval(js: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? {
|
||||||
val bindings = ScriptBindings()
|
val bindings = ScriptBindings()
|
||||||
bindings.apply(bindingsConfig)
|
Context.enter()
|
||||||
|
try {
|
||||||
|
bindings.apply(bindingsConfig)
|
||||||
|
} finally {
|
||||||
|
Context.exit()
|
||||||
|
}
|
||||||
return eval(js, bindings)
|
return eval(js, bindings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +254,7 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
return newScope
|
return newScope
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRuntimeScope(bindings: ScriptBindings): ScriptBindings {
|
override fun getRuntimeScope(bindings: ScriptBindings): Scriptable {
|
||||||
val cx = Context.enter()
|
val cx = Context.enter()
|
||||||
try {
|
try {
|
||||||
bindings.prototype = cx.initStandardObjects()
|
bindings.prototype = cx.initStandardObjects()
|
||||||
|
|||||||
Reference in New Issue
Block a user