fix(multiple-subtitles): [PKG-MULTI-SUB-08] preserve entity text and semantic cue wrappers

This commit is contained in:
Harvey Zhao committed 2026-09-14 12:14:21 +08:00
1 parent 4acf85ea69
commit 675b095b27
22 files changed
+744 -59

No files matched your search

@@ -0,0 +1,351 @@
{
"task": "PKG-MULTI-SUB-08",
"date": "2026-09-14",
"baselineCommit": "4acf85ea696a99f05fce71089711bc4a4ca0d5b6",
"node": "v24.21.0",
"yarn": "1.22.22",
"platform": "win32",
"before": {
"artifact": {
"path": "refactor/.cache/multiple-subtitles-entities-before.js",
"sha256": "8ad5ddfa1ee1d79f7183b7a5fade748ca2093ceba7b467ec19b5b79ad129a249"
},
"initial": {
"path": "refactor/.cache/multi-entities-before.log",
"sha256": "cbe8d2bbb32db2682856e35ede9dd5600e9280b04efa148d2f75aea69b8eb716",
"passed": 0,
"failed": 5
},
"final": {
"path": "refactor/.cache/multi-entities-before-final.log",
"sha256": "0c56f858e5b0b42fb208f7505423b85a2013385bedf84aa9bb5f2749b3c71682",
"passed": 3,
"failed": 8
}
},
"sources": [
{
"path": "packages/artplayer-plugin-multiple-subtitles/src/merge.ts",
"sha256": "e41514f3a62833d9e42bee20e693b5a13fb42cfb3ea2a08f0821bbcb2d450cfd"
},
{
"path": "packages/artplayer-plugin-multiple-subtitles/src/text.ts",
"sha256": "15660d74726e36831939799d72e8126ede3e3becd22ba9cc2127db4277171d0f"
}
],
"tests": [
{
"path": "test/multiple-subtitles-entities.test.js",
"sha256": "23ff2ca0561a26347bb2602c1fb69b34bf5d664ad23c5c8877bccb383e66861e"
},
{
"path": "test/multiple-subtitles-merge.test.js",
"sha256": "c7a7ac447ad76e559d5710a590054599412806db6f4282fd2a856fa05092f533"
},
{
"path": "test/multiple-subtitles-failures.test.js",
"sha256": "d987af07a2c42ade51c6bd7b8eb2441191e748e5ddf7f3be5cbf4809a8be034f"
},
{
"path": "test/browser/multiple-subtitles-entities.spec.js",
"sha256": "cdc9dfc23900761c8110581ee81ad9f17c5796e03190c154b21cbdcb686c806e"
}
],
"vendor": {
"unchangedFromBaseline": true,
"sha256LF": "ba582074d57fa2d72880e6e4253fe14646787916b2b68e2a1e748e685cf96ab1",
"check": {
"provenance": {
"revision": "380cfcce34ba8b472d3a31474874eb72a0e5f460",
"packageVersionAtRevision": "2.1.2",
"scope": "Pinned comparison revision, not proof of historical acquisition commit. After removing IIFE/global exportify and adding named ESM exports, normalized executable content matches local parser.",
"sources": [
{
"file": "refactor/baselines/multiple-subtitles-vendor/parser.txt",
"upstream": "https://raw.githubusercontent.com/w3c/webvtt.js/380cfcce34ba8b472d3a31474874eb72a0e5f460/parser.js",
"sha256": "35a112e585b7cb1b4fd30350b0e8c8f6d1efa2670a6008c4a6038e07c9f8d727"
},
{
"file": "refactor/baselines/multiple-subtitles-vendor/license.txt",
"upstream": "https://raw.githubusercontent.com/w3c/webvtt.js/380cfcce34ba8b472d3a31474874eb72a0e5f460/LICENSE.md",
"sha256": "6cc655a5df52fefac69058311c090f4e70b7c37b8f6488f9498420a930b8275d"
},
{
"file": "refactor/baselines/multiple-subtitles-vendor/package.json.txt",
"upstream": "https://raw.githubusercontent.com/w3c/webvtt.js/380cfcce34ba8b472d3a31474874eb72a0e5f460/package.json",
"sha256": "d0102b9276839f1136ecafd9527102a28b44643e8ff403b3ddb1e51c04777a7b"
}
]
},
"normalizedSha256": "e71dc5073db409dcb8eef66a0d6bfe6c8d96fa7d157ff51a68decf6f05a7c80f",
"localSha256LF": "ba582074d57fa2d72880e6e4253fe14646787916b2b68e2a1e748e685cf96ab1",
"noticesSha256LF": "50755f38458d41151c7f0b1675c744aa365f0510dc11f53832691ef5c14ce6b6"
}
},
"results": [
{
"path": "refactor/.cache/multi-entities-suite-final.log",
"sha256": "2d38f2518283940e4d898823093a0959f6095c82883d97b1726874e20209beec",
"passed": 294,
"failed": 0,
"skipped": 0
},
{
"path": "refactor/.cache/multi-entities-main.log",
"sha256": "9eec0b8e567456842a4678da1ce57099c8c2faba98e0cc42b2d85e290afd037b",
"passed": 11,
"failed": 0,
"skipped": 0
},
{
"path": "refactor/.cache/multi-entities-legacy.log",
"sha256": "9eeb325f9df16ab584a8f722c4e31cc92411f776061d4ad5252bfcabbb830673",
"passed": 11,
"failed": 0,
"skipped": 0
},
{
"path": "refactor/.cache/multi-entities-ci.log",
"sha256": "c37a11d7fc5dca6e2dc84f308611fd26653a10d6b6528b62063f4aea5ccc58e6",
"passed": 50,
"failed": 0,
"skipped": 0
}
],
"browsers": [
{
"path": "refactor/.cache/multi-entities-source-browser/report.json",
"sha256": "accb4d48bda22f45b1ea8ece707532dbdc84bc31b65b787340ad1bf77b5fe4a3",
"stats": {
"startTime": "2026-09-14T04:03:29.211Z",
"duration": 50430.384999999995,
"expected": 42,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"observations": [
{
"project": "chromium",
"core": "published",
"browser": "153.0.8010.12",
"pluginSha256": "475afec2cd440de885520c6aee4165a7453fce8e03a920a7d809b8fe93db510c",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "chromium",
"core": "candidate",
"browser": "153.0.8010.12",
"pluginSha256": "475afec2cd440de885520c6aee4165a7453fce8e03a920a7d809b8fe93db510c",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "firefox",
"core": "published",
"browser": "155.0",
"pluginSha256": "475afec2cd440de885520c6aee4165a7453fce8e03a920a7d809b8fe93db510c",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "firefox",
"core": "candidate",
"browser": "155.0",
"pluginSha256": "475afec2cd440de885520c6aee4165a7453fce8e03a920a7d809b8fe93db510c",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "webkit",
"core": "published",
"browser": "26.6",
"pluginSha256": "475afec2cd440de885520c6aee4165a7453fce8e03a920a7d809b8fe93db510c",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "webkit",
"core": "candidate",
"browser": "26.6",
"pluginSha256": "475afec2cd440de885520c6aee4165a7453fce8e03a920a7d809b8fe93db510c",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
}
],
"scope": "Source entity and lifecycle tests; final equivalent wrapper loop separately covered by full Node and actual artifact browser run"
},
{
"path": "refactor/.cache/multi-entities-artifact-browser/report.json",
"sha256": "0f8d3c53fd5616814ee9bf9cba1afb197dd3b956c0b5e84a8ce9cb390fcc1140",
"stats": {
"startTime": "2026-09-14T04:07:08.987Z",
"duration": 15602.046,
"expected": 6,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"observations": [
{
"project": "chromium",
"core": "published",
"browser": "153.0.8010.12",
"pluginSha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "chromium",
"core": "candidate",
"browser": "153.0.8010.12",
"pluginSha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "firefox",
"core": "published",
"browser": "155.0",
"pluginSha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "firefox",
"core": "candidate",
"browser": "155.0",
"pluginSha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "webkit",
"core": "published",
"browser": "26.6",
"pluginSha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
},
{
"project": "webkit",
"core": "candidate",
"browser": "26.6",
"pluginSha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b",
"native": [
"A & < > ‎ ‏   | <b>literal</b> | &lt;",
"bold & safe tail <i>"
],
"literal": "A & < > ‎ ‏   | <b>literal</b> | &lt;",
"scope": "Actual native VTT and HTML caption display, playback, selection/reset; desktop browser engines only"
}
],
"scope": "Actual main UMD, published/candidate core, native fragment and HTML caption text"
}
],
"artifacts": [
{
"path": "packages/artplayer-plugin-multiple-subtitles/dist/artplayer-plugin-multiple-subtitles.js",
"sha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b",
"docs": {
"path": "docs/compiled/artplayer-plugin-multiple-subtitles.js",
"sha256": "e2192514ab4836a04c56420fa8c260efa657e2afa32f299d0cf7786c91adc39b"
}
},
{
"path": "packages/artplayer-plugin-multiple-subtitles/dist/artplayer-plugin-multiple-subtitles.legacy.js",
"sha256": "6e3716ea5e70a028b4fdb6648d1f8be151364bd6fd798719e3a5809924457c6e",
"docs": {
"path": "docs/compiled/artplayer-plugin-multiple-subtitles.legacy.js",
"sha256": "6e3716ea5e70a028b4fdb6648d1f8be151364bd6fd798719e3a5809924457c6e"
}
},
{
"path": "packages/artplayer-plugin-multiple-subtitles/dist/artplayer-plugin-multiple-subtitles.mjs",
"sha256": "8d1f36140e6c4ca64d6330621fd421f1323ed9fb58434a797cfa2afae6205b39",
"docs": {
"path": "docs/compiled/artplayer-plugin-multiple-subtitles.mjs",
"sha256": "8d1f36140e6c4ca64d6330621fd421f1323ed9fb58434a797cfa2afae6205b39"
}
}
],
"checks": [
{
"path": "refactor/.cache/multi-entities-types.log",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"exitCode": 0
},
{
"path": "refactor/.cache/multi-entities-build.log",
"sha256": "d352d68782fddd9e62989746c6e4f1a8e0310069115f6d779bdd13663cddfbfc",
"exitCode": 0
},
{
"path": "refactor/.cache/multi-entities-lint-final.log",
"sha256": "c5b143fd109b076988b84670ce8fc536d4069edf71a512ad2990f926c63baaa1",
"exitCode": 0
},
{
"path": "refactor/.cache/multi-entities-final.log",
"sha256": "e3bd33003aa4d5b47edd8da0966a1830656a4279e3b1cf519541e11bff9509ba",
"exitCode": 0
}
],
"initialLintFailure": {
"path": "refactor/.cache/multi-entities-lint-initial.log",
"sha256": "9202a274e0cca24968f932d2fac2a31ba602f652897d083b454573042bd68772"
},
"scope": [
"Fix six existing named entities via configured vendor table; preserve lenient aliases and vendor body",
"Escape literal cue text through existing onVttLoad pipeline; wrap semantic nodes outside annotation fields",
"Nine historical implementations still reproduce entity and malformed-tag defects",
"Public types, factory alias, Promise/selection ordering unchanged",
"Desktop Windows engines only; full old-core/device/distribution gates remain tasks05/06",
"No new dependency, lock/version change, push or publication"
]
}
@@ -0,0 +1,79 @@
# PKG-MULTI-SUB-08: entity text and semantic tag wrapping
Baseline: 4acf85ea696a99f05fce71089711bc4a4ca0d5b6. This independent correction
precedes task05's complete core/combination acceptance; it does not complete that
task or publication readiness.
## Old behavior and corrections
Nine historical implementations reproduce `&lt;`/`&gt;`/`&amp;` decoding with stray
semicolons. The vendor's default table contains bare keys, while its exact-match
branch looks for the semicolon-terminated key and falls through to partial-match
handling. `text.ts` supplies both forms for the six existing named entities using
the parser's already-supported constructor option. Bare/partial-name aliases,
numeric references and unknown-reference handling retain the existing parser path.
No upstream/vendor execution body or provenance snapshot is edited.
Correctly decoded text must remain literal after the existing onVttLoad unescape.
Text values therefore receive a separate escaping layer before the serializer
protects the complete VTT. Literal `<b>` and timestamp-shaped text remain visible
text; `&amp;lt;` displays `&lt;` rather than decoding repeatedly. Real b/i/c/v/ruby
cue nodes remain semantic nodes, and inline timestamps retain their numeric data.
Related tag coverage exposed a second historical bug: the old merge assigned an
HTML wrapper to a semantic node's annotation field, yielding output such as
`<b <div ...>undefined</div>>bold</b>`. Nine historical implementations now reproduce
that exact malformed structure separately. Merge wraps prepared nodes with sibling
opening/closing text nodes instead. CSS hooks remain `.art-subtitle-<name>`; markup
annotations are preserved and source trees are still immutable across selections.
Plain-text/timing output remains byte-matched outside these intentional fixes.
## Structure, compatibility and ownership
- `text.ts`: entity configuration and literal-text protection through the two
existing serialization/HTML stages. It introduces no browser API or dependency.
- `merge.ts`: recursively prepare text/timestamp/object nodes and wrap top-level
nodes without changing annotations. A simple loop avoids requiring Array.flatMap
in older environments. Parsing/selection order and original cue times remain.
- Vendor parser/serializer, request/lifetime/render/caption code, public types,
factory/default alias, tracks/reset, Promise behavior and distribution paths
are unchanged. This is an authored adapter around a frozen vendor, not a vendor
upgrade or an unexplained relaxation of its fingerprint check.
There are no new resources or lifetime responsibilities. Existing download, URL,
destroy/restart and host-error checks still apply. Corrected entity/tag output is
an intentional bug fix; malformed attributes and visible semicolons are not kept
as compatibility requirements. Tests formerly comparing those erroneous serialized
bytes move to explicit corrected text/markup expectations. Raw ampersands and
malformed angle text retain a separate actual-old-versus-current visible-output
comparison. No historical failure fixture is rewritten to pretend old releases
were correct.
## Verification
Source/log/artifact hashes and actual counts are in
[multiple-subtitles-entities-validation.json](../baselines/multiple-subtitles-entities-validation.json).
- The initial5 entity/rendering tests fail against the frozen pre-change bundle.
The final expanded11-case file is rerun against both old and new artifacts.
- Full package suite294 passes, including11 focused cases, immutable tree and
timestamps,9 historical entity failures,9 historical malformed-tag failures,
actual release contracts/types and complete unchanged vendor parity/notices.
- Windows source browser suite42 passes: entity/markup native VTT and HTML display
on published/candidate cores, plus existing playback, SRT, timestamps, selection,
source replacement and cleanup. An early implementation used flatMap; the final
equivalent loop has full Node coverage and actual built-browser verification.
- Production main/legacy artifacts each run the focused Node suite; actual main
also runs entity display in all3 engines on both core variants. UMD/legacy/ESM
and matching docs copies are regenerated using the normal build.
- Strict package TypeScript passes. Initial Unicode escape casing/list formatting
lint errors are corrected; final root lint has only its one existing docs type
warning. CI and final plan/risk checks are recorded separately.
This is desktop engine evidence, not physical Safari/mobile, all historical core
versions or a remote CI run. Complete core combinations remain task05, distribution
and demo acceptance task06. No lockfile, dependency, public declaration or version
change. The package architecture and test maintenance documentation explain the
adapter and corrected behavior. Revert the dedicated task08 commit, including
generated outputs, to restore the prior implementation. Local commit only; no
push or npm publication.
+6 -4
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 246 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 247 项,范围 22 个包及工作区/示例。
状态:todo 56 / doing 16 / blocked 0 / done 174 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 56 / doing 16 / blocked 0 / done 175 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -28,7 +28,7 @@
| artplayer-plugin-document-pip | 1.1.0 | PKG-DPIP-01, PKG-DPIP-02, PKG-DPIP-03, PKG-DPIP-04, PKG-DPIP-05, PKG-DPIP-06 |
| artplayer-plugin-hls-control | 1.1.0 | PKG-HLS-01, PKG-HLS-02, PKG-HLS-03, PKG-HLS-04, PKG-HLS-SDK-01, PKG-HLS-05, PKG-HLS-06 |
| artplayer-plugin-jassub | 1.1.0 | PKG-JASSUB-01, PKG-JASSUB-02, PKG-JASSUB-03, PKG-JASSUB-04, PKG-JASSUB-05, PKG-JASSUB-06, PKG-JASSUB-07, PKG-JASSUB-08, PKG-JASSUB-09 |
| artplayer-plugin-multiple-subtitles | 1.2.0 | PKG-MULTI-SUB-01, PKG-MULTI-SUB-02, PKG-MULTI-SUB-03, PKG-MULTI-SUB-04, PKG-MULTI-SUB-07, PKG-MULTI-SUB-05, PKG-MULTI-SUB-06 |
| artplayer-plugin-multiple-subtitles | 1.2.0 | PKG-MULTI-SUB-01, PKG-MULTI-SUB-02, PKG-MULTI-SUB-03, PKG-MULTI-SUB-04, PKG-MULTI-SUB-07, PKG-MULTI-SUB-08, PKG-MULTI-SUB-05, PKG-MULTI-SUB-06 |
| artplayer-plugin-vast | 1.2.0 | PKG-VAST-01, PKG-VAST-02, PKG-VAST-03, PKG-VAST-04, PKG-VAST-05, PKG-VAST-06 |
| artplayer-plugin-vtt-thumbnail | 1.1.0 | PKG-VTT-THUMB-01, PKG-VTT-THUMB-02, PKG-VTT-THUMB-03, PKG-VTT-THUMB-04, PKG-VTT-THUMB-05, PKG-VTT-THUMB-06 |
| artplayer-proxy-canvas | 1.1.0 | PKG-AMBILIGHT-PROXY-01, PKG-CANVAS-01, PKG-CANVAS-02, PKG-CANVAS-03, PKG-CANVAS-04, PKG-CANVAS-05, PKG-CANVAS-06, PKG-FACTORY-01 |
@@ -226,7 +226,8 @@
| PKG-MULTI-SUB-03 | artplayer-plugin-multiple-subtitles<br>整理内部职责与资源 | PKG-MULTI-SUB-02, CORE-15 | 解析与合并/获取/渲染分离,过期请求及对象 URL 清理 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
| PKG-MULTI-SUB-04 | artplayer-plugin-multiple-subtitles<br>迁移自有源码和公开类型 | PKG-MULTI-SUB-03, ENG-04, ENG-06, CORE-07 | 准确 parser/cue/tree/result 类型与真实异步形状 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
| PKG-MULTI-SUB-07 | artplayer-plugin-multiple-subtitles<br>修复字幕内嵌时间戳序列化 | PKG-MULTI-SUB-03 | 保留数字时间戳节点、修正无效 NaN 输出、明确旧/新字幕输出差异 | 旧九份实现可复现,候选有效内嵌时间戳及文字/CSS/原生字幕通过,公开工厂与选择接口不变 | H | done |
| PKG-MULTI-SUB-05 | artplayer-plugin-multiple-subtitles<br>验证新旧核心和组合 | PKG-MULTI-SUB-04, CORE-22, PKG-MULTI-SUB-07 | 与核心字幕/偏移/全屏组合,旧名称调用不变 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-MULTI-SUB-08 | artplayer-plugin-multiple-subtitles<br>修复字幕实体解码与嵌套标签包装 | PKG-MULTI-SUB-04, PKG-MULTI-SUB-07 | 使用解析器既有实体表入口修复多余分号;保护字面文本并以兄弟节点包装标签,保留CSS钩子和时间戳 | 冻结旧实现复现、实体/双重编码/标签/选择重置回归、新旧核心真实字幕显示通过;vendor原文与来源校验不变,类型/分发兼容 | M | done |
| PKG-MULTI-SUB-05 | artplayer-plugin-multiple-subtitles<br>验证新旧核心和组合 | PKG-MULTI-SUB-04, CORE-22, PKG-MULTI-SUB-07, PKG-MULTI-SUB-08 | 与核心字幕/偏移/全屏组合,旧名称调用不变 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-MULTI-SUB-06 | artplayer-plugin-multiple-subtitles<br>验证分发并同步文档 | PKG-MULTI-SUB-05, ENG-07 | multiple.subtitles.js、parser 来源许可及打包边界 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
## 5 包迁移:artplayer-plugin-jassub
@@ -552,6 +553,7 @@
- PKG-MULTI-SUB-03: [记录](baselines/multiple-subtitles-resources.json) [记录](changes/2026-09-13-PKG-MULTI-SUB-03-resources.md)
- PKG-MULTI-SUB-04: [记录](baselines/multiple-subtitles-runtime-types.json) [记录](changes/2026-09-13-PKG-MULTI-SUB-04-runtime-types.md) [记录](baselines/multiple-subtitles-public-types.json) [记录](changes/2026-09-13-PKG-MULTI-SUB-04-public-types.md) [记录](type-compatibility-policy.md) [记录](baselines/multiple-subtitles-approved-types.json) [记录](changes/2026-09-13-PKG-MULTI-SUB-04-approved-types.md)
- PKG-MULTI-SUB-07: [记录](baselines/multiple-subtitles-timestamps.json) [记录](changes/2026-09-13-PKG-MULTI-SUB-07-timestamps.md)
- PKG-MULTI-SUB-08: [记录](changes/2026-09-14-PKG-MULTI-SUB-08-entities.md) [记录](baselines/multiple-subtitles-entities-validation.json)
- PKG-JASSUB-01: [记录](baselines/jassub-release.json) [记录](baselines/jassub-vendor.json) [记录](baselines/jassub-font-metadata.json) [记录](baselines/jassub-contract.md) [记录](baselines/jassub-contract-validation.json) [记录](changes/2026-09-13-PKG-JASSUB-01-baseline.md) [记录](baselines/jassub-provenance.json) [记录](baselines/jassub-provenance-validation.json) [记录](changes/2026-09-14-PKG-JASSUB-01-provenance.md)
- PKG-JASSUB-02: [记录](changes/2026-09-14-PKG-JASSUB-02-failure-baseline.md) [记录](baselines/jassub-failures-validation.json)
- PKG-JASSUB-03: [记录](changes/2026-09-14-PKG-JASSUB-03-registration.md) [记录](baselines/jassub-registration-validation.json)
+13
View File
@@ -1,5 +1,18 @@
# 进度与证据
## PKG-MULTI-SUB-08 字幕实体与标签包装完成
通过解析器既有实体表入口修复标准命名实体后多余分号,保留原始vendor文件与
来源校验;独立转义字面文本,避免实体形式的标签/时间戳被再次解释。同步修复
把包装节点塞进b等标签注释字段的问题,改为节点外包装,保留CSS钩子与时间戳。
九套历史实现分别复现两类旧缺陷,最终11项新用例在旧bundle中8红3绿,候选及
实际main/legacy各11项全绿。完整插件294项、源码浏览器42项、实际main浏览器
6项、CI50项通过;严格TS与vendor校验通过,lint 1既有warning。三格式与docs
副本正常重建,公开类型/依赖/版本未改。详见[记录](changes/2026-09-14-PKG-MULTI-SUB-08-entities.md)
和[证据](baselines/multiple-subtitles-entities-validation.json)。关闭实体与标签包装
风险,247项变为175 done、16 doing、56 todo;这不完成全部旧核心/真机/分发
验收,下一步继续任务05组合验证。独立本地提交,无推送/发布。
## PKG-AUTO-THUMB-10 编码归属与取消时限完成
JPEG编码拆为独立TS模块,原来帧等待结束后编码无时限,现有独立30秒编码时限。
+2 -1
View File
@@ -201,7 +201,7 @@
| MULTI-SUB-HTTP-01 | resolved / 已复现 | HTTP error responses with parseable bodies are installed as subtitles | PKG-MULTI-SUB-03, PKG-MULTI-SUB-05 |
| MULTI-SUB-HOST-01 | resolved / 已复现 | Subtitle init rejections are ignored and failed installation or URL replacement leaks or invalidates resources | PKG-MULTI-SUB-03, PKG-MULTI-SUB-05 |
| MULTI-SUB-TIMESTAMP-01 | resolved / 已复现 | Text wrappers replace numeric inline cue timestamps and serialize NaN times | PKG-MULTI-SUB-07, PKG-MULTI-SUB-05 |
| MULTI-SUB-ENTITY-01 | open / 已复现 | Vendored cue entity decoding retains semicolons after lt, gt and amp entities | PKG-MULTI-SUB-05 |
| MULTI-SUB-ENTITY-01 | resolved / 已复现 | Vendored cue entity decoding retains semicolons after lt, gt and amp entities | PKG-MULTI-SUB-05, PKG-MULTI-SUB-08 |
| JASSUB-TYPE-01 | open / 已复现 | JASSUB declared required URLs, Promise methods and resize parameter order differ from actual historical behavior | PKG-JASSUB-04 |
| JASSUB-EXPORT-01 | open / 已复现 | JASSUB historical CommonJS object.default changes to a direct factory in 1.1.0 | PKG-JASSUB-04, PKG-JASSUB-06 |
| CORE-DEFAULTS-SSR-01 | resolved / 已复现 | Reading static defaults throws when navigator is absent | CORE-25 |
@@ -264,3 +264,4 @@
| SCAFFOLD-OUTPUT-01 | resolved / 已复现 | Plugin generation overwrites existing examples and links to a different example name | MOD-PLUGIN-01 |
| DEV-SERVOR-PORT-01 | resolved / 已复现 | Servor exits the entire dev process with status zero when the requested port is occupied | MOD-DEV-01 |
| AUTO-THUMB-ENCODE-TIMEOUT-01 | resolved / 源码/产物事实 | Pending JPEG encoding has no bounded lifetime after frame readiness finishes | PKG-AUTO-THUMB-10 |
| MULTI-SUB-MARKUP-01 | resolved / 已复现 | Semantic cue nodes receive HTML wrappers inside their annotation fields | PKG-MULTI-SUB-08 |
+36 -5
View File
@@ -4521,17 +4521,26 @@
"id": "MULTI-SUB-ENTITY-01",
"title": "Vendored cue entity decoding retains semicolons after lt, gt and amp entities",
"confirmation": "reproduced",
"status": "open",
"status": "resolved",
"owners": [
"PKG-MULTI-SUB-05"
"PKG-MULTI-SUB-05",
"PKG-MULTI-SUB-08"
],
"evidence": [
"test/multiple-subtitles-failures.test.js",
"refactor/baselines/multiple-subtitles-timestamps.json",
"refactor/changes/2026-09-13-PKG-MULTI-SUB-07-timestamps.md"
"refactor/changes/2026-09-13-PKG-MULTI-SUB-07-timestamps.md",
"refactor/changes/2026-09-14-PKG-MULTI-SUB-08-entities.md",
"refactor/baselines/multiple-subtitles-entities-validation.json"
],
"compatibleResolution": "Independently fix valid named-entity decoding, documenting the vendor patch and preserving provenance checks and ordinary cue behavior.",
"closureCriteria": "Nine historical implementations reproduce the defect; candidate entity/markup regressions and real subtitle display pass, with vendor adaptation and provenance documentation updated."
"compatibleResolution": "Supply exact named entities through the existing parser constructor option, preserve historical lenient aliases and the frozen vendor body, and protect literal text through serialization/unescape.",
"closureCriteria": "Nine historical implementations reproduce the defect; candidate entity/markup regressions and real subtitle display pass, with vendor adaptation and provenance documentation updated.",
"workspaceState": "Nine historical implementations retain stray semicolons; candidate table adapter and text escaping fix six named references, double encoding and literal tags. Actual native VTT and HTML display pass in all3 Windows engines on published/candidate cores. Complete historical-core/device combinations remain task05.",
"resolutionEvidence": [
"refactor/changes/2026-09-14-PKG-MULTI-SUB-08-entities.md",
"refactor/baselines/multiple-subtitles-entities-validation.json"
],
"resolutionRationale": "Eleven focused cases,294 package tests,42 source browser and6 actual built-main browser cases pass. The parser executable body is unchanged and its full upstream adaptation/notices checks remain enforced; the authored configuration adapter resolves the plugin defect without a vendor patch."
},
{
"id": "JASSUB-TYPE-01",
@@ -5962,6 +5971,28 @@
"test/browser/auto-thumbnail-lifecycle.spec.js"
],
"resolutionRationale": "Nine controlled cases and real native JPEG tests cover held/late callbacks and decoder/canvas disposal. Actual production UMD passes11 Node and9 browser checks; previous preview survives timeout. Very slow encoding can now be discarded explicitly; public options, registration and frame-time formula remain intact."
},
{
"id": "MULTI-SUB-MARKUP-01",
"title": "Semantic cue nodes receive HTML wrappers inside their annotation fields",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"PKG-MULTI-SUB-08"
],
"evidence": [
"test/multiple-subtitles-failures.test.js",
"refactor/changes/2026-09-14-PKG-MULTI-SUB-08-entities.md",
"refactor/baselines/multiple-subtitles-entities-validation.json"
],
"compatibleResolution": "Wrap prepared cue nodes with sibling opening/closing nodes, retaining annotations, CSS hooks, nested timestamps and escaped literal text.",
"closureCriteria": "Nine historical implementations reproduce malformed b attributes and undefined text; candidate tag/text/selection/reset and real published/candidate core display pass.",
"workspaceState": "Nine frozen implementations serialize malformed b attributes containing an undefined wrapper. Authored merge now wraps nodes outside annotations. Vendor and public types are unchanged.",
"resolutionEvidence": [
"refactor/changes/2026-09-14-PKG-MULTI-SUB-08-entities.md",
"refactor/baselines/multiple-subtitles-entities-validation.json"
],
"resolutionRationale": "Historical regressions retain old output; corrected b/c/v/ruby and text cases plus actual b/literal-tag native/HTML display pass. Immutable trees, timestamps and lifecycle tests remain green."
}
]
}
+22 -1
View File
@@ -2377,6 +2377,26 @@
"changes/2026-09-13-PKG-MULTI-SUB-07-timestamps.md"
]
},
{
"id": "PKG-MULTI-SUB-08",
"phase": "5 包迁移:artplayer-plugin-multiple-subtitles",
"title": "修复字幕实体解码与嵌套标签包装",
"scope": [
"artplayer-plugin-multiple-subtitles"
],
"dependsOn": [
"PKG-MULTI-SUB-04",
"PKG-MULTI-SUB-07"
],
"status": "done",
"risk": "M",
"deliverable": "使用解析器既有实体表入口修复多余分号;保护字面文本并以兄弟节点包装标签,保留CSS钩子和时间戳",
"acceptance": "冻结旧实现复现、实体/双重编码/标签/选择重置回归、新旧核心真实字幕显示通过;vendor原文与来源校验不变,类型/分发兼容",
"evidence": [
"changes/2026-09-14-PKG-MULTI-SUB-08-entities.md",
"baselines/multiple-subtitles-entities-validation.json"
]
},
{
"id": "PKG-MULTI-SUB-05",
"phase": "5 包迁移:artplayer-plugin-multiple-subtitles",
@@ -2387,7 +2407,8 @@
"dependsOn": [
"PKG-MULTI-SUB-04",
"CORE-22",
"PKG-MULTI-SUB-07"
"PKG-MULTI-SUB-07",
"PKG-MULTI-SUB-08"
],
"status": "todo",
"risk": "H",