@doist/typist 13.0.0 → 13.0.1
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
|
+
## [13.0.1](https://github.com/Doist/typist/compare/v13.0.0...v13.0.1) (2026-06-11)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* replace wrapping empty textblock when inserting block-only Markdown content ([#1372](https://github.com/Doist/typist/issues/1372)) ([9ed9697](https://github.com/Doist/typist/commit/9ed969732647541c15c4548df4da20af92ccfe31))
|
|
6
|
+
|
|
1
7
|
## [13.0.0](https://github.com/Doist/typist/compare/v12.0.0...v13.0.0) (2026-06-09)
|
|
2
8
|
|
|
3
9
|
### ⚠ BREAKING CHANGES
|
|
@@ -17,7 +17,7 @@ function insertMarkdownContentAt(position, markdown, options) {
|
|
|
17
17
|
updateSelection: true,
|
|
18
18
|
...options
|
|
19
19
|
};
|
|
20
|
-
|
|
20
|
+
let { from, to } = typeof position === "number" ? {
|
|
21
21
|
from: position,
|
|
22
22
|
to: position
|
|
23
23
|
} : {
|
|
@@ -26,6 +26,17 @@ function insertMarkdownContentAt(position, markdown, options) {
|
|
|
26
26
|
};
|
|
27
27
|
const htmlContent = getHTMLSerializerInstance(editor.schema).serialize(markdown);
|
|
28
28
|
const content = DOMParser.fromSchema(editor.schema).parseSlice(parseHtmlToElement(htmlContent), options.parseOptions);
|
|
29
|
+
let isOnlyBlockContent = content.content.childCount > 0;
|
|
30
|
+
content.content.forEach((node) => {
|
|
31
|
+
isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false;
|
|
32
|
+
});
|
|
33
|
+
if (from === to && isOnlyBlockContent) {
|
|
34
|
+
const { parent } = tr.doc.resolve(from);
|
|
35
|
+
if (parent.isTextblock && !parent.type.spec.code && !parent.childCount) {
|
|
36
|
+
from -= 1;
|
|
37
|
+
to += 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
29
40
|
tr.replaceRange(from, to, content);
|
|
30
41
|
if (options.updateSelection) selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
|
|
31
42
|
}
|
package/dist/extensions/core/extra-editor-commands/commands/insert-markdown-content-at.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insert-markdown-content-at.js","names":[],"sources":["../../../../../src/extensions/core/extra-editor-commands/commands/insert-markdown-content-at.ts"],"sourcesContent":["import { RawCommands, selectionToInsertionEnd } from '@tiptap/core'\nimport { DOMParser } from '@tiptap/pm/model'\n\nimport { parseHtmlToElement } from '../../../../helpers/dom'\nimport { getHTMLSerializerInstance } from '../../../../serializers/html/html'\n\nimport type { Range } from '@tiptap/core'\nimport type { ParseOptions } from '@tiptap/pm/model'\n\n/**\n * Augment the official `@tiptap/core` module with extra commands so that the compiler knows about\n * them. For this to work externally, a wildcard export needs to be added to the root `index.ts`.\n */\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n insertMarkdownContentAt: {\n /**\n * Inserts the provided Markdown content as HTML into the editor at a specific position.\n *\n * @param position The position or range the Markdown will be inserted in.\n * @param markdown The Markdown content to parse and insert as HTML.\n * @param options An optional object with the following parameters:\n * @param options.parseOptions The parse options to use when the HTML content is parsed by ProseMirror.\n * @param options.updateSelection Whether the selection should move to the newly inserted content.\n */\n insertMarkdownContentAt: (\n position: number | Range,\n markdown: string,\n options?: {\n parseOptions?: ParseOptions\n updateSelection?: boolean\n },\n ) => ReturnType\n }\n }\n}\n\n/**\n * Inserts the provided Markdown content as HTML into the editor at a specific position.\n *\n * The solution for this function was inspired by how ProseMirror pastes content from the clipboard,\n * and how Tiptap inserts content with the `insertContentAt` command.\n */\nfunction insertMarkdownContentAt(\n position: number | Range,\n markdown: string,\n options?: {\n parseOptions?: ParseOptions\n updateSelection?: boolean\n },\n): ReturnType<RawCommands['insertMarkdownContentAt']> {\n return ({ editor, tr, dispatch }) => {\n // Check if the transaction should be dispatched\n // ref: https://tiptap.dev/api/commands#dry-run-for-commands\n if (dispatch) {\n // Default values for command options must be set here\n // (they do not work if set in the function signature)\n options = {\n parseOptions: {},\n updateSelection: true,\n ...options,\n }\n\n // Get the start and end positions from the provided position\n
|
|
1
|
+
{"version":3,"file":"insert-markdown-content-at.js","names":[],"sources":["../../../../../src/extensions/core/extra-editor-commands/commands/insert-markdown-content-at.ts"],"sourcesContent":["import { RawCommands, selectionToInsertionEnd } from '@tiptap/core'\nimport { DOMParser } from '@tiptap/pm/model'\n\nimport { parseHtmlToElement } from '../../../../helpers/dom'\nimport { getHTMLSerializerInstance } from '../../../../serializers/html/html'\n\nimport type { Range } from '@tiptap/core'\nimport type { ParseOptions } from '@tiptap/pm/model'\n\n/**\n * Augment the official `@tiptap/core` module with extra commands so that the compiler knows about\n * them. For this to work externally, a wildcard export needs to be added to the root `index.ts`.\n */\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n insertMarkdownContentAt: {\n /**\n * Inserts the provided Markdown content as HTML into the editor at a specific position.\n *\n * @param position The position or range the Markdown will be inserted in.\n * @param markdown The Markdown content to parse and insert as HTML.\n * @param options An optional object with the following parameters:\n * @param options.parseOptions The parse options to use when the HTML content is parsed by ProseMirror.\n * @param options.updateSelection Whether the selection should move to the newly inserted content.\n */\n insertMarkdownContentAt: (\n position: number | Range,\n markdown: string,\n options?: {\n parseOptions?: ParseOptions\n updateSelection?: boolean\n },\n ) => ReturnType\n }\n }\n}\n\n/**\n * Inserts the provided Markdown content as HTML into the editor at a specific position.\n *\n * The solution for this function was inspired by how ProseMirror pastes content from the clipboard,\n * and how Tiptap inserts content with the `insertContentAt` command.\n */\nfunction insertMarkdownContentAt(\n position: number | Range,\n markdown: string,\n options?: {\n parseOptions?: ParseOptions\n updateSelection?: boolean\n },\n): ReturnType<RawCommands['insertMarkdownContentAt']> {\n return ({ editor, tr, dispatch }) => {\n // Check if the transaction should be dispatched\n // ref: https://tiptap.dev/api/commands#dry-run-for-commands\n if (dispatch) {\n // Default values for command options must be set here\n // (they do not work if set in the function signature)\n options = {\n parseOptions: {},\n updateSelection: true,\n ...options,\n }\n\n // Get the start and end positions from the provided position\n let { from, to } =\n typeof position === 'number'\n ? { from: position, to: position }\n : { from: position.from, to: position.to }\n\n // Parse the Markdown to HTML and then then into ProseMirror nodes\n const htmlContent = getHTMLSerializerInstance(editor.schema).serialize(markdown)\n const content = DOMParser.fromSchema(editor.schema).parseSlice(\n parseHtmlToElement(htmlContent),\n options.parseOptions,\n )\n\n // Check if the parsed content is non-empty and composed of block nodes only (the\n // initial value guards against an empty insert deleting the wrapping textblock below)\n let isOnlyBlockContent = content.content.childCount > 0\n\n content.content.forEach((node) => {\n isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false\n })\n\n // Expand the insertion range to replace the wrapping empty textblock when only block\n // content is inserted at a cursor position, mirroring the official `insertContentAt`\n // command behaviour (e.g., a table pasted into an empty paragraph should replace the\n // paragraph, instead of keeping the empty paragraph below the table)\n if (from === to && isOnlyBlockContent) {\n const { parent } = tr.doc.resolve(from)\n\n const isEmptyTextBlock =\n parent.isTextblock && !parent.type.spec.code && !parent.childCount\n\n if (isEmptyTextBlock) {\n from -= 1\n to += 1\n }\n }\n\n // Inserts the content into the editor while preserving the current selection\n tr.replaceRange(from, to, content)\n\n // Set the text cursor to the end of the inserted content\n if (options.updateSelection) {\n selectionToInsertionEnd(tr, tr.steps.length - 1, -1)\n }\n }\n\n return true\n }\n}\n\nexport { insertMarkdownContentAt }\n"],"mappings":";;;;;;;;;;;AA2CA,SAAS,wBACL,UACA,UACA,SAIkD;CAClD,QAAQ,EAAE,QAAQ,IAAI,eAAe;EAGjC,IAAI,UAAU;GAGV,UAAU;IACN,cAAc,CAAC;IACf,iBAAiB;IACjB,GAAG;GACP;GAGA,IAAI,EAAE,MAAM,OACR,OAAO,aAAa,WACd;IAAE,MAAM;IAAU,IAAI;GAAS,IAC/B;IAAE,MAAM,SAAS;IAAM,IAAI,SAAS;GAAG;GAGjD,MAAM,cAAc,0BAA0B,OAAO,MAAM,CAAC,CAAC,UAAU,QAAQ;GAC/E,MAAM,UAAU,UAAU,WAAW,OAAO,MAAM,CAAC,CAAC,WAChD,mBAAmB,WAAW,GAC9B,QAAQ,YACZ;GAIA,IAAI,qBAAqB,QAAQ,QAAQ,aAAa;GAEtD,QAAQ,QAAQ,SAAS,SAAS;IAC9B,qBAAqB,qBAAqB,KAAK,UAAU;GAC7D,CAAC;GAMD,IAAI,SAAS,MAAM,oBAAoB;IACnC,MAAM,EAAE,WAAW,GAAG,IAAI,QAAQ,IAAI;IAKtC,IAFI,OAAO,eAAe,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,OAAO,YAEtC;KAClB,QAAQ;KACR,MAAM;IACV;GACJ;GAGA,GAAG,aAAa,MAAM,IAAI,OAAO;GAGjC,IAAI,QAAQ,iBACR,wBAAwB,IAAI,GAAG,MAAM,SAAS,GAAG,EAAE;EAE3D;EAEA,OAAO;CACX;AACJ"}
|
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": "13.0.
|
|
4
|
+
"version": "13.0.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://typist.doist.dev/",
|
|
7
7
|
"repository": {
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"unist-util-visit": "5.1.0"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
107
|
-
"@doist/reactist": "
|
|
107
|
+
"@doist/reactist": "33.0.1",
|
|
108
108
|
"@mdx-js/react": "3.1.1",
|
|
109
109
|
"@semantic-release/changelog": "6.0.3",
|
|
110
110
|
"@semantic-release/exec": "7.1.0",
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
"@testing-library/react": "16.3.2",
|
|
118
118
|
"@types/hast": "3.0.4",
|
|
119
119
|
"@types/lodash-es": "4.17.12",
|
|
120
|
-
"@types/react": "18.3.
|
|
120
|
+
"@types/react": "18.3.31",
|
|
121
121
|
"@types/react-dom": "18.3.7",
|
|
122
122
|
"@types/react-syntax-highlighter": "15.5.13",
|
|
123
123
|
"@types/turndown": "5.0.6",
|