Files
wordpress-theme-aksrt/assets/creator-studio/src/editor-content-style.ts
T
kate522andClaude Opus 5 4f9347b6aa fix(submit): let the editor iframe grow with the body instead of scrolling internally
正文超过 iframe 高度时会在编辑器内部出现第二根滚动条,正文应该随页面一起变长。
登录态实测确认了滚动来源与两个副作用:

1. 经典投稿表单完全没做高度同步(iframe 固定 504px,正文 1824px → 内滚动)。
   在共用基础插件里补上 syncHeight():测量正文高度并同步 iframe,
   下限取编辑器声明高度;图片加载后重新同步。工作台自带 syncEditorHeight()
   负责块浮层定位,用 __jioStudioOwnsEditorHeight 让插件跳过,避免双写。

2. 直接量 scrollHeight 会把 body 的 min-height 撑满算进内容高度,形成
   「撑高 → 再撑高」的反馈循环(实测涨到 22616px)。测量时临时把
   min-height 归零、同帧恢复。

3. body 的 min-height 基准从 100% 改成 100vh:iframe 随正文变高,
   百分比会跟着循环;同时把 WordPress content CSS 的 body 外边距改内边距,
   外边距不计入高度,会让 html 比 iframe 高一截、长正文时又冒出内滚动。

登录态实测(studio 与经典两条路径):
- iframe 2152px / 1874px,与正文一致,innerHasScrollbar=false;
- 空正文占位符正常、点击空白落光标正常;
- 只有页面级滚动。

测试:新增 iframe 随正文增长、测量忽略 min-height 两个回归用例;903 全通过。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-09 21:37:14 +08:00

