feat(creator-studio): portal dropdowns, hidden content, two-step block delete

Toolbar
- New ToolMenu renders menus through a portal on body, so they are no longer
  clipped by the horizontally scrolling toolbar and no longer fall back to a
  native <select>. Triggers reuse .jio-creator__tool-btn geometry, fixing the
  heading button's mismatched height/size/position.
- Heading / list / align / quote / hidden-content are all dropdowns.
- Lists: unordered + ordered via InsertOrderedList/InsertUnorderedList.
  The TOC button is removed (it also used the wrong icon).
- Adds left / center / right alignment.
- Adds hidden content: comment / login / VIP / paid, wired to the existing
  [reply], [jio_hide mode="login"], [vip] and [payshow] shortcodes.

Editor content
- Quote blocks now match the live article: full .quote_q structure, four
  colour variables, and an SVG-mask quote mark that does not depend on the
  Font Awesome font being present inside the iframe.
- Block math is centred on a transparent background instead of a full-width
  grey bar.
- Code blocks are plain <pre><code>, identical to the article page; language
  and theme selection is gone and EnlighterJS handles highlighting globally.
  The classic submit editor's code modal follows the same shape.
- Hidden content reuses the .tinymce-hide structure and shows a readable label
  while keeping the shortcode text in the DOM for saving.

Block deletion
- Two-step delete, WPS style: the first click only selects and highlights the
  block, the second click removes it. Clicking elsewhere or Esc cancels.

Contracts updated and extended; 884 widget-system tests pass.
This commit is contained in:
kate522 committed 2026-11-09 15:03:50 +08:00
1 parent 3e48fdf61e
commit c5bdbc0457
16 files changed
+1090 -545

No files matched your search

@@ -224,16 +224,19 @@ test('front submit exposes the complete reference media and formatting toolset',
assert.match(editor, /new-dplayer post-dplayer dplayer/);
assert.match(editor, /file-download-box/);
assert.match(editor, /wp-block-embed is-type-video/);
assert.match(editor, /data-enlighter-language/);
assert.match(editor, /data-enlighter-theme/);
assert.match(editor, /enlighter-pre/);
// 代码块与前台文章页一致(pre > code),语言由全局代码高亮设置决定,编辑器不再选语言 / 主题。
assert.match(editor, /'<pre><code>' \+ encoded \+ '<\/code><\/pre>'/);
assert.doesNotMatch(editor, /data-enlighter-language/);
assert.doesNotMatch(editor, /data-enlighter-theme/);
assert.doesNotMatch(editor, /enlighter-pre/);
assert.match(editor, /qe_wzk_c-red/);
assert.match(editor, /qe_wzk_lan/);
assert.match(editor, /qe_wzk_lv/);
assert.match(editorCss, /\.quote_q/);
assert.match(editorCss, /\.quote_q \[contenteditable="true"\][\s\S]*?box-shadow:\s*none/);
assert.match(editorCss, /\.file-download-box/);
assert.match(editorCss, /\.enlighter-pre/);
assert.match(editorCss, /pre code \{/);
assert.doesNotMatch(editorCss, /\.enlighter-pre/);
assert.doesNotMatch(editor, /shop|forum|bbs_/i);
});