This commit is contained in:
kunfei
2023-04-21 14:04:59 +08:00
parent 1dbe4b4ec0
commit a4a4de8ef1
13 changed files with 95 additions and 92 deletions
@@ -37,7 +37,7 @@ class AndroidJsTest {
queryStringWithSign queryStringWithSign
""".trimIndent() """.trimIndent()
Rhino.use { Rhino.use {
evaluateString(initStandardObjects(), js, "yy", 1, null) evaluateString(it, js, "yy", 1, null)
} }
@Language("js") @Language("js")
val js1 = """ val js1 = """
@@ -45,7 +45,7 @@ class AndroidJsTest {
returnData.getErrorMsg() returnData.getErrorMsg()
""".trimIndent() """.trimIndent()
val result1 = Rhino.use { val result1 = Rhino.use {
evaluateString(initStandardObjects(), js1, "xx", 1, null) evaluateString(it, js1, "xx", 1, null)
} }
Assert.assertEquals(result1, "未知错误,请联系开发者!").let { Assert.assertEquals(result1, "未知错误,请联系开发者!").let {
@@ -59,17 +59,15 @@ class AndroidJsTest {
@Language("js") @Language("js")
val jsMap = "$=result;id=$.id;id" val jsMap = "$=result;id=$.id;id"
val result = Rhino.use { val result = Rhino.use {
val scope = initStandardObjects() it.putBinding("result", map)
scope.putBinding("result", map) evaluateString(it, jsMap, "xxx", 1, null)
evaluateString(scope, jsMap, "xxx", 1, null)
} }
Assert.assertEquals("3242532321", result) Assert.assertEquals("3242532321", result)
@Language("js") @Language("js")
val jsMap1 = """result.get("id")""" val jsMap1 = """result.get("id")"""
val result1 = Rhino.use { val result1 = Rhino.use {
val scope = initStandardObjects() it.putBinding("result", map)
scope.putBinding("result", map) evaluateString(it, jsMap1, "xxx", 1, null)
evaluateString(scope, jsMap1, "xxx", 1, null)
} }
Assert.assertEquals("3242532321", result1) Assert.assertEquals("3242532321", result1)
} }
-2
View File
@@ -10,7 +10,6 @@ import android.os.Build
import com.github.liuyueyi.quick.transfer.ChineseUtils import com.github.liuyueyi.quick.transfer.ChineseUtils
import com.github.liuyueyi.quick.transfer.constants.TransType import com.github.liuyueyi.quick.transfer.constants.TransType
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.script.rhino.RhinoScriptEngine
import io.legado.app.base.AppContextWrapper import io.legado.app.base.AppContextWrapper
import io.legado.app.constant.AppConst.channelIdDownload import io.legado.app.constant.AppConst.channelIdDownload
import io.legado.app.constant.AppConst.channelIdReadAloud import io.legado.app.constant.AppConst.channelIdReadAloud
@@ -41,7 +40,6 @@ class App : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
RhinoScriptEngine
oldConfig = Configuration(resources.configuration) oldConfig = Configuration(resources.configuration)
CrashHandler(this) CrashHandler(this)
//预下载Cronet so //预下载Cronet so
@@ -236,15 +236,19 @@ interface BaseSource : JsExtensions {
bindings["baseUrl"] = getKey() bindings["baseUrl"] = getKey()
bindings["cookie"] = CookieStore bindings["cookie"] = CookieStore
bindings["cache"] = CacheManager bindings["cache"] = CacheManager
// return Rhino.use { // return Rhino.use { scope ->
// val scope = initStandardObjects()
// scope.putBindings(bindings) // scope.putBindings(bindings)
// getShareScope()?.let { // getShareScope()?.let {
// scope.prototype = it // scope.prototype = it
// } // }
// evaluate(scope, jsStr) // eval(scope, jsStr)
// } // }
return RhinoScriptEngine.eval(jsStr, SimpleBindings(bindings)) val context = RhinoScriptEngine.getScriptContext(SimpleBindings(bindings))
val scope = RhinoScriptEngine.getRuntimeScope(context)
getShareScope()?.let {
scope.prototype = it
}
return RhinoScriptEngine.eval(jsStr, scope)
} }
fun getShareScope(): Scriptable? { fun getShareScope(): Scriptable? {
@@ -241,9 +241,8 @@ fun Book.getExportFileName(suffix: String): String {
bindings["author"] = getRealAuthor() bindings["author"] = getRealAuthor()
return kotlin.runCatching { return kotlin.runCatching {
Rhino.use { Rhino.use {
val scope = initStandardObjects() it.putBindings(bindings)
scope.putBindings(bindings) evaluateString(it, jsStr, "name&author", 1, null)
evaluateString(scope, jsStr, "name&author", 1, null)
}.toString() + "." + suffix }.toString() + "." + suffix
}.onFailure { }.onFailure {
AppLog.put("导出书名规则错误,使用默认规则\n${it.localizedMessage}", it) AppLog.put("导出书名规则错误,使用默认规则\n${it.localizedMessage}", it)
@@ -32,7 +32,7 @@ object SharedJsScope {
var scope = scopeMap[key]?.get() var scope = scopeMap[key]?.get()
if (scope == null) { if (scope == null) {
Rhino.use { Rhino.use {
scope = initStandardObjects() scope = it
if (jsLib.isJsonObject()) { if (jsLib.isJsonObject()) {
val jsMap: Map<String, String> = GSON.fromJson( val jsMap: Map<String, String> = GSON.fromJson(
jsLib, jsLib,
@@ -258,6 +258,7 @@ class AnalyzeRule(
} else { } else {
getAnalyzeByJSoup(it).getString(sourceRule.rule) getAnalyzeByJSoup(it).getString(sourceRule.rule)
} }
else -> sourceRule.rule else -> sourceRule.rule
} }
} }
@@ -307,6 +308,7 @@ class AnalyzeRule(
result.toString(), result.toString(),
sourceRule.rule.splitNotBlank("&&") sourceRule.rule.splitNotBlank("&&")
) )
Mode.Js -> evalJS(sourceRule.rule, it) Mode.Js -> evalJS(sourceRule.rule, it)
Mode.Json -> getAnalyzeByJSonPath(it).getObject(sourceRule.rule) Mode.Json -> getAnalyzeByJSonPath(it).getObject(sourceRule.rule)
Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule) Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule)
@@ -339,6 +341,7 @@ class AnalyzeRule(
result.toString(), result.toString(),
sourceRule.rule.splitNotBlank("&&") sourceRule.rule.splitNotBlank("&&")
) )
Mode.Js -> evalJS(sourceRule.rule, result) Mode.Js -> evalJS(sourceRule.rule, result)
Mode.Json -> getAnalyzeByJSonPath(it).getList(sourceRule.rule) Mode.Json -> getAnalyzeByJSonPath(it).getList(sourceRule.rule)
Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule) Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule)
@@ -389,7 +392,7 @@ class AnalyzeRule(
if (rule.replaceRegex.isEmpty()) return result if (rule.replaceRegex.isEmpty()) return result
var vResult = result var vResult = result
vResult = if (rule.replaceFirst) { vResult = if (rule.replaceFirst) {
/* ##match##replace### 获取第一个匹配到的结果并进行替换 */ /* ##match##replace### 获取第一个匹配到的结果并进行替换 */
kotlin.runCatching { kotlin.runCatching {
val pattern = Pattern.compile(rule.replaceRegex) val pattern = Pattern.compile(rule.replaceRegex)
val matcher = pattern.matcher(vResult) val matcher = pattern.matcher(vResult)
@@ -402,7 +405,7 @@ class AnalyzeRule(
rule.replacement rule.replacement
} }
} else { } else {
/* ##match##replace 替换*/ /* ##match##replace 替换*/
kotlin.runCatching { kotlin.runCatching {
vResult.replace(rule.replaceRegex.toRegex(), rule.replacement) vResult.replace(rule.replaceRegex.toRegex(), rule.replacement)
}.getOrElse { }.getOrElse {
@@ -476,26 +479,32 @@ class AnalyzeRule(
mode = Mode.Default mode = Mode.Default
ruleStr ruleStr
} }
ruleStr.startsWith("@@") -> { ruleStr.startsWith("@@") -> {
mode = Mode.Default mode = Mode.Default
ruleStr.substring(2) ruleStr.substring(2)
} }
ruleStr.startsWith("@XPath:", true) -> { ruleStr.startsWith("@XPath:", true) -> {
mode = Mode.XPath mode = Mode.XPath
ruleStr.substring(7) ruleStr.substring(7)
} }
ruleStr.startsWith("@Json:", true) -> { ruleStr.startsWith("@Json:", true) -> {
mode = Mode.Json mode = Mode.Json
ruleStr.substring(6) ruleStr.substring(6)
} }
isJSON || ruleStr.startsWith("$.") || ruleStr.startsWith("$[") -> { isJSON || ruleStr.startsWith("$.") || ruleStr.startsWith("$[") -> {
mode = Mode.Json mode = Mode.Json
ruleStr ruleStr
} }
ruleStr.startsWith("/") -> {//XPath特征很明显,无需配置单独的识别标头 ruleStr.startsWith("/") -> {//XPath特征很明显,无需配置单独的识别标头
mode = Mode.XPath mode = Mode.XPath
ruleStr ruleStr
} }
else -> ruleStr else -> ruleStr
} }
//分离put //分离put
@@ -523,10 +532,12 @@ class AnalyzeRule(
ruleType.add(getRuleType) ruleType.add(getRuleType)
ruleParam.add(tmp.substring(6, tmp.lastIndex)) ruleParam.add(tmp.substring(6, tmp.lastIndex))
} }
tmp.startsWith("{{") -> { tmp.startsWith("{{") -> {
ruleType.add(jsRuleType) ruleType.add(jsRuleType)
ruleParam.add(tmp.substring(2, tmp.length - 2)) ruleParam.add(tmp.substring(2, tmp.length - 2))
} }
else -> { else -> {
splitRegex(tmp) splitRegex(tmp)
} }
@@ -592,6 +603,7 @@ class AnalyzeRule(
} }
} ?: infoVal.insert(0, ruleParam[index]) } ?: infoVal.insert(0, ruleParam[index])
} }
regType == jsRuleType -> { regType == jsRuleType -> {
if (isRule(ruleParam[index])) { if (isRule(ruleParam[index])) {
getString(arrayListOf(SourceRule(ruleParam[index]))).let { getString(arrayListOf(SourceRule(ruleParam[index]))).let {
@@ -606,13 +618,16 @@ class AnalyzeRule(
0, 0,
String.format("%.0f", jsEval) String.format("%.0f", jsEval)
) )
else -> infoVal.insert(0, jsEval.toString()) else -> infoVal.insert(0, jsEval.toString())
} }
} }
} }
regType == getRuleType -> { regType == getRuleType -> {
infoVal.insert(0, get(ruleParam[index])) infoVal.insert(0, get(ruleParam[index]))
} }
else -> infoVal.insert(0, ruleParam[index]) else -> infoVal.insert(0, ruleParam[index])
} }
} }
@@ -667,6 +682,7 @@ class AnalyzeRule(
"bookName" -> book?.let { "bookName" -> book?.let {
return it.name return it.name
} }
"title" -> chapter?.let { "title" -> chapter?.let {
return it.title return it.title
} }
@@ -694,15 +710,19 @@ class AnalyzeRule(
bindings["title"] = chapter?.title bindings["title"] = chapter?.title
bindings["src"] = content bindings["src"] = content
bindings["nextChapterUrl"] = nextChapterUrl bindings["nextChapterUrl"] = nextChapterUrl
// return Rhino.use { // return Rhino.use { scope ->
// val scope = initStandardObjects()
// scope.putBindings(bindings) // scope.putBindings(bindings)
// source?.getShareScope()?.let { // source?.getShareScope()?.let {
// scope.prototype = it // scope.prototype = it
// } // }
// evaluate(scope, jsStr) // eval(scope, jsStr)
// } // }
return RhinoScriptEngine.eval(jsStr, SimpleBindings(bindings)) val context = RhinoScriptEngine.getScriptContext(SimpleBindings(bindings))
val scope = RhinoScriptEngine.getRuntimeScope(context)
source?.getShareScope()?.let {
scope.prototype = it
}
return RhinoScriptEngine.eval(jsStr, scope)
} }
override fun getSource(): BaseSource? { override fun getSource(): BaseSource? {
@@ -215,6 +215,7 @@ class AnalyzeUrl(
urlNoQuery = url.substring(0, pos) urlNoQuery = url.substring(0, pos)
} }
} }
RequestMethod.POST -> body?.let { RequestMethod.POST -> body?.let {
if (!it.isJson() && !it.isXml() && headerMap["Content-Type"].isNullOrEmpty()) { if (!it.isJson() && !it.isXml() && headerMap["Content-Type"].isNullOrEmpty()) {
analyzeFields(it) analyzeFields(it)
@@ -266,15 +267,19 @@ class AnalyzeUrl(
bindings["book"] = ruleData as? Book bindings["book"] = ruleData as? Book
bindings["source"] = source bindings["source"] = source
bindings["result"] = result bindings["result"] = result
// return Rhino.use { // return Rhino.use { scope ->
// val scope = initStandardObjects()
// scope.putBindings(bindings) // scope.putBindings(bindings)
// source?.getShareScope()?.let { // source?.getShareScope()?.let {
// scope.prototype = it // scope.prototype = it
// } // }
// evaluate(scope, jsStr) // eval(scope, jsStr)
// } // }
return RhinoScriptEngine.eval(jsStr, SimpleBindings(bindings)) val context = RhinoScriptEngine.getScriptContext(SimpleBindings(bindings))
val scope = RhinoScriptEngine.getRuntimeScope(context)
source?.getShareScope()?.let {
scope.prototype = it
}
return RhinoScriptEngine.eval(jsStr, scope)
} }
fun put(key: String, value: String): String { fun put(key: String, value: String): String {
@@ -288,6 +293,7 @@ class AnalyzeUrl(
"bookName" -> (ruleData as? Book)?.let { "bookName" -> (ruleData as? Book)?.let {
return it.name return it.name
} }
"title" -> chapter?.let { "title" -> chapter?.let {
return it.title return it.title
} }
@@ -353,7 +359,10 @@ class AnalyzeUrl(
} }
} }
if (waitTime > 0) { if (waitTime > 0) {
throw ConcurrentException("根据并发率还需等待${waitTime}毫秒才可以访问", waitTime = waitTime) throw ConcurrentException(
"根据并发率还需等待${waitTime}毫秒才可以访问",
waitTime = waitTime
)
} }
return fetchRecord return fetchRecord
} }
@@ -414,6 +423,7 @@ class AnalyzeUrl(
headerMap = headerMap headerMap = headerMap
).getStrResponse() ).getStrResponse()
} }
else -> BackstageWebView( else -> BackstageWebView(
url = url, url = url,
tag = source?.getKey(), tag = source?.getKey(),
@@ -439,6 +449,7 @@ class AnalyzeUrl(
postJson(body) postJson(body)
} }
} }
else -> get(urlNoQuery, fieldMap, true) else -> get(urlNoQuery, fieldMap, true)
} }
}.let { }.let {
@@ -500,6 +511,7 @@ class AnalyzeUrl(
postJson(body) postJson(body)
} }
} }
else -> get(urlNoQuery, fieldMap, true) else -> get(urlNoQuery, fieldMap, true)
} }
} }
@@ -20,7 +20,7 @@ import io.legado.app.lib.webdav.WebDav
import io.legado.app.lib.webdav.WebDavException import io.legado.app.lib.webdav.WebDavException
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.rhino.Rhino import io.legado.app.rhino.Rhino
import io.legado.app.rhino.evaluate import io.legado.app.rhino.eval
import io.legado.app.rhino.putBinding import io.legado.app.rhino.putBinding
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@@ -272,9 +272,8 @@ object LocalBook {
AppConfig.bookImportFileName + "\nJSON.stringify({author:author,name:name})" AppConfig.bookImportFileName + "\nJSON.stringify({author:author,name:name})"
//在脚本中定义如何分解文件名成书名、作者名 //在脚本中定义如何分解文件名成书名、作者名
val jsonStr = Rhino.use { val jsonStr = Rhino.use {
val scope = initStandardObjects() it.putBinding("src", tempFileName)
scope.putBinding("src", tempFileName) eval(it, js)
evaluate(scope, js)
}.toString() }.toString()
val bookMess = GSON.fromJsonObject<HashMap<String, String>>(jsonStr) val bookMess = GSON.fromJsonObject<HashMap<String, String>>(jsonStr)
.getOrThrow() .getOrThrow()
@@ -1,15 +1,18 @@
package io.legado.app.rhino package io.legado.app.rhino
import org.mozilla.javascript.Context import org.mozilla.javascript.Context
import org.mozilla.javascript.ImporterTopLevel
import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.Undefined import org.mozilla.javascript.Undefined
import org.mozilla.javascript.Wrapper import org.mozilla.javascript.Wrapper
object Rhino { object Rhino {
inline fun <T> use(block: Context.() -> T): T { inline fun <T> use(block: Context.(Scriptable) -> T): T {
return try { return try {
val cx = Context.enter() val cx = Context.enter()
block.invoke(cx) val scope = cx.initStandardObjects(ImporterTopLevel(cx))
block.invoke(cx, scope)
} finally { } finally {
Context.exit() Context.exit()
} }
@@ -7,7 +7,7 @@ import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject import org.mozilla.javascript.ScriptableObject
import java.io.Reader import java.io.Reader
fun Context.evaluate( fun Context.eval(
scope: Scriptable, scope: Scriptable,
source: String, source: String,
sourceName: String = "<Unknown source>", sourceName: String = "<Unknown source>",
@@ -19,21 +19,7 @@ fun Context.evaluate(
) )
} }
fun Context.evaluate( fun Context.eval(
bindings: Bindings,
source: String,
sourceName: String = "<Unknown source>",
lineno: Int = 1,
securityDomain: Any? = null
): Any? {
val scope = initStandardObjects()
scope.putBindings(bindings)
return Rhino.unwrapReturnValue(
evaluateString(scope, source, sourceName, lineno, securityDomain)
)
}
fun Context.evaluate(
scope: Scriptable, scope: Scriptable,
reader: Reader, reader: Reader,
sourceName: String = "<Unknown source>", sourceName: String = "<Unknown source>",
@@ -45,20 +31,6 @@ fun Context.evaluate(
) )
} }
fun Context.evaluate(
bindings: Bindings,
reader: Reader,
sourceName: String = "<Unknown source>",
lineno: Int = 1,
securityDomain: Any? = null
): Any? {
val scope = initStandardObjects()
scope.putBindings(bindings)
return Rhino.unwrapReturnValue(
evaluateReader(scope, reader, sourceName, lineno, securityDomain)
)
}
fun Scriptable.putBinding(key: String, value: Any?) { fun Scriptable.putBinding(key: String, value: Any?) {
val wrappedOut = Context.javaToJS(value, this) val wrappedOut = Context.javaToJS(value, this)
ScriptableObject.putProperty(this, key, wrappedOut) ScriptableObject.putProperty(this, key, wrappedOut)
@@ -3,7 +3,8 @@ package io.legado.app.utils
import io.legado.app.constant.AppPattern.EXP_PATTERN import io.legado.app.constant.AppPattern.EXP_PATTERN
import io.legado.app.rhino.Bindings import io.legado.app.rhino.Bindings
import io.legado.app.rhino.Rhino import io.legado.app.rhino.Rhino
import io.legado.app.rhino.evaluate import io.legado.app.rhino.eval
import io.legado.app.rhino.putBindings
object JsUtils { object JsUtils {
@@ -14,9 +15,10 @@ object JsUtils {
val sb = StringBuffer() val sb = StringBuffer()
val expMatcher = EXP_PATTERN.matcher(js) val expMatcher = EXP_PATTERN.matcher(js)
while (expMatcher.find()) { while (expMatcher.find()) {
val result = expMatcher.group(1)?.let { val result = expMatcher.group(1)?.let { js1 ->
Rhino.use { Rhino.use {
evaluate(bindings, it) it.putBindings(bindings)
eval(it, js1)
} }
} ?: "" } ?: ""
if (result is String) { if (result is String) {
@@ -31,7 +33,8 @@ object JsUtils {
return sb.toString() return sb.toString()
} }
return Rhino.use { return Rhino.use {
evaluate(bindings, js) it.putBindings(bindings)
eval(it, js)
}.toString() }.toString()
} }
@@ -4,9 +4,9 @@ import androidx.core.os.postDelayed
import io.legado.app.exception.RegexTimeoutException import io.legado.app.exception.RegexTimeoutException
import io.legado.app.help.CrashHandler import io.legado.app.help.CrashHandler
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.rhino.Bindings
import io.legado.app.rhino.Rhino import io.legado.app.rhino.Rhino
import io.legado.app.rhino.evaluate import io.legado.app.rhino.eval
import io.legado.app.rhino.putBinding
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import splitties.init.appCtx import splitties.init.appCtx
@@ -31,10 +31,9 @@ fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): Stri
val stringBuffer = StringBuffer() val stringBuffer = StringBuffer()
while (matcher.find()) { while (matcher.find()) {
if (isJs) { if (isJs) {
val bindings = Bindings()
bindings["result"] = matcher.group()
val jsResult = Rhino.use { val jsResult = Rhino.use {
evaluate(bindings, replacement1) it.putBinding("result", matcher.group())
eval(it, replacement1)
}.toString() }.toString()
matcher.appendReplacement(stringBuffer, jsResult) matcher.appendReplacement(stringBuffer, jsResult)
} else { } else {
+14 -18
View File
@@ -3,7 +3,7 @@ package io.legado.app
import com.script.SimpleBindings import com.script.SimpleBindings
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.rhino.Rhino import io.legado.app.rhino.Rhino
import io.legado.app.rhino.evaluate import io.legado.app.rhino.eval
import io.legado.app.rhino.putBinding import io.legado.app.rhino.putBinding
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
import org.junit.Assert import org.junit.Assert
@@ -42,9 +42,8 @@ class JsTest {
@Language("js") @Language("js")
val jsMap1 = """result.get("id")""" val jsMap1 = """result.get("id")"""
val result1 = Rhino.use { val result1 = Rhino.use {
val scope = initStandardObjects() it.putBinding("result", map)
scope.putBinding("result", map) evaluateString(it, jsMap1, "xxx", 1, null)
evaluateString(scope, jsMap1, "xxx", 1, null)
} }
Assert.assertEquals("3242532321", result1) Assert.assertEquals("3242532321", result1)
} }
@@ -52,9 +51,8 @@ class JsTest {
@Test @Test
fun testFor() { fun testFor() {
val scope = Rhino.use { val scope = Rhino.use {
val scope = initStandardObjects() evaluateString(it, printJs, "print", 1, null)
evaluateString(scope, printJs, "print", 1, null) it
scope
} }
@Language("js") @Language("js")
@@ -77,7 +75,8 @@ class JsTest {
result result
""".trimIndent() """.trimIndent()
val result = Rhino.use { val result = Rhino.use {
evaluateString(scope, jsFor, "jsFor", 1, null) it.prototype = scope
evaluateString(it, jsFor, "jsFor", 1, null)
} }
Assert.assertEquals("12012", result) Assert.assertEquals("12012", result)
} }
@@ -85,7 +84,7 @@ class JsTest {
@Test @Test
fun testReturnNull() { fun testReturnNull() {
val result = Rhino.use { val result = Rhino.use {
evaluate(initStandardObjects(), "null") eval(it, "null")
} }
Assert.assertEquals(null, result) Assert.assertEquals(null, result)
} }
@@ -103,9 +102,8 @@ class JsTest {
.replace(/\:/g,":") .replace(/\:/g,":")
""".trimIndent() """.trimIndent()
val result = Rhino.use { val result = Rhino.use {
val scope = initStandardObjects() it.putBinding("result", ",.!?…;:")
scope.putBinding("result", ",.!?…;:") eval(it, js)
evaluate(scope, js)
} }
Assert.assertEquals(result, ",。!?……;:") Assert.assertEquals(result, ",。!?……;:")
} }
@@ -119,9 +117,8 @@ class JsTest {
@Language("js") @Language("js")
val js = "chapter.title" val js = "chapter.title"
val result = Rhino.use { val result = Rhino.use {
val scope = initStandardObjects() it.putBinding("chapter", chapter)
scope.putBinding("chapter", chapter) eval(it, js)
evaluate(scope, js)
} }
Assert.assertEquals(result, "xxxyyy") Assert.assertEquals(result, "xxxyyy")
} }
@@ -137,9 +134,8 @@ class JsTest {
result result
""".trimIndent() """.trimIndent()
val result = Rhino.use { val result = Rhino.use {
val scope = initStandardObjects() it.putBinding("list", list)
scope.putBinding("list", list) eval(it, js)
evaluate(scope, js)
} }
Assert.assertEquals(result, 6.0) Assert.assertEquals(result, 6.0)
} }