feat(comments): 评论区按 Zibll 1:1 全量复刻

- 评论项/表单/工具栏/筛选/分页/空状态 DOM 全部替换为 zibll 原始类名
  (li.comment、comt-main、comt-meta、list-inline、dropup 工具栏、
  theme-pagination/pagenav、post_ajax_loader 骨架等)
- 移植 zibll main.css L9412–9751 桌面 + 移动端评论样式,
  缺失基础组件(title-theme/dropdown-menu/line-form/tab-nav-theme 等)
  以 #comments 作用域补齐
- 删除全部 aksrt-comment__* 旧类名与旧样式,无兼容层
- JS 选择器对齐 zibll DOM:片段整块替换 #postcomments、骨架加载、
  跳页输入、prepend 插入、addComment onclick 剥离,
  移除 WP comment-reply enqueue 避免双 moveForm
- 表情资源替换为 zibll 全套 gif(内容逐字节一致,git 无差异)
- REST 后端 (CommentActions) 不变

验证:php -l 全部通过;5 个改动 JS 语法校验通过;
node --test tests/widget-system/post-visual-contract.test.cjs 12/12 通过
This commit is contained in:
2026-08-22 13:29:51 +08:00
parent 251fe86527
commit e1f176429b
15 changed files with 1286 additions and 1439 deletions
+74 -54
View File
@@ -1,6 +1,9 @@
<?php
/**
* Comment form partials — virtual-input, expand toolbar, respond shell helpers.
* Comment form partials — virtual-input + expand toolbar (Zibll DOM contract).
*
* Mirrors zib_get_respond_mobile() and zib_get_input_expand_but()
* from zibll/inc/functions.
*
* @package AKSRT
*/
@@ -9,18 +12,19 @@ defined('ABSPATH') || exit;
if (!function_exists('aksrt_get_comment_virtual_input_html')) :
/**
* Mobile virtual input bar that opens FixedInput #respond.
* Mobile virtual input bar (zibll: zib_get_respond_mobile).
*
* @param string $placeholder Placeholder text.
* @param string $target CSS selector for FixedInput target.
* @param string $target CSS selector for the FixedInput target.
* @return string
*/
function aksrt_get_comment_virtual_input_html(string $placeholder = '', string $target = '#respond'): string {
$user_id = get_current_user_id();
$avatar = get_avatar($user_id, 36, '', '', ['class' => 'avatar-img']);
$avatar = get_avatar($user_id, 36, '', '', ['class' => 'avatar']);
if ($placeholder === '') {
$placeholder = __('说点什么吧...', 'aksrt');
}
$html = '<div class="flex ac jsb virtual-input hide-pc" fixed-input="' . esc_attr($target) . '">';
$html = '<div class="flex ac jsb virtual-input" fixed-input="' . esc_attr($target) . '">';
$html .= '<div class="flex flex1 ac">';
$html .= $avatar;
$html .= '<div class="text-ellipsis simulation mr10">' . esc_html($placeholder) . '</div>';
@@ -33,46 +37,27 @@ endif;
if (!function_exists('aksrt_get_input_expand_but')) :
/**
* zibll-style expand toolbar button + dropdown.
* zibll-style expand toolbar button + dropdown (zibll: zib_get_input_expand_but).
*
* @param string $type smilie|code|image|quick|upload.
* @param mixed $arg1 Type-specific.
* @param array<string,mixed> $ctx Optional context (upload enabled, phrases).
* @param string $type smilie|code|image|quick|link.
* @param mixed $arg1 Type-specific arg.
* @param array<string,mixed> $ctx Optional context (upload, phrases).
* @return string
*/
function aksrt_get_input_expand_but(string $type = 'smilie', $arg1 = null, array $ctx = []): string {
$but = '';
$dropdown = '';
switch ($type) {
case 'smilie':
$map = function_exists('aksrt_comment_smilie_map') ? aksrt_comment_smilie_map() : [];
$icons = '';
foreach ($map as $key => $url) {
$icons .= '<a class="smilie-icon" href="javascript:;" data-smilie="' . esc_attr((string) $key) . '"><img' . aksrt_get_lazy_attr('lazy_comment', (string) $url, '', aksrt_get_lazy_thumb('sm')) . ' alt="[' . esc_attr((string) $key) . ']" width="28" height="28"></a>';
}
$but = '<a class="but btn-input-expand input-smilie mr6" href="javascript:;" data-toggle-class="open" data-target=".dropdown-smilie-wrap" title="' . esc_attr__('表情', 'aksrt') . '"><i class="fa fas fa-fw fa-smile" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('表情', 'aksrt') . '</span></a>';
$drop = '<div class="dropdown-smilie-wrap relative dropup"><div class="dropdown-smilie scroll-y mini-scrollbar dropdown-menu">' . $icons . '</div></div>';
return '<span class="dropup relative input-expand-wrap input-expand-smilie">' . $but . $drop . '</span>';
case 'code':
$but = '<a class="but btn-input-expand input-code mr6" href="javascript:;" data-toggle-class="open" data-target=".dropdown-code" title="' . esc_attr__('代码', 'aksrt') . '"><i class="fa fas fa-fw fa-code" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('代码', 'aksrt') . '</span></a>';
$drop = '<div class="dropdown-code dropdown-menu box-body" style="width:280px;">'
. '<p class="muted-2-color em09 mb6">' . esc_html__('插入代码块', 'aksrt') . '</p>'
. '<textarea class="form-control mb6" rows="4" placeholder="' . esc_attr__('粘贴代码…', 'aksrt') . '"></textarea>'
. '<button type="button" class="but c-blue pw-1em input-code-submit">' . esc_html__('插入', 'aksrt') . '</button>'
. '</div>';
return '<span class="dropup relative input-expand-wrap input-expand-code">' . $but . $drop . '</span>';
case 'image':
$upload = !empty($arg1) || !empty($ctx['upload']);
$but = '<a class="but btn-input-expand input-image mr6" href="javascript:;" data-toggle-class="open" data-target=".dropdown-image" title="' . esc_attr__('图片', 'aksrt') . '"><i class="fa fas fa-fw fa-image" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('图片', 'aksrt') . '</span></a>';
$upload_btn = $upload
? '<button type="button" class="but hollow mr6 input-image-upload" data-toolbar-action="upload-image">' . esc_html__('上传', 'aksrt') . '</button>'
: '';
$drop = '<div class="dropdown-image dropdown-menu box-body" style="width:280px;">'
. '<p class="muted-2-color em09 mb6">' . esc_html__('插入图片地址', 'aksrt') . '</p>'
. '<input type="url" class="form-control mb6 input-image-url" placeholder="https://" />'
. $upload_btn
. '<button type="button" class="but c-blue pw-1em input-image-submit">' . esc_html__('插入', 'aksrt') . '</button>'
. '</div>';
return '<span class="dropup relative input-expand-wrap input-expand-image">' . $but . $drop . '</span>';
case 'link':
$but = '<a class="but btn-input-expand input-link mr6" href="javascript:;"><i class="fa fa-fw fa-link" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('链接', 'aksrt') . '</span></a>';
$dropdown = '<div class="dropdown-link">';
$dropdown .= '<p>' . esc_html__('请输入链接:', 'aksrt') . '</p>';
$dropdown .= '<p><textarea rows="2" tabindex="1" class="form-control input-textarea link-textarea" style="height:55px;" placeholder="https://..."></textarea></p>';
$dropdown .= '<p><input type="text" class="form-control link-text" placeholder="' . esc_attr__('链接文本', 'aksrt') . '"></p>';
$dropdown .= '<div class="text-right"><a type="submit" class="but c-blue pw-1em input-link-submit" href="javascript:;">' . esc_html__('确认', 'aksrt') . '</a></div>';
$dropdown .= '</div>';
break;
case 'quick':
$phrases = [];
@@ -81,30 +66,65 @@ if (!function_exists('aksrt_get_input_expand_but')) :
} elseif (!empty($ctx['quick_phrases']) && is_array($ctx['quick_phrases'])) {
$phrases = $ctx['quick_phrases'];
}
if (empty($phrases)) {
$phrases = [
__('不错,学习了', 'aksrt'),
__('感谢分享', 'aksrt'),
__('期待更新', 'aksrt'),
];
}
$items = '';
$sys_lists = '';
foreach ($phrases as $p) {
$items .= '<a class="quick-reply-item" href="javascript:;" data-text="' . esc_attr((string) $p) . '">' . esc_html((string) $p) . '</a>';
$sys_lists .= '<div class="quick-reply-item">' . esc_html((string) $p) . '</div>';
}
$but = '<a class="but btn-input-expand input-quick mr6" href="javascript:;" data-toggle-class="open" data-target=".dropdown-quick" title="' . esc_attr__('快捷', 'aksrt') . '"><i class="fa fas fa-fw fa-bolt" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('快捷', 'aksrt') . '</span></a>';
$drop = '<div class="dropdown-quick dropdown-menu box-body scroll-y mini-scrollbar" style="max-height:220px;min-width:160px;">' . $items . '</div>';
return '<span class="dropup relative input-expand-wrap input-expand-quick">' . $but . $drop . '</span>';
if ($sys_lists === '') {
$sys_lists = '<div class="text-center muted-2-color" style="margin: 60px 0;">' . esc_html__('系统暂无快捷回复', 'aksrt') . '</div>';
}
$but = '<a class="but btn-input-expand input-quick mr6" href="javascript:;"><i class="fa fa-fw fa-bolt" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('快捷回复', 'aksrt') . '</span></a>';
$dropdown = '<div class="relative dropdown-quick-often"><div class="quick-often-box scroll-y mini-scrollbar">' . $sys_lists . '</div></div>';
break;
case 'smilie':
$map = function_exists('aksrt_comment_smilie_map') ? aksrt_comment_smilie_map() : [];
$smilie_icon = '';
foreach ($map as $key => $url) {
$smilie_icon .= '<a class="smilie-icon" href="javascript:;" data-smilie="' . esc_attr((string) $key) . '"><img src="' . esc_url((string) $url) . '" alt="[' . esc_attr((string) $key) . ']" /></a>';
}
$but = '<a class="but btn-input-expand input-smilie mr6" href="javascript:;"><i class="fa fa-fw fa-smile-o" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('表情', 'aksrt') . '</span></a>';
$dropdown = '<div class="dropdown-smilie scroll-y mini-scrollbar">' . $smilie_icon . '</div>';
break;
case 'code':
$but = '<a class="but btn-input-expand input-code mr6" href="javascript:;"><i class="fa fa-fw fa-code" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('代码', 'aksrt') . '</span></a>';
$dropdown = '<div class="dropdown-code">';
$dropdown .= '<p>' . esc_html__('请输入代码:', 'aksrt') . '</p>';
$dropdown .= '<p><textarea rows="6" tabindex="1" class="form-control input-textarea" placeholder="' . esc_attr__('在此处粘贴或输入代码', 'aksrt') . '"></textarea></p>';
$dropdown .= '<div class="text-right"><a type="submit" class="but c-blue pw-1em input-code-submit" href="javascript:;">' . esc_html__('确认', 'aksrt') . '</a></div>';
$dropdown .= '</div>';
break;
case 'image':
$upload = !empty($arg1) || !empty($ctx['upload']);
$but = '<a class="but btn-input-expand input-image mr6" href="javascript:;"><i class="fa fa-fw fa-image" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('图片', 'aksrt') . '</span></a>';
$dropdown = '<div class="dropdown-image">';
$dropdown .= '<p>' . esc_html__('请填写图片地址:', 'aksrt') . '</p>';
$dropdown .= '<p><textarea rows="2" tabindex="1" class="form-control input-textarea input-image-url" style="height:95px;" placeholder="http://..."></textarea></p>';
$dropdown .= '<div class="text-right">';
if ($upload) {
$dropdown .= '<a class="but c-yellow mr10 pw-1em input-image-upload" href="javascript:;">' . esc_html__('上传图片', 'aksrt') . '</a>';
}
$dropdown .= '<a type="submit" class="but c-blue pw-1em input-image-submit" href="javascript:;">' . esc_html__('确认', 'aksrt') . '</a>';
$dropdown .= '</div>';
$dropdown .= '</div>';
break;
default:
return '';
}
$con = $but . '<div class="dropdown-menu">' . $dropdown . '</div>';
return '<span class="dropup relative ' . esc_attr($type) . '">' . $con . '</span>';
}
endif;
if (!function_exists('aksrt_render_comment_expand_toolbar')) :
/**
* Render left-side expand tools based on settings.
* Render left-side expand tools based on settings (zibll order: smilie/code/image/link/quick).
*
* @param array<string,mixed> $ctx Comments context.
*/