跳到正文
豫言包管理
← 全部包

豫言操作系统网页界面 0.3.0

豫言 · 库

以元素标识读写网页界面、读回控件与属性状态、点击与摆放元素并接收界面事件的公共接口。

网页界面接口规范 0.3.0

本包适用于提供带标识元素和事件队列的宿主。浏览器可用 DOM 实现;其他宿主只有在能提供相同语义时才声明此包。应用依赖本包后,全部函数都必须实现,缺少任何一个函数时不得装载。

0.2.0 在 0.1.0 的四个函数(读取页面语言、设置节点文字、设置节点属性、等待界面事件)之上增加:控件值读回与写入、显示/禁用/只读/类名、焦点、输入光标与选区、滚动、模态框、页面状态。旧函数的签名不变;设置节点属性 的属性白册扩充,等待界面事件 改为按类型从统一事件队列取事件(见[网页事件接口规范](../网页事件/规范.汉语.md))。

0.3.0 在 0.2.0 之上只增函数(旧函数签名与语义不变):读取节点属性、移除节点属性、读取节点文字(读回与移除)、点击节点(程序性点击)、设置节点位置、读取节点矩形(摆放浮层)。它们服务于云控制台与阅读页从 JavaScript 迁入豫言时遇到的缺口,见[前端补全计划](../../豫言操作系统/文档/前端补全计划.汉语.md)。

所有函数按元素 ID 定位页面中已经存在的元素,不产生句柄,不向应用暴露原生 DOM 对象。字符串均为豫言字符串。

失败语义

本包的所有失败都属于违规调用或平台故障,一律抛豫言事故(可被应用捕获),事故消息为中文并保留原因:元素不存在、元素类型不符、参数越界或格式不合规、属性或链接不在白册内、浏览器拒绝操作(如对已打开的 dialog 再次 showModal)。宿主不得把失败当作成功,也不得让宿主异常越过豫言边界而使应用无法捕获。没有“可恢复业务情形”,因此没有返回值形式的错误。

危险元素:script、style、iframe、object、embed、link、meta、base、frame、frameset、applet 不可作为读写目标(iframe 仅可设 class、title、hidden 及 data-*、aria-* 属性,其地址只能经网页文树包的 设置页面框架地址 修改)。

函数

页面语言与文字

  • 读取页面语言 : 有 → 字符串:读取根元素的语言标签,未设置时为空字符串。
  • 设置节点文字 : 字符串 → 字符串 → 有:把元素的文字内容整体换成纯文本,不解析 HTML;文字至多 8 MiB(UTF-16 码元);br、input 这类空元素只接受空文字。

属性

设置节点属性 : 字符串(ID) → 字符串(名称) → 字符串(值) → 有

名称须以 ASCII 小写字母开头,其后为小写字母、数字与短横线(至多 64 个字符),值不得含控制字符(制表、换行、回车除外),值至多 65536 个 UTF-16 码元。允许的属性(白册,与网页文树包共用同一张表):

| 属性 | 适用元素 | 值的规则 | | --- | --- | --- | | class | 任意 | 见 设置节点类名 | | id | 任意 | 不含空白、引号、<、>、&、反引号、反斜杠与控制字符,1 至 128 个字符,且文档中不得已有别的元素使用;空串表示移除 | | role | 任意 | [a-z][a-z-]*,至多 32 个字符 | | title | 任意 | 至多 4096 个字符 | | hidden disabled readonly checked selected open | 任意 | 布尔属性,值只能是 ""、"true"(存在)或 "false"(移除) | | tabindex | 任意 | 只允许 -1 与 0 | | type | button:button submit reset;input:button submit reset checkbox radio text search number email url tel password range date time datetime-local | 值在所列集合内 | | placeholder | input、textarea | 至多 4096 个字符 | | datetime | time | [0-9TZ:.+\- ],至多 64 个字符 | | maxlength | input、textarea | 至多 6 位数字 | | rows | textarea | 至多 6 位数字 | | colspan rowspan | td、th | 至多 6 位数字 | | for | label | 同 id 的字符规则 | | value | input、option、button | 任意(≤ 65536 码元) | | href | 仅 a | 见下 | | target | 仅 a | 只允许 _blank、_self;设为 _blank 时宿主强制同时设置 rel="noopener noreferrer" | | aria-*、data-* | 任意 | 名称 aria- 或 data- 后接 [a-z0-9-]+;值任意(受上述总限制) |

data-yy- 前缀保留给宿主:应用不得设置(data-yy 本身是操作键,应用可以设置)。style、src、srcdoc、rel、name、action、formaction、sandbox 以及所有 on* 事件处理属性一律拒绝。

a[href] 只允许:以 / 开头但不以 // 开头的站内路径、以 # 开头的锚、https:// 网址、http:// 网址(不区分大小写)。含空白、控制字符或反斜杠的地址,以及 javascript:、data:、vbscript:、mailto:、// 协议相对地址等一概拒绝。`http:` 仅对 `a[href]` 放行。

类名

