@tiptap/extension-list 3.24.0 → 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.
package/dist/index.cjs CHANGED
@@ -115,7 +115,116 @@ var BulletList = import_core.Node.create({
115
115
  });
116
116
 
117
117
  // src/item/list-item.ts
118
+ var import_core3 = require("@tiptap/core");
119
+
120
+ // src/helpers/createBranchingListDeleteKeymap.ts
118
121
  var import_core2 = require("@tiptap/core");
122
+
123
+ // src/helpers/hoistBranchingNestedList.ts
124
+ var import_model = require("@tiptap/pm/model");
125
+
126
+ // src/helpers/getBranchingNestedListAtCursor.ts
127
+ var getBranchingNestedListAtCursor = (state, itemName, wrapperNames) => {
128
+ const { selection } = state;
129
+ if (!selection.empty) {
130
+ return null;
131
+ }
132
+ const { $from } = selection;
133
+ if (!$from.parent.isTextblock) {
134
+ return null;
135
+ }
136
+ if ($from.parentOffset !== $from.parent.content.size) {
137
+ return null;
138
+ }
139
+ let listItemDepth = -1;
140
+ for (let depth = $from.depth; depth > 0; depth -= 1) {
141
+ if ($from.node(depth).type.name === itemName) {
142
+ listItemDepth = depth;
143
+ break;
144
+ }
145
+ }
146
+ if (listItemDepth < 0) {
147
+ return null;
148
+ }
149
+ const listItem = $from.node(listItemDepth);
150
+ const indexInListItem = $from.index(listItemDepth);
151
+ if (indexInListItem + 1 >= listItem.childCount) {
152
+ return null;
153
+ }
154
+ const nextChild = listItem.child(indexInListItem + 1);
155
+ if (!wrapperNames.includes(nextChild.type.name)) {
156
+ return null;
157
+ }
158
+ const itemType = state.schema.nodes[itemName];
159
+ let hasBranching = false;
160
+ nextChild.forEach((child) => {
161
+ if (child.type === itemType && child.childCount > 1) {
162
+ hasBranching = true;
163
+ }
164
+ });
165
+ if (!hasBranching) {
166
+ return null;
167
+ }
168
+ const nodeAfter = state.doc.resolve($from.after()).nodeAfter;
169
+ if (!nodeAfter || !wrapperNames.includes(nodeAfter.type.name)) {
170
+ return null;
171
+ }
172
+ const items = [];
173
+ nodeAfter.forEach((child) => {
174
+ items.push(child);
175
+ });
176
+ if (items.length === 0) {
177
+ return null;
178
+ }
179
+ return {
180
+ listItemDepth,
181
+ nestedList: nodeAfter,
182
+ nestedListPos: $from.after(),
183
+ insertPos: $from.after(listItemDepth),
184
+ items
185
+ };
186
+ };
187
+
188
+ // src/helpers/hoistBranchingNestedList.ts
189
+ var hoistBranchingNestedList = (state, dispatch, itemName, wrapperNames) => {
190
+ const context = getBranchingNestedListAtCursor(state, itemName, wrapperNames);
191
+ if (!context) {
192
+ return false;
193
+ }
194
+ const { selection } = state;
195
+ const { nestedList, nestedListPos, insertPos, items } = context;
196
+ const tr = state.tr;
197
+ tr.delete(nestedListPos, nestedListPos + nestedList.nodeSize);
198
+ const mappedInsertPos = tr.mapping.map(insertPos);
199
+ tr.insert(mappedInsertPos, import_model.Fragment.from(items));
200
+ tr.setSelection(selection.map(tr.doc, tr.mapping));
201
+ if (dispatch) {
202
+ dispatch(tr);
203
+ }
204
+ return true;
205
+ };
206
+
207
+ // src/helpers/handleDeleteBranchingNestedList.ts
208
+ var handleDeleteBranchingNestedList = (editor, itemName, wrapperNames) => {
209
+ return hoistBranchingNestedList(editor.state, editor.view.dispatch, itemName, wrapperNames);
210
+ };
211
+
212
+ // src/helpers/createBranchingListDeleteKeymap.ts
213
+ var createBranchingListDeleteKeymap = (itemName, wrapperNames) => {
214
+ return import_core2.Extension.create({
215
+ name: `${itemName}BranchingDeleteKeymap`,
216
+ priority: 101,
217
+ addKeyboardShortcuts() {
218
+ const handleDelete2 = () => handleDeleteBranchingNestedList(this.editor, itemName, wrapperNames);
219
+ return {
220
+ Delete: handleDelete2,
221
+ "Mod-Delete": handleDelete2
222
+ };
223
+ }
224
+ });
225
+ };
226
+
227
+ // src/item/list-item.ts
119
228
  function isSameLineOrderedListToken(token) {
120
229
  var _a, _b;
121
230
  const nestedToken = (_a = token.tokens) == null ? void 0 : _a[0];
@@ -135,7 +244,7 @@ function parseSameLineOrderedListText(text, helpers) {
135
244
  }
136
245
  ]);
