6.7.0 - Alpha13 - 选择器支持正则表达式标志 (i, m, s, u); 等价系列及包含系列选择器支持正则表达式参数
This commit is contained in:
@@ -23,6 +23,8 @@
|
||||
"UiObject#isShifted 方法, 用于检测控件位置变化",
|
||||
"crash 全局方法, 用于测试崩溃报告页面",
|
||||
"structuredClone 全局方法, 用于深拷贝 JavaScript 对象 (参阅 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/structuredClone))",
|
||||
"等价系列选择器 (UiSelector#id/text/...) 及包含系列选择器 (UiSelector#xxxContains) 支持正则表达式参数",
|
||||
"选择器的正则表达式参数支持使用标志 (i, m, s, u)",
|
||||
"设置页面增加 \"Java 原始类型包装\" 设置选项 _[`issue #435`](http://issues.autojs6.com/435)_",
|
||||
"设置页面增加 \"定时任务调度引擎\" 设置选项, 支持 AlarmManager/WorkManager/JobScheduler _[`issue #457`](http://issues.autojs6.com/457)_ _[`issue #388`](http://issues.autojs6.com/388)_ _[`issue #163`](http://issues.autojs6.com/163)_ _[`issue #53`](http://issues.autojs6.com/53)_ _[`issue #21`](http://issues.autojs6.com/21)_",
|
||||
"设置页面增加 \"应用启动器图标\" 设置选项, 支持自适应图标/透明背景图标 _[`issue #405`](http://issues.autojs6.com/405)_",
|
||||
|
||||
@@ -48,7 +48,6 @@ import org.autojs.autojs.runtime.exception.ScriptInterruptedException
|
||||
import org.autojs.autojs.util.App
|
||||
import org.autojs.autojs.util.RhinoUtils
|
||||
import org.autojs.autojs.util.RhinoUtils.isMainThread
|
||||
import org.autojs.autojs.util.StringUtils.convertRegex
|
||||
import org.autojs.autojs.util.StringUtils.str
|
||||
import org.autojs.autojs6.R
|
||||
import org.mozilla.javascript.BaseFunction
|
||||
@@ -83,7 +82,10 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
}
|
||||
|
||||
@ScriptInterface
|
||||
fun id(str: String) = also { addFilter(IdFilter.equals(str)) }
|
||||
fun id(s: String) = also { addFilter(IdFilter.equals(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun id(regex: NativeRegExp) = also { addFilter(IdFilter.equals(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun idStartsWith(prefix: String) = also { addFilter(IdFilter.startsWith(prefix)) }
|
||||
@@ -92,28 +94,34 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
fun idEndsWith(suffix: String) = also { addFilter(IdFilter.endsWith(suffix)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun idContains(str: String) = also { addFilter(IdFilter.contains(str)) }
|
||||
fun idContains(s: String) = also { addFilter(IdFilter.contains(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("idMatch(regex)"))
|
||||
fun idMatches(regex: String) = also { addFilter(IdFilter.matches(convertRegex(regex))) }
|
||||
fun idContains(regex: NativeRegExp) = also { addFilter(IdFilter.contains(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("idMatch(s)"))
|
||||
fun idMatches(s: String) = also { addFilter(IdFilter.matches(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("idMatch(regex)"))
|
||||
fun idMatches(regex: NativeRegExp) = idMatches(regex.toString())
|
||||
fun idMatches(regex: NativeRegExp) = also { addFilter(IdFilter.matches(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun idMatch(regex: String) = also { addFilter(IdFilter.match(regex)) }
|
||||
fun idMatch(s: String) = also { addFilter(IdFilter.match(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun idMatch(regex: NativeRegExp) = idMatch(convertRegex(regex.toString()))
|
||||
fun idMatch(regex: NativeRegExp) = also { addFilter(IdFilter.match(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun idHex(str: String) = also { addFilter(IdHexFilter.equals(str)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun text(str: String) = also { addFilter(TextFilter.equals(str)) }
|
||||
fun text(s: String) = also { addFilter(TextFilter.equals(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun text(regex: NativeRegExp) = also { addFilter(TextFilter.equals(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun textStartsWith(prefix: String) = also { addFilter(TextFilter.startsWith(prefix)) }
|
||||
@@ -122,25 +130,31 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
fun textEndsWith(suffix: String) = also { addFilter(TextFilter.endsWith(suffix)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun textContains(str: String) = also { addFilter(TextFilter.contains(str)) }
|
||||
fun textContains(s: String) = also { addFilter(TextFilter.contains(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("textMatch(regex)"))
|
||||
fun textMatches(regex: String) = also { addFilter(TextFilter.matches(convertRegex(regex))) }
|
||||
fun textContains(regex: NativeRegExp) = also { addFilter(TextFilter.contains(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("textMatch(s)"))
|
||||
fun textMatches(s: String) = also { addFilter(TextFilter.matches(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("textMatch(regex)"))
|
||||
fun textMatches(regex: NativeRegExp) = textMatches(regex.toString())
|
||||
fun textMatches(regex: NativeRegExp) = also { addFilter(TextFilter.matches(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun textMatch(regex: String) = also { addFilter(TextFilter.match(regex)) }
|
||||
fun textMatch(s: String) = also { addFilter(TextFilter.match(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun textMatch(regex: NativeRegExp) = textMatch(convertRegex(regex.toString()))
|
||||
fun textMatch(regex: NativeRegExp) = also { addFilter(TextFilter.match(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun desc(str: String) = also { addFilter(DescFilter.equals(str)) }
|
||||
fun desc(s: String) = also { addFilter(DescFilter.equals(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun desc(regex: NativeRegExp) = also { addFilter(DescFilter.equals(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun descStartsWith(prefix: String) = also { addFilter(DescFilter.startsWith(prefix)) }
|
||||
@@ -149,25 +163,31 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
fun descEndsWith(suffix: String) = also { addFilter(DescFilter.endsWith(suffix)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun descContains(str: String) = also { addFilter(DescFilter.contains(str)) }
|
||||
fun descContains(s: String) = also { addFilter(DescFilter.contains(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun descContains(regex: NativeRegExp) = also { addFilter(DescFilter.contains(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("descMatch(regex)"))
|
||||
fun descMatches(regex: String) = also { addFilter(DescFilter.matches(convertRegex(regex))) }
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("descMatch(s)"))
|
||||
fun descMatches(s: String) = also { addFilter(DescFilter.matches(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("descMatch(regex)"))
|
||||
fun descMatches(regex: NativeRegExp) = descMatches(regex.toString())
|
||||
fun descMatches(regex: NativeRegExp) = also { addFilter(DescFilter.matches(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun descMatch(regex: String) = also { addFilter(DescFilter.match(regex)) }
|
||||
fun descMatch(s: String) = also { addFilter(DescFilter.match(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun descMatch(regex: NativeRegExp) = descMatch(convertRegex(regex.toString()))
|
||||
fun descMatch(regex: NativeRegExp) = also { addFilter(DescFilter.match(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun content(str: String) = also { addFilter(ContentFilter.equals(str)) }
|
||||
fun content(s: String) = also { addFilter(ContentFilter.equals(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun content(regex: NativeRegExp) = also { addFilter(ContentFilter.equals(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun contentStartsWith(prefix: String) = also { addFilter(ContentFilter.startsWith(prefix)) }
|
||||
@@ -176,25 +196,31 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
fun contentEndsWith(suffix: String) = also { addFilter(ContentFilter.endsWith(suffix)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun contentContains(str: String) = also { addFilter(ContentFilter.contains(str)) }
|
||||
fun contentContains(s: String) = also { addFilter(ContentFilter.contains(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun contentContains(regex: NativeRegExp) = also { addFilter(ContentFilter.contains(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("contentMatch(regex)"))
|
||||
fun contentMatches(regex: String) = also { addFilter(ContentFilter.matches(convertRegex(regex))) }
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("contentMatch(s)"))
|
||||
fun contentMatches(s: String) = also { addFilter(ContentFilter.matches(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("contentMatch(regex)"))
|
||||
fun contentMatches(regex: NativeRegExp) = contentMatches(regex.toString())
|
||||
fun contentMatches(regex: NativeRegExp) = also { addFilter(ContentFilter.matches(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun contentMatch(regex: String) = also { addFilter(ContentFilter.match(regex)) }
|
||||
fun contentMatch(s: String) = also { addFilter(ContentFilter.match(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun contentMatch(regex: NativeRegExp) = contentMatch(convertRegex(regex.toString()))
|
||||
fun contentMatch(regex: NativeRegExp) = also { addFilter(ContentFilter.match(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun className(str: String) = also { addFilter(ClassNameFilter.equals(str)) }
|
||||
fun className(s: String) = also { addFilter(ClassNameFilter.equals(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun className(regex: NativeRegExp) = also { addFilter(ClassNameFilter.equals(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun classNameStartsWith(prefix: String) = also { addFilter(ClassNameFilter.startsWith(prefix)) }
|
||||
@@ -203,25 +229,31 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
fun classNameEndsWith(suffix: String) = also { addFilter(ClassNameFilter.endsWith(suffix)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun classNameContains(str: String) = also { addFilter(ClassNameFilter.contains(str)) }
|
||||
fun classNameContains(s: String) = also { addFilter(ClassNameFilter.contains(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("classNameMatch(regex)"))
|
||||
fun classNameMatches(regex: String) = also { addFilter(ClassNameFilter.matches(convertRegex(regex))) }
|
||||
fun classNameContains(regex: NativeRegExp) = also { addFilter(ClassNameFilter.contains(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("classNameMatch(s)"))
|
||||
fun classNameMatches(s: String) = also { addFilter(ClassNameFilter.matches(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("classNameMatch(regex)"))
|
||||
fun classNameMatches(regex: NativeRegExp) = classNameMatches(regex.toString())
|
||||
fun classNameMatches(regex: NativeRegExp) = also { addFilter(ClassNameFilter.matches(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun classNameMatch(regex: String) = also { addFilter(ClassNameFilter.match(regex)) }
|
||||
fun classNameMatch(s: String) = also { addFilter(ClassNameFilter.match(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun classNameMatch(regex: NativeRegExp) = classNameMatch(convertRegex(regex.toString()))
|
||||
fun classNameMatch(regex: NativeRegExp) = also { addFilter(ClassNameFilter.match(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun packageName(str: String) = also { addFilter(PackageNameFilter.equals(str)) }
|
||||
fun packageName(s: String) = also { addFilter(PackageNameFilter.equals(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun packageName(regex: NativeRegExp) = also { addFilter(PackageNameFilter.equals(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun packageName(app: App) = also { addFilter(PackageNameFilter.equals(app.packageName)) }
|
||||
@@ -233,22 +265,25 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
fun packageNameEndsWith(suffix: String) = also { addFilter(PackageNameFilter.endsWith(suffix)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun packageNameContains(str: String) = also { addFilter(PackageNameFilter.contains(str)) }
|
||||
fun packageNameContains(s: String) = also { addFilter(PackageNameFilter.contains(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun packageNameContains(regex: NativeRegExp) = also { addFilter(PackageNameFilter.contains(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("packageNameMatch(regex)"))
|
||||
fun packageNameMatches(regex: String) = also { addFilter(PackageNameFilter.matches(convertRegex(regex))) }
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("packageNameMatch(s)"))
|
||||
fun packageNameMatches(s: String) = also { addFilter(PackageNameFilter.matches(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Deprecated in Java", ReplaceWith("packageNameMatch(regex)"))
|
||||
fun packageNameMatches(regex: NativeRegExp) = packageNameMatches(regex.toString())
|
||||
fun packageNameMatches(regex: NativeRegExp) = also { addFilter(PackageNameFilter.matches(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun packageNameMatch(regex: String) = also { addFilter(PackageNameFilter.match(regex)) }
|
||||
fun packageNameMatch(s: String) = also { addFilter(PackageNameFilter.match(s)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun packageNameMatch(regex: NativeRegExp) = packageNameMatch(convertRegex(regex.toString()))
|
||||
fun packageNameMatch(regex: NativeRegExp) = also { addFilter(PackageNameFilter.match(regex)) }
|
||||
|
||||
@ScriptInterface
|
||||
fun currentApp(app: App) = also { addFilter(AppFilter(app)) }
|
||||
@@ -1019,7 +1054,7 @@ open class UiSelector : UiObjectActions, StringReadable {
|
||||
.invoke(tmp)
|
||||
is String -> tmp::class.java
|
||||
.getMethod(key, cString)
|
||||
.invoke(tmp, value.toString())
|
||||
.invoke(tmp, value)
|
||||
is NativeRegExp -> tmp::class.java
|
||||
.getMethod(key, cNativeRegExp)
|
||||
.invoke(tmp, value)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
object ClassNameFilter {
|
||||
|
||||
@@ -59,7 +60,11 @@ object ClassNameFilter {
|
||||
else -> extendedClassNameMap[text] ?: "android.widget.$text"
|
||||
}.let { StringEqualsFilter(it, CLASS_NAME_GETTER) }
|
||||
|
||||
fun contains(str: String) = StringContainsFilter(str, CLASS_NAME_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(regex: NativeRegExp) = StringEqualsFilter(regex, CLASS_NAME_GETTER)
|
||||
|
||||
fun contains(s: String) = StringContainsFilter(s, CLASS_NAME_GETTER)
|
||||
fun contains(regex: NativeRegExp) = StringContainsFilter(regex, CLASS_NAME_GETTER)
|
||||
|
||||
fun startsWith(prefix: String) = when (prefix.contains(".")) {
|
||||
true -> prefix
|
||||
@@ -68,8 +73,10 @@ object ClassNameFilter {
|
||||
|
||||
fun endsWith(suffix: String) = StringEndsWithFilter(suffix, CLASS_NAME_GETTER)
|
||||
|
||||
fun matches(regex: String) = StringMatchesFilter(regex, CLASS_NAME_GETTER)
|
||||
fun matches(s: String) = StringMatchesFilter(s, CLASS_NAME_GETTER)
|
||||
fun matches(regex: NativeRegExp) = StringMatchesFilter(regex, CLASS_NAME_GETTER)
|
||||
|
||||
fun match(regex: String) = StringMatchFilter(regex, CLASS_NAME_GETTER)
|
||||
fun match(s: String) = StringMatchFilter(s, CLASS_NAME_GETTER)
|
||||
fun match(regex: NativeRegExp) = StringMatchFilter(regex, CLASS_NAME_GETTER)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by SuperMonster003 on Jun 10, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
object ContentFilter {
|
||||
|
||||
@@ -15,16 +17,23 @@ object ContentFilter {
|
||||
|
||||
}
|
||||
|
||||
fun equals(text: String) = StringListEqualsFilter(text, CONTENT_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(s: String) = StringListEqualsFilter(s, CONTENT_GETTER)
|
||||
|
||||
fun contains(str: String) = StringListContainsFilter(str, CONTENT_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(regex: NativeRegExp) = StringListEqualsFilter(regex, CONTENT_GETTER)
|
||||
|
||||
fun contains(s: String) = StringListContainsFilter(s, CONTENT_GETTER)
|
||||
fun contains(regex: NativeRegExp) = StringListContainsFilter(regex, CONTENT_GETTER)
|
||||
|
||||
fun startsWith(prefix: String) = StringListStartsWithFilter(prefix, CONTENT_GETTER)
|
||||
|
||||
fun endsWith(suffix: String) = StringListEndsWithFilter(suffix, CONTENT_GETTER)
|
||||
|
||||
fun matches(regex: String) = StringListMatchesFilter(regex, CONTENT_GETTER)
|
||||
fun matches(s: String) = StringListMatchesFilter(s, CONTENT_GETTER)
|
||||
fun matches(regex: NativeRegExp) = StringListMatchesFilter(regex, CONTENT_GETTER)
|
||||
|
||||
fun match(regex: String) = StringListMatchFilter(regex, CONTENT_GETTER)
|
||||
fun match(s: String) = StringListMatchFilter(s, CONTENT_GETTER)
|
||||
fun match(regex: NativeRegExp) = StringListMatchFilter(regex, CONTENT_GETTER)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
object DescFilter {
|
||||
|
||||
@@ -16,16 +17,23 @@ object DescFilter {
|
||||
|
||||
}
|
||||
|
||||
fun equals(text: String) = StringEqualsFilter(text, DESC_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(s: String) = StringEqualsFilter(s, DESC_GETTER)
|
||||
|
||||
fun contains(str: String) = StringContainsFilter(str, DESC_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(regex: NativeRegExp) = StringEqualsFilter(regex, DESC_GETTER)
|
||||
|
||||
fun contains(s: String) = StringContainsFilter(s, DESC_GETTER)
|
||||
fun contains(regex: NativeRegExp) = StringContainsFilter(regex, DESC_GETTER)
|
||||
|
||||
fun startsWith(prefix: String) = StringStartsWithFilter(prefix, DESC_GETTER)
|
||||
|
||||
fun endsWith(suffix: String) = StringEndsWithFilter(suffix, DESC_GETTER)
|
||||
|
||||
fun matches(regex: String) = StringMatchesFilter(regex, DESC_GETTER)
|
||||
fun matches(s: String) = StringMatchesFilter(s, DESC_GETTER)
|
||||
fun matches(regex: NativeRegExp) = StringMatchesFilter(regex, DESC_GETTER)
|
||||
|
||||
fun match(regex: String) = StringMatchFilter(regex, DESC_GETTER)
|
||||
fun match(s: String) = StringMatchFilter(s, DESC_GETTER)
|
||||
fun match(regex: NativeRegExp) = StringMatchFilter(regex, DESC_GETTER)
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.accessibility.UiSelector.Companion.ID_IDENTIFIER
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
object IdFilter {
|
||||
|
||||
@@ -18,17 +19,27 @@ object IdFilter {
|
||||
}
|
||||
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(str: String) = when (str.contains(ID_IDENTIFIER)) {
|
||||
true -> StringEqualsFilter(str, ID_GETTER)
|
||||
fun equals(s: String) = when (s.contains(ID_IDENTIFIER)) {
|
||||
true -> StringEqualsFilter(s, ID_GETTER)
|
||||
else -> object : Filter {
|
||||
override fun filter(node: UiObject) = node.id()?.let { id ->
|
||||
when (id.contains(ID_IDENTIFIER)) {
|
||||
true -> id.split(ID_IDENTIFIER).last() == str
|
||||
else -> id == str
|
||||
true -> id.split(ID_IDENTIFIER).last() == s
|
||||
else -> id == s
|
||||
}
|
||||
} ?: false
|
||||
|
||||
override fun toString() = "id(\"$str\")"
|
||||
override fun toString() = "${ID_GETTER}(\"$s\")"
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(regex: NativeRegExp): Filter {
|
||||
return object : StringMatchesFilter(regex, ID_GETTER) {
|
||||
override fun toString(): String {
|
||||
val literal = JsRegexUtils.formatAsJsRegexLiteral(regex.toString())
|
||||
return "${ID_GETTER}($literal)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,16 +53,19 @@ object IdFilter {
|
||||
}
|
||||
} ?: false
|
||||
|
||||
override fun toString() = "idStartsWith(\"$prefix\")"
|
||||
override fun toString() = "${ID_GETTER}StartsWith(\"$prefix\")"
|
||||
}
|
||||
}
|
||||
|
||||
fun endsWith(suffix: String) = StringEndsWithFilter(suffix, ID_GETTER)
|
||||
|
||||
fun contains(contains: String) = StringContainsFilter(contains, ID_GETTER)
|
||||
fun contains(s: String) = StringContainsFilter(s, ID_GETTER)
|
||||
fun contains(regex: NativeRegExp) = StringContainsFilter(regex, ID_GETTER)
|
||||
|
||||
fun matches(regex: String) = StringMatchesFilter(regex, ID_GETTER)
|
||||
fun matches(s: String) = StringMatchesFilter(s, ID_GETTER)
|
||||
fun matches(regex: NativeRegExp) = StringMatchesFilter(regex, ID_GETTER)
|
||||
|
||||
fun match(regex: String) = StringMatchFilter(regex, ID_GETTER)
|
||||
fun match(s: String) = StringMatchFilter(s, ID_GETTER)
|
||||
fun match(regex: NativeRegExp) = StringMatchFilter(regex, ID_GETTER)
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
internal object JsRegexUtils {
|
||||
|
||||
// Compile JavaScript regex literal "/pattern/flags" or plain pattern string to Kotlin Regex.
|
||||
// zh-CN: 将 JavaScript 正则字面量 "/pattern/flags" 或普通模式字符串编译为 Kotlin 的 Regex.
|
||||
fun compileJsOrPlainRegex(input: String): Regex {
|
||||
parseJsRegexLiteral(input)?.let { (pattern, flags) ->
|
||||
val javaFlags = toJavaPatternFlags(flags)
|
||||
return Pattern.compile(pattern, javaFlags).toRegex()
|
||||
}
|
||||
return input.toRegex()
|
||||
}
|
||||
|
||||
// Parse JavaScript regex literal by scanning delimiter '/' while respecting escapes and character classes.
|
||||
// zh-CN: 通过扫描分隔符 '/' 解析 JavaScript 正则字面量, 同时处理转义与字符类.
|
||||
fun parseJsRegexLiteral(input: String): Pair<String, String>? {
|
||||
if (input.length < 2 || input[0] != '/') return null
|
||||
|
||||
var escaped = false
|
||||
var inCharClass = false
|
||||
|
||||
for (i in 1 until input.length) {
|
||||
val ch = input[i]
|
||||
when {
|
||||
escaped -> escaped = false
|
||||
ch == '\\' -> escaped = true
|
||||
ch == '[' -> inCharClass = true
|
||||
ch == ']' && inCharClass -> inCharClass = false
|
||||
ch == '/' && !inCharClass -> {
|
||||
val pattern = input.substring(1, i)
|
||||
val flags = input.substring(i + 1)
|
||||
return pattern to flags
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// Map JavaScript flags to java.util.regex.Pattern flags. Unknown flags are ignored.
|
||||
// zh-CN: 将 JavaScript flags 映射到 java.util.regex.Pattern flags, 未知 flags 将被忽略.
|
||||
fun toJavaPatternFlags(flags: String): Int {
|
||||
var f = 0
|
||||
if (flags.contains('i')) f = f or Pattern.CASE_INSENSITIVE
|
||||
if (flags.contains('m')) f = f or Pattern.MULTILINE
|
||||
if (flags.contains('s')) f = f or Pattern.DOTALL
|
||||
|
||||
// Java "u" is not identical to JavaScript "u", but enabling Unicode-aware behavior is usually closer.
|
||||
// zh-CN: Java 的 "u" 与 JavaScript 的 "u" 并不完全等价, 但开启 Unicode 相关行为通常更接近预期.
|
||||
if (flags.contains('u')) {
|
||||
f = f or Pattern.UNICODE_CASE
|
||||
f = f or Pattern.UNICODE_CHARACTER_CLASS
|
||||
}
|
||||
|
||||
// JavaScript "g/y" affects iteration/sticky behavior rather than "does it match", so it is ignored here.
|
||||
// zh-CN: JavaScript 的 "g/y" 影响的是迭代/粘连行为, 而不是 "是否匹配", 因此这里忽略.
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// Format input regex as a JavaScript regex literal string for debugging display.
|
||||
// zh-CN: 将输入正则格式化为 JavaScript 正则字面量字符串, 用于调试展示.
|
||||
fun formatAsJsRegexLiteral(input: String): String {
|
||||
val (pattern, flags) = parseJsRegexLiteral(input) ?: (input to "")
|
||||
val safePattern = when (pattern.isEmpty()) {
|
||||
true -> "(?:)"
|
||||
else -> pattern.toRegex().toString().replace("/", "\\/")
|
||||
}
|
||||
return "/$safePattern/$flags"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
object PackageNameFilter {
|
||||
|
||||
@@ -16,16 +17,23 @@ object PackageNameFilter {
|
||||
|
||||
}
|
||||
|
||||
fun equals(text: String) = StringEqualsFilter(text, PACKAGE_NAME_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(s: String) = StringEqualsFilter(s, PACKAGE_NAME_GETTER)
|
||||
|
||||
fun contains(str: String) = StringContainsFilter(str, PACKAGE_NAME_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(regex: NativeRegExp) = StringEqualsFilter(regex, PACKAGE_NAME_GETTER)
|
||||
|
||||
fun contains(s: String) = StringContainsFilter(s, PACKAGE_NAME_GETTER)
|
||||
fun contains(regex: NativeRegExp) = StringContainsFilter(regex, PACKAGE_NAME_GETTER)
|
||||
|
||||
fun startsWith(prefix: String) = StringStartsWithFilter(prefix, PACKAGE_NAME_GETTER)
|
||||
|
||||
fun endsWith(suffix: String) = StringEndsWithFilter(suffix, PACKAGE_NAME_GETTER)
|
||||
|
||||
fun matches(regex: String) = StringMatchesFilter(regex, PACKAGE_NAME_GETTER)
|
||||
fun matches(s: String) = StringMatchesFilter(s, PACKAGE_NAME_GETTER)
|
||||
fun matches(regex: NativeRegExp) = StringMatchesFilter(regex, PACKAGE_NAME_GETTER)
|
||||
|
||||
fun match(regex: String) = StringMatchFilter(regex, PACKAGE_NAME_GETTER)
|
||||
fun match(s: String) = StringMatchFilter(s, PACKAGE_NAME_GETTER)
|
||||
fun match(regex: NativeRegExp) = StringMatchFilter(regex, PACKAGE_NAME_GETTER)
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.util.StringUtils.uppercaseFirstChar
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by SuperMonster003 on Dec 27, 2025.
|
||||
*/
|
||||
abstract class RegexFilter(s: String, keyGetter: KeyGetter) : Filter {
|
||||
|
||||
open val actionName: String = ""
|
||||
|
||||
protected val input = s
|
||||
protected val keyGetter = keyGetter
|
||||
|
||||
protected var isRegexSource = false
|
||||
private set
|
||||
|
||||
// Compile regex only once to avoid repeated compilation during tree traversal.
|
||||
// zh-CN: 仅编译一次正则, 避免在遍历节点树时重复编译带来的开销.
|
||||
protected val compiledRegex by lazy(LazyThreadSafetyMode.NONE) { JsRegexUtils.compileJsOrPlainRegex(input) }
|
||||
|
||||
constructor(regex: NativeRegExp, keyGetter: KeyGetter) : this(regex.toString(), keyGetter) {
|
||||
isRegexSource = true
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val literal = when {
|
||||
isRegexSource -> JsRegexUtils.formatAsJsRegexLiteral(input)
|
||||
else -> "\"$input\""
|
||||
}
|
||||
return "${keyGetter}${actionName.uppercaseFirstChar()}($literal)"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.util.StringUtils.uppercaseFirstChar
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by SuperMonster003 on Dec 27, 2025.
|
||||
*/
|
||||
abstract class RegexListFilter(s: String, keysGetter: KeysGetter) : Filter {
|
||||
|
||||
open val actionName: String = ""
|
||||
|
||||
protected val input = s
|
||||
protected val keysGetter = keysGetter
|
||||
|
||||
protected var isRegexSource = false
|
||||
private set
|
||||
|
||||
// Compile regex only once to avoid repeated compilation during tree traversal.
|
||||
// zh-CN: 仅编译一次正则, 避免在遍历节点树时重复编译带来的开销.
|
||||
protected val compiledRegex by lazy(LazyThreadSafetyMode.NONE) { JsRegexUtils.compileJsOrPlainRegex(input) }
|
||||
|
||||
constructor(regex: NativeRegExp, keysGetter: KeysGetter) : this(regex.toString(), keysGetter) {
|
||||
isRegexSource = true
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val literal = when {
|
||||
isRegexSource -> JsRegexUtils.formatAsJsRegexLiteral(input)
|
||||
else -> "\"$input\""
|
||||
}
|
||||
return "${keysGetter}${actionName.uppercaseFirstChar()}($literal)"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,19 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringContainsFilter internal constructor(private val mContains: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
class StringContainsFilter : RegexFilter {
|
||||
|
||||
override fun filter(node: UiObject) = mKeyGetter.getKey(node)?.contains(mContains) ?: false
|
||||
override val actionName = "contains"
|
||||
|
||||
override fun toString() = "${mKeyGetter}Contains(\"$mContains\")"
|
||||
constructor(s: String, keyGetter: KeyGetter) : super(s, keyGetter)
|
||||
constructor(regex: NativeRegExp, keyGetter: KeyGetter) : super(regex, keyGetter)
|
||||
|
||||
override fun filter(node: UiObject) = keyGetter.getKey(node)?.contains(compiledRegex) == true
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringEqualsFilter(private val mValue: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
class StringEqualsFilter : RegexFilter {
|
||||
|
||||
override fun filter(node: UiObject) = mKeyGetter.getKey(node)?.let { it == mValue } ?: false
|
||||
constructor(s: String, keyGetter: KeyGetter) : super(s, keyGetter)
|
||||
constructor(regex: NativeRegExp, keyGetter: KeyGetter) : super(regex, keyGetter)
|
||||
|
||||
override fun toString() = "$mKeyGetter(\"$mValue\")"
|
||||
override fun filter(node: UiObject) = when {
|
||||
isRegexSource -> keyGetter.getKey(node)?.matches(compiledRegex) == true
|
||||
else -> keyGetter.getKey(node)?.contentEquals(input) == true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by SuperMonster003 on Jun 10, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringListContainsFilter internal constructor(private val mContains: String, private val mKeysGetter: KeysGetter) : Filter {
|
||||
class StringListContainsFilter : RegexListFilter {
|
||||
|
||||
override fun filter(node: UiObject) = mKeysGetter.getKeys(node).any { it?.contains(mContains) ?: false }
|
||||
override val actionName = "contains"
|
||||
|
||||
override fun toString() = "${mKeysGetter}Contains(\"$mContains\")"
|
||||
constructor(s: String, keysGetter: KeysGetter) : super(s, keysGetter)
|
||||
constructor(regex: NativeRegExp, keysGetter: KeysGetter) : super(regex, keysGetter)
|
||||
|
||||
override fun filter(node: UiObject) = keysGetter.getKeys(node).any {
|
||||
it?.contains(compiledRegex) == true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by SuperMonster003 on Jun 10, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringListEqualsFilter(private val mValue: String, private val mKeysGetter: KeysGetter) : Filter {
|
||||
class StringListEqualsFilter : RegexListFilter {
|
||||
|
||||
override fun filter(node: UiObject) = mKeysGetter.getKeys(node).any { it.contentEquals(mValue) }
|
||||
|
||||
override fun toString() = "$mKeysGetter(\"$mValue\")"
|
||||
constructor(s: String, keysGetter: KeysGetter) : super(s, keysGetter)
|
||||
constructor(regex: NativeRegExp, keysGetter: KeysGetter) : super(regex, keysGetter)
|
||||
|
||||
override fun filter(node: UiObject) = when {
|
||||
isRegexSource -> keysGetter.getKeys(node).any {
|
||||
it?.matches(compiledRegex) == true
|
||||
}
|
||||
else -> keysGetter.getKeys(node).any {
|
||||
it?.contentEquals(input) == true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,21 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by SuperMonster003 on Oct 17, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringListMatchFilter internal constructor(private val mRegex: String, private val mKeysGetter: KeysGetter) : Filter {
|
||||
class StringListMatchFilter : RegexListFilter {
|
||||
|
||||
// @Hint by SuperMonster003 on Oct 17, 2022.
|
||||
// ! Similar to JavaScript "String.prototype.match"
|
||||
// ! which returns the result of matching a string against a regular expression.
|
||||
// ! https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
|
||||
// ! https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/contains-match-in.html
|
||||
// ! https://stackoverflow.com/questions/21883629/difference-in-results-between-java-matches-vs-javascript-match
|
||||
// ! zh-CN:
|
||||
// ! 与 JavaScript 的方法 "String.prototype.match" 类似,
|
||||
// ! 它返回字符串与正则表达式匹配的结果.
|
||||
// ! 参考链接见上.
|
||||
override fun filter(node: UiObject) = mKeysGetter.getKeys(node).any {
|
||||
it ?: return@any false
|
||||
val prefix = "/"
|
||||
val suffix = "/i"
|
||||
if (mRegex.startsWith(prefix) && mRegex.endsWith(suffix)) {
|
||||
mRegex
|
||||
.slice(prefix.length until mRegex.length - suffix.length)
|
||||
.toRegex(RegexOption.IGNORE_CASE)
|
||||
.containsMatchIn(it)
|
||||
} else {
|
||||
mRegex.toRegex().containsMatchIn(it)
|
||||
}
|
||||
override val actionName = "match"
|
||||
|
||||
constructor(s: String, keysGetter: KeysGetter) : super(s, keysGetter)
|
||||
constructor(regex: NativeRegExp, keysGetter: KeysGetter) : super(regex, keysGetter)
|
||||
|
||||
override fun filter(node: UiObject) = keysGetter.getKeys(node).any {
|
||||
it?.contains(compiledRegex) == true
|
||||
}
|
||||
|
||||
override fun toString() = "${mKeysGetter}Match(\"$mRegex\")"
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by SuperMonster003 on Jun 10, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringListMatchesFilter internal constructor(private val mRegex: String, private val mKeysGetter: KeysGetter) : Filter {
|
||||
class StringListMatchesFilter : RegexListFilter {
|
||||
|
||||
// @Hint by SuperMonster003 on Oct 17, 2022.
|
||||
// ! Kotlin method "CharSequence.matches(regex: Regex): Boolean"
|
||||
// ! indicates whether the regular expression matches the ENTIRE input (not partial input).
|
||||
// ! https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/matches.html
|
||||
// ! https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/matches.html
|
||||
// ! https://stackoverflow.com/questions/21883629/difference-in-results-between-java-matches-vs-javascript-match
|
||||
// ! zh-CN:
|
||||
// ! Kotlin 的方法 "CharSequence.matches(regex: Regex): Boolean"
|
||||
// ! 表示正则表达式是否完全匹配输入 (注意是完全而非部分匹配).
|
||||
// ! 参考链接见上.
|
||||
override fun filter(node: UiObject) = mKeysGetter.getKeys(node).any { it?.matches(mRegex.toRegex()) ?: false }
|
||||
override val actionName = "matches"
|
||||
|
||||
override fun toString() = "${mKeysGetter}Matches(\"$mRegex\")"
|
||||
constructor(s: String, keysGetter: KeysGetter) : super(s, keysGetter)
|
||||
constructor(regex: NativeRegExp, keysGetter: KeysGetter) : super(regex, keysGetter)
|
||||
|
||||
override fun filter(node: UiObject) = keysGetter.getKeys(node).any {
|
||||
it?.matches(compiledRegex) == true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,31 +1,19 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringMatchFilter internal constructor(private val mRegex: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
class StringMatchFilter : RegexFilter {
|
||||
|
||||
// @Hint by SuperMonster003 on Oct 17, 2022.
|
||||
// ! Similar to JavaScript "String.prototype.match"
|
||||
// ! which returns the result of matching a string against a regular expression.
|
||||
// ! https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
|
||||
// ! https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/contains-match-in.html
|
||||
// ! https://stackoverflow.com/questions/21883629/difference-in-results-between-java-matches-vs-javascript-match
|
||||
// ! zh-CN:
|
||||
// ! 与 JavaScript 的方法 "String.prototype.match" 类似,
|
||||
// ! 它返回字符串与正则表达式匹配的结果.
|
||||
// ! 参考链接见上.
|
||||
override fun filter(node: UiObject) = mKeyGetter.getKey(node)?.contains(mRegex.toRegex()) ?: false
|
||||
override val actionName = "match"
|
||||
|
||||
override fun toString(): String {
|
||||
val regexStr = when (mRegex.isEmpty()) {
|
||||
true -> "(?:)"
|
||||
else -> mRegex.toRegex().toString().replace("/", "\\/")
|
||||
}
|
||||
return "${mKeyGetter}Match(/$regexStr/)"
|
||||
}
|
||||
constructor(s: String, keyGetter: KeyGetter) : super(s, keyGetter)
|
||||
constructor(regex: NativeRegExp, keyGetter: KeyGetter) : super(regex, keyGetter)
|
||||
|
||||
override fun filter(node: UiObject) = keyGetter.getKey(node)?.contains(compiledRegex) == true
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +1,19 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
class StringMatchesFilter internal constructor(private val mRegex: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
open class StringMatchesFilter : RegexFilter {
|
||||
|
||||
// @Hint by SuperMonster003 on Oct 17, 2022.
|
||||
// ! Kotlin method "CharSequence.matches(regex: Regex): Boolean"
|
||||
// ! indicates whether the regular expression matches the ENTIRE input (not partial input).
|
||||
// ! https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/matches.html
|
||||
// ! https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/matches.html
|
||||
// ! https://stackoverflow.com/questions/21883629/difference-in-results-between-java-matches-vs-javascript-match
|
||||
// ! zh-CN:
|
||||
// ! Kotlin 的方法 "CharSequence.matches(regex: Regex): Boolean"
|
||||
// ! 表示正则表达式是否完全匹配输入 (注意是完全而非部分匹配).
|
||||
// ! 参考链接见上.
|
||||
override fun filter(node: UiObject) = mKeyGetter.getKey(node)?.matches(mRegex.toRegex()) ?: false
|
||||
override val actionName = "matches"
|
||||
|
||||
override fun toString(): String {
|
||||
val regexStr = when (mRegex.isEmpty()) {
|
||||
true -> "(?:)"
|
||||
else -> mRegex.toRegex().toString().replace("/", "\\/")
|
||||
}
|
||||
return "${mKeyGetter}Matches(/$regexStr/)"
|
||||
}
|
||||
constructor(s: String, keyGetter: KeyGetter) : super(s, keyGetter)
|
||||
constructor(regex: NativeRegExp, keyGetter: KeyGetter) : super(regex, keyGetter)
|
||||
|
||||
override fun filter(node: UiObject) = keyGetter.getKey(node)?.matches(compiledRegex) == true
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.autojs.autojs.core.automator.filter
|
||||
|
||||
import org.autojs.autojs.core.automator.UiObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
/**
|
||||
* Created by Stardust on Mar 9, 2017.
|
||||
* Modified by SuperMonster003 as of Nov 19, 2022.
|
||||
* Modified by SuperMonster003 as of Dec 27, 2025.
|
||||
*/
|
||||
object TextFilter {
|
||||
|
||||
@@ -16,16 +17,23 @@ object TextFilter {
|
||||
|
||||
}
|
||||
|
||||
fun equals(text: String) = StringEqualsFilter(text, TEXT_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(s: String) = StringEqualsFilter(s, TEXT_GETTER)
|
||||
|
||||
fun contains(str: String) = StringContainsFilter(str, TEXT_GETTER)
|
||||
@Suppress("CovariantEquals")
|
||||
fun equals(regex: NativeRegExp) = StringEqualsFilter(regex, TEXT_GETTER)
|
||||
|
||||
fun contains(s: String) = StringContainsFilter(s, TEXT_GETTER)
|
||||
fun contains(regex: NativeRegExp) = StringContainsFilter(regex, TEXT_GETTER)
|
||||
|
||||
fun startsWith(prefix: String) = StringStartsWithFilter(prefix, TEXT_GETTER)
|
||||
|
||||
fun endsWith(suffix: String) = StringEndsWithFilter(suffix, TEXT_GETTER)
|
||||
|
||||
fun matches(regex: String) = StringMatchesFilter(regex, TEXT_GETTER)
|
||||
fun matches(s: String) = StringMatchesFilter(s, TEXT_GETTER)
|
||||
fun matches(regex: NativeRegExp) = StringMatchesFilter(regex, TEXT_GETTER)
|
||||
|
||||
fun match(regex: String) = StringMatchFilter(regex, TEXT_GETTER)
|
||||
fun match(s: String) = StringMatchFilter(s, TEXT_GETTER)
|
||||
fun match(regex: NativeRegExp) = StringMatchFilter(regex, TEXT_GETTER)
|
||||
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ abstract class Augmentable(private val scriptRuntime: ScriptRuntime? = null) : F
|
||||
open val key: String
|
||||
get() = when {
|
||||
mIsOriginalKeyName -> javaClass.simpleName
|
||||
else -> lowercaseFirstChar(javaClass.simpleName)
|
||||
else -> javaClass.simpleName.lowercaseFirstChar()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,11 +30,11 @@ open class AugmentableProxy(private val scriptRuntime: ScriptRuntime) : Augmenta
|
||||
val setterResult = listOf(
|
||||
when {
|
||||
Regex("^set[A-Z].*").containsMatchIn(key) -> key
|
||||
else -> "set${uppercaseFirstChar(key)}"
|
||||
else -> "set${key.uppercaseFirstChar()}"
|
||||
},
|
||||
when {
|
||||
Regex("^is[A-Z].*").containsMatchIn(key) -> key
|
||||
else -> "is${uppercaseFirstChar(key)}"
|
||||
else -> "is${key.uppercaseFirstChar()}"
|
||||
},
|
||||
).any { setCore(augmented, it, value) }
|
||||
|
||||
@@ -62,8 +62,8 @@ open class AugmentableProxy(private val scriptRuntime: ScriptRuntime) : Augmenta
|
||||
open fun get(augmented: ScriptableObject, key: String): Any? {
|
||||
listOf(
|
||||
key,
|
||||
"get${uppercaseFirstChar(key)}",
|
||||
"is${uppercaseFirstChar(key)}",
|
||||
"get${key.uppercaseFirstChar()}",
|
||||
"is${key.uppercaseFirstChar()}",
|
||||
).forEach {
|
||||
getCore(augmented, it).let { result ->
|
||||
if (result != NOT_FOUND) return result
|
||||
|
||||
@@ -55,7 +55,7 @@ class ColorNativeObject @JvmOverloads constructor(color: Any? = BLACK) : NativeO
|
||||
return when (name) {
|
||||
"equals", StringReadable.KEY -> true
|
||||
in mProxySetterNames -> true
|
||||
in mProxyTowardsNames.map { "to${uppercaseFirstChar(it)}" } -> true
|
||||
in mProxyTowardsNames.map { "to${it.uppercaseFirstChar()}" } -> true
|
||||
else -> super.has(name, start)
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class ColorNativeObject @JvmOverloads constructor(color: Any? = BLACK) : NativeO
|
||||
}
|
||||
else -> {
|
||||
val protoName = when (name) {
|
||||
in mProxyTowardsNames -> "to${uppercaseFirstChar(name)}"
|
||||
in mProxyTowardsNames -> "to${name.uppercaseFirstChar()}"
|
||||
else -> name
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -220,14 +220,14 @@ class Console(scriptRuntime: ScriptRuntime) : AugmentableProxy(scriptRuntime) {
|
||||
@JvmStatic
|
||||
@RhinoRuntimeFunctionInterface
|
||||
fun input(scriptRuntime: ScriptRuntime, args: Array<out Any?>) {
|
||||
val s = "${lowercaseFirstChar(Console::class.java.simpleName)}.${::input.name}"
|
||||
val s = "${Console::class.java.simpleName.lowercaseFirstChar()}.${::input.name}"
|
||||
throw RuntimeException(globalContext.getString(R.string.error_abandoned_method, s))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoRuntimeFunctionInterface
|
||||
fun rawInput(scriptRuntime: ScriptRuntime, args: Array<out Any?>) {
|
||||
val s = "${lowercaseFirstChar(Console::class.java.simpleName)}.${::rawInput.name}"
|
||||
val s = "${Console::class.java.simpleName.lowercaseFirstChar()}.${::rawInput.name}"
|
||||
throw RuntimeException(globalContext.getString(R.string.error_abandoned_method, s))
|
||||
}
|
||||
|
||||
@@ -311,11 +311,11 @@ class Console(scriptRuntime: ScriptRuntime) : AugmentableProxy(scriptRuntime) {
|
||||
val fName = listOf(
|
||||
when {
|
||||
Regex("^set[A-Z].*").containsMatchIn(key) -> key
|
||||
else -> "set${uppercaseFirstChar(key)}"
|
||||
else -> "set${key.uppercaseFirstChar()}"
|
||||
},
|
||||
when {
|
||||
Regex("^is[A-Z].*").containsMatchIn(key) -> key
|
||||
else -> "is${uppercaseFirstChar(key)}"
|
||||
else -> "is${key.uppercaseFirstChar()}"
|
||||
},
|
||||
).find { name ->
|
||||
configurator::class.java.methods.any { method -> method.name == name }
|
||||
|
||||
@@ -15,6 +15,10 @@ import org.autojs.autojs.extension.AnyExtensions.isJsXml
|
||||
import org.autojs.autojs.extension.AnyExtensions.jsBrief
|
||||
import org.autojs.autojs.extension.AnyExtensions.jsUnwrapped
|
||||
import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component3
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component4
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
||||
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
||||
@@ -36,7 +40,7 @@ import org.autojs.autojs.util.RhinoUtils.isUiThread
|
||||
import org.autojs.autojs.util.RhinoUtils.js_eval
|
||||
import org.autojs.autojs.util.RhinoUtils.newBaseFunction
|
||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||
import org.autojs.autojs.util.StringUtils
|
||||
import org.autojs.autojs.util.StringUtils.uppercaseFirstChar
|
||||
import org.autojs.autojs6.R
|
||||
import org.mozilla.javascript.BaseFunction
|
||||
import org.mozilla.javascript.Context
|
||||
@@ -672,7 +676,7 @@ class Dialogs(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
|
||||
if (animation == "default") {
|
||||
win.setWindowAnimations(android.R.style.Animation)
|
||||
} else {
|
||||
val suffix = StringUtils.uppercaseFirstChar(animation.replace('-', '_'))
|
||||
val suffix = animation.replace('-', '_').uppercaseFirstChar()
|
||||
val animationStyle = android.R.style::class.java.getDeclaredField("Animation_$suffix").getInt(null)
|
||||
win.setWindowAnimations(animationStyle)
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||
import org.autojs.autojs.util.RhinoUtils.flatten
|
||||
import org.autojs.autojs.util.StringUtils
|
||||
import org.autojs.autojs.util.StringUtils.lowercaseFirstChar
|
||||
import org.autojs.autojs.util.StringUtils.uppercaseFirstChar
|
||||
import org.mozilla.javascript.Undefined
|
||||
|
||||
class Jsox(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
||||
|
||||
override val key = lowercaseFirstChar(javaClass.simpleName)
|
||||
override val key = javaClass.simpleName.lowercaseFirstChar()
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
::extend.name,
|
||||
@@ -73,7 +73,7 @@ class Jsox(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
|
||||
fun extendAllRhinoWithRuntime(scriptRuntime: ScriptRuntime): Undefined = extendRhinoWithRuntime(scriptRuntime, presetModules)
|
||||
|
||||
private fun normalizeModuleName(name: String): String {
|
||||
return StringUtils.uppercaseFirstChar(if (!name.endsWith('x')) "${name}x" else name)
|
||||
return "${name.removeSuffix("x")}x".uppercaseFirstChar()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.autojs.autojs.util.AndroidUtils.SystemProperties
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceIntNumber
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||
import org.autojs.autojs.util.StringUtils.convertRegex
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import org.mozilla.javascript.regexp.NativeRegExp
|
||||
|
||||
@@ -85,7 +84,7 @@ class SysProps(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invok
|
||||
|
||||
private fun matchFilter(input: String, filter: Any?) = when {
|
||||
filter.isJsNullish() -> true
|
||||
filter is NativeRegExp -> Regex(convertRegex(filter.toString())).containsMatchIn(input)
|
||||
filter is NativeRegExp -> filter.toString().toRegex().containsMatchIn(input)
|
||||
else -> input.contains(coerceString(filter))
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,6 @@ object IntentUtils {
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.let { context.startActivity(it) }
|
||||
}
|
||||
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
exceptionHolder?.show(R.string.error_no_applications_available_for_browsing_this_link)
|
||||
// ViewUtils.showToast(context, R.string.text_no_browser, true)
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.autojs.autojs.extension.NumberExtensions.roundToString
|
||||
import org.opencv.core.Point
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.Locale
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
|
||||
@@ -21,8 +21,6 @@ import kotlin.math.pow
|
||||
*/
|
||||
object StringUtils {
|
||||
|
||||
private val regexPattern = "^/(.+)/$".toRegex()
|
||||
|
||||
private val globalAppContext by lazy { GlobalAppContext.get() }
|
||||
|
||||
private val localePref = mapOf(
|
||||
@@ -39,22 +37,6 @@ object StringUtils {
|
||||
@JvmStatic
|
||||
fun key(@LocaleNonRelated resId: Int): String = globalAppContext.getString(resId)
|
||||
|
||||
// @Overwrite by SuperMonster003 on May 5, 2022.
|
||||
// ! Dunno what "better implementation" really means.
|
||||
// ! The only thing I did was make code more "lightweight". ;)
|
||||
// ! zh-CN:
|
||||
// ! 不清楚 "更好的实现方式" 的真正含义.
|
||||
// ! 唯一做的只是使代码更 "轻量级". [眨眼符号]
|
||||
// @TodoDiary by Stardust on Jan 30, 2018.
|
||||
// ! 更好的实现方式.
|
||||
// ! en-US (translated by SuperMonster003 on Jul 29, 2024):
|
||||
// ! Better implementation.
|
||||
@JvmStatic
|
||||
fun convertRegex(regex: String) = regex.apply { if (shouldTakenAsRegex(this)) return replace(regexPattern, "$1") }
|
||||
|
||||
@JvmStatic
|
||||
fun shouldTakenAsRegex(s: String) = regexPattern.containsMatchIn(s)
|
||||
|
||||
@JvmStatic
|
||||
fun join(delimiter: CharSequence?, vararg tokens: Any?): String = TextUtils.join(delimiter!!, tokens)
|
||||
|
||||
@@ -209,14 +191,20 @@ object StringUtils {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun uppercaseFirstChar(s: String) = if (s.isEmpty()) s else s.replaceFirstChar { s[0].uppercaseChar() }
|
||||
fun String.uppercaseFirstChar(): String {
|
||||
val s = this
|
||||
return if (s.isEmpty()) s else s.replaceFirstChar { s[0].uppercaseChar() }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun lowercaseFirstChar(s: String) = if (s.isEmpty()) s else s.replaceFirstChar { s[0].lowercaseChar() }
|
||||
fun String.lowercaseFirstChar(): String {
|
||||
val s = this
|
||||
return if (s.isEmpty()) s else s.replaceFirstChar { s[0].lowercaseChar() }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Deprecated("Deprecated since v6.6.0", ReplaceWith("uppercaseFirstChar(s)"))
|
||||
fun toUpperCaseFirst(s: String) = uppercaseFirstChar(s)
|
||||
fun toUpperCaseFirst(s: String) = s.uppercaseFirstChar()
|
||||
|
||||
@JvmStatic
|
||||
fun toFormattedSummary(dataList: List<Pair<String, () -> Any?>>): String {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Sat Dec 27 13:20:38 CST 2025
|
||||
BUILD_TIME=1766812838968
|
||||
#Sat Dec 27 21:41:16 CST 2025
|
||||
BUILD_TIME=1766842876384
|
||||
COMPILE_SDK_VERSION=36
|
||||
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
||||
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
|
||||
TARGET_SDK_VERSION=36
|
||||
TARGET_SDK_VERSION_INRT=29
|
||||
VERSION_BUILD=3554
|
||||
VERSION_BUILD=3557
|
||||
VERSION_NAME=6.7.0 Alpha13
|
||||
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
||||
|
||||
Reference in New Issue
Block a user