设置节点类名 : 字符串(ID) → 字符串(类名,空格分隔) → 有:整体替换元素的 class。每个类名只允许 Unicode 字母、数字、下划线与短横线(因此中文类名可用),分隔符只能是 ASCII 空格(连续空格并为一个);至多 32 个类名,每个至多 64 个字符,总长至多 512;空串清除 class。

设置节点类标记 : 字符串(ID) → 字符串(单个类名) → 爻 → 有:设置元素上单个类名的有无(对应 classList.toggle(类名, 有)):阳加上、阴去掉,其余类名不受影响。类名只允许一个,字符规则同 设置节点类名(至多 64 个字符,不得含空格)。

控件值

  • 读取节点值 : 字符串 → 字符串:读取 input、textarea、select 的当前值;值按 UTF-8 计超过 8 MiB 时抛事故(宿主与应用交换数据的单次上限是 16 MiB,不能让它变成无法捕获的宿主异常)。读取选区文字 同此限制。
  • 设置节点值 : 字符串 → 字符串 → 有:设置上述控件的值,不触发 input 或 change 事件;值至多 8 MiB;文件输入框不可设值;select 若没有值相同的选项则抛事故。

显示、禁用、只读

设置节点显示 : 字符串 → 爻 → 有(阳显示,阴隐藏,对应 hidden 属性)、设置节点禁用(disabled)、设置节点只读(readonly)。

焦点

  • 聚焦节点 : 字符串 → 有:使元素获得焦点;不可聚焦的元素不报错,焦点不变。
  • 读取聚焦标识 : 有 → 字符串:当前获得焦点的元素 ID;没有焦点或该元素没有 ID 时为空字符串。
  • 节点包含焦点 : 字符串 → 爻:元素自身或其后代拥有焦点时为阳。

输入光标与选区

  • 设置输入光标 : 字符串 → 整数 → 整数 → 有:设置 input 或 textarea 的选区,参数为起、止位置。
  • 读取输入光标 : 字符串 → (整数 合 整数):读取选区的起、止位置。
  • 位置按豫言字符(Unicode 码点)计数,不是 JavaScript 的 UTF-16 码元;宿主负责换算(例如 😀 在豫言里占 1 个位置,在浏览器里占 2 个码元)。须 0 ≤ 起 ≤ 止 ≤ 文字长度,否则抛事故;不支持选区的输入类型(如 number、email)抛事故。
  • 读取选区文字 : 有 → 字符串:读取当前选中的文字。当前聚焦的输入框内有选区时返回该选区,否则返回页面上的选中文字(getSelection()),没有选区时为空字符串。

滚动

  • 读取滚动度量 : 字符串 → 字符串:返回 JSON 文字 {"顶":整数,"总高":整数,"可视高":整数},分别是 scrollTop、scrollHeight、clientHeight(四舍五入取整)。
  • 设置滚动顶 : 字符串 → 整数 → 有:设置 scrollTop。

模态框

打开模态框 : 字符串 → 有、关闭模态框 : 字符串 → 有:对 dialog 元素调用 showModal() 与 close();元素不是 dialog、宿主不支持 dialog 或浏览器拒绝(如对已打开的 dialog 再次打开)时抛事故。dialog 的 cancel(Esc)与 close 事件走网页事件包:应用用 订阅界面事件 订阅并可在策略里同步阻止 cancel 的默认动作。浏览器只在页面已获用户激活时允许取消 `cancel`(未经用户交互时 cancel 不可取消,dialog 照常关闭),此时事件载荷带 可取消:false、已阻止默认:false。

页面状态与可见

  • 读取页面状态 : 有 → 字符串:返回 JSON 文字 {"可见":爻,"联机":爻,"窄屏":爻}。可见 为 !document.hidden,联机 为 navigator.onLine,窄屏 由固定媒体查询 (max-width: 700px) 决定(宿主没有媒体查询能力时为阴)。
  • 读取节点可见 : 字符串 → 爻:元素已连入文档,且自身与所有祖先元素的计算样式 display 都不是 none 时为阳。

属性读回与移除、文字读回(0.3.0)

  • 读取节点属性 : 字符串(ID) → 字符串(名称) → (爻 合 字符串):读取元素上某个属性的原样文字(getAttribute,不是 DOM 属性,也不是计算样式)。除元素 ID 外,标识还可以是保留字 `文档根`(<html>)与 `页体`(<body>),因此 ID 为“文档根”“页体”的元素只能由保留字指代其根元素。属性存在时返回(阳,值),布尔属性存在时值为空字符串(例如 <details open>);不存在时返回(阴,空字符串)。名称须为 [a-z][a-z0-9:_-]*(至多 64 个字符),不得以 on 开头,不得是 style 或 srcdoc。元素是危险元素、iframe 上要读白册之外的属性、值超过 65536 个 UTF-16 码元时抛事故。type=password 输入框的 value 属性视为不存在(与界面事件载荷同规)。典型用法:读根元素的 data-lang,读 <details> 的 open,读 aria-expanded。
  • 移除节点属性 : 字符串(ID) → 字符串(名称) → 有:移除元素上一个白册内的属性(removeAttribute);属性本来不存在时什么也不做;名称不在“属性”一节的白册内(含 data-yy- 前缀、style、on*)时抛事故。移除 class 等同于 设置节点类名 传入空文字;移除 id 等同于用空串设置 id;移除 target 不会自动移除此前被强制加上的 rel。
  • 读取节点文字 : 字符串(ID) → 字符串:读取元素的 textContent;文字按 UTF-8 计超过 8 MiB 时抛事故;危险元素与不存在的元素抛事故。

