@tiptap/extension-list 3.23.6 → 3.25.0

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.
Files changed (41) hide show
  1. package/dist/index.cjs +192 -68
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +170 -46
  4. package/dist/index.js.map +1 -1
  5. package/dist/item/index.cjs +120 -3
  6. package/dist/item/index.cjs.map +1 -1
  7. package/dist/item/index.js +117 -0
  8. package/dist/item/index.js.map +1 -1
  9. package/dist/keymap/index.cjs +37 -47
  10. package/dist/keymap/index.cjs.map +1 -1
  11. package/dist/keymap/index.js +30 -40
  12. package/dist/keymap/index.js.map +1 -1
  13. package/dist/kit/index.cjs +192 -68
  14. package/dist/kit/index.cjs.map +1 -1
  15. package/dist/kit/index.js +170 -46
  16. package/dist/kit/index.js.map +1 -1
  17. package/dist/ordered-list/index.cjs +8 -1
  18. package/dist/ordered-list/index.cjs.map +1 -1
  19. package/dist/ordered-list/index.js +8 -1
  20. package/dist/ordered-list/index.js.map +1 -1
  21. package/dist/task-item/index.cjs +120 -5
  22. package/dist/task-item/index.cjs.map +1 -1
  23. package/dist/task-item/index.js +115 -0
  24. package/dist/task-item/index.js.map +1 -1
  25. package/dist/task-list/index.cjs +5 -1
  26. package/dist/task-list/index.cjs.map +1 -1
  27. package/dist/task-list/index.js +5 -1
  28. package/dist/task-list/index.js.map +1 -1
  29. package/package.json +19 -20
  30. package/src/helpers/createBranchingListDeleteKeymap.ts +24 -0
  31. package/src/helpers/getBranchingNestedListAtCursor.ts +116 -0
  32. package/src/helpers/handleDeleteBranchingNestedList.ts +25 -0
  33. package/src/helpers/hasBranchingNestedListAfterCursor.ts +30 -0
  34. package/src/helpers/hoistBranchingNestedList.ts +56 -0
  35. package/src/item/list-item.ts +21 -5
  36. package/src/keymap/listHelpers/handleBackspace.ts +3 -22
  37. package/src/keymap/listHelpers/hasListBefore.ts +5 -1
  38. package/src/ordered-list/ordered-list.ts +3 -1
  39. package/src/ordered-list/utils.ts +15 -2
  40. package/src/task-item/task-item.ts +10 -0
  41. package/src/task-list/task-list.ts +5 -1
@@ -23,7 +23,7 @@ __export(index_exports, {
23
23
  ListKit: () => ListKit
24
24
  });
25
25
  module.exports = __toCommonJS(index_exports);
26
- var import_core12 = require("@tiptap/core");
26
+ var import_core13 = require("@tiptap/core");
27
27
 
28
28
  // src/bullet-list/bullet-list.ts
29
29
  var import_core = require("@tiptap/core");
@@ -106,7 +106,116 @@ var BulletList = import_core.Node.create({
106
106
  });
107
107
 
108
108
  // src/item/list-item.ts
109
+ var import_core3 = require("@tiptap/core");
110
+
111
+ // src/helpers/createBranchingListDeleteKeymap.ts
109
112
  var import_core2 = require("@tiptap/core");
