From 7c41af6d2b9b36d00440a9c8b7e971d025f98327 Mon Sep 17 00:00:00 2001 From: aiselp Date: Wed, 30 Aug 2023 04:36:22 +0800 Subject: [PATCH] =?UTF-8?q?jsBrides=E6=94=B9=E7=94=A8=E5=8E=9F=E7=94=9F?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../autojs/engine/RhinoJavaScriptEngine.kt | 2 +- .../stardust/autojs/runtime/ScriptBridges.kt | 82 ++++++++++++------- .../stardust/automator/UiObjectCollection.kt | 10 +-- 3 files changed, 57 insertions(+), 37 deletions(-) diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt index 64d3a5de3..0a7b83a05 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt @@ -150,7 +150,7 @@ open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Co override fun wrap(cx: Context, scope: Scriptable, obj: Any?, staticType: Class<*>?): Any? { return when { obj is String -> runtime.bridges.toString(obj.toString()) - staticType == UiObjectCollection::class.java -> runtime.bridges.asArray(obj) + staticType == UiObjectCollection::class.java -> runtime.bridges.asArray(obj as UiObjectCollection) else -> super.wrap(cx, scope, obj, staticType) } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.kt b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.kt index 9edd24d97..ce79b8560 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.kt +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.kt @@ -1,5 +1,8 @@ package com.stardust.autojs.runtime +import android.os.Build +import androidx.annotation.RequiresApi +import com.stardust.automator.UiObjectCollection import org.mozilla.javascript.BaseFunction import org.mozilla.javascript.Context import org.mozilla.javascript.Scriptable @@ -10,6 +13,17 @@ import org.mozilla.javascript.annotations.JSFunction * Created by Stardust on 2017/7/21. */ class ScriptBridges { + companion object { + fun useJsContext(f: (context: Context) -> T): T { + val context = Context.getCurrentContext() + try { + return f(context ?: Context.enter()) + } finally { + context ?: Context.exit() + } + } + } + interface Bridges { fun call(func: Any?, target: Any?, arg: Any?): Any fun toArray(o: Iterable<*>?): Any @@ -22,46 +36,58 @@ class ScriptBridges { } var bridges: Bridges? = null - fun callFunction(func: Any?, target: Any?, args: Array<*>): Any { + fun callFunction(func: Any?, target: Any?, args: Array<*>): Any = useJsContext { context -> val jsFn = func as BaseFunction - val cx = Context.getCurrentContext() val scope = jsFn.parentScope - val arr = args.map { Context.javaToJS(it, scope) }.toTypedArray() - try { - return jsFn.call( - cx ?: Context.enter(), - scope, - (Context.javaToJS(target, scope) as? Scriptable) ?: Undefined.SCRIPTABLE_UNDEFINED, - arr - ) - } finally { - cx ?: Context.exit() - } - } + val arg = args.map { Context.javaToJS(it, scope) }.toTypedArray() - private fun checkBridges() { - checkNotNull(bridges) { "no bridges set" } + return@useJsContext jsFn.call( + context, scope, + (Context.javaToJS(target, scope) as? Scriptable) ?: Undefined.SCRIPTABLE_UNDEFINED, + arg + ) } @JSFunction - fun toArray(c: Iterable<*>): Scriptable { - val cx = Context.getCurrentContext() - val te = cx ?: Context.enter() - try { - return te.newArray(te.initStandardObjects(), c.toList().toTypedArray()) - } finally { - cx ?: Context.exit() - } + fun toArray(c: Iterable<*>): Scriptable = useJsContext { context -> + val scope = context.initStandardObjects() + return@useJsContext context.newArray( + context.initStandardObjects(), + c.map { Context.javaToJS(it, scope) }.toTypedArray() + ) } fun toString(obj: Any?): String { return Context.toString(obj) } - fun asArray(list: Any?): Any { - val arr = toArray(emptyList()) + fun asArray(obj: UiObjectCollection): Any = useJsContext { context -> + val arr = toArray(obj.mNodes) + obj::class.members.forEach { + val name = it.name + val method = object : BaseFunction() { + override fun getFunctionName(): String { + return name + } - checkBridges() - return bridges!!.asArray(list) + override fun call( + cx: Context?, + scope: Scriptable?, + thisObj: Scriptable?, + args: Array? + ): Any? { + return if (args != null) { + it.call(obj, *args) + } else it.call(obj) + } + + @RequiresApi(Build.VERSION_CODES.O) + override fun getLength(): Int { + return it.parameters.size + } + } + arr.put(name, arr, method) + } + return@useJsContext arr } } \ No newline at end of file diff --git a/automator/src/main/java/com/stardust/automator/UiObjectCollection.kt b/automator/src/main/java/com/stardust/automator/UiObjectCollection.kt index 712cccfa3..28e9fd949 100644 --- a/automator/src/main/java/com/stardust/automator/UiObjectCollection.kt +++ b/automator/src/main/java/com/stardust/automator/UiObjectCollection.kt @@ -1,12 +1,6 @@ package com.stardust.automator import android.os.Bundle - -import com.stardust.util.Consumer - -import java.util.ArrayList -import java.util.Collections - import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE @@ -38,13 +32,13 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_UP import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_PROGRESS import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SHOW_ON_SCREEN +import com.stardust.util.Consumer /** * Created by Stardust on 2017/3/9. */ -class UiObjectCollection private constructor(private val mNodes: List) { - +class UiObjectCollection private constructor(val mNodes: List) { val isEmpty: Boolean get() = mNodes.isEmpty()