6.7.0 - Alpha6 - console.log 等方法打印全局对象 (images, app, ocr 等) 时支持显示详细信息

This commit is contained in:
SuperMonster003
2025-10-05 13:29:04 +08:00
parent 9dd55a063d
commit 4235ffda82
26 changed files with 221 additions and 76 deletions

View File

@@ -1,7 +1,7 @@
{ {
"$data": { "$data": {
"v6.7.0": { "v6.7.0": {
"released_date": "2025/10/02", "released_date": "2025/10/05",
"feature": [ "feature": [
"zip 模块, 用于文件压缩与解压缩操作 (Ref to [Auto.js Pro](https://g.pro.autojs.org/)) (参阅 项目文档 > [Zip](https://docs.autojs6.com/#/zip))", "zip 模块, 用于文件压缩与解压缩操作 (Ref to [Auto.js Pro](https://g.pro.autojs.org/)) (参阅 项目文档 > [Zip](https://docs.autojs6.com/#/zip))",
"mediainfo 模块, 用于查看媒体文件的详细信息 (参阅 项目文档 > [媒体信息](https://docs.autojs6.com/#/mediainfo))", "mediainfo 模块, 用于查看媒体文件的详细信息 (参阅 项目文档 > [媒体信息](https://docs.autojs6.com/#/mediainfo))",
@@ -15,6 +15,7 @@
"timers.keepAlive 方法 timeout 参数功能无效的问题", "timers.keepAlive 方法 timeout 参数功能无效的问题",
"floaty.window/rawWindow 方法无法接受字符串参数的问题", "floaty.window/rawWindow 方法无法接受字符串参数的问题",
"util.class[Name]/getClass[Name] 可能返回错误结果的问题", "util.class[Name]/getClass[Name] 可能返回错误结果的问题",
"部分全局对象可能丢失 JavaScript 原型属性及方法的问题",
"使用 XML 语法将 JavaScript 表达式作为属性值时, this 对象可能出现指向错误的问题", "使用 XML 语法将 JavaScript 表达式作为属性值时, this 对象可能出现指向错误的问题",
"canvas 元素控件 setMaxFps 方法内部帧率计算错误", "canvas 元素控件 setMaxFps 方法内部帧率计算错误",
"images.concat 方法纵向拼接时宽度值计算错误", "images.concat 方法纵向拼接时宽度值计算错误",
@@ -32,6 +33,7 @@
"构建工具启用 isCleanup[Paddle/Rapid]Ocr 配置选项时无法正常完成 Rebuild Project 任务的问题" "构建工具启用 isCleanup[Paddle/Rapid]Ocr 配置选项时无法正常完成 Rebuild Project 任务的问题"
], ],
"improvement": [ "improvement": [
"console.log 等方法打印全局对象 (images, app, ocr 等) 时支持显示详细信息",
"http 模块相关方法支持不安全选项参数 (isInsecure/insecure), 用于忽略证书相关异常 _[`issue #417`](http://issues.autojs6.com/417)_", "http 模块相关方法支持不安全选项参数 (isInsecure/insecure), 用于忽略证书相关异常 _[`issue #417`](http://issues.autojs6.com/417)_",
"android.graphics.Paint#setColor 支持正常解析 ColorInt/ColorHex/ColorName 等颜色参数", "android.graphics.Paint#setColor 支持正常解析 ColorInt/ColorHex/ColorName 等颜色参数",
"内置模块相关方法实参类型的异常消息增加类型摘要信息", "内置模块相关方法实参类型的异常消息增加类型摘要信息",

View File

@@ -12,7 +12,7 @@
"android_studio_latest_recommended_file_size_of_tar": "1.37 GiB", "android_studio_latest_recommended_file_size_of_tar": "1.37 GiB",
"var_date_contribution_table_data_updated": "2025/09/06", "var_date_contribution_table_data_updated": "2025/09/06",
"latest_rhino_engine_name_with_github_lineno_address": "[v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3)", "latest_rhino_engine_name_with_github_lineno_address": "[v1.8.1-SNAPSHOT](http://rhino.autojs6.com/blob/master/gradle.properties#L3)",
"var_date_rhino_engine_latest_committed": "2025/09/10", "var_date_rhino_engine_latest_committed": "2025/10/05",
"var_date_jdk_max_supported": "%CURRENT_DATE%", "var_date_jdk_max_supported": "%CURRENT_DATE%",
"var_date_active_maintenance_phase_statistics_since_when": "%CURRENT_DATE%" "var_date_active_maintenance_phase_statistics_since_when": "%CURRENT_DATE%"
} }

View File

@@ -19,7 +19,11 @@ plugins {
idea { idea {
module { 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/"),
))
} }
} }

View File

@@ -30,7 +30,9 @@ import org.mozilla.javascript.NativeArray
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
import org.mozilla.javascript.Script import org.mozilla.javascript.Script
import org.mozilla.javascript.Scriptable import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject.DONTENUM
import org.mozilla.javascript.ScriptableObject.PERMANENT 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.RequireBuilder
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider
import java.io.File import java.io.File
@@ -103,7 +105,7 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con
override fun init() { override fun init() {
thread = Thread.currentThread() thread = Thread.currentThread()
scriptable.defineProp("__engine__", this) scriptable.defineProp("__engine__", this, READONLY or DONTENUM or PERMANENT)
initRequireBuilder(context, scriptable) initRequireBuilder(context, scriptable)
runtime.withTimeConsuming("runtime-init-prologue") { runtime.withTimeConsuming("runtime-init-prologue") {

View File

@@ -24,7 +24,7 @@ class ShizukuPermission(override val context: Context) : PermissionItemHelper {
} catch (e: Throwable) { } catch (e: Throwable) {
e.printStackTrace() 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 } ?: 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 { return when {
!WrappedShizuku.isInstalled(context) -> false.also { ViewUtils.showToast(context, R.string.error_shizuku_is_not_installed) } !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) } 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 } ?: ViewUtils.showToast(context, R.string.error_failed_to_revoke_shizuku_access).let { false }
} }
} }

View File

@@ -73,6 +73,12 @@ open class ProxyObject() : NativeObject() {
@JvmField @JvmField
val PROXY_OBJECT_KEY = "__proxy__" val PROXY_OBJECT_KEY = "__proxy__"
@JvmField
val AUGMENTED_OBJECT_KEY = "__augmented__"
@JvmField
val AUGMENTED_CUSTOM_TO_STRING_KEY = "__augmented_custom_to_string__"
@JvmField @JvmField
val PROXY_SETTER_KEY = "set" val PROXY_SETTER_KEY = "set"

View File

@@ -458,7 +458,7 @@ class ScriptRuntime private constructor(builder: Builder) {
floaty = ApiFloaty(uiHandler, this) floaty = ApiFloaty(uiHandler, this)
ui = ApiUI(mUiHandlerAppContext, this) ui = ApiUI(mUiHandlerAppContext, this)
util = ApiUtil(mUiHandlerAppContext, this) util = ApiUtil
images = ApiImages(mUiHandlerAppContext, this) images = ApiImages(mUiHandlerAppContext, this)
device = ApiDevice(mUiHandlerAppContext) device = ApiDevice(mUiHandlerAppContext)
media = ApiMedia(mUiHandlerAppContext, this) media = ApiMedia(mUiHandlerAppContext, this)

View File

@@ -1,9 +1,8 @@
package org.autojs.autojs.runtime.api package org.autojs.autojs.runtime.api
import org.autojs.autojs.extension.AnyExtensions.jsBrief 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") fun `class`(o: Any?) = getClassInternal(o, "class")

View File

@@ -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() } false.also { if (e.message?.contains(Regex("binder .+n[o']t been received", RegexOption.IGNORE_CASE)) == false) e.printStackTrace() }
} }
@JvmStatic
@ScriptInterface @ScriptInterface
fun isOperational(): Boolean = isRunning() && hasPermission() fun isOperational(): Boolean = isRunning() && hasPermission()
@@ -130,12 +129,11 @@ object WrappedShizuku {
@ScriptInterface @ScriptInterface
fun requestPermission() = Shizuku.requestPermission(mRequestCode) fun requestPermission() = Shizuku.requestPermission(mRequestCode)
@ScriptInterface
fun config(isRequest: Boolean?) = config(GlobalAppContext.get(), isRequest)
@ScriptInterface @ScriptInterface
@JvmOverloads @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) context.startActivity(it)
val message = when (isRequest) { 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)})" 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)})"