137
246
  }
138
- var ListItem = import_core2.Node.create({
247
+ var ListItem = import_core3.Node.create({
139
248
  name: "listItem",
140
249
  addOptions() {
141
250
  return {
@@ -154,7 +263,7 @@ var ListItem = import_core2.Node.create({
154
263
  ];
155
264
  },
156
265
  renderHTML({ HTMLAttributes }) {
157
- return ["li", (0, import_core2.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
266
+ return ["li", (0, import_core3.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
158
267
  },
159
268
  markdownTokenName: "list_item",
160
269
  parseMarkdown: (token, helpers) => {
@@ -213,7 +322,7 @@ var ListItem = import_core2.Node.create({
213
322
  };
214
323
  },
215
324
  renderMarkdown: (node, h, ctx) => {
216
- return (0, import_core2.renderNestedMarkdownContent)(
325
+ return (0, import_core3.renderNestedMarkdownContent)(
217
326
  node,
218
327
  h,
219
328
  (context) => {
@@ -230,6 +339,14 @@ var ListItem = import_core2.Node.create({
230
339
  ctx
231
340
  );
232
341
  },
342
+ addExtensions() {
343
+ return [
344
+ createBranchingListDeleteKeymap(this.name, [
345
+ this.options.bulletListTypeName,
346
+ this.options.orderedListTypeName
347
+ ])
348
+ ];
349
+ },
233
350
  addKeyboardShortcuts() {
234
351
  return {
235
352
  Enter: () => this.editor.commands.splitListItem(this.name),
@@ -240,7 +357,7 @@ var ListItem = import_core2.Node.create({
240
357
  });
241
358
 
242
359
  // src/keymap/list-keymap.ts
243
- var import_core8 = require("@tiptap/core");
360
+ var import_core9 = require("@tiptap/core");
244
361
 
245
362
  // src/keymap/listHelpers/index.ts
246
363
  var listHelpers_exports = {};
@@ -258,10 +375,10 @@ __export(listHelpers_exports, {
258
375
  });
259
376
 
260
377
  // src/keymap/listHelpers/findListItemPos.ts
261
- var import_core3 = require("@tiptap/core");
378
+ var import_core4 = require("@tiptap/core");
262
379
  var findListItemPos = (typeOrName, state) => {
263
380
  const { $from } = state.selection;
264
- const nodeType = (0, import_core3.getNodeType)(typeOrName, state.schema);
381
+ const nodeType = (0, import_core4.getNodeType)(typeOrName, state.schema);
265
382
  let currentNode = null;
266
383
  let currentDepth = $from.depth;
267
384
  let currentPos = $from.pos;
@@ -282,13 +399,13 @@ var findListItemPos = (typeOrName, state) => {
282
399
  };
283
400
 
284
401
  // src/keymap/listHelpers/getNextListDepth.ts
285
- var import_core4 = require("@tiptap/core");
402
+ var import_core5 = require("@tiptap/core");
286
403
  var getNextListDepth = (typeOrName, state) => {
287
404
  const listItemPos = findListItemPos(typeOrName, state);
288
405
  if (!listItemPos) {
289
406
  return false;
290
407
  }
291
- const [, depth] = (0, import_core4.getNodeAtPosition)(state, typeOrName, listItemPos.$pos.pos + 4);
408
+ const [, depth] = (0, import_core5.getNodeAtPosition)(state, typeOrName, listItemPos.$pos.pos + 4);
292
409
  return depth;
293
410
  };
294
411
 
@@ -306,36 +423,6 @@ var hasListBefore = (editorState, name, parentListTypes) => {
306
423
  return true;
307
424
  };
308
425
 
309
- // src/keymap/listHelpers/hasListItemBefore.ts
310
- var hasListItemBefore = (typeOrName, state) => {
311
- var _a;
312
- const { $anchor } = state.selection;
313
- const $targetPos = state.doc.resolve($anchor.pos - 2);
314
- if ($targetPos.index() === 0) {
315
- return false;
316
- }
317
- if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
318
- return false;
319
- }
320
- return true;
321
- };
322
-
323
- // src/keymap/listHelpers/listItemHasSubList.ts
324
- var import_core5 = require("@tiptap/core");
325
- var listItemHasSubList = (typeOrName, state, node) => {
326
- if (!node) {
327
- return false;
328
- }
329
- const nodeType = (0, import_core5.getNodeType)(typeOrName, state.schema);
330
- let hasSubList = false;
331
- node.descendants((child) => {
332
- if (child.type === nodeType) {
333
- hasSubList = true;
334
- }
335
- });
336
- return hasSubList;
337
- };
338
-
339
426
  // src/keymap/listHelpers/handleBackspace.ts
340
427
  var handleBackspace = (editor, name, parentListTypes) => {
341
428
  if (editor.commands.undoInputRule()) {
@@ -366,16 +453,6 @@ var handleBackspace = (editor, name, parentListTypes) => {
366
453
  if (!(0, import_core6.isAtStartOfNode)(editor.state)) {
367
454
  return false;
368
455
  }
369
- const listItemPos = findListItemPos(name, editor.state);
370
- if (!listItemPos) {
371
- return false;
372
- }
373
- const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
374
- const prevNode = $prev.node(listItemPos.depth);
375
- const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
376
- if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
377
- return editor.commands.joinItemBackward();
378
- }
379
456
  return editor.chain().liftListItem(name).run();
380
457
  };
381
458
 
@@ -444,8 +521,38 @@ var hasListItemAfter = (typeOrName, state) => {
444
521
  return true;
445
522
  };
446
523
 
524
+ // src/keymap/listHelpers/hasListItemBefore.ts
525
+ var hasListItemBefore = (typeOrName, state) => {
526
+ var _a;
527
+ const { $anchor } = state.selection;
528
+ const $targetPos = state.doc.resolve($anchor.pos - 2);
529
+ if ($targetPos.index() === 0) {
530
+ return false;
531
+ }
532
+ if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
533
+ return false;
534
+ }
535
+ return true;
536
+ };
537
+
538
+ // src/keymap/listHelpers/listItemHasSubList.ts
539
+ var import_core8 = require("@tiptap/core");
540
+ var listItemHasSubList = (typeOrName, state, node) => {
541
+ if (!node) {
542
+ return false;
543
+ }
544
+ const nodeType = (0, import_core8.getNodeType)(typeOrName, state.schema);
545
+ let hasSubList = false;
546
+ node.descendants((child) => {
547
+ if (child.type === nodeType) {
548
+ hasSubList = true;
549
+ }
550
+ });
551
+ return hasSubList;
552
+ };
553
+
447
554
  // src/keymap/list-keymap.ts
448
- var ListKeymap = import_core8.Extension.create({
555
+ var ListKeymap = import_core9.Extension.create({
449
556
  name: "listKeymap",
450
557
  addOptions() {
451
558
  return {
@@ -516,10 +623,10 @@ var ListKeymap = import_core8.Extension.create({
516
623
  });
517
624
 
518
625
  // src/kit/index.ts
519
- var import_core12 = require("@tiptap/core");
626
+ var import_core13 = require("@tiptap/core");
520
627
 
521
628
  // src/ordered-list/ordered-list.ts
522
- var import_core9 = require("@tiptap/core");
629
+ var import_core10 = require("@tiptap/core");
523
630
 
524
631
  // src/ordered-list/utils.ts
525
632
  var ORDERED_LIST_ITEM_REGEX = /^(\s*)(\d+)\.\s+(.*)$/;
@@ -698,7 +805,7 @@ function parseListItems(items, helpers) {
698
805
  var ListItemName2 = "listItem";
699
806
  var TextStyleName2 = "textStyle";
700
807
  var orderedListInputRegex = /^(\d+)\.\s$/;
701
- var OrderedList = import_core9.Node.create({
808
+ var OrderedList = import_core10.Node.create({
702
809
  name: "orderedList",
703
810
  addOptions() {
704
811
  return {
@@ -735,7 +842,7 @@ var OrderedList = import_core9.Node.create({
735
842
  },
736
843
  renderHTML({ HTMLAttributes }) {
737
844
  const { start, ...attributesWithoutStart } = HTMLAttributes;
738
- return start === 1 ? ["ol", (0, import_core9.mergeAttributes)(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", (0, import_core9.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
845
+ return start === 1 ? ["ol", (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
739
846
  },
740
847
  markdownTokenName: "list",
741
848
  parseMarkdown: (token, helpers) => {
@@ -810,14 +917,14 @@ var OrderedList = import_core9.Node.create({
810
917
  };
811
918
  },
812
919
  addInputRules() {
813
- let inputRule = (0, import_core9.wrappingInputRule)({
920
+ let inputRule = (0, import_core10.wrappingInputRule)({
814
921
  find: orderedListInputRegex,
815
922
  type: this.type,
816
923
  getAttributes: (match) => ({ start: +match[1] }),
817
924
  joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1]
818
925
  });
819
926
  if (this.options.keepMarks || this.options.keepAttributes) {
820
- inputRule = (0, import_core9.wrappingInputRule)({
927
+ inputRule = (0, import_core10.wrappingInputRule)({
821
928
  find: orderedListInputRegex,
822
929
  type: this.type,
823
930
  keepMarks: this.options.keepMarks,
@@ -832,9 +939,9 @@ var OrderedList = import_core9.Node.create({
832
939
  });
833
940
 
834
941
  // src/task-item/task-item.ts
835
- var import_core10 = require("@tiptap/core");
942
+ var import_core11 = require("@tiptap/core");
836
943
  var inputRegex = /^\s*(\[([( |x])?\])\s$/;
837
- var TaskItem = import_core10.Node.create({
944
+ var TaskItem = import_core11.Node.create({
838
945
  name: "taskItem",
839
946
  addOptions() {
840
947
  return {
@@ -874,7 +981,7 @@ var TaskItem = import_core10.Node.create({
874
981
  renderHTML({ node, HTMLAttributes }) {
875
982
  return [
876
983
  "li",
877
- (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
984
+ (0, import_core11.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
878
985
  "data-type": this.name
879
986
  }),
880
987
  [
@@ -910,7 +1017,13 @@ var TaskItem = import_core10.Node.create({
910
1017
  var _a;
911
1018
  const checkedChar = ((_a = node.attrs) == null ? void 0 : _a.checked) ? "x" : " ";
912
1019
  const prefix = `- [${checkedChar}] `;
913
- return (0, import_core10.renderNestedMarkdownContent)(node, h, prefix);
1020
+ return (0, import_core11.renderNestedMarkdownContent)(node, h, prefix);
1021
+ },
1022
+ addExtensions() {
1023
+ if (!this.options.nested) {
1024
+ return [];
1025
+ }
1026
+ return [createBranchingListDeleteKeymap(this.name, [this.options.taskListTypeName])];
914
1027
  },
915
1028
  addKeyboardShortcuts() {
916
1029
  const shortcuts = {
@@ -988,7 +1101,7 @@ var TaskItem = import_core10.Node.create({
988
1101
  checkbox.checked = updatedNode.attrs.checked;
989
1102
  updateA11Y(updatedNode);
990
1103
  const extensionAttributes = editor.extensionManager.attributes;
991
- const newHTMLAttributes = (0, import_core10.getRenderedAttributes)(updatedNode, extensionAttributes);
1104
+ const newHTMLAttributes = (0, import_core11.getRenderedAttributes)(updatedNode, extensionAttributes);
992
1105
  const newKeys = new Set(Object.keys(newHTMLAttributes));
993
1106
  const staticAttrs = this.options.HTMLAttributes;
994
1107
  prevRenderedAttributeKeys.forEach((key) => {
@@ -1019,7 +1132,7 @@ var TaskItem = import_core10.Node.create({
1019
1132
  },
1020
1133
  addInputRules() {
1021
1134
  return [
1022
- (0, import_core10.wrappingInputRule)({
1135
+ (0, import_core11.wrappingInputRule)({
1023
1136
  find: inputRegex,
1024
1137
  type: this.type,
1025
1138
  getAttributes: (match) => ({
@@ -1031,8 +1144,8 @@ var TaskItem = import_core10.Node.create({
1031
1144
  });
1032
1145
 
1033
1146
  // src/task-list/task-list.ts
1034
- var import_core11 = require("@tiptap/core");
1035
- var TaskList = import_core11.Node.create({
1147
+ var import_core12 = require("@tiptap/core");
1148
+ var TaskList = import_core12.Node.create({
1036
1149
  name: "taskList",
1037
1150
  addOptions() {
1038
1151
  return {
@@ -1055,7 +1168,7 @@ var TaskList = import_core11.Node.create({
1055
1168
  renderHTML({ HTMLAttributes }) {
1056
1169
  return [
1057
1170
  "ul",
1058
- (0, import_core11.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }),
1171
+ (0, import_core12.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }),
1059
1172
  0
1060
1173
  ];
1061
1174
  },
@@ -1078,7 +1191,7 @@ var TaskList = import_core11.Node.create({
1078
1191
  },
1079
1192
  tokenize(src, tokens, lexer) {
1080
1193
  const parseTaskListContent = (content) => {
1081
- const nestedResult = (0, import_core11.parseIndentedBlocks)(
1194
+ const nestedResult = (0, import_core12.parseIndentedBlocks)(
1082
1195
  content,
1083
1196
  {
1084
1197
  itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
@@ -1113,7 +1226,7 @@ var TaskList = import_core11.Node.create({
1113
1226
  }
1114
1227
  return lexer.blockTokens(content);
1115
1228
  };
1116
- const result = (0, import_core11.parseIndentedBlocks)(
1229
+ const result = (0, import_core12.parseIndentedBlocks)(
1117
1230
  src,
1118
1231
  {
1119
1232
  itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
@@ -1165,7 +1278,7 @@ var TaskList = import_core11.Node.create({
1165
1278
  });
1166
1279
 
1167
1280
  // src/kit/index.ts
1168
- var ListKit = import_core12.Extension.create({
1281
+ var ListKit = import_core13.Extension.create({
1169
1282
  name: "listKit",
1170
1283
  addExtensions() {
1171
1284
  const extensions = [];