@doist/typist 14.1.1 → 14.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [14.1.2](https://github.com/Doist/typist/compare/v14.1.1...v14.1.2) (2026-06-18)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **rich-text:** Degrade pasted HTML tables to string when tables unavailable ([#1386](https://github.com/Doist/typist/issues/1386)) ([f2111fd](https://github.com/Doist/typist/commit/f2111fd340102739ec201aeb1f193d9ecf65b103))
6
+
1
7
  ## [14.1.1](https://github.com/Doist/typist/compare/v14.1.0...v14.1.1) (2026-06-17)
2
8
 
3
9
  ### Bug Fixes
@@ -105,6 +105,15 @@ type RichTextKitOptions = {
105
105
  * Set to `false` to disable the `PasteEmojis` extension.
106
106
  */
107
107
  pasteEmojis: false;
108
+ /**
109
+ * Set to `false` to disable the `PasteHTMLTableAsString` extension, which converts pasted HTML
110
+ * tables (e.g. from spreadsheets or GitHub Flavored Markdown) into space-separated paragraphs.
111
+ *
112
+ * This extension is only registered when native table support is unavailable (i.e. `table` is
113
+ * `false`, or the document is singleline). When tables are enabled, pasted tables become native
114
+ * tables instead, so this option has no effect.
115
+ */
116
+ pasteHTMLTableAsString: false;
108
117
  /**
109
118
  * Set to `false` to disable the `PasteMarkdown` extension.
110
119
  */
@@ -1 +1 @@
1
- {"version":3,"file":"rich-text-kit.d.ts","names":[],"sources":["../../../src/extensions/rich-text/rich-text-kit.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAwD6D;KAKxD,kBAAA;;;;EAID,UAAA,EAAY,OAAA,CAAQ,iBAAA;EAKd;;;EAAN,IAAA,EAAM,OAAA,CAAQ,WAAA;EAUR;;;EALN,UAAA,EAAY,OAAA,CAAQ,yBAAA;EAeV;;;EAVV,IAAA,EAAM,OAAA,CAAQ,WAAA;EAyBH;;;EApBX,SAAA,EAAW,OAAA,CAAQ,gBAAA;EA8BV;;;EAzBT,QAAA,EAAU,OAAA,CAAQ,uBAAA;EAmCX;;;EA9BP,UAAA,EAAY,OAAA,CAAQ,iBAAA;EAwCd;;;EAnCN,SAAA;EA6CY;;;EAxCZ,SAAA,EAAW,OAAA,CAAQ,gBAAA;EAkDR;;;EA7CX,OAAA,EAAS,OAAA,CAAQ,sBAAA;EA2EV;;;EAtEP,OAAA,EAAS,OAAA,CAAQ,cAAA;EAlDL;;;EAuDZ,cAAA,EAAgB,OAAA,CAAQ,qBAAA;EAlDV;;;EAuDd,KAAA,EAAO,OAAA,CAAQ,oBAAA;EA7Cf;;;EAkDA,MAAA,EAAQ,OAAA,CAAQ,aAAA;EA7CL;;;EAkDX,IAAA,EAAM,OAAA,CAAQ,mBAAA;EA7CI;;;EAkDlB,QAAA,EAAU,OAAA,CAAQ,eAAA;EAxClB;;;EA6CA,UAAA,EAAY,OAAA,CAAQ,iBAAA;EAnCpB;;;EAwCA,WAAA,EAAa,OAAA,CAAQ,0BAAA;EAnCZ;;;EAwCT,SAAA,EAAW,OAAA,CAAQ,gBAAA;EAnCK;;;EAwCxB,WAAA;EA9BA;;;EAmCA,aAAA;EA9BM;;;EAmCN,mBAAA;EA9BkB;;;EAmClB,MAAA,EAAQ,OAAA,CAAQ,4BAAA;EAzBhB;;;;;;;;EAmCA,KAAA,EAAO,OAAA,CAAQ,oBAAA;EAVf;;;EAeA,IAAA;EALO;;;EAUP,UAAA;AAAA;AAAU;AAAA;;;;AAAA,cAQR,WAAA,EAAW,SAAA,CAAA,kBAAA"}
1
+ {"version":3,"file":"rich-text-kit.d.ts","names":[],"sources":["../../../src/extensions/rich-text/rich-text-kit.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyD6D;KAKxD,kBAAA;;;;EAID,UAAA,EAAY,OAAA,CAAQ,iBAAA;EAKd;;;EAAN,IAAA,EAAM,OAAA,CAAQ,WAAA;EAUR;;;EALN,UAAA,EAAY,OAAA,CAAQ,yBAAA;EAeV;;;EAVV,IAAA,EAAM,OAAA,CAAQ,WAAA;EAyBH;;;EApBX,SAAA,EAAW,OAAA,CAAQ,gBAAA;EA8BV;;;EAzBT,QAAA,EAAU,OAAA,CAAQ,uBAAA;EAmCX;;;EA9BP,UAAA,EAAY,OAAA,CAAQ,iBAAA;EAwCd;;;EAnCN,SAAA;EA6CY;;;EAxCZ,SAAA,EAAW,OAAA,CAAQ,gBAAA;EAkDR;;;EA7CX,OAAA,EAAS,OAAA,CAAQ,sBAAA;EAqFV;;;EAhFP,OAAA,EAAS,OAAA,CAAQ,cAAA;EAlDL;;;EAuDZ,cAAA,EAAgB,OAAA,CAAQ,qBAAA;EAlDV;;;EAuDd,KAAA,EAAO,OAAA,CAAQ,oBAAA;EA7Cf;;;EAkDA,MAAA,EAAQ,OAAA,CAAQ,aAAA;EA7CL;;;EAkDX,IAAA,EAAM,OAAA,CAAQ,mBAAA;EA7CI;;;EAkDlB,QAAA,EAAU,OAAA,CAAQ,eAAA;EAxClB;;;EA6CA,UAAA,EAAY,OAAA,CAAQ,iBAAA;EAnCpB;;;EAwCA,WAAA,EAAa,OAAA,CAAQ,0BAAA;EAnCZ;;;EAwCT,SAAA,EAAW,OAAA,CAAQ,gBAAA;EAnCK;;;EAwCxB,WAAA;EA9BA;;;;;;;;EAwCA,sBAAA;EAzBA;;;EA8BA,aAAA;EAzBa;;;EA8Bb,mBAAA;EAzBmB;;;EA8BnB,MAAA,EAAQ,OAAA,CAAQ,4BAAA;EALhB;;;;;;;;EAeA,KAAA,EAAO,OAAA,CAAQ,oBAAA;EAUL;AAAA;AAAA;EALV,IAAA;;;AAaa;EARb,UAAA;AAAA;;;;;;cAQE,WAAA,EAAW,SAAA,CAAA,kBAAA"}
@@ -1,5 +1,6 @@
1
1
  import "../../constants/extension-priorities.js";
2
2
  import { CopyMarkdownSource } from "../shared/copy-markdown-source.js";
3
+ import { PasteHTMLTableAsString } from "../shared/paste-html-table-as-string.js";
3
4
  import { PasteSinglelineText } from "../shared/paste-singleline-text.js";
4
5
  import { BoldAndItalics } from "./bold-and-italics.js";
5
6
  import { CurvenoteCodemark } from "./curvenote-codemark.js";
@@ -70,6 +71,7 @@ const RichTextKit = Extension.create({
70
71
  if (this.options.strike !== false) extensions.push(RichTextStrikethrough.configure(this.options?.strike));
71
72
  const isSinglelineDocument = this.options.document !== false && this.options.document?.multiline === false;
72
73
  if (this.options.table !== false && !isSinglelineDocument) extensions.push(RichTextTable.configure(this.options?.table), TableRow, TableHeader.extend({ content: "paragraph" }), TableCell.extend({ content: "paragraph" }));
74
+ else if (this.options.pasteHTMLTableAsString !== false) extensions.push(PasteHTMLTableAsString);
73
75
  if (this.options.text !== false) extensions.push(Text);
74
76
  if (this.options.typography !== false) extensions.push(Typography);
75
77
  return extensions;
@@ -1 +1 @@
1
- {"version":3,"file":"rich-text-kit.js","names":[],"sources":["../../../src/extensions/rich-text/rich-text-kit.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport { Blockquote } from '@tiptap/extension-blockquote'\nimport { Bold } from '@tiptap/extension-bold'\nimport { CodeBlock } from '@tiptap/extension-code-block'\nimport { Dropcursor } from '@tiptap/extension-dropcursor'\nimport { Gapcursor } from '@tiptap/extension-gapcursor'\nimport { HardBreak } from '@tiptap/extension-hard-break'\nimport { History } from '@tiptap/extension-history'\nimport { HorizontalRule } from '@tiptap/extension-horizontal-rule'\nimport { Italic } from '@tiptap/extension-italic'\nimport { ListItem } from '@tiptap/extension-list-item'\nimport { ListKeymap } from '@tiptap/extension-list-keymap'\nimport { Paragraph } from '@tiptap/extension-paragraph'\nimport { TableCell } from '@tiptap/extension-table-cell'\nimport { TableHeader } from '@tiptap/extension-table-header'\nimport { TableRow } from '@tiptap/extension-table-row'\nimport { Text } from '@tiptap/extension-text'\nimport { Typography } from '@tiptap/extension-typography'\n\nimport { BLOCKQUOTE_EXTENSION_PRIORITY } from '../../constants/extension-priorities'\nimport { CopyMarkdownSource } from '../shared/copy-markdown-source'\nimport { PasteSinglelineText } from '../shared/paste-singleline-text'\n\nimport { BoldAndItalics } from './bold-and-italics'\nimport { CurvenoteCodemark } from './curvenote-codemark'\nimport { PasteEmojis } from './paste-emojis'\nimport { PasteMarkdown } from './paste-markdown'\nimport { RichTextBulletList } from './rich-text-bullet-list'\nimport { RichTextCode } from './rich-text-code'\nimport { RichTextDocument } from './rich-text-document'\nimport { RichTextHeading, RichTextHeadingOptions } from './rich-text-heading'\nimport { RichTextImage } from './rich-text-image'\nimport { RichTextLink } from './rich-text-link'\nimport { RichTextOrderedList } from './rich-text-ordered-list'\nimport { RichTextStrikethrough } from './rich-text-strikethrough'\nimport { RichTextTable } from './rich-text-table'\n\nimport type { Extensions } from '@tiptap/core'\nimport type { BlockquoteOptions } from '@tiptap/extension-blockquote'\nimport type { BoldOptions } from '@tiptap/extension-bold'\nimport type { CodeOptions } from '@tiptap/extension-code'\nimport type { CodeBlockOptions } from '@tiptap/extension-code-block'\nimport type { DropcursorOptions } from '@tiptap/extension-dropcursor'\nimport type { HardBreakOptions } from '@tiptap/extension-hard-break'\nimport type { HistoryOptions } from '@tiptap/extension-history'\nimport type { HorizontalRuleOptions } from '@tiptap/extension-horizontal-rule'\nimport type { ItalicOptions } from '@tiptap/extension-italic'\nimport type { ListItemOptions } from '@tiptap/extension-list-item'\nimport type { ListKeymapOptions } from '@tiptap/extension-list-keymap'\nimport type { ParagraphOptions } from '@tiptap/extension-paragraph'\nimport type { RichTextBulletListOptions } from './rich-text-bullet-list'\nimport type { RichTextDocumentOptions } from './rich-text-document'\nimport type { RichTextImageOptions } from './rich-text-image'\nimport type { RichTextLinkOptions } from './rich-text-link'\nimport type { RichTextOrderedListOptions } from './rich-text-ordered-list'\nimport type { RichTextStrikethroughOptions } from './rich-text-strikethrough'\nimport type { RichTextTableOptions } from './rich-text-table'\n\n/**\n * The options available to customize the `RichTextKit` extension.\n */\ntype RichTextKitOptions = {\n /**\n * Set options for the `Blockquote` extension, or `false` to disable.\n */\n blockquote: Partial<BlockquoteOptions> | false\n\n /**\n * Set options for the `Bold` extension, or `false` to disable.\n */\n bold: Partial<BoldOptions> | false\n\n /**\n * Set options for the `BulletList` extension, or `false` to disable.\n */\n bulletList: Partial<RichTextBulletListOptions> | false\n\n /**\n * Set options for the `Code` extension, or `false` to disable.\n */\n code: Partial<CodeOptions> | false\n\n /**\n * Set options for the `CodeBlock` extension, or `false` to disable.\n */\n codeBlock: Partial<CodeBlockOptions> | false\n\n /**\n * Set options for the `Document` extension, or `false` to disable.\n */\n document: Partial<RichTextDocumentOptions> | false\n\n /**\n * Set options for the `Dropcursor` extension, or `false` to disable.\n */\n dropCursor: Partial<DropcursorOptions> | false\n\n /**\n * Set to `false` to disable the `Gapcursor` extension.\n */\n gapCursor: false\n\n /**\n * Set options for the `HardBreak` extension, or `false` to disable.\n */\n hardBreak: Partial<HardBreakOptions> | false\n\n /**\n * Set options for the `Heading` extension, or `false` to disable.\n */\n heading: Partial<RichTextHeadingOptions> | false\n\n /**\n * Set options for the `History` extension, or `false` to disable.\n */\n history: Partial<HistoryOptions> | false\n\n /**\n * Set options for the `HorizontalRule` extension, or `false` to disable.\n */\n horizontalRule: Partial<HorizontalRuleOptions> | false\n\n /**\n * Set options for the `Image` extension, or `false` to disable.\n */\n image: Partial<RichTextImageOptions> | false\n\n /**\n * Set options for the `Italic` extension, or `false` to disable.\n */\n italic: Partial<ItalicOptions> | false\n\n /**\n * Set options for the `Link` extension, or `false` to disable.\n */\n link: Partial<RichTextLinkOptions> | false\n\n /**\n * Set options for the `ListItem` extension, or `false` to disable.\n */\n listItem: Partial<ListItemOptions> | false\n\n /**\n * Set options for the `ListKeymap` extension, or `false` to disable.\n */\n listKeymap: Partial<ListKeymapOptions> | false\n\n /**\n * Set options for the `OrderedList` extension, or `false` to disable.\n */\n orderedList: Partial<RichTextOrderedListOptions> | false\n\n /**\n * Set options for the `Paragraph` extension, or `false` to disable.\n */\n paragraph: Partial<ParagraphOptions> | false\n\n /**\n * Set to `false` to disable the `PasteEmojis` extension.\n */\n pasteEmojis: false\n\n /**\n * Set to `false` to disable the `PasteMarkdown` extension.\n */\n pasteMarkdown: false\n\n /**\n * Set to `false` to disable the `PasteSinglelineText` extension.\n */\n pasteSinglelineText: false\n\n /**\n * Set options for the `Strike` extension, or `false` to disable.\n */\n strike: Partial<RichTextStrikethroughOptions> | false\n\n /**\n * Set options for the `Table` extension, or `false` to disable.\n *\n * Note that table cells are restricted to a single paragraph of content, since the GFM table\n * syntax cannot represent multiple blocks within a cell (which also means that tables require\n * a `paragraph` node in the editor schema). Additionally, tables are always disabled in\n * singleline documents, since they serialize to multiple lines of Markdown.\n */\n table: Partial<RichTextTableOptions> | false\n\n /**\n * Set to `false` to disable the `Text` extension.\n */\n text: false\n\n /**\n * Set to `false` to disable the `Typography` extension.\n */\n typography: false\n}\n\n/**\n * The `RichTextKit` extension is a collection of the minimal required extensions to have a full\n * WYSIWYG text editor working. This extension is based on the official `StarterKit` extension\n * implementation, allowing almost every extension to be customized or disabled.\n */\nconst RichTextKit = Extension.create<RichTextKitOptions>({\n name: 'richTextKit',\n addExtensions() {\n const extensions: Extensions = []\n\n if (this.options.blockquote !== false) {\n extensions.push(\n Blockquote.extend({\n priority: BLOCKQUOTE_EXTENSION_PRIORITY,\n }).configure(this.options?.blockquote),\n )\n }\n\n if (this.options.bold !== false) {\n extensions.push(Bold.configure(this.options?.bold))\n }\n\n if (this.options.bulletList !== false) {\n extensions.push(RichTextBulletList.configure(this.options?.bulletList))\n }\n\n if (this.options.code !== false) {\n extensions.push(\n RichTextCode.configure(this.options?.code),\n\n // Enhances the Code extension capabilities with additional features\n CurvenoteCodemark,\n )\n }\n\n if (this.options.codeBlock !== false) {\n extensions.push(CodeBlock.configure(this.options?.codeBlock))\n }\n\n if (this.options.document !== false) {\n extensions.push(\n RichTextDocument.configure(this.options?.document),\n\n // Supports copying the underlying Markdown source to the clipboard\n CopyMarkdownSource.configure({\n keyboardShortcut: 'Mod-Shift-c',\n }),\n )\n\n if (this.options?.pasteEmojis !== false) {\n // Supports pasting HTML image emojis as unicode characters\n extensions.push(PasteEmojis)\n }\n\n if (this.options?.pasteMarkdown !== false) {\n // Supports pasting Markdown content as HTML into the editor\n extensions.push(PasteMarkdown)\n }\n\n if (\n this.options?.document?.multiline === false &&\n this.options?.pasteSinglelineText !== false\n ) {\n // Supports pasting multiple lines into a singleline editor, by joining all the\n // pasted lines together\n extensions.push(PasteSinglelineText)\n }\n }\n\n if (this.options.dropCursor !== false) {\n extensions.push(Dropcursor.configure(this.options?.dropCursor))\n }\n\n if (this.options.gapCursor !== false) {\n extensions.push(Gapcursor)\n }\n\n if (this.options.hardBreak !== false) {\n extensions.push(HardBreak.configure(this.options?.hardBreak))\n }\n\n if (this.options.heading !== false) {\n extensions.push(RichTextHeading.configure(this.options?.heading))\n }\n\n if (this.options.history !== false) {\n extensions.push(History.configure(this.options?.history))\n }\n\n if (this.options.horizontalRule !== false) {\n extensions.push(HorizontalRule.configure(this.options?.horizontalRule))\n }\n\n if (this.options.image !== false) {\n extensions.push(RichTextImage.configure(this.options?.image))\n }\n\n if (this.options.italic !== false) {\n extensions.push(Italic.configure(this.options?.italic))\n }\n\n if (this.options.bold !== false && this.options.italic !== false) {\n extensions.push(BoldAndItalics)\n }\n\n if (this.options.link !== false) {\n extensions.push(RichTextLink.configure(this.options?.link))\n }\n\n if (this.options.listItem !== false) {\n extensions.push(ListItem.configure(this.options?.listItem))\n }\n\n if (this.options.listKeymap !== false) {\n extensions.push(ListKeymap.configure(this.options?.listKeymap))\n }\n\n if (this.options.orderedList !== false) {\n extensions.push(RichTextOrderedList.configure(this.options?.orderedList))\n }\n\n if (this.options.paragraph !== false) {\n extensions.push(Paragraph.configure(this.options?.paragraph))\n }\n\n if (this.options.strike !== false) {\n extensions.push(RichTextStrikethrough.configure(this.options?.strike))\n }\n\n // Tables are not supported in singleline documents because, although a table is a single\n // block node (which would technically fit the singleline schema), it serializes to\n // multiple lines of Markdown, breaking the singleline contract\n const isSinglelineDocument =\n this.options.document !== false && this.options.document?.multiline === false\n\n if (this.options.table !== false && !isSinglelineDocument) {\n extensions.push(\n RichTextTable.configure(this.options?.table),\n TableRow,\n\n // Restrict cells to a single paragraph (instead of one or more blocks), since the\n // GFM table syntax cannot represent multiple blocks within a cell, ensuring the\n // editor cannot produce tables that lose content when serialized to Markdown\n TableHeader.extend({ content: 'paragraph' }),\n TableCell.extend({ content: 'paragraph' }),\n )\n }\n\n if (this.options.text !== false) {\n extensions.push(Text)\n }\n\n if (this.options.typography !== false) {\n extensions.push(Typography)\n }\n\n return extensions\n },\n})\n\nexport { RichTextKit }\n\nexport type { RichTextKitOptions }\n"],"mappings":"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"}
1
+ {"version":3,"file":"rich-text-kit.js","names":[],"sources":["../../../src/extensions/rich-text/rich-text-kit.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport { Blockquote } from '@tiptap/extension-blockquote'\nimport { Bold } from '@tiptap/extension-bold'\nimport { CodeBlock } from '@tiptap/extension-code-block'\nimport { Dropcursor } from '@tiptap/extension-dropcursor'\nimport { Gapcursor } from '@tiptap/extension-gapcursor'\nimport { HardBreak } from '@tiptap/extension-hard-break'\nimport { History } from '@tiptap/extension-history'\nimport { HorizontalRule } from '@tiptap/extension-horizontal-rule'\nimport { Italic } from '@tiptap/extension-italic'\nimport { ListItem } from '@tiptap/extension-list-item'\nimport { ListKeymap } from '@tiptap/extension-list-keymap'\nimport { Paragraph } from '@tiptap/extension-paragraph'\nimport { TableCell } from '@tiptap/extension-table-cell'\nimport { TableHeader } from '@tiptap/extension-table-header'\nimport { TableRow } from '@tiptap/extension-table-row'\nimport { Text } from '@tiptap/extension-text'\nimport { Typography } from '@tiptap/extension-typography'\n\nimport { BLOCKQUOTE_EXTENSION_PRIORITY } from '../../constants/extension-priorities'\nimport { CopyMarkdownSource } from '../shared/copy-markdown-source'\nimport { PasteHTMLTableAsString } from '../shared/paste-html-table-as-string'\nimport { PasteSinglelineText } from '../shared/paste-singleline-text'\n\nimport { BoldAndItalics } from './bold-and-italics'\nimport { CurvenoteCodemark } from './curvenote-codemark'\nimport { PasteEmojis } from './paste-emojis'\nimport { PasteMarkdown } from './paste-markdown'\nimport { RichTextBulletList } from './rich-text-bullet-list'\nimport { RichTextCode } from './rich-text-code'\nimport { RichTextDocument } from './rich-text-document'\nimport { RichTextHeading, RichTextHeadingOptions } from './rich-text-heading'\nimport { RichTextImage } from './rich-text-image'\nimport { RichTextLink } from './rich-text-link'\nimport { RichTextOrderedList } from './rich-text-ordered-list'\nimport { RichTextStrikethrough } from './rich-text-strikethrough'\nimport { RichTextTable } from './rich-text-table'\n\nimport type { Extensions } from '@tiptap/core'\nimport type { BlockquoteOptions } from '@tiptap/extension-blockquote'\nimport type { BoldOptions } from '@tiptap/extension-bold'\nimport type { CodeOptions } from '@tiptap/extension-code'\nimport type { CodeBlockOptions } from '@tiptap/extension-code-block'\nimport type { DropcursorOptions } from '@tiptap/extension-dropcursor'\nimport type { HardBreakOptions } from '@tiptap/extension-hard-break'\nimport type { HistoryOptions } from '@tiptap/extension-history'\nimport type { HorizontalRuleOptions } from '@tiptap/extension-horizontal-rule'\nimport type { ItalicOptions } from '@tiptap/extension-italic'\nimport type { ListItemOptions } from '@tiptap/extension-list-item'\nimport type { ListKeymapOptions } from '@tiptap/extension-list-keymap'\nimport type { ParagraphOptions } from '@tiptap/extension-paragraph'\nimport type { RichTextBulletListOptions } from './rich-text-bullet-list'\nimport type { RichTextDocumentOptions } from './rich-text-document'\nimport type { RichTextImageOptions } from './rich-text-image'\nimport type { RichTextLinkOptions } from './rich-text-link'\nimport type { RichTextOrderedListOptions } from './rich-text-ordered-list'\nimport type { RichTextStrikethroughOptions } from './rich-text-strikethrough'\nimport type { RichTextTableOptions } from './rich-text-table'\n\n/**\n * The options available to customize the `RichTextKit` extension.\n */\ntype RichTextKitOptions = {\n /**\n * Set options for the `Blockquote` extension, or `false` to disable.\n */\n blockquote: Partial<BlockquoteOptions> | false\n\n /**\n * Set options for the `Bold` extension, or `false` to disable.\n */\n bold: Partial<BoldOptions> | false\n\n /**\n * Set options for the `BulletList` extension, or `false` to disable.\n */\n bulletList: Partial<RichTextBulletListOptions> | false\n\n /**\n * Set options for the `Code` extension, or `false` to disable.\n */\n code: Partial<CodeOptions> | false\n\n /**\n * Set options for the `CodeBlock` extension, or `false` to disable.\n */\n codeBlock: Partial<CodeBlockOptions> | false\n\n /**\n * Set options for the `Document` extension, or `false` to disable.\n */\n document: Partial<RichTextDocumentOptions> | false\n\n /**\n * Set options for the `Dropcursor` extension, or `false` to disable.\n */\n dropCursor: Partial<DropcursorOptions> | false\n\n /**\n * Set to `false` to disable the `Gapcursor` extension.\n */\n gapCursor: false\n\n /**\n * Set options for the `HardBreak` extension, or `false` to disable.\n */\n hardBreak: Partial<HardBreakOptions> | false\n\n /**\n * Set options for the `Heading` extension, or `false` to disable.\n */\n heading: Partial<RichTextHeadingOptions> | false\n\n /**\n * Set options for the `History` extension, or `false` to disable.\n */\n history: Partial<HistoryOptions> | false\n\n /**\n * Set options for the `HorizontalRule` extension, or `false` to disable.\n */\n horizontalRule: Partial<HorizontalRuleOptions> | false\n\n /**\n * Set options for the `Image` extension, or `false` to disable.\n */\n image: Partial<RichTextImageOptions> | false\n\n /**\n * Set options for the `Italic` extension, or `false` to disable.\n */\n italic: Partial<ItalicOptions> | false\n\n /**\n * Set options for the `Link` extension, or `false` to disable.\n */\n link: Partial<RichTextLinkOptions> | false\n\n /**\n * Set options for the `ListItem` extension, or `false` to disable.\n */\n listItem: Partial<ListItemOptions> | false\n\n /**\n * Set options for the `ListKeymap` extension, or `false` to disable.\n */\n listKeymap: Partial<ListKeymapOptions> | false\n\n /**\n * Set options for the `OrderedList` extension, or `false` to disable.\n */\n orderedList: Partial<RichTextOrderedListOptions> | false\n\n /**\n * Set options for the `Paragraph` extension, or `false` to disable.\n */\n paragraph: Partial<ParagraphOptions> | false\n\n /**\n * Set to `false` to disable the `PasteEmojis` extension.\n */\n pasteEmojis: false\n\n /**\n * Set to `false` to disable the `PasteHTMLTableAsString` extension, which converts pasted HTML\n * tables (e.g. from spreadsheets or GitHub Flavored Markdown) into space-separated paragraphs.\n *\n * This extension is only registered when native table support is unavailable (i.e. `table` is\n * `false`, or the document is singleline). When tables are enabled, pasted tables become native\n * tables instead, so this option has no effect.\n */\n pasteHTMLTableAsString: false\n\n /**\n * Set to `false` to disable the `PasteMarkdown` extension.\n */\n pasteMarkdown: false\n\n /**\n * Set to `false` to disable the `PasteSinglelineText` extension.\n */\n pasteSinglelineText: false\n\n /**\n * Set options for the `Strike` extension, or `false` to disable.\n */\n strike: Partial<RichTextStrikethroughOptions> | false\n\n /**\n * Set options for the `Table` extension, or `false` to disable.\n *\n * Note that table cells are restricted to a single paragraph of content, since the GFM table\n * syntax cannot represent multiple blocks within a cell (which also means that tables require\n * a `paragraph` node in the editor schema). Additionally, tables are always disabled in\n * singleline documents, since they serialize to multiple lines of Markdown.\n */\n table: Partial<RichTextTableOptions> | false\n\n /**\n * Set to `false` to disable the `Text` extension.\n */\n text: false\n\n /**\n * Set to `false` to disable the `Typography` extension.\n */\n typography: false\n}\n\n/**\n * The `RichTextKit` extension is a collection of the minimal required extensions to have a full\n * WYSIWYG text editor working. This extension is based on the official `StarterKit` extension\n * implementation, allowing almost every extension to be customized or disabled.\n */\nconst RichTextKit = Extension.create<RichTextKitOptions>({\n name: 'richTextKit',\n addExtensions() {\n const extensions: Extensions = []\n\n if (this.options.blockquote !== false) {\n extensions.push(\n Blockquote.extend({\n priority: BLOCKQUOTE_EXTENSION_PRIORITY,\n }).configure(this.options?.blockquote),\n )\n }\n\n if (this.options.bold !== false) {\n extensions.push(Bold.configure(this.options?.bold))\n }\n\n if (this.options.bulletList !== false) {\n extensions.push(RichTextBulletList.configure(this.options?.bulletList))\n }\n\n if (this.options.code !== false) {\n extensions.push(\n RichTextCode.configure(this.options?.code),\n\n // Enhances the Code extension capabilities with additional features\n CurvenoteCodemark,\n )\n }\n\n if (this.options.codeBlock !== false) {\n extensions.push(CodeBlock.configure(this.options?.codeBlock))\n }\n\n if (this.options.document !== false) {\n extensions.push(\n RichTextDocument.configure(this.options?.document),\n\n // Supports copying the underlying Markdown source to the clipboard\n CopyMarkdownSource.configure({\n keyboardShortcut: 'Mod-Shift-c',\n }),\n )\n\n if (this.options?.pasteEmojis !== false) {\n // Supports pasting HTML image emojis as unicode characters\n extensions.push(PasteEmojis)\n }\n\n if (this.options?.pasteMarkdown !== false) {\n // Supports pasting Markdown content as HTML into the editor\n extensions.push(PasteMarkdown)\n }\n\n if (\n this.options?.document?.multiline === false &&\n this.options?.pasteSinglelineText !== false\n ) {\n // Supports pasting multiple lines into a singleline editor, by joining all the\n // pasted lines together\n extensions.push(PasteSinglelineText)\n }\n }\n\n if (this.options.dropCursor !== false) {\n extensions.push(Dropcursor.configure(this.options?.dropCursor))\n }\n\n if (this.options.gapCursor !== false) {\n extensions.push(Gapcursor)\n }\n\n if (this.options.hardBreak !== false) {\n extensions.push(HardBreak.configure(this.options?.hardBreak))\n }\n\n if (this.options.heading !== false) {\n extensions.push(RichTextHeading.configure(this.options?.heading))\n }\n\n if (this.options.history !== false) {\n extensions.push(History.configure(this.options?.history))\n }\n\n if (this.options.horizontalRule !== false) {\n extensions.push(HorizontalRule.configure(this.options?.horizontalRule))\n }\n\n if (this.options.image !== false) {\n extensions.push(RichTextImage.configure(this.options?.image))\n }\n\n if (this.options.italic !== false) {\n extensions.push(Italic.configure(this.options?.italic))\n }\n\n if (this.options.bold !== false && this.options.italic !== false) {\n extensions.push(BoldAndItalics)\n }\n\n if (this.options.link !== false) {\n extensions.push(RichTextLink.configure(this.options?.link))\n }\n\n if (this.options.listItem !== false) {\n extensions.push(ListItem.configure(this.options?.listItem))\n }\n\n if (this.options.listKeymap !== false) {\n extensions.push(ListKeymap.configure(this.options?.listKeymap))\n }\n\n if (this.options.orderedList !== false) {\n extensions.push(RichTextOrderedList.configure(this.options?.orderedList))\n }\n\n if (this.options.paragraph !== false) {\n extensions.push(Paragraph.configure(this.options?.paragraph))\n }\n\n if (this.options.strike !== false) {\n extensions.push(RichTextStrikethrough.configure(this.options?.strike))\n }\n\n // Tables are not supported in singleline documents because, although a table is a single\n // block node (which would technically fit the singleline schema), it serializes to\n // multiple lines of Markdown, breaking the singleline contract\n const isSinglelineDocument =\n this.options.document !== false && this.options.document?.multiline === false\n\n if (this.options.table !== false && !isSinglelineDocument) {\n extensions.push(\n RichTextTable.configure(this.options?.table),\n TableRow,\n\n // Restrict cells to a single paragraph (instead of one or more blocks), since the\n // GFM table syntax cannot represent multiple blocks within a cell, ensuring the\n // editor cannot produce tables that lose content when serialized to Markdown\n TableHeader.extend({ content: 'paragraph' }),\n TableCell.extend({ content: 'paragraph' }),\n )\n } else if (this.options.pasteHTMLTableAsString !== false) {\n // When native tables aren't available (disabled, or a singleline document), gracefully\n // degrade pasted HTML tables (from spreadsheets or GFM) into space-separated paragraphs\n // instead of letting the cell contents run together. This mirrors the `PlainTextKit`,\n // which always registers this extension since it never supports native tables\n extensions.push(PasteHTMLTableAsString)\n }\n\n if (this.options.text !== false) {\n extensions.push(Text)\n }\n\n if (this.options.typography !== false) {\n extensions.push(Typography)\n }\n\n return extensions\n },\n})\n\nexport { RichTextKit }\n\nexport type { RichTextKitOptions }\n"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { Plugin, PluginKey } from "@tiptap/pm/state";
7
7
  * Transforms pasted HTML by converting tables to paragraphs while preserving surrounding content.
8
8
  */
9
9
  function transformPastedHTML(html) {
10
+ if (!/<table[\s>]/i.test(html)) return html;
10
11
  const body = parseHtmlToElement(html);
11
12
  const tables = body.querySelectorAll("table");
12
13
  if (tables.length === 0) return html;
@@ -1 +1 @@
1
- {"version":3,"file":"paste-html-table-as-string.js","names":[],"sources":["../../../src/extensions/shared/paste-html-table-as-string.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { PASTE_HTML_TABLE_AS_STRING_EXTENSION_PRIORITY } from '../../constants/extension-priorities'\nimport { parseHtmlToElement } from '../../helpers/dom'\n\n/**\n * Transforms pasted HTML by converting tables to paragraphs while preserving surrounding content.\n */\nfunction transformPastedHTML(html: string): string {\n const body = parseHtmlToElement(html)\n const tables = body.querySelectorAll('table')\n\n if (tables.length === 0) {\n return html\n }\n\n for (const table of Array.from(tables)) {\n if (!table.rows) {\n continue\n }\n\n // Convert table rows to paragraphs (using innerHTML to preserve formatting)\n const paragraphs = Array.from(table.rows)\n .map((row) =>\n Array.from(row.cells)\n .map((cell) => {\n // Unwrap paragraphs but preserve inline formatting\n const cellParagraphs = cell.querySelectorAll('p')\n\n for (const p of Array.from(cellParagraphs)) {\n p.replaceWith(...Array.from(p.childNodes))\n }\n\n return cell.innerHTML\n })\n .join(' '),\n )\n .filter((row) => row.trim().length > 0)\n .map((row) => {\n const p = document.createElement('p')\n p.innerHTML = row\n return p\n })\n\n table.replaceWith(...paragraphs)\n }\n\n return body.innerHTML\n}\n\n/**\n * The `PasteHTMLTableAsString` extension adds the ability to paste a table copied from a spreadsheet\n * web app (e.g., Google Sheets, Microsoft Excel), along with tables rendered by GitHub Flavored\n * Markdown (GFM), into a plain-text editor.\n *\n * Since plain-text documents cannot represent tables, this extension simply pastes the table as a\n * string of paragraphs (one paragraph per row), with each cell separated by a space character.\n *\n * Lastly, please note that formatting is lost when the copied table comes from Google Sheets or\n * Microsoft Excel, because unfortunately, these apps style the cell contents using CSS.\n */\nconst PasteHTMLTableAsString = Extension.create({\n name: 'pasteHTMLTableAsString',\n priority: PASTE_HTML_TABLE_AS_STRING_EXTENSION_PRIORITY,\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: new PluginKey('pasteHTMLTableAsString'),\n props: {\n transformPastedHTML,\n },\n }),\n ]\n },\n})\n\nexport { PasteHTMLTableAsString, transformPastedHTML }\n"],"mappings":";;;;;;;;AASA,SAAS,oBAAoB,MAAsB;CAC/C,MAAM,OAAO,mBAAmB,IAAI;CACpC,MAAM,SAAS,KAAK,iBAAiB,OAAO;CAE5C,IAAI,OAAO,WAAW,GAClB,OAAO;CAGX,KAAK,MAAM,SAAS,MAAM,KAAK,MAAM,GAAG;EACpC,IAAI,CAAC,MAAM,MACP;EAIJ,MAAM,aAAa,MAAM,KAAK,MAAM,IAAI,CAAC,CACpC,KAAK,QACF,MAAM,KAAK,IAAI,KAAK,CAAC,CAChB,KAAK,SAAS;GAEX,MAAM,iBAAiB,KAAK,iBAAiB,GAAG;GAEhD,KAAK,MAAM,KAAK,MAAM,KAAK,cAAc,GACrC,EAAE,YAAY,GAAG,MAAM,KAAK,EAAE,UAAU,CAAC;GAG7C,OAAO,KAAK;EAChB,CAAC,CAAC,CACD,KAAK,GAAG,CACjB,CAAC,CACA,QAAQ,QAAQ,IAAI,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CACtC,KAAK,QAAQ;GACV,MAAM,IAAI,SAAS,cAAc,GAAG;GACpC,EAAE,YAAY;GACd,OAAO;EACX,CAAC;EAEL,MAAM,YAAY,GAAG,UAAU;CACnC;CAEA,OAAO,KAAK;AAChB;;;;;;;;;;;;AAaA,MAAM,yBAAyB,UAAU,OAAO;CAC5C,MAAM;CACN,UAAU;CACV,wBAAwB;EACpB,OAAO,CACH,IAAI,OAAO;GACP,KAAK,IAAI,UAAU,wBAAwB;GAC3C,OAAO,EACH,oBACJ;EACJ,CAAC,CACL;CACJ;AACJ,CAAC"}
1
+ {"version":3,"file":"paste-html-table-as-string.js","names":[],"sources":["../../../src/extensions/shared/paste-html-table-as-string.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { PASTE_HTML_TABLE_AS_STRING_EXTENSION_PRIORITY } from '../../constants/extension-priorities'\nimport { parseHtmlToElement } from '../../helpers/dom'\n\n/**\n * Transforms pasted HTML by converting tables to paragraphs while preserving surrounding content.\n */\nfunction transformPastedHTML(html: string): string {\n // Cheap guard so non-table HTML pastes skip the full `DOMParser` parse below, which matters now\n // that this extension is also registered for singleline and `table: false` rich-text editors.\n if (!/<table[\\s>]/i.test(html)) {\n return html\n }\n\n const body = parseHtmlToElement(html)\n const tables = body.querySelectorAll('table')\n\n if (tables.length === 0) {\n return html\n }\n\n for (const table of Array.from(tables)) {\n if (!table.rows) {\n continue\n }\n\n // Convert table rows to paragraphs (using innerHTML to preserve formatting)\n const paragraphs = Array.from(table.rows)\n .map((row) =>\n Array.from(row.cells)\n .map((cell) => {\n // Unwrap paragraphs but preserve inline formatting\n const cellParagraphs = cell.querySelectorAll('p')\n\n for (const p of Array.from(cellParagraphs)) {\n p.replaceWith(...Array.from(p.childNodes))\n }\n\n return cell.innerHTML\n })\n .join(' '),\n )\n .filter((row) => row.trim().length > 0)\n .map((row) => {\n const p = document.createElement('p')\n p.innerHTML = row\n return p\n })\n\n table.replaceWith(...paragraphs)\n }\n\n return body.innerHTML\n}\n\n/**\n * The `PasteHTMLTableAsString` extension adds the ability to paste a table copied from a spreadsheet\n * web app (e.g., Google Sheets, Microsoft Excel), along with tables rendered by GitHub Flavored\n * Markdown (GFM), into a plain-text editor.\n *\n * Since plain-text documents cannot represent tables, this extension simply pastes the table as a\n * string of paragraphs (one paragraph per row), with each cell separated by a space character.\n *\n * Lastly, please note that formatting is lost when the copied table comes from Google Sheets or\n * Microsoft Excel, because unfortunately, these apps style the cell contents using CSS.\n */\nconst PasteHTMLTableAsString = Extension.create({\n name: 'pasteHTMLTableAsString',\n priority: PASTE_HTML_TABLE_AS_STRING_EXTENSION_PRIORITY,\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: new PluginKey('pasteHTMLTableAsString'),\n props: {\n transformPastedHTML,\n },\n }),\n ]\n },\n})\n\nexport { PasteHTMLTableAsString, transformPastedHTML }\n"],"mappings":";;;;;;;;AASA,SAAS,oBAAoB,MAAsB;CAG/C,IAAI,CAAC,eAAe,KAAK,IAAI,GACzB,OAAO;CAGX,MAAM,OAAO,mBAAmB,IAAI;CACpC,MAAM,SAAS,KAAK,iBAAiB,OAAO;CAE5C,IAAI,OAAO,WAAW,GAClB,OAAO;CAGX,KAAK,MAAM,SAAS,MAAM,KAAK,MAAM,GAAG;EACpC,IAAI,CAAC,MAAM,MACP;EAIJ,MAAM,aAAa,MAAM,KAAK,MAAM,IAAI,CAAC,CACpC,KAAK,QACF,MAAM,KAAK,IAAI,KAAK,CAAC,CAChB,KAAK,SAAS;GAEX,MAAM,iBAAiB,KAAK,iBAAiB,GAAG;GAEhD,KAAK,MAAM,KAAK,MAAM,KAAK,cAAc,GACrC,EAAE,YAAY,GAAG,MAAM,KAAK,EAAE,UAAU,CAAC;GAG7C,OAAO,KAAK;EAChB,CAAC,CAAC,CACD,KAAK,GAAG,CACjB,CAAC,CACA,QAAQ,QAAQ,IAAI,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CACtC,KAAK,QAAQ;GACV,MAAM,IAAI,SAAS,cAAc,GAAG;GACpC,EAAE,YAAY;GACd,OAAO;EACX,CAAC;EAEL,MAAM,YAAY,GAAG,UAAU;CACnC;CAEA,OAAO,KAAK;AAChB;;;;;;;;;;;;AAaA,MAAM,yBAAyB,UAAU,OAAO;CAC5C,MAAM;CACN,UAAU;CACV,wBAAwB;EACpB,OAAO,CACH,IAAI,OAAO;GACP,KAAK,IAAI,UAAU,wBAAwB;GAC3C,OAAO,EACH,oBACJ;EACJ,CAAC,CACL;CACJ;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@doist/typist",
3
3
  "description": "The mighty Tiptap-based rich-text editor React component that powers Doist products.",
4
- "version": "14.1.1",
4
+ "version": "14.1.2",
5
5
  "license": "MIT",
6
6
  "homepage": "https://typist.doist.dev/",
7
7
  "repository": {