300 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* TinyMCE iframe 内的正文样式。
*
* 编辑器正文跑在 iframe 里,页面级 SCSS 影响不到它,所以这里显式给出:
* 正文排版、主题引用 .quote_q、隐藏内容 .tinymce-hide、表格、公式、
* 块级删除控件与块选中态。
*
* @package Jio
*/
export const EDITOR_CONTENT_STYLE = `
/*
* 正文撑满编辑区:内容很短时点击正文下方的空白区域也应落光标。
* iframe 高度由 syncEditorHeight() 跟随内容。
*
* 高度基准取 iframe 视口(100vh 而不是 100%):iframe 会随正文同步变高,
* 用百分比会形成「撑高 → 再撑高」的循环。100vh 只保证空正文铺满一屏。
*/
body {
position: relative;
box-sizing: border-box;
min-height: 100vh;
margin: 0;
color: #2b2b2b;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
font-size: 16px;
line-height: 1.8;
letter-spacing: 0.01em;
}
p { margin: 0 0 1.1em; }
/*
* 正文占位符:TinyMCE 4.9 没有内置 placeholder 插件,由主题插件
* (front-submit-editor-basics.js)在正文为空时给 body 打 data-jio-empty,
* 这里用 ::before 渲染提示。不插 DOM 节点,避免被 setContent 清掉、
* 也避免占住首行挡住点击。
*/
body[data-jio-empty="1"]::before {
position: absolute;
top: 0;
left: 0;
color: #b9bfbc;
content: attr(data-jio-placeholder);
pointer-events: none;
user-select: none;
}
h1, h2, h3, h4, h5, h6 { margin: 1.5em 0 0.65em; line-height: 1.4; }
img, iframe { max-width: 100%; }
img { height: auto; }
/*
* 块级删除控件。它由 editor-runtime 插进 iframe 的 body,样式必须写在这里:
* 父页面样式表管不到 iframe 内部,缺这条规则时按钮会退化成正文顶部的常显小方块。
* 正文是流式布局且 iframe 高度随内容增长,所以按整篇正文定位,而不是相对某个块。
*/
#jio-block-actions {
position: absolute;
z-index: 5;
top: 6px;
left: 6px;
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease;
}
#jio-block-actions.is-visible {
opacity: 1;
pointer-events: auto;
}
#jio-block-actions .jio-creator__block-action {
display: inline-flex;
height: 26px;
align-items: center;
gap: 5px;
padding: 0 9px;
border: 1px solid #e3e7e5;
border-radius: 6px;
background: #fff;
color: #7d8683;
font: inherit;
font-size: 12px;
line-height: 1;
white-space: nowrap;
box-shadow: 0 2px 8px rgba(24, 39, 34, 0.08);
cursor: pointer;
}
#jio-block-actions .jio-creator__block-action-icon {
font-size: 11px;
line-height: 1;
}
#jio-block-actions .jio-creator__block-action:hover {
border-color: #cdd6d2;
color: #4f5957;
}
#jio-block-actions.is-selected .jio-creator__block-action {
border-color: #e0a99b;
background: #fdf2ee;
color: #b4573f;
}
#jio-block-actions.is-selected .jio-creator__block-action:hover {
border-color: #cf8574;
background: #fbe7e1;
}
/* 第一次点击选中的块:虚线高亮,明确「还没删」。 */
.jio-creator__block-selected {
outline: 2px dashed rgba(180, 87, 63, 0.55);
outline-offset: 3px;
border-radius: 4px;
}
/*
* 代码块:与前台文章页保持一致,只用 pre > code。
* 前台由 EnlighterJS 高亮,编辑器里给出同一份底色与等宽排版。
*/
pre {
margin: 0 0 1.1em;
padding: 14px 18px;
overflow-x: auto;
border-radius: 8px;
background: #f2f4f5;
color: #2b2b2b;
font-family: Consolas, Monaco, "Courier New", monospace;
font-size: 13px;
line-height: 1.6;
white-space: pre-wrap;
word-wrap: break-word;
}
pre code {
border: 0;
background: transparent;
color: inherit;
font-family: inherit;
font-size: inherit;
line-height: inherit;
padding: 0;
white-space: inherit;
}
/* 引用:与前台主题的 .quote_q 视觉一致。 */
.quote_q {
position: relative;
margin: 10px 0 20px;
padding: 1.2em;
border-radius: 6px;
--quote-color: #555;
color: var(--quote-color);
}
.quote_q::before {
position: absolute;
inset: 0;
border-radius: 6px;
background: var(--quote-color);
content: '';
opacity: 0.04;
}
.quote_q.quote-mce::after {
position: absolute;
top: 20px;
left: 20px;
width: 1em;
height: 1em;
color: var(--quote-color);
content: '';
font-size: 1.2em;
line-height: 1;
opacity: 0.6;
/* 引号用图标字体绘制时依赖 FA;这里用内联 SVG 数据,编辑器与前台都不缺图标。 */
background: var(--quote-color);
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M464 256h-80v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8c-88.4 0-160 71.6-160 160v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zm-288 0H96v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8C71.6 32 0 103.6 0 192v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z'/%3E%3C/svg%3E") center / contain no-repeat;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M464 256h-80v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8c-88.4 0-160 71.6-160 160v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zm-288 0H96v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8C71.6 32 0 103.6 0 192v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.quote_q > div {
position: relative;
min-height: 24px;
padding-left: 2em;
opacity: 0.7;
}
.quote_q > div > :first-child { margin-top: 0; }
.quote_q > div > :last-child { margin-bottom: 0; }
.quote_q [contenteditable="true"] {
outline: 0;
border-radius: 0;
box-shadow: none;
}
.quote_q.qe_wzk_c-red { --quote-color: #dc3f3f; }
.quote_q.qe_wzk_lan { --quote-color: #0092ff; }
.quote_q.qe_wzk_lv { --quote-color: #23790e; }
/* 表格。 */
.jio-content-table {
width: 100%;
margin: 0 0 1.1em;
border-collapse: collapse;
font-size: 14px;
}
.jio-content-table th,
.jio-content-table td {
padding: 10px 12px;
border: 1px solid #e6e9e8;
line-height: 1.6;
}
.jio-content-table thead th {
background: #f6f8f7;
font-weight: 600;
text-align: left;
}
.jio-content-table.is-striped tbody tr:nth-child(odd) td { background: #f7f9f8; }
/* 公式:独占一行时居中显示,不铺满整行底色。 */
.jio-math {
font-family: "Cambria Math", "Latin Modern Math", "Times New Roman", serif;
font-size: 1.05em;
white-space: pre-wrap;
}
.jio-math--block {
display: block;
max-width: 100%;
margin: 0 auto;
padding: 2px 0;
overflow-x: auto;
text-align: center;
background: transparent;
border: 0;
}
.jio-math sup, .jio-math sub { font-size: 0.72em; }
/* 隐藏内容:短代码放进 .hide-before / .hide-after,编辑器只显示可读标签。 */
.tinymce-hide {
position: relative;
margin: 18px 0;
padding: 38px 14px 14px;
border: 1px dashed rgba(240, 68, 148, 0.35);
border-radius: 6px;
background: rgba(240, 68, 148, 0.04);
}
.tinymce-hide > .hide-before,
.tinymce-hide > .hide-after {
margin: 0;
font-family: Consolas, Monaco, monospace;
font-size: 0;
line-height: 1.5;
color: #f04494;
}
.tinymce-hide > .hide-before {
position: absolute;
top: 10px;
left: 14px;
}
.tinymce-hide > .hide-before::before {
content: attr(data-jio-hide-label);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.02em;
}
.tinymce-hide > .hide-after {
display: none;
}
.tinymce-hide > [contenteditable="true"] {
min-height: 38px;
padding: 10px;
border-radius: 4px;
background: rgba(255, 255, 255, 0.75);
outline: 0;
}
.tinymce-hide > [contenteditable="true"] > :first-child { margin-top: 0; }
.tinymce-hide > [contenteditable="true"] > :last-child { margin-bottom: 0; }
/* 注释:编辑器里显示上标标记,发布后由服务端渲染编号与注释列表。 */
.jio-footnote-ref {
display: inline-block;
max-width: 100%;
padding: 0 6px;
border-radius: 4px;
background: #eef5f2;
color: #267665;
font-size: 0.78em;
line-height: 1.6;
vertical-align: super;
cursor: default;
}
.jio-footnote-ref::before {
content: '注 ';
opacity: 0.6;
}
/* 附件链接。 */
.jio-file-link {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border: 1px solid #e6e9e8;
border-radius: 6px;
background: #f7f8f8;
text-decoration: none;
}
`;