113
+
114
+ // src/helpers/hoistBranchingNestedList.ts
115
+ var import_model = require("@tiptap/pm/model");
116
+
117
+ // src/helpers/getBranchingNestedListAtCursor.ts
118
+ var getBranchingNestedListAtCursor = (state, itemName, wrapperNames) => {
119
+ const { selection } = state;
120
+ if (!selection.empty) {
121
+ return null;
122
+ }
123
+ const { $from } = selection;
124
+ if (!$from.parent.isTextblock) {
125
+ return null;
126
+ }
127
+ if ($from.parentOffset !== $from.parent.content.size) {
128
+ return null;
129
+ }
130
+ let listItemDepth = -1;
131
+ for (let depth = $from.depth; depth > 0; depth -= 1) {
132
+ if ($from.node(depth).type.name === itemName) {
133
+ listItemDepth = depth;
134
+ break;
135
+ }
136
+ }
137
+ if (listItemDepth < 0) {
138
+ return null;
139
+ }
140
+ const listItem = $from.node(listItemDepth);
141
+ const indexInListItem = $from.index(listItemDepth);
142
+ if (indexInListItem + 1 >= listItem.childCount) {
143
+ return null;
144
+ }
145
+ const nextChild = listItem.child(indexInListItem + 1);
146
+ if (!wrapperNames.includes(nextChild.type.name)) {
147
+ return null;
148
+ }
149
+ const itemType = state.schema.nodes[itemName];
150
+ let hasBranching = false;
151
+ nextChild.forEach((child) => {
152
+ if (child.type === itemType && child.childCount > 1) {
153
+ hasBranching = true;
154
+ }
155
+ });
156
+ if (!hasBranching) {
157
+ return null;
158
+ }
159
+ const nodeAfter = state.doc.resolve($from.after()).nodeAfter;
160
+ if (!nodeAfter || !wrapperNames.includes(nodeAfter.type.name)) {
161
+ return null;
162
+ }
163
+ const items = [];
164
+ nodeAfter.forEach((child) => {
165
+ items.push(child);
166
+ });
167
+ if (items.length === 0) {
168
+ return null;
169
+ }
170
+ return {
171
+ listItemDepth,
172
+ nestedList: nodeAfter,
173
+ nestedListPos: $from.after(),
174
+ insertPos: $from.after(listItemDepth),
175
+ items
176
+ };
177
+ };
178
+
179
+ // src/helpers/hoistBranchingNestedList.ts
180
+ var hoistBranchingNestedList = (state, dispatch, itemName, wrapperNames) => {
181
+ const context = getBranchingNestedListAtCursor(state, itemName, wrapperNames);
182
+ if (!context) {
183
+ return false;
184
+ }
185
+ const { selection } = state;
186
+ const { nestedList, nestedListPos, insertPos, items } = context;
187
+ const tr = state.tr;
188
+ tr.delete(nestedListPos, nestedListPos + nestedList.nodeSize);
189
+ const mappedInsertPos = tr.mapping.map(insertPos);
190
+ tr.insert(mappedInsertPos, import_model.Fragment.from(items));
191
+ tr.setSelection(selection.map(tr.doc, tr.mapping));
192
+ if (dispatch) {
193
+ dispatch(tr);
194
+ }
195
+ return true;
196
+ };
197
+
198
+ // src/helpers/handleDeleteBranchingNestedList.ts
199
+ var handleDeleteBranchingNestedList = (editor, itemName, wrapperNames) => {
200
+ return hoistBranchingNestedList(editor.state, editor.view.dispatch, itemName, wrapperNames);
201
+ };
202
+
203
+ // src/helpers/createBranchingListDeleteKeymap.ts
204
+ var createBranchingListDeleteKeymap = (itemName, wrapperNames) => {
205
+ return import_core2.Extension.create({
206
+ name: `${itemName}BranchingDeleteKeymap`,
207
+ priority: 101,
208
+ addKeyboardShortcuts() {
209
+ const handleDelete2 = () => handleDeleteBranchingNestedList(this.editor, itemName, wrapperNames);
210
+ return {
211
+ Delete: handleDelete2,
212
+ "Mod-Delete": handleDelete2
213
+ };
214
+ }
215
+ });
216
+ };
217
+
218
+ // src/item/list-item.ts
110
219
  function isSameLineOrderedListToken(token) {
111
220
  var _a, _b;
112
221
  const nestedToken = (_a = token.tokens) == null ? void 0 : _a[0];
@@ -126,7 +235,7 @@ function parseSameLineOrderedListText(text, helpers) {
126
235
  }
127
236
  ]);
128
237
  }
