mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-25 08:01:20 -08:00
docs(core): [SITE-04] document public utility contracts
This commit is contained in:
1 parent
bd3f3c0689
commit
9afbf9940d
96 files changed
+4526
-2333
No files matched your search
@@ -75,6 +75,92 @@ console.info(Artplayer.utils);
|
||||
|
||||
:::
|
||||
|
||||
### 环境与类型 {#utils-contract}
|
||||
|
||||
`Artplayer.utils` 是公开工具集合,不绑定某个播放器。纯文本和数据函数可独立使用;DOM、图片、样式和测量函数需要浏览器及相应节点。不会因为工具来自 Artplayer,就自动在播放器销毁时清理调用者创建的资源。
|
||||
|
||||
`isBrowser`、`userAgent`、`isMobile`、`isSafari`、`isIOS`、`isIOS13` 在模块加载时计算,不随之后的窗口或 UA 修改更新。UA 优先取加载前设置的 `globalThis.CUSTOM_USER_AGENT`,否则取 navigator;`isIOS13` 也包含带触摸能力的 Macintosh 判断。这些是兼容性启发式判断,不是某项播放能力或系统版本的保证。
|
||||
|
||||
根 `Utils` 保留旧类型签名;`artplayer/runtime` 的 `Utils` 描述实际返回值和更广的 DOM 输入。内部辅助形状 `StyledElement` 只要求 style,`EventPathSource` 要求 target 和可选 composedPath;它们不是 runtime 入口单独导出的命名类型。泛型查询只提供静态类型,不校验节点的实际标签。
|
||||
|
||||
### DOM 与样式 {#utils-dom}
|
||||
|
||||
| 工具 | 参数、返回值和边界 |
|
||||
| --- | --- |
|
||||
| `query(selector, parent?)` / `queryAll(selector, parent?)` | 默认 parent 为 document;返回首个元素或 null / 新数组。查询的是后代,不含 parent 自己;非法选择器仍抛错 |
|
||||
| `createElement(tag)` | 新建原生 HTML 元素,不挂载 |
|
||||
| `addClass` / `removeClass` / `hasClass` | 接收节点与单个 class token;前两者返回 undefined,后者返回布尔;保留原生 classList 的参数错误 |
|
||||
| `append(parent, child)` | 同 realm Element 会被移动;其他值先转字符串再作为 HTML 追加。返回 lastElementChild,若不存在才取 lastChild,因此不保证返回刚追加的文本,空父节点可能返回 null |
|
||||
| `remove(child)` / `replaceElement(newChild, oldChild)` | 分别返回被移除节点 / 新节点;节点没有父节点时仍会抛错 |
|
||||
| `siblings(target)` / `inverseClass(target, name)` | 前者返回同父元素的其他元素;后者移除兄弟元素上的类并给目标添加,返回 undefined。要求目标有 parentElement |
|
||||
| `setStyle(element, key, value)` / `setStyles(element, styles)` | 直接写 style 并返回原元素;setStyles 遍历可枚举字符串属性,包括继承属性。不补单位、不自动清空旧样式 |
|
||||
| `getStyle(element, key, numberType = true)` | 用 getComputedStyle/getPropertyValue 读取;默认 parseFloat,不能转为数字时为 NaN;传 false 返回原字符串。使用 CSS 属性名,如 `font-size` |
|
||||
| `setStyleText(id, cssText)` | 更新已有同 id 元素的 textContent;否则创建 style。document 正在加载时延迟到 DOMContentLoaded 挂入 head;无 Promise 或自动释放,调用者应使用独立 id |
|
||||
| `getRect(element)` | 原样返回 getBoundingClientRect 的 DOMRect,而不只是旧类型里的四个字段 |
|
||||
| `getIcon(key = '', html = '')` | 每次返回新的 i 元素,带 art-icon 与 art-icon-key 类;使用 append 规则插入内容,元素不会复制 |
|
||||
| `tooltip(target, message, position = 'top')` | 非移动端设置 aria-label 和 hint--rounded / hint--position 类;移动端不操作。再次调用不会移除旧方向类 |
|
||||
|
||||
HTML 字符串不会自动净化。需要显示纯文本时使用 textContent,或先按用途转义;不要把不可信输入直接交给 append/getIcon。
|
||||
|
||||
### 事件与测量 {#utils-measure}
|
||||
|
||||
| 工具 | 实际行为 |
|
||||
| --- | --- |
|
||||
| `getComposedPath(event)` | 有 composedPath 时保留其 receiver 并直接返回原数组;否则沿 target.parentNode 向上遍历,浏览器中补入 window。fallback 不模拟完整 Shadow DOM 路径 |
|
||||
| `includeFromEvent(event, target)` | 判断目标是否在上述路径中,不是另一次 DOM contains 查询 |
|
||||
| `isInViewport(element, offset = 0)` | 判断矩形与窗口是否相交,包含边界;不是完全可见、遮挡或 IntersectionObserver 判断,保留历史 offset 算法 |
|
||||
| `getSafeAreaInsets()` | 挂载临时不可见节点,读取四个 env(safe-area-inset-*) 的数值,不能解析时为0;成功或失败都移除该节点,要求 document.body 可用 |
|
||||
| `supportsFlex()` | 只检查新建元素能否接受 display:flex,不验证实际布局能力 |
|
||||
|
||||
### 字幕、图片与文件 {#utils-resources}
|
||||
|
||||
| 工具 | 实际行为与归属 |
|
||||
| --- | --- |
|
||||
| `srtToVtt(text)` / `assToVtt(text)` | 同步返回 WebVTT 字符串;前者规范毫秒与部分样式标记,后者提取 Dialogue 的基础时间/文本,不是完整字幕校验器或 ASS 排版引擎 |
|
||||
| `vttToBlob(text)` | 返回 text/vtt 的 Blob URL,不返回 Blob 对象;调用者在不再使用时 URL.revokeObjectURL |
|
||||
| `getExt(url)` | 去除查询/片段,trim并转小写,取最后一个点之后的文本;没有点时返回剩余字符串,不检查资源或 MIME |
|
||||
| `download(url, name)` | 临时创建带 download 的链接、点击并移除;不返回完成通知,不代表浏览器一定保存成功,也不回收传入 URL |
|
||||
| `loadImg(url, scale?)` | 返回加载完成的 HTMLImageElement。scale 为假值或1时使用原图;其他值通过 canvas/toBlob 再加载缩放图。缩放成功后的 image.src 是调用者拥有的 Blob URL,用完必须回收 |
|
||||
|
||||
`loadImg` 不自动设置 crossOrigin,也没有公开取消或超时参数。跨域原图能显示不代表可读 canvas;加载、画布或编码失败会拒绝 Promise。成功后的监听器已清理;缩放中失败会释放已创建的 Blob URL。仅在页面不再使用缩放结果后回收其 src,原图 URL 不属于此函数。
|
||||
|
||||
### 数据、错误与调度 {#utils-data}
|
||||
|
||||
| 工具 | 实际行为 |
|
||||
| --- | --- |
|
||||
| `def(object, key, descriptor)` | Object.defineProperty 本身,返回原对象;根声明保留的字符串 key 重载返回 void 并非运行时结果 |
|
||||
| `has(object, key)` / `get(object, key)` | 仅检查自有属性 / 获取自有描述符,缺少描述符为 undefined |
|
||||
| `mergeDeep(...objects)` | 新建顶层对象;遍历 Object.keys,两个非数组对象递归合并。两个数组使用旧 concat 展开规则,可能展开后一个数组中的嵌套数组;不是完全深拷贝,未合并的值会保留引用。不支持循环图合并;__proto__ 作为自有数据写入 |
|
||||
| `clamp(number, a, b)` | 将数值限制在两端点之间,允许端点反序;NaN 仍为 NaN |
|
||||
| `secondToTime(seconds)` | 向下取整为 mm:ss,达到一小时后为 hh:mm:ss,小时可超过两位;假值为00:00。不额外校验负数或非有限值 |
|
||||
| `escape(text)` / `unescape(text)` | 只处理 &、<、>、单引号和双引号对应的五种固定实体;单次替换,unescape 不是通用 HTML 实体解析器 |
|
||||
| `capitalize(text)` | 只将第一个字符大写,其余不变 |
|
||||
| `ArtPlayerError(message?, context?)` / `errorHandle(condition, message?)` | 前者是 name 为 ArtPlayerError 的 Error,context 用于支持的 stack capture;后者对假值抛该错误,对真值返回原值 |
|
||||
| `silencePromise(value)` | 有可调用 catch 时返回 catch 吞掉拒绝后的结果,否则原样返回;按 catch 能力判断而不是 instanceof Promise,不捕获调用 catch 本身的同步错误 |
|
||||
| `sleep(milliseconds = 0)` | 定时后兑现为 undefined;没有取消方法 |
|
||||
| `debounce(callback, duration)` | trailing 调用,只保留最后一次参数和调用者 this;忽略旧 context 参数,包装函数返回 undefined |
|
||||
| `throttle(callback, duration)` | leading 同步调用,等待期内丢弃调用,无 trailing;保留调用者 this,包装函数返回 undefined |
|
||||
|
||||
两个包装器不提供 cancel/flush,不随播放器销毁自动取消。throttle 在回调正常返回之后才进入等待期,因此保留同步重入和抛错后再次调用的行为。根类型的旧回调返回值推导不改变这些实际语义。
|
||||
|
||||
```ts
|
||||
import Artplayer from 'artplayer/runtime';
|
||||
import type { Utils } from 'artplayer/runtime';
|
||||
|
||||
const utils: Utils = Artplayer.utils;
|
||||
const fragment = document.createDocumentFragment();
|
||||
const missing: HTMLVideoElement | null = utils.query<HTMLVideoElement>('video', fragment);
|
||||
const div = utils.createElement('div');
|
||||
const styled: HTMLDivElement = utils.setStyle(div, 'fontSize', '20px');
|
||||
const width: string = utils.getStyle(div, 'width', false);
|
||||
const invoke = utils.debounce(function (this: { value: number }, step: number) {
|
||||
this.value += step;
|
||||
}, 20);
|
||||
const returned: void = invoke.call({ value: 0 }, 1);
|
||||
void [missing, styled, width, returned];
|
||||
```
|
||||
|
||||
|
||||
## `scheme`
|
||||
|
||||
返回播放器选项的校验方案
|
||||
|
||||
@@ -75,6 +75,92 @@ console.info(Artplayer.utils);
|
||||
|
||||
:::
|
||||
|
||||
### Environment and types {#utils-contract}
|
||||
|
||||
`Artplayer.utils` is a public collection, not bound to a player instance. Text and data helpers work independently; DOM, image, style, and measurement helpers require a browser and the relevant nodes. Resources you create through these utilities are not automatically released when a player is destroyed.
|
||||
|
||||
`isBrowser`, `userAgent`, `isMobile`, `isSafari`, `isIOS`, and `isIOS13` are calculated at module load, not updated after window or UA changes. The UA uses `globalThis.CUSTOM_USER_AGENT` if set before loading, otherwise navigator. `isIOS13` also recognizes a touch-capable Macintosh. These are compatibility heuristics, not guarantees of media capabilities or OS versions.
|
||||
|
||||
The root `Utils` retains historical signatures; `Utils` from `artplayer/runtime` describes actual returns and broader DOM inputs. Internal helper shapes require only style for `StyledElement`, and target plus optional composedPath for `EventPathSource`; neither is a separately named export from the runtime entry. A generic query provides a static type without checking the actual element tag.
|
||||
|
||||
### DOM and styles {#utils-dom}
|
||||
|
||||
| Utility | Arguments, returns, and boundaries |
|
||||
| --- | --- |
|
||||
| `query(selector, parent?)` / `queryAll(selector, parent?)` | Default to document; return the first element or null / a fresh array. Search descendants, excluding the parent itself; invalid selectors still throw |
|
||||
| `createElement(tag)` | Creates a native HTML element without attaching it |
|
||||
| `addClass` / `removeClass` / `hasClass` | Accept a node and one class token; the first two return undefined, the last a boolean. Native classList argument errors are preserved |
|
||||
| `append(parent, child)` | Moves same-realm Elements; other values are stringified and appended as HTML. Returns lastElementChild, falling back to lastChild, so appended text is not necessarily the return value; an empty parent may yield null |
|
||||
| `remove(child)` / `replaceElement(newChild, oldChild)` | Return the removed node / new node; missing parents still cause errors |
|
||||
| `siblings(target)` / `inverseClass(target, name)` | Return other elements under the same parent / remove the class from siblings and add it to target, returning undefined. Require parentElement |
|
||||
| `setStyle(element, key, value)` / `setStyles(element, styles)` | Assign directly to style and return the original element. setStyles includes inherited enumerable string keys; neither adds units nor clears previous styles |
|
||||
| `getStyle(element, key, numberType = true)` | Reads getComputedStyle/getPropertyValue; defaults to parseFloat, yielding NaN for nonnumeric values. Pass false for the raw string. Use CSS names such as `font-size` |
|
||||
| `setStyleText(id, cssText)` | Replaces textContent of an existing element with that id, otherwise creates style. While the document is loading, attachment to head waits for DOMContentLoaded. No Promise or automatic disposal; use a dedicated id |
|
||||
| `getRect(element)` | Returns the original getBoundingClientRect DOMRect, beyond the four fields in the root type |
|
||||
| `getIcon(key = '', html = '')` | Returns a new i element with art-icon and art-icon-key classes, using append rules for contents; elements are moved, not cloned |
|
||||
| `tooltip(target, message, position = 'top')` | On desktop, sets aria-label and hint--rounded / hint--position classes; does nothing on mobile. Later calls do not remove earlier direction classes |
|
||||
|
||||
HTML strings are not sanitized. Use textContent for plain text or escape for the intended context; do not pass untrusted content directly to append/getIcon.
|
||||
|
||||
### Events and measurement {#utils-measure}
|
||||
|
||||
| Utility | Behavior |
|
||||
| --- | --- |
|
||||
| `getComposedPath(event)` | Calls composedPath with its original receiver and returns its array directly. Otherwise walks target.parentNode and appends window in a browser. The fallback does not reproduce a complete Shadow DOM path |
|
||||
| `includeFromEvent(event, target)` | Tests membership in that path, rather than performing a separate DOM contains query |
|
||||
| `isInViewport(element, offset = 0)` | Tests rectangle/window intersection, including boundaries. It does not prove full visibility or lack of occlusion, and retains the historical offset calculation |
|
||||
| `getSafeAreaInsets()` | Attaches a temporary invisible node and reads numeric env(safe-area-inset-*) values, using zero for unparseable values. Removes the node on success or failure; requires document.body |
|
||||
| `supportsFlex()` | Only tests whether an element accepts display:flex, not whether layout works correctly |
|
||||
|
||||
### Subtitles, images, and files {#utils-resources}
|
||||
|
||||
| Utility | Behavior and ownership |
|
||||
| --- | --- |
|
||||
| `srtToVtt(text)` / `assToVtt(text)` | Synchronously return WebVTT text. The former normalizes milliseconds and some style markers; the latter extracts basic Dialogue timing/text. Neither is a full subtitle validator or ASS renderer |
|
||||
| `vttToBlob(text)` | Returns a text/vtt Blob URL, not a Blob. The caller must revoke the URL when finished |
|
||||
| `getExt(url)` | Removes query/fragment, trims and lowercases, then takes text after the last dot. Without a dot it returns the remaining string; no resource or MIME check |
|
||||
| `download(url, name)` | Creates, clicks, and removes a temporary download link. No completion result or guarantee the browser saves a file; does not revoke the input URL |
|
||||
| `loadImg(url, scale?)` | Resolves with a loaded HTMLImageElement. Falsy scale or1 returns the original image; other values use canvas/toBlob and load the scaled result. Its image.src is a caller-owned Blob URL that must be revoked after use |
|
||||
|
||||
`loadImg` does not set crossOrigin and has no public cancellation or timeout option. A cross-origin image can display while still making canvas unreadable. Image loading, canvas, or encoding failures reject the Promise. Successful listeners are removed; failure during scaling releases an already created Blob URL. Revoke a scaled result's src only after the page no longer needs it; the original image URL is not owned by this function.
|
||||
|
||||
### Data, errors, and scheduling {#utils-data}
|
||||
|
||||
| Utility | Behavior |
|
||||
| --- | --- |
|
||||
| `def(object, key, descriptor)` | Object.defineProperty itself, returning the original object. The root string-key overload's historical void return is not the runtime result |
|
||||
| `has(object, key)` / `get(object, key)` | Test own-property presence / retrieve an own descriptor, returning undefined if missing |
|
||||
| `mergeDeep(...objects)` | Creates a new top-level object using Object.keys. Two non-array objects merge recursively; two arrays use the historical concat/spread rule, which can flatten nested arrays in the latter array. Not a complete deep clone: unmerged values retain references. Cyclic merging is unsupported; __proto__ is stored as own data |
|
||||
| `clamp(number, a, b)` | Clamps between either ordering of endpoints; NaN remains NaN |
|
||||
| `secondToTime(seconds)` | Floors to mm:ss, or hh:mm:ss from one hour; hours can exceed two digits. Falsy inputs yield00:00. Does not additionally validate negative or nonfinite inputs |
|
||||
| `escape(text)` / `unescape(text)` | Only the five fixed entities for ampersand, angle brackets, and single/double quotes, in one pass. unescape is not a general HTML entity parser |
|
||||
| `capitalize(text)` | Uppercases only the first character |
|
||||
| `ArtPlayerError(message?, context?)` / `errorHandle(condition, message?)` | Error subclass named ArtPlayerError, with context used for supported stack capture / throw that error for falsy conditions, otherwise return the original value |
|
||||
| `silencePromise(value)` | If catch is callable, return the result of catching and consuming a rejection; otherwise return the value unchanged. Uses catch capability, not instanceof Promise; synchronous errors thrown by catch itself still propagate |
|
||||
| `sleep(milliseconds = 0)` | Resolves with undefined after a timer, without cancellation |
|
||||
| `debounce(callback, duration)` | Trailing call with the last arguments and call receiver. Ignores the historical context argument; wrapper returns undefined |
|
||||
| `throttle(callback, duration)` | Synchronous leading call, dropping calls during the wait without a trailing call. Preserves the call receiver; wrapper returns undefined |
|
||||
|
||||
Neither wrapper offers cancel/flush or automatic cancellation on player destruction. Throttle enters its waiting period only after the callback returns normally, preserving synchronous reentry and another attempt after a thrown error. Historical root return inference does not change this behavior.
|
||||
|
||||
```ts
|
||||
import Artplayer from 'artplayer/runtime';
|
||||
import type { Utils } from 'artplayer/runtime';
|
||||
|
||||
const utils: Utils = Artplayer.utils;
|
||||
const fragment = document.createDocumentFragment();
|
||||
const missing: HTMLVideoElement | null = utils.query<HTMLVideoElement>('video', fragment);
|
||||
const div = utils.createElement('div');
|
||||
const styled: HTMLDivElement = utils.setStyle(div, 'fontSize', '20px');
|
||||
const width: string = utils.getStyle(div, 'width', false);
|
||||
const invoke = utils.debounce(function (this: { value: number }, step: number) {
|
||||
this.value += step;
|
||||
}, 20);
|
||||
const returned: void = invoke.call({ value: 0 }, 1);
|
||||
void [missing, styled, width, returned];
|
||||
```
|
||||
|
||||
|
||||
## `scheme`
|
||||
|
||||
Returns the validation schema for player options.
|
||||
|
||||
Reference in new issue
Block a user