@select-org/select-post-builder 1.1.0 → 1.1.2
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.d.ts +24 -24
- package/dist/post-builder.cjs.js +1548 -1547
- package/dist/post-builder.js +1548 -1547
- package/package.json +1 -1
package/dist/post-builder.cjs.js
CHANGED
|
@@ -21042,6 +21042,46 @@ const EditMediaToolbar = ({
|
|
|
21042
21042
|
}
|
|
21043
21043
|
)
|
|
21044
21044
|
] }) : null;
|
|
21045
|
+
var NAME = "AspectRatio";
|
|
21046
|
+
var AspectRatio$1 = React__namespace.forwardRef(
|
|
21047
|
+
(props, forwardedRef) => {
|
|
21048
|
+
const { ratio = 1 / 1, style, ...aspectRatioProps } = props;
|
|
21049
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21050
|
+
"div",
|
|
21051
|
+
{
|
|
21052
|
+
style: {
|
|
21053
|
+
// ensures inner element is contained
|
|
21054
|
+
position: "relative",
|
|
21055
|
+
// ensures padding bottom trick maths works
|
|
21056
|
+
width: "100%",
|
|
21057
|
+
paddingBottom: `${100 / ratio}%`
|
|
21058
|
+
},
|
|
21059
|
+
"data-radix-aspect-ratio-wrapper": "",
|
|
21060
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21061
|
+
Primitive.div,
|
|
21062
|
+
{
|
|
21063
|
+
...aspectRatioProps,
|
|
21064
|
+
ref: forwardedRef,
|
|
21065
|
+
style: {
|
|
21066
|
+
...style,
|
|
21067
|
+
// ensures children expand in ratio
|
|
21068
|
+
position: "absolute",
|
|
21069
|
+
top: 0,
|
|
21070
|
+
right: 0,
|
|
21071
|
+
bottom: 0,
|
|
21072
|
+
left: 0
|
|
21073
|
+
}
|
|
21074
|
+
}
|
|
21075
|
+
)
|
|
21076
|
+
}
|
|
21077
|
+
);
|
|
21078
|
+
}
|
|
21079
|
+
);
|
|
21080
|
+
AspectRatio$1.displayName = NAME;
|
|
21081
|
+
var Root$1 = AspectRatio$1;
|
|
21082
|
+
function AspectRatio({ ...props }) {
|
|
21083
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Root$1, { "data-slot": "aspect-ratio", ...props });
|
|
21084
|
+
}
|
|
21045
21085
|
var PROGRESS_NAME = "Progress";
|
|
21046
21086
|
var DEFAULT_MAX = 100;
|
|
21047
21087
|
var [createProgressContext] = createContextScope(PROGRESS_NAME);
|
|
@@ -21126,11 +21166,11 @@ function getInvalidValueError(propValue, componentName) {
|
|
|
21126
21166
|
|
|
21127
21167
|
Defaulting to \`null\`.`;
|
|
21128
21168
|
}
|
|
21129
|
-
var Root
|
|
21169
|
+
var Root = Progress$1;
|
|
21130
21170
|
var Indicator = ProgressIndicator;
|
|
21131
21171
|
function Progress({ className, value, ...props }) {
|
|
21132
21172
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21133
|
-
Root
|
|
21173
|
+
Root,
|
|
21134
21174
|
{
|
|
21135
21175
|
"data-slot": "progress",
|
|
21136
21176
|
className: cn("bg-primary/20 relative h-2 w-full overflow-hidden rounded-full", className),
|
|
@@ -21146,1709 +21186,1661 @@ function Progress({ className, value, ...props }) {
|
|
|
21146
21186
|
}
|
|
21147
21187
|
);
|
|
21148
21188
|
}
|
|
21149
|
-
const
|
|
21150
|
-
|
|
21151
|
-
|
|
21152
|
-
|
|
21153
|
-
|
|
21154
|
-
|
|
21155
|
-
|
|
21156
|
-
|
|
21157
|
-
|
|
21158
|
-
|
|
21159
|
-
}
|
|
21160
|
-
|
|
21161
|
-
|
|
21162
|
-
|
|
21163
|
-
|
|
21164
|
-
|
|
21165
|
-
|
|
21166
|
-
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21172
|
-
|
|
21173
|
-
|
|
21174
|
-
|
|
21175
|
-
|
|
21176
|
-
|
|
21177
|
-
|
|
21178
|
-
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
|
|
21182
|
-
|
|
21183
|
-
|
|
21184
|
-
|
|
21185
|
-
|
|
21186
|
-
|
|
21187
|
-
|
|
21188
|
-
|
|
21189
|
-
|
|
21190
|
-
|
|
21191
|
-
|
|
21192
|
-
|
|
21193
|
-
|
|
21194
|
-
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
21198
|
-
}
|
|
21199
|
-
|
|
21200
|
-
|
|
21201
|
-
|
|
21202
|
-
|
|
21203
|
-
|
|
21204
|
-
|
|
21205
|
-
|
|
21206
|
-
|
|
21207
|
-
this.inverted = inverted;
|
|
21208
|
-
if (!ranges.length && StepMap.empty)
|
|
21209
|
-
return StepMap.empty;
|
|
21210
|
-
}
|
|
21211
|
-
/**
|
|
21212
|
-
@internal
|
|
21213
|
-
*/
|
|
21214
|
-
recover(value) {
|
|
21215
|
-
let diff = 0, index2 = recoverIndex(value);
|
|
21216
|
-
if (!this.inverted)
|
|
21217
|
-
for (let i = 0; i < index2; i++)
|
|
21218
|
-
diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1];
|
|
21219
|
-
return this.ranges[index2 * 3] + diff + recoverOffset(value);
|
|
21220
|
-
}
|
|
21221
|
-
mapResult(pos, assoc = 1) {
|
|
21222
|
-
return this._map(pos, assoc, false);
|
|
21223
|
-
}
|
|
21224
|
-
map(pos, assoc = 1) {
|
|
21225
|
-
return this._map(pos, assoc, true);
|
|
21226
|
-
}
|
|
21227
|
-
/**
|
|
21228
|
-
@internal
|
|
21229
|
-
*/
|
|
21230
|
-
_map(pos, assoc, simple) {
|
|
21231
|
-
let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
21232
|
-
for (let i = 0; i < this.ranges.length; i += 3) {
|
|
21233
|
-
let start2 = this.ranges[i] - (this.inverted ? diff : 0);
|
|
21234
|
-
if (start2 > pos)
|
|
21235
|
-
break;
|
|
21236
|
-
let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end2 = start2 + oldSize;
|
|
21237
|
-
if (pos <= end2) {
|
|
21238
|
-
let side = !oldSize ? assoc : pos == start2 ? -1 : pos == end2 ? 1 : assoc;
|
|
21239
|
-
let result = start2 + diff + (side < 0 ? 0 : newSize);
|
|
21240
|
-
if (simple)
|
|
21241
|
-
return result;
|
|
21242
|
-
let recover = pos == (assoc < 0 ? start2 : end2) ? null : makeRecover(i / 3, pos - start2);
|
|
21243
|
-
let del = pos == start2 ? DEL_AFTER : pos == end2 ? DEL_BEFORE : DEL_ACROSS;
|
|
21244
|
-
if (assoc < 0 ? pos != start2 : pos != end2)
|
|
21245
|
-
del |= DEL_SIDE;
|
|
21246
|
-
return new MapResult(result, del, recover);
|
|
21189
|
+
const MediaNodeView = ({
|
|
21190
|
+
node,
|
|
21191
|
+
updateAttributes,
|
|
21192
|
+
editor,
|
|
21193
|
+
selected,
|
|
21194
|
+
getPos
|
|
21195
|
+
}) => {
|
|
21196
|
+
const handleDelete = () => {
|
|
21197
|
+
const pos = getPos() ?? NaN;
|
|
21198
|
+
if (!Number.isFinite(pos)) return;
|
|
21199
|
+
editor.chain().focus().deleteRange({ from: pos, to: pos + node.nodeSize }).focus().run();
|
|
21200
|
+
};
|
|
21201
|
+
const handleAlign = (align) => updateAttributes({ align });
|
|
21202
|
+
if (node.attrs.uploading) {
|
|
21203
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21204
|
+
react.NodeViewWrapper,
|
|
21205
|
+
{
|
|
21206
|
+
className: cn(
|
|
21207
|
+
"flex my-4",
|
|
21208
|
+
node.attrs.align === Alignment.CENTER ? "justify-center" : node.attrs.align === Alignment.RIGHT ? "justify-end" : ""
|
|
21209
|
+
),
|
|
21210
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-full", children: [
|
|
21211
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative bg-muted rounded-lg overflow-hidden", children: [
|
|
21212
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21213
|
+
AspectRatio,
|
|
21214
|
+
{
|
|
21215
|
+
ratio: node.attrs.type === MediaNodeTypes.Audio ? 4 / 1 : 16 / 4,
|
|
21216
|
+
className: cn("flex items-center justify-center bg-muted"),
|
|
21217
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center space-y-3", children: [
|
|
21218
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-center", children: [
|
|
21219
|
+
node.attrs.type === MediaNodeTypes.Image && /* @__PURE__ */ jsxRuntime.jsx(Image$1, { className: "w-12 h-12 text-muted-foreground/50" }),
|
|
21220
|
+
node.attrs.type === MediaNodeTypes.Video && /* @__PURE__ */ jsxRuntime.jsx(Video, { className: "w-12 h-12 text-muted-foreground/50" }),
|
|
21221
|
+
node.attrs.type === MediaNodeTypes.Audio && /* @__PURE__ */ jsxRuntime.jsx(Music, { className: "w-12 h-12 text-muted-foreground/50" })
|
|
21222
|
+
] }),
|
|
21223
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground font-medium", children: [
|
|
21224
|
+
"Uploading ",
|
|
21225
|
+
node.attrs.type,
|
|
21226
|
+
"..."
|
|
21227
|
+
] })
|
|
21228
|
+
] })
|
|
21229
|
+
}
|
|
21230
|
+
),
|
|
21231
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4", children: /* @__PURE__ */ jsxRuntime.jsx(Progress, { value: node.attrs.progress ?? 0, className: "h-2" }) }),
|
|
21232
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21233
|
+
"button",
|
|
21234
|
+
{
|
|
21235
|
+
onClick: handleDelete,
|
|
21236
|
+
className: "absolute top-2 right-2 p-2 bg-background/90 hover:bg-background rounded-full shadow-sm transition-colors",
|
|
21237
|
+
title: "Cancel upload",
|
|
21238
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(X, { className: "w-4 h-4" })
|
|
21239
|
+
}
|
|
21240
|
+
)
|
|
21241
|
+
] }),
|
|
21242
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground text-center mt-2", children: [
|
|
21243
|
+
Math.round(node.attrs.progress ?? 0),
|
|
21244
|
+
"%"
|
|
21245
|
+
] })
|
|
21246
|
+
] })
|
|
21247
21247
|
}
|
|
21248
|
-
|
|
21249
|
-
}
|
|
21250
|
-
return simple ? pos + diff : new MapResult(pos + diff, 0, null);
|
|
21251
|
-
}
|
|
21252
|
-
/**
|
|
21253
|
-
@internal
|
|
21254
|
-
*/
|
|
21255
|
-
touches(pos, recover) {
|
|
21256
|
-
let diff = 0, index2 = recoverIndex(recover);
|
|
21257
|
-
let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
21258
|
-
for (let i = 0; i < this.ranges.length; i += 3) {
|
|
21259
|
-
let start2 = this.ranges[i] - (this.inverted ? diff : 0);
|
|
21260
|
-
if (start2 > pos)
|
|
21261
|
-
break;
|
|
21262
|
-
let oldSize = this.ranges[i + oldIndex], end2 = start2 + oldSize;
|
|
21263
|
-
if (pos <= end2 && i == index2 * 3)
|
|
21264
|
-
return true;
|
|
21265
|
-
diff += this.ranges[i + newIndex] - oldSize;
|
|
21266
|
-
}
|
|
21267
|
-
return false;
|
|
21268
|
-
}
|
|
21269
|
-
/**
|
|
21270
|
-
Calls the given function on each of the changed ranges included in
|
|
21271
|
-
this map.
|
|
21272
|
-
*/
|
|
21273
|
-
forEach(f) {
|
|
21274
|
-
let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
21275
|
-
for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {
|
|
21276
|
-
let start2 = this.ranges[i], oldStart = start2 - (this.inverted ? diff : 0), newStart = start2 + (this.inverted ? 0 : diff);
|
|
21277
|
-
let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex];
|
|
21278
|
-
f(oldStart, oldStart + oldSize, newStart, newStart + newSize);
|
|
21279
|
-
diff += newSize - oldSize;
|
|
21280
|
-
}
|
|
21281
|
-
}
|
|
21282
|
-
/**
|
|
21283
|
-
Create an inverted version of this map. The result can be used to
|
|
21284
|
-
map positions in the post-step document to the pre-step document.
|
|
21285
|
-
*/
|
|
21286
|
-
invert() {
|
|
21287
|
-
return new StepMap(this.ranges, !this.inverted);
|
|
21288
|
-
}
|
|
21289
|
-
/**
|
|
21290
|
-
@internal
|
|
21291
|
-
*/
|
|
21292
|
-
toString() {
|
|
21293
|
-
return (this.inverted ? "-" : "") + JSON.stringify(this.ranges);
|
|
21294
|
-
}
|
|
21295
|
-
/**
|
|
21296
|
-
Create a map that moves all positions by offset `n` (which may be
|
|
21297
|
-
negative). This can be useful when applying steps meant for a
|
|
21298
|
-
sub-document to a larger document, or vice-versa.
|
|
21299
|
-
*/
|
|
21300
|
-
static offset(n) {
|
|
21301
|
-
return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]);
|
|
21248
|
+
);
|
|
21302
21249
|
}
|
|
21303
|
-
|
|
21304
|
-
|
|
21305
|
-
|
|
21306
|
-
|
|
21307
|
-
|
|
21308
|
-
|
|
21309
|
-
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21313
|
-
|
|
21314
|
-
|
|
21315
|
-
|
|
21316
|
-
|
|
21317
|
-
|
|
21318
|
-
|
|
21319
|
-
|
|
21320
|
-
|
|
21321
|
-
|
|
21322
|
-
|
|
21323
|
-
|
|
21324
|
-
|
|
21325
|
-
|
|
21326
|
-
|
|
21327
|
-
|
|
21328
|
-
|
|
21329
|
-
|
|
21330
|
-
|
|
21331
|
-
|
|
21332
|
-
|
|
21333
|
-
|
|
21334
|
-
|
|
21335
|
-
|
|
21336
|
-
|
|
21337
|
-
|
|
21338
|
-
|
|
21339
|
-
|
|
21340
|
-
|
|
21341
|
-
|
|
21342
|
-
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21349
|
-
|
|
21350
|
-
|
|
21351
|
-
|
|
21352
|
-
|
|
21353
|
-
|
|
21354
|
-
|
|
21355
|
-
|
|
21356
|
-
|
|
21357
|
-
|
|
21358
|
-
|
|
21359
|
-
|
|
21360
|
-
|
|
21361
|
-
|
|
21362
|
-
|
|
21363
|
-
|
|
21364
|
-
|
|
21365
|
-
|
|
21366
|
-
|
|
21367
|
-
|
|
21368
|
-
|
|
21369
|
-
/**
|
|
21370
|
-
Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given
|
|
21371
|
-
arguments. Create a successful result if it succeeds, and a
|
|
21372
|
-
failed one if it throws a `ReplaceError`.
|
|
21373
|
-
*/
|
|
21374
|
-
static fromReplace(doc, from, to, slice) {
|
|
21375
|
-
try {
|
|
21376
|
-
return StepResult.ok(doc.replace(from, to, slice));
|
|
21377
|
-
} catch (e) {
|
|
21378
|
-
if (e instanceof ReplaceError)
|
|
21379
|
-
return StepResult.fail(e.message);
|
|
21380
|
-
throw e;
|
|
21250
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21251
|
+
react.NodeViewWrapper,
|
|
21252
|
+
{
|
|
21253
|
+
"data-drag-handle": true,
|
|
21254
|
+
className: cn(
|
|
21255
|
+
"flex",
|
|
21256
|
+
node.attrs.align === Alignment.CENTER ? "justify-center" : node.attrs.align === Alignment.RIGHT ? "justify-end" : ""
|
|
21257
|
+
),
|
|
21258
|
+
children: node.attrs.type === MediaNodeTypes.Image ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21259
|
+
ResizableWithToolbarWrapper,
|
|
21260
|
+
{
|
|
21261
|
+
open: selected,
|
|
21262
|
+
mediaType: node.attrs.type,
|
|
21263
|
+
align: node.attrs.align,
|
|
21264
|
+
onResize: (maxWidth) => updateAttributes({ maxWidth }),
|
|
21265
|
+
onAlign: handleAlign,
|
|
21266
|
+
onDelete: handleDelete,
|
|
21267
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21268
|
+
"img",
|
|
21269
|
+
{
|
|
21270
|
+
src: node.attrs.src,
|
|
21271
|
+
alt: node.attrs.caption,
|
|
21272
|
+
className: cn(
|
|
21273
|
+
"object-contain w-full h-auto rounded-lg",
|
|
21274
|
+
selected && "border-2 border-blue-500"
|
|
21275
|
+
)
|
|
21276
|
+
}
|
|
21277
|
+
)
|
|
21278
|
+
}
|
|
21279
|
+
) : node.attrs.type === MediaNodeTypes.Video ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21280
|
+
ResizableWithToolbarWrapper,
|
|
21281
|
+
{
|
|
21282
|
+
open: selected,
|
|
21283
|
+
mediaType: node.attrs.type,
|
|
21284
|
+
align: node.attrs.align,
|
|
21285
|
+
onResize: (maxWidth) => updateAttributes({ maxWidth }),
|
|
21286
|
+
onAlign: handleAlign,
|
|
21287
|
+
onDelete: handleDelete,
|
|
21288
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21289
|
+
"video",
|
|
21290
|
+
{
|
|
21291
|
+
src: node.attrs.src,
|
|
21292
|
+
controls: true,
|
|
21293
|
+
className: cn("object-contain w-full h-auto", selected && "border-2 border-blue-500")
|
|
21294
|
+
}
|
|
21295
|
+
)
|
|
21296
|
+
}
|
|
21297
|
+
) : node.attrs.type === MediaNodeTypes.Audio ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative p-4 bg-accent/20 border border-border/20 w-full", children: [
|
|
21298
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21299
|
+
EditMediaToolbar,
|
|
21300
|
+
{
|
|
21301
|
+
open: selected,
|
|
21302
|
+
align: node.attrs.align,
|
|
21303
|
+
onAlign: handleAlign,
|
|
21304
|
+
onDelete: handleDelete
|
|
21305
|
+
}
|
|
21306
|
+
),
|
|
21307
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21308
|
+
"audio",
|
|
21309
|
+
{
|
|
21310
|
+
src: node.attrs.src,
|
|
21311
|
+
controls: true,
|
|
21312
|
+
className: cn("w-full", selected && "rounded-full border-2 border-blue-500")
|
|
21313
|
+
}
|
|
21314
|
+
)
|
|
21315
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-sm text-gray-600", children: "Unsupported media" })
|
|
21381
21316
|
}
|
|
21382
|
-
|
|
21383
|
-
}
|
|
21384
|
-
|
|
21385
|
-
|
|
21386
|
-
|
|
21387
|
-
|
|
21388
|
-
|
|
21389
|
-
|
|
21390
|
-
|
|
21391
|
-
|
|
21392
|
-
|
|
21393
|
-
|
|
21394
|
-
|
|
21395
|
-
|
|
21396
|
-
|
|
21397
|
-
|
|
21398
|
-
|
|
21399
|
-
|
|
21400
|
-
|
|
21401
|
-
|
|
21402
|
-
|
|
21403
|
-
|
|
21404
|
-
|
|
21405
|
-
|
|
21406
|
-
|
|
21407
|
-
|
|
21408
|
-
let
|
|
21409
|
-
let
|
|
21410
|
-
|
|
21411
|
-
|
|
21412
|
-
|
|
21413
|
-
|
|
21414
|
-
|
|
21415
|
-
}
|
|
21416
|
-
invert() {
|
|
21417
|
-
return new RemoveMarkStep(this.from, this.to, this.mark);
|
|
21418
|
-
}
|
|
21419
|
-
map(mapping) {
|
|
21420
|
-
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
21421
|
-
if (from.deleted && to.deleted || from.pos >= to.pos)
|
|
21422
|
-
return null;
|
|
21423
|
-
return new AddMarkStep(from.pos, to.pos, this.mark);
|
|
21424
|
-
}
|
|
21425
|
-
merge(other) {
|
|
21426
|
-
if (other instanceof AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from)
|
|
21427
|
-
return new AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
|
|
21428
|
-
return null;
|
|
21429
|
-
}
|
|
21430
|
-
toJSON() {
|
|
21431
|
-
return {
|
|
21432
|
-
stepType: "addMark",
|
|
21433
|
-
mark: this.mark.toJSON(),
|
|
21434
|
-
from: this.from,
|
|
21435
|
-
to: this.to
|
|
21436
|
-
};
|
|
21437
|
-
}
|
|
21438
|
-
/**
|
|
21439
|
-
@internal
|
|
21440
|
-
*/
|
|
21441
|
-
static fromJSON(schema, json) {
|
|
21442
|
-
if (typeof json.from != "number" || typeof json.to != "number")
|
|
21443
|
-
throw new RangeError("Invalid input for AddMarkStep.fromJSON");
|
|
21444
|
-
return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
|
|
21445
|
-
}
|
|
21446
|
-
}
|
|
21447
|
-
Step.jsonID("addMark", AddMarkStep);
|
|
21448
|
-
class RemoveMarkStep extends Step {
|
|
21449
|
-
/**
|
|
21450
|
-
Create a mark-removing step.
|
|
21451
|
-
*/
|
|
21452
|
-
constructor(from, to, mark) {
|
|
21453
|
-
super();
|
|
21454
|
-
this.from = from;
|
|
21455
|
-
this.to = to;
|
|
21456
|
-
this.mark = mark;
|
|
21457
|
-
}
|
|
21458
|
-
apply(doc) {
|
|
21459
|
-
let oldSlice = doc.slice(this.from, this.to);
|
|
21460
|
-
let slice = new Slice(mapFragment(oldSlice.content, (node) => {
|
|
21461
|
-
return node.mark(this.mark.removeFromSet(node.marks));
|
|
21462
|
-
}, doc), oldSlice.openStart, oldSlice.openEnd);
|
|
21463
|
-
return StepResult.fromReplace(doc, this.from, this.to, slice);
|
|
21464
|
-
}
|
|
21465
|
-
invert() {
|
|
21466
|
-
return new AddMarkStep(this.from, this.to, this.mark);
|
|
21467
|
-
}
|
|
21468
|
-
map(mapping) {
|
|
21469
|
-
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
21470
|
-
if (from.deleted && to.deleted || from.pos >= to.pos)
|
|
21471
|
-
return null;
|
|
21472
|
-
return new RemoveMarkStep(from.pos, to.pos, this.mark);
|
|
21473
|
-
}
|
|
21474
|
-
merge(other) {
|
|
21475
|
-
if (other instanceof RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from)
|
|
21476
|
-
return new RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
|
|
21477
|
-
return null;
|
|
21478
|
-
}
|
|
21479
|
-
toJSON() {
|
|
21480
|
-
return {
|
|
21481
|
-
stepType: "removeMark",
|
|
21482
|
-
mark: this.mark.toJSON(),
|
|
21483
|
-
from: this.from,
|
|
21484
|
-
to: this.to
|
|
21485
|
-
};
|
|
21486
|
-
}
|
|
21487
|
-
/**
|
|
21488
|
-
@internal
|
|
21489
|
-
*/
|
|
21490
|
-
static fromJSON(schema, json) {
|
|
21491
|
-
if (typeof json.from != "number" || typeof json.to != "number")
|
|
21492
|
-
throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");
|
|
21493
|
-
return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
|
|
21494
|
-
}
|
|
21495
|
-
}
|
|
21496
|
-
Step.jsonID("removeMark", RemoveMarkStep);
|
|
21497
|
-
class AddNodeMarkStep extends Step {
|
|
21498
|
-
/**
|
|
21499
|
-
Create a node mark step.
|
|
21500
|
-
*/
|
|
21501
|
-
constructor(pos, mark) {
|
|
21502
|
-
super();
|
|
21503
|
-
this.pos = pos;
|
|
21504
|
-
this.mark = mark;
|
|
21505
|
-
}
|
|
21506
|
-
apply(doc) {
|
|
21507
|
-
let node = doc.nodeAt(this.pos);
|
|
21508
|
-
if (!node)
|
|
21509
|
-
return StepResult.fail("No node at mark step's position");
|
|
21510
|
-
let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
|
|
21511
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
21512
|
-
}
|
|
21513
|
-
invert(doc) {
|
|
21514
|
-
let node = doc.nodeAt(this.pos);
|
|
21515
|
-
if (node) {
|
|
21516
|
-
let newSet = this.mark.addToSet(node.marks);
|
|
21517
|
-
if (newSet.length == node.marks.length) {
|
|
21518
|
-
for (let i = 0; i < node.marks.length; i++)
|
|
21519
|
-
if (!node.marks[i].isInSet(newSet))
|
|
21520
|
-
return new AddNodeMarkStep(this.pos, node.marks[i]);
|
|
21521
|
-
return new AddNodeMarkStep(this.pos, this.mark);
|
|
21317
|
+
);
|
|
21318
|
+
};
|
|
21319
|
+
const ResizableWithToolbarWrapper = ({
|
|
21320
|
+
open,
|
|
21321
|
+
align,
|
|
21322
|
+
onAlign,
|
|
21323
|
+
onDelete,
|
|
21324
|
+
onResize,
|
|
21325
|
+
mediaType,
|
|
21326
|
+
children
|
|
21327
|
+
}) => {
|
|
21328
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21329
|
+
ResizableWrapper,
|
|
21330
|
+
{
|
|
21331
|
+
onResize,
|
|
21332
|
+
className: cn(mediaType === MediaNodeTypes.Audio && "relative p-4 bg-accent/50"),
|
|
21333
|
+
children: [
|
|
21334
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditMediaToolbar, { open, align, onAlign, onDelete }),
|
|
21335
|
+
children
|
|
21336
|
+
]
|
|
21337
|
+
}
|
|
21338
|
+
);
|
|
21339
|
+
};
|
|
21340
|
+
const createDeleteByUidCommand = (nodeName) => {
|
|
21341
|
+
return (uid) => ({ state: state2, commands }) => {
|
|
21342
|
+
const { doc } = state2;
|
|
21343
|
+
let targetPos = null;
|
|
21344
|
+
let targetSize = null;
|
|
21345
|
+
doc.descendants((node, pos) => {
|
|
21346
|
+
if (node.type.name === nodeName && node.attrs.uid === uid) {
|
|
21347
|
+
targetPos = pos;
|
|
21348
|
+
targetSize = node.nodeSize;
|
|
21349
|
+
return false;
|
|
21522
21350
|
}
|
|
21351
|
+
});
|
|
21352
|
+
if (targetPos !== null && targetSize !== null) {
|
|
21353
|
+
return commands.deleteRange({
|
|
21354
|
+
from: targetPos,
|
|
21355
|
+
to: Number(targetPos) + Number(targetSize)
|
|
21356
|
+
});
|
|
21523
21357
|
}
|
|
21524
|
-
return
|
|
21525
|
-
}
|
|
21526
|
-
|
|
21527
|
-
|
|
21528
|
-
|
|
21529
|
-
|
|
21530
|
-
|
|
21531
|
-
|
|
21532
|
-
|
|
21533
|
-
|
|
21534
|
-
|
|
21535
|
-
|
|
21536
|
-
|
|
21537
|
-
|
|
21538
|
-
|
|
21539
|
-
|
|
21540
|
-
|
|
21541
|
-
}
|
|
21542
|
-
|
|
21543
|
-
|
|
21544
|
-
|
|
21545
|
-
|
|
21546
|
-
|
|
21547
|
-
|
|
21548
|
-
|
|
21549
|
-
|
|
21550
|
-
|
|
21551
|
-
|
|
21552
|
-
|
|
21553
|
-
|
|
21554
|
-
if (!
|
|
21555
|
-
|
|
21556
|
-
let
|
|
21557
|
-
|
|
21558
|
-
|
|
21559
|
-
|
|
21560
|
-
|
|
21561
|
-
|
|
21562
|
-
|
|
21563
|
-
|
|
21564
|
-
|
|
21565
|
-
|
|
21566
|
-
|
|
21567
|
-
|
|
21568
|
-
|
|
21569
|
-
|
|
21570
|
-
|
|
21571
|
-
|
|
21572
|
-
|
|
21573
|
-
|
|
21574
|
-
|
|
21575
|
-
|
|
21576
|
-
|
|
21577
|
-
|
|
21578
|
-
|
|
21579
|
-
|
|
21580
|
-
}
|
|
21581
|
-
|
|
21582
|
-
|
|
21583
|
-
|
|
21584
|
-
|
|
21585
|
-
|
|
21586
|
-
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
21592
|
-
|
|
21593
|
-
|
|
21594
|
-
|
|
21595
|
-
|
|
21596
|
-
|
|
21597
|
-
|
|
21598
|
-
|
|
21599
|
-
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
|
|
21603
|
-
|
|
21604
|
-
|
|
21605
|
-
|
|
21606
|
-
|
|
21607
|
-
|
|
21608
|
-
|
|
21609
|
-
|
|
21610
|
-
|
|
21611
|
-
|
|
21612
|
-
|
|
21613
|
-
|
|
21614
|
-
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21358
|
+
return false;
|
|
21359
|
+
};
|
|
21360
|
+
};
|
|
21361
|
+
const createUpdateByUidCommand = (nodeName) => {
|
|
21362
|
+
return (uid, attrs) => ({ state: state2, dispatch }) => {
|
|
21363
|
+
if (!dispatch) return false;
|
|
21364
|
+
const { doc, tr } = state2;
|
|
21365
|
+
let found2 = false;
|
|
21366
|
+
doc.descendants((node, pos) => {
|
|
21367
|
+
if (node.type.name === nodeName && node.attrs.uid === uid) {
|
|
21368
|
+
tr.setNodeMarkup(pos, void 0, {
|
|
21369
|
+
...node.attrs,
|
|
21370
|
+
...attrs
|
|
21371
|
+
});
|
|
21372
|
+
found2 = true;
|
|
21373
|
+
return false;
|
|
21374
|
+
}
|
|
21375
|
+
});
|
|
21376
|
+
if (found2) {
|
|
21377
|
+
dispatch(tr);
|
|
21378
|
+
return true;
|
|
21379
|
+
}
|
|
21380
|
+
return false;
|
|
21381
|
+
};
|
|
21382
|
+
};
|
|
21383
|
+
const createDeleteMarkByUidCommand = (markName) => {
|
|
21384
|
+
return (uid) => ({
|
|
21385
|
+
state: state2,
|
|
21386
|
+
dispatch
|
|
21387
|
+
}) => {
|
|
21388
|
+
if (!dispatch) return false;
|
|
21389
|
+
const { doc, schema } = state2;
|
|
21390
|
+
let tr = state2.tr;
|
|
21391
|
+
let found2 = false;
|
|
21392
|
+
const positions = [];
|
|
21393
|
+
doc.descendants((node, pos) => {
|
|
21394
|
+
if (node.isText && node.marks?.length) {
|
|
21395
|
+
node.marks.forEach((mark) => {
|
|
21396
|
+
if (mark.type.name === markName && mark.attrs.uid === uid) {
|
|
21397
|
+
positions.push({
|
|
21398
|
+
from: pos,
|
|
21399
|
+
to: pos + node.nodeSize
|
|
21400
|
+
});
|
|
21401
|
+
found2 = true;
|
|
21402
|
+
}
|
|
21403
|
+
});
|
|
21404
|
+
}
|
|
21405
|
+
});
|
|
21406
|
+
if (found2) {
|
|
21407
|
+
const markType = schema.marks[markName];
|
|
21408
|
+
if (markType) {
|
|
21409
|
+
positions.forEach(({ from, to }) => {
|
|
21410
|
+
tr = tr.removeMark(from, to, markType);
|
|
21411
|
+
});
|
|
21412
|
+
dispatch(tr);
|
|
21413
|
+
}
|
|
21414
|
+
}
|
|
21415
|
+
return found2;
|
|
21416
|
+
};
|
|
21417
|
+
};
|
|
21418
|
+
const createUpdateMarkByUidCommand = (markName) => {
|
|
21419
|
+
return (uid, attrs) => ({
|
|
21420
|
+
state: state2,
|
|
21421
|
+
dispatch
|
|
21422
|
+
}) => {
|
|
21423
|
+
console.log("=== UPDATE MARK COMMAND START ===");
|
|
21424
|
+
console.log("markName:", markName);
|
|
21425
|
+
console.log("uid:", uid);
|
|
21426
|
+
console.log("attrs:", attrs);
|
|
21427
|
+
console.log("state.doc:", state2.doc.toJSON());
|
|
21428
|
+
if (!dispatch) {
|
|
21429
|
+
console.log("No dispatch, returning false");
|
|
21430
|
+
return false;
|
|
21431
|
+
}
|
|
21432
|
+
const { doc, schema } = state2;
|
|
21433
|
+
let tr = state2.tr;
|
|
21434
|
+
let found2 = false;
|
|
21435
|
+
const positions = [];
|
|
21436
|
+
doc.descendants((node, pos) => {
|
|
21437
|
+
if (node.isText && node.marks?.length) {
|
|
21438
|
+
node.marks.forEach((mark) => {
|
|
21439
|
+
console.log("Checking mark:", {
|
|
21440
|
+
markType: mark.type.name,
|
|
21441
|
+
markUid: mark.attrs.uid,
|
|
21442
|
+
targetMarkName: markName,
|
|
21443
|
+
targetUid: uid,
|
|
21444
|
+
matches: mark.type.name === markName && mark.attrs.uid === uid
|
|
21445
|
+
});
|
|
21446
|
+
if (mark.type.name === markName && mark.attrs.uid === uid) {
|
|
21447
|
+
positions.push({
|
|
21448
|
+
from: pos,
|
|
21449
|
+
to: pos + node.nodeSize,
|
|
21450
|
+
mark
|
|
21451
|
+
});
|
|
21452
|
+
found2 = true;
|
|
21453
|
+
console.log("Found matching mark at:", { from: pos, to: pos + node.nodeSize });
|
|
21454
|
+
}
|
|
21455
|
+
});
|
|
21456
|
+
}
|
|
21457
|
+
});
|
|
21458
|
+
console.log("Total positions found:", positions.length);
|
|
21459
|
+
console.log("Positions:", positions);
|
|
21460
|
+
if (found2) {
|
|
21461
|
+
positions.forEach(({ from, to, mark }) => {
|
|
21462
|
+
const newAttrs = { ...mark.attrs, ...attrs };
|
|
21463
|
+
const markType = schema.marks[markName];
|
|
21464
|
+
console.log("Applying update:", { from, to, oldAttrs: mark.attrs, newAttrs });
|
|
21465
|
+
if (markType) {
|
|
21466
|
+
console.log("Before removeMark - tr.doc:", tr.doc.toJSON());
|
|
21467
|
+
tr = tr.removeMark(from, to, markType);
|
|
21468
|
+
console.log("After removeMark - tr.doc:", tr.doc.toJSON());
|
|
21469
|
+
tr = tr.addMark(from, to, markType.create(newAttrs));
|
|
21470
|
+
console.log("After addMark - tr.doc:", tr.doc.toJSON());
|
|
21471
|
+
}
|
|
21472
|
+
});
|
|
21473
|
+
console.log("About to dispatch transaction");
|
|
21474
|
+
console.log("Final tr.doc:", tr.doc.toJSON());
|
|
21475
|
+
console.log("Original state.doc:", state2.doc.toJSON());
|
|
21476
|
+
dispatch(tr);
|
|
21477
|
+
console.log("Transaction dispatched successfully");
|
|
21627
21478
|
}
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
|
|
21631
|
-
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
this
|
|
21663
|
-
}
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21671
|
-
|
|
21672
|
-
|
|
21673
|
-
|
|
21674
|
-
|
|
21675
|
-
|
|
21676
|
-
|
|
21677
|
-
|
|
21678
|
-
|
|
21679
|
-
|
|
21680
|
-
|
|
21681
|
-
|
|
21682
|
-
|
|
21683
|
-
|
|
21684
|
-
}
|
|
21685
|
-
|
|
21686
|
-
|
|
21687
|
-
|
|
21688
|
-
|
|
21689
|
-
|
|
21690
|
-
|
|
21691
|
-
|
|
21692
|
-
|
|
21693
|
-
|
|
21694
|
-
|
|
21695
|
-
|
|
21696
|
-
|
|
21697
|
-
|
|
21698
|
-
|
|
21699
|
-
|
|
21700
|
-
|
|
21701
|
-
|
|
21702
|
-
|
|
21703
|
-
|
|
21704
|
-
|
|
21479
|
+
console.log("=== UPDATE MARK COMMAND END ===");
|
|
21480
|
+
return found2;
|
|
21481
|
+
};
|
|
21482
|
+
};
|
|
21483
|
+
const DEFAULT_MEDIA_ATTRS = {
|
|
21484
|
+
uid: "",
|
|
21485
|
+
src: "",
|
|
21486
|
+
type: MediaNodeTypes.Image,
|
|
21487
|
+
style: "object-fit: contain; width: 100%; border-radius: 0.5rem;",
|
|
21488
|
+
maxWidth: MEDIA_MIN_WIDTH,
|
|
21489
|
+
align: Alignment.LEFT,
|
|
21490
|
+
caption: "",
|
|
21491
|
+
uploading: false,
|
|
21492
|
+
progress: 0
|
|
21493
|
+
};
|
|
21494
|
+
const MediaNode = core.Node.create({
|
|
21495
|
+
name: "media",
|
|
21496
|
+
group: "block",
|
|
21497
|
+
atom: true,
|
|
21498
|
+
addAttributes() {
|
|
21499
|
+
return {
|
|
21500
|
+
uid: { default: DEFAULT_MEDIA_ATTRS.uid },
|
|
21501
|
+
src: { default: DEFAULT_MEDIA_ATTRS.src },
|
|
21502
|
+
type: { default: DEFAULT_MEDIA_ATTRS.type },
|
|
21503
|
+
style: { default: DEFAULT_MEDIA_ATTRS.style },
|
|
21504
|
+
maxWidth: { default: DEFAULT_MEDIA_ATTRS.maxWidth },
|
|
21505
|
+
align: { default: DEFAULT_MEDIA_ATTRS.align },
|
|
21506
|
+
caption: { default: DEFAULT_MEDIA_ATTRS.caption },
|
|
21507
|
+
uploading: { default: DEFAULT_MEDIA_ATTRS.uploading },
|
|
21508
|
+
progress: { default: DEFAULT_MEDIA_ATTRS.progress },
|
|
21509
|
+
payload: { default: null, parseHTML: () => null, renderHTML: () => ({}) }
|
|
21510
|
+
};
|
|
21511
|
+
},
|
|
21512
|
+
draggable() {
|
|
21513
|
+
return Boolean(!this?.options?.attrs?.uploading && !this?.options?.attrs?.mediaMode);
|
|
21514
|
+
},
|
|
21515
|
+
selectable() {
|
|
21516
|
+
return Boolean(!this?.options?.attrs?.mediaMode);
|
|
21517
|
+
},
|
|
21518
|
+
parseHTML() {
|
|
21519
|
+
return [
|
|
21520
|
+
{
|
|
21521
|
+
tag: "div[data-media]",
|
|
21522
|
+
getAttrs: (dom) => {
|
|
21523
|
+
return {
|
|
21524
|
+
uid: dom.getAttribute("data-uid") || "",
|
|
21525
|
+
src: dom.getAttribute("data-src") || "",
|
|
21526
|
+
type: dom.getAttribute("data-type") || MediaNodeTypes.Image,
|
|
21527
|
+
align: dom.getAttribute("data-align") || Alignment.LEFT,
|
|
21528
|
+
caption: dom.getAttribute("data-caption") || "",
|
|
21529
|
+
style: dom.getAttribute("style") || DEFAULT_MEDIA_ATTRS.style
|
|
21530
|
+
};
|
|
21531
|
+
}
|
|
21532
|
+
}
|
|
21533
|
+
];
|
|
21534
|
+
},
|
|
21535
|
+
renderHTML({ HTMLAttributes }) {
|
|
21536
|
+
const { uid, src, style, type, align, maxWidth, caption } = HTMLAttributes;
|
|
21537
|
+
const tag = MEDIA_TAGS[type];
|
|
21538
|
+
const wrapperAttrs = core.mergeAttributes({
|
|
21539
|
+
style: buildWrapperStyle(align),
|
|
21540
|
+
"data-media": true,
|
|
21541
|
+
"data-uid": uid,
|
|
21542
|
+
"data-type": type,
|
|
21543
|
+
"data-src": src,
|
|
21544
|
+
"data-caption": caption || "",
|
|
21545
|
+
"data-align": align
|
|
21546
|
+
});
|
|
21547
|
+
const mediaAttrs = core.mergeAttributes(
|
|
21548
|
+
{ src, style: buildMediaStyle(style, type, maxWidth) },
|
|
21549
|
+
{ controls: type === MediaNodeTypes.Audio || type === MediaNodeTypes.Video }
|
|
21550
|
+
);
|
|
21551
|
+
return ["div", wrapperAttrs, [tag, mediaAttrs]];
|
|
21552
|
+
},
|
|
21553
|
+
addNodeView() {
|
|
21554
|
+
return react.ReactNodeViewRenderer(MediaNodeView);
|
|
21555
|
+
},
|
|
21556
|
+
addCommands() {
|
|
21557
|
+
return {
|
|
21558
|
+
insertMedia: (options) => ({ commands, chain }) => {
|
|
21559
|
+
if (this?.options?.attrs?.mediaMode) {
|
|
21560
|
+
return chain().insertContent([{ type: this.name, attrs: options }]).command(({ tr, dispatch }) => {
|
|
21561
|
+
if (dispatch) {
|
|
21562
|
+
const endPos = tr.doc.content.size;
|
|
21563
|
+
const $pos = tr.doc.resolve(endPos);
|
|
21564
|
+
tr.setSelection(state.TextSelection.near($pos));
|
|
21565
|
+
}
|
|
21566
|
+
return true;
|
|
21567
|
+
}).run();
|
|
21568
|
+
}
|
|
21569
|
+
return commands.insertContent([
|
|
21570
|
+
{ type: this.name, attrs: options },
|
|
21571
|
+
{ type: "paragraph" }
|
|
21572
|
+
//! Fixes multiple media overlapping issue (But removes default selection feature)
|
|
21573
|
+
]);
|
|
21574
|
+
},
|
|
21575
|
+
updateMediaByUid: createUpdateByUidCommand(this.name),
|
|
21576
|
+
deleteMediaByUid: createDeleteByUidCommand(this.name),
|
|
21577
|
+
updateMediaProgress: (uid, progress) => ({ commands }) => {
|
|
21578
|
+
return commands.updateMediaByUid(uid, { progress });
|
|
21579
|
+
}
|
|
21580
|
+
};
|
|
21581
|
+
},
|
|
21582
|
+
addKeyboardShortcuts() {
|
|
21583
|
+
return {
|
|
21584
|
+
Backspace: () => {
|
|
21585
|
+
const { selection, doc } = this.editor.state;
|
|
21586
|
+
const $pos = selection.$anchor;
|
|
21587
|
+
const nodeBefore = $pos.nodeBefore;
|
|
21588
|
+
if (nodeBefore?.type.name === this.name && nodeBefore.attrs.uploading) {
|
|
21589
|
+
toast.info("Please wait for upload to complete or cancel it first");
|
|
21590
|
+
return true;
|
|
21591
|
+
}
|
|
21592
|
+
const nodeAtSelection = doc.nodeAt(selection.from);
|
|
21593
|
+
if (nodeAtSelection?.type.name === this.name && nodeAtSelection.attrs.uploading) {
|
|
21594
|
+
toast.info("Please wait for upload to complete or cancel it first");
|
|
21595
|
+
return true;
|
|
21596
|
+
}
|
|
21597
|
+
return false;
|
|
21598
|
+
},
|
|
21599
|
+
Delete: () => {
|
|
21600
|
+
const { selection, doc } = this.editor.state;
|
|
21601
|
+
const $pos = selection.$anchor;
|
|
21602
|
+
const nodeAfter = $pos.nodeAfter;
|
|
21603
|
+
if (nodeAfter?.type.name === this.name && nodeAfter.attrs.uploading) {
|
|
21604
|
+
toast.info("Please wait for upload to complete or cancel it first");
|
|
21605
|
+
return true;
|
|
21606
|
+
}
|
|
21607
|
+
const nodeAtSelection = doc.nodeAt(selection.from);
|
|
21608
|
+
if (nodeAtSelection?.type.name === this.name && nodeAtSelection.attrs.uploading) {
|
|
21609
|
+
toast.info("Please wait for upload to complete or cancel it first");
|
|
21610
|
+
return true;
|
|
21611
|
+
}
|
|
21612
|
+
return false;
|
|
21613
|
+
}
|
|
21705
21614
|
};
|
|
21706
|
-
if (this.slice.size)
|
|
21707
|
-
json.slice = this.slice.toJSON();
|
|
21708
|
-
if (this.structure)
|
|
21709
|
-
json.structure = true;
|
|
21710
|
-
return json;
|
|
21711
|
-
}
|
|
21712
|
-
/**
|
|
21713
|
-
@internal
|
|
21714
|
-
*/
|
|
21715
|
-
static fromJSON(schema, json) {
|
|
21716
|
-
if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number")
|
|
21717
|
-
throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");
|
|
21718
|
-
return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure);
|
|
21719
21615
|
}
|
|
21616
|
+
});
|
|
21617
|
+
const buildWrapperStyle = (align) => `width: 100%; display: flex; justify-content: ${getAlignmentStyle(align)}; margin:16px 0`;
|
|
21618
|
+
const buildMediaStyle = (baseStyle, type, maxWidth) => `${baseStyle}; max-width: ${type === MediaNodeTypes.Audio ? "100%" : `${maxWidth}%`}; ${type !== MediaNodeTypes.Audio ? "height: auto;" : ""}`;
|
|
21619
|
+
const getAlignmentStyle = (align) => {
|
|
21620
|
+
const map = {
|
|
21621
|
+
[Alignment.LEFT]: "flex-start",
|
|
21622
|
+
[Alignment.CENTER]: "center",
|
|
21623
|
+
[Alignment.RIGHT]: "flex-end"
|
|
21624
|
+
};
|
|
21625
|
+
return map[align] || "flex-start";
|
|
21626
|
+
};
|
|
21627
|
+
const lower16 = 65535;
|
|
21628
|
+
const factor16 = Math.pow(2, 16);
|
|
21629
|
+
function makeRecover(index2, offset2) {
|
|
21630
|
+
return index2 + offset2 * factor16;
|
|
21720
21631
|
}
|
|
21721
|
-
|
|
21722
|
-
|
|
21723
|
-
let $from = doc.resolve(from), dist = to - from, depth = $from.depth;
|
|
21724
|
-
while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {
|
|
21725
|
-
depth--;
|
|
21726
|
-
dist--;
|
|
21727
|
-
}
|
|
21728
|
-
if (dist > 0) {
|
|
21729
|
-
let next = $from.node(depth).maybeChild($from.indexAfter(depth));
|
|
21730
|
-
while (dist > 0) {
|
|
21731
|
-
if (!next || next.isLeaf)
|
|
21732
|
-
return true;
|
|
21733
|
-
next = next.firstChild;
|
|
21734
|
-
dist--;
|
|
21735
|
-
}
|
|
21736
|
-
}
|
|
21737
|
-
return false;
|
|
21632
|
+
function recoverIndex(value) {
|
|
21633
|
+
return value & lower16;
|
|
21738
21634
|
}
|
|
21739
|
-
|
|
21635
|
+
function recoverOffset(value) {
|
|
21636
|
+
return (value - (value & lower16)) / factor16;
|
|
21637
|
+
}
|
|
21638
|
+
const DEL_BEFORE = 1, DEL_AFTER = 2, DEL_ACROSS = 4, DEL_SIDE = 8;
|
|
21639
|
+
class MapResult {
|
|
21740
21640
|
/**
|
|
21741
|
-
|
|
21641
|
+
@internal
|
|
21742
21642
|
*/
|
|
21743
|
-
constructor(pos,
|
|
21744
|
-
super();
|
|
21643
|
+
constructor(pos, delInfo, recover) {
|
|
21745
21644
|
this.pos = pos;
|
|
21746
|
-
this.
|
|
21747
|
-
this.
|
|
21748
|
-
}
|
|
21749
|
-
apply(doc) {
|
|
21750
|
-
let node = doc.nodeAt(this.pos);
|
|
21751
|
-
if (!node)
|
|
21752
|
-
return StepResult.fail("No node at attribute step's position");
|
|
21753
|
-
let attrs = /* @__PURE__ */ Object.create(null);
|
|
21754
|
-
for (let name in node.attrs)
|
|
21755
|
-
attrs[name] = node.attrs[name];
|
|
21756
|
-
attrs[this.attr] = this.value;
|
|
21757
|
-
let updated = node.type.create(attrs, null, node.marks);
|
|
21758
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
21759
|
-
}
|
|
21760
|
-
getMap() {
|
|
21761
|
-
return StepMap.empty;
|
|
21762
|
-
}
|
|
21763
|
-
invert(doc) {
|
|
21764
|
-
return new AttrStep(this.pos, this.attr, doc.nodeAt(this.pos).attrs[this.attr]);
|
|
21765
|
-
}
|
|
21766
|
-
map(mapping) {
|
|
21767
|
-
let pos = mapping.mapResult(this.pos, 1);
|
|
21768
|
-
return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value);
|
|
21769
|
-
}
|
|
21770
|
-
toJSON() {
|
|
21771
|
-
return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value };
|
|
21772
|
-
}
|
|
21773
|
-
static fromJSON(schema, json) {
|
|
21774
|
-
if (typeof json.pos != "number" || typeof json.attr != "string")
|
|
21775
|
-
throw new RangeError("Invalid input for AttrStep.fromJSON");
|
|
21776
|
-
return new AttrStep(json.pos, json.attr, json.value);
|
|
21645
|
+
this.delInfo = delInfo;
|
|
21646
|
+
this.recover = recover;
|
|
21777
21647
|
}
|
|
21778
|
-
}
|
|
21779
|
-
Step.jsonID("attr", AttrStep);
|
|
21780
|
-
class DocAttrStep extends Step {
|
|
21781
21648
|
/**
|
|
21782
|
-
|
|
21649
|
+
Tells you whether the position was deleted, that is, whether the
|
|
21650
|
+
step removed the token on the side queried (via the `assoc`)
|
|
21651
|
+
argument from the document.
|
|
21783
21652
|
*/
|
|
21784
|
-
|
|
21785
|
-
|
|
21786
|
-
this.attr = attr;
|
|
21787
|
-
this.value = value;
|
|
21788
|
-
}
|
|
21789
|
-
apply(doc) {
|
|
21790
|
-
let attrs = /* @__PURE__ */ Object.create(null);
|
|
21791
|
-
for (let name in doc.attrs)
|
|
21792
|
-
attrs[name] = doc.attrs[name];
|
|
21793
|
-
attrs[this.attr] = this.value;
|
|
21794
|
-
let updated = doc.type.create(attrs, doc.content, doc.marks);
|
|
21795
|
-
return StepResult.ok(updated);
|
|
21796
|
-
}
|
|
21797
|
-
getMap() {
|
|
21798
|
-
return StepMap.empty;
|
|
21799
|
-
}
|
|
21800
|
-
invert(doc) {
|
|
21801
|
-
return new DocAttrStep(this.attr, doc.attrs[this.attr]);
|
|
21653
|
+
get deleted() {
|
|
21654
|
+
return (this.delInfo & DEL_SIDE) > 0;
|
|
21802
21655
|
}
|
|
21803
|
-
|
|
21804
|
-
|
|
21656
|
+
/**
|
|
21657
|
+
Tells you whether the token before the mapped position was deleted.
|
|
21658
|
+
*/
|
|
21659
|
+
get deletedBefore() {
|
|
21660
|
+
return (this.delInfo & (DEL_BEFORE | DEL_ACROSS)) > 0;
|
|
21805
21661
|
}
|
|
21806
|
-
|
|
21807
|
-
|
|
21662
|
+
/**
|
|
21663
|
+
True when the token after the mapped position was deleted.
|
|
21664
|
+
*/
|
|
21665
|
+
get deletedAfter() {
|
|
21666
|
+
return (this.delInfo & (DEL_AFTER | DEL_ACROSS)) > 0;
|
|
21808
21667
|
}
|
|
21809
|
-
|
|
21810
|
-
|
|
21811
|
-
|
|
21812
|
-
|
|
21668
|
+
/**
|
|
21669
|
+
Tells whether any of the steps mapped through deletes across the
|
|
21670
|
+
position (including both the token before and after the
|
|
21671
|
+
position).
|
|
21672
|
+
*/
|
|
21673
|
+
get deletedAcross() {
|
|
21674
|
+
return (this.delInfo & DEL_ACROSS) > 0;
|
|
21813
21675
|
}
|
|
21814
21676
|
}
|
|
21815
|
-
|
|
21816
|
-
let TransformError = class extends Error {
|
|
21817
|
-
};
|
|
21818
|
-
TransformError = function TransformError2(message) {
|
|
21819
|
-
let err = Error.call(this, message);
|
|
21820
|
-
err.__proto__ = TransformError2.prototype;
|
|
21821
|
-
return err;
|
|
21822
|
-
};
|
|
21823
|
-
TransformError.prototype = Object.create(Error.prototype);
|
|
21824
|
-
TransformError.prototype.constructor = TransformError;
|
|
21825
|
-
TransformError.prototype.name = "TransformError";
|
|
21826
|
-
const classesById = /* @__PURE__ */ Object.create(null);
|
|
21827
|
-
class Selection {
|
|
21677
|
+
class StepMap {
|
|
21828
21678
|
/**
|
|
21829
|
-
|
|
21830
|
-
|
|
21831
|
-
|
|
21679
|
+
Create a position map. The modifications to the document are
|
|
21680
|
+
represented as an array of numbers, in which each group of three
|
|
21681
|
+
represents a modified chunk as `[start, oldSize, newSize]`.
|
|
21832
21682
|
*/
|
|
21833
|
-
constructor(
|
|
21834
|
-
this
|
|
21835
|
-
this
|
|
21836
|
-
|
|
21683
|
+
constructor(ranges, inverted = false) {
|
|
21684
|
+
this.ranges = ranges;
|
|
21685
|
+
this.inverted = inverted;
|
|
21686
|
+
if (!ranges.length && StepMap.empty)
|
|
21687
|
+
return StepMap.empty;
|
|
21837
21688
|
}
|
|
21838
21689
|
/**
|
|
21839
|
-
|
|
21690
|
+
@internal
|
|
21840
21691
|
*/
|
|
21841
|
-
|
|
21842
|
-
|
|
21692
|
+
recover(value) {
|
|
21693
|
+
let diff = 0, index2 = recoverIndex(value);
|
|
21694
|
+
if (!this.inverted)
|
|
21695
|
+
for (let i = 0; i < index2; i++)
|
|
21696
|
+
diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1];
|
|
21697
|
+
return this.ranges[index2 * 3] + diff + recoverOffset(value);
|
|
21698
|
+
}
|
|
21699
|
+
mapResult(pos, assoc = 1) {
|
|
21700
|
+
return this._map(pos, assoc, false);
|
|
21701
|
+
}
|
|
21702
|
+
map(pos, assoc = 1) {
|
|
21703
|
+
return this._map(pos, assoc, true);
|
|
21843
21704
|
}
|
|
21844
21705
|
/**
|
|
21845
|
-
|
|
21706
|
+
@internal
|
|
21846
21707
|
*/
|
|
21847
|
-
|
|
21848
|
-
|
|
21708
|
+
_map(pos, assoc, simple) {
|
|
21709
|
+
let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
21710
|
+
for (let i = 0; i < this.ranges.length; i += 3) {
|
|
21711
|
+
let start2 = this.ranges[i] - (this.inverted ? diff : 0);
|
|
21712
|
+
if (start2 > pos)
|
|
21713
|
+
break;
|
|
21714
|
+
let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end2 = start2 + oldSize;
|
|
21715
|
+
if (pos <= end2) {
|
|
21716
|
+
let side = !oldSize ? assoc : pos == start2 ? -1 : pos == end2 ? 1 : assoc;
|
|
21717
|
+
let result = start2 + diff + (side < 0 ? 0 : newSize);
|
|
21718
|
+
if (simple)
|
|
21719
|
+
return result;
|
|
21720
|
+
let recover = pos == (assoc < 0 ? start2 : end2) ? null : makeRecover(i / 3, pos - start2);
|
|
21721
|
+
let del = pos == start2 ? DEL_AFTER : pos == end2 ? DEL_BEFORE : DEL_ACROSS;
|
|
21722
|
+
if (assoc < 0 ? pos != start2 : pos != end2)
|
|
21723
|
+
del |= DEL_SIDE;
|
|
21724
|
+
return new MapResult(result, del, recover);
|
|
21725
|
+
}
|
|
21726
|
+
diff += newSize - oldSize;
|
|
21727
|
+
}
|
|
21728
|
+
return simple ? pos + diff : new MapResult(pos + diff, 0, null);
|
|
21849
21729
|
}
|
|
21850
21730
|
/**
|
|
21851
|
-
|
|
21731
|
+
@internal
|
|
21852
21732
|
*/
|
|
21853
|
-
|
|
21854
|
-
|
|
21733
|
+
touches(pos, recover) {
|
|
21734
|
+
let diff = 0, index2 = recoverIndex(recover);
|
|
21735
|
+
let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
21736
|
+
for (let i = 0; i < this.ranges.length; i += 3) {
|
|
21737
|
+
let start2 = this.ranges[i] - (this.inverted ? diff : 0);
|
|
21738
|
+
if (start2 > pos)
|
|
21739
|
+
break;
|
|
21740
|
+
let oldSize = this.ranges[i + oldIndex], end2 = start2 + oldSize;
|
|
21741
|
+
if (pos <= end2 && i == index2 * 3)
|
|
21742
|
+
return true;
|
|
21743
|
+
diff += this.ranges[i + newIndex] - oldSize;
|
|
21744
|
+
}
|
|
21745
|
+
return false;
|
|
21855
21746
|
}
|
|
21856
21747
|
/**
|
|
21857
|
-
|
|
21748
|
+
Calls the given function on each of the changed ranges included in
|
|
21749
|
+
this map.
|
|
21858
21750
|
*/
|
|
21859
|
-
|
|
21860
|
-
|
|
21751
|
+
forEach(f) {
|
|
21752
|
+
let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
|
|
21753
|
+
for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {
|
|
21754
|
+
let start2 = this.ranges[i], oldStart = start2 - (this.inverted ? diff : 0), newStart = start2 + (this.inverted ? 0 : diff);
|
|
21755
|
+
let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex];
|
|
21756
|
+
f(oldStart, oldStart + oldSize, newStart, newStart + newSize);
|
|
21757
|
+
diff += newSize - oldSize;
|
|
21758
|
+
}
|
|
21861
21759
|
}
|
|
21862
21760
|
/**
|
|
21863
|
-
|
|
21761
|
+
Create an inverted version of this map. The result can be used to
|
|
21762
|
+
map positions in the post-step document to the pre-step document.
|
|
21864
21763
|
*/
|
|
21865
|
-
|
|
21866
|
-
return this.ranges
|
|
21764
|
+
invert() {
|
|
21765
|
+
return new StepMap(this.ranges, !this.inverted);
|
|
21867
21766
|
}
|
|
21868
21767
|
/**
|
|
21869
|
-
|
|
21768
|
+
@internal
|
|
21870
21769
|
*/
|
|
21871
|
-
|
|
21872
|
-
return this.ranges
|
|
21770
|
+
toString() {
|
|
21771
|
+
return (this.inverted ? "-" : "") + JSON.stringify(this.ranges);
|
|
21873
21772
|
}
|
|
21874
21773
|
/**
|
|
21875
|
-
|
|
21876
|
-
|
|
21877
|
-
|
|
21878
|
-
|
|
21879
|
-
|
|
21880
|
-
|
|
21881
|
-
return false;
|
|
21882
|
-
return true;
|
|
21774
|
+
Create a map that moves all positions by offset `n` (which may be
|
|
21775
|
+
negative). This can be useful when applying steps meant for a
|
|
21776
|
+
sub-document to a larger document, or vice-versa.
|
|
21777
|
+
*/
|
|
21778
|
+
static offset(n) {
|
|
21779
|
+
return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]);
|
|
21883
21780
|
}
|
|
21781
|
+
}
|
|
21782
|
+
StepMap.empty = new StepMap([]);
|
|
21783
|
+
const stepsByID = /* @__PURE__ */ Object.create(null);
|
|
21784
|
+
class Step {
|
|
21884
21785
|
/**
|
|
21885
|
-
Get the
|
|
21786
|
+
Get the step map that represents the changes made by this step,
|
|
21787
|
+
and which can be used to transform between positions in the old
|
|
21788
|
+
and the new document.
|
|
21886
21789
|
*/
|
|
21887
|
-
|
|
21888
|
-
return
|
|
21790
|
+
getMap() {
|
|
21791
|
+
return StepMap.empty;
|
|
21889
21792
|
}
|
|
21890
21793
|
/**
|
|
21891
|
-
|
|
21892
|
-
|
|
21794
|
+
Try to merge this step with another one, to be applied directly
|
|
21795
|
+
after it. Returns the merged step when possible, null if the
|
|
21796
|
+
steps can't be merged.
|
|
21893
21797
|
*/
|
|
21894
|
-
|
|
21895
|
-
|
|
21896
|
-
for (let i = 0; i < content.openEnd; i++) {
|
|
21897
|
-
lastParent = lastNode;
|
|
21898
|
-
lastNode = lastNode.lastChild;
|
|
21899
|
-
}
|
|
21900
|
-
let mapFrom = tr.steps.length, ranges = this.ranges;
|
|
21901
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
21902
|
-
let { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
|
|
21903
|
-
tr.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
|
|
21904
|
-
if (i == 0)
|
|
21905
|
-
selectionToInsertionEnd(tr, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1);
|
|
21906
|
-
}
|
|
21798
|
+
merge(other) {
|
|
21799
|
+
return null;
|
|
21907
21800
|
}
|
|
21908
21801
|
/**
|
|
21909
|
-
|
|
21910
|
-
to the
|
|
21802
|
+
Deserialize a step from its JSON representation. Will call
|
|
21803
|
+
through to the step class' own implementation of this method.
|
|
21911
21804
|
*/
|
|
21912
|
-
|
|
21913
|
-
|
|
21914
|
-
|
|
21915
|
-
|
|
21916
|
-
|
|
21917
|
-
|
|
21918
|
-
|
|
21919
|
-
} else {
|
|
21920
|
-
tr.replaceRangeWith(from, to, node);
|
|
21921
|
-
selectionToInsertionEnd(tr, mapFrom, node.isInline ? -1 : 1);
|
|
21922
|
-
}
|
|
21923
|
-
}
|
|
21805
|
+
static fromJSON(schema, json) {
|
|
21806
|
+
if (!json || !json.stepType)
|
|
21807
|
+
throw new RangeError("Invalid input for Step.fromJSON");
|
|
21808
|
+
let type = stepsByID[json.stepType];
|
|
21809
|
+
if (!type)
|
|
21810
|
+
throw new RangeError(`No step type ${json.stepType} defined`);
|
|
21811
|
+
return type.fromJSON(schema, json);
|
|
21924
21812
|
}
|
|
21925
21813
|
/**
|
|
21926
|
-
|
|
21927
|
-
|
|
21928
|
-
|
|
21929
|
-
|
|
21930
|
-
found.
|
|
21814
|
+
To be able to serialize steps to JSON, each step needs a string
|
|
21815
|
+
ID to attach to its JSON representation. Use this method to
|
|
21816
|
+
register an ID for your step classes. Try to pick something
|
|
21817
|
+
that's unlikely to clash with steps from other modules.
|
|
21931
21818
|
*/
|
|
21932
|
-
static
|
|
21933
|
-
|
|
21934
|
-
|
|
21935
|
-
|
|
21936
|
-
|
|
21937
|
-
|
|
21938
|
-
if (found2)
|
|
21939
|
-
return found2;
|
|
21940
|
-
}
|
|
21941
|
-
return null;
|
|
21819
|
+
static jsonID(id, stepClass) {
|
|
21820
|
+
if (id in stepsByID)
|
|
21821
|
+
throw new RangeError("Duplicate use of step JSON ID " + id);
|
|
21822
|
+
stepsByID[id] = stepClass;
|
|
21823
|
+
stepClass.prototype.jsonID = id;
|
|
21824
|
+
return stepClass;
|
|
21942
21825
|
}
|
|
21826
|
+
}
|
|
21827
|
+
class StepResult {
|
|
21943
21828
|
/**
|
|
21944
|
-
|
|
21945
|
-
position. Searches forward first by default, but if `bias` is
|
|
21946
|
-
negative, it will search backwards first.
|
|
21829
|
+
@internal
|
|
21947
21830
|
*/
|
|
21948
|
-
|
|
21949
|
-
|
|
21831
|
+
constructor(doc, failed) {
|
|
21832
|
+
this.doc = doc;
|
|
21833
|
+
this.failed = failed;
|
|
21950
21834
|
}
|
|
21951
21835
|
/**
|
|
21952
|
-
|
|
21953
|
-
the given document. Will return an
|
|
21954
|
-
[`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position
|
|
21955
|
-
exists.
|
|
21836
|
+
Create a successful step result.
|
|
21956
21837
|
*/
|
|
21957
|
-
static
|
|
21958
|
-
return
|
|
21838
|
+
static ok(doc) {
|
|
21839
|
+
return new StepResult(doc, null);
|
|
21959
21840
|
}
|
|
21960
21841
|
/**
|
|
21961
|
-
|
|
21962
|
-
given document.
|
|
21842
|
+
Create a failed step result.
|
|
21963
21843
|
*/
|
|
21964
|
-
static
|
|
21965
|
-
return
|
|
21844
|
+
static fail(message) {
|
|
21845
|
+
return new StepResult(null, message);
|
|
21966
21846
|
}
|
|
21967
21847
|
/**
|
|
21968
|
-
|
|
21969
|
-
|
|
21848
|
+
Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given
|
|
21849
|
+
arguments. Create a successful result if it succeeds, and a
|
|
21850
|
+
failed one if it throws a `ReplaceError`.
|
|
21970
21851
|
*/
|
|
21971
|
-
static
|
|
21972
|
-
|
|
21973
|
-
|
|
21974
|
-
|
|
21975
|
-
|
|
21976
|
-
|
|
21977
|
-
|
|
21852
|
+
static fromReplace(doc, from, to, slice) {
|
|
21853
|
+
try {
|
|
21854
|
+
return StepResult.ok(doc.replace(from, to, slice));
|
|
21855
|
+
} catch (e) {
|
|
21856
|
+
if (e instanceof ReplaceError)
|
|
21857
|
+
return StepResult.fail(e.message);
|
|
21858
|
+
throw e;
|
|
21859
|
+
}
|
|
21860
|
+
}
|
|
21861
|
+
}
|
|
21862
|
+
function mapFragment(fragment, f, parent2) {
|
|
21863
|
+
let mapped = [];
|
|
21864
|
+
for (let i = 0; i < fragment.childCount; i++) {
|
|
21865
|
+
let child = fragment.child(i);
|
|
21866
|
+
if (child.content.size)
|
|
21867
|
+
child = child.copy(mapFragment(child.content, f, child));
|
|
21868
|
+
if (child.isInline)
|
|
21869
|
+
child = f(child, parent2, i);
|
|
21870
|
+
mapped.push(child);
|
|
21978
21871
|
}
|
|
21872
|
+
return Fragment.fromArray(mapped);
|
|
21873
|
+
}
|
|
21874
|
+
class AddMarkStep extends Step {
|
|
21979
21875
|
/**
|
|
21980
|
-
|
|
21981
|
-
classes must register themselves with an ID string, so that they
|
|
21982
|
-
can be disambiguated. Try to pick something that's unlikely to
|
|
21983
|
-
clash with classes from other modules.
|
|
21876
|
+
Create a mark step.
|
|
21984
21877
|
*/
|
|
21985
|
-
|
|
21986
|
-
|
|
21987
|
-
|
|
21988
|
-
|
|
21989
|
-
|
|
21990
|
-
|
|
21878
|
+
constructor(from, to, mark) {
|
|
21879
|
+
super();
|
|
21880
|
+
this.from = from;
|
|
21881
|
+
this.to = to;
|
|
21882
|
+
this.mark = mark;
|
|
21883
|
+
}
|
|
21884
|
+
apply(doc) {
|
|
21885
|
+
let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from);
|
|
21886
|
+
let parent2 = $from.node($from.sharedDepth(this.to));
|
|
21887
|
+
let slice = new Slice(mapFragment(oldSlice.content, (node, parent3) => {
|
|
21888
|
+
if (!node.isAtom || !parent3.type.allowsMarkType(this.mark.type))
|
|
21889
|
+
return node;
|
|
21890
|
+
return node.mark(this.mark.addToSet(node.marks));
|
|
21891
|
+
}, parent2), oldSlice.openStart, oldSlice.openEnd);
|
|
21892
|
+
return StepResult.fromReplace(doc, this.from, this.to, slice);
|
|
21893
|
+
}
|
|
21894
|
+
invert() {
|
|
21895
|
+
return new RemoveMarkStep(this.from, this.to, this.mark);
|
|
21896
|
+
}
|
|
21897
|
+
map(mapping) {
|
|
21898
|
+
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
21899
|
+
if (from.deleted && to.deleted || from.pos >= to.pos)
|
|
21900
|
+
return null;
|
|
21901
|
+
return new AddMarkStep(from.pos, to.pos, this.mark);
|
|
21902
|
+
}
|
|
21903
|
+
merge(other) {
|
|
21904
|
+
if (other instanceof AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from)
|
|
21905
|
+
return new AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
|
|
21906
|
+
return null;
|
|
21907
|
+
}
|
|
21908
|
+
toJSON() {
|
|
21909
|
+
return {
|
|
21910
|
+
stepType: "addMark",
|
|
21911
|
+
mark: this.mark.toJSON(),
|
|
21912
|
+
from: this.from,
|
|
21913
|
+
to: this.to
|
|
21914
|
+
};
|
|
21991
21915
|
}
|
|
21992
21916
|
/**
|
|
21993
|
-
|
|
21994
|
-
which is a value that can be mapped without having access to a
|
|
21995
|
-
current document, and later resolved to a real selection for a
|
|
21996
|
-
given document again. (This is used mostly by the history to
|
|
21997
|
-
track and restore old selections.) The default implementation of
|
|
21998
|
-
this method just converts the selection to a text selection and
|
|
21999
|
-
returns the bookmark for that.
|
|
21917
|
+
@internal
|
|
22000
21918
|
*/
|
|
22001
|
-
|
|
22002
|
-
|
|
21919
|
+
static fromJSON(schema, json) {
|
|
21920
|
+
if (typeof json.from != "number" || typeof json.to != "number")
|
|
21921
|
+
throw new RangeError("Invalid input for AddMarkStep.fromJSON");
|
|
21922
|
+
return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
|
|
22003
21923
|
}
|
|
22004
21924
|
}
|
|
22005
|
-
|
|
22006
|
-
class
|
|
21925
|
+
Step.jsonID("addMark", AddMarkStep);
|
|
21926
|
+
class RemoveMarkStep extends Step {
|
|
22007
21927
|
/**
|
|
22008
|
-
Create a
|
|
21928
|
+
Create a mark-removing step.
|
|
22009
21929
|
*/
|
|
22010
|
-
constructor(
|
|
22011
|
-
|
|
22012
|
-
this
|
|
21930
|
+
constructor(from, to, mark) {
|
|
21931
|
+
super();
|
|
21932
|
+
this.from = from;
|
|
21933
|
+
this.to = to;
|
|
21934
|
+
this.mark = mark;
|
|
22013
21935
|
}
|
|
22014
|
-
|
|
22015
|
-
let
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
21936
|
+
apply(doc) {
|
|
21937
|
+
let oldSlice = doc.slice(this.from, this.to);
|
|
21938
|
+
let slice = new Slice(mapFragment(oldSlice.content, (node) => {
|
|
21939
|
+
return node.mark(this.mark.removeFromSet(node.marks));
|
|
21940
|
+
}, doc), oldSlice.openStart, oldSlice.openEnd);
|
|
21941
|
+
return StepResult.fromReplace(doc, this.from, this.to, slice);
|
|
21942
|
+
}
|
|
21943
|
+
invert() {
|
|
21944
|
+
return new AddMarkStep(this.from, this.to, this.mark);
|
|
21945
|
+
}
|
|
21946
|
+
map(mapping) {
|
|
21947
|
+
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
21948
|
+
if (from.deleted && to.deleted || from.pos >= to.pos)
|
|
21949
|
+
return null;
|
|
21950
|
+
return new RemoveMarkStep(from.pos, to.pos, this.mark);
|
|
21951
|
+
}
|
|
21952
|
+
merge(other) {
|
|
21953
|
+
if (other instanceof RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from)
|
|
21954
|
+
return new RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
|
|
21955
|
+
return null;
|
|
21956
|
+
}
|
|
21957
|
+
toJSON() {
|
|
21958
|
+
return {
|
|
21959
|
+
stepType: "removeMark",
|
|
21960
|
+
mark: this.mark.toJSON(),
|
|
21961
|
+
from: this.from,
|
|
21962
|
+
to: this.to
|
|
21963
|
+
};
|
|
22020
21964
|
}
|
|
22021
|
-
}
|
|
22022
|
-
class TextSelection extends Selection {
|
|
22023
21965
|
/**
|
|
22024
|
-
|
|
21966
|
+
@internal
|
|
22025
21967
|
*/
|
|
22026
|
-
|
|
22027
|
-
|
|
22028
|
-
|
|
22029
|
-
|
|
21968
|
+
static fromJSON(schema, json) {
|
|
21969
|
+
if (typeof json.from != "number" || typeof json.to != "number")
|
|
21970
|
+
throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");
|
|
21971
|
+
return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
|
|
22030
21972
|
}
|
|
21973
|
+
}
|
|
21974
|
+
Step.jsonID("removeMark", RemoveMarkStep);
|
|
21975
|
+
class AddNodeMarkStep extends Step {
|
|
22031
21976
|
/**
|
|
22032
|
-
|
|
22033
|
-
empty text selection), and null otherwise.
|
|
21977
|
+
Create a node mark step.
|
|
22034
21978
|
*/
|
|
22035
|
-
|
|
22036
|
-
|
|
21979
|
+
constructor(pos, mark) {
|
|
21980
|
+
super();
|
|
21981
|
+
this.pos = pos;
|
|
21982
|
+
this.mark = mark;
|
|
22037
21983
|
}
|
|
22038
|
-
|
|
22039
|
-
let
|
|
22040
|
-
if (
|
|
22041
|
-
return
|
|
22042
|
-
let
|
|
22043
|
-
return new
|
|
21984
|
+
apply(doc) {
|
|
21985
|
+
let node = doc.nodeAt(this.pos);
|
|
21986
|
+
if (!node)
|
|
21987
|
+
return StepResult.fail("No node at mark step's position");
|
|
21988
|
+
let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
|
|
21989
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
22044
21990
|
}
|
|
22045
|
-
|
|
22046
|
-
|
|
22047
|
-
if (
|
|
22048
|
-
let
|
|
22049
|
-
if (marks)
|
|
22050
|
-
|
|
21991
|
+
invert(doc) {
|
|
21992
|
+
let node = doc.nodeAt(this.pos);
|
|
21993
|
+
if (node) {
|
|
21994
|
+
let newSet = this.mark.addToSet(node.marks);
|
|
21995
|
+
if (newSet.length == node.marks.length) {
|
|
21996
|
+
for (let i = 0; i < node.marks.length; i++)
|
|
21997
|
+
if (!node.marks[i].isInSet(newSet))
|
|
21998
|
+
return new AddNodeMarkStep(this.pos, node.marks[i]);
|
|
21999
|
+
return new AddNodeMarkStep(this.pos, this.mark);
|
|
22000
|
+
}
|
|
22051
22001
|
}
|
|
22002
|
+
return new RemoveNodeMarkStep(this.pos, this.mark);
|
|
22052
22003
|
}
|
|
22053
|
-
|
|
22054
|
-
|
|
22055
|
-
|
|
22056
|
-
getBookmark() {
|
|
22057
|
-
return new TextBookmark(this.anchor, this.head);
|
|
22004
|
+
map(mapping) {
|
|
22005
|
+
let pos = mapping.mapResult(this.pos, 1);
|
|
22006
|
+
return pos.deletedAfter ? null : new AddNodeMarkStep(pos.pos, this.mark);
|
|
22058
22007
|
}
|
|
22059
22008
|
toJSON() {
|
|
22060
|
-
return {
|
|
22009
|
+
return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() };
|
|
22061
22010
|
}
|
|
22062
22011
|
/**
|
|
22063
22012
|
@internal
|
|
22064
22013
|
*/
|
|
22065
|
-
static fromJSON(
|
|
22066
|
-
if (typeof json.
|
|
22067
|
-
throw new RangeError("Invalid input for
|
|
22068
|
-
return new
|
|
22014
|
+
static fromJSON(schema, json) {
|
|
22015
|
+
if (typeof json.pos != "number")
|
|
22016
|
+
throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");
|
|
22017
|
+
return new AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
|
|
22069
22018
|
}
|
|
22019
|
+
}
|
|
22020
|
+
Step.jsonID("addNodeMark", AddNodeMarkStep);
|
|
22021
|
+
class RemoveNodeMarkStep extends Step {
|
|
22070
22022
|
/**
|
|
22071
|
-
Create a
|
|
22023
|
+
Create a mark-removing step.
|
|
22072
22024
|
*/
|
|
22073
|
-
|
|
22074
|
-
|
|
22075
|
-
|
|
22025
|
+
constructor(pos, mark) {
|
|
22026
|
+
super();
|
|
22027
|
+
this.pos = pos;
|
|
22028
|
+
this.mark = mark;
|
|
22029
|
+
}
|
|
22030
|
+
apply(doc) {
|
|
22031
|
+
let node = doc.nodeAt(this.pos);
|
|
22032
|
+
if (!node)
|
|
22033
|
+
return StepResult.fail("No node at mark step's position");
|
|
22034
|
+
let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
|
|
22035
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
22036
|
+
}
|
|
22037
|
+
invert(doc) {
|
|
22038
|
+
let node = doc.nodeAt(this.pos);
|
|
22039
|
+
if (!node || !this.mark.isInSet(node.marks))
|
|
22040
|
+
return this;
|
|
22041
|
+
return new AddNodeMarkStep(this.pos, this.mark);
|
|
22042
|
+
}
|
|
22043
|
+
map(mapping) {
|
|
22044
|
+
let pos = mapping.mapResult(this.pos, 1);
|
|
22045
|
+
return pos.deletedAfter ? null : new RemoveNodeMarkStep(pos.pos, this.mark);
|
|
22046
|
+
}
|
|
22047
|
+
toJSON() {
|
|
22048
|
+
return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() };
|
|
22076
22049
|
}
|
|
22077
22050
|
/**
|
|
22078
|
-
|
|
22079
|
-
they aren't text positions, find a text selection near them.
|
|
22080
|
-
`bias` determines whether the method searches forward (default)
|
|
22081
|
-
or backwards (negative number) first. Will fall back to calling
|
|
22082
|
-
[`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document
|
|
22083
|
-
doesn't contain a valid text position.
|
|
22051
|
+
@internal
|
|
22084
22052
|
*/
|
|
22085
|
-
static
|
|
22086
|
-
|
|
22087
|
-
|
|
22088
|
-
|
|
22089
|
-
if (!$head.parent.inlineContent) {
|
|
22090
|
-
let found2 = Selection.findFrom($head, bias, true) || Selection.findFrom($head, -bias, true);
|
|
22091
|
-
if (found2)
|
|
22092
|
-
$head = found2.$head;
|
|
22093
|
-
else
|
|
22094
|
-
return Selection.near($head, bias);
|
|
22095
|
-
}
|
|
22096
|
-
if (!$anchor.parent.inlineContent) {
|
|
22097
|
-
if (dPos == 0) {
|
|
22098
|
-
$anchor = $head;
|
|
22099
|
-
} else {
|
|
22100
|
-
$anchor = (Selection.findFrom($anchor, -bias, true) || Selection.findFrom($anchor, bias, true)).$anchor;
|
|
22101
|
-
if ($anchor.pos < $head.pos != dPos < 0)
|
|
22102
|
-
$anchor = $head;
|
|
22103
|
-
}
|
|
22104
|
-
}
|
|
22105
|
-
return new TextSelection($anchor, $head);
|
|
22053
|
+
static fromJSON(schema, json) {
|
|
22054
|
+
if (typeof json.pos != "number")
|
|
22055
|
+
throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");
|
|
22056
|
+
return new RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
|
|
22106
22057
|
}
|
|
22107
22058
|
}
|
|
22108
|
-
|
|
22109
|
-
class
|
|
22110
|
-
|
|
22111
|
-
|
|
22112
|
-
|
|
22059
|
+
Step.jsonID("removeNodeMark", RemoveNodeMarkStep);
|
|
22060
|
+
class ReplaceStep extends Step {
|
|
22061
|
+
/**
|
|
22062
|
+
The given `slice` should fit the 'gap' between `from` and
|
|
22063
|
+
`to`—the depths must line up, and the surrounding nodes must be
|
|
22064
|
+
able to be joined with the open sides of the slice. When
|
|
22065
|
+
`structure` is true, the step will fail if the content between
|
|
22066
|
+
from and to is not just a sequence of closing and then opening
|
|
22067
|
+
tokens (this is to guard against rebased replace steps
|
|
22068
|
+
overwriting something they weren't supposed to).
|
|
22069
|
+
*/
|
|
22070
|
+
constructor(from, to, slice, structure = false) {
|
|
22071
|
+
super();
|
|
22072
|
+
this.from = from;
|
|
22073
|
+
this.to = to;
|
|
22074
|
+
this.slice = slice;
|
|
22075
|
+
this.structure = structure;
|
|
22076
|
+
}
|
|
22077
|
+
apply(doc) {
|
|
22078
|
+
if (this.structure && contentBetween(doc, this.from, this.to))
|
|
22079
|
+
return StepResult.fail("Structure replace would overwrite content");
|
|
22080
|
+
return StepResult.fromReplace(doc, this.from, this.to, this.slice);
|
|
22081
|
+
}
|
|
22082
|
+
getMap() {
|
|
22083
|
+
return new StepMap([this.from, this.to - this.from, this.slice.size]);
|
|
22084
|
+
}
|
|
22085
|
+
invert(doc) {
|
|
22086
|
+
return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
|
|
22113
22087
|
}
|
|
22114
22088
|
map(mapping) {
|
|
22115
|
-
|
|
22089
|
+
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
22090
|
+
if (from.deletedAcross && to.deletedAcross)
|
|
22091
|
+
return null;
|
|
22092
|
+
return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
|
|
22116
22093
|
}
|
|
22117
|
-
|
|
22118
|
-
|
|
22094
|
+
merge(other) {
|
|
22095
|
+
if (!(other instanceof ReplaceStep) || other.structure || this.structure)
|
|
22096
|
+
return null;
|
|
22097
|
+
if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) {
|
|
22098
|
+
let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd);
|
|
22099
|
+
return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure);
|
|
22100
|
+
} else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) {
|
|
22101
|
+
let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd);
|
|
22102
|
+
return new ReplaceStep(other.from, this.to, slice, this.structure);
|
|
22103
|
+
} else {
|
|
22104
|
+
return null;
|
|
22105
|
+
}
|
|
22106
|
+
}
|
|
22107
|
+
toJSON() {
|
|
22108
|
+
let json = { stepType: "replace", from: this.from, to: this.to };
|
|
22109
|
+
if (this.slice.size)
|
|
22110
|
+
json.slice = this.slice.toJSON();
|
|
22111
|
+
if (this.structure)
|
|
22112
|
+
json.structure = true;
|
|
22113
|
+
return json;
|
|
22114
|
+
}
|
|
22115
|
+
/**
|
|
22116
|
+
@internal
|
|
22117
|
+
*/
|
|
22118
|
+
static fromJSON(schema, json) {
|
|
22119
|
+
if (typeof json.from != "number" || typeof json.to != "number")
|
|
22120
|
+
throw new RangeError("Invalid input for ReplaceStep.fromJSON");
|
|
22121
|
+
return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
|
|
22119
22122
|
}
|
|
22120
22123
|
}
|
|
22121
|
-
|
|
22124
|
+
Step.jsonID("replace", ReplaceStep);
|
|
22125
|
+
class ReplaceAroundStep extends Step {
|
|
22122
22126
|
/**
|
|
22123
|
-
Create a
|
|
22124
|
-
|
|
22127
|
+
Create a replace-around step with the given range and gap.
|
|
22128
|
+
`insert` should be the point in the slice into which the content
|
|
22129
|
+
of the gap should be moved. `structure` has the same meaning as
|
|
22130
|
+
it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class.
|
|
22125
22131
|
*/
|
|
22126
|
-
constructor(
|
|
22127
|
-
|
|
22128
|
-
|
|
22129
|
-
|
|
22130
|
-
this.
|
|
22132
|
+
constructor(from, to, gapFrom, gapTo, slice, insert, structure = false) {
|
|
22133
|
+
super();
|
|
22134
|
+
this.from = from;
|
|
22135
|
+
this.to = to;
|
|
22136
|
+
this.gapFrom = gapFrom;
|
|
22137
|
+
this.gapTo = gapTo;
|
|
22138
|
+
this.slice = slice;
|
|
22139
|
+
this.insert = insert;
|
|
22140
|
+
this.structure = structure;
|
|
22131
22141
|
}
|
|
22132
|
-
|
|
22133
|
-
|
|
22134
|
-
|
|
22135
|
-
|
|
22136
|
-
|
|
22137
|
-
|
|
22142
|
+
apply(doc) {
|
|
22143
|
+
if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || contentBetween(doc, this.gapTo, this.to)))
|
|
22144
|
+
return StepResult.fail("Structure gap-replace would overwrite content");
|
|
22145
|
+
let gap = doc.slice(this.gapFrom, this.gapTo);
|
|
22146
|
+
if (gap.openStart || gap.openEnd)
|
|
22147
|
+
return StepResult.fail("Gap is not a flat range");
|
|
22148
|
+
let inserted = this.slice.insertAt(this.insert, gap.content);
|
|
22149
|
+
if (!inserted)
|
|
22150
|
+
return StepResult.fail("Content does not fit in gap");
|
|
22151
|
+
return StepResult.fromReplace(doc, this.from, this.to, inserted);
|
|
22138
22152
|
}
|
|
22139
|
-
|
|
22140
|
-
return new
|
|
22153
|
+
getMap() {
|
|
22154
|
+
return new StepMap([
|
|
22155
|
+
this.from,
|
|
22156
|
+
this.gapFrom - this.from,
|
|
22157
|
+
this.insert,
|
|
22158
|
+
this.gapTo,
|
|
22159
|
+
this.to - this.gapTo,
|
|
22160
|
+
this.slice.size - this.insert
|
|
22161
|
+
]);
|
|
22162
|
+
}
|
|
22163
|
+
invert(doc) {
|
|
22164
|
+
let gap = this.gapTo - this.gapFrom;
|
|
22165
|
+
return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure);
|
|
22141
22166
|
}
|
|
22142
|
-
|
|
22143
|
-
|
|
22167
|
+
map(mapping) {
|
|
22168
|
+
let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
|
|
22169
|
+
let gapFrom = this.from == this.gapFrom ? from.pos : mapping.map(this.gapFrom, -1);
|
|
22170
|
+
let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1);
|
|
22171
|
+
if (from.deletedAcross && to.deletedAcross || gapFrom < from.pos || gapTo > to.pos)
|
|
22172
|
+
return null;
|
|
22173
|
+
return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure);
|
|
22144
22174
|
}
|
|
22145
22175
|
toJSON() {
|
|
22146
|
-
|
|
22147
|
-
|
|
22148
|
-
|
|
22149
|
-
|
|
22176
|
+
let json = {
|
|
22177
|
+
stepType: "replaceAround",
|
|
22178
|
+
from: this.from,
|
|
22179
|
+
to: this.to,
|
|
22180
|
+
gapFrom: this.gapFrom,
|
|
22181
|
+
gapTo: this.gapTo,
|
|
22182
|
+
insert: this.insert
|
|
22183
|
+
};
|
|
22184
|
+
if (this.slice.size)
|
|
22185
|
+
json.slice = this.slice.toJSON();
|
|
22186
|
+
if (this.structure)
|
|
22187
|
+
json.structure = true;
|
|
22188
|
+
return json;
|
|
22150
22189
|
}
|
|
22151
22190
|
/**
|
|
22152
22191
|
@internal
|
|
22153
22192
|
*/
|
|
22154
|
-
static fromJSON(
|
|
22155
|
-
if (typeof json.
|
|
22156
|
-
throw new RangeError("Invalid input for
|
|
22157
|
-
return new
|
|
22158
|
-
}
|
|
22159
|
-
/**
|
|
22160
|
-
Create a node selection from non-resolved positions.
|
|
22161
|
-
*/
|
|
22162
|
-
static create(doc, from) {
|
|
22163
|
-
return new NodeSelection(doc.resolve(from));
|
|
22164
|
-
}
|
|
22165
|
-
/**
|
|
22166
|
-
Determines whether the given node may be selected as a node
|
|
22167
|
-
selection.
|
|
22168
|
-
*/
|
|
22169
|
-
static isSelectable(node) {
|
|
22170
|
-
return !node.isText && node.type.spec.selectable !== false;
|
|
22193
|
+
static fromJSON(schema, json) {
|
|
22194
|
+
if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number")
|
|
22195
|
+
throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");
|
|
22196
|
+
return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure);
|
|
22171
22197
|
}
|
|
22172
22198
|
}
|
|
22173
|
-
|
|
22174
|
-
|
|
22175
|
-
|
|
22176
|
-
|
|
22177
|
-
|
|
22178
|
-
|
|
22179
|
-
map(mapping) {
|
|
22180
|
-
let { deleted, pos } = mapping.mapResult(this.anchor);
|
|
22181
|
-
return deleted ? new TextBookmark(pos, pos) : new NodeBookmark(pos);
|
|
22199
|
+
Step.jsonID("replaceAround", ReplaceAroundStep);
|
|
22200
|
+
function contentBetween(doc, from, to) {
|
|
22201
|
+
let $from = doc.resolve(from), dist = to - from, depth = $from.depth;
|
|
22202
|
+
while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {
|
|
22203
|
+
depth--;
|
|
22204
|
+
dist--;
|
|
22182
22205
|
}
|
|
22183
|
-
|
|
22184
|
-
let
|
|
22185
|
-
|
|
22186
|
-
|
|
22187
|
-
|
|
22206
|
+
if (dist > 0) {
|
|
22207
|
+
let next = $from.node(depth).maybeChild($from.indexAfter(depth));
|
|
22208
|
+
while (dist > 0) {
|
|
22209
|
+
if (!next || next.isLeaf)
|
|
22210
|
+
return true;
|
|
22211
|
+
next = next.firstChild;
|
|
22212
|
+
dist--;
|
|
22213
|
+
}
|
|
22188
22214
|
}
|
|
22215
|
+
return false;
|
|
22189
22216
|
}
|
|
22190
|
-
class
|
|
22217
|
+
class AttrStep extends Step {
|
|
22191
22218
|
/**
|
|
22192
|
-
|
|
22219
|
+
Construct an attribute step.
|
|
22193
22220
|
*/
|
|
22194
|
-
constructor(
|
|
22195
|
-
super(
|
|
22221
|
+
constructor(pos, attr, value) {
|
|
22222
|
+
super();
|
|
22223
|
+
this.pos = pos;
|
|
22224
|
+
this.attr = attr;
|
|
22225
|
+
this.value = value;
|
|
22196
22226
|
}
|
|
22197
|
-
|
|
22198
|
-
|
|
22199
|
-
|
|
22200
|
-
|
|
22201
|
-
|
|
22202
|
-
|
|
22203
|
-
|
|
22204
|
-
|
|
22205
|
-
|
|
22227
|
+
apply(doc) {
|
|
22228
|
+
let node = doc.nodeAt(this.pos);
|
|
22229
|
+
if (!node)
|
|
22230
|
+
return StepResult.fail("No node at attribute step's position");
|
|
22231
|
+
let attrs = /* @__PURE__ */ Object.create(null);
|
|
22232
|
+
for (let name in node.attrs)
|
|
22233
|
+
attrs[name] = node.attrs[name];
|
|
22234
|
+
attrs[this.attr] = this.value;
|
|
22235
|
+
let updated = node.type.create(attrs, null, node.marks);
|
|
22236
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
22206
22237
|
}
|
|
22207
|
-
|
|
22208
|
-
return
|
|
22238
|
+
getMap() {
|
|
22239
|
+
return StepMap.empty;
|
|
22209
22240
|
}
|
|
22210
|
-
|
|
22211
|
-
|
|
22212
|
-
*/
|
|
22213
|
-
static fromJSON(doc) {
|
|
22214
|
-
return new AllSelection(doc);
|
|
22241
|
+
invert(doc) {
|
|
22242
|
+
return new AttrStep(this.pos, this.attr, doc.nodeAt(this.pos).attrs[this.attr]);
|
|
22215
22243
|
}
|
|
22216
|
-
map(
|
|
22217
|
-
|
|
22244
|
+
map(mapping) {
|
|
22245
|
+
let pos = mapping.mapResult(this.pos, 1);
|
|
22246
|
+
return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value);
|
|
22218
22247
|
}
|
|
22219
|
-
|
|
22220
|
-
return
|
|
22248
|
+
toJSON() {
|
|
22249
|
+
return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value };
|
|
22221
22250
|
}
|
|
22222
|
-
|
|
22223
|
-
|
|
22251
|
+
static fromJSON(schema, json) {
|
|
22252
|
+
if (typeof json.pos != "number" || typeof json.attr != "string")
|
|
22253
|
+
throw new RangeError("Invalid input for AttrStep.fromJSON");
|
|
22254
|
+
return new AttrStep(json.pos, json.attr, json.value);
|
|
22224
22255
|
}
|
|
22225
22256
|
}
|
|
22226
|
-
|
|
22227
|
-
|
|
22228
|
-
|
|
22229
|
-
|
|
22230
|
-
|
|
22231
|
-
|
|
22232
|
-
|
|
22257
|
+
Step.jsonID("attr", AttrStep);
|
|
22258
|
+
class DocAttrStep extends Step {
|
|
22259
|
+
/**
|
|
22260
|
+
Construct an attribute step.
|
|
22261
|
+
*/
|
|
22262
|
+
constructor(attr, value) {
|
|
22263
|
+
super();
|
|
22264
|
+
this.attr = attr;
|
|
22265
|
+
this.value = value;
|
|
22233
22266
|
}
|
|
22234
|
-
|
|
22235
|
-
|
|
22236
|
-
|
|
22237
|
-
|
|
22238
|
-
|
|
22239
|
-
let
|
|
22240
|
-
|
|
22241
|
-
let inner = findSelectionIn(doc, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text2);
|
|
22242
|
-
if (inner)
|
|
22243
|
-
return inner;
|
|
22244
|
-
} else if (!text2 && NodeSelection.isSelectable(child)) {
|
|
22245
|
-
return NodeSelection.create(doc, pos - (dir < 0 ? child.nodeSize : 0));
|
|
22246
|
-
}
|
|
22247
|
-
pos += child.nodeSize * dir;
|
|
22267
|
+
apply(doc) {
|
|
22268
|
+
let attrs = /* @__PURE__ */ Object.create(null);
|
|
22269
|
+
for (let name in doc.attrs)
|
|
22270
|
+
attrs[name] = doc.attrs[name];
|
|
22271
|
+
attrs[this.attr] = this.value;
|
|
22272
|
+
let updated = doc.type.create(attrs, doc.content, doc.marks);
|
|
22273
|
+
return StepResult.ok(updated);
|
|
22248
22274
|
}
|
|
22249
|
-
|
|
22250
|
-
|
|
22251
|
-
function selectionToInsertionEnd(tr, startLen, bias) {
|
|
22252
|
-
let last2 = tr.steps.length - 1;
|
|
22253
|
-
if (last2 < startLen)
|
|
22254
|
-
return;
|
|
22255
|
-
let step = tr.steps[last2];
|
|
22256
|
-
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep))
|
|
22257
|
-
return;
|
|
22258
|
-
let map = tr.mapping.maps[last2], end2;
|
|
22259
|
-
map.forEach((_from, _to, _newFrom, newTo) => {
|
|
22260
|
-
if (end2 == null)
|
|
22261
|
-
end2 = newTo;
|
|
22262
|
-
});
|
|
22263
|
-
tr.setSelection(Selection.near(tr.doc.resolve(end2), bias));
|
|
22264
|
-
}
|
|
22265
|
-
function bind(f, self2) {
|
|
22266
|
-
return !self2 || !f ? f : f.bind(self2);
|
|
22267
|
-
}
|
|
22268
|
-
class FieldDesc {
|
|
22269
|
-
constructor(name, desc, self2) {
|
|
22270
|
-
this.name = name;
|
|
22271
|
-
this.init = bind(desc.init, self2);
|
|
22272
|
-
this.apply = bind(desc.apply, self2);
|
|
22275
|
+
getMap() {
|
|
22276
|
+
return StepMap.empty;
|
|
22273
22277
|
}
|
|
22274
|
-
|
|
22275
|
-
[
|
|
22276
|
-
new FieldDesc("doc", {
|
|
22277
|
-
init(config) {
|
|
22278
|
-
return config.doc || config.schema.topNodeType.createAndFill();
|
|
22279
|
-
},
|
|
22280
|
-
apply(tr) {
|
|
22281
|
-
return tr.doc;
|
|
22282
|
-
}
|
|
22283
|
-
}),
|
|
22284
|
-
new FieldDesc("selection", {
|
|
22285
|
-
init(config, instance) {
|
|
22286
|
-
return config.selection || Selection.atStart(instance.doc);
|
|
22287
|
-
},
|
|
22288
|
-
apply(tr) {
|
|
22289
|
-
return tr.selection;
|
|
22290
|
-
}
|
|
22291
|
-
}),
|
|
22292
|
-
new FieldDesc("storedMarks", {
|
|
22293
|
-
init(config) {
|
|
22294
|
-
return config.storedMarks || null;
|
|
22295
|
-
},
|
|
22296
|
-
apply(tr, _marks, _old, state2) {
|
|
22297
|
-
return state2.selection.$cursor ? tr.storedMarks : null;
|
|
22298
|
-
}
|
|
22299
|
-
}),
|
|
22300
|
-
new FieldDesc("scrollToSelection", {
|
|
22301
|
-
init() {
|
|
22302
|
-
return 0;
|
|
22303
|
-
},
|
|
22304
|
-
apply(tr, prev) {
|
|
22305
|
-
return tr.scrolledIntoView ? prev + 1 : prev;
|
|
22306
|
-
}
|
|
22307
|
-
})
|
|
22308
|
-
];
|
|
22309
|
-
function bindProps(obj, self2, target) {
|
|
22310
|
-
for (let prop in obj) {
|
|
22311
|
-
let val = obj[prop];
|
|
22312
|
-
if (val instanceof Function)
|
|
22313
|
-
val = val.bind(self2);
|
|
22314
|
-
else if (prop == "handleDOMEvents")
|
|
22315
|
-
val = bindProps(val, self2, {});
|
|
22316
|
-
target[prop] = val;
|
|
22278
|
+
invert(doc) {
|
|
22279
|
+
return new DocAttrStep(this.attr, doc.attrs[this.attr]);
|
|
22317
22280
|
}
|
|
22318
|
-
|
|
22319
|
-
|
|
22320
|
-
|
|
22321
|
-
|
|
22322
|
-
|
|
22323
|
-
*/
|
|
22324
|
-
constructor(spec) {
|
|
22325
|
-
this.spec = spec;
|
|
22326
|
-
this.props = {};
|
|
22327
|
-
if (spec.props)
|
|
22328
|
-
bindProps(spec.props, this, this.props);
|
|
22329
|
-
this.key = spec.key ? spec.key.key : createKey("plugin");
|
|
22281
|
+
map(mapping) {
|
|
22282
|
+
return this;
|
|
22283
|
+
}
|
|
22284
|
+
toJSON() {
|
|
22285
|
+
return { stepType: "docAttr", attr: this.attr, value: this.value };
|
|
22330
22286
|
}
|
|
22331
|
-
|
|
22332
|
-
|
|
22333
|
-
|
|
22334
|
-
|
|
22335
|
-
return state2[this.key];
|
|
22287
|
+
static fromJSON(schema, json) {
|
|
22288
|
+
if (typeof json.attr != "string")
|
|
22289
|
+
throw new RangeError("Invalid input for DocAttrStep.fromJSON");
|
|
22290
|
+
return new DocAttrStep(json.attr, json.value);
|
|
22336
22291
|
}
|
|
22337
22292
|
}
|
|
22338
|
-
|
|
22339
|
-
|
|
22340
|
-
|
|
22341
|
-
|
|
22342
|
-
|
|
22343
|
-
|
|
22344
|
-
|
|
22345
|
-
|
|
22293
|
+
Step.jsonID("docAttr", DocAttrStep);
|
|
22294
|
+
let TransformError = class extends Error {
|
|
22295
|
+
};
|
|
22296
|
+
TransformError = function TransformError2(message) {
|
|
22297
|
+
let err = Error.call(this, message);
|
|
22298
|
+
err.__proto__ = TransformError2.prototype;
|
|
22299
|
+
return err;
|
|
22300
|
+
};
|
|
22301
|
+
TransformError.prototype = Object.create(Error.prototype);
|
|
22302
|
+
TransformError.prototype.constructor = TransformError;
|
|
22303
|
+
TransformError.prototype.name = "TransformError";
|
|
22304
|
+
const classesById = /* @__PURE__ */ Object.create(null);
|
|
22305
|
+
class Selection {
|
|
22346
22306
|
/**
|
|
22347
|
-
|
|
22307
|
+
Initialize a selection with the head and anchor and ranges. If no
|
|
22308
|
+
ranges are given, constructs a single range across `$anchor` and
|
|
22309
|
+
`$head`.
|
|
22348
22310
|
*/
|
|
22349
|
-
constructor(
|
|
22350
|
-
this
|
|
22311
|
+
constructor($anchor, $head, ranges) {
|
|
22312
|
+
this.$anchor = $anchor;
|
|
22313
|
+
this.$head = $head;
|
|
22314
|
+
this.ranges = ranges || [new SelectionRange($anchor.min($head), $anchor.max($head))];
|
|
22351
22315
|
}
|
|
22352
22316
|
/**
|
|
22353
|
-
|
|
22354
|
-
state.
|
|
22317
|
+
The selection's anchor, as an unresolved position.
|
|
22355
22318
|
*/
|
|
22356
|
-
get(
|
|
22357
|
-
return
|
|
22319
|
+
get anchor() {
|
|
22320
|
+
return this.$anchor.pos;
|
|
22358
22321
|
}
|
|
22359
22322
|
/**
|
|
22360
|
-
|
|
22323
|
+
The selection's head.
|
|
22361
22324
|
*/
|
|
22362
|
-
|
|
22363
|
-
return
|
|
22364
|
-
}
|
|
22365
|
-
}
|
|
22366
|
-
var NAME = "AspectRatio";
|
|
22367
|
-
var AspectRatio$1 = React__namespace.forwardRef(
|
|
22368
|
-
(props, forwardedRef) => {
|
|
22369
|
-
const { ratio = 1 / 1, style, ...aspectRatioProps } = props;
|
|
22370
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22371
|
-
"div",
|
|
22372
|
-
{
|
|
22373
|
-
style: {
|
|
22374
|
-
// ensures inner element is contained
|
|
22375
|
-
position: "relative",
|
|
22376
|
-
// ensures padding bottom trick maths works
|
|
22377
|
-
width: "100%",
|
|
22378
|
-
paddingBottom: `${100 / ratio}%`
|
|
22379
|
-
},
|
|
22380
|
-
"data-radix-aspect-ratio-wrapper": "",
|
|
22381
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22382
|
-
Primitive.div,
|
|
22383
|
-
{
|
|
22384
|
-
...aspectRatioProps,
|
|
22385
|
-
ref: forwardedRef,
|
|
22386
|
-
style: {
|
|
22387
|
-
...style,
|
|
22388
|
-
// ensures children expand in ratio
|
|
22389
|
-
position: "absolute",
|
|
22390
|
-
top: 0,
|
|
22391
|
-
right: 0,
|
|
22392
|
-
bottom: 0,
|
|
22393
|
-
left: 0
|
|
22394
|
-
}
|
|
22395
|
-
}
|
|
22396
|
-
)
|
|
22397
|
-
}
|
|
22398
|
-
);
|
|
22399
|
-
}
|
|
22400
|
-
);
|
|
22401
|
-
AspectRatio$1.displayName = NAME;
|
|
22402
|
-
var Root = AspectRatio$1;
|
|
22403
|
-
function AspectRatio({ ...props }) {
|
|
22404
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Root, { "data-slot": "aspect-ratio", ...props });
|
|
22405
|
-
}
|
|
22406
|
-
const MediaNodeView = ({ node, updateAttributes, editor, getPos }) => {
|
|
22407
|
-
const [selected, setSelected] = React.useState(false);
|
|
22408
|
-
React.useEffect(() => {
|
|
22409
|
-
const checkSelection = () => {
|
|
22410
|
-
const selection = editor.state.selection;
|
|
22411
|
-
const selectedNode = selection instanceof NodeSelection ? selection.node : null;
|
|
22412
|
-
if (selectedNode === node) requestAnimationFrame(() => setSelected(true));
|
|
22413
|
-
else setSelected(false);
|
|
22414
|
-
};
|
|
22415
|
-
checkSelection();
|
|
22416
|
-
editor.on("selectionUpdate", checkSelection);
|
|
22417
|
-
return () => {
|
|
22418
|
-
editor.off("selectionUpdate", checkSelection);
|
|
22419
|
-
};
|
|
22420
|
-
}, [editor, node]);
|
|
22421
|
-
const handleDelete = () => {
|
|
22422
|
-
const pos = getPos() ?? NaN;
|
|
22423
|
-
if (!Number.isFinite(pos)) return;
|
|
22424
|
-
editor.chain().focus().deleteRange({ from: pos, to: pos + node.nodeSize }).focus().run();
|
|
22425
|
-
};
|
|
22426
|
-
const handleAlign = (align) => updateAttributes({ align });
|
|
22427
|
-
if (node.attrs.uploading) {
|
|
22428
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22429
|
-
react.NodeViewWrapper,
|
|
22430
|
-
{
|
|
22431
|
-
className: cn(
|
|
22432
|
-
"flex my-4",
|
|
22433
|
-
node.attrs.align === Alignment.CENTER ? "justify-center" : node.attrs.align === Alignment.RIGHT ? "justify-end" : ""
|
|
22434
|
-
),
|
|
22435
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-full", children: [
|
|
22436
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative bg-muted rounded-lg overflow-hidden", children: [
|
|
22437
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22438
|
-
AspectRatio,
|
|
22439
|
-
{
|
|
22440
|
-
ratio: node.attrs.type === MediaNodeTypes.Audio ? 4 / 1 : 16 / 4,
|
|
22441
|
-
className: cn("flex items-center justify-center bg-muted"),
|
|
22442
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center space-y-3", children: [
|
|
22443
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-center", children: [
|
|
22444
|
-
node.attrs.type === MediaNodeTypes.Image && /* @__PURE__ */ jsxRuntime.jsx(Image$1, { className: "w-12 h-12 text-muted-foreground/50" }),
|
|
22445
|
-
node.attrs.type === MediaNodeTypes.Video && /* @__PURE__ */ jsxRuntime.jsx(Video, { className: "w-12 h-12 text-muted-foreground/50" }),
|
|
22446
|
-
node.attrs.type === MediaNodeTypes.Audio && /* @__PURE__ */ jsxRuntime.jsx(Music, { className: "w-12 h-12 text-muted-foreground/50" })
|
|
22447
|
-
] }),
|
|
22448
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground font-medium", children: [
|
|
22449
|
-
"Uploading ",
|
|
22450
|
-
node.attrs.type,
|
|
22451
|
-
"..."
|
|
22452
|
-
] })
|
|
22453
|
-
] })
|
|
22454
|
-
}
|
|
22455
|
-
),
|
|
22456
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4", children: /* @__PURE__ */ jsxRuntime.jsx(Progress, { value: node.attrs.progress ?? 0, className: "h-2" }) }),
|
|
22457
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22458
|
-
"button",
|
|
22459
|
-
{
|
|
22460
|
-
onClick: handleDelete,
|
|
22461
|
-
className: "absolute top-2 right-2 p-2 bg-background/90 hover:bg-background rounded-full shadow-sm transition-colors",
|
|
22462
|
-
title: "Cancel upload",
|
|
22463
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(X, { className: "w-4 h-4" })
|
|
22464
|
-
}
|
|
22465
|
-
)
|
|
22466
|
-
] }),
|
|
22467
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground text-center mt-2", children: [
|
|
22468
|
-
Math.round(node.attrs.progress ?? 0),
|
|
22469
|
-
"%"
|
|
22470
|
-
] })
|
|
22471
|
-
] })
|
|
22472
|
-
}
|
|
22473
|
-
);
|
|
22325
|
+
get head() {
|
|
22326
|
+
return this.$head.pos;
|
|
22474
22327
|
}
|
|
22475
|
-
|
|
22476
|
-
|
|
22477
|
-
|
|
22478
|
-
|
|
22479
|
-
|
|
22480
|
-
|
|
22481
|
-
|
|
22482
|
-
|
|
22483
|
-
|
|
22484
|
-
|
|
22485
|
-
|
|
22486
|
-
|
|
22487
|
-
|
|
22488
|
-
|
|
22489
|
-
|
|
22490
|
-
|
|
22491
|
-
|
|
22492
|
-
|
|
22493
|
-
|
|
22494
|
-
|
|
22495
|
-
|
|
22496
|
-
|
|
22497
|
-
|
|
22498
|
-
|
|
22499
|
-
|
|
22500
|
-
|
|
22501
|
-
|
|
22502
|
-
|
|
22503
|
-
|
|
22504
|
-
|
|
22505
|
-
|
|
22506
|
-
{
|
|
22507
|
-
open: selected,
|
|
22508
|
-
mediaType: node.attrs.type,
|
|
22509
|
-
align: node.attrs.align,
|
|
22510
|
-
onResize: (maxWidth) => updateAttributes({ maxWidth }),
|
|
22511
|
-
onAlign: handleAlign,
|
|
22512
|
-
onDelete: handleDelete,
|
|
22513
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22514
|
-
"video",
|
|
22515
|
-
{
|
|
22516
|
-
src: node.attrs.src,
|
|
22517
|
-
controls: true,
|
|
22518
|
-
className: cn("object-contain w-full h-auto", selected && "border-2 border-blue-500")
|
|
22519
|
-
}
|
|
22520
|
-
)
|
|
22521
|
-
}
|
|
22522
|
-
) : node.attrs.type === MediaNodeTypes.Audio ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative p-4 bg-accent/20 border border-border/20 w-full", children: [
|
|
22523
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22524
|
-
EditMediaToolbar,
|
|
22525
|
-
{
|
|
22526
|
-
open: selected,
|
|
22527
|
-
align: node.attrs.align,
|
|
22528
|
-
onAlign: handleAlign,
|
|
22529
|
-
onDelete: handleDelete
|
|
22530
|
-
}
|
|
22531
|
-
),
|
|
22532
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22533
|
-
"audio",
|
|
22534
|
-
{
|
|
22535
|
-
src: node.attrs.src,
|
|
22536
|
-
controls: true,
|
|
22537
|
-
className: cn("w-full", selected && "rounded-full border-2 border-blue-500")
|
|
22538
|
-
}
|
|
22539
|
-
)
|
|
22540
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-sm text-gray-600", children: "Unsupported media" })
|
|
22541
|
-
}
|
|
22542
|
-
);
|
|
22543
|
-
};
|
|
22544
|
-
const ResizableWithToolbarWrapper = ({
|
|
22545
|
-
open,
|
|
22546
|
-
align,
|
|
22547
|
-
onAlign,
|
|
22548
|
-
onDelete,
|
|
22549
|
-
onResize,
|
|
22550
|
-
mediaType,
|
|
22551
|
-
children
|
|
22552
|
-
}) => {
|
|
22553
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22554
|
-
ResizableWrapper,
|
|
22555
|
-
{
|
|
22556
|
-
onResize,
|
|
22557
|
-
className: cn(mediaType === MediaNodeTypes.Audio && "relative p-4 bg-accent/50"),
|
|
22558
|
-
children: [
|
|
22559
|
-
/* @__PURE__ */ jsxRuntime.jsx(EditMediaToolbar, { open, align, onAlign, onDelete }),
|
|
22560
|
-
children
|
|
22561
|
-
]
|
|
22562
|
-
}
|
|
22563
|
-
);
|
|
22564
|
-
};
|
|
22565
|
-
const createDeleteByUidCommand = (nodeName) => {
|
|
22566
|
-
return (uid) => ({ state: state2, commands }) => {
|
|
22567
|
-
const { doc } = state2;
|
|
22568
|
-
let targetPos = null;
|
|
22569
|
-
let targetSize = null;
|
|
22570
|
-
doc.descendants((node, pos) => {
|
|
22571
|
-
if (node.type.name === nodeName && node.attrs.uid === uid) {
|
|
22572
|
-
targetPos = pos;
|
|
22573
|
-
targetSize = node.nodeSize;
|
|
22328
|
+
/**
|
|
22329
|
+
The lower bound of the selection's main range.
|
|
22330
|
+
*/
|
|
22331
|
+
get from() {
|
|
22332
|
+
return this.$from.pos;
|
|
22333
|
+
}
|
|
22334
|
+
/**
|
|
22335
|
+
The upper bound of the selection's main range.
|
|
22336
|
+
*/
|
|
22337
|
+
get to() {
|
|
22338
|
+
return this.$to.pos;
|
|
22339
|
+
}
|
|
22340
|
+
/**
|
|
22341
|
+
The resolved lower bound of the selection's main range.
|
|
22342
|
+
*/
|
|
22343
|
+
get $from() {
|
|
22344
|
+
return this.ranges[0].$from;
|
|
22345
|
+
}
|
|
22346
|
+
/**
|
|
22347
|
+
The resolved upper bound of the selection's main range.
|
|
22348
|
+
*/
|
|
22349
|
+
get $to() {
|
|
22350
|
+
return this.ranges[0].$to;
|
|
22351
|
+
}
|
|
22352
|
+
/**
|
|
22353
|
+
Indicates whether the selection contains any content.
|
|
22354
|
+
*/
|
|
22355
|
+
get empty() {
|
|
22356
|
+
let ranges = this.ranges;
|
|
22357
|
+
for (let i = 0; i < ranges.length; i++)
|
|
22358
|
+
if (ranges[i].$from.pos != ranges[i].$to.pos)
|
|
22574
22359
|
return false;
|
|
22575
|
-
|
|
22576
|
-
|
|
22577
|
-
|
|
22578
|
-
|
|
22579
|
-
|
|
22580
|
-
|
|
22581
|
-
|
|
22360
|
+
return true;
|
|
22361
|
+
}
|
|
22362
|
+
/**
|
|
22363
|
+
Get the content of this selection as a slice.
|
|
22364
|
+
*/
|
|
22365
|
+
content() {
|
|
22366
|
+
return this.$from.doc.slice(this.from, this.to, true);
|
|
22367
|
+
}
|
|
22368
|
+
/**
|
|
22369
|
+
Replace the selection with a slice or, if no slice is given,
|
|
22370
|
+
delete the selection. Will append to the given transaction.
|
|
22371
|
+
*/
|
|
22372
|
+
replace(tr, content = Slice.empty) {
|
|
22373
|
+
let lastNode = content.content.lastChild, lastParent = null;
|
|
22374
|
+
for (let i = 0; i < content.openEnd; i++) {
|
|
22375
|
+
lastParent = lastNode;
|
|
22376
|
+
lastNode = lastNode.lastChild;
|
|
22582
22377
|
}
|
|
22583
|
-
|
|
22584
|
-
|
|
22585
|
-
};
|
|
22586
|
-
|
|
22587
|
-
|
|
22588
|
-
|
|
22589
|
-
const { doc, tr } = state2;
|
|
22590
|
-
let found2 = false;
|
|
22591
|
-
doc.descendants((node, pos) => {
|
|
22592
|
-
if (node.type.name === nodeName && node.attrs.uid === uid) {
|
|
22593
|
-
tr.setNodeMarkup(pos, void 0, {
|
|
22594
|
-
...node.attrs,
|
|
22595
|
-
...attrs
|
|
22596
|
-
});
|
|
22597
|
-
found2 = true;
|
|
22598
|
-
return false;
|
|
22599
|
-
}
|
|
22600
|
-
});
|
|
22601
|
-
if (found2) {
|
|
22602
|
-
dispatch(tr);
|
|
22603
|
-
return true;
|
|
22378
|
+
let mapFrom = tr.steps.length, ranges = this.ranges;
|
|
22379
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
22380
|
+
let { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
|
|
22381
|
+
tr.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
|
|
22382
|
+
if (i == 0)
|
|
22383
|
+
selectionToInsertionEnd(tr, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1);
|
|
22604
22384
|
}
|
|
22605
|
-
|
|
22606
|
-
|
|
22607
|
-
|
|
22608
|
-
|
|
22609
|
-
|
|
22610
|
-
|
|
22611
|
-
|
|
22612
|
-
|
|
22613
|
-
|
|
22614
|
-
|
|
22615
|
-
|
|
22616
|
-
|
|
22617
|
-
|
|
22618
|
-
|
|
22619
|
-
|
|
22620
|
-
node.marks.forEach((mark) => {
|
|
22621
|
-
if (mark.type.name === markName && mark.attrs.uid === uid) {
|
|
22622
|
-
positions.push({
|
|
22623
|
-
from: pos,
|
|
22624
|
-
to: pos + node.nodeSize
|
|
22625
|
-
});
|
|
22626
|
-
found2 = true;
|
|
22627
|
-
}
|
|
22628
|
-
});
|
|
22629
|
-
}
|
|
22630
|
-
});
|
|
22631
|
-
if (found2) {
|
|
22632
|
-
const markType = schema.marks[markName];
|
|
22633
|
-
if (markType) {
|
|
22634
|
-
positions.forEach(({ from, to }) => {
|
|
22635
|
-
tr = tr.removeMark(from, to, markType);
|
|
22636
|
-
});
|
|
22637
|
-
dispatch(tr);
|
|
22385
|
+
}
|
|
22386
|
+
/**
|
|
22387
|
+
Replace the selection with the given node, appending the changes
|
|
22388
|
+
to the given transaction.
|
|
22389
|
+
*/
|
|
22390
|
+
replaceWith(tr, node) {
|
|
22391
|
+
let mapFrom = tr.steps.length, ranges = this.ranges;
|
|
22392
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
22393
|
+
let { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
|
|
22394
|
+
let from = mapping.map($from.pos), to = mapping.map($to.pos);
|
|
22395
|
+
if (i) {
|
|
22396
|
+
tr.deleteRange(from, to);
|
|
22397
|
+
} else {
|
|
22398
|
+
tr.replaceRangeWith(from, to, node);
|
|
22399
|
+
selectionToInsertionEnd(tr, mapFrom, node.isInline ? -1 : 1);
|
|
22638
22400
|
}
|
|
22639
22401
|
}
|
|
22640
|
-
|
|
22641
|
-
|
|
22642
|
-
|
|
22643
|
-
|
|
22644
|
-
|
|
22645
|
-
|
|
22646
|
-
|
|
22647
|
-
|
|
22648
|
-
|
|
22649
|
-
|
|
22650
|
-
|
|
22651
|
-
|
|
22652
|
-
|
|
22653
|
-
|
|
22654
|
-
|
|
22655
|
-
|
|
22402
|
+
}
|
|
22403
|
+
/**
|
|
22404
|
+
Find a valid cursor or leaf node selection starting at the given
|
|
22405
|
+
position and searching back if `dir` is negative, and forward if
|
|
22406
|
+
positive. When `textOnly` is true, only consider cursor
|
|
22407
|
+
selections. Will return null when no valid selection position is
|
|
22408
|
+
found.
|
|
22409
|
+
*/
|
|
22410
|
+
static findFrom($pos, dir, textOnly = false) {
|
|
22411
|
+
let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
|
|
22412
|
+
if (inner)
|
|
22413
|
+
return inner;
|
|
22414
|
+
for (let depth = $pos.depth - 1; depth >= 0; depth--) {
|
|
22415
|
+
let found2 = dir < 0 ? findSelectionIn($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly);
|
|
22416
|
+
if (found2)
|
|
22417
|
+
return found2;
|
|
22418
|
+
}
|
|
22419
|
+
return null;
|
|
22420
|
+
}
|
|
22421
|
+
/**
|
|
22422
|
+
Find a valid cursor or leaf node selection near the given
|
|
22423
|
+
position. Searches forward first by default, but if `bias` is
|
|
22424
|
+
negative, it will search backwards first.
|
|
22425
|
+
*/
|
|
22426
|
+
static near($pos, bias = 1) {
|
|
22427
|
+
return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection($pos.node(0));
|
|
22428
|
+
}
|
|
22429
|
+
/**
|
|
22430
|
+
Find the cursor or leaf node selection closest to the start of
|
|
22431
|
+
the given document. Will return an
|
|
22432
|
+
[`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position
|
|
22433
|
+
exists.
|
|
22434
|
+
*/
|
|
22435
|
+
static atStart(doc) {
|
|
22436
|
+
return findSelectionIn(doc, doc, 0, 0, 1) || new AllSelection(doc);
|
|
22437
|
+
}
|
|
22438
|
+
/**
|
|
22439
|
+
Find the cursor or leaf node selection closest to the end of the
|
|
22440
|
+
given document.
|
|
22441
|
+
*/
|
|
22442
|
+
static atEnd(doc) {
|
|
22443
|
+
return findSelectionIn(doc, doc, doc.content.size, doc.childCount, -1) || new AllSelection(doc);
|
|
22444
|
+
}
|
|
22445
|
+
/**
|
|
22446
|
+
Deserialize the JSON representation of a selection. Must be
|
|
22447
|
+
implemented for custom classes (as a static class method).
|
|
22448
|
+
*/
|
|
22449
|
+
static fromJSON(doc, json) {
|
|
22450
|
+
if (!json || !json.type)
|
|
22451
|
+
throw new RangeError("Invalid input for Selection.fromJSON");
|
|
22452
|
+
let cls = classesById[json.type];
|
|
22453
|
+
if (!cls)
|
|
22454
|
+
throw new RangeError(`No selection type ${json.type} defined`);
|
|
22455
|
+
return cls.fromJSON(doc, json);
|
|
22456
|
+
}
|
|
22457
|
+
/**
|
|
22458
|
+
To be able to deserialize selections from JSON, custom selection
|
|
22459
|
+
classes must register themselves with an ID string, so that they
|
|
22460
|
+
can be disambiguated. Try to pick something that's unlikely to
|
|
22461
|
+
clash with classes from other modules.
|
|
22462
|
+
*/
|
|
22463
|
+
static jsonID(id, selectionClass) {
|
|
22464
|
+
if (id in classesById)
|
|
22465
|
+
throw new RangeError("Duplicate use of selection JSON ID " + id);
|
|
22466
|
+
classesById[id] = selectionClass;
|
|
22467
|
+
selectionClass.prototype.jsonID = id;
|
|
22468
|
+
return selectionClass;
|
|
22469
|
+
}
|
|
22470
|
+
/**
|
|
22471
|
+
Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection,
|
|
22472
|
+
which is a value that can be mapped without having access to a
|
|
22473
|
+
current document, and later resolved to a real selection for a
|
|
22474
|
+
given document again. (This is used mostly by the history to
|
|
22475
|
+
track and restore old selections.) The default implementation of
|
|
22476
|
+
this method just converts the selection to a text selection and
|
|
22477
|
+
returns the bookmark for that.
|
|
22478
|
+
*/
|
|
22479
|
+
getBookmark() {
|
|
22480
|
+
return TextSelection.between(this.$anchor, this.$head).getBookmark();
|
|
22481
|
+
}
|
|
22482
|
+
}
|
|
22483
|
+
Selection.prototype.visible = true;
|
|
22484
|
+
class SelectionRange {
|
|
22485
|
+
/**
|
|
22486
|
+
Create a range.
|
|
22487
|
+
*/
|
|
22488
|
+
constructor($from, $to) {
|
|
22489
|
+
this.$from = $from;
|
|
22490
|
+
this.$to = $to;
|
|
22491
|
+
}
|
|
22492
|
+
}
|
|
22493
|
+
let warnedAboutTextSelection = false;
|
|
22494
|
+
function checkTextSelection($pos) {
|
|
22495
|
+
if (!warnedAboutTextSelection && !$pos.parent.inlineContent) {
|
|
22496
|
+
warnedAboutTextSelection = true;
|
|
22497
|
+
console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
|
|
22498
|
+
}
|
|
22499
|
+
}
|
|
22500
|
+
class TextSelection extends Selection {
|
|
22501
|
+
/**
|
|
22502
|
+
Construct a text selection between the given points.
|
|
22503
|
+
*/
|
|
22504
|
+
constructor($anchor, $head = $anchor) {
|
|
22505
|
+
checkTextSelection($anchor);
|
|
22506
|
+
checkTextSelection($head);
|
|
22507
|
+
super($anchor, $head);
|
|
22508
|
+
}
|
|
22509
|
+
/**
|
|
22510
|
+
Returns a resolved position if this is a cursor selection (an
|
|
22511
|
+
empty text selection), and null otherwise.
|
|
22512
|
+
*/
|
|
22513
|
+
get $cursor() {
|
|
22514
|
+
return this.$anchor.pos == this.$head.pos ? this.$head : null;
|
|
22515
|
+
}
|
|
22516
|
+
map(doc, mapping) {
|
|
22517
|
+
let $head = doc.resolve(mapping.map(this.head));
|
|
22518
|
+
if (!$head.parent.inlineContent)
|
|
22519
|
+
return Selection.near($head);
|
|
22520
|
+
let $anchor = doc.resolve(mapping.map(this.anchor));
|
|
22521
|
+
return new TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head);
|
|
22522
|
+
}
|
|
22523
|
+
replace(tr, content = Slice.empty) {
|
|
22524
|
+
super.replace(tr, content);
|
|
22525
|
+
if (content == Slice.empty) {
|
|
22526
|
+
let marks = this.$from.marksAcross(this.$to);
|
|
22527
|
+
if (marks)
|
|
22528
|
+
tr.ensureMarks(marks);
|
|
22656
22529
|
}
|
|
22657
|
-
|
|
22658
|
-
|
|
22659
|
-
|
|
22660
|
-
|
|
22661
|
-
|
|
22662
|
-
|
|
22663
|
-
|
|
22664
|
-
|
|
22665
|
-
|
|
22666
|
-
|
|
22667
|
-
|
|
22668
|
-
|
|
22669
|
-
|
|
22670
|
-
|
|
22671
|
-
|
|
22672
|
-
|
|
22673
|
-
|
|
22674
|
-
|
|
22675
|
-
|
|
22676
|
-
|
|
22677
|
-
|
|
22678
|
-
|
|
22679
|
-
|
|
22680
|
-
|
|
22681
|
-
|
|
22682
|
-
|
|
22683
|
-
|
|
22684
|
-
|
|
22685
|
-
|
|
22686
|
-
|
|
22687
|
-
|
|
22688
|
-
|
|
22689
|
-
|
|
22690
|
-
|
|
22691
|
-
|
|
22692
|
-
|
|
22693
|
-
|
|
22694
|
-
|
|
22695
|
-
|
|
22696
|
-
|
|
22697
|
-
|
|
22698
|
-
|
|
22699
|
-
|
|
22700
|
-
console.log("Original state.doc:", state2.doc.toJSON());
|
|
22701
|
-
dispatch(tr);
|
|
22702
|
-
console.log("Transaction dispatched successfully");
|
|
22530
|
+
}
|
|
22531
|
+
eq(other) {
|
|
22532
|
+
return other instanceof TextSelection && other.anchor == this.anchor && other.head == this.head;
|
|
22533
|
+
}
|
|
22534
|
+
getBookmark() {
|
|
22535
|
+
return new TextBookmark(this.anchor, this.head);
|
|
22536
|
+
}
|
|
22537
|
+
toJSON() {
|
|
22538
|
+
return { type: "text", anchor: this.anchor, head: this.head };
|
|
22539
|
+
}
|
|
22540
|
+
/**
|
|
22541
|
+
@internal
|
|
22542
|
+
*/
|
|
22543
|
+
static fromJSON(doc, json) {
|
|
22544
|
+
if (typeof json.anchor != "number" || typeof json.head != "number")
|
|
22545
|
+
throw new RangeError("Invalid input for TextSelection.fromJSON");
|
|
22546
|
+
return new TextSelection(doc.resolve(json.anchor), doc.resolve(json.head));
|
|
22547
|
+
}
|
|
22548
|
+
/**
|
|
22549
|
+
Create a text selection from non-resolved positions.
|
|
22550
|
+
*/
|
|
22551
|
+
static create(doc, anchor, head = anchor) {
|
|
22552
|
+
let $anchor = doc.resolve(anchor);
|
|
22553
|
+
return new this($anchor, head == anchor ? $anchor : doc.resolve(head));
|
|
22554
|
+
}
|
|
22555
|
+
/**
|
|
22556
|
+
Return a text selection that spans the given positions or, if
|
|
22557
|
+
they aren't text positions, find a text selection near them.
|
|
22558
|
+
`bias` determines whether the method searches forward (default)
|
|
22559
|
+
or backwards (negative number) first. Will fall back to calling
|
|
22560
|
+
[`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document
|
|
22561
|
+
doesn't contain a valid text position.
|
|
22562
|
+
*/
|
|
22563
|
+
static between($anchor, $head, bias) {
|
|
22564
|
+
let dPos = $anchor.pos - $head.pos;
|
|
22565
|
+
if (!bias || dPos)
|
|
22566
|
+
bias = dPos >= 0 ? 1 : -1;
|
|
22567
|
+
if (!$head.parent.inlineContent) {
|
|
22568
|
+
let found2 = Selection.findFrom($head, bias, true) || Selection.findFrom($head, -bias, true);
|
|
22569
|
+
if (found2)
|
|
22570
|
+
$head = found2.$head;
|
|
22571
|
+
else
|
|
22572
|
+
return Selection.near($head, bias);
|
|
22703
22573
|
}
|
|
22704
|
-
|
|
22705
|
-
|
|
22706
|
-
|
|
22707
|
-
}
|
|
22708
|
-
|
|
22709
|
-
|
|
22710
|
-
|
|
22711
|
-
type: MediaNodeTypes.Image,
|
|
22712
|
-
style: "object-fit: contain; width: 100%; border-radius: 0.5rem;",
|
|
22713
|
-
maxWidth: MEDIA_MIN_WIDTH,
|
|
22714
|
-
align: Alignment.LEFT,
|
|
22715
|
-
caption: "",
|
|
22716
|
-
uploading: false,
|
|
22717
|
-
progress: 0
|
|
22718
|
-
};
|
|
22719
|
-
const MediaNode = core.Node.create({
|
|
22720
|
-
name: "media",
|
|
22721
|
-
group: "block",
|
|
22722
|
-
atom: true,
|
|
22723
|
-
addAttributes() {
|
|
22724
|
-
return {
|
|
22725
|
-
uid: { default: DEFAULT_MEDIA_ATTRS.uid },
|
|
22726
|
-
src: { default: DEFAULT_MEDIA_ATTRS.src },
|
|
22727
|
-
type: { default: DEFAULT_MEDIA_ATTRS.type },
|
|
22728
|
-
style: { default: DEFAULT_MEDIA_ATTRS.style },
|
|
22729
|
-
maxWidth: { default: DEFAULT_MEDIA_ATTRS.maxWidth },
|
|
22730
|
-
align: { default: DEFAULT_MEDIA_ATTRS.align },
|
|
22731
|
-
caption: { default: DEFAULT_MEDIA_ATTRS.caption },
|
|
22732
|
-
uploading: { default: DEFAULT_MEDIA_ATTRS.uploading },
|
|
22733
|
-
progress: { default: DEFAULT_MEDIA_ATTRS.progress },
|
|
22734
|
-
payload: { default: null, parseHTML: () => null, renderHTML: () => ({}) }
|
|
22735
|
-
};
|
|
22736
|
-
},
|
|
22737
|
-
draggable() {
|
|
22738
|
-
return Boolean(!this?.options?.attrs?.uploading && !this?.options?.attrs?.mediaMode);
|
|
22739
|
-
},
|
|
22740
|
-
selectable() {
|
|
22741
|
-
return Boolean(!this?.options?.attrs?.mediaMode);
|
|
22742
|
-
},
|
|
22743
|
-
parseHTML() {
|
|
22744
|
-
return [
|
|
22745
|
-
{
|
|
22746
|
-
tag: "div[data-media]",
|
|
22747
|
-
getAttrs: (dom) => {
|
|
22748
|
-
return {
|
|
22749
|
-
uid: dom.getAttribute("data-uid") || "",
|
|
22750
|
-
src: dom.getAttribute("data-src") || "",
|
|
22751
|
-
type: dom.getAttribute("data-type") || MediaNodeTypes.Image,
|
|
22752
|
-
align: dom.getAttribute("data-align") || Alignment.LEFT,
|
|
22753
|
-
caption: dom.getAttribute("data-caption") || "",
|
|
22754
|
-
style: dom.getAttribute("style") || DEFAULT_MEDIA_ATTRS.style
|
|
22755
|
-
};
|
|
22756
|
-
}
|
|
22757
|
-
}
|
|
22758
|
-
];
|
|
22759
|
-
},
|
|
22760
|
-
renderHTML({ HTMLAttributes }) {
|
|
22761
|
-
const { uid, src, style, type, align, maxWidth, caption } = HTMLAttributes;
|
|
22762
|
-
const tag = MEDIA_TAGS[type];
|
|
22763
|
-
const wrapperAttrs = core.mergeAttributes({
|
|
22764
|
-
style: buildWrapperStyle(align),
|
|
22765
|
-
"data-media": true,
|
|
22766
|
-
"data-uid": uid,
|
|
22767
|
-
"data-type": type,
|
|
22768
|
-
"data-src": src,
|
|
22769
|
-
"data-caption": caption || "",
|
|
22770
|
-
"data-align": align
|
|
22771
|
-
});
|
|
22772
|
-
const mediaAttrs = core.mergeAttributes(
|
|
22773
|
-
{ src, style: buildMediaStyle(style, type, maxWidth) },
|
|
22774
|
-
{ controls: type === MediaNodeTypes.Audio || type === MediaNodeTypes.Video }
|
|
22775
|
-
);
|
|
22776
|
-
return ["div", wrapperAttrs, [tag, mediaAttrs]];
|
|
22777
|
-
},
|
|
22778
|
-
addNodeView() {
|
|
22779
|
-
return react.ReactNodeViewRenderer(MediaNodeView);
|
|
22780
|
-
},
|
|
22781
|
-
addCommands() {
|
|
22782
|
-
return {
|
|
22783
|
-
insertMedia: (options) => ({ commands, chain }) => {
|
|
22784
|
-
if (this?.options?.attrs?.mediaMode) {
|
|
22785
|
-
return chain().insertContent([{ type: this.name, attrs: options }]).command(({ tr, dispatch }) => {
|
|
22786
|
-
if (dispatch) {
|
|
22787
|
-
const endPos = tr.doc.content.size;
|
|
22788
|
-
const $pos = tr.doc.resolve(endPos);
|
|
22789
|
-
tr.setSelection(state.TextSelection.near($pos));
|
|
22790
|
-
}
|
|
22791
|
-
return true;
|
|
22792
|
-
}).run();
|
|
22793
|
-
}
|
|
22794
|
-
return commands.insertContent([
|
|
22795
|
-
{ type: this.name, attrs: options },
|
|
22796
|
-
{ type: "paragraph" }
|
|
22797
|
-
//! Fixes multiple media overlapping issue (But removes default selection feature)
|
|
22798
|
-
]);
|
|
22799
|
-
},
|
|
22800
|
-
updateMediaByUid: createUpdateByUidCommand(this.name),
|
|
22801
|
-
deleteMediaByUid: createDeleteByUidCommand(this.name),
|
|
22802
|
-
updateMediaProgress: (uid, progress) => ({ commands }) => {
|
|
22803
|
-
return commands.updateMediaByUid(uid, { progress });
|
|
22574
|
+
if (!$anchor.parent.inlineContent) {
|
|
22575
|
+
if (dPos == 0) {
|
|
22576
|
+
$anchor = $head;
|
|
22577
|
+
} else {
|
|
22578
|
+
$anchor = (Selection.findFrom($anchor, -bias, true) || Selection.findFrom($anchor, bias, true)).$anchor;
|
|
22579
|
+
if ($anchor.pos < $head.pos != dPos < 0)
|
|
22580
|
+
$anchor = $head;
|
|
22804
22581
|
}
|
|
22805
|
-
}
|
|
22582
|
+
}
|
|
22583
|
+
return new TextSelection($anchor, $head);
|
|
22584
|
+
}
|
|
22585
|
+
}
|
|
22586
|
+
Selection.jsonID("text", TextSelection);
|
|
22587
|
+
class TextBookmark {
|
|
22588
|
+
constructor(anchor, head) {
|
|
22589
|
+
this.anchor = anchor;
|
|
22590
|
+
this.head = head;
|
|
22591
|
+
}
|
|
22592
|
+
map(mapping) {
|
|
22593
|
+
return new TextBookmark(mapping.map(this.anchor), mapping.map(this.head));
|
|
22594
|
+
}
|
|
22595
|
+
resolve(doc) {
|
|
22596
|
+
return TextSelection.between(doc.resolve(this.anchor), doc.resolve(this.head));
|
|
22597
|
+
}
|
|
22598
|
+
}
|
|
22599
|
+
class NodeSelection extends Selection {
|
|
22600
|
+
/**
|
|
22601
|
+
Create a node selection. Does not verify the validity of its
|
|
22602
|
+
argument.
|
|
22603
|
+
*/
|
|
22604
|
+
constructor($pos) {
|
|
22605
|
+
let node = $pos.nodeAfter;
|
|
22606
|
+
let $end = $pos.node(0).resolve($pos.pos + node.nodeSize);
|
|
22607
|
+
super($pos, $end);
|
|
22608
|
+
this.node = node;
|
|
22609
|
+
}
|
|
22610
|
+
map(doc, mapping) {
|
|
22611
|
+
let { deleted, pos } = mapping.mapResult(this.anchor);
|
|
22612
|
+
let $pos = doc.resolve(pos);
|
|
22613
|
+
if (deleted)
|
|
22614
|
+
return Selection.near($pos);
|
|
22615
|
+
return new NodeSelection($pos);
|
|
22616
|
+
}
|
|
22617
|
+
content() {
|
|
22618
|
+
return new Slice(Fragment.from(this.node), 0, 0);
|
|
22619
|
+
}
|
|
22620
|
+
eq(other) {
|
|
22621
|
+
return other instanceof NodeSelection && other.anchor == this.anchor;
|
|
22622
|
+
}
|
|
22623
|
+
toJSON() {
|
|
22624
|
+
return { type: "node", anchor: this.anchor };
|
|
22625
|
+
}
|
|
22626
|
+
getBookmark() {
|
|
22627
|
+
return new NodeBookmark(this.anchor);
|
|
22628
|
+
}
|
|
22629
|
+
/**
|
|
22630
|
+
@internal
|
|
22631
|
+
*/
|
|
22632
|
+
static fromJSON(doc, json) {
|
|
22633
|
+
if (typeof json.anchor != "number")
|
|
22634
|
+
throw new RangeError("Invalid input for NodeSelection.fromJSON");
|
|
22635
|
+
return new NodeSelection(doc.resolve(json.anchor));
|
|
22636
|
+
}
|
|
22637
|
+
/**
|
|
22638
|
+
Create a node selection from non-resolved positions.
|
|
22639
|
+
*/
|
|
22640
|
+
static create(doc, from) {
|
|
22641
|
+
return new NodeSelection(doc.resolve(from));
|
|
22642
|
+
}
|
|
22643
|
+
/**
|
|
22644
|
+
Determines whether the given node may be selected as a node
|
|
22645
|
+
selection.
|
|
22646
|
+
*/
|
|
22647
|
+
static isSelectable(node) {
|
|
22648
|
+
return !node.isText && node.type.spec.selectable !== false;
|
|
22649
|
+
}
|
|
22650
|
+
}
|
|
22651
|
+
NodeSelection.prototype.visible = false;
|
|
22652
|
+
Selection.jsonID("node", NodeSelection);
|
|
22653
|
+
class NodeBookmark {
|
|
22654
|
+
constructor(anchor) {
|
|
22655
|
+
this.anchor = anchor;
|
|
22656
|
+
}
|
|
22657
|
+
map(mapping) {
|
|
22658
|
+
let { deleted, pos } = mapping.mapResult(this.anchor);
|
|
22659
|
+
return deleted ? new TextBookmark(pos, pos) : new NodeBookmark(pos);
|
|
22660
|
+
}
|
|
22661
|
+
resolve(doc) {
|
|
22662
|
+
let $pos = doc.resolve(this.anchor), node = $pos.nodeAfter;
|
|
22663
|
+
if (node && NodeSelection.isSelectable(node))
|
|
22664
|
+
return new NodeSelection($pos);
|
|
22665
|
+
return Selection.near($pos);
|
|
22666
|
+
}
|
|
22667
|
+
}
|
|
22668
|
+
class AllSelection extends Selection {
|
|
22669
|
+
/**
|
|
22670
|
+
Create an all-selection over the given document.
|
|
22671
|
+
*/
|
|
22672
|
+
constructor(doc) {
|
|
22673
|
+
super(doc.resolve(0), doc.resolve(doc.content.size));
|
|
22674
|
+
}
|
|
22675
|
+
replace(tr, content = Slice.empty) {
|
|
22676
|
+
if (content == Slice.empty) {
|
|
22677
|
+
tr.delete(0, tr.doc.content.size);
|
|
22678
|
+
let sel = Selection.atStart(tr.doc);
|
|
22679
|
+
if (!sel.eq(tr.selection))
|
|
22680
|
+
tr.setSelection(sel);
|
|
22681
|
+
} else {
|
|
22682
|
+
super.replace(tr, content);
|
|
22683
|
+
}
|
|
22684
|
+
}
|
|
22685
|
+
toJSON() {
|
|
22686
|
+
return { type: "all" };
|
|
22687
|
+
}
|
|
22688
|
+
/**
|
|
22689
|
+
@internal
|
|
22690
|
+
*/
|
|
22691
|
+
static fromJSON(doc) {
|
|
22692
|
+
return new AllSelection(doc);
|
|
22693
|
+
}
|
|
22694
|
+
map(doc) {
|
|
22695
|
+
return new AllSelection(doc);
|
|
22696
|
+
}
|
|
22697
|
+
eq(other) {
|
|
22698
|
+
return other instanceof AllSelection;
|
|
22699
|
+
}
|
|
22700
|
+
getBookmark() {
|
|
22701
|
+
return AllBookmark;
|
|
22702
|
+
}
|
|
22703
|
+
}
|
|
22704
|
+
Selection.jsonID("all", AllSelection);
|
|
22705
|
+
const AllBookmark = {
|
|
22706
|
+
map() {
|
|
22707
|
+
return this;
|
|
22806
22708
|
},
|
|
22807
|
-
|
|
22808
|
-
return
|
|
22809
|
-
Backspace: () => {
|
|
22810
|
-
const { selection, doc } = this.editor.state;
|
|
22811
|
-
const $pos = selection.$anchor;
|
|
22812
|
-
const nodeBefore = $pos.nodeBefore;
|
|
22813
|
-
if (nodeBefore?.type.name === this.name && nodeBefore.attrs.uploading) {
|
|
22814
|
-
toast.info("Please wait for upload to complete or cancel it first");
|
|
22815
|
-
return true;
|
|
22816
|
-
}
|
|
22817
|
-
const nodeAtSelection = doc.nodeAt(selection.from);
|
|
22818
|
-
if (nodeAtSelection?.type.name === this.name && nodeAtSelection.attrs.uploading) {
|
|
22819
|
-
toast.info("Please wait for upload to complete or cancel it first");
|
|
22820
|
-
return true;
|
|
22821
|
-
}
|
|
22822
|
-
return false;
|
|
22823
|
-
},
|
|
22824
|
-
Delete: () => {
|
|
22825
|
-
const { selection, doc } = this.editor.state;
|
|
22826
|
-
const $pos = selection.$anchor;
|
|
22827
|
-
const nodeAfter = $pos.nodeAfter;
|
|
22828
|
-
if (nodeAfter?.type.name === this.name && nodeAfter.attrs.uploading) {
|
|
22829
|
-
toast.info("Please wait for upload to complete or cancel it first");
|
|
22830
|
-
return true;
|
|
22831
|
-
}
|
|
22832
|
-
const nodeAtSelection = doc.nodeAt(selection.from);
|
|
22833
|
-
if (nodeAtSelection?.type.name === this.name && nodeAtSelection.attrs.uploading) {
|
|
22834
|
-
toast.info("Please wait for upload to complete or cancel it first");
|
|
22835
|
-
return true;
|
|
22836
|
-
}
|
|
22837
|
-
return false;
|
|
22838
|
-
}
|
|
22839
|
-
};
|
|
22709
|
+
resolve(doc) {
|
|
22710
|
+
return new AllSelection(doc);
|
|
22840
22711
|
}
|
|
22841
|
-
});
|
|
22842
|
-
const buildWrapperStyle = (align) => `width: 100%; display: flex; justify-content: ${getAlignmentStyle(align)}; margin:16px 0`;
|
|
22843
|
-
const buildMediaStyle = (baseStyle, type, maxWidth) => `${baseStyle}; max-width: ${type === MediaNodeTypes.Audio ? "100%" : `${maxWidth}%`}; ${type !== MediaNodeTypes.Audio ? "height: auto;" : ""}`;
|
|
22844
|
-
const getAlignmentStyle = (align) => {
|
|
22845
|
-
const map = {
|
|
22846
|
-
[Alignment.LEFT]: "flex-start",
|
|
22847
|
-
[Alignment.CENTER]: "center",
|
|
22848
|
-
[Alignment.RIGHT]: "flex-end"
|
|
22849
|
-
};
|
|
22850
|
-
return map[align] || "flex-start";
|
|
22851
22712
|
};
|
|
22713
|
+
function findSelectionIn(doc, node, pos, index2, dir, text2 = false) {
|
|
22714
|
+
if (node.inlineContent)
|
|
22715
|
+
return TextSelection.create(doc, pos);
|
|
22716
|
+
for (let i = index2 - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) {
|
|
22717
|
+
let child = node.child(i);
|
|
22718
|
+
if (!child.isAtom) {
|
|
22719
|
+
let inner = findSelectionIn(doc, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text2);
|
|
22720
|
+
if (inner)
|
|
22721
|
+
return inner;
|
|
22722
|
+
} else if (!text2 && NodeSelection.isSelectable(child)) {
|
|
22723
|
+
return NodeSelection.create(doc, pos - (dir < 0 ? child.nodeSize : 0));
|
|
22724
|
+
}
|
|
22725
|
+
pos += child.nodeSize * dir;
|
|
22726
|
+
}
|
|
22727
|
+
return null;
|
|
22728
|
+
}
|
|
22729
|
+
function selectionToInsertionEnd(tr, startLen, bias) {
|
|
22730
|
+
let last2 = tr.steps.length - 1;
|
|
22731
|
+
if (last2 < startLen)
|
|
22732
|
+
return;
|
|
22733
|
+
let step = tr.steps[last2];
|
|
22734
|
+
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep))
|
|
22735
|
+
return;
|
|
22736
|
+
let map = tr.mapping.maps[last2], end2;
|
|
22737
|
+
map.forEach((_from, _to, _newFrom, newTo) => {
|
|
22738
|
+
if (end2 == null)
|
|
22739
|
+
end2 = newTo;
|
|
22740
|
+
});
|
|
22741
|
+
tr.setSelection(Selection.near(tr.doc.resolve(end2), bias));
|
|
22742
|
+
}
|
|
22743
|
+
function bind(f, self2) {
|
|
22744
|
+
return !self2 || !f ? f : f.bind(self2);
|
|
22745
|
+
}
|
|
22746
|
+
class FieldDesc {
|
|
22747
|
+
constructor(name, desc, self2) {
|
|
22748
|
+
this.name = name;
|
|
22749
|
+
this.init = bind(desc.init, self2);
|
|
22750
|
+
this.apply = bind(desc.apply, self2);
|
|
22751
|
+
}
|
|
22752
|
+
}
|
|
22753
|
+
[
|
|
22754
|
+
new FieldDesc("doc", {
|
|
22755
|
+
init(config) {
|
|
22756
|
+
return config.doc || config.schema.topNodeType.createAndFill();
|
|
22757
|
+
},
|
|
22758
|
+
apply(tr) {
|
|
22759
|
+
return tr.doc;
|
|
22760
|
+
}
|
|
22761
|
+
}),
|
|
22762
|
+
new FieldDesc("selection", {
|
|
22763
|
+
init(config, instance) {
|
|
22764
|
+
return config.selection || Selection.atStart(instance.doc);
|
|
22765
|
+
},
|
|
22766
|
+
apply(tr) {
|
|
22767
|
+
return tr.selection;
|
|
22768
|
+
}
|
|
22769
|
+
}),
|
|
22770
|
+
new FieldDesc("storedMarks", {
|
|
22771
|
+
init(config) {
|
|
22772
|
+
return config.storedMarks || null;
|
|
22773
|
+
},
|
|
22774
|
+
apply(tr, _marks, _old, state2) {
|
|
22775
|
+
return state2.selection.$cursor ? tr.storedMarks : null;
|
|
22776
|
+
}
|
|
22777
|
+
}),
|
|
22778
|
+
new FieldDesc("scrollToSelection", {
|
|
22779
|
+
init() {
|
|
22780
|
+
return 0;
|
|
22781
|
+
},
|
|
22782
|
+
apply(tr, prev) {
|
|
22783
|
+
return tr.scrolledIntoView ? prev + 1 : prev;
|
|
22784
|
+
}
|
|
22785
|
+
})
|
|
22786
|
+
];
|
|
22787
|
+
function bindProps(obj, self2, target) {
|
|
22788
|
+
for (let prop in obj) {
|
|
22789
|
+
let val = obj[prop];
|
|
22790
|
+
if (val instanceof Function)
|
|
22791
|
+
val = val.bind(self2);
|
|
22792
|
+
else if (prop == "handleDOMEvents")
|
|
22793
|
+
val = bindProps(val, self2, {});
|
|
22794
|
+
target[prop] = val;
|
|
22795
|
+
}
|
|
22796
|
+
return target;
|
|
22797
|
+
}
|
|
22798
|
+
class Plugin {
|
|
22799
|
+
/**
|
|
22800
|
+
Create a plugin.
|
|
22801
|
+
*/
|
|
22802
|
+
constructor(spec) {
|
|
22803
|
+
this.spec = spec;
|
|
22804
|
+
this.props = {};
|
|
22805
|
+
if (spec.props)
|
|
22806
|
+
bindProps(spec.props, this, this.props);
|
|
22807
|
+
this.key = spec.key ? spec.key.key : createKey("plugin");
|
|
22808
|
+
}
|
|
22809
|
+
/**
|
|
22810
|
+
Extract the plugin's state field from an editor state.
|
|
22811
|
+
*/
|
|
22812
|
+
getState(state2) {
|
|
22813
|
+
return state2[this.key];
|
|
22814
|
+
}
|
|
22815
|
+
}
|
|
22816
|
+
const keys = /* @__PURE__ */ Object.create(null);
|
|
22817
|
+
function createKey(name) {
|
|
22818
|
+
if (name in keys)
|
|
22819
|
+
return name + "$" + ++keys[name];
|
|
22820
|
+
keys[name] = 0;
|
|
22821
|
+
return name + "$";
|
|
22822
|
+
}
|
|
22823
|
+
class PluginKey {
|
|
22824
|
+
/**
|
|
22825
|
+
Create a plugin key.
|
|
22826
|
+
*/
|
|
22827
|
+
constructor(name = "key") {
|
|
22828
|
+
this.key = createKey(name);
|
|
22829
|
+
}
|
|
22830
|
+
/**
|
|
22831
|
+
Get the active plugin with this key, if any, from an editor
|
|
22832
|
+
state.
|
|
22833
|
+
*/
|
|
22834
|
+
get(state2) {
|
|
22835
|
+
return state2.config.pluginsByKey[this.key];
|
|
22836
|
+
}
|
|
22837
|
+
/**
|
|
22838
|
+
Get the plugin's state from an editor state.
|
|
22839
|
+
*/
|
|
22840
|
+
getState(state2) {
|
|
22841
|
+
return state2[this.key];
|
|
22842
|
+
}
|
|
22843
|
+
}
|
|
22852
22844
|
const TextChoiceCard = ({ choice, index: index2, canRemove, onRemove }) => {
|
|
22853
22845
|
const backgroundColor = OPTION_COLORS[index2 % OPTION_COLORS.length];
|
|
22854
22846
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -30769,6 +30761,15 @@ const getPollItemsPayload = (json) => {
|
|
|
30769
30761
|
const items = poll[0].attrs?.choices;
|
|
30770
30762
|
return { items };
|
|
30771
30763
|
};
|
|
30764
|
+
const isValidItem = (item) => {
|
|
30765
|
+
if (!item) return false;
|
|
30766
|
+
const linkItem = item;
|
|
30767
|
+
const mediaItem = item;
|
|
30768
|
+
const isValidLinkItem = linkItem?.linkUrl;
|
|
30769
|
+
const mediaItemSources = mediaItem?.sources;
|
|
30770
|
+
const isValidMediaItem = mediaItemSources?.original?.url || mediaItemSources?.thumbnail?.url || mediaItemSources?.placeholder?.url;
|
|
30771
|
+
return Boolean(isValidLinkItem || isValidMediaItem);
|
|
30772
|
+
};
|
|
30772
30773
|
const generateHtmlPostPayload = ({
|
|
30773
30774
|
editor,
|
|
30774
30775
|
sendCrossMention
|
|
@@ -30785,13 +30786,13 @@ const generateHtmlPostPayload = ({
|
|
|
30785
30786
|
(node) => node?.type === "text" && (node?.marks?.some((val) => val?.type !== "customLink") ?? true)
|
|
30786
30787
|
)?.at(0);
|
|
30787
30788
|
const isEmbedOnly = isOnlyContentNode(json, "iframe");
|
|
30788
|
-
const body = isEmbedOnly ? previewItemEmbed?.attrs?.previewPayload?.linkTitle ?? "" : secondaryText?.text ?? firstText?.text ?? "";
|
|
30789
|
+
const body = isEmbedOnly ? previewItemEmbed?.attrs?.previewPayload?.linkTitle ?? previewItemEmbed?.attrs?.src ?? "" : secondaryText?.text ?? firstText?.text ?? "";
|
|
30789
30790
|
console.log({ firstText });
|
|
30790
30791
|
const items = [
|
|
30791
30792
|
previewItemMedia?.attrs?.payload,
|
|
30792
30793
|
previewItemEmbed?.attrs?.previewPayload,
|
|
30793
30794
|
linkPreviewItem
|
|
30794
|
-
]?.filter(
|
|
30795
|
+
]?.filter(isValidItem)?.filter((_, index2) => index2 === 0);
|
|
30795
30796
|
const htmlBody = html2;
|
|
30796
30797
|
return {
|
|
30797
30798
|
...commons,
|