评论区硬切换实现

This commit is contained in:
2026-08-30 17:34:29 +08:00
parent ed914d2eec
commit b8ef4d81a4
32 changed files with 946 additions and 1008 deletions
@@ -0,0 +1,46 @@
# 评论区硬切换:1:1 复刻 Zibll(不含表情包/快捷回复)
## 现状与结论
- AKSRT 评论区的 PHP 渲染(`inc/helpers/comments/item.php`、`form-parts.php`、`aksrt-comments.php`)与 JS(`assets/js/core/comments.js` 等走 `aksrt/v1` REST)已是自有代码,DOM 与 Zibll 基本一致(`li#comment-{id} > ul.list-inline > li.comt-main`、`.comment-header/.comment-content/.comt-meta`、`#commentform/.comt-title/.comt-box/.comt-ctrl` 均已对齐)。
- **样式仍由 vendored `assets/css/main.min.css` 提供**(拼进全站 `build/public.css`;`comments/shell.css` 头部明文"以 vendor 正版样式为准、禁止复制")——这是本次硬切换的主体:样式归属权切到自有文件,vendor 副本剥离。
- 快捷回复链路完整存在(schema/PHP/JS/CSS),需全链路删除;表情包已被此前的 commit 删除并有契约测试锁定,保持。
- 传输层不动:提交/点赞/编辑/删除/置顶仍走 AKSRT REST(含权限回调),不改回 Zibll 的 admin-ajax 协议;UI 与 DOM 对齐 Zibll。
## 1. CSS 硬切换(主体)
- 以参考主题 `C:\Users\Xing\Desktop\zibll\css\main.css` 为准移植评论区规则(与 AKSRT vendored 副本 diff 后以参考版为准):
- 新建 `assets/css/frontend/comments/layout.css`:桌面主段(AKSRT main.css 约 9273–9510 对应段:`#comments/#postcomments/#respond/#comment/.commentlist/.comt-*/.comment-*/.comment-signarea/.children/.comment-footer 缩进` 等)+ 散点规则(`.action-comment-like.action-animation`、`.comment-content .box-img`、`.comment-content a`、`.comment-content pre`)。
- 填充 `assets/css/frontend/comments/mobile-item.css`(现为空壳占位):移动端 `@media` 内评论规则(`.mobile-fixed/.virtual-input/头像缩进/分页` 等,main.css 约 12208 起)。
- `shell.css` 重写文件头教条(不再"vendor 提供"),保留 identity chip/medal 补充规则。
- **剔除**:`.dropdown-smilie/.smilie-icon/.dropdown-quick-often` 与 `img:not(.smilie-icon)` 类选择器。
- 从 vendored `assets/css/main.css`/`main.min.css` 剥离同批评论区域专属规则(死代码清理、消除双路)。保留:`.comment-widget-item/.comment-mini-lists`(侧栏小部件在非 singular 页使用)及共享选择器(`.pagenav/.theme-pagination/.line-form/.author-box/.avatar-img` 等别处仍用)。
- 先校验 `main.min.css ≙ minify(main.css)`(esbuild dry-run diff,防漂移),剥离后重新生成 `main.min.css`,再跑 `node tools/build-public-assets.mjs` 重出 bundle。
## 2. Markup 1:1 对齐(PHP 小增量)
- `item.php`:点赞按钮对齐 Zibll `zib_get_comment_like`(SVG 图标 + `<text></text><count>N</count>`,保留 AKSRT `data-comment-action` 接线);置顶/批准/菜单/注册图标由 FA 换成 Zibll SVG——新增小助手(如 `inc/helpers/comments/icons.php`)移植 `zib_get_svg` 所需 glyph(like/topping/approve/menu_2/signup);时间/回复链接 tooltip 属性对齐。
- `aksrt-comments.php` + `form-parts.php`:
- `!comments_open()` 时整体不渲染(Zibll 行为;当前会渲染标题+列表)。
- 工具栏渲染 `code→image→link`,补齐缺失的"链接"按钮(新设置 `comment_link`,默认关——Zibll 默认值即 false)。
- 游客 dropup 补"博客地址"字段(新设置 `comment_user_url_s`,默认关,同 Zibll)。
- `comt-title` 登录态昵称旁渲染 AKSRT 身份徽章(对应 Zibll VIP 图标位)。
## 3. 快捷回复全链路删除 + 死代码清理
- PHP:`form-parts.php` quick case 与工具栏分支;`aksrt-comments.php` context 的 `quick_s/quick_phrases`;`PostDisplay.php` 的 `quick_phrases` 字段与 `parse_comment_quick_phrases()`;`SchemaPostList.php` 镜像字段。
- Vue schema:`assets/admin/src/schema/sections/post-list/comment.js` 删 `comment_quick_s/comment_quick_often`。
- JS:`comment-tools.js` 快捷短语插入逻辑;`ScriptsPart1c.php` 删 `aksrtData.commentQuickPhrases`。
- 删除死文件:`assets/js/runtime/comment.js(+.min)`、`input-expand.js(+.min)`(已确认无代码引用)。
- `aksrt-runtime.js` 的 vendor comment 模块 stub 与委托解绑**保留**(vendor `main.min.js` 仍在全国 bundle,防回潮)。
## 4. 设置 schema(前后端镜像)
- 新增 `comment_link`、`comment_user_url_s` 开关(默认 false),镜像到 `SchemaPostList.php` 与 `PostDisplay::get_comment_display_settings()`;`npm run build` 重出 admin SPA。
## 5. 测试
- 更新 `comment-smilies-removal-contract.test.cjs`(文件清单移除已删 runtime 存档)。
- 新增 `tests/widget-system/comment-hard-cut-contract.test.cjs`:自有 comments CSS 含关键选择器清单;vendor main.css/min 不再含评论区选择器、仍含 `.comment-widget-item`;全库无快捷回复 token(`comment_quick_s/quick-reply-item/dropdown-quick-often/commentQuickPhrases/quick_phrases` 等);死文件不存在;markup 契约(`<count>`/SVG、工具栏 code/image/link 且无 quick/smilie)。
## 6. 构建与验证(不做视觉验收)
- `php -l` 全部改动 PHP;`node --test` 相关契约测试;`node tools/build-public-assets.mjs`;`npm run build`(admin)。
- 不启用 Docker 视觉对比环境(按用户要求)。
## 风险与对策
- vendor main.css 手术:先 min-sync 校验;剥离仅限评论专属选择器,逐个 grep AKSRT 模板确认无跨区使用;剥离后选择器清单复核。
- 评论区规则的 CSS 变量(`var(--…)`)与 bootstrap 类来自 bundle 中更早加载的 tokens.css/bootstrap,`aksrt-comments` 在其后加载,无影响。
@@ -15,12 +15,12 @@ export const commentSchema = {
comment_edit_window: 10, comment_edit_window: 10,
comment_code: true, comment_code: true,
comment_img: true, comment_img: true,
comment_link: false,
comment_like_s: true, comment_like_s: true,
comment_hot_threshold: 10, comment_hot_threshold: 10,
comment_quick_s: true,
comment_city_s: true, comment_city_s: true,
comment_city_type: 'province_city', comment_city_type: 'province_city',
comment_quick_often: '不错,学习了\n感谢分享\n期待更新', comment_user_url_s: false,
comment_author_tag: true, comment_author_tag: true,
comment_corderby: true, comment_corderby: true,
comment_empty_text: '暂无评论,来做第一个评论的人吧~', comment_empty_text: '暂无评论,来做第一个评论的人吧~',
@@ -66,6 +66,7 @@ export const commentSchema = {
fields: [ fields: [
{ key: 'comment_code', label: '代码插入', type: 'switch', default: true }, { key: 'comment_code', label: '代码插入', type: 'switch', default: true },
{ key: 'comment_img', label: '图片按钮', type: 'switch', default: true }, { key: 'comment_img', label: '图片按钮', type: 'switch', default: true },
{ key: 'comment_link', label: '链接按钮', type: 'switch', default: false },
{ key: 'comment_upload_img', label: '评论图片上传', type: 'switch', default: false }, { key: 'comment_upload_img', label: '评论图片上传', type: 'switch', default: false },
], ],
}, },
@@ -76,14 +77,13 @@ export const commentSchema = {
fields: [ fields: [
{ key: 'comment_hot_threshold', label: '神评点赞阈值', type: 'number', default: 10, min: 1, max: 999, help: '点赞数达到该值后显示「神评」徽章', dependsOn: { key: 'comment_like_s', value: true } }, { key: 'comment_hot_threshold', label: '神评点赞阈值', type: 'number', default: 10, min: 1, max: 999, help: '点赞数达到该值后显示「神评」徽章', dependsOn: { key: 'comment_like_s', value: true } },
{ key: 'comment_like_s', label: '评论点赞', type: 'switch', default: true }, { key: 'comment_like_s', label: '评论点赞', type: 'switch', default: true },
{ key: 'comment_quick_s', label: '快捷回复', type: 'switch', default: true }, { key: 'comment_user_url_s', label: '匿名者网址', type: 'switch', default: false, help: '用户未登录评论时,允许输入用户博客地址' },
{ key: 'comment_city_s', label: '评论城市', type: 'switch', default: true }, { key: 'comment_city_s', label: '评论城市', type: 'switch', default: true },
{ key: 'comment_city_type', label: '城市显示格式', type: 'radio', default: 'province_city', options: [ { key: 'comment_city_type', label: '城市显示格式', type: 'radio', default: 'province_city', options: [
{ label: '省份+城市', value: 'province_city' }, { label: '省份+城市', value: 'province_city' },
{ label: '仅省份', value: 'province' }, { label: '仅省份', value: 'province' },
{ label: '国家+省份', value: 'country_province' }, { label: '国家+省份', value: 'country_province' },
], dependsOn: { key: 'comment_city_s', value: true } }, ], dependsOn: { key: 'comment_city_s', value: true } },
{ key: 'comment_quick_often', label: '快捷回复短语', type: 'textarea', default: '不错,学习了\n感谢分享\n期待更新', help: '每行一条', dependsOn: { key: 'comment_quick_s', value: true } },
{ key: 'comment_author_tag', label: '作者标签', type: 'switch', default: true }, { key: 'comment_author_tag', label: '作者标签', type: 'switch', default: true },
{ key: 'comment_corderby', label: '评论排序切换', type: 'switch', default: true, help: '前台显示最新/最早/最热切换按钮' }, { key: 'comment_corderby', label: '评论排序切换', type: 'switch', default: true, help: '前台显示最新/最早/最热切换按钮' },
], ],
+359 -13
View File
@@ -1,15 +1,207 @@
/* source: assets/css/frontend/comments/layout.css */
/* ============================================================
* AKSRT Comments — 主布局(1:1 自有版权)
*
* 自参考主题评论区段全量移植(表情与快捷短语不在复刻范围),
* 是评论区布局规则的唯一来源;vendor main.min.css 已剥离同段规则。
* 依赖 bundle 中更早加载的 bootstrap 3(.list-unstyled/.list-inline/
* .dropdown-menu)与 core/tokens.css 的 CSS 变量。
* ============================================================ */
#comments .comment-box .comments-closed,
#comments .action-text,
#comments #cancel-comment-reply-link {
display: none;
}
#comments #postcomments .action-text,
#comments #postcomments #cancel-comment-reply-link {
display: inline-block;
}
#comments .comt-title {
width: 90px;
}
#comments .comt-title .comt-avatar .avatar {
width: 60px;
height: 60px;
}
#comments #postcomments .comt-title {
display: none;
}
#respond:not(.mobile-fixed) #postcomments .comt-box {
padding: 5px 5px 4px 5px;
background: var(--main-bg-color);
border-radius: 4px;
margin-top: 12px;
}
#comments #postcomments .comt-ctrl .but {
margin-bottom: 2px;
}
#comments .list-inline {
padding: 15px;
}
#comment {
margin-bottom: 5px;
}
.comment-signarea {
background: var(--main-shadow);
}
#respond + #postcomments .comment-filter,
.comment-signarea + #postcomments .comment-filter {
margin-top: 20px;
}
#postcomments .tab-nav-theme {
margin-top: 0;
}
#postcomments .tab-nav-theme li {
padding-bottom: 1px;
}
#postcomments .tab-nav-theme li::before {
bottom: -2px;
}
#postcomments .comment-footer {
position: relative;
}
#postcomments .avatar-img {
--this-size: 45px;
margin-right: 20px;
}
#postcomments .children .avatar-img {
--this-size: 26px;
vertical-align: 2px;
margin-right: 6px;
}
#postcomments .commentlist > .comment > .list-inline .author-box {
align-items: start;
}
#postcomments .commentlist > .comment > .list-inline .comment-footer {
margin-left: 65px;
margin-top: -25px;
}
#postcomments .comment .list-inline > .comt-main {
width: 100%;
}
#postcomments .commentlist .comment + .comment {
border-top: 1px solid var(--main-border-color);
}
#postcomments .comment .list-inline > li {
padding: 10px;
vertical-align: top;
}
#postcomments .comment-header {
font-size: 15px;
position: relative;
}
.comment-header .badge-status {
margin-top: 0;
width: 68px;
z-index: 0;
}
#postcomments .action count {
margin-left: 4px;
}
#postcomments .comt-meta > span:not(:empty) {
margin-right: 10px;
vertical-align: middle;
}
#postcomments .comt-meta > span a {
color: inherit;
}
#postcomments .comt-meta > span .but {
padding: 0.2em 0.8em;
}
#postcomments .comment-approve-link.unapprove {
color: #e87725;
}
#postcomments .comment-approve-link.approve {
color: #3695ff;
}
#postcomments .comt-meta > span .comment-trash-link {
color: #ff4b4b;
}
#postcomments .children {
margin-left: 86px;
background: var(--main-shadow);
border-radius: var(--main-radius);
margin-bottom: 6px;
}
#postcomments .children .children {
margin-left: 23px;
}
#postcomments .children .avatar-icontag {
font-size: 8px;
height: 14px;
width: 14px;
}
.comment-content {
word-wrap: break-word;
white-space: pre-wrap;
}
.comment-content .enlighter-default {
margin-bottom: 0;
opacity: 0.9;
}
#postcomments .comment-content img {
max-width: 260px;
max-height: 350px;
display: block;
width: auto;
height: auto;
}
.virtual-input {
display: none;
}
.commentlist .no-more {
margin: 0;
padding-bottom: 10px;
}
/* source: assets/css/frontend/comments/shell.css */ /* source: assets/css/frontend/comments/shell.css */
/* ============================================================ /* ============================================================
* AKSRT Comments — 补充层 * AKSRT Comments — 补充层
* *
* 评论区的全部样式以 vendor 的 legacy 正版样式为准: * 评论区布局样式已硬切换为自有版权(见 layout.css / mobile-item.css),
* assets/css/main.min.css(含 #comments/#postcomments * vendor main.min.css 不再提供评论区规则。
* 桌面规则与移动端媒体查询:.mobile-fixed/.virtual-input/.pagenav/ * 本文件只放 AKSRT 特有标记的补充规则(identity chip/medal)。
* .tab-nav-theme/.dropdown-menu/.line-form/.placeholder 等) * 共享基础样式仍由 bundle 中更早加载的 bootstrap 3 与
* + bootstrap 3(.list-unstyled/.list-inline) * core/tokens.css 提供。
*
* 本文件只补 AKSRT 特有标记的样式,禁止复制 legacy 规则——
* 带 #comments id 前缀的副本会覆盖 vendor 正版样式造成 UI 偏差。
* ============================================================ */ * ============================================================ */
/* 身份徽章(AKSRT 渲染于 <name> 内,对应 legacy 的认证/等级徽章位) */ /* 身份徽章(AKSRT 渲染于 <name> 内,对应 legacy 的认证/等级徽章位) */
@@ -36,10 +228,164 @@
/* source: assets/css/frontend/comments/mobile-item.css */ /* source: assets/css/frontend/comments/mobile-item.css */
/* ============================================================ /* ============================================================
* AKSRT Comments 移动端 — 补充层 * AKSRT Comments — 移动端(1:1 自有版权)
* *
* 移动端评论样式(.mobile-fixed 弹层、.virtual-input 假输入、 * 自参考主题评论区移动端媒体查询段全量移植(表情与快捷短语
* 头像/缩进/分页的移动端覆盖)全部由 vendor main.min.css 的 * 不在复刻范围),vendor main.min.css 已剥离同段规则。
* @media (max-width:767px) 提供,此处不复制,避免覆盖正版样式。 * 依赖:bundle 中更早加载的 bootstrap 3 与 core/tokens.css 变量。
* 目前无补充规则,保留文件以维持 enqueue 句柄链。
* ============================================================ */ * ============================================================ */
@media (max-width: 767px) {
.virtual-input {
display: flex;
height: 36px;
border-radius: 120px;
background: var(--main-shadow);
color: var(--muted-2-color);
}
.virtual-input .but,
.virtual-input img {
width: 28px;
height: 28px;
border-radius: 120px;
margin: 0 4px;
flex-shrink: 0;
}
.virtual-input .but {
width: auto;
padding: 3px 10px;
}
.drop-fixed-sm .dropdown-menu,
.mobile-fixed {
position: fixed;
transform: translateY(220%);
transition: 0.6s;
opacity: 1;
left: 0;
right: 0;
bottom: 0;
padding: 22px 16px;
background: var(--main-bg-color);
z-index: 1080;
border-radius: 10px 10px 0 0;
margin: 0;
}
.drop-fixed-sm.open .dropdown-menu,
.mobile-fixed.show {
box-shadow: 0 -50px 50px rgba(0, 0, 0, 0.2);
transition: 0.6s cubic-bezier(0.28, 0.9, 0.34, 0.99);
transform: unset;
}
.mobile-fixed.show .fixed-body {
visibility: unset;
z-index: -1;
}
#respond.mobile-fixed {
z-index: 1040;
}
.drop-fixed-sm .dropdown-menu {
z-index: 1045;
padding: 10px;
top: auto !important;
right: 0 !important;
left: 0 !important;
max-height: 50vh;
overflow: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.drop-fixed-sm .dropdown-menu > li > a {
font-size: 16px !important;
padding: 10px 20px;
}
.modal-open .drop-fixed-sm.open .dropdown-menu {
opacity: 0;
}
.drop-fixed-sm .dropdown-menu::before {
display: none;
}
}
@media (max-width: 640px) {
#comments .comt-title {
display: none;
}
#comments .comt-box {
width: 100%;
padding: 0;
}
#comments .list-inline {
padding: 15px 0;
margin: 0;
}
.comment-signarea h3 {
font-size: 13px;
}
.comt-tips-left .but svg,
.comt-tips-left .but .fa {
margin: 0;
}
.btn-input-expand {
width: 31px;
padding: 0;
height: 31px;
line-height: 31px;
}
#postcomments .comment-header {
font-size: 14px;
}
#postcomments .comt-meta {
font-size: 12px;
}
#postcomments .comment .list-inline > li {
padding: 0;
}
#postcomments .comment .list-inline > li + li {
padding-left: 10px;
}
#postcomments .avatar-img {
--this-size: 36px;
margin-right: 10px;
}
#postcomments .commentlist > .comment > .list-inline .comment-footer {
margin-left: 45px;
margin-top: -15px;
}
#postcomments .children {
margin-left: 0px;
}
#postcomments .children .children {
margin-left: 13px;
}
#postcomments .children .list-inline {
padding: 15px;
}
#postcomments .post_ajax_loader .ml20 {
margin-left: 5px;
}
}
+1 -1
View File
@@ -1 +1 @@
#comments .comment-header .aksrt-identity-chip{display:inline-flex;align-items:center;gap:3px;vertical-align:middle;max-width:9em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}#comments .comment-header .aksrt-identity-medal{display:inline-block;width:auto;height:1.1em;max-width:6em;object-fit:contain;vertical-align:-.15em} #comments .comment-box .comments-closed,#comments .action-text,#comments #cancel-comment-reply-link{display:none}#comments #postcomments .action-text,#comments #postcomments #cancel-comment-reply-link{display:inline-block}#comments .comt-title{width:90px}#comments .comt-title .comt-avatar .avatar{width:60px;height:60px}#comments #postcomments .comt-title{display:none}#respond:not(.mobile-fixed) #postcomments .comt-box{padding:5px 5px 4px;background:var(--main-bg-color);border-radius:4px;margin-top:12px}#comments #postcomments .comt-ctrl .but{margin-bottom:2px}#comments .list-inline{padding:15px}#comment{margin-bottom:5px}.comment-signarea{background:var(--main-shadow)}#respond+#postcomments .comment-filter,.comment-signarea+#postcomments .comment-filter{margin-top:20px}#postcomments .tab-nav-theme{margin-top:0}#postcomments .tab-nav-theme li{padding-bottom:1px}#postcomments .tab-nav-theme li:before{bottom:-2px}#postcomments .comment-footer{position:relative}#postcomments .avatar-img{--this-size: 45px;margin-right:20px}#postcomments .children .avatar-img{--this-size: 26px;vertical-align:2px;margin-right:6px}#postcomments .commentlist>.comment>.list-inline .author-box{align-items:start}#postcomments .commentlist>.comment>.list-inline .comment-footer{margin-left:65px;margin-top:-25px}#postcomments .comment .list-inline>.comt-main{width:100%}#postcomments .commentlist .comment+.comment{border-top:1px solid var(--main-border-color)}#postcomments .comment .list-inline>li{padding:10px;vertical-align:top}#postcomments .comment-header{font-size:15px;position:relative}.comment-header .badge-status{margin-top:0;width:68px;z-index:0}#postcomments .action count{margin-left:4px}#postcomments .comt-meta>span:not(:empty){margin-right:10px;vertical-align:middle}#postcomments .comt-meta>span a{color:inherit}#postcomments .comt-meta>span .but{padding:.2em .8em}#postcomments .comment-approve-link.unapprove{color:#e87725}#postcomments .comment-approve-link.approve{color:#3695ff}#postcomments .comt-meta>span .comment-trash-link{color:#ff4b4b}#postcomments .children{margin-left:86px;background:var(--main-shadow);border-radius:var(--main-radius);margin-bottom:6px}#postcomments .children .children{margin-left:23px}#postcomments .children .avatar-icontag{font-size:8px;height:14px;width:14px}.comment-content{word-wrap:break-word;white-space:pre-wrap}.comment-content .enlighter-default{margin-bottom:0;opacity:.9}#postcomments .comment-content img{max-width:260px;max-height:350px;display:block;width:auto;height:auto}.virtual-input{display:none}.commentlist .no-more{margin:0;padding-bottom:10px}#comments .comment-header .aksrt-identity-chip{display:inline-flex;align-items:center;gap:3px;vertical-align:middle;max-width:9em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}#comments .comment-header .aksrt-identity-medal{display:inline-block;width:auto;height:1.1em;max-width:6em;object-fit:contain;vertical-align:-.15em}@media(max-width:767px){.virtual-input{display:flex;height:36px;border-radius:120px;background:var(--main-shadow);color:var(--muted-2-color)}.virtual-input .but,.virtual-input img{width:28px;height:28px;border-radius:120px;margin:0 4px;flex-shrink:0}.virtual-input .but{width:auto;padding:3px 10px}.drop-fixed-sm .dropdown-menu,.mobile-fixed{position:fixed;transform:translateY(220%);transition:.6s;opacity:1;left:0;right:0;bottom:0;padding:22px 16px;background:var(--main-bg-color);z-index:1080;border-radius:10px 10px 0 0;margin:0}.drop-fixed-sm.open .dropdown-menu,.mobile-fixed.show{box-shadow:0 -50px 50px #0003;transition:.6s cubic-bezier(.28,.9,.34,.99);transform:unset}.mobile-fixed.show .fixed-body{visibility:unset;z-index:-1}#respond.mobile-fixed{z-index:1040}.drop-fixed-sm .dropdown-menu{z-index:1045;padding:10px;top:auto!important;right:0!important;left:0!important;max-height:50vh;overflow:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.drop-fixed-sm .dropdown-menu>li>a{font-size:16px!important;padding:10px 20px}.modal-open .drop-fixed-sm.open .dropdown-menu{opacity:0}.drop-fixed-sm .dropdown-menu:before{display:none}}@media(max-width:640px){#comments .comt-title{display:none}#comments .comt-box{width:100%;padding:0}#comments .list-inline{padding:15px 0;margin:0}.comment-signarea h3{font-size:13px}.comt-tips-left .but svg,.comt-tips-left .but .fa{margin:0}.btn-input-expand{width:31px;padding:0;height:31px;line-height:31px}#postcomments .comment-header{font-size:14px}#postcomments .comt-meta{font-size:12px}#postcomments .comment .list-inline>li{padding:0}#postcomments .comment .list-inline>li+li{padding-left:10px}#postcomments .avatar-img{--this-size: 36px;margin-right:10px}#postcomments .commentlist>.comment>.list-inline .comment-footer{margin-left:45px;margin-top:-15px}#postcomments .children{margin-left:0}#postcomments .children .children{margin-left:13px}#postcomments .children .list-inline{padding:15px}#postcomments .post_ajax_loader .ml20{margin-left:5px}}
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
-14
View File
@@ -1386,17 +1386,3 @@ html.dark .post-drop-meta__item:hover {
.article-tags .but.c-green { color: #5cb85c; } .article-tags .but.c-green { color: #5cb85c; }
.article-tags .but.c-purple { color: #9c27b0; } .article-tags .but.c-purple { color: #9c27b0; }
.article-tags .but.c-red { color: #f44336; } .article-tags .but.c-red { color: #f44336; }
/* ===== legacy user-card after-box ===== */
.user-card.author { margin-bottom: 16px; overflow: hidden; }
.user-card.author .user-avatar { display: flex; justify-content: center; }
.user-card.author .user-avatar .avatar,
.user-card.author .user-avatar img { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; }
.user-card.author .user-name { display: flex; flex-wrap: nowrap; align-items: center; justify-content: center; gap: 4px; }
.user-card.author .user-name .display-name { font-weight: 700; color: var(--key-color, inherit); }
.user-card.author .user-desc { text-align: center; }
.user-card.author .user-btns { text-align: center; }
.user-card.author .user-card-posts ul { list-style: none; margin: 0; padding: 0; }
.user-card.author .user-card-posts li { padding: 6px 0; border-bottom: 1px dashed var(--color-line, rgba(0,0,0,.06)); }
.user-card.author .user-card-posts li:last-child { border-bottom: 0; }
+1 -1
View File
File diff suppressed because one or more lines are too long
+193
View File
@@ -0,0 +1,193 @@
/* ============================================================
* AKSRT Comments — 主布局(1:1 自有版权)
*
* 自参考主题评论区段全量移植(表情与快捷短语不在复刻范围),
* 是评论区布局规则的唯一来源;vendor main.min.css 已剥离同段规则。
* 依赖 bundle 中更早加载的 bootstrap 3(.list-unstyled/.list-inline/
* .dropdown-menu)与 core/tokens.css 的 CSS 变量。
* ============================================================ */
#comments .comment-box .comments-closed,
#comments .action-text,
#comments #cancel-comment-reply-link {
display: none;
}
#comments #postcomments .action-text,
#comments #postcomments #cancel-comment-reply-link {
display: inline-block;
}
#comments .comt-title {
width: 90px;
}
#comments .comt-title .comt-avatar .avatar {
width: 60px;
height: 60px;
}
#comments #postcomments .comt-title {
display: none;
}
#respond:not(.mobile-fixed) #postcomments .comt-box {
padding: 5px 5px 4px 5px;
background: var(--main-bg-color);
border-radius: 4px;
margin-top: 12px;
}
#comments #postcomments .comt-ctrl .but {
margin-bottom: 2px;
}
#comments .list-inline {
padding: 15px;
}
#comment {
margin-bottom: 5px;
}
.comment-signarea {
background: var(--main-shadow);
}
#respond + #postcomments .comment-filter,
.comment-signarea + #postcomments .comment-filter {
margin-top: 20px;
}
#postcomments .tab-nav-theme {
margin-top: 0;
}
#postcomments .tab-nav-theme li {
padding-bottom: 1px;
}
#postcomments .tab-nav-theme li::before {
bottom: -2px;
}
#postcomments .comment-footer {
position: relative;
}
#postcomments .avatar-img {
--this-size: 45px;
margin-right: 20px;
}
#postcomments .children .avatar-img {
--this-size: 26px;
vertical-align: 2px;
margin-right: 6px;
}
#postcomments .commentlist > .comment > .list-inline .author-box {
align-items: start;
}
#postcomments .commentlist > .comment > .list-inline .comment-footer {
margin-left: 65px;
margin-top: -25px;
}
#postcomments .comment .list-inline > .comt-main {
width: 100%;
}
#postcomments .commentlist .comment + .comment {
border-top: 1px solid var(--main-border-color);
}
#postcomments .comment .list-inline > li {
padding: 10px;
vertical-align: top;
}
#postcomments .comment-header {
font-size: 15px;
position: relative;
}
.comment-header .badge-status {
margin-top: 0;
width: 68px;
z-index: 0;
}
#postcomments .action count {
margin-left: 4px;
}
#postcomments .comt-meta > span:not(:empty) {
margin-right: 10px;
vertical-align: middle;
}
#postcomments .comt-meta > span a {
color: inherit;
}
#postcomments .comt-meta > span .but {
padding: 0.2em 0.8em;
}
#postcomments .comment-approve-link.unapprove {
color: #e87725;
}
#postcomments .comment-approve-link.approve {
color: #3695ff;
}
#postcomments .comt-meta > span .comment-trash-link {
color: #ff4b4b;
}
#postcomments .children {
margin-left: 86px;
background: var(--main-shadow);
border-radius: var(--main-radius);
margin-bottom: 6px;
}
#postcomments .children .children {
margin-left: 23px;
}
#postcomments .children .avatar-icontag {
font-size: 8px;
height: 14px;
width: 14px;
}
.comment-content {
word-wrap: break-word;
white-space: pre-wrap;
}
.comment-content .enlighter-default {
margin-bottom: 0;
opacity: 0.9;
}
#postcomments .comment-content img {
max-width: 260px;
max-height: 350px;
display: block;
width: auto;
height: auto;
}
.virtual-input {
display: none;
}
.commentlist .no-more {
margin: 0;
padding-bottom: 10px;
}
+159 -5
View File
@@ -1,8 +1,162 @@
/* ============================================================ /* ============================================================
* AKSRT Comments 移动端 — 补充层 * AKSRT Comments — 移动端(1:1 自有版权)
* *
* 移动端评论样式(.mobile-fixed 弹层、.virtual-input 假输入、 * 自参考主题评论区移动端媒体查询段全量移植(表情与快捷短语
* 头像/缩进/分页的移动端覆盖)全部由 vendor main.min.css 的 * 不在复刻范围),vendor main.min.css 已剥离同段规则。
* @media (max-width:767px) 提供,此处不复制,避免覆盖正版样式。 * 依赖:bundle 中更早加载的 bootstrap 3 与 core/tokens.css 变量。
* 目前无补充规则,保留文件以维持 enqueue 句柄链。
* ============================================================ */ * ============================================================ */
@media (max-width: 767px) {
.virtual-input {
display: flex;
height: 36px;
border-radius: 120px;
background: var(--main-shadow);
color: var(--muted-2-color);
}
.virtual-input .but,
.virtual-input img {
width: 28px;
height: 28px;
border-radius: 120px;
margin: 0 4px;
flex-shrink: 0;
}
.virtual-input .but {
width: auto;
padding: 3px 10px;
}
.drop-fixed-sm .dropdown-menu,
.mobile-fixed {
position: fixed;
transform: translateY(220%);
transition: 0.6s;
opacity: 1;
left: 0;
right: 0;
bottom: 0;
padding: 22px 16px;
background: var(--main-bg-color);
z-index: 1080;
border-radius: 10px 10px 0 0;
margin: 0;
}
.drop-fixed-sm.open .dropdown-menu,
.mobile-fixed.show {
box-shadow: 0 -50px 50px rgba(0, 0, 0, 0.2);
transition: 0.6s cubic-bezier(0.28, 0.9, 0.34, 0.99);
transform: unset;
}
.mobile-fixed.show .fixed-body {
visibility: unset;
z-index: -1;
}
#respond.mobile-fixed {
z-index: 1040;
}
.drop-fixed-sm .dropdown-menu {
z-index: 1045;
padding: 10px;
top: auto !important;
right: 0 !important;
left: 0 !important;
max-height: 50vh;
overflow: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.drop-fixed-sm .dropdown-menu > li > a {
font-size: 16px !important;
padding: 10px 20px;
}
.modal-open .drop-fixed-sm.open .dropdown-menu {
opacity: 0;
}
.drop-fixed-sm .dropdown-menu::before {
display: none;
}
}
@media (max-width: 640px) {
#comments .comt-title {
display: none;
}
#comments .comt-box {
width: 100%;
padding: 0;
}
#comments .list-inline {
padding: 15px 0;
margin: 0;
}
.comment-signarea h3 {
font-size: 13px;
}
.comt-tips-left .but svg,
.comt-tips-left .but .fa {
margin: 0;
}
.btn-input-expand {
width: 31px;
padding: 0;
height: 31px;
line-height: 31px;
}
#postcomments .comment-header {
font-size: 14px;
}
#postcomments .comt-meta {
font-size: 12px;
}
#postcomments .comment .list-inline > li {
padding: 0;
}
#postcomments .comment .list-inline > li + li {
padding-left: 10px;
}
#postcomments .avatar-img {
--this-size: 36px;
margin-right: 10px;
}
#postcomments .commentlist > .comment > .list-inline .comment-footer {
margin-left: 45px;
margin-top: -15px;
}
#postcomments .children {
margin-left: 0px;
}
#postcomments .children .children {
margin-left: 13px;
}
#postcomments .children .list-inline {
padding: 15px;
}
#postcomments .post_ajax_loader .ml20 {
margin-left: 5px;
}
}
+5 -8
View File
@@ -1,14 +1,11 @@
/* ============================================================ /* ============================================================
* AKSRT Comments — 补充层 * AKSRT Comments — 补充层
* *
* 评论区的全部样式以 vendor 的 legacy 正版样式为准: * 评论区布局样式已硬切换为自有版权(见 layout.css / mobile-item.css),
* assets/css/main.min.css(含 #comments/#postcomments * vendor main.min.css 不再提供评论区规则。
* 桌面规则与移动端媒体查询:.mobile-fixed/.virtual-input/.pagenav/ * 本文件只放 AKSRT 特有标记的补充规则(identity chip/medal)。
* .tab-nav-theme/.dropdown-menu/.line-form/.placeholder 等) * 共享基础样式仍由 bundle 中更早加载的 bootstrap 3 与
* + bootstrap 3(.list-unstyled/.list-inline) * core/tokens.css 提供。
*
* 本文件只补 AKSRT 特有标记的样式,禁止复制 legacy 规则——
* 带 #comments id 前缀的副本会覆盖 vendor 正版样式造成 UI 偏差。
* ============================================================ */ * ============================================================ */
/* 身份徽章(AKSRT 渲染于 <name> 内,对应 legacy 的认证/等级徽章位) */ /* 身份徽章(AKSRT 渲染于 <name> 内,对应 legacy 的认证/等级徽章位) */
+7 -379
View File
@@ -2857,45 +2857,6 @@ input + .limit-warning.top::after {
max-height: 350px; max-height: 350px;
} }
.dropdown-quick-often {
width: 260px;
}
.dropdown-quick-often .scroll-y {
max-height: 280px;
}
.dropdown-quick-often .list-inline {
padding: 0 10px !important;
}
.quick-reply-item {
padding: 6px 0;
color: var(--muted-color);
margin: 0 10px;
}
.quick-reply-item + .quick-reply-item {
border-top: 1px solid var(--main-border-color);
}
.quick-reply-item.quick-active {
border-radius: 8px;
border: 1px solid var(--focus-shadow-color);
padding: 7px;
box-shadow: 0 0 10px 0 var(--focus-shadow-color);
margin: 0px 5px;
}
.quick-reply-item.quick-active .quick-reply-action {
margin: -7px;
margin-top: 7px;
}
.quick-reply-action .modal-buts.but-average {
margin: 0 !important;
}
.quick-reply-action .modal-buts.but-average > .but {
padding: 5px;
}
.dropdown-link, .dropdown-link,
.dropdown-code, .dropdown-code,
.dropdown-image { .dropdown-image {
@@ -8112,19 +8073,10 @@ badge.top,
border-radius: 100px; border-radius: 100px;
} }
.footer-tabbar .virtual-input .but,
.footer-tabbar .single-action-tabbar text { .footer-tabbar .single-action-tabbar text {
display: none; display: none;
} }
.footer-tabbar .virtual-input {
flex: auto;
height: auto;
min-height: auto;
margin: 0 12px;
overflow: hidden;
}
.footer-tabbar count { .footer-tabbar count {
color: var(--muted-2-color); color: var(--muted-2-color);
border-radius: 20px; border-radius: 20px;
@@ -9269,188 +9221,8 @@ img.alignleft {
text-align: right; text-align: right;
} }
/*------评论模块------评论模块------评论模块------评论模块------评论模块------评论模块------评论模块------评论模块------*/ /*------评论区样式已硬切换至 assets/css/frontend/comments/(自有版权),
#comments .comment-box .comments-closed, 以下仅保留全站复用的评论小部件与共享规则。------*/
#comments .action-text,
#comments #cancel-comment-reply-link {
display: none;
}
#comments #postcomments .action-text,
#comments #postcomments #cancel-comment-reply-link {
display: inline-block;
}
#comments .comt-title {
width: 90px;
}
#comments .comt-title .comt-avatar .avatar {
width: 60px;
height: 60px;
}
#comments #postcomments .comt-title {
display: none;
}
#respond:not(.mobile-fixed) #postcomments .comt-box {
padding: 5px 5px 4px 5px;
background: var(--main-bg-color);
border-radius: 4px;
margin-top: 12px;
}
#comments #postcomments .comt-ctrl .but {
margin-bottom: 2px;
}
#comments .list-inline {
padding: 15px;
}
#comment {
margin-bottom: 5px;
}
.comment-signarea {
background: var(--main-shadow);
}
#respond + #postcomments .comment-filter,
.comment-signarea + #postcomments .comment-filter {
margin-top: 20px;
}
#postcomments .tab-nav-theme {
margin-top: 0;
}
#postcomments .tab-nav-theme li {
padding-bottom: 1px;
}
#postcomments .tab-nav-theme li::before {
bottom: -2px;
}
#postcomments .comment-footer {
position: relative;
}
#postcomments .avatar-img {
--this-size: 45px;
margin-right: 20px;
}
#postcomments .children .avatar-img {
--this-size: 26px;
vertical-align: 2px;
margin-right: 6px;
}
#postcomments .commentlist > .comment > .list-inline .author-box {
align-items: start;
}
#postcomments .commentlist > .comment > .list-inline .comment-footer {
margin-left: 65px;
margin-top: -25px;
}
#postcomments .comment .list-inline > .comt-main {
width: 100%;
}
#postcomments .commentlist .comment + .comment {
border-top: 1px solid var(--main-border-color);
}
#postcomments .comment .list-inline > li {
padding: 10px;
vertical-align: top;
}
#postcomments .comment-header {
font-size: 15px;
position: relative;
}
.comment-header .badge-status {
margin-top: 0;
width: 68px;
z-index: 0;
}
#postcomments .action count {
margin-left: 4px;
}
#postcomments .comt-meta > span:not(:empty) {
margin-right: 10px;
vertical-align: middle;
}
#postcomments .comt-meta > span a {
color: inherit;
}
#postcomments .comt-meta > span .but {
padding: 0.2em 0.8em;
}
#postcomments .comment-approve-link.unapprove {
color: #e87725;
}
#postcomments .comment-approve-link.approve {
color: #3695ff;
}
#postcomments .comt-meta > span .comment-trash-link {
color: #ff4b4b;
}
#postcomments .children {
margin-left: 86px;
background: var(--main-shadow);
border-radius: var(--main-radius);
margin-bottom: 6px;
}
#postcomments .children .children {
margin-left: 23px;
}
#postcomments .children .avatar-icontag {
font-size: 8px;
height: 14px;
width: 14px;
}
.content-after-box,
.comment-content {
word-wrap: break-word;
white-space: pre-wrap;
}
.comment-content .enlighter-default {
margin-bottom: 0;
opacity: 0.9;
}
#postcomments .comment-content img {
max-width: 260px;
max-height: 350px;
display: block;
width: auto;
height: auto;
}
.virtual-input {
display: none;
}
.comment-mini-lists.aksrt-panel { .comment-mini-lists.aksrt-panel {
padding: 5px; padding: 5px;
} }
@@ -9501,7 +9273,11 @@ img.alignleft {
border-radius: 2px; border-radius: 2px;
} }
.commentlist .no-more, .content-after-box {
word-wrap: break-word;
white-space: pre-wrap;
}
.theme-pagination.pagenav { .theme-pagination.pagenav {
margin: 0; margin: 0;
padding-bottom: 10px; padding-bottom: 10px;
@@ -11600,7 +11376,6 @@ body.error404 {
font-size: 15px; font-size: 15px;
} }
.drop-fixed-sm .dropdown-menu::before,
.posts-item:not(.no-thumb) .item-excerpt { .posts-item:not(.no-thumb) .item-excerpt {
display: none; display: none;
} }
@@ -11686,81 +11461,6 @@ body.error404 {
height: calc(49px + env(safe-area-inset-bottom)); height: calc(49px + env(safe-area-inset-bottom));
} }
.virtual-input {
display: flex;
height: 36px;
border-radius: 120px;
background: var(--main-shadow);
color: var(--muted-2-color);
}
.virtual-input .but,
.virtual-input img {
width: 28px;
height: 28px;
border-radius: 120px;
margin: 0 4px;
flex-shrink: 0;
}
.virtual-input .but {
width: auto;
padding: 3px 10px;
}
.drop-fixed-sm .dropdown-menu,
.mobile-fixed {
position: fixed;
transform: translateY(220%);
transition: 0.6s;
opacity: 1;
left: 0;
right: 0;
bottom: 0;
padding: 22px 16px;
background: var(--main-bg-color);
z-index: 1080;
border-radius: 10px 10px 0 0;
margin: 0;
}
.drop-fixed-sm.open .dropdown-menu,
.mobile-fixed.show {
box-shadow: 0 -50px 50px rgba(0, 0, 0, 0.2);
transition: 0.6s cubic-bezier(0.28, 0.9, 0.34, 0.99);
transform: unset;
}
.mobile-fixed.show .fixed-body {
visibility: unset;
z-index: -1;
}
#respond.mobile-fixed {
z-index: 1040;
}
.drop-fixed-sm .dropdown-menu {
z-index: 1045;
padding: 10px;
top: auto !important;
right: 0 !important;
left: 0 !important;
max-height: 50vh;
overflow: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.drop-fixed-sm .dropdown-menu > li > a {
font-size: 16px !important;
padding: 10px 20px;
}
.modal-open .drop-fixed-sm.open .dropdown-menu {
opacity: 0;
}
.footer { .footer {
padding: 10px 0; padding: 10px 0;
} }
@@ -12205,74 +11905,6 @@ body.error404 {
width: 68px; width: 68px;
} }
#comments .comt-title {
display: none;
}
#comments .comt-box {
width: 100%;
padding: 0;
}
#comments .list-inline {
padding: 15px 0;
margin: 0;
}
.comment-signarea h3 {
font-size: 13px;
}
.comt-tips-left .but svg,
.comt-tips-left .but .fa {
margin: 0;
}
.btn-input-expand {
width: 31px;
padding: 0;
height: 31px;
line-height: 31px;
}
#postcomments .comment-header {
font-size: 14px;
}
#postcomments .comt-meta {
font-size: 12px;
}
#postcomments .comment .list-inline > li {
padding: 0;
}
#postcomments .comment .list-inline > li + li {
padding-left: 10px;
}
#postcomments .avatar-img {
--this-size: 36px;
margin-right: 10px;
}
#postcomments .commentlist > .comment > .list-inline .comment-footer {
margin-left: 45px;
margin-top: -15px;
}
#postcomments .children {
margin-left: 0px;
}
#postcomments .children .children {
margin-left: 13px;
}
#postcomments .children .list-inline {
padding: 15px;
}
.pagenav a, .pagenav a,
.pagination ul > li { .pagination ul > li {
display: none; display: none;
@@ -12289,10 +11921,6 @@ body.error404 {
min-width: 28px; min-width: 28px;
} }
#postcomments .post_ajax_loader .ml20 {
margin-left: 5px;
}
.author-minicard { .author-minicard {
width: 100%; width: 100%;
margin: 5px 0; margin: 5px 0;
+1 -1
View File
File diff suppressed because one or more lines are too long
+10 -5
View File
@@ -273,20 +273,25 @@
// §10.10a — 拦截 vendor 评论脚本 & 解绑 vendor ajax 委托 // §10.10a — 拦截 vendor 评论脚本 & 解绑 vendor ajax 委托
// ══════════════════════════════════════════════════════════════ // ══════════════════════════════════════════════════════════════
// vendor 链路:loader.js(tbquire,改造版 RequireJS)→ main.min.js 检测到 // vendor 链路:loader.js(tbquire,改造版 RequireJS)→ main.min.js 检测到
// #commentform/#postcomments 即 tbquire(["comment"]) 懒加载 comment.min.js。 // #commentform/#postcomments 即 tbquire(["comment"]) 懒加载 comment.min.js;
// 检测到 .dropdown-code/.dropdown-image 即 tbquire(["input-expand"])。
// AKSRT 自有评论脚本(comments/comment-tools/comment-fixed-input/ // AKSRT 自有评论脚本(comments/comment-tools/comment-fixed-input/
// comment-move-form/comment-ajax)已承担全部行为,vendor comment.min.js 的 // comment-move-form/comment-ajax)已承担全部行为,vendor comment.min.js 的
// 7 条 body 委托会双路触发(提交 legacy action=submit_comment 无处理器, // 7 条 body 委托会双路触发(提交 legacy action=submit_comment 无处理器,
// 即控制台「ajax请求错误」400 "0" 的来源;回复/排序/分页同理)。 // 即控制台「ajax请求错误」400 "0" 的来源;回复/排序/分页同理);
// vendor input-expand.min.js(表情/快捷回复旧链路,源文件已删除)同理不再下载。
// //
// 双层防御: // 双层防御:
// 1) tbfine 预注册空 'comment' 模块 → tbquire 不再下载 comment.min.js; // 1) tbfine 预注册空 'comment'/'input-expand' 模块 → tbquire 不再下载;
// 2) 若模块抢在注册前加载,退化为对 7 条委托做幂等 .off。 // 2) 若模块抢在注册前加载,退化为对 7 条委托做幂等 .off。
function stubVendorCommentModule() { function stubVendorCommentModule() {
if (!(window.tbfine && window.tbquire && window.tbquire.defined)) return false; if (!(window.tbfine && window.tbquire && window.tbquire.defined)) return false;
try { try {
if (window.tbquire.defined('comment')) return true; ['comment', 'input-expand'].forEach(function (name) {
window.tbfine('comment', [], function () { return {}; }); if (!window.tbquire.defined(name)) {
window.tbfine(name, [], function () { return {}; });
}
});
return true; return true;
} catch (e) { } catch (e) {
return false; return false;
+10 -5
View File
@@ -547,20 +547,25 @@ tbquire.config({
// §10.10a — 拦截 vendor 评论脚本 & 解绑 vendor ajax 委托 // §10.10a — 拦截 vendor 评论脚本 & 解绑 vendor ajax 委托
// ══════════════════════════════════════════════════════════════ // ══════════════════════════════════════════════════════════════
// vendor 链路:loader.js(tbquire,改造版 RequireJS)→ main.min.js 检测到 // vendor 链路:loader.js(tbquire,改造版 RequireJS)→ main.min.js 检测到
// #commentform/#postcomments 即 tbquire(["comment"]) 懒加载 comment.min.js。 // #commentform/#postcomments 即 tbquire(["comment"]) 懒加载 comment.min.js;
// 检测到 .dropdown-code/.dropdown-image 即 tbquire(["input-expand"])。
// AKSRT 自有评论脚本(comments/comment-tools/comment-fixed-input/ // AKSRT 自有评论脚本(comments/comment-tools/comment-fixed-input/
// comment-move-form/comment-ajax)已承担全部行为,vendor comment.min.js 的 // comment-move-form/comment-ajax)已承担全部行为,vendor comment.min.js 的
// 7 条 body 委托会双路触发(提交 legacy action=submit_comment 无处理器, // 7 条 body 委托会双路触发(提交 legacy action=submit_comment 无处理器,
// 即控制台「ajax请求错误」400 "0" 的来源;回复/排序/分页同理)。 // 即控制台「ajax请求错误」400 "0" 的来源;回复/排序/分页同理);
// vendor input-expand.min.js(表情/快捷回复旧链路,源文件已删除)同理不再下载。
// //
// 双层防御: // 双层防御:
// 1) tbfine 预注册空 'comment' 模块 → tbquire 不再下载 comment.min.js; // 1) tbfine 预注册空 'comment'/'input-expand' 模块 → tbquire 不再下载;
// 2) 若模块抢在注册前加载,退化为对 7 条委托做幂等 .off。 // 2) 若模块抢在注册前加载,退化为对 7 条委托做幂等 .off。
function stubVendorCommentModule() { function stubVendorCommentModule() {
if (!(window.tbfine && window.tbquire && window.tbquire.defined)) return false; if (!(window.tbfine && window.tbquire && window.tbquire.defined)) return false;
try { try {
if (window.tbquire.defined('comment')) return true; ['comment', 'input-expand'].forEach(function (name) {
window.tbfine('comment', [], function () { return {}; }); if (!window.tbquire.defined(name)) {
window.tbfine(name, [], function () { return {}; });
}
});
return true; return true;
} catch (e) { } catch (e) {
return false; return false;
+21 -10
View File
@@ -1,5 +1,5 @@
/** /**
* Comment expand tools — legacy-style shortcode inserts ([code] [img=] quick). * Comment expand tools — legacy-style shortcode inserts ([code] [img=]).
*/ */
(function () { (function () {
'use strict'; 'use strict';
@@ -39,6 +39,26 @@
} }
document.addEventListener('click', function (e) { document.addEventListener('click', function (e) {
var linkBtn = e.target && e.target.closest ? e.target.closest('.input-link-submit') : null;
if (linkBtn) {
e.preventDefault();
var lbox = linkBtn.closest('.dropdown-link');
var lta = lbox ? lbox.querySelector('textarea.link-textarea') : null;
var url = lta ? (lta.value || '').trim() : '';
if (!/^https?:\/\/\S+$/i.test(url)) {
notyf('请输入有效链接地址', 'warning');
return;
}
var ltext = lbox ? (lbox.querySelector('.link-text') || {}).value || '' : '';
insertAtCursor(findTextarea(linkBtn), '[link=' + url + ']' + (ltext.trim() || url) + '[/link]');
if (lta) lta.value = '';
var lt = lbox ? lbox.querySelector('.link-text') : null;
if (lt) lt.value = '';
var lw = linkBtn.closest('span.dropup');
if (lw) lw.classList.remove('open');
return;
}
var codeBtn = e.target && e.target.closest ? e.target.closest('.input-code-submit') : null; var codeBtn = e.target && e.target.closest ? e.target.closest('.input-code-submit') : null;
if (codeBtn) { if (codeBtn) {
e.preventDefault(); e.preventDefault();
@@ -96,15 +116,6 @@
fileInput.click(); fileInput.click();
return; return;
} }
var q = e.target && e.target.closest ? e.target.closest('.quick-reply-item') : null;
if (q) {
e.preventDefault();
var phrase = q.getAttribute('data-text') || q.textContent || '';
insertAtCursor(findTextarea(q), phrase);
var qw = q.closest('span.dropup');
if (qw) qw.classList.remove('open');
}
}); });
document.addEventListener('keydown', function (e) { document.addEventListener('keydown', function (e) {
-343
View File
@@ -1,343 +0,0 @@
jQuery.fn.FixedInput = function (action) {
var _this = jQuery(this);
if (!_this.attr('on-start')) {
_this
.on('click', '.fixed-body', function () {
_this.FixedInput('hide');
})
.attr('on-start', true);
}
switch (action) {
case 'show':
_this.addClass('show');
return setTimeout(() => {
jQuery(_this.find('textarea,input')[0]).focus();
}, 100);
case 'hide':
_this.find('#cancel-comment-reply-link').click();
_this.find('input,textarea').blur();
_this.find('.dropup').removeClass('open');
return _this.removeClass('show');
default:
}
};
//移动端浮动的input|暂时仅用在评论
_win.bd.on('click', '[fixed-input]', function () {
var _this = jQuery(this);
// var _input = jQuery(_this.attr('data-input'));
var _fixed = jQuery(_this.attr('fixed-input'));
scrollTopTo('#comments');
_fixed.FixedInput('show');
//_input.length && _input.focus();
});
var $comments = jQuery('#comments-title');
var $cancel = jQuery('#cancel-comment-reply-link');
var $author = jQuery('#comment-user-info');
var $submit = jQuery('#commentform #submit');
var $com_ajax_url = _win.ajax_url;
var $com_list = jQuery('#postcomments .commentlist');
//评论ajax翻页
_win.bd.on('click', '.commentlist .pagenav a,.comment-orderby', function () {
var _this = jQuery(this);
jQuery('#cancel-comment-reply-link').click();
if (_this.hasClass('pag-jump')) {
_this.addClass('ajax-next');
return;
}
var ajax_replace = !_this.attr('no-replace');
return post_ajax(jQuery(this), '.commentlist', '.commentlist', '.comment', '', '.pagenav', '', '', ajax_replace);
});
//编辑按钮,回复
_win.bd.on('click', '.comment-edit-link,.comment-reply-link', function () {
var _this = jQuery(this),
commentid = _this.attr('data-commentid');
var is_edit = _this.hasClass('comment-edit-link');
return addComment.moveForm(_this, 'div-comment-' + commentid, commentid, 'respond', _this.attr('data-postid'), is_edit), scrollTopTo(jQuery('#div-comment-' + commentid), -10), !1;
});
//回车提交
_win.bd.on('keydown', '#comment', function (e) {
var keycode = e.which || e.keyCode;
if ((e.metaKey || e.ctrlKey) && keycode == 13) {
jQuery(this).closest('#commentform').find('#submit').click();
}
});
//删除评论
_win.bd.on('click', '.comment-trash-link', function () {
var _this = jQuery(this);
var commentid = _this.attr('data-commentid');
var trash_data = {
action: 'trash_comment',
comment_id: commentid,
_wpnonce: _this.attr('data-nonce'),
};
if (confirm(aksrt__('comment_confirm_delete')) == 1) {
aksrt_ajax(
_this,
trash_data,
function (n) {
n.error ||
jQuery('#comment-' + commentid)
.slideUp()
.delay(1000, function () {
jQuery(this).remove();
});
},
aksrt__('processing')
);
}
});
//审核评论
_win.bd.on('click', '.comment-approve-link', function () {
var _this = jQuery(this);
var commentid = _this.attr('data-commentid');
var trash_data = {
action: 'approve_comment',
comment_id: commentid,
_wpnonce: _this.attr('data-nonce'),
};
var reply = jQuery('#div-comment-' + commentid).find('.reply-link');
aksrt_ajax(_this, trash_data, function (n) {
if (!n.error) {
var _text = n.status == 'hold' ? aksrt__('comment_approve') : aksrt__('comment_reject');
var _class = n.status == 'hold' ? 'approve' : 'unapprove';
var _badg = n.status == 'hold' ? '<span class="badg c-red badg-sm">' + aksrt__('comment_pending_review') + '</span>' : '';
if (n.status == 'hold') {
reply.remove();
} else {
reply.length || _this.parents('.dropdown').before('<span class="reply-link"><a class="comment-reply-link" data-commentid="' + commentid + '" href="javascript:;">' + aksrt__('comment_reply') + '</a></span>');
}
jQuery('#div-comment-' + commentid)
.find('.badge-approve')
.html(_badg);
_this.removeClass('approve unapprove').addClass(_class).find('text').html(_text);
}
});
});
function htmlEscapes(val) {
var htmlEscapes = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;',
};
var a = val.replace(/[&<>"']/g, function (match) {
return htmlEscapes[match];
});
return a;
}
function htmlUnescapes(val) {
var htmlUnescapes = {
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&quot;': '"',
'&#039;': "'",
};
var a = val.replace(/&(amp|lt|gt|quot|#039);/g, function (match) {
return htmlUnescapes[match];
});
return a;
}
//提交评论
_win.bd.on('click', '#commentform #submit', function () {
var _this = jQuery(this);
var _form = _this.parents('#commentform');
var inputs = _form.serializeObject();
if ($author.length && $author.attr('require_name_email')) {
if (inputs.author.length < 2 || inputs.email.length < 4) {
return notyf(aksrt__('comment_enter_name_email'), 'warning'), $author.addClass('open').find('[name="author"]').focus(), !1;
}
if (!is_mail(inputs.email)) {
return notyf(aksrt__('comment_email_invalid'), 'warning'), $author.addClass('open').find('[name="email"]').focus(), !1;
}
}
if (inputs.comment.length < 4) {
return notyf(aksrt__('comment_too_short'), 'warning'), jQuery('#comment').focus(), !1;
}
inputs.comment = htmlEscapes(inputs.comment);
inputs.action = 'submit_comment';
aksrt_ajax(_this, inputs, function (n) {
var data = n.html;
if (!n.error && data) {
if (inputs.edit_comment_ID) {
//编辑评论后提交
$cancel.click();
jQuery('#comment-content-' + inputs.edit_comment_ID).html(data);
} else {
//新建评论
var data = data.replace(/class="comment/, 'style="display:none;" class="comment ajax-comment');
var respond = jQuery('#respond');
var $com_list = jQuery('#postcomments .commentlist');
var is_comment_parent = respond.parent().parent('.comment');
if (is_comment_parent.length) {
var _children = is_comment_parent.find('>.children');
if (_children.length) {
_children.prepend(data);
} else {
is_comment_parent.append('<ul class="children">' + data + '</ul>');
}
} else {
if (!$com_list.length) {
respond.after('<div id="postcomments"><ol class="commentlist list-unstyled">' + data + '</ol></div>');
} else {
var $order = jQuery('#postcomments .commentlist>.comment-filter');
if ($order.length) {
$order.after(data);
} else {
$com_list.prepend(data);
}
}
}
if (jQuery('[reply-show]').length && n.comment) {
if (~~n.comment.comment_approved > 0) {
var hash = jQuery(jQuery('[reply-show]')[0]).attr('reload-hash'); //跳转
if (hash) {
window.location.hash = hash;
}
window.location.reload();
} else {
setTimeout(function () {
notyf(aksrt__('comment_hidden_after_review'), 'warning');
}, 200);
}
}
$cancel.click();
jQuery('#postcomments .ajax-comment').slideDown(200).removeClass('ajax-comment');
jQuery('#postcomments .comment-null').slideUp(200);
}
auto_fun();
wait_for(n.wait_time);
jQuery('#comment').val('');
jQuery('#respond').FixedInput('hide');
}
});
return false;
});
var addComment = {
moveForm: function (_this, commId, parentId, respondId, postId, num) {
var t = this,
div,
comm = t.I(commId),
respond = t.I(respondId),
cancel = t.I('cancel-comment-reply-link'),
parent = t.I('comment_parent'),
post = t.I('comment_post_ID');
var action_text_r = jQuery('#' + respondId + ' .action-text');
jQuery('.comment-footer').show();
if (num) {
var $submit_html = $submit.html();
action_text_r.html(aksrt__('comment_edit_content'));
t.I('comment').value = ''; //清空内容
jQuery('#comment_parent').attr('name', 'edit_comment_ID');
$submit.attr('disabled', true).html('<i class="loading mr6"></i><span>' + aksrt__('loading') + '</span>');
jQuery('#comment').attr('disabled', true).val(aksrt__('comment_fetching_content'));
jQuery('#' + commId)
.find('.comment-footer')
.hide();
var data = {
action: 'get_comment',
comment_id: parentId,
};
aksrt_ajax(
_this,
data,
function (n) {
n.error && $cancel.click();
$submit.html($submit_html).attr('disabled', false);
jQuery('#comment').attr('disabled', false).val(htmlUnescapes(n.comment_content)).focus();
},
'stop'
);
}
action_text_r.html(_this.attr('data-replyto'));
t.respondId = respondId;
postId = postId || false;
if (!t.I('wp-temp-form-div')) {
div = document.createElement('div');
div.id = 'wp-temp-form-div';
div.style.display = 'none';
respond.parentNode.insertBefore(div, respond);
}
!comm ? ((temp = t.I('wp-temp-form-div')), (t.I('comment_parent').value = '0'), temp.parentNode.insertBefore(respond, temp), temp.parentNode.removeChild(temp)) : comm.parentNode.insertBefore(respond, comm.nextSibling);
// pcsheight()
if (post && postId) post.value = postId;
parent.value = parentId;
cancel.style.display = '';
cancel.onclick = function () {
var t = addComment,
temp = t.I('wp-temp-form-div'),
respond = t.I(t.respondId);
jQuery('#comment_parent').attr('name', 'comment_parent');
t.I('comment_parent').value = '0';
jQuery('.comment-footer').show();
jQuery('#comment').val('').trigger('input');
setTimeout(function () {
jQuery('#' + respondId).removeClass('show');
}, 10);
action_text_r.html('');
if (temp && respond) {
temp.parentNode.insertBefore(respond, temp);
temp.parentNode.removeChild(temp);
}
this.style.display = 'none';
this.onclick = null;
return false;
};
try {
setTimeout(function () {
jQuery('#' + respondId).FixedInput('show');
}, 10);
} catch (e) {}
return false;
},
I: function (e) {
return document.getElementById(e);
},
};
//等待
function wait_for($time) {
var wait = $time || 15;
var $submit_html = $submit.html();
function wait_ing() {
if (wait > 0) {
$submit.html('<div style="width:55px;"><i class="loading mr10"></i>' + wait + '</div>').attr('disabled', true);
wait--;
setTimeout(wait_ing, 1000);
} else {
$submit.html($submit_html).attr('disabled', false);
wait = 15;
}
}
wait_ing();
}
File diff suppressed because one or more lines are too long
-101
View File
@@ -1,101 +0,0 @@
//内容追加到编辑框
function grin(_this, val, fun) {
var textarea = _this.parents('form').find('textarea.grin');
var t_val = textarea.val();
textarea
.val(t_val + val)
.focus()
.click();
jQuery.isFunction(fun) && fun(_this, val);
}
//编辑框添加代码
_win.bd.on('click', '.dropdown-code [type="submit"]', function () {
var _this = jQuery(this);
var val = _this.parents('.dropdown-code').find('textarea').val();
if (val.length < 2) return void notyf(aksrt__('enter_code'), 'warning');
val = '[code]\n' + val + '\n[/code]\n';
return grin(_this, val);
});
//编辑框添加图片
_win.bd.on('click', '.dropdown-image [type="submit"]', function () {
var _this = jQuery(this);
var val = _this.parents('.dropdown-image').find('textarea').val();
if (val.length < 6) return void notyf(aksrt__('enter_valid_image_url'), 'warning');
val = '[img=' + val + ']\n';
return grin(_this, val);
});
//上传图片
_win.bd.on('miniuploaded', '.input-expand-upload', function (a, data) {
var img = '[img=' + data.img_url + ']\n';
return grin(jQuery(this), img);
});
//按钮展开
_win.bd.on('click', '.btn-input-expand', function () {
return jQuery(this).parent().toggleClass('open').trigger('toggleClass'), !1;
});
//编辑框添加链接
_win.bd.on('click', '.dropdown-link [type="submit"]', function () {
var _this = jQuery(this);
var val = _this.closest('.dropdown-link').find('textarea').val();
if (val.length < 6) return void notyf(aksrt__('enter_valid_link_url'), 'warning');
//判断URL合法性
if (!aksrt_is_url(val)) {
return void notyf(aksrt__('enter_valid_link_url'), 'warning');
}
var target = '';
if (_this.closest('.dropdown-link').find('input[name="target"]').is(':checked')) {
target = 'target=_blank';
}
var text = _this.closest('.dropdown-link').find('.link-text').val() || val;
var link_val = '[link=' + val + ' ' + target + ']' + text + '[/link]';
return grin(_this, link_val);
});
//保存我的快捷回复后,自动更新
_win.bd.on('aksrt_ajax.success', '.user-quick-often-save-btn', function (e, data) {
if (data.item) {
jQuery('.quick-reply-myitem-box').html(data.item);
}
});
//快捷回复;选择内容,弹出操作按钮
_win.bd.on('click', '.quick-reply-item', function () {
var _this = jQuery(this);
var quick_reply_action = 'quick-reply-action';
var quick_active = 'quick-active';
_this.siblings().removeClass(quick_active);
_this
.parent()
.find('.' + quick_reply_action)
.remove();
_this
.data('quick-reply', _this.text())
.addClass('quick-active')
.append('<div class="' + quick_reply_action + '"><div class="modal-buts but-average"><button type="button" class="but quick-reply-btn-insert" href="javascript:;">' + aksrt__('insert') + '</button><button type="button" class="but c-blue padding-lg quick-reply-btn-send">' + aksrt__('send') + '</button></div></div>');
});
//快捷回复:插入内容或发送
_win.bd.on('click', '.quick-reply-action button', function () {
var _this = jQuery(this);
var form = _this.closest('form'); //唯一的表单
var quick_reply = _this.parents('.quick-reply-item').data('quick-reply');
var textarea = form.find('textarea.grin');
textarea.val(quick_reply);
if (_this.hasClass('quick-reply-btn-send')) {
form.find('.input-expand-submit').click();
} else {
textarea.focus();
}
});
-6
View File
@@ -1,6 +0,0 @@
function grin(n,t,i){var e=n.parents("form").find("textarea.grin"),r=e.val();e.val(r+t).focus().click(),jQuery.isFunction(i)&&i(n,t)}_win.bd.on("click",'.dropdown-code [type="submit"]',function(){var n=jQuery(this),t=n.parents(".dropdown-code").find("textarea").val();return t.length<2?void notyf(aksrt__("enter_code"),"warning"):(t=`[code]
`+t+`
[/code]
`,grin(n,t))}),_win.bd.on("click",'.dropdown-image [type="submit"]',function(){var n=jQuery(this),t=n.parents(".dropdown-image").find("textarea").val();return t.length<6?void notyf(aksrt__("enter_valid_image_url"),"warning"):(t="[img="+t+`]
`,grin(n,t))}),_win.bd.on("miniuploaded",".input-expand-upload",function(n,t){var i="[img="+t.img_url+`]
`;return grin(jQuery(this),i)}),_win.bd.on("click",".btn-input-expand",function(){return jQuery(this).parent().toggleClass("open").trigger("toggleClass"),!1}),_win.bd.on("click",'.dropdown-link [type="submit"]',function(){var n=jQuery(this),t=n.closest(".dropdown-link").find("textarea").val();if(t.length<6||!aksrt_is_url(t))return void notyf(aksrt__("enter_valid_link_url"),"warning");var i="";n.closest(".dropdown-link").find('input[name="target"]').is(":checked")&&(i="target=_blank");var e=n.closest(".dropdown-link").find(".link-text").val()||t,r="[link="+t+" "+i+"]"+e+"[/link]";return grin(n,r)}),_win.bd.on("aksrt_ajax.success",".user-quick-often-save-btn",function(n,t){t.item&&jQuery(".quick-reply-myitem-box").html(t.item)}),_win.bd.on("click",".quick-reply-item",function(){var n=jQuery(this),t="quick-reply-action",i="quick-active";n.siblings().removeClass(i),n.parent().find("."+t).remove(),n.data("quick-reply",n.text()).addClass("quick-active").append('<div class="'+t+'"><div class="modal-buts but-average"><button type="button" class="but quick-reply-btn-insert" href="javascript:;">'+aksrt__("insert")+'</button><button type="button" class="but c-blue padding-lg quick-reply-btn-send">'+aksrt__("send")+"</button></div></div>")}),_win.bd.on("click",".quick-reply-action button",function(){var n=jQuery(this),t=n.closest("form"),i=n.parents(".quick-reply-item").data("quick-reply"),e=t.find("textarea.grin");e.val(i),n.hasClass("quick-reply-btn-send")?t.find(".input-expand-submit").click():e.focus()});
+1
View File
@@ -23,6 +23,7 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-ip-geo.php';
require_once AKSRT_DIR . '/inc/helpers/comments/content.php'; require_once AKSRT_DIR . '/inc/helpers/comments/content.php';
require_once AKSRT_DIR . '/inc/helpers/comments/actions.php'; require_once AKSRT_DIR . '/inc/helpers/comments/actions.php';
require_once AKSRT_DIR . '/inc/helpers/comments/geo.php'; require_once AKSRT_DIR . '/inc/helpers/comments/geo.php';
require_once AKSRT_DIR . '/inc/helpers/comments/icons.php';
require_once AKSRT_DIR . '/inc/helpers/comments/form-parts.php'; require_once AKSRT_DIR . '/inc/helpers/comments/form-parts.php';
require_once AKSRT_DIR . '/inc/helpers/comments/item.php'; require_once AKSRT_DIR . '/inc/helpers/comments/item.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-flow.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-flow.php';
+52 -45
View File
@@ -93,35 +93,33 @@ if (!function_exists('aksrt_comments_build_context')) :
? $settings['toolbar'] ? $settings['toolbar']
: ['code' => true, 'image' => true]; : ['code' => true, 'image' => true];
$phrases = is_array($settings['quick_phrases'] ?? null) ? $settings['quick_phrases'] : []; return [
'settings' => $settings,
return [ 'comment_count' => (int) get_comments_number(),
'settings' => $settings, 'is_logged_in' => is_user_logged_in(),
'comment_count' => (int) get_comments_number(), 'current_user' => wp_get_current_user(),
'is_logged_in' => is_user_logged_in(), 'require_login' => !empty($settings['require_login']),
'current_user' => wp_get_current_user(), 'order' => $order,
'require_login' => !empty($settings['require_login']), 'reverse_comments' => $order === 'newest',
'order' => $order, 'is_hottest' => $order === 'hottest',
'reverse_comments' => $order === 'newest', 'author_only' => isset($_GET['aksrt_author_only']) && (int) $_GET['aksrt_author_only'] === 1,
'is_hottest' => $order === 'hottest', 'post_author_id' => (int) get_the_author_meta('ID'),
'author_only' => isset($_GET['aksrt_author_only']) && (int) $_GET['aksrt_author_only'] === 1, 'avatar_size' => $avatar_size,
'post_author_id' => (int) get_the_author_meta('ID'), 'max_depth' => max(1, (int) ($settings['nested_depth'] ?? 3)),
'avatar_size' => $avatar_size, 'empty_text' => (string) ($settings['empty_text'] ?? __('暂无评论,来做第一个评论的人吧~', 'aksrt')),
'max_depth' => max(1, (int) ($settings['nested_depth'] ?? 3)), 'toolbar' => $toolbar,
'empty_text' => (string) ($settings['empty_text'] ?? __('暂无评论,来做第一个评论的人吧~', 'aksrt')), 'upload_enabled' => !empty($toolbar['upload_img']),
'toolbar' => $toolbar, 'link_enabled' => !empty($toolbar['link']),
'upload_enabled' => !empty($toolbar['upload_img']), 'user_url_enabled' => !empty($settings['user_url']),
'box_placeholder' => (string) ($settings['box_placeholder'] ?? __('说点什么吧...', 'aksrt')), 'box_placeholder' => (string) ($settings['box_placeholder'] ?? __('说点什么吧...', 'aksrt')),
'submit_text' => (string) ($settings['submit_text'] ?? __('提交评论', 'aksrt')), 'submit_text' => (string) ($settings['submit_text'] ?? __('提交评论', 'aksrt')),
'title_text' => (string) ($settings['title'] ?? __('评论', 'aksrt')), 'title_text' => (string) ($settings['title'] ?? __('评论', 'aksrt')),
'corderby_enabled' => !empty($settings['corderby']), 'corderby_enabled' => !empty($settings['corderby']),
'close_comments' => !empty($settings['close_comments']), 'close_comments' => !empty($settings['close_comments']),
'quick_s' => !isset($settings['quick_s']) || !empty($settings['quick_s']), 'oauth_providers' => class_exists('\AKSRT\Auth\OAuth')
'quick_phrases' => $phrases, ? \AKSRT\Auth\OAuth::get_instance()->get_auth_providers_data()
'oauth_providers' => class_exists('\AKSRT\Auth\OAuth') : [],
? \AKSRT\Auth\OAuth::get_instance()->get_auth_providers_data() ];
: [],
];
} }
endif; endif;
@@ -409,7 +407,7 @@ if (!function_exists('aksrt_comments_render_signarea')) :
<?php if (get_option('users_can_register')) : <?php if (get_option('users_can_register')) :
$register_url = function_exists('aksrt_get_register_url') ? aksrt_get_register_url() : wp_registration_url(); $register_url = function_exists('aksrt_get_register_url') ? aksrt_get_register_url() : wp_registration_url();
?> ?>
<a href="javascript:;" data-register-url="<?php echo esc_url($register_url); ?>" class="signup-loader ml10 but c-yellow padding-lg"><i class="fa fa-fw fa-user-plus mr10" aria-hidden="true"></i><?php esc_html_e('注册', 'aksrt'); ?></a> <a href="javascript:;" data-register-url="<?php echo esc_url($register_url); ?>" class="signup-loader ml10 but c-yellow padding-lg"><?php echo aksrt_get_comment_icon('signup', 'icon mr10'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- 固定 sprite 标记。 ?><?php esc_html_e('注册', 'aksrt'); ?></a>
<?php endif; ?> <?php endif; ?>
</p> </p>
<?php if (!empty($oauth_providers)) : ?> <?php if (!empty($oauth_providers)) : ?>
@@ -448,6 +446,9 @@ if (!function_exists('aksrt_comments_render_form')) :
$comment_email = isset($_COOKIE['comment_author_email_' . COOKIEHASH]) $comment_email = isset($_COOKIE['comment_author_email_' . COOKIEHASH])
? sanitize_text_field(wp_unslash((string) $_COOKIE['comment_author_email_' . COOKIEHASH])) ? sanitize_text_field(wp_unslash((string) $_COOKIE['comment_author_email_' . COOKIEHASH]))
: ''; : '';
$comment_author_url = isset($_COOKIE['comment_author_url_' . COOKIEHASH])
? esc_url_raw(wp_unslash((string) $_COOKIE['comment_author_url_' . COOKIEHASH]))
: '';
$placeholder = (string) $ctx['box_placeholder']; $placeholder = (string) $ctx['box_placeholder'];
$post_id = (int) get_the_ID(); $post_id = (int) get_the_ID();
$can_comment = function_exists('aksrt_user_can') $can_comment = function_exists('aksrt_user_can')
@@ -471,13 +472,13 @@ if (!function_exists('aksrt_comments_render_form')) :
<div class="fixed-body"></div> <div class="fixed-body"></div>
<form id="commentform" method="post" action="<?php echo esc_url(site_url('/wp-comments-post.php')); ?>"> <form id="commentform" method="post" action="<?php echo esc_url(site_url('/wp-comments-post.php')); ?>">
<div class="flex ac"> <div class="flex ac">
<div class="comt-title text-center flex0 mr10"> <div class="comt-title text-center flex0 mr10">
<?php if ($is_logged_in && $current_user instanceof WP_User) : ?> <?php if ($is_logged_in && $current_user instanceof WP_User) : ?>
<div class="comt-avatar mb10"> <div class="comt-avatar mb10">
<?php echo get_avatar($current_user->ID, 60, '', '', ['class' => 'avatar']); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo get_avatar($current_user->ID, 60, '', '', ['class' => 'avatar']); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div> </div>
<p class="text-ellipsis muted-2-color"><?php echo esc_html($current_user->display_name); ?></p> <p class="text-ellipsis muted-2-color"><?php echo function_exists('aksrt_render_user_identity_chips') ? aksrt_render_user_identity_chips($current_user->ID, 'comment') : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- chips 内部已转义。 ?><?php echo esc_html($current_user->display_name); ?></p>
<?php else : ?> <?php else : ?>
<div class="comt-avatar mb10"> <div class="comt-avatar mb10">
<?php echo get_avatar(0, 60, '', '', ['class' => 'avatar']); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo get_avatar(0, 60, '', '', ['class' => 'avatar']); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div> </div>
@@ -524,6 +525,14 @@ if (!function_exists('aksrt_comments_render_form')) :
<div class="abs-right muted-color"><i class="fa fa-fw fa-envelope-o" aria-hidden="true"></i></div> <div class="abs-right muted-color"><i class="fa fa-fw fa-envelope-o" aria-hidden="true"></i></div>
<i class="line-form-line"></i> <i class="line-form-line"></i>
</li> </li>
<?php if (!empty($ctx['user_url_enabled'])) : ?>
<li class="line-form">
<input type="text" name="url" class="line-form-input" tabindex="3" value="<?php echo esc_attr($comment_author_url); ?>" placeholder="">
<div class="scale-placeholder"><?php esc_html_e('博客地址', 'aksrt'); ?></div>
<div class="abs-right muted-color"><i class="fa fa-fw fa-link" aria-hidden="true"></i></div>
<i class="line-form-line"></i>
</li>
<?php endif; ?>
</ul> </ul>
</div> </div>
<?php <?php
@@ -623,7 +632,7 @@ if (!function_exists('aksrt_comments_render')) :
* Compose the full comments surface. * Compose the full comments surface.
*/ */
function aksrt_comments_render(): void { function aksrt_comments_render(): void {
if (post_password_required()) { if (post_password_required() || !comments_open()) {
return; return;
} }
@@ -652,12 +661,10 @@ if (!function_exists('aksrt_comments_render')) :
</div> </div>
<div class="no_webshot main-bg theme-box box-body radius8 main-shadow"> <div class="no_webshot main-bg theme-box box-body radius8 main-shadow">
<?php if (comments_open()) : ?> <?php if (!empty($ctx['require_login']) && empty($ctx['is_logged_in'])) : ?>
<?php if (!empty($ctx['require_login']) && empty($ctx['is_logged_in'])) : ?> <?php aksrt_comments_render_signarea($ctx); ?>
<?php aksrt_comments_render_signarea($ctx); ?> <?php else : ?>
<?php else : ?> <?php aksrt_comments_render_form($ctx); ?>
<?php aksrt_comments_render_form($ctx); ?>
<?php endif; ?>
<?php endif; ?> <?php endif; ?>
<div id="postcomments"> <div id="postcomments">
@@ -670,7 +677,7 @@ if (!function_exists('aksrt_comments_render')) :
if (have_comments()) { if (have_comments()) {
aksrt_comments_render_list_items($ctx); aksrt_comments_render_list_items($ctx);
} elseif (!post_password_required()) { } else {
aksrt_comments_render_empty($ctx); aksrt_comments_render_empty($ctx);
echo '<div class="pagenav hide"><div class="next-page ajax-next"><a href="#"></a></div></div>'; echo '<div class="pagenav hide"><div class="next-page ajax-next"><a href="#"></a></div></div>';
} }
+6 -26
View File
@@ -39,9 +39,9 @@ if (!function_exists('aksrt_get_input_expand_but')) :
/** /**
* legacy-style expand toolbar button + dropdown (legacy: legacy). * legacy-style expand toolbar button + dropdown (legacy: legacy).
* *
* @param string $type code|image|quick|link. * @param string $type code|image|link.
* @param mixed $arg1 Type-specific arg. * @param mixed $arg1 Type-specific arg.
* @param array<string,mixed> $ctx Optional context (upload, phrases). * @param array<string,mixed> $ctx Optional context (upload).
* @return string * @return string
*/ */
function aksrt_get_input_expand_but(string $type, $arg1 = null, array $ctx = []): string { function aksrt_get_input_expand_but(string $type, $arg1 = null, array $ctx = []): string {
@@ -59,25 +59,6 @@ if (!function_exists('aksrt_get_input_expand_but')) :
$dropdown .= '</div>'; $dropdown .= '</div>';
break; break;
case 'quick':
$phrases = [];
if (is_string($arg1) && $arg1 !== '') {
$phrases = array_values(array_filter(array_map('trim', preg_split('/\r\n|\r|\n/', $arg1) ?: [])));
} elseif (!empty($ctx['quick_phrases']) && is_array($ctx['quick_phrases'])) {
$phrases = $ctx['quick_phrases'];
}
$sys_lists = '';
foreach ($phrases as $p) {
$sys_lists .= '<div class="quick-reply-item">' . esc_html((string) $p) . '</div>';
}
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 'code': 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>'; $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 = '<div class="dropdown-code">';
@@ -114,15 +95,14 @@ endif;
if (!function_exists('aksrt_render_comment_expand_toolbar')) : if (!function_exists('aksrt_render_comment_expand_toolbar')) :
/** /**
* Render left-side expand tools based on settings (legacy order: code/image/link/quick). * Render left-side expand tools based on settings (legacy order: code/image/link).
* *
* @param array<string,mixed> $ctx Comments context. * @param array<string,mixed> $ctx Comments context.
*/ */
function aksrt_render_comment_expand_toolbar(array $ctx): void { function aksrt_render_comment_expand_toolbar(array $ctx): void {
$toolbar = is_array($ctx['toolbar'] ?? null) ? $ctx['toolbar'] : []; $toolbar = is_array($ctx['toolbar'] ?? null) ? $ctx['toolbar'] : [];
$upload = !empty($ctx['upload_enabled']); $upload = !empty($ctx['upload_enabled']);
$phrases = is_array($ctx['quick_phrases'] ?? null) ? $ctx['quick_phrases'] : []; $link_s = !empty($ctx['link_enabled']);
$quick_s = !isset($ctx['quick_s']) || !empty($ctx['quick_s']);
if (!empty($toolbar['code'])) { if (!empty($toolbar['code'])) {
echo aksrt_get_input_expand_but('code'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo aksrt_get_input_expand_but('code'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -130,8 +110,8 @@ if (!function_exists('aksrt_render_comment_expand_toolbar')) :
if (!empty($toolbar['image'])) { if (!empty($toolbar['image'])) {
echo aksrt_get_input_expand_but('image', $upload, ['upload' => $upload]); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo aksrt_get_input_expand_but('image', $upload, ['upload' => $upload]); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} }
if ($quick_s) { if ($link_s) {
echo aksrt_get_input_expand_but('quick', null, ['quick_phrases' => $phrases]); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo aksrt_get_input_expand_but('link'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} }
} }
endif; endif;
+25
View File
@@ -0,0 +1,25 @@
<?php
/**
* Comment sprite icons — <use> references into the runtime svg-icon sprite.
*
* Mirrors zib_get_svg() from the reference comments module. Symbol
* definitions are injected by assets/js/runtime/svg-icon.js, which the
* vendor runtime lazy-loads on every page (main.js: tbquire(['svg-icon'])).
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
if (!function_exists('aksrt_get_comment_icon')) :
/**
* Sprite-referenced SVG icon (legacy: zib_get_svg).
*
* @param string $name Sprite key (like / topping / approve / menu_2 / signup).
* @param string $class Classes for the svg element.
* @return string
*/
function aksrt_get_comment_icon(string $name, string $class = 'icon'): string {
return '<svg class="' . esc_attr($class) . '" aria-hidden="true"><use xlink:href="#icon-' . esc_attr($name) . '"></use></svg>';
}
endif;
+17 -8
View File
@@ -29,13 +29,15 @@ if (!function_exists('aksrt_get_comment_like_html')) :
$like_count = function_exists('aksrt_get_comment_likes') ? (int) aksrt_get_comment_likes($comment_id) : 0; $like_count = function_exists('aksrt_get_comment_likes') ? (int) aksrt_get_comment_likes($comment_id) : 0;
$is_liked = function_exists('aksrt_is_comment_liked') && aksrt_is_comment_liked($comment_id); $is_liked = function_exists('aksrt_is_comment_liked') && aksrt_is_comment_liked($comment_id);
$classes = 'action action-comment-like muted-2-color flex0 ml10' . ($is_liked ? ' actived' : ''); $classes = 'action action-comment-like muted-2-color flex0 ml10' . ($is_liked ? ' actived' : '');
$icon = function_exists('aksrt_get_comment_icon') ? aksrt_get_comment_icon('like', 'icon mr3') : '';
return sprintf( return sprintf(
'<a href="javascript:;" data-comment-action="like" data-action="comment_like" class="%1$s" data-pid="%2$d" data-active="%3$s" aria-pressed="%4$s"><i class="fa fa-thumbs-up mr3" aria-hidden="true"></i><count>%5$s</count></a>', '<a href="javascript:;" data-comment-action="like" data-action="comment_like" class="%1$s" data-pid="%2$d" data-active="%3$s" aria-pressed="%4$s">%5$s<text></text><count>%6$s</count></a>',
esc_attr($classes), esc_attr($classes),
$comment_id, $comment_id,
$is_liked ? '1' : '0', $is_liked ? '1' : '0',
$is_liked ? 'true' : 'false', $is_liked ? 'true' : 'false',
$icon, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup.
esc_html((string) $like_count) esc_html((string) $like_count)
); );
} }
@@ -88,7 +90,8 @@ if (!function_exists('aksrt_get_comments_user_name_html')) :
$topping = ''; $topping = '';
if ($is_pinned) { if ($is_pinned) {
$topping = '<badge class="badge-topping jb-blue mr6 flex0" title="' . esc_attr__('置顶评论', 'aksrt') . '" data-toggle="tooltip"><i class="fa fa-thumbtack" aria-hidden="true"></i></badge>'; $topping_icon = function_exists('aksrt_get_comment_icon') ? aksrt_get_comment_icon('topping') : '';
$topping = '<badge class="badge-topping jb-blue mr6 flex0" title="' . esc_attr__('置顶评论', 'aksrt') . '" data-toggle="tooltip">' . $topping_icon . '</badge>';
} }
$user_name = ''; $user_name = '';
@@ -166,10 +169,11 @@ if (!function_exists('aksrt_get_comments_action_dropdown_html')) :
$lists .= '<li><a class="comment-edit-link" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fa-edit mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('编辑', 'aksrt') . '</a></li>'; $lists .= '<li><a class="comment-edit-link" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fa-edit mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('编辑', 'aksrt') . '</a></li>';
} }
if (!empty($perms['can_moderate'])) { if (!empty($perms['can_moderate'])) {
$text = $is_pending ? __('批准', 'aksrt') : __('驳回', 'aksrt'); $text = $is_pending ? __('批准', 'aksrt') : __('驳回', 'aksrt');
$class = $is_pending ? 'approve' : 'unapprove'; $class = $is_pending ? 'approve' : 'unapprove';
$action = $is_pending ? 'approve' : 'hold'; $action = $is_pending ? 'approve' : 'hold';
$lists .= '<li><a class="comment-approve-link ' . $class . '" data-comment-action="' . $action . '" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fa-check mr10 fa-fw" aria-hidden="true"></i><text>' . esc_html($text) . '</text></a></li>'; $approve_icon = function_exists('aksrt_get_comment_icon') ? aksrt_get_comment_icon('approve', 'mr10 icon fa-fw') : '';
$lists .= '<li><a class="comment-approve-link ' . $class . '" data-comment-action="' . $action . '" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;">' . $approve_icon . '<text>' . esc_html($text) . '</text></a></li>';
} }
if (!empty($perms['can_delete'])) { if (!empty($perms['can_delete'])) {
$lists .= '<li><a class="comment-trash-link c-red" data-comment-action="delete" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fa-trash-o mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('删除', 'aksrt') . '</a></li>'; $lists .= '<li><a class="comment-trash-link c-red" data-comment-action="delete" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fa-trash-o mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('删除', 'aksrt') . '</a></li>';
@@ -179,7 +183,8 @@ if (!function_exists('aksrt_get_comments_action_dropdown_html')) :
return ''; return '';
} }
$icon_a = '<a href="javascript:;" class="muted-color padding-6" data-toggle="dropdown"><i class="fa fa-ellipsis-h" aria-hidden="true"></i></a>'; $menu_icon = function_exists('aksrt_get_comment_icon') ? aksrt_get_comment_icon('menu_2') : '';
$icon_a = '<a href="javascript:;" class="muted-color padding-6" data-toggle="dropdown">' . $menu_icon . '</a>';
return '<span class="dropdown drop-fixed-sm padding-6">' . $icon_a . '<ul class="dropdown-menu">' . $lists . '</ul></span>'; return '<span class="dropdown drop-fixed-sm padding-6">' . $icon_a . '<ul class="dropdown-menu">' . $lists . '</ul></span>';
} }
@@ -198,6 +203,8 @@ if (!function_exists('aksrt_get_comment_footer_html')) :
function aksrt_get_comment_footer_html(WP_Comment $comment, array $args, int $depth, array $settings = []): string { function aksrt_get_comment_footer_html(WP_Comment $comment, array $args, int $depth, array $settings = []): string {
$is_pending = '0' === (string) $comment->comment_approved; $is_pending = '0' === (string) $comment->comment_approved;
$is_mobile = wp_is_mobile();
$badg_approve = ''; $badg_approve = '';
if ($is_pending) { if ($is_pending) {
$badg_approve = '<span class="badg c-red badg-sm">' . esc_html__('待审核', 'aksrt') . '</span>'; $badg_approve = '<span class="badg c-red badg-sm">' . esc_html__('待审核', 'aksrt') . '</span>';
@@ -208,7 +215,7 @@ if (!function_exists('aksrt_get_comment_footer_html')) :
$ago = function_exists('aksrt_time_ago') $ago = function_exists('aksrt_time_ago')
? aksrt_time_ago((string) $comment->comment_date) ? aksrt_time_ago((string) $comment->comment_date)
: human_time_diff(strtotime((string) $comment->comment_date), current_time('timestamp')) . __('前', 'aksrt'); : human_time_diff(strtotime((string) $comment->comment_date), current_time('timestamp')) . __('前', 'aksrt');
$time_html = '<span class="comt-author" title="' . esc_attr($absolute) . '">' . esc_html($ago) . '</span>'; $time_html = '<span class="comt-author"' . ($is_mobile ? ' data-toggle="tooltip"' : '') . ' title="' . esc_attr($absolute) . '">' . esc_html($ago) . '</span>';
$city_html = function_exists('aksrt_get_comment_city_badge_html') $city_html = function_exists('aksrt_get_comment_city_badge_html')
? aksrt_get_comment_city_badge_html($comment) ? aksrt_get_comment_city_badge_html($comment)
@@ -236,6 +243,8 @@ if (!function_exists('aksrt_get_comment_footer_html')) :
if ($link) { if ($link) {
// 去掉 WP 内联 onclick(addComment.moveForm),回复由 comment-move-form.js 事件委托处理。 // 去掉 WP 内联 onclick(addComment.moveForm),回复由 comment-move-form.js 事件委托处理。
$link = preg_replace('/ onclick="[^"]*"/i', '', $link); $link = preg_replace('/ onclick="[^"]*"/i', '', $link);
// legacy 契约:aria-label 换成 tooltip 触发属性。
$link = preg_replace('# aria-label=#', $is_mobile ? ' title=' : ' data-toggle="tooltip" title=', $link);
if (strpos($link, 'data-commentid') === false) { if (strpos($link, 'data-commentid') === false) {
$link = str_replace( $link = str_replace(
'comment-reply-link', 'comment-reply-link',
+2 -1
View File
@@ -80,7 +80,8 @@ $show_sidebar = function_exists('aksrt_is_show_sidebar') ? aksrt_is_show_sidebar
</article> </article>
<?php <?php
if (comments_open() || get_comments_number()) { // 评论关闭时模板整体不渲染(legacy 行为),无需空卡片。
if (comments_open()) {
echo '<div class="theme-box box-body radius8 main-shadow comments-card">'; echo '<div class="theme-box box-body radius8 main-shadow comments-card">';
comments_template(); comments_template();
echo '</div>'; echo '</div>';
+1 -1
View File
@@ -55,7 +55,7 @@ while (have_posts()) :
} }
?> ?>
<?php if (comments_open() || get_comments_number()) : ?> <?php if (comments_open()) : ?>
<?php comments_template(); ?> <?php comments_template(); ?>
<?php endif; ?> <?php endif; ?>
+2 -4
View File
@@ -225,20 +225,18 @@ class SchemaPostList {
['key' => 'toolbar', 'title' => '评论工具栏', 'fields' => [ ['key' => 'toolbar', 'title' => '评论工具栏', 'fields' => [
['key' => 'comment_code', 'label' => '代码插入', 'type' => 'switch', 'default' => true], ['key' => 'comment_code', 'label' => '代码插入', 'type' => 'switch', 'default' => true],
['key' => 'comment_img', 'label' => '图片上传', 'type' => 'switch', 'default' => true], ['key' => 'comment_img', 'label' => '图片上传', 'type' => 'switch', 'default' => true],
['key' => 'comment_link', 'label' => '链接按钮', 'type' => 'switch', 'default' => false],
]], ]],
['key' => 'interaction', 'title' => '互动功能', 'fields' => [ ['key' => 'interaction', 'title' => '互动功能', 'fields' => [
['key' => 'comment_hot_threshold', 'label' => '神评点赞阈值', 'type' => 'number', 'default' => 10, 'min' => 1, 'max' => 999], ['key' => 'comment_hot_threshold', 'label' => '神评点赞阈值', 'type' => 'number', 'default' => 10, 'min' => 1, 'max' => 999],
['key' => 'comment_like_s', 'label' => '评论点赞', 'type' => 'switch', 'default' => true], ['key' => 'comment_like_s', 'label' => '评论点赞', 'type' => 'switch', 'default' => true],
['key' => 'comment_quick_s', 'label' => '快捷回复', 'type' => 'switch', 'default' => true], ['key' => 'comment_user_url_s', 'label' => '匿名者网址', 'type' => 'switch', 'default' => false, 'description' => '用户未登录评论时,允许输入用户博客地址'],
['key' => 'comment_city_s', 'label' => '评论城市', 'type' => 'switch', 'default' => true], ['key' => 'comment_city_s', 'label' => '评论城市', 'type' => 'switch', 'default' => true],
['key' => 'comment_city_type', 'label' => '城市显示格式', 'type' => 'radio', 'default' => 'province_city', 'options' => [ ['key' => 'comment_city_type', 'label' => '城市显示格式', 'type' => 'radio', 'default' => 'province_city', 'options' => [
['label' => '省份+城市', 'value' => 'province_city'], ['label' => '省份+城市', 'value' => 'province_city'],
['label' => '仅省份', 'value' => 'province'], ['label' => '仅省份', 'value' => 'province'],
['label' => '国家+省份', 'value' => 'country_province'], ['label' => '国家+省份', 'value' => 'country_province'],
]], ]],
['key' => 'comment_quick_often', 'label' => '快捷回复短语', 'type' => 'textarea', 'default' => "不错,学习了
感谢分享
期待更新"],
['key' => 'comment_author_tag', 'label' => '作者标签', 'type' => 'switch', 'default' => true], ['key' => 'comment_author_tag', 'label' => '作者标签', 'type' => 'switch', 'default' => true],
['key' => 'comment_corderby', 'label' => '评论排序切换', 'type' => 'switch', 'default' => true, 'description' => '前台显示最新/最早/最热切换按钮'], ['key' => 'comment_corderby', 'label' => '评论排序切换', 'type' => 'switch', 'default' => true, 'description' => '前台显示最新/最早/最热切换按钮'],
]], ]],
+1 -2
View File
@@ -368,7 +368,7 @@ trait ScriptsPart1c {
} }
// Comment toolbar (code/image/quick shortcodes) — post form. // Comment toolbar (code/image/link shortcodes) — post form.
$load_comment_tools = !empty($singular_assets['needs_comment_tools']); $load_comment_tools = !empty($singular_assets['needs_comment_tools']);
if ($load_comment_tools) { if ($load_comment_tools) {
$comment_tools_path = get_template_directory() . '/assets/js/comment-tools.js'; $comment_tools_path = get_template_directory() . '/assets/js/comment-tools.js';
@@ -481,7 +481,6 @@ trait ScriptsPart1c {
'commentUploadUrl' => esc_url_raw(rest_url('aksrt/v1/comment/upload-image')), 'commentUploadUrl' => esc_url_raw(rest_url('aksrt/v1/comment/upload-image')),
'commentUploadMaxSize' => 2 * 1024 * 1024, 'commentUploadMaxSize' => 2 * 1024 * 1024,
'commentIasMax' => class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_comment_display_settings()['paging_ajax_ias_max'] : 3, 'commentIasMax' => class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_comment_display_settings()['paging_ajax_ias_max'] : 3,
'commentQuickPhrases' => class_exists('\AKSRT\Settings\Settings') ? (\AKSRT\Settings\Settings::get_comment_display_settings()['quick_phrases'] ?? []) : [],
'restUrl' => esc_url_raw(rest_url('aksrt/v1')), 'restUrl' => esc_url_raw(rest_url('aksrt/v1')),
// Alias used by modal-auth / follow / report (same value as restUrl). // Alias used by modal-auth / follow / report (same value as restUrl).
'apiUrl' => esc_url_raw(rest_url('aksrt/v1')), 'apiUrl' => esc_url_raw(rest_url('aksrt/v1')),
+2 -20
View File
@@ -385,6 +385,7 @@ class PostDisplay {
'toolbar' => [ 'toolbar' => [
'code' => !isset($settings['comment_code']) || !empty($settings['comment_code']), 'code' => !isset($settings['comment_code']) || !empty($settings['comment_code']),
'image' => !isset($settings['comment_img']) || !empty($settings['comment_img']), 'image' => !isset($settings['comment_img']) || !empty($settings['comment_img']),
'link' => !empty($settings['comment_link']),
'upload_img' => function_exists('aksrt_user_can') && aksrt_user_can('upload_comment_image', get_current_user_id()), 'upload_img' => function_exists('aksrt_user_can') && aksrt_user_can('upload_comment_image', get_current_user_id()),
], ],
'like_enabled' => !isset($settings['comment_like_s']) || !empty($settings['comment_like_s']), 'like_enabled' => !isset($settings['comment_like_s']) || !empty($settings['comment_like_s']),
@@ -397,31 +398,12 @@ class PostDisplay {
// Extended legacy-parity settings. // Extended legacy-parity settings.
'close_comments' => !empty($settings['comment_close_comments']), 'close_comments' => !empty($settings['comment_close_comments']),
'hot_threshold' => max(1, min(999, (int) ($settings['comment_hot_threshold'] ?? 10))), 'hot_threshold' => max(1, min(999, (int) ($settings['comment_hot_threshold'] ?? 10))),
'quick_s' => !isset($settings['comment_quick_s']) || !empty($settings['comment_quick_s']), 'user_url' => !empty($settings['comment_user_url_s']),
'quick_phrases' => self::parse_comment_quick_phrases((string) ($settings['comment_quick_often'] ?? '')),
'city_s' => !isset($settings['comment_city_s']) || !empty($settings['comment_city_s']), 'city_s' => !isset($settings['comment_city_s']) || !empty($settings['comment_city_s']),
'city_type' => self::normalize_comment_city_type((string) ($settings['comment_city_type'] ?? 'province_city')), 'city_type' => self::normalize_comment_city_type((string) ($settings['comment_city_type'] ?? 'province_city')),
]; ];
} }
/**
* @return array<int,string>
*/
private static function parse_comment_quick_phrases(string $raw): array {
if (trim($raw) === '') {
$raw = "不错,学习了\n感谢分享\n期待更新";
}
$lines = preg_split('/\r\n|\r|\n/', $raw) ?: [];
$out = [];
foreach ($lines as $line) {
$line = trim((string) $line);
if ($line !== '') {
$out[] = $line;
}
}
return array_values(array_unique($out));
}
private static function normalize_comment_city_type(string $type): string { private static function normalize_comment_city_type(string $type): string {
$type = sanitize_key($type); $type = sanitize_key($type);
// Map legacy legacy pro/city labels. // Map legacy legacy pro/city labels.
@@ -26,8 +26,6 @@ test('comment smilie assets and their runtime chain stay removed', () => {
'assets/js/enhancements.js', 'assets/js/enhancements.js',
'assets/js/runtime/imgbox.js', 'assets/js/runtime/imgbox.js',
'assets/js/runtime/imgbox.min.js', 'assets/js/runtime/imgbox.min.js',
'assets/js/runtime/input-expand.js',
'assets/js/runtime/input-expand.min.js',
'assets/js/runtime/main.js', 'assets/js/runtime/main.js',
'assets/js/runtime/main.min.js', 'assets/js/runtime/main.min.js',
'inc/helpers/aksrt-comments.php', 'inc/helpers/aksrt-comments.php',
+18
View File
@@ -55,6 +55,7 @@ const cssBundles = {
'assets/css/frontend/single-post/author-actions.css', 'assets/css/frontend/single-post/author-actions.css',
], ],
'comments.css': [ 'comments.css': [
'assets/css/frontend/comments/layout.css',
'assets/css/frontend/comments/shell.css', 'assets/css/frontend/comments/shell.css',
'assets/css/frontend/comments/mobile-item.css', 'assets/css/frontend/comments/mobile-item.css',
], ],
@@ -172,8 +173,25 @@ async function buildScriptBundle() {
await writeFile(path.join(jsBuildDir, 'public.js'), `${sections.join('\n\n')}\n`, 'utf8'); await writeFile(path.join(jsBuildDir, 'public.js'), `${sections.join('\n\n')}\n`, 'utf8');
} }
// 评论区硬切换后 main.min.css 由 main.css 重新生成,保持两者同步。
async function buildMainMin() {
const sourcePath = path.join(repoRoot, 'assets/css/main.css');
const outputPath = path.join(repoRoot, 'assets/css/main.min.css');
const source = await readFile(sourcePath, 'utf8');
const minified = await transform(source, {
charset: 'utf8',
legalComments: 'inline',
loader: 'css',
minify: true,
sourcefile: 'main.css',
});
await writeFile(outputPath, minified.code, 'utf8');
}
await mkdir(cssBuildDir, { recursive: true }); await mkdir(cssBuildDir, { recursive: true });
await mkdir(jsBuildDir, { recursive: true }); await mkdir(jsBuildDir, { recursive: true });
// 先刷新 main.min.css,public.css 打包时才能读到最新内容。
await buildMainMin();
for (const [outputName, sources] of Object.entries(cssBundles)) { for (const [outputName, sources] of Object.entries(cssBundles)) {
await buildCssBundle(outputName, sources); await buildCssBundle(outputName, sources);
} }