@tiptap/core 2.1.4 → 2.2.0-rc.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.umd.js CHANGED
@@ -2009,261 +2009,6 @@
2009
2009
  return { ...mark.attrs };
2010
2010
  }
2011
2011
 
2012
- const findListItemPos = (typeOrName, state) => {
2013
- const { $from } = state.selection;
2014
- const nodeType = getNodeType(typeOrName, state.schema);
2015
- let currentNode = null;
2016
- let currentDepth = $from.depth;
2017
- let currentPos = $from.pos;
2018
- let targetDepth = null;
2019
- while (currentDepth > 0 && targetDepth === null) {
2020
- currentNode = $from.node(currentDepth);
2021
- if (currentNode.type === nodeType) {
2022
- targetDepth = currentDepth;
2023
- }
2024
- else {
2025
- currentDepth -= 1;
2026
- currentPos -= 1;
2027
- }
2028
- }
2029
- if (targetDepth === null) {
2030
- return null;
2031
- }
2032
- return { $pos: state.doc.resolve(currentPos), depth: targetDepth };
2033
- };
2034
-
2035
- /**
2036
- * Finds the first node of a given type or name in the current selection.
2037
- * @param state The editor state.
2038
- * @param typeOrName The node type or name.
2039
- * @param pos The position to start searching from.
2040
- * @param maxDepth The maximum depth to search.
2041
- * @returns The node and the depth as an array.
2042
- */
2043
- const getNodeAtPosition = (state, typeOrName, pos, maxDepth = 20) => {
2044
- const $pos = state.doc.resolve(pos);
2045
- let currentDepth = maxDepth;
2046
- let node = null;
2047
- while (currentDepth > 0 && node === null) {
2048
- const currentNode = $pos.node(currentDepth);
2049
- if ((currentNode === null || currentNode === void 0 ? void 0 : currentNode.type.name) === typeOrName) {
2050
- node = currentNode;
2051
- }
2052
- else {
2053
- currentDepth -= 1;
2054
- }
2055
- }
2056
- return [node, currentDepth];
2057
- };
2058
-
2059
- const getNextListDepth = (typeOrName, state) => {
2060
- const listItemPos = findListItemPos(typeOrName, state);
2061
- if (!listItemPos) {
2062
- return false;
2063
- }
2064
- const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4);
2065
- return depth;
2066
- };
2067
-
2068
- const isAtStartOfNode = (state) => {
2069
- const { $from, $to } = state.selection;
2070
- if ($from.parentOffset > 0 || $from.pos !== $to.pos) {
2071
- return false;
2072
- }
2073
- return true;
2074
- };
2075
-
2076
- const hasListBefore = (editorState, name, parentListTypes) => {
2077
- const { $anchor } = editorState.selection;
2078
- const previousNodePos = Math.max(0, $anchor.pos - 2);
2079
- const previousNode = editorState.doc.resolve(previousNodePos).node();
2080
- if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {
2081
- return false;
2082
- }
2083
- return true;
2084
- };
2085
-
2086
- const hasListItemBefore = (typeOrName, state) => {
2087
- var _a;
2088
- const { $anchor } = state.selection;
2089
- const $targetPos = state.doc.resolve($anchor.pos - 2);
2090
- if ($targetPos.index() === 0) {
2091
- return false;
2092
- }
2093
- if (((_a = $targetPos.nodeBefore) === null || _a === void 0 ? void 0 : _a.type.name) !== typeOrName) {
2094
- return false;
2095
- }
2096
- return true;
2097
- };
2098
-
2099
- const listItemHasSubList = (typeOrName, state, node) => {
2100
- if (!node) {
2101
- return false;
2102
- }
2103
- const nodeType = getNodeType(typeOrName, state.schema);
2104
- let hasSubList = false;
2105
- node.descendants(child => {
2106
- if (child.type === nodeType) {
2107
- hasSubList = true;
2108
- }
2109
- });
2110
- return hasSubList;
2111
- };
2112
-
2113
- const handleBackspace = (editor, name, parentListTypes) => {
2114
- // this is required to still handle the undo handling
2115
- if (editor.commands.undoInputRule()) {
2116
- return true;
2117
- }
2118
- // if the current item is NOT inside a list item &
2119
- // the previous item is a list (orderedList or bulletList)
2120
- // move the cursor into the list and delete the current item
2121
- if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
2122
- const { $anchor } = editor.state.selection;
2123
- const $listPos = editor.state.doc.resolve($anchor.before() - 1);
2124
- const listDescendants = [];
2125
- $listPos.node().descendants((node, pos) => {
2126
- if (node.type.name === name) {
2127
- listDescendants.push({ node, pos });
2128
- }
2129
- });
2130
- const lastItem = listDescendants.at(-1);
2131
- if (!lastItem) {
2132
- return false;
2133
- }
2134
- const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
2135
- return editor.chain().cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end()).joinForward().run();
2136
- }
2137
- // if the cursor is not inside the current node type
2138
- // do nothing and proceed
2139
- if (!isNodeActive(editor.state, name)) {
2140
- return false;
2141
- }
2142
- // if the cursor is not at the start of a node
2143
- // do nothing and proceed
2144
- if (!isAtStartOfNode(editor.state)) {
2145
- return false;
2146
- }
2147
- const listItemPos = findListItemPos(name, editor.state);
2148
- if (!listItemPos) {
2149
- return false;
2150
- }
2151
- const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
2152
- const prevNode = $prev.node(listItemPos.depth);
2153
- const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
2154
- // if the previous item is a list item and doesn't have a sublist, join the list items
2155
- if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
2156
- return editor.commands.joinItemBackward();
2157
- }
2158
- // otherwise in the end, a backspace should
2159
- // always just lift the list item if
2160
- // joining / merging is not possible
2161
- return editor.chain().liftListItem(name).run();
2162
- };
2163
-
2164
- function findParentNodeClosestToPos($pos, predicate) {
2165
- for (let i = $pos.depth; i > 0; i -= 1) {
2166
- const node = $pos.node(i);
2167
- if (predicate(node)) {
2168
- return {
2169
- pos: i > 0 ? $pos.before(i) : 0,
2170
- start: $pos.start(i),
2171
- depth: i,
2172
- node,
2173
- };
2174
- }
2175
- }
2176
- }
2177
-
2178
- function findParentNode(predicate) {
2179
- return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
2180
- }
2181
-
2182
- const isAtEndOfNode = (state, nodeType) => {
2183
- const { $from, $to, $anchor } = state.selection;
2184
- if (nodeType) {
2185
- const parentNode = findParentNode(node => node.type.name === nodeType)(state.selection);
2186
- if (!parentNode) {
2187
- return false;
2188
- }
2189
- const $parentPos = state.doc.resolve(parentNode.pos + 1);
2190
- if ($anchor.pos + 1 === $parentPos.end()) {
2191
- return true;
2192
- }
2193
- return false;
2194
- }
2195
- if ($to.parentOffset < $to.parent.nodeSize - 2 || $from.pos !== $to.pos) {
2196
- return false;
2197
- }
2198
- return true;
2199
- };
2200
-
2201
- const nextListIsDeeper = (typeOrName, state) => {
2202
- const listDepth = getNextListDepth(typeOrName, state);
2203
- const listItemPos = findListItemPos(typeOrName, state);
2204
- if (!listItemPos || !listDepth) {
2205
- return false;
2206
- }
2207
- if (listDepth > listItemPos.depth) {
2208
- return true;
2209
- }
2210
- return false;
2211
- };
2212
-
2213
- const nextListIsHigher = (typeOrName, state) => {
2214
- const listDepth = getNextListDepth(typeOrName, state);
2215
- const listItemPos = findListItemPos(typeOrName, state);
2216
- if (!listItemPos || !listDepth) {
2217
- return false;
2218
- }
2219
- if (listDepth < listItemPos.depth) {
2220
- return true;
2221
- }
2222
- return false;
2223
- };
2224
-
2225
- const handleDelete = (editor, name) => {
2226
- // if the cursor is not inside the current node type
2227
- // do nothing and proceed
2228
- if (!isNodeActive(editor.state, name)) {
2229
- return false;
2230
- }
2231
- // if the cursor is not at the end of a node
2232
- // do nothing and proceed
2233
- if (!isAtEndOfNode(editor.state, name)) {
2234
- return false;
2235
- }
2236
- // check if the next node is a list with a deeper depth
2237
- if (nextListIsDeeper(name, editor.state)) {
2238
- return editor
2239
- .chain()
2240
- .focus(editor.state.selection.from + 4)
2241
- .lift(name)
2242
- .joinBackward()
2243
- .run();
2244
- }
2245
- if (nextListIsHigher(name, editor.state)) {
2246
- return editor.chain()
2247
- .joinForward()
2248
- .joinBackward()
2249
- .run();
2250
- }
2251
- return editor.commands.joinItemForward();
2252
- };
2253
-
2254
- const hasListItemAfter = (typeOrName, state) => {
2255
- var _a;
2256
- const { $anchor } = state.selection;
2257
- const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2);
2258
- if ($targetPos.index() === $targetPos.parent.childCount - 1) {
2259
- return false;
2260
- }
2261
- if (((_a = $targetPos.nodeAfter) === null || _a === void 0 ? void 0 : _a.type.name) !== typeOrName) {
2262
- return false;
2263
- }
2264
- return true;
2265
- };
2266
-
2267
2012
  /**
2268
2013
  * Returns a new `Transform` based on all steps of the passed transactions.
2269
2014
  */
