@youcan/celeste 0.6.30 → 0.6.32

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.
Files changed (101) hide show
  1. package/dist/celeste.css +483 -264
  2. package/dist/cjs/alert.js +2 -2
  3. package/dist/cjs/chunks/index.js +229 -2
  4. package/dist/cjs/chunks/index2.js +1457 -0
  5. package/dist/cjs/chunks/index3.js +16457 -0
  6. package/dist/cjs/chunks/sonner.js +1154 -0
  7. package/dist/cjs/config.js +136 -0
  8. package/dist/cjs/extra-settings.js +155 -0
  9. package/dist/cjs/index.js +75 -0
  10. package/dist/cjs/label.js +2 -2
  11. package/dist/cjs/link-bubble.js +228 -0
  12. package/dist/cjs/link-button.js +2 -2
  13. package/dist/cjs/rich-editor.js +4996 -0
  14. package/dist/cjs/select-icon.js +2 -2
  15. package/dist/cjs/sonner-alert.js +41 -0
  16. package/dist/cjs/sonner.js +3 -0
  17. package/dist/cjs/text-input-affix.js +2 -2
  18. package/dist/cjs/types.js +1 -0
  19. package/dist/components/index.d.ts +2 -0
  20. package/dist/components/rich-editor/config.d.ts +33 -0
  21. package/dist/components/rich-editor/extra-settings.d.ts +6 -0
  22. package/dist/components/rich-editor/index.d.ts +2 -0
  23. package/dist/components/rich-editor/link-bubble.d.ts +11 -0
  24. package/dist/components/rich-editor/rich-editor.d.ts +55 -0
  25. package/dist/components/rich-editor/types.d.ts +19 -0
  26. package/dist/components/sonner/index.d.ts +4 -0
  27. package/dist/components/sonner/sonner-alert.d.ts +13 -0
  28. package/dist/components/sonner/sonner.d.ts +5 -0
  29. package/dist/es/alert.js +2 -2
  30. package/dist/es/checkbox-label.js +1 -1
  31. package/dist/es/chunks/index.js +277 -50
  32. package/dist/es/chunks/index2.js +1457 -0
  33. package/dist/es/chunks/index3.js +16458 -0
  34. package/dist/es/chunks/sonner.js +1155 -0
  35. package/dist/es/combobox-group.js +1 -1
  36. package/dist/es/combobox-input.js +1 -1
  37. package/dist/es/combobox-item.js +1 -1
  38. package/dist/es/combobox-list.js +1 -1
  39. package/dist/es/combobox-root.js +1 -1
  40. package/dist/es/combobox-separator.js +1 -1
  41. package/dist/es/combobox-trigger.js +1 -1
  42. package/dist/es/command-group.js +1 -1
  43. package/dist/es/command-input.js +1 -1
  44. package/dist/es/command-item.js +1 -1
  45. package/dist/es/command-list.js +1 -1
  46. package/dist/es/command-root.js +1 -1
  47. package/dist/es/command-separator.js +1 -1
  48. package/dist/es/config.js +136 -0
  49. package/dist/es/dropdown-menu-group.js +1 -1
  50. package/dist/es/dropdown-menu-item.js +1 -1
  51. package/dist/es/dropdown-menu-label.js +1 -1
  52. package/dist/es/dropdown-menu-separator.js +1 -1
  53. package/dist/es/dropdown-menu-trigger.js +1 -1
  54. package/dist/es/dropdown-menu.js +1 -1
  55. package/dist/es/dropdown.js +1 -1
  56. package/dist/es/extra-settings.js +156 -0
  57. package/dist/es/index.js +94 -19
  58. package/dist/es/label.js +3 -3
  59. package/dist/es/link-bubble.js +229 -0
  60. package/dist/es/link-button.js +2 -2
  61. package/dist/es/modal-content.js +1 -1
  62. package/dist/es/modal-header.js +1 -1
  63. package/dist/es/popover-content.js +1 -1
  64. package/dist/es/popover-trigger.js +1 -1
  65. package/dist/es/rich-editor.js +4997 -0
  66. package/dist/es/scroll-bar.js +1 -1
  67. package/dist/es/segmented-control-item.js +1 -1
  68. package/dist/es/segmented-control.js +1 -1
  69. package/dist/es/select-content.js +1 -1
  70. package/dist/es/select-icon.js +2 -2
  71. package/dist/es/select-item.js +1 -1
  72. package/dist/es/select-trigger.js +1 -1
  73. package/dist/es/select-value.js +1 -1
  74. package/dist/es/sonner-alert.js +42 -0
  75. package/dist/es/sonner.js +4 -0
  76. package/dist/es/tab-menu-content.js +1 -1
  77. package/dist/es/tab-menu-item.js +1 -1
  78. package/dist/es/tab-menu-list.js +1 -1
  79. package/dist/es/tab-menu.js +1 -1
  80. package/dist/es/text-input-affix.js +2 -2
  81. package/dist/es/tooltip.js +1 -1
  82. package/dist/es/types.js +1 -0
  83. package/dist/index.d.ts +1 -0
  84. package/dist/utils/index.d.ts +3 -0
  85. package/dist/utils/sonner.d.ts +19 -0
  86. package/package.json +15 -4
  87. package/src/components/index.ts +2 -0
  88. package/src/components/rich-editor/config.ts +150 -0
  89. package/src/components/rich-editor/extra-settings.vue +151 -0
  90. package/src/components/rich-editor/index.ts +2 -0
  91. package/src/components/rich-editor/link-bubble.vue +288 -0
  92. package/src/components/rich-editor/rich-editor.vue +428 -0
  93. package/src/components/rich-editor/stories/rich-editor.stories.ts +87 -0
  94. package/src/components/rich-editor/types.ts +21 -0
  95. package/src/components/sonner/index.ts +5 -0
  96. package/src/components/sonner/sonner-alert.vue +54 -0
  97. package/src/components/sonner/sonner.vue +13 -0
  98. package/src/components/sonner/stories/sonner.stories.ts +194 -0
  99. package/src/index.ts +1 -0
  100. package/src/utils/index.ts +3 -0
  101. package/src/utils/sonner.ts +72 -0
