fix(submit): render the configured body placeholder in TinyMCE

WordPress 打包的 TinyMCE 4.9 不含官方 placeholder 插件,tinymce.init 里的
placeholder 配置被静默忽略,投稿页「投稿内容占位符」从未显示过。

新增主题插件 assets/js/front-submit-placeholder.js:正文为空时插入一个
data-mce-bogus 的占位段落,有内容即移除;序列化 / 解析都剔除该段落,
字数统计也跳过它,提示文字不会写进文章。

- 经典投稿表单与创作者工作台都通过 external_plugins 加载
  (WordPress 会丢弃名字已在 plugins 列表里的外部插件)
- 占位样式写进 iframe 的 content CSS:submit-editor.css 与
  editor-content-style.ts

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-11-09 19:01:28 +08:00
1 parent beb898b1ab
commit 44a03fd5f4
8 files changed
+228 -3

No files matched your search

@@ -377,6 +377,38 @@ test('quote, hidden content, and block math render like the live article', () =>
assert.doesNotMatch(contentStyle, /\.jio-math--block\s*\{[^}]*background:\s*#/);
});
test('submit editor renders the configured body placeholder', () => {
const plugin = read('assets/js/front-submit-placeholder.js');
const classic = read('templates/parts/submit/editor-main.php');
const studio = read('src/Core/CreatorStudio.php');
const styles = read('assets/css/frontend/pages/submit-editor.css');
const contentStyle = read('assets/creator-studio/src/editor-content-style.ts');
// WordPress 打包的 TinyMCE 4.9 没有 placeholder 插件,主题自己实现。
assert.match(plugin, /PluginManager\.add\('jio_placeholder'/);
assert.match(plugin, /getParam\('placeholder'/);
assert.match(plugin, /data-mce-bogus/);
// 占位段落不能写进文章内容。
assert.match(plugin, /addNodeFilter\('p', strip\)/);
// 图片 / 视频 / 表格即使没有文字也算有内容。
assert.match(plugin, /MEDIA = 'img,iframe,table,pre,hr,video,audio,figure/);
// 两条投稿路径都要加载插件,否则占位符在其中一个页面消失。
// 注意:WordPress 会丢弃名字已出现在 plugins 列表里的外部插件,
// 所以 jio_placeholder 只能走 external_plugins。
assert.match(classic, /\$plugins\s*=\s*'[^']*'/);
assert.doesNotMatch(classic, /\$plugins\s*=\s*'[^']*jio_placeholder/);
assert.match(classic, /\$external\['jio_placeholder'\]\s*=\s*\$placeholder_plugin_url/);
assert.match(classic, /'placeholder'\s*=>\s*\(string\) \(\$settings\['content_placeholder'\]/);
assert.match(studio, /\['placeholderPlugin'\]\s*=\s*\$this->placeholder_plugin_url\(\)/);
assert.doesNotMatch(appSource, /plugins: '[^']*jio_placeholder/);
assert.match(appSource, /external_plugins: bootstrap\.creator\?\.placeholderPlugin/);
// 占位符样式必须写进 iframe 的 content CSS,页面样式影响不到编辑器内部。
assert.match(styles, /\.jio-editor-placeholder\s*\{/);
assert.match(contentStyle, /\.jio-editor-placeholder\s*\{/);
});
test('creator studio build artifacts and contracts exist', () => {
assert.ok(exists('assets/creator-studio/package.json'));
assert.ok(exists('assets/creator-studio/package-lock.json'));