@tiptap/core 3.0.0-next.1 → 3.0.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +403 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +177 -53
- package/dist/index.d.ts +177 -53
- package/dist/index.js +375 -108
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/Editor.ts +60 -10
- package/src/EventEmitter.ts +9 -0
- package/src/ExtensionManager.ts +16 -11
- package/src/InputRule.ts +45 -30
- package/src/Node.ts +19 -0
- package/src/NodePos.ts +9 -4
- package/src/NodeView.ts +43 -12
- package/src/PasteRule.ts +96 -42
- package/src/commands/focus.ts +1 -6
- package/src/commands/insertContent.ts +9 -9
- package/src/commands/insertContentAt.ts +23 -3
- package/src/commands/selectAll.ts +10 -5
- package/src/commands/setContent.ts +10 -14
- package/src/commands/setNode.ts +9 -2
- package/src/commands/toggleNode.ts +11 -2
- package/src/commands/updateAttributes.ts +72 -12
- package/src/extensions/drop.ts +26 -0
- package/src/extensions/index.ts +2 -0
- package/src/extensions/keymap.ts +5 -2
- package/src/extensions/paste.ts +26 -0
- package/src/helpers/createDocument.ts +4 -2
- package/src/helpers/createNodeFromContent.ts +11 -2
- package/src/helpers/getMarkRange.ts +35 -8
- package/src/helpers/getRenderedAttributes.ts +3 -0
- package/src/helpers/getSchemaByResolvedExtensions.ts +2 -1
- package/src/inputRules/markInputRule.ts +1 -1
- package/src/inputRules/nodeInputRule.ts +1 -1
- package/src/inputRules/textInputRule.ts +1 -1
- package/src/inputRules/textblockTypeInputRule.ts +1 -1
- package/src/inputRules/wrappingInputRule.ts +1 -1
- package/src/pasteRules/markPasteRule.ts +1 -1
- package/src/pasteRules/nodePasteRule.ts +1 -1
- package/src/pasteRules/textPasteRule.ts +1 -1
- package/src/types.ts +107 -19
- package/src/utilities/mergeAttributes.ts +18 -1
package/dist/index.cjs
CHANGED
|
@@ -253,7 +253,7 @@ var CommandManager = class {
|
|
|
253
253
|
};
|
|
254
254
|
|
|
255
255
|
// src/Editor.ts
|
|
256
|
-
var
|
|
256
|
+
var import_state21 = require("@tiptap/pm/state");
|
|
257
257
|
var import_view = require("@tiptap/pm/view");
|
|
258
258
|
|
|
259
259
|
// src/EventEmitter.ts
|
|
@@ -286,6 +286,13 @@ var EventEmitter = class {
|
|
|
286
286
|
}
|
|
287
287
|
return this;
|
|
288
288
|
}
|
|
289
|
+
once(event, fn) {
|
|
290
|
+
const onceFn = (...args) => {
|
|
291
|
+
this.off(event, onceFn);
|
|
292
|
+
fn.apply(this, args);
|
|
293
|
+
};
|
|
294
|
+
return this.on(event, onceFn);
|
|
295
|
+
}
|
|
289
296
|
removeAllListeners() {
|
|
290
297
|
this.callbacks = {};
|
|
291
298
|
}
|
|
@@ -432,7 +439,18 @@ function mergeAttributes(...objects) {
|
|
|
432
439
|
);
|
|
433
440
|
mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
|
|
434
441
|
} else if (key === "style") {
|
|
435
|
-
|
|
442
|
+
const newStyles = value ? value.split(";").map((style2) => style2.trim()).filter(Boolean) : [];
|
|
443
|
+
const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(";").map((style2) => style2.trim()).filter(Boolean) : [];
|
|
444
|
+
const styleMap = /* @__PURE__ */ new Map();
|
|
445
|
+
existingStyles.forEach((style2) => {
|
|
446
|
+
const [property, val] = style2.split(":").map((part) => part.trim());
|
|
447
|
+
styleMap.set(property, val);
|
|
448
|
+
});
|
|
449
|
+
newStyles.forEach((style2) => {
|
|
450
|
+
const [property, val] = style2.split(":").map((part) => part.trim());
|
|
451
|
+
styleMap.set(property, val);
|
|
452
|
+
});
|
|
453
|
+
mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; ");
|
|
436
454
|
} else {
|
|
437
455
|
mergedAttributes[key] = value;
|
|
438
456
|
}
|
|
@@ -443,7 +461,9 @@ function mergeAttributes(...objects) {
|
|
|
443
461
|
|
|
444
462
|
// src/helpers/getRenderedAttributes.ts
|
|
445
463
|
function getRenderedAttributes(nodeOrMark, extensionAttributes) {
|
|
446
|
-
return extensionAttributes.filter(
|
|
464
|
+
return extensionAttributes.filter(
|
|
465
|
+
(attribute) => attribute.type === nodeOrMark.type.name
|
|
466
|
+
).filter((item) => item.attribute.rendered).map((item) => {
|
|
447
467
|
if (!item.attribute.renderHTML) {
|
|
448
468
|
return {
|
|
449
469
|
[item.name]: nodeOrMark.attrs[item.name]
|
|
@@ -577,6 +597,7 @@ function getSchemaByResolvedExtensions(extensions, editor) {
|
|
|
577
597
|
),
|
|
578
598
|
code: callOrReturn(getExtensionField(extension, "code", context)),
|
|
579
599
|
whitespace: callOrReturn(getExtensionField(extension, "whitespace", context)),
|
|
600
|
+
linebreakReplacement: callOrReturn(getExtensionField(extension, "linebreakReplacement", context)),
|
|
580
601
|
defining: callOrReturn(
|
|
581
602
|
getExtensionField(extension, "defining", context)
|
|
582
603
|
),
|
|
@@ -704,8 +725,19 @@ function isExtensionRulesEnabled(extension, enabled) {
|
|
|
704
725
|
}
|
|
705
726
|
|
|
706
727
|
// src/InputRule.ts
|
|
728
|
+
var import_model3 = require("@tiptap/pm/model");
|
|
707
729
|
var import_state = require("@tiptap/pm/state");
|
|
708
730
|
|
|
731
|
+
// src/helpers/getHTMLFromFragment.ts
|
|
732
|
+
var import_model2 = require("@tiptap/pm/model");
|
|
733
|
+
function getHTMLFromFragment(fragment, schema) {
|
|
734
|
+
const documentFragment = import_model2.DOMSerializer.fromSchema(schema).serializeFragment(fragment);
|
|
735
|
+
const temporaryDocument = document.implementation.createHTMLDocument();
|
|
736
|
+
const container = temporaryDocument.createElement("div");
|
|
737
|
+
container.appendChild(documentFragment);
|
|
738
|
+
return container.innerHTML;
|
|
739
|
+
}
|
|
740
|
+
|
|
709
741
|
// src/helpers/getTextContentFromNodes.ts
|
|
710
742
|
var getTextContentFromNodes = ($from, maxMatch = 500) => {
|
|
711
743
|
let textBefore = "";
|
|
@@ -834,7 +866,7 @@ function inputRulesPlugin(props) {
|
|
|
834
866
|
init() {
|
|
835
867
|
return null;
|
|
836
868
|
},
|
|
837
|
-
apply(tr, prev) {
|
|
869
|
+
apply(tr, prev, state) {
|
|
838
870
|
const stored = tr.getMeta(plugin);
|
|
839
871
|
if (stored) {
|
|
840
872
|
return stored;
|
|
@@ -843,7 +875,13 @@ function inputRulesPlugin(props) {
|
|
|
843
875
|
const isSimulatedInput = !!simulatedInputMeta;
|
|
844
876
|
if (isSimulatedInput) {
|
|
845
877
|
setTimeout(() => {
|
|
846
|
-
|
|
878
|
+
let { text } = simulatedInputMeta;
|
|
879
|
+
if (typeof text === "string") {
|
|
880
|
+
text = text;
|
|
881
|
+
} else {
|
|
882
|
+
text = getHTMLFromFragment(import_model3.Fragment.from(text), state.schema);
|
|
883
|
+
}
|
|
884
|
+
const { from } = simulatedInputMeta;
|
|
847
885
|
const to = from + text.length;
|
|
848
886
|
run({
|
|
849
887
|
editor,
|
|
@@ -1035,6 +1073,7 @@ var Mark = class _Mark {
|
|
|
1035
1073
|
};
|
|
1036
1074
|
|
|
1037
1075
|
// src/PasteRule.ts
|
|
1076
|
+
var import_model4 = require("@tiptap/pm/model");
|
|
1038
1077
|
var import_state2 = require("@tiptap/pm/state");
|
|
1039
1078
|
|
|
1040
1079
|
// src/utilities/isNumber.ts
|
|
@@ -1122,6 +1161,7 @@ function run2(config) {
|
|
|
1122
1161
|
const success = handlers.every((handler) => handler !== null);
|
|
1123
1162
|
return success;
|
|
1124
1163
|
}
|
|
1164
|
+
var tiptapDragFromOtherEditor = null;
|
|
1125
1165
|
var createClipboardPasteEvent = (text) => {
|
|
1126
1166
|
var _a;
|
|
1127
1167
|
const event = new ClipboardEvent("paste", {
|
|
@@ -1136,7 +1176,12 @@ function pasteRulesPlugin(props) {
|
|
|
1136
1176
|
let isPastedFromProseMirror = false;
|
|
1137
1177
|
let isDroppedFromProseMirror = false;
|
|
1138
1178
|
let pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
|
|
1139
|
-
let dropEvent
|
|
1179
|
+
let dropEvent;
|
|
1180
|
+
try {
|
|
1181
|
+
dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null;
|
|
1182
|
+
} catch (e) {
|
|
1183
|
+
dropEvent = null;
|
|
1184
|
+
}
|
|
1140
1185
|
const processEvent = ({
|
|
1141
1186
|
state,
|
|
1142
1187
|
from,
|
|
@@ -1161,7 +1206,11 @@ function pasteRulesPlugin(props) {
|
|
|
1161
1206
|
if (!handler || !tr.steps.length) {
|
|
1162
1207
|
return;
|
|
1163
1208
|
}
|
|
1164
|
-
|
|
1209
|
+
try {
|
|
1210
|
+
dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null;
|
|
1211
|
+
} catch (e) {
|
|
1212
|
+
dropEvent = null;
|
|
1213
|
+
}
|
|
1165
1214
|
pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
|
|
1166
1215
|
return tr;
|
|
1167
1216
|
};
|
|
@@ -1172,11 +1221,21 @@ function pasteRulesPlugin(props) {
|
|
|
1172
1221
|
const handleDragstart = (event) => {
|
|
1173
1222
|
var _a;
|
|
1174
1223
|
dragSourceElement = ((_a = view.dom.parentElement) == null ? void 0 : _a.contains(event.target)) ? view.dom.parentElement : null;
|
|
1224
|
+
if (dragSourceElement) {
|
|
1225
|
+
tiptapDragFromOtherEditor = editor;
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
1228
|
+
const handleDragend = () => {
|
|
1229
|
+
if (tiptapDragFromOtherEditor) {
|
|
1230
|
+
tiptapDragFromOtherEditor = null;
|
|
1231
|
+
}
|
|
1175
1232
|
};
|
|
1176
1233
|
window.addEventListener("dragstart", handleDragstart);
|
|
1234
|
+
window.addEventListener("dragend", handleDragend);
|
|
1177
1235
|
return {
|
|
1178
1236
|
destroy() {
|
|
1179
1237
|
window.removeEventListener("dragstart", handleDragstart);
|
|
1238
|
+
window.removeEventListener("dragend", handleDragend);
|
|
1180
1239
|
}
|
|
1181
1240
|
};
|
|
1182
1241
|
},
|
|
@@ -1185,6 +1244,17 @@ function pasteRulesPlugin(props) {
|
|
|
1185
1244
|
drop: (view, event) => {
|
|
1186
1245
|
isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
|
|
1187
1246
|
dropEvent = event;
|
|
1247
|
+
if (!isDroppedFromProseMirror) {
|
|
1248
|
+
const dragFromOtherEditor = tiptapDragFromOtherEditor;
|
|
1249
|
+
if (dragFromOtherEditor) {
|
|
1250
|
+
setTimeout(() => {
|
|
1251
|
+
const selection = dragFromOtherEditor.state.selection;
|
|
1252
|
+
if (selection) {
|
|
1253
|
+
dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to });
|
|
1254
|
+
}
|
|
1255
|
+
}, 10);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1188
1258
|
return false;
|
|
1189
1259
|
},
|
|
1190
1260
|
paste: (_view, event) => {
|
|
@@ -1206,7 +1276,13 @@ function pasteRulesPlugin(props) {
|
|
|
1206
1276
|
return;
|
|
1207
1277
|
}
|
|
1208
1278
|
if (isSimulatedPaste) {
|
|
1209
|
-
|
|
1279
|
+
let { text } = simulatedPasteMeta;
|
|
1280
|
+
if (typeof text === "string") {
|
|
1281
|
+
text = text;
|
|
1282
|
+
} else {
|
|
1283
|
+
text = getHTMLFromFragment(import_model4.Fragment.from(text), state.schema);
|
|
1284
|
+
}
|
|
1285
|
+
const { from: from2 } = simulatedPasteMeta;
|
|
1210
1286
|
const to2 = from2 + text.length;
|
|
1211
1287
|
const pasteEvt = createClipboardPasteEvent(text);
|
|
1212
1288
|
return processEvent({
|
|
@@ -1445,15 +1521,19 @@ var ExtensionManager = class _ExtensionManager {
|
|
|
1445
1521
|
if (!addNodeView) {
|
|
1446
1522
|
return [];
|
|
1447
1523
|
}
|
|
1448
|
-
const nodeview = (node, view, getPos, decorations) => {
|
|
1524
|
+
const nodeview = (node, view, getPos, decorations, innerDecorations) => {
|
|
1449
1525
|
const HTMLAttributes = getRenderedAttributes(node, extensionAttributes);
|
|
1450
1526
|
return addNodeView()({
|
|
1451
|
-
|
|
1527
|
+
// pass-through
|
|
1452
1528
|
node,
|
|
1529
|
+
view,
|
|
1453
1530
|
getPos,
|
|
1454
1531
|
decorations,
|
|
1455
|
-
|
|
1456
|
-
|
|
1532
|
+
innerDecorations,
|
|
1533
|
+
// tiptap-specific
|
|
1534
|
+
editor,
|
|
1535
|
+
extension,
|
|
1536
|
+
HTMLAttributes
|
|
1457
1537
|
});
|
|
1458
1538
|
};
|
|
1459
1539
|
return [extension.name, nodeview];
|
|
@@ -1534,9 +1614,11 @@ var extensions_exports = {};
|
|
|
1534
1614
|
__export(extensions_exports, {
|
|
1535
1615
|
ClipboardTextSerializer: () => ClipboardTextSerializer,
|
|
1536
1616
|
Commands: () => Commands,
|
|
1617
|
+
Drop: () => Drop,
|
|
1537
1618
|
Editable: () => Editable,
|
|
1538
1619
|
FocusEvents: () => FocusEvents,
|
|
1539
1620
|
Keymap: () => Keymap,
|
|
1621
|
+
Paste: () => Paste,
|
|
1540
1622
|
Tabindex: () => Tabindex
|
|
1541
1623
|
});
|
|
1542
1624
|
|
|
@@ -1913,23 +1995,29 @@ function objectIncludes(object1, object2, options = { strict: true }) {
|
|
|
1913
1995
|
// src/helpers/getMarkRange.ts
|
|
1914
1996
|
function findMarkInSet(marks, type, attributes = {}) {
|
|
1915
1997
|
return marks.find((item) => {
|
|
1916
|
-
return item.type === type && objectIncludes(
|
|
1998
|
+
return item.type === type && objectIncludes(
|
|
1999
|
+
// Only check equality for the attributes that are provided
|
|
2000
|
+
Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])),
|
|
2001
|
+
attributes
|
|
2002
|
+
);
|
|
1917
2003
|
});
|
|
1918
2004
|
}
|
|
1919
2005
|
function isMarkInSet(marks, type, attributes = {}) {
|
|
1920
2006
|
return !!findMarkInSet(marks, type, attributes);
|
|
1921
2007
|
}
|
|
1922
|
-
function getMarkRange($pos, type, attributes
|
|
2008
|
+
function getMarkRange($pos, type, attributes) {
|
|
2009
|
+
var _a;
|
|
1923
2010
|
if (!$pos || !type) {
|
|
1924
2011
|
return;
|
|
1925
2012
|
}
|
|
1926
2013
|
let start = $pos.parent.childAfter($pos.parentOffset);
|
|
1927
|
-
if (
|
|
2014
|
+
if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) {
|
|
1928
2015
|
start = $pos.parent.childBefore($pos.parentOffset);
|
|
1929
2016
|
}
|
|
1930
|
-
if (!start.node) {
|
|
2017
|
+
if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) {
|
|
1931
2018
|
return;
|
|
1932
2019
|
}
|
|
2020
|
+
attributes = attributes || ((_a = start.node.marks[0]) == null ? void 0 : _a.attrs);
|
|
1933
2021
|
const mark = findMarkInSet([...start.node.marks], type, attributes);
|
|
1934
2022
|
if (!mark) {
|
|
1935
2023
|
return;
|
|
@@ -1938,8 +2026,7 @@ function getMarkRange($pos, type, attributes = {}) {
|
|
|
1938
2026
|
let startPos = $pos.start() + start.offset;
|
|
1939
2027
|
let endIndex = startIndex + 1;
|
|
1940
2028
|
let endPos = startPos + start.node.nodeSize;
|
|
1941
|
-
|
|
1942
|
-
while (startIndex > 0 && mark.isInSet($pos.parent.child(startIndex - 1).marks)) {
|
|
2029
|
+
while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) {
|
|
1943
2030
|
startIndex -= 1;
|
|
1944
2031
|
startPos -= $pos.parent.child(startIndex).nodeSize;
|
|
1945
2032
|
}
|
|
@@ -2035,18 +2122,6 @@ function resolveFocusPosition(doc, position = null) {
|
|
|
2035
2122
|
);
|
|
2036
2123
|
}
|
|
2037
2124
|
|
|
2038
|
-
// src/utilities/isiOS.ts
|
|
2039
|
-
function isiOS() {
|
|
2040
|
-
return [
|
|
2041
|
-
"iPad Simulator",
|
|
2042
|
-
"iPhone Simulator",
|
|
2043
|
-
"iPod Simulator",
|
|
2044
|
-
"iPad",
|
|
2045
|
-
"iPhone",
|
|
2046
|
-
"iPod"
|
|
2047
|
-
].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
|
|
2048
|
-
}
|
|
2049
|
-
|
|
2050
2125
|
// src/commands/focus.ts
|
|
2051
2126
|
var focus = (position = null, options = {}) => ({
|
|
2052
2127
|
editor,
|
|
@@ -2059,9 +2134,7 @@ var focus = (position = null, options = {}) => ({
|
|
|
2059
2134
|
...options
|
|
2060
2135
|
};
|
|
2061
2136
|
const delayedFocus = () => {
|
|
2062
|
-
|
|
2063
|
-
view.dom.focus();
|
|
2064
|
-
}
|
|
2137
|
+
view.dom.focus();
|
|
2065
2138
|
requestAnimationFrame(() => {
|
|
2066
2139
|
if (!editor.isDestroyed) {
|
|
2067
2140
|
view.focus();
|
|
@@ -2106,8 +2179,11 @@ var insertContent = (value, options) => ({ tr, commands }) => {
|
|
|
2106
2179
|
);
|
|
2107
2180
|
};
|
|
2108
2181
|
|
|
2182
|
+
// src/commands/insertContentAt.ts
|
|
2183
|
+
var import_model6 = require("@tiptap/pm/model");
|
|
2184
|
+
|
|
2109
2185
|
// src/helpers/createNodeFromContent.ts
|
|
2110
|
-
var
|
|
2186
|
+
var import_model5 = require("@tiptap/pm/model");
|
|
2111
2187
|
|
|
2112
2188
|
// src/utilities/elementFromString.ts
|
|
2113
2189
|
var removeWhitespaces = (node) => {
|
|
@@ -2130,6 +2206,9 @@ function elementFromString(value) {
|
|
|
2130
2206
|
|
|
2131
2207
|
// src/helpers/createNodeFromContent.ts
|
|
2132
2208
|
function createNodeFromContent(content, schema, options) {
|
|
2209
|
+
if (content instanceof import_model5.Node || content instanceof import_model5.Fragment) {
|
|
2210
|
+
return content;
|
|
2211
|
+
}
|
|
2133
2212
|
options = {
|
|
2134
2213
|
slice: true,
|
|
2135
2214
|
parseOptions: {},
|
|
@@ -2141,9 +2220,13 @@ function createNodeFromContent(content, schema, options) {
|
|
|
2141
2220
|
try {
|
|
2142
2221
|
const isArrayContent = Array.isArray(content) && content.length > 0;
|
|
2143
2222
|
if (isArrayContent) {
|
|
2144
|
-
return
|
|
2223
|
+
return import_model5.Fragment.fromArray(content.map((item) => schema.nodeFromJSON(item)));
|
|
2145
2224
|
}
|
|
2146
|
-
|
|
2225
|
+
const node = schema.nodeFromJSON(content);
|
|
2226
|
+
if (options.errorOnInvalidContent) {
|
|
2227
|
+
node.check();
|
|
2228
|
+
}
|
|
2229
|
+
return node;
|
|
2147
2230
|
} catch (error) {
|
|
2148
2231
|
if (options.errorOnInvalidContent) {
|
|
2149
2232
|
throw new Error("[tiptap error]: Invalid JSON content", { cause: error });
|
|
@@ -2156,7 +2239,7 @@ function createNodeFromContent(content, schema, options) {
|
|
|
2156
2239
|
if (options.errorOnInvalidContent) {
|
|
2157
2240
|
let hasInvalidContent = false;
|
|
2158
2241
|
let invalidContent = "";
|
|
2159
|
-
const contentCheckSchema = new
|
|
2242
|
+
const contentCheckSchema = new import_model5.Schema({
|
|
2160
2243
|
topNode: schema.spec.topNode,
|
|
2161
2244
|
marks: schema.spec.marks,
|
|
2162
2245
|
// Prosemirror's schemas are executed such that: the last to execute, matches last
|
|
@@ -2179,15 +2262,15 @@ function createNodeFromContent(content, schema, options) {
|
|
|
2179
2262
|
})
|
|
2180
2263
|
});
|
|
2181
2264
|
if (options.slice) {
|
|
2182
|
-
|
|
2265
|
+
import_model5.DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
|
|
2183
2266
|
} else {
|
|
2184
|
-
|
|
2267
|
+
import_model5.DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
|
|
2185
2268
|
}
|
|
2186
2269
|
if (options.errorOnInvalidContent && hasInvalidContent) {
|
|
2187
2270
|
throw new Error("[tiptap error]: Invalid HTML content", { cause: new Error(`Invalid element found: ${invalidContent}`) });
|
|
2188
2271
|
}
|
|
2189
2272
|
}
|
|
2190
|
-
const parser =
|
|
2273
|
+
const parser = import_model5.DOMParser.fromSchema(schema);
|
|
2191
2274
|
if (options.slice) {
|
|
2192
2275
|
return parser.parseSlice(elementFromString(content), options.parseOptions).content;
|
|
2193
2276
|
}
|
|
@@ -2226,13 +2309,14 @@ var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) =
|
|
|
2226
2309
|
var _a;
|
|
2227
2310
|
if (dispatch) {
|
|
2228
2311
|
options = {
|
|
2229
|
-
parseOptions:
|
|
2312
|
+
parseOptions: editor.options.parseOptions,
|
|
2230
2313
|
updateSelection: true,
|
|
2231
2314
|
applyInputRules: false,
|
|
2232
2315
|
applyPasteRules: false,
|
|
2233
2316
|
...options
|
|
2234
2317
|
};
|
|
2235
2318
|
let content;
|
|
2319
|
+
const { selection } = editor.state;
|
|
2236
2320
|
try {
|
|
2237
2321
|
content = createNodeFromContent(value, editor.schema, {
|
|
2238
2322
|
parseOptions: {
|
|
@@ -2246,7 +2330,9 @@ var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) =
|
|
|
2246
2330
|
editor,
|
|
2247
2331
|
error: e,
|
|
2248
2332
|
disableCollaboration: () => {
|
|
2249
|
-
|
|
2333
|
+
if (editor.storage.collaboration) {
|
|
2334
|
+
editor.storage.collaboration.isDisabled = true;
|
|
2335
|
+
}
|
|
2250
2336
|
}
|
|
2251
2337
|
});
|
|
2252
2338
|
return false;
|
|
@@ -2272,6 +2358,14 @@ var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) =
|
|
|
2272
2358
|
if (isOnlyTextContent) {
|
|
2273
2359
|
if (Array.isArray(value)) {
|
|
2274
2360
|
newContent = value.map((v) => v.text || "").join("");
|
|
2361
|
+
} else if (value instanceof import_model6.Fragment) {
|
|
2362
|
+
let text = "";
|
|
2363
|
+
value.forEach((node) => {
|
|
2364
|
+
if (node.text) {
|
|
2365
|
+
text += node.text;
|
|
2366
|
+
}
|
|
2367
|
+
});
|
|
2368
|
+
newContent = text;
|
|
2275
2369
|
} else if (typeof value === "object" && !!value && !!value.text) {
|
|
2276
2370
|
newContent = value.text;
|
|
2277
2371
|
} else {
|
|
@@ -2280,6 +2374,11 @@ var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) =
|
|
|
2280
2374
|
tr.insertText(newContent, from, to);
|
|
2281
2375
|
} else {
|
|
2282
2376
|
newContent = content;
|
|
2377
|
+
const fromSelectionAtStart = selection.$from.parentOffset === 0;
|
|
2378
|
+
const isTextSelection2 = selection.$from.node().isText || selection.$from.node().isTextblock;
|
|
2379
|
+
if (fromSelectionAtStart && isTextSelection2) {
|
|
2380
|
+
from = Math.max(0, from - 1);
|
|
2381
|
+
}
|
|
2283
2382
|
tr.replaceWith(from, to, newContent);
|
|
2284
2383
|
}
|
|
2285
2384
|
if (options.updateSelection) {
|
|
@@ -2366,6 +2465,18 @@ var joinTextblockForward = () => ({ state, dispatch }) => {
|
|
|
2366
2465
|
return (0, import_commands6.joinTextblockForward)(state, dispatch);
|
|
2367
2466
|
};
|
|
2368
2467
|
|
|
2468
|
+
// src/utilities/isiOS.ts
|
|
2469
|
+
function isiOS() {
|
|
2470
|
+
return [
|
|
2471
|
+
"iPad Simulator",
|
|
2472
|
+
"iPhone Simulator",
|
|
2473
|
+
"iPod Simulator",
|
|
2474
|
+
"iPad",
|
|
2475
|
+
"iPhone",
|
|
2476
|
+
"iPod"
|
|
2477
|
+
].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
|
|
2478
|
+
}
|
|
2479
|
+
|
|
2369
2480
|
// src/utilities/isMacOS.ts
|
|
2370
2481
|
function isMacOS() {
|
|
2371
2482
|
return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
|
|
@@ -2579,11 +2690,13 @@ var scrollIntoView = () => ({ tr, dispatch }) => {
|
|
|
2579
2690
|
};
|
|
2580
2691
|
|
|
2581
2692
|
// src/commands/selectAll.ts
|
|
2582
|
-
var
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2693
|
+
var import_state9 = require("@tiptap/pm/state");
|
|
2694
|
+
var selectAll = () => ({ tr, dispatch }) => {
|
|
2695
|
+
if (dispatch) {
|
|
2696
|
+
const selection = new import_state9.AllSelection(tr.doc);
|
|
2697
|
+
tr.setSelection(selection);
|
|
2698
|
+
}
|
|
2699
|
+
return true;
|
|
2587
2700
|
};
|
|
2588
2701
|
|
|
2589
2702
|
// src/commands/selectNodeBackward.ts
|
|
@@ -2646,14 +2759,10 @@ var setContent = (content, emitUpdate = false, parseOptions = {}, options = {})
|
|
|
2646
2759
|
if (dispatch) {
|
|
2647
2760
|
tr.setMeta("preventUpdate", !emitUpdate);
|
|
2648
2761
|
}
|
|
2649
|
-
return commands.insertContentAt(
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
parseOptions,
|
|
2654
|
-
errorOnInvalidContent: (_b = options.errorOnInvalidContent) != null ? _b : editor.options.enableContentCheck
|
|
2655
|
-
}
|
|
2656
|
-
);
|
|
2762
|
+
return commands.insertContentAt({ from: 0, to: doc.content.size }, content, {
|
|
2763
|
+
parseOptions,
|
|
2764
|
+
errorOnInvalidContent: (_b = options.errorOnInvalidContent) != null ? _b : editor.options.enableContentCheck
|
|
2765
|
+
});
|
|
2657
2766
|
};
|
|
2658
2767
|
|
|
2659
2768
|
// src/helpers/getMarkAttributes.ts
|
|
@@ -2750,17 +2859,7 @@ function findParentNode(predicate) {
|
|
|
2750
2859
|
}
|
|
2751
2860
|
|
|
2752
2861
|
// src/helpers/generateHTML.ts
|
|
2753
|
-
var
|
|
2754
|
-
|
|
2755
|
-
// src/helpers/getHTMLFromFragment.ts
|
|
2756
|
-
var import_model3 = require("@tiptap/pm/model");
|
|
2757
|
-
function getHTMLFromFragment(fragment, schema) {
|
|
2758
|
-
const documentFragment = import_model3.DOMSerializer.fromSchema(schema).serializeFragment(fragment);
|
|
2759
|
-
const temporaryDocument = document.implementation.createHTMLDocument();
|
|
2760
|
-
const container = temporaryDocument.createElement("div");
|
|
2761
|
-
container.appendChild(documentFragment);
|
|
2762
|
-
return container.innerHTML;
|
|
2763
|
-
}
|
|
2862
|
+
var import_model7 = require("@tiptap/pm/model");
|
|
2764
2863
|
|
|
2765
2864
|
// src/helpers/getSchema.ts
|
|
2766
2865
|
function getSchema(extensions, editor) {
|
|
@@ -2771,20 +2870,20 @@ function getSchema(extensions, editor) {
|
|
|
2771
2870
|
// src/helpers/generateHTML.ts
|
|
2772
2871
|
function generateHTML(doc, extensions) {
|
|
2773
2872
|
const schema = getSchema(extensions);
|
|
2774
|
-
const contentNode =
|
|
2873
|
+
const contentNode = import_model7.Node.fromJSON(schema, doc);
|
|
2775
2874
|
return getHTMLFromFragment(contentNode.content, schema);
|
|
2776
2875
|
}
|
|
2777
2876
|
|
|
2778
2877
|
// src/helpers/generateJSON.ts
|
|
2779
|
-
var
|
|
2878
|
+
var import_model8 = require("@tiptap/pm/model");
|
|
2780
2879
|
function generateJSON(html, extensions) {
|
|
2781
2880
|
const schema = getSchema(extensions);
|
|
2782
2881
|
const dom = elementFromString(html);
|
|
2783
|
-
return
|
|
2882
|
+
return import_model8.DOMParser.fromSchema(schema).parse(dom).toJSON();
|
|
2784
2883
|
}
|
|
2785
2884
|
|
|
2786
2885
|
// src/helpers/generateText.ts
|
|
2787
|
-
var
|
|
2886
|
+
var import_model9 = require("@tiptap/pm/model");
|
|
2788
2887
|
|
|
2789
2888
|
// src/helpers/getText.ts
|
|
2790
2889
|
function getText(node, options) {
|
|
@@ -2799,7 +2898,7 @@ function getText(node, options) {
|
|
|
2799
2898
|
function generateText(doc, extensions, options) {
|
|
2800
2899
|
const { blockSeparator = "\n\n", textSerializers = {} } = options || {};
|
|
2801
2900
|
const schema = getSchema(extensions);
|
|
2802
|
-
const contentNode =
|
|
2901
|
+
const contentNode = import_model9.Node.fromJSON(schema, doc);
|
|
2803
2902
|
return getText(contentNode, {
|
|
2804
2903
|
blockSeparator,
|
|
2805
2904
|
textSerializers: {
|
|
@@ -3150,9 +3249,9 @@ function isNodeEmpty(node, {
|
|
|
3150
3249
|
}
|
|
3151
3250
|
|
|
3152
3251
|
// src/helpers/isNodeSelection.ts
|
|
3153
|
-
var
|
|
3252
|
+
var import_state10 = require("@tiptap/pm/state");
|
|
3154
3253
|
function isNodeSelection(value) {
|
|
3155
|
-
return value instanceof
|
|
3254
|
+
return value instanceof import_state10.NodeSelection;
|
|
3156
3255
|
}
|
|
3157
3256
|
|
|
3158
3257
|
// src/helpers/posToDOMRect.ts
|
|
@@ -3270,44 +3369,48 @@ var setMeta = (key, value) => ({ tr }) => {
|
|
|
3270
3369
|
var import_commands15 = require("@tiptap/pm/commands");
|
|
3271
3370
|
var setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => {
|
|
3272
3371
|
const type = getNodeType(typeOrName, state.schema);
|
|
3372
|
+
let attributesToCopy;
|
|
3373
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
3374
|
+
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
3375
|
+
}
|
|
3273
3376
|
if (!type.isTextblock) {
|
|
3274
3377
|
console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.');
|
|
3275
3378
|
return false;
|
|
3276
3379
|
}
|
|
3277
3380
|
return chain().command(({ commands }) => {
|
|
3278
|
-
const canSetBlock = (0, import_commands15.setBlockType)(type, attributes)(state);
|
|
3381
|
+
const canSetBlock = (0, import_commands15.setBlockType)(type, { ...attributesToCopy, ...attributes })(state);
|
|
3279
3382
|
if (canSetBlock) {
|
|
3280
3383
|
return true;
|
|
3281
3384
|
}
|
|
3282
3385
|
return commands.clearNodes();
|
|
3283
3386
|
}).command(({ state: updatedState }) => {
|
|
3284
|
-
return (0, import_commands15.setBlockType)(type, attributes)(updatedState, dispatch);
|
|
3387
|
+
return (0, import_commands15.setBlockType)(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch);
|
|
3285
3388
|
}).run();
|
|
3286
3389
|
};
|
|
3287
3390
|
|
|
3288
3391
|
// src/commands/setNodeSelection.ts
|
|
3289
|
-
var
|
|
3392
|
+
var import_state11 = require("@tiptap/pm/state");
|
|
3290
3393
|
var setNodeSelection = (position) => ({ tr, dispatch }) => {
|
|
3291
3394
|
if (dispatch) {
|
|
3292
3395
|
const { doc } = tr;
|
|
3293
3396
|
const from = minMax(position, 0, doc.content.size);
|
|
3294
|
-
const selection =
|
|
3397
|
+
const selection = import_state11.NodeSelection.create(doc, from);
|
|
3295
3398
|
tr.setSelection(selection);
|
|
3296
3399
|
}
|
|
3297
3400
|
return true;
|
|
3298
3401
|
};
|
|
3299
3402
|
|
|
3300
3403
|
// src/commands/setTextSelection.ts
|
|
3301
|
-
var
|
|
3404
|
+
var import_state12 = require("@tiptap/pm/state");
|
|
3302
3405
|
var setTextSelection = (position) => ({ tr, dispatch }) => {
|
|
3303
3406
|
if (dispatch) {
|
|
3304
3407
|
const { doc } = tr;
|
|
3305
3408
|
const { from, to } = typeof position === "number" ? { from: position, to: position } : position;
|
|
3306
|
-
const minPos =
|
|
3307
|
-
const maxPos =
|
|
3409
|
+
const minPos = import_state12.TextSelection.atStart(doc).from;
|
|
3410
|
+
const maxPos = import_state12.TextSelection.atEnd(doc).to;
|
|
3308
3411
|
const resolvedFrom = minMax(from, minPos, maxPos);
|
|
3309
3412
|
const resolvedEnd = minMax(to, minPos, maxPos);
|
|
3310
|
-
const selection =
|
|
3413
|
+
const selection = import_state12.TextSelection.create(doc, resolvedFrom, resolvedEnd);
|
|
3311
3414
|
tr.setSelection(selection);
|
|
3312
3415
|
}
|
|
3313
3416
|
return true;
|
|
@@ -3321,7 +3424,7 @@ var sinkListItem = (typeOrName) => ({ state, dispatch }) => {
|
|
|
3321
3424
|
};
|
|
3322
3425
|
|
|
3323
3426
|
// src/commands/splitBlock.ts
|
|
3324
|
-
var
|
|
3427
|
+
var import_state13 = require("@tiptap/pm/state");
|
|
3325
3428
|
var import_transform6 = require("@tiptap/pm/transform");
|
|
3326
3429
|
function ensureMarks(state, splittableMarks) {
|
|
3327
3430
|
const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks();
|
|
@@ -3344,7 +3447,7 @@ var splitBlock = ({ keepMarks = true } = {}) => ({
|
|
|
3344
3447
|
$from.node().type.name,
|
|
3345
3448
|
$from.node().attrs
|
|
3346
3449
|
);
|
|
3347
|
-
if (selection instanceof
|
|
3450
|
+
if (selection instanceof import_state13.NodeSelection && selection.node.isBlock) {
|
|
3348
3451
|
if (!$from.parentOffset || !(0, import_transform6.canSplit)(doc, $from.pos)) {
|
|
3349
3452
|
return false;
|
|
3350
3453
|
}
|
|
@@ -3379,7 +3482,7 @@ var splitBlock = ({ keepMarks = true } = {}) => ({
|
|
|
3379
3482
|
}
|
|
3380
3483
|
if (dispatch) {
|
|
3381
3484
|
if (can) {
|
|
3382
|
-
if (selection instanceof
|
|
3485
|
+
if (selection instanceof import_state13.TextSelection) {
|
|
3383
3486
|
tr.deleteSelection();
|
|
3384
3487
|
}
|
|
3385
3488
|
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
@@ -3400,8 +3503,8 @@ var splitBlock = ({ keepMarks = true } = {}) => ({
|
|
|
3400
3503
|
};
|
|
3401
3504
|
|
|
3402
3505
|
// src/commands/splitListItem.ts
|
|
3403
|
-
var
|
|
3404
|
-
var
|
|
3506
|
+
var import_model10 = require("@tiptap/pm/model");
|
|
3507
|
+
var import_state14 = require("@tiptap/pm/state");
|
|
3405
3508
|
var import_transform7 = require("@tiptap/pm/transform");
|
|
3406
3509
|
var splitListItem = (typeOrName, overrideAttrs = {}) => ({
|
|
3407
3510
|
tr,
|
|
@@ -3426,10 +3529,10 @@ var splitListItem = (typeOrName, overrideAttrs = {}) => ({
|
|
|
3426
3529
|
return false;
|
|
3427
3530
|
}
|
|
3428
3531
|
if (dispatch) {
|
|
3429
|
-
let wrap =
|
|
3532
|
+
let wrap = import_model10.Fragment.empty;
|
|
3430
3533
|
const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3;
|
|
3431
3534
|
for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d -= 1) {
|
|
3432
|
-
wrap =
|
|
3535
|
+
wrap = import_model10.Fragment.from($from.node(d).copy(wrap));
|
|
3433
3536
|
}
|
|
3434
3537
|
const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3;
|
|
3435
3538
|
const newNextTypeAttributes2 = {
|
|
@@ -3441,9 +3544,9 @@ var splitListItem = (typeOrName, overrideAttrs = {}) => ({
|
|
|
3441
3544
|
...overrideAttrs
|
|
3442
3545
|
};
|
|
3443
3546
|
const nextType2 = ((_a = type.contentMatch.defaultType) == null ? void 0 : _a.createAndFill(newNextTypeAttributes2)) || void 0;
|
|
3444
|
-
wrap = wrap.append(
|
|
3547
|
+
wrap = wrap.append(import_model10.Fragment.from(type.createAndFill(null, nextType2) || void 0));
|
|
3445
3548
|
const start = $from.before($from.depth - (depthBefore - 1));
|
|
3446
|
-
tr.replace(start, $from.after(-depthAfter), new
|
|
3549
|
+
tr.replace(start, $from.after(-depthAfter), new import_model10.Slice(wrap, 4 - depthBefore, 0));
|
|
3447
3550
|
let sel = -1;
|
|
3448
3551
|
tr.doc.nodesBetween(start, tr.doc.content.size, (n, pos) => {
|
|
3449
3552
|
if (sel > -1) {
|
|
@@ -3454,7 +3557,7 @@ var splitListItem = (typeOrName, overrideAttrs = {}) => ({
|
|
|
3454
3557
|
}
|
|
3455
3558
|
});
|
|
3456
3559
|
if (sel > -1) {
|
|
3457
|
-
tr.setSelection(
|
|
3560
|
+
tr.setSelection(import_state14.TextSelection.near(tr.doc.resolve(sel)));
|
|
3458
3561
|
}
|
|
3459
3562
|
tr.scrollIntoView();
|
|
3460
3563
|
}
|
|
@@ -3602,10 +3705,14 @@ var toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, co
|
|
|
3602
3705
|
const type = getNodeType(typeOrName, state.schema);
|
|
3603
3706
|
const toggleType = getNodeType(toggleTypeOrName, state.schema);
|
|
3604
3707
|
const isActive2 = isNodeActive(state, type, attributes);
|
|
3708
|
+
let attributesToCopy;
|
|
3709
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
3710
|
+
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
3711
|
+
}
|
|
3605
3712
|
if (isActive2) {
|
|
3606
|
-
return commands.setNode(toggleType);
|
|
3713
|
+
return commands.setNode(toggleType, attributesToCopy);
|
|
3607
3714
|
}
|
|
3608
|
-
return commands.setNode(type, attributes);
|
|
3715
|
+
return commands.setNode(type, { ...attributesToCopy, ...attributes });
|
|
3609
3716
|
};
|
|
3610
3717
|
|
|
3611
3718
|
// src/commands/toggleWrap.ts
|
|
@@ -3708,18 +3815,63 @@ var updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch }
|
|
|
3708
3815
|
tr.selection.ranges.forEach((range) => {
|
|
3709
3816
|
const from = range.$from.pos;
|
|
3710
3817
|
const to = range.$to.pos;
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3818
|
+
let lastPos;
|
|
3819
|
+
let lastNode;
|
|
3820
|
+
let trimmedFrom;
|
|
3821
|
+
let trimmedTo;
|
|
3822
|
+
if (tr.selection.empty) {
|
|
3823
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
3824
|
+
if (nodeType && nodeType === node.type) {
|
|
3825
|
+
trimmedFrom = Math.max(pos, from);
|
|
3826
|
+
trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
3827
|
+
lastPos = pos;
|
|
3828
|
+
lastNode = node;
|
|
3829
|
+
}
|
|
3830
|
+
});
|
|
3831
|
+
} else {
|
|
3832
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
3833
|
+
if (pos < from && nodeType && nodeType === node.type) {
|
|
3834
|
+
trimmedFrom = Math.max(pos, from);
|
|
3835
|
+
trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
3836
|
+
lastPos = pos;
|
|
3837
|
+
lastNode = node;
|
|
3838
|
+
}
|
|
3839
|
+
if (pos >= from && pos <= to) {
|
|
3840
|
+
if (nodeType && nodeType === node.type) {
|
|
3841
|
+
tr.setNodeMarkup(pos, void 0, {
|
|
3842
|
+
...node.attrs,
|
|
3843
|
+
...attributes
|
|
3844
|
+
});
|
|
3845
|
+
}
|
|
3846
|
+
if (markType && node.marks.length) {
|
|
3847
|
+
node.marks.forEach((mark) => {
|
|
3848
|
+
if (markType === mark.type) {
|
|
3849
|
+
const trimmedFrom2 = Math.max(pos, from);
|
|
3850
|
+
const trimmedTo2 = Math.min(pos + node.nodeSize, to);
|
|
3851
|
+
tr.addMark(
|
|
3852
|
+
trimmedFrom2,
|
|
3853
|
+
trimmedTo2,
|
|
3854
|
+
markType.create({
|
|
3855
|
+
...mark.attrs,
|
|
3856
|
+
...attributes
|
|
3857
|
+
})
|
|
3858
|
+
);
|
|
3859
|
+
}
|
|
3860
|
+
});
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
});
|
|
3864
|
+
}
|
|
3865
|
+
if (lastNode) {
|
|
3866
|
+
if (lastPos !== void 0) {
|
|
3867
|
+
tr.setNodeMarkup(lastPos, void 0, {
|
|
3868
|
+
...lastNode.attrs,
|
|
3715
3869
|
...attributes
|
|
3716
3870
|
});
|
|
3717
3871
|
}
|
|
3718
|
-
if (markType &&
|
|
3719
|
-
|
|
3872
|
+
if (markType && lastNode.marks.length) {
|
|
3873
|
+
lastNode.marks.forEach((mark) => {
|
|
3720
3874
|
if (markType === mark.type) {
|
|
3721
|
-
const trimmedFrom = Math.max(pos, from);
|
|
3722
|
-
const trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
3723
3875
|
tr.addMark(
|
|
3724
3876
|
trimmedFrom,
|
|
3725
3877
|
trimmedTo,
|
|
@@ -3731,7 +3883,7 @@ var updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch }
|
|
|
3731
3883
|
}
|
|
3732
3884
|
});
|
|
3733
3885
|
}
|
|
3734
|
-
}
|
|
3886
|
+
}
|
|
3735
3887
|
});
|
|
3736
3888
|
}
|
|
3737
3889
|
return true;
|
|
@@ -3761,14 +3913,37 @@ var Commands = Extension.create({
|
|
|
3761
3913
|
}
|
|
3762
3914
|
});
|
|
3763
3915
|
|
|
3916
|
+
// src/extensions/drop.ts
|
|
3917
|
+
var import_state15 = require("@tiptap/pm/state");
|
|
3918
|
+
var Drop = Extension.create({
|
|
3919
|
+
name: "drop",
|
|
3920
|
+
addProseMirrorPlugins() {
|
|
3921
|
+
return [
|
|
3922
|
+
new import_state15.Plugin({
|
|
3923
|
+
key: new import_state15.PluginKey("tiptapDrop"),
|
|
3924
|
+
props: {
|
|
3925
|
+
handleDrop: (_, e, slice, moved) => {
|
|
3926
|
+
this.editor.emit("drop", {
|
|
3927
|
+
editor: this.editor,
|
|
3928
|
+
event: e,
|
|
3929
|
+
slice,
|
|
3930
|
+
moved
|
|
3931
|
+
});
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3934
|
+
})
|
|
3935
|
+
];
|
|
3936
|
+
}
|
|
3937
|
+
});
|
|
3938
|
+
|
|
3764
3939
|
// src/extensions/editable.ts
|
|
3765
|
-
var
|
|
3940
|
+
var import_state16 = require("@tiptap/pm/state");
|
|
3766
3941
|
var Editable = Extension.create({
|
|
3767
3942
|
name: "editable",
|
|
3768
3943
|
addProseMirrorPlugins() {
|
|
3769
3944
|
return [
|
|
3770
|
-
new
|
|
3771
|
-
key: new
|
|
3945
|
+
new import_state16.Plugin({
|
|
3946
|
+
key: new import_state16.PluginKey("editable"),
|
|
3772
3947
|
props: {
|
|
3773
3948
|
editable: () => this.editor.options.editable
|
|
3774
3949
|
}
|
|
@@ -3778,14 +3953,14 @@ var Editable = Extension.create({
|
|
|
3778
3953
|
});
|
|
3779
3954
|
|
|
3780
3955
|
// src/extensions/focusEvents.ts
|
|
3781
|
-
var
|
|
3956
|
+
var import_state17 = require("@tiptap/pm/state");
|
|
3782
3957
|
var FocusEvents = Extension.create({
|
|
3783
3958
|
name: "focusEvents",
|
|
3784
3959
|
addProseMirrorPlugins() {
|
|
3785
3960
|
const { editor } = this;
|
|
3786
3961
|
return [
|
|
3787
|
-
new
|
|
3788
|
-
key: new
|
|
3962
|
+
new import_state17.Plugin({
|
|
3963
|
+
key: new import_state17.PluginKey("focusEvents"),
|
|
3789
3964
|
props: {
|
|
3790
3965
|
handleDOMEvents: {
|
|
3791
3966
|
focus: (view, event) => {
|
|
@@ -3808,7 +3983,7 @@ var FocusEvents = Extension.create({
|
|
|
3808
3983
|
});
|
|
3809
3984
|
|
|
3810
3985
|
// src/extensions/keymap.ts
|
|
3811
|
-
var
|
|
3986
|
+
var import_state18 = require("@tiptap/pm/state");
|
|
3812
3987
|
var Keymap = Extension.create({
|
|
3813
3988
|
name: "keymap",
|
|
3814
3989
|
addKeyboardShortcuts() {
|
|
@@ -3822,7 +3997,7 @@ var Keymap = Extension.create({
|
|
|
3822
3997
|
const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr.doc.resolve(pos - 1) : $anchor;
|
|
3823
3998
|
const parentIsIsolating = $parentPos.parent.type.spec.isolating;
|
|
3824
3999
|
const parentPos = $anchor.pos - $anchor.parentOffset;
|
|
3825
|
-
const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos :
|
|
4000
|
+
const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos : import_state18.Selection.atStart(doc).from === pos;
|
|
3826
4001
|
if (!empty || !parent.type.isTextblock || parent.textContent.length || !isAtStart || isAtStart && $anchor.parent.type.name === "paragraph") {
|
|
3827
4002
|
return false;
|
|
3828
4003
|
}
|
|
@@ -3880,21 +4055,22 @@ var Keymap = Extension.create({
|
|
|
3880
4055
|
// to a paragraph if necessary.
|
|
3881
4056
|
// This is an alternative to ProseMirror's `AllSelection`, which doesn’t work well
|
|
3882
4057
|
// with many other commands.
|
|
3883
|
-
new
|
|
3884
|
-
key: new
|
|
4058
|
+
new import_state18.Plugin({
|
|
4059
|
+
key: new import_state18.PluginKey("clearDocument"),
|
|
3885
4060
|
appendTransaction: (transactions, oldState, newState) => {
|
|
3886
4061
|
const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
|
|
3887
|
-
|
|
4062
|
+
const ignoreTr = transactions.some((transaction) => transaction.getMeta("preventClearDocument"));
|
|
4063
|
+
if (!docChanges || ignoreTr) {
|
|
3888
4064
|
return;
|
|
3889
4065
|
}
|
|
3890
4066
|
const { empty, from, to } = oldState.selection;
|
|
3891
|
-
const allFrom =
|
|
3892
|
-
const allEnd =
|
|
4067
|
+
const allFrom = import_state18.Selection.atStart(oldState.doc).from;
|
|
4068
|
+
const allEnd = import_state18.Selection.atEnd(oldState.doc).to;
|
|
3893
4069
|
const allWasSelected = from === allFrom && to === allEnd;
|
|
3894
4070
|
if (empty || !allWasSelected) {
|
|
3895
4071
|
return;
|
|
3896
4072
|
}
|
|
3897
|
-
const isEmpty =
|
|
4073
|
+
const isEmpty = isNodeEmpty(newState.doc);
|
|
3898
4074
|
if (!isEmpty) {
|
|
3899
4075
|
return;
|
|
3900
4076
|
}
|
|
@@ -3918,14 +4094,36 @@ var Keymap = Extension.create({
|
|
|
3918
4094
|
}
|
|
3919
4095
|
});
|
|
3920
4096
|
|
|
4097
|
+
// src/extensions/paste.ts
|
|
4098
|
+
var import_state19 = require("@tiptap/pm/state");
|
|
4099
|
+
var Paste = Extension.create({
|
|
4100
|
+
name: "paste",
|
|
4101
|
+
addProseMirrorPlugins() {
|
|
4102
|
+
return [
|
|
4103
|
+
new import_state19.Plugin({
|
|
4104
|
+
key: new import_state19.PluginKey("tiptapPaste"),
|
|
4105
|
+
props: {
|
|
4106
|
+
handlePaste: (_view, e, slice) => {
|
|
4107
|
+
this.editor.emit("paste", {
|
|
4108
|
+
editor: this.editor,
|
|
4109
|
+
event: e,
|
|
4110
|
+
slice
|
|
4111
|
+
});
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
})
|
|
4115
|
+
];
|
|
4116
|
+
}
|
|
4117
|
+
});
|
|
4118
|
+
|
|
3921
4119
|
// src/extensions/tabindex.ts
|
|
3922
|
-
var
|
|
4120
|
+
var import_state20 = require("@tiptap/pm/state");
|
|
3923
4121
|
var Tabindex = Extension.create({
|
|
3924
4122
|
name: "tabindex",
|
|
3925
4123
|
addProseMirrorPlugins() {
|
|
3926
4124
|
return [
|
|
3927
|
-
new
|
|
3928
|
-
key: new
|
|
4125
|
+
new import_state20.Plugin({
|
|
4126
|
+
key: new import_state20.PluginKey("tabindex"),
|
|
3929
4127
|
props: {
|
|
3930
4128
|
attributes: () => this.editor.isEditable ? { tabindex: "0" } : {}
|
|
3931
4129
|
}
|
|
@@ -4029,7 +4227,8 @@ var NodePos = class _NodePos {
|
|
|
4029
4227
|
const children = [];
|
|
4030
4228
|
this.node.content.forEach((node, offset) => {
|
|
4031
4229
|
const isBlock = node.isBlock && !node.isTextblock;
|
|
4032
|
-
const
|
|
4230
|
+
const isNonTextAtom = node.isAtom && !node.isText;
|
|
4231
|
+
const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1);
|
|
4033
4232
|
const $pos = this.resolvedPos.doc.resolve(targetPos);
|
|
4034
4233
|
if (!isBlock && $pos.depth <= this.depth) {
|
|
4035
4234
|
return;
|
|
@@ -4098,8 +4297,12 @@ var NodePos = class _NodePos {
|
|
|
4098
4297
|
return nodes;
|
|
4099
4298
|
}
|
|
4100
4299
|
setAttribute(attributes) {
|
|
4101
|
-
const
|
|
4102
|
-
|
|
4300
|
+
const { tr } = this.editor.state;
|
|
4301
|
+
tr.setNodeMarkup(this.from, void 0, {
|
|
4302
|
+
...this.node.attrs,
|
|
4303
|
+
...attributes
|
|
4304
|
+
});
|
|
4305
|
+
this.editor.view.dispatch(tr);
|
|
4103
4306
|
}
|
|
4104
4307
|
};
|
|
4105
4308
|
|
|
@@ -4202,6 +4405,10 @@ var Editor = class extends EventEmitter {
|
|
|
4202
4405
|
*/
|
|
4203
4406
|
this.isInitialized = false;
|
|
4204
4407
|
this.extensionStorage = {};
|
|
4408
|
+
/**
|
|
4409
|
+
* A unique ID for this editor instance.
|
|
4410
|
+
*/
|
|
4411
|
+
this.instanceId = Math.random().toString(36).slice(2, 9);
|
|
4205
4412
|
this.options = {
|
|
4206
4413
|
element: document.createElement("div"),
|
|
4207
4414
|
content: "",
|
|
@@ -4227,7 +4434,9 @@ var Editor = class extends EventEmitter {
|
|
|
4227
4434
|
onDestroy: () => null,
|
|
4228
4435
|
onContentError: ({ error }) => {
|
|
4229
4436
|
throw error;
|
|
4230
|
-
}
|
|
4437
|
+
},
|
|
4438
|
+
onPaste: () => null,
|
|
4439
|
+
onDrop: () => null
|
|
4231
4440
|
};
|
|
4232
4441
|
this.isCapturingTransaction = false;
|
|
4233
4442
|
this.capturedTransaction = null;
|
|
@@ -4247,6 +4456,8 @@ var Editor = class extends EventEmitter {
|
|
|
4247
4456
|
this.on("focus", this.options.onFocus);
|
|
4248
4457
|
this.on("blur", this.options.onBlur);
|
|
4249
4458
|
this.on("destroy", this.options.onDestroy);
|
|
4459
|
+
this.on("drop", ({ event, slice, moved }) => this.options.onDrop(event, slice, moved));
|
|
4460
|
+
this.on("paste", ({ event, slice }) => this.options.onPaste(event, slice));
|
|
4250
4461
|
window.setTimeout(() => {
|
|
4251
4462
|
if (this.isDestroyed) {
|
|
4252
4463
|
return;
|
|
@@ -4332,27 +4543,38 @@ var Editor = class extends EventEmitter {
|
|
|
4332
4543
|
*
|
|
4333
4544
|
* @param plugin A ProseMirror plugin
|
|
4334
4545
|
* @param handlePlugins Control how to merge the plugin into the existing plugins.
|
|
4546
|
+
* @returns The new editor state
|
|
4335
4547
|
*/
|
|
4336
4548
|
registerPlugin(plugin, handlePlugins) {
|
|
4337
4549
|
const plugins = isFunction(handlePlugins) ? handlePlugins(plugin, [...this.state.plugins]) : [...this.state.plugins, plugin];
|
|
4338
4550
|
const state = this.state.reconfigure({ plugins });
|
|
4339
4551
|
this.view.updateState(state);
|
|
4552
|
+
return state;
|
|
4340
4553
|
}
|
|
4341
4554
|
/**
|
|
4342
4555
|
* Unregister a ProseMirror plugin.
|
|
4343
4556
|
*
|
|
4344
|
-
* @param
|
|
4557
|
+
* @param nameOrPluginKeyToRemove The plugins name
|
|
4558
|
+
* @returns The new editor state or undefined if the editor is destroyed
|
|
4345
4559
|
*/
|
|
4346
|
-
unregisterPlugin(
|
|
4560
|
+
unregisterPlugin(nameOrPluginKeyToRemove) {
|
|
4347
4561
|
if (this.isDestroyed) {
|
|
4348
|
-
return;
|
|
4562
|
+
return void 0;
|
|
4563
|
+
}
|
|
4564
|
+
const prevPlugins = this.state.plugins;
|
|
4565
|
+
let plugins = prevPlugins;
|
|
4566
|
+
[].concat(nameOrPluginKeyToRemove).forEach((nameOrPluginKey) => {
|
|
4567
|
+
const name = typeof nameOrPluginKey === "string" ? `${nameOrPluginKey}$` : nameOrPluginKey.key;
|
|
4568
|
+
plugins = prevPlugins.filter((plugin) => !plugin.key.startsWith(name));
|
|
4569
|
+
});
|
|
4570
|
+
if (prevPlugins.length === plugins.length) {
|
|
4571
|
+
return void 0;
|
|
4349
4572
|
}
|
|
4350
|
-
const name = typeof nameOrPluginKey === "string" ? `${nameOrPluginKey}$` : nameOrPluginKey.key;
|
|
4351
4573
|
const state = this.state.reconfigure({
|
|
4352
|
-
|
|
4353
|
-
plugins: this.state.plugins.filter((plugin) => !plugin.key.startsWith(name))
|
|
4574
|
+
plugins
|
|
4354
4575
|
});
|
|
4355
4576
|
this.view.updateState(state);
|
|
4577
|
+
return state;
|
|
4356
4578
|
}
|
|
4357
4579
|
/**
|
|
4358
4580
|
* Creates an extension manager.
|
|
@@ -4367,8 +4589,15 @@ var Editor = class extends EventEmitter {
|
|
|
4367
4589
|
Commands,
|
|
4368
4590
|
FocusEvents,
|
|
4369
4591
|
Keymap,
|
|
4370
|
-
Tabindex
|
|
4371
|
-
|
|
4592
|
+
Tabindex,
|
|
4593
|
+
Drop,
|
|
4594
|
+
Paste
|
|
4595
|
+
].filter((ext) => {
|
|
4596
|
+
if (typeof this.options.enableCoreExtensions === "object") {
|
|
4597
|
+
return this.options.enableCoreExtensions[ext.name] !== false;
|
|
4598
|
+
}
|
|
4599
|
+
return true;
|
|
4600
|
+
}) : [];
|
|
4372
4601
|
const allExtensions = [...coreExtensions, ...this.options.extensions].filter((extension) => {
|
|
4373
4602
|
return ["extension", "node", "mark"].includes(extension == null ? void 0 : extension.type);
|
|
4374
4603
|
});
|
|
@@ -4392,6 +4621,7 @@ var Editor = class extends EventEmitter {
|
|
|
4392
4621
|
* Creates a ProseMirror view.
|
|
4393
4622
|
*/
|
|
4394
4623
|
createView() {
|
|
4624
|
+
var _a;
|
|
4395
4625
|
let doc;
|
|
4396
4626
|
try {
|
|
4397
4627
|
doc = createDocument(
|
|
@@ -4408,6 +4638,9 @@ var Editor = class extends EventEmitter {
|
|
|
4408
4638
|
editor: this,
|
|
4409
4639
|
error: e,
|
|
4410
4640
|
disableCollaboration: () => {
|
|
4641
|
+
if (this.storage.collaboration) {
|
|
4642
|
+
this.storage.collaboration.isDisabled = true;
|
|
4643
|
+
}
|
|
4411
4644
|
this.options.extensions = this.options.extensions.filter((extension) => extension.name !== "collaboration");
|
|
4412
4645
|
this.createExtensionManager();
|
|
4413
4646
|
}
|
|
@@ -4422,8 +4655,13 @@ var Editor = class extends EventEmitter {
|
|
|
4422
4655
|
const selection = resolveFocusPosition(doc, this.options.autofocus);
|
|
4423
4656
|
this.view = new import_view.EditorView(this.options.element, {
|
|
4424
4657
|
...this.options.editorProps,
|
|
4658
|
+
attributes: {
|
|
4659
|
+
// add `role="textbox"` to the editor element
|
|
4660
|
+
role: "textbox",
|
|
4661
|
+
...(_a = this.options.editorProps) == null ? void 0 : _a.attributes
|
|
4662
|
+
},
|
|
4425
4663
|
dispatchTransaction: this.dispatchTransaction.bind(this),
|
|
4426
|
-
state:
|
|
4664
|
+
state: import_state21.EditorState.create({
|
|
4427
4665
|
doc,
|
|
4428
4666
|
selection: selection || void 0
|
|
4429
4667
|
})
|
|
@@ -4583,6 +4821,10 @@ var Editor = class extends EventEmitter {
|
|
|
4583
4821
|
destroy() {
|
|
4584
4822
|
this.emit("destroy");
|
|
4585
4823
|
if (this.view) {
|
|
4824
|
+
const dom = this.view.dom;
|
|
4825
|
+
if (dom && dom.editor) {
|
|
4826
|
+
delete dom.editor;
|
|
4827
|
+
}
|
|
4586
4828
|
this.view.destroy();
|
|
4587
4829
|
}
|
|
4588
4830
|
this.removeAllListeners();
|
|
@@ -4836,7 +5078,7 @@ var Node3 = class _Node {
|
|
|
4836
5078
|
};
|
|
4837
5079
|
|
|
4838
5080
|
// src/NodeView.ts
|
|
4839
|
-
var
|
|
5081
|
+
var import_state22 = require("@tiptap/pm/state");
|
|
4840
5082
|
|
|
4841
5083
|
// src/utilities/isAndroid.ts
|
|
4842
5084
|
function isAndroid() {
|
|
@@ -4857,6 +5099,9 @@ var NodeView = class {
|
|
|
4857
5099
|
this.extension = props.extension;
|
|
4858
5100
|
this.node = props.node;
|
|
4859
5101
|
this.decorations = props.decorations;
|
|
5102
|
+
this.innerDecorations = props.innerDecorations;
|
|
5103
|
+
this.view = props.view;
|
|
5104
|
+
this.HTMLAttributes = props.HTMLAttributes;
|
|
4860
5105
|
this.getPos = props.getPos;
|
|
4861
5106
|
this.mount();
|
|
4862
5107
|
}
|
|
@@ -4888,7 +5133,11 @@ var NodeView = class {
|
|
|
4888
5133
|
y = handleBox.y - domBox.y + offsetY;
|
|
4889
5134
|
}
|
|
4890
5135
|
(_g = event.dataTransfer) == null ? void 0 : _g.setDragImage(this.dom, x, y);
|
|
4891
|
-
const
|
|
5136
|
+
const pos = this.getPos();
|
|
5137
|
+
if (typeof pos !== "number") {
|
|
5138
|
+
return;
|
|
5139
|
+
}
|
|
5140
|
+
const selection = import_state22.NodeSelection.create(view.state.doc, pos);
|
|
4892
5141
|
const transaction = view.state.tr.setSelection(selection);
|
|
4893
5142
|
view.dispatch(transaction);
|
|
4894
5143
|
}
|
|
@@ -4914,15 +5163,15 @@ var NodeView = class {
|
|
|
4914
5163
|
const { isEditable } = this.editor;
|
|
4915
5164
|
const { isDragging } = this;
|
|
4916
5165
|
const isDraggable = !!this.node.type.spec.draggable;
|
|
4917
|
-
const isSelectable =
|
|
5166
|
+
const isSelectable = import_state22.NodeSelection.isSelectable(this.node);
|
|
4918
5167
|
const isCopyEvent = event.type === "copy";
|
|
4919
5168
|
const isPasteEvent = event.type === "paste";
|
|
4920
5169
|
const isCutEvent = event.type === "cut";
|
|
4921
5170
|
const isClickEvent = event.type === "mousedown";
|
|
4922
|
-
if (!isDraggable && isSelectable && isDragEvent) {
|
|
5171
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
4923
5172
|
event.preventDefault();
|
|
4924
5173
|
}
|
|
4925
|
-
if (isDraggable && isDragEvent && !isDragging) {
|
|
5174
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
4926
5175
|
event.preventDefault();
|
|
4927
5176
|
return false;
|
|
4928
5177
|
}
|
|
@@ -4959,6 +5208,11 @@ var NodeView = class {
|
|
|
4959
5208
|
}
|
|
4960
5209
|
return true;
|
|
4961
5210
|
}
|
|
5211
|
+
/**
|
|
5212
|
+
* Called when a DOM [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) or a selection change happens within the view.
|
|
5213
|
+
* @return `false` if the editor should re-read the selection or re-parse the range around the mutation
|
|
5214
|
+
* @return `true` if it can safely be ignored.
|
|
5215
|
+
*/
|
|
4962
5216
|
ignoreMutation(mutation) {
|
|
4963
5217
|
if (!this.dom || !this.contentDOM) {
|
|
4964
5218
|
return true;
|
|
@@ -4989,9 +5243,15 @@ var NodeView = class {
|
|
|
4989
5243
|
}
|
|
4990
5244
|
return true;
|
|
4991
5245
|
}
|
|
5246
|
+
/**
|
|
5247
|
+
* Update the attributes of the prosemirror node.
|
|
5248
|
+
*/
|
|
4992
5249
|
updateAttributes(attributes) {
|
|
4993
5250
|
this.editor.commands.command(({ tr }) => {
|
|
4994
5251
|
const pos = this.getPos();
|
|
5252
|
+
if (typeof pos !== "number") {
|
|
5253
|
+
return false;
|
|
5254
|
+
}
|
|
4995
5255
|
tr.setNodeMarkup(pos, void 0, {
|
|
4996
5256
|
...this.node.attrs,
|
|
4997
5257
|
...attributes
|
|
@@ -4999,8 +5259,14 @@ var NodeView = class {
|
|
|
4999
5259
|
return true;
|
|
5000
5260
|
});
|
|
5001
5261
|
}
|
|
5262
|
+
/**
|
|
5263
|
+
* Delete the node.
|
|
5264
|
+
*/
|
|
5002
5265
|
deleteNode() {
|
|
5003
5266
|
const from = this.getPos();
|
|
5267
|
+
if (typeof from !== "number") {
|
|
5268
|
+
return;
|
|
5269
|
+
}
|
|
5004
5270
|
const to = from + this.node.nodeSize;
|
|
5005
5271
|
this.editor.commands.deleteRange({ from, to });
|
|
5006
5272
|
}
|