点击、位置与矩形(0.3.0)

  • 点击节点 : 字符串(ID) → 有:对元素执行一次程序性点击(HTMLElement.click())。页面上对该元素的所有订阅(含网页事件包的委托订阅)照常收到 click 事件,事件不是“受信任事件”,浏览器不会因此打开弹窗或文件选择框。文件输入框、危险元素、href 不满足上文链接规则的 <a>、不存在的元素抛事故;被禁用的元素点击无效果且不抛事故。回放被自己拦截的点击时,须先取消拦截订阅,再点击,随后重订(否则宿主又会拦下这次点击)。
  • 设置节点位置 : 字符串(ID) → 整数 → 整数 → 有:把元素的 style.left、style.top 设为给定的像素整数(−100000 至 100000),用于摆放悬浮提示等浮层。元素的 position(absolute 或 fixed)由页面样式表另行指定;本包不开放其他样式。
  • 读取节点矩形 : 字符串(ID) → 字符串:返回 JSON 文字 {"左":整数,"上":整数,"右":整数,"下":整数},是元素相对视口的位置(getBoundingClientRect,四舍五入取整);display:none 或未连入文档的元素四项均为 0。

事件

等待界面事件 : 有 → (字符串 合 字符串):按宿主收到的顺序取一个界面类型的事件,返回(事件名称,目标元素 ID);目标没有 ID 时第二项为空字符串。其他类型(消息、定时……)的事件留在统一队列里,不被吞掉。宿主关闭队列时返回(“关闭”,空字符串),之后的调用继续返回相同关闭标记。

界面事件的来源有两类:(1) 旧式隐式监听:宿主对文档里带 ID 元素的 click、input、change、submit 自动产生事件,行为与 0.1.0 相同;(2) 网页事件包的 订阅界面事件 订阅得到的事件(含委托:无 ID 的后代元素触发时第二项为空字符串)。某个同名事件已被 订阅界面事件 覆盖时,旧式隐式监听让路,同一次点击不会报两遍。需要事件载荷(键盘、值、操作键……)时,应用应改用 等待网页事件。

限额

| 项 | 限额 | | --- | --- | | 文字与控件值 | 至多 8 MiB | | 属性值 | 至多 65536 个 UTF-16 码元 | | 类名 | ≤ 32 个、每个 ≤ 64 个字符、总长 ≤ 512 | | 光标位置 | 0 至文字长度(码点) |

跨宿主一致性

  • 所有元素定位按当前文档里的 ID;同一 ID 有多个元素时,取文档顺序里的第一个。
  • 白册、限额与失败分类必须与本文一致;宿主可以更严,不可以更松。
  • 属性与链接校验在宿主完成,应用不得依赖“先写后被浏览器拦截”。

一致性样例

  1. 设置节点文字("盒", "<img src=x onerror=alert(1)>"):元素里只有这串纯文字,没有子元素。
  2. 设置节点属性("链", "href", "javascript:alert(1)"):抛事故;设置节点属性("链", "target", "_blank") 之后元素的 rel 为 noopener noreferrer。
  3. 输入框值为“a😀bc”:设置输入光标(ID, 1, 3) 后 读取选区文字 为“😀b”,读取输入光标 为(1,3)。
  4. 设置节点值("下拉", "不存在的值"):抛事故;读取节点值("盒")(盒是 div):抛事故。
  5. (0.3.0)根元素为 <html data-lang="wen">:读取节点属性("文档根", "data-lang") 为(阳,“wen”),读取节点属性("文档根", "data-无") 为(阴,“”);<details id="项" open>:读取节点属性("项", "open") 为(阳,“”);移除节点属性("项", "open") 后为(阴,“”)。
  6. (0.3.0)点击节点("钮") 之后,订阅了该按钮 click 的应用收到事件;被拦截订阅的应用须先 取消订阅界面事件 才能让点击到达页面上别的监听者。点击节点("链")(href 为 javascript:…):抛事故。
  7. (0.3.0)设置节点位置("提示", 12, 34) 后元素 style.left 为 12px、style.top 为 34px;读取节点矩形("提示") 的左、上与之相符(在 position:absolute 且无偏移的容器中)。

边界

本包不规定:节点创建、选择器(见网页文树包 0.3.0 的查询)、事件的键盘与组字载荷(见网页事件包)、定时器、剪贴板、网络、任意样式(style)读写(仅 设置节点位置 一项例外)、getComputedStyle 的其他属性、拖放与文件选择。

依赖

查看包配置

上传历史

当前上传修订:1 ·

  1. 上传修订 1
    下载 ZIP

包层级

父包:豫言操作系统接口

没有子包。