## 目标与边界 将 AKSRT 前台 DOM 架构一次性硬切换为 `C:\Users\Xing\Desktop\zibll` 的真实架构: ```text WordPress 配置/_win → jQuery → Bootstrap → runtime/loader.js → tbquire(['main']) → main.js 顶层全局委托 + window.auto_fun() → 局部 AJAX:post_ajax.ed → JSON AJAX:zib_ajax.success → 远程 modal:loaded.bs.modal → auto_fun() ``` 不保留 `AksrtFrontend`、不写兼容适配器、不做双路初始化、不保留“迁移中”分支。保留 AKSRT 的业务能力和安全处理,但全部挂到参考主题的唯一 `main/auto_fun` owner 上。按用户要求只做静态、契约、VM、语法和构建验证,不做真实视觉验收。 ## 一、运行时入口硬切换 1. **重写 `assets/js/runtime/loader.js`** - 以参考主题 loader 为行为基准,恢复 RequireJS 改名运行时、`tbquire.config()` 和最后的 `tbquire(['main'])`。 - 根据 AKSRT 实际目录调整 `baseUrl` 与 URL 版本参数,但保持参考主题的加载语义和 module mapping 结构。 - 将当前仍有业务消费者的模块纳入 mapping:main、imgbox、page-navs、section-navs、comment、message、input-expand、mini-upload、page-template、page-edit、author、poster-share、captcha、pay、swiper、dplayer、lazySizes、clipboard、svg-icon、enlighter、translate 等;每个 mapping 只指向一个真实文件,不复制第二份实现。 - 删除当前仅为 `AksrtFrontend`/`aksrt.tbquire` 服务的映射和 fallback。 2. **重写 `assets/js/runtime/main.js`** - 以参考主题 `zibll/js/main.js` 的全局顺序为骨架:顶层建立 `_win.bd`/`_win.window`,注册 body/document 委托,定义全局 API 与插件,定义 `z_auto_fun`,暴露 `window.auto_fun = debounce(z_auto_fun, 100)`,顶层首次调用 `auto_fun()`,最后执行单一 `$(document).ready(...)` 首屏逻辑。 - 将 AKSRT 当前 `aksrt-runtime.js` 中仍需要的 declarative action、确认、通知、上传/安全/站点功能直接并入该唯一运行时或对应 `tbquire` 模块,不再通过第二个 runtime 注册表调用。 - 将所有按 DOM 条件加载逻辑集中到 `z_auto_fun()`:支付、消息、输入扩展、上传、海报分享、验证码、复制、tooltip、popover、affix、Swiper、DPlayer、SVG、代码高亮、灯箱等,严格按参考主题调用 `tbquire()`。 - 删除 `AksrtFrontend.register('aksrt-legacy-main', ...)`、`window.auto_fun` 到 `AksrtFrontend.rehydrate()` 的 wrapper、`z_auto_fun()` 中对新 registry 的依赖。 - 将原先局部更新后的 `AksrtFrontend.rehydrate(root, 'ajax'/'modal')` 全部改为参考主题调用顺序:注入完成后触发 `post_ajax.ed`(列表场景)或 `loaded.bs.modal`(远程 modal),随后调用防抖 `auto_fun()`。 - 保留必要的幂等 class/data 标记(如 `is-on`、`swiper-container-initialized`、`dplayer-initialized`),但删除无法再被调用的 registry 保护代码。 3. **删除新生命周期核心** - 删除 `assets/js/rehydrate.js`。 - 将 `assets/js/aksrt-runtime.js` 中仍需的实际业务行为迁移到 `runtime/main.js` 或对应按需模块后,删除该文件及其作为公共入口的职责;不得留下空壳 `aksrt-runtime` 适配层。 - 清理所有 `AksrtFrontend.register/boot/rehydrate`、`aksrt.autoFun`、`aksrt:ready`、`aksrt:rehydrated` 引用和注释。 ## 二、公共构建与 PHP 入队重构 1. **调整 `tools/build-public-assets.mjs`** - 不再把整个 canonical 模块集合拼成一个 `public.js` 再依赖 `AksrtFrontend`。 - 以参考主题的独立 loader + 独立动态模块为构建图;对仍需生成的压缩文件只从唯一源码生成,避免 source/min 双 owner。 - 保留 CSS bundle 构建;JS 构建只生成 loader/main 及实际 mapping 所需的 min 产物。 - 生成后执行静态顺序检查,确保 loader 先于 main 动态加载,且没有 `tbquire(['main'])` 之外的第二个 boot。 2. **调整 `src/Core/Scripts.php`、`ScriptsPart1b.php`、`ScriptsPart1c.php` 及 WidgetSystem AssetManager** - 前台基础依赖改为 jQuery → Bootstrap → `runtime/loader.js`,不再将 `build/public.js` 作为全局生命周期入口。 - 删除所有 routed script 对 `aksrt-runtime` 的依赖;路由模块改由 loader/main 按 DOM 条件加载,直接遵循参考主题的条件加载方式。 - 将 `_win` 作为唯一前台运行时配置对象;把必须保留的 AKSRT 数据字段合并进去,避免同时维护 `_win`、`aksrtData` 两套 DOM 生命周期配置。 - WidgetSystem 只保留一个前端 owner:将 widget 的初始化接入 `auto_fun`/对应动态模块,禁止 `assets/widgets/frontend.js` 与旧 widget-set/main 重复初始化同一节点;同步调整第三方资源注册和依赖。 - 清理已迁移到 loader/main 的独立 enqueue、重复 inline boot、重复条件判断和无实际动作的 Swiper 注册。 ## 三、局部更新协议统一为参考主题行为 1. **列表 AJAX:`assets/js/core/ajax-list.js`、`homepage-fixed.js`、`pagination.js`、`comments.js`、`routes/user-center.js`、`author.js`、`widgets/frontend.js` 等** - 保留现有请求、安全、错误提示和业务响应格式。 - 删除直接 `AksrtFrontend.rehydrate()` 的调用。 - 按场景统一为:before 状态 → HTML parse/replace/append → 触发容器上的 `post_ajax.ed` → `auto_fun()`;保留参考主题的 `ing`/loading/分页/route 顺序。 - 对复杂 panel 继续使用现有 destroy 能力(例如订单中心),但 destroy 只是业务实例清理,不再扩展成第二套全局 lifecycle。 - 明确旧 `.ajax-next` 与新 `data-aksrt-*` 的唯一 ownership;最终删除重复 click handler,控制只由一个 `post_ajax` 实现处理。 2. **JSON AJAX:`comment-ajax.js`、`auth.js`、`follow.js`、`credits.js`、`reward.js`、`messages.js` 等** - 统一使用参考主题的 `zib_ajax()` 语义:按钮状态、错误/成功提示、`zib_ajax.success` 事件、业务 callback、可选 modal/reload。 - 删除以 `aksrt:rehydrated` 或 registry 事件作为成功信号的路径;只有真正 HTML 注入后才调用 `auto_fun()`。 3. **远程 modal 与历史路由** - modal HTML 更新改为 Bootstrap `loaded.bs.modal`,由 main 的全局监听调用 `auto_fun()`。 - 保留 `history.pushState/replaceState` 与 Tab `popstate` 行为,但删除 `AksrtFrontend` 路由 API 和独立页面 boot;不引入 PJAX、Turbolinks、InstantClick 或全局 MutationObserver 重初始化。 ## 四、灯箱、懒加载和 DOM 标记恢复为参考主题契约 1. **灯箱硬切换** - 删除 `AksrtLightbox`、`data-aksrt-lightbox*`、`aksrt-lightbox` overlay 和其专用 CSS/配置桥接。 - 从参考主题恢复单一 `imgbox` owner:新增/恢复 `assets/js/runtime/imgbox.js`(压缩产物由构建生成),使用 `Miniimgbox`、`imgbox-container`、`a[data-imgbox]`、`imgbox_data` 和参考主题的幂等标记。 - `main.js` 只在 `_win.imgbox` 且存在目标 DOM 时 `tbquire(['imgbox'])`;不得再有第二个灯箱监听器。 - 更新 `single.php`、`page.php`、gallery/content renderer、图片 helper、相关 CSS 和设置输出,使 DOM 属性、分组、缩略图、zoom/full/play/down 开关与参考主题一致。 2. **懒加载单一 owner** - 删除 `lazy-image-attr.js` bridge 及其 enqueue/build/test 依赖;lazySizes、`lazybeforeunveil`、`data-src`/`data-srcset`/`data-bg`、兼容属性处理全部由 main/lazySizes owner 负责。 - 保留必要的 PHP 图片 URL 生成和占位图能力,但统一输出参考主题可识别的 DOM,不再并行维护第二套 lazy switch 或 IntersectionObserver 初始化。 - 保留 lazySizes 自有 MutationObserver;禁止把它扩展成全局组件 rehydrate 机制。 ## 五、所有业务模块去 registry 化 逐一处理当前已注册的 public/routed 文件(article、comments、comment-fixed-input、pagination、archive、footer-tabbar、misc、follow、enhancements、enhancements2、color-extract、effects、captcha、auth、author、page-navs、section-navs、messages、front-submit、mini-upload、page-template、page-edit、post-share、poster-share、pay-vip、video-player、download-status、ban-appeal、docs-navigation、input-expand、waterfall、yiyan、site-notice、user-badge-actions、widgets 等): - 删除 `AksrtFrontend.register()` 包装和对 registry API 的防御性分支。 - 将脚本改成参考主题式:被 `tbquire` 加载后立即定义/绑定,或暴露单一模块初始化函数供 main 调用;依赖 DOM 委托和 `is-on`/class/data 标记实现重复调用安全。 - 任何需要窗口/文档监听的模块只绑定一次,并使用参考主题的全局 owner;不新增 destroy registry、root 广播或双入口 ready。 - 保留 AKSRT 的 nonce、REST 权限、输出转义和业务接口,不改变安全边界。 ## 六、死代码清理 在改造前后用 `rg/git grep` 建立引用图,仅删除已确认无入口的代码,避免把仍被动态 loader 使用的资源误删: - 删除 `assets/js/revenue.js`(确认无 PHP、JS、构建和模板引用后)。 - 删除当前 `rehydrate.js`、`aksrt-runtime.js` 生命周期专用代码及其测试夹具。 - 删除 `runtime/main.js` 中已迁移功能的 registry 适配、注释掉的 waterfall 分支、未使用 `auto_fun` 转发代码和重复事件派发。 - 删除确认无 mapping、enqueue、模板或第三方引用的 `runtime/widget-set.*`、`runtime/mini-touch.*`、`waterfall.*` 等 orphan;若仍被参考主题式 loader 使用,则保留唯一映射,不凭文件名删除。 - 删除 `AksrtLightbox`、旧 overlay、runtime/imgbox 的冲突副本和无消费者的 `aksrt.*` API;`_win`、`tbquire`、main、loader、Swiper/DPlayer/lazySizes 只在确认所有消费者迁移后保留。 - 同步清理文档、注释、PHP handles、构建清单、测试中的旧 token,确保仓库不存在“旧入口还能被重新接回”的死配置。 ## 七、测试与非视觉验证改造 1. 删除/重写锁定旧架构的测试: - `global-dom-init-contract.test.cjs` → `legacy-loader-runtime-contract.test.cjs`:验证 loader config、mapping、`tbquire(['main'])`、唯一 boot owner。 - `rehydrate-runtime-contract.test.cjs` → `legacy-auto-fun-contract.test.cjs`:VM 验证 `auto_fun` 防抖、重复调用、`auto_fun` 事件、异常隔离和 DOM 标记幂等。 - `public-bundle-parity-contract.test.cjs`:改为验证 loader/main 构建图,不再断言 `AksrtFrontend`。 - `homepage-dom-contract.test.cjs`:改为验证 HTML 注入后 `post_ajax.ed → auto_fun` 顺序和唯一 delegated owner。 - `lightbox-contract.test.cjs`:改为 `Miniimgbox`/`data-imgbox`/`imgbox` mapping 契约。 - `lazyload-contract.test.cjs`:改为 main/lazySizes 单 owner 契约。 - `legacy-navigation-contract.test.cjs`:验证 loader 的 page-navs/section-navs mapping 和 `auto_fun` 条件加载。 2. 新增/保留 VM 与静态契约: - loader URL 解析和模块缓存只发生一次。 - 同一 DOM 多次 `auto_fun()` 不重复绑定 tooltip、Swiper、DPlayer、imgbox、上传和 widget。 - `post_ajax.ed`、`zib_ajax.success`、`loaded.bs.modal` 三种事件不混用。 - 全仓库禁止 `AksrtFrontend`、`aksrt.autoFun`、`aksrt:ready`、`aksrt:rehydrated`、第二套 `DOMContentLoaded` 页面 boot。 - 静态检查没有 PJAX/InstantClick/全局 MutationObserver reinit 新入口。 3. 继续运行与改造后的验证: - Node widget/navigation 契约测试。 - `tools/test-credits-rehydrate.mjs`(改名或改断言为 auto_fun 重入 harness)。 - WidgetSystem PHP audit、asset ledger、业务安全/支付/评论相关测试。 - `node --check` 检查所有改动后的 JS 和构建脚本。 - `php -l` 检查所有改动后的 PHP。 - `node tools/build-public-assets.mjs` 后再次运行 bundle/source parity、旧入口扫描和 `git diff --check`。 ## 八、实施顺序与完成标准 1. 先完成只读引用图和测试基线,记录当前失败/通过集合。 2. 先改 loader/main/构建/PHP 入队,建立唯一运行时入口。 3. 再批量去掉所有 registry 调用并统一 AJAX/modal 事件顺序。 4. 再恢复参考主题灯箱和 lazySizes owner,更新模板/CSS/配置。 5. 最后删除确认死代码与旧测试,重建生成产物。 6. 完成标准: - 前台只有 `loader → main → auto_fun` 一条初始 DOM 路径。 - 没有任何 `AksrtFrontend` 或其双路兼容代码。 - 列表、JSON、modal 三类更新分别遵循参考主题事件协议。 - Swiper、DPlayer、lazySizes、imgbox、WidgetSystem 各只有一个 owner。 - 所有已确认死代码和旧契约被删除或改写。 - 非视觉测试、语法检查、构建和静态引用审计通过;不执行真实视觉验收。