refactor(core): CORE-14 split typed settings and scope tree lifetimes

This commit is contained in:
Harvey Zhao committed 2026-09-11 06:49:04 +08:00
1 parent 697817eceb
commit 64d1939daa
51 files changed
+28144 -1519

No files matched your search

@@ -0,0 +1,543 @@
{
"task": "CORE-14",
"status": "partial",
"date": "2026-09-11",
"node": "v24.21.0",
"scope": "Typed specialized manager, root event ownership, animated layout recovery, add failure unlink and removal cleanup",
"files": {
"packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb",
"packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53",
"packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404",
"packages/artplayer/src/setting/index.ts": "5041441ae24cb3610fc28dba563fb3904dd007710423175373b36f47eefb95b2",
"packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d",
"packages/artplayer/src/setting/model.ts": "944006a0191b675a8d76605a0544d81409e1e63224332f4b56de43a5f1a3a173",
"packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a",
"packages/artplayer/src/setting/render.ts": "256c2561d28bac2e0af8bb81b971f62c180063928ecdd70782b6e0d035488d8f",
"packages/artplayer/src/setting/resources.ts": "4b1a9507ecb13833fe80e6afc5d8ee315bdd4aab7b4fe761491472fad937d71d",
"packages/artplayer/src/setting/selection.ts": "7664f73e31837fd0b8d22f7eb401877f04ab7fe3a972e4cb958e0f817ed3a92c",
"packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83",
"packages/artplayer/src/setting/types.ts": "12930e46c43b66803521403759dbdef658860e13006f8ac6f917d2fb1be96b5c",
"test/setting-model.test.js": "931bee643bea3cbd93927f7c9739a1bf559da5aaf58783d19b6898a092ba56bc",
"test/setting-layout.test.js": "a7da46075bd478182559b9af4817b128eb9f9c219b6032d77fd437370f2a3563",
"test/setting-resources.test.js": "8fbc541cfede17cc63a7c54f630fcad2eba91ad780172c56f8fbe774d1586cc8",
"test/types/setting-model.ts": "ba024ffeae26428d06f07f98f62f211db94ef8b259251f9f424a4203f1187c7b",
"test/types/setting-manager.ts": "27e3687a89909ea6f97aa842347cb8fbcd6f8ce5cf779a24d5dabad3eff8dc5c",
"test/browser/setting.spec.js": "b36e91e4ba96138db482f894a57307cb56e0f58d624861ff21841784275b9526",
"package.json": "82459e37eb54391bb73ebd84b1b27a3c37750d7cc2cd24607fc8f983f7342960"
},
"ci": {
"passed": 194,
"unit": 165,
"engineering": 4,
"baseline": 25,
"strictSourceFiles": 122,
"logSha256": "fdd702b63a53c1d973a1eca7010bb19181e7182596a8b0f86a8e557398c9db14"
},
"browser": {
"stats": {
"startTime": "2026-09-10T21:45:56.846Z",
"duration": 20664.667999999998,
"expected": 72,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"reportSha256": "9b38aef6211411133a08c75d7ca782d146331546d66833731cc6541394f950d0",
"candidate": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer\\src\\index.js"
},
"sha256": "dec3a08b4c185499fdddfd0ba91c33b2bbfb4cbba62b64b63c6ce1d52ad30e34",
"bytes": 256143
},
"versions": {
"chromium": "153.0.8010.12",
"firefox": "155.0",
"webkit": "26.6"
},
"cases": [
{
"title": "published: builtin setting subscriptions are replaced and removed with their row",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: deferred setting mounts belong to the rendered item generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: removed setting subtrees release child listeners and cached panels",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: setting button results cannot overwrite an updated or newer item",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: sibling setting selections share the parent result generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: setting callback rejection retains its original failure identity",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: builtin setting subscriptions are replaced and removed with their row",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: deferred setting mounts belong to the rendered item generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: removed setting subtrees release child listeners and cached panels",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting button results cannot overwrite an updated or newer item",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: sibling setting selections share the parent result generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting callback rejection retains its original failure identity",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: open settings follow container and control height changes with fallback=false",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: open settings follow container and control height changes with fallback=true",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: failed setting additions leave existing rows usable and allow retry",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: builtin setting subscriptions are replaced and removed with their row",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: deferred setting mounts belong to the rendered item generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: removed setting subtrees release child listeners and cached panels",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: setting button results cannot overwrite an updated or newer item",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: sibling setting selections share the parent result generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: setting callback rejection retains its original failure identity",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: builtin setting subscriptions are replaced and removed with their row",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: deferred setting mounts belong to the rendered item generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: removed setting subtrees release child listeners and cached panels",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting button results cannot overwrite an updated or newer item",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: sibling setting selections share the parent result generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting callback rejection retains its original failure identity",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: open settings follow container and control height changes with fallback=false",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: open settings follow container and control height changes with fallback=true",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: failed setting additions leave existing rows usable and allow retry",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: builtin setting subscriptions are replaced and removed with their row",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: deferred setting mounts belong to the rendered item generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: removed setting subtrees release child listeners and cached panels",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: setting button results cannot overwrite an updated or newer item",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: sibling setting selections share the parent result generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: setting callback rejection retains its original failure identity",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: builtin setting subscriptions are replaced and removed with their row",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: deferred setting mounts belong to the rendered item generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: removed setting subtrees release child listeners and cached panels",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting button results cannot overwrite an updated or newer item",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: sibling setting selections share the parent result generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting callback rejection retains its original failure identity",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: open settings follow container and control height changes with fallback=false",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: open settings follow container and control height changes with fallback=true",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: failed setting additions leave existing rows usable and allow retry",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws",
"engine": "webkit",
"status": "passed",
"retry": 0
}
]
},
"failures": [
{
"file": "refactor/.cache/core14-manager-browser.json",
"sha256": "9319f4023678b3cec40d5dcc617a86bd4ba1a5cb17e43fc485d576bf9ea645ed",
"stats": {
"startTime": "2026-09-10T21:34:14.601Z",
"duration": 30176.837,
"expected": 63,
"skipped": 0,
"unexpected": 3,
"flaky": 0
},
"reason": "ResizeObserver reads animated bottom before the final control-height offset"
},
{
"file": "refactor/.cache/core14-manager-layout-browser.json",
"sha256": "08dc1621f4e475f1f7b7e74e37d985330912bf8844316821d964b967deecc31f",
"stats": {
"startTime": "2026-09-10T21:40:47.436Z",
"duration": 29928.708,
"expected": 63,
"skipped": 0,
"unexpected": 3,
"flaky": 0
},
"reason": "Style observation alone still reads the transition starting value"
},
{
"file": "refactor/.cache/core14-manager-recovery-browser.json",
"sha256": "b519d98e1248894c606c6cf4faa54cfcda5f3da3a7d54874d9833527fb94fa29",
"stats": {
"startTime": "2026-09-10T21:44:13.564Z",
"duration": 20791.101000000002,
"expected": 69,
"skipped": 0,
"unexpected": 3,
"flaky": 0
},
"reason": "Fault injection used unregistered callbacks, which real Events.remove does not invoke"
}
],
"limits": [
"Source fixture validation only; final CORE-14 installed UMD and legacy validation remains outstanding",
"Transactional update and panel-render rollback, independent header cleanup and reentry remain unfinished",
"Cross-instance sharing/reuse, switch/range, long text and mobile/rotation still need coverage",
"No generic rollback of arbitrary getter/setter or Proxy side effects; failed new input may retain hidden metadata",
"Without ResizeObserver, external container resize requires the existing window/core resize signal",
"BASE-DOM-02/06/07 and BASE-LIFE-12/13/14 remain open"
]
}
@@ -0,0 +1,200 @@
{
"task": "CORE-14",
"status": "partial",
"scope": "Tree model and initial bounded layout only; manager/render/selection/resource migration is unfinished.",
"date": "2026-09-11",
"files": {
"packages/artplayer/src/setting/model.ts": "2486cf5b4dc68ca2bf23351eed2d0010506682324e4e1ac8f1c318ac2cc35163",
"packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d",
"packages/artplayer/src/setting/index.js": "6bf37e3c321200474d0b6c953ed923a52f399b32674930589bb38fd71f0c535c",
"test/setting-model.test.js": "bb1c4237646f128436450d5412a3202f6007831629f104c54dbcb025cd04d27a",
"test/setting-layout.test.js": "a7da46075bd478182559b9af4817b128eb9f9c219b6032d77fd437370f2a3563",
"test/types/setting-model.ts": "ba024ffeae26428d06f07f98f62f211db94ef8b259251f9f424a4203f1187c7b",
"test/browser/setting.spec.js": "498d4281b6373c456d64f4257b335cc7f72604577d5ead701a781ec2dad042b2",
"package.json": "900034e913876951a050e9d896d5b6b83871663d252a0fe602a5ed016fd8ebaa"
},
"ci": {
"passed": 187,
"unit": 158,
"engineering": 4,
"baseline": 25,
"strictSourceFiles": 112,
"logSha256": "6e3a59e7662709c0baad4f9474be3d3853df98f24b898a536945d24a8aa11775"
},
"browser": {
"stats": {
"startTime": "2026-09-10T21:08:42.006Z",
"duration": 13188.141,
"expected": 24,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"candidate": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer\\src\\index.js"
},
"sha256": "e2f0b26373cc8e9865eb326d9d8d4f62122307154c9dadbfdd78843c17bb1f2a",
"bytes": 248698
},
"versions": {
"chromium": "153.0.8010.12",
"firefox": "155.0",
"webkit": "26.6"
},
"cases": [
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "webkit",
"status": "passed",
"retry": 0
}
]
},
"limits": [
"Source fixture validation only; no final CORE-14 installed-package validation",
"Setting manager and builtin rendering remain JavaScript",
"Descendant/panel cleanup, obsolete callbacks, mounted timers and strict host integration remain pending",
"BASE-DOM-02/06/07 remain open",
"Mobile/rotation, long text and dynamic container changes require further browser coverage"
]
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,426 @@
{
"task": "CORE-14",
"status": "partial",
"scope": "Tree/layout plus rendering, callback generations, item resources and builtin TS migration; manager integration and failure rollback remain unfinished.",
"date": "2026-09-11",
"node": "v24.21.0",
"files": {
"packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb",
"packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404",
"packages/artplayer/src/setting/index.js": "50d1c640a18faa671368b94bd750a0c2b3cf57316c93439a4b2dbfe9c87e0426",
"packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d",
"packages/artplayer/src/setting/model.ts": "2486cf5b4dc68ca2bf23351eed2d0010506682324e4e1ac8f1c318ac2cc35163",
"packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a",
"packages/artplayer/src/setting/render.ts": "256c2561d28bac2e0af8bb81b971f62c180063928ecdd70782b6e0d035488d8f",
"packages/artplayer/src/setting/resources.ts": "8f0bbc4246ad5848fbd9bbd02c7eb9614ad64cd67615622995597a2eaae0f356",
"packages/artplayer/src/setting/selection.ts": "7664f73e31837fd0b8d22f7eb401877f04ab7fe3a972e4cb958e0f817ed3a92c",
"packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83",
"packages/artplayer/src/setting/types.ts": "81ad8ae3892510a2189bdd414b1743696bc713cccff8e4bc58eed24abcc99eac",
"test/setting-model.test.js": "bb1c4237646f128436450d5412a3202f6007831629f104c54dbcb025cd04d27a",
"test/setting-layout.test.js": "a7da46075bd478182559b9af4817b128eb9f9c219b6032d77fd437370f2a3563",
"test/setting-resources.test.js": "8fbc541cfede17cc63a7c54f630fcad2eba91ad780172c56f8fbe774d1586cc8",
"test/types/setting-model.ts": "ba024ffeae26428d06f07f98f62f211db94ef8b259251f9f424a4203f1187c7b",
"test/browser/setting.spec.js": "4c4c001b42fafeeeb1677b9d1b2d596af0591c6897a3882a93c1e84d1f56925e",
"package.json": "82459e37eb54391bb73ebd84b1b27a3c37750d7cc2cd24607fc8f983f7342960"
},
"ci": {
"passed": 193,
"unit": 164,
"engineering": 4,
"baseline": 25,
"strictSourceFiles": 120,
"logSha256": "8e49058f0d7c8f7565add94c0e94bc7c2e65242305854a0b932972ade7d26792"
},
"browser": {
"stats": {
"startTime": "2026-09-10T21:25:43.963Z",
"duration": 18728.229,
"expected": 60,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"candidate": {
"source": {
"kind": "workspace-build",
"entry": "packages\\artplayer\\src\\index.js"
},
"sha256": "2904030e8d84eca8678ecc6cedadb01af0ebffccae66a58ff0248800e66524c2",
"bytes": 252544
},
"versions": {
"chromium": "153.0.8010.12",
"firefox": "155.0",
"webkit": "26.6"
},
"cases": [
{
"title": "published: builtin setting subscriptions are replaced and removed with their row",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: deferred setting mounts belong to the rendered item generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: removed setting subtrees release child listeners and cached panels",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: setting button results cannot overwrite an updated or newer item",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: sibling setting selections share the parent result generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: setting callback rejection retains its original failure identity",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: builtin setting subscriptions are replaced and removed with their row",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: deferred setting mounts belong to the rendered item generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: removed setting subtrees release child listeners and cached panels",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting button results cannot overwrite an updated or newer item",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: sibling setting selections share the parent result generation",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting callback rejection retains its original failure identity",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "chromium",
"status": "passed",
"retry": 0
},
{
"title": "published: builtin setting subscriptions are replaced and removed with their row",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: deferred setting mounts belong to the rendered item generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: removed setting subtrees release child listeners and cached panels",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: setting button results cannot overwrite an updated or newer item",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: sibling setting selections share the parent result generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: setting callback rejection retains its original failure identity",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: builtin setting subscriptions are replaced and removed with their row",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: deferred setting mounts belong to the rendered item generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: removed setting subtrees release child listeners and cached panels",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting button results cannot overwrite an updated or newer item",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: sibling setting selections share the parent result generation",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting callback rejection retains its original failure identity",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "firefox",
"status": "passed",
"retry": 0
},
{
"title": "published: builtin setting subscriptions are replaced and removed with their row",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: deferred setting mounts belong to the rendered item generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: removed setting subtrees release child listeners and cached panels",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: setting button results cannot overwrite an updated or newer item",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: sibling setting selections share the parent result generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: setting callback rejection retains its original failure identity",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: setting registry retains item returns and hidden tree bindings",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: moved setting items bind to their current parent and panel",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "published: automatic setting names and explicit nested names have an explicit baseline",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: builtin setting subscriptions are replaced and removed with their row",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: deferred setting mounts belong to the rendered item generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: removed setting subtrees release child listeners and cached panels",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting button results cannot overwrite an updated or newer item",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: sibling setting selections share the parent result generation",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting callback rejection retains its original failure identity",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: a wide nested setting panel fits the narrow player and remains selectable",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: setting registry retains item returns and hidden tree bindings",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: moved setting items bind to their current parent and panel",
"engine": "webkit",
"status": "passed",
"retry": 0
},
{
"title": "candidate: automatic setting names and explicit nested names have an explicit baseline",
"engine": "webkit",
"status": "passed",
"retry": 0
}
]
},
"limits": [
"Source fixture validation only; no final CORE-14 installed-package validation",
"Setting manager remains JavaScript; its root subscriptions have not yet migrated",
"Atomic update/render failure, independent header cleanup and cross-instance reuse still require work",
"BASE-DOM-02/06/07 and BASE-LIFE-12/13/14 remain open",
"Dynamic layout, switch/range, long text and mobile/rotation still need additional coverage"
]
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,105 @@
# CORE-14 设置树、渲染与布局
状态:完成。设置目录的 TS 拆分、生命周期、失败恢复、布局和交互已通过最终安装包验收。以下各批记录保留当时的进度与失败原因,当前结论以末尾最终交付证据为准。
## 已接入的源码
setting/model.ts 管理树遍历、查找、结构预检、自动名称及父级绑定。setting/index.ts 的 traverse/format/find 委托该模型;仍保留按选项数组缓存面板的专用管理器,不把它强行套进 Control 返回类型。add/update 返回原条目、remove 返回 undefined、find 缺失返回 null;当前公开 d.ts 保持不变,BASE-TYPE-07 的兼容视图出口仍需 CORE-21 完成。
父级、所在数组、父级数组和事件列表保留非枚举、不可配置 getter;WeakMap 允许同一条目从旧父级移除后重新绑定,getter 函数及事件数组身份保持。遍历保留前序和回调期间添加子节点的可见性。正常显式名称和自动计数规则保留;自动名称遇到整树显式名称时跳过冲突 ID。重复名称、循环/重复条目或不可重定义的外来绑定先预检,不先给前面的条目写入元数据。外部任意 setter/Proxy 抛错的事务边界,以及同时跨活动实例共享同一条目对象,仍需随管理器和资源阶段核对,当前不宣称已覆盖。
setting/layout.ts 将尺寸计算与 DOM 测量分开,面板宽度不超过播放器扣除 padding 后的空间,高度限制在实际控件上方,可滚动访问嵌套内容。padding 从 bottom 的已计算样式读取,支持 CSS 单位解析;控件中心按播放器缩放换算。正常右侧溢出时保持旧 CSS right 锚点,移动端/旋转分支保留原定位策略。动态尺寸观察、长文本、旋转/移动端和完整旧新组合仍需继续验证。
## 首批验证与待办
新增 7 项模型与 3 项布局单元测试;类型正反例覆盖保留自定义字段、数字计数器和 nullable 查找。浏览器新旧对照覆盖条目返回/绑定、移动条目、名称冲突、320x180 的超宽嵌套面板及真实点击最后一项。初轮 24 项三浏览器通过并已检查旧新截图:旧面板裁切在容器外,候选可滚动选择。最终锚点兼容调整后,24 项专项复跑通过;yarn ci:check 共 187 项通过(158 单元、4 工程、25 基线),112 个生产 TS 文件严格检查。见 [阶段证据](../baselines/setting-model-layout-validation.json)。尚未完成整个 CORE-14 或安装包回归。
首批结束时计划迁移 manager/types、selection、render 与内置设置(第二批完成情况见下文),建立条目/面板作用域,处理删除子树、缓存面板更新、过期异步回调和 mounted 定时器。补充失败与重入、默认高亮、长文本、实际窄尺寸变化、旧插件交互,之后构建并验证安装 UMD/legacy、公开类型消费和最终文档。BASE-DOM-02 此时仍 open。
package.json 将 setting-model.test.js 与 setting-layout.test.js 纳入 test:unit;无新增依赖、锁文件或版本变更。任务未完成,尚不提交本任务,不推送或发布。
## 第二批:渲染、回调与条目资源
render.ts 保留 div/类名、item 的动态 html/icon/tooltip/switch/range 描述符、数据写入和条目身份;管理器入口继续转发 createHeader/createItem/render。selection.ts 保留原 callback this、item、DOM 与 Event,range 的同步值写入和选择 default 标志;按实际写入对象隔离异步结果,兄弟 selector 共用父项代次,更新/删除关闭旧条目作用域。原始失败用 console.warn 报告,不吞掉原异常身份。没有取消用户自己的异步 SDK 工作。
resources.ts 管理条目作用域、DOM 事件与内置 Emitter 订阅。删除/更新父项时递归释放子项并移除其 selector 数组对应的缓存面板;清理失败仍尝试其余事件。注册中重入销毁会释放刚返回的监听器。延迟 mounted 绑定本次条目与 DOM,移除/更新取消旧定时器;mounted 的同步失败或返回 Promise 拒绝会报告,不把其返回值当 disposer。
playbackRate/aspectRatio/flip/subtitleOffset 四个内置设置已迁移 TS;订阅随条目关闭。数值/字符串断言仅对应内置工厂自己创建的 selector 值,不改变运行时转换。6 项资源单元用例与新旧浏览器用例覆盖乱序、更新后写入、拒绝身份、子树缓存/监听器、延迟 mounted、订阅重复及移除。最终同步导航异常保护已通过单元及专项复验;设置专项 60 项三浏览器通过,CI 193 项通过(164 单元、4 工程、25 基线),120 个生产 TS 文件严格检查。见 [第二批阶段证据](../baselines/setting-resources-validation.json),该记录明确为 partial。
尚待:管理器转 TS 与专用继承类型边界;add/update/渲染失败时的对象、DOM、面板和监听器回滚;子面板 header 的独立失败清理;跨实例共享/复用和非扩展对象预检;动态尺寸观察、长文本、switch/range 与重入/销毁专项;完整核心/旧插件与最终 UMD/legacy 安装产物。不能用当前已通过专项替代这些剩余验收。
## 第三批:管理器、根事件与失败处理
index.ts 保留实际 Component 原型继承,用最小构造类型视图表达 Setting 自己的数组缓存及返回约定,没有通过双重断言伪装成通用组件。新增管理器类型正反例,验证 add 保留输入自定义字段、find 可为 null、remove 为 void。
events.ts 接管 blur/focus/resize 和尺寸观察,实例关闭后解绑。ResizeObserver 观察播放器与控件;MutationObserver 观察播放器 class/style,并在缺少 ResizeObserver 时补充控件变化。没有 ResizeObserver 的环境仍依赖已有 window/core resize 信号发现外部容器尺寸变化,不能宣称自动发现所有祖先 CSS 修改。
最初动态布局测试三浏览器均失败:宽度已收缩到 300px,但面板高度仍为 124px,目标为 78px。补上 style 观察后仍失败,证实只增加观察不够;设置面板 `transition: all` 使 getComputedStyle(bottom) 在回调时返回过渡起点。现在额外监听面板自身 bottom 的 transitionend,过渡结束后重算,保持现有动画。6 项原生观察/回退专项通过,随后完整设置专项 72 项通过;销毁后晚到观察与 resize 均不调用管理器。
第三批 yarn ci:check 194 项通过(165 单元、4 工程、25 基线),122 个生产 TS 文件严格检查;设置专项 72 项为当前工作区构建,三浏览器无重试、跳过或未处理异常。源码、报告、候选构建及失败记录指纹见 [第三批阶段证据](../baselines/setting-manager-validation.json),仍明确为 partial。
formatTree 新增非扩展对象和不可写自动名称预检,重复名称保持原 ArtPlayerError。add 失败移除本次追加位置;格式化成功后才释放新条目的部分渲染资源,避免无效共享子树触及已有监听器。remove 即使清理失败也继续移除原 DOM 并恢复根面板,再汇总异常。资源树释放有已访问集合,避免外部后续构造循环导致无限递归。
浏览器失败注入覆盖重复名称、同一对象/共享子项、不可扩展对象、html getter 抛错、渲染阶段抛错后的 mounted 取消、再次添加和旧条目可用性。移除失败测试的首版直接向 $events 塞入任意函数,但真实 Events.remove 只处理登记过的监听器,导致三项断言失败;现改为真实 art.proxy 登记与 event-removal 钩子注入,验证原错误身份、后续清理、DOM 删除和兄弟条目均正常。保留失败日志,不以假函数改变生产事件约定。
仍未解决的边界:update 的原对象/描述符/监听器事务恢复、面板创建失败后的缓存与 header 独立清理、重入时的归属以及跨活动实例共享条目。任意 getter/setter/Proxy 的外部副作用不能承诺通用回滚;失败后的新输入可能保留已安装的隐藏元数据。长文本、switch/range、移动端/旋转、完整旧插件组合和最终安装包仍需验收。前两批阶段记录保留当时源码路径与指纹,不改写为最新完成证据。
## 第四批:面板作用域与新面板渲染恢复
panels.ts 管理按选项数组缓存的面板作用域,条目作用域挂到所属面板;返回按钮由面板持有,并仍登记在父项的公开 $events 数组中。失败、删除子树或销毁时释放其监听器、延迟 mounted、缓存和 DOM。清理返回按钮时从原事件数组移除对应登记,不影响父项其他监听器,也不重复移除已被父项释放的监听器。
checkpoint.ts 不调用用户 getter,保存条目的原属性描述符及直接传入 html/icon/tooltip 的节点位置。新面板创建若在 header、条目或 resize 阶段抛错,释放部分面板,恢复原输入节点和描述符、之前活动面板以及 height/width/left/right,调用者仍收到原始错误。归属检查避免恢复已经由别的面板接管的条目;创建 header 时重入删除父项或销毁实例,后续条目不会继续创建。该阶段没有把这些保证扩展为所有 update 或任意用户重入均已解决。
新增 15 项三浏览器测试,覆盖三种失败阶段、失败后正常重试、原 DOM 节点身份与位置、mounted 不重复、父项监听器数量、返回按钮和删除后的迟到点击,以及 header 创建中的 remove/destroy 重入。设置专项共 87 项通过。初次测试在回滚后等待定时器才比较 style,与正常 ResizeObserver 后续布局混在一起,九项失败;分开记录同步回滚和下一轮布局后,证实同步恢复正确。布局失败注入钩子随后也需在同步调用结束后撤销,避免测试自己的异常污染异步观察器。保留两轮失败报告和前后样式附件,未放宽未处理错误检查。
第四批 CI 194 项通过(165 单元、4 工程、25 基线),124 个生产 TS 文件严格检查。完整工作区 UMD 三浏览器 429 项通过,含设置 87 项以及现有播放、切源、章节插件、全屏、生命周期等检查;无重试、跳过或未处理异常。专项与完整运行的候选构建指纹一致,见 [第四批阶段证据](../baselines/setting-panels-validation.json)。这是当前工作区构建证据,不能替代最终安装包和 legacy 验收。
仍需完成:已缓存面板切换及 update 的失败/重入恢复、跨实例条目复用、长文本与 switch/range、移动端/旋转、最终安装 UMD/legacy 回归和包指纹核对。CORE-14 继续 doing,风险尚未关闭,未提交本任务。
## 第五批:设置项 update 事务与重入
update.ts 保留原条目身份和返回值,在赋值前暂停旧子树,渲染成功后才释放旧资源。resources.ts 让暂停的作用域暂存旧监听器,公开 $events 数组身份不变,新一代登记写入原数组;activity.ts 阻止暂停期间的旧回调及异步写入。回滚恢复原监听器,不重新登记,也不重复执行已经运行的 mounted;成功则释放旧代,新代继续工作,销毁时两代都释放。
checkpoint.ts 保存框架管理的 switch/range 闭包状态,恢复 range 原数组引用、内容和原生 input 的边界、步进及值;DOM 检查点恢复实际旧节点及其属性,不用克隆节点替代原节点。赋值、整树校验、条目渲染或最终 render 失败时恢复这些受管理状态,调用者仍收到原错误。提交后若旧资源清理异常,保留已经成功的新行并报告清理错误,不假装已释放的旧资源还能恢复。
按 Reflect.ownKeys 的顺序读取可枚举自有字段,保留通常的 Object.assign 读写顺序,同时在每个用户读取/写入之后检查当前操作。重入新 update、remove、destroy 或后代 update 会终止旧操作;删除祖先先取消其后代的未完成更新。渲染持有自己的操作/作用域,旧 getter 在新行完成后继续返回或抛错,也不能覆盖新句柄或清理新行。任意自定义 setter/Proxy 的外部副作用,以及任意覆写方法在返回前自行发起的额外操作,不能承诺通用回滚。
4 项新增资源单元检查覆盖恢复原登记、只提交新代、销毁两代及清理异常仍恢复旧监听器。新增独立 setting-update.spec.js,覆盖四个失败阶段的 range/DOM/监听器身份、失败后重试、switch 显示状态、同项和父子重入、祖先删除,以及 icon/switch/range 渲染 getter 的重入。此前 87 项设置专项和第一轮新增 27 项均通过;扩展重入检查后的 123 项也通过。最后补充的控制句柄检查随本轮完整运行验证,以下阶段证据以最终完整运行指纹为准,不把较早专项当作最后源码的证据。
第五批最终 CI 198 项通过(169 单元、4 工程、25 基线),126 个生产 TS 文件严格检查;工作区 UMD 完整三浏览器 471 项通过,其中设置相关 129 项,无重试、跳过或未处理异常。见 [第五批阶段证据](../baselines/setting-update-validation.json),包含最终源码/测试/构建和报告指纹。尚未运行本任务最终安装包和 legacy 验收。
仍需完成:直接切换已缓存面板时的失败恢复、跨实例共享/复用、长文本与完整 switch/range 交互、移动端/旋转、最终安装 UMD/legacy 与打包类型验收。当前公开 d.ts 未变,CORE-14 仍 doing,不关闭风险、不提交未完成任务。
## 第六批:缓存导航恢复与实例归属
render 的缓存分支现在也处理 resize 失败,恢复之前的活动面板及布局属性,保留缓存 DOM 和监听器。每次导航有独立代次;失败前若重入导航、删除面板或销毁实例,外层失败不再覆盖较新的结果。导航专项最初三项失败源于测试假定根面板与子面板尺寸必不相同,实际两者此时均为两行;活动面板和 class 断言证明重入导航正确,尺寸相等不是回滚的证据。修正该断言并保留初轮报告。
实际旧/新对照复现 BASE-DOM-08:同一条目给两台活动播放器使用,旧发布版的第二台没有条目,但第一台仍可点击;归属保护前的候选会重新绑定到第二台并释放第一台监听器。现在整树预检拒绝仍由另一活动树持有的条目,抛出 ArtPlayerError,两个树及先前监听器都不修改。没有静默克隆条目,因为那会改变 add/update 返回原对象及回调引用约定。此前这种共享本身不能正常显示两台播放器,因此登记为旧缺陷修正;同时显示时使用各自的条目对象,回调函数仍可共用。
owner 状态不直接保存播放器或 manager 对象,销毁时清空树和作用域引用,避免绑定保留旧实例。关闭中的作用域也视为非活动;旧树 remove 或实例 destroy 后,原条目/子树可交给另一实例使用,父级绑定随之更新,隐藏 getter 与 $events 数组身份保留,原实例晚到清理不会影响新实例。新增两项模型单元和 24 项归属/导航三浏览器检查,均通过;包含冲突 add 不改旧树、原对象移交、旧节点迟到点击及新回调 this。
第六批最终 CI 200 项通过(171 单元、4 工程、25 基线),126 个生产 TS 文件严格检查;工作区 UMD 完整三浏览器 495 项通过,其中设置相关 153 项,无重试、跳过或未处理异常。见 [第六批阶段证据](../baselines/setting-ownership-validation.json),保留旧/新共享对象的初始诊断和最终构建指纹。
仍需完成长文本、完整 switch/range 原生交互、移动端/旋转,以及 CORE-14 最终安装 UMD/legacy、类型消费和文件指纹验收。BASE-DOM-08 与其他 CORE-14 风险保持 open,任务保持 doing。
## 第七批:原生交互、长文本与旋转
setting-interaction.spec.js 使用真实键盘与指针事件核对 range 的 input/change 次序、每次同步值、回调 this/条目/DOM 与最终 tooltip,并用真实点击切换 switch。移动 UA/视口与触摸事件结合本地视频和实际内置 autoOrientation,验证正常与旋转状态的嵌套菜单滚动和最后一项选择;没有把这些测试标成实体手机验收。
长文本初轮在三个引擎复现控件被挤出行内,旧版与候选都存在。setting.less 让标签与提示缩短显示,给原生控件及图标保留宽度,并保留左右内容间隔;文本仍完整保留在 DOM。已检查旧/新长文本和旋转截图,新版 range/switch 可见且可通过键盘/指针操作。交互专项 18 项通过;额外 add 重入检查合入后,交互与更新两组共 66 项通过。
收尾审查补上 registration.ts:外层 add 的 getter 在内层成功 add/update 同一对象后抛错时,旧操作不能移除新行。记录新的注册归属,remove/update 使旧注册失效;保留外层原始异常及内层成功结果。最终打包验收将覆盖最新源码,不以此前局部运行替代它。
本任务的完整浏览器矩阵指仓库现有核心、历史核心及章节插件组合和契约套件;全部生态包/SDK 的专项迁移与最终发布矩阵仍由对应后续任务负责。BASE-TYPE-07 保持开放至 CORE-21 的兼容公开类型出口,CORE-14 不伪造运行时返回值来迁就旧声明。
## 最终交付证据
- yarn ci:check:200 项通过(171 单元、4 工程、25 基线),127 个生产 TS 文件严格检查;核心 122、chapter 5。
- 核心构建与 i18n 生成成功。核心/chapter 实际 tarball 仓库外安装:27 项运行时、五组类型零诊断。
- 实际安装 UMD 与 legacy 各 519 项三浏览器通过,其中各含 177 项设置相关检查;无重试、跳过、flaky 或未处理页面异常。
- [最终验证记录](../baselines/setting-validation.json) 核对全部核心源码与构建快照、三个分发格式与 tarball/docs/compiled、公开声明、包内架构文档、22 个语言文件和独立分发许可。阶段失败与原始旧行为记录仍保留。
- legacy 首次启动时,临时映射中的包路径被重复拼接,服务尚未启动即失败;已改为 Resolve-Path 得到的绝对产物路径,保留启动失败日志。最终验收核对实际映射的包内字节,不把启动失败计作通过或测试重试。
- 关闭 BASE-DOM-02/06/07/08 与 BASE-LIFE-12/13/14。BASE-TYPE-07 保留给 CORE-15/18/21 等公开类型后续责任;本任务不改变旧公开声明来掩盖实际 item/null/void 返回。
- 移动端检查采用真实引擎、触摸事件、模拟 UA/视口和实际 autoOrientation,未宣称实体设备、全部外部 SDK、远端 CI 或完整生态发布验收。
本任务独立本地提交,不推送或发布。当前 214 项中 50 完成、164 待办;下一项 CORE-15 字幕获取、解析和渲染。
+2 -2
View File
@@ -5,7 +5,7 @@
## 现状证据
- [入口](../packages/artplayer/src/index.js)顺序构造所有子系统;[player](../packages/artplayer/src/player/index.js)通过 mixin 将属性安装到 art。
- [Component](../packages/artplayer/src/utils/component.ts)负责控件缓存、DOM 和监听器;[Setting](../packages/artplayer/src/setting/index.js)还有独立的树、渲染和更新语义。
- [Component](../packages/artplayer/src/utils/component.ts)负责控件缓存、DOM 和监听器;[Setting](../packages/artplayer/src/setting/index.ts)还有独立的树、渲染和更新语义。
- [Events](../packages/artplayer/src/events/index.js)集中管理一部分 DOM 监听器,但定时器、异步请求和内部 Emitter 订阅仍由各模块管理。
- [声明](../packages/artplayer/types/artplayer.d.ts)与源码独立维护;[build-ts](../scripts/build-ts.js)进行文本拼接。
@@ -20,7 +20,7 @@
| 媒体能力 | template、proxy、player | 内部精确的能力接口与原生视频类型分离;公共 video 兼容层保留 |
| 播放流程 | play/pause/toggle/seek/url/switch/eventInit | 媒体状态、操作身份、加载恢复与 UI 响应分离 |
| UI 注册 | utils/component、control、layer、contextmenu | 保留 name/cache/update/remove;明确 DOM 和绑定的归属 |
| 设置面板 | setting/index.js | 分开树整理、选择状态、渲染、布局、绑定;共享能共享的逻辑,不强行统一返回类型 |
| 设置面板 | setting/index.ts | 分开树整理、选择状态、渲染、布局、绑定;共享能共享的逻辑,不强行统一返回类型 |
| 字幕 | subtitle.js、utils/subtitle.js | 获取、解析、track/DOM 渲染、取消和对象 URL 回收分开 |
| 显示模式 | fullscreen/fullscreenWeb/pip/mini/auto* | 显式恢复位置和样式,保持互斥顺序、用户手势与移动端语义 |
| 输入 | events、hotkey | 鼠标/触控/键盘/焦点归属清晰,跨 document 重新绑定和清理 |
+3 -2
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。
状态:todo 165 / doing 0 / blocked 0 / done 49 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 164 / doing 0 / blocked 0 / done 50 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -117,7 +117,7 @@
| CORE-11 | artplayer<br>整理媒体事件、ready 与重连 | CORE-10 | 媒体转发、重连、UI 响应职责分离 | readiness 次数/顺序、过期重连、原错误参数有回归 | H | done |
| CORE-12 | artplayer<br>迁移模板及公开资源入口 | CORE-06, CORE-04, BASE-04 | template/icons/i18n/style、SSR 与 proxy 挂载 | DOM/CSS/global/样式注入、i18n 子路径及 SSR import 保持;不把 SSR import/useSSR 保持扩大为服务端构造播放器;复跑 BASE-05 的 SSR import/模板、浏览器 useSSR 节点复用和非浏览器构造错误;接续 VENDOR-01/02,核对 screenfull/hint 复制版本、修改与分发通知,保留 DOM/CSS/fullscreen 行为 | H | done |
| CORE-13 | artplayer<br>迁移组件注册与控件 | CORE-12, CORE-08 | Component/control/layer/contextmenu 的资源与 TS 边界 | add/update/remove、name、selector、mounted/beforeUnmount 通过;处理 BASE-DOM-02 窄容器控件裁切,保留 controls.update 的旧 undefined 返回值 | H | done |
| CORE-14 | artplayer<br>拆分设置树、渲染和布局 | CORE-13 | setting model/selection/render/layout 的分批实现 | 不强行统一控件返回值,嵌套选择、默认高亮、更新清理通过;结合 BASE-DOM-02 验证窄容器设置定位;接续 BASE-TYPE-07 的 find null、add/update item、remove undefined 声明冲突 | H | todo |
| CORE-14 | artplayer<br>拆分设置树、渲染和布局 | CORE-13 | setting model/selection/render/layout 的分批实现 | 不强行统一控件返回值,嵌套选择、默认高亮、更新清理通过;结合 BASE-DOM-02 验证窄容器设置定位;接续 BASE-TYPE-07 的 find null、add/update item、remove undefined 声明冲突 | H | done |
| CORE-15 | artplayer<br>迁移字幕获取、解析和渲染 | CORE-11, CORE-13 | subtitle 请求/track/DOM/URL 生命周期与类型 | 过期结果、偏移、cue 数组、原生全屏及错误路径通过;接续 BASE-TYPE-07 的真实 cue 数组与旧隐式 scalar 回调声明兼容 | H | todo |
| CORE-16 | artplayer<br>迁移全屏、PiP、mini 与尺寸模式 | CORE-11, CORE-12 | 显示模式服务和原公开属性门面 | 模式互斥/恢复位置、手势权限、移动方向和退出失败通过 | H | todo |
| CORE-17 | artplayer<br>迁移键盘、手势、焦点和全局事件 | CORE-13, CORE-16 | events/hotkey 的明确 document 与资源归属 | 跨 document 重绑、触摸/键盘、快捷键及销毁无重复响应;修复 BASE-PERF-01 pending resize debounce 销毁后执行,并验证正常 resize 不变 | H | todo |
@@ -448,6 +448,7 @@
- CORE-11: [记录](changes/2026-09-11-CORE-11-media-events.md) [记录](baselines/media-events-validation.json)
- CORE-12: [记录](changes/2026-09-11-CORE-12-template-resources.md) [记录](baselines/template-resources-validation.json)
- CORE-13: [记录](changes/2026-09-11-CORE-13-components.md) [记录](baselines/components-validation.json)
- CORE-14: [记录](changes/2026-09-11-CORE-14-setting.md) [记录](baselines/setting-validation.json)
- PKG-CHAPTER-01: [记录](changes/2026-09-10-PKG-CHAPTER-01-contract.md) [记录](baselines/chapter-contract.md)
- PKG-CHAPTER-02: [记录](changes/2026-09-10-PKG-CHAPTER-02-tests.md) [记录](baselines/chapter-validation.json)
- PKG-CHAPTER-03: [记录](changes/2026-09-10-PKG-CHAPTER-03-typescript-modules.md) [记录](baselines/chapter-migration-validation.json)
+8
View File
@@ -1,5 +1,13 @@
# 进度与证据
## 当前实施:CORE-14 设置树、渲染与布局完成
设置目录迁移为 17 个 TS 模块,拆清树模型、渲染、布局、选择、条目/面板资源、更新事务、注册代次与根事件;保留原对象和返回约定,修复失效回调、残留订阅、失败恢复、跨实例绑定抢占及长文本控件裁切。
CI 200 项通过,核心 122 个与 chapter 5 个生产 TS 文件严格检查;实际安装 UMD 与 legacy 各 519 项三浏览器通过,其中各含 177 项设置检查。真实 tarball 27 项运行时及五组类型零诊断;源码、三个格式、公开类型、包内文档、语言及许可指纹一致。见 [交付](changes/2026-09-11-CORE-14-setting.md) 和 [最终证据](baselines/setting-validation.json)。
关闭 BASE-DOM-02/06/07/08、BASE-LIFE-12/13/14,公开返回声明差异 BASE-TYPE-07 保持开放。当前 214 项,50 完成、164 待办;下一项 CORE-15 字幕获取、解析和渲染。本任务独立本地提交,未推送或发布。
## 当前实施:CORE-13 组件注册与控件完成
Component/control/layer/contextmenu 与 qualityMix 迁移 TS,拆清注册、DOM、资源、选择生命周期、进度交互和布局;修复移除后残留订阅、失败注册与重入清理、过期选择写入、selector 重用和文本属性注入。正常回调/排序/别名/描述符保持,controls.add/update 仍返回 undefined。
+7 -1
View File
@@ -11,7 +11,7 @@
| BASE-LIFE-04 | resolved / 已复现 | Destroying an instance twice unregisters a different live instance | CORE-04 |
| BASE-LIFE-05 | resolved / 已复现 | Failed constructor leaves initialized markup/listeners until explicit probe cleanup | CORE-04 |
| BASE-DOM-01 | open / 已复现 | 控件 Tab 不可达 | CORE-23, CORE-17 |
| BASE-DOM-02 | open / 已复现 | 窄容器中控件裁切 | CORE-13, CORE-14 |
| BASE-DOM-02 | resolved / 已复现 | 窄容器中控件裁切 | CORE-13, CORE-14 |
| BASE-DEMO-01 | open / 源码/产物事实 | 旧 thumbnail 插件示例不对应当前 workspace 包 | SITE-01, EX-03 |
| BASE-TYPE-01 | resolved / 已复现 | NodeNext ESM 默认导出与声明互操作失配 | ENG-04, CORE-07, PKG-CHAPTER-04 |
| BASE-TYPE-02 | resolved / 已复现 | chapter 可选运行时参数被声明为必填 | PKG-CHAPTER-02 |
@@ -62,3 +62,9 @@
| BASE-DOM-03 | resolved / 已复现 | Reusing selector items after update redefines nonconfigurable properties | CORE-13 |
| BASE-DOM-04 | resolved / 已复现 | A component named __proto__ changes its registry prototype | CORE-13 |
| BASE-DOM-05 | resolved / 已复现 | Highlight text interpolation permits unintended HTML attributes | CORE-13 |
| BASE-DOM-06 | resolved / 已复现 | Moved setting items retain parent and option bindings from the old tree | CORE-14 |
| BASE-DOM-07 | resolved / 已复现 | Generated setting names collide with explicit names in nested branches | CORE-14 |
| BASE-LIFE-12 | resolved / 已复现 | Removed or updated setting rows retain descendant panels and builtin subscriptions | CORE-14 |
| BASE-LIFE-13 | resolved / 已复现 | Obsolete setting callback completions overwrite current UI and failures are unhandled | CORE-14 |
| BASE-LIFE-14 | resolved / 已复现 | Removed or replaced setting items still run deferred mounted callbacks | CORE-14 |
| BASE-DOM-08 | resolved / 已复现 | Sharing a live setting object leaves a second published instance blank and can steal candidate bindings | CORE-14 |
+177 -3
View File
@@ -161,7 +161,7 @@
"id": "BASE-DOM-02",
"title": "窄容器中控件裁切",
"confirmation": "reproduced",
"status": "open",
"status": "resolved",
"owners": [
"CORE-13",
"CORE-14"
@@ -171,7 +171,18 @@
],
"compatibleResolution": "在保留自定义控件扩展入口下修正布局。",
"closureCriteria": "320px 及正常容器的设置/模式操作真实可用。",
"workspaceState": "CORE-13 final installed UMD and legacy verify wrapped controls at 640/320/240px with real 16:9 heights and observed total-height offsets, including ResizeObserver fallback. Narrow setting tree/panel interactions still require CORE-14; this finding remains open."
"workspaceState": "CORE-13 wrapped controls and CORE-14 bounded settings/native input/autoOrientation checks now pass the final installed UMD and legacy matrices; 320px layouts remain operable with long text and wrapped control rows.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-14-setting.md",
"refactor/baselines/setting-validation.json",
"test/browser/setting.spec.js",
"test/browser/setting-update.spec.js",
"test/browser/setting-ownership.spec.js",
"test/browser/setting-interaction.spec.js",
"test/setting-model.test.js",
"test/setting-resources.test.js"
],
"resolutionRationale": "Final installed UMD and legacy each pass the complete 519-case three-engine matrix. Managed tree/DOM/resource rollback, async generation guards, scoped mounts and panel/header ownership preserve normal identities, callbacks and returns. Narrow layouts and native input/touch interactions pass; simultaneous live object sharing fails before mutation while transfer after removal/destruction preserves the original object. Source and shipped package bytes match the tested artifacts."
},
{
"id": "BASE-DEMO-01",
@@ -888,7 +899,8 @@
],
"compatibleResolution": "Keep legacy consumers; add explicit cue-array listener overloads, type internal implementations accurately, and resolve remaining generated/public facade contracts at CORE-21 without false intersections.",
"closureCriteria": "Actual setting/null/void and notice boolean returns, cue array callbacks and old legal type consumers all have an explicit compatible declaration strategy and package tests.",
"scopeNote": "CORE-07 provides runtime evidence and explicit cue-array overloads; old inferred scalar event callbacks and return signatures are not claimed corrected."
"scopeNote": "CORE-07 provides runtime evidence and explicit cue-array overloads; old inferred scalar event callbacks and return signatures are not claimed corrected.",
"workspaceState": "CORE-14 source manager accurately models add/update item, remove void and missing find null; installed historical public consumers still compile. Public declaration coordination remains open for CORE-15/18/21."
},
{
"id": "BASE-TYPE-08",
@@ -1132,6 +1144,168 @@
"test/component-resources.test.js"
],
"resolutionRationale": "Published/candidate behavior comparisons and both final installed artifact matrices pass. Entry ownership, transactional registration/removal, current selection guards and literal text assignment correct reproduced defects while retaining normal callbacks, return values, descriptors and public declarations. Source and shipped bytes match the tested package."
},
{
"id": "BASE-DOM-06",
"title": "Moved setting items retain parent and option bindings from the old tree",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-14"
],
"evidence": [
"test/browser/setting.spec.js",
"test/setting-model.test.js",
"refactor/changes/2026-09-11-CORE-14-setting.md"
],
"compatibleResolution": "Preserve hidden getter flags and identity while rebinding a removed item to its current parent/panel.",
"closureCriteria": "Final Setting migration, cleanup, strict types and installed UMD/legacy regressions must pass. Source-only model results do not close this task.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-14-setting.md",
"refactor/baselines/setting-validation.json",
"test/browser/setting.spec.js",
"test/browser/setting-update.spec.js",
"test/browser/setting-ownership.spec.js",
"test/browser/setting-interaction.spec.js",
"test/setting-model.test.js",
"test/setting-resources.test.js"
],
"resolutionRationale": "Final installed UMD and legacy each pass the complete 519-case three-engine matrix. Managed tree/DOM/resource rollback, async generation guards, scoped mounts and panel/header ownership preserve normal identities, callbacks and returns. Narrow layouts and native input/touch interactions pass; simultaneous live object sharing fails before mutation while transfer after removal/destruction preserves the original object. Source and shipped package bytes match the tested artifacts."
},
{
"id": "BASE-DOM-07",
"title": "Generated setting names collide with explicit names in nested branches",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-14"
],
"evidence": [
"test/browser/setting.spec.js",
"test/setting-model.test.js",
"refactor/changes/2026-09-11-CORE-14-setting.md"
],
"compatibleResolution": "Reserve explicit names before allocating IDs; preserve normal names and monotonic counters.",
"closureCriteria": "Final Setting migration, cleanup, strict types and installed UMD/legacy regressions must pass. Source-only model results do not close this task.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-14-setting.md",
"refactor/baselines/setting-validation.json",
"test/browser/setting.spec.js",
"test/browser/setting-update.spec.js",
"test/browser/setting-ownership.spec.js",
"test/browser/setting-interaction.spec.js",
"test/setting-model.test.js",
"test/setting-resources.test.js"
],
"resolutionRationale": "Final installed UMD and legacy each pass the complete 519-case three-engine matrix. Managed tree/DOM/resource rollback, async generation guards, scoped mounts and panel/header ownership preserve normal identities, callbacks and returns. Narrow layouts and native input/touch interactions pass; simultaneous live object sharing fails before mutation while transfer after removal/destruction preserves the original object. Source and shipped package bytes match the tested artifacts."
},
{
"id": "BASE-LIFE-12",
"title": "Removed or updated setting rows retain descendant panels and builtin subscriptions",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-14"
],
"evidence": [
"test/browser/setting.spec.js",
"test/setting-resources.test.js",
"refactor/changes/2026-09-11-CORE-14-setting.md"
],
"compatibleResolution": "Own DOM/Emitter subscriptions per rendered item and release descendants and cached panels on update/removal.",
"closureCriteria": "Finish manager/resource rollback and verify strict source types, full installed UMD/legacy and builtin/legacy plugin combinations before closure.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-14-setting.md",
"refactor/baselines/setting-validation.json",
"test/browser/setting.spec.js",
"test/browser/setting-update.spec.js",
"test/browser/setting-ownership.spec.js",
"test/browser/setting-interaction.spec.js",
"test/setting-model.test.js",
"test/setting-resources.test.js"
],
"resolutionRationale": "Final installed UMD and legacy each pass the complete 519-case three-engine matrix. Managed tree/DOM/resource rollback, async generation guards, scoped mounts and panel/header ownership preserve normal identities, callbacks and returns. Narrow layouts and native input/touch interactions pass; simultaneous live object sharing fails before mutation while transfer after removal/destruction preserves the original object. Source and shipped package bytes match the tested artifacts."
},
{
"id": "BASE-LIFE-13",
"title": "Obsolete setting callback completions overwrite current UI and failures are unhandled",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-14"
],
"evidence": [
"test/browser/setting.spec.js",
"test/setting-resources.test.js",
"refactor/changes/2026-09-11-CORE-14-setting.md"
],
"compatibleResolution": "Preserve callback arguments and synchronous state; only the latest live write target may accept completion, and report the original failure.",
"closureCriteria": "Finish manager/resource rollback and verify strict source types, full installed UMD/legacy and builtin/legacy plugin combinations before closure.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-14-setting.md",
"refactor/baselines/setting-validation.json",
"test/browser/setting.spec.js",
"test/browser/setting-update.spec.js",
"test/browser/setting-ownership.spec.js",
"test/browser/setting-interaction.spec.js",
"test/setting-model.test.js",
"test/setting-resources.test.js"
],
"resolutionRationale": "Final installed UMD and legacy each pass the complete 519-case three-engine matrix. Managed tree/DOM/resource rollback, async generation guards, scoped mounts and panel/header ownership preserve normal identities, callbacks and returns. Narrow layouts and native input/touch interactions pass; simultaneous live object sharing fails before mutation while transfer after removal/destruction preserves the original object. Source and shipped package bytes match the tested artifacts."
},
{
"id": "BASE-LIFE-14",
"title": "Removed or replaced setting items still run deferred mounted callbacks",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-14"
],
"evidence": [
"test/browser/setting.spec.js",
"test/setting-resources.test.js",
"refactor/changes/2026-09-11-CORE-14-setting.md"
],
"compatibleResolution": "Bind deferred mounted to its rendered generation and cancel obsolete timers without introducing a disposer return contract.",
"closureCriteria": "Finish manager/resource rollback and verify strict source types, full installed UMD/legacy and builtin/legacy plugin combinations before closure.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-14-setting.md",
"refactor/baselines/setting-validation.json",
"test/browser/setting.spec.js",
"test/browser/setting-update.spec.js",
"test/browser/setting-ownership.spec.js",
"test/browser/setting-interaction.spec.js",
"test/setting-model.test.js",
"test/setting-resources.test.js"
],
"resolutionRationale": "Final installed UMD and legacy each pass the complete 519-case three-engine matrix. Managed tree/DOM/resource rollback, async generation guards, scoped mounts and panel/header ownership preserve normal identities, callbacks and returns. Narrow layouts and native input/touch interactions pass; simultaneous live object sharing fails before mutation while transfer after removal/destruction preserves the original object. Source and shipped package bytes match the tested artifacts."
},
{
"id": "BASE-DOM-08",
"title": "Sharing a live setting object leaves a second published instance blank and can steal candidate bindings",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-14"
],
"evidence": [
"test/browser/setting-ownership.spec.js",
"test/setting-model.test.js",
"refactor/changes/2026-09-11-CORE-14-setting.md"
],
"compatibleResolution": "Reject transfer from an active owner before mutating either tree; allow original-object reuse after removal or destruction, preserving item return identity and immutable getters.",
"closureCriteria": "Retain the published sharing baseline and candidate ownership diagnosis; verify rejection, both owner lifetimes, subtree reuse, full strict checks and final installed UMD/legacy matrices before closure.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-14-setting.md",
"refactor/baselines/setting-validation.json",
"test/browser/setting.spec.js",
"test/browser/setting-update.spec.js",
"test/browser/setting-ownership.spec.js",
"test/browser/setting-interaction.spec.js",
"test/setting-model.test.js",
"test/setting-resources.test.js"
],
"resolutionRationale": "Final installed UMD and legacy each pass the complete 519-case three-engine matrix. Managed tree/DOM/resource rollback, async generation guards, scoped mounts and panel/header ownership preserve normal identities, callbacks and returns. Narrow layouts and native input/touch interactions pass; simultaneous live object sharing fails before mutation while transfer after removal/destruction preserves the original object. Source and shipped package bytes match the tested artifacts."
}
]
}
+5 -2
View File
@@ -1009,11 +1009,14 @@
"dependsOn": [
"CORE-13"
],
"status": "todo",
"status": "done",
"risk": "H",
"deliverable": "setting model/selection/render/layout 的分批实现",
"acceptance": "不强行统一控件返回值,嵌套选择、默认高亮、更新清理通过;结合 BASE-DOM-02 验证窄容器设置定位;接续 BASE-TYPE-07 的 find null、add/update item、remove undefined 声明冲突",
"evidence": []
"evidence": [
"changes/2026-09-11-CORE-14-setting.md",
"baselines/setting-validation.json"
]
},
{
"id": "CORE-15",