From 0fea035a05ff18c93d533f26150873f31fc7e266 Mon Sep 17 00:00:00 2001 From: Horis <8674809+821938089@users.noreply.github.com> Date: Wed, 31 Jul 2024 19:20:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/data/entities/BaseSource.kt | 16 +++++----- .../io/legado/app/help/book/BookExtensions.kt | 29 ++++++++++--------- .../app/model/analyzeRule/AnalyzeRule.kt | 26 +++++++++-------- .../app/model/analyzeRule/AnalyzeUrl.kt | 27 ++++++++--------- .../app/model/webBook/BookChapterList.kt | 29 +++++++++++-------- gradle/libs.versions.toml | 1 - .../main/java/com/script/ScriptBindings.kt | 4 +++ .../com/script/ScriptBindingsExtensions.kt | 14 +++++++++ .../com/script/rhino/RhinoScriptEngine.kt | 9 ++++-- 9 files changed, 95 insertions(+), 60 deletions(-) create mode 100644 modules/rhino/src/main/java/com/script/ScriptBindingsExtensions.kt diff --git a/app/src/main/java/io/legado/app/data/entities/BaseSource.kt b/app/src/main/java/io/legado/app/data/entities/BaseSource.kt index fa6e74af0..d9453a8f5 100644 --- a/app/src/main/java/io/legado/app/data/entities/BaseSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BaseSource.kt @@ -2,6 +2,7 @@ package io.legado.app.data.entities import cn.hutool.crypto.symmetric.AES import com.script.ScriptBindings +import com.script.buildScriptBindings import com.script.rhino.RhinoScriptEngine import io.legado.app.constant.AppConst import io.legado.app.constant.AppLog @@ -232,13 +233,14 @@ interface BaseSource : JsExtensions { */ @Throws(Exception::class) fun evalJS(jsStr: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? { - val bindings = ScriptBindings() - bindings.apply(bindingsConfig) - bindings["java"] = this - bindings["source"] = this - bindings["baseUrl"] = getKey() - bindings["cookie"] = CookieStore - bindings["cache"] = CacheManager + val bindings = buildScriptBindings { bindings -> + bindings.apply(bindingsConfig) + bindings["java"] = this + bindings["source"] = this + bindings["baseUrl"] = getKey() + bindings["cookie"] = CookieStore + bindings["cache"] = CacheManager + } val scope = RhinoScriptEngine.getRuntimeScope(bindings) getShareScope()?.let { scope.prototype = it diff --git a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt index 1b6068fb3..c90e11de3 100644 --- a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt +++ b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt @@ -3,7 +3,7 @@ package io.legado.app.help.book import android.net.Uri -import com.script.ScriptBindings +import com.script.buildScriptBindings import com.script.rhino.RhinoScriptEngine import io.legado.app.constant.AppLog import io.legado.app.constant.BookSourceType @@ -273,10 +273,11 @@ fun Book.getExportFileName(suffix: String): String { if (jsStr.isNullOrBlank()) { return "$name 作者:${getRealAuthor()}.$suffix" } - val bindings = ScriptBindings() - bindings["epubIndex"] = ""// 兼容老版本,修复可能存在的错误 - bindings["name"] = name - bindings["author"] = getRealAuthor() + val bindings = buildScriptBindings { bindings -> + bindings["epubIndex"] = ""// 兼容老版本,修复可能存在的错误 + bindings["name"] = name + bindings["author"] = getRealAuthor() + } return kotlin.runCatching { RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix }.onFailure { @@ -297,10 +298,11 @@ fun Book.getExportFileName( if (jsStr.isNullOrBlank()) { return default } - val bindings = ScriptBindings() - bindings["name"] = name - bindings["author"] = getRealAuthor() - bindings["epubIndex"] = epubIndex + val bindings = buildScriptBindings { bindings -> + bindings["name"] = name + bindings["author"] = getRealAuthor() + bindings["epubIndex"] = epubIndex + } return kotlin.runCatching { RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix }.onFailure { @@ -327,10 +329,11 @@ fun Book.readSimulating(): Boolean { } fun tryParesExportFileName(jsStr: String): Boolean { - val bindings = ScriptBindings() - bindings["name"] = "name" - bindings["author"] = "author" - bindings["epubIndex"] = "epubIndex" + val bindings = buildScriptBindings { bindings -> + bindings["name"] = "name" + bindings["author"] = "author" + bindings["epubIndex"] = "epubIndex" + } return runCatching { RhinoScriptEngine.eval(jsStr, bindings) true diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index b076af9c4..9431fe7ef 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -3,6 +3,7 @@ package io.legado.app.model.analyzeRule import android.text.TextUtils import androidx.annotation.Keep import com.script.ScriptBindings +import com.script.buildScriptBindings import com.script.rhino.RhinoScriptEngine import io.legado.app.constant.AppPattern.JS_PATTERN import io.legado.app.data.entities.BaseBook @@ -745,18 +746,19 @@ class AnalyzeRule( * 执行JS */ fun evalJS(jsStr: String, result: Any? = null): Any? { - val bindings = ScriptBindings() - bindings["java"] = this - bindings["cookie"] = CookieStore - bindings["cache"] = CacheManager - bindings["source"] = source - bindings["book"] = book - bindings["result"] = result - bindings["baseUrl"] = baseUrl - bindings["chapter"] = chapter - bindings["title"] = chapter?.title - bindings["src"] = content - bindings["nextChapterUrl"] = nextChapterUrl + val bindings = buildScriptBindings { bindings -> + bindings["java"] = this + bindings["cookie"] = CookieStore + bindings["cache"] = CacheManager + bindings["source"] = source + bindings["book"] = book + bindings["result"] = result + bindings["baseUrl"] = baseUrl + bindings["chapter"] = chapter + bindings["title"] = chapter?.title + bindings["src"] = content + bindings["nextChapterUrl"] = nextChapterUrl + } val scope = RhinoScriptEngine.getRuntimeScope(bindings) source?.getShareScope()?.let { scope.prototype = it diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index fb026abf6..7b2f87069 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -6,7 +6,7 @@ import androidx.annotation.Keep import androidx.media3.common.MediaItem import cn.hutool.core.util.HexUtil import com.bumptech.glide.load.model.GlideUrl -import com.script.ScriptBindings +import com.script.buildScriptBindings import com.script.rhino.RhinoScriptEngine import io.legado.app.constant.AppConst.UA_NAME import io.legado.app.constant.AppPattern @@ -266,18 +266,19 @@ class AnalyzeUrl( * 执行JS */ fun evalJS(jsStr: String, result: Any? = null): Any? { - val bindings = ScriptBindings() - bindings["java"] = this - bindings["baseUrl"] = baseUrl - bindings["cookie"] = CookieStore - bindings["cache"] = CacheManager - bindings["page"] = page - bindings["key"] = key - bindings["speakText"] = speakText - bindings["speakSpeed"] = speakSpeed - bindings["book"] = ruleData as? Book - bindings["source"] = source - bindings["result"] = result + val bindings = buildScriptBindings { bindings -> + bindings["java"] = this + bindings["baseUrl"] = baseUrl + bindings["cookie"] = CookieStore + bindings["cache"] = CacheManager + bindings["page"] = page + bindings["key"] = key + bindings["speakText"] = speakText + bindings["speakSpeed"] = speakSpeed + bindings["book"] = ruleData as? Book + bindings["source"] = source + bindings["result"] = result + } val scope = RhinoScriptEngine.getRuntimeScope(bindings) source?.getShareScope()?.let { scope.prototype = it diff --git a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt index 49c4d0416..d4041ebf4 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt @@ -20,6 +20,7 @@ import io.legado.app.utils.isTrue import io.legado.app.utils.mapAsync import kotlinx.coroutines.ensureActive import kotlinx.coroutines.flow.flow +import org.mozilla.javascript.Context import splitties.init.appCtx import kotlin.coroutines.coroutineContext @@ -126,21 +127,25 @@ object BookChapterList { } Debug.log(book.origin, "◇目录总数:${list.size}") coroutineContext.ensureActive() - val formatJs = tocRule.formatJs - val bindings = ScriptBindings() - bindings["gInt"] = 0 list.forEachIndexed { index, bookChapter -> bookChapter.index = index - if (!formatJs.isNullOrBlank()) { - bindings["index"] = index + 1 - bindings["chapter"] = bookChapter - bindings["title"] = bookChapter.title - RhinoScriptEngine.runCatching { - eval(formatJs, bindings)?.toString()?.let { - bookChapter.title = it + } + val formatJs = tocRule.formatJs + if (!formatJs.isNullOrBlank()) { + Context.enter().use { + val bindings = ScriptBindings() + bindings["gInt"] = 0 + 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}") } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d011b9e5b..664e6b94a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" } - room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } diff --git a/modules/rhino/src/main/java/com/script/ScriptBindings.kt b/modules/rhino/src/main/java/com/script/ScriptBindings.kt index 341ea7903..a285179e8 100644 --- a/modules/rhino/src/main/java/com/script/ScriptBindings.kt +++ b/modules/rhino/src/main/java/com/script/ScriptBindings.kt @@ -39,4 +39,8 @@ class ScriptBindings : NativeObject() { } } + fun put(key: String, value: Any?) { + set(key, value) + } + } diff --git a/modules/rhino/src/main/java/com/script/ScriptBindingsExtensions.kt b/modules/rhino/src/main/java/com/script/ScriptBindingsExtensions.kt new file mode 100644 index 000000000..9161d2099 --- /dev/null +++ b/modules/rhino/src/main/java/com/script/ScriptBindingsExtensions.kt @@ -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 +} diff --git a/modules/rhino/src/main/java/com/script/rhino/RhinoScriptEngine.kt b/modules/rhino/src/main/java/com/script/rhino/RhinoScriptEngine.kt index 5fcaabc9a..a50436bd1 100644 --- a/modules/rhino/src/main/java/com/script/rhino/RhinoScriptEngine.kt +++ b/modules/rhino/src/main/java/com/script/rhino/RhinoScriptEngine.kt @@ -55,7 +55,12 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable { fun eval(js: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? { val bindings = ScriptBindings() - bindings.apply(bindingsConfig) + Context.enter() + try { + bindings.apply(bindingsConfig) + } finally { + Context.exit() + } return eval(js, bindings) } @@ -249,7 +254,7 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable { return newScope } - override fun getRuntimeScope(bindings: ScriptBindings): ScriptBindings { + override fun getRuntimeScope(bindings: ScriptBindings): Scriptable { val cx = Context.enter() try { bindings.prototype = cx.initStandardObjects()