View File

@@ -5,9 +5,11 @@ import org.autojs.autojs.app.GlobalAppContext
import org.autojs.autojs.extension.AnyExtensions.isJsNullish import org.autojs.autojs.extension.AnyExtensions.isJsNullish
import org.autojs.autojs.extension.AnyExtensions.jsBrief import org.autojs.autojs.extension.AnyExtensions.jsBrief
import org.autojs.autojs.extension.FlexibleArray 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.defineProp
import org.autojs.autojs.extension.ScriptableExtensions.prop import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.rhino.ProxyObject 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.rhino.ProxyObject.Companion.PROXY_GETTER_KEY
import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.augment.events.Events 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> * List element cases: <br>
* - <1> - name to getter * - <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> * List element cases: <br>
@@ -264,17 +267,19 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
objProtoList += Events.__asEmitter__(scriptRuntime, emptyArray()) objProtoList += Events.__asEmitter__(scriptRuntime, emptyArray())
} }
objProtoList.forEachIndexed { index, prototypeObject -> augmentPrototypesAt(index, newObj, prototypeObject) } val newObjOriginalPrototype = newObj.prototype
scopeProtoList.forEachIndexed { index, prototypeObject -> augmentPrototypesAt(index, global, prototypeObject) } 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) { when (index) {
0 -> o.prototype = proto 0 -> o.prototype = proto.apply { prototype = originalProto }
1 -> o.prototype.prototype = proto 1 -> o.prototype.prototype = proto.apply { prototype = originalProto }
2 -> o.prototype.prototype.prototype = proto 2 -> o.prototype.prototype.prototype = proto.apply { prototype = originalProto }
3 -> o.prototype.prototype.prototype.prototype = proto 3 -> o.prototype.prototype.prototype.prototype = proto.apply { prototype = originalProto }
4 -> o.prototype.prototype.prototype.prototype.prototype = proto 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") 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) { if (flag and AS_GLOBAL != 0) {
globalFunctions += name to alias to (PERMANENT or refineAttributes(flag)) 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") 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) { when (item) {
is String -> globalFunctions += item to item to PERMANENT is String -> globalFunctions += item to item to PERMANENT
is Pair<*, *> -> { is Pair<*, *> -> {
val first = item.first val (first, second) = item
val second = item.second
val name: String val name: String
val aliasList = mutableListOf<String>() val aliasList = mutableListOf<String>()
var flag = 0 var flag = 0
@@ -474,33 +481,62 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
throw WrappedRuntimeException(niceMessage) throw WrappedRuntimeException(niceMessage)
} }
}, NOT_CONSTRUCTABLE) }, NOT_CONSTRUCTABLE)
destination.defineProperty(funcNameAlias, f, attributes) destination.defineWith(funcNameAlias, f, attributes)
} }
} }
@Suppress("UnnecessaryVariable", "UNCHECKED_CAST")
private fun augmentGettersAndSetters(target: ScriptableObject, global: ScriptableObject) { private fun augmentGettersAndSetters(target: ScriptableObject, global: ScriptableObject) {
selfAssignmentGetters.forEach { pair -> selfAssignmentGetters.forEach { item ->
val (name, getter) = pair when (item) {
target.defineProperty(name, getter, null, PERMANENT) 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 -> selfAssignmentGettersAndSetters.forEach { triple ->
val (name, getter, setter) = triple val (name, getter, setter) = triple
target.defineProperty(name, getter, setter, PERMANENT) target.defineWith(name, getter, setter, PERMANENT)
} }
globalAssignmentGetters.forEach { pair -> globalAssignmentGetters.forEach { pair ->
val (name, getter) = pair val (name, getter) = pair
global.defineProperty(name, getter, null, PERMANENT) global.defineWith(name, getter, null, PERMANENT)
} }
} }
private fun augmentJavaClasses(target: ScriptableObject, global: ScriptableObject) { private fun augmentJavaClasses(target: ScriptableObject, global: ScriptableObject) {
selfAssignmentJavaClasses.forEach { pair -> selfAssignmentJavaClasses.forEach { pair ->
val (name, clazz) = pair val (name, clazz) = pair
target.defineProperty(name, NativeJavaClass(global, clazz.java), PERMANENT) target.defineWith(name, NativeJavaClass(global, clazz.java), PERMANENT)
} }
globalAssignmentJavaClasses.forEach { pair -> globalAssignmentJavaClasses.forEach { pair ->
val (name, clazz) = 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() { companion object : FlexibleArray() {
const val AS_GLOBAL = 0x1000 // @Caution by SuperMonster003 on Oct 5, 2025.
const val AS_IGNORED = 0x2000 // ! 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 val globalContext: Context
get() = GlobalAppContext.get() get() = GlobalAppContext.get()
fun refineAttributes(attributes: Int) = attributes and (READONLY or DONTENUM or PERMANENT or UNINITIALIZED_CONST) 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)
}
}
} }
} }

View File

@@ -1,8 +1,11 @@
package org.autojs.autojs.runtime.api.augment 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.defineProp
import org.autojs.autojs.extension.ScriptableExtensions.prop import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.rhino.ProxyObject 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.ScriptRuntime
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.util.RhinoUtils.UNDEFINED import org.autojs.autojs.util.RhinoUtils.UNDEFINED
@@ -70,8 +73,9 @@ open class AugmentableProxy(private val scriptRuntime: ScriptRuntime) : Augmenta
return NOT_FOUND return NOT_FOUND
} }
open fun getCore(augmented: ScriptableObject, key: String): Any? { open fun getCore(augmented: ScriptableObject, key: String): Any? = when (key) {
return when (val value = augmented.prop(key)) { AUGMENTED_OBJECT_KEY -> augmented
else -> when (val value = augmented.prop(key)) {
is BaseFunction -> when { is BaseFunction -> when {
// @Hint by SuperMonster003 on Nov 6, 2024. // @Hint by SuperMonster003 on Nov 6, 2024.
// ! Indicated that `key` is not defined in `augmented` // ! Indicated that `key` is not defined in `augmented`

View File

@@ -41,6 +41,7 @@ import org.mozilla.javascript.NativeArray
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
import org.mozilla.javascript.Scriptable import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.Scriptable.NOT_FOUND import org.mozilla.javascript.Scriptable.NOT_FOUND
import org.mozilla.javascript.ScriptableObject.DONTENUM
import java.util.function.Supplier import java.util.function.Supplier
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -83,8 +84,10 @@ object Colors : Augmentable(), SimpleGetterProxy {
colorMap colorMap
} }
private val allForNativeObject by lazy { all.toNativeObject() }
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
"toString", "toString" to AS_FUNCTIONAL_TO_STRING,
::toInt.name, ::toInt.name,
::toHex.name, ::toHex.name,
::toFullHex.name, ::toFullHex.name,
@@ -150,8 +153,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
table::class.java.simpleName.lowercase() to table table::class.java.simpleName.lowercase() to table
} }
override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>( override val selfAssignmentGetters = listOf(
"all" to Supplier { all.toNativeObject() }, "all" to Supplier { allForNativeObject } to DONTENUM,
) )
@JvmStatic @JvmStatic

View File

@@ -20,12 +20,15 @@ import org.mozilla.javascript.Context
import org.mozilla.javascript.NativeJavaMethod import org.mozilla.javascript.NativeJavaMethod
import org.mozilla.javascript.Scriptable import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject 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 import java.lang.reflect.Modifier
class Events(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { class Events(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
::__asEmitter__.name, ::__asEmitter__.name to (READONLY or DONTENUM or PERMANENT),
) )
companion object : FlexibleArray() { companion object : FlexibleArray() {

View File

@@ -58,7 +58,7 @@ class Global(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunti
) )
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
"toString", "toString" to AS_LITERAL_TO_STRING,
::TODO.name, ::TODO.name,
::isUiThread.name, ::isUiThread.name,
::isJavaObject.name, ::isJavaObject.name,

View File

@@ -65,7 +65,7 @@ import java.net.URI
class Http(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { class Http(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
override val selfAssignmentProperties = listOf( 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( override val selfAssignmentFunctions = listOf(

View File

@@ -31,7 +31,7 @@ import org.opencv.core.Rect as OpencvRect
class Ocr(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable { class Ocr(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
"toString", "toString" to AS_LITERAL_TO_STRING,
::tap.name, ::tap.name,
::recognizeText.name, ::recognizeText.name,
::detect.name, ::detect.name,

View File

@@ -123,10 +123,10 @@ class UI(private val scriptRuntime: ScriptRuntime) : AugmentableProxy(scriptRunt
::keepScreenOn.name, ::keepScreenOn.name,
) )
override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>( override val selfAssignmentGetters = listOf(
"R" to Supplier { scriptRuntime.topLevelScope.prop("R").jsUnwrapped() }, "R" to Supplier { scriptRuntime.topLevelScope.prop("R").jsUnwrapped() },
"__widgets__" to Supplier { scriptRuntime.ui.widgets }, "__widgets__" to Supplier { scriptRuntime.ui.widgets },
"root" to Supplier { "root" to Supplier<Any?> {
val activity = getActivity(scriptRuntime) val activity = getActivity(scriptRuntime)
(activity as? ScriptExecuteActivity)?.findViewById(android.R.id.content) (activity as? ScriptExecuteActivity)?.findViewById(android.R.id.content)
}, },

View File

@@ -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.FlexibleArray.Companion.component2
import org.autojs.autojs.extension.NumberExtensions.jsString import org.autojs.autojs.extension.NumberExtensions.jsString
import org.autojs.autojs.extension.ScriptableExtensions.prop 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_GETTER_KEY
import org.autojs.autojs.rhino.ProxyObject.Companion.PROXY_SETTER_KEY import org.autojs.autojs.rhino.ProxyObject.Companion.PROXY_SETTER_KEY
import org.autojs.autojs.runtime.api.StringReadable 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.Invokable
import org.autojs.autojs.runtime.api.augment.global.Species.isErrorRhino 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.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.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.ShouldNeverHappenException
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.util.RhinoUtils 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.autojs.autojs.util.RhinoUtils.newNativeObject
import org.mozilla.javascript.BaseFunction import org.mozilla.javascript.BaseFunction
import org.mozilla.javascript.Context import org.mozilla.javascript.Context
import org.mozilla.javascript.MemberBox
import org.mozilla.javascript.NativeArray import org.mozilla.javascript.NativeArray
import org.mozilla.javascript.NativeDate import org.mozilla.javascript.NativeDate
import org.mozilla.javascript.NativeError import org.mozilla.javascript.NativeError
import org.mozilla.javascript.NativeJavaClass import org.mozilla.javascript.NativeJavaClass
import org.mozilla.javascript.NativeJavaMethod
import org.mozilla.javascript.NativeJavaPackage import org.mozilla.javascript.NativeJavaPackage
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
import org.mozilla.javascript.Scriptable import org.mozilla.javascript.Scriptable
@@ -75,7 +80,6 @@ object Inspect : Augmentable(), Invokable {
* SGR (Select Graphic Rendition) parameters * 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> * @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 { private val srg = object {
val fg = object { val fg = object {
val BLACK = 30 val BLACK = 30
@@ -306,21 +310,58 @@ object Inspect : Augmentable(), Invokable {
if (value is NativeJavaClass) return value.toString() if (value is NativeJavaClass) return value.toString()
if (value.javaClass.isArray) return javaArrayToString(value) if (value.javaClass.isArray) return javaArrayToString(value)
if (value !is ScriptableObject) return Context.toString(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. // @Hint by SuperMonster003 on Apr 16, 2024.
// ! Check if the object has a custom overwritten toString() method. // ! Check if the object has a custom overwritten toString() method.
// ! zh-CN: 检查对象是否有自定义的 toString() 覆写方法. // ! zh-CN: 检查对象是否有自定义的 toString() 覆写方法.
if (isObjectRhino(value)) { if (isReferenceRhino(value)) {
var tmp: Scriptable = value var cur: Scriptable = value
val objectPrototype by lazy { ScriptableObject.getObjectPrototype(value) } val objProtoForJs: Scriptable? = ScriptableObject.getObjectPrototype(cur)
do { val objProtoForAugmentable: Scriptable = RhinoUtils.objectPrototype
if (js_object_hasOwnProperty(tmp, "toString")) { val arrProtoForAugmentable: Scriptable = RhinoUtils.arrayPrototype
if ((tmp.prop("toString") as? BaseFunction)?.arity == 0) { val funcProtoForAugmentable: Scriptable = RhinoUtils.functionPrototype
return callToStringFunction(value) var owner: Scriptable? = null
} while (true) {
if (js_object_hasOwnProperty(cur, "toString")) {
owner = cur
break
} }
tmp = tmp.prototype ?: break cur = cur.prototype ?: break
} while (tmp != objectPrototype) }
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. // Look up the keys of the object.
@@ -328,7 +369,6 @@ object Inspect : Augmentable(), Invokable {
val visibleKeys = newNativeObject().also { o -> val visibleKeys = newNativeObject().also { o ->
keys.forEach { o.put(Context.toString(it), o, true) } keys.forEach { o.put(Context.toString(it), o, true) }
} }
if (ctx.showHidden) { if (ctx.showHidden) {
keys = js_object_getOwnPropertyNames(value) keys = js_object_getOwnPropertyNames(value)
} }
@@ -419,6 +459,18 @@ object Inspect : Augmentable(), Invokable {
return reduceToSingleString(output, base, braces) 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(value: Any) = "[JavaObject: ${value.javaClass.name}@${Integer.toHexString(value.hashCode())}]"
private fun toJavaObjectString(className: Any?, value: Any?) = "[JavaObject: $className@${Integer.toHexString(value.hashCode())}]" private fun toJavaObjectString(className: Any?, value: Any?) = "[JavaObject: $className@${Integer.toHexString(value.hashCode())}]"

View File

@@ -20,10 +20,10 @@ import org.mozilla.javascript.Scriptable
class MorseCodeNativeObject(val parser: MorseCodeParser) : NativeObject(), StringReadable { class MorseCodeNativeObject(val parser: MorseCodeParser) : NativeObject(), StringReadable {
private val mFunctionNames = arrayOf( private val mFunctionNames = arrayOf(
"toString",
::getPattern.name, ::getPattern.name,
::getCode.name, ::getCode.name,
::vibrate.name, ::vibrate.name,
"toString",
) )
init { init {

View File

@@ -62,6 +62,7 @@ import org.mozilla.javascript.ScriptRuntime as RhinoScriptRuntime
object Util : Augmentable() { object Util : Augmentable() {
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
::__assignFunctions__.name to (READONLY or DONTENUM or PERMANENT),
::isArray.name, ::isArray.name,
::isBoolean.name, ::isBoolean.name,
::isNull.name, ::isNull.name,
@@ -84,7 +85,6 @@ object Util : Augmentable() {
::isEmptyObject.name, ::isEmptyObject.name,
::unwrapJavaObject.name, ::unwrapJavaObject.name,
::extend.name, ::extend.name,
::__assignFunctions__.name,
::format.name, ::format.name,
::deprecate.name, ::deprecate.name,
::debuglog.name, ::debuglog.name,

View File

@@ -5,6 +5,7 @@ import org.autojs.autojs.annotation.RhinoStandardFunctionInterface
import org.autojs.autojs.extension.AnyExtensions.isJsNullish import org.autojs.autojs.extension.AnyExtensions.isJsNullish
import org.autojs.autojs.extension.ArrayExtensions.toNativeArray import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
import org.autojs.autojs.extension.FlexibleArray 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.NumberExtensions.jsString
import org.autojs.autojs.extension.ScriptableExtensions.prop import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.runtime.api.augment.Augmentable 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.NativeObject
import org.mozilla.javascript.ScriptRuntime.wrapNumber import org.mozilla.javascript.ScriptRuntime.wrapNumber
import org.mozilla.javascript.Scriptable import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject.DONTENUM
import org.mozilla.javascript.ScriptableObject.PERMANENT import org.mozilla.javascript.ScriptableObject.PERMANENT
import org.mozilla.javascript.ScriptableObject.READONLY import org.mozilla.javascript.ScriptableObject.READONLY
import java.util.* import java.util.*
@@ -26,7 +28,7 @@ import java.util.*
object VersionCodes : Augmentable() { object VersionCodes : Augmentable() {
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
"toString", "toString" to AS_LITERAL_TO_STRING,
::search.name, ::search.name,
::searchAll.name, ::searchAll.name,
::summary.name, ::summary.name,
@@ -84,14 +86,14 @@ object VersionCodes : Augmentable() {
val releaseTimestamp = releaseTimestampLong.jsString val releaseTimestamp = releaseTimestampLong.jsString
fun toNativeObject() = newNativeObject().also { fun toNativeObject() = newNativeObject().also {
it.put("versionCode", it, versionCode) it.defineProperty("versionCode", versionCode, READONLY or PERMANENT)
it.put("apiLevel", it, apiLevel.toInt()) it.defineProperty("apiLevel", apiLevel.toInt(), READONLY or PERMANENT)
it.put("releaseName", it, releaseName) it.defineProperty("releaseName", releaseName, READONLY or PERMANENT)
it.put("platformVersion", it, platformVersion) it.defineProperty("platformVersion", platformVersion, READONLY or PERMANENT)
it.put("internalCodename", it, internalCodename) it.defineProperty("internalCodename", internalCodename, READONLY or PERMANENT)
it.put("releaseDate", it, releaseDate) it.defineProperty("releaseDate", releaseDate, READONLY or PERMANENT)
it.put("releaseTimestamp", it, releaseTimestampLong) it.defineProperty("releaseTimestamp", releaseTimestampLong, READONLY or PERMANENT)
it.defineFunctionProperties(arrayOf("valueOf"), javaClass, READONLY and PERMANENT) it.defineFunctionProperties(arrayOf("valueOf"), javaClass, READONLY or DONTENUM or PERMANENT)
} }
private fun parseTimestamp(s: String): Long { 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? { fun valueOf(cx: Context, thisObj: Scriptable, args: Array<Any?>, funObj: Function): Any? {
return thisObj.prop("apiLevel") return thisObj.prop("apiLevel")
} }
} }
} }
internal object Searcher { internal object Searcher {

View File

@@ -3,6 +3,8 @@ package org.autojs.autojs.runtime.api.augment.util
import android.os.Build import android.os.Build
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.util.RhinoUtils.newNativeObject import org.autojs.autojs.util.RhinoUtils.newNativeObject
import org.mozilla.javascript.ScriptableObject.PERMANENT
import org.mozilla.javascript.ScriptableObject.READONLY
object VersionCodesInfo { object VersionCodesInfo {
@@ -55,7 +57,7 @@ object VersionCodesInfo {
for ((versionCode, infoList) in raw) { for ((versionCode, infoList) in raw) {
val (releaseName, internalCodename, platformVersion, apiLevel, releaseDate) = infoList val (releaseName, internalCodename, platformVersion, apiLevel, releaseDate) = infoList
val info = VersionCodes.Info(versionCode, releaseName, internalCodename, platformVersion, apiLevel, releaseDate) 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 list += info
} }
} }

View File

@@ -217,7 +217,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener, LayoutInsp
} }
private void applyComponentInformation() { private void applyComponentInformation() {
if (WrappedShizuku.isOperational() && WrappedShizuku.service != null) { if (WrappedShizuku.INSTANCE.isOperational() && WrappedShizuku.service != null) {
try { try {
mRunningPackage = WrappedShizuku.service.currentPackage(); mRunningPackage = WrappedShizuku.service.currentPackage();
mRunningActivity = WrappedShizuku.service.currentActivity(); mRunningActivity = WrappedShizuku.service.currentActivity();

View File

@@ -127,7 +127,7 @@ object RhinoUtils {
fun callFunction(scriptRuntime: ScriptRuntime?, obj: Scriptable, name: String, paramsToFunction: Array<Any?>): Any? { fun callFunction(scriptRuntime: ScriptRuntime?, obj: Scriptable, name: String, paramsToFunction: Array<Any?>): Any? {
val property = obj.prop(name) val property = obj.prop(name)
if (property == NOT_FOUND) throw IllegalArgumentException("Property $name not found on $obj") 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) return callFunction(scriptRuntime, property, obj, obj, paramsToFunction)
} }

View File

@@ -1,5 +1,5 @@
#Thu Oct 02 17:27:13 CST 2025 #Sun Oct 05 13:27:08 CST 2025
BUILD_TIME=1759397233140 BUILD_TIME=1759642028837
COMPILE_SDK_VERSION=36 COMPILE_SDK_VERSION=36
IMAGE_QUANT_CMAKE_VERSION=3.22.1 IMAGE_QUANT_CMAKE_VERSION=3.22.1
IMAGE_QUANT_NDK_VERSION=26.1.10909125 IMAGE_QUANT_NDK_VERSION=26.1.10909125
@@ -27,6 +27,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
TARGET_SDK_VERSION=36 TARGET_SDK_VERSION=36
TARGET_SDK_VERSION_INRT=29 TARGET_SDK_VERSION_INRT=29
VERSION_BUILD=3395 VERSION_BUILD=3404
VERSION_NAME=6.7.0 Alpha6 VERSION_NAME=6.7.0 Alpha6
VSCODE_EXT_REQUIRED_VERSION=1.0.8 VSCODE_EXT_REQUIRED_VERSION=1.0.8