mirror of
https://github.com/gkd-kit/docs.git
synced 2024-11-16 17:32:21 +08:00
feat: selector
This commit is contained in:
parent
309165ae7b
commit
e386168e67
|
@ -1,27 +1,35 @@
|
|||
<script setup lang="ts">
|
||||
import { shallowRef, computed } from 'vue';
|
||||
import { useDebounce } from '@vueuse/core';
|
||||
|
||||
const value = shallowRef('');
|
||||
const reg = /^[_a-zA-Z][a-zA-Z0-9_]*(\.[_a-zA-Z][a-zA-Z0-9_]*)*$/;
|
||||
const reg = /^[_a-zA-Z][a-zA-Z0-9_]*$/;
|
||||
const lazyValue = useDebounce(value, 300);
|
||||
const test = computed(() => reg.test(lazyValue.value));
|
||||
const test = computed(() => {
|
||||
return (
|
||||
lazyValue.value !== 'null' &&
|
||||
lazyValue.value !== 'true' &&
|
||||
lazyValue.value !== 'false' &&
|
||||
reg.test(lazyValue.value)
|
||||
);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<input
|
||||
placeholder="请输入属性名测试是否合法"
|
||||
placeholder="请输入标识符测试是否合法"
|
||||
type="text"
|
||||
v-model="value"
|
||||
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<div
|
||||
mt-4px
|
||||
mt-4px
|
||||
:class="{
|
||||
'color-red': !test,
|
||||
'opacity-0': !lazyValue || !value,
|
||||
}"
|
||||
>
|
||||
{{ test ? `合法属性名✅` : `非法属性名❌` }}
|
||||
{{ test ? `合法标识符✅` : `非法标识符❌` }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -41,15 +41,20 @@ export default defineConfig({
|
|||
text: '指引',
|
||||
items: [
|
||||
{ text: '开始使用', link: '/guide/' },
|
||||
{ text: '高级选择器', link: '/selector/' },
|
||||
{ text: '订阅规则', link: '/subscription/' },
|
||||
{ text: '疑难解答', link: '/faq/' },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '选择器',
|
||||
items: [
|
||||
{ text: '语法介绍', link: '/selector/' },
|
||||
{ text: '属性方法', link: '/selector/node' },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'API',
|
||||
link: '/api/',
|
||||
collapsed: true,
|
||||
items: typedocSidebar,
|
||||
},
|
||||
],
|
||||
|
|
|
@ -8,13 +8,13 @@ titleTemplate: 自定义屏幕点击应用
|
|||
hero:
|
||||
name: 'GKD'
|
||||
text: '自定义屏幕点击应用'
|
||||
tagline: '基于无障碍+高级选择器+订阅规则'
|
||||
tagline: '基于无障碍+选择器+订阅规则'
|
||||
actions:
|
||||
- theme: brand
|
||||
text: 开始使用
|
||||
link: /guide/
|
||||
- theme: alt
|
||||
text: 高级选择器
|
||||
text: 选择器
|
||||
link: /selector/
|
||||
- theme: alt
|
||||
text: 订阅规则
|
||||
|
@ -29,8 +29,8 @@ hero:
|
|||
features:
|
||||
- title: 🐔 开放源代码
|
||||
details: 任何人均可审查源代码, 确保安全性和质量
|
||||
- title: 🐋 高级选择器
|
||||
details: 一种能联系节点上下文信息的的高级选择器, 更容易也更精确找到目标节点
|
||||
- title: 🐋 选择器
|
||||
details: 一种能联系节点上下文信息的的查询语法, 更容易也更精确找到目标节点
|
||||
- title: 🎤 订阅规则
|
||||
details: 您可编写本地订阅满足自己需求, 远程订阅能让您直接使用大众维护的开源规则
|
||||
- title: 🏀 快照审查
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# 高级选择器 {#title}
|
||||
# 选择器 {#title}
|
||||
|
||||
<script setup>
|
||||
import ValueField from '/.vitepress/components/ValueField.vue';
|
||||
import IdentifierField from '/.vitepress/components/IdentifierField.vue';
|
||||
</script>
|
||||
|
||||
一个类似 CSS 选择器的高级选择器, 能联系节点上下文信息, 更容易也更精确找到目标节点
|
||||
一个类似 CSS 选择器的选择器, 能联系节点上下文信息, 更容易也更精确找到目标节点
|
||||
|
||||
## 为什么需要选择器 {#why}
|
||||
|
||||
|
@ -30,11 +30,11 @@ import ValueField from '/.vitepress/components/ValueField.vue';
|
|||
|
||||
下面分别介绍 [属性选择器](#attr) 和 [关系选择器](#connect)
|
||||
|
||||
## 属性选择器 {#attr}
|
||||
## 属性选择 {#attr}
|
||||
|
||||
它和 CSS 语法的 属性选择器很相似, 但更强大, 如下是一个示例
|
||||
|
||||
`@TextView[a=1][b^='2'][c*='a'||d.length>7&&e=false]`
|
||||
`@TextView[a=1][b^='2'][c*='a'||d.length>7&&e=false][!(f=true)][g.plus(1)>0]`
|
||||
|
||||
`@` 表示选择此节点, 一条规则最后属性选择器 `@` 生效, 如果没有 `@`, 取最后一个属性选择器
|
||||
|
||||
|
@ -44,28 +44,131 @@ import ValueField from '/.vitepress/components/ValueField.vue';
|
|||
|
||||
为了方便书写规则, 上述 `TextView` 等价 `[name='TextView'||name$='.TextView']`
|
||||
|
||||
`[]` 内部是一个 逻辑表达式/布尔表达式
|
||||
`[]` 内部是一个 逻辑表达式/布尔表达式/取反表达式
|
||||
|
||||
- 逻辑表达式 -> `name='TextView'||name$='.TextView'`
|
||||
- 布尔表达式 -> `name='TextView'`
|
||||
- 取反表达式 -> `!(name$='TextView')`, `!(name='TextView'||name$='.TextView')`
|
||||
|
||||
逻辑表达式 有两个操作符 `||` 和 `&&`. `&&` 优先级更高, 即 `[a>1||b>1&&c>1||d>1]` 等价于 `[a>1||(b>1&&c>1)||d>1]`
|
||||
注意 取反表达式 后面必须是 `(...)`, `!!(...)` 是非法的
|
||||
|
||||
逻辑表达式 有两个操作符 `||` 和 `&&`. `&&` 优先级更高
|
||||
|
||||
即 `[a>1||b>1&&c>1||d>1]` 等价于 `[a>1||(b>1&&c>1)||d>1]`
|
||||
|
||||
并列的 `[]` 视为使用 `&&` 的逻辑表达式, 即 `[a=1][b=1]` 等价于 `[a=1&&b=1]`
|
||||
|
||||
布尔表达式 由 [属性名](#attr-name) [操作符](#attr-operator) [值](#attr-value) 顺序构成
|
||||
布尔表达式 由 `左值 操作符 右值` 构成, 左值/右值 是一个 值表达式
|
||||
|
||||
### 属性名 {#attr-name}
|
||||
下面分别介绍 [值表达式](#value-exp) 和 [操作符](#attr-operator)
|
||||
|
||||
正则匹配 `^[_a-zA-Z][a-zA-Z0-9_]*(\.[_a-zA-Z][a-zA-Z0-9_]*)*$` 的字符串
|
||||
## 值表达式 {#value-exp}
|
||||
|
||||
类似合法变量名 `a`/`a.length`, 下面可输入属性名测试否是合法
|
||||
值表达式分两类: 变量 和 字面量, 下图是关系表格
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2"> <div text-center>值表达式</div> </th>
|
||||
<th>示例</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="3">变量</td>
|
||||
<td>标识符</td>
|
||||
<td>
|
||||
<code> a </code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>成员表达式</td>
|
||||
<td>
|
||||
<code>a.b</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>调用表达式</td>
|
||||
<td><code>a(b,c)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="4">字面量</td>
|
||||
<td>null</td>
|
||||
<td><code>null</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>boolean</td>
|
||||
<td><code>false</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>int</td>
|
||||
<td><code>114514</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>string</td>
|
||||
<td><code>'ikun'</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
每个值表达式都有其类型, 可细分为两类
|
||||
|
||||
基础类型: `null` `boolean` `int` `string`
|
||||
|
||||
对象类型: `object`
|
||||
|
||||
对象类型可细分为 `context` 和 `node` 两种类型
|
||||
|
||||
比如选择器 `[parent=null]` 代表选择一个父节点是 null 的节点, 即根节点
|
||||
|
||||
上面的 `parent` 属于 值表达式/变量/标识符, 类型是 `node`
|
||||
|
||||
`context` 类型指代当前节点的上下文, 当想使用不属于 `node` 上的属性方法时就需要 `context`
|
||||
|
||||
### 变量 {#var}
|
||||
|
||||
首先需要了解 **标识符**: 正则匹配 `^[_a-zA-Z][a-zA-Z0-9_]*$` 并且不是 `null`/`true`/`false` 的字符串
|
||||
|
||||
示例合法变量名: `a` `ikun` `manbaout`, 下面可输入字符测试否是合法
|
||||
|
||||
::: raw
|
||||
<ValueField />
|
||||
<IdentifierField />
|
||||
:::
|
||||
|
||||
### 操作符 {#attr-operator}
|
||||
---
|
||||
|
||||
接下来了解 **成员表达式** `a.b`, 它被 `.` 分为两个部分, 前部分是另一个变量, 后部分是一个标识符作为属性
|
||||
|
||||
同理 `a.b.c` 也是一个 成员表达式, 其中 `a.b` 是它的变量部分, `c` 是一个合法的标识符作为属性
|
||||
|
||||
根据上面标识符的规则, `a.1`, `a.null`, `a.true` 都是非法成员表达式
|
||||
|
||||
---
|
||||
|
||||
最后了解 **调用表达式** `a(b,c)`, 它由两个部分构成, `(` 的左侧 `a` 是一个变量作为 调用者
|
||||
|
||||
`(c,d)` 作为调用参数(值类型), 调用参数数量可以是 0 或任意个, 即 `a()` 也是合法的
|
||||
|
||||
合法的其它例子: `a.b(c,d).e(f).g(1,2,true)`
|
||||
|
||||
需要注意调用者不能是 调用表达式, 即 `a()()` 非法
|
||||
|
||||
### 字面量 {#literal}
|
||||
|
||||
根据上面的表格, 字面量有 4 种: `null`, `boolean`, `int`, `string`
|
||||
|
||||
- null
|
||||
- boolean 使用 `true`/`false`
|
||||
- int 匹配 `^-?[0-9]$`, 即10进制自然数, 示例 `-1`,`0`,`1`, 不支持 `+1` 这种写法
|
||||
- string 使用 ' ` " 之一成对包裹, 内部字符转义使用 `\`\
|
||||
所有的转义字符示例 `\\`, `\'`, `\"`, `` \` ``, `\n`, `\r`, `\t`, `\b`, `\xfF`, `\uffFF`\
|
||||
不支持多行字符, 处于 `[0, 0x1F]` 的控制字符必须使用转义字符表示
|
||||
|
||||
此外使用 string 时需要了解 [嵌套转义字符](#nest-escape) 以避免出现错误
|
||||
|
||||
## 操作符 {#attr-operator}
|
||||
|
||||
操作符 用于连接两个 值表达式
|
||||
|
||||
| 操作符 | 名称 | 说明 |
|
||||
| :----: | :-----------: | :-----------: |
|
||||
|
@ -86,20 +189,7 @@ import ValueField from '/.vitepress/components/ValueField.vue';
|
|||
|
||||
附加说明: `matches`/`notMatches` 要求 值 必须是合法的 [Java/Kotlin 正则表达式](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html), 否则提示语法错误
|
||||
|
||||
### 值 {#attr-value}
|
||||
|
||||
值: 4 种类型, `null`, `boolean`, `string`, `int`
|
||||
|
||||
- null
|
||||
- boolean 使用 `true`/`false`
|
||||
- int 匹配 `^-?[0-9]$`, 即10进制自然数, 示例 `-1`,`0`,`1`
|
||||
- string 使用 ' ` " 之一成对包裹, 内部字符转义使用 `\`\
|
||||
所有的转义字符示例 `\\`, `\'`, `\"`, `` \` ``, `\n`, `\r`, `\t`, `\b`, `\xfF`, `\uffFF`\
|
||||
不支持多行字符, 处于 `[0, 0x1F]` 的控制字符必须使用转义字符表示
|
||||
|
||||
此外使用 string 类型需要了解 [嵌套转义字符](#nest-escape) 以避免出现错误
|
||||
|
||||
操作符只能使用在对应的类型的值, 比如 `a>''` 类型不匹配, 将提示 `非法类型`/`非法选择器`
|
||||
操作符只能使用在对应的类型的值, 比如 `a>''` 类型不匹配, 将提示 `非法类型`
|
||||
|
||||
下面表格中 `-` 表示类型不匹配
|
||||
|
||||
|
@ -122,22 +212,26 @@ import ValueField from '/.vitepress/components/ValueField.vue';
|
|||
|
||||
除 `=`/`!=` 以外的操作符, 当节点属性是 null 时表达式为 `false`
|
||||
|
||||
- a > 233
|
||||
- a >= 233
|
||||
- a < 233
|
||||
- a <= 233
|
||||
- a ^= 'xxx'
|
||||
- a > 233
|
||||
- a >= 233
|
||||
- a < 233
|
||||
- a <= 233
|
||||
- a ^= 'xxx'
|
||||
- a !^= 'xxx'
|
||||
- a \*= 'xxx'
|
||||
- a !\* 'xxx'
|
||||
- a $= 'xxx'
|
||||
- a $= 'xxx'
|
||||
- a !$= 'xxx'
|
||||
- a ~= 'xxx'
|
||||
- a ~= 'xxx'
|
||||
- a !~= 'xxx'
|
||||
|
||||
即当 a 是 `null` 时以上表达式为 `false`
|
||||
|
||||
## 关系选择器 {#connect}
|
||||
你可能会对 `a !$= 'xxx'` 在 a 是 `null` 表达式为 `false` 感到奇怪
|
||||
|
||||
那你可以换一种写法使用 `a=null || a!$='xxx'` 或 `!(a$='xxx')`
|
||||
|
||||
## 关系选择 {#connect}
|
||||
|
||||
关系选择器 由 关系操作符 和 关系表达式 构成, 用于连接两个属性选择器
|
||||
|
||||
|
|
78
docs/selector/node.md
Normal file
78
docs/selector/node.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
# 属性方法 {#title}
|
||||
|
||||
此章节介绍各个类型可用的属性及其方法
|
||||
|
||||
> 注: `null` 无任何属性方法\
|
||||
> 所有的属性方法当调用者是 null 时, 均返回 null
|
||||
|
||||
## boolean
|
||||
|
||||
| 方法名 | 参数 | 返回类型 | 描述 |
|
||||
| ------ | ---- | -------- | ----------- |
|
||||
| toInt | | `int` | 转为 0 或 1 |
|
||||
|
||||
## int
|
||||
|
||||
| 方法名 | 参数 | 返回类型 | 描述 |
|
||||
| -------- | ----- | ------------------- | -------------------- |
|
||||
| toString | | [`string`](#string) | 转为10进制字符串 |
|
||||
| toString | `int` | `string` | 转为对应进制的字符串 |
|
||||
| plus | `int` | `string` | 加上 |
|
||||
| minus | `int` | `string` | 减去 |
|
||||
| times | `int` | `string` | 乘以 |
|
||||
| div | `int` | `string` | 除以 |
|
||||
| rem | `int` | `string` | 取余 |
|
||||
|
||||
## string
|
||||
|
||||
| 标识符 | 属性类型 | 描述 |
|
||||
| ------ | ------------- | ---------- |
|
||||
| length | [`int`](#int) | 字符串长度 |
|
||||
|
||||
| 方法名 | 参数 | 返回类型 | 描述 |
|
||||
| --------- | -------------- | -------- | ------------------------------------- |
|
||||
| get | [`int`](#int) | `string` | 获取对应索引字符串 |
|
||||
| at | `int` | `string` | 同上,但是参数传负数时从最后一个字符取 |
|
||||
| substring | `int` | `string` | 截取指定索引到结尾字符串 |
|
||||
| substring | `int`,`int` | `string` | 截取指定间隔字符串 |
|
||||
| toInt | | `int` | 转为10进制数字 |
|
||||
| toInt | `int` | `int` | 转为指定进制的数字 |
|
||||
| indexOf | `string` | `int` | 查找指定字符串的索引 |
|
||||
| indexOf | `string`,`int` | `int` | 从指定索引开始查找指定字符串的索引 |
|
||||
|
||||
## node
|
||||
|
||||
| 标识符 | 属性类型 | 描述 |
|
||||
| ------------- | ------------------- | ---------- |
|
||||
| \_id | [`int`](#int) | |
|
||||
| \_pid | `int` | |
|
||||
| id | [`string`](#string) | |
|
||||
| vid | `string` | |
|
||||
| name | `string` | |
|
||||
| text | `string` | |
|
||||
| desc | `string` | |
|
||||
| clickable | `boolean` | |
|
||||
| focusable | `boolean` | |
|
||||
| checkable | `boolean` | |
|
||||
| checked | `boolean` | |
|
||||
| editable | `boolean` | |
|
||||
| longClickable | `boolean` | |
|
||||
| visibleToUser | `boolean` | |
|
||||
| left | `int` | |
|
||||
| top | `int` | |
|
||||
| right | `int` | |
|
||||
| bottom | `int` | |
|
||||
| width | `int` | |
|
||||
| height | `int` | |
|
||||
| childCount | `int` | |
|
||||
| index | `int` | |
|
||||
| depth | `int` | |
|
||||
| parent | [`node`](#node) | 获取父节点 |
|
||||
|
||||
| 方法名 | 参数 | 返回类型 | 描述 |
|
||||
| -------- | ---- | --------------- | -------------------- |
|
||||
| getChild | int | [`node`](#node) | 获取指定索引的子节点 |
|
||||
|
||||
## context
|
||||
|
||||
属性方法暂与 [node](#node) 一致
|
Loading…
Reference in New Issue
Block a user