129
- var ListItem = import_core2.Node.create({
238
+ var ListItem = import_core3.Node.create({
130
239
  name: "listItem",
131
240
  addOptions() {
132
241
  return {
@@ -145,7 +254,7 @@ var ListItem = import_core2.Node.create({
145
254
  ];
146
255
  },
147
256
  renderHTML({ HTMLAttributes }) {
148
- return ["li", (0, import_core2.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
257
+ return ["li", (0, import_core3.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
149
258
  },
150
259
  markdownTokenName: "list_item",
151
260
  parseMarkdown: (token, helpers) => {
@@ -204,7 +313,7 @@ var ListItem = import_core2.Node.create({
204
313
  };
205
314
  },
206
315
  renderMarkdown: (node, h, ctx) => {
207
- return (0, import_core2.renderNestedMarkdownContent)(
316
+ return (0, import_core3.renderNestedMarkdownContent)(
208
317
  node,
209
318
  h,
210
319
  (context) => {
@@ -221,6 +330,14 @@ var ListItem = import_core2.Node.create({
221
330
  ctx
222
331
  );
223
332
  },
333
+ addExtensions() {
334
+ return [
335
+ createBranchingListDeleteKeymap(this.name, [
336
+ this.options.bulletListTypeName,
337
+ this.options.orderedListTypeName
338
+ ])
339
+ ];
340
+ },
224
341
  addKeyboardShortcuts() {
225
342
  return {
226
343
  Enter: () => this.editor.commands.splitListItem(this.name),
@@ -231,7 +348,7 @@ var ListItem = import_core2.Node.create({
231
348
  });
232
349
 
233
350
  // src/keymap/list-keymap.ts
234
- var import_core8 = require("@tiptap/core");
351
+ var import_core9 = require("@tiptap/core");
235
352
 
236
353
  // src/keymap/listHelpers/index.ts
237
354
  var listHelpers_exports = {};
@@ -249,10 +366,10 @@ __export(listHelpers_exports, {
249
366
  });
250
367
 
251
368
  // src/keymap/listHelpers/findListItemPos.ts
252
- var import_core3 = require("@tiptap/core");
369
+ var import_core4 = require("@tiptap/core");
253
370
  var findListItemPos = (typeOrName, state) => {
254
371
  const { $from } = state.selection;
255
- const nodeType = (0, import_core3.getNodeType)(typeOrName, state.schema);
372
+ const nodeType = (0, import_core4.getNodeType)(typeOrName, state.schema);
256
373
  let currentNode = null;
257
374
  let currentDepth = $from.depth;
258
375
  let currentPos = $from.pos;
@@ -273,13 +390,13 @@ var findListItemPos = (typeOrName, state) => {
273
390
  };
274
391
 
275
392
  // src/keymap/listHelpers/getNextListDepth.ts
276
- var import_core4 = require("@tiptap/core");
393
+ var import_core5 = require("@tiptap/core");
277
394
  var getNextListDepth = (typeOrName, state) => {
278
395
  const listItemPos = findListItemPos(typeOrName, state);
279
396
  if (!listItemPos) {
280
397
  return false;
281
398
  }
282
- const [, depth] = (0, import_core4.getNodeAtPosition)(state, typeOrName, listItemPos.$pos.pos + 4);
399
+ const [, depth] = (0, import_core5.getNodeAtPosition)(state, typeOrName, listItemPos.$pos.pos + 4);
283
400
  return depth;
284
401
  };
285
402
 
@@ -297,36 +414,6 @@ var hasListBefore = (editorState, name, parentListTypes) => {
297
414
  return true;
298
415
  };
299
416
 
300
- // src/keymap/listHelpers/hasListItemBefore.ts
301
- var hasListItemBefore = (typeOrName, state) => {
302
- var _a;
303
- const { $anchor } = state.selection;
304
- const $targetPos = state.doc.resolve($anchor.pos - 2);
305
- if ($targetPos.index() === 0) {
306
- return false;
307
- }
308
- if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
309
- return false;
310
- }
311
- return true;
312
- };
313
-
314
- // src/keymap/listHelpers/listItemHasSubList.ts
315
- var import_core5 = require("@tiptap/core");
316
- var listItemHasSubList = (typeOrName, state, node) => {
317
- if (!node) {
318
- return false;
319
- }
320
- const nodeType = (0, import_core5.getNodeType)(typeOrName, state.schema);
321
- let hasSubList = false;
322
- node.descendants((child) => {
323
- if (child.type === nodeType) {
324
- hasSubList = true;
325
- }
326
- });
327
- return hasSubList;
328
- };
329
-
330
417
  // src/keymap/listHelpers/handleBackspace.ts
331
418
  var handleBackspace = (editor, name, parentListTypes) => {
332
419
  if (editor.commands.undoInputRule()) {
@@ -357,16 +444,6 @@ var handleBackspace = (editor, name, parentListTypes) => {
357
444
  if (!(0, import_core6.isAtStartOfNode)(editor.state)) {
358
445
  return false;
359
446
  }
360
- const listItemPos = findListItemPos(name, editor.state);
361
- if (!listItemPos) {
362
- return false;
363
- }
364
- const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
365
- const prevNode = $prev.node(listItemPos.depth);
366
- const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
367
- if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
368
- return editor.commands.joinItemBackward();
369
- }
370
447
  return editor.chain().liftListItem(name).run();
371
448
  };
372
449
 
@@ -435,8 +512,38 @@ var hasListItemAfter = (typeOrName, state) => {
435
512
  return true;
436
513
  };
437
514
 
515
+ // src/keymap/listHelpers/hasListItemBefore.ts
516
+ var hasListItemBefore = (typeOrName, state) => {
517
+ var _a;
518
+ const { $anchor } = state.selection;
519
+ const $targetPos = state.doc.resolve($anchor.pos - 2);
520
+ if ($targetPos.index() === 0) {
521
+ return false;
522
+ }
523
+ if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
524
+ return false;
525
+ }
526
+ return true;
527
+ };
528
+
529
+ // src/keymap/listHelpers/listItemHasSubList.ts
530
+ var import_core8 = require("@tiptap/core");
531
+ var listItemHasSubList = (typeOrName, state, node) => {
532
+ if (!node) {
533
+ return false;
534
+ }
535
+ const nodeType = (0, import_core8.getNodeType)(typeOrName, state.schema);
536
+ let hasSubList = false;
537
+ node.descendants((child) => {
538
+ if (child.type === nodeType) {
539
+ hasSubList = true;
540
+ }
541
+ });
542
+ return hasSubList;
543
+ };
544
+
438
545
  // src/keymap/list-keymap.ts
439
- var ListKeymap = import_core8.Extension.create({
546
+ var ListKeymap = import_core9.Extension.create({
440
547
  name: "listKeymap",
441
548
  addOptions() {
442
549
  return {
@@ -507,14 +614,21 @@ var ListKeymap = import_core8.Extension.create({
507
614
  });
508
615
 
509
616
  // src/ordered-list/ordered-list.ts
510
- var import_core9 = require("@tiptap/core");
617
+ var import_core10 = require("@tiptap/core");
511
618
 
512
619
  // src/ordered-list/utils.ts
513
620
  var ORDERED_LIST_ITEM_REGEX = /^(\s*)(\d+)\.\s+(.*)$/;
514
621
  var INDENTED_LINE_REGEX = /^\s/;
515
622
  function isBlockContentLine(line) {
516
623
  const trimmedLine = line.trimStart();
517
- return /^[-+*]\s+/.test(trimmedLine) || /^\d+\.\s+/.test(trimmedLine) || /^>\s?/.test(trimmedLine) || /^```/.test(trimmedLine) || /^~~~/.test(trimmedLine);
624
+ return (
625
+ // oxlint-disable-next-line prefer-string-starts-ends-with
626
+ /^[-+*]\s+/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
627
+ /^\d+\.\s+/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
628
+ /^>\s?/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
629
+ /^```/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
630
+ /^~~~/.test(trimmedLine)
631
+ );
518
632
  }
519
633
  function splitItemContent(contentLines) {
520
634
  const paragraphLines = [];
@@ -679,7 +793,7 @@ function parseListItems(items, helpers) {
679
793
  var ListItemName2 = "listItem";
680
794
  var TextStyleName2 = "textStyle";
681
795
  var orderedListInputRegex = /^(\d+)\.\s$/;
682
- var OrderedList = import_core9.Node.create({
796
+ var OrderedList = import_core10.Node.create({
683
797
  name: "orderedList",
684
798
  addOptions() {
685
799
  return {
@@ -716,7 +830,7 @@ var OrderedList = import_core9.Node.create({
716
830
  },
717
831
  renderHTML({ HTMLAttributes }) {
718
832
  const { start, ...attributesWithoutStart } = HTMLAttributes;
719
- return start === 1 ? ["ol", (0, import_core9.mergeAttributes)(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", (0, import_core9.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
833
+ return start === 1 ? ["ol", (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
720
834
  },
721
835
  markdownTokenName: "list",
722
836
  parseMarkdown: (token, helpers) => {
@@ -791,14 +905,14 @@ var OrderedList = import_core9.Node.create({
791
905
  };
792
906
  },
793
907
  addInputRules() {
794
- let inputRule = (0, import_core9.wrappingInputRule)({
908
+ let inputRule = (0, import_core10.wrappingInputRule)({
795
909
  find: orderedListInputRegex,
796
910
  type: this.type,
797
911
  getAttributes: (match) => ({ start: +match[1] }),
798
912
  joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1]
799
913
  });
800
914
  if (this.options.keepMarks || this.options.keepAttributes) {
801
- inputRule = (0, import_core9.wrappingInputRule)({
915
+ inputRule = (0, import_core10.wrappingInputRule)({
802
916
  find: orderedListInputRegex,
803
917
  type: this.type,
804
918
  keepMarks: this.options.keepMarks,
@@ -813,9 +927,9 @@ var OrderedList = import_core9.Node.create({
813
927
  });
814
928
 
815
929
  // src/task-item/task-item.ts
816
- var import_core10 = require("@tiptap/core");
930
+ var import_core11 = require("@tiptap/core");
817
931
  var inputRegex = /^\s*(\[([( |x])?\])\s$/;
818
- var TaskItem = import_core10.Node.create({
932
+ var TaskItem = import_core11.Node.create({
819
933
  name: "taskItem",
820
934
  addOptions() {
821
935
  return {
@@ -855,7 +969,7 @@ var TaskItem = import_core10.Node.create({
855
969
  renderHTML({ node, HTMLAttributes }) {
856
970
  return [
857
971
  "li",
858
- (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
972
+ (0, import_core11.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
859
973
  "data-type": this.name
860
974
  }),
861
975
  [
@@ -891,7 +1005,13 @@ var TaskItem = import_core10.Node.create({
891
1005
  var _a;
892
1006
  const checkedChar = ((_a = node.attrs) == null ? void 0 : _a.checked) ? "x" : " ";
893
1007
  const prefix = `- [${checkedChar}] `;
894
- return (0, import_core10.renderNestedMarkdownContent)(node, h, prefix);
1008
+ return (0, import_core11.renderNestedMarkdownContent)(node, h, prefix);
1009
+ },
1010
+ addExtensions() {
1011
+ if (!this.options.nested) {
1012
+ return [];
1013
+ }
1014
+ return [createBranchingListDeleteKeymap(this.name, [this.options.taskListTypeName])];
895
1015
  },
896
1016
  addKeyboardShortcuts() {
897
1017
  const shortcuts = {
@@ -969,7 +1089,7 @@ var TaskItem = import_core10.Node.create({
969
1089
  checkbox.checked = updatedNode.attrs.checked;
970
1090
  updateA11Y(updatedNode);
971
1091
  const extensionAttributes = editor.extensionManager.attributes;
972
- const newHTMLAttributes = (0, import_core10.getRenderedAttributes)(updatedNode, extensionAttributes);
1092
+ const newHTMLAttributes = (0, import_core11.getRenderedAttributes)(updatedNode, extensionAttributes);
973
1093
  const newKeys = new Set(Object.keys(newHTMLAttributes));
974
1094
  const staticAttrs = this.options.HTMLAttributes;
975
1095
  prevRenderedAttributeKeys.forEach((key) => {
@@ -1000,7 +1120,7 @@ var TaskItem = import_core10.Node.create({
1000
1120
  },
1001
1121
  addInputRules() {
1002
1122
  return [
1003
- (0, import_core10.wrappingInputRule)({
1123
+ (0, import_core11.wrappingInputRule)({
1004
1124
  find: inputRegex,
1005
1125
  type: this.type,
1006
1126
  getAttributes: (match) => ({
@@ -1012,8 +1132,8 @@ var TaskItem = import_core10.Node.create({
1012
1132
  });
1013
1133
 
1014
1134
  // src/task-list/task-list.ts
1015
- var import_core11 = require("@tiptap/core");
1016
- var TaskList = import_core11.Node.create({
1135
+ var import_core12 = require("@tiptap/core");
1136
+ var TaskList = import_core12.Node.create({
1017
1137
  name: "taskList",
1018
1138
  addOptions() {
1019
1139
  return {
@@ -1034,7 +1154,11 @@ var TaskList = import_core11.Node.create({
1034
1154
  ];
1035
1155
  },
1036
1156
  renderHTML({ HTMLAttributes }) {
1037
- return ["ul", (0, import_core11.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }), 0];
1157
+ return [
1158
+ "ul",
1159
+ (0, import_core12.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }),
1160
+ 0
1161
+ ];
1038
1162
  },
1039
1163
  parseMarkdown: (token, h) => {
1040
1164
  return h.createNode("taskList", {}, h.parseChildren(token.items || []));
@@ -1055,7 +1179,7 @@ var TaskList = import_core11.Node.create({
1055
1179
  },
1056
1180
  tokenize(src, tokens, lexer) {
1057
1181
  const parseTaskListContent = (content) => {
1058
- const nestedResult = (0, import_core11.parseIndentedBlocks)(
1182
+ const nestedResult = (0, import_core12.parseIndentedBlocks)(
1059
1183
  content,
1060
1184
  {
1061
1185
  itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
@@ -1090,7 +1214,7 @@ var TaskList = import_core11.Node.create({
1090
1214
  }
1091
1215
  return lexer.blockTokens(content);
1092
1216
  };
1093
- const result = (0, import_core11.parseIndentedBlocks)(
1217
+ const result = (0, import_core12.parseIndentedBlocks)(
1094
1218
  src,
1095
1219
  {
1096
1220
  itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
@@ -1142,7 +1266,7 @@ var TaskList = import_core11.Node.create({
1142
1266
  });
1143
1267
 
1144
1268
  // src/kit/index.ts
1145
- var ListKit = import_core12.Extension.create({
1269
+ var ListKit = import_core13.Extension.create({
1146
1270
  name: "listKit",
1147
1271
  addExtensions() {
1148
1272
  const extensions = [];