bridgerte 0.9.5 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dom.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-B_g23O7q.cjs"),t=require("./index-H5V0EMkq.cjs");exports.createFloatingLayer=e.createFloatingLayer;exports.createRichTextEditor=e.createRichTextEditor;exports.createWebViewBridgeRuntime=e.createWebViewBridgeRuntime;exports.createRichTextToolbar=t.createRichTextToolbar;exports.hasMeaningfulHtmlContent=t.hasMeaningfulHtmlContent;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-B_g23O7q.cjs"),t=require("./index-Ce7rOCpH.cjs");exports.createFloatingLayer=e.createFloatingLayer;exports.createRichTextEditor=e.createRichTextEditor;exports.createWebViewBridgeRuntime=e.createWebViewBridgeRuntime;exports.createRichTextToolbar=t.createRichTextToolbar;exports.hasMeaningfulHtmlContent=t.hasMeaningfulHtmlContent;
2
2
  //# sourceMappingURL=dom.cjs.map
package/dist/dom.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { c as t, a as r, b as o } from "./index-DyCMSFrm.js";
2
- import { c as i, h as n } from "./index-BWi3d-Zp.js";
2
+ import { c as i, h as n } from "./index-DGPoit9-.js";
3
3
  export {
4
4
  t as createFloatingLayer,
5
5
  r as createRichTextEditor,
@@ -0,0 +1,36 @@
1
+ "use strict";const X=require("./native-spec.cjs"),m=require("./index-B_g23O7q.cjs"),U={toolbarGroup:`
2
+ <svg
3
+ aria-hidden="true"
4
+ class="lucide lucide-ellipsis"
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ width="18"
7
+ height="18"
8
+ viewBox="0 0 24 24"
9
+ fill="none"
10
+ stroke="currentColor"
11
+ stroke-width="2"
12
+ stroke-linecap="round"
13
+ stroke-linejoin="round"
14
+ >
15
+ <circle cx="12" cy="12" r="1" />
16
+ <circle cx="19" cy="12" r="1" />
17
+ <circle cx="5" cy="12" r="1" />
18
+ </svg>
19
+ `,chevronDown:`
20
+ <svg
21
+ aria-hidden="true"
22
+ class="lucide lucide-chevron-down"
23
+ xmlns="http://www.w3.org/2000/svg"
24
+ width="12"
25
+ height="12"
26
+ viewBox="0 0 24 24"
27
+ fill="none"
28
+ stroke="currentColor"
29
+ stroke-width="2"
30
+ stroke-linecap="round"
31
+ stroke-linejoin="round"
32
+ >
33
+ <path d="m6 9 6 6 6-6" />
34
+ </svg>
35
+ `},W=e=>Array.from(e.querySelectorAll(".bridgerte__toolbar-group-menu-item")).filter(t=>!t.disabled),oe=(e,t)=>{const l=W(e)[t];l&&l.focus()},ne=e=>{oe(e,0)},re=(e,t,s,l,c)=>{var d,u;const r=W(t),a=document.activeElement instanceof HTMLButtonElement?r.indexOf(document.activeElement):-1,b=T=>{var v;if(r.length===0)return;const f=((a>=0?a:0)+T+r.length)%r.length;(v=r[f])==null||v.focus()};switch(e.key){case"ArrowDown":e.preventDefault(),b(1);break;case"ArrowUp":e.preventDefault(),b(-1);break;case"Home":e.preventDefault(),(d=r[0])==null||d.focus();break;case"End":e.preventDefault(),(u=r.at(-1))==null||u.focus();break;case"Enter":case" ":document.activeElement instanceof HTMLButtonElement&&(e.preventDefault(),l(document.activeElement),c(),s.focus());break;case"Escape":e.preventDefault(),s.focus(),c();break}},A="button[data-bridgerte-toolbar-group-id]",ae="button[data-bridgerte-toolbar-item-id]",se=[ae,".bridgerte__toolbar-group-menu-item"].join(","),le=(e,t)=>{const s=e.map(l=>m.getMenuStateForItem(l,t));return{active:s.some(l=>l.active),disabled:s.length>0&&s.every(l=>l.disabled)}},ie=(e,t,s,l,c)=>{const r=m.getMenuStateForItem(t,s),a=document.createElement("button"),b=l[t.icon]??m.defaultMenuIcons[t.icon];a.type="button",a.className="bridgerte__toolbar-button",a.disabled=r.disabled,a.dataset.active=String(r.active),a.dataset.bridgerteToolbarItemId=t.id,a.setAttribute("aria-label",t.label),a.setAttribute("aria-pressed",String(r.active)),c&&(a.dataset.tooltip=t.label),m.appendMenuIcon(a,b,t.label),e.append(a)},ue=(e,t,s,l,c)=>{const r=document.createElement("button"),a=le(t.items,s),b=t.icon?l[t.icon]??m.defaultMenuIcons[t.icon]:U.toolbarGroup,d=document.createElement("span");r.type="button",r.className="bridgerte__toolbar-button bridgerte__toolbar-group-button",r.disabled=a.disabled,r.dataset.active=String(a.active),r.dataset.bridgerteToolbarGroupId=t.key,r.dataset.open="false",r.setAttribute("aria-label",t.title),r.setAttribute("aria-haspopup","menu"),r.setAttribute("aria-expanded","false"),r.setAttribute("aria-pressed",String(a.active)),c&&(r.dataset.tooltip=t.title),m.appendMenuIcon(r,b,t.title),d.className="bridgerte__toolbar-group-indicator",d.setAttribute("aria-hidden","true"),d.innerHTML=U.chevronDown,r.append(d),e.append(r)},ce=(e,t,s,l,c)=>{e.textContent="",t.forEach(r=>{if(r.type==="separator"){const b=document.createElement("span");b.className="bridgerte__toolbar-separator",b.dataset.separatorId=r.key,b.setAttribute("aria-hidden","true"),e.append(b);return}if(r.type==="button"){ie(e,r.item,s,l,c);return}const a=document.createElement("div");a.className="bridgerte__toolbar-group",a.dataset.group=r.key,a.setAttribute("aria-label",r.title),e.append(a),ue(a,r,s,l,c)})},M=(e,t,s,l)=>{if(e.textContent="",!t){e.dataset.visible="false";return}t.items.forEach(c=>{const r=m.getMenuStateForItem(c,s),a=document.createElement("button"),b=l[c.icon]??m.defaultMenuIcons[c.icon],d=document.createElement("span");a.type="button",a.className="bridgerte__menu-item bridgerte__toolbar-group-menu-item",a.disabled=r.disabled,a.dataset.active=String(r.active),a.dataset.bridgerteToolbarItemId=c.id,a.setAttribute("role","menuitem"),a.setAttribute("aria-label",c.label),a.setAttribute("aria-pressed",String(r.active)),m.appendMenuIcon(a,b,c.label),d.className="bridgerte__toolbar-group-menu-label",d.textContent=c.label,a.append(d),e.append(a)}),e.dataset.visible="true",e.style.minWidth=`${t.button.offsetWidth}px`},D=(e,t)=>{e.querySelectorAll(A).forEach(s=>{const l=(t==null?void 0:t.groupKey)===s.dataset.bridgerteToolbarGroupId;s.dataset.open=String(l),s.setAttribute("aria-expanded",String(l))})},$=(e,t)=>e.find(s=>s.type==="group"&&s.key===t),de=4,pe=8,be=6,k={capture:!0,passive:!1},me=()=>{var e;return typeof window<"u"&&((e=window.matchMedia)==null?void 0:e.call(window,"(hover: hover) and (pointer: fine)").matches)===!0},_=e=>{const t=e instanceof Element?e.closest(se):null;return t instanceof HTMLButtonElement?t:null},fe=e=>{const t=e instanceof Element?e.closest(A):null;return t instanceof HTMLButtonElement?t:null};function ge(e,t){const s=t.placement??"top",l=m.resolveMenuSchemaForDom(t.menuSchema??X.defaultMenuSchema,{menuLabels:t.menuLabels,payloadPanelConfig:t.payloadPanelConfig}),c=X.resolveToolbarMenu(t.toolbarConfig,l),r=c.flatMap(o=>o.type==="button"?[o.item]:o.type==="group"?o.items:[]),a=t.icons??{},b=me(),d=document.createElement("div"),u=document.createElement("div"),T=e.closest(".bridgerte")??e;let E=!1,f=null,v=!1,L=t.editor.getCommandStates(),i=null,g=null;const z=m.bindTouchPressedState(e,{targetSelector:["button[data-bridgerte-toolbar-item-id]","button[data-bridgerte-toolbar-group-id]"].join(",")}),J=m.bindTouchPressedState(u,{targetSelector:".bridgerte__toolbar-group-menu-item"}),G=()=>{T.append(d),T.append(u)},C=()=>{g==null||g.setOpen(!1),g==null||g.destroy(),g=null},P=()=>{i&&(C(),g=m.createFloatingLayer(i.button,u,{placement:s==="bottom"?"top-start":"bottom-start",offset:be,strategy:"fixed"}),g.setOpen(!0))},h=()=>{C(),i=null,M(u,i,L,a),D(e,i)},I=o=>{if(!E&&(L=o,i&&C(),ce(e,c,o,a,b),G(),i)){const n=Array.from(e.querySelectorAll(A)).find(te=>te.dataset.bridgerteToolbarGroupId===(i==null?void 0:i.groupKey)),p=$(c,i.groupKey);i=n&&p?{groupKey:i.groupKey,button:n,items:p.items}:null,M(u,i,L,a),D(e,i),i&&P()}},Q=()=>{E||I(t.editor.getCommandStates())},y=()=>{d.dataset.visible="false",d.textContent=""},Y=o=>{const n=o.dataset.tooltip;if(!b||!n||f)return;const p=o.getBoundingClientRect();d.textContent=n,d.dataset.visible="true",d.style.left=`${p.left+p.width/2}px`,d.style.top=`${p.top-pe}px`},H=o=>{const n=_(o.target);n&&Y(n)},N=o=>{const n=o.relatedTarget,p=_(o.target);p&&n instanceof Node&&p.contains(n)||y()},F=()=>{f=null,delete e.dataset.dragging,document.removeEventListener("pointermove",K),document.removeEventListener("pointerup",x),document.removeEventListener("pointercancel",x)},K=o=>{if(!f)return;const n=f.startClientX-o.clientX;Math.abs(n)>de&&(f.hasDragged=!0,v=!0,y(),h()),e.scrollLeft=f.startScrollLeft+n},x=o=>{const n=f;F(),n&&o.type!=="pointercancel"&&n.pointerType!=="mouse"&&!n.hasDragged&&n.startButton&&(B(n.startButton),v=!0)},R=o=>{if(o.pointerType==="mouse"&&o.button!==0)return;const n=_(o.target);o.preventDefault(),f={startClientX:o.clientX,startScrollLeft:e.scrollLeft,pointerType:o.pointerType,hasDragged:!1,startButton:n??void 0},e.dataset.dragging="true",y(),document.addEventListener("pointermove",K),document.addEventListener("pointerup",x),document.addEventListener("pointercancel",x)},S=o=>{o.defaultPrevented||o.cancelable&&o.preventDefault()},B=o=>{if(!(o instanceof HTMLButtonElement)||o.disabled)return;const n=r.find(p=>p.id===o.dataset.bridgerteToolbarItemId);if(n){if(n.payloadPanel){const p=o.getBoundingClientRect();t.editor.requestPayloadPanel({menuId:n.id,command:n.command,panel:n.payloadPanel,currentValues:m.getPayloadPanelCurrentValues(n,t.editor.getCommandStates()),anchorRect:{x:p.left,y:p.top,width:p.width,height:p.height}});return}t.editor.executeCommand(n.command)}},Z=o=>{const n=$(c,o.dataset.bridgerteToolbarGroupId);if(!(!n||o.disabled)){if((i==null?void 0:i.groupKey)===n.key){h();return}i={groupKey:n.key,button:o,items:n.items},y(),M(u,i,L,a),D(e,i),P(),ne(u)}},w=o=>{if(v){v=!1,o.preventDefault(),o.stopPropagation();return}const n=fe(o.target);if(n){o.preventDefault(),o.stopPropagation(),Z(n);return}const p=_(o.target);p&&(o.preventDefault(),o.stopPropagation(),B(p),h())},O=o=>{o.pointerType==="mouse"&&o.button!==0||o.preventDefault()},q=o=>{const n=o.target;n instanceof Node&&(e.contains(n)||u.contains(n))||h()},j=o=>{if(i&&u.contains(document.activeElement)){re(o,u,i.button,B,h);return}o.key==="Escape"&&h()};e.classList.add("bridgerte__toolbar"),d.className="bridgerte__toolbar-tooltip",d.dataset.visible="false",u.className="bridgerte__floating-menu bridgerte__toolbar-group-menu",u.dataset.visible="false",u.setAttribute("role","menu"),e.dataset.placement=s,e.setAttribute("role","toolbar"),e.setAttribute("aria-label",s==="bottom"?"BridgeRTE tabbar":"BridgeRTE toolbar"),e.addEventListener("pointerdown",R,!0),e.addEventListener("touchstart",S,k),e.addEventListener("click",w),u.addEventListener("pointerdown",O,!0),u.addEventListener("touchstart",S,k),u.addEventListener("click",w),document.addEventListener("click",q),document.addEventListener("keydown",j),b&&(e.addEventListener("mouseover",H),e.addEventListener("mouseout",N)),e.addEventListener("focusout",y),G();const ee=t.editor.subscribeCommandStateChange(I);return{update:Q,destroy(){E||(E=!0,F(),ee(),h(),e.removeEventListener("pointerdown",R,!0),e.removeEventListener("touchstart",S,k),e.removeEventListener("click",w),u.removeEventListener("pointerdown",O,!0),u.removeEventListener("touchstart",S,k),u.removeEventListener("click",w),document.removeEventListener("click",q),document.removeEventListener("keydown",j),b&&(e.removeEventListener("mouseover",H),e.removeEventListener("mouseout",N)),z(),J(),e.removeEventListener("focusout",y),d.remove(),u.remove(),e.classList.remove("bridgerte__toolbar"),delete e.dataset.placement,e.textContent="",e.removeAttribute("role"),e.removeAttribute("aria-label"))}}}const ve=/[\u200B-\u200D\uFEFF]/g,he=["img","video","audio","iframe","table","pre","code","hr","figure","canvas","svg","math",'[data-type="mention"]'].join(","),V=e=>(e==null?void 0:e.replace(ve,"").trim())??"",ye=e=>{if(!V(e))return!1;const t=document.createElement("template");return t.innerHTML=e,!!(V(t.content.textContent)||t.content.querySelector(he))};exports.createRichTextToolbar=ge;exports.hasMeaningfulHtmlContent=ye;
36
+ //# sourceMappingURL=index-Ce7rOCpH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Ce7rOCpH.cjs","sources":["../../dom/src/menuIcon/uiIcons.ts","../../dom/src/richTextToolbar/groupMenuKeyboard.ts","../../dom/src/richTextToolbar/render.ts","../../dom/src/richTextToolbar/index.ts","../../dom/src/htmlContent/index.ts"],"sourcesContent":["/**\r\n * DOM UI chrome icon 表。\r\n *\r\n * 这里放 toolbar 收纳入口、下拉箭头这类控件自身图标。它们不属于 `MenuItem.icon`\r\n * 跨端 schema,也不应该进入 `defaultMenuIcons` 的 schema 对齐检查。\r\n */\r\nexport const defaultMenuUiIcons = {\r\n toolbarGroup: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-ellipsis\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\r\n </svg>\r\n `,\r\n chevronDown: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-chevron-down\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"12\"\r\n height=\"12\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n `\r\n} as const;\r\n","export const getEnabledGroupMenuButtons = (menuElement: HTMLElement) => (\r\n Array.from(\r\n menuElement.querySelectorAll<HTMLButtonElement>('.bridgerte__toolbar-group-menu-item')\r\n ).filter((button) => !button.disabled)\r\n);\r\n\r\nexport const focusToolbarGroupMenuItem = (menuElement: HTMLElement, index: number) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const nextButton = buttons[index];\r\n\r\n if (nextButton) nextButton.focus();\r\n};\r\n\r\nexport const focusFirstToolbarGroupMenuItem = (menuElement: HTMLElement) => {\r\n /*\r\n * group menu 使用 ARIA menu 语义,打开后焦点必须进入第一个可操作项。\r\n * 这样键盘用户可以继续用方向键浏览,而不是停留在展开按钮上。\r\n */\r\n focusToolbarGroupMenuItem(menuElement, 0);\r\n};\r\n\r\nexport const handleToolbarGroupMenuKeyDown = (\r\n event: KeyboardEvent,\r\n menuElement: HTMLElement,\r\n returnButton: HTMLButtonElement,\r\n executeToolbarButton: (button: HTMLButtonElement) => void,\r\n closeGroupMenu: () => void\r\n) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const activeIndex = document.activeElement instanceof HTMLButtonElement\r\n ? buttons.indexOf(document.activeElement)\r\n : -1;\r\n const focusByOffset = (offset: number) => {\r\n if (buttons.length === 0) return;\r\n\r\n const baseIndex = activeIndex >= 0 ? activeIndex : 0;\r\n const nextIndex = (baseIndex + offset + buttons.length) % buttons.length;\r\n\r\n buttons[nextIndex]?.focus();\r\n };\r\n\r\n /*\r\n * ARIA menu 语义要求支持 roving focus。这里不改 toolbar 的横向键盘模型,\r\n * 只在已打开的纵向收纳菜单内处理上下方向、首尾跳转和执行/关闭。\r\n */\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n focusByOffset(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n focusByOffset(-1);\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n buttons[0]?.focus();\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n buttons.at(-1)?.focus();\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n if (document.activeElement instanceof HTMLButtonElement) {\r\n event.preventDefault();\r\n executeToolbarButton(document.activeElement);\r\n closeGroupMenu();\r\n returnButton.focus();\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n returnButton.focus();\r\n closeGroupMenu();\r\n break;\r\n default:\r\n break;\r\n }\r\n};\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport type { MenuItem, ResolvedToolbarItem } from '@bridgerte/native-spec';\r\nimport {\r\n appendMenuIcon,\r\n defaultMenuIcons,\r\n defaultMenuUiIcons\r\n} from './icons';\r\nimport { getMenuStateForItem } from '../menuRuntime';\r\nimport type {\r\n RichTextToolbarIcons,\r\n ToolbarGroupMenuState\r\n} from './type';\r\n\r\nexport const toolbarGroupButtonSelector = 'button[data-bridgerte-toolbar-group-id]';\r\nexport const toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\r\n// 可执行按钮同时覆盖 toolbar 主按钮和 group menu 子项,避免浮层子菜单绕过统一命令入口。\r\nexport const toolbarExecutableButtonSelector = [\n toolbarButtonSelector,\n '.bridgerte__toolbar-group-menu-item'\n].join(',');\n\r\nconst getGroupMenuState = (items: MenuItem[], commandStates: CommandState[]) => {\r\n const itemStates = items.map((item) => getMenuStateForItem(item, commandStates));\r\n\r\n return {\r\n active: itemStates.some((state) => state.active),\r\n disabled: itemStates.length > 0 && itemStates.every((state) => state.disabled)\r\n };\r\n};\r\n\r\nconst renderToolbarButton = (\r\n groupElement: HTMLElement,\r\n item: MenuItem,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n // icon 兜底顺序固定为:业务覆盖 > DOM 默认 SVG > label 文本。\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button';\r\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n if (enableTooltip) button.dataset.tooltip = item.label;\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n\r\n groupElement.append(button);\r\n};\r\n\r\nconst renderToolbarGroupButton = (\r\n groupElement: HTMLElement,\r\n toolbarItem: Extract<ResolvedToolbarItem, { type: 'group' }>,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const button = document.createElement('button');\r\n const groupState = getGroupMenuState(toolbarItem.items, commandStates);\r\n const iconSvg = toolbarItem.icon\r\n ? icons[toolbarItem.icon] ?? defaultMenuIcons[toolbarItem.icon]\r\n : defaultMenuUiIcons.toolbarGroup;\r\n const indicator = document.createElement('span');\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button bridgerte__toolbar-group-button';\r\n button.disabled = groupState.disabled;\r\n button.dataset.active = String(groupState.active);\r\n button.dataset.bridgerteToolbarGroupId = toolbarItem.key;\r\n button.dataset.open = 'false';\r\n button.setAttribute('aria-label', toolbarItem.title);\r\n button.setAttribute('aria-haspopup', 'menu');\r\n button.setAttribute('aria-expanded', 'false');\r\n button.setAttribute('aria-pressed', String(groupState.active));\r\n if (enableTooltip) button.dataset.tooltip = toolbarItem.title;\r\n\r\n appendMenuIcon(button, iconSvg, toolbarItem.title);\r\n\r\n indicator.className = 'bridgerte__toolbar-group-indicator';\r\n indicator.setAttribute('aria-hidden', 'true');\r\n indicator.innerHTML = defaultMenuUiIcons.chevronDown;\r\n button.append(indicator);\r\n groupElement.append(button);\r\n};\r\n\r\n/**\r\n * 渲染 toolbar 横向主入口。\n *\n * 字符串菜单直接渲染为按钮,`|` 渲染分割线。\n * 只有用户显式声明的 group 配置才生成收纳入口,避免 schema 隐式改变 DOM 结构。\n */\r\nexport const renderToolbar = (\r\n toolbarElement: HTMLElement,\r\n toolbarItems: ResolvedToolbarItem[],\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n toolbarElement.textContent = '';\r\n\r\n toolbarItems.forEach((toolbarItem) => {\n if (toolbarItem.type === 'separator') {\n const separatorElement = document.createElement('span');\n\n separatorElement.className = 'bridgerte__toolbar-separator';\n separatorElement.dataset.separatorId = toolbarItem.key;\r\n separatorElement.setAttribute('aria-hidden', 'true');\r\n toolbarElement.append(separatorElement);\r\n return;\n }\n\n if (toolbarItem.type === 'button') {\n renderToolbarButton(\n toolbarElement,\n toolbarItem.item,\n commandStates,\n icons,\n enableTooltip\n );\n return;\n }\n\n /*\n * 收纳菜单是用户在 toolbarConfig 里显式声明的结构;普通菜单不会自动生成 DOM 包裹,\n * 显示分组完全交给用户用 group 配置或 `|` 控制。\n */\n const groupElement = document.createElement('div');\n\n groupElement.className = 'bridgerte__toolbar-group';\n groupElement.dataset.group = toolbarItem.key;\n groupElement.setAttribute('aria-label', toolbarItem.title);\n toolbarElement.append(groupElement);\n\n renderToolbarGroupButton(\n groupElement,\n toolbarItem,\n commandStates,\n icons,\n enableTooltip\r\n );\r\n });\r\n};\r\n\r\n/**\r\n * 渲染 group button 打开的纵向收纳菜单。\r\n *\r\n * 浮层只展示 MenuItem 子项并复用现有 item id,点击执行仍由 index.ts 统一走 EditorAPI。\r\n */\r\nexport const renderToolbarGroupMenu = (\r\n menuElement: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons\r\n) => {\r\n menuElement.textContent = '';\r\n\r\n if (!groupMenuState) {\r\n menuElement.dataset.visible = 'false';\r\n return;\r\n }\r\n\r\n groupMenuState.items.forEach((item) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n const labelElement = document.createElement('span');\n\n button.type = 'button';\n button.className = 'bridgerte__menu-item bridgerte__toolbar-group-menu-item';\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('role', 'menuitem');\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n labelElement.className = 'bridgerte__toolbar-group-menu-label';\r\n labelElement.textContent = item.label;\r\n button.append(labelElement);\r\n menuElement.append(button);\r\n });\r\n\r\n menuElement.dataset.visible = 'true';\r\n menuElement.style.minWidth = `${groupMenuState.button.offsetWidth}px`;\r\n};\r\n\r\nexport const syncToolbarGroupButtonState = (\r\n container: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null\r\n) => {\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector).forEach((button) => {\r\n const open = groupMenuState?.groupKey === button.dataset.bridgerteToolbarGroupId;\r\n\r\n button.dataset.open = String(open);\r\n button.setAttribute('aria-expanded', String(open));\r\n });\r\n};\r\n\r\nexport const findToolbarGroupMenuItem = (\r\n toolbarItems: ResolvedToolbarItem[],\r\n groupKey: string | undefined\r\n) => toolbarItems.find((item): item is Extract<ResolvedToolbarItem, { type: 'group' }> => (\r\n item.type === 'group' && item.key === groupKey\r\n));\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport {\r\n defaultMenuSchema,\r\n resolveToolbarMenu\r\n} from '@bridgerte/native-spec';\r\nimport { createFloatingLayer, type RichTextFloatingLayer } from '../floatingLayer';\r\nimport { bindTouchPressedState } from '../interactionState';\r\nimport {\r\n getPayloadPanelCurrentValues,\r\n resolveMenuSchemaForDom\r\n} from '../menuRuntime';\r\nimport {\r\n focusFirstToolbarGroupMenuItem,\r\n handleToolbarGroupMenuKeyDown\r\n} from './groupMenuKeyboard';\r\nimport {\r\n findToolbarGroupMenuItem,\r\n renderToolbar,\r\n renderToolbarGroupMenu,\r\n syncToolbarGroupButtonState,\r\n toolbarExecutableButtonSelector,\r\n toolbarGroupButtonSelector\r\n} from './render';\r\nimport type {\r\n RichTextToolbarAPI,\r\n ToolbarGroupMenuState,\r\n RichTextToolbarOptions,\r\n ToolbarDragState\r\n} from './type';\r\n\r\nconst toolbarDragClickThresholdPx = 4;\nconst toolbarTooltipOffsetPx = 8;\nconst toolbarGroupMenuOffsetPx = 6;\nconst toolbarTouchStartOptions = {\n capture: true,\n passive: false\n} as const;\n\r\nexport type * from './type';\r\n\r\nconst canUseHoverTooltip = () => (\r\n typeof window !== 'undefined'\r\n && window.matchMedia?.('(hover: hover) and (pointer: fine)').matches === true\r\n);\r\n\r\nconst getToolbarButtonFromTarget = (target: EventTarget | null) => {\r\n /*\r\n * 图标覆盖常用 SVG,H5 pointer 事件可能落在 svg/path 上。\r\n * 这里用 Element 而不是 HTMLElement,保证触屏兜底和 click 都能向上命中真实按钮。\r\n */\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarExecutableButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\nconst getToolbarGroupButtonFromTarget = (target: EventTarget | null) => {\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\n/**\r\n * 创建独立菜单实例。\r\n *\r\n * toolbar/tabbar 只订阅 EditorAPI 状态并派发命令,不接触编辑器内部 DOM 或 Lexical 实例。\r\n */\r\nexport function createRichTextToolbar(\r\n container: HTMLElement,\r\n options: RichTextToolbarOptions\r\n): RichTextToolbarAPI {\r\n const placement = options.placement ?? 'top';\r\n const menuSchema = resolveMenuSchemaForDom(options.menuSchema ?? defaultMenuSchema, {\r\n menuLabels: options.menuLabels,\r\n payloadPanelConfig: options.payloadPanelConfig\r\n });\r\n const toolbarItems = resolveToolbarMenu(options.toolbarConfig, menuSchema);\r\n /*\r\n * click 事件只需要能执行命令的菜单项。分割线和 group 容器是渲染结构,\r\n * 先在这里摊平,后续点击时就不用理解 toolbarConfig 的展示层级。\r\n */\r\n const executableMenuItems = toolbarItems.flatMap((toolbarItem) => (\r\n toolbarItem.type === 'button' ? [toolbarItem.item]\r\n : toolbarItem.type === 'group' ? toolbarItem.items\r\n : []\r\n ));\r\n const icons = options.icons ?? {};\r\n /*\r\n * tooltip 只属于 PC 精细指针体验。H5 上即使没有原生 title,部分浏览器也会把 hover/mouseover\r\n * 模拟成首触摸状态,导致第一次点像是只唤醒提示;所以触屏端不写 tooltip 数据也不挂监听。\r\n */\r\n const enableTooltip = canUseHoverTooltip();\r\n const tooltipElement = document.createElement('div');\r\n const groupMenuElement = document.createElement('div');\r\n const overlayHost = container.closest('.bridgerte') ?? container;\r\n let destroyed = false;\r\n let dragState: ToolbarDragState | null = null;\r\n let shouldSuppressNextClick = false;\r\n let latestCommandStates = options.editor.getCommandStates();\r\n let groupMenuState: ToolbarGroupMenuState | null = null;\r\n let groupMenuFloatingLayer: RichTextFloatingLayer | null = null;\r\n const clearToolbarPressedState = bindTouchPressedState(container, {\r\n targetSelector: [\r\n 'button[data-bridgerte-toolbar-item-id]',\r\n 'button[data-bridgerte-toolbar-group-id]'\r\n ].join(',')\r\n });\r\n const clearGroupMenuPressedState = bindTouchPressedState(groupMenuElement, {\r\n targetSelector: '.bridgerte__toolbar-group-menu-item'\r\n });\r\n\r\n const mountToolbarOverlays = () => {\r\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\r\n overlayHost.append(tooltipElement);\r\n overlayHost.append(groupMenuElement);\r\n };\r\n\r\n const closeGroupMenuFloatingLayer = () => {\r\n groupMenuFloatingLayer?.setOpen(false);\r\n groupMenuFloatingLayer?.destroy();\r\n groupMenuFloatingLayer = null;\r\n };\r\n\r\n const openGroupMenuFloatingLayer = () => {\r\n if (!groupMenuState) return;\r\n\r\n closeGroupMenuFloatingLayer();\r\n /*\r\n * group menu 和 hoverbar/mention/slash 一样属于轻浮层,必须走 floatingLayer。\r\n * 这里按 toolbar placement 给出首选方向,真正的翻转、键盘可视区和左右夹紧交给\r\n * createFloatingLayer 内部的 visualViewport + flip + shift + clamp 统一处理。\r\n */\r\n groupMenuFloatingLayer = createFloatingLayer(groupMenuState.button, groupMenuElement, {\r\n placement: placement === 'bottom' ? 'top-start' : 'bottom-start',\r\n offset: toolbarGroupMenuOffsetPx,\r\n strategy: 'fixed'\r\n });\r\n groupMenuFloatingLayer.setOpen(true);\r\n };\r\n\r\n const closeGroupMenu = () => {\r\n closeGroupMenuFloatingLayer();\r\n groupMenuState = null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n };\r\n\r\n const renderStates = (states: CommandState[]) => {\r\n if (destroyed) return;\r\n\r\n latestCommandStates = states;\r\n if (groupMenuState) closeGroupMenuFloatingLayer();\r\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\r\n mountToolbarOverlays();\r\n if (groupMenuState) {\r\n const nextButton = Array.from(\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n ).find((button) => button.dataset.bridgerteToolbarGroupId === groupMenuState?.groupKey);\r\n const nextGroupItem = findToolbarGroupMenuItem(toolbarItems, groupMenuState.groupKey);\r\n\r\n groupMenuState = nextButton && nextGroupItem\r\n ? {\r\n groupKey: groupMenuState.groupKey,\r\n button: nextButton,\r\n items: nextGroupItem.items\r\n }\r\n : null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n if (groupMenuState) openGroupMenuFloatingLayer();\r\n }\r\n };\r\n\r\n const update = () => {\r\n if (destroyed) return;\r\n\r\n renderStates(options.editor.getCommandStates());\r\n };\r\n\r\n const hideTooltip = () => {\r\n tooltipElement.dataset.visible = 'false';\r\n tooltipElement.textContent = '';\r\n };\r\n\r\n const showTooltip = (button: HTMLButtonElement) => {\r\n const tooltipText = button.dataset.tooltip;\r\n\r\n if (!enableTooltip || !tooltipText || dragState) return;\r\n\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n tooltipElement.textContent = tooltipText;\r\n tooltipElement.dataset.visible = 'true';\r\n tooltipElement.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\r\n tooltipElement.style.top = `${buttonRect.top - toolbarTooltipOffsetPx}px`;\r\n };\r\n\r\n const handleTooltipTarget = (event: Event) => {\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (button) {\r\n showTooltip(button);\r\n }\r\n };\r\n\r\n const handleTooltipLeave = (event: MouseEvent) => {\r\n const relatedTarget = event.relatedTarget;\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (\r\n button\r\n && relatedTarget instanceof Node\r\n && button.contains(relatedTarget)\r\n ) return;\r\n\r\n hideTooltip();\r\n };\r\n\r\n const stopToolbarDrag = () => {\r\n dragState = null;\r\n\r\n delete container.dataset.dragging;\r\n // 拖动过程中监听挂在 document 上,松手或 destroy 必须统一清掉,避免离开 toolbar 后残留滚动状态。\r\n document.removeEventListener('pointermove', handlePointerMove);\r\n document.removeEventListener('pointerup', handlePointerUp);\r\n document.removeEventListener('pointercancel', handlePointerUp);\r\n };\r\n\r\n const handlePointerMove = (event: PointerEvent) => {\r\n if (!dragState) return;\r\n\r\n const deltaX = dragState.startClientX - event.clientX;\r\n\r\n if (Math.abs(deltaX) > toolbarDragClickThresholdPx) {\r\n dragState.hasDragged = true;\r\n shouldSuppressNextClick = true;\r\n hideTooltip();\r\n closeGroupMenu();\r\n }\r\n\r\n container.scrollLeft = dragState.startScrollLeft + deltaX;\r\n };\r\n\r\n const handlePointerUp = (event: PointerEvent) => {\r\n const currentDragState = dragState;\r\n\r\n stopToolbarDrag();\r\n if (\r\n currentDragState\r\n && event.type !== 'pointercancel'\r\n && currentDragState.pointerType !== 'mouse'\r\n && !currentDragState.hasDragged\r\n && currentDragState.startButton\r\n ) {\r\n executeToolbarButton(currentDragState.startButton);\r\n shouldSuppressNextClick = true;\r\n }\r\n };\r\n\r\n const handlePointerDown = (event: PointerEvent) => {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n\n const startButton = getToolbarButtonFromTarget(event.target);\n\r\n // 点击和拖动 toolbar 都要保留编辑区 selection,命令才能继续作用在原选区。\r\n event.preventDefault();\r\n dragState = {\r\n startClientX: event.clientX,\r\n startScrollLeft: container.scrollLeft,\r\n pointerType: event.pointerType,\r\n hasDragged: false,\r\n startButton: startButton ?? undefined\r\n };\r\n container.dataset.dragging = 'true';\r\n hideTooltip();\r\n // pointermove 放到 document,保证用户按住 X 轴拖出 toolbar 后仍能完成滚动和释放。\r\n document.addEventListener('pointermove', handlePointerMove);\r\n document.addEventListener('pointerup', handlePointerUp);\r\n document.addEventListener('pointercancel', handlePointerUp);\n };\n\n const handleTouchStart = (event: TouchEvent) => {\n /*\n * H5/WebView 里触摸 contenteditable 外部按钮可能先触发编辑器 blur,\n * 导致软键盘收起、底部 toolbar 消失。touchstart 必须用非 passive capture\n * 兜底拦截默认失焦;实际横向滚动仍交给 pointermove 手动更新 scrollLeft。\n */\n if (event.defaultPrevented) return;\n\n if (event.cancelable) event.preventDefault();\n };\n\n const executeToolbarButton = (button: HTMLButtonElement) => {\n if (!(button instanceof HTMLButtonElement) || button.disabled) return;\n\r\n const menuItem = executableMenuItems.find((item) => (\r\n item.id === button.dataset.bridgerteToolbarItemId\r\n ));\r\n\r\n if (!menuItem) return;\r\n\r\n if (menuItem.payloadPanel) {\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n /*\r\n * 带 payloadPanel 的菜单不直接执行基础 command,而是发起参数请求。\r\n * DOM 内置面板和业务/RN/Flutter 自绘都走同一个 request,避免后续颜色、\r\n * 字体、链接等参数菜单各自发明一套协议。\r\n */\r\n options.editor.requestPayloadPanel({\r\n menuId: menuItem.id,\r\n command: menuItem.command,\r\n panel: menuItem.payloadPanel,\r\n currentValues: getPayloadPanelCurrentValues(menuItem, options.editor.getCommandStates()),\r\n anchorRect: {\r\n x: buttonRect.left,\r\n y: buttonRect.top,\r\n width: buttonRect.width,\r\n height: buttonRect.height\r\n }\r\n });\r\n return;\r\n }\r\n\r\n options.editor.executeCommand(menuItem.command);\r\n };\r\n\r\n const toggleGroupMenu = (button: HTMLButtonElement) => {\r\n const groupItem = findToolbarGroupMenuItem(\r\n toolbarItems,\r\n button.dataset.bridgerteToolbarGroupId\r\n );\r\n\r\n if (!groupItem || button.disabled) return;\r\n\r\n if (groupMenuState?.groupKey === groupItem.key) {\r\n closeGroupMenu();\r\n return;\r\n }\r\n\r\n groupMenuState = {\r\n groupKey: groupItem.key,\r\n button,\r\n items: groupItem.items\r\n };\r\n hideTooltip();\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n openGroupMenuFloatingLayer();\r\n focusFirstToolbarGroupMenuItem(groupMenuElement);\r\n };\r\n\r\n const handleClick = (event: MouseEvent) => {\r\n if (shouldSuppressNextClick) {\r\n shouldSuppressNextClick = false;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n const groupButton = getToolbarGroupButtonFromTarget(event.target);\r\n if (groupButton) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n toggleGroupMenu(groupButton);\r\n return;\r\n }\r\n\r\n const button = getToolbarButtonFromTarget(event.target);\r\n if (!button) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n executeToolbarButton(button);\r\n closeGroupMenu();\r\n };\r\n\r\n const handleGroupMenuPointerDown = (event: PointerEvent) => {\r\n /*\r\n * group 菜单浮层挂在 toolbar 容器外,不能复用容器级 pointerdown。\r\n * 子菜单点击仍要保留编辑区 selection,否则格式命令会丢失原选区。\r\n */\r\n if (event.pointerType === 'mouse' && event.button !== 0) return;\r\n\r\n event.preventDefault();\r\n };\r\n\r\n const handleDocumentClick = (event: MouseEvent) => {\r\n const target = event.target;\r\n\r\n if (\r\n target instanceof Node\r\n && (container.contains(target) || groupMenuElement.contains(target))\r\n ) return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (groupMenuState && groupMenuElement.contains(document.activeElement)) {\r\n handleToolbarGroupMenuKeyDown(\r\n event,\r\n groupMenuElement,\r\n groupMenuState.button,\r\n executeToolbarButton,\r\n closeGroupMenu\r\n );\r\n return;\r\n }\r\n\r\n if (event.key !== 'Escape') return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n container.classList.add('bridgerte__toolbar');\r\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\r\n tooltipElement.dataset.visible = 'false';\r\n groupMenuElement.className = 'bridgerte__floating-menu bridgerte__toolbar-group-menu';\n groupMenuElement.dataset.visible = 'false';\r\n groupMenuElement.setAttribute('role', 'menu');\r\n container.dataset.placement = placement;\r\n container.setAttribute('role', 'toolbar');\r\n container.setAttribute(\r\n 'aria-label',\r\n placement === 'bottom' ? 'BridgeRTE tabbar' : 'BridgeRTE toolbar'\r\n );\r\n container.addEventListener('pointerdown', handlePointerDown, true);\n container.addEventListener('touchstart', handleTouchStart, toolbarTouchStartOptions);\n container.addEventListener('click', handleClick);\n groupMenuElement.addEventListener('pointerdown', handleGroupMenuPointerDown, true);\n groupMenuElement.addEventListener('touchstart', handleTouchStart, toolbarTouchStartOptions);\n groupMenuElement.addEventListener('click', handleClick);\n document.addEventListener('click', handleDocumentClick);\n document.addEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.addEventListener('mouseover', handleTooltipTarget);\r\n container.addEventListener('mouseout', handleTooltipLeave);\r\n }\r\n container.addEventListener('focusout', hideTooltip);\r\n // 浮层挂在最近的编辑器根容器下,既能继承变量,也不会操作编辑内容 DOM。\r\n mountToolbarOverlays();\r\n\r\n // 独立 toolbar 只订阅 public API 状态,不依赖 DOM 编辑器内部实现。\r\n const unsubscribe = options.editor.subscribeCommandStateChange(renderStates);\r\n\r\n return {\r\n update,\r\n destroy() {\r\n if (destroyed) return;\r\n\r\n destroyed = true;\r\n stopToolbarDrag();\r\n unsubscribe();\n closeGroupMenu();\n container.removeEventListener('pointerdown', handlePointerDown, true);\n container.removeEventListener('touchstart', handleTouchStart, toolbarTouchStartOptions);\n container.removeEventListener('click', handleClick);\n groupMenuElement.removeEventListener('pointerdown', handleGroupMenuPointerDown, true);\n groupMenuElement.removeEventListener(\n 'touchstart',\n handleTouchStart,\n toolbarTouchStartOptions\n );\n groupMenuElement.removeEventListener('click', handleClick);\n document.removeEventListener('click', handleDocumentClick);\n document.removeEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.removeEventListener('mouseover', handleTooltipTarget);\r\n container.removeEventListener('mouseout', handleTooltipLeave);\r\n }\r\n clearToolbarPressedState();\r\n clearGroupMenuPressedState();\r\n container.removeEventListener('focusout', hideTooltip);\r\n tooltipElement.remove();\r\n groupMenuElement.remove();\r\n container.classList.remove('bridgerte__toolbar');\r\n delete container.dataset.placement;\r\n container.textContent = '';\r\n container.removeAttribute('role');\r\n container.removeAttribute('aria-label');\r\n }\r\n };\r\n}\r\n","const invisibleTextPattern = /[\\u200B-\\u200D\\uFEFF]/g;\n\n/*\n * HTML 片段里这些元素没有 textContent 也应算有效内容。\n * 纯排版容器不放进来,避免 `<p><br></p>`、空列表项这类编辑器占位被误判为非空。\n */\nconst meaningfulHtmlContentSelector = [\n 'img',\n 'video',\n 'audio',\n 'iframe',\n 'table',\n 'pre',\n 'code',\n 'hr',\n 'figure',\n 'canvas',\n 'svg',\n 'math',\n '[data-type=\"mention\"]'\n].join(',');\n\nconst normalizeHtmlText = (text: string | null | undefined): string => (\n text?.replace(invisibleTextPattern, '').trim() ?? ''\n);\n\n/**\n * 判断一段 HTML 片段是否包含可保存的富文本内容。\n *\n * 这个工具会使用浏览器 template 解析 HTML,适合只拿到 HTML 字符串的业务表单;如果已经持有\n * `EditorContent`,优先使用 core 的 `isEditorContentEmpty()`,避免额外 DOM parse。\n */\nexport const hasMeaningfulHtmlContent = (html: string): boolean => {\n if (!normalizeHtmlText(html)) return false;\n\n const template = document.createElement('template');\n\n template.innerHTML = html;\n\n return Boolean(\n normalizeHtmlText(template.content.textContent)\n || template.content.querySelector(meaningfulHtmlContentSelector)\n );\n};\n"],"names":["defaultMenuUiIcons","getEnabledGroupMenuButtons","menuElement","button","focusToolbarGroupMenuItem","index","nextButton","focusFirstToolbarGroupMenuItem","handleToolbarGroupMenuKeyDown","event","returnButton","executeToolbarButton","closeGroupMenu","buttons","activeIndex","focusByOffset","offset","nextIndex","_a","_b","toolbarGroupButtonSelector","toolbarButtonSelector","toolbarExecutableButtonSelector","getGroupMenuState","items","commandStates","itemStates","item","getMenuStateForItem","state","renderToolbarButton","groupElement","icons","enableTooltip","iconSvg","defaultMenuIcons","appendMenuIcon","renderToolbarGroupButton","toolbarItem","groupState","indicator","renderToolbar","toolbarElement","toolbarItems","separatorElement","renderToolbarGroupMenu","groupMenuState","labelElement","syncToolbarGroupButtonState","container","open","findToolbarGroupMenuItem","groupKey","toolbarDragClickThresholdPx","toolbarTooltipOffsetPx","toolbarGroupMenuOffsetPx","toolbarTouchStartOptions","canUseHoverTooltip","getToolbarButtonFromTarget","target","getToolbarGroupButtonFromTarget","createRichTextToolbar","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","groupMenuElement","overlayHost","destroyed","dragState","shouldSuppressNextClick","latestCommandStates","groupMenuFloatingLayer","clearToolbarPressedState","bindTouchPressedState","clearGroupMenuPressedState","mountToolbarOverlays","closeGroupMenuFloatingLayer","openGroupMenuFloatingLayer","createFloatingLayer","renderStates","states","nextGroupItem","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","handleTooltipLeave","relatedTarget","stopToolbarDrag","handlePointerMove","handlePointerUp","deltaX","currentDragState","handlePointerDown","startButton","handleTouchStart","menuItem","getPayloadPanelCurrentValues","toggleGroupMenu","groupItem","handleClick","groupButton","handleGroupMenuPointerDown","handleDocumentClick","handleKeyDown","unsubscribe","invisibleTextPattern","meaningfulHtmlContentSelector","normalizeHtmlText","text","hasMeaningfulHtmlContent","html","template"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { defaultMenuSchema as oe, resolveToolbarMenu as re } from "./native-spec.js";
2
- import { g as C, d as D, e as A, r as ne, f as X, h as ae, c as se } from "./index-DyCMSFrm.js";
3
- const U = {
1
+ import { defaultMenuSchema as ne, resolveToolbarMenu as ae } from "./native-spec.js";
2
+ import { g as A, d as G, e as P, r as se, f as $, h as le, c as ie } from "./index-DyCMSFrm.js";
3
+ const V = {
4
4
  toolbarGroup: `
5
5
  <svg
6
6
  aria-hidden="true"
@@ -37,20 +37,20 @@ const U = {
37
37
  <path d="m6 9 6 6 6-6" />
38
38
  </svg>
39
39
  `
40
- }, W = (e) => Array.from(
40
+ }, J = (e) => Array.from(
41
41
  e.querySelectorAll(".bridgerte__toolbar-group-menu-item")
42
- ).filter((t) => !t.disabled), le = (e, t) => {
43
- const l = W(e)[t];
42
+ ).filter((t) => !t.disabled), ce = (e, t) => {
43
+ const l = J(e)[t];
44
44
  l && l.focus();
45
- }, ie = (e) => {
46
- le(e, 0);
47
- }, de = (e, t, s, l, d) => {
48
- var c, u;
49
- const n = W(t), a = document.activeElement instanceof HTMLButtonElement ? n.indexOf(document.activeElement) : -1, b = (E) => {
50
- var f;
45
+ }, de = (e) => {
46
+ ce(e, 0);
47
+ }, ue = (e, t, s, l, d) => {
48
+ var u, c;
49
+ const n = J(t), a = document.activeElement instanceof HTMLButtonElement ? n.indexOf(document.activeElement) : -1, b = (E) => {
50
+ var g;
51
51
  if (n.length === 0) return;
52
52
  const m = ((a >= 0 ? a : 0) + E + n.length) % n.length;
53
- (f = n[m]) == null || f.focus();
53
+ (g = n[m]) == null || g.focus();
54
54
  };
55
55
  switch (e.key) {
56
56
  case "ArrowDown":
@@ -60,10 +60,10 @@ const U = {
60
60
  e.preventDefault(), b(-1);
61
61
  break;
62
62
  case "Home":
63
- e.preventDefault(), (c = n[0]) == null || c.focus();
63
+ e.preventDefault(), (u = n[0]) == null || u.focus();
64
64
  break;
65
65
  case "End":
66
- e.preventDefault(), (u = n.at(-1)) == null || u.focus();
66
+ e.preventDefault(), (c = n.at(-1)) == null || c.focus();
67
67
  break;
68
68
  case "Enter":
69
69
  case " ":
@@ -73,22 +73,22 @@ const U = {
73
73
  e.preventDefault(), s.focus(), d();
74
74
  break;
75
75
  }
76
- }, G = "button[data-bridgerte-toolbar-group-id]", ce = "button[data-bridgerte-toolbar-item-id]", ue = [
77
- ce,
76
+ }, M = "button[data-bridgerte-toolbar-group-id]", pe = "button[data-bridgerte-toolbar-item-id]", be = [
77
+ pe,
78
78
  ".bridgerte__toolbar-group-menu-item"
79
- ].join(","), pe = (e, t) => {
80
- const s = e.map((l) => C(l, t));
79
+ ].join(","), me = (e, t) => {
80
+ const s = e.map((l) => A(l, t));
81
81
  return {
82
82
  active: s.some((l) => l.active),
83
83
  disabled: s.length > 0 && s.every((l) => l.disabled)
84
84
  };
85
- }, be = (e, t, s, l, d) => {
86
- const n = C(t, s), a = document.createElement("button"), b = l[t.icon] ?? D[t.icon];
87
- a.type = "button", a.className = "bridgerte__toolbar-button", a.disabled = n.disabled, a.dataset.active = String(n.active), a.dataset.bridgerteToolbarItemId = t.id, a.setAttribute("aria-label", t.label), a.setAttribute("aria-pressed", String(n.active)), d && (a.dataset.tooltip = t.label), A(a, b, t.label), e.append(a);
88
- }, me = (e, t, s, l, d) => {
89
- const n = document.createElement("button"), a = pe(t.items, s), b = t.icon ? l[t.icon] ?? D[t.icon] : U.toolbarGroup, c = document.createElement("span");
90
- n.type = "button", n.className = "bridgerte__toolbar-button bridgerte__toolbar-group-button", n.disabled = a.disabled, n.dataset.active = String(a.active), n.dataset.bridgerteToolbarGroupId = t.key, n.dataset.open = "false", n.setAttribute("aria-label", t.title), n.setAttribute("aria-haspopup", "menu"), n.setAttribute("aria-expanded", "false"), n.setAttribute("aria-pressed", String(a.active)), d && (n.dataset.tooltip = t.title), A(n, b, t.title), c.className = "bridgerte__toolbar-group-indicator", c.setAttribute("aria-hidden", "true"), c.innerHTML = U.chevronDown, n.append(c), e.append(n);
85
+ }, fe = (e, t, s, l, d) => {
86
+ const n = A(t, s), a = document.createElement("button"), b = l[t.icon] ?? G[t.icon];
87
+ a.type = "button", a.className = "bridgerte__toolbar-button", a.disabled = n.disabled, a.dataset.active = String(n.active), a.dataset.bridgerteToolbarItemId = t.id, a.setAttribute("aria-label", t.label), a.setAttribute("aria-pressed", String(n.active)), d && (a.dataset.tooltip = t.label), P(a, b, t.label), e.append(a);
91
88
  }, ge = (e, t, s, l, d) => {
89
+ const n = document.createElement("button"), a = me(t.items, s), b = t.icon ? l[t.icon] ?? G[t.icon] : V.toolbarGroup, u = document.createElement("span");
90
+ n.type = "button", n.className = "bridgerte__toolbar-button bridgerte__toolbar-group-button", n.disabled = a.disabled, n.dataset.active = String(a.active), n.dataset.bridgerteToolbarGroupId = t.key, n.dataset.open = "false", n.setAttribute("aria-label", t.title), n.setAttribute("aria-haspopup", "menu"), n.setAttribute("aria-expanded", "false"), n.setAttribute("aria-pressed", String(a.active)), d && (n.dataset.tooltip = t.title), P(n, b, t.title), u.className = "bridgerte__toolbar-group-indicator", u.setAttribute("aria-hidden", "true"), u.innerHTML = V.chevronDown, n.append(u), e.append(n);
91
+ }, ve = (e, t, s, l, d) => {
92
92
  e.textContent = "", t.forEach((n) => {
93
93
  if (n.type === "separator") {
94
94
  const b = document.createElement("span");
@@ -96,7 +96,7 @@ const U = {
96
96
  return;
97
97
  }
98
98
  if (n.type === "button") {
99
- be(
99
+ fe(
100
100
  e,
101
101
  n.item,
102
102
  s,
@@ -106,7 +106,7 @@ const U = {
106
106
  return;
107
107
  }
108
108
  const a = document.createElement("div");
109
- a.className = "bridgerte__toolbar-group", a.dataset.group = n.key, a.setAttribute("aria-label", n.title), e.append(a), me(
109
+ a.className = "bridgerte__toolbar-group", a.dataset.group = n.key, a.setAttribute("aria-label", n.title), e.append(a), ge(
110
110
  a,
111
111
  n,
112
112
  s,
@@ -114,101 +114,106 @@ const U = {
114
114
  d
115
115
  );
116
116
  });
117
- }, _ = (e, t, s, l) => {
117
+ }, C = (e, t, s, l) => {
118
118
  if (e.textContent = "", !t) {
119
119
  e.dataset.visible = "false";
120
120
  return;
121
121
  }
122
122
  t.items.forEach((d) => {
123
- const n = C(d, s), a = document.createElement("button"), b = l[d.icon] ?? D[d.icon], c = document.createElement("span");
124
- a.type = "button", a.className = "bridgerte__menu-item bridgerte__toolbar-group-menu-item", a.disabled = n.disabled, a.dataset.active = String(n.active), a.dataset.bridgerteToolbarItemId = d.id, a.setAttribute("role", "menuitem"), a.setAttribute("aria-label", d.label), a.setAttribute("aria-pressed", String(n.active)), A(a, b, d.label), c.className = "bridgerte__toolbar-group-menu-label", c.textContent = d.label, a.append(c), e.append(a);
123
+ const n = A(d, s), a = document.createElement("button"), b = l[d.icon] ?? G[d.icon], u = document.createElement("span");
124
+ a.type = "button", a.className = "bridgerte__menu-item bridgerte__toolbar-group-menu-item", a.disabled = n.disabled, a.dataset.active = String(n.active), a.dataset.bridgerteToolbarItemId = d.id, a.setAttribute("role", "menuitem"), a.setAttribute("aria-label", d.label), a.setAttribute("aria-pressed", String(n.active)), P(a, b, d.label), u.className = "bridgerte__toolbar-group-menu-label", u.textContent = d.label, a.append(u), e.append(a);
125
125
  }), e.dataset.visible = "true", e.style.minWidth = `${t.button.offsetWidth}px`;
126
- }, B = (e, t) => {
127
- e.querySelectorAll(G).forEach((s) => {
126
+ }, D = (e, t) => {
127
+ e.querySelectorAll(M).forEach((s) => {
128
128
  const l = (t == null ? void 0 : t.groupKey) === s.dataset.bridgerteToolbarGroupId;
129
129
  s.dataset.open = String(l), s.setAttribute("aria-expanded", String(l));
130
130
  });
131
- }, $ = (e, t) => e.find((s) => s.type === "group" && s.key === t), fe = 4, ve = 8, he = 6, ye = () => {
131
+ }, W = (e, t) => e.find((s) => s.type === "group" && s.key === t), he = 4, ye = 8, Ee = 6, S = {
132
+ capture: !0,
133
+ passive: !1
134
+ }, Te = () => {
132
135
  var e;
133
136
  return typeof window < "u" && ((e = window.matchMedia) == null ? void 0 : e.call(window, "(hover: hover) and (pointer: fine)").matches) === !0;
134
- }, x = (e) => {
135
- const t = e instanceof Element ? e.closest(ue) : null;
137
+ }, k = (e) => {
138
+ const t = e instanceof Element ? e.closest(be) : null;
136
139
  return t instanceof HTMLButtonElement ? t : null;
137
- }, Ee = (e) => {
138
- const t = e instanceof Element ? e.closest(G) : null;
140
+ }, Le = (e) => {
141
+ const t = e instanceof Element ? e.closest(M) : null;
139
142
  return t instanceof HTMLButtonElement ? t : null;
140
143
  };
141
- function ke(e, t) {
142
- const s = t.placement ?? "top", l = ne(t.menuSchema ?? oe, {
144
+ function _e(e, t) {
145
+ const s = t.placement ?? "top", l = se(t.menuSchema ?? ne, {
143
146
  menuLabels: t.menuLabels,
144
147
  payloadPanelConfig: t.payloadPanelConfig
145
- }), d = re(t.toolbarConfig, l), n = d.flatMap((o) => o.type === "button" ? [o.item] : o.type === "group" ? o.items : []), a = t.icons ?? {}, b = ye(), c = document.createElement("div"), u = document.createElement("div"), E = e.closest(".bridgerte") ?? e;
146
- let y = !1, m = null, f = !1, T = t.editor.getCommandStates(), i = null, g = null;
147
- const z = X(e, {
148
+ }), d = ae(t.toolbarConfig, l), n = d.flatMap((o) => o.type === "button" ? [o.item] : o.type === "group" ? o.items : []), a = t.icons ?? {}, b = Te(), u = document.createElement("div"), c = document.createElement("div"), E = e.closest(".bridgerte") ?? e;
149
+ let y = !1, m = null, g = !1, T = t.editor.getCommandStates(), i = null, f = null;
150
+ const Q = $(e, {
148
151
  targetSelector: [
149
152
  "button[data-bridgerte-toolbar-item-id]",
150
153
  "button[data-bridgerte-toolbar-group-id]"
151
154
  ].join(",")
152
- }), J = X(u, {
155
+ }), Y = $(c, {
153
156
  targetSelector: ".bridgerte__toolbar-group-menu-item"
154
- }), M = () => {
155
- E.append(c), E.append(u);
156
- }, k = () => {
157
- g == null || g.setOpen(!1), g == null || g.destroy(), g = null;
158
- }, P = () => {
159
- i && (k(), g = se(i.button, u, {
157
+ }), H = () => {
158
+ E.append(u), E.append(c);
159
+ }, _ = () => {
160
+ f == null || f.setOpen(!1), f == null || f.destroy(), f = null;
161
+ }, I = () => {
162
+ i && (_(), f = ie(i.button, c, {
160
163
  placement: s === "bottom" ? "top-start" : "bottom-start",
161
- offset: he,
164
+ offset: Ee,
162
165
  strategy: "fixed"
163
- }), g.setOpen(!0));
166
+ }), f.setOpen(!0));
164
167
  }, v = () => {
165
- k(), i = null, _(u, i, T, a), B(e, i);
166
- }, H = (o) => {
167
- if (!y && (T = o, i && k(), ge(e, d, o, a, b), M(), i)) {
168
+ _(), i = null, C(c, i, T, a), D(e, i);
169
+ }, N = (o) => {
170
+ if (!y && (T = o, i && _(), ve(e, d, o, a, b), H(), i)) {
168
171
  const r = Array.from(
169
- e.querySelectorAll(G)
170
- ).find((te) => te.dataset.bridgerteToolbarGroupId === (i == null ? void 0 : i.groupKey)), p = $(d, i.groupKey);
172
+ e.querySelectorAll(M)
173
+ ).find((re) => re.dataset.bridgerteToolbarGroupId === (i == null ? void 0 : i.groupKey)), p = W(d, i.groupKey);
171
174
  i = r && p ? {
172
175
  groupKey: i.groupKey,
173
176
  button: r,
174
177
  items: p.items
175
- } : null, _(u, i, T, a), B(e, i), i && P();
178
+ } : null, C(c, i, T, a), D(e, i), i && I();
176
179
  }
177
- }, Q = () => {
178
- y || H(t.editor.getCommandStates());
180
+ }, Z = () => {
181
+ y || N(t.editor.getCommandStates());
179
182
  }, h = () => {
180
- c.dataset.visible = "false", c.textContent = "";
181
- }, Y = (o) => {
183
+ u.dataset.visible = "false", u.textContent = "";
184
+ }, ee = (o) => {
182
185
  const r = o.dataset.tooltip;
183
186
  if (!b || !r || m) return;
184
187
  const p = o.getBoundingClientRect();
185
- c.textContent = r, c.dataset.visible = "true", c.style.left = `${p.left + p.width / 2}px`, c.style.top = `${p.top - ve}px`;
186
- }, I = (o) => {
187
- const r = x(o.target);
188
- r && Y(r);
189
- }, N = (o) => {
190
- const r = o.relatedTarget, p = x(o.target);
191
- p && r instanceof Node && p.contains(r) || h();
192
- }, K = () => {
193
- m = null, delete e.dataset.dragging, document.removeEventListener("pointermove", F), document.removeEventListener("pointerup", L), document.removeEventListener("pointercancel", L);
188
+ u.textContent = r, u.dataset.visible = "true", u.style.left = `${p.left + p.width / 2}px`, u.style.top = `${p.top - ye}px`;
189
+ }, K = (o) => {
190
+ const r = k(o.target);
191
+ r && ee(r);
194
192
  }, F = (o) => {
193
+ const r = o.relatedTarget, p = k(o.target);
194
+ p && r instanceof Node && p.contains(r) || h();
195
+ }, O = () => {
196
+ m = null, delete e.dataset.dragging, document.removeEventListener("pointermove", R), document.removeEventListener("pointerup", L), document.removeEventListener("pointercancel", L);
197
+ }, R = (o) => {
195
198
  if (!m) return;
196
199
  const r = m.startClientX - o.clientX;
197
- Math.abs(r) > fe && (m.hasDragged = !0, f = !0, h(), v()), e.scrollLeft = m.startScrollLeft + r;
200
+ Math.abs(r) > he && (m.hasDragged = !0, g = !0, h(), v()), e.scrollLeft = m.startScrollLeft + r;
198
201
  }, L = (o) => {
199
202
  const r = m;
200
- K(), r && o.type !== "pointercancel" && r.pointerType !== "mouse" && !r.hasDragged && r.startButton && (S(r.startButton), f = !0);
201
- }, R = (o) => {
203
+ O(), r && o.type !== "pointercancel" && r.pointerType !== "mouse" && !r.hasDragged && r.startButton && (B(r.startButton), g = !0);
204
+ }, j = (o) => {
202
205
  if (o.pointerType === "mouse" && o.button !== 0) return;
203
- const r = x(o.target);
206
+ const r = k(o.target);
204
207
  o.preventDefault(), m = {
205
208
  startClientX: o.clientX,
206
209
  startScrollLeft: e.scrollLeft,
207
210
  pointerType: o.pointerType,
208
211
  hasDragged: !1,
209
212
  startButton: r ?? void 0
210
- }, e.dataset.dragging = "true", h(), document.addEventListener("pointermove", F), document.addEventListener("pointerup", L), document.addEventListener("pointercancel", L);
211
- }, S = (o) => {
213
+ }, e.dataset.dragging = "true", h(), document.addEventListener("pointermove", R), document.addEventListener("pointerup", L), document.addEventListener("pointercancel", L);
214
+ }, w = (o) => {
215
+ o.defaultPrevented || o.cancelable && o.preventDefault();
216
+ }, B = (o) => {
212
217
  if (!(o instanceof HTMLButtonElement) || o.disabled) return;
213
218
  const r = n.find((p) => p.id === o.dataset.bridgerteToolbarItemId);
214
219
  if (r) {
@@ -218,7 +223,7 @@ function ke(e, t) {
218
223
  menuId: r.id,
219
224
  command: r.command,
220
225
  panel: r.payloadPanel,
221
- currentValues: ae(r, t.editor.getCommandStates()),
226
+ currentValues: le(r, t.editor.getCommandStates()),
222
227
  anchorRect: {
223
228
  x: p.left,
224
229
  y: p.top,
@@ -230,8 +235,8 @@ function ke(e, t) {
230
235
  }
231
236
  t.editor.executeCommand(r.command);
232
237
  }
233
- }, Z = (o) => {
234
- const r = $(
238
+ }, te = (o) => {
239
+ const r = W(
235
240
  d,
236
241
  o.dataset.bridgerteToolbarGroupId
237
242
  );
@@ -244,51 +249,55 @@ function ke(e, t) {
244
249
  groupKey: r.key,
245
250
  button: o,
246
251
  items: r.items
247
- }, h(), _(u, i, T, a), B(e, i), P(), ie(u);
252
+ }, h(), C(c, i, T, a), D(e, i), I(), de(c);
248
253
  }
249
- }, w = (o) => {
250
- if (f) {
251
- f = !1, o.preventDefault(), o.stopPropagation();
254
+ }, x = (o) => {
255
+ if (g) {
256
+ g = !1, o.preventDefault(), o.stopPropagation();
252
257
  return;
253
258
  }
254
- const r = Ee(o.target);
259
+ const r = Le(o.target);
255
260
  if (r) {
256
- o.preventDefault(), o.stopPropagation(), Z(r);
261
+ o.preventDefault(), o.stopPropagation(), te(r);
257
262
  return;
258
263
  }
259
- const p = x(o.target);
260
- p && (o.preventDefault(), o.stopPropagation(), S(p), v());
261
- }, O = (o) => {
264
+ const p = k(o.target);
265
+ p && (o.preventDefault(), o.stopPropagation(), B(p), v());
266
+ }, q = (o) => {
262
267
  o.pointerType === "mouse" && o.button !== 0 || o.preventDefault();
263
- }, j = (o) => {
268
+ }, X = (o) => {
264
269
  const r = o.target;
265
- r instanceof Node && (e.contains(r) || u.contains(r)) || v();
266
- }, q = (o) => {
267
- if (i && u.contains(document.activeElement)) {
268
- de(
270
+ r instanceof Node && (e.contains(r) || c.contains(r)) || v();
271
+ }, U = (o) => {
272
+ if (i && c.contains(document.activeElement)) {
273
+ ue(
269
274
  o,
270
- u,
275
+ c,
271
276
  i.button,
272
- S,
277
+ B,
273
278
  v
274
279
  );
275
280
  return;
276
281
  }
277
282
  o.key === "Escape" && v();
278
283
  };
279
- e.classList.add("bridgerte__toolbar"), c.className = "bridgerte__toolbar-tooltip", c.dataset.visible = "false", u.className = "bridgerte__floating-menu bridgerte__toolbar-group-menu", u.dataset.visible = "false", u.setAttribute("role", "menu"), e.dataset.placement = s, e.setAttribute("role", "toolbar"), e.setAttribute(
284
+ e.classList.add("bridgerte__toolbar"), u.className = "bridgerte__toolbar-tooltip", u.dataset.visible = "false", c.className = "bridgerte__floating-menu bridgerte__toolbar-group-menu", c.dataset.visible = "false", c.setAttribute("role", "menu"), e.dataset.placement = s, e.setAttribute("role", "toolbar"), e.setAttribute(
280
285
  "aria-label",
281
286
  s === "bottom" ? "BridgeRTE tabbar" : "BridgeRTE toolbar"
282
- ), e.addEventListener("pointerdown", R, !0), e.addEventListener("click", w), u.addEventListener("pointerdown", O, !0), u.addEventListener("click", w), document.addEventListener("click", j), document.addEventListener("keydown", q), b && (e.addEventListener("mouseover", I), e.addEventListener("mouseout", N)), e.addEventListener("focusout", h), M();
283
- const ee = t.editor.subscribeCommandStateChange(H);
287
+ ), e.addEventListener("pointerdown", j, !0), e.addEventListener("touchstart", w, S), e.addEventListener("click", x), c.addEventListener("pointerdown", q, !0), c.addEventListener("touchstart", w, S), c.addEventListener("click", x), document.addEventListener("click", X), document.addEventListener("keydown", U), b && (e.addEventListener("mouseover", K), e.addEventListener("mouseout", F)), e.addEventListener("focusout", h), H();
288
+ const oe = t.editor.subscribeCommandStateChange(N);
284
289
  return {
285
- update: Q,
290
+ update: Z,
286
291
  destroy() {
287
- y || (y = !0, K(), ee(), v(), e.removeEventListener("pointerdown", R, !0), e.removeEventListener("click", w), u.removeEventListener("pointerdown", O, !0), u.removeEventListener("click", w), document.removeEventListener("click", j), document.removeEventListener("keydown", q), b && (e.removeEventListener("mouseover", I), e.removeEventListener("mouseout", N)), z(), J(), e.removeEventListener("focusout", h), c.remove(), u.remove(), e.classList.remove("bridgerte__toolbar"), delete e.dataset.placement, e.textContent = "", e.removeAttribute("role"), e.removeAttribute("aria-label"));
292
+ y || (y = !0, O(), oe(), v(), e.removeEventListener("pointerdown", j, !0), e.removeEventListener("touchstart", w, S), e.removeEventListener("click", x), c.removeEventListener("pointerdown", q, !0), c.removeEventListener(
293
+ "touchstart",
294
+ w,
295
+ S
296
+ ), c.removeEventListener("click", x), document.removeEventListener("click", X), document.removeEventListener("keydown", U), b && (e.removeEventListener("mouseover", K), e.removeEventListener("mouseout", F)), Q(), Y(), e.removeEventListener("focusout", h), u.remove(), c.remove(), e.classList.remove("bridgerte__toolbar"), delete e.dataset.placement, e.textContent = "", e.removeAttribute("role"), e.removeAttribute("aria-label"));
288
297
  }
289
298
  };
290
299
  }
291
- const Te = /[\u200B-\u200D\uFEFF]/g, Le = [
300
+ const we = /[\u200B-\u200D\uFEFF]/g, xe = [
292
301
  "img",
293
302
  "video",
294
303
  "audio",
@@ -302,13 +311,13 @@ const Te = /[\u200B-\u200D\uFEFF]/g, Le = [
302
311
  "svg",
303
312
  "math",
304
313
  '[data-type="mention"]'
305
- ].join(","), V = (e) => (e == null ? void 0 : e.replace(Te, "").trim()) ?? "", Se = (e) => {
306
- if (!V(e)) return !1;
314
+ ].join(","), z = (e) => (e == null ? void 0 : e.replace(we, "").trim()) ?? "", Be = (e) => {
315
+ if (!z(e)) return !1;
307
316
  const t = document.createElement("template");
308
- return t.innerHTML = e, !!(V(t.content.textContent) || t.content.querySelector(Le));
317
+ return t.innerHTML = e, !!(z(t.content.textContent) || t.content.querySelector(xe));
309
318
  };
310
319
  export {
311
- ke as c,
312
- Se as h
320
+ _e as c,
321
+ Be as h
313
322
  };
314
- //# sourceMappingURL=index-BWi3d-Zp.js.map
323
+ //# sourceMappingURL=index-DGPoit9-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DGPoit9-.js","sources":["../../dom/src/menuIcon/uiIcons.ts","../../dom/src/richTextToolbar/groupMenuKeyboard.ts","../../dom/src/richTextToolbar/render.ts","../../dom/src/richTextToolbar/index.ts","../../dom/src/htmlContent/index.ts"],"sourcesContent":["/**\r\n * DOM UI chrome icon 表。\r\n *\r\n * 这里放 toolbar 收纳入口、下拉箭头这类控件自身图标。它们不属于 `MenuItem.icon`\r\n * 跨端 schema,也不应该进入 `defaultMenuIcons` 的 schema 对齐检查。\r\n */\r\nexport const defaultMenuUiIcons = {\r\n toolbarGroup: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-ellipsis\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\r\n </svg>\r\n `,\r\n chevronDown: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-chevron-down\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"12\"\r\n height=\"12\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n `\r\n} as const;\r\n","export const getEnabledGroupMenuButtons = (menuElement: HTMLElement) => (\r\n Array.from(\r\n menuElement.querySelectorAll<HTMLButtonElement>('.bridgerte__toolbar-group-menu-item')\r\n ).filter((button) => !button.disabled)\r\n);\r\n\r\nexport const focusToolbarGroupMenuItem = (menuElement: HTMLElement, index: number) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const nextButton = buttons[index];\r\n\r\n if (nextButton) nextButton.focus();\r\n};\r\n\r\nexport const focusFirstToolbarGroupMenuItem = (menuElement: HTMLElement) => {\r\n /*\r\n * group menu 使用 ARIA menu 语义,打开后焦点必须进入第一个可操作项。\r\n * 这样键盘用户可以继续用方向键浏览,而不是停留在展开按钮上。\r\n */\r\n focusToolbarGroupMenuItem(menuElement, 0);\r\n};\r\n\r\nexport const handleToolbarGroupMenuKeyDown = (\r\n event: KeyboardEvent,\r\n menuElement: HTMLElement,\r\n returnButton: HTMLButtonElement,\r\n executeToolbarButton: (button: HTMLButtonElement) => void,\r\n closeGroupMenu: () => void\r\n) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const activeIndex = document.activeElement instanceof HTMLButtonElement\r\n ? buttons.indexOf(document.activeElement)\r\n : -1;\r\n const focusByOffset = (offset: number) => {\r\n if (buttons.length === 0) return;\r\n\r\n const baseIndex = activeIndex >= 0 ? activeIndex : 0;\r\n const nextIndex = (baseIndex + offset + buttons.length) % buttons.length;\r\n\r\n buttons[nextIndex]?.focus();\r\n };\r\n\r\n /*\r\n * ARIA menu 语义要求支持 roving focus。这里不改 toolbar 的横向键盘模型,\r\n * 只在已打开的纵向收纳菜单内处理上下方向、首尾跳转和执行/关闭。\r\n */\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n focusByOffset(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n focusByOffset(-1);\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n buttons[0]?.focus();\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n buttons.at(-1)?.focus();\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n if (document.activeElement instanceof HTMLButtonElement) {\r\n event.preventDefault();\r\n executeToolbarButton(document.activeElement);\r\n closeGroupMenu();\r\n returnButton.focus();\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n returnButton.focus();\r\n closeGroupMenu();\r\n break;\r\n default:\r\n break;\r\n }\r\n};\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport type { MenuItem, ResolvedToolbarItem } from '@bridgerte/native-spec';\r\nimport {\r\n appendMenuIcon,\r\n defaultMenuIcons,\r\n defaultMenuUiIcons\r\n} from './icons';\r\nimport { getMenuStateForItem } from '../menuRuntime';\r\nimport type {\r\n RichTextToolbarIcons,\r\n ToolbarGroupMenuState\r\n} from './type';\r\n\r\nexport const toolbarGroupButtonSelector = 'button[data-bridgerte-toolbar-group-id]';\r\nexport const toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\r\n// 可执行按钮同时覆盖 toolbar 主按钮和 group menu 子项,避免浮层子菜单绕过统一命令入口。\r\nexport const toolbarExecutableButtonSelector = [\n toolbarButtonSelector,\n '.bridgerte__toolbar-group-menu-item'\n].join(',');\n\r\nconst getGroupMenuState = (items: MenuItem[], commandStates: CommandState[]) => {\r\n const itemStates = items.map((item) => getMenuStateForItem(item, commandStates));\r\n\r\n return {\r\n active: itemStates.some((state) => state.active),\r\n disabled: itemStates.length > 0 && itemStates.every((state) => state.disabled)\r\n };\r\n};\r\n\r\nconst renderToolbarButton = (\r\n groupElement: HTMLElement,\r\n item: MenuItem,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n // icon 兜底顺序固定为:业务覆盖 > DOM 默认 SVG > label 文本。\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button';\r\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n if (enableTooltip) button.dataset.tooltip = item.label;\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n\r\n groupElement.append(button);\r\n};\r\n\r\nconst renderToolbarGroupButton = (\r\n groupElement: HTMLElement,\r\n toolbarItem: Extract<ResolvedToolbarItem, { type: 'group' }>,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const button = document.createElement('button');\r\n const groupState = getGroupMenuState(toolbarItem.items, commandStates);\r\n const iconSvg = toolbarItem.icon\r\n ? icons[toolbarItem.icon] ?? defaultMenuIcons[toolbarItem.icon]\r\n : defaultMenuUiIcons.toolbarGroup;\r\n const indicator = document.createElement('span');\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button bridgerte__toolbar-group-button';\r\n button.disabled = groupState.disabled;\r\n button.dataset.active = String(groupState.active);\r\n button.dataset.bridgerteToolbarGroupId = toolbarItem.key;\r\n button.dataset.open = 'false';\r\n button.setAttribute('aria-label', toolbarItem.title);\r\n button.setAttribute('aria-haspopup', 'menu');\r\n button.setAttribute('aria-expanded', 'false');\r\n button.setAttribute('aria-pressed', String(groupState.active));\r\n if (enableTooltip) button.dataset.tooltip = toolbarItem.title;\r\n\r\n appendMenuIcon(button, iconSvg, toolbarItem.title);\r\n\r\n indicator.className = 'bridgerte__toolbar-group-indicator';\r\n indicator.setAttribute('aria-hidden', 'true');\r\n indicator.innerHTML = defaultMenuUiIcons.chevronDown;\r\n button.append(indicator);\r\n groupElement.append(button);\r\n};\r\n\r\n/**\r\n * 渲染 toolbar 横向主入口。\n *\n * 字符串菜单直接渲染为按钮,`|` 渲染分割线。\n * 只有用户显式声明的 group 配置才生成收纳入口,避免 schema 隐式改变 DOM 结构。\n */\r\nexport const renderToolbar = (\r\n toolbarElement: HTMLElement,\r\n toolbarItems: ResolvedToolbarItem[],\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n toolbarElement.textContent = '';\r\n\r\n toolbarItems.forEach((toolbarItem) => {\n if (toolbarItem.type === 'separator') {\n const separatorElement = document.createElement('span');\n\n separatorElement.className = 'bridgerte__toolbar-separator';\n separatorElement.dataset.separatorId = toolbarItem.key;\r\n separatorElement.setAttribute('aria-hidden', 'true');\r\n toolbarElement.append(separatorElement);\r\n return;\n }\n\n if (toolbarItem.type === 'button') {\n renderToolbarButton(\n toolbarElement,\n toolbarItem.item,\n commandStates,\n icons,\n enableTooltip\n );\n return;\n }\n\n /*\n * 收纳菜单是用户在 toolbarConfig 里显式声明的结构;普通菜单不会自动生成 DOM 包裹,\n * 显示分组完全交给用户用 group 配置或 `|` 控制。\n */\n const groupElement = document.createElement('div');\n\n groupElement.className = 'bridgerte__toolbar-group';\n groupElement.dataset.group = toolbarItem.key;\n groupElement.setAttribute('aria-label', toolbarItem.title);\n toolbarElement.append(groupElement);\n\n renderToolbarGroupButton(\n groupElement,\n toolbarItem,\n commandStates,\n icons,\n enableTooltip\r\n );\r\n });\r\n};\r\n\r\n/**\r\n * 渲染 group button 打开的纵向收纳菜单。\r\n *\r\n * 浮层只展示 MenuItem 子项并复用现有 item id,点击执行仍由 index.ts 统一走 EditorAPI。\r\n */\r\nexport const renderToolbarGroupMenu = (\r\n menuElement: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons\r\n) => {\r\n menuElement.textContent = '';\r\n\r\n if (!groupMenuState) {\r\n menuElement.dataset.visible = 'false';\r\n return;\r\n }\r\n\r\n groupMenuState.items.forEach((item) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n const labelElement = document.createElement('span');\n\n button.type = 'button';\n button.className = 'bridgerte__menu-item bridgerte__toolbar-group-menu-item';\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('role', 'menuitem');\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n labelElement.className = 'bridgerte__toolbar-group-menu-label';\r\n labelElement.textContent = item.label;\r\n button.append(labelElement);\r\n menuElement.append(button);\r\n });\r\n\r\n menuElement.dataset.visible = 'true';\r\n menuElement.style.minWidth = `${groupMenuState.button.offsetWidth}px`;\r\n};\r\n\r\nexport const syncToolbarGroupButtonState = (\r\n container: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null\r\n) => {\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector).forEach((button) => {\r\n const open = groupMenuState?.groupKey === button.dataset.bridgerteToolbarGroupId;\r\n\r\n button.dataset.open = String(open);\r\n button.setAttribute('aria-expanded', String(open));\r\n });\r\n};\r\n\r\nexport const findToolbarGroupMenuItem = (\r\n toolbarItems: ResolvedToolbarItem[],\r\n groupKey: string | undefined\r\n) => toolbarItems.find((item): item is Extract<ResolvedToolbarItem, { type: 'group' }> => (\r\n item.type === 'group' && item.key === groupKey\r\n));\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport {\r\n defaultMenuSchema,\r\n resolveToolbarMenu\r\n} from '@bridgerte/native-spec';\r\nimport { createFloatingLayer, type RichTextFloatingLayer } from '../floatingLayer';\r\nimport { bindTouchPressedState } from '../interactionState';\r\nimport {\r\n getPayloadPanelCurrentValues,\r\n resolveMenuSchemaForDom\r\n} from '../menuRuntime';\r\nimport {\r\n focusFirstToolbarGroupMenuItem,\r\n handleToolbarGroupMenuKeyDown\r\n} from './groupMenuKeyboard';\r\nimport {\r\n findToolbarGroupMenuItem,\r\n renderToolbar,\r\n renderToolbarGroupMenu,\r\n syncToolbarGroupButtonState,\r\n toolbarExecutableButtonSelector,\r\n toolbarGroupButtonSelector\r\n} from './render';\r\nimport type {\r\n RichTextToolbarAPI,\r\n ToolbarGroupMenuState,\r\n RichTextToolbarOptions,\r\n ToolbarDragState\r\n} from './type';\r\n\r\nconst toolbarDragClickThresholdPx = 4;\nconst toolbarTooltipOffsetPx = 8;\nconst toolbarGroupMenuOffsetPx = 6;\nconst toolbarTouchStartOptions = {\n capture: true,\n passive: false\n} as const;\n\r\nexport type * from './type';\r\n\r\nconst canUseHoverTooltip = () => (\r\n typeof window !== 'undefined'\r\n && window.matchMedia?.('(hover: hover) and (pointer: fine)').matches === true\r\n);\r\n\r\nconst getToolbarButtonFromTarget = (target: EventTarget | null) => {\r\n /*\r\n * 图标覆盖常用 SVG,H5 pointer 事件可能落在 svg/path 上。\r\n * 这里用 Element 而不是 HTMLElement,保证触屏兜底和 click 都能向上命中真实按钮。\r\n */\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarExecutableButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\nconst getToolbarGroupButtonFromTarget = (target: EventTarget | null) => {\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\n/**\r\n * 创建独立菜单实例。\r\n *\r\n * toolbar/tabbar 只订阅 EditorAPI 状态并派发命令,不接触编辑器内部 DOM 或 Lexical 实例。\r\n */\r\nexport function createRichTextToolbar(\r\n container: HTMLElement,\r\n options: RichTextToolbarOptions\r\n): RichTextToolbarAPI {\r\n const placement = options.placement ?? 'top';\r\n const menuSchema = resolveMenuSchemaForDom(options.menuSchema ?? defaultMenuSchema, {\r\n menuLabels: options.menuLabels,\r\n payloadPanelConfig: options.payloadPanelConfig\r\n });\r\n const toolbarItems = resolveToolbarMenu(options.toolbarConfig, menuSchema);\r\n /*\r\n * click 事件只需要能执行命令的菜单项。分割线和 group 容器是渲染结构,\r\n * 先在这里摊平,后续点击时就不用理解 toolbarConfig 的展示层级。\r\n */\r\n const executableMenuItems = toolbarItems.flatMap((toolbarItem) => (\r\n toolbarItem.type === 'button' ? [toolbarItem.item]\r\n : toolbarItem.type === 'group' ? toolbarItem.items\r\n : []\r\n ));\r\n const icons = options.icons ?? {};\r\n /*\r\n * tooltip 只属于 PC 精细指针体验。H5 上即使没有原生 title,部分浏览器也会把 hover/mouseover\r\n * 模拟成首触摸状态,导致第一次点像是只唤醒提示;所以触屏端不写 tooltip 数据也不挂监听。\r\n */\r\n const enableTooltip = canUseHoverTooltip();\r\n const tooltipElement = document.createElement('div');\r\n const groupMenuElement = document.createElement('div');\r\n const overlayHost = container.closest('.bridgerte') ?? container;\r\n let destroyed = false;\r\n let dragState: ToolbarDragState | null = null;\r\n let shouldSuppressNextClick = false;\r\n let latestCommandStates = options.editor.getCommandStates();\r\n let groupMenuState: ToolbarGroupMenuState | null = null;\r\n let groupMenuFloatingLayer: RichTextFloatingLayer | null = null;\r\n const clearToolbarPressedState = bindTouchPressedState(container, {\r\n targetSelector: [\r\n 'button[data-bridgerte-toolbar-item-id]',\r\n 'button[data-bridgerte-toolbar-group-id]'\r\n ].join(',')\r\n });\r\n const clearGroupMenuPressedState = bindTouchPressedState(groupMenuElement, {\r\n targetSelector: '.bridgerte__toolbar-group-menu-item'\r\n });\r\n\r\n const mountToolbarOverlays = () => {\r\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\r\n overlayHost.append(tooltipElement);\r\n overlayHost.append(groupMenuElement);\r\n };\r\n\r\n const closeGroupMenuFloatingLayer = () => {\r\n groupMenuFloatingLayer?.setOpen(false);\r\n groupMenuFloatingLayer?.destroy();\r\n groupMenuFloatingLayer = null;\r\n };\r\n\r\n const openGroupMenuFloatingLayer = () => {\r\n if (!groupMenuState) return;\r\n\r\n closeGroupMenuFloatingLayer();\r\n /*\r\n * group menu 和 hoverbar/mention/slash 一样属于轻浮层,必须走 floatingLayer。\r\n * 这里按 toolbar placement 给出首选方向,真正的翻转、键盘可视区和左右夹紧交给\r\n * createFloatingLayer 内部的 visualViewport + flip + shift + clamp 统一处理。\r\n */\r\n groupMenuFloatingLayer = createFloatingLayer(groupMenuState.button, groupMenuElement, {\r\n placement: placement === 'bottom' ? 'top-start' : 'bottom-start',\r\n offset: toolbarGroupMenuOffsetPx,\r\n strategy: 'fixed'\r\n });\r\n groupMenuFloatingLayer.setOpen(true);\r\n };\r\n\r\n const closeGroupMenu = () => {\r\n closeGroupMenuFloatingLayer();\r\n groupMenuState = null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n };\r\n\r\n const renderStates = (states: CommandState[]) => {\r\n if (destroyed) return;\r\n\r\n latestCommandStates = states;\r\n if (groupMenuState) closeGroupMenuFloatingLayer();\r\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\r\n mountToolbarOverlays();\r\n if (groupMenuState) {\r\n const nextButton = Array.from(\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n ).find((button) => button.dataset.bridgerteToolbarGroupId === groupMenuState?.groupKey);\r\n const nextGroupItem = findToolbarGroupMenuItem(toolbarItems, groupMenuState.groupKey);\r\n\r\n groupMenuState = nextButton && nextGroupItem\r\n ? {\r\n groupKey: groupMenuState.groupKey,\r\n button: nextButton,\r\n items: nextGroupItem.items\r\n }\r\n : null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n if (groupMenuState) openGroupMenuFloatingLayer();\r\n }\r\n };\r\n\r\n const update = () => {\r\n if (destroyed) return;\r\n\r\n renderStates(options.editor.getCommandStates());\r\n };\r\n\r\n const hideTooltip = () => {\r\n tooltipElement.dataset.visible = 'false';\r\n tooltipElement.textContent = '';\r\n };\r\n\r\n const showTooltip = (button: HTMLButtonElement) => {\r\n const tooltipText = button.dataset.tooltip;\r\n\r\n if (!enableTooltip || !tooltipText || dragState) return;\r\n\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n tooltipElement.textContent = tooltipText;\r\n tooltipElement.dataset.visible = 'true';\r\n tooltipElement.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\r\n tooltipElement.style.top = `${buttonRect.top - toolbarTooltipOffsetPx}px`;\r\n };\r\n\r\n const handleTooltipTarget = (event: Event) => {\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (button) {\r\n showTooltip(button);\r\n }\r\n };\r\n\r\n const handleTooltipLeave = (event: MouseEvent) => {\r\n const relatedTarget = event.relatedTarget;\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (\r\n button\r\n && relatedTarget instanceof Node\r\n && button.contains(relatedTarget)\r\n ) return;\r\n\r\n hideTooltip();\r\n };\r\n\r\n const stopToolbarDrag = () => {\r\n dragState = null;\r\n\r\n delete container.dataset.dragging;\r\n // 拖动过程中监听挂在 document 上,松手或 destroy 必须统一清掉,避免离开 toolbar 后残留滚动状态。\r\n document.removeEventListener('pointermove', handlePointerMove);\r\n document.removeEventListener('pointerup', handlePointerUp);\r\n document.removeEventListener('pointercancel', handlePointerUp);\r\n };\r\n\r\n const handlePointerMove = (event: PointerEvent) => {\r\n if (!dragState) return;\r\n\r\n const deltaX = dragState.startClientX - event.clientX;\r\n\r\n if (Math.abs(deltaX) > toolbarDragClickThresholdPx) {\r\n dragState.hasDragged = true;\r\n shouldSuppressNextClick = true;\r\n hideTooltip();\r\n closeGroupMenu();\r\n }\r\n\r\n container.scrollLeft = dragState.startScrollLeft + deltaX;\r\n };\r\n\r\n const handlePointerUp = (event: PointerEvent) => {\r\n const currentDragState = dragState;\r\n\r\n stopToolbarDrag();\r\n if (\r\n currentDragState\r\n && event.type !== 'pointercancel'\r\n && currentDragState.pointerType !== 'mouse'\r\n && !currentDragState.hasDragged\r\n && currentDragState.startButton\r\n ) {\r\n executeToolbarButton(currentDragState.startButton);\r\n shouldSuppressNextClick = true;\r\n }\r\n };\r\n\r\n const handlePointerDown = (event: PointerEvent) => {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n\n const startButton = getToolbarButtonFromTarget(event.target);\n\r\n // 点击和拖动 toolbar 都要保留编辑区 selection,命令才能继续作用在原选区。\r\n event.preventDefault();\r\n dragState = {\r\n startClientX: event.clientX,\r\n startScrollLeft: container.scrollLeft,\r\n pointerType: event.pointerType,\r\n hasDragged: false,\r\n startButton: startButton ?? undefined\r\n };\r\n container.dataset.dragging = 'true';\r\n hideTooltip();\r\n // pointermove 放到 document,保证用户按住 X 轴拖出 toolbar 后仍能完成滚动和释放。\r\n document.addEventListener('pointermove', handlePointerMove);\r\n document.addEventListener('pointerup', handlePointerUp);\r\n document.addEventListener('pointercancel', handlePointerUp);\n };\n\n const handleTouchStart = (event: TouchEvent) => {\n /*\n * H5/WebView 里触摸 contenteditable 外部按钮可能先触发编辑器 blur,\n * 导致软键盘收起、底部 toolbar 消失。touchstart 必须用非 passive capture\n * 兜底拦截默认失焦;实际横向滚动仍交给 pointermove 手动更新 scrollLeft。\n */\n if (event.defaultPrevented) return;\n\n if (event.cancelable) event.preventDefault();\n };\n\n const executeToolbarButton = (button: HTMLButtonElement) => {\n if (!(button instanceof HTMLButtonElement) || button.disabled) return;\n\r\n const menuItem = executableMenuItems.find((item) => (\r\n item.id === button.dataset.bridgerteToolbarItemId\r\n ));\r\n\r\n if (!menuItem) return;\r\n\r\n if (menuItem.payloadPanel) {\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n /*\r\n * 带 payloadPanel 的菜单不直接执行基础 command,而是发起参数请求。\r\n * DOM 内置面板和业务/RN/Flutter 自绘都走同一个 request,避免后续颜色、\r\n * 字体、链接等参数菜单各自发明一套协议。\r\n */\r\n options.editor.requestPayloadPanel({\r\n menuId: menuItem.id,\r\n command: menuItem.command,\r\n panel: menuItem.payloadPanel,\r\n currentValues: getPayloadPanelCurrentValues(menuItem, options.editor.getCommandStates()),\r\n anchorRect: {\r\n x: buttonRect.left,\r\n y: buttonRect.top,\r\n width: buttonRect.width,\r\n height: buttonRect.height\r\n }\r\n });\r\n return;\r\n }\r\n\r\n options.editor.executeCommand(menuItem.command);\r\n };\r\n\r\n const toggleGroupMenu = (button: HTMLButtonElement) => {\r\n const groupItem = findToolbarGroupMenuItem(\r\n toolbarItems,\r\n button.dataset.bridgerteToolbarGroupId\r\n );\r\n\r\n if (!groupItem || button.disabled) return;\r\n\r\n if (groupMenuState?.groupKey === groupItem.key) {\r\n closeGroupMenu();\r\n return;\r\n }\r\n\r\n groupMenuState = {\r\n groupKey: groupItem.key,\r\n button,\r\n items: groupItem.items\r\n };\r\n hideTooltip();\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n openGroupMenuFloatingLayer();\r\n focusFirstToolbarGroupMenuItem(groupMenuElement);\r\n };\r\n\r\n const handleClick = (event: MouseEvent) => {\r\n if (shouldSuppressNextClick) {\r\n shouldSuppressNextClick = false;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n const groupButton = getToolbarGroupButtonFromTarget(event.target);\r\n if (groupButton) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n toggleGroupMenu(groupButton);\r\n return;\r\n }\r\n\r\n const button = getToolbarButtonFromTarget(event.target);\r\n if (!button) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n executeToolbarButton(button);\r\n closeGroupMenu();\r\n };\r\n\r\n const handleGroupMenuPointerDown = (event: PointerEvent) => {\r\n /*\r\n * group 菜单浮层挂在 toolbar 容器外,不能复用容器级 pointerdown。\r\n * 子菜单点击仍要保留编辑区 selection,否则格式命令会丢失原选区。\r\n */\r\n if (event.pointerType === 'mouse' && event.button !== 0) return;\r\n\r\n event.preventDefault();\r\n };\r\n\r\n const handleDocumentClick = (event: MouseEvent) => {\r\n const target = event.target;\r\n\r\n if (\r\n target instanceof Node\r\n && (container.contains(target) || groupMenuElement.contains(target))\r\n ) return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (groupMenuState && groupMenuElement.contains(document.activeElement)) {\r\n handleToolbarGroupMenuKeyDown(\r\n event,\r\n groupMenuElement,\r\n groupMenuState.button,\r\n executeToolbarButton,\r\n closeGroupMenu\r\n );\r\n return;\r\n }\r\n\r\n if (event.key !== 'Escape') return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n container.classList.add('bridgerte__toolbar');\r\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\r\n tooltipElement.dataset.visible = 'false';\r\n groupMenuElement.className = 'bridgerte__floating-menu bridgerte__toolbar-group-menu';\n groupMenuElement.dataset.visible = 'false';\r\n groupMenuElement.setAttribute('role', 'menu');\r\n container.dataset.placement = placement;\r\n container.setAttribute('role', 'toolbar');\r\n container.setAttribute(\r\n 'aria-label',\r\n placement === 'bottom' ? 'BridgeRTE tabbar' : 'BridgeRTE toolbar'\r\n );\r\n container.addEventListener('pointerdown', handlePointerDown, true);\n container.addEventListener('touchstart', handleTouchStart, toolbarTouchStartOptions);\n container.addEventListener('click', handleClick);\n groupMenuElement.addEventListener('pointerdown', handleGroupMenuPointerDown, true);\n groupMenuElement.addEventListener('touchstart', handleTouchStart, toolbarTouchStartOptions);\n groupMenuElement.addEventListener('click', handleClick);\n document.addEventListener('click', handleDocumentClick);\n document.addEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.addEventListener('mouseover', handleTooltipTarget);\r\n container.addEventListener('mouseout', handleTooltipLeave);\r\n }\r\n container.addEventListener('focusout', hideTooltip);\r\n // 浮层挂在最近的编辑器根容器下,既能继承变量,也不会操作编辑内容 DOM。\r\n mountToolbarOverlays();\r\n\r\n // 独立 toolbar 只订阅 public API 状态,不依赖 DOM 编辑器内部实现。\r\n const unsubscribe = options.editor.subscribeCommandStateChange(renderStates);\r\n\r\n return {\r\n update,\r\n destroy() {\r\n if (destroyed) return;\r\n\r\n destroyed = true;\r\n stopToolbarDrag();\r\n unsubscribe();\n closeGroupMenu();\n container.removeEventListener('pointerdown', handlePointerDown, true);\n container.removeEventListener('touchstart', handleTouchStart, toolbarTouchStartOptions);\n container.removeEventListener('click', handleClick);\n groupMenuElement.removeEventListener('pointerdown', handleGroupMenuPointerDown, true);\n groupMenuElement.removeEventListener(\n 'touchstart',\n handleTouchStart,\n toolbarTouchStartOptions\n );\n groupMenuElement.removeEventListener('click', handleClick);\n document.removeEventListener('click', handleDocumentClick);\n document.removeEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.removeEventListener('mouseover', handleTooltipTarget);\r\n container.removeEventListener('mouseout', handleTooltipLeave);\r\n }\r\n clearToolbarPressedState();\r\n clearGroupMenuPressedState();\r\n container.removeEventListener('focusout', hideTooltip);\r\n tooltipElement.remove();\r\n groupMenuElement.remove();\r\n container.classList.remove('bridgerte__toolbar');\r\n delete container.dataset.placement;\r\n container.textContent = '';\r\n container.removeAttribute('role');\r\n container.removeAttribute('aria-label');\r\n }\r\n };\r\n}\r\n","const invisibleTextPattern = /[\\u200B-\\u200D\\uFEFF]/g;\n\n/*\n * HTML 片段里这些元素没有 textContent 也应算有效内容。\n * 纯排版容器不放进来,避免 `<p><br></p>`、空列表项这类编辑器占位被误判为非空。\n */\nconst meaningfulHtmlContentSelector = [\n 'img',\n 'video',\n 'audio',\n 'iframe',\n 'table',\n 'pre',\n 'code',\n 'hr',\n 'figure',\n 'canvas',\n 'svg',\n 'math',\n '[data-type=\"mention\"]'\n].join(',');\n\nconst normalizeHtmlText = (text: string | null | undefined): string => (\n text?.replace(invisibleTextPattern, '').trim() ?? ''\n);\n\n/**\n * 判断一段 HTML 片段是否包含可保存的富文本内容。\n *\n * 这个工具会使用浏览器 template 解析 HTML,适合只拿到 HTML 字符串的业务表单;如果已经持有\n * `EditorContent`,优先使用 core 的 `isEditorContentEmpty()`,避免额外 DOM parse。\n */\nexport const hasMeaningfulHtmlContent = (html: string): boolean => {\n if (!normalizeHtmlText(html)) return false;\n\n const template = document.createElement('template');\n\n template.innerHTML = html;\n\n return Boolean(\n normalizeHtmlText(template.content.textContent)\n || template.content.querySelector(meaningfulHtmlContentSelector)\n );\n};\n"],"names":["defaultMenuUiIcons","getEnabledGroupMenuButtons","menuElement","button","focusToolbarGroupMenuItem","index","nextButton","focusFirstToolbarGroupMenuItem","handleToolbarGroupMenuKeyDown","event","returnButton","executeToolbarButton","closeGroupMenu","buttons","activeIndex","focusByOffset","offset","nextIndex","_a","_b","toolbarGroupButtonSelector","toolbarButtonSelector","toolbarExecutableButtonSelector","getGroupMenuState","items","commandStates","itemStates","item","getMenuStateForItem","state","renderToolbarButton","groupElement","icons","enableTooltip","iconSvg","defaultMenuIcons","appendMenuIcon","renderToolbarGroupButton","toolbarItem","groupState","indicator","renderToolbar","toolbarElement","toolbarItems","separatorElement","renderToolbarGroupMenu","groupMenuState","labelElement","syncToolbarGroupButtonState","container","open","findToolbarGroupMenuItem","groupKey","toolbarDragClickThresholdPx","toolbarTooltipOffsetPx","toolbarGroupMenuOffsetPx","toolbarTouchStartOptions","canUseHoverTooltip","getToolbarButtonFromTarget","target","getToolbarGroupButtonFromTarget","createRichTextToolbar","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","groupMenuElement","overlayHost","destroyed","dragState","shouldSuppressNextClick","latestCommandStates","groupMenuFloatingLayer","clearToolbarPressedState","bindTouchPressedState","clearGroupMenuPressedState","mountToolbarOverlays","closeGroupMenuFloatingLayer","openGroupMenuFloatingLayer","createFloatingLayer","renderStates","states","nextGroupItem","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","handleTooltipLeave","relatedTarget","stopToolbarDrag","handlePointerMove","handlePointerUp","deltaX","currentDragState","handlePointerDown","startButton","handleTouchStart","menuItem","getPayloadPanelCurrentValues","toggleGroupMenu","groupItem","handleClick","groupButton","handleGroupMenuPointerDown","handleDocumentClick","handleKeyDown","unsubscribe","invisibleTextPattern","meaningfulHtmlContentSelector","normalizeHtmlText","text","hasMeaningfulHtmlContent","html","template"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./index-GaS65GL0.cjs"),a=require("./bridge.cjs"),e=require("./native-spec.cjs"),n=require("./index-B_g23O7q.cjs"),o=require("./index-H5V0EMkq.cjs"),r=require("./core.cjs"),i=require("./index-DF8OhKI4.cjs");exports.BRIDGERTE_CONTENT_VERSION=t.BRIDGERTE_CONTENT_VERSION;exports.BRIDGERTE_TABLE_INSERT_MAX_COLS=t.BRIDGERTE_TABLE_INSERT_MAX_COLS;exports.BRIDGERTE_TABLE_INSERT_MAX_ROWS=t.BRIDGERTE_TABLE_INSERT_MAX_ROWS;exports.BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS=a.BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS;exports.BRIDGE_HEIGHT_CHANGE_THROTTLE_MS=a.BRIDGE_HEIGHT_CHANGE_THROTTLE_MS;exports.defaultBridgeEventTiming=a.defaultBridgeEventTiming;exports.isBridgeMessage=a.isBridgeMessage;exports.codeBlockLanguagePanel=e.codeBlockLanguagePanel;exports.codeBlockLanguagePayloadPanel=e.codeBlockLanguagePayloadPanel;exports.createDisabledCommandStates=e.createDisabledCommandStates;exports.defaultMenuSchema=e.defaultMenuSchema;exports.defaultToolbarConfig=e.defaultToolbarConfig;exports.getCommandStateMatchValue=e.getCommandStateMatchValue;exports.isCommandStateForCommand=e.isCommandStateForCommand;exports.isMenuItemCommandState=e.isMenuItemCommandState;exports.resolveToolbarMenu=e.resolveToolbarMenu;exports.tableHeaderMenuItems=e.tableHeaderMenuItems;exports.createFloatingLayer=n.createFloatingLayer;exports.createRichTextEditor=n.createRichTextEditor;exports.createWebViewBridgeRuntime=n.createWebViewBridgeRuntime;exports.createRichTextToolbar=o.createRichTextToolbar;exports.hasMeaningfulHtmlContent=o.hasMeaningfulHtmlContent;exports.isEditorContentEmpty=r.isEditorContentEmpty;exports.resolvePayloadPanelSchema=i.resolvePayloadPanelSchema;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./index-GaS65GL0.cjs"),a=require("./bridge.cjs"),e=require("./native-spec.cjs"),n=require("./index-B_g23O7q.cjs"),o=require("./index-Ce7rOCpH.cjs"),r=require("./core.cjs"),i=require("./index-DF8OhKI4.cjs");exports.BRIDGERTE_CONTENT_VERSION=t.BRIDGERTE_CONTENT_VERSION;exports.BRIDGERTE_TABLE_INSERT_MAX_COLS=t.BRIDGERTE_TABLE_INSERT_MAX_COLS;exports.BRIDGERTE_TABLE_INSERT_MAX_ROWS=t.BRIDGERTE_TABLE_INSERT_MAX_ROWS;exports.BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS=a.BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS;exports.BRIDGE_HEIGHT_CHANGE_THROTTLE_MS=a.BRIDGE_HEIGHT_CHANGE_THROTTLE_MS;exports.defaultBridgeEventTiming=a.defaultBridgeEventTiming;exports.isBridgeMessage=a.isBridgeMessage;exports.codeBlockLanguagePanel=e.codeBlockLanguagePanel;exports.codeBlockLanguagePayloadPanel=e.codeBlockLanguagePayloadPanel;exports.createDisabledCommandStates=e.createDisabledCommandStates;exports.defaultMenuSchema=e.defaultMenuSchema;exports.defaultToolbarConfig=e.defaultToolbarConfig;exports.getCommandStateMatchValue=e.getCommandStateMatchValue;exports.isCommandStateForCommand=e.isCommandStateForCommand;exports.isMenuItemCommandState=e.isMenuItemCommandState;exports.resolveToolbarMenu=e.resolveToolbarMenu;exports.tableHeaderMenuItems=e.tableHeaderMenuItems;exports.createFloatingLayer=n.createFloatingLayer;exports.createRichTextEditor=n.createRichTextEditor;exports.createWebViewBridgeRuntime=n.createWebViewBridgeRuntime;exports.createRichTextToolbar=o.createRichTextToolbar;exports.hasMeaningfulHtmlContent=o.hasMeaningfulHtmlContent;exports.isEditorContentEmpty=r.isEditorContentEmpty;exports.resolvePayloadPanelSchema=i.resolvePayloadPanelSchema;
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { B as t, a as o, b as r } from "./index-CuNKUHed.js";
2
2
  import { BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS as n, BRIDGE_HEIGHT_CHANGE_THROTTLE_MS as E, defaultBridgeEventTiming as l, isBridgeMessage as s } from "./bridge.js";
3
3
  import { codeBlockLanguagePanel as d, codeBlockLanguagePayloadPanel as i, createDisabledCommandStates as _, defaultMenuSchema as c, defaultToolbarConfig as R, getCommandStateMatchValue as B, isCommandStateForCommand as C, isMenuItemCommandState as g, resolveToolbarMenu as S, tableHeaderMenuItems as f } from "./native-spec.js";
4
4
  import { c as I, a as M, b as N } from "./index-DyCMSFrm.js";
5
- import { c as b, h as p } from "./index-BWi3d-Zp.js";
5
+ import { c as b, h as p } from "./index-DGPoit9-.js";
6
6
  import { isEditorContentEmpty as h } from "./core.js";
7
7
  import { r as H } from "./index-sbZNOcCB.js";
8
8
  export {
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- :root,.bridgerte{--bridgerte-color-primary:#1677ff;--bridgerte-color-text:#1f2329;--bridgerte-color-text-muted:#86909c;--bridgerte-color-bg:#fff;--bridgerte-color-panel:#fff;--bridgerte-color-border:#e5e6eb;--bridgerte-color-active-bg:#e8f3ff;--bridgerte-color-code-bg:#f3f4f6;--bridgerte-color-placeholder:#b7bcc5;--bridgerte-color-disabled:#c9cdd4;--bridgerte-color-danger:#f53f3f;--bridgerte-shadow-panel:0 12px 32px #0f172a24;--bridgerte-shadow-popup:0 10px 24px #0f172a1a;--bridgerte-font-size:15px;--bridgerte-line-height:1.7;--bridgerte-radius:8px;--bridgerte-radius-large:12px;--bridgerte-toolbar-height:42px;--bridgerte-control-height:32px;--bridgerte-control-height-small:28px;--bridgerte-touch-target-size:32px;--bridgerte-hoverbar-button-size:28px;--bridgerte-safe-area-bottom:env(safe-area-inset-bottom,0px);--bridgerte-editor-padding:12px;--bridgerte-z-index-toolbar:20;--bridgerte-code-font-family:"JetBrains Mono", Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;--bridgerte-code-block-control-height:32px;--bridgerte-code-token-text:#000;--bridgerte-code-token-comment:#708090;--bridgerte-code-token-keyword:#a626a4;--bridgerte-code-token-operator:#0184bc;--bridgerte-code-token-function:#4078f2;--bridgerte-code-token-string:#50a14f;--bridgerte-code-token-number:#986801;--bridgerte-code-token-class:#4078f2;--bridgerte-code-token-builtin:#50a14f;--bridgerte-code-token-property:#e45649;--bridgerte-code-token-variable:#e90;--bridgerte-code-token-tag:#c18401;--bridgerte-code-token-punctuation:#999;--bridgerte-code-token-regex:#e90;--bridgerte-code-token-inserted:#690;--bridgerte-code-token-deleted:#905;--bridgerte-media-controls-button-height:28px;--bridgerte-table-controls-button-height:28px;--bridgerte-payload-panel-color-wheel-size:136px;--bridgerte-payload-panel-color-handle-size:14px;--bridgerte-payload-panel-color-swatch-width:22px;--bridgerte-payload-panel-color-swatch-height:40px;--bridgerte-payload-panel-table-cell-size:16px;--bridgerte-payload-panel-title-height:28px;--bridgerte-payload-panel-option-height:28px;--bridgerte-payload-panel-field-height:32px;--bridgerte-todo-marker-hit-size:32px;--bridgerte-todo-marker-size:16px}.bridgerte{width:100%;height:100%;min-height:0;color:var(--bridgerte-color-text);background:var(--bridgerte-color-bg);font-family:inherit;font-size:var(--bridgerte-font-size);line-height:var(--bridgerte-line-height);overflow-wrap:anywhere;outline:none;transition:background-color .16s,color .16s;position:relative}.bridgerte[data-readonly=true]{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel);cursor:default}.bridgerte__editor{flex-direction:column;width:100%;height:100%;min-height:0;display:flex}.bridgerte__body{flex-direction:column;flex:1;min-height:0;display:flex}.bridgerte__content{min-height:0;padding:var(--bridgerte-editor-padding);-webkit-tap-highlight-color:transparent;outline:none;flex:1;position:relative;overflow-y:auto}.bridgerte__content[data-placeholder][data-empty=true]:before{top:var(--bridgerte-editor-padding);left:var(--bridgerte-editor-padding);color:var(--bridgerte-color-text-muted);content:attr(data-placeholder);pointer-events:none;position:absolute}.bridgerte__content[data-empty=true] .bridgerte__paragraph:first-child{margin-top:0}.bridgerte__paragraph{margin:0 0 .75em}.bridgerte__heading{color:var(--bridgerte-color-text);margin:1em 0 .55em;font-weight:700;line-height:1.25}.bridgerte__heading--h1{font-size:32px}.bridgerte__heading--h2{font-size:28px}.bridgerte__heading--h3{font-size:24px}.bridgerte__heading--h4{font-size:21px}.bridgerte__heading--h5{font-size:18px}.bridgerte__heading--h6{font-size:16px}.bridgerte__list{margin:0 0 .75em;padding-left:1.5em}.bridgerte__list-item{margin:.25em 0}.bridgerte__quote{border-left:3px solid var(--bridgerte-color-primary);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);background:var(--bridgerte-color-code-bg);margin:.85em 0;padding:.45em .85em}.bridgerte__quote>:last-child{margin-bottom:0}.bridgerte__divider{background:var(--bridgerte-color-border);border:0;height:1px;margin:1em 0}.bridgerte__link{color:var(--bridgerte-color-primary);text-underline-offset:.18em;text-decoration:underline}.bridgerte__text--bold{font-weight:700}.bridgerte__text--italic{font-style:italic}.bridgerte__text--underline{text-underline-offset:.18em;text-decoration-line:underline}.bridgerte__text--strike{text-decoration-line:line-through}.bridgerte__text--underline-strike,.bridgerte__text--underline.bridgerte__text--strike{text-underline-offset:.18em;text-decoration-line:underline line-through}.bridgerte__list--todo{padding-left:0;list-style:none}.bridgerte__list-item--checked,.bridgerte__list-item--unchecked{outline:none;margin-left:.15em;padding-left:2em;list-style:none;position:relative}.bridgerte__list-item--checked:before,.bridgerte__list-item--unchecked:before{top:calc(var(--bridgerte-line-height) * .5em);width:var(--bridgerte-todo-marker-hit-size);height:var(--bridgerte-todo-marker-hit-size);box-sizing:border-box;content:"";border-radius:999px;position:absolute;left:0;transform:translateY(-50%)}.bridgerte__list-item--checked:after,.bridgerte__list-item--unchecked:after{top:calc(var(--bridgerte-line-height) * .5em);width:var(--bridgerte-todo-marker-size);height:var(--bridgerte-todo-marker-size);box-sizing:border-box;border:1px solid var(--bridgerte-color-border);content:"";pointer-events:none;border-radius:999px;position:absolute;left:0;transform:translateY(-50%)}.bridgerte__list-item--checked:focus-visible:after,.bridgerte__list-item--unchecked:focus-visible:after{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg)}.bridgerte__list-item--checked{color:var(--bridgerte-color-text-muted);text-decoration:line-through}.bridgerte__list-item--checked:after{border-color:var(--bridgerte-color-primary);background:radial-gradient(circle at center,var(--bridgerte-color-bg) 0 4px,transparent 4.5px),var(--bridgerte-color-primary)}.bridgerte__code{border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-code-bg);font-family:var(--bridgerte-code-font-family);padding:.12em .3em;font-size:.92em}.bridgerte__code-block{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius-large);color:var(--bridgerte-code-token-text);background:var(--bridgerte-color-code-bg);font-family:var(--bridgerte-code-font-family);line-height:var(--bridgerte-line-height);white-space:pre;margin:12px 0;padding:44px 12px 12px;display:block;overflow:auto}.bridgerte__code-token{color:var(--bridgerte-code-token-text)}.bridgerte__code-token--comment{color:var(--bridgerte-code-token-comment);font-style:italic}.bridgerte__code-token--keyword{color:var(--bridgerte-code-token-keyword)}.bridgerte__code-token--operator{color:var(--bridgerte-code-token-operator)}.bridgerte__code-token--function{color:var(--bridgerte-code-token-function)}.bridgerte__code-token--string,.bridgerte__code-token--attr-value{color:var(--bridgerte-code-token-string)}.bridgerte__code-token--number,.bridgerte__code-token--boolean,.bridgerte__code-token--constant{color:var(--bridgerte-code-token-number)}.bridgerte__code-token--class-name{color:var(--bridgerte-code-token-class)}.bridgerte__code-token--builtin{color:var(--bridgerte-code-token-builtin)}.bridgerte__code-token--property,.bridgerte__code-token--attr,.bridgerte__code-token--attr-name{color:var(--bridgerte-code-token-property)}.bridgerte__code-token--variable{color:var(--bridgerte-code-token-variable)}.bridgerte__code-token--tag,.bridgerte__code-token--selector,.bridgerte__code-token--namespace{color:var(--bridgerte-code-token-tag)}.bridgerte__code-token--punctuation,.bridgerte__code-token--prefix,.bridgerte__code-token--unchanged{color:var(--bridgerte-code-token-punctuation)}.bridgerte__code-token--regex,.bridgerte__code-token--url{color:var(--bridgerte-code-token-regex)}.bridgerte__code-token--inserted{color:var(--bridgerte-code-token-inserted)}.bridgerte__code-token--deleted{color:var(--bridgerte-code-token-deleted)}.bridgerte__code-block-controls-layer{z-index:calc(var(--bridgerte-z-index-toolbar) - 1);pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__code-block-control{width:max-content;min-height:var(--bridgerte-code-block-control-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-placeholder);font:inherit;cursor:pointer;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;gap:8px;padding:0 8px;font-size:13px;display:flex;position:absolute;top:0;left:0}.bridgerte__code-block-control:focus-visible{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__code-block-control-arrow{border-top:5px solid var(--bridgerte-color-text-muted);border-left:5px solid #0000;border-right:5px solid #0000;flex:none;width:0;height:0}.bridgerte__code-block-control-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.bridgerte__media{width:var(--bridgerte-media-display-width,50%);border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius-large);background:var(--bridgerte-color-panel);max-width:100%;margin:12px 0;display:block;overflow:hidden}.bridgerte__media-placeholder{min-height:160px;aspect-ratio:var(--bridgerte-media-aspect-ratio,16 / 9);color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-code-bg);justify-content:center;align-items:center;gap:8px;font-size:13px;display:flex}.bridgerte__media-placeholder-icon{border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-bg);padding:2px 6px;font-size:11px;line-height:1.4}.bridgerte__media[data-load-state=loaded] .bridgerte__media-placeholder{display:none}.bridgerte__media[data-load-state=error] .bridgerte__media-placeholder{color:var(--bridgerte-color-danger)}.bridgerte__media[data-align=center]{margin-left:auto;margin-right:auto}.bridgerte__media[data-align=right]{margin-left:auto;margin-right:0}.bridgerte__media-element{width:100%;max-width:100%;height:auto;display:block}.bridgerte__media[data-load-state=loading] .bridgerte__media-element,.bridgerte__media[data-load-state=error] .bridgerte__media-element{opacity:0;width:1px;height:1px}.bridgerte__media[data-load-state=loaded] .bridgerte__media-element,.bridgerte__media:not([data-load-state]) .bridgerte__media-element{opacity:1}.bridgerte__media-status{border-top:1px solid var(--bridgerte-color-border);color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-bg);padding:8px 10px;font-size:13px}.bridgerte__media[data-status=error] .bridgerte__media-status{color:var(--bridgerte-color-danger)}.bridgerte__media-controls-layer{z-index:calc(var(--bridgerte-z-index-toolbar) - 1);pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__media-controls{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-popup);pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent;align-items:center;gap:2px;padding:3px;display:inline-flex;position:absolute;top:0;left:0}.bridgerte__media-controls-button{min-height:var(--bridgerte-media-controls-button-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;padding:0 8px;font-size:12px;line-height:1;display:inline-flex}.bridgerte__media-controls-button:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__media-controls-button[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte[data-readonly=true] .bridgerte__media-controls-button{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__table-wrapper{box-sizing:border-box;border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius-large);background:var(--bridgerte-color-panel);scrollbar-width:thin;margin:12px 0;position:relative;overflow-x:auto}.bridgerte__table{border-collapse:separate;border-spacing:0;width:max-content;min-width:100%;color:var(--bridgerte-color-text);background:var(--bridgerte-color-bg)}.bridgerte__table-cell{border:0;border-top:1px solid var(--bridgerte-color-border);border-left:1px solid var(--bridgerte-color-border);vertical-align:top;padding:8px}.bridgerte__table-cell:first-child{border-left:0}.bridgerte__table-row:first-of-type .bridgerte__table-cell{border-top:0}.bridgerte__table-cell--header{background:var(--bridgerte-color-code-bg);font-weight:700}.bridgerte__table-controls-layer{z-index:calc(var(--bridgerte-z-index-toolbar) - 1);pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__table-controls{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-popup);pointer-events:auto;scrollbar-width:none;touch-action:pan-x;-webkit-tap-highlight-color:transparent;align-items:center;gap:2px;padding:4px;display:inline-flex;position:absolute;top:0;left:0;overflow-x:auto}.bridgerte__table-controls::-webkit-scrollbar{display:none}.bridgerte__table-controls-button{min-height:var(--bridgerte-table-controls-button-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;flex:none;align-items:center;padding:0 8px;font-size:12px;line-height:1;display:inline-flex}.bridgerte__table-controls-button:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte[data-readonly=true] .bridgerte__table-controls-button{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__toolbar{z-index:var(--bridgerte-z-index-toolbar);min-height:var(--bridgerte-toolbar-height);border-bottom:1px solid var(--bridgerte-color-border);padding:5px calc(var(--bridgerte-editor-padding) - 2px);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);cursor:grab;overscroll-behavior-x:contain;scrollbar-width:none;touch-action:pan-x;-webkit-tap-highlight-color:transparent;flex-wrap:nowrap;align-items:center;gap:4px;display:flex;position:sticky;top:0;overflow:auto hidden}.bridgerte__toolbar::-webkit-scrollbar{display:none}.bridgerte__toolbar[data-placement=bottom]{min-height:calc(var(--bridgerte-toolbar-height) + var(--bridgerte-safe-area-bottom));border-top:1px solid var(--bridgerte-color-border);padding-top:5px;padding-bottom:calc(5px + var(--bridgerte-safe-area-bottom));border-bottom:0;top:auto;bottom:0}.bridgerte__toolbar[data-dragging=true]{cursor:grabbing;-webkit-user-select:none;user-select:none}.bridgerte__toolbar-group{flex:none;align-items:center;gap:2px;display:inline-flex}.bridgerte__toolbar-separator{background:var(--bridgerte-color-border);flex:none;width:1px;height:22px;margin:0 6px}.bridgerte__toolbar-button{border-radius:calc(var(--bridgerte-radius) - 2px);min-width:30px;height:30px;color:var(--bridgerte-color-text);cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:1px solid #0000;justify-content:center;align-items:center;padding:0 7px;font-family:inherit;font-size:13px;font-weight:600;line-height:1;transition:border-color .12s,background-color .12s,color .12s;display:inline-flex;position:relative}.bridgerte__toolbar-button:focus-visible{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__toolbar-button[aria-pressed=true],.bridgerte__toolbar-button[data-active=true]{border-color:var(--bridgerte-color-active-bg);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__toolbar-button:disabled,.bridgerte__toolbar-button[aria-disabled=true]{color:var(--bridgerte-color-disabled);cursor:not-allowed;background:0 0}.bridgerte__toolbar-button>svg,.bridgerte__toolbar-group-indicator>svg{flex:none;display:block}.bridgerte__toolbar-group-button{gap:4px}.bridgerte__toolbar-group-button[data-open=true]{border-color:var(--bridgerte-color-primary);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__toolbar-group-indicator{justify-content:center;align-items:center;width:12px;height:12px;font-size:11px;line-height:1;display:inline-flex}.bridgerte__toolbar-group-menu{opacity:0;pointer-events:none;gap:2px;min-width:128px;max-height:min(320px,100vh - 24px);padding:4px;transition:opacity .12s,transform .12s;display:grid;position:fixed;overflow:hidden auto;transform:translateY(-2px)}.bridgerte__toolbar-group-menu[data-visible=true]{opacity:1;pointer-events:auto;transform:translateY(0)}.bridgerte__menu-item.bridgerte__toolbar-group-menu-item{border-radius:calc(var(--bridgerte-radius) - 2px);gap:6px;min-height:30px;padding:0 7px;font-size:13px;font-weight:500;line-height:1.15}.bridgerte__toolbar-group-menu-item>svg,.bridgerte__toolbar-group-menu-item>.bridgerte__menu-icon-text{flex:none;width:16px;height:16px}.bridgerte__toolbar-group-menu-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.bridgerte__toolbar-tooltip{z-index:calc(var(--bridgerte-z-index-toolbar) + 2);opacity:0;border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-bg);background:var(--bridgerte-color-text);box-shadow:var(--bridgerte-shadow-panel);pointer-events:none;white-space:nowrap;padding:5px 7px;font-size:12px;font-weight:500;line-height:1;transition:opacity .12s,transform .12s;position:fixed;transform:translate(-50%,-100%)translateY(2px)}.bridgerte__toolbar-tooltip[data-visible=true]{opacity:1;transform:translate(-50%,-100%)translateY(0)}.bridgerte__panel,.bridgerte__floating-menu{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-panel)}.bridgerte__floating-menu{z-index:calc(var(--bridgerte-z-index-toolbar) + 1);min-width:180px;padding:6px}.bridgerte__menu-item{border-radius:var(--bridgerte-radius);width:100%;min-height:34px;color:var(--bridgerte-color-text);font:inherit;text-align:left;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;gap:8px;padding:0 8px;display:flex}.bridgerte__menu-item:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);outline:none}.bridgerte__menu-item[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__menu-item:disabled,.bridgerte__menu-item[aria-disabled=true]{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__menu-icon-text{text-overflow:ellipsis;white-space:nowrap;flex:none;display:inline-block;overflow:hidden}.bridgerte__slash-command-menu{overscroll-behavior:contain;scrollbar-width:thin;touch-action:pan-y;-webkit-overflow-scrolling:touch;gap:2px;width:min(120px,100vw - 24px);min-width:0;max-height:min(232px,100vh - 24px);padding:4px;display:grid;overflow-y:auto}.bridgerte__slash-command-menu[hidden]{display:none}.bridgerte__slash-command-anchor{pointer-events:none;width:1px;position:fixed}.bridgerte__slash-command-item{text-align:left;flex-direction:row;justify-content:flex-start;align-items:center;gap:4px;min-height:30px;padding:0 8px}.bridgerte__slash-command-item-icon{width:18px;height:18px;color:var(--bridgerte-color-text-muted);flex:none;place-items:center;display:inline-grid}.bridgerte__slash-command-item-title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:13px;font-weight:700;line-height:1.2;overflow:hidden}.bridgerte__slash-command-item-description{color:var(--bridgerte-color-text-muted);font-size:12px;line-height:1.2;display:none}.bridgerte__slash-command-status{color:var(--bridgerte-color-text-muted);text-align:center;padding:8px;font-size:13px;line-height:1.3}.bridgerte__mention{border-radius:calc(var(--bridgerte-radius) - 2px);max-width:100%;color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);white-space:nowrap;align-items:center;padding:0 3px;display:inline-flex}.bridgerte__mention-menu{overscroll-behavior:contain;scrollbar-width:thin;touch-action:pan-y;-webkit-overflow-scrolling:touch;gap:2px;width:min(120px,100vw - 24px);min-width:0;max-height:min(232px,100vh - 24px);padding:4px;display:grid;overflow-y:auto}.bridgerte__mention-menu[hidden]{display:none}.bridgerte__mention-anchor{pointer-events:none;width:1px;position:fixed}.bridgerte__mention-item{text-align:left;flex-direction:row;justify-content:flex-start;align-items:center;gap:4px;min-height:30px;padding:0 8px}.bridgerte__mention-item-avatar,.bridgerte__mention-item-icon{border-radius:50%;flex:none;width:18px;height:18px}.bridgerte__mention-item-avatar{object-fit:cover;background:var(--bridgerte-color-active-bg)}.bridgerte__mention-item-icon{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-active-bg);place-items:center;font-size:12px;line-height:1;display:inline-grid}.bridgerte__mention-item-title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:13px;font-weight:700;line-height:1.2;overflow:hidden}.bridgerte__mention-item-description{color:var(--bridgerte-color-text-muted);font-size:12px;line-height:1.2;display:none}.bridgerte__mention-status{color:var(--bridgerte-color-text-muted);text-align:center;padding:8px;font-size:13px;line-height:1.3}.bridgerte__hoverbar{gap:2px;width:max-content;min-width:0;max-width:calc(100vw - 24px);padding:4px;display:flex}.bridgerte__hoverbar[hidden]{display:none}.bridgerte__hoverbar-anchor{pointer-events:none;position:fixed}.bridgerte__hoverbar-separator{width:1px;height:var(--bridgerte-hoverbar-button-size);background:var(--bridgerte-color-border);margin:0 2px}.bridgerte__hoverbar-button{width:var(--bridgerte-hoverbar-button-size);min-width:var(--bridgerte-hoverbar-button-size);height:var(--bridgerte-hoverbar-button-size);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text-muted);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;justify-content:center;align-items:center;font-size:12px;font-weight:700;line-height:1;display:inline-flex;overflow:hidden}.bridgerte__hoverbar-button[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__hoverbar-button:disabled{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__hoverbar-button:focus-visible{box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__hoverbar-button>svg,.bridgerte__hoverbar-button>.bridgerte__menu-icon-text{width:calc(var(--bridgerte-hoverbar-button-size) - 12px);height:calc(var(--bridgerte-hoverbar-button-size) - 12px);flex:none}.bridgerte__dialog-backdrop{z-index:var(--bridgerte-z-index-toolbar);opacity:0;pointer-events:none;background:0 0;position:fixed;top:0;right:0;bottom:0;left:0}.bridgerte__dialog-backdrop[data-visible=true]{opacity:1;pointer-events:auto}.bridgerte__dialog{z-index:calc(var(--bridgerte-z-index-toolbar) + 2);width:min(220px,100vw - 24px);max-height:calc(var(--bridgerte-dialog-visible-height,100vh) - 32px);opacity:0;border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-panel);font:inherit;pointer-events:none;transition:opacity .12s,transform .12s;display:grid;position:fixed;top:0;left:0;transform:translateY(-4px)scale(.98)}.bridgerte__dialog[data-visible=true]{opacity:1;pointer-events:auto;transform:translateY(0)scale(1)}.bridgerte__code-block-menu{width:min(var(--bridgerte-dialog-anchor-width),calc(100vw - 24px));max-height:min(360px,calc(var(--bridgerte-dialog-visible-height,100vh) - 32px));border-color:var(--bridgerte-color-border);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-popup)}.bridgerte__code-block-menu .bridgerte__dialog-content{min-height:0;max-height:inherit;overflow:hidden}.bridgerte__code-block-menu-list{max-height:min(340px,calc(var(--bridgerte-dialog-visible-height,100vh) - 48px));overscroll-behavior:contain;scrollbar-width:thin;touch-action:pan-y;-webkit-overflow-scrolling:touch;gap:2px;padding:8px;display:grid;overflow-y:auto}.bridgerte__code-block-menu-item{min-height:var(--bridgerte-payload-panel-field-height);border-radius:calc(var(--bridgerte-radius) - 2px);padding:0 12px}.bridgerte__payload-panel{padding:6px}.bridgerte__payload-panel-title{min-height:var(--bridgerte-payload-panel-title-height);color:var(--bridgerte-color-text);justify-content:space-between;align-items:center;gap:8px;padding:2px 4px 6px;font-size:13px;font-weight:700;line-height:1.2;display:flex}.bridgerte__payload-panel-clear{color:var(--bridgerte-color-text-muted);font:inherit;text-align:right;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;flex:none;padding:0;font-size:12px;font-weight:600;line-height:1}.bridgerte__payload-panel-clear:focus-visible{color:var(--bridgerte-color-primary);text-underline-offset:.18em;outline:none;text-decoration:underline}.bridgerte__payload-panel-field{gap:7px;display:grid}.bridgerte__payload-panel-option-list{gap:2px;display:grid}.bridgerte__payload-panel-color-picker{width:calc(var(--bridgerte-payload-panel-color-wheel-size) + var(--bridgerte-payload-panel-color-swatch-width) * 2 + 20px);justify-self:center;place-items:center;max-width:100%;display:grid;position:relative}.bridgerte__payload-panel-color-wheel{width:var(--bridgerte-payload-panel-color-wheel-size);aspect-ratio:1;border:1px solid var(--bridgerte-color-border);background:radial-gradient(circle,var(--bridgerte-color-bg) 0%,transparent 68%),conic-gradient(from 90deg,red,#ff0,#0f0,#0ff,#00f,#f0f,red);cursor:crosshair;touch-action:none;border-radius:999px;position:relative}.bridgerte__payload-panel-color-wheel:focus-visible{box-shadow:0 0 0 3px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-color-wheel-handle{width:var(--bridgerte-payload-panel-color-handle-size);height:var(--bridgerte-payload-panel-color-handle-size);border:2px solid var(--bridgerte-color-bg);box-shadow:0 0 0 1px var(--bridgerte-color-border),var(--bridgerte-shadow-panel);opacity:0;pointer-events:none;border-radius:999px;position:absolute;transform:translate(-50%,-50%)}.bridgerte__payload-panel-color-wheel[data-active=true] .bridgerte__payload-panel-color-wheel-handle{opacity:1}.bridgerte__payload-panel-color-preview{border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);min-height:24px;box-shadow:inset 0 0 0 1px var(--bridgerte-color-panel)}.bridgerte__payload-panel-color-preview[data-empty=true]{background:linear-gradient(45deg,transparent 45%,var(--bridgerte-color-border) 45%,var(--bridgerte-color-border) 55%,transparent 55%),linear-gradient(-45deg,transparent 45%,var(--bridgerte-color-border) 45%,var(--bridgerte-color-border) 55%,transparent 55%),var(--bridgerte-color-bg);background-position:50%;background-size:12px 12px}.bridgerte__payload-panel-color-actions{align-items:center;gap:6px;display:flex}.bridgerte__payload-panel-color-actions[data-layout=sides]{pointer-events:none;justify-content:space-between;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__payload-panel-color-actions[data-layout=grid]{flex-wrap:wrap;justify-content:center;margin-top:6px}.bridgerte__payload-panel-color-swatch{width:var(--bridgerte-payload-panel-color-swatch-width);height:var(--bridgerte-payload-panel-color-swatch-height);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);background:var(--bridgerte-color-bg);box-shadow:inset 0 0 0 1px var(--bridgerte-color-panel);cursor:pointer;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent;padding:0}.bridgerte__payload-panel-color-swatch:focus-visible{border-color:var(--bridgerte-color-primary);box-shadow:inset 0 0 0 1px var(--bridgerte-color-bg),0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-text-field{color:var(--bridgerte-color-text-muted);gap:5px;font-size:12px;font-weight:600;line-height:1.2;display:grid}.bridgerte__payload-panel-text-input{width:100%;min-height:var(--bridgerte-payload-panel-field-height);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);background:var(--bridgerte-color-bg);font:inherit;-webkit-tap-highlight-color:transparent;padding:0 10px;font-size:13px}.bridgerte__payload-panel-text-input:focus-visible{border-color:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-table-grid{grid-template-columns:repeat(var(--bridgerte-payload-panel-table-cols),var(--bridgerte-payload-panel-table-cell-size));touch-action:none;-webkit-tap-highlight-color:transparent;justify-content:center;gap:2px;max-width:100%;padding:2px;display:grid}.bridgerte__payload-panel-table-cell{width:var(--bridgerte-payload-panel-table-cell-size);height:var(--bridgerte-payload-panel-table-cell-size);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 4px);background:var(--bridgerte-color-bg);cursor:pointer;-webkit-tap-highlight-color:transparent;padding:0}.bridgerte__payload-panel-table-cell[data-active=true]{border-color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-table-cell:focus-visible{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-table-status{min-height:18px;color:var(--bridgerte-color-text-muted);text-align:center;font-size:12px;font-weight:600;line-height:1.5}.bridgerte__payload-panel-submit{min-height:var(--bridgerte-payload-panel-field-height);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-bg);background:var(--bridgerte-color-primary);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;padding:0 10px;font-size:13px;font-weight:700}.bridgerte__payload-panel-submit:focus-visible{box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-option{min-height:var(--bridgerte-payload-panel-option-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);font:inherit;text-align:left;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;padding:0 7px;display:flex}.bridgerte__payload-panel-option[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-option:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}@media(hover:hover)and (pointer:fine){.bridgerte__code-block-control:hover{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel)}.bridgerte__toolbar-button:hover{border-color:var(--bridgerte-color-active-bg);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__code-block-menu-item:hover,.bridgerte__media-controls-button:hover,.bridgerte__table-controls-button:hover,.bridgerte__hoverbar-button:hover,.bridgerte__payload-panel-option:hover,.bridgerte__mention-item:hover,.bridgerte__slash-command-item:hover,.bridgerte__menu-item:hover{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-clear:hover{color:var(--bridgerte-color-primary)}.bridgerte__payload-panel-color-wheel:hover{box-shadow:0 0 0 3px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-table-cell:hover{border-color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-color-swatch:hover{border-color:var(--bridgerte-color-primary);box-shadow:inset 0 0 0 1px var(--bridgerte-color-bg),0 0 0 2px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-submit:hover{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg)}}@media(hover:none),(pointer:coarse){.bridgerte__code-block-control:active,.bridgerte__code-block-control[data-pressed=true]{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel)}.bridgerte__toolbar-button:active,.bridgerte__toolbar-button[data-pressed=true]{border-color:var(--bridgerte-color-active-bg);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__code-block-menu-item:active,.bridgerte__code-block-menu-item[data-pressed=true],.bridgerte__media-controls-button:active,.bridgerte__media-controls-button[data-pressed=true],.bridgerte__table-controls-button:active,.bridgerte__table-controls-button[data-pressed=true],.bridgerte__hoverbar-button:active,.bridgerte__hoverbar-button[data-pressed=true],.bridgerte__payload-panel-option:active,.bridgerte__payload-panel-option[data-pressed=true],.bridgerte__mention-item:active,.bridgerte__mention-item[data-pressed=true],.bridgerte__slash-command-item:active,.bridgerte__slash-command-item[data-pressed=true],.bridgerte__menu-item[data-pressed=true],.bridgerte__menu-item:active{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-clear:active,.bridgerte__payload-panel-clear[data-pressed=true]{color:var(--bridgerte-color-primary)}.bridgerte__payload-panel-color-wheel:active,.bridgerte__payload-panel-color-wheel[data-pressed=true]{box-shadow:0 0 0 3px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-table-cell:active,.bridgerte__payload-panel-table-cell[data-pressed=true]{border-color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-color-swatch:active,.bridgerte__payload-panel-color-swatch[data-pressed=true]{border-color:var(--bridgerte-color-primary);box-shadow:inset 0 0 0 1px var(--bridgerte-color-bg),0 0 0 2px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-submit:active,.bridgerte__payload-panel-submit[data-pressed=true]{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg)}}@media(max-width:760px){.bridgerte{min-height:220px}.bridgerte__toolbar-button{min-width:38px;height:38px}}
1
+ :root,.bridgerte{--bridgerte-color-primary:#1677ff;--bridgerte-color-text:#1f2329;--bridgerte-color-text-muted:#86909c;--bridgerte-color-bg:#fff;--bridgerte-color-panel:#fff;--bridgerte-color-border:#e5e6eb;--bridgerte-color-active-bg:#e8f3ff;--bridgerte-color-code-bg:#f3f4f6;--bridgerte-color-placeholder:#b7bcc5;--bridgerte-color-disabled:#c9cdd4;--bridgerte-color-danger:#f53f3f;--bridgerte-shadow-panel:0 12px 32px #0f172a24;--bridgerte-shadow-popup:0 10px 24px #0f172a1a;--bridgerte-font-size:15px;--bridgerte-line-height:1.7;--bridgerte-radius:8px;--bridgerte-radius-large:12px;--bridgerte-toolbar-height:42px;--bridgerte-control-height:32px;--bridgerte-control-height-small:28px;--bridgerte-touch-target-size:32px;--bridgerte-hoverbar-button-size:28px;--bridgerte-safe-area-bottom:env(safe-area-inset-bottom,0px);--bridgerte-editor-padding:12px;--bridgerte-z-index-toolbar:20;--bridgerte-code-font-family:"JetBrains Mono", Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;--bridgerte-code-block-control-height:32px;--bridgerte-code-token-text:#000;--bridgerte-code-token-comment:#708090;--bridgerte-code-token-keyword:#a626a4;--bridgerte-code-token-operator:#0184bc;--bridgerte-code-token-function:#4078f2;--bridgerte-code-token-string:#50a14f;--bridgerte-code-token-number:#986801;--bridgerte-code-token-class:#4078f2;--bridgerte-code-token-builtin:#50a14f;--bridgerte-code-token-property:#e45649;--bridgerte-code-token-variable:#e90;--bridgerte-code-token-tag:#c18401;--bridgerte-code-token-punctuation:#999;--bridgerte-code-token-regex:#e90;--bridgerte-code-token-inserted:#690;--bridgerte-code-token-deleted:#905;--bridgerte-media-controls-button-height:28px;--bridgerte-table-controls-button-height:28px;--bridgerte-payload-panel-color-wheel-size:136px;--bridgerte-payload-panel-color-handle-size:14px;--bridgerte-payload-panel-color-swatch-width:22px;--bridgerte-payload-panel-color-swatch-height:40px;--bridgerte-payload-panel-table-cell-size:16px;--bridgerte-payload-panel-title-height:28px;--bridgerte-payload-panel-option-height:28px;--bridgerte-payload-panel-field-height:32px;--bridgerte-todo-marker-hit-size:32px;--bridgerte-todo-marker-size:16px}.bridgerte{width:100%;height:100%;min-height:0;color:var(--bridgerte-color-text);background:var(--bridgerte-color-bg);font-family:inherit;font-size:var(--bridgerte-font-size);line-height:var(--bridgerte-line-height);overflow-wrap:anywhere;outline:none;transition:background-color .16s,color .16s;position:relative}.bridgerte[data-readonly=true]{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel);cursor:default}.bridgerte__editor{flex-direction:column;width:100%;height:100%;min-height:0;display:flex}.bridgerte__body{flex-direction:column;flex:1;min-height:0;display:flex}.bridgerte__content{min-height:0;padding:var(--bridgerte-editor-padding);-webkit-tap-highlight-color:transparent;outline:none;flex:1;position:relative;overflow-y:auto}.bridgerte__content[data-placeholder][data-empty=true]:before{top:var(--bridgerte-editor-padding);left:var(--bridgerte-editor-padding);color:var(--bridgerte-color-text-muted);content:attr(data-placeholder);pointer-events:none;position:absolute}.bridgerte__content[data-empty=true] .bridgerte__paragraph:first-child{margin-top:0}.bridgerte__paragraph{margin:0 0 .75em}.bridgerte__heading{color:var(--bridgerte-color-text);margin:1em 0 .55em;font-weight:700;line-height:1.25}.bridgerte__heading--h1{font-size:32px}.bridgerte__heading--h2{font-size:28px}.bridgerte__heading--h3{font-size:24px}.bridgerte__heading--h4{font-size:21px}.bridgerte__heading--h5{font-size:18px}.bridgerte__heading--h6{font-size:16px}.bridgerte__list{margin:0 0 .75em;padding-left:1.5em}.bridgerte__list-item{margin:.25em 0}.bridgerte__quote{border-left:3px solid var(--bridgerte-color-primary);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);background:var(--bridgerte-color-code-bg);margin:.85em 0;padding:.45em .85em}.bridgerte__quote>:last-child{margin-bottom:0}.bridgerte__divider{background:var(--bridgerte-color-border);border:0;height:1px;margin:1em 0}.bridgerte__link{color:var(--bridgerte-color-primary);text-underline-offset:.18em;text-decoration:underline}.bridgerte__text--bold{font-weight:700}.bridgerte__text--italic{font-style:italic}.bridgerte__text--underline{text-underline-offset:.18em;text-decoration-line:underline}.bridgerte__text--strike{text-decoration-line:line-through}.bridgerte__text--underline-strike,.bridgerte__text--underline.bridgerte__text--strike{text-underline-offset:.18em;text-decoration-line:underline line-through}.bridgerte__list--todo{padding-left:0;list-style:none}.bridgerte__list-item--checked,.bridgerte__list-item--unchecked{outline:none;margin-left:.15em;padding-left:2em;list-style:none;position:relative}.bridgerte__list-item--checked:before,.bridgerte__list-item--unchecked:before{top:calc(var(--bridgerte-line-height) * .5em);width:var(--bridgerte-todo-marker-hit-size);height:var(--bridgerte-todo-marker-hit-size);box-sizing:border-box;content:"";border-radius:999px;position:absolute;left:0;transform:translateY(-50%)}.bridgerte__list-item--checked:after,.bridgerte__list-item--unchecked:after{top:calc(var(--bridgerte-line-height) * .5em);width:var(--bridgerte-todo-marker-size);height:var(--bridgerte-todo-marker-size);box-sizing:border-box;border:1px solid var(--bridgerte-color-border);content:"";pointer-events:none;border-radius:999px;position:absolute;left:0;transform:translateY(-50%)}.bridgerte__list-item--checked:focus-visible:after,.bridgerte__list-item--unchecked:focus-visible:after{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg)}.bridgerte__list-item--checked{color:var(--bridgerte-color-text-muted);text-decoration:line-through}.bridgerte__list-item--checked:after{border-color:var(--bridgerte-color-primary);background:radial-gradient(circle at center,var(--bridgerte-color-bg) 0 4px,transparent 4.5px),var(--bridgerte-color-primary)}.bridgerte__code{border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-code-bg);font-family:var(--bridgerte-code-font-family);padding:.12em .3em;font-size:.92em}.bridgerte__code-block{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius-large);color:var(--bridgerte-code-token-text);background:var(--bridgerte-color-code-bg);font-family:var(--bridgerte-code-font-family);line-height:var(--bridgerte-line-height);white-space:pre;margin:12px 0;padding:44px 12px 12px;display:block;overflow:auto}.bridgerte__code-token{color:var(--bridgerte-code-token-text)}.bridgerte__code-token--comment{color:var(--bridgerte-code-token-comment);font-style:italic}.bridgerte__code-token--keyword{color:var(--bridgerte-code-token-keyword)}.bridgerte__code-token--operator{color:var(--bridgerte-code-token-operator)}.bridgerte__code-token--function{color:var(--bridgerte-code-token-function)}.bridgerte__code-token--string,.bridgerte__code-token--attr-value{color:var(--bridgerte-code-token-string)}.bridgerte__code-token--number,.bridgerte__code-token--boolean,.bridgerte__code-token--constant{color:var(--bridgerte-code-token-number)}.bridgerte__code-token--class-name{color:var(--bridgerte-code-token-class)}.bridgerte__code-token--builtin{color:var(--bridgerte-code-token-builtin)}.bridgerte__code-token--property,.bridgerte__code-token--attr,.bridgerte__code-token--attr-name{color:var(--bridgerte-code-token-property)}.bridgerte__code-token--variable{color:var(--bridgerte-code-token-variable)}.bridgerte__code-token--tag,.bridgerte__code-token--selector,.bridgerte__code-token--namespace{color:var(--bridgerte-code-token-tag)}.bridgerte__code-token--punctuation,.bridgerte__code-token--prefix,.bridgerte__code-token--unchanged{color:var(--bridgerte-code-token-punctuation)}.bridgerte__code-token--regex,.bridgerte__code-token--url{color:var(--bridgerte-code-token-regex)}.bridgerte__code-token--inserted{color:var(--bridgerte-code-token-inserted)}.bridgerte__code-token--deleted{color:var(--bridgerte-code-token-deleted)}.bridgerte__code-block-controls-layer{z-index:calc(var(--bridgerte-z-index-toolbar) - 1);pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__code-block-control{width:max-content;min-height:var(--bridgerte-code-block-control-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-placeholder);font:inherit;cursor:pointer;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;gap:8px;padding:0 8px;font-size:13px;display:flex;position:absolute;top:0;left:0}.bridgerte__code-block-control:focus-visible{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__code-block-control-arrow{border-top:5px solid var(--bridgerte-color-text-muted);border-left:5px solid #0000;border-right:5px solid #0000;flex:none;width:0;height:0}.bridgerte__code-block-control-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.bridgerte__media{width:var(--bridgerte-media-display-width,50%);border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius-large);background:var(--bridgerte-color-panel);max-width:100%;margin:12px 0;display:block;overflow:hidden}.bridgerte__media-placeholder{min-height:160px;aspect-ratio:var(--bridgerte-media-aspect-ratio,16 / 9);color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-code-bg);justify-content:center;align-items:center;gap:8px;font-size:13px;display:flex}.bridgerte__media-placeholder-icon{border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-bg);padding:2px 6px;font-size:11px;line-height:1.4}.bridgerte__media[data-load-state=loaded] .bridgerte__media-placeholder{display:none}.bridgerte__media[data-load-state=error] .bridgerte__media-placeholder{color:var(--bridgerte-color-danger)}.bridgerte__media[data-align=center]{margin-left:auto;margin-right:auto}.bridgerte__media[data-align=right]{margin-left:auto;margin-right:0}.bridgerte__media-element{width:100%;max-width:100%;height:auto;display:block}.bridgerte__media[data-load-state=loading] .bridgerte__media-element,.bridgerte__media[data-load-state=error] .bridgerte__media-element{opacity:0;width:1px;height:1px}.bridgerte__media[data-load-state=loaded] .bridgerte__media-element,.bridgerte__media:not([data-load-state]) .bridgerte__media-element{opacity:1}.bridgerte__media-status{border-top:1px solid var(--bridgerte-color-border);color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-bg);padding:8px 10px;font-size:13px}.bridgerte__media[data-status=error] .bridgerte__media-status{color:var(--bridgerte-color-danger)}.bridgerte__media-controls-layer{z-index:calc(var(--bridgerte-z-index-toolbar) - 1);pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__media-controls{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-popup);pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent;align-items:center;gap:2px;padding:3px;display:inline-flex;position:absolute;top:0;left:0}.bridgerte__media-controls-button{min-height:var(--bridgerte-media-controls-button-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;padding:0 8px;font-size:12px;line-height:1;display:inline-flex}.bridgerte__media-controls-button:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__media-controls-button[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte[data-readonly=true] .bridgerte__media-controls-button{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__table-wrapper{box-sizing:border-box;border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius-large);background:var(--bridgerte-color-panel);scrollbar-width:thin;margin:12px 0;position:relative;overflow-x:auto}.bridgerte__table{border-collapse:separate;border-spacing:0;width:max-content;min-width:100%;color:var(--bridgerte-color-text);background:var(--bridgerte-color-bg)}.bridgerte__table-cell{border:0;border-top:1px solid var(--bridgerte-color-border);border-left:1px solid var(--bridgerte-color-border);vertical-align:top;padding:8px}.bridgerte__table-cell:first-child{border-left:0}.bridgerte__table-row:first-of-type .bridgerte__table-cell{border-top:0}.bridgerte__table-cell--header{background:var(--bridgerte-color-code-bg);font-weight:700}.bridgerte__table-controls-layer{z-index:calc(var(--bridgerte-z-index-toolbar) - 1);pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__table-controls{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-popup);pointer-events:auto;scrollbar-width:none;touch-action:pan-x;-webkit-tap-highlight-color:transparent;align-items:center;gap:2px;padding:4px;display:inline-flex;position:absolute;top:0;left:0;overflow-x:auto}.bridgerte__table-controls::-webkit-scrollbar{display:none}.bridgerte__table-controls-button{min-height:var(--bridgerte-table-controls-button-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;flex:none;align-items:center;padding:0 8px;font-size:12px;line-height:1;display:inline-flex}.bridgerte__table-controls-button:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte[data-readonly=true] .bridgerte__table-controls-button{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__toolbar{z-index:var(--bridgerte-z-index-toolbar);min-height:var(--bridgerte-toolbar-height);border-bottom:1px solid var(--bridgerte-color-border);padding:5px calc(var(--bridgerte-editor-padding) - 2px);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);cursor:grab;overscroll-behavior-x:contain;scrollbar-width:none;touch-action:pan-x;-webkit-tap-highlight-color:transparent;flex-wrap:nowrap;align-items:center;gap:4px;display:flex;position:sticky;top:0;overflow:auto hidden}.bridgerte__toolbar::-webkit-scrollbar{display:none}.bridgerte__toolbar[data-placement=bottom]{min-height:calc(var(--bridgerte-toolbar-height) + var(--bridgerte-safe-area-bottom));border-top:1px solid var(--bridgerte-color-border);padding-top:5px;padding-bottom:calc(5px + var(--bridgerte-safe-area-bottom));border-bottom:0;top:auto;bottom:0}.bridgerte__toolbar[data-dragging=true]{cursor:grabbing;-webkit-user-select:none;user-select:none}.bridgerte__toolbar-group{flex:none;align-items:center;gap:2px;display:inline-flex}.bridgerte__toolbar-separator{background:var(--bridgerte-color-border);flex:none;width:1px;height:22px;margin:0 6px}.bridgerte__toolbar-button{border-radius:calc(var(--bridgerte-radius) - 2px);min-width:30px;height:30px;color:var(--bridgerte-color-text);cursor:pointer;touch-action:pan-x;-webkit-tap-highlight-color:transparent;background:0 0;border:1px solid #0000;justify-content:center;align-items:center;padding:0 7px;font-family:inherit;font-size:13px;font-weight:600;line-height:1;transition:border-color .12s,background-color .12s,color .12s;display:inline-flex;position:relative}.bridgerte__toolbar-button:focus-visible{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__toolbar-button[aria-pressed=true],.bridgerte__toolbar-button[data-active=true]{border-color:var(--bridgerte-color-active-bg);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__toolbar-button:disabled,.bridgerte__toolbar-button[aria-disabled=true]{color:var(--bridgerte-color-disabled);cursor:not-allowed;background:0 0}.bridgerte__toolbar-button>svg,.bridgerte__toolbar-group-indicator>svg{flex:none;display:block}.bridgerte__toolbar-group-button{gap:4px}.bridgerte__toolbar-group-button[data-open=true]{border-color:var(--bridgerte-color-primary);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__toolbar-group-indicator{justify-content:center;align-items:center;width:12px;height:12px;font-size:11px;line-height:1;display:inline-flex}.bridgerte__toolbar-group-menu{opacity:0;pointer-events:none;gap:2px;min-width:128px;max-height:min(320px,100vh - 24px);padding:4px;transition:opacity .12s,transform .12s;display:grid;position:fixed;overflow:hidden auto;transform:translateY(-2px)}.bridgerte__toolbar-group-menu[data-visible=true]{opacity:1;pointer-events:auto;transform:translateY(0)}.bridgerte__menu-item.bridgerte__toolbar-group-menu-item{border-radius:calc(var(--bridgerte-radius) - 2px);gap:6px;min-height:30px;padding:0 7px;font-size:13px;font-weight:500;line-height:1.15}.bridgerte__toolbar-group-menu-item>svg,.bridgerte__toolbar-group-menu-item>.bridgerte__menu-icon-text{flex:none;width:16px;height:16px}.bridgerte__toolbar-group-menu-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.bridgerte__toolbar-tooltip{z-index:calc(var(--bridgerte-z-index-toolbar) + 2);opacity:0;border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-bg);background:var(--bridgerte-color-text);box-shadow:var(--bridgerte-shadow-panel);pointer-events:none;white-space:nowrap;padding:5px 7px;font-size:12px;font-weight:500;line-height:1;transition:opacity .12s,transform .12s;position:fixed;transform:translate(-50%,-100%)translateY(2px)}.bridgerte__toolbar-tooltip[data-visible=true]{opacity:1;transform:translate(-50%,-100%)translateY(0)}.bridgerte__panel,.bridgerte__floating-menu{border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-panel)}.bridgerte__floating-menu{z-index:calc(var(--bridgerte-z-index-toolbar) + 1);min-width:180px;padding:6px}.bridgerte__menu-item{border-radius:var(--bridgerte-radius);width:100%;min-height:34px;color:var(--bridgerte-color-text);font:inherit;text-align:left;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;gap:8px;padding:0 8px;display:flex}.bridgerte__menu-item:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);outline:none}.bridgerte__menu-item[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__menu-item:disabled,.bridgerte__menu-item[aria-disabled=true]{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__menu-icon-text{text-overflow:ellipsis;white-space:nowrap;flex:none;display:inline-block;overflow:hidden}.bridgerte__slash-command-menu{overscroll-behavior:contain;scrollbar-width:thin;touch-action:pan-y;-webkit-overflow-scrolling:touch;gap:2px;width:min(120px,100vw - 24px);min-width:0;max-height:min(232px,100vh - 24px);padding:4px;display:grid;overflow-y:auto}.bridgerte__slash-command-menu[hidden]{display:none}.bridgerte__slash-command-anchor{pointer-events:none;width:1px;position:fixed}.bridgerte__slash-command-item{text-align:left;flex-direction:row;justify-content:flex-start;align-items:center;gap:4px;min-height:30px;padding:0 8px}.bridgerte__slash-command-item-icon{width:18px;height:18px;color:var(--bridgerte-color-text-muted);flex:none;place-items:center;display:inline-grid}.bridgerte__slash-command-item-title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:13px;font-weight:700;line-height:1.2;overflow:hidden}.bridgerte__slash-command-item-description{color:var(--bridgerte-color-text-muted);font-size:12px;line-height:1.2;display:none}.bridgerte__slash-command-status{color:var(--bridgerte-color-text-muted);text-align:center;padding:8px;font-size:13px;line-height:1.3}.bridgerte__mention{border-radius:calc(var(--bridgerte-radius) - 2px);max-width:100%;color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);white-space:nowrap;align-items:center;padding:0 3px;display:inline-flex}.bridgerte__mention-menu{overscroll-behavior:contain;scrollbar-width:thin;touch-action:pan-y;-webkit-overflow-scrolling:touch;gap:2px;width:min(120px,100vw - 24px);min-width:0;max-height:min(232px,100vh - 24px);padding:4px;display:grid;overflow-y:auto}.bridgerte__mention-menu[hidden]{display:none}.bridgerte__mention-anchor{pointer-events:none;width:1px;position:fixed}.bridgerte__mention-item{text-align:left;flex-direction:row;justify-content:flex-start;align-items:center;gap:4px;min-height:30px;padding:0 8px}.bridgerte__mention-item-avatar,.bridgerte__mention-item-icon{border-radius:50%;flex:none;width:18px;height:18px}.bridgerte__mention-item-avatar{object-fit:cover;background:var(--bridgerte-color-active-bg)}.bridgerte__mention-item-icon{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-active-bg);place-items:center;font-size:12px;line-height:1;display:inline-grid}.bridgerte__mention-item-title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:13px;font-weight:700;line-height:1.2;overflow:hidden}.bridgerte__mention-item-description{color:var(--bridgerte-color-text-muted);font-size:12px;line-height:1.2;display:none}.bridgerte__mention-status{color:var(--bridgerte-color-text-muted);text-align:center;padding:8px;font-size:13px;line-height:1.3}.bridgerte__hoverbar{gap:2px;width:max-content;min-width:0;max-width:calc(100vw - 24px);padding:4px;display:flex}.bridgerte__hoverbar[hidden]{display:none}.bridgerte__hoverbar-anchor{pointer-events:none;position:fixed}.bridgerte__hoverbar-separator{width:1px;height:var(--bridgerte-hoverbar-button-size);background:var(--bridgerte-color-border);margin:0 2px}.bridgerte__hoverbar-button{width:var(--bridgerte-hoverbar-button-size);min-width:var(--bridgerte-hoverbar-button-size);height:var(--bridgerte-hoverbar-button-size);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text-muted);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;justify-content:center;align-items:center;font-size:12px;font-weight:700;line-height:1;display:inline-flex;overflow:hidden}.bridgerte__hoverbar-button[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__hoverbar-button:disabled{color:var(--bridgerte-color-disabled);cursor:not-allowed}.bridgerte__hoverbar-button:focus-visible{box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__hoverbar-button>svg,.bridgerte__hoverbar-button>.bridgerte__menu-icon-text{width:calc(var(--bridgerte-hoverbar-button-size) - 12px);height:calc(var(--bridgerte-hoverbar-button-size) - 12px);flex:none}.bridgerte__dialog-backdrop{z-index:var(--bridgerte-z-index-toolbar);opacity:0;pointer-events:none;background:0 0;position:fixed;top:0;right:0;bottom:0;left:0}.bridgerte__dialog-backdrop[data-visible=true]{opacity:1;pointer-events:auto}.bridgerte__dialog{z-index:calc(var(--bridgerte-z-index-toolbar) + 2);width:min(220px,100vw - 24px);max-height:calc(var(--bridgerte-dialog-visible-height,100vh) - 32px);opacity:0;border:1px solid var(--bridgerte-color-border);border-radius:var(--bridgerte-radius);color:var(--bridgerte-color-text);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-panel);font:inherit;pointer-events:none;transition:opacity .12s,transform .12s;display:grid;position:fixed;top:0;left:0;transform:translateY(-4px)scale(.98)}.bridgerte__dialog[data-visible=true]{opacity:1;pointer-events:auto;transform:translateY(0)scale(1)}.bridgerte__code-block-menu{width:min(var(--bridgerte-dialog-anchor-width),calc(100vw - 24px));max-height:min(360px,calc(var(--bridgerte-dialog-visible-height,100vh) - 32px));border-color:var(--bridgerte-color-border);background:var(--bridgerte-color-panel);box-shadow:var(--bridgerte-shadow-popup)}.bridgerte__code-block-menu .bridgerte__dialog-content{min-height:0;max-height:inherit;overflow:hidden}.bridgerte__code-block-menu-list{max-height:min(340px,calc(var(--bridgerte-dialog-visible-height,100vh) - 48px));overscroll-behavior:contain;scrollbar-width:thin;touch-action:pan-y;-webkit-overflow-scrolling:touch;gap:2px;padding:8px;display:grid;overflow-y:auto}.bridgerte__code-block-menu-item{min-height:var(--bridgerte-payload-panel-field-height);border-radius:calc(var(--bridgerte-radius) - 2px);padding:0 12px}.bridgerte__payload-panel{padding:6px}.bridgerte__payload-panel-title{min-height:var(--bridgerte-payload-panel-title-height);color:var(--bridgerte-color-text);justify-content:space-between;align-items:center;gap:8px;padding:2px 4px 6px;font-size:13px;font-weight:700;line-height:1.2;display:flex}.bridgerte__payload-panel-clear{color:var(--bridgerte-color-text-muted);font:inherit;text-align:right;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;flex:none;padding:0;font-size:12px;font-weight:600;line-height:1}.bridgerte__payload-panel-clear:focus-visible{color:var(--bridgerte-color-primary);text-underline-offset:.18em;outline:none;text-decoration:underline}.bridgerte__payload-panel-field{gap:7px;display:grid}.bridgerte__payload-panel-option-list{gap:2px;display:grid}.bridgerte__payload-panel-color-picker{width:calc(var(--bridgerte-payload-panel-color-wheel-size) + var(--bridgerte-payload-panel-color-swatch-width) * 2 + 20px);justify-self:center;place-items:center;max-width:100%;display:grid;position:relative}.bridgerte__payload-panel-color-wheel{width:var(--bridgerte-payload-panel-color-wheel-size);aspect-ratio:1;border:1px solid var(--bridgerte-color-border);background:radial-gradient(circle,var(--bridgerte-color-bg) 0%,transparent 68%),conic-gradient(from 90deg,red,#ff0,#0f0,#0ff,#00f,#f0f,red);cursor:crosshair;touch-action:none;border-radius:999px;position:relative}.bridgerte__payload-panel-color-wheel:focus-visible{box-shadow:0 0 0 3px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-color-wheel-handle{width:var(--bridgerte-payload-panel-color-handle-size);height:var(--bridgerte-payload-panel-color-handle-size);border:2px solid var(--bridgerte-color-bg);box-shadow:0 0 0 1px var(--bridgerte-color-border),var(--bridgerte-shadow-panel);opacity:0;pointer-events:none;border-radius:999px;position:absolute;transform:translate(-50%,-50%)}.bridgerte__payload-panel-color-wheel[data-active=true] .bridgerte__payload-panel-color-wheel-handle{opacity:1}.bridgerte__payload-panel-color-preview{border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);min-height:24px;box-shadow:inset 0 0 0 1px var(--bridgerte-color-panel)}.bridgerte__payload-panel-color-preview[data-empty=true]{background:linear-gradient(45deg,transparent 45%,var(--bridgerte-color-border) 45%,var(--bridgerte-color-border) 55%,transparent 55%),linear-gradient(-45deg,transparent 45%,var(--bridgerte-color-border) 45%,var(--bridgerte-color-border) 55%,transparent 55%),var(--bridgerte-color-bg);background-position:50%;background-size:12px 12px}.bridgerte__payload-panel-color-actions{align-items:center;gap:6px;display:flex}.bridgerte__payload-panel-color-actions[data-layout=sides]{pointer-events:none;justify-content:space-between;position:absolute;top:0;right:0;bottom:0;left:0}.bridgerte__payload-panel-color-actions[data-layout=grid]{flex-wrap:wrap;justify-content:center;margin-top:6px}.bridgerte__payload-panel-color-swatch{width:var(--bridgerte-payload-panel-color-swatch-width);height:var(--bridgerte-payload-panel-color-swatch-height);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);background:var(--bridgerte-color-bg);box-shadow:inset 0 0 0 1px var(--bridgerte-color-panel);cursor:pointer;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent;padding:0}.bridgerte__payload-panel-color-swatch:focus-visible{border-color:var(--bridgerte-color-primary);box-shadow:inset 0 0 0 1px var(--bridgerte-color-bg),0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-text-field{color:var(--bridgerte-color-text-muted);gap:5px;font-size:12px;font-weight:600;line-height:1.2;display:grid}.bridgerte__payload-panel-text-input{width:100%;min-height:var(--bridgerte-payload-panel-field-height);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);background:var(--bridgerte-color-bg);font:inherit;-webkit-tap-highlight-color:transparent;padding:0 10px;font-size:13px}.bridgerte__payload-panel-text-input:focus-visible{border-color:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-table-grid{grid-template-columns:repeat(var(--bridgerte-payload-panel-table-cols),var(--bridgerte-payload-panel-table-cell-size));touch-action:none;-webkit-tap-highlight-color:transparent;justify-content:center;gap:2px;max-width:100%;padding:2px;display:grid}.bridgerte__payload-panel-table-cell{width:var(--bridgerte-payload-panel-table-cell-size);height:var(--bridgerte-payload-panel-table-cell-size);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 4px);background:var(--bridgerte-color-bg);cursor:pointer;-webkit-tap-highlight-color:transparent;padding:0}.bridgerte__payload-panel-table-cell[data-active=true]{border-color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-table-cell:focus-visible{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-table-status{min-height:18px;color:var(--bridgerte-color-text-muted);text-align:center;font-size:12px;font-weight:600;line-height:1.5}.bridgerte__payload-panel-submit{min-height:var(--bridgerte-payload-panel-field-height);border:1px solid var(--bridgerte-color-border);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-bg);background:var(--bridgerte-color-primary);font:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;padding:0 10px;font-size:13px;font-weight:700}.bridgerte__payload-panel-submit:focus-visible{box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}.bridgerte__payload-panel-option{min-height:var(--bridgerte-payload-panel-option-height);border-radius:calc(var(--bridgerte-radius) - 2px);color:var(--bridgerte-color-text);font:inherit;text-align:left;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;background:0 0;border:0;align-items:center;padding:0 7px;display:flex}.bridgerte__payload-panel-option[data-active=true]{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-option:focus-visible{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg);outline:none}@media(hover:hover)and (pointer:fine){.bridgerte__code-block-control:hover{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel)}.bridgerte__toolbar-button:hover{border-color:var(--bridgerte-color-active-bg);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__code-block-menu-item:hover,.bridgerte__media-controls-button:hover,.bridgerte__table-controls-button:hover,.bridgerte__hoverbar-button:hover,.bridgerte__payload-panel-option:hover,.bridgerte__mention-item:hover,.bridgerte__slash-command-item:hover,.bridgerte__menu-item:hover{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-clear:hover{color:var(--bridgerte-color-primary)}.bridgerte__payload-panel-color-wheel:hover{box-shadow:0 0 0 3px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-table-cell:hover{border-color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-color-swatch:hover{border-color:var(--bridgerte-color-primary);box-shadow:inset 0 0 0 1px var(--bridgerte-color-bg),0 0 0 2px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-submit:hover{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg)}}@media(hover:none),(pointer:coarse){.bridgerte__code-block-control:active,.bridgerte__code-block-control[data-pressed=true]{color:var(--bridgerte-color-text-muted);background:var(--bridgerte-color-panel)}.bridgerte__toolbar-button:active,.bridgerte__toolbar-button[data-pressed=true]{border-color:var(--bridgerte-color-active-bg);color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__code-block-menu-item:active,.bridgerte__code-block-menu-item[data-pressed=true],.bridgerte__media-controls-button:active,.bridgerte__media-controls-button[data-pressed=true],.bridgerte__table-controls-button:active,.bridgerte__table-controls-button[data-pressed=true],.bridgerte__hoverbar-button:active,.bridgerte__hoverbar-button[data-pressed=true],.bridgerte__payload-panel-option:active,.bridgerte__payload-panel-option[data-pressed=true],.bridgerte__mention-item:active,.bridgerte__mention-item[data-pressed=true],.bridgerte__slash-command-item:active,.bridgerte__slash-command-item[data-pressed=true],.bridgerte__menu-item[data-pressed=true],.bridgerte__menu-item:active{color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-clear:active,.bridgerte__payload-panel-clear[data-pressed=true]{color:var(--bridgerte-color-primary)}.bridgerte__payload-panel-color-wheel:active,.bridgerte__payload-panel-color-wheel[data-pressed=true]{box-shadow:0 0 0 3px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-table-cell:active,.bridgerte__payload-panel-table-cell[data-pressed=true]{border-color:var(--bridgerte-color-primary);background:var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-color-swatch:active,.bridgerte__payload-panel-color-swatch[data-pressed=true]{border-color:var(--bridgerte-color-primary);box-shadow:inset 0 0 0 1px var(--bridgerte-color-bg),0 0 0 2px var(--bridgerte-color-active-bg)}.bridgerte__payload-panel-submit:active,.bridgerte__payload-panel-submit[data-pressed=true]{border-color:var(--bridgerte-color-primary);box-shadow:0 0 0 2px var(--bridgerte-color-active-bg)}}@media(max-width:760px){.bridgerte{min-height:220px}.bridgerte__toolbar-button{min-width:38px;height:38px}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bridgerte",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Cross-platform rich text editor with WebView bridge support.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-BWi3d-Zp.js","sources":["../../dom/src/menuIcon/uiIcons.ts","../../dom/src/richTextToolbar/groupMenuKeyboard.ts","../../dom/src/richTextToolbar/render.ts","../../dom/src/richTextToolbar/index.ts","../../dom/src/htmlContent/index.ts"],"sourcesContent":["/**\r\n * DOM UI chrome icon 表。\r\n *\r\n * 这里放 toolbar 收纳入口、下拉箭头这类控件自身图标。它们不属于 `MenuItem.icon`\r\n * 跨端 schema,也不应该进入 `defaultMenuIcons` 的 schema 对齐检查。\r\n */\r\nexport const defaultMenuUiIcons = {\r\n toolbarGroup: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-ellipsis\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\r\n </svg>\r\n `,\r\n chevronDown: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-chevron-down\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"12\"\r\n height=\"12\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n `\r\n} as const;\r\n","export const getEnabledGroupMenuButtons = (menuElement: HTMLElement) => (\r\n Array.from(\r\n menuElement.querySelectorAll<HTMLButtonElement>('.bridgerte__toolbar-group-menu-item')\r\n ).filter((button) => !button.disabled)\r\n);\r\n\r\nexport const focusToolbarGroupMenuItem = (menuElement: HTMLElement, index: number) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const nextButton = buttons[index];\r\n\r\n if (nextButton) nextButton.focus();\r\n};\r\n\r\nexport const focusFirstToolbarGroupMenuItem = (menuElement: HTMLElement) => {\r\n /*\r\n * group menu 使用 ARIA menu 语义,打开后焦点必须进入第一个可操作项。\r\n * 这样键盘用户可以继续用方向键浏览,而不是停留在展开按钮上。\r\n */\r\n focusToolbarGroupMenuItem(menuElement, 0);\r\n};\r\n\r\nexport const handleToolbarGroupMenuKeyDown = (\r\n event: KeyboardEvent,\r\n menuElement: HTMLElement,\r\n returnButton: HTMLButtonElement,\r\n executeToolbarButton: (button: HTMLButtonElement) => void,\r\n closeGroupMenu: () => void\r\n) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const activeIndex = document.activeElement instanceof HTMLButtonElement\r\n ? buttons.indexOf(document.activeElement)\r\n : -1;\r\n const focusByOffset = (offset: number) => {\r\n if (buttons.length === 0) return;\r\n\r\n const baseIndex = activeIndex >= 0 ? activeIndex : 0;\r\n const nextIndex = (baseIndex + offset + buttons.length) % buttons.length;\r\n\r\n buttons[nextIndex]?.focus();\r\n };\r\n\r\n /*\r\n * ARIA menu 语义要求支持 roving focus。这里不改 toolbar 的横向键盘模型,\r\n * 只在已打开的纵向收纳菜单内处理上下方向、首尾跳转和执行/关闭。\r\n */\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n focusByOffset(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n focusByOffset(-1);\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n buttons[0]?.focus();\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n buttons.at(-1)?.focus();\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n if (document.activeElement instanceof HTMLButtonElement) {\r\n event.preventDefault();\r\n executeToolbarButton(document.activeElement);\r\n closeGroupMenu();\r\n returnButton.focus();\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n returnButton.focus();\r\n closeGroupMenu();\r\n break;\r\n default:\r\n break;\r\n }\r\n};\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport type { MenuItem, ResolvedToolbarItem } from '@bridgerte/native-spec';\r\nimport {\r\n appendMenuIcon,\r\n defaultMenuIcons,\r\n defaultMenuUiIcons\r\n} from './icons';\r\nimport { getMenuStateForItem } from '../menuRuntime';\r\nimport type {\r\n RichTextToolbarIcons,\r\n ToolbarGroupMenuState\r\n} from './type';\r\n\r\nexport const toolbarGroupButtonSelector = 'button[data-bridgerte-toolbar-group-id]';\r\nexport const toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\r\n// 可执行按钮同时覆盖 toolbar 主按钮和 group menu 子项,避免浮层子菜单绕过统一命令入口。\r\nexport const toolbarExecutableButtonSelector = [\n toolbarButtonSelector,\n '.bridgerte__toolbar-group-menu-item'\n].join(',');\n\r\nconst getGroupMenuState = (items: MenuItem[], commandStates: CommandState[]) => {\r\n const itemStates = items.map((item) => getMenuStateForItem(item, commandStates));\r\n\r\n return {\r\n active: itemStates.some((state) => state.active),\r\n disabled: itemStates.length > 0 && itemStates.every((state) => state.disabled)\r\n };\r\n};\r\n\r\nconst renderToolbarButton = (\r\n groupElement: HTMLElement,\r\n item: MenuItem,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n // icon 兜底顺序固定为:业务覆盖 > DOM 默认 SVG > label 文本。\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button';\r\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n if (enableTooltip) button.dataset.tooltip = item.label;\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n\r\n groupElement.append(button);\r\n};\r\n\r\nconst renderToolbarGroupButton = (\r\n groupElement: HTMLElement,\r\n toolbarItem: Extract<ResolvedToolbarItem, { type: 'group' }>,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const button = document.createElement('button');\r\n const groupState = getGroupMenuState(toolbarItem.items, commandStates);\r\n const iconSvg = toolbarItem.icon\r\n ? icons[toolbarItem.icon] ?? defaultMenuIcons[toolbarItem.icon]\r\n : defaultMenuUiIcons.toolbarGroup;\r\n const indicator = document.createElement('span');\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button bridgerte__toolbar-group-button';\r\n button.disabled = groupState.disabled;\r\n button.dataset.active = String(groupState.active);\r\n button.dataset.bridgerteToolbarGroupId = toolbarItem.key;\r\n button.dataset.open = 'false';\r\n button.setAttribute('aria-label', toolbarItem.title);\r\n button.setAttribute('aria-haspopup', 'menu');\r\n button.setAttribute('aria-expanded', 'false');\r\n button.setAttribute('aria-pressed', String(groupState.active));\r\n if (enableTooltip) button.dataset.tooltip = toolbarItem.title;\r\n\r\n appendMenuIcon(button, iconSvg, toolbarItem.title);\r\n\r\n indicator.className = 'bridgerte__toolbar-group-indicator';\r\n indicator.setAttribute('aria-hidden', 'true');\r\n indicator.innerHTML = defaultMenuUiIcons.chevronDown;\r\n button.append(indicator);\r\n groupElement.append(button);\r\n};\r\n\r\n/**\r\n * 渲染 toolbar 横向主入口。\n *\n * 字符串菜单直接渲染为按钮,`|` 渲染分割线。\n * 只有用户显式声明的 group 配置才生成收纳入口,避免 schema 隐式改变 DOM 结构。\n */\r\nexport const renderToolbar = (\r\n toolbarElement: HTMLElement,\r\n toolbarItems: ResolvedToolbarItem[],\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n toolbarElement.textContent = '';\r\n\r\n toolbarItems.forEach((toolbarItem) => {\n if (toolbarItem.type === 'separator') {\n const separatorElement = document.createElement('span');\n\n separatorElement.className = 'bridgerte__toolbar-separator';\n separatorElement.dataset.separatorId = toolbarItem.key;\r\n separatorElement.setAttribute('aria-hidden', 'true');\r\n toolbarElement.append(separatorElement);\r\n return;\n }\n\n if (toolbarItem.type === 'button') {\n renderToolbarButton(\n toolbarElement,\n toolbarItem.item,\n commandStates,\n icons,\n enableTooltip\n );\n return;\n }\n\n /*\n * 收纳菜单是用户在 toolbarConfig 里显式声明的结构;普通菜单不会自动生成 DOM 包裹,\n * 显示分组完全交给用户用 group 配置或 `|` 控制。\n */\n const groupElement = document.createElement('div');\n\n groupElement.className = 'bridgerte__toolbar-group';\n groupElement.dataset.group = toolbarItem.key;\n groupElement.setAttribute('aria-label', toolbarItem.title);\n toolbarElement.append(groupElement);\n\n renderToolbarGroupButton(\n groupElement,\n toolbarItem,\n commandStates,\n icons,\n enableTooltip\r\n );\r\n });\r\n};\r\n\r\n/**\r\n * 渲染 group button 打开的纵向收纳菜单。\r\n *\r\n * 浮层只展示 MenuItem 子项并复用现有 item id,点击执行仍由 index.ts 统一走 EditorAPI。\r\n */\r\nexport const renderToolbarGroupMenu = (\r\n menuElement: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons\r\n) => {\r\n menuElement.textContent = '';\r\n\r\n if (!groupMenuState) {\r\n menuElement.dataset.visible = 'false';\r\n return;\r\n }\r\n\r\n groupMenuState.items.forEach((item) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n const labelElement = document.createElement('span');\n\n button.type = 'button';\n button.className = 'bridgerte__menu-item bridgerte__toolbar-group-menu-item';\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('role', 'menuitem');\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n labelElement.className = 'bridgerte__toolbar-group-menu-label';\r\n labelElement.textContent = item.label;\r\n button.append(labelElement);\r\n menuElement.append(button);\r\n });\r\n\r\n menuElement.dataset.visible = 'true';\r\n menuElement.style.minWidth = `${groupMenuState.button.offsetWidth}px`;\r\n};\r\n\r\nexport const syncToolbarGroupButtonState = (\r\n container: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null\r\n) => {\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector).forEach((button) => {\r\n const open = groupMenuState?.groupKey === button.dataset.bridgerteToolbarGroupId;\r\n\r\n button.dataset.open = String(open);\r\n button.setAttribute('aria-expanded', String(open));\r\n });\r\n};\r\n\r\nexport const findToolbarGroupMenuItem = (\r\n toolbarItems: ResolvedToolbarItem[],\r\n groupKey: string | undefined\r\n) => toolbarItems.find((item): item is Extract<ResolvedToolbarItem, { type: 'group' }> => (\r\n item.type === 'group' && item.key === groupKey\r\n));\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport {\r\n defaultMenuSchema,\r\n resolveToolbarMenu\r\n} from '@bridgerte/native-spec';\r\nimport { createFloatingLayer, type RichTextFloatingLayer } from '../floatingLayer';\r\nimport { bindTouchPressedState } from '../interactionState';\r\nimport {\r\n getPayloadPanelCurrentValues,\r\n resolveMenuSchemaForDom\r\n} from '../menuRuntime';\r\nimport {\r\n focusFirstToolbarGroupMenuItem,\r\n handleToolbarGroupMenuKeyDown\r\n} from './groupMenuKeyboard';\r\nimport {\r\n findToolbarGroupMenuItem,\r\n renderToolbar,\r\n renderToolbarGroupMenu,\r\n syncToolbarGroupButtonState,\r\n toolbarExecutableButtonSelector,\r\n toolbarGroupButtonSelector\r\n} from './render';\r\nimport type {\r\n RichTextToolbarAPI,\r\n ToolbarGroupMenuState,\r\n RichTextToolbarOptions,\r\n ToolbarDragState\r\n} from './type';\r\n\r\nconst toolbarDragClickThresholdPx = 4;\r\nconst toolbarTooltipOffsetPx = 8;\r\nconst toolbarGroupMenuOffsetPx = 6;\r\n\r\nexport type * from './type';\r\n\r\nconst canUseHoverTooltip = () => (\r\n typeof window !== 'undefined'\r\n && window.matchMedia?.('(hover: hover) and (pointer: fine)').matches === true\r\n);\r\n\r\nconst getToolbarButtonFromTarget = (target: EventTarget | null) => {\r\n /*\r\n * 图标覆盖常用 SVG,H5 pointer 事件可能落在 svg/path 上。\r\n * 这里用 Element 而不是 HTMLElement,保证触屏兜底和 click 都能向上命中真实按钮。\r\n */\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarExecutableButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\nconst getToolbarGroupButtonFromTarget = (target: EventTarget | null) => {\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\n/**\r\n * 创建独立菜单实例。\r\n *\r\n * toolbar/tabbar 只订阅 EditorAPI 状态并派发命令,不接触编辑器内部 DOM 或 Lexical 实例。\r\n */\r\nexport function createRichTextToolbar(\r\n container: HTMLElement,\r\n options: RichTextToolbarOptions\r\n): RichTextToolbarAPI {\r\n const placement = options.placement ?? 'top';\r\n const menuSchema = resolveMenuSchemaForDom(options.menuSchema ?? defaultMenuSchema, {\r\n menuLabels: options.menuLabels,\r\n payloadPanelConfig: options.payloadPanelConfig\r\n });\r\n const toolbarItems = resolveToolbarMenu(options.toolbarConfig, menuSchema);\r\n /*\r\n * click 事件只需要能执行命令的菜单项。分割线和 group 容器是渲染结构,\r\n * 先在这里摊平,后续点击时就不用理解 toolbarConfig 的展示层级。\r\n */\r\n const executableMenuItems = toolbarItems.flatMap((toolbarItem) => (\r\n toolbarItem.type === 'button' ? [toolbarItem.item]\r\n : toolbarItem.type === 'group' ? toolbarItem.items\r\n : []\r\n ));\r\n const icons = options.icons ?? {};\r\n /*\r\n * tooltip 只属于 PC 精细指针体验。H5 上即使没有原生 title,部分浏览器也会把 hover/mouseover\r\n * 模拟成首触摸状态,导致第一次点像是只唤醒提示;所以触屏端不写 tooltip 数据也不挂监听。\r\n */\r\n const enableTooltip = canUseHoverTooltip();\r\n const tooltipElement = document.createElement('div');\r\n const groupMenuElement = document.createElement('div');\r\n const overlayHost = container.closest('.bridgerte') ?? container;\r\n let destroyed = false;\r\n let dragState: ToolbarDragState | null = null;\r\n let shouldSuppressNextClick = false;\r\n let latestCommandStates = options.editor.getCommandStates();\r\n let groupMenuState: ToolbarGroupMenuState | null = null;\r\n let groupMenuFloatingLayer: RichTextFloatingLayer | null = null;\r\n const clearToolbarPressedState = bindTouchPressedState(container, {\r\n targetSelector: [\r\n 'button[data-bridgerte-toolbar-item-id]',\r\n 'button[data-bridgerte-toolbar-group-id]'\r\n ].join(',')\r\n });\r\n const clearGroupMenuPressedState = bindTouchPressedState(groupMenuElement, {\r\n targetSelector: '.bridgerte__toolbar-group-menu-item'\r\n });\r\n\r\n const mountToolbarOverlays = () => {\r\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\r\n overlayHost.append(tooltipElement);\r\n overlayHost.append(groupMenuElement);\r\n };\r\n\r\n const closeGroupMenuFloatingLayer = () => {\r\n groupMenuFloatingLayer?.setOpen(false);\r\n groupMenuFloatingLayer?.destroy();\r\n groupMenuFloatingLayer = null;\r\n };\r\n\r\n const openGroupMenuFloatingLayer = () => {\r\n if (!groupMenuState) return;\r\n\r\n closeGroupMenuFloatingLayer();\r\n /*\r\n * group menu 和 hoverbar/mention/slash 一样属于轻浮层,必须走 floatingLayer。\r\n * 这里按 toolbar placement 给出首选方向,真正的翻转、键盘可视区和左右夹紧交给\r\n * createFloatingLayer 内部的 visualViewport + flip + shift + clamp 统一处理。\r\n */\r\n groupMenuFloatingLayer = createFloatingLayer(groupMenuState.button, groupMenuElement, {\r\n placement: placement === 'bottom' ? 'top-start' : 'bottom-start',\r\n offset: toolbarGroupMenuOffsetPx,\r\n strategy: 'fixed'\r\n });\r\n groupMenuFloatingLayer.setOpen(true);\r\n };\r\n\r\n const closeGroupMenu = () => {\r\n closeGroupMenuFloatingLayer();\r\n groupMenuState = null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n };\r\n\r\n const renderStates = (states: CommandState[]) => {\r\n if (destroyed) return;\r\n\r\n latestCommandStates = states;\r\n if (groupMenuState) closeGroupMenuFloatingLayer();\r\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\r\n mountToolbarOverlays();\r\n if (groupMenuState) {\r\n const nextButton = Array.from(\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n ).find((button) => button.dataset.bridgerteToolbarGroupId === groupMenuState?.groupKey);\r\n const nextGroupItem = findToolbarGroupMenuItem(toolbarItems, groupMenuState.groupKey);\r\n\r\n groupMenuState = nextButton && nextGroupItem\r\n ? {\r\n groupKey: groupMenuState.groupKey,\r\n button: nextButton,\r\n items: nextGroupItem.items\r\n }\r\n : null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n if (groupMenuState) openGroupMenuFloatingLayer();\r\n }\r\n };\r\n\r\n const update = () => {\r\n if (destroyed) return;\r\n\r\n renderStates(options.editor.getCommandStates());\r\n };\r\n\r\n const hideTooltip = () => {\r\n tooltipElement.dataset.visible = 'false';\r\n tooltipElement.textContent = '';\r\n };\r\n\r\n const showTooltip = (button: HTMLButtonElement) => {\r\n const tooltipText = button.dataset.tooltip;\r\n\r\n if (!enableTooltip || !tooltipText || dragState) return;\r\n\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n tooltipElement.textContent = tooltipText;\r\n tooltipElement.dataset.visible = 'true';\r\n tooltipElement.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\r\n tooltipElement.style.top = `${buttonRect.top - toolbarTooltipOffsetPx}px`;\r\n };\r\n\r\n const handleTooltipTarget = (event: Event) => {\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (button) {\r\n showTooltip(button);\r\n }\r\n };\r\n\r\n const handleTooltipLeave = (event: MouseEvent) => {\r\n const relatedTarget = event.relatedTarget;\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (\r\n button\r\n && relatedTarget instanceof Node\r\n && button.contains(relatedTarget)\r\n ) return;\r\n\r\n hideTooltip();\r\n };\r\n\r\n const stopToolbarDrag = () => {\r\n dragState = null;\r\n\r\n delete container.dataset.dragging;\r\n // 拖动过程中监听挂在 document 上,松手或 destroy 必须统一清掉,避免离开 toolbar 后残留滚动状态。\r\n document.removeEventListener('pointermove', handlePointerMove);\r\n document.removeEventListener('pointerup', handlePointerUp);\r\n document.removeEventListener('pointercancel', handlePointerUp);\r\n };\r\n\r\n const handlePointerMove = (event: PointerEvent) => {\r\n if (!dragState) return;\r\n\r\n const deltaX = dragState.startClientX - event.clientX;\r\n\r\n if (Math.abs(deltaX) > toolbarDragClickThresholdPx) {\r\n dragState.hasDragged = true;\r\n shouldSuppressNextClick = true;\r\n hideTooltip();\r\n closeGroupMenu();\r\n }\r\n\r\n container.scrollLeft = dragState.startScrollLeft + deltaX;\r\n };\r\n\r\n const handlePointerUp = (event: PointerEvent) => {\r\n const currentDragState = dragState;\r\n\r\n stopToolbarDrag();\r\n if (\r\n currentDragState\r\n && event.type !== 'pointercancel'\r\n && currentDragState.pointerType !== 'mouse'\r\n && !currentDragState.hasDragged\r\n && currentDragState.startButton\r\n ) {\r\n executeToolbarButton(currentDragState.startButton);\r\n shouldSuppressNextClick = true;\r\n }\r\n };\r\n\r\n const handlePointerDown = (event: PointerEvent) => {\r\n if (event.pointerType === 'mouse' && event.button !== 0) return;\r\n\r\n const startButton = getToolbarButtonFromTarget(event.target);\r\n\r\n // 点击和拖动 toolbar 都要保留编辑区 selection,命令才能继续作用在原选区。\r\n event.preventDefault();\r\n dragState = {\r\n startClientX: event.clientX,\r\n startScrollLeft: container.scrollLeft,\r\n pointerType: event.pointerType,\r\n hasDragged: false,\r\n startButton: startButton ?? undefined\r\n };\r\n container.dataset.dragging = 'true';\r\n hideTooltip();\r\n // pointermove 放到 document,保证用户按住 X 轴拖出 toolbar 后仍能完成滚动和释放。\r\n document.addEventListener('pointermove', handlePointerMove);\r\n document.addEventListener('pointerup', handlePointerUp);\r\n document.addEventListener('pointercancel', handlePointerUp);\r\n };\r\n\r\n const executeToolbarButton = (button: HTMLButtonElement) => {\r\n if (!(button instanceof HTMLButtonElement) || button.disabled) return;\r\n\r\n const menuItem = executableMenuItems.find((item) => (\r\n item.id === button.dataset.bridgerteToolbarItemId\r\n ));\r\n\r\n if (!menuItem) return;\r\n\r\n if (menuItem.payloadPanel) {\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n /*\r\n * 带 payloadPanel 的菜单不直接执行基础 command,而是发起参数请求。\r\n * DOM 内置面板和业务/RN/Flutter 自绘都走同一个 request,避免后续颜色、\r\n * 字体、链接等参数菜单各自发明一套协议。\r\n */\r\n options.editor.requestPayloadPanel({\r\n menuId: menuItem.id,\r\n command: menuItem.command,\r\n panel: menuItem.payloadPanel,\r\n currentValues: getPayloadPanelCurrentValues(menuItem, options.editor.getCommandStates()),\r\n anchorRect: {\r\n x: buttonRect.left,\r\n y: buttonRect.top,\r\n width: buttonRect.width,\r\n height: buttonRect.height\r\n }\r\n });\r\n return;\r\n }\r\n\r\n options.editor.executeCommand(menuItem.command);\r\n };\r\n\r\n const toggleGroupMenu = (button: HTMLButtonElement) => {\r\n const groupItem = findToolbarGroupMenuItem(\r\n toolbarItems,\r\n button.dataset.bridgerteToolbarGroupId\r\n );\r\n\r\n if (!groupItem || button.disabled) return;\r\n\r\n if (groupMenuState?.groupKey === groupItem.key) {\r\n closeGroupMenu();\r\n return;\r\n }\r\n\r\n groupMenuState = {\r\n groupKey: groupItem.key,\r\n button,\r\n items: groupItem.items\r\n };\r\n hideTooltip();\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n openGroupMenuFloatingLayer();\r\n focusFirstToolbarGroupMenuItem(groupMenuElement);\r\n };\r\n\r\n const handleClick = (event: MouseEvent) => {\r\n if (shouldSuppressNextClick) {\r\n shouldSuppressNextClick = false;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n const groupButton = getToolbarGroupButtonFromTarget(event.target);\r\n if (groupButton) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n toggleGroupMenu(groupButton);\r\n return;\r\n }\r\n\r\n const button = getToolbarButtonFromTarget(event.target);\r\n if (!button) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n executeToolbarButton(button);\r\n closeGroupMenu();\r\n };\r\n\r\n const handleGroupMenuPointerDown = (event: PointerEvent) => {\r\n /*\r\n * group 菜单浮层挂在 toolbar 容器外,不能复用容器级 pointerdown。\r\n * 子菜单点击仍要保留编辑区 selection,否则格式命令会丢失原选区。\r\n */\r\n if (event.pointerType === 'mouse' && event.button !== 0) return;\r\n\r\n event.preventDefault();\r\n };\r\n\r\n const handleDocumentClick = (event: MouseEvent) => {\r\n const target = event.target;\r\n\r\n if (\r\n target instanceof Node\r\n && (container.contains(target) || groupMenuElement.contains(target))\r\n ) return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (groupMenuState && groupMenuElement.contains(document.activeElement)) {\r\n handleToolbarGroupMenuKeyDown(\r\n event,\r\n groupMenuElement,\r\n groupMenuState.button,\r\n executeToolbarButton,\r\n closeGroupMenu\r\n );\r\n return;\r\n }\r\n\r\n if (event.key !== 'Escape') return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n container.classList.add('bridgerte__toolbar');\r\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\r\n tooltipElement.dataset.visible = 'false';\r\n groupMenuElement.className = 'bridgerte__floating-menu bridgerte__toolbar-group-menu';\n groupMenuElement.dataset.visible = 'false';\r\n groupMenuElement.setAttribute('role', 'menu');\r\n container.dataset.placement = placement;\r\n container.setAttribute('role', 'toolbar');\r\n container.setAttribute(\r\n 'aria-label',\r\n placement === 'bottom' ? 'BridgeRTE tabbar' : 'BridgeRTE toolbar'\r\n );\r\n container.addEventListener('pointerdown', handlePointerDown, true);\r\n container.addEventListener('click', handleClick);\r\n groupMenuElement.addEventListener('pointerdown', handleGroupMenuPointerDown, true);\r\n groupMenuElement.addEventListener('click', handleClick);\r\n document.addEventListener('click', handleDocumentClick);\r\n document.addEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.addEventListener('mouseover', handleTooltipTarget);\r\n container.addEventListener('mouseout', handleTooltipLeave);\r\n }\r\n container.addEventListener('focusout', hideTooltip);\r\n // 浮层挂在最近的编辑器根容器下,既能继承变量,也不会操作编辑内容 DOM。\r\n mountToolbarOverlays();\r\n\r\n // 独立 toolbar 只订阅 public API 状态,不依赖 DOM 编辑器内部实现。\r\n const unsubscribe = options.editor.subscribeCommandStateChange(renderStates);\r\n\r\n return {\r\n update,\r\n destroy() {\r\n if (destroyed) return;\r\n\r\n destroyed = true;\r\n stopToolbarDrag();\r\n unsubscribe();\r\n closeGroupMenu();\r\n container.removeEventListener('pointerdown', handlePointerDown, true);\r\n container.removeEventListener('click', handleClick);\r\n groupMenuElement.removeEventListener('pointerdown', handleGroupMenuPointerDown, true);\r\n groupMenuElement.removeEventListener('click', handleClick);\r\n document.removeEventListener('click', handleDocumentClick);\r\n document.removeEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.removeEventListener('mouseover', handleTooltipTarget);\r\n container.removeEventListener('mouseout', handleTooltipLeave);\r\n }\r\n clearToolbarPressedState();\r\n clearGroupMenuPressedState();\r\n container.removeEventListener('focusout', hideTooltip);\r\n tooltipElement.remove();\r\n groupMenuElement.remove();\r\n container.classList.remove('bridgerte__toolbar');\r\n delete container.dataset.placement;\r\n container.textContent = '';\r\n container.removeAttribute('role');\r\n container.removeAttribute('aria-label');\r\n }\r\n };\r\n}\r\n","const invisibleTextPattern = /[\\u200B-\\u200D\\uFEFF]/g;\n\n/*\n * HTML 片段里这些元素没有 textContent 也应算有效内容。\n * 纯排版容器不放进来,避免 `<p><br></p>`、空列表项这类编辑器占位被误判为非空。\n */\nconst meaningfulHtmlContentSelector = [\n 'img',\n 'video',\n 'audio',\n 'iframe',\n 'table',\n 'pre',\n 'code',\n 'hr',\n 'figure',\n 'canvas',\n 'svg',\n 'math',\n '[data-type=\"mention\"]'\n].join(',');\n\nconst normalizeHtmlText = (text: string | null | undefined): string => (\n text?.replace(invisibleTextPattern, '').trim() ?? ''\n);\n\n/**\n * 判断一段 HTML 片段是否包含可保存的富文本内容。\n *\n * 这个工具会使用浏览器 template 解析 HTML,适合只拿到 HTML 字符串的业务表单;如果已经持有\n * `EditorContent`,优先使用 core 的 `isEditorContentEmpty()`,避免额外 DOM parse。\n */\nexport const hasMeaningfulHtmlContent = (html: string): boolean => {\n if (!normalizeHtmlText(html)) return false;\n\n const template = document.createElement('template');\n\n template.innerHTML = html;\n\n return Boolean(\n normalizeHtmlText(template.content.textContent)\n || template.content.querySelector(meaningfulHtmlContentSelector)\n );\n};\n"],"names":["defaultMenuUiIcons","getEnabledGroupMenuButtons","menuElement","button","focusToolbarGroupMenuItem","index","nextButton","focusFirstToolbarGroupMenuItem","handleToolbarGroupMenuKeyDown","event","returnButton","executeToolbarButton","closeGroupMenu","buttons","activeIndex","focusByOffset","offset","nextIndex","_a","_b","toolbarGroupButtonSelector","toolbarButtonSelector","toolbarExecutableButtonSelector","getGroupMenuState","items","commandStates","itemStates","item","getMenuStateForItem","state","renderToolbarButton","groupElement","icons","enableTooltip","iconSvg","defaultMenuIcons","appendMenuIcon","renderToolbarGroupButton","toolbarItem","groupState","indicator","renderToolbar","toolbarElement","toolbarItems","separatorElement","renderToolbarGroupMenu","groupMenuState","labelElement","syncToolbarGroupButtonState","container","open","findToolbarGroupMenuItem","groupKey","toolbarDragClickThresholdPx","toolbarTooltipOffsetPx","toolbarGroupMenuOffsetPx","canUseHoverTooltip","getToolbarButtonFromTarget","target","getToolbarGroupButtonFromTarget","createRichTextToolbar","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","groupMenuElement","overlayHost","destroyed","dragState","shouldSuppressNextClick","latestCommandStates","groupMenuFloatingLayer","clearToolbarPressedState","bindTouchPressedState","clearGroupMenuPressedState","mountToolbarOverlays","closeGroupMenuFloatingLayer","openGroupMenuFloatingLayer","createFloatingLayer","renderStates","states","nextGroupItem","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","handleTooltipLeave","relatedTarget","stopToolbarDrag","handlePointerMove","handlePointerUp","deltaX","currentDragState","handlePointerDown","startButton","menuItem","getPayloadPanelCurrentValues","toggleGroupMenu","groupItem","handleClick","groupButton","handleGroupMenuPointerDown","handleDocumentClick","handleKeyDown","unsubscribe","invisibleTextPattern","meaningfulHtmlContentSelector","normalizeHtmlText","text","hasMeaningfulHtmlContent","html","template"],"mappings":"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"}
@@ -1,36 +0,0 @@
1
- "use strict";const O=require("./native-spec.cjs"),m=require("./index-B_g23O7q.cjs"),j={toolbarGroup:`
2
- <svg
3
- aria-hidden="true"
4
- class="lucide lucide-ellipsis"
5
- xmlns="http://www.w3.org/2000/svg"
6
- width="18"
7
- height="18"
8
- viewBox="0 0 24 24"
9
- fill="none"
10
- stroke="currentColor"
11
- stroke-width="2"
12
- stroke-linecap="round"
13
- stroke-linejoin="round"
14
- >
15
- <circle cx="12" cy="12" r="1" />
16
- <circle cx="19" cy="12" r="1" />
17
- <circle cx="5" cy="12" r="1" />
18
- </svg>
19
- `,chevronDown:`
20
- <svg
21
- aria-hidden="true"
22
- class="lucide lucide-chevron-down"
23
- xmlns="http://www.w3.org/2000/svg"
24
- width="12"
25
- height="12"
26
- viewBox="0 0 24 24"
27
- fill="none"
28
- stroke="currentColor"
29
- stroke-width="2"
30
- stroke-linecap="round"
31
- stroke-linejoin="round"
32
- >
33
- <path d="m6 9 6 6 6-6" />
34
- </svg>
35
- `},$=e=>Array.from(e.querySelectorAll(".bridgerte__toolbar-group-menu-item")).filter(t=>!t.disabled),ee=(e,t)=>{const l=$(e)[t];l&&l.focus()},te=e=>{ee(e,0)},oe=(e,t,s,l,u)=>{var c,d;const r=$(t),a=document.activeElement instanceof HTMLButtonElement?r.indexOf(document.activeElement):-1,b=E=>{var v;if(r.length===0)return;const g=((a>=0?a:0)+E+r.length)%r.length;(v=r[g])==null||v.focus()};switch(e.key){case"ArrowDown":e.preventDefault(),b(1);break;case"ArrowUp":e.preventDefault(),b(-1);break;case"Home":e.preventDefault(),(c=r[0])==null||c.focus();break;case"End":e.preventDefault(),(d=r.at(-1))==null||d.focus();break;case"Enter":case" ":document.activeElement instanceof HTMLButtonElement&&(e.preventDefault(),l(document.activeElement),u(),s.focus());break;case"Escape":e.preventDefault(),s.focus(),u();break}},M="button[data-bridgerte-toolbar-group-id]",ne="button[data-bridgerte-toolbar-item-id]",re=[ne,".bridgerte__toolbar-group-menu-item"].join(","),ae=(e,t)=>{const s=e.map(l=>m.getMenuStateForItem(l,t));return{active:s.some(l=>l.active),disabled:s.length>0&&s.every(l=>l.disabled)}},se=(e,t,s,l,u)=>{const r=m.getMenuStateForItem(t,s),a=document.createElement("button"),b=l[t.icon]??m.defaultMenuIcons[t.icon];a.type="button",a.className="bridgerte__toolbar-button",a.disabled=r.disabled,a.dataset.active=String(r.active),a.dataset.bridgerteToolbarItemId=t.id,a.setAttribute("aria-label",t.label),a.setAttribute("aria-pressed",String(r.active)),u&&(a.dataset.tooltip=t.label),m.appendMenuIcon(a,b,t.label),e.append(a)},le=(e,t,s,l,u)=>{const r=document.createElement("button"),a=ae(t.items,s),b=t.icon?l[t.icon]??m.defaultMenuIcons[t.icon]:j.toolbarGroup,c=document.createElement("span");r.type="button",r.className="bridgerte__toolbar-button bridgerte__toolbar-group-button",r.disabled=a.disabled,r.dataset.active=String(a.active),r.dataset.bridgerteToolbarGroupId=t.key,r.dataset.open="false",r.setAttribute("aria-label",t.title),r.setAttribute("aria-haspopup","menu"),r.setAttribute("aria-expanded","false"),r.setAttribute("aria-pressed",String(a.active)),u&&(r.dataset.tooltip=t.title),m.appendMenuIcon(r,b,t.title),c.className="bridgerte__toolbar-group-indicator",c.setAttribute("aria-hidden","true"),c.innerHTML=j.chevronDown,r.append(c),e.append(r)},ie=(e,t,s,l,u)=>{e.textContent="",t.forEach(r=>{if(r.type==="separator"){const b=document.createElement("span");b.className="bridgerte__toolbar-separator",b.dataset.separatorId=r.key,b.setAttribute("aria-hidden","true"),e.append(b);return}if(r.type==="button"){se(e,r.item,s,l,u);return}const a=document.createElement("div");a.className="bridgerte__toolbar-group",a.dataset.group=r.key,a.setAttribute("aria-label",r.title),e.append(a),le(a,r,s,l,u)})},C=(e,t,s,l)=>{if(e.textContent="",!t){e.dataset.visible="false";return}t.items.forEach(u=>{const r=m.getMenuStateForItem(u,s),a=document.createElement("button"),b=l[u.icon]??m.defaultMenuIcons[u.icon],c=document.createElement("span");a.type="button",a.className="bridgerte__menu-item bridgerte__toolbar-group-menu-item",a.disabled=r.disabled,a.dataset.active=String(r.active),a.dataset.bridgerteToolbarItemId=u.id,a.setAttribute("role","menuitem"),a.setAttribute("aria-label",u.label),a.setAttribute("aria-pressed",String(r.active)),m.appendMenuIcon(a,b,u.label),c.className="bridgerte__toolbar-group-menu-label",c.textContent=u.label,a.append(c),e.append(a)}),e.dataset.visible="true",e.style.minWidth=`${t.button.offsetWidth}px`},B=(e,t)=>{e.querySelectorAll(M).forEach(s=>{const l=(t==null?void 0:t.groupKey)===s.dataset.bridgerteToolbarGroupId;s.dataset.open=String(l),s.setAttribute("aria-expanded",String(l))})},X=(e,t)=>e.find(s=>s.type==="group"&&s.key===t),ue=4,ce=8,de=6,pe=()=>{var e;return typeof window<"u"&&((e=window.matchMedia)==null?void 0:e.call(window,"(hover: hover) and (pointer: fine)").matches)===!0},S=e=>{const t=e instanceof Element?e.closest(re):null;return t instanceof HTMLButtonElement?t:null},be=e=>{const t=e instanceof Element?e.closest(M):null;return t instanceof HTMLButtonElement?t:null};function me(e,t){const s=t.placement??"top",l=m.resolveMenuSchemaForDom(t.menuSchema??O.defaultMenuSchema,{menuLabels:t.menuLabels,payloadPanelConfig:t.payloadPanelConfig}),u=O.resolveToolbarMenu(t.toolbarConfig,l),r=u.flatMap(o=>o.type==="button"?[o.item]:o.type==="group"?o.items:[]),a=t.icons??{},b=pe(),c=document.createElement("div"),d=document.createElement("div"),E=e.closest(".bridgerte")??e;let T=!1,g=null,v=!1,x=t.editor.getCommandStates(),i=null,f=null;const V=m.bindTouchPressedState(e,{targetSelector:["button[data-bridgerte-toolbar-item-id]","button[data-bridgerte-toolbar-group-id]"].join(",")}),W=m.bindTouchPressedState(d,{targetSelector:".bridgerte__toolbar-group-menu-item"}),D=()=>{E.append(c),E.append(d)},k=()=>{f==null||f.setOpen(!1),f==null||f.destroy(),f=null},A=()=>{i&&(k(),f=m.createFloatingLayer(i.button,d,{placement:s==="bottom"?"top-start":"bottom-start",offset:de,strategy:"fixed"}),f.setOpen(!0))},h=()=>{k(),i=null,C(d,i,x,a),B(e,i)},G=o=>{if(!T&&(x=o,i&&k(),ie(e,u,o,a,b),D(),i)){const n=Array.from(e.querySelectorAll(M)).find(Z=>Z.dataset.bridgerteToolbarGroupId===(i==null?void 0:i.groupKey)),p=X(u,i.groupKey);i=n&&p?{groupKey:i.groupKey,button:n,items:p.items}:null,C(d,i,x,a),B(e,i),i&&A()}},z=()=>{T||G(t.editor.getCommandStates())},y=()=>{c.dataset.visible="false",c.textContent=""},J=o=>{const n=o.dataset.tooltip;if(!b||!n||g)return;const p=o.getBoundingClientRect();c.textContent=n,c.dataset.visible="true",c.style.left=`${p.left+p.width/2}px`,c.style.top=`${p.top-ce}px`},P=o=>{const n=S(o.target);n&&J(n)},I=o=>{const n=o.relatedTarget,p=S(o.target);p&&n instanceof Node&&p.contains(n)||y()},H=()=>{g=null,delete e.dataset.dragging,document.removeEventListener("pointermove",N),document.removeEventListener("pointerup",L),document.removeEventListener("pointercancel",L)},N=o=>{if(!g)return;const n=g.startClientX-o.clientX;Math.abs(n)>ue&&(g.hasDragged=!0,v=!0,y(),h()),e.scrollLeft=g.startScrollLeft+n},L=o=>{const n=g;H(),n&&o.type!=="pointercancel"&&n.pointerType!=="mouse"&&!n.hasDragged&&n.startButton&&(_(n.startButton),v=!0)},F=o=>{if(o.pointerType==="mouse"&&o.button!==0)return;const n=S(o.target);o.preventDefault(),g={startClientX:o.clientX,startScrollLeft:e.scrollLeft,pointerType:o.pointerType,hasDragged:!1,startButton:n??void 0},e.dataset.dragging="true",y(),document.addEventListener("pointermove",N),document.addEventListener("pointerup",L),document.addEventListener("pointercancel",L)},_=o=>{if(!(o instanceof HTMLButtonElement)||o.disabled)return;const n=r.find(p=>p.id===o.dataset.bridgerteToolbarItemId);if(n){if(n.payloadPanel){const p=o.getBoundingClientRect();t.editor.requestPayloadPanel({menuId:n.id,command:n.command,panel:n.payloadPanel,currentValues:m.getPayloadPanelCurrentValues(n,t.editor.getCommandStates()),anchorRect:{x:p.left,y:p.top,width:p.width,height:p.height}});return}t.editor.executeCommand(n.command)}},Q=o=>{const n=X(u,o.dataset.bridgerteToolbarGroupId);if(!(!n||o.disabled)){if((i==null?void 0:i.groupKey)===n.key){h();return}i={groupKey:n.key,button:o,items:n.items},y(),C(d,i,x,a),B(e,i),A(),te(d)}},w=o=>{if(v){v=!1,o.preventDefault(),o.stopPropagation();return}const n=be(o.target);if(n){o.preventDefault(),o.stopPropagation(),Q(n);return}const p=S(o.target);p&&(o.preventDefault(),o.stopPropagation(),_(p),h())},K=o=>{o.pointerType==="mouse"&&o.button!==0||o.preventDefault()},R=o=>{const n=o.target;n instanceof Node&&(e.contains(n)||d.contains(n))||h()},q=o=>{if(i&&d.contains(document.activeElement)){oe(o,d,i.button,_,h);return}o.key==="Escape"&&h()};e.classList.add("bridgerte__toolbar"),c.className="bridgerte__toolbar-tooltip",c.dataset.visible="false",d.className="bridgerte__floating-menu bridgerte__toolbar-group-menu",d.dataset.visible="false",d.setAttribute("role","menu"),e.dataset.placement=s,e.setAttribute("role","toolbar"),e.setAttribute("aria-label",s==="bottom"?"BridgeRTE tabbar":"BridgeRTE toolbar"),e.addEventListener("pointerdown",F,!0),e.addEventListener("click",w),d.addEventListener("pointerdown",K,!0),d.addEventListener("click",w),document.addEventListener("click",R),document.addEventListener("keydown",q),b&&(e.addEventListener("mouseover",P),e.addEventListener("mouseout",I)),e.addEventListener("focusout",y),D();const Y=t.editor.subscribeCommandStateChange(G);return{update:z,destroy(){T||(T=!0,H(),Y(),h(),e.removeEventListener("pointerdown",F,!0),e.removeEventListener("click",w),d.removeEventListener("pointerdown",K,!0),d.removeEventListener("click",w),document.removeEventListener("click",R),document.removeEventListener("keydown",q),b&&(e.removeEventListener("mouseover",P),e.removeEventListener("mouseout",I)),V(),W(),e.removeEventListener("focusout",y),c.remove(),d.remove(),e.classList.remove("bridgerte__toolbar"),delete e.dataset.placement,e.textContent="",e.removeAttribute("role"),e.removeAttribute("aria-label"))}}}const ge=/[\u200B-\u200D\uFEFF]/g,fe=["img","video","audio","iframe","table","pre","code","hr","figure","canvas","svg","math",'[data-type="mention"]'].join(","),U=e=>(e==null?void 0:e.replace(ge,"").trim())??"",ve=e=>{if(!U(e))return!1;const t=document.createElement("template");return t.innerHTML=e,!!(U(t.content.textContent)||t.content.querySelector(fe))};exports.createRichTextToolbar=me;exports.hasMeaningfulHtmlContent=ve;
36
- //# sourceMappingURL=index-H5V0EMkq.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-H5V0EMkq.cjs","sources":["../../dom/src/menuIcon/uiIcons.ts","../../dom/src/richTextToolbar/groupMenuKeyboard.ts","../../dom/src/richTextToolbar/render.ts","../../dom/src/richTextToolbar/index.ts","../../dom/src/htmlContent/index.ts"],"sourcesContent":["/**\r\n * DOM UI chrome icon 表。\r\n *\r\n * 这里放 toolbar 收纳入口、下拉箭头这类控件自身图标。它们不属于 `MenuItem.icon`\r\n * 跨端 schema,也不应该进入 `defaultMenuIcons` 的 schema 对齐检查。\r\n */\r\nexport const defaultMenuUiIcons = {\r\n toolbarGroup: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-ellipsis\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\r\n </svg>\r\n `,\r\n chevronDown: `\r\n <svg\r\n aria-hidden=\"true\"\r\n class=\"lucide lucide-chevron-down\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"12\"\r\n height=\"12\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n `\r\n} as const;\r\n","export const getEnabledGroupMenuButtons = (menuElement: HTMLElement) => (\r\n Array.from(\r\n menuElement.querySelectorAll<HTMLButtonElement>('.bridgerte__toolbar-group-menu-item')\r\n ).filter((button) => !button.disabled)\r\n);\r\n\r\nexport const focusToolbarGroupMenuItem = (menuElement: HTMLElement, index: number) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const nextButton = buttons[index];\r\n\r\n if (nextButton) nextButton.focus();\r\n};\r\n\r\nexport const focusFirstToolbarGroupMenuItem = (menuElement: HTMLElement) => {\r\n /*\r\n * group menu 使用 ARIA menu 语义,打开后焦点必须进入第一个可操作项。\r\n * 这样键盘用户可以继续用方向键浏览,而不是停留在展开按钮上。\r\n */\r\n focusToolbarGroupMenuItem(menuElement, 0);\r\n};\r\n\r\nexport const handleToolbarGroupMenuKeyDown = (\r\n event: KeyboardEvent,\r\n menuElement: HTMLElement,\r\n returnButton: HTMLButtonElement,\r\n executeToolbarButton: (button: HTMLButtonElement) => void,\r\n closeGroupMenu: () => void\r\n) => {\r\n const buttons = getEnabledGroupMenuButtons(menuElement);\r\n const activeIndex = document.activeElement instanceof HTMLButtonElement\r\n ? buttons.indexOf(document.activeElement)\r\n : -1;\r\n const focusByOffset = (offset: number) => {\r\n if (buttons.length === 0) return;\r\n\r\n const baseIndex = activeIndex >= 0 ? activeIndex : 0;\r\n const nextIndex = (baseIndex + offset + buttons.length) % buttons.length;\r\n\r\n buttons[nextIndex]?.focus();\r\n };\r\n\r\n /*\r\n * ARIA menu 语义要求支持 roving focus。这里不改 toolbar 的横向键盘模型,\r\n * 只在已打开的纵向收纳菜单内处理上下方向、首尾跳转和执行/关闭。\r\n */\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n focusByOffset(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n focusByOffset(-1);\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n buttons[0]?.focus();\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n buttons.at(-1)?.focus();\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n if (document.activeElement instanceof HTMLButtonElement) {\r\n event.preventDefault();\r\n executeToolbarButton(document.activeElement);\r\n closeGroupMenu();\r\n returnButton.focus();\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n returnButton.focus();\r\n closeGroupMenu();\r\n break;\r\n default:\r\n break;\r\n }\r\n};\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport type { MenuItem, ResolvedToolbarItem } from '@bridgerte/native-spec';\r\nimport {\r\n appendMenuIcon,\r\n defaultMenuIcons,\r\n defaultMenuUiIcons\r\n} from './icons';\r\nimport { getMenuStateForItem } from '../menuRuntime';\r\nimport type {\r\n RichTextToolbarIcons,\r\n ToolbarGroupMenuState\r\n} from './type';\r\n\r\nexport const toolbarGroupButtonSelector = 'button[data-bridgerte-toolbar-group-id]';\r\nexport const toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\r\n// 可执行按钮同时覆盖 toolbar 主按钮和 group menu 子项,避免浮层子菜单绕过统一命令入口。\r\nexport const toolbarExecutableButtonSelector = [\n toolbarButtonSelector,\n '.bridgerte__toolbar-group-menu-item'\n].join(',');\n\r\nconst getGroupMenuState = (items: MenuItem[], commandStates: CommandState[]) => {\r\n const itemStates = items.map((item) => getMenuStateForItem(item, commandStates));\r\n\r\n return {\r\n active: itemStates.some((state) => state.active),\r\n disabled: itemStates.length > 0 && itemStates.every((state) => state.disabled)\r\n };\r\n};\r\n\r\nconst renderToolbarButton = (\r\n groupElement: HTMLElement,\r\n item: MenuItem,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n // icon 兜底顺序固定为:业务覆盖 > DOM 默认 SVG > label 文本。\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button';\r\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n if (enableTooltip) button.dataset.tooltip = item.label;\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n\r\n groupElement.append(button);\r\n};\r\n\r\nconst renderToolbarGroupButton = (\r\n groupElement: HTMLElement,\r\n toolbarItem: Extract<ResolvedToolbarItem, { type: 'group' }>,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n const button = document.createElement('button');\r\n const groupState = getGroupMenuState(toolbarItem.items, commandStates);\r\n const iconSvg = toolbarItem.icon\r\n ? icons[toolbarItem.icon] ?? defaultMenuIcons[toolbarItem.icon]\r\n : defaultMenuUiIcons.toolbarGroup;\r\n const indicator = document.createElement('span');\r\n\r\n button.type = 'button';\r\n button.className = 'bridgerte__toolbar-button bridgerte__toolbar-group-button';\r\n button.disabled = groupState.disabled;\r\n button.dataset.active = String(groupState.active);\r\n button.dataset.bridgerteToolbarGroupId = toolbarItem.key;\r\n button.dataset.open = 'false';\r\n button.setAttribute('aria-label', toolbarItem.title);\r\n button.setAttribute('aria-haspopup', 'menu');\r\n button.setAttribute('aria-expanded', 'false');\r\n button.setAttribute('aria-pressed', String(groupState.active));\r\n if (enableTooltip) button.dataset.tooltip = toolbarItem.title;\r\n\r\n appendMenuIcon(button, iconSvg, toolbarItem.title);\r\n\r\n indicator.className = 'bridgerte__toolbar-group-indicator';\r\n indicator.setAttribute('aria-hidden', 'true');\r\n indicator.innerHTML = defaultMenuUiIcons.chevronDown;\r\n button.append(indicator);\r\n groupElement.append(button);\r\n};\r\n\r\n/**\r\n * 渲染 toolbar 横向主入口。\n *\n * 字符串菜单直接渲染为按钮,`|` 渲染分割线。\n * 只有用户显式声明的 group 配置才生成收纳入口,避免 schema 隐式改变 DOM 结构。\n */\r\nexport const renderToolbar = (\r\n toolbarElement: HTMLElement,\r\n toolbarItems: ResolvedToolbarItem[],\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons,\r\n enableTooltip: boolean\r\n) => {\r\n toolbarElement.textContent = '';\r\n\r\n toolbarItems.forEach((toolbarItem) => {\n if (toolbarItem.type === 'separator') {\n const separatorElement = document.createElement('span');\n\n separatorElement.className = 'bridgerte__toolbar-separator';\n separatorElement.dataset.separatorId = toolbarItem.key;\r\n separatorElement.setAttribute('aria-hidden', 'true');\r\n toolbarElement.append(separatorElement);\r\n return;\n }\n\n if (toolbarItem.type === 'button') {\n renderToolbarButton(\n toolbarElement,\n toolbarItem.item,\n commandStates,\n icons,\n enableTooltip\n );\n return;\n }\n\n /*\n * 收纳菜单是用户在 toolbarConfig 里显式声明的结构;普通菜单不会自动生成 DOM 包裹,\n * 显示分组完全交给用户用 group 配置或 `|` 控制。\n */\n const groupElement = document.createElement('div');\n\n groupElement.className = 'bridgerte__toolbar-group';\n groupElement.dataset.group = toolbarItem.key;\n groupElement.setAttribute('aria-label', toolbarItem.title);\n toolbarElement.append(groupElement);\n\n renderToolbarGroupButton(\n groupElement,\n toolbarItem,\n commandStates,\n icons,\n enableTooltip\r\n );\r\n });\r\n};\r\n\r\n/**\r\n * 渲染 group button 打开的纵向收纳菜单。\r\n *\r\n * 浮层只展示 MenuItem 子项并复用现有 item id,点击执行仍由 index.ts 统一走 EditorAPI。\r\n */\r\nexport const renderToolbarGroupMenu = (\r\n menuElement: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null,\r\n commandStates: CommandState[],\r\n icons: RichTextToolbarIcons\r\n) => {\r\n menuElement.textContent = '';\r\n\r\n if (!groupMenuState) {\r\n menuElement.dataset.visible = 'false';\r\n return;\r\n }\r\n\r\n groupMenuState.items.forEach((item) => {\r\n const state = getMenuStateForItem(item, commandStates);\r\n const button = document.createElement('button');\r\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\r\n const labelElement = document.createElement('span');\n\n button.type = 'button';\n button.className = 'bridgerte__menu-item bridgerte__toolbar-group-menu-item';\n button.disabled = state.disabled;\r\n button.dataset.active = String(state.active);\r\n button.dataset.bridgerteToolbarItemId = item.id;\r\n button.setAttribute('role', 'menuitem');\r\n button.setAttribute('aria-label', item.label);\r\n button.setAttribute('aria-pressed', String(state.active));\r\n\r\n appendMenuIcon(button, iconSvg, item.label);\r\n labelElement.className = 'bridgerte__toolbar-group-menu-label';\r\n labelElement.textContent = item.label;\r\n button.append(labelElement);\r\n menuElement.append(button);\r\n });\r\n\r\n menuElement.dataset.visible = 'true';\r\n menuElement.style.minWidth = `${groupMenuState.button.offsetWidth}px`;\r\n};\r\n\r\nexport const syncToolbarGroupButtonState = (\r\n container: HTMLElement,\r\n groupMenuState: ToolbarGroupMenuState | null\r\n) => {\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector).forEach((button) => {\r\n const open = groupMenuState?.groupKey === button.dataset.bridgerteToolbarGroupId;\r\n\r\n button.dataset.open = String(open);\r\n button.setAttribute('aria-expanded', String(open));\r\n });\r\n};\r\n\r\nexport const findToolbarGroupMenuItem = (\r\n toolbarItems: ResolvedToolbarItem[],\r\n groupKey: string | undefined\r\n) => toolbarItems.find((item): item is Extract<ResolvedToolbarItem, { type: 'group' }> => (\r\n item.type === 'group' && item.key === groupKey\r\n));\r\n","import type { CommandState } from '@bridgerte/core';\r\nimport {\r\n defaultMenuSchema,\r\n resolveToolbarMenu\r\n} from '@bridgerte/native-spec';\r\nimport { createFloatingLayer, type RichTextFloatingLayer } from '../floatingLayer';\r\nimport { bindTouchPressedState } from '../interactionState';\r\nimport {\r\n getPayloadPanelCurrentValues,\r\n resolveMenuSchemaForDom\r\n} from '../menuRuntime';\r\nimport {\r\n focusFirstToolbarGroupMenuItem,\r\n handleToolbarGroupMenuKeyDown\r\n} from './groupMenuKeyboard';\r\nimport {\r\n findToolbarGroupMenuItem,\r\n renderToolbar,\r\n renderToolbarGroupMenu,\r\n syncToolbarGroupButtonState,\r\n toolbarExecutableButtonSelector,\r\n toolbarGroupButtonSelector\r\n} from './render';\r\nimport type {\r\n RichTextToolbarAPI,\r\n ToolbarGroupMenuState,\r\n RichTextToolbarOptions,\r\n ToolbarDragState\r\n} from './type';\r\n\r\nconst toolbarDragClickThresholdPx = 4;\r\nconst toolbarTooltipOffsetPx = 8;\r\nconst toolbarGroupMenuOffsetPx = 6;\r\n\r\nexport type * from './type';\r\n\r\nconst canUseHoverTooltip = () => (\r\n typeof window !== 'undefined'\r\n && window.matchMedia?.('(hover: hover) and (pointer: fine)').matches === true\r\n);\r\n\r\nconst getToolbarButtonFromTarget = (target: EventTarget | null) => {\r\n /*\r\n * 图标覆盖常用 SVG,H5 pointer 事件可能落在 svg/path 上。\r\n * 这里用 Element 而不是 HTMLElement,保证触屏兜底和 click 都能向上命中真实按钮。\r\n */\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarExecutableButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\nconst getToolbarGroupButtonFromTarget = (target: EventTarget | null) => {\r\n const button = target instanceof Element\r\n ? target.closest<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n : null;\r\n\r\n return button instanceof HTMLButtonElement ? button : null;\r\n};\r\n\r\n/**\r\n * 创建独立菜单实例。\r\n *\r\n * toolbar/tabbar 只订阅 EditorAPI 状态并派发命令,不接触编辑器内部 DOM 或 Lexical 实例。\r\n */\r\nexport function createRichTextToolbar(\r\n container: HTMLElement,\r\n options: RichTextToolbarOptions\r\n): RichTextToolbarAPI {\r\n const placement = options.placement ?? 'top';\r\n const menuSchema = resolveMenuSchemaForDom(options.menuSchema ?? defaultMenuSchema, {\r\n menuLabels: options.menuLabels,\r\n payloadPanelConfig: options.payloadPanelConfig\r\n });\r\n const toolbarItems = resolveToolbarMenu(options.toolbarConfig, menuSchema);\r\n /*\r\n * click 事件只需要能执行命令的菜单项。分割线和 group 容器是渲染结构,\r\n * 先在这里摊平,后续点击时就不用理解 toolbarConfig 的展示层级。\r\n */\r\n const executableMenuItems = toolbarItems.flatMap((toolbarItem) => (\r\n toolbarItem.type === 'button' ? [toolbarItem.item]\r\n : toolbarItem.type === 'group' ? toolbarItem.items\r\n : []\r\n ));\r\n const icons = options.icons ?? {};\r\n /*\r\n * tooltip 只属于 PC 精细指针体验。H5 上即使没有原生 title,部分浏览器也会把 hover/mouseover\r\n * 模拟成首触摸状态,导致第一次点像是只唤醒提示;所以触屏端不写 tooltip 数据也不挂监听。\r\n */\r\n const enableTooltip = canUseHoverTooltip();\r\n const tooltipElement = document.createElement('div');\r\n const groupMenuElement = document.createElement('div');\r\n const overlayHost = container.closest('.bridgerte') ?? container;\r\n let destroyed = false;\r\n let dragState: ToolbarDragState | null = null;\r\n let shouldSuppressNextClick = false;\r\n let latestCommandStates = options.editor.getCommandStates();\r\n let groupMenuState: ToolbarGroupMenuState | null = null;\r\n let groupMenuFloatingLayer: RichTextFloatingLayer | null = null;\r\n const clearToolbarPressedState = bindTouchPressedState(container, {\r\n targetSelector: [\r\n 'button[data-bridgerte-toolbar-item-id]',\r\n 'button[data-bridgerte-toolbar-group-id]'\r\n ].join(',')\r\n });\r\n const clearGroupMenuPressedState = bindTouchPressedState(groupMenuElement, {\r\n targetSelector: '.bridgerte__toolbar-group-menu-item'\r\n });\r\n\r\n const mountToolbarOverlays = () => {\r\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\r\n overlayHost.append(tooltipElement);\r\n overlayHost.append(groupMenuElement);\r\n };\r\n\r\n const closeGroupMenuFloatingLayer = () => {\r\n groupMenuFloatingLayer?.setOpen(false);\r\n groupMenuFloatingLayer?.destroy();\r\n groupMenuFloatingLayer = null;\r\n };\r\n\r\n const openGroupMenuFloatingLayer = () => {\r\n if (!groupMenuState) return;\r\n\r\n closeGroupMenuFloatingLayer();\r\n /*\r\n * group menu 和 hoverbar/mention/slash 一样属于轻浮层,必须走 floatingLayer。\r\n * 这里按 toolbar placement 给出首选方向,真正的翻转、键盘可视区和左右夹紧交给\r\n * createFloatingLayer 内部的 visualViewport + flip + shift + clamp 统一处理。\r\n */\r\n groupMenuFloatingLayer = createFloatingLayer(groupMenuState.button, groupMenuElement, {\r\n placement: placement === 'bottom' ? 'top-start' : 'bottom-start',\r\n offset: toolbarGroupMenuOffsetPx,\r\n strategy: 'fixed'\r\n });\r\n groupMenuFloatingLayer.setOpen(true);\r\n };\r\n\r\n const closeGroupMenu = () => {\r\n closeGroupMenuFloatingLayer();\r\n groupMenuState = null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n };\r\n\r\n const renderStates = (states: CommandState[]) => {\r\n if (destroyed) return;\r\n\r\n latestCommandStates = states;\r\n if (groupMenuState) closeGroupMenuFloatingLayer();\r\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\r\n mountToolbarOverlays();\r\n if (groupMenuState) {\r\n const nextButton = Array.from(\r\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector)\r\n ).find((button) => button.dataset.bridgerteToolbarGroupId === groupMenuState?.groupKey);\r\n const nextGroupItem = findToolbarGroupMenuItem(toolbarItems, groupMenuState.groupKey);\r\n\r\n groupMenuState = nextButton && nextGroupItem\r\n ? {\r\n groupKey: groupMenuState.groupKey,\r\n button: nextButton,\r\n items: nextGroupItem.items\r\n }\r\n : null;\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n if (groupMenuState) openGroupMenuFloatingLayer();\r\n }\r\n };\r\n\r\n const update = () => {\r\n if (destroyed) return;\r\n\r\n renderStates(options.editor.getCommandStates());\r\n };\r\n\r\n const hideTooltip = () => {\r\n tooltipElement.dataset.visible = 'false';\r\n tooltipElement.textContent = '';\r\n };\r\n\r\n const showTooltip = (button: HTMLButtonElement) => {\r\n const tooltipText = button.dataset.tooltip;\r\n\r\n if (!enableTooltip || !tooltipText || dragState) return;\r\n\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n tooltipElement.textContent = tooltipText;\r\n tooltipElement.dataset.visible = 'true';\r\n tooltipElement.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\r\n tooltipElement.style.top = `${buttonRect.top - toolbarTooltipOffsetPx}px`;\r\n };\r\n\r\n const handleTooltipTarget = (event: Event) => {\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (button) {\r\n showTooltip(button);\r\n }\r\n };\r\n\r\n const handleTooltipLeave = (event: MouseEvent) => {\r\n const relatedTarget = event.relatedTarget;\r\n const button = getToolbarButtonFromTarget(event.target);\r\n\r\n if (\r\n button\r\n && relatedTarget instanceof Node\r\n && button.contains(relatedTarget)\r\n ) return;\r\n\r\n hideTooltip();\r\n };\r\n\r\n const stopToolbarDrag = () => {\r\n dragState = null;\r\n\r\n delete container.dataset.dragging;\r\n // 拖动过程中监听挂在 document 上,松手或 destroy 必须统一清掉,避免离开 toolbar 后残留滚动状态。\r\n document.removeEventListener('pointermove', handlePointerMove);\r\n document.removeEventListener('pointerup', handlePointerUp);\r\n document.removeEventListener('pointercancel', handlePointerUp);\r\n };\r\n\r\n const handlePointerMove = (event: PointerEvent) => {\r\n if (!dragState) return;\r\n\r\n const deltaX = dragState.startClientX - event.clientX;\r\n\r\n if (Math.abs(deltaX) > toolbarDragClickThresholdPx) {\r\n dragState.hasDragged = true;\r\n shouldSuppressNextClick = true;\r\n hideTooltip();\r\n closeGroupMenu();\r\n }\r\n\r\n container.scrollLeft = dragState.startScrollLeft + deltaX;\r\n };\r\n\r\n const handlePointerUp = (event: PointerEvent) => {\r\n const currentDragState = dragState;\r\n\r\n stopToolbarDrag();\r\n if (\r\n currentDragState\r\n && event.type !== 'pointercancel'\r\n && currentDragState.pointerType !== 'mouse'\r\n && !currentDragState.hasDragged\r\n && currentDragState.startButton\r\n ) {\r\n executeToolbarButton(currentDragState.startButton);\r\n shouldSuppressNextClick = true;\r\n }\r\n };\r\n\r\n const handlePointerDown = (event: PointerEvent) => {\r\n if (event.pointerType === 'mouse' && event.button !== 0) return;\r\n\r\n const startButton = getToolbarButtonFromTarget(event.target);\r\n\r\n // 点击和拖动 toolbar 都要保留编辑区 selection,命令才能继续作用在原选区。\r\n event.preventDefault();\r\n dragState = {\r\n startClientX: event.clientX,\r\n startScrollLeft: container.scrollLeft,\r\n pointerType: event.pointerType,\r\n hasDragged: false,\r\n startButton: startButton ?? undefined\r\n };\r\n container.dataset.dragging = 'true';\r\n hideTooltip();\r\n // pointermove 放到 document,保证用户按住 X 轴拖出 toolbar 后仍能完成滚动和释放。\r\n document.addEventListener('pointermove', handlePointerMove);\r\n document.addEventListener('pointerup', handlePointerUp);\r\n document.addEventListener('pointercancel', handlePointerUp);\r\n };\r\n\r\n const executeToolbarButton = (button: HTMLButtonElement) => {\r\n if (!(button instanceof HTMLButtonElement) || button.disabled) return;\r\n\r\n const menuItem = executableMenuItems.find((item) => (\r\n item.id === button.dataset.bridgerteToolbarItemId\r\n ));\r\n\r\n if (!menuItem) return;\r\n\r\n if (menuItem.payloadPanel) {\r\n const buttonRect = button.getBoundingClientRect();\r\n\r\n /*\r\n * 带 payloadPanel 的菜单不直接执行基础 command,而是发起参数请求。\r\n * DOM 内置面板和业务/RN/Flutter 自绘都走同一个 request,避免后续颜色、\r\n * 字体、链接等参数菜单各自发明一套协议。\r\n */\r\n options.editor.requestPayloadPanel({\r\n menuId: menuItem.id,\r\n command: menuItem.command,\r\n panel: menuItem.payloadPanel,\r\n currentValues: getPayloadPanelCurrentValues(menuItem, options.editor.getCommandStates()),\r\n anchorRect: {\r\n x: buttonRect.left,\r\n y: buttonRect.top,\r\n width: buttonRect.width,\r\n height: buttonRect.height\r\n }\r\n });\r\n return;\r\n }\r\n\r\n options.editor.executeCommand(menuItem.command);\r\n };\r\n\r\n const toggleGroupMenu = (button: HTMLButtonElement) => {\r\n const groupItem = findToolbarGroupMenuItem(\r\n toolbarItems,\r\n button.dataset.bridgerteToolbarGroupId\r\n );\r\n\r\n if (!groupItem || button.disabled) return;\r\n\r\n if (groupMenuState?.groupKey === groupItem.key) {\r\n closeGroupMenu();\r\n return;\r\n }\r\n\r\n groupMenuState = {\r\n groupKey: groupItem.key,\r\n button,\r\n items: groupItem.items\r\n };\r\n hideTooltip();\r\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\r\n syncToolbarGroupButtonState(container, groupMenuState);\r\n openGroupMenuFloatingLayer();\r\n focusFirstToolbarGroupMenuItem(groupMenuElement);\r\n };\r\n\r\n const handleClick = (event: MouseEvent) => {\r\n if (shouldSuppressNextClick) {\r\n shouldSuppressNextClick = false;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n const groupButton = getToolbarGroupButtonFromTarget(event.target);\r\n if (groupButton) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n toggleGroupMenu(groupButton);\r\n return;\r\n }\r\n\r\n const button = getToolbarButtonFromTarget(event.target);\r\n if (!button) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n executeToolbarButton(button);\r\n closeGroupMenu();\r\n };\r\n\r\n const handleGroupMenuPointerDown = (event: PointerEvent) => {\r\n /*\r\n * group 菜单浮层挂在 toolbar 容器外,不能复用容器级 pointerdown。\r\n * 子菜单点击仍要保留编辑区 selection,否则格式命令会丢失原选区。\r\n */\r\n if (event.pointerType === 'mouse' && event.button !== 0) return;\r\n\r\n event.preventDefault();\r\n };\r\n\r\n const handleDocumentClick = (event: MouseEvent) => {\r\n const target = event.target;\r\n\r\n if (\r\n target instanceof Node\r\n && (container.contains(target) || groupMenuElement.contains(target))\r\n ) return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (groupMenuState && groupMenuElement.contains(document.activeElement)) {\r\n handleToolbarGroupMenuKeyDown(\r\n event,\r\n groupMenuElement,\r\n groupMenuState.button,\r\n executeToolbarButton,\r\n closeGroupMenu\r\n );\r\n return;\r\n }\r\n\r\n if (event.key !== 'Escape') return;\r\n\r\n closeGroupMenu();\r\n };\r\n\r\n container.classList.add('bridgerte__toolbar');\r\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\r\n tooltipElement.dataset.visible = 'false';\r\n groupMenuElement.className = 'bridgerte__floating-menu bridgerte__toolbar-group-menu';\n groupMenuElement.dataset.visible = 'false';\r\n groupMenuElement.setAttribute('role', 'menu');\r\n container.dataset.placement = placement;\r\n container.setAttribute('role', 'toolbar');\r\n container.setAttribute(\r\n 'aria-label',\r\n placement === 'bottom' ? 'BridgeRTE tabbar' : 'BridgeRTE toolbar'\r\n );\r\n container.addEventListener('pointerdown', handlePointerDown, true);\r\n container.addEventListener('click', handleClick);\r\n groupMenuElement.addEventListener('pointerdown', handleGroupMenuPointerDown, true);\r\n groupMenuElement.addEventListener('click', handleClick);\r\n document.addEventListener('click', handleDocumentClick);\r\n document.addEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.addEventListener('mouseover', handleTooltipTarget);\r\n container.addEventListener('mouseout', handleTooltipLeave);\r\n }\r\n container.addEventListener('focusout', hideTooltip);\r\n // 浮层挂在最近的编辑器根容器下,既能继承变量,也不会操作编辑内容 DOM。\r\n mountToolbarOverlays();\r\n\r\n // 独立 toolbar 只订阅 public API 状态,不依赖 DOM 编辑器内部实现。\r\n const unsubscribe = options.editor.subscribeCommandStateChange(renderStates);\r\n\r\n return {\r\n update,\r\n destroy() {\r\n if (destroyed) return;\r\n\r\n destroyed = true;\r\n stopToolbarDrag();\r\n unsubscribe();\r\n closeGroupMenu();\r\n container.removeEventListener('pointerdown', handlePointerDown, true);\r\n container.removeEventListener('click', handleClick);\r\n groupMenuElement.removeEventListener('pointerdown', handleGroupMenuPointerDown, true);\r\n groupMenuElement.removeEventListener('click', handleClick);\r\n document.removeEventListener('click', handleDocumentClick);\r\n document.removeEventListener('keydown', handleKeyDown);\r\n if (enableTooltip) {\r\n container.removeEventListener('mouseover', handleTooltipTarget);\r\n container.removeEventListener('mouseout', handleTooltipLeave);\r\n }\r\n clearToolbarPressedState();\r\n clearGroupMenuPressedState();\r\n container.removeEventListener('focusout', hideTooltip);\r\n tooltipElement.remove();\r\n groupMenuElement.remove();\r\n container.classList.remove('bridgerte__toolbar');\r\n delete container.dataset.placement;\r\n container.textContent = '';\r\n container.removeAttribute('role');\r\n container.removeAttribute('aria-label');\r\n }\r\n };\r\n}\r\n","const invisibleTextPattern = /[\\u200B-\\u200D\\uFEFF]/g;\n\n/*\n * HTML 片段里这些元素没有 textContent 也应算有效内容。\n * 纯排版容器不放进来,避免 `<p><br></p>`、空列表项这类编辑器占位被误判为非空。\n */\nconst meaningfulHtmlContentSelector = [\n 'img',\n 'video',\n 'audio',\n 'iframe',\n 'table',\n 'pre',\n 'code',\n 'hr',\n 'figure',\n 'canvas',\n 'svg',\n 'math',\n '[data-type=\"mention\"]'\n].join(',');\n\nconst normalizeHtmlText = (text: string | null | undefined): string => (\n text?.replace(invisibleTextPattern, '').trim() ?? ''\n);\n\n/**\n * 判断一段 HTML 片段是否包含可保存的富文本内容。\n *\n * 这个工具会使用浏览器 template 解析 HTML,适合只拿到 HTML 字符串的业务表单;如果已经持有\n * `EditorContent`,优先使用 core 的 `isEditorContentEmpty()`,避免额外 DOM parse。\n */\nexport const hasMeaningfulHtmlContent = (html: string): boolean => {\n if (!normalizeHtmlText(html)) return false;\n\n const template = document.createElement('template');\n\n template.innerHTML = html;\n\n return Boolean(\n normalizeHtmlText(template.content.textContent)\n || template.content.querySelector(meaningfulHtmlContentSelector)\n );\n};\n"],"names":["defaultMenuUiIcons","getEnabledGroupMenuButtons","menuElement","button","focusToolbarGroupMenuItem","index","nextButton","focusFirstToolbarGroupMenuItem","handleToolbarGroupMenuKeyDown","event","returnButton","executeToolbarButton","closeGroupMenu","buttons","activeIndex","focusByOffset","offset","nextIndex","_a","_b","toolbarGroupButtonSelector","toolbarButtonSelector","toolbarExecutableButtonSelector","getGroupMenuState","items","commandStates","itemStates","item","getMenuStateForItem","state","renderToolbarButton","groupElement","icons","enableTooltip","iconSvg","defaultMenuIcons","appendMenuIcon","renderToolbarGroupButton","toolbarItem","groupState","indicator","renderToolbar","toolbarElement","toolbarItems","separatorElement","renderToolbarGroupMenu","groupMenuState","labelElement","syncToolbarGroupButtonState","container","open","findToolbarGroupMenuItem","groupKey","toolbarDragClickThresholdPx","toolbarTooltipOffsetPx","toolbarGroupMenuOffsetPx","canUseHoverTooltip","getToolbarButtonFromTarget","target","getToolbarGroupButtonFromTarget","createRichTextToolbar","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","groupMenuElement","overlayHost","destroyed","dragState","shouldSuppressNextClick","latestCommandStates","groupMenuFloatingLayer","clearToolbarPressedState","bindTouchPressedState","clearGroupMenuPressedState","mountToolbarOverlays","closeGroupMenuFloatingLayer","openGroupMenuFloatingLayer","createFloatingLayer","renderStates","states","nextGroupItem","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","handleTooltipLeave","relatedTarget","stopToolbarDrag","handlePointerMove","handlePointerUp","deltaX","currentDragState","handlePointerDown","startButton","menuItem","getPayloadPanelCurrentValues","toggleGroupMenu","groupItem","handleClick","groupButton","handleGroupMenuPointerDown","handleDocumentClick","handleKeyDown","unsubscribe","invisibleTextPattern","meaningfulHtmlContentSelector","normalizeHtmlText","text","hasMeaningfulHtmlContent","html","template"],"mappings":"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"}