@tiptap/core 2.0.0-beta.180 → 2.0.0-beta.183
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/packages/core/src/Mark.d.ts +8 -0
- package/dist/packages/core/src/pasteRules/index.d.ts +1 -0
- package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +12 -0
- package/dist/tiptap-core.cjs.js +83 -57
- package/dist/tiptap-core.cjs.js.map +1 -1
- package/dist/tiptap-core.esm.js +83 -58
- package/dist/tiptap-core.esm.js.map +1 -1
- package/dist/tiptap-core.umd.js +83 -57
- package/dist/tiptap-core.umd.js.map +1 -1
- package/package.json +9 -9
- package/src/CommandManager.ts +2 -2
- package/src/Editor.ts +1 -0
- package/src/ExtensionManager.ts +13 -4
- package/src/Mark.ts +39 -0
- package/src/PasteRule.ts +2 -2
- package/src/commands/focus.ts +3 -1
- package/src/commands/setContent.ts +1 -4
- package/src/commands/setNodeSelection.ts +3 -5
- package/src/commands/splitBlock.ts +1 -12
- package/src/extensions/focusEvents.ts +2 -2
- package/src/helpers/getTextContentFromNodes.ts +1 -1
- package/src/helpers/isNodeSelection.ts +1 -3
- package/src/helpers/isTextSelection.ts +1 -3
- package/src/pasteRules/index.ts +1 -0
- package/src/pasteRules/nodePasteRule.ts +39 -0
- package/dist/packages/core/src/utilities/isClass.d.ts +0 -1
- package/dist/packages/core/src/utilities/isObject.d.ts +0 -1
- package/src/utilities/isClass.ts +0 -7
- package/src/utilities/isObject.ts +0 -10
package/dist/tiptap-core.esm.js
CHANGED
|
@@ -105,13 +105,13 @@ class CommandManager {
|
|
|
105
105
|
}
|
|
106
106
|
createCan(startTr) {
|
|
107
107
|
const { rawCommands, state } = this;
|
|
108
|
-
const dispatch =
|
|
108
|
+
const dispatch = false;
|
|
109
109
|
const tr = startTr || state.tr;
|
|
110
110
|
const props = this.buildProps(tr, dispatch);
|
|
111
111
|
const formattedCommands = Object.fromEntries(Object
|
|
112
112
|
.entries(rawCommands)
|
|
113
113
|
.map(([name, command]) => {
|
|
114
|
-
return [name, (...args) => command(...args)({ ...props, dispatch })];
|
|
114
|
+
return [name, (...args) => command(...args)({ ...props, dispatch: undefined })];
|
|
115
115
|
}));
|
|
116
116
|
return {
|
|
117
117
|
...formattedCommands,
|
|
@@ -542,10 +542,10 @@ function isExtensionRulesEnabled(extension, enabled) {
|
|
|
542
542
|
const getTextContentFromNodes = ($from, maxMatch = 500) => {
|
|
543
543
|
let textBefore = '';
|
|
544
544
|
$from.parent.nodesBetween(Math.max(0, $from.parentOffset - maxMatch), $from.parentOffset, (node, pos, parent, index) => {
|
|
545
|
-
var _a, _b;
|
|
545
|
+
var _a, _b, _c;
|
|
546
546
|
textBefore += ((_b = (_a = node.type.spec).toText) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
|
547
547
|
node, pos, parent, index,
|
|
548
|
-
})) ||
|
|
548
|
+
})) || ((_c = $from.nodeBefore) === null || _c === void 0 ? void 0 : _c.text) || '%leaf%';
|
|
549
549
|
});
|
|
550
550
|
return textBefore;
|
|
551
551
|
};
|
|
@@ -858,7 +858,7 @@ function pasteRulesPlugin(props) {
|
|
|
858
858
|
editor,
|
|
859
859
|
state: chainableState,
|
|
860
860
|
from: Math.max(from - 1, 0),
|
|
861
|
-
to: to.b,
|
|
861
|
+
to: to.b - 1,
|
|
862
862
|
rule,
|
|
863
863
|
});
|
|
864
864
|
// stop if there are no changes
|
|
@@ -1016,15 +1016,21 @@ class ExtensionManager {
|
|
|
1016
1016
|
};
|
|
1017
1017
|
const plugins = [];
|
|
1018
1018
|
const addKeyboardShortcuts = getExtensionField(extension, 'addKeyboardShortcuts', context);
|
|
1019
|
+
let defaultBindings = {};
|
|
1020
|
+
// bind exit handling
|
|
1021
|
+
if (extension.type === 'mark' && extension.config.exitable) {
|
|
1022
|
+
defaultBindings.ArrowRight = () => Mark.handleExit({ editor, mark: extension });
|
|
1023
|
+
}
|
|
1019
1024
|
if (addKeyboardShortcuts) {
|
|
1020
1025
|
const bindings = Object.fromEntries(Object
|
|
1021
1026
|
.entries(addKeyboardShortcuts())
|
|
1022
1027
|
.map(([shortcut, method]) => {
|
|
1023
1028
|
return [shortcut, () => method({ editor })];
|
|
1024
1029
|
}));
|
|
1025
|
-
|
|
1026
|
-
plugins.push(keyMapPlugin);
|
|
1030
|
+
defaultBindings = { ...defaultBindings, ...bindings };
|
|
1027
1031
|
}
|
|
1032
|
+
const keyMapPlugin = keymap(defaultBindings);
|
|
1033
|
+
plugins.push(keyMapPlugin);
|
|
1028
1034
|
const addInputRules = getExtensionField(extension, 'addInputRules', context);
|
|
1029
1035
|
if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
|
|
1030
1036
|
inputRules.push(...addInputRules());
|
|
@@ -1447,23 +1453,8 @@ const first = commands => props => {
|
|
|
1447
1453
|
return false;
|
|
1448
1454
|
};
|
|
1449
1455
|
|
|
1450
|
-
function isClass(value) {
|
|
1451
|
-
var _a;
|
|
1452
|
-
if (((_a = value.constructor) === null || _a === void 0 ? void 0 : _a.toString().substring(0, 5)) !== 'class') {
|
|
1453
|
-
return false;
|
|
1454
|
-
}
|
|
1455
|
-
return true;
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
function isObject(value) {
|
|
1459
|
-
return (value
|
|
1460
|
-
&& typeof value === 'object'
|
|
1461
|
-
&& !Array.isArray(value)
|
|
1462
|
-
&& !isClass(value));
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
1456
|
function isTextSelection(value) {
|
|
1466
|
-
return
|
|
1457
|
+
return value instanceof TextSelection;
|
|
1467
1458
|
}
|
|
1468
1459
|
|
|
1469
1460
|
function minMax(value = 0, min = 0, max = 0) {
|
|
@@ -1533,7 +1524,9 @@ const focus = (position = null, options = {}) => ({ editor, view, tr, dispatch,
|
|
|
1533
1524
|
delayedFocus();
|
|
1534
1525
|
return true;
|
|
1535
1526
|
}
|
|
1536
|
-
|
|
1527
|
+
// pass through tr.doc instead of editor.state.doc
|
|
1528
|
+
// since transactions could change the editors state before this command has been run
|
|
1529
|
+
const selection = resolveFocusPosition(tr.doc, position) || editor.state.selection;
|
|
1537
1530
|
const isSameSelection = editor.state.selection.eq(selection);
|
|
1538
1531
|
if (dispatch) {
|
|
1539
1532
|
if (!isSameSelection) {
|
|
@@ -1932,10 +1925,8 @@ function createDocument(content, schema, parseOptions = {}) {
|
|
|
1932
1925
|
const setContent = (content, emitUpdate = false, parseOptions = {}) => ({ tr, editor, dispatch }) => {
|
|
1933
1926
|
const { doc } = tr;
|
|
1934
1927
|
const document = createDocument(content, editor.schema, parseOptions);
|
|
1935
|
-
const selection = TextSelection.create(doc, 0, doc.content.size);
|
|
1936
1928
|
if (dispatch) {
|
|
1937
|
-
tr.
|
|
1938
|
-
.replaceSelectionWith(document, false)
|
|
1929
|
+
tr.replaceWith(0, doc.content.size, document)
|
|
1939
1930
|
.setMeta('preventUpdate', !emitUpdate);
|
|
1940
1931
|
}
|
|
1941
1932
|
return true;
|
|
@@ -2036,10 +2027,8 @@ const setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) =>
|
|
|
2036
2027
|
const setNodeSelection = position => ({ tr, dispatch }) => {
|
|
2037
2028
|
if (dispatch) {
|
|
2038
2029
|
const { doc } = tr;
|
|
2039
|
-
const
|
|
2040
|
-
const
|
|
2041
|
-
const resolvedPos = minMax(position, minPos, maxPos);
|
|
2042
|
-
const selection = NodeSelection.create(doc, resolvedPos);
|
|
2030
|
+
const from = minMax(position, 0, doc.content.size);
|
|
2031
|
+
const selection = NodeSelection.create(doc, from);
|
|
2043
2032
|
tr.setSelection(selection);
|
|
2044
2033
|
}
|
|
2045
2034
|
return true;
|
|
@@ -2066,6 +2055,16 @@ const sinkListItem = typeOrName => ({ state, dispatch }) => {
|
|
|
2066
2055
|
return sinkListItem$1(type)(state, dispatch);
|
|
2067
2056
|
};
|
|
2068
2057
|
|
|
2058
|
+
function defaultBlockAt(match) {
|
|
2059
|
+
for (let i = 0; i < match.edgeCount; i += 1) {
|
|
2060
|
+
const { type } = match.edge(i);
|
|
2061
|
+
if (type.isTextblock && !type.hasRequiredAttrs()) {
|
|
2062
|
+
return type;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
return null;
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2069
2068
|
function getSplittedAttributes(extensionAttributes, typeName, attributes) {
|
|
2070
2069
|
return Object.fromEntries(Object
|
|
2071
2070
|
.entries(attributes)
|
|
@@ -2080,15 +2079,6 @@ function getSplittedAttributes(extensionAttributes, typeName, attributes) {
|
|
|
2080
2079
|
}));
|
|
2081
2080
|
}
|
|
2082
2081
|
|
|
2083
|
-
function defaultBlockAt$1(match) {
|
|
2084
|
-
for (let i = 0; i < match.edgeCount; i += 1) {
|
|
2085
|
-
const { type } = match.edge(i);
|
|
2086
|
-
if (type.isTextblock && !type.hasRequiredAttrs()) {
|
|
2087
|
-
return type;
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
return null;
|
|
2091
|
-
}
|
|
2092
2082
|
function ensureMarks(state, splittableMarks) {
|
|
2093
2083
|
const marks = state.storedMarks
|
|
2094
2084
|
|| (state.selection.$to.parentOffset && state.selection.$from.marks());
|
|
@@ -2124,7 +2114,7 @@ const splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor
|
|
|
2124
2114
|
}
|
|
2125
2115
|
const deflt = $from.depth === 0
|
|
2126
2116
|
? undefined
|
|
2127
|
-
: defaultBlockAt
|
|
2117
|
+
: defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
|
|
2128
2118
|
let types = atEnd && deflt
|
|
2129
2119
|
? [{
|
|
2130
2120
|
type: deflt,
|
|
@@ -3089,6 +3079,7 @@ class Editor extends EventEmitter {
|
|
|
3089
3079
|
*/
|
|
3090
3080
|
setEditable(editable) {
|
|
3091
3081
|
this.setOptions({ editable });
|
|
3082
|
+
this.emit('update', { editor: this, transaction: this.state.tr });
|
|
3092
3083
|
}
|
|
3093
3084
|
/**
|
|
3094
3085
|
* Returns whether the editor is editable.
|
|
@@ -3346,16 +3337,6 @@ function combineTransactionSteps(oldDoc, transactions) {
|
|
|
3346
3337
|
return transform;
|
|
3347
3338
|
}
|
|
3348
3339
|
|
|
3349
|
-
function defaultBlockAt(match) {
|
|
3350
|
-
for (let i = 0; i < match.edgeCount; i += 1) {
|
|
3351
|
-
const { type } = match.edge(i);
|
|
3352
|
-
if (type.isTextblock && !type.hasRequiredAttrs()) {
|
|
3353
|
-
return type;
|
|
3354
|
-
}
|
|
3355
|
-
}
|
|
3356
|
-
return null;
|
|
3357
|
-
}
|
|
3358
|
-
|
|
3359
3340
|
function findChildren(node, predicate) {
|
|
3360
3341
|
const nodesWithPos = [];
|
|
3361
3342
|
node.descendants((child, pos) => {
|
|
@@ -3573,7 +3554,7 @@ function getMarksBetween(from, to, doc) {
|
|
|
3573
3554
|
}
|
|
3574
3555
|
|
|
3575
3556
|
function isNodeSelection(value) {
|
|
3576
|
-
return
|
|
3557
|
+
return value instanceof NodeSelection;
|
|
3577
3558
|
}
|
|
3578
3559
|
|
|
3579
3560
|
function posToDOMRect(view, from, to) {
|
|
@@ -3834,6 +3815,26 @@ class Mark {
|
|
|
3834
3815
|
}));
|
|
3835
3816
|
return extension;
|
|
3836
3817
|
}
|
|
3818
|
+
static handleExit({ editor, mark, }) {
|
|
3819
|
+
const { tr } = editor.state;
|
|
3820
|
+
const currentPos = editor.state.selection.$from;
|
|
3821
|
+
const isAtEnd = currentPos.pos === currentPos.end();
|
|
3822
|
+
if (isAtEnd) {
|
|
3823
|
+
const currentMarks = currentPos.marks();
|
|
3824
|
+
const isInMark = !!currentMarks.find(m => (m === null || m === void 0 ? void 0 : m.type.name) === mark.name);
|
|
3825
|
+
if (!isInMark) {
|
|
3826
|
+
return false;
|
|
3827
|
+
}
|
|
3828
|
+
const removeMark = currentMarks.find(m => (m === null || m === void 0 ? void 0 : m.type.name) === mark.name);
|
|
3829
|
+
if (removeMark) {
|
|
3830
|
+
tr.removeStoredMark(removeMark);
|
|
3831
|
+
}
|
|
3832
|
+
tr.insertText(' ', currentPos.pos);
|
|
3833
|
+
editor.view.dispatch(tr);
|
|
3834
|
+
return true;
|
|
3835
|
+
}
|
|
3836
|
+
return false;
|
|
3837
|
+
}
|
|
3837
3838
|
}
|
|
3838
3839
|
|
|
3839
3840
|
class Node {
|
|
@@ -4132,6 +4133,35 @@ function markPasteRule(config) {
|
|
|
4132
4133
|
});
|
|
4133
4134
|
}
|
|
4134
4135
|
|
|
4136
|
+
// source: https://stackoverflow.com/a/6969486
|
|
4137
|
+
function escapeForRegEx(string) {
|
|
4138
|
+
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
4139
|
+
}
|
|
4140
|
+
|
|
4141
|
+
/**
|
|
4142
|
+
* Build an paste rule that adds a node when the
|
|
4143
|
+
* matched text is pasted into it.
|
|
4144
|
+
*/
|
|
4145
|
+
function nodePasteRule(config) {
|
|
4146
|
+
return new PasteRule({
|
|
4147
|
+
find: config.find,
|
|
4148
|
+
handler({ match, chain, range }) {
|
|
4149
|
+
const attributes = callOrReturn(config.getAttributes, undefined, match);
|
|
4150
|
+
if (attributes === false || attributes === null) {
|
|
4151
|
+
return null;
|
|
4152
|
+
}
|
|
4153
|
+
if (match.input) {
|
|
4154
|
+
chain()
|
|
4155
|
+
.deleteRange(range)
|
|
4156
|
+
.insertContent({
|
|
4157
|
+
type: config.type.name,
|
|
4158
|
+
attrs: attributes,
|
|
4159
|
+
});
|
|
4160
|
+
}
|
|
4161
|
+
},
|
|
4162
|
+
});
|
|
4163
|
+
}
|
|
4164
|
+
|
|
4135
4165
|
/**
|
|
4136
4166
|
* Build an paste rule that replaces text when the
|
|
4137
4167
|
* matched text is pasted into it.
|
|
@@ -4183,10 +4213,5 @@ class Tracker {
|
|
|
4183
4213
|
}
|
|
4184
4214
|
}
|
|
4185
4215
|
|
|
4186
|
-
|
|
4187
|
-
function escapeForRegEx(string) {
|
|
4188
|
-
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
4189
|
-
}
|
|
4190
|
-
|
|
4191
|
-
export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, defaultBlockAt, escapeForRegEx, extensions, findChildren, findChildrenInRange, findParentNode, findParentNodeClosestToPos, generateHTML, generateJSON, generateText, getAttributes, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAttributes, getNodeType, getSchema, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, inputRulesPlugin, isActive, isList, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isTextSelection, markInputRule, markPasteRule, mergeAttributes, nodeInputRule, pasteRulesPlugin, posToDOMRect, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
|
|
4216
|
+
export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, defaultBlockAt, escapeForRegEx, extensions, findChildren, findChildrenInRange, findParentNode, findParentNodeClosestToPos, generateHTML, generateJSON, generateText, getAttributes, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAttributes, getNodeType, getSchema, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, inputRulesPlugin, isActive, isList, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isTextSelection, markInputRule, markPasteRule, mergeAttributes, nodeInputRule, nodePasteRule, pasteRulesPlugin, posToDOMRect, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
|
|
4192
4217
|
//# sourceMappingURL=tiptap-core.esm.js.map
|