3.2.24: 评论富文本工具条(B/I/颜色/表情移入)+ kses 放行 span+style + 后台设置页标签左列竖排重排
This commit is contained in:
+145
-18
@@ -925,11 +925,147 @@
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* 工具条 */
|
||||
/* 工具条:加粗 / 斜体 / 字体颜色 / 表情。
|
||||
*
|
||||
* 位于输入框上方,与 textarea 同在 .comment-textarea 这个带边框的
|
||||
* 容器里 —— 工具条铺满容器顶部,输入框一聚焦整框(含工具条)
|
||||
* 一起亮主色描边,视觉上是"一个编辑器",而不是两条孤立的横条。
|
||||
* 面板(色板 / 表情)从按钮**下方**弹出:按钮在容器顶部,
|
||||
* 向上弹会飘到表单外面盖住上文,向下弹只盖住自己的输入区。 */
|
||||
.comment-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 5px 9px;
|
||||
border-bottom: 1px solid #edf0f4;
|
||||
border-radius: var(--yq-radius, 4px) var(--yq-radius, 4px) 0 0;
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
/* 面板的定位父级:每个带面板的按钮各包一层 */
|
||||
.comment-tool-group {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 按钮组之间的细分隔线 */
|
||||
.comment-toolbar-sep {
|
||||
align-self: center;
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
margin: 0 5px;
|
||||
background-color: #e2e7ee;
|
||||
}
|
||||
|
||||
.comment-tool-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 30px;
|
||||
height: 30px;
|
||||
padding: 0 7px;
|
||||
border: 0;
|
||||
border-radius: var(--yq-radius, 4px);
|
||||
background: none;
|
||||
color: var(--yq-text-2, #4b5563);
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
transition: color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease);
|
||||
}
|
||||
|
||||
.comment-tool-btn:hover {
|
||||
background-color: var(--yq-primary-soft, #eaf6ff);
|
||||
color: var(--yq-primary-dark, #0089db);
|
||||
}
|
||||
|
||||
.comment-tool-btn:focus-visible {
|
||||
outline: 2px solid var(--yq-primary, #00a2ff);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
/* 字形:B 用粗体、I 用衬线斜体,一眼能认出对应排版效果 */
|
||||
.comment-tool-glyph {
|
||||
display: inline-block;
|
||||
font-family: inherit;
|
||||
font-size: 14.5px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.comment-tool-glyph-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.comment-tool-glyph-italic {
|
||||
font-family: Georgia, "Times New Roman", serif;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 颜色按钮:字母 A 底下压一条渐变色条,点开是色板 */
|
||||
.comment-tool-glyph-color {
|
||||
position: relative;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.comment-tool-glyph-color::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 1px;
|
||||
right: 1px;
|
||||
bottom: -3px;
|
||||
height: 3px;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(90deg, #e74c3c 0%, #f1c40f 30%, #2ecc71 55%, #00a2ff 80%, #9b59b6 100%);
|
||||
}
|
||||
|
||||
/* 色板:8 个圆点,从按钮下方弹出 */
|
||||
.comment-color-panel {
|
||||
position: absolute;
|
||||
top: calc(100% + 6px);
|
||||
left: 0;
|
||||
z-index: 21;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
width: 164px;
|
||||
padding: 10px;
|
||||
border: 1px solid #e2e7ee;
|
||||
border-radius: var(--yq-radius-lg, 6px);
|
||||
background-color: #fff;
|
||||
box-shadow: 0 6px 20px rgba(31, 35, 40, 0.12);
|
||||
}
|
||||
|
||||
.comment-color-panel[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.comment-color-swatch {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
transition: transform 0.12s var(--yq-ease), box-shadow 0.12s var(--yq-ease);
|
||||
}
|
||||
|
||||
.comment-color-swatch:hover {
|
||||
transform: scale(1.18);
|
||||
box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px var(--yq-primary, #00a2ff);
|
||||
}
|
||||
|
||||
.comment-color-swatch:focus-visible {
|
||||
outline: 2px solid var(--yq-primary, #00a2ff);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
/* 底栏:表情移进工具条后只剩状态提示 + 提交按钮 */
|
||||
.comment-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 8px 11px;
|
||||
border-top: 1px solid #edf0f4;
|
||||
@@ -937,27 +1073,18 @@
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
.comment-bar-left,
|
||||
.comment-bar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.comment-bar-left {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 表情按钮:并入工具条后尺寸与其它工具按钮一致(原 4px 8px 小药丸) */
|
||||
.comment-smile-btn {
|
||||
padding: 4px 8px;
|
||||
border: 0;
|
||||
border-radius: var(--yq-radius, 4px);
|
||||
background: none;
|
||||
color: var(--yq-text-3, #6b7280);
|
||||
font-size: 17px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
transition: color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease);
|
||||
min-width: 30px;
|
||||
height: 30px;
|
||||
padding: 0 7px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.comment-smile-btn:hover {
|
||||
@@ -965,10 +1092,10 @@
|
||||
color: var(--yq-primary-dark, #0089db);
|
||||
}
|
||||
|
||||
/* 表情面板:3 行 8 列 */
|
||||
/* 表情面板:按钮在容器顶部,改为**向下**弹出(原 bottom 定位作废) */
|
||||
.comment-smile-panel {
|
||||
position: absolute;
|
||||
bottom: calc(100% + 8px);
|
||||
top: calc(100% + 6px);
|
||||
left: 0;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
|
||||
@@ -176,6 +176,76 @@
|
||||
}
|
||||
})
|
||||
|
||||
/* ── 富文本工具条(3.2.24)─────────────────────────────────
|
||||
* 评论内容仍是纯文本存储;工具条只在光标/选区处插入受控标签:
|
||||
* B → <strong>…</strong> I → <em>…</em>
|
||||
* 颜色 → <span style="color:#xxx">…</span>
|
||||
* 后端由 theme-comments.php 的 kses 白名单放行这三种标签
|
||||
* (style 属性再经 WP 核心 safecss_filter_attr 消毒,只留安全属性)。
|
||||
*
|
||||
* 选区为空时插入占位文本并**选中**它 —— 用户直接打字就覆盖占位,
|
||||
* 这是各家编辑器工具条的通行做法;不选中的话占位文本会留在正文里。
|
||||
*/
|
||||
function wrapSelection (before, after, placeholder) {
|
||||
if (!textarea) return
|
||||
textarea.focus()
|
||||
var s = textarea.selectionStart || 0
|
||||
var e = textarea.selectionEnd || 0
|
||||
var v = textarea.value
|
||||
var sel = v.slice(s, e)
|
||||
var usedPlaceholder = false
|
||||
if (sel === '') {
|
||||
sel = placeholder || ''
|
||||
usedPlaceholder = true
|
||||
}
|
||||
textarea.value = v.slice(0, s) + before + sel + after + v.slice(e)
|
||||
// 选中被包裹的内容(或占位文本),光标落回包裹体内
|
||||
var a = s + before.length
|
||||
var b = a + sel.length
|
||||
try { textarea.setSelectionRange(a, b) } catch (ex) { /* 老 IE 忽略 */ }
|
||||
return usedPlaceholder
|
||||
}
|
||||
|
||||
// B / I:按钮上带 data-wrap-before / data-wrap-after,加新按钮不用改 JS
|
||||
$$('.comment-tool-btn[data-wrap-before]', form).forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
wrapSelection(
|
||||
btn.getAttribute('data-wrap-before') || '',
|
||||
btn.getAttribute('data-wrap-after') || '',
|
||||
I18N.boldPlaceholder || '加粗文字'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
/* 字体颜色面板:开合 + 色板点击包裹选区。
|
||||
* 与表情面板同款交互:点按钮开/关,点外面关,选中后关。 */
|
||||
var colorBtn = $('#yang-tool-color', form)
|
||||
var colorPanel = $('#yang-color-panel', form)
|
||||
if (colorBtn && colorPanel) {
|
||||
colorBtn.addEventListener('click', function (ev) {
|
||||
ev.stopPropagation()
|
||||
var open = !colorPanel.hidden
|
||||
colorPanel.hidden = open
|
||||
colorBtn.setAttribute('aria-expanded', open ? 'false' : 'true')
|
||||
})
|
||||
document.addEventListener('click', function (ev) {
|
||||
if (colorPanel.hidden) return
|
||||
if (colorPanel.contains(ev.target) || colorBtn.contains(ev.target)) return
|
||||
colorPanel.hidden = true
|
||||
colorBtn.setAttribute('aria-expanded', 'false')
|
||||
})
|
||||
colorPanel.addEventListener('click', function (ev) {
|
||||
var sw = ev.target.closest ? ev.target.closest('.comment-color-swatch') : null
|
||||
if (!sw) return
|
||||
var c = sw.getAttribute('data-color') || '#000000'
|
||||
// 色值只允许 #rrggbb,面板里写死的,这里再挡一道
|
||||
if (!/^#[0-9a-fA-F]{6}$/.test(c)) return
|
||||
wrapSelection('<span style="color:' + c + '">', '</span>', I18N.colorPlaceholder || '彩色文字')
|
||||
colorPanel.hidden = true
|
||||
colorBtn.setAttribute('aria-expanded', 'false')
|
||||
})
|
||||
}
|
||||
|
||||
/* ── 表情面板 ──────────────────────────────────────────────
|
||||
* 点表情按钮 → 把对应代码插到光标处(不是简单追加到末尾)。
|
||||
* 旧实现是 `myField.value += tag`,光标本在中间也会跑到最后,
|
||||
|
||||
Reference in New Issue
Block a user