fix: resolve TypeScript errors in frontend build
This commit is contained in:
21
node_modules/@tiptap/extension-list/LICENSE.md
generated
vendored
Normal file
21
node_modules/@tiptap/extension-list/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025, Tiptap GmbH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
18
node_modules/@tiptap/extension-list/README.md
generated
vendored
Normal file
18
node_modules/@tiptap/extension-list/README.md
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# @tiptap/extension-list
|
||||
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-list)
|
||||
[](https://npmcharts.com/compare/tiptap?minimal=true)
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-list)
|
||||
[](https://github.com/sponsors/ueberdosis)
|
||||
|
||||
## Introduction
|
||||
|
||||
Tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as _New York Times_, _The Guardian_ or _Atlassian_.
|
||||
|
||||
## Official Documentation
|
||||
|
||||
Documentation can be found on the [Tiptap website](https://tiptap.dev).
|
||||
|
||||
## License
|
||||
|
||||
Tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md).
|
||||
112
node_modules/@tiptap/extension-list/dist/bullet-list/index.cjs
generated
vendored
Normal file
112
node_modules/@tiptap/extension-list/dist/bullet-list/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/bullet-list/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
BulletList: () => BulletList,
|
||||
bulletListInputRegex: () => bulletListInputRegex
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/bullet-list/bullet-list.ts
|
||||
var import_core = require("@tiptap/core");
|
||||
var ListItemName = "listItem";
|
||||
var TextStyleName = "textStyle";
|
||||
var bulletListInputRegex = /^\s*([-+*])\s$/;
|
||||
var BulletList = import_core.Node.create({
|
||||
name: "bulletList",
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: "listItem",
|
||||
HTMLAttributes: {},
|
||||
keepMarks: false,
|
||||
keepAttributes: false
|
||||
};
|
||||
},
|
||||
group: "block list",
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`;
|
||||
},
|
||||
parseHTML() {
|
||||
return [{ tag: "ul" }];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ["ul", (0, import_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
markdownTokenName: "list",
|
||||
parseMarkdown: (token, helpers) => {
|
||||
if (token.type !== "list" || token.ordered) {
|
||||
return [];
|
||||
}
|
||||
return {
|
||||
type: "bulletList",
|
||||
content: token.items ? helpers.parseChildren(token.items) : []
|
||||
};
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return "";
|
||||
}
|
||||
return h.renderChildren(node.content, "\n");
|
||||
},
|
||||
markdownOptions: {
|
||||
indentsContent: true
|
||||
},
|
||||
addCommands() {
|
||||
return {
|
||||
toggleBulletList: () => ({ commands, chain }) => {
|
||||
if (this.options.keepAttributes) {
|
||||
return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run();
|
||||
}
|
||||
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
|
||||
}
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
"Mod-Shift-8": () => this.editor.commands.toggleBulletList()
|
||||
};
|
||||
},
|
||||
addInputRules() {
|
||||
let inputRule = (0, import_core.wrappingInputRule)({
|
||||
find: bulletListInputRegex,
|
||||
type: this.type
|
||||
});
|
||||
if (this.options.keepMarks || this.options.keepAttributes) {
|
||||
inputRule = (0, import_core.wrappingInputRule)({
|
||||
find: bulletListInputRegex,
|
||||
type: this.type,
|
||||
keepMarks: this.options.keepMarks,
|
||||
keepAttributes: this.options.keepAttributes,
|
||||
getAttributes: () => {
|
||||
return this.editor.getAttributes(TextStyleName);
|
||||
},
|
||||
editor: this.editor
|
||||
});
|
||||
}
|
||||
return [inputRule];
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BulletList,
|
||||
bulletListInputRegex
|
||||
});
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@tiptap/extension-list/dist/bullet-list/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/bullet-list/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
51
node_modules/@tiptap/extension-list/dist/bullet-list/index.d.cts
generated
vendored
Normal file
51
node_modules/@tiptap/extension-list/dist/bullet-list/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface BulletListOptions {
|
||||
/**
|
||||
* The node name for the list items
|
||||
* @default 'listItem'
|
||||
* @example 'paragraph'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* HTML attributes to add to the bullet list element
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
bulletList: {
|
||||
/**
|
||||
* Toggle a bullet list
|
||||
*/
|
||||
toggleBulletList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches a bullet list to a dash or asterisk.
|
||||
*/
|
||||
declare const bulletListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create bullet lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://tiptap.dev/api/nodes/bullet-list
|
||||
* @see https://tiptap.dev/api/nodes/list-item.
|
||||
*/
|
||||
declare const BulletList: Node<BulletListOptions, any>;
|
||||
|
||||
export { BulletList, type BulletListOptions, bulletListInputRegex };
|
||||
51
node_modules/@tiptap/extension-list/dist/bullet-list/index.d.ts
generated
vendored
Normal file
51
node_modules/@tiptap/extension-list/dist/bullet-list/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface BulletListOptions {
|
||||
/**
|
||||
* The node name for the list items
|
||||
* @default 'listItem'
|
||||
* @example 'paragraph'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* HTML attributes to add to the bullet list element
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
bulletList: {
|
||||
/**
|
||||
* Toggle a bullet list
|
||||
*/
|
||||
toggleBulletList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches a bullet list to a dash or asterisk.
|
||||
*/
|
||||
declare const bulletListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create bullet lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://tiptap.dev/api/nodes/bullet-list
|
||||
* @see https://tiptap.dev/api/nodes/list-item.
|
||||
*/
|
||||
declare const BulletList: Node<BulletListOptions, any>;
|
||||
|
||||
export { BulletList, type BulletListOptions, bulletListInputRegex };
|
||||
84
node_modules/@tiptap/extension-list/dist/bullet-list/index.js
generated
vendored
Normal file
84
node_modules/@tiptap/extension-list/dist/bullet-list/index.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// src/bullet-list/bullet-list.ts
|
||||
import { mergeAttributes, Node, wrappingInputRule } from "@tiptap/core";
|
||||
var ListItemName = "listItem";
|
||||
var TextStyleName = "textStyle";
|
||||
var bulletListInputRegex = /^\s*([-+*])\s$/;
|
||||
var BulletList = Node.create({
|
||||
name: "bulletList",
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: "listItem",
|
||||
HTMLAttributes: {},
|
||||
keepMarks: false,
|
||||
keepAttributes: false
|
||||
};
|
||||
},
|
||||
group: "block list",
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`;
|
||||
},
|
||||
parseHTML() {
|
||||
return [{ tag: "ul" }];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ["ul", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
markdownTokenName: "list",
|
||||
parseMarkdown: (token, helpers) => {
|
||||
if (token.type !== "list" || token.ordered) {
|
||||
return [];
|
||||
}
|
||||
return {
|
||||
type: "bulletList",
|
||||
content: token.items ? helpers.parseChildren(token.items) : []
|
||||
};
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return "";
|
||||
}
|
||||
return h.renderChildren(node.content, "\n");
|
||||
},
|
||||
markdownOptions: {
|
||||
indentsContent: true
|
||||
},
|
||||
addCommands() {
|
||||
return {
|
||||
toggleBulletList: () => ({ commands, chain }) => {
|
||||
if (this.options.keepAttributes) {
|
||||
return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run();
|
||||
}
|
||||
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
|
||||
}
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
"Mod-Shift-8": () => this.editor.commands.toggleBulletList()
|
||||
};
|
||||
},
|
||||
addInputRules() {
|
||||
let inputRule = wrappingInputRule({
|
||||
find: bulletListInputRegex,
|
||||
type: this.type
|
||||
});
|
||||
if (this.options.keepMarks || this.options.keepAttributes) {
|
||||
inputRule = wrappingInputRule({
|
||||
find: bulletListInputRegex,
|
||||
type: this.type,
|
||||
keepMarks: this.options.keepMarks,
|
||||
keepAttributes: this.options.keepAttributes,
|
||||
getAttributes: () => {
|
||||
return this.editor.getAttributes(TextStyleName);
|
||||
},
|
||||
editor: this.editor
|
||||
});
|
||||
}
|
||||
return [inputRule];
|
||||
}
|
||||
});
|
||||
export {
|
||||
BulletList,
|
||||
bulletListInputRegex
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@tiptap/extension-list/dist/bullet-list/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/bullet-list/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1130
node_modules/@tiptap/extension-list/dist/index.cjs
generated
vendored
Normal file
1130
node_modules/@tiptap/extension-list/dist/index.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@tiptap/extension-list/dist/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
300
node_modules/@tiptap/extension-list/dist/index.d.cts
generated
vendored
Normal file
300
node_modules/@tiptap/extension-list/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
import { Node, Extension, Editor } from '@tiptap/core';
|
||||
import * as prosemirror_model from 'prosemirror-model';
|
||||
import { NodeType, Node as Node$1 } from '@tiptap/pm/model';
|
||||
import { EditorState } from '@tiptap/pm/state';
|
||||
|
||||
interface BulletListOptions {
|
||||
/**
|
||||
* The node name for the list items
|
||||
* @default 'listItem'
|
||||
* @example 'paragraph'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* HTML attributes to add to the bullet list element
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
bulletList: {
|
||||
/**
|
||||
* Toggle a bullet list
|
||||
*/
|
||||
toggleBulletList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches a bullet list to a dash or asterisk.
|
||||
*/
|
||||
declare const bulletListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create bullet lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://tiptap.dev/api/nodes/bullet-list
|
||||
* @see https://tiptap.dev/api/nodes/list-item.
|
||||
*/
|
||||
declare const BulletList: Node<BulletListOptions, any>;
|
||||
|
||||
interface ListItemOptions {
|
||||
/**
|
||||
* The HTML attributes for a list item node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for bulletList nodes
|
||||
* @default 'bulletList'
|
||||
* @example 'myCustomBulletList'
|
||||
*/
|
||||
bulletListTypeName: string;
|
||||
/**
|
||||
* The node type for orderedList nodes
|
||||
* @default 'orderedList'
|
||||
* @example 'myCustomOrderedList'
|
||||
*/
|
||||
orderedListTypeName: string;
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create list items.
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const ListItem: Node<ListItemOptions, any>;
|
||||
|
||||
type ListKeymapOptions = {
|
||||
/**
|
||||
* An array of list types. This is used for item and wrapper list matching.
|
||||
* @default []
|
||||
* @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]
|
||||
*/
|
||||
listTypes: Array<{
|
||||
itemName: string;
|
||||
wrapperNames: string[];
|
||||
}>;
|
||||
};
|
||||
/**
|
||||
* This extension registers custom keymaps to change the behaviour of the backspace and delete keys.
|
||||
* By default Prosemirror keyhandling will always lift or sink items so paragraphs are joined into
|
||||
* the adjacent or previous list item. This extension will prevent this behaviour and instead will
|
||||
* try to join paragraphs from two list items into a single list item.
|
||||
* @see https://www.tiptap.dev/api/extensions/list-keymap
|
||||
*/
|
||||
declare const ListKeymap: Extension<ListKeymapOptions, any>;
|
||||
|
||||
declare const findListItemPos: (typeOrName: string | NodeType, state: EditorState) => {
|
||||
$pos: prosemirror_model.ResolvedPos;
|
||||
depth: number;
|
||||
} | null;
|
||||
|
||||
declare const getNextListDepth: (typeOrName: string, state: EditorState) => number | false;
|
||||
|
||||
declare const handleBackspace: (editor: Editor, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const handleDelete: (editor: Editor, name: string) => boolean;
|
||||
|
||||
declare const hasListBefore: (editorState: EditorState, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const hasListItemAfter: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const hasListItemBefore: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const listItemHasSubList: (typeOrName: string, state: EditorState, node?: Node$1) => boolean;
|
||||
|
||||
declare const nextListIsDeeper: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const nextListIsHigher: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const index_findListItemPos: typeof findListItemPos;
|
||||
declare const index_getNextListDepth: typeof getNextListDepth;
|
||||
declare const index_handleBackspace: typeof handleBackspace;
|
||||
declare const index_handleDelete: typeof handleDelete;
|
||||
declare const index_hasListBefore: typeof hasListBefore;
|
||||
declare const index_hasListItemAfter: typeof hasListItemAfter;
|
||||
declare const index_hasListItemBefore: typeof hasListItemBefore;
|
||||
declare const index_listItemHasSubList: typeof listItemHasSubList;
|
||||
declare const index_nextListIsDeeper: typeof nextListIsDeeper;
|
||||
declare const index_nextListIsHigher: typeof nextListIsHigher;
|
||||
declare namespace index {
|
||||
export { index_findListItemPos as findListItemPos, index_getNextListDepth as getNextListDepth, index_handleBackspace as handleBackspace, index_handleDelete as handleDelete, index_hasListBefore as hasListBefore, index_hasListItemAfter as hasListItemAfter, index_hasListItemBefore as hasListItemBefore, index_listItemHasSubList as listItemHasSubList, index_nextListIsDeeper as nextListIsDeeper, index_nextListIsHigher as nextListIsHigher };
|
||||
}
|
||||
|
||||
interface OrderedListOptions {
|
||||
/**
|
||||
* The node type name for list items.
|
||||
* @default 'listItem'
|
||||
* @example 'myListItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for an ordered list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
orderedList: {
|
||||
/**
|
||||
* Toggle an ordered list
|
||||
* @example editor.commands.toggleOrderedList()
|
||||
*/
|
||||
toggleOrderedList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches an ordered list to a 1. on input (or any number followed by a dot).
|
||||
*/
|
||||
declare const orderedListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create ordered lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://www.tiptap.dev/api/nodes/ordered-list
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const OrderedList: Node<OrderedListOptions, any>;
|
||||
|
||||
interface TaskItemOptions {
|
||||
/**
|
||||
* A callback function that is called when the checkbox is clicked while the editor is in readonly mode.
|
||||
* @param node The prosemirror node of the task item
|
||||
* @param checked The new checked state
|
||||
* @returns boolean
|
||||
*/
|
||||
onReadOnlyChecked?: (node: Node$1, checked: boolean) => boolean;
|
||||
/**
|
||||
* Controls whether the task items can be nested or not.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
nested: boolean;
|
||||
/**
|
||||
* HTML attributes to add to the task item element.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for taskList nodes
|
||||
* @default 'taskList'
|
||||
* @example 'myCustomTaskList'
|
||||
*/
|
||||
taskListTypeName: string;
|
||||
/**
|
||||
* Accessibility options for the task item.
|
||||
* @default {}
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
|
||||
* }
|
||||
*/
|
||||
a11y?: {
|
||||
checkboxLabel?: (node: Node$1, checked: boolean) => string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Matches a task item to a - [ ] on input.
|
||||
*/
|
||||
declare const inputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create task items.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-item
|
||||
*/
|
||||
declare const TaskItem: Node<TaskItemOptions, any>;
|
||||
|
||||
interface TaskListOptions {
|
||||
/**
|
||||
* The node type name for a task item.
|
||||
* @default 'taskItem'
|
||||
* @example 'myCustomTaskItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for a task list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
taskList: {
|
||||
/**
|
||||
* Toggle a task list
|
||||
* @example editor.commands.toggleTaskList()
|
||||
*/
|
||||
toggleTaskList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create task lists.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-list
|
||||
*/
|
||||
declare const TaskList: Node<TaskListOptions, any>;
|
||||
|
||||
interface ListKitOptions {
|
||||
/**
|
||||
* If set to false, the bulletList extension will not be registered
|
||||
* @example table: false
|
||||
*/
|
||||
bulletList: Partial<BulletListOptions> | false;
|
||||
/**
|
||||
* If set to false, the listItem extension will not be registered
|
||||
*/
|
||||
listItem: Partial<ListItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the listKeymap extension will not be registered
|
||||
*/
|
||||
listKeymap: Partial<ListKeymapOptions> | false;
|
||||
/**
|
||||
* If set to false, the orderedList extension will not be registered
|
||||
*/
|
||||
orderedList: Partial<OrderedListOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskItem extension will not be registered
|
||||
*/
|
||||
taskItem: Partial<TaskItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskList extension will not be registered
|
||||
*/
|
||||
taskList: Partial<TaskListOptions> | false;
|
||||
}
|
||||
/**
|
||||
* The table kit is a collection of table editor extensions.
|
||||
*
|
||||
* It’s a good starting point for building your own table in Tiptap.
|
||||
*/
|
||||
declare const ListKit: Extension<ListKitOptions, any>;
|
||||
|
||||
export { BulletList, type BulletListOptions, ListItem, type ListItemOptions, ListKeymap, type ListKeymapOptions, ListKit, type ListKitOptions, OrderedList, type OrderedListOptions, TaskItem, type TaskItemOptions, TaskList, type TaskListOptions, bulletListInputRegex, inputRegex, index as listHelpers, orderedListInputRegex };
|
||||
300
node_modules/@tiptap/extension-list/dist/index.d.ts
generated
vendored
Normal file
300
node_modules/@tiptap/extension-list/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
import { Node, Extension, Editor } from '@tiptap/core';
|
||||
import * as prosemirror_model from 'prosemirror-model';
|
||||
import { NodeType, Node as Node$1 } from '@tiptap/pm/model';
|
||||
import { EditorState } from '@tiptap/pm/state';
|
||||
|
||||
interface BulletListOptions {
|
||||
/**
|
||||
* The node name for the list items
|
||||
* @default 'listItem'
|
||||
* @example 'paragraph'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* HTML attributes to add to the bullet list element
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
bulletList: {
|
||||
/**
|
||||
* Toggle a bullet list
|
||||
*/
|
||||
toggleBulletList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches a bullet list to a dash or asterisk.
|
||||
*/
|
||||
declare const bulletListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create bullet lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://tiptap.dev/api/nodes/bullet-list
|
||||
* @see https://tiptap.dev/api/nodes/list-item.
|
||||
*/
|
||||
declare const BulletList: Node<BulletListOptions, any>;
|
||||
|
||||
interface ListItemOptions {
|
||||
/**
|
||||
* The HTML attributes for a list item node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for bulletList nodes
|
||||
* @default 'bulletList'
|
||||
* @example 'myCustomBulletList'
|
||||
*/
|
||||
bulletListTypeName: string;
|
||||
/**
|
||||
* The node type for orderedList nodes
|
||||
* @default 'orderedList'
|
||||
* @example 'myCustomOrderedList'
|
||||
*/
|
||||
orderedListTypeName: string;
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create list items.
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const ListItem: Node<ListItemOptions, any>;
|
||||
|
||||
type ListKeymapOptions = {
|
||||
/**
|
||||
* An array of list types. This is used for item and wrapper list matching.
|
||||
* @default []
|
||||
* @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]
|
||||
*/
|
||||
listTypes: Array<{
|
||||
itemName: string;
|
||||
wrapperNames: string[];
|
||||
}>;
|
||||
};
|
||||
/**
|
||||
* This extension registers custom keymaps to change the behaviour of the backspace and delete keys.
|
||||
* By default Prosemirror keyhandling will always lift or sink items so paragraphs are joined into
|
||||
* the adjacent or previous list item. This extension will prevent this behaviour and instead will
|
||||
* try to join paragraphs from two list items into a single list item.
|
||||
* @see https://www.tiptap.dev/api/extensions/list-keymap
|
||||
*/
|
||||
declare const ListKeymap: Extension<ListKeymapOptions, any>;
|
||||
|
||||
declare const findListItemPos: (typeOrName: string | NodeType, state: EditorState) => {
|
||||
$pos: prosemirror_model.ResolvedPos;
|
||||
depth: number;
|
||||
} | null;
|
||||
|
||||
declare const getNextListDepth: (typeOrName: string, state: EditorState) => number | false;
|
||||
|
||||
declare const handleBackspace: (editor: Editor, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const handleDelete: (editor: Editor, name: string) => boolean;
|
||||
|
||||
declare const hasListBefore: (editorState: EditorState, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const hasListItemAfter: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const hasListItemBefore: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const listItemHasSubList: (typeOrName: string, state: EditorState, node?: Node$1) => boolean;
|
||||
|
||||
declare const nextListIsDeeper: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const nextListIsHigher: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const index_findListItemPos: typeof findListItemPos;
|
||||
declare const index_getNextListDepth: typeof getNextListDepth;
|
||||
declare const index_handleBackspace: typeof handleBackspace;
|
||||
declare const index_handleDelete: typeof handleDelete;
|
||||
declare const index_hasListBefore: typeof hasListBefore;
|
||||
declare const index_hasListItemAfter: typeof hasListItemAfter;
|
||||
declare const index_hasListItemBefore: typeof hasListItemBefore;
|
||||
declare const index_listItemHasSubList: typeof listItemHasSubList;
|
||||
declare const index_nextListIsDeeper: typeof nextListIsDeeper;
|
||||
declare const index_nextListIsHigher: typeof nextListIsHigher;
|
||||
declare namespace index {
|
||||
export { index_findListItemPos as findListItemPos, index_getNextListDepth as getNextListDepth, index_handleBackspace as handleBackspace, index_handleDelete as handleDelete, index_hasListBefore as hasListBefore, index_hasListItemAfter as hasListItemAfter, index_hasListItemBefore as hasListItemBefore, index_listItemHasSubList as listItemHasSubList, index_nextListIsDeeper as nextListIsDeeper, index_nextListIsHigher as nextListIsHigher };
|
||||
}
|
||||
|
||||
interface OrderedListOptions {
|
||||
/**
|
||||
* The node type name for list items.
|
||||
* @default 'listItem'
|
||||
* @example 'myListItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for an ordered list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
orderedList: {
|
||||
/**
|
||||
* Toggle an ordered list
|
||||
* @example editor.commands.toggleOrderedList()
|
||||
*/
|
||||
toggleOrderedList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches an ordered list to a 1. on input (or any number followed by a dot).
|
||||
*/
|
||||
declare const orderedListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create ordered lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://www.tiptap.dev/api/nodes/ordered-list
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const OrderedList: Node<OrderedListOptions, any>;
|
||||
|
||||
interface TaskItemOptions {
|
||||
/**
|
||||
* A callback function that is called when the checkbox is clicked while the editor is in readonly mode.
|
||||
* @param node The prosemirror node of the task item
|
||||
* @param checked The new checked state
|
||||
* @returns boolean
|
||||
*/
|
||||
onReadOnlyChecked?: (node: Node$1, checked: boolean) => boolean;
|
||||
/**
|
||||
* Controls whether the task items can be nested or not.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
nested: boolean;
|
||||
/**
|
||||
* HTML attributes to add to the task item element.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for taskList nodes
|
||||
* @default 'taskList'
|
||||
* @example 'myCustomTaskList'
|
||||
*/
|
||||
taskListTypeName: string;
|
||||
/**
|
||||
* Accessibility options for the task item.
|
||||
* @default {}
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
|
||||
* }
|
||||
*/
|
||||
a11y?: {
|
||||
checkboxLabel?: (node: Node$1, checked: boolean) => string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Matches a task item to a - [ ] on input.
|
||||
*/
|
||||
declare const inputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create task items.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-item
|
||||
*/
|
||||
declare const TaskItem: Node<TaskItemOptions, any>;
|
||||
|
||||
interface TaskListOptions {
|
||||
/**
|
||||
* The node type name for a task item.
|
||||
* @default 'taskItem'
|
||||
* @example 'myCustomTaskItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for a task list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
taskList: {
|
||||
/**
|
||||
* Toggle a task list
|
||||
* @example editor.commands.toggleTaskList()
|
||||
*/
|
||||
toggleTaskList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create task lists.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-list
|
||||
*/
|
||||
declare const TaskList: Node<TaskListOptions, any>;
|
||||
|
||||
interface ListKitOptions {
|
||||
/**
|
||||
* If set to false, the bulletList extension will not be registered
|
||||
* @example table: false
|
||||
*/
|
||||
bulletList: Partial<BulletListOptions> | false;
|
||||
/**
|
||||
* If set to false, the listItem extension will not be registered
|
||||
*/
|
||||
listItem: Partial<ListItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the listKeymap extension will not be registered
|
||||
*/
|
||||
listKeymap: Partial<ListKeymapOptions> | false;
|
||||
/**
|
||||
* If set to false, the orderedList extension will not be registered
|
||||
*/
|
||||
orderedList: Partial<OrderedListOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskItem extension will not be registered
|
||||
*/
|
||||
taskItem: Partial<TaskItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskList extension will not be registered
|
||||
*/
|
||||
taskList: Partial<TaskListOptions> | false;
|
||||
}
|
||||
/**
|
||||
* The table kit is a collection of table editor extensions.
|
||||
*
|
||||
* It’s a good starting point for building your own table in Tiptap.
|
||||
*/
|
||||
declare const ListKit: Extension<ListKitOptions, any>;
|
||||
|
||||
export { BulletList, type BulletListOptions, ListItem, type ListItemOptions, ListKeymap, type ListKeymapOptions, ListKit, type ListKitOptions, OrderedList, type OrderedListOptions, TaskItem, type TaskItemOptions, TaskList, type TaskListOptions, bulletListInputRegex, inputRegex, index as listHelpers, orderedListInputRegex };
|
||||
1105
node_modules/@tiptap/extension-list/dist/index.js
generated
vendored
Normal file
1105
node_modules/@tiptap/extension-list/dist/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@tiptap/extension-list/dist/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
125
node_modules/@tiptap/extension-list/dist/item/index.cjs
generated
vendored
Normal file
125
node_modules/@tiptap/extension-list/dist/item/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/item/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
ListItem: () => ListItem
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/item/list-item.ts
|
||||
var import_core = require("@tiptap/core");
|
||||
var ListItem = import_core.Node.create({
|
||||
name: "listItem",
|
||||
addOptions() {
|
||||
return {
|
||||
HTMLAttributes: {},
|
||||
bulletListTypeName: "bulletList",
|
||||
orderedListTypeName: "orderedList"
|
||||
};
|
||||
},
|
||||
content: "paragraph block*",
|
||||
defining: true,
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: "li"
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ["li", (0, import_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
markdownTokenName: "list_item",
|
||||
parseMarkdown: (token, helpers) => {
|
||||
var _a;
|
||||
if (token.type !== "list_item") {
|
||||
return [];
|
||||
}
|
||||
const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren;
|
||||
let content = [];
|
||||
if (token.tokens && token.tokens.length > 0) {
|
||||
const hasParagraphTokens = token.tokens.some((t) => t.type === "paragraph");
|
||||
if (hasParagraphTokens) {
|
||||
content = parseBlockChildren(token.tokens);
|
||||
} else {
|
||||
const firstToken = token.tokens[0];
|
||||
if (firstToken && firstToken.type === "text" && firstToken.tokens && firstToken.tokens.length > 0) {
|
||||
const inlineContent = helpers.parseInline(firstToken.tokens);
|
||||
content = [
|
||||
{
|
||||
type: "paragraph",
|
||||
content: inlineContent
|
||||
}
|
||||
];
|
||||
if (token.tokens.length > 1) {
|
||||
const remainingTokens = token.tokens.slice(1);
|
||||
const additionalContent = parseBlockChildren(remainingTokens);
|
||||
content.push(...additionalContent);
|
||||
}
|
||||
} else {
|
||||
content = parseBlockChildren(token.tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (content.length === 0) {
|
||||
content = [
|
||||
{
|
||||
type: "paragraph",
|
||||
content: []
|
||||
}
|
||||
];
|
||||
}
|
||||
return {
|
||||
type: "listItem",
|
||||
content
|
||||
};
|
||||
},
|
||||
renderMarkdown: (node, h, ctx) => {
|
||||
return (0, import_core.renderNestedMarkdownContent)(
|
||||
node,
|
||||
h,
|
||||
(context) => {
|
||||
var _a, _b;
|
||||
if (context.parentType === "bulletList") {
|
||||
return "- ";
|
||||
}
|
||||
if (context.parentType === "orderedList") {
|
||||
const start = ((_b = (_a = context.meta) == null ? void 0 : _a.parentAttrs) == null ? void 0 : _b.start) || 1;
|
||||
return `${start + context.index}. `;
|
||||
}
|
||||
return "- ";
|
||||
},
|
||||
ctx
|
||||
);
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Enter: () => this.editor.commands.splitListItem(this.name),
|
||||
Tab: () => this.editor.commands.sinkListItem(this.name),
|
||||
"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
|
||||
};
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ListItem
|
||||
});
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@tiptap/extension-list/dist/item/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/item/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
29
node_modules/@tiptap/extension-list/dist/item/index.d.cts
generated
vendored
Normal file
29
node_modules/@tiptap/extension-list/dist/item/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface ListItemOptions {
|
||||
/**
|
||||
* The HTML attributes for a list item node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for bulletList nodes
|
||||
* @default 'bulletList'
|
||||
* @example 'myCustomBulletList'
|
||||
*/
|
||||
bulletListTypeName: string;
|
||||
/**
|
||||
* The node type for orderedList nodes
|
||||
* @default 'orderedList'
|
||||
* @example 'myCustomOrderedList'
|
||||
*/
|
||||
orderedListTypeName: string;
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create list items.
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const ListItem: Node<ListItemOptions, any>;
|
||||
|
||||
export { ListItem, type ListItemOptions };
|
||||
29
node_modules/@tiptap/extension-list/dist/item/index.d.ts
generated
vendored
Normal file
29
node_modules/@tiptap/extension-list/dist/item/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface ListItemOptions {
|
||||
/**
|
||||
* The HTML attributes for a list item node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for bulletList nodes
|
||||
* @default 'bulletList'
|
||||
* @example 'myCustomBulletList'
|
||||
*/
|
||||
bulletListTypeName: string;
|
||||
/**
|
||||
* The node type for orderedList nodes
|
||||
* @default 'orderedList'
|
||||
* @example 'myCustomOrderedList'
|
||||
*/
|
||||
orderedListTypeName: string;
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create list items.
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const ListItem: Node<ListItemOptions, any>;
|
||||
|
||||
export { ListItem, type ListItemOptions };
|
||||
98
node_modules/@tiptap/extension-list/dist/item/index.js
generated
vendored
Normal file
98
node_modules/@tiptap/extension-list/dist/item/index.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// src/item/list-item.ts
|
||||
import { mergeAttributes, Node, renderNestedMarkdownContent } from "@tiptap/core";
|
||||
var ListItem = Node.create({
|
||||
name: "listItem",
|
||||
addOptions() {
|
||||
return {
|
||||
HTMLAttributes: {},
|
||||
bulletListTypeName: "bulletList",
|
||||
orderedListTypeName: "orderedList"
|
||||
};
|
||||
},
|
||||
content: "paragraph block*",
|
||||
defining: true,
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: "li"
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ["li", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
markdownTokenName: "list_item",
|
||||
parseMarkdown: (token, helpers) => {
|
||||
var _a;
|
||||
if (token.type !== "list_item") {
|
||||
return [];
|
||||
}
|
||||
const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren;
|
||||
let content = [];
|
||||
if (token.tokens && token.tokens.length > 0) {
|
||||
const hasParagraphTokens = token.tokens.some((t) => t.type === "paragraph");
|
||||
if (hasParagraphTokens) {
|
||||
content = parseBlockChildren(token.tokens);
|
||||
} else {
|
||||
const firstToken = token.tokens[0];
|
||||
if (firstToken && firstToken.type === "text" && firstToken.tokens && firstToken.tokens.length > 0) {
|
||||
const inlineContent = helpers.parseInline(firstToken.tokens);
|
||||
content = [
|
||||
{
|
||||
type: "paragraph",
|
||||
content: inlineContent
|
||||
}
|
||||
];
|
||||
if (token.tokens.length > 1) {
|
||||
const remainingTokens = token.tokens.slice(1);
|
||||
const additionalContent = parseBlockChildren(remainingTokens);
|
||||
content.push(...additionalContent);
|
||||
}
|
||||
} else {
|
||||
content = parseBlockChildren(token.tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (content.length === 0) {
|
||||
content = [
|
||||
{
|
||||
type: "paragraph",
|
||||
content: []
|
||||
}
|
||||
];
|
||||
}
|
||||
return {
|
||||
type: "listItem",
|
||||
content
|
||||
};
|
||||
},
|
||||
renderMarkdown: (node, h, ctx) => {
|
||||
return renderNestedMarkdownContent(
|
||||
node,
|
||||
h,
|
||||
(context) => {
|
||||
var _a, _b;
|
||||
if (context.parentType === "bulletList") {
|
||||
return "- ";
|
||||
}
|
||||
if (context.parentType === "orderedList") {
|
||||
const start = ((_b = (_a = context.meta) == null ? void 0 : _a.parentAttrs) == null ? void 0 : _b.start) || 1;
|
||||
return `${start + context.index}. `;
|
||||
}
|
||||
return "- ";
|
||||
},
|
||||
ctx
|
||||
);
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Enter: () => this.editor.commands.splitListItem(this.name),
|
||||
Tab: () => this.editor.commands.sinkListItem(this.name),
|
||||
"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
|
||||
};
|
||||
}
|
||||
});
|
||||
export {
|
||||
ListItem
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@tiptap/extension-list/dist/item/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/item/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
308
node_modules/@tiptap/extension-list/dist/keymap/index.cjs
generated
vendored
Normal file
308
node_modules/@tiptap/extension-list/dist/keymap/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/keymap/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
ListKeymap: () => ListKeymap,
|
||||
listHelpers: () => listHelpers_exports
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/keymap/list-keymap.ts
|
||||
var import_core6 = require("@tiptap/core");
|
||||
|
||||
// src/keymap/listHelpers/index.ts
|
||||
var listHelpers_exports = {};
|
||||
__export(listHelpers_exports, {
|
||||
findListItemPos: () => findListItemPos,
|
||||
getNextListDepth: () => getNextListDepth,
|
||||
handleBackspace: () => handleBackspace,
|
||||
handleDelete: () => handleDelete,
|
||||
hasListBefore: () => hasListBefore,
|
||||
hasListItemAfter: () => hasListItemAfter,
|
||||
hasListItemBefore: () => hasListItemBefore,
|
||||
listItemHasSubList: () => listItemHasSubList,
|
||||
nextListIsDeeper: () => nextListIsDeeper,
|
||||
nextListIsHigher: () => nextListIsHigher
|
||||
});
|
||||
|
||||
// src/keymap/listHelpers/findListItemPos.ts
|
||||
var import_core = require("@tiptap/core");
|
||||
var findListItemPos = (typeOrName, state) => {
|
||||
const { $from } = state.selection;
|
||||
const nodeType = (0, import_core.getNodeType)(typeOrName, state.schema);
|
||||
let currentNode = null;
|
||||
let currentDepth = $from.depth;
|
||||
let currentPos = $from.pos;
|
||||
let targetDepth = null;
|
||||
while (currentDepth > 0 && targetDepth === null) {
|
||||
currentNode = $from.node(currentDepth);
|
||||
if (currentNode.type === nodeType) {
|
||||
targetDepth = currentDepth;
|
||||
} else {
|
||||
currentDepth -= 1;
|
||||
currentPos -= 1;
|
||||
}
|
||||
}
|
||||
if (targetDepth === null) {
|
||||
return null;
|
||||
}
|
||||
return { $pos: state.doc.resolve(currentPos), depth: targetDepth };
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/getNextListDepth.ts
|
||||
var import_core2 = require("@tiptap/core");
|
||||
var getNextListDepth = (typeOrName, state) => {
|
||||
const listItemPos = findListItemPos(typeOrName, state);
|
||||
if (!listItemPos) {
|
||||
return false;
|
||||
}
|
||||
const [, depth] = (0, import_core2.getNodeAtPosition)(state, typeOrName, listItemPos.$pos.pos + 4);
|
||||
return depth;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleBackspace.ts
|
||||
var import_core4 = require("@tiptap/core");
|
||||
|
||||
// src/keymap/listHelpers/hasListBefore.ts
|
||||
var hasListBefore = (editorState, name, parentListTypes) => {
|
||||
const { $anchor } = editorState.selection;
|
||||
const previousNodePos = Math.max(0, $anchor.pos - 2);
|
||||
const previousNode = editorState.doc.resolve(previousNodePos).node();
|
||||
if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/hasListItemBefore.ts
|
||||
var hasListItemBefore = (typeOrName, state) => {
|
||||
var _a;
|
||||
const { $anchor } = state.selection;
|
||||
const $targetPos = state.doc.resolve($anchor.pos - 2);
|
||||
if ($targetPos.index() === 0) {
|
||||
return false;
|
||||
}
|
||||
if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/listItemHasSubList.ts
|
||||
var import_core3 = require("@tiptap/core");
|
||||
var listItemHasSubList = (typeOrName, state, node) => {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
const nodeType = (0, import_core3.getNodeType)(typeOrName, state.schema);
|
||||
let hasSubList = false;
|
||||
node.descendants((child) => {
|
||||
if (child.type === nodeType) {
|
||||
hasSubList = true;
|
||||
}
|
||||
});
|
||||
return hasSubList;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleBackspace.ts
|
||||
var handleBackspace = (editor, name, parentListTypes) => {
|
||||
if (editor.commands.undoInputRule()) {
|
||||
return true;
|
||||
}
|
||||
if (editor.state.selection.from !== editor.state.selection.to) {
|
||||
return false;
|
||||
}
|
||||
if (!(0, import_core4.isNodeActive)(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
|
||||
const { $anchor } = editor.state.selection;
|
||||
const $listPos = editor.state.doc.resolve($anchor.before() - 1);
|
||||
const listDescendants = [];
|
||||
$listPos.node().descendants((node, pos) => {
|
||||
if (node.type.name === name) {
|
||||
listDescendants.push({ node, pos });
|
||||
}
|
||||
});
|
||||
const lastItem = listDescendants.at(-1);
|
||||
if (!lastItem) {
|
||||
return false;
|
||||
}
|
||||
const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
|
||||
return editor.chain().cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end()).joinForward().run();
|
||||
}
|
||||
if (!(0, import_core4.isNodeActive)(editor.state, name)) {
|
||||
return false;
|
||||
}
|
||||
if (!(0, import_core4.isAtStartOfNode)(editor.state)) {
|
||||
return false;
|
||||
}
|
||||
const listItemPos = findListItemPos(name, editor.state);
|
||||
if (!listItemPos) {
|
||||
return false;
|
||||
}
|
||||
const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
|
||||
const prevNode = $prev.node(listItemPos.depth);
|
||||
const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
|
||||
if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
|
||||
return editor.commands.joinItemBackward();
|
||||
}
|
||||
return editor.chain().liftListItem(name).run();
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleDelete.ts
|
||||
var import_core5 = require("@tiptap/core");
|
||||
|
||||
// src/keymap/listHelpers/nextListIsDeeper.ts
|
||||
var nextListIsDeeper = (typeOrName, state) => {
|
||||
const listDepth = getNextListDepth(typeOrName, state);
|
||||
const listItemPos = findListItemPos(typeOrName, state);
|
||||
if (!listItemPos || !listDepth) {
|
||||
return false;
|
||||
}
|
||||
if (listDepth > listItemPos.depth) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/nextListIsHigher.ts
|
||||
var nextListIsHigher = (typeOrName, state) => {
|
||||
const listDepth = getNextListDepth(typeOrName, state);
|
||||
const listItemPos = findListItemPos(typeOrName, state);
|
||||
if (!listItemPos || !listDepth) {
|
||||
return false;
|
||||
}
|
||||
if (listDepth < listItemPos.depth) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleDelete.ts
|
||||
var handleDelete = (editor, name) => {
|
||||
if (!(0, import_core5.isNodeActive)(editor.state, name)) {
|
||||
return false;
|
||||
}
|
||||
if (!(0, import_core5.isAtEndOfNode)(editor.state, name)) {
|
||||
return false;
|
||||
}
|
||||
const { selection } = editor.state;
|
||||
const { $from, $to } = selection;
|
||||
if (!selection.empty && $from.sameParent($to)) {
|
||||
return false;
|
||||
}
|
||||
if (nextListIsDeeper(name, editor.state)) {
|
||||
return editor.chain().focus(editor.state.selection.from + 4).lift(name).joinBackward().run();
|
||||
}
|
||||
if (nextListIsHigher(name, editor.state)) {
|
||||
return editor.chain().joinForward().joinBackward().run();
|
||||
}
|
||||
return editor.commands.joinItemForward();
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/hasListItemAfter.ts
|
||||
var hasListItemAfter = (typeOrName, state) => {
|
||||
var _a;
|
||||
const { $anchor } = state.selection;
|
||||
const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2);
|
||||
if ($targetPos.index() === $targetPos.parent.childCount - 1) {
|
||||
return false;
|
||||
}
|
||||
if (((_a = $targetPos.nodeAfter) == null ? void 0 : _a.type.name) !== typeOrName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// src/keymap/list-keymap.ts
|
||||
var ListKeymap = import_core6.Extension.create({
|
||||
name: "listKeymap",
|
||||
addOptions() {
|
||||
return {
|
||||
listTypes: [
|
||||
{
|
||||
itemName: "listItem",
|
||||
wrapperNames: ["bulletList", "orderedList"]
|
||||
},
|
||||
{
|
||||
itemName: "taskItem",
|
||||
wrapperNames: ["taskList"]
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Delete: ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleDelete(editor, itemName)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
},
|
||||
"Mod-Delete": ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleDelete(editor, itemName)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
},
|
||||
Backspace: ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleBackspace(editor, itemName, wrapperNames)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
},
|
||||
"Mod-Backspace": ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleBackspace(editor, itemName, wrapperNames)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ListKeymap,
|
||||
listHelpers
|
||||
});
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@tiptap/extension-list/dist/keymap/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/keymap/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
63
node_modules/@tiptap/extension-list/dist/keymap/index.d.cts
generated
vendored
Normal file
63
node_modules/@tiptap/extension-list/dist/keymap/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Extension, Editor } from '@tiptap/core';
|
||||
import * as prosemirror_model from 'prosemirror-model';
|
||||
import { NodeType, Node } from '@tiptap/pm/model';
|
||||
import { EditorState } from '@tiptap/pm/state';
|
||||
|
||||
type ListKeymapOptions = {
|
||||
/**
|
||||
* An array of list types. This is used for item and wrapper list matching.
|
||||
* @default []
|
||||
* @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]
|
||||
*/
|
||||
listTypes: Array<{
|
||||
itemName: string;
|
||||
wrapperNames: string[];
|
||||
}>;
|
||||
};
|
||||
/**
|
||||
* This extension registers custom keymaps to change the behaviour of the backspace and delete keys.
|
||||
* By default Prosemirror keyhandling will always lift or sink items so paragraphs are joined into
|
||||
* the adjacent or previous list item. This extension will prevent this behaviour and instead will
|
||||
* try to join paragraphs from two list items into a single list item.
|
||||
* @see https://www.tiptap.dev/api/extensions/list-keymap
|
||||
*/
|
||||
declare const ListKeymap: Extension<ListKeymapOptions, any>;
|
||||
|
||||
declare const findListItemPos: (typeOrName: string | NodeType, state: EditorState) => {
|
||||
$pos: prosemirror_model.ResolvedPos;
|
||||
depth: number;
|
||||
} | null;
|
||||
|
||||
declare const getNextListDepth: (typeOrName: string, state: EditorState) => number | false;
|
||||
|
||||
declare const handleBackspace: (editor: Editor, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const handleDelete: (editor: Editor, name: string) => boolean;
|
||||
|
||||
declare const hasListBefore: (editorState: EditorState, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const hasListItemAfter: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const hasListItemBefore: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const listItemHasSubList: (typeOrName: string, state: EditorState, node?: Node) => boolean;
|
||||
|
||||
declare const nextListIsDeeper: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const nextListIsHigher: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const index_findListItemPos: typeof findListItemPos;
|
||||
declare const index_getNextListDepth: typeof getNextListDepth;
|
||||
declare const index_handleBackspace: typeof handleBackspace;
|
||||
declare const index_handleDelete: typeof handleDelete;
|
||||
declare const index_hasListBefore: typeof hasListBefore;
|
||||
declare const index_hasListItemAfter: typeof hasListItemAfter;
|
||||
declare const index_hasListItemBefore: typeof hasListItemBefore;
|
||||
declare const index_listItemHasSubList: typeof listItemHasSubList;
|
||||
declare const index_nextListIsDeeper: typeof nextListIsDeeper;
|
||||
declare const index_nextListIsHigher: typeof nextListIsHigher;
|
||||
declare namespace index {
|
||||
export { index_findListItemPos as findListItemPos, index_getNextListDepth as getNextListDepth, index_handleBackspace as handleBackspace, index_handleDelete as handleDelete, index_hasListBefore as hasListBefore, index_hasListItemAfter as hasListItemAfter, index_hasListItemBefore as hasListItemBefore, index_listItemHasSubList as listItemHasSubList, index_nextListIsDeeper as nextListIsDeeper, index_nextListIsHigher as nextListIsHigher };
|
||||
}
|
||||
|
||||
export { ListKeymap, type ListKeymapOptions, index as listHelpers };
|
||||
63
node_modules/@tiptap/extension-list/dist/keymap/index.d.ts
generated
vendored
Normal file
63
node_modules/@tiptap/extension-list/dist/keymap/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Extension, Editor } from '@tiptap/core';
|
||||
import * as prosemirror_model from 'prosemirror-model';
|
||||
import { NodeType, Node } from '@tiptap/pm/model';
|
||||
import { EditorState } from '@tiptap/pm/state';
|
||||
|
||||
type ListKeymapOptions = {
|
||||
/**
|
||||
* An array of list types. This is used for item and wrapper list matching.
|
||||
* @default []
|
||||
* @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]
|
||||
*/
|
||||
listTypes: Array<{
|
||||
itemName: string;
|
||||
wrapperNames: string[];
|
||||
}>;
|
||||
};
|
||||
/**
|
||||
* This extension registers custom keymaps to change the behaviour of the backspace and delete keys.
|
||||
* By default Prosemirror keyhandling will always lift or sink items so paragraphs are joined into
|
||||
* the adjacent or previous list item. This extension will prevent this behaviour and instead will
|
||||
* try to join paragraphs from two list items into a single list item.
|
||||
* @see https://www.tiptap.dev/api/extensions/list-keymap
|
||||
*/
|
||||
declare const ListKeymap: Extension<ListKeymapOptions, any>;
|
||||
|
||||
declare const findListItemPos: (typeOrName: string | NodeType, state: EditorState) => {
|
||||
$pos: prosemirror_model.ResolvedPos;
|
||||
depth: number;
|
||||
} | null;
|
||||
|
||||
declare const getNextListDepth: (typeOrName: string, state: EditorState) => number | false;
|
||||
|
||||
declare const handleBackspace: (editor: Editor, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const handleDelete: (editor: Editor, name: string) => boolean;
|
||||
|
||||
declare const hasListBefore: (editorState: EditorState, name: string, parentListTypes: string[]) => boolean;
|
||||
|
||||
declare const hasListItemAfter: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const hasListItemBefore: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const listItemHasSubList: (typeOrName: string, state: EditorState, node?: Node) => boolean;
|
||||
|
||||
declare const nextListIsDeeper: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const nextListIsHigher: (typeOrName: string, state: EditorState) => boolean;
|
||||
|
||||
declare const index_findListItemPos: typeof findListItemPos;
|
||||
declare const index_getNextListDepth: typeof getNextListDepth;
|
||||
declare const index_handleBackspace: typeof handleBackspace;
|
||||
declare const index_handleDelete: typeof handleDelete;
|
||||
declare const index_hasListBefore: typeof hasListBefore;
|
||||
declare const index_hasListItemAfter: typeof hasListItemAfter;
|
||||
declare const index_hasListItemBefore: typeof hasListItemBefore;
|
||||
declare const index_listItemHasSubList: typeof listItemHasSubList;
|
||||
declare const index_nextListIsDeeper: typeof nextListIsDeeper;
|
||||
declare const index_nextListIsHigher: typeof nextListIsHigher;
|
||||
declare namespace index {
|
||||
export { index_findListItemPos as findListItemPos, index_getNextListDepth as getNextListDepth, index_handleBackspace as handleBackspace, index_handleDelete as handleDelete, index_hasListBefore as hasListBefore, index_hasListItemAfter as hasListItemAfter, index_hasListItemBefore as hasListItemBefore, index_listItemHasSubList as listItemHasSubList, index_nextListIsDeeper as nextListIsDeeper, index_nextListIsHigher as nextListIsHigher };
|
||||
}
|
||||
|
||||
export { ListKeymap, type ListKeymapOptions, index as listHelpers };
|
||||
286
node_modules/@tiptap/extension-list/dist/keymap/index.js
generated
vendored
Normal file
286
node_modules/@tiptap/extension-list/dist/keymap/index.js
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
var __defProp = Object.defineProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
|
||||
// src/keymap/list-keymap.ts
|
||||
import { Extension } from "@tiptap/core";
|
||||
|
||||
// src/keymap/listHelpers/index.ts
|
||||
var listHelpers_exports = {};
|
||||
__export(listHelpers_exports, {
|
||||
findListItemPos: () => findListItemPos,
|
||||
getNextListDepth: () => getNextListDepth,
|
||||
handleBackspace: () => handleBackspace,
|
||||
handleDelete: () => handleDelete,
|
||||
hasListBefore: () => hasListBefore,
|
||||
hasListItemAfter: () => hasListItemAfter,
|
||||
hasListItemBefore: () => hasListItemBefore,
|
||||
listItemHasSubList: () => listItemHasSubList,
|
||||
nextListIsDeeper: () => nextListIsDeeper,
|
||||
nextListIsHigher: () => nextListIsHigher
|
||||
});
|
||||
|
||||
// src/keymap/listHelpers/findListItemPos.ts
|
||||
import { getNodeType } from "@tiptap/core";
|
||||
var findListItemPos = (typeOrName, state) => {
|
||||
const { $from } = state.selection;
|
||||
const nodeType = getNodeType(typeOrName, state.schema);
|
||||
let currentNode = null;
|
||||
let currentDepth = $from.depth;
|
||||
let currentPos = $from.pos;
|
||||
let targetDepth = null;
|
||||
while (currentDepth > 0 && targetDepth === null) {
|
||||
currentNode = $from.node(currentDepth);
|
||||
if (currentNode.type === nodeType) {
|
||||
targetDepth = currentDepth;
|
||||
} else {
|
||||
currentDepth -= 1;
|
||||
currentPos -= 1;
|
||||
}
|
||||
}
|
||||
if (targetDepth === null) {
|
||||
return null;
|
||||
}
|
||||
return { $pos: state.doc.resolve(currentPos), depth: targetDepth };
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/getNextListDepth.ts
|
||||
import { getNodeAtPosition } from "@tiptap/core";
|
||||
var getNextListDepth = (typeOrName, state) => {
|
||||
const listItemPos = findListItemPos(typeOrName, state);
|
||||
if (!listItemPos) {
|
||||
return false;
|
||||
}
|
||||
const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4);
|
||||
return depth;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleBackspace.ts
|
||||
import { isAtStartOfNode, isNodeActive } from "@tiptap/core";
|
||||
|
||||
// src/keymap/listHelpers/hasListBefore.ts
|
||||
var hasListBefore = (editorState, name, parentListTypes) => {
|
||||
const { $anchor } = editorState.selection;
|
||||
const previousNodePos = Math.max(0, $anchor.pos - 2);
|
||||
const previousNode = editorState.doc.resolve(previousNodePos).node();
|
||||
if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/hasListItemBefore.ts
|
||||
var hasListItemBefore = (typeOrName, state) => {
|
||||
var _a;
|
||||
const { $anchor } = state.selection;
|
||||
const $targetPos = state.doc.resolve($anchor.pos - 2);
|
||||
if ($targetPos.index() === 0) {
|
||||
return false;
|
||||
}
|
||||
if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/listItemHasSubList.ts
|
||||
import { getNodeType as getNodeType2 } from "@tiptap/core";
|
||||
var listItemHasSubList = (typeOrName, state, node) => {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
const nodeType = getNodeType2(typeOrName, state.schema);
|
||||
let hasSubList = false;
|
||||
node.descendants((child) => {
|
||||
if (child.type === nodeType) {
|
||||
hasSubList = true;
|
||||
}
|
||||
});
|
||||
return hasSubList;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleBackspace.ts
|
||||
var handleBackspace = (editor, name, parentListTypes) => {
|
||||
if (editor.commands.undoInputRule()) {
|
||||
return true;
|
||||
}
|
||||
if (editor.state.selection.from !== editor.state.selection.to) {
|
||||
return false;
|
||||
}
|
||||
if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
|
||||
const { $anchor } = editor.state.selection;
|
||||
const $listPos = editor.state.doc.resolve($anchor.before() - 1);
|
||||
const listDescendants = [];
|
||||
$listPos.node().descendants((node, pos) => {
|
||||
if (node.type.name === name) {
|
||||
listDescendants.push({ node, pos });
|
||||
}
|
||||
});
|
||||
const lastItem = listDescendants.at(-1);
|
||||
if (!lastItem) {
|
||||
return false;
|
||||
}
|
||||
const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
|
||||
return editor.chain().cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end()).joinForward().run();
|
||||
}
|
||||
if (!isNodeActive(editor.state, name)) {
|
||||
return false;
|
||||
}
|
||||
if (!isAtStartOfNode(editor.state)) {
|
||||
return false;
|
||||
}
|
||||
const listItemPos = findListItemPos(name, editor.state);
|
||||
if (!listItemPos) {
|
||||
return false;
|
||||
}
|
||||
const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
|
||||
const prevNode = $prev.node(listItemPos.depth);
|
||||
const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
|
||||
if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
|
||||
return editor.commands.joinItemBackward();
|
||||
}
|
||||
return editor.chain().liftListItem(name).run();
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleDelete.ts
|
||||
import { isAtEndOfNode, isNodeActive as isNodeActive2 } from "@tiptap/core";
|
||||
|
||||
// src/keymap/listHelpers/nextListIsDeeper.ts
|
||||
var nextListIsDeeper = (typeOrName, state) => {
|
||||
const listDepth = getNextListDepth(typeOrName, state);
|
||||
const listItemPos = findListItemPos(typeOrName, state);
|
||||
if (!listItemPos || !listDepth) {
|
||||
return false;
|
||||
}
|
||||
if (listDepth > listItemPos.depth) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/nextListIsHigher.ts
|
||||
var nextListIsHigher = (typeOrName, state) => {
|
||||
const listDepth = getNextListDepth(typeOrName, state);
|
||||
const listItemPos = findListItemPos(typeOrName, state);
|
||||
if (!listItemPos || !listDepth) {
|
||||
return false;
|
||||
}
|
||||
if (listDepth < listItemPos.depth) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/handleDelete.ts
|
||||
var handleDelete = (editor, name) => {
|
||||
if (!isNodeActive2(editor.state, name)) {
|
||||
return false;
|
||||
}
|
||||
if (!isAtEndOfNode(editor.state, name)) {
|
||||
return false;
|
||||
}
|
||||
const { selection } = editor.state;
|
||||
const { $from, $to } = selection;
|
||||
if (!selection.empty && $from.sameParent($to)) {
|
||||
return false;
|
||||
}
|
||||
if (nextListIsDeeper(name, editor.state)) {
|
||||
return editor.chain().focus(editor.state.selection.from + 4).lift(name).joinBackward().run();
|
||||
}
|
||||
if (nextListIsHigher(name, editor.state)) {
|
||||
return editor.chain().joinForward().joinBackward().run();
|
||||
}
|
||||
return editor.commands.joinItemForward();
|
||||
};
|
||||
|
||||
// src/keymap/listHelpers/hasListItemAfter.ts
|
||||
var hasListItemAfter = (typeOrName, state) => {
|
||||
var _a;
|
||||
const { $anchor } = state.selection;
|
||||
const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2);
|
||||
if ($targetPos.index() === $targetPos.parent.childCount - 1) {
|
||||
return false;
|
||||
}
|
||||
if (((_a = $targetPos.nodeAfter) == null ? void 0 : _a.type.name) !== typeOrName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// src/keymap/list-keymap.ts
|
||||
var ListKeymap = Extension.create({
|
||||
name: "listKeymap",
|
||||
addOptions() {
|
||||
return {
|
||||
listTypes: [
|
||||
{
|
||||
itemName: "listItem",
|
||||
wrapperNames: ["bulletList", "orderedList"]
|
||||
},
|
||||
{
|
||||
itemName: "taskItem",
|
||||
wrapperNames: ["taskList"]
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Delete: ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleDelete(editor, itemName)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
},
|
||||
"Mod-Delete": ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleDelete(editor, itemName)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
},
|
||||
Backspace: ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleBackspace(editor, itemName, wrapperNames)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
},
|
||||
"Mod-Backspace": ({ editor }) => {
|
||||
let handled = false;
|
||||
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
||||
if (editor.state.schema.nodes[itemName] === void 0) {
|
||||
return;
|
||||
}
|
||||
if (handleBackspace(editor, itemName, wrapperNames)) {
|
||||
handled = true;
|
||||
}
|
||||
});
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
export {
|
||||
ListKeymap,
|
||||
listHelpers_exports as listHelpers
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@tiptap/extension-list/dist/keymap/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/keymap/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1108
node_modules/@tiptap/extension-list/dist/kit/index.cjs
generated
vendored
Normal file
1108
node_modules/@tiptap/extension-list/dist/kit/index.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@tiptap/extension-list/dist/kit/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/kit/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
212
node_modules/@tiptap/extension-list/dist/kit/index.d.cts
generated
vendored
Normal file
212
node_modules/@tiptap/extension-list/dist/kit/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
import { Extension } from '@tiptap/core';
|
||||
import { Node } from '@tiptap/pm/model';
|
||||
|
||||
interface BulletListOptions {
|
||||
/**
|
||||
* The node name for the list items
|
||||
* @default 'listItem'
|
||||
* @example 'paragraph'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* HTML attributes to add to the bullet list element
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
bulletList: {
|
||||
/**
|
||||
* Toggle a bullet list
|
||||
*/
|
||||
toggleBulletList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface ListItemOptions {
|
||||
/**
|
||||
* The HTML attributes for a list item node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for bulletList nodes
|
||||
* @default 'bulletList'
|
||||
* @example 'myCustomBulletList'
|
||||
*/
|
||||
bulletListTypeName: string;
|
||||
/**
|
||||
* The node type for orderedList nodes
|
||||
* @default 'orderedList'
|
||||
* @example 'myCustomOrderedList'
|
||||
*/
|
||||
orderedListTypeName: string;
|
||||
}
|
||||
|
||||
type ListKeymapOptions = {
|
||||
/**
|
||||
* An array of list types. This is used for item and wrapper list matching.
|
||||
* @default []
|
||||
* @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]
|
||||
*/
|
||||
listTypes: Array<{
|
||||
itemName: string;
|
||||
wrapperNames: string[];
|
||||
}>;
|
||||
};
|
||||
|
||||
interface OrderedListOptions {
|
||||
/**
|
||||
* The node type name for list items.
|
||||
* @default 'listItem'
|
||||
* @example 'myListItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for an ordered list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
orderedList: {
|
||||
/**
|
||||
* Toggle an ordered list
|
||||
* @example editor.commands.toggleOrderedList()
|
||||
*/
|
||||
toggleOrderedList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface TaskItemOptions {
|
||||
/**
|
||||
* A callback function that is called when the checkbox is clicked while the editor is in readonly mode.
|
||||
* @param node The prosemirror node of the task item
|
||||
* @param checked The new checked state
|
||||
* @returns boolean
|
||||
*/
|
||||
onReadOnlyChecked?: (node: Node, checked: boolean) => boolean;
|
||||
/**
|
||||
* Controls whether the task items can be nested or not.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
nested: boolean;
|
||||
/**
|
||||
* HTML attributes to add to the task item element.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for taskList nodes
|
||||
* @default 'taskList'
|
||||
* @example 'myCustomTaskList'
|
||||
*/
|
||||
taskListTypeName: string;
|
||||
/**
|
||||
* Accessibility options for the task item.
|
||||
* @default {}
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
|
||||
* }
|
||||
*/
|
||||
a11y?: {
|
||||
checkboxLabel?: (node: Node, checked: boolean) => string;
|
||||
};
|
||||
}
|
||||
|
||||
interface TaskListOptions {
|
||||
/**
|
||||
* The node type name for a task item.
|
||||
* @default 'taskItem'
|
||||
* @example 'myCustomTaskItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for a task list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
taskList: {
|
||||
/**
|
||||
* Toggle a task list
|
||||
* @example editor.commands.toggleTaskList()
|
||||
*/
|
||||
toggleTaskList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface ListKitOptions {
|
||||
/**
|
||||
* If set to false, the bulletList extension will not be registered
|
||||
* @example table: false
|
||||
*/
|
||||
bulletList: Partial<BulletListOptions> | false;
|
||||
/**
|
||||
* If set to false, the listItem extension will not be registered
|
||||
*/
|
||||
listItem: Partial<ListItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the listKeymap extension will not be registered
|
||||
*/
|
||||
listKeymap: Partial<ListKeymapOptions> | false;
|
||||
/**
|
||||
* If set to false, the orderedList extension will not be registered
|
||||
*/
|
||||
orderedList: Partial<OrderedListOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskItem extension will not be registered
|
||||
*/
|
||||
taskItem: Partial<TaskItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskList extension will not be registered
|
||||
*/
|
||||
taskList: Partial<TaskListOptions> | false;
|
||||
}
|
||||
/**
|
||||
* The table kit is a collection of table editor extensions.
|
||||
*
|
||||
* It’s a good starting point for building your own table in Tiptap.
|
||||
*/
|
||||
declare const ListKit: Extension<ListKitOptions, any>;
|
||||
|
||||
export { ListKit, type ListKitOptions };
|
||||
212
node_modules/@tiptap/extension-list/dist/kit/index.d.ts
generated
vendored
Normal file
212
node_modules/@tiptap/extension-list/dist/kit/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
import { Extension } from '@tiptap/core';
|
||||
import { Node } from '@tiptap/pm/model';
|
||||
|
||||
interface BulletListOptions {
|
||||
/**
|
||||
* The node name for the list items
|
||||
* @default 'listItem'
|
||||
* @example 'paragraph'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* HTML attributes to add to the bullet list element
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
bulletList: {
|
||||
/**
|
||||
* Toggle a bullet list
|
||||
*/
|
||||
toggleBulletList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface ListItemOptions {
|
||||
/**
|
||||
* The HTML attributes for a list item node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for bulletList nodes
|
||||
* @default 'bulletList'
|
||||
* @example 'myCustomBulletList'
|
||||
*/
|
||||
bulletListTypeName: string;
|
||||
/**
|
||||
* The node type for orderedList nodes
|
||||
* @default 'orderedList'
|
||||
* @example 'myCustomOrderedList'
|
||||
*/
|
||||
orderedListTypeName: string;
|
||||
}
|
||||
|
||||
type ListKeymapOptions = {
|
||||
/**
|
||||
* An array of list types. This is used for item and wrapper list matching.
|
||||
* @default []
|
||||
* @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]
|
||||
*/
|
||||
listTypes: Array<{
|
||||
itemName: string;
|
||||
wrapperNames: string[];
|
||||
}>;
|
||||
};
|
||||
|
||||
interface OrderedListOptions {
|
||||
/**
|
||||
* The node type name for list items.
|
||||
* @default 'listItem'
|
||||
* @example 'myListItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for an ordered list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
orderedList: {
|
||||
/**
|
||||
* Toggle an ordered list
|
||||
* @example editor.commands.toggleOrderedList()
|
||||
*/
|
||||
toggleOrderedList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface TaskItemOptions {
|
||||
/**
|
||||
* A callback function that is called when the checkbox is clicked while the editor is in readonly mode.
|
||||
* @param node The prosemirror node of the task item
|
||||
* @param checked The new checked state
|
||||
* @returns boolean
|
||||
*/
|
||||
onReadOnlyChecked?: (node: Node, checked: boolean) => boolean;
|
||||
/**
|
||||
* Controls whether the task items can be nested or not.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
nested: boolean;
|
||||
/**
|
||||
* HTML attributes to add to the task item element.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for taskList nodes
|
||||
* @default 'taskList'
|
||||
* @example 'myCustomTaskList'
|
||||
*/
|
||||
taskListTypeName: string;
|
||||
/**
|
||||
* Accessibility options for the task item.
|
||||
* @default {}
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
|
||||
* }
|
||||
*/
|
||||
a11y?: {
|
||||
checkboxLabel?: (node: Node, checked: boolean) => string;
|
||||
};
|
||||
}
|
||||
|
||||
interface TaskListOptions {
|
||||
/**
|
||||
* The node type name for a task item.
|
||||
* @default 'taskItem'
|
||||
* @example 'myCustomTaskItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for a task list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
taskList: {
|
||||
/**
|
||||
* Toggle a task list
|
||||
* @example editor.commands.toggleTaskList()
|
||||
*/
|
||||
toggleTaskList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface ListKitOptions {
|
||||
/**
|
||||
* If set to false, the bulletList extension will not be registered
|
||||
* @example table: false
|
||||
*/
|
||||
bulletList: Partial<BulletListOptions> | false;
|
||||
/**
|
||||
* If set to false, the listItem extension will not be registered
|
||||
*/
|
||||
listItem: Partial<ListItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the listKeymap extension will not be registered
|
||||
*/
|
||||
listKeymap: Partial<ListKeymapOptions> | false;
|
||||
/**
|
||||
* If set to false, the orderedList extension will not be registered
|
||||
*/
|
||||
orderedList: Partial<OrderedListOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskItem extension will not be registered
|
||||
*/
|
||||
taskItem: Partial<TaskItemOptions> | false;
|
||||
/**
|
||||
* If set to false, the taskList extension will not be registered
|
||||
*/
|
||||
taskList: Partial<TaskListOptions> | false;
|
||||
}
|
||||
/**
|
||||
* The table kit is a collection of table editor extensions.
|
||||
*
|
||||
* It’s a good starting point for building your own table in Tiptap.
|
||||
*/
|
||||
declare const ListKit: Extension<ListKitOptions, any>;
|
||||
|
||||
export { ListKit, type ListKitOptions };
|
||||
1095
node_modules/@tiptap/extension-list/dist/kit/index.js
generated
vendored
Normal file
1095
node_modules/@tiptap/extension-list/dist/kit/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@tiptap/extension-list/dist/kit/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/kit/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
302
node_modules/@tiptap/extension-list/dist/ordered-list/index.cjs
generated
vendored
Normal file
302
node_modules/@tiptap/extension-list/dist/ordered-list/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/ordered-list/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
OrderedList: () => OrderedList,
|
||||
orderedListInputRegex: () => orderedListInputRegex
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/ordered-list/ordered-list.ts
|
||||
var import_core = require("@tiptap/core");
|
||||
|
||||
// src/ordered-list/utils.ts
|
||||
var ORDERED_LIST_ITEM_REGEX = /^(\s*)(\d+)\.\s+(.*)$/;
|
||||
var INDENTED_LINE_REGEX = /^\s/;
|
||||
function collectOrderedListItems(lines) {
|
||||
const listItems = [];
|
||||
let currentLineIndex = 0;
|
||||
let consumed = 0;
|
||||
while (currentLineIndex < lines.length) {
|
||||
const line = lines[currentLineIndex];
|
||||
const match = line.match(ORDERED_LIST_ITEM_REGEX);
|
||||
if (!match) {
|
||||
break;
|
||||
}
|
||||
const [, indent, number, content] = match;
|
||||
const indentLevel = indent.length;
|
||||
let itemContent = content;
|
||||
let nextLineIndex = currentLineIndex + 1;
|
||||
const itemLines = [line];
|
||||
while (nextLineIndex < lines.length) {
|
||||
const nextLine = lines[nextLineIndex];
|
||||
const nextMatch = nextLine.match(ORDERED_LIST_ITEM_REGEX);
|
||||
if (nextMatch) {
|
||||
break;
|
||||
}
|
||||
if (nextLine.trim() === "") {
|
||||
itemLines.push(nextLine);
|
||||
itemContent += "\n";
|
||||
nextLineIndex += 1;
|
||||
} else if (nextLine.match(INDENTED_LINE_REGEX)) {
|
||||
itemLines.push(nextLine);
|
||||
itemContent += `
|
||||
${nextLine.slice(indentLevel + 2)}`;
|
||||
nextLineIndex += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
listItems.push({
|
||||
indent: indentLevel,
|
||||
number: parseInt(number, 10),
|
||||
content: itemContent.trim(),
|
||||
raw: itemLines.join("\n")
|
||||
});
|
||||
consumed = nextLineIndex;
|
||||
currentLineIndex = nextLineIndex;
|
||||
}
|
||||
return [listItems, consumed];
|
||||
}
|
||||
function buildNestedStructure(items, baseIndent, lexer) {
|
||||
var _a;
|
||||
const result = [];
|
||||
let currentIndex = 0;
|
||||
while (currentIndex < items.length) {
|
||||
const item = items[currentIndex];
|
||||
if (item.indent === baseIndent) {
|
||||
const contentLines = item.content.split("\n");
|
||||
const mainText = ((_a = contentLines[0]) == null ? void 0 : _a.trim()) || "";
|
||||
const tokens = [];
|
||||
if (mainText) {
|
||||
tokens.push({
|
||||
type: "paragraph",
|
||||
raw: mainText,
|
||||
tokens: lexer.inlineTokens(mainText)
|
||||
});
|
||||
}
|
||||
const additionalContent = contentLines.slice(1).join("\n").trim();
|
||||
if (additionalContent) {
|
||||
const blockTokens = lexer.blockTokens(additionalContent);
|
||||
tokens.push(...blockTokens);
|
||||
}
|
||||
let lookAheadIndex = currentIndex + 1;
|
||||
const nestedItems = [];
|
||||
while (lookAheadIndex < items.length && items[lookAheadIndex].indent > baseIndent) {
|
||||
nestedItems.push(items[lookAheadIndex]);
|
||||
lookAheadIndex += 1;
|
||||
}
|
||||
if (nestedItems.length > 0) {
|
||||
const nextIndent = Math.min(...nestedItems.map((nestedItem) => nestedItem.indent));
|
||||
const nestedListItems = buildNestedStructure(nestedItems, nextIndent, lexer);
|
||||
tokens.push({
|
||||
type: "list",
|
||||
ordered: true,
|
||||
start: nestedItems[0].number,
|
||||
items: nestedListItems,
|
||||
raw: nestedItems.map((nestedItem) => nestedItem.raw).join("\n")
|
||||
});
|
||||
}
|
||||
result.push({
|
||||
type: "list_item",
|
||||
raw: item.raw,
|
||||
tokens
|
||||
});
|
||||
currentIndex = lookAheadIndex;
|
||||
} else {
|
||||
currentIndex += 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function parseListItems(items, helpers) {
|
||||
return items.map((item) => {
|
||||
if (item.type !== "list_item") {
|
||||
return helpers.parseChildren([item])[0];
|
||||
}
|
||||
const content = [];
|
||||
if (item.tokens && item.tokens.length > 0) {
|
||||
item.tokens.forEach((itemToken) => {
|
||||
if (itemToken.type === "paragraph" || itemToken.type === "list" || itemToken.type === "blockquote" || itemToken.type === "code") {
|
||||
content.push(...helpers.parseChildren([itemToken]));
|
||||
} else if (itemToken.type === "text" && itemToken.tokens) {
|
||||
const inlineContent = helpers.parseChildren([itemToken]);
|
||||
content.push({
|
||||
type: "paragraph",
|
||||
content: inlineContent
|
||||
});
|
||||
} else {
|
||||
const parsed = helpers.parseChildren([itemToken]);
|
||||
if (parsed.length > 0) {
|
||||
content.push(...parsed);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: "listItem",
|
||||
content
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// src/ordered-list/ordered-list.ts
|
||||
var ListItemName = "listItem";
|
||||
var TextStyleName = "textStyle";
|
||||
var orderedListInputRegex = /^(\d+)\.\s$/;
|
||||
var OrderedList = import_core.Node.create({
|
||||
name: "orderedList",
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: "listItem",
|
||||
HTMLAttributes: {},
|
||||
keepMarks: false,
|
||||
keepAttributes: false
|
||||
};
|
||||
},
|
||||
group: "block list",
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`;
|
||||
},
|
||||
addAttributes() {
|
||||
return {
|
||||
start: {
|
||||
default: 1,
|
||||
parseHTML: (element) => {
|
||||
return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
|
||||
}
|
||||
},
|
||||
type: {
|
||||
default: null,
|
||||
parseHTML: (element) => element.getAttribute("type")
|
||||
}
|
||||
};
|
||||
},
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: "ol"
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
const { start, ...attributesWithoutStart } = HTMLAttributes;
|
||||
return start === 1 ? ["ol", (0, import_core.mergeAttributes)(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", (0, import_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
markdownTokenName: "list",
|
||||
parseMarkdown: (token, helpers) => {
|
||||
if (token.type !== "list" || !token.ordered) {
|
||||
return [];
|
||||
}
|
||||
const startValue = token.start || 1;
|
||||
const content = token.items ? parseListItems(token.items, helpers) : [];
|
||||
if (startValue !== 1) {
|
||||
return {
|
||||
type: "orderedList",
|
||||
attrs: { start: startValue },
|
||||
content
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: "orderedList",
|
||||
content
|
||||
};
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return "";
|
||||
}
|
||||
return h.renderChildren(node.content, "\n");
|
||||
},
|
||||
markdownTokenizer: {
|
||||
name: "orderedList",
|
||||
level: "block",
|
||||
start: (src) => {
|
||||
const match = src.match(/^(\s*)(\d+)\.\s+/);
|
||||
const index = match == null ? void 0 : match.index;
|
||||
return index !== void 0 ? index : -1;
|
||||
},
|
||||
tokenize: (src, _tokens, lexer) => {
|
||||
var _a;
|
||||
const lines = src.split("\n");
|
||||
const [listItems, consumed] = collectOrderedListItems(lines);
|
||||
if (listItems.length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
const items = buildNestedStructure(listItems, 0, lexer);
|
||||
if (items.length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
const startValue = ((_a = listItems[0]) == null ? void 0 : _a.number) || 1;
|
||||
return {
|
||||
type: "list",
|
||||
ordered: true,
|
||||
start: startValue,
|
||||
items,
|
||||
raw: lines.slice(0, consumed).join("\n")
|
||||
};
|
||||
}
|
||||
},
|
||||
markdownOptions: {
|
||||
indentsContent: true
|
||||
},
|
||||
addCommands() {
|
||||
return {
|
||||
toggleOrderedList: () => ({ commands, chain }) => {
|
||||
if (this.options.keepAttributes) {
|
||||
return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run();
|
||||
}
|
||||
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
|
||||
}
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
"Mod-Shift-7": () => this.editor.commands.toggleOrderedList()
|
||||
};
|
||||
},
|
||||
addInputRules() {
|
||||
let inputRule = (0, import_core.wrappingInputRule)({
|
||||
find: orderedListInputRegex,
|
||||
type: this.type,
|
||||
getAttributes: (match) => ({ start: +match[1] }),
|
||||
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1]
|
||||
});
|
||||
if (this.options.keepMarks || this.options.keepAttributes) {
|
||||
inputRule = (0, import_core.wrappingInputRule)({
|
||||
find: orderedListInputRegex,
|
||||
type: this.type,
|
||||
keepMarks: this.options.keepMarks,
|
||||
keepAttributes: this.options.keepAttributes,
|
||||
getAttributes: (match) => ({ start: +match[1], ...this.editor.getAttributes(TextStyleName) }),
|
||||
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
|
||||
editor: this.editor
|
||||
});
|
||||
}
|
||||
return [inputRule];
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
OrderedList,
|
||||
orderedListInputRegex
|
||||
});
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@tiptap/extension-list/dist/ordered-list/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/ordered-list/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
52
node_modules/@tiptap/extension-list/dist/ordered-list/index.d.cts
generated
vendored
Normal file
52
node_modules/@tiptap/extension-list/dist/ordered-list/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface OrderedListOptions {
|
||||
/**
|
||||
* The node type name for list items.
|
||||
* @default 'listItem'
|
||||
* @example 'myListItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for an ordered list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
orderedList: {
|
||||
/**
|
||||
* Toggle an ordered list
|
||||
* @example editor.commands.toggleOrderedList()
|
||||
*/
|
||||
toggleOrderedList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches an ordered list to a 1. on input (or any number followed by a dot).
|
||||
*/
|
||||
declare const orderedListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create ordered lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://www.tiptap.dev/api/nodes/ordered-list
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const OrderedList: Node<OrderedListOptions, any>;
|
||||
|
||||
export { OrderedList, type OrderedListOptions, orderedListInputRegex };
|
||||
52
node_modules/@tiptap/extension-list/dist/ordered-list/index.d.ts
generated
vendored
Normal file
52
node_modules/@tiptap/extension-list/dist/ordered-list/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface OrderedListOptions {
|
||||
/**
|
||||
* The node type name for list items.
|
||||
* @default 'listItem'
|
||||
* @example 'myListItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for an ordered list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* Keep the marks when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean;
|
||||
/**
|
||||
* Keep the attributes when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
orderedList: {
|
||||
/**
|
||||
* Toggle an ordered list
|
||||
* @example editor.commands.toggleOrderedList()
|
||||
*/
|
||||
toggleOrderedList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Matches an ordered list to a 1. on input (or any number followed by a dot).
|
||||
*/
|
||||
declare const orderedListInputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create ordered lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://www.tiptap.dev/api/nodes/ordered-list
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
declare const OrderedList: Node<OrderedListOptions, any>;
|
||||
|
||||
export { OrderedList, type OrderedListOptions, orderedListInputRegex };
|
||||
274
node_modules/@tiptap/extension-list/dist/ordered-list/index.js
generated
vendored
Normal file
274
node_modules/@tiptap/extension-list/dist/ordered-list/index.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
// src/ordered-list/ordered-list.ts
|
||||
import { mergeAttributes, Node, wrappingInputRule } from "@tiptap/core";
|
||||
|
||||
// src/ordered-list/utils.ts
|
||||
var ORDERED_LIST_ITEM_REGEX = /^(\s*)(\d+)\.\s+(.*)$/;
|
||||
var INDENTED_LINE_REGEX = /^\s/;
|
||||
function collectOrderedListItems(lines) {
|
||||
const listItems = [];
|
||||
let currentLineIndex = 0;
|
||||
let consumed = 0;
|
||||
while (currentLineIndex < lines.length) {
|
||||
const line = lines[currentLineIndex];
|
||||
const match = line.match(ORDERED_LIST_ITEM_REGEX);
|
||||
if (!match) {
|
||||
break;
|
||||
}
|
||||
const [, indent, number, content] = match;
|
||||
const indentLevel = indent.length;
|
||||
let itemContent = content;
|
||||
let nextLineIndex = currentLineIndex + 1;
|
||||
const itemLines = [line];
|
||||
while (nextLineIndex < lines.length) {
|
||||
const nextLine = lines[nextLineIndex];
|
||||
const nextMatch = nextLine.match(ORDERED_LIST_ITEM_REGEX);
|
||||
if (nextMatch) {
|
||||
break;
|
||||
}
|
||||
if (nextLine.trim() === "") {
|
||||
itemLines.push(nextLine);
|
||||
itemContent += "\n";
|
||||
nextLineIndex += 1;
|
||||
} else if (nextLine.match(INDENTED_LINE_REGEX)) {
|
||||
itemLines.push(nextLine);
|
||||
itemContent += `
|
||||
${nextLine.slice(indentLevel + 2)}`;
|
||||
nextLineIndex += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
listItems.push({
|
||||
indent: indentLevel,
|
||||
number: parseInt(number, 10),
|
||||
content: itemContent.trim(),
|
||||
raw: itemLines.join("\n")
|
||||
});
|
||||
consumed = nextLineIndex;
|
||||
currentLineIndex = nextLineIndex;
|
||||
}
|
||||
return [listItems, consumed];
|
||||
}
|
||||
function buildNestedStructure(items, baseIndent, lexer) {
|
||||
var _a;
|
||||
const result = [];
|
||||
let currentIndex = 0;
|
||||
while (currentIndex < items.length) {
|
||||
const item = items[currentIndex];
|
||||
if (item.indent === baseIndent) {
|
||||
const contentLines = item.content.split("\n");
|
||||
const mainText = ((_a = contentLines[0]) == null ? void 0 : _a.trim()) || "";
|
||||
const tokens = [];
|
||||
if (mainText) {
|
||||
tokens.push({
|
||||
type: "paragraph",
|
||||
raw: mainText,
|
||||
tokens: lexer.inlineTokens(mainText)
|
||||
});
|
||||
}
|
||||
const additionalContent = contentLines.slice(1).join("\n").trim();
|
||||
if (additionalContent) {
|
||||
const blockTokens = lexer.blockTokens(additionalContent);
|
||||
tokens.push(...blockTokens);
|
||||
}
|
||||
let lookAheadIndex = currentIndex + 1;
|
||||
const nestedItems = [];
|
||||
while (lookAheadIndex < items.length && items[lookAheadIndex].indent > baseIndent) {
|
||||
nestedItems.push(items[lookAheadIndex]);
|
||||
lookAheadIndex += 1;
|
||||
}
|
||||
if (nestedItems.length > 0) {
|
||||
const nextIndent = Math.min(...nestedItems.map((nestedItem) => nestedItem.indent));
|
||||
const nestedListItems = buildNestedStructure(nestedItems, nextIndent, lexer);
|
||||
tokens.push({
|
||||
type: "list",
|
||||
ordered: true,
|
||||
start: nestedItems[0].number,
|
||||
items: nestedListItems,
|
||||
raw: nestedItems.map((nestedItem) => nestedItem.raw).join("\n")
|
||||
});
|
||||
}
|
||||
result.push({
|
||||
type: "list_item",
|
||||
raw: item.raw,
|
||||
tokens
|
||||
});
|
||||
currentIndex = lookAheadIndex;
|
||||
} else {
|
||||
currentIndex += 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function parseListItems(items, helpers) {
|
||||
return items.map((item) => {
|
||||
if (item.type !== "list_item") {
|
||||
return helpers.parseChildren([item])[0];
|
||||
}
|
||||
const content = [];
|
||||
if (item.tokens && item.tokens.length > 0) {
|
||||
item.tokens.forEach((itemToken) => {
|
||||
if (itemToken.type === "paragraph" || itemToken.type === "list" || itemToken.type === "blockquote" || itemToken.type === "code") {
|
||||
content.push(...helpers.parseChildren([itemToken]));
|
||||
} else if (itemToken.type === "text" && itemToken.tokens) {
|
||||
const inlineContent = helpers.parseChildren([itemToken]);
|
||||
content.push({
|
||||
type: "paragraph",
|
||||
content: inlineContent
|
||||
});
|
||||
} else {
|
||||
const parsed = helpers.parseChildren([itemToken]);
|
||||
if (parsed.length > 0) {
|
||||
content.push(...parsed);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: "listItem",
|
||||
content
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// src/ordered-list/ordered-list.ts
|
||||
var ListItemName = "listItem";
|
||||
var TextStyleName = "textStyle";
|
||||
var orderedListInputRegex = /^(\d+)\.\s$/;
|
||||
var OrderedList = Node.create({
|
||||
name: "orderedList",
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: "listItem",
|
||||
HTMLAttributes: {},
|
||||
keepMarks: false,
|
||||
keepAttributes: false
|
||||
};
|
||||
},
|
||||
group: "block list",
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`;
|
||||
},
|
||||
addAttributes() {
|
||||
return {
|
||||
start: {
|
||||
default: 1,
|
||||
parseHTML: (element) => {
|
||||
return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
|
||||
}
|
||||
},
|
||||
type: {
|
||||
default: null,
|
||||
parseHTML: (element) => element.getAttribute("type")
|
||||
}
|
||||
};
|
||||
},
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: "ol"
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
const { start, ...attributesWithoutStart } = HTMLAttributes;
|
||||
return start === 1 ? ["ol", mergeAttributes(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
markdownTokenName: "list",
|
||||
parseMarkdown: (token, helpers) => {
|
||||
if (token.type !== "list" || !token.ordered) {
|
||||
return [];
|
||||
}
|
||||
const startValue = token.start || 1;
|
||||
const content = token.items ? parseListItems(token.items, helpers) : [];
|
||||
if (startValue !== 1) {
|
||||
return {
|
||||
type: "orderedList",
|
||||
attrs: { start: startValue },
|
||||
content
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: "orderedList",
|
||||
content
|
||||
};
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return "";
|
||||
}
|
||||
return h.renderChildren(node.content, "\n");
|
||||
},
|
||||
markdownTokenizer: {
|
||||
name: "orderedList",
|
||||
level: "block",
|
||||
start: (src) => {
|
||||
const match = src.match(/^(\s*)(\d+)\.\s+/);
|
||||
const index = match == null ? void 0 : match.index;
|
||||
return index !== void 0 ? index : -1;
|
||||
},
|
||||
tokenize: (src, _tokens, lexer) => {
|
||||
var _a;
|
||||
const lines = src.split("\n");
|
||||
const [listItems, consumed] = collectOrderedListItems(lines);
|
||||
if (listItems.length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
const items = buildNestedStructure(listItems, 0, lexer);
|
||||
if (items.length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
const startValue = ((_a = listItems[0]) == null ? void 0 : _a.number) || 1;
|
||||
return {
|
||||
type: "list",
|
||||
ordered: true,
|
||||
start: startValue,
|
||||
items,
|
||||
raw: lines.slice(0, consumed).join("\n")
|
||||
};
|
||||
}
|
||||
},
|
||||
markdownOptions: {
|
||||
indentsContent: true
|
||||
},
|
||||
addCommands() {
|
||||
return {
|
||||
toggleOrderedList: () => ({ commands, chain }) => {
|
||||
if (this.options.keepAttributes) {
|
||||
return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run();
|
||||
}
|
||||
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
|
||||
}
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
"Mod-Shift-7": () => this.editor.commands.toggleOrderedList()
|
||||
};
|
||||
},
|
||||
addInputRules() {
|
||||
let inputRule = wrappingInputRule({
|
||||
find: orderedListInputRegex,
|
||||
type: this.type,
|
||||
getAttributes: (match) => ({ start: +match[1] }),
|
||||
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1]
|
||||
});
|
||||
if (this.options.keepMarks || this.options.keepAttributes) {
|
||||
inputRule = wrappingInputRule({
|
||||
find: orderedListInputRegex,
|
||||
type: this.type,
|
||||
keepMarks: this.options.keepMarks,
|
||||
keepAttributes: this.options.keepAttributes,
|
||||
getAttributes: (match) => ({ start: +match[1], ...this.editor.getAttributes(TextStyleName) }),
|
||||
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
|
||||
editor: this.editor
|
||||
});
|
||||
}
|
||||
return [inputRule];
|
||||
}
|
||||
});
|
||||
export {
|
||||
OrderedList,
|
||||
orderedListInputRegex
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@tiptap/extension-list/dist/ordered-list/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/ordered-list/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
231
node_modules/@tiptap/extension-list/dist/task-item/index.cjs
generated
vendored
Normal file
231
node_modules/@tiptap/extension-list/dist/task-item/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/task-item/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
TaskItem: () => TaskItem,
|
||||
inputRegex: () => inputRegex
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/task-item/task-item.ts
|
||||
var import_core = require("@tiptap/core");
|
||||
var inputRegex = /^\s*(\[([( |x])?\])\s$/;
|
||||
var TaskItem = import_core.Node.create({
|
||||
name: "taskItem",
|
||||
addOptions() {
|
||||
return {
|
||||
nested: false,
|
||||
HTMLAttributes: {},
|
||||
taskListTypeName: "taskList",
|
||||
a11y: void 0
|
||||
};
|
||||
},
|
||||
content() {
|
||||
return this.options.nested ? "paragraph block*" : "paragraph+";
|
||||
},
|
||||
defining: true,
|
||||
addAttributes() {
|
||||
return {
|
||||
checked: {
|
||||
default: false,
|
||||
keepOnSplit: false,
|
||||
parseHTML: (element) => {
|
||||
const dataChecked = element.getAttribute("data-checked");
|
||||
return dataChecked === "" || dataChecked === "true";
|
||||
},
|
||||
renderHTML: (attributes) => ({
|
||||
"data-checked": attributes.checked
|
||||
})
|
||||
}
|
||||
};
|
||||
},
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `li[data-type="${this.name}"]`,
|
||||
priority: 51
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ node, HTMLAttributes }) {
|
||||
return [
|
||||
"li",
|
||||
(0, import_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
|
||||
"data-type": this.name
|
||||
}),
|
||||
[
|
||||
"label",
|
||||
[
|
||||
"input",
|
||||
{
|
||||
type: "checkbox",
|
||||
checked: node.attrs.checked ? "checked" : null
|
||||
}
|
||||
],
|
||||
["span"]
|
||||
],
|
||||
["div", 0]
|
||||
];
|
||||
},
|
||||
parseMarkdown: (token, h) => {
|
||||
const content = [];
|
||||
if (token.tokens && token.tokens.length > 0) {
|
||||
content.push(h.createNode("paragraph", {}, h.parseInline(token.tokens)));
|
||||
} else if (token.text) {
|
||||
content.push(h.createNode("paragraph", {}, [h.createNode("text", { text: token.text })]));
|
||||
} else {
|
||||
content.push(h.createNode("paragraph", {}, []));
|
||||
}
|
||||
if (token.nestedTokens && token.nestedTokens.length > 0) {
|
||||
const nestedContent = h.parseChildren(token.nestedTokens);
|
||||
content.push(...nestedContent);
|
||||
}
|
||||
return h.createNode("taskItem", { checked: token.checked || false }, content);
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
var _a;
|
||||
const checkedChar = ((_a = node.attrs) == null ? void 0 : _a.checked) ? "x" : " ";
|
||||
const prefix = `- [${checkedChar}] `;
|
||||
return (0, import_core.renderNestedMarkdownContent)(node, h, prefix);
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
const shortcuts = {
|
||||
Enter: () => this.editor.commands.splitListItem(this.name),
|
||||
"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
|
||||
};
|
||||
if (!this.options.nested) {
|
||||
return shortcuts;
|
||||
}
|
||||
return {
|
||||
...shortcuts,
|
||||
Tab: () => this.editor.commands.sinkListItem(this.name)
|
||||
};
|
||||
},
|
||||
addNodeView() {
|
||||
return ({ node, HTMLAttributes, getPos, editor }) => {
|
||||
const listItem = document.createElement("li");
|
||||
const checkboxWrapper = document.createElement("label");
|
||||
const checkboxStyler = document.createElement("span");
|
||||
const checkbox = document.createElement("input");
|
||||
const content = document.createElement("div");
|
||||
const updateA11Y = (currentNode) => {
|
||||
var _a, _b;
|
||||
checkbox.ariaLabel = ((_b = (_a = this.options.a11y) == null ? void 0 : _a.checkboxLabel) == null ? void 0 : _b.call(_a, currentNode, checkbox.checked)) || `Task item checkbox for ${currentNode.textContent || "empty task item"}`;
|
||||
};
|
||||
updateA11Y(node);
|
||||
checkboxWrapper.contentEditable = "false";
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.addEventListener("mousedown", (event) => event.preventDefault());
|
||||
checkbox.addEventListener("change", (event) => {
|
||||
if (!editor.isEditable && !this.options.onReadOnlyChecked) {
|
||||
checkbox.checked = !checkbox.checked;
|
||||
return;
|
||||
}
|
||||
const { checked } = event.target;
|
||||
if (editor.isEditable && typeof getPos === "function") {
|
||||
editor.chain().focus(void 0, { scrollIntoView: false }).command(({ tr }) => {
|
||||
const position = getPos();
|
||||
if (typeof position !== "number") {
|
||||
return false;
|
||||
}
|
||||
const currentNode = tr.doc.nodeAt(position);
|
||||
tr.setNodeMarkup(position, void 0, {
|
||||
...currentNode == null ? void 0 : currentNode.attrs,
|
||||
checked
|
||||
});
|
||||
return true;
|
||||
}).run();
|
||||
}
|
||||
if (!editor.isEditable && this.options.onReadOnlyChecked) {
|
||||
if (!this.options.onReadOnlyChecked(node, checked)) {
|
||||
checkbox.checked = !checkbox.checked;
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
|
||||
listItem.setAttribute(key, value);
|
||||
});
|
||||
listItem.dataset.checked = node.attrs.checked;
|
||||
checkbox.checked = node.attrs.checked;
|
||||
checkboxWrapper.append(checkbox, checkboxStyler);
|
||||
listItem.append(checkboxWrapper, content);
|
||||
Object.entries(HTMLAttributes).forEach(([key, value]) => {
|
||||
listItem.setAttribute(key, value);
|
||||
});
|
||||
let prevRenderedAttributeKeys = new Set(Object.keys(HTMLAttributes));
|
||||
return {
|
||||
dom: listItem,
|
||||
contentDOM: content,
|
||||
update: (updatedNode) => {
|
||||
if (updatedNode.type !== this.type) {
|
||||
return false;
|
||||
}
|
||||
listItem.dataset.checked = updatedNode.attrs.checked;
|
||||
checkbox.checked = updatedNode.attrs.checked;
|
||||
updateA11Y(updatedNode);
|
||||
const extensionAttributes = editor.extensionManager.attributes;
|
||||
const newHTMLAttributes = (0, import_core.getRenderedAttributes)(updatedNode, extensionAttributes);
|
||||
const newKeys = new Set(Object.keys(newHTMLAttributes));
|
||||
const staticAttrs = this.options.HTMLAttributes;
|
||||
prevRenderedAttributeKeys.forEach((key) => {
|
||||
if (!newKeys.has(key)) {
|
||||
if (key in staticAttrs) {
|
||||
listItem.setAttribute(key, staticAttrs[key]);
|
||||
} else {
|
||||
listItem.removeAttribute(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.entries(newHTMLAttributes).forEach(([key, value]) => {
|
||||
if (value === null || value === void 0) {
|
||||
if (key in staticAttrs) {
|
||||
listItem.setAttribute(key, staticAttrs[key]);
|
||||
} else {
|
||||
listItem.removeAttribute(key);
|
||||
}
|
||||
} else {
|
||||
listItem.setAttribute(key, value);
|
||||
}
|
||||
});
|
||||
prevRenderedAttributeKeys = newKeys;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
addInputRules() {
|
||||
return [
|
||||
(0, import_core.wrappingInputRule)({
|
||||
find: inputRegex,
|
||||
type: this.type,
|
||||
getAttributes: (match) => ({
|
||||
checked: match[match.length - 1] === "x"
|
||||
})
|
||||
})
|
||||
];
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TaskItem,
|
||||
inputRegex
|
||||
});
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@tiptap/extension-list/dist/task-item/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/task-item/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
53
node_modules/@tiptap/extension-list/dist/task-item/index.d.cts
generated
vendored
Normal file
53
node_modules/@tiptap/extension-list/dist/task-item/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Node as Node$1 } from '@tiptap/core';
|
||||
import { Node } from '@tiptap/pm/model';
|
||||
|
||||
interface TaskItemOptions {
|
||||
/**
|
||||
* A callback function that is called when the checkbox is clicked while the editor is in readonly mode.
|
||||
* @param node The prosemirror node of the task item
|
||||
* @param checked The new checked state
|
||||
* @returns boolean
|
||||
*/
|
||||
onReadOnlyChecked?: (node: Node, checked: boolean) => boolean;
|
||||
/**
|
||||
* Controls whether the task items can be nested or not.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
nested: boolean;
|
||||
/**
|
||||
* HTML attributes to add to the task item element.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for taskList nodes
|
||||
* @default 'taskList'
|
||||
* @example 'myCustomTaskList'
|
||||
*/
|
||||
taskListTypeName: string;
|
||||
/**
|
||||
* Accessibility options for the task item.
|
||||
* @default {}
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
|
||||
* }
|
||||
*/
|
||||
a11y?: {
|
||||
checkboxLabel?: (node: Node, checked: boolean) => string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Matches a task item to a - [ ] on input.
|
||||
*/
|
||||
declare const inputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create task items.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-item
|
||||
*/
|
||||
declare const TaskItem: Node$1<TaskItemOptions, any>;
|
||||
|
||||
export { TaskItem, type TaskItemOptions, inputRegex };
|
||||
53
node_modules/@tiptap/extension-list/dist/task-item/index.d.ts
generated
vendored
Normal file
53
node_modules/@tiptap/extension-list/dist/task-item/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Node as Node$1 } from '@tiptap/core';
|
||||
import { Node } from '@tiptap/pm/model';
|
||||
|
||||
interface TaskItemOptions {
|
||||
/**
|
||||
* A callback function that is called when the checkbox is clicked while the editor is in readonly mode.
|
||||
* @param node The prosemirror node of the task item
|
||||
* @param checked The new checked state
|
||||
* @returns boolean
|
||||
*/
|
||||
onReadOnlyChecked?: (node: Node, checked: boolean) => boolean;
|
||||
/**
|
||||
* Controls whether the task items can be nested or not.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
nested: boolean;
|
||||
/**
|
||||
* HTML attributes to add to the task item element.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
/**
|
||||
* The node type for taskList nodes
|
||||
* @default 'taskList'
|
||||
* @example 'myCustomTaskList'
|
||||
*/
|
||||
taskListTypeName: string;
|
||||
/**
|
||||
* Accessibility options for the task item.
|
||||
* @default {}
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
|
||||
* }
|
||||
*/
|
||||
a11y?: {
|
||||
checkboxLabel?: (node: Node, checked: boolean) => string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Matches a task item to a - [ ] on input.
|
||||
*/
|
||||
declare const inputRegex: RegExp;
|
||||
/**
|
||||
* This extension allows you to create task items.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-item
|
||||
*/
|
||||
declare const TaskItem: Node$1<TaskItemOptions, any>;
|
||||
|
||||
export { TaskItem, type TaskItemOptions, inputRegex };
|
||||
209
node_modules/@tiptap/extension-list/dist/task-item/index.js
generated
vendored
Normal file
209
node_modules/@tiptap/extension-list/dist/task-item/index.js
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
// src/task-item/task-item.ts
|
||||
import {
|
||||
getRenderedAttributes,
|
||||
mergeAttributes,
|
||||
Node,
|
||||
renderNestedMarkdownContent,
|
||||
wrappingInputRule
|
||||
} from "@tiptap/core";
|
||||
var inputRegex = /^\s*(\[([( |x])?\])\s$/;
|
||||
var TaskItem = Node.create({
|
||||
name: "taskItem",
|
||||
addOptions() {
|
||||
return {
|
||||
nested: false,
|
||||
HTMLAttributes: {},
|
||||
taskListTypeName: "taskList",
|
||||
a11y: void 0
|
||||
};
|
||||
},
|
||||
content() {
|
||||
return this.options.nested ? "paragraph block*" : "paragraph+";
|
||||
},
|
||||
defining: true,
|
||||
addAttributes() {
|
||||
return {
|
||||
checked: {
|
||||
default: false,
|
||||
keepOnSplit: false,
|
||||
parseHTML: (element) => {
|
||||
const dataChecked = element.getAttribute("data-checked");
|
||||
return dataChecked === "" || dataChecked === "true";
|
||||
},
|
||||
renderHTML: (attributes) => ({
|
||||
"data-checked": attributes.checked
|
||||
})
|
||||
}
|
||||
};
|
||||
},
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `li[data-type="${this.name}"]`,
|
||||
priority: 51
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ node, HTMLAttributes }) {
|
||||
return [
|
||||
"li",
|
||||
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
|
||||
"data-type": this.name
|
||||
}),
|
||||
[
|
||||
"label",
|
||||
[
|
||||
"input",
|
||||
{
|
||||
type: "checkbox",
|
||||
checked: node.attrs.checked ? "checked" : null
|
||||
}
|
||||
],
|
||||
["span"]
|
||||
],
|
||||
["div", 0]
|
||||
];
|
||||
},
|
||||
parseMarkdown: (token, h) => {
|
||||
const content = [];
|
||||
if (token.tokens && token.tokens.length > 0) {
|
||||
content.push(h.createNode("paragraph", {}, h.parseInline(token.tokens)));
|
||||
} else if (token.text) {
|
||||
content.push(h.createNode("paragraph", {}, [h.createNode("text", { text: token.text })]));
|
||||
} else {
|
||||
content.push(h.createNode("paragraph", {}, []));
|
||||
}
|
||||
if (token.nestedTokens && token.nestedTokens.length > 0) {
|
||||
const nestedContent = h.parseChildren(token.nestedTokens);
|
||||
content.push(...nestedContent);
|
||||
}
|
||||
return h.createNode("taskItem", { checked: token.checked || false }, content);
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
var _a;
|
||||
const checkedChar = ((_a = node.attrs) == null ? void 0 : _a.checked) ? "x" : " ";
|
||||
const prefix = `- [${checkedChar}] `;
|
||||
return renderNestedMarkdownContent(node, h, prefix);
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
const shortcuts = {
|
||||
Enter: () => this.editor.commands.splitListItem(this.name),
|
||||
"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
|
||||
};
|
||||
if (!this.options.nested) {
|
||||
return shortcuts;
|
||||
}
|
||||
return {
|
||||
...shortcuts,
|
||||
Tab: () => this.editor.commands.sinkListItem(this.name)
|
||||
};
|
||||
},
|
||||
addNodeView() {
|
||||
return ({ node, HTMLAttributes, getPos, editor }) => {
|
||||
const listItem = document.createElement("li");
|
||||
const checkboxWrapper = document.createElement("label");
|
||||
const checkboxStyler = document.createElement("span");
|
||||
const checkbox = document.createElement("input");
|
||||
const content = document.createElement("div");
|
||||
const updateA11Y = (currentNode) => {
|
||||
var _a, _b;
|
||||
checkbox.ariaLabel = ((_b = (_a = this.options.a11y) == null ? void 0 : _a.checkboxLabel) == null ? void 0 : _b.call(_a, currentNode, checkbox.checked)) || `Task item checkbox for ${currentNode.textContent || "empty task item"}`;
|
||||
};
|
||||
updateA11Y(node);
|
||||
checkboxWrapper.contentEditable = "false";
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.addEventListener("mousedown", (event) => event.preventDefault());
|
||||
checkbox.addEventListener("change", (event) => {
|
||||
if (!editor.isEditable && !this.options.onReadOnlyChecked) {
|
||||
checkbox.checked = !checkbox.checked;
|
||||
return;
|
||||
}
|
||||
const { checked } = event.target;
|
||||
if (editor.isEditable && typeof getPos === "function") {
|
||||
editor.chain().focus(void 0, { scrollIntoView: false }).command(({ tr }) => {
|
||||
const position = getPos();
|
||||
if (typeof position !== "number") {
|
||||
return false;
|
||||
}
|
||||
const currentNode = tr.doc.nodeAt(position);
|
||||
tr.setNodeMarkup(position, void 0, {
|
||||
...currentNode == null ? void 0 : currentNode.attrs,
|
||||
checked
|
||||
});
|
||||
return true;
|
||||
}).run();
|
||||
}
|
||||
if (!editor.isEditable && this.options.onReadOnlyChecked) {
|
||||
if (!this.options.onReadOnlyChecked(node, checked)) {
|
||||
checkbox.checked = !checkbox.checked;
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
|
||||
listItem.setAttribute(key, value);
|
||||
});
|
||||
listItem.dataset.checked = node.attrs.checked;
|
||||
checkbox.checked = node.attrs.checked;
|
||||
checkboxWrapper.append(checkbox, checkboxStyler);
|
||||
listItem.append(checkboxWrapper, content);
|
||||
Object.entries(HTMLAttributes).forEach(([key, value]) => {
|
||||
listItem.setAttribute(key, value);
|
||||
});
|
||||
let prevRenderedAttributeKeys = new Set(Object.keys(HTMLAttributes));
|
||||
return {
|
||||
dom: listItem,
|
||||
contentDOM: content,
|
||||
update: (updatedNode) => {
|
||||
if (updatedNode.type !== this.type) {
|
||||
return false;
|
||||
}
|
||||
listItem.dataset.checked = updatedNode.attrs.checked;
|
||||
checkbox.checked = updatedNode.attrs.checked;
|
||||
updateA11Y(updatedNode);
|
||||
const extensionAttributes = editor.extensionManager.attributes;
|
||||
const newHTMLAttributes = getRenderedAttributes(updatedNode, extensionAttributes);
|
||||
const newKeys = new Set(Object.keys(newHTMLAttributes));
|
||||
const staticAttrs = this.options.HTMLAttributes;
|
||||
prevRenderedAttributeKeys.forEach((key) => {
|
||||
if (!newKeys.has(key)) {
|
||||
if (key in staticAttrs) {
|
||||
listItem.setAttribute(key, staticAttrs[key]);
|
||||
} else {
|
||||
listItem.removeAttribute(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.entries(newHTMLAttributes).forEach(([key, value]) => {
|
||||
if (value === null || value === void 0) {
|
||||
if (key in staticAttrs) {
|
||||
listItem.setAttribute(key, staticAttrs[key]);
|
||||
} else {
|
||||
listItem.removeAttribute(key);
|
||||
}
|
||||
} else {
|
||||
listItem.setAttribute(key, value);
|
||||
}
|
||||
});
|
||||
prevRenderedAttributeKeys = newKeys;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
addInputRules() {
|
||||
return [
|
||||
wrappingInputRule({
|
||||
find: inputRegex,
|
||||
type: this.type,
|
||||
getAttributes: (match) => ({
|
||||
checked: match[match.length - 1] === "x"
|
||||
})
|
||||
})
|
||||
];
|
||||
}
|
||||
});
|
||||
export {
|
||||
TaskItem,
|
||||
inputRegex
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@tiptap/extension-list/dist/task-item/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/task-item/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
160
node_modules/@tiptap/extension-list/dist/task-list/index.cjs
generated
vendored
Normal file
160
node_modules/@tiptap/extension-list/dist/task-list/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/task-list/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
TaskList: () => TaskList
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/task-list/task-list.ts
|
||||
var import_core = require("@tiptap/core");
|
||||
var TaskList = import_core.Node.create({
|
||||
name: "taskList",
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: "taskItem",
|
||||
HTMLAttributes: {}
|
||||
};
|
||||
},
|
||||
group: "block list",
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`;
|
||||
},
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `ul[data-type="${this.name}"]`,
|
||||
priority: 51
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ["ul", (0, import_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }), 0];
|
||||
},
|
||||
parseMarkdown: (token, h) => {
|
||||
return h.createNode("taskList", {}, h.parseChildren(token.items || []));
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return "";
|
||||
}
|
||||
return h.renderChildren(node.content, "\n");
|
||||
},
|
||||
markdownTokenizer: {
|
||||
name: "taskList",
|
||||
level: "block",
|
||||
start(src) {
|
||||
var _a;
|
||||
const index = (_a = src.match(/^\s*[-+*]\s+\[([ xX])\]\s+/)) == null ? void 0 : _a.index;
|
||||
return index !== void 0 ? index : -1;
|
||||
},
|
||||
tokenize(src, tokens, lexer) {
|
||||
const parseTaskListContent = (content) => {
|
||||
const nestedResult = (0, import_core.parseIndentedBlocks)(
|
||||
content,
|
||||
{
|
||||
itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
|
||||
extractItemData: (match) => ({
|
||||
indentLevel: match[1].length,
|
||||
mainContent: match[4],
|
||||
checked: match[3].toLowerCase() === "x"
|
||||
}),
|
||||
createToken: (data, nestedTokens) => ({
|
||||
type: "taskItem",
|
||||
raw: "",
|
||||
mainContent: data.mainContent,
|
||||
indentLevel: data.indentLevel,
|
||||
checked: data.checked,
|
||||
text: data.mainContent,
|
||||
tokens: lexer.inlineTokens(data.mainContent),
|
||||
nestedTokens
|
||||
}),
|
||||
// Allow recursive nesting
|
||||
customNestedParser: parseTaskListContent
|
||||
},
|
||||
lexer
|
||||
);
|
||||
if (nestedResult) {
|
||||
return [
|
||||
{
|
||||
type: "taskList",
|
||||
raw: nestedResult.raw,
|
||||
items: nestedResult.items
|
||||
}
|
||||
];
|
||||
}
|
||||
return lexer.blockTokens(content);
|
||||
};
|
||||
const result = (0, import_core.parseIndentedBlocks)(
|
||||
src,
|
||||
{
|
||||
itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
|
||||
extractItemData: (match) => ({
|
||||
indentLevel: match[1].length,
|
||||
mainContent: match[4],
|
||||
checked: match[3].toLowerCase() === "x"
|
||||
}),
|
||||
createToken: (data, nestedTokens) => ({
|
||||
type: "taskItem",
|
||||
raw: "",
|
||||
mainContent: data.mainContent,
|
||||
indentLevel: data.indentLevel,
|
||||
checked: data.checked,
|
||||
text: data.mainContent,
|
||||
tokens: lexer.inlineTokens(data.mainContent),
|
||||
nestedTokens
|
||||
}),
|
||||
// Use the recursive parser for nested content
|
||||
customNestedParser: parseTaskListContent
|
||||
},
|
||||
lexer
|
||||
);
|
||||
if (!result) {
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
type: "taskList",
|
||||
raw: result.raw,
|
||||
items: result.items
|
||||
};
|
||||
}
|
||||
},
|
||||
markdownOptions: {
|
||||
indentsContent: true
|
||||
},
|
||||
addCommands() {
|
||||
return {
|
||||
toggleTaskList: () => ({ commands }) => {
|
||||
return commands.toggleList(this.name, this.options.itemTypeName);
|
||||
}
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
"Mod-Shift-9": () => this.editor.commands.toggleTaskList()
|
||||
};
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TaskList
|
||||
});
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@tiptap/extension-list/dist/task-list/index.cjs.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/task-list/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
34
node_modules/@tiptap/extension-list/dist/task-list/index.d.cts
generated
vendored
Normal file
34
node_modules/@tiptap/extension-list/dist/task-list/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface TaskListOptions {
|
||||
/**
|
||||
* The node type name for a task item.
|
||||
* @default 'taskItem'
|
||||
* @example 'myCustomTaskItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for a task list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
taskList: {
|
||||
/**
|
||||
* Toggle a task list
|
||||
* @example editor.commands.toggleTaskList()
|
||||
*/
|
||||
toggleTaskList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create task lists.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-list
|
||||
*/
|
||||
declare const TaskList: Node<TaskListOptions, any>;
|
||||
|
||||
export { TaskList, type TaskListOptions };
|
||||
34
node_modules/@tiptap/extension-list/dist/task-list/index.d.ts
generated
vendored
Normal file
34
node_modules/@tiptap/extension-list/dist/task-list/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
|
||||
interface TaskListOptions {
|
||||
/**
|
||||
* The node type name for a task item.
|
||||
* @default 'taskItem'
|
||||
* @example 'myCustomTaskItem'
|
||||
*/
|
||||
itemTypeName: string;
|
||||
/**
|
||||
* The HTML attributes for a task list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
taskList: {
|
||||
/**
|
||||
* Toggle a task list
|
||||
* @example editor.commands.toggleTaskList()
|
||||
*/
|
||||
toggleTaskList: () => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This extension allows you to create task lists.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-list
|
||||
*/
|
||||
declare const TaskList: Node<TaskListOptions, any>;
|
||||
|
||||
export { TaskList, type TaskListOptions };
|
||||
133
node_modules/@tiptap/extension-list/dist/task-list/index.js
generated
vendored
Normal file
133
node_modules/@tiptap/extension-list/dist/task-list/index.js
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// src/task-list/task-list.ts
|
||||
import { mergeAttributes, Node, parseIndentedBlocks } from "@tiptap/core";
|
||||
var TaskList = Node.create({
|
||||
name: "taskList",
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: "taskItem",
|
||||
HTMLAttributes: {}
|
||||
};
|
||||
},
|
||||
group: "block list",
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`;
|
||||
},
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `ul[data-type="${this.name}"]`,
|
||||
priority: 51
|
||||
}
|
||||
];
|
||||
},
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ["ul", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }), 0];
|
||||
},
|
||||
parseMarkdown: (token, h) => {
|
||||
return h.createNode("taskList", {}, h.parseChildren(token.items || []));
|
||||
},
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return "";
|
||||
}
|
||||
return h.renderChildren(node.content, "\n");
|
||||
},
|
||||
markdownTokenizer: {
|
||||
name: "taskList",
|
||||
level: "block",
|
||||
start(src) {
|
||||
var _a;
|
||||
const index = (_a = src.match(/^\s*[-+*]\s+\[([ xX])\]\s+/)) == null ? void 0 : _a.index;
|
||||
return index !== void 0 ? index : -1;
|
||||
},
|
||||
tokenize(src, tokens, lexer) {
|
||||
const parseTaskListContent = (content) => {
|
||||
const nestedResult = parseIndentedBlocks(
|
||||
content,
|
||||
{
|
||||
itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
|
||||
extractItemData: (match) => ({
|
||||
indentLevel: match[1].length,
|
||||
mainContent: match[4],
|
||||
checked: match[3].toLowerCase() === "x"
|
||||
}),
|
||||
createToken: (data, nestedTokens) => ({
|
||||
type: "taskItem",
|
||||
raw: "",
|
||||
mainContent: data.mainContent,
|
||||
indentLevel: data.indentLevel,
|
||||
checked: data.checked,
|
||||
text: data.mainContent,
|
||||
tokens: lexer.inlineTokens(data.mainContent),
|
||||
nestedTokens
|
||||
}),
|
||||
// Allow recursive nesting
|
||||
customNestedParser: parseTaskListContent
|
||||
},
|
||||
lexer
|
||||
);
|
||||
if (nestedResult) {
|
||||
return [
|
||||
{
|
||||
type: "taskList",
|
||||
raw: nestedResult.raw,
|
||||
items: nestedResult.items
|
||||
}
|
||||
];
|
||||
}
|
||||
return lexer.blockTokens(content);
|
||||
};
|
||||
const result = parseIndentedBlocks(
|
||||
src,
|
||||
{
|
||||
itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
|
||||
extractItemData: (match) => ({
|
||||
indentLevel: match[1].length,
|
||||
mainContent: match[4],
|
||||
checked: match[3].toLowerCase() === "x"
|
||||
}),
|
||||
createToken: (data, nestedTokens) => ({
|
||||
type: "taskItem",
|
||||
raw: "",
|
||||
mainContent: data.mainContent,
|
||||
indentLevel: data.indentLevel,
|
||||
checked: data.checked,
|
||||
text: data.mainContent,
|
||||
tokens: lexer.inlineTokens(data.mainContent),
|
||||
nestedTokens
|
||||
}),
|
||||
// Use the recursive parser for nested content
|
||||
customNestedParser: parseTaskListContent
|
||||
},
|
||||
lexer
|
||||
);
|
||||
if (!result) {
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
type: "taskList",
|
||||
raw: result.raw,
|
||||
items: result.items
|
||||
};
|
||||
}
|
||||
},
|
||||
markdownOptions: {
|
||||
indentsContent: true
|
||||
},
|
||||
addCommands() {
|
||||
return {
|
||||
toggleTaskList: () => ({ commands }) => {
|
||||
return commands.toggleList(this.name, this.options.itemTypeName);
|
||||
}
|
||||
};
|
||||
},
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
"Mod-Shift-9": () => this.editor.commands.toggleTaskList()
|
||||
};
|
||||
}
|
||||
});
|
||||
export {
|
||||
TaskList
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@tiptap/extension-list/dist/task-list/index.js.map
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/dist/task-list/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
106
node_modules/@tiptap/extension-list/package.json
generated
vendored
Normal file
106
node_modules/@tiptap/extension-list/package.json
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"name": "@tiptap/extension-list",
|
||||
"description": "List extension for tiptap",
|
||||
"version": "3.21.0",
|
||||
"homepage": "https://tiptap.dev",
|
||||
"keywords": [
|
||||
"tiptap",
|
||||
"tiptap extension"
|
||||
],
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": {
|
||||
"import": "./dist/index.d.ts",
|
||||
"require": "./dist/index.d.cts"
|
||||
},
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./bullet-list": {
|
||||
"types": {
|
||||
"import": "./dist/bullet-list/index.d.ts",
|
||||
"require": "./dist/bullet-list/index.d.cts"
|
||||
},
|
||||
"import": "./dist/bullet-list/index.js",
|
||||
"require": "./dist/bullet-list/index.cjs"
|
||||
},
|
||||
"./item": {
|
||||
"types": {
|
||||
"import": "./dist/item/index.d.ts",
|
||||
"require": "./dist/item/index.d.cts"
|
||||
},
|
||||
"import": "./dist/item/index.js",
|
||||
"require": "./dist/item/index.cjs"
|
||||
},
|
||||
"./keymap": {
|
||||
"types": {
|
||||
"import": "./dist/keymap/index.d.ts",
|
||||
"require": "./dist/keymap/index.d.cts"
|
||||
},
|
||||
"import": "./dist/keymap/index.js",
|
||||
"require": "./dist/keymap/index.cjs"
|
||||
},
|
||||
"./kit": {
|
||||
"types": {
|
||||
"import": "./dist/kit/index.d.ts",
|
||||
"require": "./dist/kit/index.d.cts"
|
||||
},
|
||||
"import": "./dist/kit/index.js",
|
||||
"require": "./dist/kit/index.cjs"
|
||||
},
|
||||
"./ordered-list": {
|
||||
"types": {
|
||||
"import": "./dist/ordered-list/index.d.ts",
|
||||
"require": "./dist/ordered-list/index.d.cts"
|
||||
},
|
||||
"import": "./dist/ordered-list/index.js",
|
||||
"require": "./dist/ordered-list/index.cjs"
|
||||
},
|
||||
"./task-item": {
|
||||
"types": {
|
||||
"import": "./dist/task-item/index.d.ts",
|
||||
"require": "./dist/task-item/index.d.cts"
|
||||
},
|
||||
"import": "./dist/task-item/index.js",
|
||||
"require": "./dist/task-item/index.cjs"
|
||||
},
|
||||
"./task-list": {
|
||||
"types": {
|
||||
"import": "./dist/task-list/index.d.ts",
|
||||
"require": "./dist/task-list/index.d.cts"
|
||||
},
|
||||
"import": "./dist/task-list/index.js",
|
||||
"require": "./dist/task-list/index.cjs"
|
||||
}
|
||||
},
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"src",
|
||||
"dist"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@tiptap/core": "^3.21.0",
|
||||
"@tiptap/pm": "^3.21.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^3.21.0",
|
||||
"@tiptap/pm": "^3.21.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ueberdosis/tiptap",
|
||||
"directory": "packages/extension-list"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
|
||||
}
|
||||
}
|
||||
151
node_modules/@tiptap/extension-list/src/bullet-list/bullet-list.ts
generated
vendored
Normal file
151
node_modules/@tiptap/extension-list/src/bullet-list/bullet-list.ts
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'
|
||||
|
||||
const ListItemName = 'listItem'
|
||||
const TextStyleName = 'textStyle'
|
||||
|
||||
export interface BulletListOptions {
|
||||
/**
|
||||
* The node name for the list items
|
||||
* @default 'listItem'
|
||||
* @example 'paragraph'
|
||||
*/
|
||||
itemTypeName: string
|
||||
|
||||
/**
|
||||
* HTML attributes to add to the bullet list element
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>
|
||||
|
||||
/**
|
||||
* Keep the marks when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean
|
||||
|
||||
/**
|
||||
* Keep the attributes when splitting the list
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean
|
||||
}
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
bulletList: {
|
||||
/**
|
||||
* Toggle a bullet list
|
||||
*/
|
||||
toggleBulletList: () => ReturnType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a bullet list to a dash or asterisk.
|
||||
*/
|
||||
export const bulletListInputRegex = /^\s*([-+*])\s$/
|
||||
|
||||
/**
|
||||
* This extension allows you to create bullet lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://tiptap.dev/api/nodes/bullet-list
|
||||
* @see https://tiptap.dev/api/nodes/list-item.
|
||||
*/
|
||||
export const BulletList = Node.create<BulletListOptions>({
|
||||
name: 'bulletList',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: 'listItem',
|
||||
HTMLAttributes: {},
|
||||
keepMarks: false,
|
||||
keepAttributes: false,
|
||||
}
|
||||
},
|
||||
|
||||
group: 'block list',
|
||||
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [{ tag: 'ul' }]
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ['ul', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]
|
||||
},
|
||||
|
||||
markdownTokenName: 'list',
|
||||
|
||||
parseMarkdown: (token, helpers) => {
|
||||
if (token.type !== 'list' || (token as any).ordered) {
|
||||
return []
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'bulletList',
|
||||
content: token.items ? helpers.parseChildren(token.items) : [],
|
||||
}
|
||||
},
|
||||
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return h.renderChildren(node.content, '\n')
|
||||
},
|
||||
|
||||
markdownOptions: {
|
||||
indentsContent: true,
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
toggleBulletList:
|
||||
() =>
|
||||
({ commands, chain }) => {
|
||||
if (this.options.keepAttributes) {
|
||||
return chain()
|
||||
.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)
|
||||
.updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName))
|
||||
.run()
|
||||
}
|
||||
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
'Mod-Shift-8': () => this.editor.commands.toggleBulletList(),
|
||||
}
|
||||
},
|
||||
|
||||
addInputRules() {
|
||||
let inputRule = wrappingInputRule({
|
||||
find: bulletListInputRegex,
|
||||
type: this.type,
|
||||
})
|
||||
|
||||
if (this.options.keepMarks || this.options.keepAttributes) {
|
||||
inputRule = wrappingInputRule({
|
||||
find: bulletListInputRegex,
|
||||
type: this.type,
|
||||
keepMarks: this.options.keepMarks,
|
||||
keepAttributes: this.options.keepAttributes,
|
||||
getAttributes: () => {
|
||||
return this.editor.getAttributes(TextStyleName)
|
||||
},
|
||||
editor: this.editor,
|
||||
})
|
||||
}
|
||||
return [inputRule]
|
||||
},
|
||||
})
|
||||
1
node_modules/@tiptap/extension-list/src/bullet-list/index.ts
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/src/bullet-list/index.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './bullet-list.js'
|
||||
7
node_modules/@tiptap/extension-list/src/index.ts
generated
vendored
Normal file
7
node_modules/@tiptap/extension-list/src/index.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export * from './bullet-list/index.js'
|
||||
export * from './item/index.js'
|
||||
export * from './keymap/index.js'
|
||||
export * from './kit/index.js'
|
||||
export * from './ordered-list/index.js'
|
||||
export * from './task-item/index.js'
|
||||
export * from './task-list/index.js'
|
||||
1
node_modules/@tiptap/extension-list/src/item/index.ts
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/src/item/index.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './list-item.js'
|
||||
146
node_modules/@tiptap/extension-list/src/item/list-item.ts
generated
vendored
Normal file
146
node_modules/@tiptap/extension-list/src/item/list-item.ts
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
import { mergeAttributes, Node, renderNestedMarkdownContent } from '@tiptap/core'
|
||||
|
||||
export interface ListItemOptions {
|
||||
/**
|
||||
* The HTML attributes for a list item node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>
|
||||
|
||||
/**
|
||||
* The node type for bulletList nodes
|
||||
* @default 'bulletList'
|
||||
* @example 'myCustomBulletList'
|
||||
*/
|
||||
bulletListTypeName: string
|
||||
|
||||
/**
|
||||
* The node type for orderedList nodes
|
||||
* @default 'orderedList'
|
||||
* @example 'myCustomOrderedList'
|
||||
*/
|
||||
orderedListTypeName: string
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to create list items.
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
export const ListItem = Node.create<ListItemOptions>({
|
||||
name: 'listItem',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
HTMLAttributes: {},
|
||||
bulletListTypeName: 'bulletList',
|
||||
orderedListTypeName: 'orderedList',
|
||||
}
|
||||
},
|
||||
|
||||
content: 'paragraph block*',
|
||||
|
||||
defining: true,
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: 'li',
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ['li', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]
|
||||
},
|
||||
|
||||
markdownTokenName: 'list_item',
|
||||
|
||||
parseMarkdown: (token, helpers) => {
|
||||
if (token.type !== 'list_item') {
|
||||
return []
|
||||
}
|
||||
|
||||
const parseBlockChildren = helpers.parseBlockChildren ?? helpers.parseChildren
|
||||
let content: any[] = []
|
||||
|
||||
if (token.tokens && token.tokens.length > 0) {
|
||||
// Check if we have paragraph tokens (complex list items)
|
||||
const hasParagraphTokens = token.tokens.some(t => t.type === 'paragraph')
|
||||
|
||||
if (hasParagraphTokens) {
|
||||
// If we have paragraph tokens, parse them as block elements
|
||||
content = parseBlockChildren(token.tokens)
|
||||
} else {
|
||||
// Check if the first token is a text token with nested inline tokens
|
||||
const firstToken = token.tokens[0]
|
||||
|
||||
if (firstToken && firstToken.type === 'text' && firstToken.tokens && firstToken.tokens.length > 0) {
|
||||
// Parse the inline content from the text token
|
||||
const inlineContent = helpers.parseInline(firstToken.tokens)
|
||||
|
||||
// Start with the paragraph containing the inline content
|
||||
content = [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: inlineContent,
|
||||
},
|
||||
]
|
||||
|
||||
// If there are additional tokens after the first text token (like nested lists),
|
||||
// parse them as block elements and add them
|
||||
if (token.tokens.length > 1) {
|
||||
const remainingTokens = token.tokens.slice(1)
|
||||
const additionalContent = parseBlockChildren(remainingTokens)
|
||||
content.push(...additionalContent)
|
||||
}
|
||||
} else {
|
||||
// Fallback: parse all tokens as block elements
|
||||
content = parseBlockChildren(token.tokens)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we always have at least an empty paragraph
|
||||
if (content.length === 0) {
|
||||
content = [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'listItem',
|
||||
content,
|
||||
}
|
||||
},
|
||||
|
||||
renderMarkdown: (node, h, ctx) => {
|
||||
return renderNestedMarkdownContent(
|
||||
node,
|
||||
h,
|
||||
(context: any) => {
|
||||
if (context.parentType === 'bulletList') {
|
||||
return '- '
|
||||
}
|
||||
if (context.parentType === 'orderedList') {
|
||||
const start = context.meta?.parentAttrs?.start || 1
|
||||
return `${start + context.index}. `
|
||||
}
|
||||
// Fallback to bullet list for unknown parent types
|
||||
return '- '
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Enter: () => this.editor.commands.splitListItem(this.name),
|
||||
Tab: () => this.editor.commands.sinkListItem(this.name),
|
||||
'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
|
||||
}
|
||||
},
|
||||
})
|
||||
2
node_modules/@tiptap/extension-list/src/keymap/index.ts
generated
vendored
Normal file
2
node_modules/@tiptap/extension-list/src/keymap/index.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './list-keymap.js'
|
||||
export * as listHelpers from './listHelpers/index.js'
|
||||
106
node_modules/@tiptap/extension-list/src/keymap/list-keymap.ts
generated
vendored
Normal file
106
node_modules/@tiptap/extension-list/src/keymap/list-keymap.ts
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
import { handleBackspace, handleDelete } from './listHelpers/index.js'
|
||||
|
||||
export type ListKeymapOptions = {
|
||||
/**
|
||||
* An array of list types. This is used for item and wrapper list matching.
|
||||
* @default []
|
||||
* @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]
|
||||
*/
|
||||
listTypes: Array<{
|
||||
itemName: string
|
||||
wrapperNames: string[]
|
||||
}>
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension registers custom keymaps to change the behaviour of the backspace and delete keys.
|
||||
* By default Prosemirror keyhandling will always lift or sink items so paragraphs are joined into
|
||||
* the adjacent or previous list item. This extension will prevent this behaviour and instead will
|
||||
* try to join paragraphs from two list items into a single list item.
|
||||
* @see https://www.tiptap.dev/api/extensions/list-keymap
|
||||
*/
|
||||
export const ListKeymap = Extension.create<ListKeymapOptions>({
|
||||
name: 'listKeymap',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
listTypes: [
|
||||
{
|
||||
itemName: 'listItem',
|
||||
wrapperNames: ['bulletList', 'orderedList'],
|
||||
},
|
||||
{
|
||||
itemName: 'taskItem',
|
||||
wrapperNames: ['taskList'],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Delete: ({ editor }) => {
|
||||
let handled = false
|
||||
|
||||
this.options.listTypes.forEach(({ itemName }) => {
|
||||
if (editor.state.schema.nodes[itemName] === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (handleDelete(editor, itemName)) {
|
||||
handled = true
|
||||
}
|
||||
})
|
||||
|
||||
return handled
|
||||
},
|
||||
'Mod-Delete': ({ editor }) => {
|
||||
let handled = false
|
||||
|
||||
this.options.listTypes.forEach(({ itemName }) => {
|
||||
if (editor.state.schema.nodes[itemName] === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (handleDelete(editor, itemName)) {
|
||||
handled = true
|
||||
}
|
||||
})
|
||||
|
||||
return handled
|
||||
},
|
||||
Backspace: ({ editor }) => {
|
||||
let handled = false
|
||||
|
||||
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
||||
if (editor.state.schema.nodes[itemName] === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (handleBackspace(editor, itemName, wrapperNames)) {
|
||||
handled = true
|
||||
}
|
||||
})
|
||||
|
||||
return handled
|
||||
},
|
||||
'Mod-Backspace': ({ editor }) => {
|
||||
let handled = false
|
||||
|
||||
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
||||
if (editor.state.schema.nodes[itemName] === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (handleBackspace(editor, itemName, wrapperNames)) {
|
||||
handled = true
|
||||
}
|
||||
})
|
||||
|
||||
return handled
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
30
node_modules/@tiptap/extension-list/src/keymap/listHelpers/findListItemPos.ts
generated
vendored
Normal file
30
node_modules/@tiptap/extension-list/src/keymap/listHelpers/findListItemPos.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { getNodeType } from '@tiptap/core'
|
||||
import type { NodeType } from '@tiptap/pm/model'
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
export const findListItemPos = (typeOrName: string | NodeType, state: EditorState) => {
|
||||
const { $from } = state.selection
|
||||
const nodeType = getNodeType(typeOrName, state.schema)
|
||||
|
||||
let currentNode = null
|
||||
let currentDepth = $from.depth
|
||||
let currentPos = $from.pos
|
||||
let targetDepth: number | null = null
|
||||
|
||||
while (currentDepth > 0 && targetDepth === null) {
|
||||
currentNode = $from.node(currentDepth)
|
||||
|
||||
if (currentNode.type === nodeType) {
|
||||
targetDepth = currentDepth
|
||||
} else {
|
||||
currentDepth -= 1
|
||||
currentPos -= 1
|
||||
}
|
||||
}
|
||||
|
||||
if (targetDepth === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return { $pos: state.doc.resolve(currentPos), depth: targetDepth }
|
||||
}
|
||||
16
node_modules/@tiptap/extension-list/src/keymap/listHelpers/getNextListDepth.ts
generated
vendored
Normal file
16
node_modules/@tiptap/extension-list/src/keymap/listHelpers/getNextListDepth.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import { getNodeAtPosition } from '@tiptap/core'
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
import { findListItemPos } from './findListItemPos.js'
|
||||
|
||||
export const getNextListDepth = (typeOrName: string, state: EditorState) => {
|
||||
const listItemPos = findListItemPos(typeOrName, state)
|
||||
|
||||
if (!listItemPos) {
|
||||
return false
|
||||
}
|
||||
|
||||
const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4)
|
||||
|
||||
return depth
|
||||
}
|
||||
85
node_modules/@tiptap/extension-list/src/keymap/listHelpers/handleBackspace.ts
generated
vendored
Normal file
85
node_modules/@tiptap/extension-list/src/keymap/listHelpers/handleBackspace.ts
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
import type { Editor } from '@tiptap/core'
|
||||
import { isAtStartOfNode, isNodeActive } from '@tiptap/core'
|
||||
import type { Node } from '@tiptap/pm/model'
|
||||
|
||||
import { findListItemPos } from './findListItemPos.js'
|
||||
import { hasListBefore } from './hasListBefore.js'
|
||||
import { hasListItemBefore } from './hasListItemBefore.js'
|
||||
import { listItemHasSubList } from './listItemHasSubList.js'
|
||||
|
||||
export const handleBackspace = (editor: Editor, name: string, parentListTypes: string[]) => {
|
||||
// this is required to still handle the undo handling
|
||||
if (editor.commands.undoInputRule()) {
|
||||
return true
|
||||
}
|
||||
|
||||
// if the selection is not collapsed
|
||||
// we can rely on the default backspace behavior
|
||||
if (editor.state.selection.from !== editor.state.selection.to) {
|
||||
return false
|
||||
}
|
||||
|
||||
// if the current item is NOT inside a list item &
|
||||
// the previous item is a list (orderedList or bulletList)
|
||||
// move the cursor into the list and delete the current item
|
||||
if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
|
||||
const { $anchor } = editor.state.selection
|
||||
|
||||
const $listPos = editor.state.doc.resolve($anchor.before() - 1)
|
||||
|
||||
const listDescendants: Array<{ node: Node; pos: number }> = []
|
||||
|
||||
$listPos.node().descendants((node, pos) => {
|
||||
if (node.type.name === name) {
|
||||
listDescendants.push({ node, pos })
|
||||
}
|
||||
})
|
||||
|
||||
const lastItem = listDescendants.at(-1)
|
||||
|
||||
if (!lastItem) {
|
||||
return false
|
||||
}
|
||||
|
||||
const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1)
|
||||
|
||||
return editor
|
||||
.chain()
|
||||
.cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end())
|
||||
.joinForward()
|
||||
.run()
|
||||
}
|
||||
|
||||
// if the cursor is not inside the current node type
|
||||
// do nothing and proceed
|
||||
if (!isNodeActive(editor.state, name)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// if the cursor is not at the start of a node
|
||||
// do nothing and proceed
|
||||
if (!isAtStartOfNode(editor.state)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const listItemPos = findListItemPos(name, editor.state)
|
||||
|
||||
if (!listItemPos) {
|
||||
return false
|
||||
}
|
||||
|
||||
const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2)
|
||||
const prevNode = $prev.node(listItemPos.depth)
|
||||
|
||||
const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode)
|
||||
|
||||
// if the previous item is a list item and doesn't have a sublist, join the list items
|
||||
if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
|
||||
return editor.commands.joinItemBackward()
|
||||
}
|
||||
|
||||
// otherwise in the end, a backspace should
|
||||
// always just lift the list item if
|
||||
// joining / merging is not possible
|
||||
return editor.chain().liftListItem(name).run()
|
||||
}
|
||||
44
node_modules/@tiptap/extension-list/src/keymap/listHelpers/handleDelete.ts
generated
vendored
Normal file
44
node_modules/@tiptap/extension-list/src/keymap/listHelpers/handleDelete.ts
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { Editor } from '@tiptap/core'
|
||||
import { isAtEndOfNode, isNodeActive } from '@tiptap/core'
|
||||
|
||||
import { nextListIsDeeper } from './nextListIsDeeper.js'
|
||||
import { nextListIsHigher } from './nextListIsHigher.js'
|
||||
|
||||
export const handleDelete = (editor: Editor, name: string) => {
|
||||
// if the cursor is not inside the current node type
|
||||
// do nothing and proceed
|
||||
if (!isNodeActive(editor.state, name)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// if the cursor is not at the end of a node
|
||||
// do nothing and proceed
|
||||
if (!isAtEndOfNode(editor.state, name)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// if the selection is not collapsed, or not within a single node
|
||||
// do nothing and proceed
|
||||
const { selection } = editor.state
|
||||
const { $from, $to } = selection
|
||||
|
||||
if (!selection.empty && $from.sameParent($to)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// check if the next node is a list with a deeper depth
|
||||
if (nextListIsDeeper(name, editor.state)) {
|
||||
return editor
|
||||
.chain()
|
||||
.focus(editor.state.selection.from + 4)
|
||||
.lift(name)
|
||||
.joinBackward()
|
||||
.run()
|
||||
}
|
||||
|
||||
if (nextListIsHigher(name, editor.state)) {
|
||||
return editor.chain().joinForward().joinBackward().run()
|
||||
}
|
||||
|
||||
return editor.commands.joinItemForward()
|
||||
}
|
||||
15
node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListBefore.ts
generated
vendored
Normal file
15
node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListBefore.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
export const hasListBefore = (editorState: EditorState, name: string, parentListTypes: string[]) => {
|
||||
const { $anchor } = editorState.selection
|
||||
|
||||
const previousNodePos = Math.max(0, $anchor.pos - 2)
|
||||
|
||||
const previousNode = editorState.doc.resolve(previousNodePos).node()
|
||||
|
||||
if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
17
node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListItemAfter.ts
generated
vendored
Normal file
17
node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListItemAfter.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
export const hasListItemAfter = (typeOrName: string, state: EditorState): boolean => {
|
||||
const { $anchor } = state.selection
|
||||
|
||||
const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2)
|
||||
|
||||
if ($targetPos.index() === $targetPos.parent.childCount - 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
if ($targetPos.nodeAfter?.type.name !== typeOrName) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
17
node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListItemBefore.ts
generated
vendored
Normal file
17
node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListItemBefore.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
export const hasListItemBefore = (typeOrName: string, state: EditorState): boolean => {
|
||||
const { $anchor } = state.selection
|
||||
|
||||
const $targetPos = state.doc.resolve($anchor.pos - 2)
|
||||
|
||||
if ($targetPos.index() === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
if ($targetPos.nodeBefore?.type.name !== typeOrName) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
10
node_modules/@tiptap/extension-list/src/keymap/listHelpers/index.ts
generated
vendored
Normal file
10
node_modules/@tiptap/extension-list/src/keymap/listHelpers/index.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export * from './findListItemPos.js'
|
||||
export * from './getNextListDepth.js'
|
||||
export * from './handleBackspace.js'
|
||||
export * from './handleDelete.js'
|
||||
export * from './hasListBefore.js'
|
||||
export * from './hasListItemAfter.js'
|
||||
export * from './hasListItemBefore.js'
|
||||
export * from './listItemHasSubList.js'
|
||||
export * from './nextListIsDeeper.js'
|
||||
export * from './nextListIsHigher.js'
|
||||
21
node_modules/@tiptap/extension-list/src/keymap/listHelpers/listItemHasSubList.ts
generated
vendored
Normal file
21
node_modules/@tiptap/extension-list/src/keymap/listHelpers/listItemHasSubList.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { getNodeType } from '@tiptap/core'
|
||||
import type { Node } from '@tiptap/pm/model'
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
export const listItemHasSubList = (typeOrName: string, state: EditorState, node?: Node) => {
|
||||
if (!node) {
|
||||
return false
|
||||
}
|
||||
|
||||
const nodeType = getNodeType(typeOrName, state.schema)
|
||||
|
||||
let hasSubList = false
|
||||
|
||||
node.descendants(child => {
|
||||
if (child.type === nodeType) {
|
||||
hasSubList = true
|
||||
}
|
||||
})
|
||||
|
||||
return hasSubList
|
||||
}
|
||||
19
node_modules/@tiptap/extension-list/src/keymap/listHelpers/nextListIsDeeper.ts
generated
vendored
Normal file
19
node_modules/@tiptap/extension-list/src/keymap/listHelpers/nextListIsDeeper.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
import { findListItemPos } from './findListItemPos.js'
|
||||
import { getNextListDepth } from './getNextListDepth.js'
|
||||
|
||||
export const nextListIsDeeper = (typeOrName: string, state: EditorState) => {
|
||||
const listDepth = getNextListDepth(typeOrName, state)
|
||||
const listItemPos = findListItemPos(typeOrName, state)
|
||||
|
||||
if (!listItemPos || !listDepth) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (listDepth > listItemPos.depth) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
19
node_modules/@tiptap/extension-list/src/keymap/listHelpers/nextListIsHigher.ts
generated
vendored
Normal file
19
node_modules/@tiptap/extension-list/src/keymap/listHelpers/nextListIsHigher.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { EditorState } from '@tiptap/pm/state'
|
||||
|
||||
import { findListItemPos } from './findListItemPos.js'
|
||||
import { getNextListDepth } from './getNextListDepth.js'
|
||||
|
||||
export const nextListIsHigher = (typeOrName: string, state: EditorState) => {
|
||||
const listDepth = getNextListDepth(typeOrName, state)
|
||||
const listItemPos = findListItemPos(typeOrName, state)
|
||||
|
||||
if (!listItemPos || !listDepth) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (listDepth < listItemPos.depth) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
81
node_modules/@tiptap/extension-list/src/kit/index.ts
generated
vendored
Normal file
81
node_modules/@tiptap/extension-list/src/kit/index.ts
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
import type { BulletListOptions } from '../bullet-list/index.js'
|
||||
import { BulletList } from '../bullet-list/index.js'
|
||||
import type { ListItemOptions } from '../item/index.js'
|
||||
import { ListItem } from '../item/index.js'
|
||||
import type { ListKeymapOptions } from '../keymap/index.js'
|
||||
import { ListKeymap } from '../keymap/index.js'
|
||||
import type { OrderedListOptions } from '../ordered-list/index.js'
|
||||
import { OrderedList } from '../ordered-list/index.js'
|
||||
import type { TaskItemOptions } from '../task-item/index.js'
|
||||
import { TaskItem } from '../task-item/index.js'
|
||||
import type { TaskListOptions } from '../task-list/index.js'
|
||||
import { TaskList } from '../task-list/index.js'
|
||||
|
||||
export interface ListKitOptions {
|
||||
/**
|
||||
* If set to false, the bulletList extension will not be registered
|
||||
* @example table: false
|
||||
*/
|
||||
bulletList: Partial<BulletListOptions> | false
|
||||
/**
|
||||
* If set to false, the listItem extension will not be registered
|
||||
*/
|
||||
listItem: Partial<ListItemOptions> | false
|
||||
/**
|
||||
* If set to false, the listKeymap extension will not be registered
|
||||
*/
|
||||
listKeymap: Partial<ListKeymapOptions> | false
|
||||
/**
|
||||
* If set to false, the orderedList extension will not be registered
|
||||
*/
|
||||
orderedList: Partial<OrderedListOptions> | false
|
||||
/**
|
||||
* If set to false, the taskItem extension will not be registered
|
||||
*/
|
||||
taskItem: Partial<TaskItemOptions> | false
|
||||
/**
|
||||
* If set to false, the taskList extension will not be registered
|
||||
*/
|
||||
taskList: Partial<TaskListOptions> | false
|
||||
}
|
||||
|
||||
/**
|
||||
* The table kit is a collection of table editor extensions.
|
||||
*
|
||||
* It’s a good starting point for building your own table in Tiptap.
|
||||
*/
|
||||
export const ListKit = Extension.create<ListKitOptions>({
|
||||
name: 'listKit',
|
||||
|
||||
addExtensions() {
|
||||
const extensions = []
|
||||
|
||||
if (this.options.bulletList !== false) {
|
||||
extensions.push(BulletList.configure(this.options.bulletList))
|
||||
}
|
||||
|
||||
if (this.options.listItem !== false) {
|
||||
extensions.push(ListItem.configure(this.options.listItem))
|
||||
}
|
||||
|
||||
if (this.options.listKeymap !== false) {
|
||||
extensions.push(ListKeymap.configure(this.options.listKeymap))
|
||||
}
|
||||
|
||||
if (this.options.orderedList !== false) {
|
||||
extensions.push(OrderedList.configure(this.options.orderedList))
|
||||
}
|
||||
|
||||
if (this.options.taskItem !== false) {
|
||||
extensions.push(TaskItem.configure(this.options.taskItem))
|
||||
}
|
||||
|
||||
if (this.options.taskList !== false) {
|
||||
extensions.push(TaskList.configure(this.options.taskList))
|
||||
}
|
||||
|
||||
return extensions
|
||||
},
|
||||
})
|
||||
1
node_modules/@tiptap/extension-list/src/ordered-list/index.ts
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/src/ordered-list/index.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './ordered-list.js'
|
||||
223
node_modules/@tiptap/extension-list/src/ordered-list/ordered-list.ts
generated
vendored
Normal file
223
node_modules/@tiptap/extension-list/src/ordered-list/ordered-list.ts
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'
|
||||
|
||||
import { buildNestedStructure, collectOrderedListItems, parseListItems } from './utils.js'
|
||||
|
||||
const ListItemName = 'listItem'
|
||||
const TextStyleName = 'textStyle'
|
||||
|
||||
export interface OrderedListOptions {
|
||||
/**
|
||||
* The node type name for list items.
|
||||
* @default 'listItem'
|
||||
* @example 'myListItem'
|
||||
*/
|
||||
itemTypeName: string
|
||||
|
||||
/**
|
||||
* The HTML attributes for an ordered list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>
|
||||
|
||||
/**
|
||||
* Keep the marks when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepMarks: boolean
|
||||
|
||||
/**
|
||||
* Keep the attributes when splitting a list item.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
keepAttributes: boolean
|
||||
}
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
orderedList: {
|
||||
/**
|
||||
* Toggle an ordered list
|
||||
* @example editor.commands.toggleOrderedList()
|
||||
*/
|
||||
toggleOrderedList: () => ReturnType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches an ordered list to a 1. on input (or any number followed by a dot).
|
||||
*/
|
||||
export const orderedListInputRegex = /^(\d+)\.\s$/
|
||||
|
||||
/**
|
||||
* This extension allows you to create ordered lists.
|
||||
* This requires the ListItem extension
|
||||
* @see https://www.tiptap.dev/api/nodes/ordered-list
|
||||
* @see https://www.tiptap.dev/api/nodes/list-item
|
||||
*/
|
||||
export const OrderedList = Node.create<OrderedListOptions>({
|
||||
name: 'orderedList',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: 'listItem',
|
||||
HTMLAttributes: {},
|
||||
keepMarks: false,
|
||||
keepAttributes: false,
|
||||
}
|
||||
},
|
||||
|
||||
group: 'block list',
|
||||
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`
|
||||
},
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
start: {
|
||||
default: 1,
|
||||
parseHTML: element => {
|
||||
return element.hasAttribute('start') ? parseInt(element.getAttribute('start') || '', 10) : 1
|
||||
},
|
||||
},
|
||||
type: {
|
||||
default: null,
|
||||
parseHTML: element => element.getAttribute('type'),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: 'ol',
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
const { start, ...attributesWithoutStart } = HTMLAttributes
|
||||
|
||||
return start === 1
|
||||
? ['ol', mergeAttributes(this.options.HTMLAttributes, attributesWithoutStart), 0]
|
||||
: ['ol', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]
|
||||
},
|
||||
|
||||
markdownTokenName: 'list',
|
||||
|
||||
parseMarkdown: (token, helpers) => {
|
||||
if (token.type !== 'list' || !token.ordered) {
|
||||
return []
|
||||
}
|
||||
|
||||
const startValue = token.start || 1
|
||||
const content = token.items ? parseListItems(token.items, helpers) : []
|
||||
|
||||
if (startValue !== 1) {
|
||||
return {
|
||||
type: 'orderedList',
|
||||
attrs: { start: startValue },
|
||||
content,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'orderedList',
|
||||
content,
|
||||
}
|
||||
},
|
||||
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return h.renderChildren(node.content, '\n')
|
||||
},
|
||||
|
||||
markdownTokenizer: {
|
||||
name: 'orderedList',
|
||||
level: 'block',
|
||||
start: (src: string) => {
|
||||
const match = src.match(/^(\s*)(\d+)\.\s+/)
|
||||
const index = match?.index
|
||||
return index !== undefined ? index : -1
|
||||
},
|
||||
tokenize: (src: string, _tokens, lexer) => {
|
||||
const lines = src.split('\n')
|
||||
const [listItems, consumed] = collectOrderedListItems(lines)
|
||||
|
||||
if (listItems.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const items = buildNestedStructure(listItems, 0, lexer)
|
||||
|
||||
if (items.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const startValue = listItems[0]?.number || 1
|
||||
|
||||
return {
|
||||
type: 'list',
|
||||
ordered: true,
|
||||
start: startValue,
|
||||
items,
|
||||
raw: lines.slice(0, consumed).join('\n'),
|
||||
} as unknown as object
|
||||
},
|
||||
},
|
||||
|
||||
markdownOptions: {
|
||||
indentsContent: true,
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
toggleOrderedList:
|
||||
() =>
|
||||
({ commands, chain }) => {
|
||||
if (this.options.keepAttributes) {
|
||||
return chain()
|
||||
.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)
|
||||
.updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName))
|
||||
.run()
|
||||
}
|
||||
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
'Mod-Shift-7': () => this.editor.commands.toggleOrderedList(),
|
||||
}
|
||||
},
|
||||
|
||||
addInputRules() {
|
||||
let inputRule = wrappingInputRule({
|
||||
find: orderedListInputRegex,
|
||||
type: this.type,
|
||||
getAttributes: match => ({ start: +match[1] }),
|
||||
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
|
||||
})
|
||||
|
||||
if (this.options.keepMarks || this.options.keepAttributes) {
|
||||
inputRule = wrappingInputRule({
|
||||
find: orderedListInputRegex,
|
||||
type: this.type,
|
||||
keepMarks: this.options.keepMarks,
|
||||
keepAttributes: this.options.keepAttributes,
|
||||
getAttributes: match => ({ start: +match[1], ...this.editor.getAttributes(TextStyleName) }),
|
||||
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
|
||||
editor: this.editor,
|
||||
})
|
||||
}
|
||||
return [inputRule]
|
||||
},
|
||||
})
|
||||
234
node_modules/@tiptap/extension-list/src/ordered-list/utils.ts
generated
vendored
Normal file
234
node_modules/@tiptap/extension-list/src/ordered-list/utils.ts
generated
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
import type { JSONContent, MarkdownLexerConfiguration, MarkdownParseHelpers, MarkdownToken } from '@tiptap/core'
|
||||
|
||||
/**
|
||||
* Matches an ordered list item line with optional leading whitespace.
|
||||
* Captures: (1) indentation spaces, (2) item number, (3) content after marker
|
||||
* Example matches: "1. Item", " 2. Nested item", " 3. Deeply nested"
|
||||
*/
|
||||
const ORDERED_LIST_ITEM_REGEX = /^(\s*)(\d+)\.\s+(.*)$/
|
||||
|
||||
/**
|
||||
* Matches any line that starts with whitespace (indented content).
|
||||
* Used to identify continuation content that belongs to a list item.
|
||||
*/
|
||||
const INDENTED_LINE_REGEX = /^\s/
|
||||
|
||||
/**
|
||||
* Represents a parsed ordered list item with indentation information
|
||||
*/
|
||||
export interface OrderedListItem {
|
||||
indent: number
|
||||
number: number
|
||||
content: string
|
||||
raw: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects all ordered list items from lines, parsing them into a flat array
|
||||
* with indentation information. Stops collecting continuation content when
|
||||
* encountering nested list items, allowing them to be processed separately.
|
||||
*
|
||||
* @param lines - Array of source lines to parse
|
||||
* @returns Tuple of [listItems array, number of lines consumed]
|
||||
*/
|
||||
export function collectOrderedListItems(lines: string[]): [OrderedListItem[], number] {
|
||||
const listItems: OrderedListItem[] = []
|
||||
let currentLineIndex = 0
|
||||
let consumed = 0
|
||||
|
||||
while (currentLineIndex < lines.length) {
|
||||
const line = lines[currentLineIndex]
|
||||
const match = line.match(ORDERED_LIST_ITEM_REGEX)
|
||||
|
||||
if (!match) {
|
||||
break
|
||||
}
|
||||
|
||||
const [, indent, number, content] = match
|
||||
const indentLevel = indent.length
|
||||
let itemContent = content
|
||||
let nextLineIndex = currentLineIndex + 1
|
||||
const itemLines = [line]
|
||||
|
||||
// Collect continuation lines for this item (but NOT nested list items)
|
||||
while (nextLineIndex < lines.length) {
|
||||
const nextLine = lines[nextLineIndex]
|
||||
const nextMatch = nextLine.match(ORDERED_LIST_ITEM_REGEX)
|
||||
|
||||
// If it's another list item (nested or not), stop collecting
|
||||
if (nextMatch) {
|
||||
break
|
||||
}
|
||||
|
||||
// Check for continuation content (non-list content)
|
||||
if (nextLine.trim() === '') {
|
||||
// Empty line
|
||||
itemLines.push(nextLine)
|
||||
itemContent += '\n'
|
||||
nextLineIndex += 1
|
||||
} else if (nextLine.match(INDENTED_LINE_REGEX)) {
|
||||
// Indented content - part of this item (but not a list item)
|
||||
itemLines.push(nextLine)
|
||||
itemContent += `\n${nextLine.slice(indentLevel + 2)}` // Remove list marker indent
|
||||
nextLineIndex += 1
|
||||
} else {
|
||||
// Non-indented line means end of list
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
listItems.push({
|
||||
indent: indentLevel,
|
||||
number: parseInt(number, 10),
|
||||
content: itemContent.trim(),
|
||||
raw: itemLines.join('\n'),
|
||||
})
|
||||
|
||||
consumed = nextLineIndex
|
||||
currentLineIndex = nextLineIndex
|
||||
}
|
||||
|
||||
return [listItems, consumed]
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively builds a nested structure from a flat array of list items
|
||||
* based on their indentation levels. Creates proper markdown tokens with
|
||||
* nested lists where appropriate.
|
||||
*
|
||||
* @param items - Flat array of list items with indentation info
|
||||
* @param baseIndent - The indentation level to process at this recursion level
|
||||
* @param lexer - Markdown lexer for parsing inline and block content
|
||||
* @returns Array of list_item tokens with proper nesting
|
||||
*/
|
||||
export function buildNestedStructure(
|
||||
items: OrderedListItem[],
|
||||
baseIndent: number,
|
||||
lexer: MarkdownLexerConfiguration,
|
||||
): unknown[] {
|
||||
const result: unknown[] = []
|
||||
let currentIndex = 0
|
||||
|
||||
while (currentIndex < items.length) {
|
||||
const item = items[currentIndex]
|
||||
|
||||
if (item.indent === baseIndent) {
|
||||
// This item belongs at the current level
|
||||
const contentLines = item.content.split('\n')
|
||||
const mainText = contentLines[0]?.trim() || ''
|
||||
|
||||
const tokens = []
|
||||
|
||||
// Always wrap the main text in a paragraph token
|
||||
if (mainText) {
|
||||
tokens.push({
|
||||
type: 'paragraph',
|
||||
raw: mainText,
|
||||
tokens: lexer.inlineTokens(mainText),
|
||||
})
|
||||
}
|
||||
|
||||
// Handle additional content after the main text
|
||||
const additionalContent = contentLines.slice(1).join('\n').trim()
|
||||
if (additionalContent) {
|
||||
// Parse as block tokens (handles mixed unordered lists, etc.)
|
||||
const blockTokens = lexer.blockTokens(additionalContent)
|
||||
tokens.push(...blockTokens)
|
||||
}
|
||||
|
||||
// Look ahead to find nested items at deeper indent levels
|
||||
let lookAheadIndex = currentIndex + 1
|
||||
const nestedItems = []
|
||||
|
||||
while (lookAheadIndex < items.length && items[lookAheadIndex].indent > baseIndent) {
|
||||
nestedItems.push(items[lookAheadIndex])
|
||||
lookAheadIndex += 1
|
||||
}
|
||||
|
||||
// If we have nested items, recursively build their structure
|
||||
if (nestedItems.length > 0) {
|
||||
// Find the next indent level (immediate children)
|
||||
const nextIndent = Math.min(...nestedItems.map(nestedItem => nestedItem.indent))
|
||||
|
||||
// Build the nested list recursively with all nested items
|
||||
// The recursive call will handle further nesting
|
||||
const nestedListItems = buildNestedStructure(nestedItems, nextIndent, lexer)
|
||||
|
||||
// Create a nested list token
|
||||
tokens.push({
|
||||
type: 'list',
|
||||
ordered: true,
|
||||
start: nestedItems[0].number,
|
||||
items: nestedListItems,
|
||||
raw: nestedItems.map(nestedItem => nestedItem.raw).join('\n'),
|
||||
})
|
||||
}
|
||||
|
||||
result.push({
|
||||
type: 'list_item',
|
||||
raw: item.raw,
|
||||
tokens,
|
||||
})
|
||||
|
||||
// Skip the nested items we just processed
|
||||
currentIndex = lookAheadIndex
|
||||
} else {
|
||||
// This item has deeper indent than we're currently processing
|
||||
// It should be handled by a recursive call
|
||||
currentIndex += 1
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses markdown list item tokens into Tiptap JSONContent structure,
|
||||
* ensuring text content is properly wrapped in paragraph nodes.
|
||||
*
|
||||
* @param items - Array of markdown tokens representing list items
|
||||
* @param helpers - Markdown parse helpers for recursive parsing
|
||||
* @returns Array of listItem JSONContent nodes
|
||||
*/
|
||||
export function parseListItems(items: MarkdownToken[], helpers: MarkdownParseHelpers): JSONContent[] {
|
||||
return items.map(item => {
|
||||
if (item.type !== 'list_item') {
|
||||
return helpers.parseChildren([item])[0]
|
||||
}
|
||||
|
||||
// Parse the tokens within the list item
|
||||
const content: JSONContent[] = []
|
||||
|
||||
if (item.tokens && item.tokens.length > 0) {
|
||||
item.tokens.forEach(itemToken => {
|
||||
// If it's already a proper block node (paragraph, list, etc.), parse it directly
|
||||
if (
|
||||
itemToken.type === 'paragraph' ||
|
||||
itemToken.type === 'list' ||
|
||||
itemToken.type === 'blockquote' ||
|
||||
itemToken.type === 'code'
|
||||
) {
|
||||
content.push(...helpers.parseChildren([itemToken]))
|
||||
} else if (itemToken.type === 'text' && itemToken.tokens) {
|
||||
// If it's inline text tokens, wrap them in a paragraph
|
||||
const inlineContent = helpers.parseChildren([itemToken])
|
||||
content.push({
|
||||
type: 'paragraph',
|
||||
content: inlineContent,
|
||||
})
|
||||
} else {
|
||||
// For any other content, try to parse it
|
||||
const parsed = helpers.parseChildren([itemToken])
|
||||
if (parsed.length > 0) {
|
||||
content.push(...parsed)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'listItem',
|
||||
content,
|
||||
}
|
||||
})
|
||||
}
|
||||
1
node_modules/@tiptap/extension-list/src/task-item/index.ts
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/src/task-item/index.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './task-item.js'
|
||||
320
node_modules/@tiptap/extension-list/src/task-item/task-item.ts
generated
vendored
Normal file
320
node_modules/@tiptap/extension-list/src/task-item/task-item.ts
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
import type { KeyboardShortcutCommand } from '@tiptap/core'
|
||||
import {
|
||||
getRenderedAttributes,
|
||||
mergeAttributes,
|
||||
Node,
|
||||
renderNestedMarkdownContent,
|
||||
wrappingInputRule,
|
||||
} from '@tiptap/core'
|
||||
import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
||||
|
||||
export interface TaskItemOptions {
|
||||
/**
|
||||
* A callback function that is called when the checkbox is clicked while the editor is in readonly mode.
|
||||
* @param node The prosemirror node of the task item
|
||||
* @param checked The new checked state
|
||||
* @returns boolean
|
||||
*/
|
||||
onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean
|
||||
|
||||
/**
|
||||
* Controls whether the task items can be nested or not.
|
||||
* @default false
|
||||
* @example true
|
||||
*/
|
||||
nested: boolean
|
||||
|
||||
/**
|
||||
* HTML attributes to add to the task item element.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>
|
||||
|
||||
/**
|
||||
* The node type for taskList nodes
|
||||
* @default 'taskList'
|
||||
* @example 'myCustomTaskList'
|
||||
*/
|
||||
taskListTypeName: string
|
||||
|
||||
/**
|
||||
* Accessibility options for the task item.
|
||||
* @default {}
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
|
||||
* }
|
||||
*/
|
||||
a11y?: {
|
||||
checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a task item to a - [ ] on input.
|
||||
*/
|
||||
export const inputRegex = /^\s*(\[([( |x])?\])\s$/
|
||||
|
||||
/**
|
||||
* This extension allows you to create task items.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-item
|
||||
*/
|
||||
export const TaskItem = Node.create<TaskItemOptions>({
|
||||
name: 'taskItem',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
nested: false,
|
||||
HTMLAttributes: {},
|
||||
taskListTypeName: 'taskList',
|
||||
a11y: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
content() {
|
||||
return this.options.nested ? 'paragraph block*' : 'paragraph+'
|
||||
},
|
||||
|
||||
defining: true,
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
checked: {
|
||||
default: false,
|
||||
keepOnSplit: false,
|
||||
parseHTML: element => {
|
||||
const dataChecked = element.getAttribute('data-checked')
|
||||
|
||||
return dataChecked === '' || dataChecked === 'true'
|
||||
},
|
||||
renderHTML: attributes => ({
|
||||
'data-checked': attributes.checked,
|
||||
}),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `li[data-type="${this.name}"]`,
|
||||
priority: 51,
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
renderHTML({ node, HTMLAttributes }) {
|
||||
return [
|
||||
'li',
|
||||
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
|
||||
'data-type': this.name,
|
||||
}),
|
||||
[
|
||||
'label',
|
||||
[
|
||||
'input',
|
||||
{
|
||||
type: 'checkbox',
|
||||
checked: node.attrs.checked ? 'checked' : null,
|
||||
},
|
||||
],
|
||||
['span'],
|
||||
],
|
||||
['div', 0],
|
||||
]
|
||||
},
|
||||
|
||||
parseMarkdown: (token, h) => {
|
||||
// Parse the task item's text content into paragraph content
|
||||
const content = []
|
||||
|
||||
// First, add the main paragraph content
|
||||
if (token.tokens && token.tokens.length > 0) {
|
||||
// If we have tokens, create a paragraph with the inline content
|
||||
content.push(h.createNode('paragraph', {}, h.parseInline(token.tokens)))
|
||||
} else if (token.text) {
|
||||
// If we have raw text, create a paragraph with text node
|
||||
content.push(h.createNode('paragraph', {}, [h.createNode('text', { text: token.text })]))
|
||||
} else {
|
||||
// Fallback: empty paragraph
|
||||
content.push(h.createNode('paragraph', {}, []))
|
||||
}
|
||||
|
||||
// Then, add any nested content (like nested task lists)
|
||||
if (token.nestedTokens && token.nestedTokens.length > 0) {
|
||||
const nestedContent = h.parseChildren(token.nestedTokens)
|
||||
content.push(...nestedContent)
|
||||
}
|
||||
|
||||
return h.createNode('taskItem', { checked: token.checked || false }, content)
|
||||
},
|
||||
|
||||
renderMarkdown: (node, h) => {
|
||||
const checkedChar = node.attrs?.checked ? 'x' : ' '
|
||||
const prefix = `- [${checkedChar}] `
|
||||
|
||||
return renderNestedMarkdownContent(node, h, prefix)
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
const shortcuts: {
|
||||
[key: string]: KeyboardShortcutCommand
|
||||
} = {
|
||||
Enter: () => this.editor.commands.splitListItem(this.name),
|
||||
'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
|
||||
}
|
||||
|
||||
if (!this.options.nested) {
|
||||
return shortcuts
|
||||
}
|
||||
|
||||
return {
|
||||
...shortcuts,
|
||||
Tab: () => this.editor.commands.sinkListItem(this.name),
|
||||
}
|
||||
},
|
||||
|
||||
addNodeView() {
|
||||
return ({ node, HTMLAttributes, getPos, editor }) => {
|
||||
const listItem = document.createElement('li')
|
||||
const checkboxWrapper = document.createElement('label')
|
||||
const checkboxStyler = document.createElement('span')
|
||||
const checkbox = document.createElement('input')
|
||||
const content = document.createElement('div')
|
||||
|
||||
const updateA11Y = (currentNode: ProseMirrorNode) => {
|
||||
checkbox.ariaLabel =
|
||||
this.options.a11y?.checkboxLabel?.(currentNode, checkbox.checked) ||
|
||||
`Task item checkbox for ${currentNode.textContent || 'empty task item'}`
|
||||
}
|
||||
|
||||
updateA11Y(node)
|
||||
|
||||
checkboxWrapper.contentEditable = 'false'
|
||||
checkbox.type = 'checkbox'
|
||||
checkbox.addEventListener('mousedown', event => event.preventDefault())
|
||||
checkbox.addEventListener('change', event => {
|
||||
// if the editor isn’t editable and we don't have a handler for
|
||||
// readonly checks we have to undo the latest change
|
||||
if (!editor.isEditable && !this.options.onReadOnlyChecked) {
|
||||
checkbox.checked = !checkbox.checked
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const { checked } = event.target as any
|
||||
|
||||
if (editor.isEditable && typeof getPos === 'function') {
|
||||
editor
|
||||
.chain()
|
||||
.focus(undefined, { scrollIntoView: false })
|
||||
.command(({ tr }) => {
|
||||
const position = getPos()
|
||||
|
||||
if (typeof position !== 'number') {
|
||||
return false
|
||||
}
|
||||
const currentNode = tr.doc.nodeAt(position)
|
||||
|
||||
tr.setNodeMarkup(position, undefined, {
|
||||
...currentNode?.attrs,
|
||||
checked,
|
||||
})
|
||||
|
||||
return true
|
||||
})
|
||||
.run()
|
||||
}
|
||||
if (!editor.isEditable && this.options.onReadOnlyChecked) {
|
||||
// Reset state if onReadOnlyChecked returns false
|
||||
if (!this.options.onReadOnlyChecked(node, checked)) {
|
||||
checkbox.checked = !checkbox.checked
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
|
||||
listItem.setAttribute(key, value)
|
||||
})
|
||||
|
||||
listItem.dataset.checked = node.attrs.checked
|
||||
checkbox.checked = node.attrs.checked
|
||||
|
||||
checkboxWrapper.append(checkbox, checkboxStyler)
|
||||
listItem.append(checkboxWrapper, content)
|
||||
|
||||
Object.entries(HTMLAttributes).forEach(([key, value]) => {
|
||||
listItem.setAttribute(key, value)
|
||||
})
|
||||
|
||||
// Track the keys of previously rendered HTML attributes for proper removal
|
||||
let prevRenderedAttributeKeys = new Set(Object.keys(HTMLAttributes))
|
||||
|
||||
return {
|
||||
dom: listItem,
|
||||
contentDOM: content,
|
||||
update: updatedNode => {
|
||||
if (updatedNode.type !== this.type) {
|
||||
return false
|
||||
}
|
||||
|
||||
listItem.dataset.checked = updatedNode.attrs.checked
|
||||
checkbox.checked = updatedNode.attrs.checked
|
||||
updateA11Y(updatedNode)
|
||||
|
||||
// Sync all HTML attributes from the updated node
|
||||
const extensionAttributes = editor.extensionManager.attributes
|
||||
const newHTMLAttributes = getRenderedAttributes(updatedNode, extensionAttributes)
|
||||
const newKeys = new Set(Object.keys(newHTMLAttributes))
|
||||
|
||||
// Remove attributes that were previously rendered but are no longer present
|
||||
// If the attribute exists in static options, restore it instead of removing
|
||||
const staticAttrs = this.options.HTMLAttributes
|
||||
|
||||
prevRenderedAttributeKeys.forEach(key => {
|
||||
if (!newKeys.has(key)) {
|
||||
if (key in staticAttrs) {
|
||||
listItem.setAttribute(key, staticAttrs[key])
|
||||
} else {
|
||||
listItem.removeAttribute(key)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Update or add new attributes
|
||||
Object.entries(newHTMLAttributes).forEach(([key, value]) => {
|
||||
if (value === null || value === undefined) {
|
||||
// If the attribute exists in static options, restore it instead of removing
|
||||
if (key in staticAttrs) {
|
||||
listItem.setAttribute(key, staticAttrs[key])
|
||||
} else {
|
||||
listItem.removeAttribute(key)
|
||||
}
|
||||
} else {
|
||||
listItem.setAttribute(key, value)
|
||||
}
|
||||
})
|
||||
|
||||
// Update the tracked keys for next update
|
||||
prevRenderedAttributeKeys = newKeys
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addInputRules() {
|
||||
return [
|
||||
wrappingInputRule({
|
||||
find: inputRegex,
|
||||
type: this.type,
|
||||
getAttributes: match => ({
|
||||
checked: match[match.length - 1] === 'x',
|
||||
}),
|
||||
}),
|
||||
]
|
||||
},
|
||||
})
|
||||
1
node_modules/@tiptap/extension-list/src/task-list/index.ts
generated
vendored
Normal file
1
node_modules/@tiptap/extension-list/src/task-list/index.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './task-list.js'
|
||||
183
node_modules/@tiptap/extension-list/src/task-list/task-list.ts
generated
vendored
Normal file
183
node_modules/@tiptap/extension-list/src/task-list/task-list.ts
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
import { mergeAttributes, Node, parseIndentedBlocks } from '@tiptap/core'
|
||||
|
||||
export interface TaskListOptions {
|
||||
/**
|
||||
* The node type name for a task item.
|
||||
* @default 'taskItem'
|
||||
* @example 'myCustomTaskItem'
|
||||
*/
|
||||
itemTypeName: string
|
||||
|
||||
/**
|
||||
* The HTML attributes for a task list node.
|
||||
* @default {}
|
||||
* @example { class: 'foo' }
|
||||
*/
|
||||
HTMLAttributes: Record<string, any>
|
||||
}
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
taskList: {
|
||||
/**
|
||||
* Toggle a task list
|
||||
* @example editor.commands.toggleTaskList()
|
||||
*/
|
||||
toggleTaskList: () => ReturnType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to create task lists.
|
||||
* @see https://www.tiptap.dev/api/nodes/task-list
|
||||
*/
|
||||
export const TaskList = Node.create<TaskListOptions>({
|
||||
name: 'taskList',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
itemTypeName: 'taskItem',
|
||||
HTMLAttributes: {},
|
||||
}
|
||||
},
|
||||
|
||||
group: 'block list',
|
||||
|
||||
content() {
|
||||
return `${this.options.itemTypeName}+`
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `ul[data-type="${this.name}"]`,
|
||||
priority: 51,
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ['ul', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': this.name }), 0]
|
||||
},
|
||||
|
||||
parseMarkdown: (token, h) => {
|
||||
return h.createNode('taskList', {}, h.parseChildren(token.items || []))
|
||||
},
|
||||
|
||||
renderMarkdown: (node, h) => {
|
||||
if (!node.content) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return h.renderChildren(node.content, '\n')
|
||||
},
|
||||
|
||||
markdownTokenizer: {
|
||||
name: 'taskList',
|
||||
level: 'block',
|
||||
start(src) {
|
||||
// Look for the start of a task list item
|
||||
const index = src.match(/^\s*[-+*]\s+\[([ xX])\]\s+/)?.index
|
||||
return index !== undefined ? index : -1
|
||||
},
|
||||
tokenize(src, tokens, lexer) {
|
||||
// Helper function to recursively parse task lists
|
||||
const parseTaskListContent = (content: string): any[] | undefined => {
|
||||
const nestedResult = parseIndentedBlocks(
|
||||
content,
|
||||
{
|
||||
itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
|
||||
extractItemData: match => ({
|
||||
indentLevel: match[1].length,
|
||||
mainContent: match[4],
|
||||
checked: match[3].toLowerCase() === 'x',
|
||||
}),
|
||||
createToken: (data, nestedTokens) => ({
|
||||
type: 'taskItem',
|
||||
raw: '',
|
||||
mainContent: data.mainContent,
|
||||
indentLevel: data.indentLevel,
|
||||
checked: data.checked,
|
||||
text: data.mainContent,
|
||||
tokens: lexer.inlineTokens(data.mainContent),
|
||||
nestedTokens,
|
||||
}),
|
||||
// Allow recursive nesting
|
||||
customNestedParser: parseTaskListContent,
|
||||
},
|
||||
lexer,
|
||||
)
|
||||
|
||||
if (nestedResult) {
|
||||
// Return as task list token
|
||||
return [
|
||||
{
|
||||
type: 'taskList',
|
||||
raw: nestedResult.raw,
|
||||
items: nestedResult.items,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
// Fall back to regular markdown parsing if not a task list
|
||||
return lexer.blockTokens(content)
|
||||
}
|
||||
|
||||
const result = parseIndentedBlocks(
|
||||
src,
|
||||
{
|
||||
itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
|
||||
extractItemData: match => ({
|
||||
indentLevel: match[1].length,
|
||||
mainContent: match[4],
|
||||
checked: match[3].toLowerCase() === 'x',
|
||||
}),
|
||||
createToken: (data, nestedTokens) => ({
|
||||
type: 'taskItem',
|
||||
raw: '',
|
||||
mainContent: data.mainContent,
|
||||
indentLevel: data.indentLevel,
|
||||
checked: data.checked,
|
||||
text: data.mainContent,
|
||||
tokens: lexer.inlineTokens(data.mainContent),
|
||||
nestedTokens,
|
||||
}),
|
||||
// Use the recursive parser for nested content
|
||||
customNestedParser: parseTaskListContent,
|
||||
},
|
||||
lexer,
|
||||
)
|
||||
|
||||
if (!result) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'taskList',
|
||||
raw: result.raw,
|
||||
items: result.items,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
markdownOptions: {
|
||||
indentsContent: true,
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
toggleTaskList:
|
||||
() =>
|
||||
({ commands }) => {
|
||||
return commands.toggleList(this.name, this.options.itemTypeName)
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
'Mod-Shift-9': () => this.editor.commands.toggleTaskList(),
|
||||
}
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user