hazo_ui 2.2.3 → 2.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +4762 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -13
- package/dist/index.d.ts +88 -13
- package/dist/index.js +4751 -35
- package/dist/index.js.map +1 -1
- package/dist/styles.css +170 -51
- package/package.json +40 -2
- package/tailwind.preset.js +6 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React6 from 'react';
|
|
1
|
+
import * as React14 from 'react';
|
|
3
2
|
import { useState, useEffect } from 'react';
|
|
4
3
|
import { Slot } from '@radix-ui/react-slot';
|
|
5
4
|
import { cva } from 'class-variance-authority';
|
|
6
5
|
import { clsx } from 'clsx';
|
|
7
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
|
+
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
8
8
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
9
9
|
import { X, ChevronDown, ChevronUp, Check, Circle, Filter, Plus, ChevronsUpDown, ArrowUpDown, Trash2, GripVertical, Calendar as Calendar$1, ChevronRight, ChevronLeft } from 'lucide-react';
|
|
10
10
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
@@ -19,19 +19,50 @@ import { CSS } from '@dnd-kit/utilities';
|
|
|
19
19
|
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
20
20
|
import * as FaIcons from 'react-icons/fa';
|
|
21
21
|
import * as MdIcons from 'react-icons/md';
|
|
22
|
+
import { MdFormatClear } from 'react-icons/md';
|
|
22
23
|
import * as HiIcons from 'react-icons/hi';
|
|
23
24
|
import * as BiIcons from 'react-icons/bi';
|
|
25
|
+
import { BiBracket } from 'react-icons/bi';
|
|
24
26
|
import * as AiIcons from 'react-icons/ai';
|
|
25
27
|
import * as BsIcons from 'react-icons/bs';
|
|
26
28
|
import * as FiIcons from 'react-icons/fi';
|
|
29
|
+
import { FiMinus, FiPlus, FiChevronDown, FiType, FiList, FiCode, FiBold, FiItalic, FiUnderline, FiAlignLeft, FiAlignCenter, FiAlignRight, FiAlignJustify, FiLink, FiImage, FiPaperclip, FiTable, FiTrash2, FiColumns, FiSearch, FiEye } from 'react-icons/fi';
|
|
27
30
|
import * as IoIcons from 'react-icons/io5';
|
|
28
31
|
import * as RiIcons from 'react-icons/ri';
|
|
32
|
+
import { RiInsertRowBottom, RiInsertColumnRight, RiDeleteRow, RiDeleteColumn } from 'react-icons/ri';
|
|
29
33
|
import * as TbIcons from 'react-icons/tb';
|
|
30
34
|
import * as CiIcons from 'react-icons/ci';
|
|
35
|
+
import { ReactNodeViewRenderer, NodeViewWrapper, useEditor, EditorContent } from '@tiptap/react';
|
|
36
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
37
|
+
import { Underline } from '@tiptap/extension-underline';
|
|
38
|
+
import { TextStyle } from '@tiptap/extension-text-style';
|
|
39
|
+
import { Color } from '@tiptap/extension-color';
|
|
40
|
+
import { Highlight } from '@tiptap/extension-highlight';
|
|
41
|
+
import { FontFamily } from '@tiptap/extension-font-family';
|
|
42
|
+
import { TextAlign } from '@tiptap/extension-text-align';
|
|
43
|
+
import { Link } from '@tiptap/extension-link';
|
|
44
|
+
import { Image } from '@tiptap/extension-image';
|
|
45
|
+
import { Table } from '@tiptap/extension-table';
|
|
46
|
+
import { TableRow } from '@tiptap/extension-table-row';
|
|
47
|
+
import { TableCell } from '@tiptap/extension-table-cell';
|
|
48
|
+
import { TableHeader } from '@tiptap/extension-table-header';
|
|
49
|
+
import { TaskList } from '@tiptap/extension-task-list';
|
|
50
|
+
import { TaskItem } from '@tiptap/extension-task-item';
|
|
51
|
+
import { Subscript } from '@tiptap/extension-subscript';
|
|
52
|
+
import { Superscript } from '@tiptap/extension-superscript';
|
|
53
|
+
import { Placeholder } from '@tiptap/extension-placeholder';
|
|
54
|
+
import { HexColorPicker } from 'react-colorful';
|
|
55
|
+
import { LuUndo2, LuRedo2, LuHeading1, LuHeading2, LuHeading3, LuListOrdered, LuListTodo, LuQuote, LuStrikethrough, LuSubscript, LuSuperscript, LuHighlighter, LuTableProperties, LuColumns2 } from 'react-icons/lu';
|
|
56
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
57
|
+
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
58
|
+
import { RemoveMarkStep, Transform, liftTarget, joinPoint, canSplit, ReplaceStep, ReplaceAroundStep, canJoin } from '@tiptap/pm/transform';
|
|
59
|
+
import { createParagraphNear as createParagraphNear$1, deleteSelection as deleteSelection$1, exitCode as exitCode$1, joinUp as joinUp$1, joinDown as joinDown$1, joinBackward as joinBackward$1, joinForward as joinForward$1, joinTextblockBackward as joinTextblockBackward$1, joinTextblockForward as joinTextblockForward$1, lift as lift$1, liftEmptyBlock as liftEmptyBlock$1, newlineInCode as newlineInCode$1, selectNodeBackward as selectNodeBackward$1, selectNodeForward as selectNodeForward$1, selectParentNode as selectParentNode$1, selectTextblockEnd as selectTextblockEnd$1, selectTextblockStart as selectTextblockStart$1, setBlockType, wrapIn as wrapIn$1 } from '@tiptap/pm/commands';
|
|
60
|
+
import { Plugin, PluginKey, Selection, TextSelection, AllSelection, NodeSelection } from '@tiptap/pm/state';
|
|
61
|
+
import { Fragment, Slice, Node, Schema, DOMParser } from '@tiptap/pm/model';
|
|
62
|
+
import { liftListItem as liftListItem$1, sinkListItem as sinkListItem$1, wrapInList as wrapInList$1 } from '@tiptap/pm/schema-list';
|
|
63
|
+
import '@tiptap/pm/view';
|
|
64
|
+
import '@tiptap/pm/keymap';
|
|
31
65
|
|
|
32
|
-
var ExampleComponent = ({ children, className = "" }) => {
|
|
33
|
-
return /* @__PURE__ */ jsx("div", { className: `cls_example_component ${className}`, children });
|
|
34
|
-
};
|
|
35
66
|
function cn(...inputs) {
|
|
36
67
|
return twMerge(clsx(inputs));
|
|
37
68
|
}
|
|
@@ -60,7 +91,7 @@ var buttonVariants = cva(
|
|
|
60
91
|
}
|
|
61
92
|
}
|
|
62
93
|
);
|
|
63
|
-
var Button =
|
|
94
|
+
var Button = React14.forwardRef(
|
|
64
95
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
65
96
|
const Comp = asChild ? Slot : "button";
|
|
66
97
|
return /* @__PURE__ */ jsx(
|
|
@@ -77,7 +108,7 @@ Button.displayName = "Button";
|
|
|
77
108
|
var Dialog = DialogPrimitive.Root;
|
|
78
109
|
var DialogTrigger = DialogPrimitive.Trigger;
|
|
79
110
|
var DialogPortal = DialogPrimitive.Portal;
|
|
80
|
-
var DialogOverlay =
|
|
111
|
+
var DialogOverlay = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
81
112
|
DialogPrimitive.Overlay,
|
|
82
113
|
{
|
|
83
114
|
ref,
|
|
@@ -89,7 +120,7 @@ var DialogOverlay = React6.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
89
120
|
}
|
|
90
121
|
));
|
|
91
122
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
92
|
-
var DialogContent =
|
|
123
|
+
var DialogContent = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
93
124
|
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
94
125
|
/* @__PURE__ */ jsxs(
|
|
95
126
|
DialogPrimitive.Content,
|
|
@@ -139,7 +170,7 @@ var DialogFooter = ({
|
|
|
139
170
|
}
|
|
140
171
|
);
|
|
141
172
|
DialogFooter.displayName = "DialogFooter";
|
|
142
|
-
var DialogTitle =
|
|
173
|
+
var DialogTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
143
174
|
DialogPrimitive.Title,
|
|
144
175
|
{
|
|
145
176
|
ref,
|
|
@@ -151,7 +182,7 @@ var DialogTitle = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
151
182
|
}
|
|
152
183
|
));
|
|
153
184
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
154
|
-
var DialogDescription =
|
|
185
|
+
var DialogDescription = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
155
186
|
DialogPrimitive.Description,
|
|
156
187
|
{
|
|
157
188
|
ref,
|
|
@@ -160,7 +191,7 @@ var DialogDescription = React6.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
160
191
|
}
|
|
161
192
|
));
|
|
162
193
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
163
|
-
var Command =
|
|
194
|
+
var Command = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
164
195
|
"div",
|
|
165
196
|
{
|
|
166
197
|
ref,
|
|
@@ -172,7 +203,7 @@ var Command = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
|
|
|
172
203
|
}
|
|
173
204
|
));
|
|
174
205
|
Command.displayName = "Command";
|
|
175
|
-
var CommandInput =
|
|
206
|
+
var CommandInput = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
176
207
|
"input",
|
|
177
208
|
{
|
|
178
209
|
ref,
|
|
@@ -184,7 +215,7 @@ var CommandInput = React6.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
184
215
|
}
|
|
185
216
|
));
|
|
186
217
|
CommandInput.displayName = "CommandInput";
|
|
187
|
-
var CommandList =
|
|
218
|
+
var CommandList = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
188
219
|
"div",
|
|
189
220
|
{
|
|
190
221
|
ref,
|
|
@@ -193,7 +224,7 @@ var CommandList = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
193
224
|
}
|
|
194
225
|
));
|
|
195
226
|
CommandList.displayName = "CommandList";
|
|
196
|
-
var CommandEmpty =
|
|
227
|
+
var CommandEmpty = React14.forwardRef((props, ref) => /* @__PURE__ */ jsx(
|
|
197
228
|
"div",
|
|
198
229
|
{
|
|
199
230
|
ref,
|
|
@@ -202,7 +233,7 @@ var CommandEmpty = React6.forwardRef((props, ref) => /* @__PURE__ */ jsx(
|
|
|
202
233
|
}
|
|
203
234
|
));
|
|
204
235
|
CommandEmpty.displayName = "CommandEmpty";
|
|
205
|
-
var CommandGroup =
|
|
236
|
+
var CommandGroup = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
206
237
|
"div",
|
|
207
238
|
{
|
|
208
239
|
ref,
|
|
@@ -214,7 +245,7 @@ var CommandGroup = React6.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
214
245
|
}
|
|
215
246
|
));
|
|
216
247
|
CommandGroup.displayName = "CommandGroup";
|
|
217
|
-
var CommandItem =
|
|
248
|
+
var CommandItem = React14.forwardRef(({ className, onSelect, value, ...props }, ref) => {
|
|
218
249
|
const handleClick = () => {
|
|
219
250
|
if (onSelect && value) {
|
|
220
251
|
onSelect(value);
|
|
@@ -236,7 +267,7 @@ var CommandItem = React6.forwardRef(({ className, onSelect, value, ...props }, r
|
|
|
236
267
|
CommandItem.displayName = "CommandItem";
|
|
237
268
|
var Popover = PopoverPrimitive.Root;
|
|
238
269
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
239
|
-
var PopoverContent =
|
|
270
|
+
var PopoverContent = React14.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
240
271
|
PopoverPrimitive.Content,
|
|
241
272
|
{
|
|
242
273
|
ref,
|
|
@@ -250,7 +281,7 @@ var PopoverContent = React6.forwardRef(({ className, align = "center", sideOffse
|
|
|
250
281
|
}
|
|
251
282
|
) }));
|
|
252
283
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
253
|
-
var Input =
|
|
284
|
+
var Input = React14.forwardRef(
|
|
254
285
|
({ className, type, ...props }, ref) => {
|
|
255
286
|
return /* @__PURE__ */ jsx(
|
|
256
287
|
"input",
|
|
@@ -269,7 +300,7 @@ var Input = React6.forwardRef(
|
|
|
269
300
|
Input.displayName = "Input";
|
|
270
301
|
var Select = SelectPrimitive.Root;
|
|
271
302
|
var SelectValue = SelectPrimitive.Value;
|
|
272
|
-
var SelectTrigger =
|
|
303
|
+
var SelectTrigger = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
273
304
|
SelectPrimitive.Trigger,
|
|
274
305
|
{
|
|
275
306
|
ref,
|
|
@@ -285,7 +316,7 @@ var SelectTrigger = React6.forwardRef(({ className, children, ...props }, ref) =
|
|
|
285
316
|
}
|
|
286
317
|
));
|
|
287
318
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
288
|
-
var SelectScrollUpButton =
|
|
319
|
+
var SelectScrollUpButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
289
320
|
SelectPrimitive.ScrollUpButton,
|
|
290
321
|
{
|
|
291
322
|
ref,
|
|
@@ -298,7 +329,7 @@ var SelectScrollUpButton = React6.forwardRef(({ className, ...props }, ref) => /
|
|
|
298
329
|
}
|
|
299
330
|
));
|
|
300
331
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
301
|
-
var SelectScrollDownButton =
|
|
332
|
+
var SelectScrollDownButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
302
333
|
SelectPrimitive.ScrollDownButton,
|
|
303
334
|
{
|
|
304
335
|
ref,
|
|
@@ -311,7 +342,7 @@ var SelectScrollDownButton = React6.forwardRef(({ className, ...props }, ref) =>
|
|
|
311
342
|
}
|
|
312
343
|
));
|
|
313
344
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
314
|
-
var SelectContent =
|
|
345
|
+
var SelectContent = React14.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
315
346
|
SelectPrimitive.Content,
|
|
316
347
|
{
|
|
317
348
|
ref,
|
|
@@ -339,7 +370,7 @@ var SelectContent = React6.forwardRef(({ className, children, position = "popper
|
|
|
339
370
|
}
|
|
340
371
|
) }));
|
|
341
372
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
342
|
-
var SelectLabel =
|
|
373
|
+
var SelectLabel = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
343
374
|
SelectPrimitive.Label,
|
|
344
375
|
{
|
|
345
376
|
ref,
|
|
@@ -348,7 +379,7 @@ var SelectLabel = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
348
379
|
}
|
|
349
380
|
));
|
|
350
381
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
351
|
-
var SelectItem =
|
|
382
|
+
var SelectItem = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
352
383
|
SelectPrimitive.Item,
|
|
353
384
|
{
|
|
354
385
|
ref,
|
|
@@ -364,7 +395,7 @@ var SelectItem = React6.forwardRef(({ className, children, ...props }, ref) => /
|
|
|
364
395
|
}
|
|
365
396
|
));
|
|
366
397
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
367
|
-
var SelectSeparator =
|
|
398
|
+
var SelectSeparator = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
368
399
|
SelectPrimitive.Separator,
|
|
369
400
|
{
|
|
370
401
|
ref,
|
|
@@ -376,7 +407,7 @@ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
|
376
407
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
377
408
|
var Tooltip = TooltipPrimitive.Root;
|
|
378
409
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
379
|
-
var TooltipContent =
|
|
410
|
+
var TooltipContent = React14.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
380
411
|
TooltipPrimitive.Content,
|
|
381
412
|
{
|
|
382
413
|
ref,
|
|
@@ -847,7 +878,7 @@ function HazoUiMultiFilterDialog({
|
|
|
847
878
|
] })
|
|
848
879
|
] });
|
|
849
880
|
}
|
|
850
|
-
var Switch =
|
|
881
|
+
var Switch = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
851
882
|
SwitchPrimitives.Root,
|
|
852
883
|
{
|
|
853
884
|
className: cn(
|
|
@@ -867,7 +898,7 @@ var Switch = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
867
898
|
}
|
|
868
899
|
));
|
|
869
900
|
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
870
|
-
var Label2 =
|
|
901
|
+
var Label2 = React14.forwardRef(
|
|
871
902
|
({ className, ...props }, ref) => {
|
|
872
903
|
return /* @__PURE__ */ jsx(
|
|
873
904
|
"label",
|
|
@@ -1161,7 +1192,7 @@ function HazoUiMultiSortDialog({
|
|
|
1161
1192
|
] })
|
|
1162
1193
|
] });
|
|
1163
1194
|
}
|
|
1164
|
-
var RadioGroup =
|
|
1195
|
+
var RadioGroup = React14.forwardRef(({ className, ...props }, ref) => {
|
|
1165
1196
|
return /* @__PURE__ */ jsx(
|
|
1166
1197
|
RadioGroupPrimitive.Root,
|
|
1167
1198
|
{
|
|
@@ -1172,7 +1203,7 @@ var RadioGroup = React6.forwardRef(({ className, ...props }, ref) => {
|
|
|
1172
1203
|
);
|
|
1173
1204
|
});
|
|
1174
1205
|
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
|
|
1175
|
-
var RadioGroupItem =
|
|
1206
|
+
var RadioGroupItem = React14.forwardRef(({ className, ...props }, ref) => {
|
|
1176
1207
|
return /* @__PURE__ */ jsx(
|
|
1177
1208
|
RadioGroupPrimitive.Item,
|
|
1178
1209
|
{
|
|
@@ -1526,7 +1557,7 @@ function filterInputValue(value, input_type, num_decimals) {
|
|
|
1526
1557
|
}
|
|
1527
1558
|
}
|
|
1528
1559
|
}
|
|
1529
|
-
var HazoUiFlexInput =
|
|
1560
|
+
var HazoUiFlexInput = React14.forwardRef(
|
|
1530
1561
|
({
|
|
1531
1562
|
className,
|
|
1532
1563
|
input_type = "mixed",
|
|
@@ -1543,13 +1574,13 @@ var HazoUiFlexInput = React6.forwardRef(
|
|
|
1543
1574
|
onBlur,
|
|
1544
1575
|
...props
|
|
1545
1576
|
}, ref) => {
|
|
1546
|
-
const [internalValue, setInternalValue] =
|
|
1577
|
+
const [internalValue, setInternalValue] = React14.useState(
|
|
1547
1578
|
typeof controlledValue === "string" ? controlledValue : typeof controlledValue === "number" ? String(controlledValue) : ""
|
|
1548
1579
|
);
|
|
1549
|
-
const [errorMessage, setErrorMessage] =
|
|
1580
|
+
const [errorMessage, setErrorMessage] = React14.useState();
|
|
1550
1581
|
const isControlled = controlledValue !== void 0;
|
|
1551
1582
|
const currentValue = isControlled ? typeof controlledValue === "string" ? controlledValue : String(controlledValue || "") : internalValue;
|
|
1552
|
-
|
|
1583
|
+
React14.useEffect(() => {
|
|
1553
1584
|
if (isControlled) {
|
|
1554
1585
|
const newValue = typeof controlledValue === "string" ? controlledValue : String(controlledValue || "");
|
|
1555
1586
|
if (newValue !== internalValue) {
|
|
@@ -1630,6 +1661,4691 @@ var HazoUiFlexInput = React6.forwardRef(
|
|
|
1630
1661
|
);
|
|
1631
1662
|
HazoUiFlexInput.displayName = "HazoUiFlexInput";
|
|
1632
1663
|
|
|
1633
|
-
|
|
1664
|
+
// src/components/hazo_ui_richtext_editor/constants.ts
|
|
1665
|
+
var FONT_FAMILIES = [
|
|
1666
|
+
{ value: "Arial", label: "Arial" },
|
|
1667
|
+
{ value: "Verdana", label: "Verdana" },
|
|
1668
|
+
{ value: "Times New Roman", label: "Times New Roman" },
|
|
1669
|
+
{ value: "Georgia", label: "Georgia" },
|
|
1670
|
+
{ value: "Courier New", label: "Courier New" },
|
|
1671
|
+
{ value: "Trebuchet MS", label: "Trebuchet MS" }
|
|
1672
|
+
];
|
|
1673
|
+
var FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72];
|
|
1674
|
+
var DEFAULT_FONT_SIZE = 16;
|
|
1675
|
+
var MIN_FONT_SIZE = 8;
|
|
1676
|
+
var MAX_FONT_SIZE = 72;
|
|
1677
|
+
var PRESET_COLORS = [
|
|
1678
|
+
"#000000",
|
|
1679
|
+
"#ffffff",
|
|
1680
|
+
"#f44336",
|
|
1681
|
+
"#e91e63",
|
|
1682
|
+
"#9c27b0",
|
|
1683
|
+
"#673ab7",
|
|
1684
|
+
"#3f51b5",
|
|
1685
|
+
"#2196f3",
|
|
1686
|
+
"#03a9f4",
|
|
1687
|
+
"#00bcd4",
|
|
1688
|
+
"#009688",
|
|
1689
|
+
"#4caf50",
|
|
1690
|
+
"#8bc34a",
|
|
1691
|
+
"#cddc39",
|
|
1692
|
+
"#ffeb3b",
|
|
1693
|
+
"#ffc107",
|
|
1694
|
+
"#ff9800",
|
|
1695
|
+
"#ff5722",
|
|
1696
|
+
"#795548",
|
|
1697
|
+
"#9e9e9e"
|
|
1698
|
+
];
|
|
1699
|
+
var DEFAULT_TEXT_COLOR = "#000000";
|
|
1700
|
+
var DEFAULT_HIGHLIGHT_COLOR = "#ffff00";
|
|
1701
|
+
var DEFAULT_MIN_HEIGHT = "200px";
|
|
1702
|
+
var DEFAULT_MAX_HEIGHT = "500px";
|
|
1703
|
+
var DEFAULT_PLACEHOLDER = "Start typing...";
|
|
1704
|
+
function ColorPickerPopover({
|
|
1705
|
+
color,
|
|
1706
|
+
on_color_change,
|
|
1707
|
+
trigger_icon,
|
|
1708
|
+
trigger_label = "Pick color"
|
|
1709
|
+
}) {
|
|
1710
|
+
const [is_open, set_is_open] = React14.useState(false);
|
|
1711
|
+
const [hex_input, set_hex_input] = React14.useState(color);
|
|
1712
|
+
React14.useEffect(() => {
|
|
1713
|
+
set_hex_input(color);
|
|
1714
|
+
}, [color]);
|
|
1715
|
+
const handle_hex_input_change = (e) => {
|
|
1716
|
+
const value = e.target.value;
|
|
1717
|
+
set_hex_input(value);
|
|
1718
|
+
if (/^#[0-9A-Fa-f]{6}$/.test(value)) {
|
|
1719
|
+
on_color_change(value);
|
|
1720
|
+
}
|
|
1721
|
+
};
|
|
1722
|
+
const handle_preset_select = (preset_color) => {
|
|
1723
|
+
on_color_change(preset_color);
|
|
1724
|
+
set_hex_input(preset_color);
|
|
1725
|
+
};
|
|
1726
|
+
return /* @__PURE__ */ jsxs(Popover, { open: is_open, onOpenChange: set_is_open, children: [
|
|
1727
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1728
|
+
Button,
|
|
1729
|
+
{
|
|
1730
|
+
variant: "ghost",
|
|
1731
|
+
size: "sm",
|
|
1732
|
+
className: "cls_color_picker_trigger h-8 w-8 p-0",
|
|
1733
|
+
"aria-label": trigger_label,
|
|
1734
|
+
children: /* @__PURE__ */ jsxs("div", { className: "cls_color_picker_icon_wrapper relative", children: [
|
|
1735
|
+
trigger_icon,
|
|
1736
|
+
/* @__PURE__ */ jsx(
|
|
1737
|
+
"div",
|
|
1738
|
+
{
|
|
1739
|
+
className: "cls_color_picker_indicator absolute -bottom-0.5 left-1/2 -translate-x-1/2 h-1 w-4 rounded-full",
|
|
1740
|
+
style: { backgroundColor: color }
|
|
1741
|
+
}
|
|
1742
|
+
)
|
|
1743
|
+
] })
|
|
1744
|
+
}
|
|
1745
|
+
) }),
|
|
1746
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_color_picker_popover w-64 p-3", align: "start", children: /* @__PURE__ */ jsxs("div", { className: "cls_color_picker_content space-y-3", children: [
|
|
1747
|
+
/* @__PURE__ */ jsx(
|
|
1748
|
+
HexColorPicker,
|
|
1749
|
+
{
|
|
1750
|
+
color,
|
|
1751
|
+
onChange: (new_color) => {
|
|
1752
|
+
on_color_change(new_color);
|
|
1753
|
+
set_hex_input(new_color);
|
|
1754
|
+
},
|
|
1755
|
+
className: "cls_color_picker_main !w-full"
|
|
1756
|
+
}
|
|
1757
|
+
),
|
|
1758
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_color_picker_hex_input flex items-center gap-2", children: [
|
|
1759
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Hex:" }),
|
|
1760
|
+
/* @__PURE__ */ jsx(
|
|
1761
|
+
Input,
|
|
1762
|
+
{
|
|
1763
|
+
value: hex_input,
|
|
1764
|
+
onChange: handle_hex_input_change,
|
|
1765
|
+
className: "h-8 font-mono text-sm",
|
|
1766
|
+
placeholder: "#000000"
|
|
1767
|
+
}
|
|
1768
|
+
)
|
|
1769
|
+
] }),
|
|
1770
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_color_picker_presets", children: [
|
|
1771
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mb-2 block", children: "Presets" }),
|
|
1772
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-10 gap-1", children: PRESET_COLORS.map((preset_color) => /* @__PURE__ */ jsx(
|
|
1773
|
+
"button",
|
|
1774
|
+
{
|
|
1775
|
+
onClick: () => handle_preset_select(preset_color),
|
|
1776
|
+
className: cn(
|
|
1777
|
+
"cls_color_preset h-5 w-5 rounded border border-border transition-transform",
|
|
1778
|
+
"hover:scale-110 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1",
|
|
1779
|
+
color === preset_color && "ring-2 ring-primary ring-offset-1"
|
|
1780
|
+
),
|
|
1781
|
+
style: { backgroundColor: preset_color },
|
|
1782
|
+
"aria-label": `Select color ${preset_color}`
|
|
1783
|
+
},
|
|
1784
|
+
preset_color
|
|
1785
|
+
)) })
|
|
1786
|
+
] })
|
|
1787
|
+
] }) })
|
|
1788
|
+
] });
|
|
1789
|
+
}
|
|
1790
|
+
function TableSizePicker({
|
|
1791
|
+
max_rows = 8,
|
|
1792
|
+
max_cols = 8,
|
|
1793
|
+
on_select
|
|
1794
|
+
}) {
|
|
1795
|
+
const [hover_row, set_hover_row] = React14.useState(0);
|
|
1796
|
+
const [hover_col, set_hover_col] = React14.useState(0);
|
|
1797
|
+
return /* @__PURE__ */ jsxs("div", { className: "cls_table_size_picker p-2", children: [
|
|
1798
|
+
/* @__PURE__ */ jsx("div", { className: "cls_table_size_label text-sm text-muted-foreground mb-2 text-center", children: hover_row > 0 && hover_col > 0 ? `${hover_row} x ${hover_col} Table` : "Select table size" }),
|
|
1799
|
+
/* @__PURE__ */ jsx(
|
|
1800
|
+
"div",
|
|
1801
|
+
{
|
|
1802
|
+
className: "cls_table_size_grid grid gap-1",
|
|
1803
|
+
style: {
|
|
1804
|
+
gridTemplateColumns: `repeat(${max_cols}, 1fr)`
|
|
1805
|
+
},
|
|
1806
|
+
onMouseLeave: () => {
|
|
1807
|
+
set_hover_row(0);
|
|
1808
|
+
set_hover_col(0);
|
|
1809
|
+
},
|
|
1810
|
+
children: Array.from({ length: max_rows * max_cols }).map((_, index) => {
|
|
1811
|
+
const row = Math.floor(index / max_cols) + 1;
|
|
1812
|
+
const col = index % max_cols + 1;
|
|
1813
|
+
const is_highlighted = row <= hover_row && col <= hover_col;
|
|
1814
|
+
return /* @__PURE__ */ jsx(
|
|
1815
|
+
"div",
|
|
1816
|
+
{
|
|
1817
|
+
className: cn(
|
|
1818
|
+
"cls_table_size_cell w-4 h-4 border border-border rounded-sm cursor-pointer transition-colors",
|
|
1819
|
+
is_highlighted ? "bg-primary border-primary" : "bg-background hover:bg-muted"
|
|
1820
|
+
),
|
|
1821
|
+
onMouseEnter: () => {
|
|
1822
|
+
set_hover_row(row);
|
|
1823
|
+
set_hover_col(col);
|
|
1824
|
+
},
|
|
1825
|
+
onClick: () => on_select(row, col)
|
|
1826
|
+
},
|
|
1827
|
+
index
|
|
1828
|
+
);
|
|
1829
|
+
})
|
|
1830
|
+
}
|
|
1831
|
+
)
|
|
1832
|
+
] });
|
|
1833
|
+
}
|
|
1834
|
+
function ToolbarButton({ icon, label, on_click, is_active, disabled, className }) {
|
|
1835
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
1836
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1837
|
+
Button,
|
|
1838
|
+
{
|
|
1839
|
+
variant: "ghost",
|
|
1840
|
+
size: "sm",
|
|
1841
|
+
onClick: on_click,
|
|
1842
|
+
disabled,
|
|
1843
|
+
className: cn(
|
|
1844
|
+
"cls_toolbar_button h-8 w-8 p-0",
|
|
1845
|
+
is_active && "bg-accent text-accent-foreground",
|
|
1846
|
+
className
|
|
1847
|
+
),
|
|
1848
|
+
children: icon
|
|
1849
|
+
}
|
|
1850
|
+
) }),
|
|
1851
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: label }) })
|
|
1852
|
+
] });
|
|
1853
|
+
}
|
|
1854
|
+
function ToolbarDivider() {
|
|
1855
|
+
return /* @__PURE__ */ jsx("div", { className: "cls_toolbar_divider mx-1 h-6 w-px bg-border" });
|
|
1856
|
+
}
|
|
1857
|
+
function get_current_font_size(editor) {
|
|
1858
|
+
if (!editor) return DEFAULT_FONT_SIZE;
|
|
1859
|
+
const attrs = editor.getAttributes("textStyle");
|
|
1860
|
+
if (attrs?.fontSize) {
|
|
1861
|
+
const parsed = parseInt(attrs.fontSize.replace("px", ""), 10);
|
|
1862
|
+
return isNaN(parsed) ? DEFAULT_FONT_SIZE : parsed;
|
|
1863
|
+
}
|
|
1864
|
+
return DEFAULT_FONT_SIZE;
|
|
1865
|
+
}
|
|
1866
|
+
function Toolbar({ editor, on_open_variables_modal, variables, on_image_embed, on_add_attachment }) {
|
|
1867
|
+
const [link_url, set_link_url] = React14.useState("");
|
|
1868
|
+
const [is_link_popover_open, set_is_link_popover_open] = React14.useState(false);
|
|
1869
|
+
const [is_block_type_open, set_is_block_type_open] = React14.useState(false);
|
|
1870
|
+
const [is_table_popover_open, set_is_table_popover_open] = React14.useState(false);
|
|
1871
|
+
const [is_table_controls_open, set_is_table_controls_open] = React14.useState(false);
|
|
1872
|
+
const [is_columns_popover_open, set_is_columns_popover_open] = React14.useState(false);
|
|
1873
|
+
const [is_uploading_image, set_is_uploading_image] = React14.useState(false);
|
|
1874
|
+
const [is_uploading_attachment, set_is_uploading_attachment] = React14.useState(false);
|
|
1875
|
+
const image_input_ref = React14.useRef(null);
|
|
1876
|
+
const attachment_input_ref = React14.useRef(null);
|
|
1877
|
+
if (!editor) {
|
|
1878
|
+
return null;
|
|
1879
|
+
}
|
|
1880
|
+
const is_in_table = editor.isActive("table");
|
|
1881
|
+
const current_font_family = editor.getAttributes("textStyle").fontFamily || "Arial";
|
|
1882
|
+
const current_text_color = editor.getAttributes("textStyle").color || DEFAULT_TEXT_COLOR;
|
|
1883
|
+
const current_highlight_color = editor.getAttributes("highlight").color || DEFAULT_HIGHLIGHT_COLOR;
|
|
1884
|
+
const current_font_size = get_current_font_size(editor);
|
|
1885
|
+
const handle_insert_link = () => {
|
|
1886
|
+
if (link_url) {
|
|
1887
|
+
editor.chain().focus().setLink({ href: link_url }).run();
|
|
1888
|
+
set_link_url("");
|
|
1889
|
+
set_is_link_popover_open(false);
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
const handle_image_change = async (e) => {
|
|
1893
|
+
const file = e.target.files?.[0];
|
|
1894
|
+
if (!file || !on_image_embed) return;
|
|
1895
|
+
set_is_uploading_image(true);
|
|
1896
|
+
try {
|
|
1897
|
+
await on_image_embed(file);
|
|
1898
|
+
} catch (error) {
|
|
1899
|
+
console.error("Image embed failed:", error);
|
|
1900
|
+
} finally {
|
|
1901
|
+
set_is_uploading_image(false);
|
|
1902
|
+
if (image_input_ref.current) {
|
|
1903
|
+
image_input_ref.current.value = "";
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
};
|
|
1907
|
+
const handle_attachment_change = async (e) => {
|
|
1908
|
+
const file = e.target.files?.[0];
|
|
1909
|
+
if (!file || !on_add_attachment) return;
|
|
1910
|
+
set_is_uploading_attachment(true);
|
|
1911
|
+
try {
|
|
1912
|
+
await on_add_attachment(file);
|
|
1913
|
+
} catch (error) {
|
|
1914
|
+
console.error("Attachment failed:", error);
|
|
1915
|
+
} finally {
|
|
1916
|
+
set_is_uploading_attachment(false);
|
|
1917
|
+
if (attachment_input_ref.current) {
|
|
1918
|
+
attachment_input_ref.current.value = "";
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
};
|
|
1922
|
+
const select_block_type = (command2) => {
|
|
1923
|
+
command2();
|
|
1924
|
+
set_is_block_type_open(false);
|
|
1925
|
+
};
|
|
1926
|
+
const handle_insert_table = (rows, cols) => {
|
|
1927
|
+
editor.chain().focus().insertTable({ rows, cols, withHeaderRow: true }).run();
|
|
1928
|
+
set_is_table_popover_open(false);
|
|
1929
|
+
};
|
|
1930
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxs("div", { className: "cls_toolbar flex flex-wrap items-center gap-0.5 p-2 border-b border-border bg-muted/30", children: [
|
|
1931
|
+
/* @__PURE__ */ jsx(
|
|
1932
|
+
ToolbarButton,
|
|
1933
|
+
{
|
|
1934
|
+
icon: /* @__PURE__ */ jsx(LuUndo2, { className: "h-4 w-4" }),
|
|
1935
|
+
label: "Undo",
|
|
1936
|
+
on_click: () => editor.chain().focus().undo().run(),
|
|
1937
|
+
disabled: !editor.can().undo()
|
|
1938
|
+
}
|
|
1939
|
+
),
|
|
1940
|
+
/* @__PURE__ */ jsx(
|
|
1941
|
+
ToolbarButton,
|
|
1942
|
+
{
|
|
1943
|
+
icon: /* @__PURE__ */ jsx(LuRedo2, { className: "h-4 w-4" }),
|
|
1944
|
+
label: "Redo",
|
|
1945
|
+
on_click: () => editor.chain().focus().redo().run(),
|
|
1946
|
+
disabled: !editor.can().redo()
|
|
1947
|
+
}
|
|
1948
|
+
),
|
|
1949
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
1950
|
+
/* @__PURE__ */ jsxs(
|
|
1951
|
+
Select,
|
|
1952
|
+
{
|
|
1953
|
+
value: current_font_family,
|
|
1954
|
+
onValueChange: (value) => editor.chain().focus().setFontFamily(value).run(),
|
|
1955
|
+
children: [
|
|
1956
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_toolbar_font_family h-8 w-32 text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
1957
|
+
/* @__PURE__ */ jsx(SelectContent, { children: FONT_FAMILIES.map((font) => /* @__PURE__ */ jsx(SelectItem, { value: font.value, style: { fontFamily: font.value }, children: font.label }, font.value)) })
|
|
1958
|
+
]
|
|
1959
|
+
}
|
|
1960
|
+
),
|
|
1961
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
1962
|
+
/* @__PURE__ */ jsx(
|
|
1963
|
+
ToolbarButton,
|
|
1964
|
+
{
|
|
1965
|
+
icon: /* @__PURE__ */ jsx(FiMinus, { className: "h-4 w-4" }),
|
|
1966
|
+
label: "Decrease font size",
|
|
1967
|
+
on_click: () => editor.chain().focus().decreaseFontSize().run()
|
|
1968
|
+
}
|
|
1969
|
+
),
|
|
1970
|
+
/* @__PURE__ */ jsx("span", { className: "cls_toolbar_font_size w-8 text-center text-xs tabular-nums", children: current_font_size }),
|
|
1971
|
+
/* @__PURE__ */ jsx(
|
|
1972
|
+
ToolbarButton,
|
|
1973
|
+
{
|
|
1974
|
+
icon: /* @__PURE__ */ jsx(FiPlus, { className: "h-4 w-4" }),
|
|
1975
|
+
label: "Increase font size",
|
|
1976
|
+
on_click: () => editor.chain().focus().increaseFontSize().run()
|
|
1977
|
+
}
|
|
1978
|
+
),
|
|
1979
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
1980
|
+
/* @__PURE__ */ jsxs(Popover, { open: is_block_type_open, onOpenChange: set_is_block_type_open, children: [
|
|
1981
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", className: "cls_toolbar_block_type h-8 gap-1 px-2", children: [
|
|
1982
|
+
/* @__PURE__ */ jsx(LuHeading1, { className: "h-4 w-4" }),
|
|
1983
|
+
/* @__PURE__ */ jsx(FiChevronDown, { className: "h-3 w-3" })
|
|
1984
|
+
] }) }),
|
|
1985
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_block_type_popover w-48 p-1", align: "start", children: /* @__PURE__ */ jsxs("div", { className: "cls_block_type_list space-y-0.5", children: [
|
|
1986
|
+
/* @__PURE__ */ jsxs(
|
|
1987
|
+
Button,
|
|
1988
|
+
{
|
|
1989
|
+
variant: editor.isActive("paragraph") ? "secondary" : "ghost",
|
|
1990
|
+
size: "sm",
|
|
1991
|
+
className: "w-full justify-start",
|
|
1992
|
+
onClick: () => select_block_type(() => editor.chain().focus().setParagraph().run()),
|
|
1993
|
+
children: [
|
|
1994
|
+
/* @__PURE__ */ jsx(FiType, { className: "mr-2 h-4 w-4" }),
|
|
1995
|
+
"Paragraph"
|
|
1996
|
+
]
|
|
1997
|
+
}
|
|
1998
|
+
),
|
|
1999
|
+
/* @__PURE__ */ jsxs(
|
|
2000
|
+
Button,
|
|
2001
|
+
{
|
|
2002
|
+
variant: editor.isActive("heading", { level: 1 }) ? "secondary" : "ghost",
|
|
2003
|
+
size: "sm",
|
|
2004
|
+
className: "w-full justify-start",
|
|
2005
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleHeading({ level: 1 }).run()),
|
|
2006
|
+
children: [
|
|
2007
|
+
/* @__PURE__ */ jsx(LuHeading1, { className: "mr-2 h-4 w-4" }),
|
|
2008
|
+
"Heading 1"
|
|
2009
|
+
]
|
|
2010
|
+
}
|
|
2011
|
+
),
|
|
2012
|
+
/* @__PURE__ */ jsxs(
|
|
2013
|
+
Button,
|
|
2014
|
+
{
|
|
2015
|
+
variant: editor.isActive("heading", { level: 2 }) ? "secondary" : "ghost",
|
|
2016
|
+
size: "sm",
|
|
2017
|
+
className: "w-full justify-start",
|
|
2018
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleHeading({ level: 2 }).run()),
|
|
2019
|
+
children: [
|
|
2020
|
+
/* @__PURE__ */ jsx(LuHeading2, { className: "mr-2 h-4 w-4" }),
|
|
2021
|
+
"Heading 2"
|
|
2022
|
+
]
|
|
2023
|
+
}
|
|
2024
|
+
),
|
|
2025
|
+
/* @__PURE__ */ jsxs(
|
|
2026
|
+
Button,
|
|
2027
|
+
{
|
|
2028
|
+
variant: editor.isActive("heading", { level: 3 }) ? "secondary" : "ghost",
|
|
2029
|
+
size: "sm",
|
|
2030
|
+
className: "w-full justify-start",
|
|
2031
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleHeading({ level: 3 }).run()),
|
|
2032
|
+
children: [
|
|
2033
|
+
/* @__PURE__ */ jsx(LuHeading3, { className: "mr-2 h-4 w-4" }),
|
|
2034
|
+
"Heading 3"
|
|
2035
|
+
]
|
|
2036
|
+
}
|
|
2037
|
+
),
|
|
2038
|
+
/* @__PURE__ */ jsxs(
|
|
2039
|
+
Button,
|
|
2040
|
+
{
|
|
2041
|
+
variant: editor.isActive("bulletList") ? "secondary" : "ghost",
|
|
2042
|
+
size: "sm",
|
|
2043
|
+
className: "w-full justify-start",
|
|
2044
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleBulletList().run()),
|
|
2045
|
+
children: [
|
|
2046
|
+
/* @__PURE__ */ jsx(FiList, { className: "mr-2 h-4 w-4" }),
|
|
2047
|
+
"Bullet List"
|
|
2048
|
+
]
|
|
2049
|
+
}
|
|
2050
|
+
),
|
|
2051
|
+
/* @__PURE__ */ jsxs(
|
|
2052
|
+
Button,
|
|
2053
|
+
{
|
|
2054
|
+
variant: editor.isActive("orderedList") ? "secondary" : "ghost",
|
|
2055
|
+
size: "sm",
|
|
2056
|
+
className: "w-full justify-start",
|
|
2057
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleOrderedList().run()),
|
|
2058
|
+
children: [
|
|
2059
|
+
/* @__PURE__ */ jsx(LuListOrdered, { className: "mr-2 h-4 w-4" }),
|
|
2060
|
+
"Numbered List"
|
|
2061
|
+
]
|
|
2062
|
+
}
|
|
2063
|
+
),
|
|
2064
|
+
/* @__PURE__ */ jsxs(
|
|
2065
|
+
Button,
|
|
2066
|
+
{
|
|
2067
|
+
variant: editor.isActive("taskList") ? "secondary" : "ghost",
|
|
2068
|
+
size: "sm",
|
|
2069
|
+
className: "w-full justify-start",
|
|
2070
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleTaskList().run()),
|
|
2071
|
+
children: [
|
|
2072
|
+
/* @__PURE__ */ jsx(LuListTodo, { className: "mr-2 h-4 w-4" }),
|
|
2073
|
+
"Task List"
|
|
2074
|
+
]
|
|
2075
|
+
}
|
|
2076
|
+
),
|
|
2077
|
+
/* @__PURE__ */ jsxs(
|
|
2078
|
+
Button,
|
|
2079
|
+
{
|
|
2080
|
+
variant: editor.isActive("blockquote") ? "secondary" : "ghost",
|
|
2081
|
+
size: "sm",
|
|
2082
|
+
className: "w-full justify-start",
|
|
2083
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleBlockquote().run()),
|
|
2084
|
+
children: [
|
|
2085
|
+
/* @__PURE__ */ jsx(LuQuote, { className: "mr-2 h-4 w-4" }),
|
|
2086
|
+
"Quote"
|
|
2087
|
+
]
|
|
2088
|
+
}
|
|
2089
|
+
),
|
|
2090
|
+
/* @__PURE__ */ jsxs(
|
|
2091
|
+
Button,
|
|
2092
|
+
{
|
|
2093
|
+
variant: editor.isActive("codeBlock") ? "secondary" : "ghost",
|
|
2094
|
+
size: "sm",
|
|
2095
|
+
className: "w-full justify-start",
|
|
2096
|
+
onClick: () => select_block_type(() => editor.chain().focus().toggleCodeBlock().run()),
|
|
2097
|
+
children: [
|
|
2098
|
+
/* @__PURE__ */ jsx(FiCode, { className: "mr-2 h-4 w-4" }),
|
|
2099
|
+
"Code Block"
|
|
2100
|
+
]
|
|
2101
|
+
}
|
|
2102
|
+
)
|
|
2103
|
+
] }) })
|
|
2104
|
+
] }),
|
|
2105
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
2106
|
+
/* @__PURE__ */ jsx(
|
|
2107
|
+
ToolbarButton,
|
|
2108
|
+
{
|
|
2109
|
+
icon: /* @__PURE__ */ jsx(FiBold, { className: "h-4 w-4" }),
|
|
2110
|
+
label: "Bold",
|
|
2111
|
+
on_click: () => editor.chain().focus().toggleBold().run(),
|
|
2112
|
+
is_active: editor.isActive("bold")
|
|
2113
|
+
}
|
|
2114
|
+
),
|
|
2115
|
+
/* @__PURE__ */ jsx(
|
|
2116
|
+
ToolbarButton,
|
|
2117
|
+
{
|
|
2118
|
+
icon: /* @__PURE__ */ jsx(FiItalic, { className: "h-4 w-4" }),
|
|
2119
|
+
label: "Italic",
|
|
2120
|
+
on_click: () => editor.chain().focus().toggleItalic().run(),
|
|
2121
|
+
is_active: editor.isActive("italic")
|
|
2122
|
+
}
|
|
2123
|
+
),
|
|
2124
|
+
/* @__PURE__ */ jsx(
|
|
2125
|
+
ToolbarButton,
|
|
2126
|
+
{
|
|
2127
|
+
icon: /* @__PURE__ */ jsx(FiUnderline, { className: "h-4 w-4" }),
|
|
2128
|
+
label: "Underline",
|
|
2129
|
+
on_click: () => editor.chain().focus().toggleUnderline().run(),
|
|
2130
|
+
is_active: editor.isActive("underline")
|
|
2131
|
+
}
|
|
2132
|
+
),
|
|
2133
|
+
/* @__PURE__ */ jsx(
|
|
2134
|
+
ToolbarButton,
|
|
2135
|
+
{
|
|
2136
|
+
icon: /* @__PURE__ */ jsx(LuStrikethrough, { className: "h-4 w-4" }),
|
|
2137
|
+
label: "Strikethrough",
|
|
2138
|
+
on_click: () => editor.chain().focus().toggleStrike().run(),
|
|
2139
|
+
is_active: editor.isActive("strike")
|
|
2140
|
+
}
|
|
2141
|
+
),
|
|
2142
|
+
/* @__PURE__ */ jsx(
|
|
2143
|
+
ToolbarButton,
|
|
2144
|
+
{
|
|
2145
|
+
icon: /* @__PURE__ */ jsx(LuSubscript, { className: "h-4 w-4" }),
|
|
2146
|
+
label: "Subscript",
|
|
2147
|
+
on_click: () => editor.chain().focus().toggleSubscript().run(),
|
|
2148
|
+
is_active: editor.isActive("subscript")
|
|
2149
|
+
}
|
|
2150
|
+
),
|
|
2151
|
+
/* @__PURE__ */ jsx(
|
|
2152
|
+
ToolbarButton,
|
|
2153
|
+
{
|
|
2154
|
+
icon: /* @__PURE__ */ jsx(LuSuperscript, { className: "h-4 w-4" }),
|
|
2155
|
+
label: "Superscript",
|
|
2156
|
+
on_click: () => editor.chain().focus().toggleSuperscript().run(),
|
|
2157
|
+
is_active: editor.isActive("superscript")
|
|
2158
|
+
}
|
|
2159
|
+
),
|
|
2160
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
2161
|
+
/* @__PURE__ */ jsx(
|
|
2162
|
+
ColorPickerPopover,
|
|
2163
|
+
{
|
|
2164
|
+
color: current_text_color,
|
|
2165
|
+
on_color_change: (color) => editor.chain().focus().setColor(color).run(),
|
|
2166
|
+
trigger_icon: /* @__PURE__ */ jsx(FiType, { className: "h-4 w-4" }),
|
|
2167
|
+
trigger_label: "Text color"
|
|
2168
|
+
}
|
|
2169
|
+
),
|
|
2170
|
+
/* @__PURE__ */ jsx(
|
|
2171
|
+
ColorPickerPopover,
|
|
2172
|
+
{
|
|
2173
|
+
color: current_highlight_color,
|
|
2174
|
+
on_color_change: (color) => editor.chain().focus().toggleHighlight({ color }).run(),
|
|
2175
|
+
trigger_icon: /* @__PURE__ */ jsx(LuHighlighter, { className: "h-4 w-4" }),
|
|
2176
|
+
trigger_label: "Highlight color"
|
|
2177
|
+
}
|
|
2178
|
+
),
|
|
2179
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
2180
|
+
/* @__PURE__ */ jsx(
|
|
2181
|
+
ToolbarButton,
|
|
2182
|
+
{
|
|
2183
|
+
icon: /* @__PURE__ */ jsx(FiAlignLeft, { className: "h-4 w-4" }),
|
|
2184
|
+
label: "Align left",
|
|
2185
|
+
on_click: () => editor.chain().focus().setTextAlign("left").run(),
|
|
2186
|
+
is_active: editor.isActive({ textAlign: "left" })
|
|
2187
|
+
}
|
|
2188
|
+
),
|
|
2189
|
+
/* @__PURE__ */ jsx(
|
|
2190
|
+
ToolbarButton,
|
|
2191
|
+
{
|
|
2192
|
+
icon: /* @__PURE__ */ jsx(FiAlignCenter, { className: "h-4 w-4" }),
|
|
2193
|
+
label: "Align center",
|
|
2194
|
+
on_click: () => editor.chain().focus().setTextAlign("center").run(),
|
|
2195
|
+
is_active: editor.isActive({ textAlign: "center" })
|
|
2196
|
+
}
|
|
2197
|
+
),
|
|
2198
|
+
/* @__PURE__ */ jsx(
|
|
2199
|
+
ToolbarButton,
|
|
2200
|
+
{
|
|
2201
|
+
icon: /* @__PURE__ */ jsx(FiAlignRight, { className: "h-4 w-4" }),
|
|
2202
|
+
label: "Align right",
|
|
2203
|
+
on_click: () => editor.chain().focus().setTextAlign("right").run(),
|
|
2204
|
+
is_active: editor.isActive({ textAlign: "right" })
|
|
2205
|
+
}
|
|
2206
|
+
),
|
|
2207
|
+
/* @__PURE__ */ jsx(
|
|
2208
|
+
ToolbarButton,
|
|
2209
|
+
{
|
|
2210
|
+
icon: /* @__PURE__ */ jsx(FiAlignJustify, { className: "h-4 w-4" }),
|
|
2211
|
+
label: "Justify",
|
|
2212
|
+
on_click: () => editor.chain().focus().setTextAlign("justify").run(),
|
|
2213
|
+
is_active: editor.isActive({ textAlign: "justify" })
|
|
2214
|
+
}
|
|
2215
|
+
),
|
|
2216
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
2217
|
+
/* @__PURE__ */ jsxs(Popover, { open: is_link_popover_open, onOpenChange: set_is_link_popover_open, children: [
|
|
2218
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
2219
|
+
Button,
|
|
2220
|
+
{
|
|
2221
|
+
variant: "ghost",
|
|
2222
|
+
size: "sm",
|
|
2223
|
+
className: cn(
|
|
2224
|
+
"cls_toolbar_link h-8 w-8 p-0",
|
|
2225
|
+
editor.isActive("link") && "bg-accent text-accent-foreground"
|
|
2226
|
+
),
|
|
2227
|
+
children: /* @__PURE__ */ jsx(FiLink, { className: "h-4 w-4" })
|
|
2228
|
+
}
|
|
2229
|
+
) }),
|
|
2230
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_link_popover w-72 p-3", align: "start", children: /* @__PURE__ */ jsxs("div", { className: "cls_link_form space-y-2", children: [
|
|
2231
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Insert Link" }),
|
|
2232
|
+
/* @__PURE__ */ jsx(
|
|
2233
|
+
"input",
|
|
2234
|
+
{
|
|
2235
|
+
type: "url",
|
|
2236
|
+
placeholder: "https://example.com",
|
|
2237
|
+
value: link_url,
|
|
2238
|
+
onChange: (e) => set_link_url(e.target.value),
|
|
2239
|
+
className: "cls_link_input w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
2240
|
+
onKeyDown: (e) => e.key === "Enter" && handle_insert_link()
|
|
2241
|
+
}
|
|
2242
|
+
),
|
|
2243
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
2244
|
+
editor.isActive("link") && /* @__PURE__ */ jsx(
|
|
2245
|
+
Button,
|
|
2246
|
+
{
|
|
2247
|
+
variant: "outline",
|
|
2248
|
+
size: "sm",
|
|
2249
|
+
onClick: () => {
|
|
2250
|
+
editor.chain().focus().unsetLink().run();
|
|
2251
|
+
set_is_link_popover_open(false);
|
|
2252
|
+
},
|
|
2253
|
+
children: "Remove"
|
|
2254
|
+
}
|
|
2255
|
+
),
|
|
2256
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", onClick: handle_insert_link, children: "Insert" })
|
|
2257
|
+
] })
|
|
2258
|
+
] }) })
|
|
2259
|
+
] }),
|
|
2260
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
2261
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
2262
|
+
Button,
|
|
2263
|
+
{
|
|
2264
|
+
variant: "ghost",
|
|
2265
|
+
size: "sm",
|
|
2266
|
+
className: "cls_toolbar_image h-8 w-8 p-0",
|
|
2267
|
+
onClick: () => image_input_ref.current?.click(),
|
|
2268
|
+
disabled: is_uploading_image,
|
|
2269
|
+
children: /* @__PURE__ */ jsx(FiImage, { className: "h-4 w-4" })
|
|
2270
|
+
}
|
|
2271
|
+
) }),
|
|
2272
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: "Insert image" }) })
|
|
2273
|
+
] }),
|
|
2274
|
+
/* @__PURE__ */ jsx(
|
|
2275
|
+
"input",
|
|
2276
|
+
{
|
|
2277
|
+
ref: image_input_ref,
|
|
2278
|
+
type: "file",
|
|
2279
|
+
accept: "image/*",
|
|
2280
|
+
className: "hidden",
|
|
2281
|
+
onChange: handle_image_change
|
|
2282
|
+
}
|
|
2283
|
+
),
|
|
2284
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
2285
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
2286
|
+
Button,
|
|
2287
|
+
{
|
|
2288
|
+
variant: "ghost",
|
|
2289
|
+
size: "sm",
|
|
2290
|
+
className: "cls_toolbar_attach h-8 w-8 p-0",
|
|
2291
|
+
onClick: () => attachment_input_ref.current?.click(),
|
|
2292
|
+
disabled: is_uploading_attachment,
|
|
2293
|
+
children: /* @__PURE__ */ jsx(FiPaperclip, { className: "h-4 w-4" })
|
|
2294
|
+
}
|
|
2295
|
+
) }),
|
|
2296
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: "Add attachment" }) })
|
|
2297
|
+
] }),
|
|
2298
|
+
/* @__PURE__ */ jsx(
|
|
2299
|
+
"input",
|
|
2300
|
+
{
|
|
2301
|
+
ref: attachment_input_ref,
|
|
2302
|
+
type: "file",
|
|
2303
|
+
accept: "image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.zip,.rar",
|
|
2304
|
+
className: "hidden",
|
|
2305
|
+
onChange: handle_attachment_change
|
|
2306
|
+
}
|
|
2307
|
+
),
|
|
2308
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
2309
|
+
/* @__PURE__ */ jsxs(Popover, { open: is_table_popover_open, onOpenChange: set_is_table_popover_open, children: [
|
|
2310
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
2311
|
+
Button,
|
|
2312
|
+
{
|
|
2313
|
+
variant: "ghost",
|
|
2314
|
+
size: "sm",
|
|
2315
|
+
className: cn(
|
|
2316
|
+
"cls_toolbar_table h-8 w-8 p-0",
|
|
2317
|
+
editor.isActive("table") && "bg-accent text-accent-foreground"
|
|
2318
|
+
),
|
|
2319
|
+
children: /* @__PURE__ */ jsx(FiTable, { className: "h-4 w-4" })
|
|
2320
|
+
}
|
|
2321
|
+
) }),
|
|
2322
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_table_popover w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(
|
|
2323
|
+
TableSizePicker,
|
|
2324
|
+
{
|
|
2325
|
+
max_rows: 6,
|
|
2326
|
+
max_cols: 6,
|
|
2327
|
+
on_select: handle_insert_table
|
|
2328
|
+
}
|
|
2329
|
+
) })
|
|
2330
|
+
] }),
|
|
2331
|
+
is_in_table && /* @__PURE__ */ jsxs(Popover, { open: is_table_controls_open, onOpenChange: set_is_table_controls_open, children: [
|
|
2332
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", className: "cls_toolbar_table_controls h-8 gap-1 px-2", children: [
|
|
2333
|
+
/* @__PURE__ */ jsx(LuTableProperties, { className: "h-4 w-4" }),
|
|
2334
|
+
/* @__PURE__ */ jsx(FiChevronDown, { className: "h-3 w-3" })
|
|
2335
|
+
] }) }),
|
|
2336
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_table_controls_popover w-48 p-1", align: "start", children: /* @__PURE__ */ jsxs("div", { className: "cls_table_controls_list space-y-0.5", children: [
|
|
2337
|
+
/* @__PURE__ */ jsxs(
|
|
2338
|
+
Button,
|
|
2339
|
+
{
|
|
2340
|
+
variant: "ghost",
|
|
2341
|
+
size: "sm",
|
|
2342
|
+
className: "w-full justify-start",
|
|
2343
|
+
onClick: () => {
|
|
2344
|
+
editor.chain().focus().addRowAfter().run();
|
|
2345
|
+
set_is_table_controls_open(false);
|
|
2346
|
+
},
|
|
2347
|
+
children: [
|
|
2348
|
+
/* @__PURE__ */ jsx(RiInsertRowBottom, { className: "mr-2 h-4 w-4" }),
|
|
2349
|
+
"Add Row Below"
|
|
2350
|
+
]
|
|
2351
|
+
}
|
|
2352
|
+
),
|
|
2353
|
+
/* @__PURE__ */ jsxs(
|
|
2354
|
+
Button,
|
|
2355
|
+
{
|
|
2356
|
+
variant: "ghost",
|
|
2357
|
+
size: "sm",
|
|
2358
|
+
className: "w-full justify-start",
|
|
2359
|
+
onClick: () => {
|
|
2360
|
+
editor.chain().focus().addRowBefore().run();
|
|
2361
|
+
set_is_table_controls_open(false);
|
|
2362
|
+
},
|
|
2363
|
+
children: [
|
|
2364
|
+
/* @__PURE__ */ jsx(RiInsertRowBottom, { className: "mr-2 h-4 w-4 rotate-180" }),
|
|
2365
|
+
"Add Row Above"
|
|
2366
|
+
]
|
|
2367
|
+
}
|
|
2368
|
+
),
|
|
2369
|
+
/* @__PURE__ */ jsxs(
|
|
2370
|
+
Button,
|
|
2371
|
+
{
|
|
2372
|
+
variant: "ghost",
|
|
2373
|
+
size: "sm",
|
|
2374
|
+
className: "w-full justify-start",
|
|
2375
|
+
onClick: () => {
|
|
2376
|
+
editor.chain().focus().addColumnAfter().run();
|
|
2377
|
+
set_is_table_controls_open(false);
|
|
2378
|
+
},
|
|
2379
|
+
children: [
|
|
2380
|
+
/* @__PURE__ */ jsx(RiInsertColumnRight, { className: "mr-2 h-4 w-4" }),
|
|
2381
|
+
"Add Column Right"
|
|
2382
|
+
]
|
|
2383
|
+
}
|
|
2384
|
+
),
|
|
2385
|
+
/* @__PURE__ */ jsxs(
|
|
2386
|
+
Button,
|
|
2387
|
+
{
|
|
2388
|
+
variant: "ghost",
|
|
2389
|
+
size: "sm",
|
|
2390
|
+
className: "w-full justify-start",
|
|
2391
|
+
onClick: () => {
|
|
2392
|
+
editor.chain().focus().addColumnBefore().run();
|
|
2393
|
+
set_is_table_controls_open(false);
|
|
2394
|
+
},
|
|
2395
|
+
children: [
|
|
2396
|
+
/* @__PURE__ */ jsx(RiInsertColumnRight, { className: "mr-2 h-4 w-4 rotate-180" }),
|
|
2397
|
+
"Add Column Left"
|
|
2398
|
+
]
|
|
2399
|
+
}
|
|
2400
|
+
),
|
|
2401
|
+
/* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-border" }),
|
|
2402
|
+
/* @__PURE__ */ jsxs(
|
|
2403
|
+
Button,
|
|
2404
|
+
{
|
|
2405
|
+
variant: "ghost",
|
|
2406
|
+
size: "sm",
|
|
2407
|
+
className: "w-full justify-start text-destructive hover:text-destructive",
|
|
2408
|
+
onClick: () => {
|
|
2409
|
+
editor.chain().focus().deleteRow().run();
|
|
2410
|
+
set_is_table_controls_open(false);
|
|
2411
|
+
},
|
|
2412
|
+
children: [
|
|
2413
|
+
/* @__PURE__ */ jsx(RiDeleteRow, { className: "mr-2 h-4 w-4" }),
|
|
2414
|
+
"Delete Row"
|
|
2415
|
+
]
|
|
2416
|
+
}
|
|
2417
|
+
),
|
|
2418
|
+
/* @__PURE__ */ jsxs(
|
|
2419
|
+
Button,
|
|
2420
|
+
{
|
|
2421
|
+
variant: "ghost",
|
|
2422
|
+
size: "sm",
|
|
2423
|
+
className: "w-full justify-start text-destructive hover:text-destructive",
|
|
2424
|
+
onClick: () => {
|
|
2425
|
+
editor.chain().focus().deleteColumn().run();
|
|
2426
|
+
set_is_table_controls_open(false);
|
|
2427
|
+
},
|
|
2428
|
+
children: [
|
|
2429
|
+
/* @__PURE__ */ jsx(RiDeleteColumn, { className: "mr-2 h-4 w-4" }),
|
|
2430
|
+
"Delete Column"
|
|
2431
|
+
]
|
|
2432
|
+
}
|
|
2433
|
+
),
|
|
2434
|
+
/* @__PURE__ */ jsxs(
|
|
2435
|
+
Button,
|
|
2436
|
+
{
|
|
2437
|
+
variant: "ghost",
|
|
2438
|
+
size: "sm",
|
|
2439
|
+
className: "w-full justify-start text-destructive hover:text-destructive",
|
|
2440
|
+
onClick: () => {
|
|
2441
|
+
editor.chain().focus().deleteTable().run();
|
|
2442
|
+
set_is_table_controls_open(false);
|
|
2443
|
+
},
|
|
2444
|
+
children: [
|
|
2445
|
+
/* @__PURE__ */ jsx(FiTrash2, { className: "mr-2 h-4 w-4" }),
|
|
2446
|
+
"Delete Table"
|
|
2447
|
+
]
|
|
2448
|
+
}
|
|
2449
|
+
)
|
|
2450
|
+
] }) })
|
|
2451
|
+
] }),
|
|
2452
|
+
/* @__PURE__ */ jsx(
|
|
2453
|
+
ToolbarButton,
|
|
2454
|
+
{
|
|
2455
|
+
icon: /* @__PURE__ */ jsx(FiMinus, { className: "h-4 w-4" }),
|
|
2456
|
+
label: "Horizontal line",
|
|
2457
|
+
on_click: () => editor.chain().focus().setHorizontalRule().run()
|
|
2458
|
+
}
|
|
2459
|
+
),
|
|
2460
|
+
/* @__PURE__ */ jsxs(Popover, { open: is_columns_popover_open, onOpenChange: set_is_columns_popover_open, children: [
|
|
2461
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "cls_toolbar_columns h-8 w-8 p-0", children: /* @__PURE__ */ jsx(FiColumns, { className: "h-4 w-4" }) }) }),
|
|
2462
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_columns_popover w-36 p-1", align: "start", children: /* @__PURE__ */ jsxs("div", { className: "cls_columns_list space-y-0.5", children: [
|
|
2463
|
+
/* @__PURE__ */ jsxs(
|
|
2464
|
+
Button,
|
|
2465
|
+
{
|
|
2466
|
+
variant: "ghost",
|
|
2467
|
+
size: "sm",
|
|
2468
|
+
className: "w-full justify-start",
|
|
2469
|
+
onClick: () => {
|
|
2470
|
+
editor.chain().focus().insertColumnLayout(2).run();
|
|
2471
|
+
set_is_columns_popover_open(false);
|
|
2472
|
+
},
|
|
2473
|
+
children: [
|
|
2474
|
+
/* @__PURE__ */ jsx(LuColumns2, { className: "mr-2 h-4 w-4" }),
|
|
2475
|
+
"2 Columns"
|
|
2476
|
+
]
|
|
2477
|
+
}
|
|
2478
|
+
),
|
|
2479
|
+
/* @__PURE__ */ jsxs(
|
|
2480
|
+
Button,
|
|
2481
|
+
{
|
|
2482
|
+
variant: "ghost",
|
|
2483
|
+
size: "sm",
|
|
2484
|
+
className: "w-full justify-start",
|
|
2485
|
+
onClick: () => {
|
|
2486
|
+
editor.chain().focus().insertColumnLayout(3).run();
|
|
2487
|
+
set_is_columns_popover_open(false);
|
|
2488
|
+
},
|
|
2489
|
+
children: [
|
|
2490
|
+
/* @__PURE__ */ jsx(FiColumns, { className: "mr-2 h-4 w-4" }),
|
|
2491
|
+
"3 Columns"
|
|
2492
|
+
]
|
|
2493
|
+
}
|
|
2494
|
+
)
|
|
2495
|
+
] }) })
|
|
2496
|
+
] }),
|
|
2497
|
+
variables && variables.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2498
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
2499
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
2500
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
2501
|
+
Button,
|
|
2502
|
+
{
|
|
2503
|
+
variant: "ghost",
|
|
2504
|
+
size: "sm",
|
|
2505
|
+
onClick: on_open_variables_modal,
|
|
2506
|
+
className: "cls_toolbar_variables h-8 gap-1 px-2",
|
|
2507
|
+
children: [
|
|
2508
|
+
/* @__PURE__ */ jsx(BiBracket, { className: "h-4 w-4" }),
|
|
2509
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs", children: "Variables" })
|
|
2510
|
+
]
|
|
2511
|
+
}
|
|
2512
|
+
) }),
|
|
2513
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: "Insert variable" }) })
|
|
2514
|
+
] })
|
|
2515
|
+
] }),
|
|
2516
|
+
/* @__PURE__ */ jsx(ToolbarDivider, {}),
|
|
2517
|
+
/* @__PURE__ */ jsx(
|
|
2518
|
+
ToolbarButton,
|
|
2519
|
+
{
|
|
2520
|
+
icon: /* @__PURE__ */ jsx(MdFormatClear, { className: "h-4 w-4" }),
|
|
2521
|
+
label: "Clear formatting",
|
|
2522
|
+
on_click: () => editor.chain().focus().unsetAllMarks().clearNodes().run()
|
|
2523
|
+
}
|
|
2524
|
+
)
|
|
2525
|
+
] }) });
|
|
2526
|
+
}
|
|
2527
|
+
var Tabs = TabsPrimitive.Root;
|
|
2528
|
+
var TabsList = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2529
|
+
TabsPrimitive.List,
|
|
2530
|
+
{
|
|
2531
|
+
ref,
|
|
2532
|
+
className: cn(
|
|
2533
|
+
"cls_tabs_list inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
|
|
2534
|
+
className
|
|
2535
|
+
),
|
|
2536
|
+
...props
|
|
2537
|
+
}
|
|
2538
|
+
));
|
|
2539
|
+
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
2540
|
+
var TabsTrigger = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2541
|
+
TabsPrimitive.Trigger,
|
|
2542
|
+
{
|
|
2543
|
+
ref,
|
|
2544
|
+
className: cn(
|
|
2545
|
+
"cls_tabs_trigger inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
2546
|
+
className
|
|
2547
|
+
),
|
|
2548
|
+
...props
|
|
2549
|
+
}
|
|
2550
|
+
));
|
|
2551
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
2552
|
+
var TabsContent = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2553
|
+
TabsPrimitive.Content,
|
|
2554
|
+
{
|
|
2555
|
+
ref,
|
|
2556
|
+
className: cn(
|
|
2557
|
+
"cls_tabs_content mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
2558
|
+
className
|
|
2559
|
+
),
|
|
2560
|
+
...props
|
|
2561
|
+
}
|
|
2562
|
+
));
|
|
2563
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
2564
|
+
function HtmlView({
|
|
2565
|
+
html_content,
|
|
2566
|
+
on_html_change,
|
|
2567
|
+
html_view_mode,
|
|
2568
|
+
on_html_view_mode_change,
|
|
2569
|
+
min_height,
|
|
2570
|
+
max_height,
|
|
2571
|
+
read_only
|
|
2572
|
+
}) {
|
|
2573
|
+
return /* @__PURE__ */ jsxs("div", { className: "cls_html_view", children: [
|
|
2574
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_html_view_toggle flex items-center gap-1 p-2 border-b border-border bg-muted/30", children: [
|
|
2575
|
+
/* @__PURE__ */ jsxs(
|
|
2576
|
+
Button,
|
|
2577
|
+
{
|
|
2578
|
+
variant: html_view_mode === "preview" ? "secondary" : "ghost",
|
|
2579
|
+
size: "sm",
|
|
2580
|
+
onClick: () => on_html_view_mode_change("preview"),
|
|
2581
|
+
className: "h-7 gap-1 px-2",
|
|
2582
|
+
children: [
|
|
2583
|
+
/* @__PURE__ */ jsx(FiEye, { className: "h-3.5 w-3.5" }),
|
|
2584
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs", children: "Preview" })
|
|
2585
|
+
]
|
|
2586
|
+
}
|
|
2587
|
+
),
|
|
2588
|
+
/* @__PURE__ */ jsxs(
|
|
2589
|
+
Button,
|
|
2590
|
+
{
|
|
2591
|
+
variant: html_view_mode === "code" ? "secondary" : "ghost",
|
|
2592
|
+
size: "sm",
|
|
2593
|
+
onClick: () => on_html_view_mode_change("code"),
|
|
2594
|
+
className: "h-7 gap-1 px-2",
|
|
2595
|
+
children: [
|
|
2596
|
+
/* @__PURE__ */ jsx(FiCode, { className: "h-3.5 w-3.5" }),
|
|
2597
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs", children: "Code" })
|
|
2598
|
+
]
|
|
2599
|
+
}
|
|
2600
|
+
)
|
|
2601
|
+
] }),
|
|
2602
|
+
/* @__PURE__ */ jsx(
|
|
2603
|
+
"div",
|
|
2604
|
+
{
|
|
2605
|
+
className: "cls_html_view_content overflow-auto",
|
|
2606
|
+
style: {
|
|
2607
|
+
minHeight: min_height || DEFAULT_MIN_HEIGHT,
|
|
2608
|
+
maxHeight: max_height || DEFAULT_MAX_HEIGHT
|
|
2609
|
+
},
|
|
2610
|
+
children: html_view_mode === "preview" ? /* @__PURE__ */ jsx(
|
|
2611
|
+
"div",
|
|
2612
|
+
{
|
|
2613
|
+
className: "cls_html_preview prose prose-sm max-w-none p-4",
|
|
2614
|
+
dangerouslySetInnerHTML: { __html: html_content }
|
|
2615
|
+
}
|
|
2616
|
+
) : /* @__PURE__ */ jsx(
|
|
2617
|
+
"textarea",
|
|
2618
|
+
{
|
|
2619
|
+
value: html_content,
|
|
2620
|
+
onChange: (e) => on_html_change(e.target.value),
|
|
2621
|
+
readOnly: read_only,
|
|
2622
|
+
className: cn(
|
|
2623
|
+
"cls_html_code w-full h-full p-4 font-mono text-sm",
|
|
2624
|
+
"bg-muted/20 resize-none border-none outline-none",
|
|
2625
|
+
"focus:ring-0"
|
|
2626
|
+
),
|
|
2627
|
+
style: {
|
|
2628
|
+
minHeight: min_height || DEFAULT_MIN_HEIGHT
|
|
2629
|
+
},
|
|
2630
|
+
spellCheck: false
|
|
2631
|
+
}
|
|
2632
|
+
)
|
|
2633
|
+
}
|
|
2634
|
+
)
|
|
2635
|
+
] });
|
|
2636
|
+
}
|
|
2637
|
+
function TextView({
|
|
2638
|
+
text_content,
|
|
2639
|
+
on_text_change,
|
|
2640
|
+
min_height,
|
|
2641
|
+
max_height,
|
|
2642
|
+
read_only
|
|
2643
|
+
}) {
|
|
2644
|
+
return /* @__PURE__ */ jsx(
|
|
2645
|
+
"div",
|
|
2646
|
+
{
|
|
2647
|
+
className: "cls_text_view overflow-auto",
|
|
2648
|
+
style: {
|
|
2649
|
+
minHeight: min_height || DEFAULT_MIN_HEIGHT,
|
|
2650
|
+
maxHeight: max_height || DEFAULT_MAX_HEIGHT
|
|
2651
|
+
},
|
|
2652
|
+
children: /* @__PURE__ */ jsx(
|
|
2653
|
+
"textarea",
|
|
2654
|
+
{
|
|
2655
|
+
value: text_content,
|
|
2656
|
+
onChange: (e) => on_text_change(e.target.value),
|
|
2657
|
+
readOnly: read_only,
|
|
2658
|
+
className: cn(
|
|
2659
|
+
"cls_text_area w-full h-full p-4 text-sm",
|
|
2660
|
+
"bg-background resize-none border-none outline-none",
|
|
2661
|
+
"focus:ring-0"
|
|
2662
|
+
),
|
|
2663
|
+
style: {
|
|
2664
|
+
minHeight: min_height || DEFAULT_MIN_HEIGHT
|
|
2665
|
+
},
|
|
2666
|
+
spellCheck: true
|
|
2667
|
+
}
|
|
2668
|
+
)
|
|
2669
|
+
}
|
|
2670
|
+
);
|
|
2671
|
+
}
|
|
2672
|
+
function VisualView({ children, min_height, max_height }) {
|
|
2673
|
+
return /* @__PURE__ */ jsx(
|
|
2674
|
+
"div",
|
|
2675
|
+
{
|
|
2676
|
+
className: "cls_visual_view overflow-auto",
|
|
2677
|
+
style: {
|
|
2678
|
+
minHeight: min_height || DEFAULT_MIN_HEIGHT,
|
|
2679
|
+
maxHeight: max_height || DEFAULT_MAX_HEIGHT
|
|
2680
|
+
},
|
|
2681
|
+
children
|
|
2682
|
+
}
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
function ViewTabs({
|
|
2686
|
+
active_tab,
|
|
2687
|
+
on_tab_change,
|
|
2688
|
+
// editor is unused but kept in props interface for consistency
|
|
2689
|
+
html_content,
|
|
2690
|
+
text_content,
|
|
2691
|
+
on_html_change,
|
|
2692
|
+
on_text_change,
|
|
2693
|
+
html_view_mode,
|
|
2694
|
+
on_html_view_mode_change,
|
|
2695
|
+
min_height,
|
|
2696
|
+
max_height,
|
|
2697
|
+
read_only,
|
|
2698
|
+
children
|
|
2699
|
+
}) {
|
|
2700
|
+
return /* @__PURE__ */ jsxs(
|
|
2701
|
+
Tabs,
|
|
2702
|
+
{
|
|
2703
|
+
value: active_tab,
|
|
2704
|
+
onValueChange: (value) => on_tab_change(value),
|
|
2705
|
+
className: "cls_view_tabs",
|
|
2706
|
+
children: [
|
|
2707
|
+
/* @__PURE__ */ jsx("div", { className: "cls_view_tabs_header flex items-center justify-between border-b border-border", children: /* @__PURE__ */ jsxs(TabsList, { className: "cls_view_tabs_list h-9 bg-transparent p-0 border-none rounded-none", children: [
|
|
2708
|
+
/* @__PURE__ */ jsx(
|
|
2709
|
+
TabsTrigger,
|
|
2710
|
+
{
|
|
2711
|
+
value: "visual",
|
|
2712
|
+
className: cn(
|
|
2713
|
+
"cls_view_tab_trigger rounded-none border-b-2 border-transparent px-4 py-2",
|
|
2714
|
+
"data-[state=active]:border-primary data-[state=active]:bg-transparent"
|
|
2715
|
+
),
|
|
2716
|
+
children: "Visual"
|
|
2717
|
+
}
|
|
2718
|
+
),
|
|
2719
|
+
/* @__PURE__ */ jsx(
|
|
2720
|
+
TabsTrigger,
|
|
2721
|
+
{
|
|
2722
|
+
value: "html",
|
|
2723
|
+
className: cn(
|
|
2724
|
+
"cls_view_tab_trigger rounded-none border-b-2 border-transparent px-4 py-2",
|
|
2725
|
+
"data-[state=active]:border-primary data-[state=active]:bg-transparent"
|
|
2726
|
+
),
|
|
2727
|
+
children: "HTML"
|
|
2728
|
+
}
|
|
2729
|
+
),
|
|
2730
|
+
/* @__PURE__ */ jsx(
|
|
2731
|
+
TabsTrigger,
|
|
2732
|
+
{
|
|
2733
|
+
value: "text",
|
|
2734
|
+
className: cn(
|
|
2735
|
+
"cls_view_tab_trigger rounded-none border-b-2 border-transparent px-4 py-2",
|
|
2736
|
+
"data-[state=active]:border-primary data-[state=active]:bg-transparent"
|
|
2737
|
+
),
|
|
2738
|
+
children: "Text"
|
|
2739
|
+
}
|
|
2740
|
+
)
|
|
2741
|
+
] }) }),
|
|
2742
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "visual", className: "cls_view_tab_content mt-0", children: /* @__PURE__ */ jsx(VisualView, { min_height, max_height, children }) }),
|
|
2743
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "html", className: "cls_view_tab_content mt-0", children: /* @__PURE__ */ jsx(
|
|
2744
|
+
HtmlView,
|
|
2745
|
+
{
|
|
2746
|
+
html_content,
|
|
2747
|
+
on_html_change,
|
|
2748
|
+
html_view_mode,
|
|
2749
|
+
on_html_view_mode_change,
|
|
2750
|
+
min_height,
|
|
2751
|
+
max_height,
|
|
2752
|
+
read_only
|
|
2753
|
+
}
|
|
2754
|
+
) }),
|
|
2755
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "text", className: "cls_view_tab_content mt-0", children: /* @__PURE__ */ jsx(
|
|
2756
|
+
TextView,
|
|
2757
|
+
{
|
|
2758
|
+
text_content,
|
|
2759
|
+
on_text_change,
|
|
2760
|
+
min_height,
|
|
2761
|
+
max_height,
|
|
2762
|
+
read_only
|
|
2763
|
+
}
|
|
2764
|
+
) })
|
|
2765
|
+
]
|
|
2766
|
+
}
|
|
2767
|
+
);
|
|
2768
|
+
}
|
|
2769
|
+
var ScrollArea = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2770
|
+
ScrollAreaPrimitive.Root,
|
|
2771
|
+
{
|
|
2772
|
+
ref,
|
|
2773
|
+
className: cn("cls_scroll_area relative overflow-hidden", className),
|
|
2774
|
+
...props,
|
|
2775
|
+
children: [
|
|
2776
|
+
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
2777
|
+
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
2778
|
+
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
|
|
2779
|
+
]
|
|
2780
|
+
}
|
|
2781
|
+
));
|
|
2782
|
+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
2783
|
+
var ScrollBar = React14.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2784
|
+
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
2785
|
+
{
|
|
2786
|
+
ref,
|
|
2787
|
+
orientation,
|
|
2788
|
+
className: cn(
|
|
2789
|
+
"cls_scroll_bar flex touch-none select-none transition-colors",
|
|
2790
|
+
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
2791
|
+
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
2792
|
+
className
|
|
2793
|
+
),
|
|
2794
|
+
...props,
|
|
2795
|
+
children: /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaThumb, { className: "cls_scroll_thumb relative flex-1 rounded-full bg-border" })
|
|
2796
|
+
}
|
|
2797
|
+
));
|
|
2798
|
+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
2799
|
+
function group_variables_by_category(variables) {
|
|
2800
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
2801
|
+
for (const variable of variables) {
|
|
2802
|
+
const category = variable.category || "General";
|
|
2803
|
+
const existing = grouped.get(category) || [];
|
|
2804
|
+
grouped.set(category, [...existing, variable]);
|
|
2805
|
+
}
|
|
2806
|
+
return grouped;
|
|
2807
|
+
}
|
|
2808
|
+
function VariablesModal({
|
|
2809
|
+
is_open,
|
|
2810
|
+
on_close,
|
|
2811
|
+
variables,
|
|
2812
|
+
on_select_variable
|
|
2813
|
+
}) {
|
|
2814
|
+
const [search_query, set_search_query] = React14.useState("");
|
|
2815
|
+
const filtered_variables = React14.useMemo(() => {
|
|
2816
|
+
if (!search_query.trim()) {
|
|
2817
|
+
return variables;
|
|
2818
|
+
}
|
|
2819
|
+
const query = search_query.toLowerCase();
|
|
2820
|
+
return variables.filter(
|
|
2821
|
+
(v) => v.text.toLowerCase().includes(query) || v.description.toLowerCase().includes(query) || v.category && v.category.toLowerCase().includes(query)
|
|
2822
|
+
);
|
|
2823
|
+
}, [variables, search_query]);
|
|
2824
|
+
const grouped_variables = React14.useMemo(
|
|
2825
|
+
() => group_variables_by_category(filtered_variables),
|
|
2826
|
+
[filtered_variables]
|
|
2827
|
+
);
|
|
2828
|
+
const handle_select = (variable) => {
|
|
2829
|
+
on_select_variable(variable);
|
|
2830
|
+
on_close();
|
|
2831
|
+
set_search_query("");
|
|
2832
|
+
};
|
|
2833
|
+
React14.useEffect(() => {
|
|
2834
|
+
if (!is_open) {
|
|
2835
|
+
set_search_query("");
|
|
2836
|
+
}
|
|
2837
|
+
}, [is_open]);
|
|
2838
|
+
return /* @__PURE__ */ jsx(Dialog, { open: is_open, onOpenChange: (open) => !open && on_close(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "cls_variables_modal sm:max-w-md", children: [
|
|
2839
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
2840
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Insert Variable" }),
|
|
2841
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: "Select a variable to insert into the editor. Variables will be replaced with actual values when the content is processed." })
|
|
2842
|
+
] }),
|
|
2843
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_variables_modal_search relative", children: [
|
|
2844
|
+
/* @__PURE__ */ jsx(FiSearch, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
|
|
2845
|
+
/* @__PURE__ */ jsx(
|
|
2846
|
+
Input,
|
|
2847
|
+
{
|
|
2848
|
+
placeholder: "Search variables...",
|
|
2849
|
+
value: search_query,
|
|
2850
|
+
onChange: (e) => set_search_query(e.target.value),
|
|
2851
|
+
className: "pl-9"
|
|
2852
|
+
}
|
|
2853
|
+
)
|
|
2854
|
+
] }),
|
|
2855
|
+
/* @__PURE__ */ jsx(ScrollArea, { className: "cls_variables_modal_list h-[300px] pr-4", children: filtered_variables.length === 0 ? /* @__PURE__ */ jsx("div", { className: "cls_variables_modal_empty py-8 text-center text-muted-foreground", children: "No variables found" }) : /* @__PURE__ */ jsx("div", { className: "cls_variables_modal_groups space-y-4", children: Array.from(grouped_variables.entries()).map(([category, vars]) => /* @__PURE__ */ jsxs("div", { className: "cls_variables_modal_group", children: [
|
|
2856
|
+
/* @__PURE__ */ jsx("h4", { className: "cls_variables_modal_category mb-2 text-sm font-medium text-muted-foreground", children: category }),
|
|
2857
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: vars.map((variable) => /* @__PURE__ */ jsxs(
|
|
2858
|
+
"button",
|
|
2859
|
+
{
|
|
2860
|
+
onClick: () => handle_select(variable),
|
|
2861
|
+
className: cn(
|
|
2862
|
+
"cls_variable_item w-full text-left px-3 py-2 rounded-md",
|
|
2863
|
+
"hover:bg-accent transition-colors",
|
|
2864
|
+
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
|
|
2865
|
+
),
|
|
2866
|
+
children: [
|
|
2867
|
+
/* @__PURE__ */ jsx("div", { className: "cls_variable_item_name font-mono text-sm text-primary", children: `{{${variable.text}}}` }),
|
|
2868
|
+
/* @__PURE__ */ jsx("div", { className: "cls_variable_item_description text-xs text-muted-foreground mt-0.5", children: variable.description })
|
|
2869
|
+
]
|
|
2870
|
+
},
|
|
2871
|
+
variable.text
|
|
2872
|
+
)) })
|
|
2873
|
+
] }, category)) }) })
|
|
2874
|
+
] }) });
|
|
2875
|
+
}
|
|
2876
|
+
var __defProp = Object.defineProperty;
|
|
2877
|
+
var __export = (target, all) => {
|
|
2878
|
+
for (var name in all)
|
|
2879
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
2880
|
+
};
|
|
2881
|
+
function createChainableState(config) {
|
|
2882
|
+
const { state, transaction } = config;
|
|
2883
|
+
let { selection } = transaction;
|
|
2884
|
+
let { doc } = transaction;
|
|
2885
|
+
let { storedMarks } = transaction;
|
|
2886
|
+
return {
|
|
2887
|
+
...state,
|
|
2888
|
+
apply: state.apply.bind(state),
|
|
2889
|
+
applyTransaction: state.applyTransaction.bind(state),
|
|
2890
|
+
plugins: state.plugins,
|
|
2891
|
+
schema: state.schema,
|
|
2892
|
+
reconfigure: state.reconfigure.bind(state),
|
|
2893
|
+
toJSON: state.toJSON.bind(state),
|
|
2894
|
+
get storedMarks() {
|
|
2895
|
+
return storedMarks;
|
|
2896
|
+
},
|
|
2897
|
+
get selection() {
|
|
2898
|
+
return selection;
|
|
2899
|
+
},
|
|
2900
|
+
get doc() {
|
|
2901
|
+
return doc;
|
|
2902
|
+
},
|
|
2903
|
+
get tr() {
|
|
2904
|
+
selection = transaction.selection;
|
|
2905
|
+
doc = transaction.doc;
|
|
2906
|
+
storedMarks = transaction.storedMarks;
|
|
2907
|
+
return transaction;
|
|
2908
|
+
}
|
|
2909
|
+
};
|
|
2910
|
+
}
|
|
2911
|
+
var CommandManager = class {
|
|
2912
|
+
constructor(props) {
|
|
2913
|
+
this.editor = props.editor;
|
|
2914
|
+
this.rawCommands = this.editor.extensionManager.commands;
|
|
2915
|
+
this.customState = props.state;
|
|
2916
|
+
}
|
|
2917
|
+
get hasCustomState() {
|
|
2918
|
+
return !!this.customState;
|
|
2919
|
+
}
|
|
2920
|
+
get state() {
|
|
2921
|
+
return this.customState || this.editor.state;
|
|
2922
|
+
}
|
|
2923
|
+
get commands() {
|
|
2924
|
+
const { rawCommands, editor, state } = this;
|
|
2925
|
+
const { view } = editor;
|
|
2926
|
+
const { tr } = state;
|
|
2927
|
+
const props = this.buildProps(tr);
|
|
2928
|
+
return Object.fromEntries(
|
|
2929
|
+
Object.entries(rawCommands).map(([name, command2]) => {
|
|
2930
|
+
const method = (...args) => {
|
|
2931
|
+
const callback = command2(...args)(props);
|
|
2932
|
+
if (!tr.getMeta("preventDispatch") && !this.hasCustomState) {
|
|
2933
|
+
view.dispatch(tr);
|
|
2934
|
+
}
|
|
2935
|
+
return callback;
|
|
2936
|
+
};
|
|
2937
|
+
return [name, method];
|
|
2938
|
+
})
|
|
2939
|
+
);
|
|
2940
|
+
}
|
|
2941
|
+
get chain() {
|
|
2942
|
+
return () => this.createChain();
|
|
2943
|
+
}
|
|
2944
|
+
get can() {
|
|
2945
|
+
return () => this.createCan();
|
|
2946
|
+
}
|
|
2947
|
+
createChain(startTr, shouldDispatch = true) {
|
|
2948
|
+
const { rawCommands, editor, state } = this;
|
|
2949
|
+
const { view } = editor;
|
|
2950
|
+
const callbacks = [];
|
|
2951
|
+
const hasStartTransaction = !!startTr;
|
|
2952
|
+
const tr = startTr || state.tr;
|
|
2953
|
+
const run3 = () => {
|
|
2954
|
+
if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) {
|
|
2955
|
+
view.dispatch(tr);
|
|
2956
|
+
}
|
|
2957
|
+
return callbacks.every((callback) => callback === true);
|
|
2958
|
+
};
|
|
2959
|
+
const chain = {
|
|
2960
|
+
...Object.fromEntries(
|
|
2961
|
+
Object.entries(rawCommands).map(([name, command2]) => {
|
|
2962
|
+
const chainedCommand = (...args) => {
|
|
2963
|
+
const props = this.buildProps(tr, shouldDispatch);
|
|
2964
|
+
const callback = command2(...args)(props);
|
|
2965
|
+
callbacks.push(callback);
|
|
2966
|
+
return chain;
|
|
2967
|
+
};
|
|
2968
|
+
return [name, chainedCommand];
|
|
2969
|
+
})
|
|
2970
|
+
),
|
|
2971
|
+
run: run3
|
|
2972
|
+
};
|
|
2973
|
+
return chain;
|
|
2974
|
+
}
|
|
2975
|
+
createCan(startTr) {
|
|
2976
|
+
const { rawCommands, state } = this;
|
|
2977
|
+
const dispatch = false;
|
|
2978
|
+
const tr = startTr || state.tr;
|
|
2979
|
+
const props = this.buildProps(tr, dispatch);
|
|
2980
|
+
const formattedCommands = Object.fromEntries(
|
|
2981
|
+
Object.entries(rawCommands).map(([name, command2]) => {
|
|
2982
|
+
return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
|
|
2983
|
+
})
|
|
2984
|
+
);
|
|
2985
|
+
return {
|
|
2986
|
+
...formattedCommands,
|
|
2987
|
+
chain: () => this.createChain(tr, dispatch)
|
|
2988
|
+
};
|
|
2989
|
+
}
|
|
2990
|
+
buildProps(tr, shouldDispatch = true) {
|
|
2991
|
+
const { rawCommands, editor, state } = this;
|
|
2992
|
+
const { view } = editor;
|
|
2993
|
+
const props = {
|
|
2994
|
+
tr,
|
|
2995
|
+
editor,
|
|
2996
|
+
view,
|
|
2997
|
+
state: createChainableState({
|
|
2998
|
+
state,
|
|
2999
|
+
transaction: tr
|
|
3000
|
+
}),
|
|
3001
|
+
dispatch: shouldDispatch ? () => void 0 : void 0,
|
|
3002
|
+
chain: () => this.createChain(tr, shouldDispatch),
|
|
3003
|
+
can: () => this.createCan(tr),
|
|
3004
|
+
get commands() {
|
|
3005
|
+
return Object.fromEntries(
|
|
3006
|
+
Object.entries(rawCommands).map(([name, command2]) => {
|
|
3007
|
+
return [name, (...args) => command2(...args)(props)];
|
|
3008
|
+
})
|
|
3009
|
+
);
|
|
3010
|
+
}
|
|
3011
|
+
};
|
|
3012
|
+
return props;
|
|
3013
|
+
}
|
|
3014
|
+
};
|
|
3015
|
+
var commands_exports = {};
|
|
3016
|
+
__export(commands_exports, {
|
|
3017
|
+
blur: () => blur,
|
|
3018
|
+
clearContent: () => clearContent,
|
|
3019
|
+
clearNodes: () => clearNodes,
|
|
3020
|
+
command: () => command,
|
|
3021
|
+
createParagraphNear: () => createParagraphNear,
|
|
3022
|
+
cut: () => cut,
|
|
3023
|
+
deleteCurrentNode: () => deleteCurrentNode,
|
|
3024
|
+
deleteNode: () => deleteNode,
|
|
3025
|
+
deleteRange: () => deleteRange,
|
|
3026
|
+
deleteSelection: () => deleteSelection,
|
|
3027
|
+
enter: () => enter,
|
|
3028
|
+
exitCode: () => exitCode,
|
|
3029
|
+
extendMarkRange: () => extendMarkRange,
|
|
3030
|
+
first: () => first,
|
|
3031
|
+
focus: () => focus,
|
|
3032
|
+
forEach: () => forEach,
|
|
3033
|
+
insertContent: () => insertContent,
|
|
3034
|
+
insertContentAt: () => insertContentAt,
|
|
3035
|
+
joinBackward: () => joinBackward,
|
|
3036
|
+
joinDown: () => joinDown,
|
|
3037
|
+
joinForward: () => joinForward,
|
|
3038
|
+
joinItemBackward: () => joinItemBackward,
|
|
3039
|
+
joinItemForward: () => joinItemForward,
|
|
3040
|
+
joinTextblockBackward: () => joinTextblockBackward,
|
|
3041
|
+
joinTextblockForward: () => joinTextblockForward,
|
|
3042
|
+
joinUp: () => joinUp,
|
|
3043
|
+
keyboardShortcut: () => keyboardShortcut,
|
|
3044
|
+
lift: () => lift,
|
|
3045
|
+
liftEmptyBlock: () => liftEmptyBlock,
|
|
3046
|
+
liftListItem: () => liftListItem,
|
|
3047
|
+
newlineInCode: () => newlineInCode,
|
|
3048
|
+
resetAttributes: () => resetAttributes,
|
|
3049
|
+
scrollIntoView: () => scrollIntoView,
|
|
3050
|
+
selectAll: () => selectAll,
|
|
3051
|
+
selectNodeBackward: () => selectNodeBackward,
|
|
3052
|
+
selectNodeForward: () => selectNodeForward,
|
|
3053
|
+
selectParentNode: () => selectParentNode,
|
|
3054
|
+
selectTextblockEnd: () => selectTextblockEnd,
|
|
3055
|
+
selectTextblockStart: () => selectTextblockStart,
|
|
3056
|
+
setContent: () => setContent,
|
|
3057
|
+
setMark: () => setMark,
|
|
3058
|
+
setMeta: () => setMeta,
|
|
3059
|
+
setNode: () => setNode,
|
|
3060
|
+
setNodeSelection: () => setNodeSelection,
|
|
3061
|
+
setTextDirection: () => setTextDirection,
|
|
3062
|
+
setTextSelection: () => setTextSelection,
|
|
3063
|
+
sinkListItem: () => sinkListItem,
|
|
3064
|
+
splitBlock: () => splitBlock,
|
|
3065
|
+
splitListItem: () => splitListItem,
|
|
3066
|
+
toggleList: () => toggleList,
|
|
3067
|
+
toggleMark: () => toggleMark,
|
|
3068
|
+
toggleNode: () => toggleNode,
|
|
3069
|
+
toggleWrap: () => toggleWrap,
|
|
3070
|
+
undoInputRule: () => undoInputRule,
|
|
3071
|
+
unsetAllMarks: () => unsetAllMarks,
|
|
3072
|
+
unsetMark: () => unsetMark,
|
|
3073
|
+
unsetTextDirection: () => unsetTextDirection,
|
|
3074
|
+
updateAttributes: () => updateAttributes,
|
|
3075
|
+
wrapIn: () => wrapIn,
|
|
3076
|
+
wrapInList: () => wrapInList
|
|
3077
|
+
});
|
|
3078
|
+
var blur = () => ({ editor, view }) => {
|
|
3079
|
+
requestAnimationFrame(() => {
|
|
3080
|
+
var _a;
|
|
3081
|
+
if (!editor.isDestroyed) {
|
|
3082
|
+
view.dom.blur();
|
|
3083
|
+
(_a = window == null ? void 0 : window.getSelection()) == null ? void 0 : _a.removeAllRanges();
|
|
3084
|
+
}
|
|
3085
|
+
});
|
|
3086
|
+
return true;
|
|
3087
|
+
};
|
|
3088
|
+
var clearContent = (emitUpdate = true) => ({ commands }) => {
|
|
3089
|
+
return commands.setContent("", { emitUpdate });
|
|
3090
|
+
};
|
|
3091
|
+
var clearNodes = () => ({ state, tr, dispatch }) => {
|
|
3092
|
+
const { selection } = tr;
|
|
3093
|
+
const { ranges } = selection;
|
|
3094
|
+
if (!dispatch) {
|
|
3095
|
+
return true;
|
|
3096
|
+
}
|
|
3097
|
+
ranges.forEach(({ $from, $to }) => {
|
|
3098
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
3099
|
+
if (node.type.isText) {
|
|
3100
|
+
return;
|
|
3101
|
+
}
|
|
3102
|
+
const { doc, mapping } = tr;
|
|
3103
|
+
const $mappedFrom = doc.resolve(mapping.map(pos));
|
|
3104
|
+
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
|
|
3105
|
+
const nodeRange = $mappedFrom.blockRange($mappedTo);
|
|
3106
|
+
if (!nodeRange) {
|
|
3107
|
+
return;
|
|
3108
|
+
}
|
|
3109
|
+
const targetLiftDepth = liftTarget(nodeRange);
|
|
3110
|
+
if (node.type.isTextblock) {
|
|
3111
|
+
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
|
|
3112
|
+
tr.setNodeMarkup(nodeRange.start, defaultType);
|
|
3113
|
+
}
|
|
3114
|
+
if (targetLiftDepth || targetLiftDepth === 0) {
|
|
3115
|
+
tr.lift(nodeRange, targetLiftDepth);
|
|
3116
|
+
}
|
|
3117
|
+
});
|
|
3118
|
+
});
|
|
3119
|
+
return true;
|
|
3120
|
+
};
|
|
3121
|
+
var command = (fn) => (props) => {
|
|
3122
|
+
return fn(props);
|
|
3123
|
+
};
|
|
3124
|
+
var createParagraphNear = () => ({ state, dispatch }) => {
|
|
3125
|
+
return createParagraphNear$1(state, dispatch);
|
|
3126
|
+
};
|
|
3127
|
+
var cut = (originRange, targetPos) => ({ editor, tr }) => {
|
|
3128
|
+
const { state } = editor;
|
|
3129
|
+
const contentSlice = state.doc.slice(originRange.from, originRange.to);
|
|
3130
|
+
tr.deleteRange(originRange.from, originRange.to);
|
|
3131
|
+
const newPos = tr.mapping.map(targetPos);
|
|
3132
|
+
tr.insert(newPos, contentSlice.content);
|
|
3133
|
+
tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
|
|
3134
|
+
return true;
|
|
3135
|
+
};
|
|
3136
|
+
var deleteCurrentNode = () => ({ tr, dispatch }) => {
|
|
3137
|
+
const { selection } = tr;
|
|
3138
|
+
const currentNode = selection.$anchor.node();
|
|
3139
|
+
if (currentNode.content.size > 0) {
|
|
3140
|
+
return false;
|
|
3141
|
+
}
|
|
3142
|
+
const $pos = tr.selection.$anchor;
|
|
3143
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
3144
|
+
const node = $pos.node(depth);
|
|
3145
|
+
if (node.type === currentNode.type) {
|
|
3146
|
+
if (dispatch) {
|
|
3147
|
+
const from = $pos.before(depth);
|
|
3148
|
+
const to = $pos.after(depth);
|
|
3149
|
+
tr.delete(from, to).scrollIntoView();
|
|
3150
|
+
}
|
|
3151
|
+
return true;
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
return false;
|
|
3155
|
+
};
|
|
3156
|
+
function getNodeType(nameOrType, schema) {
|
|
3157
|
+
if (typeof nameOrType === "string") {
|
|
3158
|
+
if (!schema.nodes[nameOrType]) {
|
|
3159
|
+
throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
3160
|
+
}
|
|
3161
|
+
return schema.nodes[nameOrType];
|
|
3162
|
+
}
|
|
3163
|
+
return nameOrType;
|
|
3164
|
+
}
|
|
3165
|
+
var deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
|
|
3166
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
3167
|
+
const $pos = tr.selection.$anchor;
|
|
3168
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
3169
|
+
const node = $pos.node(depth);
|
|
3170
|
+
if (node.type === type) {
|
|
3171
|
+
if (dispatch) {
|
|
3172
|
+
const from = $pos.before(depth);
|
|
3173
|
+
const to = $pos.after(depth);
|
|
3174
|
+
tr.delete(from, to).scrollIntoView();
|
|
3175
|
+
}
|
|
3176
|
+
return true;
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
return false;
|
|
3180
|
+
};
|
|
3181
|
+
var deleteRange = (range) => ({ tr, dispatch }) => {
|
|
3182
|
+
const { from, to } = range;
|
|
3183
|
+
if (dispatch) {
|
|
3184
|
+
tr.delete(from, to);
|
|
3185
|
+
}
|
|
3186
|
+
return true;
|
|
3187
|
+
};
|
|
3188
|
+
var deleteSelection = () => ({ state, dispatch }) => {
|
|
3189
|
+
return deleteSelection$1(state, dispatch);
|
|
3190
|
+
};
|
|
3191
|
+
var enter = () => ({ commands }) => {
|
|
3192
|
+
return commands.keyboardShortcut("Enter");
|
|
3193
|
+
};
|
|
3194
|
+
var exitCode = () => ({ state, dispatch }) => {
|
|
3195
|
+
return exitCode$1(state, dispatch);
|
|
3196
|
+
};
|
|
3197
|
+
function isRegExp(value) {
|
|
3198
|
+
return Object.prototype.toString.call(value) === "[object RegExp]";
|
|
3199
|
+
}
|
|
3200
|
+
function objectIncludes(object1, object2, options = { strict: true }) {
|
|
3201
|
+
const keys = Object.keys(object2);
|
|
3202
|
+
if (!keys.length) {
|
|
3203
|
+
return true;
|
|
3204
|
+
}
|
|
3205
|
+
return keys.every((key) => {
|
|
3206
|
+
if (options.strict) {
|
|
3207
|
+
return object2[key] === object1[key];
|
|
3208
|
+
}
|
|
3209
|
+
if (isRegExp(object2[key])) {
|
|
3210
|
+
return object2[key].test(object1[key]);
|
|
3211
|
+
}
|
|
3212
|
+
return object2[key] === object1[key];
|
|
3213
|
+
});
|
|
3214
|
+
}
|
|
3215
|
+
function findMarkInSet(marks, type, attributes = {}) {
|
|
3216
|
+
return marks.find((item) => {
|
|
3217
|
+
return item.type === type && objectIncludes(
|
|
3218
|
+
// Only check equality for the attributes that are provided
|
|
3219
|
+
Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])),
|
|
3220
|
+
attributes
|
|
3221
|
+
);
|
|
3222
|
+
});
|
|
3223
|
+
}
|
|
3224
|
+
function isMarkInSet(marks, type, attributes = {}) {
|
|
3225
|
+
return !!findMarkInSet(marks, type, attributes);
|
|
3226
|
+
}
|
|
3227
|
+
function getMarkRange($pos, type, attributes) {
|
|
3228
|
+
var _a;
|
|
3229
|
+
if (!$pos || !type) {
|
|
3230
|
+
return;
|
|
3231
|
+
}
|
|
3232
|
+
let start = $pos.parent.childAfter($pos.parentOffset);
|
|
3233
|
+
if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) {
|
|
3234
|
+
start = $pos.parent.childBefore($pos.parentOffset);
|
|
3235
|
+
}
|
|
3236
|
+
if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) {
|
|
3237
|
+
return;
|
|
3238
|
+
}
|
|
3239
|
+
attributes = attributes || ((_a = start.node.marks[0]) == null ? void 0 : _a.attrs);
|
|
3240
|
+
const mark = findMarkInSet([...start.node.marks], type, attributes);
|
|
3241
|
+
if (!mark) {
|
|
3242
|
+
return;
|
|
3243
|
+
}
|
|
3244
|
+
let startIndex = start.index;
|
|
3245
|
+
let startPos = $pos.start() + start.offset;
|
|
3246
|
+
let endIndex = startIndex + 1;
|
|
3247
|
+
let endPos = startPos + start.node.nodeSize;
|
|
3248
|
+
while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) {
|
|
3249
|
+
startIndex -= 1;
|
|
3250
|
+
startPos -= $pos.parent.child(startIndex).nodeSize;
|
|
3251
|
+
}
|
|
3252
|
+
while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) {
|
|
3253
|
+
endPos += $pos.parent.child(endIndex).nodeSize;
|
|
3254
|
+
endIndex += 1;
|
|
3255
|
+
}
|
|
3256
|
+
return {
|
|
3257
|
+
from: startPos,
|
|
3258
|
+
to: endPos
|
|
3259
|
+
};
|
|
3260
|
+
}
|
|
3261
|
+
function getMarkType(nameOrType, schema) {
|
|
3262
|
+
if (typeof nameOrType === "string") {
|
|
3263
|
+
if (!schema.marks[nameOrType]) {
|
|
3264
|
+
throw Error(`There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
3265
|
+
}
|
|
3266
|
+
return schema.marks[nameOrType];
|
|
3267
|
+
}
|
|
3268
|
+
return nameOrType;
|
|
3269
|
+
}
|
|
3270
|
+
var extendMarkRange = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
|
3271
|
+
const type = getMarkType(typeOrName, state.schema);
|
|
3272
|
+
const { doc, selection } = tr;
|
|
3273
|
+
const { $from, from, to } = selection;
|
|
3274
|
+
if (dispatch) {
|
|
3275
|
+
const range = getMarkRange($from, type, attributes);
|
|
3276
|
+
if (range && range.from <= from && range.to >= to) {
|
|
3277
|
+
const newSelection = TextSelection.create(doc, range.from, range.to);
|
|
3278
|
+
tr.setSelection(newSelection);
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
return true;
|
|
3282
|
+
};
|
|
3283
|
+
var first = (commands) => (props) => {
|
|
3284
|
+
const items = typeof commands === "function" ? commands(props) : commands;
|
|
3285
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
3286
|
+
if (items[i](props)) {
|
|
3287
|
+
return true;
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
return false;
|
|
3291
|
+
};
|
|
3292
|
+
function isTextSelection(value) {
|
|
3293
|
+
return value instanceof TextSelection;
|
|
3294
|
+
}
|
|
3295
|
+
function minMax(value = 0, min = 0, max = 0) {
|
|
3296
|
+
return Math.min(Math.max(value, min), max);
|
|
3297
|
+
}
|
|
3298
|
+
function resolveFocusPosition(doc, position = null) {
|
|
3299
|
+
if (!position) {
|
|
3300
|
+
return null;
|
|
3301
|
+
}
|
|
3302
|
+
const selectionAtStart = Selection.atStart(doc);
|
|
3303
|
+
const selectionAtEnd = Selection.atEnd(doc);
|
|
3304
|
+
if (position === "start" || position === true) {
|
|
3305
|
+
return selectionAtStart;
|
|
3306
|
+
}
|
|
3307
|
+
if (position === "end") {
|
|
3308
|
+
return selectionAtEnd;
|
|
3309
|
+
}
|
|
3310
|
+
const minPos = selectionAtStart.from;
|
|
3311
|
+
const maxPos = selectionAtEnd.to;
|
|
3312
|
+
if (position === "all") {
|
|
3313
|
+
return TextSelection.create(doc, minMax(0, minPos, maxPos), minMax(doc.content.size, minPos, maxPos));
|
|
3314
|
+
}
|
|
3315
|
+
return TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
|
|
3316
|
+
}
|
|
3317
|
+
function isAndroid() {
|
|
3318
|
+
return navigator.platform === "Android" || /android/i.test(navigator.userAgent);
|
|
3319
|
+
}
|
|
3320
|
+
function isiOS() {
|
|
3321
|
+
return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(navigator.platform) || // iPad on iOS 13 detection
|
|
3322
|
+
navigator.userAgent.includes("Mac") && "ontouchend" in document;
|
|
3323
|
+
}
|
|
3324
|
+
var focus = (position = null, options = {}) => ({ editor, view, tr, dispatch }) => {
|
|
3325
|
+
options = {
|
|
3326
|
+
scrollIntoView: true,
|
|
3327
|
+
...options
|
|
3328
|
+
};
|
|
3329
|
+
const delayedFocus = () => {
|
|
3330
|
+
if (isiOS() || isAndroid()) {
|
|
3331
|
+
view.dom.focus();
|
|
3332
|
+
}
|
|
3333
|
+
requestAnimationFrame(() => {
|
|
3334
|
+
if (!editor.isDestroyed) {
|
|
3335
|
+
view.focus();
|
|
3336
|
+
if (options == null ? void 0 : options.scrollIntoView) {
|
|
3337
|
+
editor.commands.scrollIntoView();
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
});
|
|
3341
|
+
};
|
|
3342
|
+
if (view.hasFocus() && position === null || position === false) {
|
|
3343
|
+
return true;
|
|
3344
|
+
}
|
|
3345
|
+
if (dispatch && position === null && !isTextSelection(editor.state.selection)) {
|
|
3346
|
+
delayedFocus();
|
|
3347
|
+
return true;
|
|
3348
|
+
}
|
|
3349
|
+
const selection = resolveFocusPosition(tr.doc, position) || editor.state.selection;
|
|
3350
|
+
const isSameSelection = editor.state.selection.eq(selection);
|
|
3351
|
+
if (dispatch) {
|
|
3352
|
+
if (!isSameSelection) {
|
|
3353
|
+
tr.setSelection(selection);
|
|
3354
|
+
}
|
|
3355
|
+
if (isSameSelection && tr.storedMarks) {
|
|
3356
|
+
tr.setStoredMarks(tr.storedMarks);
|
|
3357
|
+
}
|
|
3358
|
+
delayedFocus();
|
|
3359
|
+
}
|
|
3360
|
+
return true;
|
|
3361
|
+
};
|
|
3362
|
+
var forEach = (items, fn) => (props) => {
|
|
3363
|
+
return items.every((item, index) => fn(item, { ...props, index }));
|
|
3364
|
+
};
|
|
3365
|
+
var insertContent = (value, options) => ({ tr, commands }) => {
|
|
3366
|
+
return commands.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, value, options);
|
|
3367
|
+
};
|
|
3368
|
+
var removeWhitespaces = (node) => {
|
|
3369
|
+
const children = node.childNodes;
|
|
3370
|
+
for (let i = children.length - 1; i >= 0; i -= 1) {
|
|
3371
|
+
const child = children[i];
|
|
3372
|
+
if (child.nodeType === 3 && child.nodeValue && /^(\n\s\s|\n)$/.test(child.nodeValue)) {
|
|
3373
|
+
node.removeChild(child);
|
|
3374
|
+
} else if (child.nodeType === 1) {
|
|
3375
|
+
removeWhitespaces(child);
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
return node;
|
|
3379
|
+
};
|
|
3380
|
+
function elementFromString(value) {
|
|
3381
|
+
if (typeof window === "undefined") {
|
|
3382
|
+
throw new Error("[tiptap error]: there is no window object available, so this function cannot be used");
|
|
3383
|
+
}
|
|
3384
|
+
const wrappedValue = `<body>${value}</body>`;
|
|
3385
|
+
const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body;
|
|
3386
|
+
return removeWhitespaces(html);
|
|
3387
|
+
}
|
|
3388
|
+
function createNodeFromContent(content, schema, options) {
|
|
3389
|
+
if (content instanceof Node || content instanceof Fragment) {
|
|
3390
|
+
return content;
|
|
3391
|
+
}
|
|
3392
|
+
options = {
|
|
3393
|
+
slice: true,
|
|
3394
|
+
parseOptions: {},
|
|
3395
|
+
...options
|
|
3396
|
+
};
|
|
3397
|
+
const isJSONContent = typeof content === "object" && content !== null;
|
|
3398
|
+
const isTextContent = typeof content === "string";
|
|
3399
|
+
if (isJSONContent) {
|
|
3400
|
+
try {
|
|
3401
|
+
const isArrayContent = Array.isArray(content) && content.length > 0;
|
|
3402
|
+
if (isArrayContent) {
|
|
3403
|
+
return Fragment.fromArray(content.map((item) => schema.nodeFromJSON(item)));
|
|
3404
|
+
}
|
|
3405
|
+
const node = schema.nodeFromJSON(content);
|
|
3406
|
+
if (options.errorOnInvalidContent) {
|
|
3407
|
+
node.check();
|
|
3408
|
+
}
|
|
3409
|
+
return node;
|
|
3410
|
+
} catch (error) {
|
|
3411
|
+
if (options.errorOnInvalidContent) {
|
|
3412
|
+
throw new Error("[tiptap error]: Invalid JSON content", { cause: error });
|
|
3413
|
+
}
|
|
3414
|
+
console.warn("[tiptap warn]: Invalid content.", "Passed value:", content, "Error:", error);
|
|
3415
|
+
return createNodeFromContent("", schema, options);
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
if (isTextContent) {
|
|
3419
|
+
if (options.errorOnInvalidContent) {
|
|
3420
|
+
let hasInvalidContent = false;
|
|
3421
|
+
let invalidContent = "";
|
|
3422
|
+
const contentCheckSchema = new Schema({
|
|
3423
|
+
topNode: schema.spec.topNode,
|
|
3424
|
+
marks: schema.spec.marks,
|
|
3425
|
+
// Prosemirror's schemas are executed such that: the last to execute, matches last
|
|
3426
|
+
// This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle
|
|
3427
|
+
nodes: schema.spec.nodes.append({
|
|
3428
|
+
__tiptap__private__unknown__catch__all__node: {
|
|
3429
|
+
content: "inline*",
|
|
3430
|
+
group: "block",
|
|
3431
|
+
parseDOM: [
|
|
3432
|
+
{
|
|
3433
|
+
tag: "*",
|
|
3434
|
+
getAttrs: (e) => {
|
|
3435
|
+
hasInvalidContent = true;
|
|
3436
|
+
invalidContent = typeof e === "string" ? e : e.outerHTML;
|
|
3437
|
+
return null;
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
]
|
|
3441
|
+
}
|
|
3442
|
+
})
|
|
3443
|
+
});
|
|
3444
|
+
if (options.slice) {
|
|
3445
|
+
DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
|
|
3446
|
+
} else {
|
|
3447
|
+
DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
|
|
3448
|
+
}
|
|
3449
|
+
if (options.errorOnInvalidContent && hasInvalidContent) {
|
|
3450
|
+
throw new Error("[tiptap error]: Invalid HTML content", {
|
|
3451
|
+
cause: new Error(`Invalid element found: ${invalidContent}`)
|
|
3452
|
+
});
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
const parser = DOMParser.fromSchema(schema);
|
|
3456
|
+
if (options.slice) {
|
|
3457
|
+
return parser.parseSlice(elementFromString(content), options.parseOptions).content;
|
|
3458
|
+
}
|
|
3459
|
+
return parser.parse(elementFromString(content), options.parseOptions);
|
|
3460
|
+
}
|
|
3461
|
+
return createNodeFromContent("", schema, options);
|
|
3462
|
+
}
|
|
3463
|
+
function selectionToInsertionEnd(tr, startLen, bias) {
|
|
3464
|
+
const last = tr.steps.length - 1;
|
|
3465
|
+
if (last < startLen) {
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
const step = tr.steps[last];
|
|
3469
|
+
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) {
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3472
|
+
const map = tr.mapping.maps[last];
|
|
3473
|
+
let end = 0;
|
|
3474
|
+
map.forEach((_from, _to, _newFrom, newTo) => {
|
|
3475
|
+
if (end === 0) {
|
|
3476
|
+
end = newTo;
|
|
3477
|
+
}
|
|
3478
|
+
});
|
|
3479
|
+
tr.setSelection(Selection.near(tr.doc.resolve(end), bias));
|
|
3480
|
+
}
|
|
3481
|
+
var isFragment = (nodeOrFragment) => {
|
|
3482
|
+
return !("type" in nodeOrFragment);
|
|
3483
|
+
};
|
|
3484
|
+
var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) => {
|
|
3485
|
+
var _a;
|
|
3486
|
+
if (dispatch) {
|
|
3487
|
+
options = {
|
|
3488
|
+
parseOptions: editor.options.parseOptions,
|
|
3489
|
+
updateSelection: true,
|
|
3490
|
+
applyInputRules: false,
|
|
3491
|
+
applyPasteRules: false,
|
|
3492
|
+
...options
|
|
3493
|
+
};
|
|
3494
|
+
let content;
|
|
3495
|
+
const emitContentError = (error) => {
|
|
3496
|
+
editor.emit("contentError", {
|
|
3497
|
+
editor,
|
|
3498
|
+
error,
|
|
3499
|
+
disableCollaboration: () => {
|
|
3500
|
+
if ("collaboration" in editor.storage && typeof editor.storage.collaboration === "object" && editor.storage.collaboration) {
|
|
3501
|
+
editor.storage.collaboration.isDisabled = true;
|
|
3502
|
+
}
|
|
3503
|
+
}
|
|
3504
|
+
});
|
|
3505
|
+
};
|
|
3506
|
+
const parseOptions = {
|
|
3507
|
+
preserveWhitespace: "full",
|
|
3508
|
+
...options.parseOptions
|
|
3509
|
+
};
|
|
3510
|
+
if (!options.errorOnInvalidContent && !editor.options.enableContentCheck && editor.options.emitContentError) {
|
|
3511
|
+
try {
|
|
3512
|
+
createNodeFromContent(value, editor.schema, {
|
|
3513
|
+
parseOptions,
|
|
3514
|
+
errorOnInvalidContent: true
|
|
3515
|
+
});
|
|
3516
|
+
} catch (e) {
|
|
3517
|
+
emitContentError(e);
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3520
|
+
try {
|
|
3521
|
+
content = createNodeFromContent(value, editor.schema, {
|
|
3522
|
+
parseOptions,
|
|
3523
|
+
errorOnInvalidContent: (_a = options.errorOnInvalidContent) != null ? _a : editor.options.enableContentCheck
|
|
3524
|
+
});
|
|
3525
|
+
} catch (e) {
|
|
3526
|
+
emitContentError(e);
|
|
3527
|
+
return false;
|
|
3528
|
+
}
|
|
3529
|
+
let { from, to } = typeof position === "number" ? { from: position, to: position } : { from: position.from, to: position.to };
|
|
3530
|
+
let isOnlyTextContent = true;
|
|
3531
|
+
let isOnlyBlockContent = true;
|
|
3532
|
+
const nodes = isFragment(content) ? content : [content];
|
|
3533
|
+
nodes.forEach((node) => {
|
|
3534
|
+
node.check();
|
|
3535
|
+
isOnlyTextContent = isOnlyTextContent ? node.isText && node.marks.length === 0 : false;
|
|
3536
|
+
isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false;
|
|
3537
|
+
});
|
|
3538
|
+
if (from === to && isOnlyBlockContent) {
|
|
3539
|
+
const { parent } = tr.doc.resolve(from);
|
|
3540
|
+
const isEmptyTextBlock = parent.isTextblock && !parent.type.spec.code && !parent.childCount;
|
|
3541
|
+
if (isEmptyTextBlock) {
|
|
3542
|
+
from -= 1;
|
|
3543
|
+
to += 1;
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
let newContent;
|
|
3547
|
+
if (isOnlyTextContent) {
|
|
3548
|
+
if (Array.isArray(value)) {
|
|
3549
|
+
newContent = value.map((v) => v.text || "").join("");
|
|
3550
|
+
} else if (value instanceof Fragment) {
|
|
3551
|
+
let text = "";
|
|
3552
|
+
value.forEach((node) => {
|
|
3553
|
+
if (node.text) {
|
|
3554
|
+
text += node.text;
|
|
3555
|
+
}
|
|
3556
|
+
});
|
|
3557
|
+
newContent = text;
|
|
3558
|
+
} else if (typeof value === "object" && !!value && !!value.text) {
|
|
3559
|
+
newContent = value.text;
|
|
3560
|
+
} else {
|
|
3561
|
+
newContent = value;
|
|
3562
|
+
}
|
|
3563
|
+
tr.insertText(newContent, from, to);
|
|
3564
|
+
} else {
|
|
3565
|
+
newContent = content;
|
|
3566
|
+
const $from = tr.doc.resolve(from);
|
|
3567
|
+
const $fromNode = $from.node();
|
|
3568
|
+
const fromSelectionAtStart = $from.parentOffset === 0;
|
|
3569
|
+
const isTextSelection2 = $fromNode.isText || $fromNode.isTextblock;
|
|
3570
|
+
const hasContent = $fromNode.content.size > 0;
|
|
3571
|
+
if (fromSelectionAtStart && isTextSelection2 && hasContent) {
|
|
3572
|
+
from = Math.max(0, from - 1);
|
|
3573
|
+
}
|
|
3574
|
+
tr.replaceWith(from, to, newContent);
|
|
3575
|
+
}
|
|
3576
|
+
if (options.updateSelection) {
|
|
3577
|
+
selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
|
|
3578
|
+
}
|
|
3579
|
+
if (options.applyInputRules) {
|
|
3580
|
+
tr.setMeta("applyInputRules", { from, text: newContent });
|
|
3581
|
+
}
|
|
3582
|
+
if (options.applyPasteRules) {
|
|
3583
|
+
tr.setMeta("applyPasteRules", { from, text: newContent });
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
return true;
|
|
3587
|
+
};
|
|
3588
|
+
var joinUp = () => ({ state, dispatch }) => {
|
|
3589
|
+
return joinUp$1(state, dispatch);
|
|
3590
|
+
};
|
|
3591
|
+
var joinDown = () => ({ state, dispatch }) => {
|
|
3592
|
+
return joinDown$1(state, dispatch);
|
|
3593
|
+
};
|
|
3594
|
+
var joinBackward = () => ({ state, dispatch }) => {
|
|
3595
|
+
return joinBackward$1(state, dispatch);
|
|
3596
|
+
};
|
|
3597
|
+
var joinForward = () => ({ state, dispatch }) => {
|
|
3598
|
+
return joinForward$1(state, dispatch);
|
|
3599
|
+
};
|
|
3600
|
+
var joinItemBackward = () => ({ state, dispatch, tr }) => {
|
|
3601
|
+
try {
|
|
3602
|
+
const point = joinPoint(state.doc, state.selection.$from.pos, -1);
|
|
3603
|
+
if (point === null || point === void 0) {
|
|
3604
|
+
return false;
|
|
3605
|
+
}
|
|
3606
|
+
tr.join(point, 2);
|
|
3607
|
+
if (dispatch) {
|
|
3608
|
+
dispatch(tr);
|
|
3609
|
+
}
|
|
3610
|
+
return true;
|
|
3611
|
+
} catch {
|
|
3612
|
+
return false;
|
|
3613
|
+
}
|
|
3614
|
+
};
|
|
3615
|
+
var joinItemForward = () => ({ state, dispatch, tr }) => {
|
|
3616
|
+
try {
|
|
3617
|
+
const point = joinPoint(state.doc, state.selection.$from.pos, 1);
|
|
3618
|
+
if (point === null || point === void 0) {
|
|
3619
|
+
return false;
|
|
3620
|
+
}
|
|
3621
|
+
tr.join(point, 2);
|
|
3622
|
+
if (dispatch) {
|
|
3623
|
+
dispatch(tr);
|
|
3624
|
+
}
|
|
3625
|
+
return true;
|
|
3626
|
+
} catch {
|
|
3627
|
+
return false;
|
|
3628
|
+
}
|
|
3629
|
+
};
|
|
3630
|
+
var joinTextblockBackward = () => ({ state, dispatch }) => {
|
|
3631
|
+
return joinTextblockBackward$1(state, dispatch);
|
|
3632
|
+
};
|
|
3633
|
+
var joinTextblockForward = () => ({ state, dispatch }) => {
|
|
3634
|
+
return joinTextblockForward$1(state, dispatch);
|
|
3635
|
+
};
|
|
3636
|
+
function isMacOS() {
|
|
3637
|
+
return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
|
|
3638
|
+
}
|
|
3639
|
+
function normalizeKeyName(name) {
|
|
3640
|
+
const parts = name.split(/-(?!$)/);
|
|
3641
|
+
let result = parts[parts.length - 1];
|
|
3642
|
+
if (result === "Space") {
|
|
3643
|
+
result = " ";
|
|
3644
|
+
}
|
|
3645
|
+
let alt;
|
|
3646
|
+
let ctrl;
|
|
3647
|
+
let shift;
|
|
3648
|
+
let meta;
|
|
3649
|
+
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
3650
|
+
const mod = parts[i];
|
|
3651
|
+
if (/^(cmd|meta|m)$/i.test(mod)) {
|
|
3652
|
+
meta = true;
|
|
3653
|
+
} else if (/^a(lt)?$/i.test(mod)) {
|
|
3654
|
+
alt = true;
|
|
3655
|
+
} else if (/^(c|ctrl|control)$/i.test(mod)) {
|
|
3656
|
+
ctrl = true;
|
|
3657
|
+
} else if (/^s(hift)?$/i.test(mod)) {
|
|
3658
|
+
shift = true;
|
|
3659
|
+
} else if (/^mod$/i.test(mod)) {
|
|
3660
|
+
if (isiOS() || isMacOS()) {
|
|
3661
|
+
meta = true;
|
|
3662
|
+
} else {
|
|
3663
|
+
ctrl = true;
|
|
3664
|
+
}
|
|
3665
|
+
} else {
|
|
3666
|
+
throw new Error(`Unrecognized modifier name: ${mod}`);
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
if (alt) {
|
|
3670
|
+
result = `Alt-${result}`;
|
|
3671
|
+
}
|
|
3672
|
+
if (ctrl) {
|
|
3673
|
+
result = `Ctrl-${result}`;
|
|
3674
|
+
}
|
|
3675
|
+
if (meta) {
|
|
3676
|
+
result = `Meta-${result}`;
|
|
3677
|
+
}
|
|
3678
|
+
if (shift) {
|
|
3679
|
+
result = `Shift-${result}`;
|
|
3680
|
+
}
|
|
3681
|
+
return result;
|
|
3682
|
+
}
|
|
3683
|
+
var keyboardShortcut = (name) => ({ editor, view, tr, dispatch }) => {
|
|
3684
|
+
const keys = normalizeKeyName(name).split(/-(?!$)/);
|
|
3685
|
+
const key = keys.find((item) => !["Alt", "Ctrl", "Meta", "Shift"].includes(item));
|
|
3686
|
+
const event = new KeyboardEvent("keydown", {
|
|
3687
|
+
key: key === "Space" ? " " : key,
|
|
3688
|
+
altKey: keys.includes("Alt"),
|
|
3689
|
+
ctrlKey: keys.includes("Ctrl"),
|
|
3690
|
+
metaKey: keys.includes("Meta"),
|
|
3691
|
+
shiftKey: keys.includes("Shift"),
|
|
3692
|
+
bubbles: true,
|
|
3693
|
+
cancelable: true
|
|
3694
|
+
});
|
|
3695
|
+
const capturedTransaction = editor.captureTransaction(() => {
|
|
3696
|
+
view.someProp("handleKeyDown", (f) => f(view, event));
|
|
3697
|
+
});
|
|
3698
|
+
capturedTransaction == null ? void 0 : capturedTransaction.steps.forEach((step) => {
|
|
3699
|
+
const newStep = step.map(tr.mapping);
|
|
3700
|
+
if (newStep && dispatch) {
|
|
3701
|
+
tr.maybeStep(newStep);
|
|
3702
|
+
}
|
|
3703
|
+
});
|
|
3704
|
+
return true;
|
|
3705
|
+
};
|
|
3706
|
+
function isNodeActive(state, typeOrName, attributes = {}) {
|
|
3707
|
+
const { from, to, empty } = state.selection;
|
|
3708
|
+
const type = typeOrName ? getNodeType(typeOrName, state.schema) : null;
|
|
3709
|
+
const nodeRanges = [];
|
|
3710
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
3711
|
+
if (node.isText) {
|
|
3712
|
+
return;
|
|
3713
|
+
}
|
|
3714
|
+
const relativeFrom = Math.max(from, pos);
|
|
3715
|
+
const relativeTo = Math.min(to, pos + node.nodeSize);
|
|
3716
|
+
nodeRanges.push({
|
|
3717
|
+
node,
|
|
3718
|
+
from: relativeFrom,
|
|
3719
|
+
to: relativeTo
|
|
3720
|
+
});
|
|
3721
|
+
});
|
|
3722
|
+
const selectionRange = to - from;
|
|
3723
|
+
const matchedNodeRanges = nodeRanges.filter((nodeRange) => {
|
|
3724
|
+
if (!type) {
|
|
3725
|
+
return true;
|
|
3726
|
+
}
|
|
3727
|
+
return type.name === nodeRange.node.type.name;
|
|
3728
|
+
}).filter((nodeRange) => objectIncludes(nodeRange.node.attrs, attributes, { strict: false }));
|
|
3729
|
+
if (empty) {
|
|
3730
|
+
return !!matchedNodeRanges.length;
|
|
3731
|
+
}
|
|
3732
|
+
const range = matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0);
|
|
3733
|
+
return range >= selectionRange;
|
|
3734
|
+
}
|
|
3735
|
+
var lift = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
|
|
3736
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
3737
|
+
const isActive2 = isNodeActive(state, type, attributes);
|
|
3738
|
+
if (!isActive2) {
|
|
3739
|
+
return false;
|
|
3740
|
+
}
|
|
3741
|
+
return lift$1(state, dispatch);
|
|
3742
|
+
};
|
|
3743
|
+
var liftEmptyBlock = () => ({ state, dispatch }) => {
|
|
3744
|
+
return liftEmptyBlock$1(state, dispatch);
|
|
3745
|
+
};
|
|
3746
|
+
var liftListItem = (typeOrName) => ({ state, dispatch }) => {
|
|
3747
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
3748
|
+
return liftListItem$1(type)(state, dispatch);
|
|
3749
|
+
};
|
|
3750
|
+
var newlineInCode = () => ({ state, dispatch }) => {
|
|
3751
|
+
return newlineInCode$1(state, dispatch);
|
|
3752
|
+
};
|
|
3753
|
+
function getSchemaTypeNameByName(name, schema) {
|
|
3754
|
+
if (schema.nodes[name]) {
|
|
3755
|
+
return "node";
|
|
3756
|
+
}
|
|
3757
|
+
if (schema.marks[name]) {
|
|
3758
|
+
return "mark";
|
|
3759
|
+
}
|
|
3760
|
+
return null;
|
|
3761
|
+
}
|
|
3762
|
+
function deleteProps(obj, propOrProps) {
|
|
3763
|
+
const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
|
|
3764
|
+
return Object.keys(obj).reduce((newObj, prop) => {
|
|
3765
|
+
if (!props.includes(prop)) {
|
|
3766
|
+
newObj[prop] = obj[prop];
|
|
3767
|
+
}
|
|
3768
|
+
return newObj;
|
|
3769
|
+
}, {});
|
|
3770
|
+
}
|
|
3771
|
+
var resetAttributes = (typeOrName, attributes) => ({ tr, state, dispatch }) => {
|
|
3772
|
+
let nodeType = null;
|
|
3773
|
+
let markType = null;
|
|
3774
|
+
const schemaType = getSchemaTypeNameByName(
|
|
3775
|
+
typeof typeOrName === "string" ? typeOrName : typeOrName.name,
|
|
3776
|
+
state.schema
|
|
3777
|
+
);
|
|
3778
|
+
if (!schemaType) {
|
|
3779
|
+
return false;
|
|
3780
|
+
}
|
|
3781
|
+
if (schemaType === "node") {
|
|
3782
|
+
nodeType = getNodeType(typeOrName, state.schema);
|
|
3783
|
+
}
|
|
3784
|
+
if (schemaType === "mark") {
|
|
3785
|
+
markType = getMarkType(typeOrName, state.schema);
|
|
3786
|
+
}
|
|
3787
|
+
let canReset = false;
|
|
3788
|
+
tr.selection.ranges.forEach((range) => {
|
|
3789
|
+
state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => {
|
|
3790
|
+
if (nodeType && nodeType === node.type) {
|
|
3791
|
+
canReset = true;
|
|
3792
|
+
if (dispatch) {
|
|
3793
|
+
tr.setNodeMarkup(pos, void 0, deleteProps(node.attrs, attributes));
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
if (markType && node.marks.length) {
|
|
3797
|
+
node.marks.forEach((mark) => {
|
|
3798
|
+
if (markType === mark.type) {
|
|
3799
|
+
canReset = true;
|
|
3800
|
+
if (dispatch) {
|
|
3801
|
+
tr.addMark(pos, pos + node.nodeSize, markType.create(deleteProps(mark.attrs, attributes)));
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
});
|
|
3805
|
+
}
|
|
3806
|
+
});
|
|
3807
|
+
});
|
|
3808
|
+
return canReset;
|
|
3809
|
+
};
|
|
3810
|
+
var scrollIntoView = () => ({ tr, dispatch }) => {
|
|
3811
|
+
if (dispatch) {
|
|
3812
|
+
tr.scrollIntoView();
|
|
3813
|
+
}
|
|
3814
|
+
return true;
|
|
3815
|
+
};
|
|
3816
|
+
var selectAll = () => ({ tr, dispatch }) => {
|
|
3817
|
+
if (dispatch) {
|
|
3818
|
+
const selection = new AllSelection(tr.doc);
|
|
3819
|
+
tr.setSelection(selection);
|
|
3820
|
+
}
|
|
3821
|
+
return true;
|
|
3822
|
+
};
|
|
3823
|
+
var selectNodeBackward = () => ({ state, dispatch }) => {
|
|
3824
|
+
return selectNodeBackward$1(state, dispatch);
|
|
3825
|
+
};
|
|
3826
|
+
var selectNodeForward = () => ({ state, dispatch }) => {
|
|
3827
|
+
return selectNodeForward$1(state, dispatch);
|
|
3828
|
+
};
|
|
3829
|
+
var selectParentNode = () => ({ state, dispatch }) => {
|
|
3830
|
+
return selectParentNode$1(state, dispatch);
|
|
3831
|
+
};
|
|
3832
|
+
var selectTextblockEnd = () => ({ state, dispatch }) => {
|
|
3833
|
+
return selectTextblockEnd$1(state, dispatch);
|
|
3834
|
+
};
|
|
3835
|
+
var selectTextblockStart = () => ({ state, dispatch }) => {
|
|
3836
|
+
return selectTextblockStart$1(state, dispatch);
|
|
3837
|
+
};
|
|
3838
|
+
function createDocument(content, schema, parseOptions = {}, options = {}) {
|
|
3839
|
+
return createNodeFromContent(content, schema, {
|
|
3840
|
+
slice: false,
|
|
3841
|
+
parseOptions,
|
|
3842
|
+
errorOnInvalidContent: options.errorOnInvalidContent
|
|
3843
|
+
});
|
|
3844
|
+
}
|
|
3845
|
+
var setContent = (content, { errorOnInvalidContent, emitUpdate = true, parseOptions = {} } = {}) => ({ editor, tr, dispatch, commands }) => {
|
|
3846
|
+
const { doc } = tr;
|
|
3847
|
+
if (parseOptions.preserveWhitespace !== "full") {
|
|
3848
|
+
const document2 = createDocument(content, editor.schema, parseOptions, {
|
|
3849
|
+
errorOnInvalidContent: errorOnInvalidContent != null ? errorOnInvalidContent : editor.options.enableContentCheck
|
|
3850
|
+
});
|
|
3851
|
+
if (dispatch) {
|
|
3852
|
+
tr.replaceWith(0, doc.content.size, document2).setMeta("preventUpdate", !emitUpdate);
|
|
3853
|
+
}
|
|
3854
|
+
return true;
|
|
3855
|
+
}
|
|
3856
|
+
if (dispatch) {
|
|
3857
|
+
tr.setMeta("preventUpdate", !emitUpdate);
|
|
3858
|
+
}
|
|
3859
|
+
return commands.insertContentAt({ from: 0, to: doc.content.size }, content, {
|
|
3860
|
+
parseOptions,
|
|
3861
|
+
errorOnInvalidContent: errorOnInvalidContent != null ? errorOnInvalidContent : editor.options.enableContentCheck
|
|
3862
|
+
});
|
|
3863
|
+
};
|
|
3864
|
+
function getMarkAttributes(state, typeOrName) {
|
|
3865
|
+
const type = getMarkType(typeOrName, state.schema);
|
|
3866
|
+
const { from, to, empty } = state.selection;
|
|
3867
|
+
const marks = [];
|
|
3868
|
+
if (empty) {
|
|
3869
|
+
if (state.storedMarks) {
|
|
3870
|
+
marks.push(...state.storedMarks);
|
|
3871
|
+
}
|
|
3872
|
+
marks.push(...state.selection.$head.marks());
|
|
3873
|
+
} else {
|
|
3874
|
+
state.doc.nodesBetween(from, to, (node) => {
|
|
3875
|
+
marks.push(...node.marks);
|
|
3876
|
+
});
|
|
3877
|
+
}
|
|
3878
|
+
const mark = marks.find((markItem) => markItem.type.name === type.name);
|
|
3879
|
+
if (!mark) {
|
|
3880
|
+
return {};
|
|
3881
|
+
}
|
|
3882
|
+
return { ...mark.attrs };
|
|
3883
|
+
}
|
|
3884
|
+
function combineTransactionSteps(oldDoc, transactions) {
|
|
3885
|
+
const transform = new Transform(oldDoc);
|
|
3886
|
+
transactions.forEach((transaction) => {
|
|
3887
|
+
transaction.steps.forEach((step) => {
|
|
3888
|
+
transform.step(step);
|
|
3889
|
+
});
|
|
3890
|
+
});
|
|
3891
|
+
return transform;
|
|
3892
|
+
}
|
|
3893
|
+
function defaultBlockAt(match) {
|
|
3894
|
+
for (let i = 0; i < match.edgeCount; i += 1) {
|
|
3895
|
+
const { type } = match.edge(i);
|
|
3896
|
+
if (type.isTextblock && !type.hasRequiredAttrs()) {
|
|
3897
|
+
return type;
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3900
|
+
return null;
|
|
3901
|
+
}
|
|
3902
|
+
function findParentNodeClosestToPos($pos, predicate) {
|
|
3903
|
+
for (let i = $pos.depth; i > 0; i -= 1) {
|
|
3904
|
+
const node = $pos.node(i);
|
|
3905
|
+
if (predicate(node)) {
|
|
3906
|
+
return {
|
|
3907
|
+
pos: i > 0 ? $pos.before(i) : 0,
|
|
3908
|
+
start: $pos.start(i),
|
|
3909
|
+
depth: i,
|
|
3910
|
+
node
|
|
3911
|
+
};
|
|
3912
|
+
}
|
|
3913
|
+
}
|
|
3914
|
+
}
|
|
3915
|
+
function findParentNode(predicate) {
|
|
3916
|
+
return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
|
|
3917
|
+
}
|
|
3918
|
+
function getExtensionField(extension, field, context) {
|
|
3919
|
+
if (extension.config[field] === void 0 && extension.parent) {
|
|
3920
|
+
return getExtensionField(extension.parent, field, context);
|
|
3921
|
+
}
|
|
3922
|
+
if (typeof extension.config[field] === "function") {
|
|
3923
|
+
const value = extension.config[field].bind({
|
|
3924
|
+
...context,
|
|
3925
|
+
parent: extension.parent ? getExtensionField(extension.parent, field, context) : null
|
|
3926
|
+
});
|
|
3927
|
+
return value;
|
|
3928
|
+
}
|
|
3929
|
+
return extension.config[field];
|
|
3930
|
+
}
|
|
3931
|
+
function isFunction(value) {
|
|
3932
|
+
return typeof value === "function";
|
|
3933
|
+
}
|
|
3934
|
+
function callOrReturn(value, context = void 0, ...props) {
|
|
3935
|
+
if (isFunction(value)) {
|
|
3936
|
+
if (context) {
|
|
3937
|
+
return value.bind(context)(...props);
|
|
3938
|
+
}
|
|
3939
|
+
return value(...props);
|
|
3940
|
+
}
|
|
3941
|
+
return value;
|
|
3942
|
+
}
|
|
3943
|
+
function splitExtensions(extensions) {
|
|
3944
|
+
const baseExtensions = extensions.filter((extension) => extension.type === "extension");
|
|
3945
|
+
const nodeExtensions = extensions.filter((extension) => extension.type === "node");
|
|
3946
|
+
const markExtensions = extensions.filter((extension) => extension.type === "mark");
|
|
3947
|
+
return {
|
|
3948
|
+
baseExtensions,
|
|
3949
|
+
nodeExtensions,
|
|
3950
|
+
markExtensions
|
|
3951
|
+
};
|
|
3952
|
+
}
|
|
3953
|
+
function mergeAttributes(...objects) {
|
|
3954
|
+
return objects.filter((item) => !!item).reduce((items, item) => {
|
|
3955
|
+
const mergedAttributes = { ...items };
|
|
3956
|
+
Object.entries(item).forEach(([key, value]) => {
|
|
3957
|
+
const exists = mergedAttributes[key];
|
|
3958
|
+
if (!exists) {
|
|
3959
|
+
mergedAttributes[key] = value;
|
|
3960
|
+
return;
|
|
3961
|
+
}
|
|
3962
|
+
if (key === "class") {
|
|
3963
|
+
const valueClasses = value ? String(value).split(" ") : [];
|
|
3964
|
+
const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : [];
|
|
3965
|
+
const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass));
|
|
3966
|
+
mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
|
|
3967
|
+
} else if (key === "style") {
|
|
3968
|
+
const newStyles = value ? value.split(";").map((style2) => style2.trim()).filter(Boolean) : [];
|
|
3969
|
+
const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(";").map((style2) => style2.trim()).filter(Boolean) : [];
|
|
3970
|
+
const styleMap = /* @__PURE__ */ new Map();
|
|
3971
|
+
existingStyles.forEach((style2) => {
|
|
3972
|
+
const [property, val] = style2.split(":").map((part) => part.trim());
|
|
3973
|
+
styleMap.set(property, val);
|
|
3974
|
+
});
|
|
3975
|
+
newStyles.forEach((style2) => {
|
|
3976
|
+
const [property, val] = style2.split(":").map((part) => part.trim());
|
|
3977
|
+
styleMap.set(property, val);
|
|
3978
|
+
});
|
|
3979
|
+
mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; ");
|
|
3980
|
+
} else {
|
|
3981
|
+
mergedAttributes[key] = value;
|
|
3982
|
+
}
|
|
3983
|
+
});
|
|
3984
|
+
return mergedAttributes;
|
|
3985
|
+
}, {});
|
|
3986
|
+
}
|
|
3987
|
+
function getTextBetween(startNode, range, options) {
|
|
3988
|
+
const { from, to } = range;
|
|
3989
|
+
const { blockSeparator = "\n\n", textSerializers = {} } = options || {};
|
|
3990
|
+
let text = "";
|
|
3991
|
+
startNode.nodesBetween(from, to, (node, pos, parent, index) => {
|
|
3992
|
+
var _a;
|
|
3993
|
+
if (node.isBlock && pos > from) {
|
|
3994
|
+
text += blockSeparator;
|
|
3995
|
+
}
|
|
3996
|
+
const textSerializer = textSerializers == null ? void 0 : textSerializers[node.type.name];
|
|
3997
|
+
if (textSerializer) {
|
|
3998
|
+
if (parent) {
|
|
3999
|
+
text += textSerializer({
|
|
4000
|
+
node,
|
|
4001
|
+
pos,
|
|
4002
|
+
parent,
|
|
4003
|
+
index,
|
|
4004
|
+
range
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
4007
|
+
return false;
|
|
4008
|
+
}
|
|
4009
|
+
if (node.isText) {
|
|
4010
|
+
text += (_a = node == null ? void 0 : node.text) == null ? void 0 : _a.slice(Math.max(from, pos) - pos, to - pos);
|
|
4011
|
+
}
|
|
4012
|
+
});
|
|
4013
|
+
return text;
|
|
4014
|
+
}
|
|
4015
|
+
function getTextSerializersFromSchema(schema) {
|
|
4016
|
+
return Object.fromEntries(
|
|
4017
|
+
Object.entries(schema.nodes).filter(([, node]) => node.spec.toText).map(([name, node]) => [name, node.spec.toText])
|
|
4018
|
+
);
|
|
4019
|
+
}
|
|
4020
|
+
function removeDuplicates(array, by = JSON.stringify) {
|
|
4021
|
+
const seen = {};
|
|
4022
|
+
return array.filter((item) => {
|
|
4023
|
+
const key = by(item);
|
|
4024
|
+
return Object.prototype.hasOwnProperty.call(seen, key) ? false : seen[key] = true;
|
|
4025
|
+
});
|
|
4026
|
+
}
|
|
4027
|
+
function simplifyChangedRanges(changes) {
|
|
4028
|
+
const uniqueChanges = removeDuplicates(changes);
|
|
4029
|
+
return uniqueChanges.length === 1 ? uniqueChanges : uniqueChanges.filter((change, index) => {
|
|
4030
|
+
const rest = uniqueChanges.filter((_, i) => i !== index);
|
|
4031
|
+
return !rest.some((otherChange) => {
|
|
4032
|
+
return change.oldRange.from >= otherChange.oldRange.from && change.oldRange.to <= otherChange.oldRange.to && change.newRange.from >= otherChange.newRange.from && change.newRange.to <= otherChange.newRange.to;
|
|
4033
|
+
});
|
|
4034
|
+
});
|
|
4035
|
+
}
|
|
4036
|
+
function getChangedRanges(transform) {
|
|
4037
|
+
const { mapping, steps } = transform;
|
|
4038
|
+
const changes = [];
|
|
4039
|
+
mapping.maps.forEach((stepMap, index) => {
|
|
4040
|
+
const ranges = [];
|
|
4041
|
+
if (!stepMap.ranges.length) {
|
|
4042
|
+
const { from, to } = steps[index];
|
|
4043
|
+
if (from === void 0 || to === void 0) {
|
|
4044
|
+
return;
|
|
4045
|
+
}
|
|
4046
|
+
ranges.push({ from, to });
|
|
4047
|
+
} else {
|
|
4048
|
+
stepMap.forEach((from, to) => {
|
|
4049
|
+
ranges.push({ from, to });
|
|
4050
|
+
});
|
|
4051
|
+
}
|
|
4052
|
+
ranges.forEach(({ from, to }) => {
|
|
4053
|
+
const newStart = mapping.slice(index).map(from, -1);
|
|
4054
|
+
const newEnd = mapping.slice(index).map(to);
|
|
4055
|
+
const oldStart = mapping.invert().map(newStart, -1);
|
|
4056
|
+
const oldEnd = mapping.invert().map(newEnd);
|
|
4057
|
+
changes.push({
|
|
4058
|
+
oldRange: {
|
|
4059
|
+
from: oldStart,
|
|
4060
|
+
to: oldEnd
|
|
4061
|
+
},
|
|
4062
|
+
newRange: {
|
|
4063
|
+
from: newStart,
|
|
4064
|
+
to: newEnd
|
|
4065
|
+
}
|
|
4066
|
+
});
|
|
4067
|
+
});
|
|
4068
|
+
});
|
|
4069
|
+
return simplifyChangedRanges(changes);
|
|
4070
|
+
}
|
|
4071
|
+
function getSplittedAttributes(extensionAttributes, typeName, attributes) {
|
|
4072
|
+
return Object.fromEntries(
|
|
4073
|
+
Object.entries(attributes).filter(([name]) => {
|
|
4074
|
+
const extensionAttribute = extensionAttributes.find((item) => {
|
|
4075
|
+
return item.type === typeName && item.name === name;
|
|
4076
|
+
});
|
|
4077
|
+
if (!extensionAttribute) {
|
|
4078
|
+
return false;
|
|
4079
|
+
}
|
|
4080
|
+
return extensionAttribute.attribute.keepOnSplit;
|
|
4081
|
+
})
|
|
4082
|
+
);
|
|
4083
|
+
}
|
|
4084
|
+
function isMarkActive(state, typeOrName, attributes = {}) {
|
|
4085
|
+
const { empty, ranges } = state.selection;
|
|
4086
|
+
const type = typeOrName ? getMarkType(typeOrName, state.schema) : null;
|
|
4087
|
+
if (empty) {
|
|
4088
|
+
return !!(state.storedMarks || state.selection.$from.marks()).filter((mark) => {
|
|
4089
|
+
if (!type) {
|
|
4090
|
+
return true;
|
|
4091
|
+
}
|
|
4092
|
+
return type.name === mark.type.name;
|
|
4093
|
+
}).find((mark) => objectIncludes(mark.attrs, attributes, { strict: false }));
|
|
4094
|
+
}
|
|
4095
|
+
let selectionRange = 0;
|
|
4096
|
+
const markRanges = [];
|
|
4097
|
+
ranges.forEach(({ $from, $to }) => {
|
|
4098
|
+
const from = $from.pos;
|
|
4099
|
+
const to = $to.pos;
|
|
4100
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
4101
|
+
if (!node.isText && !node.marks.length) {
|
|
4102
|
+
return;
|
|
4103
|
+
}
|
|
4104
|
+
const relativeFrom = Math.max(from, pos);
|
|
4105
|
+
const relativeTo = Math.min(to, pos + node.nodeSize);
|
|
4106
|
+
const range2 = relativeTo - relativeFrom;
|
|
4107
|
+
selectionRange += range2;
|
|
4108
|
+
markRanges.push(
|
|
4109
|
+
...node.marks.map((mark) => ({
|
|
4110
|
+
mark,
|
|
4111
|
+
from: relativeFrom,
|
|
4112
|
+
to: relativeTo
|
|
4113
|
+
}))
|
|
4114
|
+
);
|
|
4115
|
+
});
|
|
4116
|
+
});
|
|
4117
|
+
if (selectionRange === 0) {
|
|
4118
|
+
return false;
|
|
4119
|
+
}
|
|
4120
|
+
const matchedRange = markRanges.filter((markRange) => {
|
|
4121
|
+
if (!type) {
|
|
4122
|
+
return true;
|
|
4123
|
+
}
|
|
4124
|
+
return type.name === markRange.mark.type.name;
|
|
4125
|
+
}).filter((markRange) => objectIncludes(markRange.mark.attrs, attributes, { strict: false })).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0);
|
|
4126
|
+
const excludedRange = markRanges.filter((markRange) => {
|
|
4127
|
+
if (!type) {
|
|
4128
|
+
return true;
|
|
4129
|
+
}
|
|
4130
|
+
return markRange.mark.type !== type && markRange.mark.type.excludes(type);
|
|
4131
|
+
}).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0);
|
|
4132
|
+
const range = matchedRange > 0 ? matchedRange + excludedRange : matchedRange;
|
|
4133
|
+
return range >= selectionRange;
|
|
4134
|
+
}
|
|
4135
|
+
function isList(name, extensions) {
|
|
4136
|
+
const { nodeExtensions } = splitExtensions(extensions);
|
|
4137
|
+
const extension = nodeExtensions.find((item) => item.name === name);
|
|
4138
|
+
if (!extension) {
|
|
4139
|
+
return false;
|
|
4140
|
+
}
|
|
4141
|
+
const context = {
|
|
4142
|
+
name: extension.name,
|
|
4143
|
+
options: extension.options,
|
|
4144
|
+
storage: extension.storage
|
|
4145
|
+
};
|
|
4146
|
+
const group = callOrReturn(getExtensionField(extension, "group", context));
|
|
4147
|
+
if (typeof group !== "string") {
|
|
4148
|
+
return false;
|
|
4149
|
+
}
|
|
4150
|
+
return group.split(" ").includes("list");
|
|
4151
|
+
}
|
|
4152
|
+
function isNodeEmpty(node, {
|
|
4153
|
+
checkChildren = true,
|
|
4154
|
+
ignoreWhitespace = false
|
|
4155
|
+
} = {}) {
|
|
4156
|
+
var _a;
|
|
4157
|
+
if (ignoreWhitespace) {
|
|
4158
|
+
if (node.type.name === "hardBreak") {
|
|
4159
|
+
return true;
|
|
4160
|
+
}
|
|
4161
|
+
if (node.isText) {
|
|
4162
|
+
return /^\s*$/m.test((_a = node.text) != null ? _a : "");
|
|
4163
|
+
}
|
|
4164
|
+
}
|
|
4165
|
+
if (node.isText) {
|
|
4166
|
+
return !node.text;
|
|
4167
|
+
}
|
|
4168
|
+
if (node.isAtom || node.isLeaf) {
|
|
4169
|
+
return false;
|
|
4170
|
+
}
|
|
4171
|
+
if (node.content.childCount === 0) {
|
|
4172
|
+
return true;
|
|
4173
|
+
}
|
|
4174
|
+
if (checkChildren) {
|
|
4175
|
+
let isContentEmpty = true;
|
|
4176
|
+
node.content.forEach((childNode) => {
|
|
4177
|
+
if (isContentEmpty === false) {
|
|
4178
|
+
return;
|
|
4179
|
+
}
|
|
4180
|
+
if (!isNodeEmpty(childNode, { ignoreWhitespace, checkChildren })) {
|
|
4181
|
+
isContentEmpty = false;
|
|
4182
|
+
}
|
|
4183
|
+
});
|
|
4184
|
+
return isContentEmpty;
|
|
4185
|
+
}
|
|
4186
|
+
return false;
|
|
4187
|
+
}
|
|
4188
|
+
function canSetMark(state, tr, newMarkType) {
|
|
4189
|
+
var _a;
|
|
4190
|
+
const { selection } = tr;
|
|
4191
|
+
let cursor = null;
|
|
4192
|
+
if (isTextSelection(selection)) {
|
|
4193
|
+
cursor = selection.$cursor;
|
|
4194
|
+
}
|
|
4195
|
+
if (cursor) {
|
|
4196
|
+
const currentMarks = (_a = state.storedMarks) != null ? _a : cursor.marks();
|
|
4197
|
+
const parentAllowsMarkType = cursor.parent.type.allowsMarkType(newMarkType);
|
|
4198
|
+
return parentAllowsMarkType && (!!newMarkType.isInSet(currentMarks) || !currentMarks.some((mark) => mark.type.excludes(newMarkType)));
|
|
4199
|
+
}
|
|
4200
|
+
const { ranges } = selection;
|
|
4201
|
+
return ranges.some(({ $from, $to }) => {
|
|
4202
|
+
let someNodeSupportsMark = $from.depth === 0 ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType) : false;
|
|
4203
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => {
|
|
4204
|
+
if (someNodeSupportsMark) {
|
|
4205
|
+
return false;
|
|
4206
|
+
}
|
|
4207
|
+
if (node.isInline) {
|
|
4208
|
+
const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType);
|
|
4209
|
+
const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks) || !node.marks.some((otherMark) => otherMark.type.excludes(newMarkType));
|
|
4210
|
+
someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType;
|
|
4211
|
+
}
|
|
4212
|
+
return !someNodeSupportsMark;
|
|
4213
|
+
});
|
|
4214
|
+
return someNodeSupportsMark;
|
|
4215
|
+
});
|
|
4216
|
+
}
|
|
4217
|
+
var setMark = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
|
4218
|
+
const { selection } = tr;
|
|
4219
|
+
const { empty, ranges } = selection;
|
|
4220
|
+
const type = getMarkType(typeOrName, state.schema);
|
|
4221
|
+
if (dispatch) {
|
|
4222
|
+
if (empty) {
|
|
4223
|
+
const oldAttributes = getMarkAttributes(state, type);
|
|
4224
|
+
tr.addStoredMark(
|
|
4225
|
+
type.create({
|
|
4226
|
+
...oldAttributes,
|
|
4227
|
+
...attributes
|
|
4228
|
+
})
|
|
4229
|
+
);
|
|
4230
|
+
} else {
|
|
4231
|
+
ranges.forEach((range) => {
|
|
4232
|
+
const from = range.$from.pos;
|
|
4233
|
+
const to = range.$to.pos;
|
|
4234
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
4235
|
+
const trimmedFrom = Math.max(pos, from);
|
|
4236
|
+
const trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
4237
|
+
const someHasMark = node.marks.find((mark) => mark.type === type);
|
|
4238
|
+
if (someHasMark) {
|
|
4239
|
+
node.marks.forEach((mark) => {
|
|
4240
|
+
if (type === mark.type) {
|
|
4241
|
+
tr.addMark(
|
|
4242
|
+
trimmedFrom,
|
|
4243
|
+
trimmedTo,
|
|
4244
|
+
type.create({
|
|
4245
|
+
...mark.attrs,
|
|
4246
|
+
...attributes
|
|
4247
|
+
})
|
|
4248
|
+
);
|
|
4249
|
+
}
|
|
4250
|
+
});
|
|
4251
|
+
} else {
|
|
4252
|
+
tr.addMark(trimmedFrom, trimmedTo, type.create(attributes));
|
|
4253
|
+
}
|
|
4254
|
+
});
|
|
4255
|
+
});
|
|
4256
|
+
}
|
|
4257
|
+
}
|
|
4258
|
+
return canSetMark(state, tr, type);
|
|
4259
|
+
};
|
|
4260
|
+
var setMeta = (key, value) => ({ tr }) => {
|
|
4261
|
+
tr.setMeta(key, value);
|
|
4262
|
+
return true;
|
|
4263
|
+
};
|
|
4264
|
+
var setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => {
|
|
4265
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
4266
|
+
let attributesToCopy;
|
|
4267
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
4268
|
+
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
4269
|
+
}
|
|
4270
|
+
if (!type.isTextblock) {
|
|
4271
|
+
console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.');
|
|
4272
|
+
return false;
|
|
4273
|
+
}
|
|
4274
|
+
return chain().command(({ commands }) => {
|
|
4275
|
+
const canSetBlock = setBlockType(type, { ...attributesToCopy, ...attributes })(state);
|
|
4276
|
+
if (canSetBlock) {
|
|
4277
|
+
return true;
|
|
4278
|
+
}
|
|
4279
|
+
return commands.clearNodes();
|
|
4280
|
+
}).command(({ state: updatedState }) => {
|
|
4281
|
+
return setBlockType(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch);
|
|
4282
|
+
}).run();
|
|
4283
|
+
};
|
|
4284
|
+
var setNodeSelection = (position) => ({ tr, dispatch }) => {
|
|
4285
|
+
if (dispatch) {
|
|
4286
|
+
const { doc } = tr;
|
|
4287
|
+
const from = minMax(position, 0, doc.content.size);
|
|
4288
|
+
const selection = NodeSelection.create(doc, from);
|
|
4289
|
+
tr.setSelection(selection);
|
|
4290
|
+
}
|
|
4291
|
+
return true;
|
|
4292
|
+
};
|
|
4293
|
+
var setTextDirection = (direction, position) => ({ tr, state, dispatch }) => {
|
|
4294
|
+
const { selection } = state;
|
|
4295
|
+
let from;
|
|
4296
|
+
let to;
|
|
4297
|
+
if (typeof position === "number") {
|
|
4298
|
+
from = position;
|
|
4299
|
+
to = position;
|
|
4300
|
+
} else if (position && "from" in position && "to" in position) {
|
|
4301
|
+
from = position.from;
|
|
4302
|
+
to = position.to;
|
|
4303
|
+
} else {
|
|
4304
|
+
from = selection.from;
|
|
4305
|
+
to = selection.to;
|
|
4306
|
+
}
|
|
4307
|
+
if (dispatch) {
|
|
4308
|
+
tr.doc.nodesBetween(from, to, (node, pos) => {
|
|
4309
|
+
if (node.isText) {
|
|
4310
|
+
return;
|
|
4311
|
+
}
|
|
4312
|
+
tr.setNodeMarkup(pos, void 0, {
|
|
4313
|
+
...node.attrs,
|
|
4314
|
+
dir: direction
|
|
4315
|
+
});
|
|
4316
|
+
});
|
|
4317
|
+
}
|
|
4318
|
+
return true;
|
|
4319
|
+
};
|
|
4320
|
+
var setTextSelection = (position) => ({ tr, dispatch }) => {
|
|
4321
|
+
if (dispatch) {
|
|
4322
|
+
const { doc } = tr;
|
|
4323
|
+
const { from, to } = typeof position === "number" ? { from: position, to: position } : position;
|
|
4324
|
+
const minPos = TextSelection.atStart(doc).from;
|
|
4325
|
+
const maxPos = TextSelection.atEnd(doc).to;
|
|
4326
|
+
const resolvedFrom = minMax(from, minPos, maxPos);
|
|
4327
|
+
const resolvedEnd = minMax(to, minPos, maxPos);
|
|
4328
|
+
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd);
|
|
4329
|
+
tr.setSelection(selection);
|
|
4330
|
+
}
|
|
4331
|
+
return true;
|
|
4332
|
+
};
|
|
4333
|
+
var sinkListItem = (typeOrName) => ({ state, dispatch }) => {
|
|
4334
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
4335
|
+
return sinkListItem$1(type)(state, dispatch);
|
|
4336
|
+
};
|
|
4337
|
+
function ensureMarks(state, splittableMarks) {
|
|
4338
|
+
const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks();
|
|
4339
|
+
if (marks) {
|
|
4340
|
+
const filteredMarks = marks.filter((mark) => splittableMarks == null ? void 0 : splittableMarks.includes(mark.type.name));
|
|
4341
|
+
state.tr.ensureMarks(filteredMarks);
|
|
4342
|
+
}
|
|
4343
|
+
}
|
|
4344
|
+
var splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor }) => {
|
|
4345
|
+
const { selection, doc } = tr;
|
|
4346
|
+
const { $from, $to } = selection;
|
|
4347
|
+
const extensionAttributes = editor.extensionManager.attributes;
|
|
4348
|
+
const newAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
|
|
4349
|
+
if (selection instanceof NodeSelection && selection.node.isBlock) {
|
|
4350
|
+
if (!$from.parentOffset || !canSplit(doc, $from.pos)) {
|
|
4351
|
+
return false;
|
|
4352
|
+
}
|
|
4353
|
+
if (dispatch) {
|
|
4354
|
+
if (keepMarks) {
|
|
4355
|
+
ensureMarks(state, editor.extensionManager.splittableMarks);
|
|
4356
|
+
}
|
|
4357
|
+
tr.split($from.pos).scrollIntoView();
|
|
4358
|
+
}
|
|
4359
|
+
return true;
|
|
4360
|
+
}
|
|
4361
|
+
if (!$from.parent.isBlock) {
|
|
4362
|
+
return false;
|
|
4363
|
+
}
|
|
4364
|
+
const atEnd = $to.parentOffset === $to.parent.content.size;
|
|
4365
|
+
const deflt = $from.depth === 0 ? void 0 : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
|
|
4366
|
+
let types = atEnd && deflt ? [
|
|
4367
|
+
{
|
|
4368
|
+
type: deflt,
|
|
4369
|
+
attrs: newAttributes
|
|
4370
|
+
}
|
|
4371
|
+
] : void 0;
|
|
4372
|
+
let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types);
|
|
4373
|
+
if (!types && !can && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) {
|
|
4374
|
+
can = true;
|
|
4375
|
+
types = deflt ? [
|
|
4376
|
+
{
|
|
4377
|
+
type: deflt,
|
|
4378
|
+
attrs: newAttributes
|
|
4379
|
+
}
|
|
4380
|
+
] : void 0;
|
|
4381
|
+
}
|
|
4382
|
+
if (dispatch) {
|
|
4383
|
+
if (can) {
|
|
4384
|
+
if (selection instanceof TextSelection) {
|
|
4385
|
+
tr.deleteSelection();
|
|
4386
|
+
}
|
|
4387
|
+
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
4388
|
+
if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
|
|
4389
|
+
const first2 = tr.mapping.map($from.before());
|
|
4390
|
+
const $first = tr.doc.resolve(first2);
|
|
4391
|
+
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) {
|
|
4392
|
+
tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
if (keepMarks) {
|
|
4397
|
+
ensureMarks(state, editor.extensionManager.splittableMarks);
|
|
4398
|
+
}
|
|
4399
|
+
tr.scrollIntoView();
|
|
4400
|
+
}
|
|
4401
|
+
return can;
|
|
4402
|
+
};
|
|
4403
|
+
var splitListItem = (typeOrName, overrideAttrs = {}) => ({ tr, state, dispatch, editor }) => {
|
|
4404
|
+
var _a;
|
|
4405
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
4406
|
+
const { $from, $to } = state.selection;
|
|
4407
|
+
const node = state.selection.node;
|
|
4408
|
+
if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) {
|
|
4409
|
+
return false;
|
|
4410
|
+
}
|
|
4411
|
+
const grandParent = $from.node(-1);
|
|
4412
|
+
if (grandParent.type !== type) {
|
|
4413
|
+
return false;
|
|
4414
|
+
}
|
|
4415
|
+
const extensionAttributes = editor.extensionManager.attributes;
|
|
4416
|
+
if ($from.parent.content.size === 0 && $from.node(-1).childCount === $from.indexAfter(-1)) {
|
|
4417
|
+
if ($from.depth === 2 || $from.node(-3).type !== type || $from.index(-2) !== $from.node(-2).childCount - 1) {
|
|
4418
|
+
return false;
|
|
4419
|
+
}
|
|
4420
|
+
if (dispatch) {
|
|
4421
|
+
let wrap = Fragment.empty;
|
|
4422
|
+
const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3;
|
|
4423
|
+
for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d -= 1) {
|
|
4424
|
+
wrap = Fragment.from($from.node(d).copy(wrap));
|
|
4425
|
+
}
|
|
4426
|
+
const depthAfter = (
|
|
4427
|
+
// eslint-disable-next-line no-nested-ternary
|
|
4428
|
+
$from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3
|
|
4429
|
+
);
|
|
4430
|
+
const newNextTypeAttributes2 = {
|
|
4431
|
+
...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
|
|
4432
|
+
...overrideAttrs
|
|
4433
|
+
};
|
|
4434
|
+
const nextType2 = ((_a = type.contentMatch.defaultType) == null ? void 0 : _a.createAndFill(newNextTypeAttributes2)) || void 0;
|
|
4435
|
+
wrap = wrap.append(Fragment.from(type.createAndFill(null, nextType2) || void 0));
|
|
4436
|
+
const start = $from.before($from.depth - (depthBefore - 1));
|
|
4437
|
+
tr.replace(start, $from.after(-depthAfter), new Slice(wrap, 4 - depthBefore, 0));
|
|
4438
|
+
let sel = -1;
|
|
4439
|
+
tr.doc.nodesBetween(start, tr.doc.content.size, (n, pos) => {
|
|
4440
|
+
if (sel > -1) {
|
|
4441
|
+
return false;
|
|
4442
|
+
}
|
|
4443
|
+
if (n.isTextblock && n.content.size === 0) {
|
|
4444
|
+
sel = pos + 1;
|
|
4445
|
+
}
|
|
4446
|
+
});
|
|
4447
|
+
if (sel > -1) {
|
|
4448
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve(sel)));
|
|
4449
|
+
}
|
|
4450
|
+
tr.scrollIntoView();
|
|
4451
|
+
}
|
|
4452
|
+
return true;
|
|
4453
|
+
}
|
|
4454
|
+
const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null;
|
|
4455
|
+
const newTypeAttributes = {
|
|
4456
|
+
...getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs),
|
|
4457
|
+
...overrideAttrs
|
|
4458
|
+
};
|
|
4459
|
+
const newNextTypeAttributes = {
|
|
4460
|
+
...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
|
|
4461
|
+
...overrideAttrs
|
|
4462
|
+
};
|
|
4463
|
+
tr.delete($from.pos, $to.pos);
|
|
4464
|
+
const types = nextType ? [
|
|
4465
|
+
{ type, attrs: newTypeAttributes },
|
|
4466
|
+
{ type: nextType, attrs: newNextTypeAttributes }
|
|
4467
|
+
] : [{ type, attrs: newTypeAttributes }];
|
|
4468
|
+
if (!canSplit(tr.doc, $from.pos, 2)) {
|
|
4469
|
+
return false;
|
|
4470
|
+
}
|
|
4471
|
+
if (dispatch) {
|
|
4472
|
+
const { selection, storedMarks } = state;
|
|
4473
|
+
const { splittableMarks } = editor.extensionManager;
|
|
4474
|
+
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
4475
|
+
tr.split($from.pos, 2, types).scrollIntoView();
|
|
4476
|
+
if (!marks || !dispatch) {
|
|
4477
|
+
return true;
|
|
4478
|
+
}
|
|
4479
|
+
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
4480
|
+
tr.ensureMarks(filteredMarks);
|
|
4481
|
+
}
|
|
4482
|
+
return true;
|
|
4483
|
+
};
|
|
4484
|
+
var joinListBackwards = (tr, listType) => {
|
|
4485
|
+
const list = findParentNode((node) => node.type === listType)(tr.selection);
|
|
4486
|
+
if (!list) {
|
|
4487
|
+
return true;
|
|
4488
|
+
}
|
|
4489
|
+
const before = tr.doc.resolve(Math.max(0, list.pos - 1)).before(list.depth);
|
|
4490
|
+
if (before === void 0) {
|
|
4491
|
+
return true;
|
|
4492
|
+
}
|
|
4493
|
+
const nodeBefore = tr.doc.nodeAt(before);
|
|
4494
|
+
const canJoinBackwards = list.node.type === (nodeBefore == null ? void 0 : nodeBefore.type) && canJoin(tr.doc, list.pos);
|
|
4495
|
+
if (!canJoinBackwards) {
|
|
4496
|
+
return true;
|
|
4497
|
+
}
|
|
4498
|
+
tr.join(list.pos);
|
|
4499
|
+
return true;
|
|
4500
|
+
};
|
|
4501
|
+
var joinListForwards = (tr, listType) => {
|
|
4502
|
+
const list = findParentNode((node) => node.type === listType)(tr.selection);
|
|
4503
|
+
if (!list) {
|
|
4504
|
+
return true;
|
|
4505
|
+
}
|
|
4506
|
+
const after = tr.doc.resolve(list.start).after(list.depth);
|
|
4507
|
+
if (after === void 0) {
|
|
4508
|
+
return true;
|
|
4509
|
+
}
|
|
4510
|
+
const nodeAfter = tr.doc.nodeAt(after);
|
|
4511
|
+
const canJoinForwards = list.node.type === (nodeAfter == null ? void 0 : nodeAfter.type) && canJoin(tr.doc, after);
|
|
4512
|
+
if (!canJoinForwards) {
|
|
4513
|
+
return true;
|
|
4514
|
+
}
|
|
4515
|
+
tr.join(after);
|
|
4516
|
+
return true;
|
|
4517
|
+
};
|
|
4518
|
+
var toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({ editor, tr, state, dispatch, chain, commands, can }) => {
|
|
4519
|
+
const { extensions, splittableMarks } = editor.extensionManager;
|
|
4520
|
+
const listType = getNodeType(listTypeOrName, state.schema);
|
|
4521
|
+
const itemType = getNodeType(itemTypeOrName, state.schema);
|
|
4522
|
+
const { selection, storedMarks } = state;
|
|
4523
|
+
const { $from, $to } = selection;
|
|
4524
|
+
const range = $from.blockRange($to);
|
|
4525
|
+
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
4526
|
+
if (!range) {
|
|
4527
|
+
return false;
|
|
4528
|
+
}
|
|
4529
|
+
const parentList = findParentNode((node) => isList(node.type.name, extensions))(selection);
|
|
4530
|
+
if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
|
|
4531
|
+
if (parentList.node.type === listType) {
|
|
4532
|
+
return commands.liftListItem(itemType);
|
|
4533
|
+
}
|
|
4534
|
+
if (isList(parentList.node.type.name, extensions) && listType.validContent(parentList.node.content) && dispatch) {
|
|
4535
|
+
return chain().command(() => {
|
|
4536
|
+
tr.setNodeMarkup(parentList.pos, listType);
|
|
4537
|
+
return true;
|
|
4538
|
+
}).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
|
|
4539
|
+
}
|
|
4540
|
+
}
|
|
4541
|
+
if (!keepMarks || !marks || !dispatch) {
|
|
4542
|
+
return chain().command(() => {
|
|
4543
|
+
const canWrapInList = can().wrapInList(listType, attributes);
|
|
4544
|
+
if (canWrapInList) {
|
|
4545
|
+
return true;
|
|
4546
|
+
}
|
|
4547
|
+
return commands.clearNodes();
|
|
4548
|
+
}).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
|
|
4549
|
+
}
|
|
4550
|
+
return chain().command(() => {
|
|
4551
|
+
const canWrapInList = can().wrapInList(listType, attributes);
|
|
4552
|
+
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
4553
|
+
tr.ensureMarks(filteredMarks);
|
|
4554
|
+
if (canWrapInList) {
|
|
4555
|
+
return true;
|
|
4556
|
+
}
|
|
4557
|
+
return commands.clearNodes();
|
|
4558
|
+
}).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
|
|
4559
|
+
};
|
|
4560
|
+
var toggleMark = (typeOrName, attributes = {}, options = {}) => ({ state, commands }) => {
|
|
4561
|
+
const { extendEmptyMarkRange = false } = options;
|
|
4562
|
+
const type = getMarkType(typeOrName, state.schema);
|
|
4563
|
+
const isActive2 = isMarkActive(state, type, attributes);
|
|
4564
|
+
if (isActive2) {
|
|
4565
|
+
return commands.unsetMark(type, { extendEmptyMarkRange });
|
|
4566
|
+
}
|
|
4567
|
+
return commands.setMark(type, attributes);
|
|
4568
|
+
};
|
|
4569
|
+
var toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands }) => {
|
|
4570
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
4571
|
+
const toggleType = getNodeType(toggleTypeOrName, state.schema);
|
|
4572
|
+
const isActive2 = isNodeActive(state, type, attributes);
|
|
4573
|
+
let attributesToCopy;
|
|
4574
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
4575
|
+
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
4576
|
+
}
|
|
4577
|
+
if (isActive2) {
|
|
4578
|
+
return commands.setNode(toggleType, attributesToCopy);
|
|
4579
|
+
}
|
|
4580
|
+
return commands.setNode(type, { ...attributesToCopy, ...attributes });
|
|
4581
|
+
};
|
|
4582
|
+
var toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
|
4583
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
4584
|
+
const isActive2 = isNodeActive(state, type, attributes);
|
|
4585
|
+
if (isActive2) {
|
|
4586
|
+
return commands.lift(type);
|
|
4587
|
+
}
|
|
4588
|
+
return commands.wrapIn(type, attributes);
|
|
4589
|
+
};
|
|
4590
|
+
var undoInputRule = () => ({ state, dispatch }) => {
|
|
4591
|
+
const plugins = state.plugins;
|
|
4592
|
+
for (let i = 0; i < plugins.length; i += 1) {
|
|
4593
|
+
const plugin = plugins[i];
|
|
4594
|
+
let undoable;
|
|
4595
|
+
if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {
|
|
4596
|
+
if (dispatch) {
|
|
4597
|
+
const tr = state.tr;
|
|
4598
|
+
const toUndo = undoable.transform;
|
|
4599
|
+
for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
|
|
4600
|
+
tr.step(toUndo.steps[j].invert(toUndo.docs[j]));
|
|
4601
|
+
}
|
|
4602
|
+
if (undoable.text) {
|
|
4603
|
+
const marks = tr.doc.resolve(undoable.from).marks();
|
|
4604
|
+
tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks));
|
|
4605
|
+
} else {
|
|
4606
|
+
tr.delete(undoable.from, undoable.to);
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4609
|
+
return true;
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
return false;
|
|
4613
|
+
};
|
|
4614
|
+
var unsetAllMarks = () => ({ tr, dispatch }) => {
|
|
4615
|
+
const { selection } = tr;
|
|
4616
|
+
const { empty, ranges } = selection;
|
|
4617
|
+
if (empty) {
|
|
4618
|
+
return true;
|
|
4619
|
+
}
|
|
4620
|
+
if (dispatch) {
|
|
4621
|
+
ranges.forEach((range) => {
|
|
4622
|
+
tr.removeMark(range.$from.pos, range.$to.pos);
|
|
4623
|
+
});
|
|
4624
|
+
}
|
|
4625
|
+
return true;
|
|
4626
|
+
};
|
|
4627
|
+
var unsetMark = (typeOrName, options = {}) => ({ tr, state, dispatch }) => {
|
|
4628
|
+
var _a;
|
|
4629
|
+
const { extendEmptyMarkRange = false } = options;
|
|
4630
|
+
const { selection } = tr;
|
|
4631
|
+
const type = getMarkType(typeOrName, state.schema);
|
|
4632
|
+
const { $from, empty, ranges } = selection;
|
|
4633
|
+
if (!dispatch) {
|
|
4634
|
+
return true;
|
|
4635
|
+
}
|
|
4636
|
+
if (empty && extendEmptyMarkRange) {
|
|
4637
|
+
let { from, to } = selection;
|
|
4638
|
+
const attrs = (_a = $from.marks().find((mark) => mark.type === type)) == null ? void 0 : _a.attrs;
|
|
4639
|
+
const range = getMarkRange($from, type, attrs);
|
|
4640
|
+
if (range) {
|
|
4641
|
+
from = range.from;
|
|
4642
|
+
to = range.to;
|
|
4643
|
+
}
|
|
4644
|
+
tr.removeMark(from, to, type);
|
|
4645
|
+
} else {
|
|
4646
|
+
ranges.forEach((range) => {
|
|
4647
|
+
tr.removeMark(range.$from.pos, range.$to.pos, type);
|
|
4648
|
+
});
|
|
4649
|
+
}
|
|
4650
|
+
tr.removeStoredMark(type);
|
|
4651
|
+
return true;
|
|
4652
|
+
};
|
|
4653
|
+
var unsetTextDirection = (position) => ({ tr, state, dispatch }) => {
|
|
4654
|
+
const { selection } = state;
|
|
4655
|
+
let from;
|
|
4656
|
+
let to;
|
|
4657
|
+
if (typeof position === "number") {
|
|
4658
|
+
from = position;
|
|
4659
|
+
to = position;
|
|
4660
|
+
} else if (position && "from" in position && "to" in position) {
|
|
4661
|
+
from = position.from;
|
|
4662
|
+
to = position.to;
|
|
4663
|
+
} else {
|
|
4664
|
+
from = selection.from;
|
|
4665
|
+
to = selection.to;
|
|
4666
|
+
}
|
|
4667
|
+
if (dispatch) {
|
|
4668
|
+
tr.doc.nodesBetween(from, to, (node, pos) => {
|
|
4669
|
+
if (node.isText) {
|
|
4670
|
+
return;
|
|
4671
|
+
}
|
|
4672
|
+
const newAttrs = { ...node.attrs };
|
|
4673
|
+
delete newAttrs.dir;
|
|
4674
|
+
tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
4675
|
+
});
|
|
4676
|
+
}
|
|
4677
|
+
return true;
|
|
4678
|
+
};
|
|
4679
|
+
var updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
|
4680
|
+
let nodeType = null;
|
|
4681
|
+
let markType = null;
|
|
4682
|
+
const schemaType = getSchemaTypeNameByName(
|
|
4683
|
+
typeof typeOrName === "string" ? typeOrName : typeOrName.name,
|
|
4684
|
+
state.schema
|
|
4685
|
+
);
|
|
4686
|
+
if (!schemaType) {
|
|
4687
|
+
return false;
|
|
4688
|
+
}
|
|
4689
|
+
if (schemaType === "node") {
|
|
4690
|
+
nodeType = getNodeType(typeOrName, state.schema);
|
|
4691
|
+
}
|
|
4692
|
+
if (schemaType === "mark") {
|
|
4693
|
+
markType = getMarkType(typeOrName, state.schema);
|
|
4694
|
+
}
|
|
4695
|
+
let canUpdate = false;
|
|
4696
|
+
tr.selection.ranges.forEach((range) => {
|
|
4697
|
+
const from = range.$from.pos;
|
|
4698
|
+
const to = range.$to.pos;
|
|
4699
|
+
let lastPos;
|
|
4700
|
+
let lastNode;
|
|
4701
|
+
let trimmedFrom;
|
|
4702
|
+
let trimmedTo;
|
|
4703
|
+
if (tr.selection.empty) {
|
|
4704
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
4705
|
+
if (nodeType && nodeType === node.type) {
|
|
4706
|
+
canUpdate = true;
|
|
4707
|
+
trimmedFrom = Math.max(pos, from);
|
|
4708
|
+
trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
4709
|
+
lastPos = pos;
|
|
4710
|
+
lastNode = node;
|
|
4711
|
+
}
|
|
4712
|
+
});
|
|
4713
|
+
} else {
|
|
4714
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
4715
|
+
if (pos < from && nodeType && nodeType === node.type) {
|
|
4716
|
+
canUpdate = true;
|
|
4717
|
+
trimmedFrom = Math.max(pos, from);
|
|
4718
|
+
trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
4719
|
+
lastPos = pos;
|
|
4720
|
+
lastNode = node;
|
|
4721
|
+
}
|
|
4722
|
+
if (pos >= from && pos <= to) {
|
|
4723
|
+
if (nodeType && nodeType === node.type) {
|
|
4724
|
+
canUpdate = true;
|
|
4725
|
+
if (dispatch) {
|
|
4726
|
+
tr.setNodeMarkup(pos, void 0, {
|
|
4727
|
+
...node.attrs,
|
|
4728
|
+
...attributes
|
|
4729
|
+
});
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
if (markType && node.marks.length) {
|
|
4733
|
+
node.marks.forEach((mark) => {
|
|
4734
|
+
if (markType === mark.type) {
|
|
4735
|
+
canUpdate = true;
|
|
4736
|
+
if (dispatch) {
|
|
4737
|
+
const trimmedFrom2 = Math.max(pos, from);
|
|
4738
|
+
const trimmedTo2 = Math.min(pos + node.nodeSize, to);
|
|
4739
|
+
tr.addMark(
|
|
4740
|
+
trimmedFrom2,
|
|
4741
|
+
trimmedTo2,
|
|
4742
|
+
markType.create({
|
|
4743
|
+
...mark.attrs,
|
|
4744
|
+
...attributes
|
|
4745
|
+
})
|
|
4746
|
+
);
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
});
|
|
4750
|
+
}
|
|
4751
|
+
}
|
|
4752
|
+
});
|
|
4753
|
+
}
|
|
4754
|
+
if (lastNode) {
|
|
4755
|
+
if (lastPos !== void 0 && dispatch) {
|
|
4756
|
+
tr.setNodeMarkup(lastPos, void 0, {
|
|
4757
|
+
...lastNode.attrs,
|
|
4758
|
+
...attributes
|
|
4759
|
+
});
|
|
4760
|
+
}
|
|
4761
|
+
if (markType && lastNode.marks.length) {
|
|
4762
|
+
lastNode.marks.forEach((mark) => {
|
|
4763
|
+
if (markType === mark.type && dispatch) {
|
|
4764
|
+
tr.addMark(
|
|
4765
|
+
trimmedFrom,
|
|
4766
|
+
trimmedTo,
|
|
4767
|
+
markType.create({
|
|
4768
|
+
...mark.attrs,
|
|
4769
|
+
...attributes
|
|
4770
|
+
})
|
|
4771
|
+
);
|
|
4772
|
+
}
|
|
4773
|
+
});
|
|
4774
|
+
}
|
|
4775
|
+
}
|
|
4776
|
+
});
|
|
4777
|
+
return canUpdate;
|
|
4778
|
+
};
|
|
4779
|
+
var wrapIn = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
|
|
4780
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
4781
|
+
return wrapIn$1(type, attributes)(state, dispatch);
|
|
4782
|
+
};
|
|
4783
|
+
var wrapInList = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
|
|
4784
|
+
const type = getNodeType(typeOrName, state.schema);
|
|
4785
|
+
return wrapInList$1(type, attributes)(state, dispatch);
|
|
4786
|
+
};
|
|
4787
|
+
function getType(value) {
|
|
4788
|
+
return Object.prototype.toString.call(value).slice(8, -1);
|
|
4789
|
+
}
|
|
4790
|
+
function isPlainObject(value) {
|
|
4791
|
+
if (getType(value) !== "Object") {
|
|
4792
|
+
return false;
|
|
4793
|
+
}
|
|
4794
|
+
return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype;
|
|
4795
|
+
}
|
|
4796
|
+
function mergeDeep(target, source) {
|
|
4797
|
+
const output = { ...target };
|
|
4798
|
+
if (isPlainObject(target) && isPlainObject(source)) {
|
|
4799
|
+
Object.keys(source).forEach((key) => {
|
|
4800
|
+
if (isPlainObject(source[key]) && isPlainObject(target[key])) {
|
|
4801
|
+
output[key] = mergeDeep(target[key], source[key]);
|
|
4802
|
+
} else {
|
|
4803
|
+
output[key] = source[key];
|
|
4804
|
+
}
|
|
4805
|
+
});
|
|
4806
|
+
}
|
|
4807
|
+
return output;
|
|
4808
|
+
}
|
|
4809
|
+
var Extendable = class {
|
|
4810
|
+
constructor(config = {}) {
|
|
4811
|
+
this.type = "extendable";
|
|
4812
|
+
this.parent = null;
|
|
4813
|
+
this.child = null;
|
|
4814
|
+
this.name = "";
|
|
4815
|
+
this.config = {
|
|
4816
|
+
name: this.name
|
|
4817
|
+
};
|
|
4818
|
+
this.config = {
|
|
4819
|
+
...this.config,
|
|
4820
|
+
...config
|
|
4821
|
+
};
|
|
4822
|
+
this.name = this.config.name;
|
|
4823
|
+
}
|
|
4824
|
+
get options() {
|
|
4825
|
+
return {
|
|
4826
|
+
...callOrReturn(
|
|
4827
|
+
getExtensionField(this, "addOptions", {
|
|
4828
|
+
name: this.name
|
|
4829
|
+
})
|
|
4830
|
+
) || {}
|
|
4831
|
+
};
|
|
4832
|
+
}
|
|
4833
|
+
get storage() {
|
|
4834
|
+
return {
|
|
4835
|
+
...callOrReturn(
|
|
4836
|
+
getExtensionField(this, "addStorage", {
|
|
4837
|
+
name: this.name,
|
|
4838
|
+
options: this.options
|
|
4839
|
+
})
|
|
4840
|
+
) || {}
|
|
4841
|
+
};
|
|
4842
|
+
}
|
|
4843
|
+
configure(options = {}) {
|
|
4844
|
+
const extension = this.extend({
|
|
4845
|
+
...this.config,
|
|
4846
|
+
addOptions: () => {
|
|
4847
|
+
return mergeDeep(this.options, options);
|
|
4848
|
+
}
|
|
4849
|
+
});
|
|
4850
|
+
extension.name = this.name;
|
|
4851
|
+
extension.parent = this.parent;
|
|
4852
|
+
return extension;
|
|
4853
|
+
}
|
|
4854
|
+
extend(extendedConfig = {}) {
|
|
4855
|
+
const extension = new this.constructor({ ...this.config, ...extendedConfig });
|
|
4856
|
+
extension.parent = this;
|
|
4857
|
+
this.child = extension;
|
|
4858
|
+
extension.name = "name" in extendedConfig ? extendedConfig.name : extension.parent.name;
|
|
4859
|
+
return extension;
|
|
4860
|
+
}
|
|
4861
|
+
};
|
|
4862
|
+
var extensions_exports = {};
|
|
4863
|
+
__export(extensions_exports, {
|
|
4864
|
+
ClipboardTextSerializer: () => ClipboardTextSerializer,
|
|
4865
|
+
Commands: () => Commands,
|
|
4866
|
+
Delete: () => Delete,
|
|
4867
|
+
Drop: () => Drop,
|
|
4868
|
+
Editable: () => Editable,
|
|
4869
|
+
FocusEvents: () => FocusEvents,
|
|
4870
|
+
Keymap: () => Keymap,
|
|
4871
|
+
Paste: () => Paste,
|
|
4872
|
+
Tabindex: () => Tabindex,
|
|
4873
|
+
TextDirection: () => TextDirection,
|
|
4874
|
+
focusEventsPluginKey: () => focusEventsPluginKey
|
|
4875
|
+
});
|
|
4876
|
+
var Extension = class _Extension extends Extendable {
|
|
4877
|
+
constructor() {
|
|
4878
|
+
super(...arguments);
|
|
4879
|
+
this.type = "extension";
|
|
4880
|
+
}
|
|
4881
|
+
/**
|
|
4882
|
+
* Create a new Extension instance
|
|
4883
|
+
* @param config - Extension configuration object or a function that returns a configuration object
|
|
4884
|
+
*/
|
|
4885
|
+
static create(config = {}) {
|
|
4886
|
+
const resolvedConfig = typeof config === "function" ? config() : config;
|
|
4887
|
+
return new _Extension(resolvedConfig);
|
|
4888
|
+
}
|
|
4889
|
+
configure(options) {
|
|
4890
|
+
return super.configure(options);
|
|
4891
|
+
}
|
|
4892
|
+
extend(extendedConfig) {
|
|
4893
|
+
const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig;
|
|
4894
|
+
return super.extend(resolvedConfig);
|
|
4895
|
+
}
|
|
4896
|
+
};
|
|
4897
|
+
var ClipboardTextSerializer = Extension.create({
|
|
4898
|
+
name: "clipboardTextSerializer",
|
|
4899
|
+
addOptions() {
|
|
4900
|
+
return {
|
|
4901
|
+
blockSeparator: void 0
|
|
4902
|
+
};
|
|
4903
|
+
},
|
|
4904
|
+
addProseMirrorPlugins() {
|
|
4905
|
+
return [
|
|
4906
|
+
new Plugin({
|
|
4907
|
+
key: new PluginKey("clipboardTextSerializer"),
|
|
4908
|
+
props: {
|
|
4909
|
+
clipboardTextSerializer: () => {
|
|
4910
|
+
const { editor } = this;
|
|
4911
|
+
const { state, schema } = editor;
|
|
4912
|
+
const { doc, selection } = state;
|
|
4913
|
+
const { ranges } = selection;
|
|
4914
|
+
const from = Math.min(...ranges.map((range2) => range2.$from.pos));
|
|
4915
|
+
const to = Math.max(...ranges.map((range2) => range2.$to.pos));
|
|
4916
|
+
const textSerializers = getTextSerializersFromSchema(schema);
|
|
4917
|
+
const range = { from, to };
|
|
4918
|
+
return getTextBetween(doc, range, {
|
|
4919
|
+
...this.options.blockSeparator !== void 0 ? { blockSeparator: this.options.blockSeparator } : {},
|
|
4920
|
+
textSerializers
|
|
4921
|
+
});
|
|
4922
|
+
}
|
|
4923
|
+
}
|
|
4924
|
+
})
|
|
4925
|
+
];
|
|
4926
|
+
}
|
|
4927
|
+
});
|
|
4928
|
+
var Commands = Extension.create({
|
|
4929
|
+
name: "commands",
|
|
4930
|
+
addCommands() {
|
|
4931
|
+
return {
|
|
4932
|
+
...commands_exports
|
|
4933
|
+
};
|
|
4934
|
+
}
|
|
4935
|
+
});
|
|
4936
|
+
var Delete = Extension.create({
|
|
4937
|
+
name: "delete",
|
|
4938
|
+
onUpdate({ transaction, appendedTransactions }) {
|
|
4939
|
+
var _a, _b, _c;
|
|
4940
|
+
const callback = () => {
|
|
4941
|
+
var _a2, _b2, _c2, _d;
|
|
4942
|
+
if ((_d = (_c2 = (_b2 = (_a2 = this.editor.options.coreExtensionOptions) == null ? void 0 : _a2.delete) == null ? void 0 : _b2.filterTransaction) == null ? void 0 : _c2.call(_b2, transaction)) != null ? _d : transaction.getMeta("y-sync$")) {
|
|
4943
|
+
return;
|
|
4944
|
+
}
|
|
4945
|
+
const nextTransaction = combineTransactionSteps(transaction.before, [transaction, ...appendedTransactions]);
|
|
4946
|
+
const changes = getChangedRanges(nextTransaction);
|
|
4947
|
+
changes.forEach((change) => {
|
|
4948
|
+
if (nextTransaction.mapping.mapResult(change.oldRange.from).deletedAfter && nextTransaction.mapping.mapResult(change.oldRange.to).deletedBefore) {
|
|
4949
|
+
nextTransaction.before.nodesBetween(change.oldRange.from, change.oldRange.to, (node, from) => {
|
|
4950
|
+
const to = from + node.nodeSize - 2;
|
|
4951
|
+
const isFullyWithinRange = change.oldRange.from <= from && to <= change.oldRange.to;
|
|
4952
|
+
this.editor.emit("delete", {
|
|
4953
|
+
type: "node",
|
|
4954
|
+
node,
|
|
4955
|
+
from,
|
|
4956
|
+
to,
|
|
4957
|
+
newFrom: nextTransaction.mapping.map(from),
|
|
4958
|
+
newTo: nextTransaction.mapping.map(to),
|
|
4959
|
+
deletedRange: change.oldRange,
|
|
4960
|
+
newRange: change.newRange,
|
|
4961
|
+
partial: !isFullyWithinRange,
|
|
4962
|
+
editor: this.editor,
|
|
4963
|
+
transaction,
|
|
4964
|
+
combinedTransform: nextTransaction
|
|
4965
|
+
});
|
|
4966
|
+
});
|
|
4967
|
+
}
|
|
4968
|
+
});
|
|
4969
|
+
const mapping = nextTransaction.mapping;
|
|
4970
|
+
nextTransaction.steps.forEach((step, index) => {
|
|
4971
|
+
var _a3, _b3;
|
|
4972
|
+
if (step instanceof RemoveMarkStep) {
|
|
4973
|
+
const newStart = mapping.slice(index).map(step.from, -1);
|
|
4974
|
+
const newEnd = mapping.slice(index).map(step.to);
|
|
4975
|
+
const oldStart = mapping.invert().map(newStart, -1);
|
|
4976
|
+
const oldEnd = mapping.invert().map(newEnd);
|
|
4977
|
+
const foundBeforeMark = (_a3 = nextTransaction.doc.nodeAt(newStart - 1)) == null ? void 0 : _a3.marks.some((mark) => mark.eq(step.mark));
|
|
4978
|
+
const foundAfterMark = (_b3 = nextTransaction.doc.nodeAt(newEnd)) == null ? void 0 : _b3.marks.some((mark) => mark.eq(step.mark));
|
|
4979
|
+
this.editor.emit("delete", {
|
|
4980
|
+
type: "mark",
|
|
4981
|
+
mark: step.mark,
|
|
4982
|
+
from: step.from,
|
|
4983
|
+
to: step.to,
|
|
4984
|
+
deletedRange: {
|
|
4985
|
+
from: oldStart,
|
|
4986
|
+
to: oldEnd
|
|
4987
|
+
},
|
|
4988
|
+
newRange: {
|
|
4989
|
+
from: newStart,
|
|
4990
|
+
to: newEnd
|
|
4991
|
+
},
|
|
4992
|
+
partial: Boolean(foundAfterMark || foundBeforeMark),
|
|
4993
|
+
editor: this.editor,
|
|
4994
|
+
transaction,
|
|
4995
|
+
combinedTransform: nextTransaction
|
|
4996
|
+
});
|
|
4997
|
+
}
|
|
4998
|
+
});
|
|
4999
|
+
};
|
|
5000
|
+
if ((_c = (_b = (_a = this.editor.options.coreExtensionOptions) == null ? void 0 : _a.delete) == null ? void 0 : _b.async) != null ? _c : true) {
|
|
5001
|
+
setTimeout(callback, 0);
|
|
5002
|
+
} else {
|
|
5003
|
+
callback();
|
|
5004
|
+
}
|
|
5005
|
+
}
|
|
5006
|
+
});
|
|
5007
|
+
var Drop = Extension.create({
|
|
5008
|
+
name: "drop",
|
|
5009
|
+
addProseMirrorPlugins() {
|
|
5010
|
+
return [
|
|
5011
|
+
new Plugin({
|
|
5012
|
+
key: new PluginKey("tiptapDrop"),
|
|
5013
|
+
props: {
|
|
5014
|
+
handleDrop: (_, e, slice, moved) => {
|
|
5015
|
+
this.editor.emit("drop", {
|
|
5016
|
+
editor: this.editor,
|
|
5017
|
+
event: e,
|
|
5018
|
+
slice,
|
|
5019
|
+
moved
|
|
5020
|
+
});
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
})
|
|
5024
|
+
];
|
|
5025
|
+
}
|
|
5026
|
+
});
|
|
5027
|
+
var Editable = Extension.create({
|
|
5028
|
+
name: "editable",
|
|
5029
|
+
addProseMirrorPlugins() {
|
|
5030
|
+
return [
|
|
5031
|
+
new Plugin({
|
|
5032
|
+
key: new PluginKey("editable"),
|
|
5033
|
+
props: {
|
|
5034
|
+
editable: () => this.editor.options.editable
|
|
5035
|
+
}
|
|
5036
|
+
})
|
|
5037
|
+
];
|
|
5038
|
+
}
|
|
5039
|
+
});
|
|
5040
|
+
var focusEventsPluginKey = new PluginKey("focusEvents");
|
|
5041
|
+
var FocusEvents = Extension.create({
|
|
5042
|
+
name: "focusEvents",
|
|
5043
|
+
addProseMirrorPlugins() {
|
|
5044
|
+
const { editor } = this;
|
|
5045
|
+
return [
|
|
5046
|
+
new Plugin({
|
|
5047
|
+
key: focusEventsPluginKey,
|
|
5048
|
+
props: {
|
|
5049
|
+
handleDOMEvents: {
|
|
5050
|
+
focus: (view, event) => {
|
|
5051
|
+
editor.isFocused = true;
|
|
5052
|
+
const transaction = editor.state.tr.setMeta("focus", { event }).setMeta("addToHistory", false);
|
|
5053
|
+
view.dispatch(transaction);
|
|
5054
|
+
return false;
|
|
5055
|
+
},
|
|
5056
|
+
blur: (view, event) => {
|
|
5057
|
+
editor.isFocused = false;
|
|
5058
|
+
const transaction = editor.state.tr.setMeta("blur", { event }).setMeta("addToHistory", false);
|
|
5059
|
+
view.dispatch(transaction);
|
|
5060
|
+
return false;
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
}
|
|
5064
|
+
})
|
|
5065
|
+
];
|
|
5066
|
+
}
|
|
5067
|
+
});
|
|
5068
|
+
var Keymap = Extension.create({
|
|
5069
|
+
name: "keymap",
|
|
5070
|
+
addKeyboardShortcuts() {
|
|
5071
|
+
const handleBackspace = () => this.editor.commands.first(({ commands }) => [
|
|
5072
|
+
() => commands.undoInputRule(),
|
|
5073
|
+
// maybe convert first text block node to default node
|
|
5074
|
+
() => commands.command(({ tr }) => {
|
|
5075
|
+
const { selection, doc } = tr;
|
|
5076
|
+
const { empty, $anchor } = selection;
|
|
5077
|
+
const { pos, parent } = $anchor;
|
|
5078
|
+
const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr.doc.resolve(pos - 1) : $anchor;
|
|
5079
|
+
const parentIsIsolating = $parentPos.parent.type.spec.isolating;
|
|
5080
|
+
const parentPos = $anchor.pos - $anchor.parentOffset;
|
|
5081
|
+
const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos : Selection.atStart(doc).from === pos;
|
|
5082
|
+
if (!empty || !parent.type.isTextblock || parent.textContent.length || !isAtStart || isAtStart && $anchor.parent.type.name === "paragraph") {
|
|
5083
|
+
return false;
|
|
5084
|
+
}
|
|
5085
|
+
return commands.clearNodes();
|
|
5086
|
+
}),
|
|
5087
|
+
() => commands.deleteSelection(),
|
|
5088
|
+
() => commands.joinBackward(),
|
|
5089
|
+
() => commands.selectNodeBackward()
|
|
5090
|
+
]);
|
|
5091
|
+
const handleDelete = () => this.editor.commands.first(({ commands }) => [
|
|
5092
|
+
() => commands.deleteSelection(),
|
|
5093
|
+
() => commands.deleteCurrentNode(),
|
|
5094
|
+
() => commands.joinForward(),
|
|
5095
|
+
() => commands.selectNodeForward()
|
|
5096
|
+
]);
|
|
5097
|
+
const handleEnter = () => this.editor.commands.first(({ commands }) => [
|
|
5098
|
+
() => commands.newlineInCode(),
|
|
5099
|
+
() => commands.createParagraphNear(),
|
|
5100
|
+
() => commands.liftEmptyBlock(),
|
|
5101
|
+
() => commands.splitBlock()
|
|
5102
|
+
]);
|
|
5103
|
+
const baseKeymap = {
|
|
5104
|
+
Enter: handleEnter,
|
|
5105
|
+
"Mod-Enter": () => this.editor.commands.exitCode(),
|
|
5106
|
+
Backspace: handleBackspace,
|
|
5107
|
+
"Mod-Backspace": handleBackspace,
|
|
5108
|
+
"Shift-Backspace": handleBackspace,
|
|
5109
|
+
Delete: handleDelete,
|
|
5110
|
+
"Mod-Delete": handleDelete,
|
|
5111
|
+
"Mod-a": () => this.editor.commands.selectAll()
|
|
5112
|
+
};
|
|
5113
|
+
const pcKeymap = {
|
|
5114
|
+
...baseKeymap
|
|
5115
|
+
};
|
|
5116
|
+
const macKeymap = {
|
|
5117
|
+
...baseKeymap,
|
|
5118
|
+
"Ctrl-h": handleBackspace,
|
|
5119
|
+
"Alt-Backspace": handleBackspace,
|
|
5120
|
+
"Ctrl-d": handleDelete,
|
|
5121
|
+
"Ctrl-Alt-Backspace": handleDelete,
|
|
5122
|
+
"Alt-Delete": handleDelete,
|
|
5123
|
+
"Alt-d": handleDelete,
|
|
5124
|
+
"Ctrl-a": () => this.editor.commands.selectTextblockStart(),
|
|
5125
|
+
"Ctrl-e": () => this.editor.commands.selectTextblockEnd()
|
|
5126
|
+
};
|
|
5127
|
+
if (isiOS() || isMacOS()) {
|
|
5128
|
+
return macKeymap;
|
|
5129
|
+
}
|
|
5130
|
+
return pcKeymap;
|
|
5131
|
+
},
|
|
5132
|
+
addProseMirrorPlugins() {
|
|
5133
|
+
return [
|
|
5134
|
+
// With this plugin we check if the whole document was selected and deleted.
|
|
5135
|
+
// In this case we will additionally call `clearNodes()` to convert e.g. a heading
|
|
5136
|
+
// to a paragraph if necessary.
|
|
5137
|
+
// This is an alternative to ProseMirror's `AllSelection`, which doesn’t work well
|
|
5138
|
+
// with many other commands.
|
|
5139
|
+
new Plugin({
|
|
5140
|
+
key: new PluginKey("clearDocument"),
|
|
5141
|
+
appendTransaction: (transactions, oldState, newState) => {
|
|
5142
|
+
if (transactions.some((tr2) => tr2.getMeta("composition"))) {
|
|
5143
|
+
return;
|
|
5144
|
+
}
|
|
5145
|
+
const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
|
|
5146
|
+
const ignoreTr = transactions.some((transaction) => transaction.getMeta("preventClearDocument"));
|
|
5147
|
+
if (!docChanges || ignoreTr) {
|
|
5148
|
+
return;
|
|
5149
|
+
}
|
|
5150
|
+
const { empty, from, to } = oldState.selection;
|
|
5151
|
+
const allFrom = Selection.atStart(oldState.doc).from;
|
|
5152
|
+
const allEnd = Selection.atEnd(oldState.doc).to;
|
|
5153
|
+
const allWasSelected = from === allFrom && to === allEnd;
|
|
5154
|
+
if (empty || !allWasSelected) {
|
|
5155
|
+
return;
|
|
5156
|
+
}
|
|
5157
|
+
const isEmpty = isNodeEmpty(newState.doc);
|
|
5158
|
+
if (!isEmpty) {
|
|
5159
|
+
return;
|
|
5160
|
+
}
|
|
5161
|
+
const tr = newState.tr;
|
|
5162
|
+
const state = createChainableState({
|
|
5163
|
+
state: newState,
|
|
5164
|
+
transaction: tr
|
|
5165
|
+
});
|
|
5166
|
+
const { commands } = new CommandManager({
|
|
5167
|
+
editor: this.editor,
|
|
5168
|
+
state
|
|
5169
|
+
});
|
|
5170
|
+
commands.clearNodes();
|
|
5171
|
+
if (!tr.steps.length) {
|
|
5172
|
+
return;
|
|
5173
|
+
}
|
|
5174
|
+
return tr;
|
|
5175
|
+
}
|
|
5176
|
+
})
|
|
5177
|
+
];
|
|
5178
|
+
}
|
|
5179
|
+
});
|
|
5180
|
+
var Paste = Extension.create({
|
|
5181
|
+
name: "paste",
|
|
5182
|
+
addProseMirrorPlugins() {
|
|
5183
|
+
return [
|
|
5184
|
+
new Plugin({
|
|
5185
|
+
key: new PluginKey("tiptapPaste"),
|
|
5186
|
+
props: {
|
|
5187
|
+
handlePaste: (_view, e, slice) => {
|
|
5188
|
+
this.editor.emit("paste", {
|
|
5189
|
+
editor: this.editor,
|
|
5190
|
+
event: e,
|
|
5191
|
+
slice
|
|
5192
|
+
});
|
|
5193
|
+
}
|
|
5194
|
+
}
|
|
5195
|
+
})
|
|
5196
|
+
];
|
|
5197
|
+
}
|
|
5198
|
+
});
|
|
5199
|
+
var Tabindex = Extension.create({
|
|
5200
|
+
name: "tabindex",
|
|
5201
|
+
addProseMirrorPlugins() {
|
|
5202
|
+
return [
|
|
5203
|
+
new Plugin({
|
|
5204
|
+
key: new PluginKey("tabindex"),
|
|
5205
|
+
props: {
|
|
5206
|
+
attributes: () => this.editor.isEditable ? { tabindex: "0" } : {}
|
|
5207
|
+
}
|
|
5208
|
+
})
|
|
5209
|
+
];
|
|
5210
|
+
}
|
|
5211
|
+
});
|
|
5212
|
+
var TextDirection = Extension.create({
|
|
5213
|
+
name: "textDirection",
|
|
5214
|
+
addOptions() {
|
|
5215
|
+
return {
|
|
5216
|
+
direction: void 0
|
|
5217
|
+
};
|
|
5218
|
+
},
|
|
5219
|
+
addGlobalAttributes() {
|
|
5220
|
+
if (!this.options.direction) {
|
|
5221
|
+
return [];
|
|
5222
|
+
}
|
|
5223
|
+
const { nodeExtensions } = splitExtensions(this.extensions);
|
|
5224
|
+
return [
|
|
5225
|
+
{
|
|
5226
|
+
types: nodeExtensions.filter((extension) => extension.name !== "text").map((extension) => extension.name),
|
|
5227
|
+
attributes: {
|
|
5228
|
+
dir: {
|
|
5229
|
+
default: this.options.direction,
|
|
5230
|
+
parseHTML: (element) => {
|
|
5231
|
+
const dir = element.getAttribute("dir");
|
|
5232
|
+
if (dir && (dir === "ltr" || dir === "rtl" || dir === "auto")) {
|
|
5233
|
+
return dir;
|
|
5234
|
+
}
|
|
5235
|
+
return this.options.direction;
|
|
5236
|
+
},
|
|
5237
|
+
renderHTML: (attributes) => {
|
|
5238
|
+
if (!attributes.dir) {
|
|
5239
|
+
return {};
|
|
5240
|
+
}
|
|
5241
|
+
return {
|
|
5242
|
+
dir: attributes.dir
|
|
5243
|
+
};
|
|
5244
|
+
}
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
];
|
|
5249
|
+
},
|
|
5250
|
+
addProseMirrorPlugins() {
|
|
5251
|
+
return [
|
|
5252
|
+
new Plugin({
|
|
5253
|
+
key: new PluginKey("textDirection"),
|
|
5254
|
+
props: {
|
|
5255
|
+
attributes: () => {
|
|
5256
|
+
const direction = this.options.direction;
|
|
5257
|
+
if (!direction) {
|
|
5258
|
+
return {};
|
|
5259
|
+
}
|
|
5260
|
+
return {
|
|
5261
|
+
dir: direction
|
|
5262
|
+
};
|
|
5263
|
+
}
|
|
5264
|
+
}
|
|
5265
|
+
})
|
|
5266
|
+
];
|
|
5267
|
+
}
|
|
5268
|
+
});
|
|
5269
|
+
var markdown_exports = {};
|
|
5270
|
+
__export(markdown_exports, {
|
|
5271
|
+
createAtomBlockMarkdownSpec: () => createAtomBlockMarkdownSpec,
|
|
5272
|
+
createBlockMarkdownSpec: () => createBlockMarkdownSpec,
|
|
5273
|
+
createInlineMarkdownSpec: () => createInlineMarkdownSpec,
|
|
5274
|
+
parseAttributes: () => parseAttributes,
|
|
5275
|
+
parseIndentedBlocks: () => parseIndentedBlocks,
|
|
5276
|
+
renderNestedMarkdownContent: () => renderNestedMarkdownContent,
|
|
5277
|
+
serializeAttributes: () => serializeAttributes
|
|
5278
|
+
});
|
|
5279
|
+
function parseAttributes(attrString) {
|
|
5280
|
+
if (!(attrString == null ? void 0 : attrString.trim())) {
|
|
5281
|
+
return {};
|
|
5282
|
+
}
|
|
5283
|
+
const attributes = {};
|
|
5284
|
+
const quotedStrings = [];
|
|
5285
|
+
const tempString = attrString.replace(/["']([^"']*)["']/g, (match) => {
|
|
5286
|
+
quotedStrings.push(match);
|
|
5287
|
+
return `__QUOTED_${quotedStrings.length - 1}__`;
|
|
5288
|
+
});
|
|
5289
|
+
const classMatches = tempString.match(/(?:^|\s)\.([a-zA-Z][\w-]*)/g);
|
|
5290
|
+
if (classMatches) {
|
|
5291
|
+
const classes = classMatches.map((match) => match.trim().slice(1));
|
|
5292
|
+
attributes.class = classes.join(" ");
|
|
5293
|
+
}
|
|
5294
|
+
const idMatch = tempString.match(/(?:^|\s)#([a-zA-Z][\w-]*)/);
|
|
5295
|
+
if (idMatch) {
|
|
5296
|
+
attributes.id = idMatch[1];
|
|
5297
|
+
}
|
|
5298
|
+
const kvRegex = /([a-zA-Z][\w-]*)\s*=\s*(__QUOTED_\d+__)/g;
|
|
5299
|
+
const kvMatches = Array.from(tempString.matchAll(kvRegex));
|
|
5300
|
+
kvMatches.forEach(([, key, quotedRef]) => {
|
|
5301
|
+
var _a;
|
|
5302
|
+
const quotedIndex = parseInt(((_a = quotedRef.match(/__QUOTED_(\d+)__/)) == null ? void 0 : _a[1]) || "0", 10);
|
|
5303
|
+
const quotedValue = quotedStrings[quotedIndex];
|
|
5304
|
+
if (quotedValue) {
|
|
5305
|
+
attributes[key] = quotedValue.slice(1, -1);
|
|
5306
|
+
}
|
|
5307
|
+
});
|
|
5308
|
+
const cleanString = tempString.replace(/(?:^|\s)\.([a-zA-Z][\w-]*)/g, "").replace(/(?:^|\s)#([a-zA-Z][\w-]*)/g, "").replace(/([a-zA-Z][\w-]*)\s*=\s*__QUOTED_\d+__/g, "").trim();
|
|
5309
|
+
if (cleanString) {
|
|
5310
|
+
const booleanAttrs = cleanString.split(/\s+/).filter(Boolean);
|
|
5311
|
+
booleanAttrs.forEach((attr) => {
|
|
5312
|
+
if (attr.match(/^[a-zA-Z][\w-]*$/)) {
|
|
5313
|
+
attributes[attr] = true;
|
|
5314
|
+
}
|
|
5315
|
+
});
|
|
5316
|
+
}
|
|
5317
|
+
return attributes;
|
|
5318
|
+
}
|
|
5319
|
+
function serializeAttributes(attributes) {
|
|
5320
|
+
if (!attributes || Object.keys(attributes).length === 0) {
|
|
5321
|
+
return "";
|
|
5322
|
+
}
|
|
5323
|
+
const parts = [];
|
|
5324
|
+
if (attributes.class) {
|
|
5325
|
+
const classes = String(attributes.class).split(/\s+/).filter(Boolean);
|
|
5326
|
+
classes.forEach((cls) => parts.push(`.${cls}`));
|
|
5327
|
+
}
|
|
5328
|
+
if (attributes.id) {
|
|
5329
|
+
parts.push(`#${attributes.id}`);
|
|
5330
|
+
}
|
|
5331
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
5332
|
+
if (key === "class" || key === "id") {
|
|
5333
|
+
return;
|
|
5334
|
+
}
|
|
5335
|
+
if (value === true) {
|
|
5336
|
+
parts.push(key);
|
|
5337
|
+
} else if (value !== false && value != null) {
|
|
5338
|
+
parts.push(`${key}="${String(value)}"`);
|
|
5339
|
+
}
|
|
5340
|
+
});
|
|
5341
|
+
return parts.join(" ");
|
|
5342
|
+
}
|
|
5343
|
+
function createAtomBlockMarkdownSpec(options) {
|
|
5344
|
+
const {
|
|
5345
|
+
nodeName,
|
|
5346
|
+
name: markdownName,
|
|
5347
|
+
parseAttributes: parseAttributes2 = parseAttributes,
|
|
5348
|
+
serializeAttributes: serializeAttributes2 = serializeAttributes,
|
|
5349
|
+
defaultAttributes = {},
|
|
5350
|
+
requiredAttributes = [],
|
|
5351
|
+
allowedAttributes
|
|
5352
|
+
} = options;
|
|
5353
|
+
const blockName = markdownName || nodeName;
|
|
5354
|
+
const filterAttributes = (attrs) => {
|
|
5355
|
+
if (!allowedAttributes) {
|
|
5356
|
+
return attrs;
|
|
5357
|
+
}
|
|
5358
|
+
const filtered = {};
|
|
5359
|
+
allowedAttributes.forEach((key) => {
|
|
5360
|
+
if (key in attrs) {
|
|
5361
|
+
filtered[key] = attrs[key];
|
|
5362
|
+
}
|
|
5363
|
+
});
|
|
5364
|
+
return filtered;
|
|
5365
|
+
};
|
|
5366
|
+
return {
|
|
5367
|
+
parseMarkdown: (token, h2) => {
|
|
5368
|
+
const attrs = { ...defaultAttributes, ...token.attributes };
|
|
5369
|
+
return h2.createNode(nodeName, attrs, []);
|
|
5370
|
+
},
|
|
5371
|
+
markdownTokenizer: {
|
|
5372
|
+
name: nodeName,
|
|
5373
|
+
level: "block",
|
|
5374
|
+
start(src) {
|
|
5375
|
+
var _a;
|
|
5376
|
+
const regex = new RegExp(`^:::${blockName}(?:\\s|$)`, "m");
|
|
5377
|
+
const index = (_a = src.match(regex)) == null ? void 0 : _a.index;
|
|
5378
|
+
return index !== void 0 ? index : -1;
|
|
5379
|
+
},
|
|
5380
|
+
tokenize(src, _tokens, _lexer) {
|
|
5381
|
+
const regex = new RegExp(`^:::${blockName}(?:\\s+\\{([^}]*)\\})?\\s*:::(?:\\n|$)`);
|
|
5382
|
+
const match = src.match(regex);
|
|
5383
|
+
if (!match) {
|
|
5384
|
+
return void 0;
|
|
5385
|
+
}
|
|
5386
|
+
const attrString = match[1] || "";
|
|
5387
|
+
const attributes = parseAttributes2(attrString);
|
|
5388
|
+
const missingRequired = requiredAttributes.find((required) => !(required in attributes));
|
|
5389
|
+
if (missingRequired) {
|
|
5390
|
+
return void 0;
|
|
5391
|
+
}
|
|
5392
|
+
return {
|
|
5393
|
+
type: nodeName,
|
|
5394
|
+
raw: match[0],
|
|
5395
|
+
attributes
|
|
5396
|
+
};
|
|
5397
|
+
}
|
|
5398
|
+
},
|
|
5399
|
+
renderMarkdown: (node) => {
|
|
5400
|
+
const filteredAttrs = filterAttributes(node.attrs || {});
|
|
5401
|
+
const attrs = serializeAttributes2(filteredAttrs);
|
|
5402
|
+
const attrString = attrs ? ` {${attrs}}` : "";
|
|
5403
|
+
return `:::${blockName}${attrString} :::`;
|
|
5404
|
+
}
|
|
5405
|
+
};
|
|
5406
|
+
}
|
|
5407
|
+
function createBlockMarkdownSpec(options) {
|
|
5408
|
+
const {
|
|
5409
|
+
nodeName,
|
|
5410
|
+
name: markdownName,
|
|
5411
|
+
getContent,
|
|
5412
|
+
parseAttributes: parseAttributes2 = parseAttributes,
|
|
5413
|
+
serializeAttributes: serializeAttributes2 = serializeAttributes,
|
|
5414
|
+
defaultAttributes = {},
|
|
5415
|
+
content = "block",
|
|
5416
|
+
allowedAttributes
|
|
5417
|
+
} = options;
|
|
5418
|
+
const blockName = markdownName || nodeName;
|
|
5419
|
+
const filterAttributes = (attrs) => {
|
|
5420
|
+
if (!allowedAttributes) {
|
|
5421
|
+
return attrs;
|
|
5422
|
+
}
|
|
5423
|
+
const filtered = {};
|
|
5424
|
+
allowedAttributes.forEach((key) => {
|
|
5425
|
+
if (key in attrs) {
|
|
5426
|
+
filtered[key] = attrs[key];
|
|
5427
|
+
}
|
|
5428
|
+
});
|
|
5429
|
+
return filtered;
|
|
5430
|
+
};
|
|
5431
|
+
return {
|
|
5432
|
+
parseMarkdown: (token, h2) => {
|
|
5433
|
+
let nodeContent;
|
|
5434
|
+
if (getContent) {
|
|
5435
|
+
const contentResult = getContent(token);
|
|
5436
|
+
nodeContent = typeof contentResult === "string" ? [{ type: "text", text: contentResult }] : contentResult;
|
|
5437
|
+
} else if (content === "block") {
|
|
5438
|
+
nodeContent = h2.parseChildren(token.tokens || []);
|
|
5439
|
+
} else {
|
|
5440
|
+
nodeContent = h2.parseInline(token.tokens || []);
|
|
5441
|
+
}
|
|
5442
|
+
const attrs = { ...defaultAttributes, ...token.attributes };
|
|
5443
|
+
return h2.createNode(nodeName, attrs, nodeContent);
|
|
5444
|
+
},
|
|
5445
|
+
markdownTokenizer: {
|
|
5446
|
+
name: nodeName,
|
|
5447
|
+
level: "block",
|
|
5448
|
+
start(src) {
|
|
5449
|
+
var _a;
|
|
5450
|
+
const regex = new RegExp(`^:::${blockName}`, "m");
|
|
5451
|
+
const index = (_a = src.match(regex)) == null ? void 0 : _a.index;
|
|
5452
|
+
return index !== void 0 ? index : -1;
|
|
5453
|
+
},
|
|
5454
|
+
tokenize(src, _tokens, lexer) {
|
|
5455
|
+
var _a;
|
|
5456
|
+
const openingRegex = new RegExp(`^:::${blockName}(?:\\s+\\{([^}]*)\\})?\\s*\\n`);
|
|
5457
|
+
const openingMatch = src.match(openingRegex);
|
|
5458
|
+
if (!openingMatch) {
|
|
5459
|
+
return void 0;
|
|
5460
|
+
}
|
|
5461
|
+
const [openingTag, attrString = ""] = openingMatch;
|
|
5462
|
+
const attributes = parseAttributes2(attrString);
|
|
5463
|
+
let level = 1;
|
|
5464
|
+
const position = openingTag.length;
|
|
5465
|
+
let matchedContent = "";
|
|
5466
|
+
const blockPattern = /^:::([\w-]*)(\s.*)?/gm;
|
|
5467
|
+
const remaining = src.slice(position);
|
|
5468
|
+
blockPattern.lastIndex = 0;
|
|
5469
|
+
for (; ; ) {
|
|
5470
|
+
const match = blockPattern.exec(remaining);
|
|
5471
|
+
if (match === null) {
|
|
5472
|
+
break;
|
|
5473
|
+
}
|
|
5474
|
+
const matchPos = match.index;
|
|
5475
|
+
const blockType = match[1];
|
|
5476
|
+
if ((_a = match[2]) == null ? void 0 : _a.endsWith(":::")) {
|
|
5477
|
+
continue;
|
|
5478
|
+
}
|
|
5479
|
+
if (blockType) {
|
|
5480
|
+
level += 1;
|
|
5481
|
+
} else {
|
|
5482
|
+
level -= 1;
|
|
5483
|
+
if (level === 0) {
|
|
5484
|
+
const rawContent = remaining.slice(0, matchPos);
|
|
5485
|
+
matchedContent = rawContent.trim();
|
|
5486
|
+
const fullMatch = src.slice(0, position + matchPos + match[0].length);
|
|
5487
|
+
let contentTokens = [];
|
|
5488
|
+
if (matchedContent) {
|
|
5489
|
+
if (content === "block") {
|
|
5490
|
+
contentTokens = lexer.blockTokens(rawContent);
|
|
5491
|
+
contentTokens.forEach((token) => {
|
|
5492
|
+
if (token.text && (!token.tokens || token.tokens.length === 0)) {
|
|
5493
|
+
token.tokens = lexer.inlineTokens(token.text);
|
|
5494
|
+
}
|
|
5495
|
+
});
|
|
5496
|
+
while (contentTokens.length > 0) {
|
|
5497
|
+
const lastToken = contentTokens[contentTokens.length - 1];
|
|
5498
|
+
if (lastToken.type === "paragraph" && (!lastToken.text || lastToken.text.trim() === "")) {
|
|
5499
|
+
contentTokens.pop();
|
|
5500
|
+
} else {
|
|
5501
|
+
break;
|
|
5502
|
+
}
|
|
5503
|
+
}
|
|
5504
|
+
} else {
|
|
5505
|
+
contentTokens = lexer.inlineTokens(matchedContent);
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
return {
|
|
5509
|
+
type: nodeName,
|
|
5510
|
+
raw: fullMatch,
|
|
5511
|
+
attributes,
|
|
5512
|
+
content: matchedContent,
|
|
5513
|
+
tokens: contentTokens
|
|
5514
|
+
};
|
|
5515
|
+
}
|
|
5516
|
+
}
|
|
5517
|
+
}
|
|
5518
|
+
return void 0;
|
|
5519
|
+
}
|
|
5520
|
+
},
|
|
5521
|
+
renderMarkdown: (node, h2) => {
|
|
5522
|
+
const filteredAttrs = filterAttributes(node.attrs || {});
|
|
5523
|
+
const attrs = serializeAttributes2(filteredAttrs);
|
|
5524
|
+
const attrString = attrs ? ` {${attrs}}` : "";
|
|
5525
|
+
const renderedContent = h2.renderChildren(node.content || [], "\n\n");
|
|
5526
|
+
return `:::${blockName}${attrString}
|
|
5527
|
+
|
|
5528
|
+
${renderedContent}
|
|
5529
|
+
|
|
5530
|
+
:::`;
|
|
5531
|
+
}
|
|
5532
|
+
};
|
|
5533
|
+
}
|
|
5534
|
+
function parseShortcodeAttributes(attrString) {
|
|
5535
|
+
if (!attrString.trim()) {
|
|
5536
|
+
return {};
|
|
5537
|
+
}
|
|
5538
|
+
const attributes = {};
|
|
5539
|
+
const regex = /(\w+)=(?:"([^"]*)"|'([^']*)')/g;
|
|
5540
|
+
let match = regex.exec(attrString);
|
|
5541
|
+
while (match !== null) {
|
|
5542
|
+
const [, key, doubleQuoted, singleQuoted] = match;
|
|
5543
|
+
attributes[key] = doubleQuoted || singleQuoted;
|
|
5544
|
+
match = regex.exec(attrString);
|
|
5545
|
+
}
|
|
5546
|
+
return attributes;
|
|
5547
|
+
}
|
|
5548
|
+
function serializeShortcodeAttributes(attrs) {
|
|
5549
|
+
return Object.entries(attrs).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}="${value}"`).join(" ");
|
|
5550
|
+
}
|
|
5551
|
+
function createInlineMarkdownSpec(options) {
|
|
5552
|
+
const {
|
|
5553
|
+
nodeName,
|
|
5554
|
+
name: shortcodeName,
|
|
5555
|
+
getContent,
|
|
5556
|
+
parseAttributes: parseAttributes2 = parseShortcodeAttributes,
|
|
5557
|
+
serializeAttributes: serializeAttributes2 = serializeShortcodeAttributes,
|
|
5558
|
+
defaultAttributes = {},
|
|
5559
|
+
selfClosing = false,
|
|
5560
|
+
allowedAttributes
|
|
5561
|
+
} = options;
|
|
5562
|
+
const shortcode = shortcodeName || nodeName;
|
|
5563
|
+
const filterAttributes = (attrs) => {
|
|
5564
|
+
if (!allowedAttributes) {
|
|
5565
|
+
return attrs;
|
|
5566
|
+
}
|
|
5567
|
+
const filtered = {};
|
|
5568
|
+
allowedAttributes.forEach((attr) => {
|
|
5569
|
+
const attrName = typeof attr === "string" ? attr : attr.name;
|
|
5570
|
+
const skipIfDefault = typeof attr === "string" ? void 0 : attr.skipIfDefault;
|
|
5571
|
+
if (attrName in attrs) {
|
|
5572
|
+
const value = attrs[attrName];
|
|
5573
|
+
if (skipIfDefault !== void 0 && value === skipIfDefault) {
|
|
5574
|
+
return;
|
|
5575
|
+
}
|
|
5576
|
+
filtered[attrName] = value;
|
|
5577
|
+
}
|
|
5578
|
+
});
|
|
5579
|
+
return filtered;
|
|
5580
|
+
};
|
|
5581
|
+
const escapedShortcode = shortcode.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5582
|
+
return {
|
|
5583
|
+
parseMarkdown: (token, h2) => {
|
|
5584
|
+
const attrs = { ...defaultAttributes, ...token.attributes };
|
|
5585
|
+
if (selfClosing) {
|
|
5586
|
+
return h2.createNode(nodeName, attrs);
|
|
5587
|
+
}
|
|
5588
|
+
const content = getContent ? getContent(token) : token.content || "";
|
|
5589
|
+
if (content) {
|
|
5590
|
+
return h2.createNode(nodeName, attrs, [h2.createTextNode(content)]);
|
|
5591
|
+
}
|
|
5592
|
+
return h2.createNode(nodeName, attrs, []);
|
|
5593
|
+
},
|
|
5594
|
+
markdownTokenizer: {
|
|
5595
|
+
name: nodeName,
|
|
5596
|
+
level: "inline",
|
|
5597
|
+
start(src) {
|
|
5598
|
+
const startPattern = selfClosing ? new RegExp(`\\[${escapedShortcode}\\s*[^\\]]*\\]`) : new RegExp(`\\[${escapedShortcode}\\s*[^\\]]*\\][\\s\\S]*?\\[\\/${escapedShortcode}\\]`);
|
|
5599
|
+
const match = src.match(startPattern);
|
|
5600
|
+
const index = match == null ? void 0 : match.index;
|
|
5601
|
+
return index !== void 0 ? index : -1;
|
|
5602
|
+
},
|
|
5603
|
+
tokenize(src, _tokens, _lexer) {
|
|
5604
|
+
const tokenPattern = selfClosing ? new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]`) : new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escapedShortcode}\\]`);
|
|
5605
|
+
const match = src.match(tokenPattern);
|
|
5606
|
+
if (!match) {
|
|
5607
|
+
return void 0;
|
|
5608
|
+
}
|
|
5609
|
+
let content = "";
|
|
5610
|
+
let attrString = "";
|
|
5611
|
+
if (selfClosing) {
|
|
5612
|
+
const [, attrs] = match;
|
|
5613
|
+
attrString = attrs;
|
|
5614
|
+
} else {
|
|
5615
|
+
const [, attrs, contentMatch] = match;
|
|
5616
|
+
attrString = attrs;
|
|
5617
|
+
content = contentMatch || "";
|
|
5618
|
+
}
|
|
5619
|
+
const attributes = parseAttributes2(attrString.trim());
|
|
5620
|
+
return {
|
|
5621
|
+
type: nodeName,
|
|
5622
|
+
raw: match[0],
|
|
5623
|
+
content: content.trim(),
|
|
5624
|
+
attributes
|
|
5625
|
+
};
|
|
5626
|
+
}
|
|
5627
|
+
},
|
|
5628
|
+
renderMarkdown: (node) => {
|
|
5629
|
+
let content = "";
|
|
5630
|
+
if (getContent) {
|
|
5631
|
+
content = getContent(node);
|
|
5632
|
+
} else if (node.content && node.content.length > 0) {
|
|
5633
|
+
content = node.content.filter((child) => child.type === "text").map((child) => child.text).join("");
|
|
5634
|
+
}
|
|
5635
|
+
const filteredAttrs = filterAttributes(node.attrs || {});
|
|
5636
|
+
const attrs = serializeAttributes2(filteredAttrs);
|
|
5637
|
+
const attrString = attrs ? ` ${attrs}` : "";
|
|
5638
|
+
if (selfClosing) {
|
|
5639
|
+
return `[${shortcode}${attrString}]`;
|
|
5640
|
+
}
|
|
5641
|
+
return `[${shortcode}${attrString}]${content}[/${shortcode}]`;
|
|
5642
|
+
}
|
|
5643
|
+
};
|
|
5644
|
+
}
|
|
5645
|
+
function parseIndentedBlocks(src, config, lexer) {
|
|
5646
|
+
var _a, _b, _c, _d;
|
|
5647
|
+
const lines = src.split("\n");
|
|
5648
|
+
const items = [];
|
|
5649
|
+
let totalRaw = "";
|
|
5650
|
+
let i = 0;
|
|
5651
|
+
const baseIndentSize = config.baseIndentSize || 2;
|
|
5652
|
+
while (i < lines.length) {
|
|
5653
|
+
const currentLine = lines[i];
|
|
5654
|
+
const itemMatch = currentLine.match(config.itemPattern);
|
|
5655
|
+
if (!itemMatch) {
|
|
5656
|
+
if (items.length > 0) {
|
|
5657
|
+
break;
|
|
5658
|
+
} else if (currentLine.trim() === "") {
|
|
5659
|
+
i += 1;
|
|
5660
|
+
totalRaw = `${totalRaw}${currentLine}
|
|
5661
|
+
`;
|
|
5662
|
+
continue;
|
|
5663
|
+
} else {
|
|
5664
|
+
return void 0;
|
|
5665
|
+
}
|
|
5666
|
+
}
|
|
5667
|
+
const itemData = config.extractItemData(itemMatch);
|
|
5668
|
+
const { indentLevel, mainContent } = itemData;
|
|
5669
|
+
totalRaw = `${totalRaw}${currentLine}
|
|
5670
|
+
`;
|
|
5671
|
+
const itemContent = [mainContent];
|
|
5672
|
+
i += 1;
|
|
5673
|
+
while (i < lines.length) {
|
|
5674
|
+
const nextLine = lines[i];
|
|
5675
|
+
if (nextLine.trim() === "") {
|
|
5676
|
+
const nextNonEmptyIndex = lines.slice(i + 1).findIndex((l) => l.trim() !== "");
|
|
5677
|
+
if (nextNonEmptyIndex === -1) {
|
|
5678
|
+
break;
|
|
5679
|
+
}
|
|
5680
|
+
const nextNonEmpty = lines[i + 1 + nextNonEmptyIndex];
|
|
5681
|
+
const nextIndent2 = ((_b = (_a = nextNonEmpty.match(/^(\s*)/)) == null ? void 0 : _a[1]) == null ? void 0 : _b.length) || 0;
|
|
5682
|
+
if (nextIndent2 > indentLevel) {
|
|
5683
|
+
itemContent.push(nextLine);
|
|
5684
|
+
totalRaw = `${totalRaw}${nextLine}
|
|
5685
|
+
`;
|
|
5686
|
+
i += 1;
|
|
5687
|
+
continue;
|
|
5688
|
+
} else {
|
|
5689
|
+
break;
|
|
5690
|
+
}
|
|
5691
|
+
}
|
|
5692
|
+
const nextIndent = ((_d = (_c = nextLine.match(/^(\s*)/)) == null ? void 0 : _c[1]) == null ? void 0 : _d.length) || 0;
|
|
5693
|
+
if (nextIndent > indentLevel) {
|
|
5694
|
+
itemContent.push(nextLine);
|
|
5695
|
+
totalRaw = `${totalRaw}${nextLine}
|
|
5696
|
+
`;
|
|
5697
|
+
i += 1;
|
|
5698
|
+
} else {
|
|
5699
|
+
break;
|
|
5700
|
+
}
|
|
5701
|
+
}
|
|
5702
|
+
let nestedTokens;
|
|
5703
|
+
const nestedContent = itemContent.slice(1);
|
|
5704
|
+
if (nestedContent.length > 0) {
|
|
5705
|
+
const dedentedNested = nestedContent.map((nestedLine) => nestedLine.slice(indentLevel + baseIndentSize)).join("\n");
|
|
5706
|
+
if (dedentedNested.trim()) {
|
|
5707
|
+
if (config.customNestedParser) {
|
|
5708
|
+
nestedTokens = config.customNestedParser(dedentedNested);
|
|
5709
|
+
} else {
|
|
5710
|
+
nestedTokens = lexer.blockTokens(dedentedNested);
|
|
5711
|
+
}
|
|
5712
|
+
}
|
|
5713
|
+
}
|
|
5714
|
+
const token = config.createToken(itemData, nestedTokens);
|
|
5715
|
+
items.push(token);
|
|
5716
|
+
}
|
|
5717
|
+
if (items.length === 0) {
|
|
5718
|
+
return void 0;
|
|
5719
|
+
}
|
|
5720
|
+
return {
|
|
5721
|
+
items,
|
|
5722
|
+
raw: totalRaw
|
|
5723
|
+
};
|
|
5724
|
+
}
|
|
5725
|
+
function renderNestedMarkdownContent(node, h2, prefixOrGenerator, ctx) {
|
|
5726
|
+
if (!node || !Array.isArray(node.content)) {
|
|
5727
|
+
return "";
|
|
5728
|
+
}
|
|
5729
|
+
const prefix = typeof prefixOrGenerator === "function" ? prefixOrGenerator(ctx) : prefixOrGenerator;
|
|
5730
|
+
const [content, ...children] = node.content;
|
|
5731
|
+
const mainContent = h2.renderChildren([content]);
|
|
5732
|
+
const output = [`${prefix}${mainContent}`];
|
|
5733
|
+
if (children && children.length > 0) {
|
|
5734
|
+
children.forEach((child) => {
|
|
5735
|
+
const childContent = h2.renderChildren([child]);
|
|
5736
|
+
if (childContent) {
|
|
5737
|
+
const indentedChild = childContent.split("\n").map((line) => line ? h2.indent(line) : "").join("\n");
|
|
5738
|
+
output.push(indentedChild);
|
|
5739
|
+
}
|
|
5740
|
+
});
|
|
5741
|
+
}
|
|
5742
|
+
return output.join("\n");
|
|
5743
|
+
}
|
|
5744
|
+
var Node3 = class _Node extends Extendable {
|
|
5745
|
+
constructor() {
|
|
5746
|
+
super(...arguments);
|
|
5747
|
+
this.type = "node";
|
|
5748
|
+
}
|
|
5749
|
+
/**
|
|
5750
|
+
* Create a new Node instance
|
|
5751
|
+
* @param config - Node configuration object or a function that returns a configuration object
|
|
5752
|
+
*/
|
|
5753
|
+
static create(config = {}) {
|
|
5754
|
+
const resolvedConfig = typeof config === "function" ? config() : config;
|
|
5755
|
+
return new _Node(resolvedConfig);
|
|
5756
|
+
}
|
|
5757
|
+
configure(options) {
|
|
5758
|
+
return super.configure(options);
|
|
5759
|
+
}
|
|
5760
|
+
extend(extendedConfig) {
|
|
5761
|
+
const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig;
|
|
5762
|
+
return super.extend(resolvedConfig);
|
|
5763
|
+
}
|
|
5764
|
+
};
|
|
5765
|
+
function get_current_font_size2(editor) {
|
|
5766
|
+
const attrs = editor.getAttributes("textStyle");
|
|
5767
|
+
if (attrs?.fontSize) {
|
|
5768
|
+
const parsed = parseInt(attrs.fontSize.replace("px", ""), 10);
|
|
5769
|
+
return isNaN(parsed) ? DEFAULT_FONT_SIZE : parsed;
|
|
5770
|
+
}
|
|
5771
|
+
return DEFAULT_FONT_SIZE;
|
|
5772
|
+
}
|
|
5773
|
+
function get_next_font_size(current, direction) {
|
|
5774
|
+
let index = FONT_SIZES.findIndex((s) => s >= current);
|
|
5775
|
+
if (index === -1) {
|
|
5776
|
+
index = FONT_SIZES.length - 1;
|
|
5777
|
+
}
|
|
5778
|
+
if (direction === "increase") {
|
|
5779
|
+
if (FONT_SIZES[index] === current) {
|
|
5780
|
+
return Math.min(FONT_SIZES[index + 1] ?? MAX_FONT_SIZE, MAX_FONT_SIZE);
|
|
5781
|
+
}
|
|
5782
|
+
return Math.min(FONT_SIZES[index], MAX_FONT_SIZE);
|
|
5783
|
+
} else {
|
|
5784
|
+
if (FONT_SIZES[index] === current && index > 0) {
|
|
5785
|
+
return Math.max(FONT_SIZES[index - 1], MIN_FONT_SIZE);
|
|
5786
|
+
}
|
|
5787
|
+
const prev_index = index > 0 ? index - 1 : 0;
|
|
5788
|
+
return Math.max(FONT_SIZES[prev_index], MIN_FONT_SIZE);
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
var FontSizeExtension = Extension.create({
|
|
5792
|
+
name: "hazoFontSize",
|
|
5793
|
+
addOptions() {
|
|
5794
|
+
return {
|
|
5795
|
+
types: ["textStyle"]
|
|
5796
|
+
};
|
|
5797
|
+
},
|
|
5798
|
+
addGlobalAttributes() {
|
|
5799
|
+
return [
|
|
5800
|
+
{
|
|
5801
|
+
types: this.options.types,
|
|
5802
|
+
attributes: {
|
|
5803
|
+
fontSize: {
|
|
5804
|
+
default: null,
|
|
5805
|
+
parseHTML: (element) => element.style.fontSize?.replace(/['"]+/g, ""),
|
|
5806
|
+
renderHTML: (attributes) => {
|
|
5807
|
+
if (!attributes.fontSize) {
|
|
5808
|
+
return {};
|
|
5809
|
+
}
|
|
5810
|
+
return {
|
|
5811
|
+
style: `font-size: ${attributes.fontSize}`
|
|
5812
|
+
};
|
|
5813
|
+
}
|
|
5814
|
+
}
|
|
5815
|
+
}
|
|
5816
|
+
}
|
|
5817
|
+
];
|
|
5818
|
+
},
|
|
5819
|
+
addCommands() {
|
|
5820
|
+
return {
|
|
5821
|
+
setFontSize: (size) => ({ chain }) => {
|
|
5822
|
+
return chain().setMark("textStyle", { fontSize: size }).run();
|
|
5823
|
+
},
|
|
5824
|
+
unsetFontSize: () => ({ chain }) => {
|
|
5825
|
+
return chain().setMark("textStyle", { fontSize: null }).removeEmptyTextStyle().run();
|
|
5826
|
+
},
|
|
5827
|
+
increaseFontSize: () => ({ chain, editor }) => {
|
|
5828
|
+
const current_size = get_current_font_size2(editor);
|
|
5829
|
+
const next_size = get_next_font_size(current_size, "increase");
|
|
5830
|
+
return chain().setMark("textStyle", { fontSize: `${next_size}px` }).run();
|
|
5831
|
+
},
|
|
5832
|
+
decreaseFontSize: () => ({ chain, editor }) => {
|
|
5833
|
+
const current_size = get_current_font_size2(editor);
|
|
5834
|
+
const next_size = get_next_font_size(current_size, "decrease");
|
|
5835
|
+
return chain().setMark("textStyle", { fontSize: `${next_size}px` }).run();
|
|
5836
|
+
}
|
|
5837
|
+
};
|
|
5838
|
+
}
|
|
5839
|
+
});
|
|
5840
|
+
function VariableChipNodeView({ node }) {
|
|
5841
|
+
const { variable_name, variable_text } = node.attrs;
|
|
5842
|
+
return /* @__PURE__ */ jsxs(
|
|
5843
|
+
NodeViewWrapper,
|
|
5844
|
+
{
|
|
5845
|
+
as: "span",
|
|
5846
|
+
className: "cls_variable_chip inline-flex items-center px-2 py-0.5 mx-0.5 rounded-md bg-primary/10 text-primary text-sm font-medium border border-primary/20 cursor-default select-none",
|
|
5847
|
+
contentEditable: false,
|
|
5848
|
+
children: [
|
|
5849
|
+
/* @__PURE__ */ jsx("span", { className: "cls_variable_chip_icon mr-1 text-xs opacity-70", children: "{" }),
|
|
5850
|
+
/* @__PURE__ */ jsx("span", { className: "cls_variable_chip_text", children: variable_text || variable_name }),
|
|
5851
|
+
/* @__PURE__ */ jsx("span", { className: "cls_variable_chip_icon ml-1 text-xs opacity-70", children: "}" })
|
|
5852
|
+
]
|
|
5853
|
+
}
|
|
5854
|
+
);
|
|
5855
|
+
}
|
|
5856
|
+
var variable_chip_default = VariableChipNodeView;
|
|
5857
|
+
|
|
5858
|
+
// src/components/hazo_ui_richtext_editor/extensions/variable_extension.ts
|
|
5859
|
+
var VariableExtension = Node3.create({
|
|
5860
|
+
name: "variable",
|
|
5861
|
+
group: "inline",
|
|
5862
|
+
inline: true,
|
|
5863
|
+
// Atomic means it's not editable directly
|
|
5864
|
+
atom: true,
|
|
5865
|
+
addOptions() {
|
|
5866
|
+
return {
|
|
5867
|
+
HTMLAttributes: {}
|
|
5868
|
+
};
|
|
5869
|
+
},
|
|
5870
|
+
addAttributes() {
|
|
5871
|
+
return {
|
|
5872
|
+
variable_name: {
|
|
5873
|
+
default: null,
|
|
5874
|
+
parseHTML: (element) => element.getAttribute("data-variable-name"),
|
|
5875
|
+
renderHTML: (attributes) => ({
|
|
5876
|
+
"data-variable-name": attributes.variable_name
|
|
5877
|
+
})
|
|
5878
|
+
},
|
|
5879
|
+
variable_text: {
|
|
5880
|
+
default: null,
|
|
5881
|
+
parseHTML: (element) => element.getAttribute("data-variable-text"),
|
|
5882
|
+
renderHTML: (attributes) => ({
|
|
5883
|
+
"data-variable-text": attributes.variable_text
|
|
5884
|
+
})
|
|
5885
|
+
}
|
|
5886
|
+
};
|
|
5887
|
+
},
|
|
5888
|
+
parseHTML() {
|
|
5889
|
+
return [
|
|
5890
|
+
{
|
|
5891
|
+
tag: 'span[data-type="variable"]'
|
|
5892
|
+
}
|
|
5893
|
+
];
|
|
5894
|
+
},
|
|
5895
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
5896
|
+
return [
|
|
5897
|
+
"span",
|
|
5898
|
+
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
|
|
5899
|
+
"data-type": "variable",
|
|
5900
|
+
class: "cls_variable_chip_output"
|
|
5901
|
+
}),
|
|
5902
|
+
`{{${node.attrs.variable_name}}}`
|
|
5903
|
+
];
|
|
5904
|
+
},
|
|
5905
|
+
// Include variable placeholder in plain text output
|
|
5906
|
+
renderText({ node }) {
|
|
5907
|
+
return `{{${node.attrs.variable_name}}}`;
|
|
5908
|
+
},
|
|
5909
|
+
addNodeView() {
|
|
5910
|
+
return ReactNodeViewRenderer(variable_chip_default);
|
|
5911
|
+
},
|
|
5912
|
+
addCommands() {
|
|
5913
|
+
return {
|
|
5914
|
+
insertVariable: (variable_name, variable_text) => ({ commands }) => {
|
|
5915
|
+
return commands.insertContent({
|
|
5916
|
+
type: this.name,
|
|
5917
|
+
attrs: { variable_name, variable_text }
|
|
5918
|
+
});
|
|
5919
|
+
}
|
|
5920
|
+
};
|
|
5921
|
+
}
|
|
5922
|
+
});
|
|
5923
|
+
|
|
5924
|
+
// src/components/hazo_ui_richtext_editor/extensions/column_layout_extension.ts
|
|
5925
|
+
var ColumnLayoutExtension = Node3.create({
|
|
5926
|
+
name: "columnLayout",
|
|
5927
|
+
group: "block",
|
|
5928
|
+
content: "column+",
|
|
5929
|
+
defining: true,
|
|
5930
|
+
addOptions() {
|
|
5931
|
+
return {
|
|
5932
|
+
HTMLAttributes: {}
|
|
5933
|
+
};
|
|
5934
|
+
},
|
|
5935
|
+
addAttributes() {
|
|
5936
|
+
return {
|
|
5937
|
+
columns: {
|
|
5938
|
+
default: 2,
|
|
5939
|
+
parseHTML: (element) => parseInt(element.getAttribute("data-columns") || "2", 10),
|
|
5940
|
+
renderHTML: (attributes) => ({
|
|
5941
|
+
"data-columns": attributes.columns
|
|
5942
|
+
})
|
|
5943
|
+
}
|
|
5944
|
+
};
|
|
5945
|
+
},
|
|
5946
|
+
parseHTML() {
|
|
5947
|
+
return [
|
|
5948
|
+
{
|
|
5949
|
+
tag: 'div[data-type="column-layout"]'
|
|
5950
|
+
}
|
|
5951
|
+
];
|
|
5952
|
+
},
|
|
5953
|
+
renderHTML({ HTMLAttributes }) {
|
|
5954
|
+
const columns = HTMLAttributes.columns || 2;
|
|
5955
|
+
return [
|
|
5956
|
+
"div",
|
|
5957
|
+
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
|
|
5958
|
+
"data-type": "column-layout",
|
|
5959
|
+
class: `cls_column_layout cls_columns_${columns}`,
|
|
5960
|
+
style: `display: grid; grid-template-columns: repeat(${columns}, 1fr); gap: 1rem;`
|
|
5961
|
+
}),
|
|
5962
|
+
0
|
|
5963
|
+
];
|
|
5964
|
+
},
|
|
5965
|
+
addCommands() {
|
|
5966
|
+
return {
|
|
5967
|
+
insertColumnLayout: (columns) => ({ commands }) => {
|
|
5968
|
+
const column_content = Array(columns).fill(null).map(() => ({
|
|
5969
|
+
type: "column",
|
|
5970
|
+
content: [{ type: "paragraph" }]
|
|
5971
|
+
}));
|
|
5972
|
+
return commands.insertContent({
|
|
5973
|
+
type: this.name,
|
|
5974
|
+
attrs: { columns },
|
|
5975
|
+
content: column_content
|
|
5976
|
+
});
|
|
5977
|
+
}
|
|
5978
|
+
};
|
|
5979
|
+
}
|
|
5980
|
+
});
|
|
5981
|
+
var ColumnExtension = Node3.create({
|
|
5982
|
+
name: "column",
|
|
5983
|
+
group: "column",
|
|
5984
|
+
content: "block+",
|
|
5985
|
+
defining: true,
|
|
5986
|
+
parseHTML() {
|
|
5987
|
+
return [
|
|
5988
|
+
{
|
|
5989
|
+
tag: 'div[data-type="column"]'
|
|
5990
|
+
}
|
|
5991
|
+
];
|
|
5992
|
+
},
|
|
5993
|
+
renderHTML({ HTMLAttributes }) {
|
|
5994
|
+
return [
|
|
5995
|
+
"div",
|
|
5996
|
+
mergeAttributes(HTMLAttributes, {
|
|
5997
|
+
"data-type": "column",
|
|
5998
|
+
class: "cls_column",
|
|
5999
|
+
style: "min-width: 0;"
|
|
6000
|
+
}),
|
|
6001
|
+
0
|
|
6002
|
+
];
|
|
6003
|
+
}
|
|
6004
|
+
});
|
|
6005
|
+
function format_file_size(bytes) {
|
|
6006
|
+
if (bytes === 0) return "0 B";
|
|
6007
|
+
const k = 1024;
|
|
6008
|
+
const sizes = ["B", "KB", "MB", "GB"];
|
|
6009
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
6010
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
|
|
6011
|
+
}
|
|
6012
|
+
function HazoRichtextEditor({
|
|
6013
|
+
initial_html = "",
|
|
6014
|
+
initial_text = "",
|
|
6015
|
+
variables = [],
|
|
6016
|
+
initial_attachments = [],
|
|
6017
|
+
on_save,
|
|
6018
|
+
on_change,
|
|
6019
|
+
on_attachments_change,
|
|
6020
|
+
on_file_attach,
|
|
6021
|
+
placeholder = DEFAULT_PLACEHOLDER,
|
|
6022
|
+
min_height = DEFAULT_MIN_HEIGHT,
|
|
6023
|
+
max_height = DEFAULT_MAX_HEIGHT,
|
|
6024
|
+
read_only = false,
|
|
6025
|
+
show_save_button = true,
|
|
6026
|
+
save_button_text = "Save",
|
|
6027
|
+
className
|
|
6028
|
+
}) {
|
|
6029
|
+
const [state, set_state] = React14.useState({
|
|
6030
|
+
active_tab: "visual",
|
|
6031
|
+
html_view_mode: "preview",
|
|
6032
|
+
html_content: initial_html,
|
|
6033
|
+
text_content: initial_text,
|
|
6034
|
+
is_variables_modal_open: false
|
|
6035
|
+
});
|
|
6036
|
+
const [attachments, set_attachments] = React14.useState(initial_attachments);
|
|
6037
|
+
const editor = useEditor({
|
|
6038
|
+
extensions: [
|
|
6039
|
+
StarterKit.configure({
|
|
6040
|
+
heading: {
|
|
6041
|
+
levels: [1, 2, 3]
|
|
6042
|
+
}
|
|
6043
|
+
}),
|
|
6044
|
+
Underline,
|
|
6045
|
+
TextStyle,
|
|
6046
|
+
Color,
|
|
6047
|
+
Highlight.configure({
|
|
6048
|
+
multicolor: true
|
|
6049
|
+
}),
|
|
6050
|
+
FontFamily,
|
|
6051
|
+
FontSizeExtension,
|
|
6052
|
+
TextAlign.configure({
|
|
6053
|
+
types: ["heading", "paragraph"]
|
|
6054
|
+
}),
|
|
6055
|
+
Link.configure({
|
|
6056
|
+
openOnClick: false,
|
|
6057
|
+
HTMLAttributes: {
|
|
6058
|
+
class: "cls_editor_link text-primary underline cursor-pointer"
|
|
6059
|
+
}
|
|
6060
|
+
}),
|
|
6061
|
+
Image.configure({
|
|
6062
|
+
HTMLAttributes: {
|
|
6063
|
+
class: "cls_editor_image max-w-full h-auto rounded-md"
|
|
6064
|
+
}
|
|
6065
|
+
}),
|
|
6066
|
+
Table.configure({
|
|
6067
|
+
resizable: true,
|
|
6068
|
+
HTMLAttributes: {
|
|
6069
|
+
class: "cls_editor_table border-collapse w-full"
|
|
6070
|
+
}
|
|
6071
|
+
}),
|
|
6072
|
+
TableRow,
|
|
6073
|
+
TableCell.configure({
|
|
6074
|
+
HTMLAttributes: {
|
|
6075
|
+
class: "cls_editor_table_cell border border-border p-2"
|
|
6076
|
+
}
|
|
6077
|
+
}),
|
|
6078
|
+
TableHeader.configure({
|
|
6079
|
+
HTMLAttributes: {
|
|
6080
|
+
class: "cls_editor_table_header border border-border p-2 bg-muted font-medium"
|
|
6081
|
+
}
|
|
6082
|
+
}),
|
|
6083
|
+
TaskList.configure({
|
|
6084
|
+
HTMLAttributes: {
|
|
6085
|
+
class: "cls_editor_task_list"
|
|
6086
|
+
}
|
|
6087
|
+
}),
|
|
6088
|
+
TaskItem.configure({
|
|
6089
|
+
nested: true,
|
|
6090
|
+
HTMLAttributes: {
|
|
6091
|
+
class: "cls_editor_task_item"
|
|
6092
|
+
}
|
|
6093
|
+
}),
|
|
6094
|
+
Subscript,
|
|
6095
|
+
Superscript,
|
|
6096
|
+
Placeholder.configure({
|
|
6097
|
+
placeholder,
|
|
6098
|
+
emptyEditorClass: "cls_editor_empty"
|
|
6099
|
+
}),
|
|
6100
|
+
VariableExtension,
|
|
6101
|
+
ColumnLayoutExtension,
|
|
6102
|
+
ColumnExtension
|
|
6103
|
+
],
|
|
6104
|
+
content: initial_html || `<p>${initial_text}</p>`,
|
|
6105
|
+
editable: !read_only,
|
|
6106
|
+
immediatelyRender: false,
|
|
6107
|
+
onUpdate: ({ editor: editor2 }) => {
|
|
6108
|
+
const html = editor2.getHTML();
|
|
6109
|
+
const text = editor2.getText();
|
|
6110
|
+
set_state((prev) => ({
|
|
6111
|
+
...prev,
|
|
6112
|
+
html_content: html,
|
|
6113
|
+
text_content: text
|
|
6114
|
+
}));
|
|
6115
|
+
on_change?.(html, text);
|
|
6116
|
+
}
|
|
6117
|
+
});
|
|
6118
|
+
React14.useEffect(() => {
|
|
6119
|
+
if (editor && state.active_tab === "visual") {
|
|
6120
|
+
const current_html = editor.getHTML();
|
|
6121
|
+
if (current_html !== state.html_content && state.html_content) {
|
|
6122
|
+
editor.commands.setContent(state.html_content);
|
|
6123
|
+
}
|
|
6124
|
+
}
|
|
6125
|
+
}, [state.active_tab, editor, state.html_content]);
|
|
6126
|
+
const handle_tab_change = (tab) => {
|
|
6127
|
+
if (editor && tab !== "visual" && state.active_tab === "visual") {
|
|
6128
|
+
set_state((prev) => ({
|
|
6129
|
+
...prev,
|
|
6130
|
+
active_tab: tab,
|
|
6131
|
+
html_content: editor.getHTML(),
|
|
6132
|
+
text_content: editor.getText()
|
|
6133
|
+
}));
|
|
6134
|
+
} else {
|
|
6135
|
+
set_state((prev) => ({
|
|
6136
|
+
...prev,
|
|
6137
|
+
active_tab: tab
|
|
6138
|
+
}));
|
|
6139
|
+
}
|
|
6140
|
+
};
|
|
6141
|
+
const handle_html_change = (html) => {
|
|
6142
|
+
set_state((prev) => ({
|
|
6143
|
+
...prev,
|
|
6144
|
+
html_content: html
|
|
6145
|
+
}));
|
|
6146
|
+
};
|
|
6147
|
+
const handle_text_change = (text) => {
|
|
6148
|
+
set_state((prev) => ({
|
|
6149
|
+
...prev,
|
|
6150
|
+
text_content: text
|
|
6151
|
+
}));
|
|
6152
|
+
};
|
|
6153
|
+
const handle_html_view_mode_change = (mode) => {
|
|
6154
|
+
set_state((prev) => ({
|
|
6155
|
+
...prev,
|
|
6156
|
+
html_view_mode: mode
|
|
6157
|
+
}));
|
|
6158
|
+
};
|
|
6159
|
+
const handle_variable_select = (variable) => {
|
|
6160
|
+
if (editor) {
|
|
6161
|
+
editor.chain().focus().insertVariable(variable.text, variable.description).run();
|
|
6162
|
+
}
|
|
6163
|
+
};
|
|
6164
|
+
const handle_save = () => {
|
|
6165
|
+
const html = editor?.getHTML() || state.html_content;
|
|
6166
|
+
const text = editor?.getText() || state.text_content;
|
|
6167
|
+
on_save?.(html, text, attachments);
|
|
6168
|
+
};
|
|
6169
|
+
const open_variables_modal = () => {
|
|
6170
|
+
set_state((prev) => ({
|
|
6171
|
+
...prev,
|
|
6172
|
+
is_variables_modal_open: true
|
|
6173
|
+
}));
|
|
6174
|
+
};
|
|
6175
|
+
const close_variables_modal = () => {
|
|
6176
|
+
set_state((prev) => ({
|
|
6177
|
+
...prev,
|
|
6178
|
+
is_variables_modal_open: false
|
|
6179
|
+
}));
|
|
6180
|
+
};
|
|
6181
|
+
const generate_attachment_id = () => {
|
|
6182
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
6183
|
+
};
|
|
6184
|
+
const handle_add_attachment = async (file) => {
|
|
6185
|
+
return new Promise((resolve, reject) => {
|
|
6186
|
+
const reader = new FileReader();
|
|
6187
|
+
reader.onload = () => {
|
|
6188
|
+
const new_attachment = {
|
|
6189
|
+
id: generate_attachment_id(),
|
|
6190
|
+
name: file.name,
|
|
6191
|
+
type: file.type,
|
|
6192
|
+
size: file.size,
|
|
6193
|
+
data: reader.result
|
|
6194
|
+
};
|
|
6195
|
+
const updated_attachments = [...attachments, new_attachment];
|
|
6196
|
+
set_attachments(updated_attachments);
|
|
6197
|
+
on_attachments_change?.(updated_attachments);
|
|
6198
|
+
resolve();
|
|
6199
|
+
};
|
|
6200
|
+
reader.onerror = reject;
|
|
6201
|
+
reader.readAsDataURL(file);
|
|
6202
|
+
});
|
|
6203
|
+
};
|
|
6204
|
+
const handle_remove_attachment = (id) => {
|
|
6205
|
+
const updated_attachments = attachments.filter((a) => a.id !== id);
|
|
6206
|
+
set_attachments(updated_attachments);
|
|
6207
|
+
on_attachments_change?.(updated_attachments);
|
|
6208
|
+
};
|
|
6209
|
+
const handle_image_embed = async (file) => {
|
|
6210
|
+
let url;
|
|
6211
|
+
let base64_data;
|
|
6212
|
+
if (on_file_attach) {
|
|
6213
|
+
url = await on_file_attach(file);
|
|
6214
|
+
base64_data = await new Promise((resolve, reject) => {
|
|
6215
|
+
const reader = new FileReader();
|
|
6216
|
+
reader.onload = () => resolve(reader.result);
|
|
6217
|
+
reader.onerror = reject;
|
|
6218
|
+
reader.readAsDataURL(file);
|
|
6219
|
+
});
|
|
6220
|
+
} else {
|
|
6221
|
+
base64_data = await new Promise((resolve, reject) => {
|
|
6222
|
+
const reader = new FileReader();
|
|
6223
|
+
reader.onload = () => resolve(reader.result);
|
|
6224
|
+
reader.onerror = reject;
|
|
6225
|
+
reader.readAsDataURL(file);
|
|
6226
|
+
});
|
|
6227
|
+
url = base64_data;
|
|
6228
|
+
}
|
|
6229
|
+
if (editor) {
|
|
6230
|
+
editor.chain().focus().setImage({ src: url, alt: file.name }).run();
|
|
6231
|
+
}
|
|
6232
|
+
const new_attachment = {
|
|
6233
|
+
id: generate_attachment_id(),
|
|
6234
|
+
name: file.name,
|
|
6235
|
+
type: file.type,
|
|
6236
|
+
size: file.size,
|
|
6237
|
+
data: base64_data
|
|
6238
|
+
};
|
|
6239
|
+
const updated_attachments = [...attachments, new_attachment];
|
|
6240
|
+
set_attachments(updated_attachments);
|
|
6241
|
+
on_attachments_change?.(updated_attachments);
|
|
6242
|
+
return url;
|
|
6243
|
+
};
|
|
6244
|
+
return /* @__PURE__ */ jsxs(
|
|
6245
|
+
"div",
|
|
6246
|
+
{
|
|
6247
|
+
className: cn(
|
|
6248
|
+
"cls_richtext_editor border border-border rounded-lg overflow-hidden bg-background",
|
|
6249
|
+
className
|
|
6250
|
+
),
|
|
6251
|
+
children: [
|
|
6252
|
+
state.active_tab === "visual" && !read_only && /* @__PURE__ */ jsx(
|
|
6253
|
+
Toolbar,
|
|
6254
|
+
{
|
|
6255
|
+
editor,
|
|
6256
|
+
on_open_variables_modal: open_variables_modal,
|
|
6257
|
+
variables,
|
|
6258
|
+
on_image_embed: handle_image_embed,
|
|
6259
|
+
on_add_attachment: handle_add_attachment
|
|
6260
|
+
}
|
|
6261
|
+
),
|
|
6262
|
+
/* @__PURE__ */ jsx(
|
|
6263
|
+
ViewTabs,
|
|
6264
|
+
{
|
|
6265
|
+
active_tab: state.active_tab,
|
|
6266
|
+
on_tab_change: handle_tab_change,
|
|
6267
|
+
editor,
|
|
6268
|
+
html_content: state.html_content,
|
|
6269
|
+
text_content: state.text_content,
|
|
6270
|
+
on_html_change: handle_html_change,
|
|
6271
|
+
on_text_change: handle_text_change,
|
|
6272
|
+
html_view_mode: state.html_view_mode,
|
|
6273
|
+
on_html_view_mode_change: handle_html_view_mode_change,
|
|
6274
|
+
min_height,
|
|
6275
|
+
max_height,
|
|
6276
|
+
read_only,
|
|
6277
|
+
children: /* @__PURE__ */ jsx(
|
|
6278
|
+
EditorContent,
|
|
6279
|
+
{
|
|
6280
|
+
editor,
|
|
6281
|
+
className: cn(
|
|
6282
|
+
"cls_editor_content prose prose-sm max-w-none p-4",
|
|
6283
|
+
"focus-within:outline-none",
|
|
6284
|
+
"[&_.ProseMirror]:outline-none [&_.ProseMirror]:min-h-[inherit]",
|
|
6285
|
+
"[&_.ProseMirror_p.is-editor-empty:first-child::before]:text-muted-foreground",
|
|
6286
|
+
"[&_.ProseMirror_p.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]",
|
|
6287
|
+
"[&_.ProseMirror_p.is-editor-empty:first-child::before]:float-left",
|
|
6288
|
+
"[&_.ProseMirror_p.is-editor-empty:first-child::before]:h-0",
|
|
6289
|
+
"[&_.ProseMirror_p.is-editor-empty:first-child::before]:pointer-events-none"
|
|
6290
|
+
)
|
|
6291
|
+
}
|
|
6292
|
+
)
|
|
6293
|
+
}
|
|
6294
|
+
),
|
|
6295
|
+
attachments.length > 0 && /* @__PURE__ */ jsxs("div", { className: "cls_attachments_section border-t border-border p-3 bg-muted/20", children: [
|
|
6296
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_attachments_header text-xs font-medium text-muted-foreground mb-2", children: [
|
|
6297
|
+
"Attachments (",
|
|
6298
|
+
attachments.length,
|
|
6299
|
+
")"
|
|
6300
|
+
] }),
|
|
6301
|
+
/* @__PURE__ */ jsx("div", { className: "cls_attachments_list flex flex-wrap gap-2", children: attachments.map((attachment) => /* @__PURE__ */ jsxs(
|
|
6302
|
+
"div",
|
|
6303
|
+
{
|
|
6304
|
+
className: "cls_attachment_item flex items-center gap-2 px-2 py-1 rounded-md bg-background border border-border text-sm",
|
|
6305
|
+
children: [
|
|
6306
|
+
attachment.type.startsWith("image/") ? /* @__PURE__ */ jsx(
|
|
6307
|
+
"img",
|
|
6308
|
+
{
|
|
6309
|
+
src: attachment.data,
|
|
6310
|
+
alt: attachment.name,
|
|
6311
|
+
className: "cls_attachment_thumbnail h-6 w-6 object-cover rounded"
|
|
6312
|
+
}
|
|
6313
|
+
) : /* @__PURE__ */ jsx("span", { className: "cls_attachment_icon text-muted-foreground", children: "\u{1F4CE}" }),
|
|
6314
|
+
/* @__PURE__ */ jsx("span", { className: "cls_attachment_name max-w-[150px] truncate", children: attachment.name }),
|
|
6315
|
+
/* @__PURE__ */ jsxs("span", { className: "cls_attachment_size text-xs text-muted-foreground", children: [
|
|
6316
|
+
"(",
|
|
6317
|
+
format_file_size(attachment.size),
|
|
6318
|
+
")"
|
|
6319
|
+
] }),
|
|
6320
|
+
!read_only && /* @__PURE__ */ jsx(
|
|
6321
|
+
"button",
|
|
6322
|
+
{
|
|
6323
|
+
onClick: () => handle_remove_attachment(attachment.id),
|
|
6324
|
+
className: "cls_attachment_remove ml-1 text-muted-foreground hover:text-destructive",
|
|
6325
|
+
"aria-label": "Remove attachment",
|
|
6326
|
+
children: "\xD7"
|
|
6327
|
+
}
|
|
6328
|
+
)
|
|
6329
|
+
]
|
|
6330
|
+
},
|
|
6331
|
+
attachment.id
|
|
6332
|
+
)) })
|
|
6333
|
+
] }),
|
|
6334
|
+
show_save_button && on_save && /* @__PURE__ */ jsx("div", { className: "cls_richtext_editor_footer flex items-center justify-end p-3 border-t border-border bg-muted/30", children: /* @__PURE__ */ jsx(Button, { onClick: handle_save, size: "sm", children: save_button_text }) }),
|
|
6335
|
+
/* @__PURE__ */ jsx(
|
|
6336
|
+
VariablesModal,
|
|
6337
|
+
{
|
|
6338
|
+
is_open: state.is_variables_modal_open,
|
|
6339
|
+
on_close: close_variables_modal,
|
|
6340
|
+
variables,
|
|
6341
|
+
on_select_variable: handle_variable_select
|
|
6342
|
+
}
|
|
6343
|
+
)
|
|
6344
|
+
]
|
|
6345
|
+
}
|
|
6346
|
+
);
|
|
6347
|
+
}
|
|
6348
|
+
|
|
6349
|
+
export { HazoRichtextEditor, HazoUiFlexInput, HazoUiFlexRadio, HazoUiMultiFilterDialog, HazoUiMultiSortDialog };
|
|
1634
6350
|
//# sourceMappingURL=index.js.map
|
|
1635
6351
|
//# sourceMappingURL=index.js.map
|