fix(payment): 导入提示不再使用 WP notice 类,避免被 common.js 搬到页面顶部
真因:wp-admin/js/common.js 在 DOM 就绪时执行
$('div.updated, div.error, div.notice').not('.inline, .below-h2').insertAfter($headerEnd)
它会把页面上所有「非 inline」的 notice 搬到 .wp-header-end(不存在时取 .wrap 内首个
h1/h2)之后。提示块原先输出 class="aksrt-submsg notice notice-warning",被判定为
notice,于是在求值之后被整块搬到页头:既脱离「添加方式—卡密数据」之间的字段区,
又因为搬迁发生在 evalDeps 之后,行内显隐逻辑无从纠正。
这也是同一现象反复出现的真因:四条提示都可见时会被整体搬到页面最上方;给提示块
补上初始隐藏后看起来像「提示不见了」;改为全文档求值后则表现为「提示显示在页面
最顶部」。此前的 foster-parenting 判断有误——服务端输出的表格结构始终合法。
改动:
- submessage_row() 只输出自有类名 aksrt-submsg,不再复用 .notice / .notice-warning。
- 外观(底色 #fef8ee + 左侧 4px #f0b849 色条)改由 .aksrt-submsg 自带,与参考主题
CSF content 字段的做法一致;元素内联样式只保留初始隐藏状态。
- 新增契约用例:提示块不得带 notice;.aksrt-submsg 必须自带 background 与 border-left;
并确认页面级错误通知仍正常使用 notice(不误伤其它通知输出)。
This commit is contained in:
@@ -855,12 +855,16 @@ class PayChargeCards {
|
||||
*/
|
||||
private function submessage_row(array $deps, string $content): void {
|
||||
$dep_attr = ' data-dep="' . esc_attr((string) wp_json_encode($deps)) . '"';
|
||||
$hidden = $this->deps_visible($deps) ? '' : 'display:none;';
|
||||
// data-dep 与初始隐藏状态必须同时挂在 <tr> 和内层提示块上,不能只依赖行:
|
||||
// 提示块一旦脱离所在行(表格上下文里出现不被允许的节点时,HTML 解析器会把它
|
||||
// foster-parent 到 <table> 之前),只有 <tr> 带状态会让四条提示永久铺开、
|
||||
// 且切换卡密类型/添加方式时求值结果无处落地。自带状态后两种结构都成立。
|
||||
echo '<tr' . $dep_attr . ($hidden === '' ? '' : ' style="' . $hidden . '"') . '><td colspan="2"><div' . $dep_attr . ' class="aksrt-submsg notice notice-warning" style="margin:6px 0;padding:6px 12px;' . $hidden . '">' . $content . '</div></td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput -- 文案已转义。
|
||||
$hidden = $this->deps_visible($deps) ? '' : ' style="display:none;"';
|
||||
// 提示块**不要**挂 WP 的 .notice / .notice-warning:wp-admin/js/common.js 在 DOM
|
||||
// 就绪时会执行
|
||||
// $('div.updated, div.error, div.notice').not('.inline, .below-h2').insertAfter($headerEnd)
|
||||
// 把页面上所有「非 inline」的 notice 整块搬到 .wp-header-end(不存在时取 .wrap 内首个
|
||||
// h1/h2)之后。提示块一旦带上 notice,就会被搬到页面顶部、脱离「添加方式—卡密数据」
|
||||
// 之间的字段区,而且搬迁发生在求值之后,行内的显隐逻辑无从纠正。
|
||||
// 外观改由 .aksrt-submsg 自带(见 print_assets),与参考主题 CSF content 字段一致。
|
||||
// data-dep 与初始隐藏状态同时挂在 <tr> 和内层提示块上:提示块若脱离所在行,仍能自行显隐。
|
||||
echo '<tr' . $dep_attr . $hidden . '><td colspan="2"><div' . $dep_attr . ' class="aksrt-submsg"' . $hidden . '>' . $content . '</div></td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput -- 文案已转义。
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1053,6 +1057,9 @@ class PayChargeCards {
|
||||
.aksrt-btnset-item input { position: absolute; opacity: 0; pointer-events: none; }
|
||||
.aksrt-btnset-item span { display: inline-block; padding: 3px 12px; border: 1px solid #c3c4c7; border-radius: 3px; background: #fff; }
|
||||
.aksrt-btnset-item input:checked + span { background: #2271b1; border-color: #2271b1; color: #fff; }
|
||||
/* 导入提示:复刻后台 notice-warning 的外观,但**不用** .notice 类 —— 见 submessage_row()
|
||||
的说明,带 .notice 会被 wp-admin/js/common.js 搬到页面顶部。改这里请连带改那里。 */
|
||||
.aksrt-submsg { margin: 6px 0; padding: 6px 12px; background: #fef8ee; border-left: 4px solid #f0b849; }
|
||||
.aksrt-copy-tip { margin-left: 6px; color: #00a32a; font-size: 12px; white-space: nowrap; }
|
||||
</style>
|
||||
<script>
|
||||
|
||||
@@ -203,15 +203,42 @@ test('两种行渲染都接入服务端预隐藏,避免首帧铺开', () => {
|
||||
assert.match(page, /private function field_row\([\s\S]*?\$hidden\s*=\s*\(\$deps && !\$this->deps_visible\(\$deps\)\)/);
|
||||
assert.match(page, /private function submessage_row\([\s\S]*?\$hidden\s*=\s*\$this->deps_visible\(\$deps\)/);
|
||||
assert.match(script, /document\.addEventListener\('DOMContentLoaded', evalDeps\)/);
|
||||
// 提示块必须自带 data-dep 与初始隐藏状态:脱离所在行时(表格解析器把非法节点
|
||||
// foster-parent 到 <table> 之前)仍能被求值并保持隐藏。
|
||||
// 提示块必须自带 data-dep 与初始隐藏状态:即使提示块脱离所在行(WP 的
|
||||
// wp-admin/js/common.js 会把页面上的 notice 搬到页头,见下一条用例),
|
||||
// 它仍能被求值并保持隐藏。
|
||||
assert.match(page, /<td colspan="2"><div'\s*\.\s*\$dep_attr/, '提示块必须自带 data-dep');
|
||||
assert.match(page, /style="margin:6px 0;padding:6px 12px;'\s*\.\s*\$hidden/, '提示块必须自带初始隐藏状态');
|
||||
// 求值范围不限域:提示块被解析器移出表格/表单子树后仍必须被求值。
|
||||
assert.match(page, /class="aksrt-submsg"'\s*\.\s*\$hidden/, '提示块必须自带初始隐藏状态');
|
||||
// 求值范围不限域:提示块被移出表格/表单子树后仍必须被求值。
|
||||
assert.match(script, /querySelectorAll\('\[data-dep\]'\)/, '求值必须全文档查找 data-dep');
|
||||
assert.doesNotMatch(script, /querySelectorAll\('\.aksrt-cardpass-form \[data-dep\]'\)/, '求值不得限域在表单内');
|
||||
});
|
||||
|
||||
test('导入提示不得使用 WP 的 .notice 类(否则被 common.js 搬到页面顶部)', () => {
|
||||
// wp-admin/js/common.js 在 DOM 就绪时执行:
|
||||
// $('div.updated, div.error, div.notice').not('.inline, .below-h2').insertAfter($headerEnd)
|
||||
// 会把页面上所有非 inline 的 notice 搬到 .wp-header-end(不存在时取 .wrap 内首个 h1/h2)之后。
|
||||
// 提示块一旦带 .notice,就会脱离「添加方式—卡密数据」之间的字段区跑到页面顶部,
|
||||
// 且搬迁发生在 evalDeps 之后,行内显隐逻辑无法纠正(历史故障:提示一直显示在页面最上方)。
|
||||
assert.match(
|
||||
page,
|
||||
/private function submessage_row\([\s\S]*?class="aksrt-submsg"/,
|
||||
'提示块只应带自有类名 aksrt-submsg'
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
page,
|
||||
/class="aksrt-submsg[^"]*\bnotice\b/,
|
||||
'提示块不得带 notice 类:会被 common.js 搬到页面顶部'
|
||||
);
|
||||
// 外观改由自有类名承担,删掉样式规则会让提示失去底色与左侧色条。
|
||||
assert.match(
|
||||
page,
|
||||
/\.aksrt-submsg \{[^}]*background:[^}]*border-left:/,
|
||||
'.aksrt-submsg 必须自带 background 与 border-left 外观'
|
||||
);
|
||||
// 允许(且要求)真正需要置顶的提示保留 notice:确认本用例没有误伤其它通知输出。
|
||||
assert.match(page, /class="notice notice-error"/, '页面级错误通知仍应使用 notice');
|
||||
});
|
||||
|
||||
test('行内脚本不再保留解析期的空操作求值(死代码)', () => {
|
||||
assert.doesNotMatch(script, /evalDeps\(\);\s*\}\)\(\);/);
|
||||
assert.match(script, /document\.addEventListener\('change'/);
|
||||
|
||||
Reference in New Issue
Block a user