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