@tiptap/core 2.5.5 → 2.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +79 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +79 -40
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +79 -40
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +7 -1
- package/dist/packages/core/src/types.d.ts +1 -3
- package/package.json +3 -3
- package/src/Editor.ts +6 -0
- package/src/commands/insertContentAt.ts +7 -0
- package/src/commands/splitBlock.ts +31 -31
- package/src/helpers/createNodeFromContent.ts +21 -13
- package/src/helpers/isNodeEmpty.ts +34 -4
- package/src/types.ts +157 -156
package/dist/index.js
CHANGED
|
@@ -1777,12 +1777,12 @@ function createNodeFromContent(content, schema, options) {
|
|
|
1777
1777
|
}
|
|
1778
1778
|
}
|
|
1779
1779
|
if (isTextContent) {
|
|
1780
|
-
|
|
1781
|
-
let hasInvalidContent = false;
|
|
1782
|
-
let invalidContent = '';
|
|
1783
|
-
// Only ever check for invalid content if we're supposed to throw an error
|
|
1780
|
+
// Check for invalid content
|
|
1784
1781
|
if (options.errorOnInvalidContent) {
|
|
1785
|
-
|
|
1782
|
+
let hasInvalidContent = false;
|
|
1783
|
+
let invalidContent = '';
|
|
1784
|
+
// A copy of the current schema with a catch-all node at the end
|
|
1785
|
+
const contentCheckSchema = new Schema({
|
|
1786
1786
|
topNode: schema.spec.topNode,
|
|
1787
1787
|
marks: schema.spec.marks,
|
|
1788
1788
|
// Prosemirror's schemas are executed such that: the last to execute, matches last
|
|
@@ -1806,15 +1806,21 @@ function createNodeFromContent(content, schema, options) {
|
|
|
1806
1806
|
},
|
|
1807
1807
|
}),
|
|
1808
1808
|
});
|
|
1809
|
+
if (options.slice) {
|
|
1810
|
+
DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
|
|
1811
|
+
}
|
|
1812
|
+
else {
|
|
1813
|
+
DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
|
|
1814
|
+
}
|
|
1815
|
+
if (options.errorOnInvalidContent && hasInvalidContent) {
|
|
1816
|
+
throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) });
|
|
1817
|
+
}
|
|
1809
1818
|
}
|
|
1810
|
-
const parser = DOMParser.fromSchema(
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
: parser.parse(elementFromString(content), options.parseOptions);
|
|
1814
|
-
if (options.errorOnInvalidContent && hasInvalidContent) {
|
|
1815
|
-
throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) });
|
|
1819
|
+
const parser = DOMParser.fromSchema(schema);
|
|
1820
|
+
if (options.slice) {
|
|
1821
|
+
return parser.parseSlice(elementFromString(content), options.parseOptions).content;
|
|
1816
1822
|
}
|
|
1817
|
-
return
|
|
1823
|
+
return parser.parse(elementFromString(content), options.parseOptions);
|
|
1818
1824
|
}
|
|
1819
1825
|
return createNodeFromContent('', schema, options);
|
|
1820
1826
|
}
|
|
@@ -1863,6 +1869,13 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
|
|
|
1863
1869
|
});
|
|
1864
1870
|
}
|
|
1865
1871
|
catch (e) {
|
|
1872
|
+
editor.emit('contentError', {
|
|
1873
|
+
editor,
|
|
1874
|
+
error: e,
|
|
1875
|
+
disableCollaboration: () => {
|
|
1876
|
+
console.error('[tiptap error]: Unable to disable collaboration at this point in time');
|
|
1877
|
+
},
|
|
1878
|
+
});
|
|
1866
1879
|
return false;
|
|
1867
1880
|
}
|
|
1868
1881
|
let { from, to } = typeof position === 'number' ? { from: position, to: position } : { from: position.from, to: position.to };
|
|
@@ -2813,12 +2826,34 @@ function isList(name, extensions) {
|
|
|
2813
2826
|
return group.split(' ').includes('list');
|
|
2814
2827
|
}
|
|
2815
2828
|
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2829
|
+
/**
|
|
2830
|
+
* Returns true if the given node is empty.
|
|
2831
|
+
* When `checkChildren` is true (default), it will also check if all children are empty.
|
|
2832
|
+
*/
|
|
2833
|
+
function isNodeEmpty(node, { checkChildren } = { checkChildren: true }) {
|
|
2834
|
+
if (node.isText) {
|
|
2835
|
+
return !node.text;
|
|
2836
|
+
}
|
|
2837
|
+
if (node.content.childCount === 0) {
|
|
2838
|
+
return true;
|
|
2839
|
+
}
|
|
2840
|
+
if (node.isLeaf) {
|
|
2819
2841
|
return false;
|
|
2820
2842
|
}
|
|
2821
|
-
|
|
2843
|
+
if (checkChildren) {
|
|
2844
|
+
let hasSameContent = true;
|
|
2845
|
+
node.content.forEach(childNode => {
|
|
2846
|
+
if (hasSameContent === false) {
|
|
2847
|
+
// Exit early for perf
|
|
2848
|
+
return;
|
|
2849
|
+
}
|
|
2850
|
+
if (!isNodeEmpty(childNode)) {
|
|
2851
|
+
hasSameContent = false;
|
|
2852
|
+
}
|
|
2853
|
+
});
|
|
2854
|
+
return hasSameContent;
|
|
2855
|
+
}
|
|
2856
|
+
return false;
|
|
2822
2857
|
}
|
|
2823
2858
|
|
|
2824
2859
|
function isNodeSelection(value) {
|
|
@@ -3016,15 +3051,24 @@ const splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor
|
|
|
3016
3051
|
if (!$from.parent.isBlock) {
|
|
3017
3052
|
return false;
|
|
3018
3053
|
}
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3054
|
+
const atEnd = $to.parentOffset === $to.parent.content.size;
|
|
3055
|
+
const deflt = $from.depth === 0
|
|
3056
|
+
? undefined
|
|
3057
|
+
: defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
|
|
3058
|
+
let types = atEnd && deflt
|
|
3059
|
+
? [
|
|
3060
|
+
{
|
|
3061
|
+
type: deflt,
|
|
3062
|
+
attrs: newAttributes,
|
|
3063
|
+
},
|
|
3064
|
+
]
|
|
3065
|
+
: undefined;
|
|
3066
|
+
let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types);
|
|
3067
|
+
if (!types
|
|
3068
|
+
&& !can
|
|
3069
|
+
&& canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined)) {
|
|
3070
|
+
can = true;
|
|
3071
|
+
types = deflt
|
|
3028
3072
|
? [
|
|
3029
3073
|
{
|
|
3030
3074
|
type: deflt,
|
|
@@ -3032,21 +3076,12 @@ const splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor
|
|
|
3032
3076
|
},
|
|
3033
3077
|
]
|
|
3034
3078
|
: undefined;
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
&& !can
|
|
3038
|
-
&& canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined)) {
|
|
3039
|
-
can = true;
|
|
3040
|
-
types = deflt
|
|
3041
|
-
? [
|
|
3042
|
-
{
|
|
3043
|
-
type: deflt,
|
|
3044
|
-
attrs: newAttributes,
|
|
3045
|
-
},
|
|
3046
|
-
]
|
|
3047
|
-
: undefined;
|
|
3048
|
-
}
|
|
3079
|
+
}
|
|
3080
|
+
if (dispatch) {
|
|
3049
3081
|
if (can) {
|
|
3082
|
+
if (selection instanceof TextSelection) {
|
|
3083
|
+
tr.deleteSelection();
|
|
3084
|
+
}
|
|
3050
3085
|
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
3051
3086
|
if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
|
|
3052
3087
|
const first = tr.mapping.map($from.before());
|
|
@@ -3061,7 +3096,7 @@ const splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor
|
|
|
3061
3096
|
}
|
|
3062
3097
|
tr.scrollIntoView();
|
|
3063
3098
|
}
|
|
3064
|
-
return
|
|
3099
|
+
return can;
|
|
3065
3100
|
};
|
|
3066
3101
|
|
|
3067
3102
|
const splitListItem = typeOrName => ({ tr, state, dispatch, editor, }) => {
|
|
@@ -4160,6 +4195,7 @@ class Editor extends EventEmitter {
|
|
|
4160
4195
|
this.prependClass();
|
|
4161
4196
|
// Let’s store the editor instance in the DOM element.
|
|
4162
4197
|
// So we’ll have access to it for tests.
|
|
4198
|
+
// @ts-ignore
|
|
4163
4199
|
const dom = this.view.dom;
|
|
4164
4200
|
dom.editor = this;
|
|
4165
4201
|
}
|
|
@@ -4167,6 +4203,9 @@ class Editor extends EventEmitter {
|
|
|
4167
4203
|
* Creates all node views.
|
|
4168
4204
|
*/
|
|
4169
4205
|
createNodeViews() {
|
|
4206
|
+
if (this.view.isDestroyed) {
|
|
4207
|
+
return;
|
|
4208
|
+
}
|
|
4170
4209
|
this.view.setProps({
|
|
4171
4210
|
nodeViews: this.extensionManager.nodeViews,
|
|
4172
4211
|
});
|