6.7.0 - Alpha6 - console.log 等方法打印全局对象 (images, app, ocr 等) 时支持显示详细信息
This commit is contained in:
@@ -19,7 +19,11 @@ plugins {
|
||||
|
||||
idea {
|
||||
module {
|
||||
excludeDirs.add(file("$rootDir/app/src/main/java/com/stardust/"))
|
||||
excludeDirs.addAll(listOf(
|
||||
file("$rootDir/app/src/main/java/com/stardust/"),
|
||||
file("$rootDir/app/src/main/assets/modules/obsolete/"),
|
||||
file("$rootDir/app/src/main/assets-app/js-beautify/"),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,9 @@ import org.mozilla.javascript.NativeArray
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import org.mozilla.javascript.Script
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.ScriptableObject.DONTENUM
|
||||
import org.mozilla.javascript.ScriptableObject.PERMANENT
|
||||
import org.mozilla.javascript.ScriptableObject.READONLY
|
||||
import org.mozilla.javascript.commonjs.module.RequireBuilder
|
||||
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider
|
||||
import java.io.File
|
||||
@@ -103,7 +105,7 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con
|
||||
|
||||
override fun init() {
|
||||
thread = Thread.currentThread()
|
||||
scriptable.defineProp("__engine__", this)
|
||||
scriptable.defineProp("__engine__", this, READONLY or DONTENUM or PERMANENT)
|
||||
initRequireBuilder(context, scriptable)
|
||||
|
||||
runtime.withTimeConsuming("runtime-init-prologue") {
|
||||
|
||||
@@ -24,7 +24,7 @@ class ShizukuPermission(override val context: Context) : PermissionItemHelper {
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
WrappedShizuku.config(context, true)?.let { true }
|
||||
WrappedShizuku.configWithContext(context, true)?.let { true }
|
||||
?: ViewUtils.showToast(context, R.string.error_failed_to_grant_shizuku_access).let { false }
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ class ShizukuPermission(override val context: Context) : PermissionItemHelper {
|
||||
return when {
|
||||
!WrappedShizuku.isInstalled(context) -> false.also { ViewUtils.showToast(context, R.string.error_shizuku_is_not_installed) }
|
||||
Shizuku.isPreV11() -> false.also { ViewUtils.showToast(context, R.string.error_shizuku_version_is_not_supported) }
|
||||
else -> WrappedShizuku.config(context, false)?.let { true }
|
||||
else -> WrappedShizuku.configWithContext(context, false)?.let { true }
|
||||
?: ViewUtils.showToast(context, R.string.error_failed_to_revoke_shizuku_access).let { false }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,12 @@ open class ProxyObject() : NativeObject() {
|
||||
@JvmField
|
||||
val PROXY_OBJECT_KEY = "__proxy__"
|
||||
|
||||
@JvmField
|
||||
val AUGMENTED_OBJECT_KEY = "__augmented__"
|
||||
|
||||
@JvmField
|
||||
val AUGMENTED_CUSTOM_TO_STRING_KEY = "__augmented_custom_to_string__"
|
||||
|
||||
@JvmField
|
||||
val PROXY_SETTER_KEY = "set"
|
||||
|
||||
|
||||
@@ -458,7 +458,7 @@ class ScriptRuntime private constructor(builder: Builder) {
|
||||
floaty = ApiFloaty(uiHandler, this)
|
||||
|
||||
ui = ApiUI(mUiHandlerAppContext, this)
|
||||
util = ApiUtil(mUiHandlerAppContext, this)
|
||||
util = ApiUtil
|
||||
images = ApiImages(mUiHandlerAppContext, this)
|
||||
device = ApiDevice(mUiHandlerAppContext)
|
||||
media = ApiMedia(mUiHandlerAppContext, this)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package org.autojs.autojs.runtime.api
|
||||
|
||||
import org.autojs.autojs.extension.AnyExtensions.jsBrief
|
||||
import org.autojs.autojs.runtime.ScriptRuntime
|
||||
|
||||
class Util(private val context: android.content.Context, private val scriptRuntime: ScriptRuntime) {
|
||||
object Util {
|
||||
|
||||
fun `class`(o: Any?) = getClassInternal(o, "class")
|
||||
|
||||
|
||||
@@ -120,7 +120,6 @@ object WrappedShizuku {
|
||||
false.also { if (e.message?.contains(Regex("binder .+n[o']t been received", RegexOption.IGNORE_CASE)) == false) e.printStackTrace() }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ScriptInterface
|
||||
fun isOperational(): Boolean = isRunning() && hasPermission()
|
||||
|
||||
@@ -130,12 +129,11 @@ object WrappedShizuku {
|
||||
@ScriptInterface
|
||||
fun requestPermission() = Shizuku.requestPermission(mRequestCode)
|
||||
|
||||
@ScriptInterface
|
||||
fun config(isRequest: Boolean?) = config(GlobalAppContext.get(), isRequest)
|
||||
|
||||
@ScriptInterface
|
||||
@JvmOverloads
|
||||
fun config(context: Context, isRequest: Boolean? = null): Intent? = getLaunchIntent(context)?.also {
|
||||
fun config(isRequest: Boolean? = null) = configWithContext(GlobalAppContext.get(), isRequest)
|
||||
|
||||
fun configWithContext(context: Context, isRequest: Boolean? = null): Intent? = getLaunchIntent(context)?.also {
|
||||
context.startActivity(it)
|
||||
val message = when (isRequest) {
|
||||
true -> "${context.getString(R.string.text_grant_autojs6_access_in_shizuku_app)} (${context.getString(R.string.text_shizuku_service_may_need_to_be_run_first)})"
|
||||
|
||||
@@ -5,9 +5,11 @@ import org.autojs.autojs.app.GlobalAppContext
|
||||
import org.autojs.autojs.extension.AnyExtensions.isJsNullish
|
||||
import org.autojs.autojs.extension.AnyExtensions.jsBrief
|
||||
import org.autojs.autojs.extension.FlexibleArray
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
||||
import org.autojs.autojs.rhino.ProxyObject
|
||||
import org.autojs.autojs.rhino.ProxyObject.Companion.AUGMENTED_CUSTOM_TO_STRING_KEY
|
||||
import org.autojs.autojs.rhino.ProxyObject.Companion.PROXY_GETTER_KEY
|
||||
import org.autojs.autojs.runtime.ScriptRuntime
|
||||
import org.autojs.autojs.runtime.api.augment.events.Events
|
||||
@@ -118,8 +120,9 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
|
||||
/**
|
||||
* List element cases: <br>
|
||||
* - <1> - name to getter
|
||||
* - <2> - name to getter to attributes
|
||||
*/
|
||||
open val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>()
|
||||
open val selfAssignmentGetters = listOf<Any>()
|
||||
|
||||
/**
|
||||
* List element cases: <br>
|
||||
@@ -264,17 +267,19 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
|
||||
objProtoList += Events.__asEmitter__(scriptRuntime, emptyArray())
|
||||
}
|
||||
|
||||
objProtoList.forEachIndexed { index, prototypeObject -> augmentPrototypesAt(index, newObj, prototypeObject) }
|
||||
scopeProtoList.forEachIndexed { index, prototypeObject -> augmentPrototypesAt(index, global, prototypeObject) }
|
||||
val newObjOriginalPrototype = newObj.prototype
|
||||
objProtoList.forEachIndexed { index, prototypeObject -> augmentPrototypesAt(index, newObj, prototypeObject, newObjOriginalPrototype) }
|
||||
val globalOriginalPrototype = global.prototype
|
||||
scopeProtoList.forEachIndexed { index, prototypeObject -> augmentPrototypesAt(index, global, prototypeObject, globalOriginalPrototype) }
|
||||
}
|
||||
|
||||
private fun augmentPrototypesAt(index: Int, o: ScriptableObject, proto: Scriptable) {
|
||||
private fun augmentPrototypesAt(index: Int, o: ScriptableObject, proto: Scriptable, originalProto: Scriptable?) {
|
||||
when (index) {
|
||||
0 -> o.prototype = proto
|
||||
1 -> o.prototype.prototype = proto
|
||||
2 -> o.prototype.prototype.prototype = proto
|
||||
3 -> o.prototype.prototype.prototype.prototype = proto
|
||||
4 -> o.prototype.prototype.prototype.prototype.prototype = proto
|
||||
0 -> o.prototype = proto.apply { prototype = originalProto }
|
||||
1 -> o.prototype.prototype = proto.apply { prototype = originalProto }
|
||||
2 -> o.prototype.prototype.prototype = proto.apply { prototype = originalProto }
|
||||
3 -> o.prototype.prototype.prototype.prototype = proto.apply { prototype = originalProto }
|
||||
4 -> o.prototype.prototype.prototype.prototype.prototype = proto.apply { prototype = originalProto }
|
||||
else -> throw RuntimeException("Augmentation can only be applied to no more than $index targets")
|
||||
}
|
||||
}
|
||||
@@ -372,6 +377,9 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
|
||||
if (flag and AS_GLOBAL != 0) {
|
||||
globalFunctions += name to alias to (PERMANENT or refineAttributes(flag))
|
||||
}
|
||||
if (flag and AS_FUNCTIONAL_TO_STRING != 0) {
|
||||
targetFunctions += AUGMENTED_CUSTOM_TO_STRING_KEY to AUGMENTED_CUSTOM_TO_STRING_KEY to (DONTENUM or PERMANENT or refineAttributes(flag))
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> throw WrappedIllegalArgumentException("Unknown function element ${item.jsBrief()} for selfAssignmentFunctions")
|
||||
@@ -381,8 +389,7 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
|
||||
when (item) {
|
||||
is String -> globalFunctions += item to item to PERMANENT
|
||||
is Pair<*, *> -> {
|
||||
val first = item.first
|
||||
val second = item.second
|
||||
val (first, second) = item
|
||||
val name: String
|
||||
val aliasList = mutableListOf<String>()
|
||||
var flag = 0
|
||||
@@ -474,33 +481,62 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
|
||||
throw WrappedRuntimeException(niceMessage)
|
||||
}
|
||||
}, NOT_CONSTRUCTABLE)
|
||||
destination.defineProperty(funcNameAlias, f, attributes)
|
||||
destination.defineWith(funcNameAlias, f, attributes)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnnecessaryVariable", "UNCHECKED_CAST")
|
||||
private fun augmentGettersAndSetters(target: ScriptableObject, global: ScriptableObject) {
|
||||
selfAssignmentGetters.forEach { pair ->
|
||||
val (name, getter) = pair
|
||||
target.defineProperty(name, getter, null, PERMANENT)
|
||||
selfAssignmentGetters.forEach { item ->
|
||||
when (item) {
|
||||
is Pair<*, *> -> {
|
||||
val (first, second) = item
|
||||
when (first) {
|
||||
is String -> {
|
||||
val name = first
|
||||
when (val getter = second) {
|
||||
is Supplier<*> -> {
|
||||
target.defineWith(name, getter as Supplier<Any?>, null, PERMANENT)
|
||||
}
|
||||
else -> throw WrappedIllegalArgumentException("Unknown second element ${second.jsBrief()} for selfAssignmentGetters")
|
||||
}
|
||||
}
|
||||
is Pair<*, *> -> {
|
||||
val (name, getter) = first
|
||||
require(name is String) {
|
||||
throw WrappedIllegalArgumentException("First element of pair must be a String for selfAssignmentGetters")
|
||||
}
|
||||
when (val attributes = second) {
|
||||
is Int -> {
|
||||
target.defineWith(name, getter as Supplier<Any?>, null, refineAttributes(attributes))
|
||||
}
|
||||
else -> throw WrappedIllegalArgumentException("Unknown second element ${second.jsBrief()} for selfAssignmentGetters")
|
||||
}
|
||||
}
|
||||
else -> throw WrappedIllegalArgumentException("Unknown item ${item.jsBrief()} for selfAssignmentGetters")
|
||||
}
|
||||
}
|
||||
else -> throw WrappedIllegalArgumentException("Unknown item ${item.jsBrief()} for selfAssignmentGetters")
|
||||
}
|
||||
}
|
||||
selfAssignmentGettersAndSetters.forEach { triple ->
|
||||
val (name, getter, setter) = triple
|
||||
target.defineProperty(name, getter, setter, PERMANENT)
|
||||
target.defineWith(name, getter, setter, PERMANENT)
|
||||
}
|
||||
globalAssignmentGetters.forEach { pair ->
|
||||
val (name, getter) = pair
|
||||
global.defineProperty(name, getter, null, PERMANENT)
|
||||
global.defineWith(name, getter, null, PERMANENT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun augmentJavaClasses(target: ScriptableObject, global: ScriptableObject) {
|
||||
selfAssignmentJavaClasses.forEach { pair ->
|
||||
val (name, clazz) = pair
|
||||
target.defineProperty(name, NativeJavaClass(global, clazz.java), PERMANENT)
|
||||
target.defineWith(name, NativeJavaClass(global, clazz.java), PERMANENT)
|
||||
}
|
||||
globalAssignmentJavaClasses.forEach { pair ->
|
||||
val (name, clazz) = pair
|
||||
global.defineProperty(name, NativeJavaClass(global, clazz.java), PERMANENT)
|
||||
global.defineWith(name, NativeJavaClass(global, clazz.java), PERMANENT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,14 +548,44 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
|
||||
|
||||
companion object : FlexibleArray() {
|
||||
|
||||
const val AS_GLOBAL = 0x1000
|
||||
const val AS_IGNORED = 0x2000
|
||||
// @Caution by SuperMonster003 on Oct 5, 2025.
|
||||
// ! These constants are "bit flags", each value is a power of 2, with only one bit being 1 in binary.
|
||||
// ! They can be combined using `bitwise OR (|)` and checked using `bitwise AND (&)` without interference.
|
||||
// ! Do not modify them to the form 0x0101/0x0102/0x0103/0x0104/...,
|
||||
// ! to avoid flag overlap causing combination and detection logic to fail,
|
||||
// ! e.g. `flags & AS_GLOBAL` may give false results.
|
||||
// ! zh-CN:
|
||||
// ! 这些常量是 "位标志" (bit flags), 每个值都是二的幂, 二进制中仅有一位为 1.
|
||||
// ! 可用 `按位或 (|)` 进行组合, `按位与 (&)` 进行检测, 互不干扰.
|
||||
// ! 不可将其修改为 0x0101/0x0102/0x0103/0x0104/... 的形式,
|
||||
// ! 以避免标志重叠造成组合与检测逻辑失效, 如 `flags & AS_GLOBAL` 可能出现误判.
|
||||
// !
|
||||
const val AS_GLOBAL = 0x0100
|
||||
const val AS_IGNORED = 0x0200
|
||||
const val AS_LITERAL_TO_STRING = 0x0400
|
||||
const val AS_FUNCTIONAL_TO_STRING = 0x0800
|
||||
|
||||
val globalContext: Context
|
||||
get() = GlobalAppContext.get()
|
||||
|
||||
fun refineAttributes(attributes: Int) = attributes and (READONLY or DONTENUM or PERMANENT or UNINITIALIZED_CONST)
|
||||
|
||||
private fun isInternalName(value: String) = value.startsWith("__") && value.endsWith("__")
|
||||
|
||||
private fun ScriptableObject.defineWith(name: String, getter: Supplier<Any?>, setter: Consumer<Any?>?, attributes: Int) {
|
||||
when (isInternalName(name)) {
|
||||
true -> this.defineProperty(name, getter, setter, DONTENUM or attributes)
|
||||
else -> this.defineProperty(name, getter, setter, attributes)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ScriptableObject.defineWith(name: String, value: Any?, attributes: Int) {
|
||||
when (isInternalName(name)) {
|
||||
true -> this.defineProperty(name, value, DONTENUM or attributes)
|
||||
else -> this.defineProperty(name, value, attributes)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package org.autojs.autojs.runtime.api.augment
|
||||
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
||||
import org.autojs.autojs.rhino.ProxyObject
|
||||
import org.autojs.autojs.rhino.ProxyObject.Companion.AUGMENTED_OBJECT_KEY
|
||||
import org.autojs.autojs.runtime.ScriptRuntime
|
||||
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
|
||||
@@ -70,8 +73,9 @@ open class AugmentableProxy(private val scriptRuntime: ScriptRuntime) : Augmenta
|
||||
return NOT_FOUND
|
||||
}
|
||||
|
||||
open fun getCore(augmented: ScriptableObject, key: String): Any? {
|
||||
return when (val value = augmented.prop(key)) {
|
||||
open fun getCore(augmented: ScriptableObject, key: String): Any? = when (key) {
|
||||
AUGMENTED_OBJECT_KEY -> augmented
|
||||
else -> when (val value = augmented.prop(key)) {
|
||||
is BaseFunction -> when {
|
||||
// @Hint by SuperMonster003 on Nov 6, 2024.
|
||||
// ! Indicated that `key` is not defined in `augmented`
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.mozilla.javascript.NativeArray
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.Scriptable.NOT_FOUND
|
||||
import org.mozilla.javascript.ScriptableObject.DONTENUM
|
||||
import java.util.function.Supplier
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
@@ -83,8 +84,10 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
colorMap
|
||||
}
|
||||
|
||||
private val allForNativeObject by lazy { all.toNativeObject() }
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
"toString",
|
||||
"toString" to AS_FUNCTIONAL_TO_STRING,
|
||||
::toInt.name,
|
||||
::toHex.name,
|
||||
::toFullHex.name,
|
||||
@@ -150,8 +153,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
table::class.java.simpleName.lowercase() to table
|
||||
}
|
||||
|
||||
override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>(
|
||||
"all" to Supplier { all.toNativeObject() },
|
||||
override val selfAssignmentGetters = listOf(
|
||||
"all" to Supplier { allForNativeObject } to DONTENUM,
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -20,12 +20,15 @@ import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.NativeJavaMethod
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.ScriptableObject
|
||||
import org.mozilla.javascript.ScriptableObject.DONTENUM
|
||||
import org.mozilla.javascript.ScriptableObject.PERMANENT
|
||||
import org.mozilla.javascript.ScriptableObject.READONLY
|
||||
import java.lang.reflect.Modifier
|
||||
|
||||
class Events(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
::__asEmitter__.name,
|
||||
::__asEmitter__.name to (READONLY or DONTENUM or PERMANENT),
|
||||
)
|
||||
|
||||
companion object : FlexibleArray() {
|
||||
|
||||
@@ -58,7 +58,7 @@ class Global(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunti
|
||||
)
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
"toString",
|
||||
"toString" to AS_LITERAL_TO_STRING,
|
||||
::TODO.name,
|
||||
::isUiThread.name,
|
||||
::isJavaObject.name,
|
||||
|
||||
@@ -65,7 +65,7 @@ import java.net.URI
|
||||
class Http(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
|
||||
|
||||
override val selfAssignmentProperties = listOf(
|
||||
"__okhttp__" to scriptRuntime.http.okhttp to DONTENUM
|
||||
"__okhttp__" to scriptRuntime.http.okhttp to (READONLY or DONTENUM or PERMANENT)
|
||||
)
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.opencv.core.Rect as OpencvRect
|
||||
class Ocr(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
"toString",
|
||||
"toString" to AS_LITERAL_TO_STRING,
|
||||
::tap.name,
|
||||
::recognizeText.name,
|
||||
::detect.name,
|
||||
|
||||
@@ -123,10 +123,10 @@ class UI(private val scriptRuntime: ScriptRuntime) : AugmentableProxy(scriptRunt
|
||||
::keepScreenOn.name,
|
||||
)
|
||||
|
||||
override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>(
|
||||
override val selfAssignmentGetters = listOf(
|
||||
"R" to Supplier { scriptRuntime.topLevelScope.prop("R").jsUnwrapped() },
|
||||
"__widgets__" to Supplier { scriptRuntime.ui.widgets },
|
||||
"root" to Supplier {
|
||||
"root" to Supplier<Any?> {
|
||||
val activity = getActivity(scriptRuntime)
|
||||
(activity as? ScriptExecuteActivity)?.findViewById(android.R.id.content)
|
||||
},
|
||||
|
||||
@@ -10,6 +10,9 @@ import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
|
||||
import org.autojs.autojs.extension.NumberExtensions.jsString
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
||||
import org.autojs.autojs.rhino.ProxyObject
|
||||
import org.autojs.autojs.rhino.ProxyObject.Companion.AUGMENTED_CUSTOM_TO_STRING_KEY
|
||||
import org.autojs.autojs.rhino.ProxyObject.Companion.AUGMENTED_OBJECT_KEY
|
||||
import org.autojs.autojs.rhino.ProxyObject.Companion.PROXY_GETTER_KEY
|
||||
import org.autojs.autojs.rhino.ProxyObject.Companion.PROXY_SETTER_KEY
|
||||
import org.autojs.autojs.runtime.api.StringReadable
|
||||
@@ -17,8 +20,8 @@ import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||
import org.autojs.autojs.runtime.api.augment.global.Species.isErrorRhino
|
||||
import org.autojs.autojs.runtime.api.augment.global.Species.isJavaObjectRhino
|
||||
import org.autojs.autojs.runtime.api.augment.global.Species.isObjectRhino
|
||||
import org.autojs.autojs.runtime.api.augment.global.Species.isStringRhino
|
||||
import org.autojs.autojs.runtime.api.augment.util.Util.isReferenceRhino
|
||||
import org.autojs.autojs.runtime.exception.ShouldNeverHappenException
|
||||
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||
import org.autojs.autojs.util.RhinoUtils
|
||||
@@ -35,10 +38,12 @@ import org.autojs.autojs.util.RhinoUtils.js_object_keys
|
||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||
import org.mozilla.javascript.BaseFunction
|
||||
import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.MemberBox
|
||||
import org.mozilla.javascript.NativeArray
|
||||
import org.mozilla.javascript.NativeDate
|
||||
import org.mozilla.javascript.NativeError
|
||||
import org.mozilla.javascript.NativeJavaClass
|
||||
import org.mozilla.javascript.NativeJavaMethod
|
||||
import org.mozilla.javascript.NativeJavaPackage
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import org.mozilla.javascript.Scriptable
|
||||
@@ -75,7 +80,6 @@ object Inspect : Augmentable(), Invokable {
|
||||
* SGR (Select Graphic Rendition) parameters
|
||||
* @see <a href="https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters">"ANSI escape code" on Wikipedia (en)</a>
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private val srg = object {
|
||||
val fg = object {
|
||||
val BLACK = 30
|
||||
@@ -306,21 +310,58 @@ object Inspect : Augmentable(), Invokable {
|
||||
if (value is NativeJavaClass) return value.toString()
|
||||
if (value.javaClass.isArray) return javaArrayToString(value)
|
||||
if (value !is ScriptableObject) return Context.toString(value)
|
||||
if (value is ProxyObject) return formatValue(ctx, value[AUGMENTED_OBJECT_KEY], recurseTimes)
|
||||
|
||||
// @Hint by SuperMonster003 on Apr 16, 2024.
|
||||
// ! Check if the object has a custom overwritten toString() method.
|
||||
// ! zh-CN: 检查对象是否有自定义的 toString() 覆写方法.
|
||||
if (isObjectRhino(value)) {
|
||||
var tmp: Scriptable = value
|
||||
val objectPrototype by lazy { ScriptableObject.getObjectPrototype(value) }
|
||||
do {
|
||||
if (js_object_hasOwnProperty(tmp, "toString")) {
|
||||
if ((tmp.prop("toString") as? BaseFunction)?.arity == 0) {
|
||||
return callToStringFunction(value)
|
||||
}
|
||||
if (isReferenceRhino(value)) {
|
||||
var cur: Scriptable = value
|
||||
val objProtoForJs: Scriptable? = ScriptableObject.getObjectPrototype(cur)
|
||||
val objProtoForAugmentable: Scriptable = RhinoUtils.objectPrototype
|
||||
val arrProtoForAugmentable: Scriptable = RhinoUtils.arrayPrototype
|
||||
val funcProtoForAugmentable: Scriptable = RhinoUtils.functionPrototype
|
||||
var owner: Scriptable? = null
|
||||
while (true) {
|
||||
if (js_object_hasOwnProperty(cur, "toString")) {
|
||||
owner = cur
|
||||
break
|
||||
}
|
||||
tmp = tmp.prototype ?: break
|
||||
} while (tmp != objectPrototype)
|
||||
cur = cur.prototype ?: break
|
||||
}
|
||||
if (js_object_hasOwnProperty(cur, AUGMENTED_CUSTOM_TO_STRING_KEY)) {
|
||||
// Augmentable's custom toString method with special functionality (like Colors.toString)
|
||||
// is not involved in custom determination.
|
||||
// zh-CN: Augmentable 自定义的具有特殊功能的 toString 方法 (如 Colors.toString), 不参与自定义判定.
|
||||
} else if (owner != null) {
|
||||
val fn = owner["toString"]
|
||||
val isCustom = run {
|
||||
if (isJavaObjectToString(fn)) {
|
||||
// Standard Java Object#toString or equivalent implementation, skip custom check.
|
||||
// zh-CN: 标准 Java Object#toString 或等价实现, 视为未自定义, 跳过自定义判定.
|
||||
return@run false
|
||||
}
|
||||
if (fn === objProtoForJs?.get("toString")) {
|
||||
// Standard JavaScript Object.prototype.toString or equivalent implementation, skip custom check.
|
||||
// zh-CN: 标准 JavaScript Object.prototype.toString 或等价实现, 视为未自定义, 跳过自定义判定.
|
||||
return@run false
|
||||
}
|
||||
val augmentableToStringList = listOf(
|
||||
objProtoForAugmentable["toString"],
|
||||
arrProtoForAugmentable["toString"],
|
||||
funcProtoForAugmentable["toString"],
|
||||
)
|
||||
if (fn in augmentableToStringList) {
|
||||
// Terminal toString in Augmentable prototype chain, skip custom check.
|
||||
// zh-CN: Augmentable 原型链终端的 toString, 不参与自定义判定.
|
||||
return@run false
|
||||
}
|
||||
return@run fn is BaseFunction && fn.arity == 0
|
||||
}
|
||||
if (isCustom) {
|
||||
return callToStringFunction(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look up the keys of the object.
|
||||
@@ -328,7 +369,6 @@ object Inspect : Augmentable(), Invokable {
|
||||
val visibleKeys = newNativeObject().also { o ->
|
||||
keys.forEach { o.put(Context.toString(it), o, true) }
|
||||
}
|
||||
|
||||
if (ctx.showHidden) {
|
||||
keys = js_object_getOwnPropertyNames(value)
|
||||
}
|
||||
@@ -419,6 +459,18 @@ object Inspect : Augmentable(), Invokable {
|
||||
return reduceToSingleString(output, base, braces)
|
||||
}
|
||||
|
||||
private fun isJavaObjectToString(fn: Any?): Boolean {
|
||||
if (fn !is NativeJavaMethod) return false
|
||||
val methods: Array<out MemberBox> = fn.methods
|
||||
return methods.any { mb ->
|
||||
val m = mb.method()
|
||||
m.name == "toString" &&
|
||||
m.parameterCount == 0 &&
|
||||
m.returnType == String::class.java &&
|
||||
m.declaringClass == Any::class.java
|
||||
}
|
||||
}
|
||||
|
||||
private fun toJavaObjectString(value: Any) = "[JavaObject: ${value.javaClass.name}@${Integer.toHexString(value.hashCode())}]"
|
||||
|
||||
private fun toJavaObjectString(className: Any?, value: Any?) = "[JavaObject: $className@${Integer.toHexString(value.hashCode())}]"
|
||||
|
||||
@@ -20,10 +20,10 @@ import org.mozilla.javascript.Scriptable
|
||||
class MorseCodeNativeObject(val parser: MorseCodeParser) : NativeObject(), StringReadable {
|
||||
|
||||
private val mFunctionNames = arrayOf(
|
||||
"toString",
|
||||
::getPattern.name,
|
||||
::getCode.name,
|
||||
::vibrate.name,
|
||||
"toString",
|
||||
)
|
||||
|
||||
init {
|
||||
|
||||
@@ -62,6 +62,7 @@ import org.mozilla.javascript.ScriptRuntime as RhinoScriptRuntime
|
||||
object Util : Augmentable() {
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
::__assignFunctions__.name to (READONLY or DONTENUM or PERMANENT),
|
||||
::isArray.name,
|
||||
::isBoolean.name,
|
||||
::isNull.name,
|
||||
@@ -84,7 +85,6 @@ object Util : Augmentable() {
|
||||
::isEmptyObject.name,
|
||||
::unwrapJavaObject.name,
|
||||
::extend.name,
|
||||
::__assignFunctions__.name,
|
||||
::format.name,
|
||||
::deprecate.name,
|
||||
::debuglog.name,
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.autojs.autojs.annotation.RhinoStandardFunctionInterface
|
||||
import org.autojs.autojs.extension.AnyExtensions.isJsNullish
|
||||
import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
|
||||
import org.autojs.autojs.extension.FlexibleArray
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||
import org.autojs.autojs.extension.NumberExtensions.jsString
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||
@@ -18,6 +19,7 @@ import org.mozilla.javascript.NativeDate
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import org.mozilla.javascript.ScriptRuntime.wrapNumber
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.ScriptableObject.DONTENUM
|
||||
import org.mozilla.javascript.ScriptableObject.PERMANENT
|
||||
import org.mozilla.javascript.ScriptableObject.READONLY
|
||||
import java.util.*
|
||||
@@ -26,7 +28,7 @@ import java.util.*
|
||||
object VersionCodes : Augmentable() {
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
"toString",
|
||||
"toString" to AS_LITERAL_TO_STRING,
|
||||
::search.name,
|
||||
::searchAll.name,
|
||||
::summary.name,
|
||||
@@ -84,14 +86,14 @@ object VersionCodes : Augmentable() {
|
||||
val releaseTimestamp = releaseTimestampLong.jsString
|
||||
|
||||
fun toNativeObject() = newNativeObject().also {
|
||||
it.put("versionCode", it, versionCode)
|
||||
it.put("apiLevel", it, apiLevel.toInt())
|
||||
it.put("releaseName", it, releaseName)
|
||||
it.put("platformVersion", it, platformVersion)
|
||||
it.put("internalCodename", it, internalCodename)
|
||||
it.put("releaseDate", it, releaseDate)
|
||||
it.put("releaseTimestamp", it, releaseTimestampLong)
|
||||
it.defineFunctionProperties(arrayOf("valueOf"), javaClass, READONLY and PERMANENT)
|
||||
it.defineProperty("versionCode", versionCode, READONLY or PERMANENT)
|
||||
it.defineProperty("apiLevel", apiLevel.toInt(), READONLY or PERMANENT)
|
||||
it.defineProperty("releaseName", releaseName, READONLY or PERMANENT)
|
||||
it.defineProperty("platformVersion", platformVersion, READONLY or PERMANENT)
|
||||
it.defineProperty("internalCodename", internalCodename, READONLY or PERMANENT)
|
||||
it.defineProperty("releaseDate", releaseDate, READONLY or PERMANENT)
|
||||
it.defineProperty("releaseTimestamp", releaseTimestampLong, READONLY or PERMANENT)
|
||||
it.defineFunctionProperties(arrayOf("valueOf"), javaClass, READONLY or DONTENUM or PERMANENT)
|
||||
}
|
||||
|
||||
private fun parseTimestamp(s: String): Long {
|
||||
@@ -130,7 +132,9 @@ object VersionCodes : Augmentable() {
|
||||
fun valueOf(cx: Context, thisObj: Scriptable, args: Array<Any?>, funObj: Function): Any? {
|
||||
return thisObj.prop("apiLevel")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal object Searcher {
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.autojs.autojs.runtime.api.augment.util
|
||||
import android.os.Build
|
||||
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||
import org.mozilla.javascript.ScriptableObject.PERMANENT
|
||||
import org.mozilla.javascript.ScriptableObject.READONLY
|
||||
|
||||
object VersionCodesInfo {
|
||||
|
||||
@@ -55,7 +57,7 @@ object VersionCodesInfo {
|
||||
for ((versionCode, infoList) in raw) {
|
||||
val (releaseName, internalCodename, platformVersion, apiLevel, releaseDate) = infoList
|
||||
val info = VersionCodes.Info(versionCode, releaseName, internalCodename, platformVersion, apiLevel, releaseDate)
|
||||
obj.put(versionCode, obj, info.toNativeObject())
|
||||
obj.defineProperty(versionCode, { info.toNativeObject() }, null, READONLY or PERMANENT)
|
||||
list += info
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener, LayoutInsp
|
||||
}
|
||||
|
||||
private void applyComponentInformation() {
|
||||
if (WrappedShizuku.isOperational() && WrappedShizuku.service != null) {
|
||||
if (WrappedShizuku.INSTANCE.isOperational() && WrappedShizuku.service != null) {
|
||||
try {
|
||||
mRunningPackage = WrappedShizuku.service.currentPackage();
|
||||
mRunningActivity = WrappedShizuku.service.currentActivity();
|
||||
|
||||
@@ -127,7 +127,7 @@ object RhinoUtils {
|
||||
fun callFunction(scriptRuntime: ScriptRuntime?, obj: Scriptable, name: String, paramsToFunction: Array<Any?>): Any? {
|
||||
val property = obj.prop(name)
|
||||
if (property == NOT_FOUND) throw IllegalArgumentException("Property $name not found on $obj")
|
||||
if (property !is BaseFunction) throw IllegalArgumentException("Property $name on $obj must be a BaseFunction")
|
||||
if (property !is BaseFunction) throw IllegalArgumentException("Property $name on $obj must be a BaseFunction instead of ${property.jsBrief()}")
|
||||
return callFunction(scriptRuntime, property, obj, obj, paramsToFunction)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user