@tiptap/core 2.2.6 → 2.3.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/dist/index.cjs +110 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +110 -32
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +110 -32
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/Editor.d.ts +1 -2
- package/dist/packages/core/src/commands/insertContent.d.ts +2 -0
- package/dist/packages/core/src/commands/insertContentAt.d.ts +2 -0
- package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +4 -1
- package/dist/packages/core/src/types.d.ts +5 -0
- package/package.json +2 -2
- package/src/Editor.ts +16 -3
- package/src/InputRule.ts +20 -0
- package/src/NodePos.ts +2 -2
- package/src/PasteRule.ts +76 -27
- package/src/commands/insertContent.ts +2 -0
- package/src/commands/insertContentAt.ts +22 -4
- package/src/extensions/clipboardTextSerializer.ts +14 -1
- package/src/types.ts +5 -0
package/dist/index.js
CHANGED
|
@@ -661,6 +661,23 @@ function inputRulesPlugin(props) {
|
|
|
661
661
|
if (stored) {
|
|
662
662
|
return stored;
|
|
663
663
|
}
|
|
664
|
+
// if InputRule is triggered by insertContent()
|
|
665
|
+
const simulatedInputMeta = tr.getMeta('applyInputRules');
|
|
666
|
+
const isSimulatedInput = !!simulatedInputMeta;
|
|
667
|
+
if (isSimulatedInput) {
|
|
668
|
+
setTimeout(() => {
|
|
669
|
+
const { from, text } = simulatedInputMeta;
|
|
670
|
+
const to = from + text.length;
|
|
671
|
+
run$1({
|
|
672
|
+
editor,
|
|
673
|
+
from,
|
|
674
|
+
to,
|
|
675
|
+
text,
|
|
676
|
+
rules,
|
|
677
|
+
plugin,
|
|
678
|
+
});
|
|
679
|
+
});
|
|
680
|
+
}
|
|
664
681
|
return tr.selectionSet || tr.docChanged ? null : prev;
|
|
665
682
|
},
|
|
666
683
|
},
|
|
@@ -792,6 +809,14 @@ function run(config) {
|
|
|
792
809
|
const success = handlers.every(handler => handler !== null);
|
|
793
810
|
return success;
|
|
794
811
|
}
|
|
812
|
+
const createClipboardPasteEvent = (text) => {
|
|
813
|
+
var _a;
|
|
814
|
+
const event = new ClipboardEvent('paste', {
|
|
815
|
+
clipboardData: new DataTransfer(),
|
|
816
|
+
});
|
|
817
|
+
(_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.setData('text/html', text);
|
|
818
|
+
return event;
|
|
819
|
+
};
|
|
795
820
|
/**
|
|
796
821
|
* Create an paste rules plugin. When enabled, it will cause pasted
|
|
797
822
|
* text that matches any of the given rules to trigger the rule’s
|
|
@@ -804,6 +829,28 @@ function pasteRulesPlugin(props) {
|
|
|
804
829
|
let isDroppedFromProseMirror = false;
|
|
805
830
|
let pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null;
|
|
806
831
|
let dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
|
|
832
|
+
const processEvent = ({ state, from, to, rule, pasteEvt, }) => {
|
|
833
|
+
const tr = state.tr;
|
|
834
|
+
const chainableState = createChainableState({
|
|
835
|
+
state,
|
|
836
|
+
transaction: tr,
|
|
837
|
+
});
|
|
838
|
+
const handler = run({
|
|
839
|
+
editor,
|
|
840
|
+
state: chainableState,
|
|
841
|
+
from: Math.max(from - 1, 0),
|
|
842
|
+
to: to.b - 1,
|
|
843
|
+
rule,
|
|
844
|
+
pasteEvent: pasteEvt,
|
|
845
|
+
dropEvent,
|
|
846
|
+
});
|
|
847
|
+
if (!handler || !tr.steps.length) {
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
|
|
851
|
+
pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null;
|
|
852
|
+
return tr;
|
|
853
|
+
};
|
|
807
854
|
const plugins = rules.map(rule => {
|
|
808
855
|
return new Plugin({
|
|
809
856
|
// we register a global drag handler to track the current drag source element
|
|
@@ -841,38 +888,39 @@ function pasteRulesPlugin(props) {
|
|
|
841
888
|
const transaction = transactions[0];
|
|
842
889
|
const isPaste = transaction.getMeta('uiEvent') === 'paste' && !isPastedFromProseMirror;
|
|
843
890
|
const isDrop = transaction.getMeta('uiEvent') === 'drop' && !isDroppedFromProseMirror;
|
|
844
|
-
if
|
|
891
|
+
// if PasteRule is triggered by insertContent()
|
|
892
|
+
const simulatedPasteMeta = transaction.getMeta('applyPasteRules');
|
|
893
|
+
const isSimulatedPaste = !!simulatedPasteMeta;
|
|
894
|
+
if (!isPaste && !isDrop && !isSimulatedPaste) {
|
|
845
895
|
return;
|
|
846
896
|
}
|
|
847
|
-
//
|
|
897
|
+
// Handle simulated paste
|
|
898
|
+
if (isSimulatedPaste) {
|
|
899
|
+
const { from, text } = simulatedPasteMeta;
|
|
900
|
+
const to = from + text.length;
|
|
901
|
+
const pasteEvt = createClipboardPasteEvent(text);
|
|
902
|
+
return processEvent({
|
|
903
|
+
rule,
|
|
904
|
+
state,
|
|
905
|
+
from,
|
|
906
|
+
to: { b: to },
|
|
907
|
+
pasteEvt,
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
// handle actual paste/drop
|
|
848
911
|
const from = oldState.doc.content.findDiffStart(state.doc.content);
|
|
849
912
|
const to = oldState.doc.content.findDiffEnd(state.doc.content);
|
|
913
|
+
// stop if there is no changed range
|
|
850
914
|
if (!isNumber(from) || !to || from === to.b) {
|
|
851
915
|
return;
|
|
852
916
|
}
|
|
853
|
-
|
|
854
|
-
// so we can use a single transaction for all paste rules
|
|
855
|
-
const tr = state.tr;
|
|
856
|
-
const chainableState = createChainableState({
|
|
857
|
-
state,
|
|
858
|
-
transaction: tr,
|
|
859
|
-
});
|
|
860
|
-
const handler = run({
|
|
861
|
-
editor,
|
|
862
|
-
state: chainableState,
|
|
863
|
-
from: Math.max(from - 1, 0),
|
|
864
|
-
to: to.b - 1,
|
|
917
|
+
return processEvent({
|
|
865
918
|
rule,
|
|
866
|
-
|
|
867
|
-
|
|
919
|
+
state,
|
|
920
|
+
from,
|
|
921
|
+
to,
|
|
922
|
+
pasteEvt: pasteEvent,
|
|
868
923
|
});
|
|
869
|
-
// stop if there are no changes
|
|
870
|
-
if (!handler || !tr.steps.length) {
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
|
|
874
|
-
pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null;
|
|
875
|
-
return tr;
|
|
876
924
|
},
|
|
877
925
|
});
|
|
878
926
|
});
|
|
@@ -1239,6 +1287,11 @@ function getTextSerializersFromSchema(schema) {
|
|
|
1239
1287
|
|
|
1240
1288
|
const ClipboardTextSerializer = Extension.create({
|
|
1241
1289
|
name: 'clipboardTextSerializer',
|
|
1290
|
+
addOptions() {
|
|
1291
|
+
return {
|
|
1292
|
+
blockSeparator: undefined,
|
|
1293
|
+
};
|
|
1294
|
+
},
|
|
1242
1295
|
addProseMirrorPlugins() {
|
|
1243
1296
|
return [
|
|
1244
1297
|
new Plugin({
|
|
@@ -1254,6 +1307,9 @@ const ClipboardTextSerializer = Extension.create({
|
|
|
1254
1307
|
const textSerializers = getTextSerializersFromSchema(schema);
|
|
1255
1308
|
const range = { from, to };
|
|
1256
1309
|
return getTextBetween(doc, range, {
|
|
1310
|
+
...(this.options.blockSeparator !== undefined
|
|
1311
|
+
? { blockSeparator: this.options.blockSeparator }
|
|
1312
|
+
: {}),
|
|
1257
1313
|
textSerializers,
|
|
1258
1314
|
});
|
|
1259
1315
|
},
|
|
@@ -1660,6 +1716,8 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
|
|
|
1660
1716
|
options = {
|
|
1661
1717
|
parseOptions: {},
|
|
1662
1718
|
updateSelection: true,
|
|
1719
|
+
applyInputRules: false,
|
|
1720
|
+
applyPasteRules: false,
|
|
1663
1721
|
...options,
|
|
1664
1722
|
};
|
|
1665
1723
|
const content = createNodeFromContent(value, editor.schema, {
|
|
@@ -1695,28 +1753,37 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
|
|
|
1695
1753
|
to += 1;
|
|
1696
1754
|
}
|
|
1697
1755
|
}
|
|
1756
|
+
let newContent;
|
|
1698
1757
|
// if there is only plain text we have to use `insertText`
|
|
1699
1758
|
// because this will keep the current marks
|
|
1700
1759
|
if (isOnlyTextContent) {
|
|
1701
1760
|
// if value is string, we can use it directly
|
|
1702
1761
|
// otherwise if it is an array, we have to join it
|
|
1703
1762
|
if (Array.isArray(value)) {
|
|
1704
|
-
|
|
1763
|
+
newContent = value.map(v => v.text || '').join('');
|
|
1705
1764
|
}
|
|
1706
1765
|
else if (typeof value === 'object' && !!value && !!value.text) {
|
|
1707
|
-
|
|
1766
|
+
newContent = value.text;
|
|
1708
1767
|
}
|
|
1709
1768
|
else {
|
|
1710
|
-
|
|
1769
|
+
newContent = value;
|
|
1711
1770
|
}
|
|
1771
|
+
tr.insertText(newContent, from, to);
|
|
1712
1772
|
}
|
|
1713
1773
|
else {
|
|
1714
|
-
|
|
1774
|
+
newContent = content;
|
|
1775
|
+
tr.replaceWith(from, to, newContent);
|
|
1715
1776
|
}
|
|
1716
1777
|
// set cursor at end of inserted content
|
|
1717
1778
|
if (options.updateSelection) {
|
|
1718
1779
|
selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
|
|
1719
1780
|
}
|
|
1781
|
+
if (options.applyInputRules) {
|
|
1782
|
+
tr.setMeta('applyInputRules', { from, text: newContent });
|
|
1783
|
+
}
|
|
1784
|
+
if (options.applyPasteRules) {
|
|
1785
|
+
tr.setMeta('applyPasteRules', { from, text: newContent });
|
|
1786
|
+
}
|
|
1720
1787
|
}
|
|
1721
1788
|
return true;
|
|
1722
1789
|
};
|
|
@@ -3327,7 +3394,7 @@ const Tabindex = Extension.create({
|
|
|
3327
3394
|
},
|
|
3328
3395
|
});
|
|
3329
3396
|
|
|
3330
|
-
var
|
|
3397
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
3331
3398
|
__proto__: null,
|
|
3332
3399
|
ClipboardTextSerializer: ClipboardTextSerializer,
|
|
3333
3400
|
Commands: Commands,
|
|
@@ -3431,7 +3498,7 @@ class NodePos {
|
|
|
3431
3498
|
const children = [];
|
|
3432
3499
|
this.node.content.forEach((node, offset) => {
|
|
3433
3500
|
const isBlock = node.isBlock && !node.isTextblock;
|
|
3434
|
-
const targetPos = this.pos + offset +
|
|
3501
|
+
const targetPos = this.pos + offset + 1;
|
|
3435
3502
|
const $pos = this.resolvedPos.doc.resolve(targetPos);
|
|
3436
3503
|
if (!isBlock && $pos.depth <= this.depth) {
|
|
3437
3504
|
return;
|
|
@@ -3480,7 +3547,7 @@ class NodePos {
|
|
|
3480
3547
|
querySelectorAll(selector, attributes = {}, firstItemOnly = false) {
|
|
3481
3548
|
let nodes = [];
|
|
3482
3549
|
// iterate through children recursively finding all nodes which match the selector with the node name
|
|
3483
|
-
if (
|
|
3550
|
+
if (!this.children || this.children.length === 0) {
|
|
3484
3551
|
return nodes;
|
|
3485
3552
|
}
|
|
3486
3553
|
this.children.forEach(childPos => {
|
|
@@ -3617,6 +3684,7 @@ class Editor extends EventEmitter {
|
|
|
3617
3684
|
editable: true,
|
|
3618
3685
|
editorProps: {},
|
|
3619
3686
|
parseOptions: {},
|
|
3687
|
+
coreExtensionOptions: {},
|
|
3620
3688
|
enableInputRules: true,
|
|
3621
3689
|
enablePasteRules: true,
|
|
3622
3690
|
enableCoreExtensions: true,
|
|
@@ -3762,7 +3830,17 @@ class Editor extends EventEmitter {
|
|
|
3762
3830
|
* Creates an extension manager.
|
|
3763
3831
|
*/
|
|
3764
3832
|
createExtensionManager() {
|
|
3765
|
-
|
|
3833
|
+
var _a, _b;
|
|
3834
|
+
const coreExtensions = this.options.enableCoreExtensions ? [
|
|
3835
|
+
Editable,
|
|
3836
|
+
ClipboardTextSerializer.configure({
|
|
3837
|
+
blockSeparator: (_b = (_a = this.options.coreExtensionOptions) === null || _a === void 0 ? void 0 : _a.clipboardTextSerializer) === null || _b === void 0 ? void 0 : _b.blockSeparator,
|
|
3838
|
+
}),
|
|
3839
|
+
Commands,
|
|
3840
|
+
FocusEvents,
|
|
3841
|
+
Keymap,
|
|
3842
|
+
Tabindex,
|
|
3843
|
+
] : [];
|
|
3766
3844
|
const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {
|
|
3767
3845
|
return ['extension', 'node', 'mark'].includes(extension === null || extension === void 0 ? void 0 : extension.type);
|
|
3768
3846
|
});
|
|
@@ -4613,5 +4691,5 @@ class Tracker {
|
|
|
4613
4691
|
}
|
|
4614
4692
|
}
|
|
4615
4693
|
|
|
4616
|
-
export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodePos, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, extensions, findChildren, findChildrenInRange, findDuplicates, findParentNode, findParentNodeClosestToPos, fromString, generateHTML, generateJSON, generateText, getAttributes, getAttributesFromExtensions, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAtPosition, getNodeAttributes, getNodeType, getRenderedAttributes, getSchema, getSchemaByResolvedExtensions, getSchemaTypeByName, getSchemaTypeNameByName, getSplittedAttributes, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, injectExtensionAttributesToParseRule, inputRulesPlugin, isActive, isAtEndOfNode, isAtStartOfNode, isEmptyObject, isExtensionRulesEnabled, isFunction, isList, isMacOS, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isNumber, isPlainObject, isRegExp, isString, isTextSelection, isiOS, markInputRule, markPasteRule, mergeAttributes, mergeDeep, minMax, nodeInputRule, nodePasteRule, objectIncludes, pasteRulesPlugin, posToDOMRect, removeDuplicates, resolveFocusPosition, selectionToInsertionEnd, splitExtensions, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
|
|
4694
|
+
export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodePos, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, index as extensions, findChildren, findChildrenInRange, findDuplicates, findParentNode, findParentNodeClosestToPos, fromString, generateHTML, generateJSON, generateText, getAttributes, getAttributesFromExtensions, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAtPosition, getNodeAttributes, getNodeType, getRenderedAttributes, getSchema, getSchemaByResolvedExtensions, getSchemaTypeByName, getSchemaTypeNameByName, getSplittedAttributes, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, injectExtensionAttributesToParseRule, inputRulesPlugin, isActive, isAtEndOfNode, isAtStartOfNode, isEmptyObject, isExtensionRulesEnabled, isFunction, isList, isMacOS, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isNumber, isPlainObject, isRegExp, isString, isTextSelection, isiOS, markInputRule, markPasteRule, mergeAttributes, mergeDeep, minMax, nodeInputRule, nodePasteRule, objectIncludes, pasteRulesPlugin, posToDOMRect, removeDuplicates, resolveFocusPosition, selectionToInsertionEnd, splitExtensions, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
|
|
4617
4695
|
//# sourceMappingURL=index.js.map
|