@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.cjs +69 -265
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +70 -256
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +69 -265
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/helpers/index.d.ts +0 -1
- package/dist/packages/core/src/types.d.ts +1 -0
- package/package.json +2 -2
- package/src/helpers/index.ts +0 -1
- package/src/types.ts +1 -0
- package/dist/packages/extension-list-keymap/src/listHelpers/findListItemPos.d.ts +0 -6
- package/dist/packages/extension-list-keymap/src/listHelpers/getNextListDepth.d.ts +0 -2
- package/dist/packages/extension-list-keymap/src/listHelpers/handleBackspace.d.ts +0 -2
- package/dist/packages/extension-list-keymap/src/listHelpers/handleDelete.d.ts +0 -2
- package/dist/packages/extension-list-keymap/src/listHelpers/hasListBefore.d.ts +0 -2
- package/dist/packages/extension-list-keymap/src/listHelpers/hasListItemAfter.d.ts +0 -2
- package/dist/packages/extension-list-keymap/src/listHelpers/hasListItemBefore.d.ts +0 -2
- package/dist/packages/extension-list-keymap/src/listHelpers/index.d.ts +0 -10
- package/dist/packages/extension-list-keymap/src/listHelpers/listItemHasSubList.d.ts +0 -3
- package/dist/packages/extension-list-keymap/src/listHelpers/nextListIsDeeper.d.ts +0 -2
- package/dist/packages/extension-list-keymap/src/listHelpers/nextListIsHigher.d.ts +0 -2
package/dist/index.js
CHANGED
|
@@ -2011,261 +2011,6 @@ function getMarkAttributes(state, typeOrName) {
|
|
|
2011
2011
|
return { ...mark.attrs };
|
|
2012
2012
|
}
|
|
2013
2013
|
|
|
2014
|
-
const findListItemPos = (typeOrName, state) => {
|
|
2015
|
-
const { $from } = state.selection;
|
|
2016
|
-
const nodeType = getNodeType(typeOrName, state.schema);
|
|
2017
|
-
let currentNode = null;
|
|
2018
|
-
let currentDepth = $from.depth;
|
|
2019
|
-
let currentPos = $from.pos;
|
|
2020
|
-
let targetDepth = null;
|
|
2021
|
-
while (currentDepth > 0 && targetDepth === null) {
|
|
2022
|
-
currentNode = $from.node(currentDepth);
|
|
2023
|
-
if (currentNode.type === nodeType) {
|
|
2024
|
-
targetDepth = currentDepth;
|
|
2025
|
-
}
|
|
2026
|
-
else {
|
|
2027
|
-
currentDepth -= 1;
|
|
2028
|
-
currentPos -= 1;
|
|
2029
|
-
}
|
|
2030
|
-
}
|
|
2031
|
-
if (targetDepth === null) {
|
|
2032
|
-
return null;
|
|
2033
|
-
}
|
|
2034
|
-
return { $pos: state.doc.resolve(currentPos), depth: targetDepth };
|
|
2035
|
-
};
|
|
2036
|
-
|
|
2037
|
-
/**
|
|
2038
|
-
* Finds the first node of a given type or name in the current selection.
|
|
2039
|
-
* @param state The editor state.
|
|
2040
|
-
* @param typeOrName The node type or name.
|
|
2041
|
-
* @param pos The position to start searching from.
|
|
2042
|
-
* @param maxDepth The maximum depth to search.
|
|
2043
|
-
* @returns The node and the depth as an array.
|
|
2044
|
-
*/
|
|
2045
|
-
const getNodeAtPosition = (state, typeOrName, pos, maxDepth = 20) => {
|
|
2046
|
-
const $pos = state.doc.resolve(pos);
|
|
2047
|
-
let currentDepth = maxDepth;
|
|
2048
|
-
let node = null;
|
|
2049
|
-
while (currentDepth > 0 && node === null) {
|
|
2050
|
-
const currentNode = $pos.node(currentDepth);
|
|
2051
|
-
if ((currentNode === null || currentNode === void 0 ? void 0 : currentNode.type.name) === typeOrName) {
|
|
2052
|
-
node = currentNode;
|
|
2053
|
-
}
|
|
2054
|
-
else {
|
|
2055
|
-
currentDepth -= 1;
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
return [node, currentDepth];
|
|
2059
|
-
};
|
|
2060
|
-
|
|
2061
|
-
const getNextListDepth = (typeOrName, state) => {
|
|
2062
|
-
const listItemPos = findListItemPos(typeOrName, state);
|
|
2063
|
-
if (!listItemPos) {
|
|
2064
|
-
return false;
|
|
2065
|
-
}
|
|
2066
|
-
const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4);
|
|
2067
|
-
return depth;
|
|
2068
|
-
};
|
|
2069
|
-
|
|
2070
|
-
const isAtStartOfNode = (state) => {
|
|
2071
|
-
const { $from, $to } = state.selection;
|
|
2072
|
-
if ($from.parentOffset > 0 || $from.pos !== $to.pos) {
|
|
2073
|
-
return false;
|
|
2074
|
-
}
|
|
2075
|
-
return true;
|
|
2076
|
-
};
|
|
2077
|
-
|
|
2078
|
-
const hasListBefore = (editorState, name, parentListTypes) => {
|
|
2079
|
-
const { $anchor } = editorState.selection;
|
|
2080
|
-
const previousNodePos = Math.max(0, $anchor.pos - 2);
|
|
2081
|
-
const previousNode = editorState.doc.resolve(previousNodePos).node();
|
|
2082
|
-
if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {
|
|
2083
|
-
return false;
|
|
2084
|
-
}
|
|
2085
|
-
return true;
|
|
2086
|
-
};
|
|
2087
|
-
|
|
2088
|
-
const hasListItemBefore = (typeOrName, state) => {
|
|
2089
|
-
var _a;
|
|
2090
|
-
const { $anchor } = state.selection;
|
|
2091
|
-
const $targetPos = state.doc.resolve($anchor.pos - 2);
|
|
2092
|
-
if ($targetPos.index() === 0) {
|
|
2093
|
-
return false;
|
|
2094
|
-
}
|
|
2095
|
-
if (((_a = $targetPos.nodeBefore) === null || _a === void 0 ? void 0 : _a.type.name) !== typeOrName) {
|
|
2096
|
-
return false;
|
|
2097
|
-
}
|
|
2098
|
-
return true;
|
|
2099
|
-
};
|
|
2100
|
-
|
|
2101
|
-
const listItemHasSubList = (typeOrName, state, node) => {
|
|
2102
|
-
if (!node) {
|
|
2103
|
-
return false;
|
|
2104
|
-
}
|
|
2105
|
-
const nodeType = getNodeType(typeOrName, state.schema);
|
|
2106
|
-
let hasSubList = false;
|
|
2107
|
-
node.descendants(child => {
|
|
2108
|
-
if (child.type === nodeType) {
|
|
2109
|
-
hasSubList = true;
|
|
2110
|
-
}
|
|
2111
|
-
});
|
|
2112
|
-
return hasSubList;
|
|
2113
|
-
};
|
|
2114
|
-
|
|
2115
|
-
const handleBackspace = (editor, name, parentListTypes) => {
|
|
2116
|
-
// this is required to still handle the undo handling
|
|
2117
|
-
if (editor.commands.undoInputRule()) {
|
|
2118
|
-
return true;
|
|
2119
|
-
}
|
|
2120
|
-
// if the current item is NOT inside a list item &
|
|
2121
|
-
// the previous item is a list (orderedList or bulletList)
|
|
2122
|
-
// move the cursor into the list and delete the current item
|
|
2123
|
-
if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
|
|
2124
|
-
const { $anchor } = editor.state.selection;
|
|
2125
|
-
const $listPos = editor.state.doc.resolve($anchor.before() - 1);
|
|
2126
|
-
const listDescendants = [];
|
|
2127
|
-
$listPos.node().descendants((node, pos) => {
|
|
2128
|
-
if (node.type.name === name) {
|
|
2129
|
-
listDescendants.push({ node, pos });
|
|
2130
|
-
}
|
|
2131
|
-
});
|
|
2132
|
-
const lastItem = listDescendants.at(-1);
|
|
2133
|
-
if (!lastItem) {
|
|
2134
|
-
return false;
|
|
2135
|
-
}
|
|
2136
|
-
const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
|
|
2137
|
-
return editor.chain().cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end()).joinForward().run();
|
|
2138
|
-
}
|
|
2139
|
-
// if the cursor is not inside the current node type
|
|
2140
|
-
// do nothing and proceed
|
|
2141
|
-
if (!isNodeActive(editor.state, name)) {
|
|
2142
|
-
return false;
|
|
2143
|
-
}
|
|
2144
|
-
// if the cursor is not at the start of a node
|
|
2145
|
-
// do nothing and proceed
|
|
2146
|
-
if (!isAtStartOfNode(editor.state)) {
|
|
2147
|
-
return false;
|
|
2148
|
-
}
|
|
2149
|
-
const listItemPos = findListItemPos(name, editor.state);
|
|
2150
|
-
if (!listItemPos) {
|
|
2151
|
-
return false;
|
|
2152
|
-
}
|
|
2153
|
-
const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
|
|
2154
|
-
const prevNode = $prev.node(listItemPos.depth);
|
|
2155
|
-
const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
|
|
2156
|
-
// if the previous item is a list item and doesn't have a sublist, join the list items
|
|
2157
|
-
if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
|
|
2158
|
-
return editor.commands.joinItemBackward();
|
|
2159
|
-
}
|
|
2160
|
-
// otherwise in the end, a backspace should
|
|
2161
|
-
// always just lift the list item if
|
|
2162
|
-
// joining / merging is not possible
|
|
2163
|
-
return editor.chain().liftListItem(name).run();
|
|
2164
|
-
};
|
|
2165
|
-
|
|
2166
|
-
function findParentNodeClosestToPos($pos, predicate) {
|
|
2167
|
-
for (let i = $pos.depth; i > 0; i -= 1) {
|
|
2168
|
-
const node = $pos.node(i);
|
|
2169
|
-
if (predicate(node)) {
|
|
2170
|
-
return {
|
|
2171
|
-
pos: i > 0 ? $pos.before(i) : 0,
|
|
2172
|
-
start: $pos.start(i),
|
|
2173
|
-
depth: i,
|
|
2174
|
-
node,
|
|
2175
|
-
};
|
|
2176
|
-
}
|
|
2177
|
-
}
|
|
2178
|
-
}
|
|
2179
|
-
|
|
2180
|
-
function findParentNode(predicate) {
|
|
2181
|
-
return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
|
|
2182
|
-
}
|
|
2183
|
-
|
|
2184
|
-
const isAtEndOfNode = (state, nodeType) => {
|
|
2185
|
-
const { $from, $to, $anchor } = state.selection;
|
|
2186
|
-
if (nodeType) {
|
|
2187
|
-
const parentNode = findParentNode(node => node.type.name === nodeType)(state.selection);
|
|
2188
|
-
if (!parentNode) {
|
|
2189
|
-
return false;
|
|
2190
|
-
}
|
|
2191
|
-
const $parentPos = state.doc.resolve(parentNode.pos + 1);
|
|
2192
|
-
if ($anchor.pos + 1 === $parentPos.end()) {
|
|
2193
|
-
return true;
|
|
2194
|
-
}
|
|
2195
|
-
return false;
|
|
2196
|
-
}
|
|
2197
|
-
if ($to.parentOffset < $to.parent.nodeSize - 2 || $from.pos !== $to.pos) {
|
|
2198
|
-
return false;
|
|
2199
|
-
}
|
|
2200
|
-
return true;
|
|
2201
|
-
};
|
|
2202
|
-
|
|
2203
|
-
const nextListIsDeeper = (typeOrName, state) => {
|
|
2204
|
-
const listDepth = getNextListDepth(typeOrName, state);
|
|
2205
|
-
const listItemPos = findListItemPos(typeOrName, state);
|
|
2206
|
-
if (!listItemPos || !listDepth) {
|
|
2207
|
-
return false;
|
|
2208
|
-
}
|
|
2209
|
-
if (listDepth > listItemPos.depth) {
|
|
2210
|
-
return true;
|
|
2211
|
-
}
|
|
2212
|
-
return false;
|
|
2213
|
-
};
|
|
2214
|
-
|
|
2215
|
-
const nextListIsHigher = (typeOrName, state) => {
|
|
2216
|
-
const listDepth = getNextListDepth(typeOrName, state);
|
|
2217
|
-
const listItemPos = findListItemPos(typeOrName, state);
|
|
2218
|
-
if (!listItemPos || !listDepth) {
|
|
2219
|
-
return false;
|
|
2220
|
-
}
|
|
2221
|
-
if (listDepth < listItemPos.depth) {
|
|
2222
|
-
return true;
|
|
2223
|
-
}
|
|
2224
|
-
return false;
|
|
2225
|
-
};
|
|
2226
|
-
|
|
2227
|
-
const handleDelete = (editor, name) => {
|
|
2228
|
-
// if the cursor is not inside the current node type
|
|
2229
|
-
// do nothing and proceed
|
|
2230
|
-
if (!isNodeActive(editor.state, name)) {
|
|
2231
|
-
return false;
|
|
2232
|
-
}
|
|
2233
|
-
// if the cursor is not at the end of a node
|
|
2234
|
-
// do nothing and proceed
|
|
2235
|
-
if (!isAtEndOfNode(editor.state, name)) {
|
|
2236
|
-
return false;
|
|
2237
|
-
}
|
|
2238
|
-
// check if the next node is a list with a deeper depth
|
|
2239
|
-
if (nextListIsDeeper(name, editor.state)) {
|
|
2240
|
-
return editor
|
|
2241
|
-
.chain()
|
|
2242
|
-
.focus(editor.state.selection.from + 4)
|
|
2243
|
-
.lift(name)
|
|
2244
|
-
.joinBackward()
|
|
2245
|
-
.run();
|
|
2246
|
-
}
|
|
2247
|
-
if (nextListIsHigher(name, editor.state)) {
|
|
2248
|
-
return editor.chain()
|
|
2249
|
-
.joinForward()
|
|
2250
|
-
.joinBackward()
|
|
2251
|
-
.run();
|
|
2252
|
-
}
|
|
2253
|
-
return editor.commands.joinItemForward();
|
|
2254
|
-
};
|
|
2255
|
-
|
|
2256
|
-
const hasListItemAfter = (typeOrName, state) => {
|
|
2257
|
-
var _a;
|
|
2258
|
-
const { $anchor } = state.selection;
|
|
2259
|
-
const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2);
|
|
2260
|
-
if ($targetPos.index() === $targetPos.parent.childCount - 1) {
|
|
2261
|
-
return false;
|
|
2262
|
-
}
|
|
2263
|
-
if (((_a = $targetPos.nodeAfter) === null || _a === void 0 ? void 0 : _a.type.name) !== typeOrName) {
|
|
2264
|
-
return false;
|
|
2265
|
-
}
|
|
2266
|
-
return true;
|
|
2267
|
-
};
|
|
2268
|
-
|
|
2269
2014
|
/**
|
|
2270
2015
|
* Returns a new `Transform` based on all steps of the passed transactions.
|
|
2271
2016
|
*/
|
|
@@ -2327,6 +2072,24 @@ function findChildrenInRange(node, range, predicate) {
|
|
|
2327
2072
|
return nodesWithPos;
|
|
2328
2073
|
}
|
|
2329
2074
|
|
|
2075
|
+
function findParentNodeClosestToPos($pos, predicate) {
|
|
2076
|
+
for (let i = $pos.depth; i > 0; i -= 1) {
|
|
2077
|
+
const node = $pos.node(i);
|
|
2078
|
+
if (predicate(node)) {
|
|
2079
|
+
return {
|
|
2080
|
+
pos: i > 0 ? $pos.before(i) : 0,
|
|
2081
|
+
start: $pos.start(i),
|
|
2082
|
+
depth: i,
|
|
2083
|
+
node,
|
|
2084
|
+
};
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
function findParentNode(predicate) {
|
|
2090
|
+
return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2330
2093
|
function getHTMLFromFragment(fragment, schema) {
|
|
2331
2094
|
const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
|
|
2332
2095
|
const temporaryDocument = document.implementation.createHTMLDocument();
|
|
@@ -2544,6 +2307,30 @@ function getMarksBetween(from, to, doc) {
|
|
|
2544
2307
|
return marks;
|
|
2545
2308
|
}
|
|
2546
2309
|
|
|
2310
|
+
/**
|
|
2311
|
+
* Finds the first node of a given type or name in the current selection.
|
|
2312
|
+
* @param state The editor state.
|
|
2313
|
+
* @param typeOrName The node type or name.
|
|
2314
|
+
* @param pos The position to start searching from.
|
|
2315
|
+
* @param maxDepth The maximum depth to search.
|
|
2316
|
+
* @returns The node and the depth as an array.
|
|
2317
|
+
*/
|
|
2318
|
+
const getNodeAtPosition = (state, typeOrName, pos, maxDepth = 20) => {
|
|
2319
|
+
const $pos = state.doc.resolve(pos);
|
|
2320
|
+
let currentDepth = maxDepth;
|
|
2321
|
+
let node = null;
|
|
2322
|
+
while (currentDepth > 0 && node === null) {
|
|
2323
|
+
const currentNode = $pos.node(currentDepth);
|
|
2324
|
+
if ((currentNode === null || currentNode === void 0 ? void 0 : currentNode.type.name) === typeOrName) {
|
|
2325
|
+
node = currentNode;
|
|
2326
|
+
}
|
|
2327
|
+
else {
|
|
2328
|
+
currentDepth -= 1;
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
return [node, currentDepth];
|
|
2332
|
+
};
|
|
2333
|
+
|
|
2547
2334
|
function getSplittedAttributes(extensionAttributes, typeName, attributes) {
|
|
2548
2335
|
return Object.fromEntries(Object
|
|
2549
2336
|
.entries(attributes)
|
|
@@ -2634,6 +2421,33 @@ function isActive(state, name, attributes = {}) {
|
|
|
2634
2421
|
return false;
|
|
2635
2422
|
}
|
|
2636
2423
|
|
|
2424
|
+
const isAtEndOfNode = (state, nodeType) => {
|
|
2425
|
+
const { $from, $to, $anchor } = state.selection;
|
|
2426
|
+
if (nodeType) {
|
|
2427
|
+
const parentNode = findParentNode(node => node.type.name === nodeType)(state.selection);
|
|
2428
|
+
if (!parentNode) {
|
|
2429
|
+
return false;
|
|
2430
|
+
}
|
|
2431
|
+
const $parentPos = state.doc.resolve(parentNode.pos + 1);
|
|
2432
|
+
if ($anchor.pos + 1 === $parentPos.end()) {
|
|
2433
|
+
return true;
|
|
2434
|
+
}
|
|
2435
|
+
return false;
|
|
2436
|
+
}
|
|
2437
|
+
if ($to.parentOffset < $to.parent.nodeSize - 2 || $from.pos !== $to.pos) {
|
|
2438
|
+
return false;
|
|
2439
|
+
}
|
|
2440
|
+
return true;
|
|
2441
|
+
};
|
|
2442
|
+
|
|
2443
|
+
const isAtStartOfNode = (state) => {
|
|
2444
|
+
const { $from, $to } = state.selection;
|
|
2445
|
+
if ($from.parentOffset > 0 || $from.pos !== $to.pos) {
|
|
2446
|
+
return false;
|
|
2447
|
+
}
|
|
2448
|
+
return true;
|
|
2449
|
+
};
|
|
2450
|
+
|
|
2637
2451
|
function isList(name, extensions) {
|
|
2638
2452
|
const { nodeExtensions } = splitExtensions(extensions);
|
|
2639
2453
|
const extension = nodeExtensions.find(item => item.name === name);
|
|
@@ -4572,5 +4386,5 @@ class Tracker {
|
|
|
4572
4386
|
}
|
|
4573
4387
|
}
|
|
4574
4388
|
|
|
4575
|
-
export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, extensions, findChildren, findChildrenInRange, findDuplicates,
|
|
4389
|
+
export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, extensions, findChildren, findChildrenInRange, findDuplicates, findParentNode, findParentNodeClosestToPos, fromString, generateHTML, generateJSON, generateText, getAttributes, getAttributesFromExtensions, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAtPosition, getNodeAttributes, getNodeType, getRenderedAttributes, getSchema, getSchemaByResolvedExtensions, getSchemaTypeByName, getSchemaTypeNameByName, getSplittedAttributes, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, injectExtensionAttributesToParseRule, inputRulesPlugin, isActive, isAtEndOfNode, isAtStartOfNode, isEmptyObject, isExtensionRulesEnabled, isFunction, isList, isMacOS, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isNumber, isPlainObject, isRegExp, isString, isTextSelection, isiOS, markInputRule, markPasteRule, mergeAttributes, mergeDeep, minMax, nodeInputRule, nodePasteRule, objectIncludes, pasteRulesPlugin, posToDOMRect, removeDuplicates, resolveFocusPosition, selectionToInsertionEnd, splitExtensions, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
|
|
4576
4390
|
//# sourceMappingURL=index.js.map
|