bridgerte 0.9.16 → 0.9.17
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 +1 -1
- package/dist/dom.js +2 -2
- package/dist/{index-CKIFd9T9.cjs → index-C9gc8336.cjs} +2 -2
- package/dist/index-C9gc8336.cjs.map +1 -0
- package/dist/index-CVyAIGlg.cjs +36 -0
- package/dist/index-CVyAIGlg.cjs.map +1 -0
- package/dist/{index-09ZQ5n0I.js → index-IG7bnHAR.js} +3 -3
- package/dist/index-IG7bnHAR.js.map +1 -0
- package/dist/{index-PixgfP7_.js → index-ZeQUaPbe.js} +78 -78
- package/dist/index-ZeQUaPbe.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/webview.cjs +1 -1
- package/dist/webview.js +1 -1
- package/package.json +1 -1
- package/dist/index-09ZQ5n0I.js.map +0 -1
- package/dist/index-CKIFd9T9.cjs.map +0 -1
- package/dist/index-ClgxmJNW.cjs +0 -36
- package/dist/index-ClgxmJNW.cjs.map +0 -1
- package/dist/index-PixgfP7_.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defaultMenuSchema as
|
|
2
|
-
import { g as
|
|
3
|
-
const
|
|
1
|
+
import { defaultMenuSchema as ot, resolveToolbarMenu as nt } from "./native-spec.js";
|
|
2
|
+
import { g as N, d as K, e as M, r as rt, f as X, h as at, c as st } from "./index-IG7bnHAR.js";
|
|
3
|
+
const Y = {
|
|
4
4
|
toolbarGroup: `
|
|
5
5
|
<svg
|
|
6
6
|
aria-hidden="true"
|
|
@@ -37,14 +37,14 @@ const X = {
|
|
|
37
37
|
<path d="m6 9 6 6 6-6" />
|
|
38
38
|
</svg>
|
|
39
39
|
`
|
|
40
|
-
},
|
|
40
|
+
}, J = (t) => Array.from(
|
|
41
41
|
t.querySelectorAll(".bridgerte__toolbar-group-menu-item")
|
|
42
|
-
).filter((e) => !e.disabled),
|
|
43
|
-
const c =
|
|
42
|
+
).filter((e) => !e.disabled), U = (t, e) => {
|
|
43
|
+
const c = J(t)[e];
|
|
44
44
|
c && c.focus();
|
|
45
|
-
},
|
|
45
|
+
}, it = (t, e, i, c, d) => {
|
|
46
46
|
var s, u;
|
|
47
|
-
const n =
|
|
47
|
+
const n = J(e), r = document.activeElement instanceof HTMLButtonElement ? n.indexOf(document.activeElement) : -1, m = (g) => {
|
|
48
48
|
var o;
|
|
49
49
|
if (n.length === 0) return;
|
|
50
50
|
const v = ((r >= 0 ? r : 0) + g + n.length) % n.length;
|
|
@@ -71,21 +71,21 @@ const X = {
|
|
|
71
71
|
t.preventDefault(), i.focus(), d();
|
|
72
72
|
break;
|
|
73
73
|
}
|
|
74
|
-
},
|
|
75
|
-
|
|
74
|
+
}, x = "button[data-bridgerte-toolbar-group-id]", I = "button[data-bridgerte-toolbar-item-id]", H = [
|
|
75
|
+
I,
|
|
76
76
|
".bridgerte__toolbar-group-menu-item"
|
|
77
77
|
].join(","), lt = (t, e) => {
|
|
78
|
-
const i = t.map((c) =>
|
|
78
|
+
const i = t.map((c) => N(c, e));
|
|
79
79
|
return {
|
|
80
80
|
active: i.some((c) => c.active),
|
|
81
81
|
disabled: i.length > 0 && i.every((c) => c.disabled)
|
|
82
82
|
};
|
|
83
83
|
}, ct = (t, e, i, c, d) => {
|
|
84
|
-
const n =
|
|
85
|
-
r.type = "button", r.className = "bridgerte__toolbar-button", r.disabled = n.disabled, r.dataset.active = String(n.active), r.dataset.bridgerteToolbarItemId = e.id, r.setAttribute("aria-label", e.label), r.setAttribute("aria-pressed", String(n.active)), d && (r.dataset.tooltip = e.label),
|
|
84
|
+
const n = N(e, i), r = document.createElement("button"), m = c[e.icon] ?? K[e.icon];
|
|
85
|
+
r.type = "button", r.className = "bridgerte__toolbar-button", r.disabled = n.disabled, r.dataset.active = String(n.active), r.dataset.bridgerteToolbarItemId = e.id, r.setAttribute("aria-label", e.label), r.setAttribute("aria-pressed", String(n.active)), d && (r.dataset.tooltip = e.label), M(r, m, e.label), t.append(r);
|
|
86
86
|
}, dt = (t, e, i, c, d) => {
|
|
87
|
-
const n = document.createElement("button"), r = lt(e.items, i), m = e.icon ? c[e.icon] ??
|
|
88
|
-
n.type = "button", n.className = "bridgerte__toolbar-button bridgerte__toolbar-group-button", n.disabled = r.disabled, n.dataset.active = String(r.active), n.dataset.bridgerteToolbarGroupId = e.key, n.dataset.open = "false", n.setAttribute("aria-label", e.title), n.setAttribute("aria-haspopup", "menu"), n.setAttribute("aria-expanded", "false"), n.setAttribute("aria-pressed", String(r.active)), d && (n.dataset.tooltip = e.title),
|
|
87
|
+
const n = document.createElement("button"), r = lt(e.items, i), m = e.icon ? c[e.icon] ?? K[e.icon] : Y.toolbarGroup, s = document.createElement("span");
|
|
88
|
+
n.type = "button", n.className = "bridgerte__toolbar-button bridgerte__toolbar-group-button", n.disabled = r.disabled, n.dataset.active = String(r.active), n.dataset.bridgerteToolbarGroupId = e.key, n.dataset.open = "false", n.setAttribute("aria-label", e.title), n.setAttribute("aria-haspopup", "menu"), n.setAttribute("aria-expanded", "false"), n.setAttribute("aria-pressed", String(r.active)), d && (n.dataset.tooltip = e.title), M(n, m, e.title), s.className = "bridgerte__toolbar-group-indicator", s.setAttribute("aria-hidden", "true"), s.innerHTML = Y.chevronDown, n.append(s), t.append(n);
|
|
89
89
|
}, ut = (t, e, i, c, d) => {
|
|
90
90
|
t.textContent = "", e.forEach((n) => {
|
|
91
91
|
if (n.type === "separator") {
|
|
@@ -118,23 +118,23 @@ const X = {
|
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
120
|
e.items.forEach((d) => {
|
|
121
|
-
const n =
|
|
122
|
-
r.type = "button", r.className = "bridgerte__menu-item bridgerte__toolbar-group-menu-item", r.disabled = n.disabled, r.dataset.active = String(n.active), r.dataset.bridgerteToolbarItemId = d.id, r.setAttribute("role", "menuitem"), r.setAttribute("aria-label", d.label), r.setAttribute("aria-pressed", String(n.active)),
|
|
121
|
+
const n = N(d, i), r = document.createElement("button"), m = c[d.icon] ?? K[d.icon], s = document.createElement("span");
|
|
122
|
+
r.type = "button", r.className = "bridgerte__menu-item bridgerte__toolbar-group-menu-item", r.disabled = n.disabled, r.dataset.active = String(n.active), r.dataset.bridgerteToolbarItemId = d.id, r.setAttribute("role", "menuitem"), r.setAttribute("aria-label", d.label), r.setAttribute("aria-pressed", String(n.active)), M(r, m, d.label), s.className = "bridgerte__toolbar-group-menu-label", s.textContent = d.label, r.append(s), t.append(r);
|
|
123
123
|
}), t.dataset.visible = "true", t.style.minWidth = `${e.button.offsetWidth}px`;
|
|
124
124
|
}, D = (t, e) => {
|
|
125
|
-
t.querySelectorAll(
|
|
125
|
+
t.querySelectorAll(x).forEach((i) => {
|
|
126
126
|
const c = (e == null ? void 0 : e.groupKey) === i.dataset.bridgerteToolbarGroupId;
|
|
127
127
|
i.dataset.open = String(c), i.setAttribute("aria-expanded", String(c));
|
|
128
128
|
});
|
|
129
|
-
},
|
|
129
|
+
}, $ = (t, e) => t.find((i) => i.type === "group" && i.key === e), V = 8, B = (t, e) => e instanceof Node && t.contains(e), w = (t, e) => t instanceof Element ? t.closest(e) : null, bt = (t, e, i, c, d) => {
|
|
130
130
|
let n = null, r = null;
|
|
131
|
-
const m = (o) =>
|
|
131
|
+
const m = (o) => w(o, x) ?? w(o, I) ?? (B(e, o) ? w(o, H) : null), s = (o) => {
|
|
132
132
|
m(o.target) && o.preventDefault();
|
|
133
133
|
}, u = (o) => {
|
|
134
|
-
const p = o.touches[0], h =
|
|
134
|
+
const p = o.touches[0], h = w(o.target, x), L = w(o.target, I), E = B(e, o.target) ? w(o.target, H) : null, y = h ?? L ?? E;
|
|
135
135
|
!y || !p || (o.preventDefault(), n = {
|
|
136
136
|
button: y,
|
|
137
|
-
kind: h ? "group" : "menu-item",
|
|
137
|
+
kind: h ? "group" : E ? "menu-item" : "button",
|
|
138
138
|
startX: p.clientX,
|
|
139
139
|
startY: p.clientY
|
|
140
140
|
});
|
|
@@ -142,10 +142,10 @@ const X = {
|
|
|
142
142
|
n = null;
|
|
143
143
|
}, f = (o) => {
|
|
144
144
|
if (!n) return;
|
|
145
|
-
const p = n, h = o.changedTouches[0],
|
|
146
|
-
if (n = null, !h ||
|
|
147
|
-
const
|
|
148
|
-
if (!(
|
|
145
|
+
const p = n, h = o.changedTouches[0], L = m(o.target);
|
|
146
|
+
if (n = null, !h || L !== p.button) return;
|
|
147
|
+
const E = Math.abs(h.clientX - p.startX), y = Math.abs(h.clientY - p.startY);
|
|
148
|
+
if (!(E > V || y > V)) {
|
|
149
149
|
if (o.preventDefault(), o.stopPropagation(), r = p.button, p.kind === "group") {
|
|
150
150
|
i(p.button);
|
|
151
151
|
return;
|
|
@@ -153,7 +153,7 @@ const X = {
|
|
|
153
153
|
c(p.button), d();
|
|
154
154
|
}
|
|
155
155
|
}, v = (o) => {
|
|
156
|
-
|
|
156
|
+
B(t, o.target) || B(e, o.target) || d();
|
|
157
157
|
};
|
|
158
158
|
return t.addEventListener("pointerdown", s), t.addEventListener("mousedown", s), t.addEventListener("touchstart", u, { passive: !1 }), t.addEventListener("touchend", f), t.addEventListener("touchcancel", g), e.addEventListener("pointerdown", s), e.addEventListener("mousedown", s), e.addEventListener("touchstart", u, { passive: !1 }), e.addEventListener("touchend", f), e.addEventListener("touchcancel", g), document.addEventListener("pointerdown", v, !0), {
|
|
159
159
|
consumeSuppressedClick(o) {
|
|
@@ -167,64 +167,64 @@ const X = {
|
|
|
167
167
|
var t;
|
|
168
168
|
return typeof window < "u" && ((t = window.matchMedia) == null ? void 0 : t.call(window, "(hover: hover) and (pointer: fine)").matches) === !0;
|
|
169
169
|
}, P = (t) => {
|
|
170
|
-
const e = t instanceof Element ? t.closest(
|
|
170
|
+
const e = t instanceof Element ? t.closest(H) : null;
|
|
171
171
|
return e instanceof HTMLButtonElement ? e : null;
|
|
172
|
-
},
|
|
173
|
-
const e = t instanceof Element ? t.closest(
|
|
172
|
+
}, W = (t) => {
|
|
173
|
+
const e = t instanceof Element ? t.closest(x) : null;
|
|
174
174
|
return e instanceof HTMLButtonElement ? e : null;
|
|
175
175
|
};
|
|
176
176
|
function Et(t, e) {
|
|
177
|
-
const i = e.placement ?? "top", c =
|
|
177
|
+
const i = e.placement ?? "top", c = rt(e.menuSchema ?? ot, {
|
|
178
178
|
menuLabels: e.menuLabels,
|
|
179
179
|
payloadPanelConfig: e.payloadPanelConfig
|
|
180
|
-
}), d =
|
|
180
|
+
}), d = nt(e.toolbarConfig, c), n = d.flatMap((a) => a.type === "button" ? [a.item] : a.type === "group" ? a.items : []), r = e.icons ?? {}, m = ft(), s = document.createElement("div"), u = document.createElement("div"), g = t.closest(".bridgerte") ?? t;
|
|
181
181
|
let f = !1, v = e.editor.getCommandStates(), o = null, p = null;
|
|
182
|
-
const h =
|
|
182
|
+
const h = X(t, {
|
|
183
183
|
targetSelector: [
|
|
184
184
|
"button[data-bridgerte-toolbar-item-id]",
|
|
185
185
|
"button[data-bridgerte-toolbar-group-id]"
|
|
186
186
|
].join(",")
|
|
187
|
-
}),
|
|
187
|
+
}), L = X(u, {
|
|
188
188
|
targetSelector: ".bridgerte__toolbar-group-menu-item"
|
|
189
|
-
}),
|
|
189
|
+
}), E = () => {
|
|
190
190
|
g.append(s), g.append(u);
|
|
191
|
-
},
|
|
191
|
+
}, y = () => {
|
|
192
192
|
p == null || p.setOpen(!1), p == null || p.destroy(), p = null;
|
|
193
|
-
},
|
|
194
|
-
o && (
|
|
193
|
+
}, R = () => {
|
|
194
|
+
o && (y(), p = st(o.button, u, {
|
|
195
195
|
placement: i === "bottom" ? "top-start" : "bottom-start",
|
|
196
196
|
offset: mt,
|
|
197
197
|
strategy: "fixed"
|
|
198
198
|
}), p.setOpen(!0));
|
|
199
|
-
},
|
|
200
|
-
!o && !p || (
|
|
201
|
-
},
|
|
202
|
-
if (!f && (v = a, o &&
|
|
199
|
+
}, T = () => {
|
|
200
|
+
!o && !p || (y(), o = null, G(u, o, v, r), D(t, o));
|
|
201
|
+
}, F = (a) => {
|
|
202
|
+
if (!f && (v = a, o && y(), ut(t, d, a, r, m), E(), o)) {
|
|
203
203
|
const l = Array.from(
|
|
204
|
-
t.querySelectorAll(
|
|
205
|
-
).find((
|
|
204
|
+
t.querySelectorAll(x)
|
|
205
|
+
).find((et) => et.dataset.bridgerteToolbarGroupId === (o == null ? void 0 : o.groupKey)), b = $(d, o.groupKey);
|
|
206
206
|
o = l && b ? {
|
|
207
207
|
groupKey: o.groupKey,
|
|
208
208
|
button: l,
|
|
209
209
|
items: b.items
|
|
210
|
-
} : null, G(u, o, v, r), D(t, o), o &&
|
|
210
|
+
} : null, G(u, o, v, r), D(t, o), o && R();
|
|
211
211
|
}
|
|
212
|
-
},
|
|
213
|
-
f ||
|
|
214
|
-
},
|
|
212
|
+
}, Q = () => {
|
|
213
|
+
f || F(e.editor.getCommandStates());
|
|
214
|
+
}, k = () => {
|
|
215
215
|
s.dataset.visible = "false", s.textContent = "";
|
|
216
|
-
},
|
|
216
|
+
}, Z = (a) => {
|
|
217
217
|
const l = a.dataset.tooltip;
|
|
218
218
|
if (!m || !l) return;
|
|
219
219
|
const b = a.getBoundingClientRect();
|
|
220
220
|
s.textContent = l, s.dataset.visible = "true", s.style.left = `${b.left + b.width / 2}px`, s.style.top = `${b.top - pt}px`;
|
|
221
|
-
}, F = (a) => {
|
|
222
|
-
const l = P(a.target);
|
|
223
|
-
l && Q(l);
|
|
224
221
|
}, O = (a) => {
|
|
222
|
+
const l = P(a.target);
|
|
223
|
+
l && Z(l);
|
|
224
|
+
}, j = (a) => {
|
|
225
225
|
const l = a.relatedTarget, b = P(a.target);
|
|
226
|
-
b && l instanceof Node && b.contains(l) ||
|
|
227
|
-
},
|
|
226
|
+
b && l instanceof Node && b.contains(l) || k();
|
|
227
|
+
}, _ = (a) => {
|
|
228
228
|
if (!(a instanceof HTMLButtonElement) || a.disabled) return;
|
|
229
229
|
const l = n.find((b) => b.id === a.dataset.bridgerteToolbarItemId);
|
|
230
230
|
if (l) {
|
|
@@ -234,7 +234,7 @@ function Et(t, e) {
|
|
|
234
234
|
menuId: l.id,
|
|
235
235
|
command: l.command,
|
|
236
236
|
panel: l.payloadPanel,
|
|
237
|
-
currentValues:
|
|
237
|
+
currentValues: at(l, e.editor.getCommandStates()),
|
|
238
238
|
anchorRect: {
|
|
239
239
|
x: b.left,
|
|
240
240
|
y: b.top,
|
|
@@ -247,67 +247,67 @@ function Et(t, e) {
|
|
|
247
247
|
e.editor.executeCommand(l.command);
|
|
248
248
|
}
|
|
249
249
|
}, C = (a, l = !1) => {
|
|
250
|
-
const b =
|
|
250
|
+
const b = $(
|
|
251
251
|
d,
|
|
252
252
|
a.dataset.bridgerteToolbarGroupId
|
|
253
253
|
);
|
|
254
254
|
if (!(!b || a.disabled)) {
|
|
255
255
|
if ((o == null ? void 0 : o.groupKey) === b.key) {
|
|
256
256
|
if (l) {
|
|
257
|
-
|
|
257
|
+
U(u, 0);
|
|
258
258
|
return;
|
|
259
259
|
}
|
|
260
|
-
|
|
260
|
+
T();
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
263
263
|
o = {
|
|
264
264
|
groupKey: b.key,
|
|
265
265
|
button: a,
|
|
266
266
|
items: b.items
|
|
267
|
-
},
|
|
267
|
+
}, k(), G(u, o, v, r), D(t, o), R(), l && U(u, 0);
|
|
268
268
|
}
|
|
269
|
-
},
|
|
270
|
-
const l =
|
|
269
|
+
}, S = (a) => {
|
|
270
|
+
const l = W(a.target);
|
|
271
271
|
if (l) {
|
|
272
272
|
if (a.preventDefault(), a.stopPropagation(), A.consumeSuppressedClick(l)) return;
|
|
273
273
|
C(l);
|
|
274
274
|
return;
|
|
275
275
|
}
|
|
276
276
|
const b = P(a.target);
|
|
277
|
-
b && (a.preventDefault(), a.stopPropagation(), !A.consumeSuppressedClick(b) && (
|
|
278
|
-
},
|
|
277
|
+
b && (a.preventDefault(), a.stopPropagation(), !A.consumeSuppressedClick(b) && (_(b), T()));
|
|
278
|
+
}, q = (a) => {
|
|
279
279
|
if (o && u.contains(document.activeElement)) {
|
|
280
|
-
|
|
280
|
+
it(
|
|
281
281
|
a,
|
|
282
282
|
u,
|
|
283
283
|
o.button,
|
|
284
|
-
|
|
285
|
-
|
|
284
|
+
_,
|
|
285
|
+
T
|
|
286
286
|
);
|
|
287
287
|
return;
|
|
288
288
|
}
|
|
289
|
-
const l =
|
|
289
|
+
const l = W(a.target);
|
|
290
290
|
if (l && (a.key === "Enter" || a.key === " " || a.key === "ArrowDown")) {
|
|
291
291
|
a.preventDefault(), a.stopPropagation(), C(l, !0);
|
|
292
292
|
return;
|
|
293
293
|
}
|
|
294
|
-
a.key === "Escape" &&
|
|
294
|
+
a.key === "Escape" && T();
|
|
295
295
|
};
|
|
296
296
|
t.classList.add("bridgerte__toolbar"), s.className = "bridgerte__toolbar-tooltip", s.dataset.visible = "false", u.className = "bridgerte__floating-menu bridgerte__toolbar-group-menu", u.dataset.visible = "false", u.setAttribute("role", "menu"), t.dataset.placement = i, t.setAttribute("role", "toolbar"), t.setAttribute(
|
|
297
297
|
"aria-label",
|
|
298
298
|
i === "bottom" ? "BridgeRTE tabbar" : "BridgeRTE toolbar"
|
|
299
|
-
), t.addEventListener("click",
|
|
299
|
+
), t.addEventListener("click", S), u.addEventListener("click", S), document.addEventListener("keydown", q), m && (t.addEventListener("mouseover", O), t.addEventListener("mouseout", j)), t.addEventListener("focusout", k), E();
|
|
300
300
|
const A = bt(
|
|
301
301
|
t,
|
|
302
302
|
u,
|
|
303
303
|
C,
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
),
|
|
304
|
+
_,
|
|
305
|
+
T
|
|
306
|
+
), tt = e.editor.subscribeCommandStateChange(F);
|
|
307
307
|
return {
|
|
308
|
-
update:
|
|
308
|
+
update: Q,
|
|
309
309
|
destroy() {
|
|
310
|
-
f || (f = !0,
|
|
310
|
+
f || (f = !0, tt(), T(), t.removeEventListener("click", S), u.removeEventListener("click", S), document.removeEventListener("keydown", q), A.destroy(), m && (t.removeEventListener("mouseover", O), t.removeEventListener("mouseout", j)), h(), L(), t.removeEventListener("focusout", k), s.remove(), u.remove(), t.classList.remove("bridgerte__toolbar"), delete t.dataset.placement, t.textContent = "", t.removeAttribute("role"), t.removeAttribute("aria-label"));
|
|
311
311
|
}
|
|
312
312
|
};
|
|
313
313
|
}
|
|
@@ -325,13 +325,13 @@ const gt = /[\u200B-\u200D\uFEFF]/g, vt = [
|
|
|
325
325
|
"svg",
|
|
326
326
|
"math",
|
|
327
327
|
'[data-type="mention"]'
|
|
328
|
-
].join(","),
|
|
329
|
-
if (!
|
|
328
|
+
].join(","), z = (t) => (t == null ? void 0 : t.replace(gt, "").trim()) ?? "", Tt = (t) => {
|
|
329
|
+
if (!z(t)) return !1;
|
|
330
330
|
const e = document.createElement("template");
|
|
331
|
-
return e.innerHTML = t, !!(
|
|
331
|
+
return e.innerHTML = t, !!(z(e.content.textContent) || e.content.querySelector(vt));
|
|
332
332
|
};
|
|
333
333
|
export {
|
|
334
334
|
Et as c,
|
|
335
335
|
Tt as h
|
|
336
336
|
};
|
|
337
|
-
//# sourceMappingURL=index-
|
|
337
|
+
//# sourceMappingURL=index-ZeQUaPbe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-ZeQUaPbe.js","sources":["../../dom/src/menuIcon/uiIcons.ts","../../dom/src/richTextToolbar/groupMenuKeyboard.ts","../../dom/src/richTextToolbar/render.ts","../../dom/src/richTextToolbar/groupMenuInteraction.ts","../../dom/src/richTextToolbar/index.ts","../../dom/src/htmlContent/index.ts"],"sourcesContent":["/**\n * DOM UI chrome icon 表。\n *\n * 这里放 toolbar 收纳入口、下拉箭头这类控件自身图标。它们不属于 `MenuItem.icon`\n * 跨端 schema,也不应该进入 `defaultMenuIcons` 的 schema 对齐检查。\n */\nexport const defaultMenuUiIcons = {\n toolbarGroup: `\n <svg\n aria-hidden=\"true\"\n class=\"lucide lucide-ellipsis\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n `,\n chevronDown: `\n <svg\n aria-hidden=\"true\"\n class=\"lucide lucide-chevron-down\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n `\n} as const;\n","export const getEnabledGroupMenuButtons = (menuElement: HTMLElement) => (\n Array.from(\n menuElement.querySelectorAll<HTMLButtonElement>('.bridgerte__toolbar-group-menu-item')\n ).filter((button) => !button.disabled)\n);\n\nexport const focusToolbarGroupMenuItem = (menuElement: HTMLElement, index: number) => {\n const buttons = getEnabledGroupMenuButtons(menuElement);\n const nextButton = buttons[index];\n\n if (nextButton) nextButton.focus();\n};\n\nexport const handleToolbarGroupMenuKeyDown = (\n event: KeyboardEvent,\n menuElement: HTMLElement,\n returnButton: HTMLButtonElement,\n executeToolbarButton: (button: HTMLButtonElement) => void,\n closeGroupMenu: () => void\n) => {\n const buttons = getEnabledGroupMenuButtons(menuElement);\n const activeIndex = document.activeElement instanceof HTMLButtonElement\n ? buttons.indexOf(document.activeElement)\n : -1;\n const focusByOffset = (offset: number) => {\n if (buttons.length === 0) return;\n\n const baseIndex = activeIndex >= 0 ? activeIndex : 0;\n const nextIndex = (baseIndex + offset + buttons.length) % buttons.length;\n\n buttons[nextIndex]?.focus();\n };\n\n /*\n * ARIA menu 语义要求支持 roving focus。这里不改 toolbar 的横向键盘模型,\n * 只在已打开的纵向收纳菜单内处理上下方向、首尾跳转和执行/关闭。\n */\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focusByOffset(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focusByOffset(-1);\n break;\n case 'Home':\n event.preventDefault();\n buttons[0]?.focus();\n break;\n case 'End':\n event.preventDefault();\n buttons.at(-1)?.focus();\n break;\n case 'Enter':\n case ' ':\n if (document.activeElement instanceof HTMLButtonElement) {\n event.preventDefault();\n executeToolbarButton(document.activeElement);\n closeGroupMenu();\n returnButton.focus();\n }\n break;\n case 'Escape':\n event.preventDefault();\n returnButton.focus();\n closeGroupMenu();\n break;\n default:\n break;\n }\n};\n","import type { CommandState } from '@bridgerte/core';\nimport type { MenuItem, ResolvedToolbarItem } from '@bridgerte/native-spec';\nimport {\n appendMenuIcon,\n defaultMenuIcons,\n defaultMenuUiIcons\n} from './icons';\nimport { getMenuStateForItem } from '../menuRuntime';\nimport type {\n RichTextToolbarIcons,\n ToolbarGroupMenuState\n} from './type';\n\nexport const toolbarGroupButtonSelector = 'button[data-bridgerte-toolbar-group-id]';\nexport const toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\n// 可执行按钮同时覆盖 toolbar 主按钮和 group menu 子项,避免浮层子菜单绕过统一命令入口。\nexport const toolbarExecutableButtonSelector = [\n toolbarButtonSelector,\n '.bridgerte__toolbar-group-menu-item'\n].join(',');\n\nconst getGroupMenuState = (items: MenuItem[], commandStates: CommandState[]) => {\n const itemStates = items.map((item) => getMenuStateForItem(item, commandStates));\n\n return {\n active: itemStates.some((state) => state.active),\n disabled: itemStates.length > 0 && itemStates.every((state) => state.disabled)\n };\n};\n\nconst renderToolbarButton = (\n groupElement: HTMLElement,\n item: MenuItem,\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n const state = getMenuStateForItem(item, commandStates);\n const button = document.createElement('button');\n // icon 兜底顺序固定为:业务覆盖 > DOM 默认 SVG > label 文本。\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\n\n button.type = 'button';\n button.className = 'bridgerte__toolbar-button';\n button.disabled = state.disabled;\n button.dataset.active = String(state.active);\n button.dataset.bridgerteToolbarItemId = item.id;\n button.setAttribute('aria-label', item.label);\n button.setAttribute('aria-pressed', String(state.active));\n if (enableTooltip) button.dataset.tooltip = item.label;\n\n appendMenuIcon(button, iconSvg, item.label);\n\n groupElement.append(button);\n};\n\nconst renderToolbarGroupButton = (\n groupElement: HTMLElement,\n toolbarItem: Extract<ResolvedToolbarItem, { type: 'group' }>,\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n const button = document.createElement('button');\n const groupState = getGroupMenuState(toolbarItem.items, commandStates);\n const iconSvg = toolbarItem.icon\n ? icons[toolbarItem.icon] ?? defaultMenuIcons[toolbarItem.icon]\n : defaultMenuUiIcons.toolbarGroup;\n const indicator = document.createElement('span');\n\n button.type = 'button';\n button.className = 'bridgerte__toolbar-button bridgerte__toolbar-group-button';\n button.disabled = groupState.disabled;\n button.dataset.active = String(groupState.active);\n button.dataset.bridgerteToolbarGroupId = toolbarItem.key;\n button.dataset.open = 'false';\n button.setAttribute('aria-label', toolbarItem.title);\n button.setAttribute('aria-haspopup', 'menu');\n button.setAttribute('aria-expanded', 'false');\n button.setAttribute('aria-pressed', String(groupState.active));\n if (enableTooltip) button.dataset.tooltip = toolbarItem.title;\n\n appendMenuIcon(button, iconSvg, toolbarItem.title);\n\n indicator.className = 'bridgerte__toolbar-group-indicator';\n indicator.setAttribute('aria-hidden', 'true');\n indicator.innerHTML = defaultMenuUiIcons.chevronDown;\n button.append(indicator);\n groupElement.append(button);\n};\n\n/**\n * 渲染 toolbar 横向主入口。\n *\n * 字符串菜单直接渲染为按钮,`|` 渲染分割线。\n * 只有用户显式声明的 group 配置才生成收纳入口,避免 schema 隐式改变 DOM 结构。\n */\nexport const renderToolbar = (\n toolbarElement: HTMLElement,\n toolbarItems: ResolvedToolbarItem[],\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n toolbarElement.textContent = '';\n\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;\n separatorElement.setAttribute('aria-hidden', 'true');\n toolbarElement.append(separatorElement);\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\n );\n });\n};\n\n/**\n * 渲染 group button 打开的纵向收纳菜单。\n *\n * 浮层只展示 MenuItem 子项并复用现有 item id,点击执行仍由 index.ts 统一走 EditorAPI。\n */\nexport const renderToolbarGroupMenu = (\n menuElement: HTMLElement,\n groupMenuState: ToolbarGroupMenuState | null,\n commandStates: CommandState[],\n icons: RichTextToolbarIcons\n) => {\n menuElement.textContent = '';\n\n if (!groupMenuState) {\n menuElement.dataset.visible = 'false';\n return;\n }\n\n groupMenuState.items.forEach((item) => {\n const state = getMenuStateForItem(item, commandStates);\n const button = document.createElement('button');\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\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;\n button.dataset.active = String(state.active);\n button.dataset.bridgerteToolbarItemId = item.id;\n button.setAttribute('role', 'menuitem');\n button.setAttribute('aria-label', item.label);\n button.setAttribute('aria-pressed', String(state.active));\n\n appendMenuIcon(button, iconSvg, item.label);\n labelElement.className = 'bridgerte__toolbar-group-menu-label';\n labelElement.textContent = item.label;\n button.append(labelElement);\n menuElement.append(button);\n });\n\n menuElement.dataset.visible = 'true';\n menuElement.style.minWidth = `${groupMenuState.button.offsetWidth}px`;\n};\n\nexport const syncToolbarGroupButtonState = (\n container: HTMLElement,\n groupMenuState: ToolbarGroupMenuState | null\n) => {\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector).forEach((button) => {\n const open = groupMenuState?.groupKey === button.dataset.bridgerteToolbarGroupId;\n\n button.dataset.open = String(open);\n button.setAttribute('aria-expanded', String(open));\n });\n};\n\nexport const findToolbarGroupMenuItem = (\n toolbarItems: ResolvedToolbarItem[],\n groupKey: string | undefined\n) => toolbarItems.find((item): item is Extract<ResolvedToolbarItem, { type: 'group' }> => (\n item.type === 'group' && item.key === groupKey\n));\n","import {\n toolbarButtonSelector,\n toolbarExecutableButtonSelector,\n toolbarGroupButtonSelector\n} from './render';\n\nconst toolbarGroupTouchMoveTolerancePx = 8;\n\nconst isInsideNode = (container: HTMLElement, target: EventTarget | null) => (\n target instanceof Node && container.contains(target)\n);\n\nconst getClosestButton = (\n target: EventTarget | null,\n selector: string\n) => (\n target instanceof Element ? target.closest<HTMLButtonElement>(selector) : null\n);\n\n/**\n * 创建 toolbar 收纳菜单交互控制器。\n *\n * 这个控制器统一处理 toolbar 可点击项的提交边界:顶层按钮、收纳入口和收纳菜单项\n * 在按下阶段都不能抢走编辑器焦点。触屏 tap 需要在 touchend 主动完成,避免浏览器\n * 生成的尾随 click 重复执行;外部 pointerdown 仍只负责关闭已打开的收纳菜单。\n */\nexport const createToolbarGroupMenuInteraction = (\n container: HTMLElement,\n groupMenuElement: HTMLElement,\n toggleGroupMenu: (button: HTMLButtonElement) => void,\n executeToolbarButton: (button: HTMLButtonElement) => void,\n closeGroupMenu: () => void\n) => {\n let pendingTouch: {\n button: HTMLButtonElement;\n kind: 'button' | 'group' | 'menu-item';\n startX: number;\n startY: number;\n } | null = null;\n let suppressNextClickButton: HTMLButtonElement | null = null;\n\n const getInteractiveButtonFromTarget = (target: EventTarget | null) => (\n getClosestButton(target, toolbarGroupButtonSelector)\n ?? getClosestButton(target, toolbarButtonSelector)\n ?? (\n isInsideNode(groupMenuElement, target)\n ? getClosestButton(target, toolbarExecutableButtonSelector)\n : null\n )\n );\n\n const handlePressStart = (event: PointerEvent | MouseEvent) => {\n const button = getInteractiveButtonFromTarget(event.target);\n\n if (!button) return;\n\n /*\n * toolbar 按钮属于编辑器工具区。按下阶段阻止默认 focus 转移,\n * 让 PC 和触屏端都能在不丢失正文 selection 的情况下执行命令。\n */\n event.preventDefault();\n };\n\n const handleTouchStart = (event: TouchEvent) => {\n const touch = event.touches[0];\n const groupButton = getClosestButton(event.target, toolbarGroupButtonSelector);\n const toolbarButton = getClosestButton(event.target, toolbarButtonSelector);\n const menuItemButton = isInsideNode(groupMenuElement, event.target)\n ? getClosestButton(event.target, toolbarExecutableButtonSelector)\n : null;\n const button = groupButton ?? toolbarButton ?? menuItemButton;\n\n if (!button || !touch) return;\n\n event.preventDefault();\n pendingTouch = {\n button,\n kind: groupButton ? 'group' : menuItemButton ? 'menu-item' : 'button',\n startX: touch.clientX,\n startY: touch.clientY\n };\n };\n\n const clearPendingTouch = () => {\n pendingTouch = null;\n };\n\n const handleTouchEnd = (event: TouchEvent) => {\n if (!pendingTouch) return;\n\n const touchState = pendingTouch;\n const touch = event.changedTouches[0];\n const endButton = getInteractiveButtonFromTarget(event.target);\n\n pendingTouch = null;\n if (!touch || endButton !== touchState.button) return;\n\n const deltaX = Math.abs(touch.clientX - touchState.startX);\n const deltaY = Math.abs(touch.clientY - touchState.startY);\n\n if (\n deltaX > toolbarGroupTouchMoveTolerancePx\n || deltaY > toolbarGroupTouchMoveTolerancePx\n ) return;\n\n event.preventDefault();\n event.stopPropagation();\n suppressNextClickButton = touchState.button;\n\n if (touchState.kind === 'group') {\n toggleGroupMenu(touchState.button);\n return;\n }\n\n executeToolbarButton(touchState.button);\n closeGroupMenu();\n };\n\n const handleDocumentPointerDown = (event: PointerEvent) => {\n if (\n isInsideNode(container, event.target)\n || isInsideNode(groupMenuElement, event.target)\n ) return;\n\n closeGroupMenu();\n };\n\n container.addEventListener('pointerdown', handlePressStart);\n container.addEventListener('mousedown', handlePressStart);\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchend', handleTouchEnd);\n container.addEventListener('touchcancel', clearPendingTouch);\n groupMenuElement.addEventListener('pointerdown', handlePressStart);\n groupMenuElement.addEventListener('mousedown', handlePressStart);\n groupMenuElement.addEventListener('touchstart', handleTouchStart, { passive: false });\n groupMenuElement.addEventListener('touchend', handleTouchEnd);\n groupMenuElement.addEventListener('touchcancel', clearPendingTouch);\n document.addEventListener('pointerdown', handleDocumentPointerDown, true);\n\n return {\n consumeSuppressedClick(button: HTMLButtonElement) {\n if (suppressNextClickButton !== button) return false;\n\n suppressNextClickButton = null;\n return true;\n },\n destroy() {\n container.removeEventListener('pointerdown', handlePressStart);\n container.removeEventListener('mousedown', handlePressStart);\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchend', handleTouchEnd);\n container.removeEventListener('touchcancel', clearPendingTouch);\n groupMenuElement.removeEventListener('pointerdown', handlePressStart);\n groupMenuElement.removeEventListener('mousedown', handlePressStart);\n groupMenuElement.removeEventListener('touchstart', handleTouchStart);\n groupMenuElement.removeEventListener('touchend', handleTouchEnd);\n groupMenuElement.removeEventListener('touchcancel', clearPendingTouch);\n document.removeEventListener('pointerdown', handleDocumentPointerDown, true);\n }\n };\n};\n","import type { CommandState } from '@bridgerte/core';\nimport {\n defaultMenuSchema,\n resolveToolbarMenu\n} from '@bridgerte/native-spec';\nimport { createFloatingLayer, type RichTextFloatingLayer } from '../floatingLayer';\nimport { bindTouchPressedState } from '../interactionState';\nimport {\n getPayloadPanelCurrentValues,\n resolveMenuSchemaForDom\n} from '../menuRuntime';\nimport {\n focusToolbarGroupMenuItem,\n handleToolbarGroupMenuKeyDown\n} from './groupMenuKeyboard';\nimport { createToolbarGroupMenuInteraction } from './groupMenuInteraction';\nimport {\n findToolbarGroupMenuItem,\n renderToolbar,\n renderToolbarGroupMenu,\n syncToolbarGroupButtonState,\n toolbarExecutableButtonSelector,\n toolbarGroupButtonSelector\n} from './render';\nimport type {\n RichTextToolbarAPI,\n ToolbarGroupMenuState,\n RichTextToolbarOptions\n} from './type';\n\nconst toolbarTooltipOffsetPx = 8;\nconst toolbarGroupMenuOffsetPx = 6;\n\nexport type * from './type';\n\nconst canUseHoverTooltip = () => (\n typeof window !== 'undefined'\n && window.matchMedia?.('(hover: hover) and (pointer: fine)').matches === true\n);\n\nconst getToolbarButtonFromTarget = (target: EventTarget | null) => {\n /*\n * 图标覆盖常用 SVG,H5 pointer 事件可能落在 svg/path 上。\n * 这里用 Element 而不是 HTMLElement,保证触屏兜底和 click 都能向上命中真实按钮。\n */\n const button = target instanceof Element\n ? target.closest<HTMLButtonElement>(toolbarExecutableButtonSelector)\n : null;\n\n return button instanceof HTMLButtonElement ? button : null;\n};\n\nconst getToolbarGroupButtonFromTarget = (target: EventTarget | null) => {\n const button = target instanceof Element\n ? target.closest<HTMLButtonElement>(toolbarGroupButtonSelector)\n : null;\n\n return button instanceof HTMLButtonElement ? button : null;\n};\n\n/**\n * 创建独立菜单实例。\n *\n * toolbar/tabbar 只订阅 EditorAPI 状态并派发命令,不接触编辑器内部 DOM 或 Lexical 实例。\n */\nexport function createRichTextToolbar(\n container: HTMLElement,\n options: RichTextToolbarOptions\n): RichTextToolbarAPI {\n const placement = options.placement ?? 'top';\n const menuSchema = resolveMenuSchemaForDom(options.menuSchema ?? defaultMenuSchema, {\n menuLabels: options.menuLabels,\n payloadPanelConfig: options.payloadPanelConfig\n });\n const toolbarItems = resolveToolbarMenu(options.toolbarConfig, menuSchema);\n /*\n * click 事件只需要能执行命令的菜单项。分割线和 group 容器是渲染结构,\n * 先在这里摊平,后续点击时就不用理解 toolbarConfig 的展示层级。\n */\n const executableMenuItems = toolbarItems.flatMap((toolbarItem) => (\n toolbarItem.type === 'button' ? [toolbarItem.item]\n : toolbarItem.type === 'group' ? toolbarItem.items\n : []\n ));\n const icons = options.icons ?? {};\n /*\n * tooltip 只属于 PC 精细指针体验。H5 上即使没有原生 title,部分浏览器也会把 hover/mouseover\n * 模拟成首触摸状态,导致第一次点像是只唤醒提示;所以触屏端不写 tooltip 数据也不挂监听。\n */\n const enableTooltip = canUseHoverTooltip();\n const tooltipElement = document.createElement('div');\n const groupMenuElement = document.createElement('div');\n const overlayHost = container.closest('.bridgerte') ?? container;\n let destroyed = false;\n let latestCommandStates = options.editor.getCommandStates();\n let groupMenuState: ToolbarGroupMenuState | null = null;\n let groupMenuFloatingLayer: RichTextFloatingLayer | null = null;\n const clearToolbarPressedState = bindTouchPressedState(container, {\n targetSelector: [\n 'button[data-bridgerte-toolbar-item-id]',\n 'button[data-bridgerte-toolbar-group-id]'\n ].join(',')\n });\n const clearGroupMenuPressedState = bindTouchPressedState(groupMenuElement, {\n targetSelector: '.bridgerte__toolbar-group-menu-item'\n });\n\n const mountToolbarOverlays = () => {\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\n overlayHost.append(tooltipElement);\n overlayHost.append(groupMenuElement);\n };\n\n const closeGroupMenuFloatingLayer = () => {\n groupMenuFloatingLayer?.setOpen(false);\n groupMenuFloatingLayer?.destroy();\n groupMenuFloatingLayer = null;\n };\n\n const openGroupMenuFloatingLayer = () => {\n if (!groupMenuState) return;\n\n closeGroupMenuFloatingLayer();\n /*\n * group menu 和 hoverbar/mention/slash 一样属于轻浮层,必须走 floatingLayer。\n * 这里按 toolbar placement 给出首选方向,真正的翻转、键盘可视区和左右夹紧交给\n * createFloatingLayer 内部的 visualViewport + flip + shift + clamp 统一处理。\n */\n groupMenuFloatingLayer = createFloatingLayer(groupMenuState.button, groupMenuElement, {\n placement: placement === 'bottom' ? 'top-start' : 'bottom-start',\n offset: toolbarGroupMenuOffsetPx,\n strategy: 'fixed'\n });\n groupMenuFloatingLayer.setOpen(true);\n };\n\n const closeGroupMenu = () => {\n if (!groupMenuState && !groupMenuFloatingLayer) return;\n\n closeGroupMenuFloatingLayer();\n groupMenuState = null;\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\n syncToolbarGroupButtonState(container, groupMenuState);\n };\n\n const renderStates = (states: CommandState[]) => {\n if (destroyed) return;\n\n latestCommandStates = states;\n if (groupMenuState) closeGroupMenuFloatingLayer();\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\n mountToolbarOverlays();\n if (groupMenuState) {\n const nextButton = Array.from(\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector)\n ).find((button) => button.dataset.bridgerteToolbarGroupId === groupMenuState?.groupKey);\n const nextGroupItem = findToolbarGroupMenuItem(toolbarItems, groupMenuState.groupKey);\n\n groupMenuState = nextButton && nextGroupItem\n ? {\n groupKey: groupMenuState.groupKey,\n button: nextButton,\n items: nextGroupItem.items\n }\n : null;\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\n syncToolbarGroupButtonState(container, groupMenuState);\n if (groupMenuState) openGroupMenuFloatingLayer();\n }\n };\n\n const update = () => {\n if (destroyed) return;\n\n renderStates(options.editor.getCommandStates());\n };\n\n const hideTooltip = () => {\n tooltipElement.dataset.visible = 'false';\n tooltipElement.textContent = '';\n };\n\n const showTooltip = (button: HTMLButtonElement) => {\n const tooltipText = button.dataset.tooltip;\n\n if (!enableTooltip || !tooltipText) return;\n\n const buttonRect = button.getBoundingClientRect();\n\n tooltipElement.textContent = tooltipText;\n tooltipElement.dataset.visible = 'true';\n tooltipElement.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n tooltipElement.style.top = `${buttonRect.top - toolbarTooltipOffsetPx}px`;\n };\n\n const handleTooltipTarget = (event: Event) => {\n const button = getToolbarButtonFromTarget(event.target);\n\n if (button) {\n showTooltip(button);\n }\n };\n\n const handleTooltipLeave = (event: MouseEvent) => {\n const relatedTarget = event.relatedTarget;\n const button = getToolbarButtonFromTarget(event.target);\n\n if (\n button\n && relatedTarget instanceof Node\n && button.contains(relatedTarget)\n ) return;\n\n hideTooltip();\n };\n\n const executeToolbarButton = (button: HTMLButtonElement) => {\n if (!(button instanceof HTMLButtonElement) || button.disabled) return;\n\n const menuItem = executableMenuItems.find((item) => (\n item.id === button.dataset.bridgerteToolbarItemId\n ));\n\n if (!menuItem) return;\n\n if (menuItem.payloadPanel) {\n const buttonRect = button.getBoundingClientRect();\n\n /*\n * 带 payloadPanel 的菜单不直接执行基础 command,而是发起参数请求。\n * DOM 内置面板和业务/RN/Flutter 自绘都走同一个 request,避免后续颜色、\n * 字体、链接等参数菜单各自发明一套协议。\n */\n options.editor.requestPayloadPanel({\n menuId: menuItem.id,\n command: menuItem.command,\n panel: menuItem.payloadPanel,\n currentValues: getPayloadPanelCurrentValues(menuItem, options.editor.getCommandStates()),\n anchorRect: {\n x: buttonRect.left,\n y: buttonRect.top,\n width: buttonRect.width,\n height: buttonRect.height\n }\n });\n return;\n }\n\n options.editor.executeCommand(menuItem.command);\n };\n\n const toggleGroupMenu = (button: HTMLButtonElement, shouldFocusMenu = false) => {\n const groupItem = findToolbarGroupMenuItem(\n toolbarItems,\n button.dataset.bridgerteToolbarGroupId\n );\n\n if (!groupItem || button.disabled) return;\n\n if (groupMenuState?.groupKey === groupItem.key) {\n if (shouldFocusMenu) {\n focusToolbarGroupMenuItem(groupMenuElement, 0);\n return;\n }\n closeGroupMenu();\n return;\n }\n\n groupMenuState = {\n groupKey: groupItem.key,\n button,\n items: groupItem.items\n };\n hideTooltip();\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\n syncToolbarGroupButtonState(container, groupMenuState);\n openGroupMenuFloatingLayer();\n if (shouldFocusMenu) focusToolbarGroupMenuItem(groupMenuElement, 0);\n };\n\n const handleClick = (event: MouseEvent) => {\n const groupButton = getToolbarGroupButtonFromTarget(event.target);\n if (groupButton) {\n event.preventDefault();\n event.stopPropagation();\n if (groupMenuInteraction.consumeSuppressedClick(groupButton)) return;\n\n toggleGroupMenu(groupButton);\n return;\n }\n\n const button = getToolbarButtonFromTarget(event.target);\n if (!button) return;\n\n event.preventDefault();\n event.stopPropagation();\n if (groupMenuInteraction.consumeSuppressedClick(button)) return;\n\n executeToolbarButton(button);\n closeGroupMenu();\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (groupMenuState && groupMenuElement.contains(document.activeElement)) {\n handleToolbarGroupMenuKeyDown(\n event,\n groupMenuElement,\n groupMenuState.button,\n executeToolbarButton,\n closeGroupMenu\n );\n return;\n }\n\n const groupButton = getToolbarGroupButtonFromTarget(event.target);\n if (\n groupButton\n && (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown')\n ) {\n /*\n * 指针点击收纳菜单不能抢编辑器焦点;键盘从入口按钮打开时则进入菜单项,\n * 保留 PC 可访问性和方向键 roving focus。\n */\n event.preventDefault();\n event.stopPropagation();\n toggleGroupMenu(groupButton, true);\n return;\n }\n\n if (event.key !== 'Escape') return;\n\n closeGroupMenu();\n };\n\n container.classList.add('bridgerte__toolbar');\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\n tooltipElement.dataset.visible = 'false';\n groupMenuElement.className = 'bridgerte__floating-menu bridgerte__toolbar-group-menu';\n groupMenuElement.dataset.visible = 'false';\n groupMenuElement.setAttribute('role', 'menu');\n container.dataset.placement = placement;\n container.setAttribute('role', 'toolbar');\n container.setAttribute(\n 'aria-label',\n placement === 'bottom' ? 'BridgeRTE tabbar' : 'BridgeRTE toolbar'\n );\n container.addEventListener('click', handleClick);\n groupMenuElement.addEventListener('click', handleClick);\n document.addEventListener('keydown', handleKeyDown);\n if (enableTooltip) {\n container.addEventListener('mouseover', handleTooltipTarget);\n container.addEventListener('mouseout', handleTooltipLeave);\n }\n container.addEventListener('focusout', hideTooltip);\n // 浮层挂在最近的编辑器根容器下,既能继承变量,也不会操作编辑内容 DOM。\n mountToolbarOverlays();\n const groupMenuInteraction = createToolbarGroupMenuInteraction(\n container,\n groupMenuElement,\n toggleGroupMenu,\n executeToolbarButton,\n closeGroupMenu\n );\n\n // 独立 toolbar 只订阅 public API 状态,不依赖 DOM 编辑器内部实现。\n const unsubscribe = options.editor.subscribeCommandStateChange(renderStates);\n\n return {\n update,\n destroy() {\n if (destroyed) return;\n\n destroyed = true;\n unsubscribe();\n closeGroupMenu();\n container.removeEventListener('click', handleClick);\n groupMenuElement.removeEventListener('click', handleClick);\n document.removeEventListener('keydown', handleKeyDown);\n groupMenuInteraction.destroy();\n if (enableTooltip) {\n container.removeEventListener('mouseover', handleTooltipTarget);\n container.removeEventListener('mouseout', handleTooltipLeave);\n }\n clearToolbarPressedState();\n clearGroupMenuPressedState();\n container.removeEventListener('focusout', hideTooltip);\n tooltipElement.remove();\n groupMenuElement.remove();\n container.classList.remove('bridgerte__toolbar');\n delete container.dataset.placement;\n container.textContent = '';\n container.removeAttribute('role');\n container.removeAttribute('aria-label');\n }\n };\n}\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","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","toolbarGroupTouchMoveTolerancePx","isInsideNode","target","getClosestButton","selector","createToolbarGroupMenuInteraction","groupMenuElement","toggleGroupMenu","pendingTouch","suppressNextClickButton","getInteractiveButtonFromTarget","handlePressStart","handleTouchStart","touch","groupButton","toolbarButton","menuItemButton","clearPendingTouch","handleTouchEnd","touchState","endButton","deltaX","deltaY","handleDocumentPointerDown","toolbarTooltipOffsetPx","toolbarGroupMenuOffsetPx","canUseHoverTooltip","getToolbarButtonFromTarget","getToolbarGroupButtonFromTarget","createRichTextToolbar","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","overlayHost","destroyed","latestCommandStates","groupMenuFloatingLayer","clearToolbarPressedState","bindTouchPressedState","clearGroupMenuPressedState","mountToolbarOverlays","closeGroupMenuFloatingLayer","openGroupMenuFloatingLayer","createFloatingLayer","renderStates","states","nextGroupItem","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","handleTooltipLeave","relatedTarget","menuItem","getPayloadPanelCurrentValues","shouldFocusMenu","groupItem","handleClick","groupMenuInteraction","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-
|
|
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-C9gc8336.cjs"),o=require("./index-CVyAIGlg.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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
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
|
-
import { c as I, a as M, b as N } from "./index-
|
|
5
|
-
import { c as b, h as p } from "./index-
|
|
4
|
+
import { c as I, a as M, b as N } from "./index-IG7bnHAR.js";
|
|
5
|
+
import { c as b, h as p } from "./index-ZeQUaPbe.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/webview.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-C9gc8336.cjs");exports.createWebViewBridgeRuntime=e.createWebViewBridgeRuntime;
|
|
2
2
|
//# sourceMappingURL=webview.cjs.map
|
package/dist/webview.js
CHANGED