根因:弹窗壳为服务端静态输出(Zibll 由 refresh_modal JS 按需创建,且其
CSS 无 bootstrap .modal 基础规则,故无此问题)。AKSRT 中 bootstrap.min.css
的 .modal{position:fixed;z-index:1050;display:none} 先加载,main.css 的
.flex{display:flex}(弹窗壳对齐 Zibll 所需的工具类)后加载且同特异性
后者胜 → 弹窗壳永久 display:flex 铺满全屏,叠加 .fade 无 .in 时的
opacity:0,形成隐形遮罩拦截整页点击。
修复:credits.css 以 (0,2,0) 特异性压制——
.modal[data-aksrt-charge-modal]{display:none}(静止态隐藏)+
.modal[data-aksrt-charge-modal].in{display:block}(展示态)。
credits.js 开关维持第 20 轮的自包含实现(内联 display:block 驱动),
关闭撤除内联样式后即回到隐藏规则,无 JS 改动。
新增契约 tests/widget-system/balance-charge-modal.test.cjs(3 例):
壳结构与 data 钩子、静止态隐藏规则(防 .flex 覆盖回潮)、开关自包含
(禁止回退 jQuery modal 运行时)。相关契约 29/29 通过。
55 lines
2.9 KiB
JavaScript
55 lines
2.9 KiB
JavaScript
/**
|
||
* 余额充值弹窗壳契约(第 19 轮 Zibll 对齐 + 第 21 轮全页不可点击回归护栏)。
|
||
*
|
||
* 关键约束:本主题的弹窗壳是服务端静态输出,与 Zibll(refresh_modal JS
|
||
* 按需创建、且其 CSS 无 bootstrap .modal 基础规则)架构不同。若弹窗壳在
|
||
* 静止态没有被显式隐藏,main.css 的 .flex{display:flex}(后加载、与
|
||
* bootstrap.min.css 的 .modal{display:none} 同特异性、后者胜)会让
|
||
* `class="modal flex jc fade"` 壳永久 display:flex 铺满全屏,叠加 .fade
|
||
* 的 opacity:0 形成隐形遮罩 → 整页所有按钮不可点击(2026-09-17 实测故障)。
|
||
*
|
||
* 因此 credits.css 必须以 (0,2,0) 特异性压制:
|
||
* .modal[data-aksrt-charge-modal] { display: none; }
|
||
* .modal[data-aksrt-charge-modal].in { display: block; }
|
||
* 展示态由 credits.js 自包含开关的内联 display:block 驱动(不依赖
|
||
* jQuery/Bootstrap 运行时),关闭后内联样式撤除即回到隐藏规则。
|
||
*/
|
||
const test = require('node:test');
|
||
const assert = require('node:assert');
|
||
const fs = require('node:fs');
|
||
const path = require('node:path');
|
||
|
||
const root = path.join(__dirname, '..', '..');
|
||
const read = (...seg) => fs.readFileSync(path.join(root, ...seg), 'utf8');
|
||
|
||
const wallet = read('inc', 'helpers', 'user-center-renderers', 'credits-wallet.php');
|
||
const creditsJs = read('assets', 'js', 'credits.js');
|
||
const creditsCss = read('assets', 'css', 'routes', 'user-center', 'credits.css');
|
||
|
||
test('弹窗壳为 Zibll refresh_modal 同构静态壳并带 data 钩子', () => {
|
||
assert.match(wallet, /class="modal flex jc fade"[^>]*data-aksrt-charge-modal/);
|
||
assert.match(wallet, /data-aksrt-charge-form/);
|
||
assert.match(wallet, /data-dismiss="modal"/);
|
||
assert.match(wallet, /initiate-pay/);
|
||
});
|
||
|
||
test('弹窗壳静止态必须被 credits.css 显式隐藏(.flex 覆盖回归护栏)', () => {
|
||
// (0,2,0) 特异性压制 main.css 的 .flex{display:flex}。
|
||
assert.match(creditsCss, /\.modal\[data-aksrt-charge-modal\]\s*\{\s*display:\s*none;/);
|
||
assert.match(creditsCss, /\.modal\[data-aksrt-charge-modal\]\.in\s*\{\s*display:\s*block;/);
|
||
});
|
||
|
||
test('开关自包含:不依赖 jQuery/Bootstrap modal 运行时', () => {
|
||
assert.match(creditsJs, /function openChargeModal/);
|
||
assert.match(creditsJs, /function closeChargeModal/);
|
||
assert.match(creditsJs, /data-aksrt-charge-open/);
|
||
// 动态创建遮罩层(bootstrap.min.css 已有 .modal-backdrop 规则)。
|
||
assert.match(creditsJs, /modal-backdrop fade in/);
|
||
// 充值弹窗开关不得回退到 jQuery modal 运行时(时序异常时弹窗打不开)。
|
||
assert.doesNotMatch(creditsJs, /\.modal\(\s*['"]show['"]/);
|
||
assert.doesNotMatch(creditsJs, /hidden\.bs\.modal/);
|
||
// 打开前移除旧缓存 hidden 标记;关闭走 300ms fade-out 收尾。
|
||
assert.match(creditsJs, /removeAttribute\('hidden'\)/);
|
||
assert.match(creditsJs, /void modal\.offsetWidth/);
|
||
});
|