@@ -0,0 +1,1457 @@
1
+ import { P as PluginKey, S as Selection, k as keydownHandler, a as SelectionRange, T as TextSelection, F as Fragment, b as Slice, E as Extension, c as Plugin, i as isTextSelection, p as posToDOMRect, g as getText, d as getTextSerializersFromSchema } from "./index3.js";
2
+ import { g as flip, s as shift, l as offset, p as arrow$1, r as size, v as autoPlacement, B as hide, D as inline, E as computePosition } from "./index.js";
3
+ import { defineComponent, ref, onMounted, onBeforeUnmount, h, Teleport } from "vue";
4
+ var readFromCache;
5
+ var addToCache;
6
+ if (typeof WeakMap != "undefined") {
7
+ let cache = /* @__PURE__ */ new WeakMap();
8
+ readFromCache = (key) => cache.get(key);
9
+ addToCache = (key, value) => {
10
+ cache.set(key, value);
11
+ return value;
12
+ };
13
+ } else {
14
+ const cache = [];
15
+ const cacheSize = 10;
16
+ let cachePos = 0;
17
+ readFromCache = (key) => {
18
+ for (let i = 0; i < cache.length; i += 2)
19
+ if (cache[i] == key) return cache[i + 1];
20
+ };
21
+ addToCache = (key, value) => {
22
+ if (cachePos == cacheSize) cachePos = 0;
23
+ cache[cachePos++] = key;
24
+ return cache[cachePos++] = value;
25
+ };
26
+ }
27
+ var TableMap = class {
28
+ constructor(width, height, map, problems) {
29
+ this.width = width;
30
+ this.height = height;
31
+ this.map = map;
32
+ this.problems = problems;
33
+ }
34
+ // Find the dimensions of the cell at the given position.
35
+ findCell(pos) {
36
+ for (let i = 0; i < this.map.length; i++) {
37
+ const curPos = this.map[i];
38
+ if (curPos != pos) continue;
39
+ const left = i % this.width;
40
+ const top = i / this.width | 0;
41
+ let right = left + 1;
42
+ let bottom = top + 1;
43
+ for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) {
44
+ right++;
45
+ }
46
+ for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) {
47
+ bottom++;
48
+ }
49
+ return { left, top, right, bottom };
50
+ }
51
+ throw new RangeError(`No cell with offset ${pos} found`);
52
+ }
53
+ // Find the left side of the cell at the given position.
54
+ colCount(pos) {
55
+ for (let i = 0; i < this.map.length; i++) {
56
+ if (this.map[i] == pos) {
57
+ return i % this.width;
58
+ }
59
+ }
60
+ throw new RangeError(`No cell with offset ${pos} found`);
61
+ }
62
+ // Find the next cell in the given direction, starting from the cell
63
+ // at `pos`, if any.
64
+ nextCell(pos, axis, dir) {
65
+ const { left, right, top, bottom } = this.findCell(pos);
66
+ if (axis == "horiz") {
67
+ if (dir < 0 ? left == 0 : right == this.width) return null;
68
+ return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
69
+ } else {
70
+ if (dir < 0 ? top == 0 : bottom == this.height) return null;
71
+ return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
72
+ }
73
+ }
74
+ // Get the rectangle spanning the two given cells.
75
+ rectBetween(a, b) {
76
+ const {
77
+ left: leftA,
78
+ right: rightA,
79
+ top: topA,
80
+ bottom: bottomA
81
+ } = this.findCell(a);
82
+ const {
83
+ left: leftB,
84
+ right: rightB,
85
+ top: topB,
86
+ bottom: bottomB
87
+ } = this.findCell(b);
88
+ return {
89
+ left: Math.min(leftA, leftB),
90
+ top: Math.min(topA, topB),
91
+ right: Math.max(rightA, rightB),
92
+ bottom: Math.max(bottomA, bottomB)
93
+ };
94
+ }
95
+ // Return the position of all cells that have the top left corner in
96
+ // the given rectangle.
97
+ cellsInRect(rect) {
98
+ const result = [];
99
+ const seen = {};
100
+ for (let row = rect.top; row < rect.bottom; row++) {
101
+ for (let col = rect.left; col < rect.right; col++) {
102
+ const index = row * this.width + col;
103
+ const pos = this.map[index];
104
+ if (seen[pos]) continue;
105
+ seen[pos] = true;
106
+ if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) {
107
+ continue;
108
+ }
109
+ result.push(pos);
110
+ }
111
+ }
112
+ return result;
113
+ }
114
+ // Return the position at which the cell at the given row and column
115
+ // starts, or would start, if a cell started there.
116
+ positionAt(row, col, table) {
117
+ for (let i = 0, rowStart = 0; ; i++) {
118
+ const rowEnd = rowStart + table.child(i).nodeSize;
119
+ if (i == row) {
120
+ let index = col + row * this.width;
121
+ const rowEndIndex = (row + 1) * this.width;
122
+ while (index < rowEndIndex && this.map[index] < rowStart) index++;
123
+ return index == rowEndIndex ? rowEnd - 1 : this.map[index];
124
+ }
125
+ rowStart = rowEnd;
126
+ }
127
+ }
128
+ // Find the table map for the given table node.
129
+ static get(table) {
130
+ return readFromCache(table) || addToCache(table, computeMap(table));
131
+ }
132
+ };
133
+ function computeMap(table) {
134
+ if (table.type.spec.tableRole != "table")
135
+ throw new RangeError("Not a table node: " + table.type.name);
136
+ const width = findWidth(table), height = table.childCount;
137
+ const map = [];
138
+ let mapPos = 0;
139
+ let problems = null;
140
+ const colWidths = [];
141
+ for (let i = 0, e = width * height; i < e; i++) map[i] = 0;
142
+ for (let row = 0, pos = 0; row < height; row++) {
143
+ const rowNode = table.child(row);
144
+ pos++;
145
+ for (let i = 0; ; i++) {
146
+ while (mapPos < map.length && map[mapPos] != 0) mapPos++;
147
+ if (i == rowNode.childCount) break;
148
+ const cellNode = rowNode.child(i);
149
+ const { colspan, rowspan, colwidth } = cellNode.attrs;
150
+ for (let h2 = 0; h2 < rowspan; h2++) {
151
+ if (h2 + row >= height) {
152
+ (problems || (problems = [])).push({
153
+ type: "overlong_rowspan",
154
+ pos,
155
+ n: rowspan - h2
156
+ });
157
+ break;
158
+ }
159
+ const start = mapPos + h2 * width;
160
+ for (let w = 0; w < colspan; w++) {
161
+ if (map[start + w] == 0) map[start + w] = pos;
162
+ else
163
+ (problems || (problems = [])).push({
164
+ type: "collision",
165
+ row,
166
+ pos,
167
+ n: colspan - w
168
+ });
169
+ const colW = colwidth && colwidth[w];
170
+ if (colW) {
171
+ const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
172
+ if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
173
+ colWidths[widthIndex] = colW;
174
+ colWidths[widthIndex + 1] = 1;
175
+ } else if (prev == colW) {
176
+ colWidths[widthIndex + 1]++;
177
+ }
178
+ }
179
+ }
180
+ }
181
+ mapPos += colspan;
182
+ pos += cellNode.nodeSize;
183
+ }
184
+ const expectedPos = (row + 1) * width;
185
+ let missing = 0;
186
+ while (mapPos < expectedPos) if (map[mapPos++] == 0) missing++;
187
+ if (missing)
188
+ (problems || (problems = [])).push({ type: "missing", row, n: missing });
189
+ pos++;
190
+ }
191
+ if (width === 0 || height === 0)
192
+ (problems || (problems = [])).push({ type: "zero_sized" });
193
+ const tableMap = new TableMap(width, height, map, problems);
194
+ let badWidths = false;
195
+ for (let i = 0; !badWidths && i < colWidths.length; i += 2)
196
+ if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
197
+ if (badWidths) findBadColWidths(tableMap, colWidths, table);
198
+ return tableMap;
199
+ }
200
+ function findWidth(table) {
201
+ let width = -1;
202
+ let hasRowSpan = false;
203
+ for (let row = 0; row < table.childCount; row++) {
204
+ const rowNode = table.child(row);
205
+ let rowWidth = 0;
206
+ if (hasRowSpan)
207
+ for (let j = 0; j < row; j++) {
208
+ const prevRow = table.child(j);
209
+ for (let i = 0; i < prevRow.childCount; i++) {
210
+ const cell = prevRow.child(i);
211
+ if (j + cell.attrs.rowspan > row) rowWidth += cell.attrs.colspan;
212
+ }
213
+ }
214
+ for (let i = 0; i < rowNode.childCount; i++) {
215
+ const cell = rowNode.child(i);
216
+ rowWidth += cell.attrs.colspan;
217
+ if (cell.attrs.rowspan > 1) hasRowSpan = true;
218
+ }
219
+ if (width == -1) width = rowWidth;
220
+ else if (width != rowWidth) width = Math.max(width, rowWidth);
221
+ }
222
+ return width;
223
+ }
224
+ function findBadColWidths(map, colWidths, table) {
225
+ if (!map.problems) map.problems = [];
226
+ const seen = {};
227
+ for (let i = 0; i < map.map.length; i++) {
228
+ const pos = map.map[i];
229
+ if (seen[pos]) continue;
230
+ seen[pos] = true;
231
+ const node = table.nodeAt(pos);
232
+ if (!node) {
233
+ throw new RangeError(`No cell with offset ${pos} found`);
234
+ }
235
+ let updated = null;
236
+ const attrs = node.attrs;
237
+ for (let j = 0; j < attrs.colspan; j++) {
238
+ const col = (i + j) % map.width;
239
+ const colWidth = colWidths[col * 2];
240
+ if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth))
241
+ (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
242
+ }
243
+ if (updated)
244
+ map.problems.unshift({
245
+ type: "colwidth mismatch",
246
+ pos,
247
+ colwidth: updated
248
+ });
249
+ }
250
+ }
251
+ function freshColWidth(attrs) {
252
+ if (attrs.colwidth) return attrs.colwidth.slice();
253
+ const result = [];
254
+ for (let i = 0; i < attrs.colspan; i++) result.push(0);
255
+ return result;
256
+ }
257
+ function tableNodeTypes(schema) {
258
+ let result = schema.cached.tableNodeTypes;
259
+ if (!result) {
260
+ result = schema.cached.tableNodeTypes = {};
261
+ for (const name in schema.nodes) {
262
+ const type = schema.nodes[name], role = type.spec.tableRole;
263
+ if (role) result[role] = type;
264
+ }
265
+ }
266
+ return result;
267
+ }
268
+ new PluginKey("selectingCells");
269
+ function cellAround($pos) {
270
+ for (let d = $pos.depth - 1; d > 0; d--)
271
+ if ($pos.node(d).type.spec.tableRole == "row")
272
+ return $pos.node(0).resolve($pos.before(d + 1));
273
+ return null;
274
+ }
275
+ function isInTable(state) {
276
+ const $head = state.selection.$head;
277
+ for (let d = $head.depth; d > 0; d--)
278
+ if ($head.node(d).type.spec.tableRole == "row") return true;
279
+ return false;
280
+ }
281
+ function selectionCell(state) {
282
+ const sel = state.selection;
283
+ if ("$anchorCell" in sel && sel.$anchorCell) {
284
+ return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
285
+ } else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") {
286
+ return sel.$anchor;
287
+ }
288
+ const $cell = cellAround(sel.$head) || cellNear(sel.$head);
289
+ if ($cell) {
290
+ return $cell;
291
+ }
292
+ throw new RangeError(`No cell found around position ${sel.head}`);
293
+ }
294
+ function cellNear($pos) {
295
+ for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
296
+ const role = after.type.spec.tableRole;
297
+ if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos);
298
+ }
299
+ for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
300
+ const role = before.type.spec.tableRole;
301
+ if (role == "cell" || role == "header_cell")
302
+ return $pos.doc.resolve(pos - before.nodeSize);
303
+ }
304
+ }
305
+ function pointsAtCell($pos) {
306
+ return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
307
+ }
308
+ function inSameTable($cellA, $cellB) {
309
+ return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
310
+ }
311
+ function nextCell($pos, axis, dir) {
312
+ const table = $pos.node(-1);
313
+ const map = TableMap.get(table);
314
+ const tableStart = $pos.start(-1);
315
+ const moved = map.nextCell($pos.pos - tableStart, axis, dir);
316
+ return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
317
+ }
318
+ function removeColSpan(attrs, pos, n = 1) {
319
+ const result = { ...attrs, colspan: attrs.colspan - n };
320
+ if (result.colwidth) {
321
+ result.colwidth = result.colwidth.slice();
322
+ result.colwidth.splice(pos, n);
323
+ if (!result.colwidth.some((w) => w > 0)) result.colwidth = null;
324
+ }
325
+ return result;
326
+ }
327
+ var CellSelection = class _CellSelection extends Selection {
328
+ // A table selection is identified by its anchor and head cells. The
329
+ // positions given to this constructor should point _before_ two
330
+ // cells in the same table. They may be the same, to select a single
331
+ // cell.
332
+ constructor($anchorCell, $headCell = $anchorCell) {
333
+ const table = $anchorCell.node(-1);
334
+ const map = TableMap.get(table);
335
+ const tableStart = $anchorCell.start(-1);
336
+ const rect = map.rectBetween(
337
+ $anchorCell.pos - tableStart,
338
+ $headCell.pos - tableStart
339
+ );
340
+ const doc = $anchorCell.node(0);
341
+ const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
342
+ cells.unshift($headCell.pos - tableStart);
343
+ const ranges = cells.map((pos) => {
344
+ const cell = table.nodeAt(pos);
345
+ if (!cell) {
346
+ throw RangeError(`No cell with offset ${pos} found`);
347
+ }
348
+ const from = tableStart + pos + 1;
349
+ return new SelectionRange(
350
+ doc.resolve(from),
351
+ doc.resolve(from + cell.content.size)
352
+ );
353
+ });
354
+ super(ranges[0].$from, ranges[0].$to, ranges);
355
+ this.$anchorCell = $anchorCell;
356
+ this.$headCell = $headCell;
357
+ }
358
+ map(doc, mapping) {
359
+ const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
360
+ const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
361
+ if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
362
+ const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
363
+ if (tableChanged && this.isRowSelection())
364
+ return _CellSelection.rowSelection($anchorCell, $headCell);
365
+ else if (tableChanged && this.isColSelection())
366
+ return _CellSelection.colSelection($anchorCell, $headCell);
367
+ else return new _CellSelection($anchorCell, $headCell);
368
+ }
369
+ return TextSelection.between($anchorCell, $headCell);
370
+ }
371
+ // Returns a rectangular slice of table rows containing the selected
372
+ // cells.
373
+ content() {
374
+ const table = this.$anchorCell.node(-1);
375
+ const map = TableMap.get(table);
376
+ const tableStart = this.$anchorCell.start(-1);
377
+ const rect = map.rectBetween(
378
+ this.$anchorCell.pos - tableStart,
379
+ this.$headCell.pos - tableStart
380
+ );
381
+ const seen = {};
382
+ const rows = [];
383
+ for (let row = rect.top; row < rect.bottom; row++) {
384
+ const rowContent = [];
385
+ for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
386
+ const pos = map.map[index];
387
+ if (seen[pos]) continue;
388
+ seen[pos] = true;
389
+ const cellRect = map.findCell(pos);
390
+ let cell = table.nodeAt(pos);
391
+ if (!cell) {
392
+ throw RangeError(`No cell with offset ${pos} found`);
393
+ }
394
+ const extraLeft = rect.left - cellRect.left;
395
+ const extraRight = cellRect.right - rect.right;
396
+ if (extraLeft > 0 || extraRight > 0) {
397
+ let attrs = cell.attrs;
398
+ if (extraLeft > 0) {
399
+ attrs = removeColSpan(attrs, 0, extraLeft);
400
+ }
401
+ if (extraRight > 0) {
402
+ attrs = removeColSpan(
403
+ attrs,
404
+ attrs.colspan - extraRight,
405
+ extraRight
406
+ );
407
+ }
408
+ if (cellRect.left < rect.left) {
409
+ cell = cell.type.createAndFill(attrs);
410
+ if (!cell) {
411
+ throw RangeError(
412
+ `Could not create cell with attrs ${JSON.stringify(attrs)}`
413
+ );
414
+ }
415
+ } else {
416
+ cell = cell.type.create(attrs, cell.content);
417
+ }
418
+ }
419
+ if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
420
+ const attrs = {
421
+ ...cell.attrs,
422
+ rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
423
+ };
424
+ if (cellRect.top < rect.top) {
425
+ cell = cell.type.createAndFill(attrs);
426
+ } else {
427
+ cell = cell.type.create(attrs, cell.content);
428
+ }
429
+ }
430
+ rowContent.push(cell);
431
+ }
432
+ rows.push(table.child(row).copy(Fragment.from(rowContent)));
433
+ }
434
+ const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
435
+ return new Slice(Fragment.from(fragment), 1, 1);
436
+ }
437
+ replace(tr, content = Slice.empty) {
438
+ const mapFrom = tr.steps.length, ranges = this.ranges;
439
+ for (let i = 0; i < ranges.length; i++) {
440
+ const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
441
+ tr.replace(
442
+ mapping.map($from.pos),
443
+ mapping.map($to.pos),
444
+ i ? Slice.empty : content
445
+ );
446
+ }
447
+ const sel = Selection.findFrom(
448
+ tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)),
449
+ -1
450
+ );
451
+ if (sel) tr.setSelection(sel);
452
+ }
453
+ replaceWith(tr, node) {
454
+ this.replace(tr, new Slice(Fragment.from(node), 0, 0));
455
+ }
456
+ forEachCell(f) {
457
+ const table = this.$anchorCell.node(-1);
458
+ const map = TableMap.get(table);
459
+ const tableStart = this.$anchorCell.start(-1);
460
+ const cells = map.cellsInRect(
461
+ map.rectBetween(
462
+ this.$anchorCell.pos - tableStart,
463
+ this.$headCell.pos - tableStart
464
+ )
465
+ );
466
+ for (let i = 0; i < cells.length; i++) {
467
+ f(table.nodeAt(cells[i]), tableStart + cells[i]);
468
+ }
469
+ }
470
+ // True if this selection goes all the way from the top to the
471
+ // bottom of the table.
472
+ isColSelection() {
473
+ const anchorTop = this.$anchorCell.index(-1);
474
+ const headTop = this.$headCell.index(-1);
475
+ if (Math.min(anchorTop, headTop) > 0) return false;
476
+ const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
477
+ const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
478
+ return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
479
+ }
480
+ // Returns the smallest column selection that covers the given anchor
481
+ // and head cell.
482
+ static colSelection($anchorCell, $headCell = $anchorCell) {
483
+ const table = $anchorCell.node(-1);
484
+ const map = TableMap.get(table);
485
+ const tableStart = $anchorCell.start(-1);
486
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
487
+ const headRect = map.findCell($headCell.pos - tableStart);
488
+ const doc = $anchorCell.node(0);
489
+ if (anchorRect.top <= headRect.top) {
490
+ if (anchorRect.top > 0)
491
+ $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
492
+ if (headRect.bottom < map.height)
493
+ $headCell = doc.resolve(
494
+ tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]
495
+ );
496
+ } else {
497
+ if (headRect.top > 0)
498
+ $headCell = doc.resolve(tableStart + map.map[headRect.left]);
499
+ if (anchorRect.bottom < map.height)
500
+ $anchorCell = doc.resolve(
501
+ tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]
502
+ );
503
+ }
504
+ return new _CellSelection($anchorCell, $headCell);
505
+ }
506
+ // True if this selection goes all the way from the left to the
507
+ // right of the table.
508
+ isRowSelection() {
509
+ const table = this.$anchorCell.node(-1);
510
+ const map = TableMap.get(table);
511
+ const tableStart = this.$anchorCell.start(-1);
512
+ const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
513
+ const headLeft = map.colCount(this.$headCell.pos - tableStart);
514
+ if (Math.min(anchorLeft, headLeft) > 0) return false;
515
+ const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
516
+ const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
517
+ return Math.max(anchorRight, headRight) == map.width;
518
+ }
519
+ eq(other) {
520
+ return other instanceof _CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
521
+ }
522
+ // Returns the smallest row selection that covers the given anchor
523
+ // and head cell.
524
+ static rowSelection($anchorCell, $headCell = $anchorCell) {
525
+ const table = $anchorCell.node(-1);
526
+ const map = TableMap.get(table);
527
+ const tableStart = $anchorCell.start(-1);
528
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
529
+ const headRect = map.findCell($headCell.pos - tableStart);
530
+ const doc = $anchorCell.node(0);
531
+ if (anchorRect.left <= headRect.left) {
532
+ if (anchorRect.left > 0)
533
+ $anchorCell = doc.resolve(
534
+ tableStart + map.map[anchorRect.top * map.width]
535
+ );
536
+ if (headRect.right < map.width)
537
+ $headCell = doc.resolve(
538
+ tableStart + map.map[map.width * (headRect.top + 1) - 1]
539
+ );
540
+ } else {
541
+ if (headRect.left > 0)
542
+ $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
543
+ if (anchorRect.right < map.width)
544
+ $anchorCell = doc.resolve(
545
+ tableStart + map.map[map.width * (anchorRect.top + 1) - 1]
546
+ );
547
+ }
548
+ return new _CellSelection($anchorCell, $headCell);
549
+ }
550
+ toJSON() {
551
+ return {
552
+ type: "cell",
553
+ anchor: this.$anchorCell.pos,
554
+ head: this.$headCell.pos
555
+ };
556
+ }
557
+ static fromJSON(doc, json) {
558
+ return new _CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
559
+ }
560
+ static create(doc, anchorCell, headCell = anchorCell) {
561
+ return new _CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
562
+ }
563
+ getBookmark() {
564
+ return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
565
+ }
566
+ };
567
+ CellSelection.prototype.visible = false;
568
+ Selection.jsonID("cell", CellSelection);
569
+ var CellBookmark = class _CellBookmark {
570
+ constructor(anchor, head) {
571
+ this.anchor = anchor;
572
+ this.head = head;
573
+ }
574
+ map(mapping) {
575
+ return new _CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
576
+ }
577
+ resolve(doc) {
578
+ const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
579
+ if ($anchorCell.parent.type.spec.tableRole == "row" && $headCell.parent.type.spec.tableRole == "row" && $anchorCell.index() < $anchorCell.parent.childCount && $headCell.index() < $headCell.parent.childCount && inSameTable($anchorCell, $headCell))
580
+ return new CellSelection($anchorCell, $headCell);
581
+ else return Selection.near($headCell, 1);
582
+ }
583
+ };
584
+ new PluginKey("fix-tables");
585
+ function selectedRect(state) {
586
+ const sel = state.selection;
587
+ const $pos = selectionCell(state);
588
+ const table = $pos.node(-1);
589
+ const tableStart = $pos.start(-1);
590
+ const map = TableMap.get(table);
591
+ const rect = sel instanceof CellSelection ? map.rectBetween(
592
+ sel.$anchorCell.pos - tableStart,
593
+ sel.$headCell.pos - tableStart
594
+ ) : map.findCell($pos.pos - tableStart);
595
+ return { ...rect, tableStart, map, table };
596
+ }
597
+ function deprecated_toggleHeader(type) {
598
+ return function(state, dispatch) {
599
+ if (!isInTable(state)) return false;
600
+ if (dispatch) {
601
+ const types = tableNodeTypes(state.schema);
602
+ const rect = selectedRect(state), tr = state.tr;
603
+ const cells = rect.map.cellsInRect(
604
+ type == "column" ? {
605
+ left: rect.left,
606
+ top: 0,
607
+ right: rect.right,
608
+ bottom: rect.map.height
609
+ } : type == "row" ? {
610
+ left: 0,
611
+ top: rect.top,
612
+ right: rect.map.width,
613
+ bottom: rect.bottom
614
+ } : rect
615
+ );
616
+ const nodes = cells.map((pos) => rect.table.nodeAt(pos));
617
+ for (let i = 0; i < cells.length; i++)
618
+ if (nodes[i].type == types.header_cell)
619
+ tr.setNodeMarkup(
620
+ rect.tableStart + cells[i],
621
+ types.cell,
622
+ nodes[i].attrs
623
+ );
624
+ if (tr.steps.length == 0)
625
+ for (let i = 0; i < cells.length; i++)
626
+ tr.setNodeMarkup(
627
+ rect.tableStart + cells[i],
628
+ types.header_cell,
629
+ nodes[i].attrs
630
+ );
631
+ dispatch(tr);
632
+ }
633
+ return true;
634
+ };
635
+ }
636
+ function isHeaderEnabledByType(type, rect, types) {
637
+ const cellPositions = rect.map.cellsInRect({
638
+ left: 0,
639
+ top: 0,
640
+ right: type == "row" ? rect.map.width : 1,
641
+ bottom: type == "column" ? rect.map.height : 1
642
+ });
643
+ for (let i = 0; i < cellPositions.length; i++) {
644
+ const cell = rect.table.nodeAt(cellPositions[i]);
645
+ if (cell && cell.type !== types.header_cell) {
646
+ return false;
647
+ }
648
+ }
649
+ return true;
650
+ }
651
+ function toggleHeader(type, options) {
652
+ options = options || { useDeprecatedLogic: false };
653
+ if (options.useDeprecatedLogic) return deprecated_toggleHeader(type);
654
+ return function(state, dispatch) {
655
+ if (!isInTable(state)) return false;
656
+ if (dispatch) {
657
+ const types = tableNodeTypes(state.schema);
658
+ const rect = selectedRect(state), tr = state.tr;
659
+ const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
660
+ const isHeaderColumnEnabled = isHeaderEnabledByType(
661
+ "column",
662
+ rect,
663
+ types
664
+ );
665
+ const isHeaderEnabled = type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false;
666
+ const selectionStartsAt = isHeaderEnabled ? 1 : 0;
667
+ const cellsRect = type == "column" ? {
668
+ left: 0,
669
+ top: selectionStartsAt,
670
+ right: 1,
671
+ bottom: rect.map.height
672
+ } : type == "row" ? {
673
+ left: selectionStartsAt,
674
+ top: 0,
675
+ right: rect.map.width,
676
+ bottom: 1
677
+ } : rect;
678
+ const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell;
679
+ rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => {
680
+ const cellPos = relativeCellPos + rect.tableStart;
681
+ const cell = tr.doc.nodeAt(cellPos);
682
+ if (cell) {
683
+ tr.setNodeMarkup(cellPos, newType, cell.attrs);
684
+ }
685
+ });
686
+ dispatch(tr);
687
+ }
688
+ return true;
689
+ };
690
+ }
691
+ toggleHeader("row", {
692
+ useDeprecatedLogic: true
693
+ });
694
+ toggleHeader("column", {
695
+ useDeprecatedLogic: true
696
+ });
697
+ toggleHeader("cell", {
698
+ useDeprecatedLogic: true
699
+ });
700
+ function deleteCellSelection(state, dispatch) {
701
+ const sel = state.selection;
702
+ if (!(sel instanceof CellSelection)) return false;
703
+ if (dispatch) {
704
+ const tr = state.tr;
705
+ const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
706
+ sel.forEachCell((cell, pos) => {
707
+ if (!cell.content.eq(baseContent))
708
+ tr.replace(
709
+ tr.mapping.map(pos + 1),
710
+ tr.mapping.map(pos + cell.nodeSize - 1),
711
+ new Slice(baseContent, 0, 0)
712
+ );
713
+ });
714
+ if (tr.docChanged) dispatch(tr);
715
+ }
716
+ return true;
717
+ }
718
+ keydownHandler({
719
+ ArrowLeft: arrow("horiz", -1),
720
+ ArrowRight: arrow("horiz", 1),
721
+ ArrowUp: arrow("vert", -1),
722
+ ArrowDown: arrow("vert", 1),
723
+ "Shift-ArrowLeft": shiftArrow("horiz", -1),
724
+ "Shift-ArrowRight": shiftArrow("horiz", 1),
725
+ "Shift-ArrowUp": shiftArrow("vert", -1),
726
+ "Shift-ArrowDown": shiftArrow("vert", 1),
727
+ Backspace: deleteCellSelection,
728
+ "Mod-Backspace": deleteCellSelection,
729
+ Delete: deleteCellSelection,
730
+ "Mod-Delete": deleteCellSelection
731
+ });
732
+ function maybeSetSelection(state, dispatch, selection) {
733
+ if (selection.eq(state.selection)) return false;
734
+ if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView());
735
+ return true;
736
+ }
737
+ function arrow(axis, dir) {
738
+ return (state, dispatch, view) => {
739
+ if (!view) return false;
740
+ const sel = state.selection;
741
+ if (sel instanceof CellSelection) {
742
+ return maybeSetSelection(
743
+ state,
744
+ dispatch,
745
+ Selection.near(sel.$headCell, dir)
746
+ );
747
+ }
748
+ if (axis != "horiz" && !sel.empty) return false;
749
+ const end = atEndOfCell(view, axis, dir);
750
+ if (end == null) return false;
751
+ if (axis == "horiz") {
752
+ return maybeSetSelection(
753
+ state,
754
+ dispatch,
755
+ Selection.near(state.doc.resolve(sel.head + dir), dir)
756
+ );
757
+ } else {
758
+ const $cell = state.doc.resolve(end);
759
+ const $next = nextCell($cell, axis, dir);
760
+ let newSel;
761
+ if ($next) newSel = Selection.near($next, 1);
762
+ else if (dir < 0)
763
+ newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1);
764
+ else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
765
+ return maybeSetSelection(state, dispatch, newSel);
766
+ }
767
+ };
768
+ }
769
+ function shiftArrow(axis, dir) {
770
+ return (state, dispatch, view) => {
771
+ if (!view) return false;
772
+ const sel = state.selection;
773
+ let cellSel;
774
+ if (sel instanceof CellSelection) {
775
+ cellSel = sel;
776
+ } else {
777
+ const end = atEndOfCell(view, axis, dir);
778
+ if (end == null) return false;
779
+ cellSel = new CellSelection(state.doc.resolve(end));
780
+ }
781
+ const $head = nextCell(cellSel.$headCell, axis, dir);
782
+ if (!$head) return false;
783
+ return maybeSetSelection(
784
+ state,
785
+ dispatch,
786
+ new CellSelection(cellSel.$anchorCell, $head)
787
+ );
788
+ };
789
+ }
790
+ function atEndOfCell(view, axis, dir) {
791
+ if (!(view.state.selection instanceof TextSelection)) return null;
792
+ const { $head } = view.state.selection;
793
+ for (let d = $head.depth - 1; d >= 0; d--) {
794
+ const parent = $head.node(d), index = dir < 0 ? $head.index(d) : $head.indexAfter(d);
795
+ if (index != (dir < 0 ? 0 : parent.childCount)) return null;
796
+ if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
797
+ const cellPos = $head.before(d);
798
+ const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
799
+ return view.endOfTextblock(dirStr) ? cellPos : null;
800
+ }
801
+ }
802
+ return null;
803
+ }
804
+ new PluginKey(
805
+ "tableColumnResizing"
806
+ );
807
+ function combineDOMRects(rect1, rect2) {
808
+ const top = Math.min(rect1.top, rect2.top);
809
+ const bottom = Math.max(rect1.bottom, rect2.bottom);
810
+ const left = Math.min(rect1.left, rect2.left);
811
+ const right = Math.max(rect1.right, rect2.right);
812
+ const width = right - left;
813
+ const height = bottom - top;
814
+ const x = left;
815
+ const y = top;
816
+ return new DOMRect(x, y, width, height);
817
+ }
818
+ var BubbleMenuView = class {
819
+ constructor({
820
+ editor,
821
+ element,
822
+ view,
823
+ updateDelay = 250,
824
+ resizeDelay = 60,
825
+ shouldShow,
826
+ options
827
+ }) {
828
+ this.preventHide = false;
829
+ this.isVisible = false;
830
+ this.floatingUIOptions = {
831
+ strategy: "absolute",
832
+ placement: "top",
833
+ offset: 8,
834
+ flip: {},
835
+ shift: {},
836
+ arrow: false,
837
+ size: false,
838
+ autoPlacement: false,
839
+ hide: false,
840
+ inline: false,
841
+ onShow: void 0,
842
+ onHide: void 0,
843
+ onUpdate: void 0,
844
+ onDestroy: void 0
845
+ };
846
+ this.shouldShow = ({ view: view2, state, from, to }) => {
847
+ const { doc, selection } = state;
848
+ const { empty } = selection;
849
+ const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection);
850
+ const isChildOfMenu = this.element.contains(document.activeElement);
851
+ const hasEditorFocus = view2.hasFocus() || isChildOfMenu;
852
+ if (!hasEditorFocus || empty || isEmptyTextBlock || !this.editor.isEditable) {
853
+ return false;
854
+ }
855
+ return true;
856
+ };
857
+ this.mousedownHandler = () => {
858
+ this.preventHide = true;
859
+ };
860
+ this.dragstartHandler = () => {
861
+ this.hide();
862
+ };
863
+ this.resizeHandler = () => {
864
+ if (this.resizeDebounceTimer) {
865
+ clearTimeout(this.resizeDebounceTimer);
866
+ }
867
+ this.resizeDebounceTimer = window.setTimeout(() => {
868
+ this.updatePosition();
869
+ }, this.resizeDelay);
870
+ };
871
+ this.focusHandler = () => {
872
+ setTimeout(() => this.update(this.editor.view));
873
+ };
874
+ this.blurHandler = ({ event }) => {
875
+ var _a;
876
+ if (this.preventHide) {
877
+ this.preventHide = false;
878
+ return;
879
+ }
880
+ if ((event == null ? void 0 : event.relatedTarget) && ((_a = this.element.parentNode) == null ? void 0 : _a.contains(event.relatedTarget))) {
881
+ return;
882
+ }
883
+ if ((event == null ? void 0 : event.relatedTarget) === this.editor.view.dom) {
884
+ return;
885
+ }
886
+ this.hide();
887
+ };
888
+ this.handleDebouncedUpdate = (view2, oldState) => {
889
+ const selectionChanged = !(oldState == null ? void 0 : oldState.selection.eq(view2.state.selection));
890
+ const docChanged = !(oldState == null ? void 0 : oldState.doc.eq(view2.state.doc));
891
+ if (!selectionChanged && !docChanged) {
892
+ return;
893
+ }
894
+ if (this.updateDebounceTimer) {
895
+ clearTimeout(this.updateDebounceTimer);
896
+ }
897
+ this.updateDebounceTimer = window.setTimeout(() => {
898
+ this.updateHandler(view2, selectionChanged, docChanged, oldState);
899
+ }, this.updateDelay);
900
+ };
901
+ this.updateHandler = (view2, selectionChanged, docChanged, oldState) => {
902
+ const { composing } = view2;
903
+ const isSame = !selectionChanged && !docChanged;
904
+ if (composing || isSame) {
905
+ return;
906
+ }
907
+ const shouldShow2 = this.getShouldShow(oldState);
908
+ if (!shouldShow2) {
909
+ this.hide();
910
+ return;
911
+ }
912
+ this.updatePosition();
913
+ this.show();
914
+ };
915
+ this.editor = editor;
916
+ this.element = element;
917
+ this.view = view;
918
+ this.updateDelay = updateDelay;
919
+ this.resizeDelay = resizeDelay;
920
+ this.floatingUIOptions = {
921
+ ...this.floatingUIOptions,
922
+ ...options
923
+ };
924
+ this.element.tabIndex = 0;
925
+ if (shouldShow) {
926
+ this.shouldShow = shouldShow;
927
+ }
928
+ this.element.addEventListener("mousedown", this.mousedownHandler, { capture: true });
929
+ this.view.dom.addEventListener("dragstart", this.dragstartHandler);
930
+ this.editor.on("focus", this.focusHandler);
931
+ this.editor.on("blur", this.blurHandler);
932
+ window.addEventListener("resize", this.resizeHandler);
933
+ this.update(view, view.state);
934
+ if (this.getShouldShow()) {
935
+ this.show();
936
+ }
937
+ }
938
+ get middlewares() {
939
+ const middlewares = [];
940
+ if (this.floatingUIOptions.flip) {
941
+ middlewares.push(flip(typeof this.floatingUIOptions.flip !== "boolean" ? this.floatingUIOptions.flip : void 0));
942
+ }
943
+ if (this.floatingUIOptions.shift) {
944
+ middlewares.push(
945
+ shift(typeof this.floatingUIOptions.shift !== "boolean" ? this.floatingUIOptions.shift : void 0)
946
+ );
947
+ }
948
+ if (this.floatingUIOptions.offset) {
949
+ middlewares.push(
950
+ offset(typeof this.floatingUIOptions.offset !== "boolean" ? this.floatingUIOptions.offset : void 0)
951
+ );
952
+ }
953
+ if (this.floatingUIOptions.arrow) {
954
+ middlewares.push(arrow$1(this.floatingUIOptions.arrow));
955
+ }
956
+ if (this.floatingUIOptions.size) {
957
+ middlewares.push(size(typeof this.floatingUIOptions.size !== "boolean" ? this.floatingUIOptions.size : void 0));
958
+ }
959
+ if (this.floatingUIOptions.autoPlacement) {
960
+ middlewares.push(
961
+ autoPlacement(
962
+ typeof this.floatingUIOptions.autoPlacement !== "boolean" ? this.floatingUIOptions.autoPlacement : void 0
963
+ )
964
+ );
965
+ }
966
+ if (this.floatingUIOptions.hide) {
967
+ middlewares.push(hide(typeof this.floatingUIOptions.hide !== "boolean" ? this.floatingUIOptions.hide : void 0));
968
+ }
969
+ if (this.floatingUIOptions.inline) {
970
+ middlewares.push(
971
+ inline(typeof this.floatingUIOptions.inline !== "boolean" ? this.floatingUIOptions.inline : void 0)
972
+ );
973
+ }
974
+ return middlewares;
975
+ }
976
+ updatePosition() {
977
+ const { selection } = this.editor.state;
978
+ const domRect = posToDOMRect(this.view, selection.from, selection.to);
979
+ let virtualElement = {
980
+ getBoundingClientRect: () => domRect,
981
+ getClientRects: () => [domRect]
982
+ };
983
+ if (selection instanceof CellSelection) {
984
+ const { $anchorCell, $headCell } = selection;
985
+ const from = $anchorCell ? $anchorCell.pos : $headCell.pos;
986
+ const to = $headCell ? $headCell.pos : $anchorCell.pos;
987
+ const fromDOM = this.view.nodeDOM(from);
988
+ const toDOM = this.view.nodeDOM(to);
989
+ if (!fromDOM || !toDOM) {
990
+ return;
991
+ }
992
+ const clientRect = fromDOM === toDOM ? fromDOM.getBoundingClientRect() : combineDOMRects(
993
+ fromDOM.getBoundingClientRect(),
994
+ toDOM.getBoundingClientRect()
995
+ );
996
+ virtualElement = {
997
+ getBoundingClientRect: () => clientRect,
998
+ getClientRects: () => [clientRect]
999
+ };
1000
+ }
1001
+ computePosition(virtualElement, this.element, {
1002
+ placement: this.floatingUIOptions.placement,
1003
+ strategy: this.floatingUIOptions.strategy,
1004
+ middleware: this.middlewares
1005
+ }).then(({ x, y, strategy }) => {
1006
+ this.element.style.width = "max-content";
1007
+ this.element.style.position = strategy;
1008
+ this.element.style.left = `${x}px`;
1009
+ this.element.style.top = `${y}px`;
1010
+ if (this.isVisible && this.floatingUIOptions.onUpdate) {
1011
+ this.floatingUIOptions.onUpdate();
1012
+ }
1013
+ });
1014
+ }
1015
+ update(view, oldState) {
1016
+ const { state } = view;
1017
+ const hasValidSelection = state.selection.from !== state.selection.to;
1018
+ if (this.updateDelay > 0 && hasValidSelection) {
1019
+ this.handleDebouncedUpdate(view, oldState);
1020
+ return;
1021
+ }
1022
+ const selectionChanged = !(oldState == null ? void 0 : oldState.selection.eq(view.state.selection));
1023
+ const docChanged = !(oldState == null ? void 0 : oldState.doc.eq(view.state.doc));
1024
+ this.updateHandler(view, selectionChanged, docChanged, oldState);
1025
+ }
1026
+ getShouldShow(oldState) {
1027
+ var _a;
1028
+ const { state } = this.view;
1029
+ const { selection } = state;
1030
+ const { ranges } = selection;
1031
+ const from = Math.min(...ranges.map((range) => range.$from.pos));
1032
+ const to = Math.max(...ranges.map((range) => range.$to.pos));
1033
+ const shouldShow = (_a = this.shouldShow) == null ? void 0 : _a.call(this, {
1034
+ editor: this.editor,
1035
+ element: this.element,
1036
+ view: this.view,
1037
+ state,
1038
+ oldState,
1039
+ from,
1040
+ to
1041
+ });
1042
+ return shouldShow;
1043
+ }
1044
+ show() {
1045
+ var _a;
1046
+ if (this.isVisible) {
1047
+ return;
1048
+ }
1049
+ this.element.style.visibility = "visible";
1050
+ this.element.style.opacity = "1";
1051
+ (_a = this.view.dom.parentElement) == null ? void 0 : _a.appendChild(this.element);
1052
+ if (this.floatingUIOptions.onShow) {
1053
+ this.floatingUIOptions.onShow();
1054
+ }
1055
+ this.isVisible = true;
1056
+ }
1057
+ hide() {
1058
+ if (!this.isVisible) {
1059
+ return;
1060
+ }
1061
+ this.element.style.visibility = "hidden";
1062
+ this.element.style.opacity = "0";
1063
+ this.element.remove();
1064
+ if (this.floatingUIOptions.onHide) {
1065
+ this.floatingUIOptions.onHide();
1066
+ }
1067
+ this.isVisible = false;
1068
+ }
1069
+ destroy() {
1070
+ this.hide();
1071
+ this.element.removeEventListener("mousedown", this.mousedownHandler, { capture: true });
1072
+ this.view.dom.removeEventListener("dragstart", this.dragstartHandler);
1073
+ window.removeEventListener("resize", this.resizeHandler);
1074
+ this.editor.off("focus", this.focusHandler);
1075
+ this.editor.off("blur", this.blurHandler);
1076
+ if (this.floatingUIOptions.onDestroy) {
1077
+ this.floatingUIOptions.onDestroy();
1078
+ }
1079
+ }
1080
+ };
1081
+ var BubbleMenuPlugin = (options) => {
1082
+ return new Plugin({
1083
+ key: typeof options.pluginKey === "string" ? new PluginKey(options.pluginKey) : options.pluginKey,
1084
+ view: (view) => new BubbleMenuView({ view, ...options })
1085
+ });
1086
+ };
1087
+ Extension.create({
1088
+ name: "bubbleMenu",
1089
+ addOptions() {
1090
+ return {
1091
+ element: null,
1092
+ pluginKey: "bubbleMenu",
1093
+ updateDelay: void 0,
1094
+ shouldShow: null
1095
+ };
1096
+ },
1097
+ addProseMirrorPlugins() {
1098
+ if (!this.options.element) {
1099
+ return [];
1100
+ }
1101
+ return [
1102
+ BubbleMenuPlugin({
1103
+ pluginKey: this.options.pluginKey,
1104
+ editor: this.editor,
1105
+ element: this.options.element,
1106
+ updateDelay: this.options.updateDelay,
1107
+ options: this.options.options,
1108
+ shouldShow: this.options.shouldShow
1109
+ })
1110
+ ];
1111
+ }
1112
+ });
1113
+ var BubbleMenu2 = defineComponent({
1114
+ name: "BubbleMenu",
1115
+ props: {
1116
+ pluginKey: {
1117
+ type: [String, Object],
1118
+ default: "bubbleMenu"
1119
+ },
1120
+ editor: {
1121
+ type: Object,
1122
+ required: true
1123
+ },
1124
+ updateDelay: {
1125
+ type: Number,
1126
+ default: void 0
1127
+ },
1128
+ resizeDelay: {
1129
+ type: Number,
1130
+ default: void 0
1131
+ },
1132
+ options: {
1133
+ type: Object,
1134
+ default: () => ({})
1135
+ },
1136
+ shouldShow: {
1137
+ type: Function,
1138
+ default: null
1139
+ }
1140
+ },
1141
+ setup(props, { slots }) {
1142
+ const root = ref(null);
1143
+ onMounted(() => {
1144
+ const { editor, options, pluginKey, resizeDelay, shouldShow, updateDelay } = props;
1145
+ if (!root.value) {
1146
+ return;
1147
+ }
1148
+ root.value.style.visibility = "hidden";
1149
+ root.value.style.position = "absolute";
1150
+ root.value.remove();
1151
+ editor.registerPlugin(
1152
+ BubbleMenuPlugin({
1153
+ editor,
1154
+ element: root.value,
1155
+ options,
1156
+ pluginKey,
1157
+ resizeDelay,
1158
+ shouldShow,
1159
+ updateDelay
1160
+ })
1161
+ );
1162
+ });
1163
+ onBeforeUnmount(() => {
1164
+ const { pluginKey, editor } = props;
1165
+ editor.unregisterPlugin(pluginKey);
1166
+ });
1167
+ return () => {
1168
+ var _a;
1169
+ return h(Teleport, { to: "body" }, h("div", { ref: root }, (_a = slots.default) == null ? void 0 : _a.call(slots)));
1170
+ };
1171
+ }
1172
+ });
1173
+ var FloatingMenuView = class {
1174
+ constructor({ editor, element, view, options, shouldShow }) {
1175
+ this.preventHide = false;
1176
+ this.isVisible = false;
1177
+ this.shouldShow = ({ view: view2, state }) => {
1178
+ const { selection } = state;
1179
+ const { $anchor, empty } = selection;
1180
+ const isRootDepth = $anchor.depth === 1;
1181
+ const isEmptyTextBlock = $anchor.parent.isTextblock && !$anchor.parent.type.spec.code && !$anchor.parent.textContent && $anchor.parent.childCount === 0 && !this.getTextContent($anchor.parent);
1182
+ if (!view2.hasFocus() || !empty || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) {
1183
+ return false;
1184
+ }
1185
+ return true;
1186
+ };
1187
+ this.floatingUIOptions = {
1188
+ strategy: "absolute",
1189
+ placement: "right",
1190
+ offset: 8,
1191
+ flip: {},
1192
+ shift: {},
1193
+ arrow: false,
1194
+ size: false,
1195
+ autoPlacement: false,
1196
+ hide: false,
1197
+ inline: false
1198
+ };
1199
+ this.updateHandler = (view2, selectionChanged, docChanged, oldState) => {
1200
+ const { composing } = view2;
1201
+ const isSame = !selectionChanged && !docChanged;
1202
+ if (composing || isSame) {
1203
+ return;
1204
+ }
1205
+ const shouldShow2 = this.getShouldShow(oldState);
1206
+ if (!shouldShow2) {
1207
+ this.hide();
1208
+ return;
1209
+ }
1210
+ this.updatePosition();
1211
+ this.show();
1212
+ };
1213
+ this.mousedownHandler = () => {
1214
+ this.preventHide = true;
1215
+ };
1216
+ this.focusHandler = () => {
1217
+ setTimeout(() => this.update(this.editor.view));
1218
+ };
1219
+ this.blurHandler = ({ event }) => {
1220
+ var _a;
1221
+ if (this.preventHide) {
1222
+ this.preventHide = false;
1223
+ return;
1224
+ }
1225
+ if ((event == null ? void 0 : event.relatedTarget) && ((_a = this.element.parentNode) == null ? void 0 : _a.contains(event.relatedTarget))) {
1226
+ return;
1227
+ }
1228
+ if ((event == null ? void 0 : event.relatedTarget) === this.editor.view.dom) {
1229
+ return;
1230
+ }
1231
+ this.hide();
1232
+ };
1233
+ this.editor = editor;
1234
+ this.element = element;
1235
+ this.view = view;
1236
+ this.floatingUIOptions = {
1237
+ ...this.floatingUIOptions,
1238
+ ...options
1239
+ };
1240
+ this.element.tabIndex = 0;
1241
+ if (shouldShow) {
1242
+ this.shouldShow = shouldShow;
1243
+ }
1244
+ this.element.addEventListener("mousedown", this.mousedownHandler, { capture: true });
1245
+ this.editor.on("focus", this.focusHandler);
1246
+ this.editor.on("blur", this.blurHandler);
1247
+ this.update(view, view.state);
1248
+ if (this.getShouldShow()) {
1249
+ this.show();
1250
+ }
1251
+ }
1252
+ getTextContent(node) {
1253
+ return getText(node, { textSerializers: getTextSerializersFromSchema(this.editor.schema) });
1254
+ }
1255
+ get middlewares() {
1256
+ const middlewares = [];
1257
+ if (this.floatingUIOptions.flip) {
1258
+ middlewares.push(flip(typeof this.floatingUIOptions.flip !== "boolean" ? this.floatingUIOptions.flip : void 0));
1259
+ }
1260
+ if (this.floatingUIOptions.shift) {
1261
+ middlewares.push(
1262
+ shift(typeof this.floatingUIOptions.shift !== "boolean" ? this.floatingUIOptions.shift : void 0)
1263
+ );
1264
+ }
1265
+ if (this.floatingUIOptions.offset) {
1266
+ middlewares.push(
1267
+ offset(typeof this.floatingUIOptions.offset !== "boolean" ? this.floatingUIOptions.offset : void 0)
1268
+ );
1269
+ }
1270
+ if (this.floatingUIOptions.arrow) {
1271
+ middlewares.push(arrow$1(this.floatingUIOptions.arrow));
1272
+ }
1273
+ if (this.floatingUIOptions.size) {
1274
+ middlewares.push(size(typeof this.floatingUIOptions.size !== "boolean" ? this.floatingUIOptions.size : void 0));
1275
+ }
1276
+ if (this.floatingUIOptions.autoPlacement) {
1277
+ middlewares.push(
1278
+ autoPlacement(
1279
+ typeof this.floatingUIOptions.autoPlacement !== "boolean" ? this.floatingUIOptions.autoPlacement : void 0
1280
+ )
1281
+ );
1282
+ }
1283
+ if (this.floatingUIOptions.hide) {
1284
+ middlewares.push(hide(typeof this.floatingUIOptions.hide !== "boolean" ? this.floatingUIOptions.hide : void 0));
1285
+ }
1286
+ if (this.floatingUIOptions.inline) {
1287
+ middlewares.push(
1288
+ inline(typeof this.floatingUIOptions.inline !== "boolean" ? this.floatingUIOptions.inline : void 0)
1289
+ );
1290
+ }
1291
+ return middlewares;
1292
+ }
1293
+ getShouldShow(oldState) {
1294
+ var _a;
1295
+ const { state } = this.view;
1296
+ const { selection } = state;
1297
+ const { ranges } = selection;
1298
+ const from = Math.min(...ranges.map((range) => range.$from.pos));
1299
+ const to = Math.max(...ranges.map((range) => range.$to.pos));
1300
+ const shouldShow = (_a = this.shouldShow) == null ? void 0 : _a.call(this, {
1301
+ editor: this.editor,
1302
+ view: this.view,
1303
+ state,
1304
+ oldState,
1305
+ from,
1306
+ to
1307
+ });
1308
+ return shouldShow;
1309
+ }
1310
+ updatePosition() {
1311
+ const { selection } = this.editor.state;
1312
+ const domRect = posToDOMRect(this.view, selection.from, selection.to);
1313
+ const virtualElement = {
1314
+ getBoundingClientRect: () => domRect,
1315
+ getClientRects: () => [domRect]
1316
+ };
1317
+ computePosition(virtualElement, this.element, {
1318
+ placement: this.floatingUIOptions.placement,
1319
+ strategy: this.floatingUIOptions.strategy,
1320
+ middleware: this.middlewares
1321
+ }).then(({ x, y, strategy }) => {
1322
+ this.element.style.width = "max-content";
1323
+ this.element.style.position = strategy;
1324
+ this.element.style.left = `${x}px`;
1325
+ this.element.style.top = `${y}px`;
1326
+ if (this.isVisible && this.floatingUIOptions.onUpdate) {
1327
+ this.floatingUIOptions.onUpdate();
1328
+ }
1329
+ });
1330
+ }
1331
+ update(view, oldState) {
1332
+ const selectionChanged = !(oldState == null ? void 0 : oldState.selection.eq(view.state.selection));
1333
+ const docChanged = !(oldState == null ? void 0 : oldState.doc.eq(view.state.doc));
1334
+ this.updateHandler(view, selectionChanged, docChanged, oldState);
1335
+ }
1336
+ show() {
1337
+ var _a;
1338
+ if (this.isVisible) {
1339
+ return;
1340
+ }
1341
+ this.element.style.visibility = "visible";
1342
+ this.element.style.opacity = "1";
1343
+ (_a = this.view.dom.parentElement) == null ? void 0 : _a.appendChild(this.element);
1344
+ if (this.floatingUIOptions.onShow) {
1345
+ this.floatingUIOptions.onShow();
1346
+ }
1347
+ this.isVisible = true;
1348
+ }
1349
+ hide() {
1350
+ if (!this.isVisible) {
1351
+ return;
1352
+ }
1353
+ this.element.style.visibility = "hidden";
1354
+ this.element.style.opacity = "0";
1355
+ this.element.remove();
1356
+ if (this.floatingUIOptions.onHide) {
1357
+ this.floatingUIOptions.onHide();
1358
+ }
1359
+ this.isVisible = false;
1360
+ }
1361
+ destroy() {
1362
+ this.hide();
1363
+ this.element.removeEventListener("mousedown", this.mousedownHandler, { capture: true });
1364
+ this.editor.off("focus", this.focusHandler);
1365
+ this.editor.off("blur", this.blurHandler);
1366
+ if (this.floatingUIOptions.onDestroy) {
1367
+ this.floatingUIOptions.onDestroy();
1368
+ }
1369
+ }
1370
+ };
1371
+ var FloatingMenuPlugin = (options) => {
1372
+ return new Plugin({
1373
+ key: typeof options.pluginKey === "string" ? new PluginKey(options.pluginKey) : options.pluginKey,
1374
+ view: (view) => new FloatingMenuView({ view, ...options })
1375
+ });
1376
+ };
1377
+ Extension.create({
1378
+ name: "floatingMenu",
1379
+ addOptions() {
1380
+ return {
1381
+ element: null,
1382
+ options: {},
1383
+ pluginKey: "floatingMenu",
1384
+ shouldShow: null
1385
+ };
1386
+ },
1387
+ addProseMirrorPlugins() {
1388
+ if (!this.options.element) {
1389
+ return [];
1390
+ }
1391
+ return [
1392
+ FloatingMenuPlugin({
1393
+ pluginKey: this.options.pluginKey,
1394
+ editor: this.editor,
1395
+ element: this.options.element,
1396
+ options: this.options.options,
1397
+ shouldShow: this.options.shouldShow
1398
+ })
1399
+ ];
1400
+ }
1401
+ });
1402
+ var FloatingMenu2 = defineComponent({
1403
+ name: "FloatingMenu",
1404
+ props: {
1405
+ pluginKey: {
1406
+ // TODO: TypeScript breaks :(
1407
+ // type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],
1408
+ type: null,
1409
+ default: "floatingMenu"
1410
+ },
1411
+ editor: {
1412
+ type: Object,
1413
+ required: true
1414
+ },
1415
+ options: {
1416
+ type: Object,
1417
+ default: () => ({})
1418
+ },
1419
+ shouldShow: {
1420
+ type: Function,
1421
+ default: null
1422
+ }
1423
+ },
1424
+ setup(props, { slots }) {
1425
+ const root = ref(null);
1426
+ onMounted(() => {
1427
+ const { pluginKey, editor, options, shouldShow } = props;
1428
+ if (!root.value) {
1429
+ return;
1430
+ }
1431
+ root.value.style.visibility = "hidden";
1432
+ root.value.style.position = "absolute";
1433
+ root.value.remove();
1434
+ editor.registerPlugin(
1435
+ FloatingMenuPlugin({
1436
+ pluginKey,
1437
+ editor,
1438
+ element: root.value,
1439
+ options,
1440
+ shouldShow
1441
+ })
1442
+ );
1443
+ });
1444
+ onBeforeUnmount(() => {
1445
+ const { pluginKey, editor } = props;
1446
+ editor.unregisterPlugin(pluginKey);
1447
+ });
1448
+ return () => {
1449
+ var _a;
1450
+ return h(Teleport, { to: "body" }, h("div", { ref: root }, (_a = slots.default) == null ? void 0 : _a.call(slots)));
1451
+ };
1452
+ }
1453
+ });
1454
+ export {
1455
+ BubbleMenu2 as BubbleMenu,
1456
+ FloatingMenu2 as FloatingMenu
1457
+ };