@@ -2325,6 +2070,24 @@
2325
2070
  return nodesWithPos;
2326
2071
  }
2327
2072
 
2073
+ function findParentNodeClosestToPos($pos, predicate) {
2074
+ for (let i = $pos.depth; i > 0; i -= 1) {
2075
+ const node = $pos.node(i);
2076
+ if (predicate(node)) {
2077
+ return {
2078
+ pos: i > 0 ? $pos.before(i) : 0,
2079
+ start: $pos.start(i),
2080
+ depth: i,
2081
+ node,
2082
+ };
2083
+ }
2084
+ }
2085
+ }
2086
+
2087
+ function findParentNode(predicate) {
2088
+ return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
2089
+ }
2090
+
2328
2091
  function getHTMLFromFragment(fragment, schema) {
2329
2092
  const documentFragment = model.DOMSerializer.fromSchema(schema).serializeFragment(fragment);
2330
2093
  const temporaryDocument = document.implementation.createHTMLDocument();
@@ -2542,6 +2305,30 @@
2542
2305
  return marks;
2543
2306
  }
2544
2307
 
2308
+ /**
2309
+ * Finds the first node of a given type or name in the current selection.
2310
+ * @param state The editor state.
2311
+ * @param typeOrName The node type or name.
2312
+ * @param pos The position to start searching from.
2313
+ * @param maxDepth The maximum depth to search.
2314
+ * @returns The node and the depth as an array.
2315
+ */
2316
+ const getNodeAtPosition = (state, typeOrName, pos, maxDepth = 20) => {
2317
+ const $pos = state.doc.resolve(pos);
2318
+ let currentDepth = maxDepth;
2319
+ let node = null;
2320
+ while (currentDepth > 0 && node === null) {
2321
+ const currentNode = $pos.node(currentDepth);
2322
+ if ((currentNode === null || currentNode === void 0 ? void 0 : currentNode.type.name) === typeOrName) {
2323
+ node = currentNode;
2324
+ }
2325
+ else {
2326
+ currentDepth -= 1;
2327
+ }
2328
+ }
2329
+ return [node, currentDepth];
2330
+ };
2331
+
2545
2332
  function getSplittedAttributes(extensionAttributes, typeName, attributes) {
2546
2333
  return Object.fromEntries(Object
2547
2334
  .entries(attributes)
@@ -2632,6 +2419,33 @@
2632
2419
  return false;
2633
2420
  }
2634
2421
 
2422
+ const isAtEndOfNode = (state, nodeType) => {
2423
+ const { $from, $to, $anchor } = state.selection;
2424
+ if (nodeType) {
2425
+ const parentNode = findParentNode(node => node.type.name === nodeType)(state.selection);
2426
+ if (!parentNode) {
2427
+ return false;
2428
+ }
2429
+ const $parentPos = state.doc.resolve(parentNode.pos + 1);
2430
+ if ($anchor.pos + 1 === $parentPos.end()) {
2431
+ return true;
2432
+ }
2433
+ return false;
2434
+ }
2435
+ if ($to.parentOffset < $to.parent.nodeSize - 2 || $from.pos !== $to.pos) {
2436
+ return false;
2437
+ }
2438
+ return true;
2439
+ };
2440
+
2441
+ const isAtStartOfNode = (state) => {
2442
+ const { $from, $to } = state.selection;
2443
+ if ($from.parentOffset > 0 || $from.pos !== $to.pos) {
2444
+ return false;
2445
+ }
2446
+ return true;
2447
+ };
2448
+
2635
2449
  function isList(name, extensions) {
2636
2450
  const { nodeExtensions } = splitExtensions(extensions);
2637
2451
  const extension = nodeExtensions.find(item => item.name === name);
@@ -4593,7 +4407,6 @@ img.ProseMirror-separator {
4593
4407
  exports.findChildren = findChildren;
4594
4408
  exports.findChildrenInRange = findChildrenInRange;
4595
4409
  exports.findDuplicates = findDuplicates;
4596
- exports.findListItemPos = findListItemPos;
4597
4410
  exports.findParentNode = findParentNode;
4598
4411
  exports.findParentNodeClosestToPos = findParentNodeClosestToPos;
4599
4412
  exports.fromString = fromString;
@@ -4610,7 +4423,6 @@ img.ProseMirror-separator {
4610
4423
  exports.getMarkRange = getMarkRange;
4611
4424
  exports.getMarkType = getMarkType;
4612
4425
  exports.getMarksBetween = getMarksBetween;
4613
- exports.getNextListDepth = getNextListDepth;
4614
4426
  exports.getNodeAtPosition = getNodeAtPosition;
4615
4427
  exports.getNodeAttributes = getNodeAttributes;
4616
4428
  exports.getNodeType = getNodeType;
@@ -4624,11 +4436,6 @@ img.ProseMirror-separator {
4624
4436
  exports.getTextBetween = getTextBetween;
4625
4437
  exports.getTextContentFromNodes = getTextContentFromNodes;
4626
4438
  exports.getTextSerializersFromSchema = getTextSerializersFromSchema;
4627
- exports.handleBackspace = handleBackspace;
4628
- exports.handleDelete = handleDelete;
4629
- exports.hasListBefore = hasListBefore;
4630
- exports.hasListItemAfter = hasListItemAfter;
4631
- exports.hasListItemBefore = hasListItemBefore;
4632
4439
  exports.injectExtensionAttributesToParseRule = injectExtensionAttributesToParseRule;
4633
4440
  exports.inputRulesPlugin = inputRulesPlugin;
4634
4441
  exports.isActive = isActive;
@@ -4649,14 +4456,11 @@ img.ProseMirror-separator {
4649
4456
  exports.isString = isString;
4650
4457
  exports.isTextSelection = isTextSelection;
4651
4458
  exports.isiOS = isiOS;
4652
- exports.listItemHasSubList = listItemHasSubList;
4653
4459
  exports.markInputRule = markInputRule;
4654
4460
  exports.markPasteRule = markPasteRule;
4655
4461
  exports.mergeAttributes = mergeAttributes;
4656
4462
  exports.mergeDeep = mergeDeep;
4657
4463
  exports.minMax = minMax;
4658
- exports.nextListIsDeeper = nextListIsDeeper;
4659
- exports.nextListIsHigher = nextListIsHigher;
4660
4464
  exports.nodeInputRule = nodeInputRule;
4661
4465
  exports.nodePasteRule = nodePasteRule;
4662
4466
  exports.objectIncludes = objectIncludes;