@ctzhian/tiptap 1.3.2 → 1.4.0
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/Editor/demo.js +1 -1
- package/dist/EditorToolbar/index.js +11 -8
- package/dist/component/CustomDragHandle/index.js +6 -29
- package/dist/component/Toolbar/EditorAlignSelect.js +11 -0
- package/dist/component/Toolbar/EditorCode.js +11 -0
- package/dist/component/Toolbar/EditorFontSize.js +11 -0
- package/dist/component/Toolbar/EditorHeading.js +11 -0
- package/dist/component/Toolbar/EditorInsert/index.js +11 -0
- package/dist/component/Toolbar/EditorListSelect.js +11 -0
- package/dist/component/Toolbar/EditorMath.js +11 -0
- package/dist/component/Toolbar/EditorMore/index.js +11 -0
- package/dist/component/Toolbar/EditorScript.js +11 -0
- package/dist/component/Toolbar/EditorVerticalAlignSelect.js +11 -0
- package/dist/component/Toolbar/Item.d.ts +1 -0
- package/dist/component/Toolbar/Item.js +11 -6
- package/dist/component/Toolbar/TableSizePicker.d.ts +5 -0
- package/dist/component/Toolbar/TableSizePicker.js +73 -0
- package/dist/contants/slash-commands.js +14 -13
- package/dist/extension/component/SlashCommandsList/index.js +27 -13
- package/dist/extension/node/Alert.d.ts +9 -1
- package/dist/extension/node/Alert.js +12 -116
- package/dist/extension/node/FileHandler.d.ts +1 -1
- package/dist/extension/node/Table.js +79 -1
- package/dist/index.css +6 -1
- package/dist/util/linewiseConvert.d.ts +0 -2
- package/dist/util/linewiseConvert.js +63 -12
- package/package.json +1 -1
- package/dist/component/ListHover/index.d.ts +0 -7
- package/dist/component/ListHover/index.js +0 -367
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import { mergeAttributes, Node } from '@tiptap/core';
|
|
2
|
-
import { TextSelection } from '@tiptap/pm/state';
|
|
3
2
|
import { ReactNodeViewRenderer } from '@tiptap/react';
|
|
4
3
|
import AlertView from "../component/Alert";
|
|
5
4
|
export var AlertExtension = Node.create({
|
|
6
5
|
name: 'alert',
|
|
7
6
|
group: 'block',
|
|
8
|
-
content: '
|
|
7
|
+
content: 'block+',
|
|
9
8
|
defining: true,
|
|
10
9
|
draggable: true,
|
|
11
10
|
addOptions: function addOptions() {
|
|
12
11
|
return {
|
|
13
|
-
HTMLAttributes: {
|
|
14
|
-
class: 'cq-alert'
|
|
15
|
-
}
|
|
12
|
+
HTMLAttributes: {}
|
|
16
13
|
};
|
|
17
14
|
},
|
|
18
15
|
addAttributes: function addAttributes() {
|
|
@@ -54,8 +51,6 @@ export var AlertExtension = Node.create({
|
|
|
54
51
|
},
|
|
55
52
|
parseHTML: function parseHTML() {
|
|
56
53
|
return [{
|
|
57
|
-
tag: 'div.cq-alert'
|
|
58
|
-
}, {
|
|
59
54
|
tag: 'div[data-node="alert"]'
|
|
60
55
|
}];
|
|
61
56
|
},
|
|
@@ -71,50 +66,15 @@ export var AlertExtension = Node.create({
|
|
|
71
66
|
setAlert: function setAlert() {
|
|
72
67
|
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
73
68
|
return function (_ref2) {
|
|
74
|
-
var
|
|
69
|
+
var commands = _ref2.commands;
|
|
75
70
|
var id = "alert_".concat(Math.random().toString(36).slice(2));
|
|
76
71
|
var variant = attrs.variant || 'info';
|
|
77
72
|
var type = attrs.type || 'icon';
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
type: type
|
|
84
|
-
}
|
|
85
|
-
}).run();
|
|
86
|
-
if (!ok) {
|
|
87
|
-
// 尝试在当前块之后插入
|
|
88
|
-
var state = _this.editor.state;
|
|
89
|
-
var $from = state.selection.$from;
|
|
90
|
-
var afterPos = $from.after($from.depth);
|
|
91
|
-
var fallback = _this.editor.commands.insertContentAt(afterPos, {
|
|
92
|
-
type: _this.name,
|
|
93
|
-
attrs: {
|
|
94
|
-
id: id,
|
|
95
|
-
variant: variant,
|
|
96
|
-
type: type
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
if (!fallback) return false;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// 将光标移动到刚插入的 Alert 内部
|
|
103
|
-
try {
|
|
104
|
-
var doc = _this.editor.state.doc;
|
|
105
|
-
var posInside = null;
|
|
106
|
-
doc.descendants(function (node, pos) {
|
|
107
|
-
if (node.type.name === _this.name && node.attrs.id === id) {
|
|
108
|
-
posInside = pos + 1;
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
return true;
|
|
112
|
-
});
|
|
113
|
-
if (posInside != null) {
|
|
114
|
-
_this.editor.commands.setTextSelection(posInside);
|
|
115
|
-
}
|
|
116
|
-
} catch (_unused) {}
|
|
117
|
-
return true;
|
|
73
|
+
return commands.wrapIn(_this.name, {
|
|
74
|
+
id: id,
|
|
75
|
+
variant: variant,
|
|
76
|
+
type: type
|
|
77
|
+
});
|
|
118
78
|
};
|
|
119
79
|
},
|
|
120
80
|
setAlertVariant: function setAlertVariant(variant) {
|
|
@@ -136,83 +96,19 @@ export var AlertExtension = Node.create({
|
|
|
136
96
|
toggleAlert: function toggleAlert() {
|
|
137
97
|
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
138
98
|
return function (_ref5) {
|
|
139
|
-
var
|
|
140
|
-
|
|
141
|
-
editor = _ref5.editor;
|
|
142
|
-
var tr = state.tr,
|
|
143
|
-
selection = state.selection,
|
|
144
|
-
schema = state.schema;
|
|
145
|
-
var $from = selection.$from;
|
|
146
|
-
var currentNode = $from.node($from.depth);
|
|
147
|
-
var posStart = $from.before($from.depth);
|
|
148
|
-
var posEnd = posStart + currentNode.nodeSize;
|
|
99
|
+
var commands = _ref5.commands;
|
|
100
|
+
var id = "alert_".concat(Math.random().toString(36).slice(2));
|
|
149
101
|
var variant = attrs.variant || 'info';
|
|
150
102
|
var type = attrs.type || 'icon';
|
|
151
|
-
|
|
152
|
-
// 已是 Alert -> 还原为段落
|
|
153
|
-
if (currentNode.type === _this.type) {
|
|
154
|
-
var paragraph = schema.nodes.paragraph.create(undefined, currentNode.content);
|
|
155
|
-
tr.replaceWith(posStart, posEnd, paragraph);
|
|
156
|
-
tr.setSelection(TextSelection.near(tr.doc.resolve(posStart + 1)));
|
|
157
|
-
if (dispatch) dispatch(tr);
|
|
158
|
-
editor.view.focus();
|
|
159
|
-
return true;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// 将当前块替换为 Alert,尽量保留 inline 内容
|
|
163
|
-
var inlineContent = null;
|
|
164
|
-
if (currentNode.isTextblock) {
|
|
165
|
-
inlineContent = currentNode.content;
|
|
166
|
-
} else {
|
|
167
|
-
var textContent = currentNode.textContent || '';
|
|
168
|
-
inlineContent = textContent ? schema.text(textContent) : undefined;
|
|
169
|
-
}
|
|
170
|
-
var id = "alert_".concat(Math.random().toString(36).slice(2));
|
|
171
|
-
var alertNode = schema.nodes.alert.create({
|
|
103
|
+
return commands.toggleWrap(_this.name, {
|
|
172
104
|
id: id,
|
|
173
105
|
variant: variant,
|
|
174
106
|
type: type
|
|
175
|
-
}
|
|
176
|
-
tr.replaceWith(posStart, posEnd, alertNode);
|
|
177
|
-
tr.setSelection(TextSelection.near(tr.doc.resolve(posStart + 1)));
|
|
178
|
-
if (dispatch) dispatch(tr);
|
|
179
|
-
editor.view.focus();
|
|
180
|
-
return true;
|
|
107
|
+
});
|
|
181
108
|
};
|
|
182
109
|
}
|
|
183
110
|
};
|
|
184
111
|
},
|
|
185
|
-
addKeyboardShortcuts: function addKeyboardShortcuts() {
|
|
186
|
-
var _this2 = this;
|
|
187
|
-
return {
|
|
188
|
-
Enter: function Enter() {
|
|
189
|
-
if (!_this2.editor.isActive(_this2.name)) return false;
|
|
190
|
-
// 按回车退出当前 Alert,并在后面新起一段落
|
|
191
|
-
return _this2.editor.chain().command(function (_ref6) {
|
|
192
|
-
var state = _ref6.state,
|
|
193
|
-
tr = _ref6.tr,
|
|
194
|
-
dispatch = _ref6.dispatch;
|
|
195
|
-
var $from = state.selection.$from;
|
|
196
|
-
// 寻找最近的 alert 节点位置
|
|
197
|
-
var pos = $from.before();
|
|
198
|
-
for (var depth = $from.depth; depth > 0; depth--) {
|
|
199
|
-
var _node = $from.node(depth);
|
|
200
|
-
if (_node.type === _this2.type) {
|
|
201
|
-
pos = $from.before(depth);
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
var node = tr.doc.nodeAt(pos);
|
|
206
|
-
if (!node || node.type !== _this2.type) return false;
|
|
207
|
-
var insertPos = pos + node.nodeSize;
|
|
208
|
-
tr.insert(insertPos, _this2.editor.schema.nodes.paragraph.create());
|
|
209
|
-
tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos + 1)));
|
|
210
|
-
if (dispatch) dispatch(tr);
|
|
211
|
-
return true;
|
|
212
|
-
}).run();
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
},
|
|
216
112
|
addNodeView: function addNodeView() {
|
|
217
113
|
return ReactNodeViewRenderer(AlertView);
|
|
218
114
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { UploadFunction } from "../../type";
|
|
2
2
|
export declare const FileHandlerExtension: (props: {
|
|
3
3
|
onUpload?: UploadFunction;
|
|
4
|
-
}) => import("@tiptap/core").Extension<Omit<import("@tiptap/extension-file-handler").FileHandlePluginOptions, "
|
|
4
|
+
}) => import("@tiptap/core").Extension<Omit<import("@tiptap/extension-file-handler").FileHandlePluginOptions, "key" | "editor">, any>;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
3
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
2
5
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
6
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
7
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -8,7 +11,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
8
11
|
|
|
9
12
|
import { Extension } from '@tiptap/core';
|
|
10
13
|
import { Table, TableCell, TableHeader, TableRow } from '@tiptap/extension-table';
|
|
11
|
-
import { TextSelection } from '@tiptap/pm/state';
|
|
14
|
+
import { Plugin, TextSelection } from '@tiptap/pm/state';
|
|
12
15
|
import { createTableContextMenuPlugin } from "../component/Table";
|
|
13
16
|
export var TableExtension = function TableExtension(_ref) {
|
|
14
17
|
var editable = _ref.editable;
|
|
@@ -169,6 +172,81 @@ export var TableExtension = function TableExtension(_ref) {
|
|
|
169
172
|
addProseMirrorPlugins: function addProseMirrorPlugins() {
|
|
170
173
|
return editable ? [createTableContextMenuPlugin(this.editor)] : [];
|
|
171
174
|
}
|
|
175
|
+
}),
|
|
176
|
+
// Safari 中文输入 deleteCompositionText 修复
|
|
177
|
+
Extension.create({
|
|
178
|
+
name: 'safariCompositionDeleteFix',
|
|
179
|
+
addProseMirrorPlugins: function addProseMirrorPlugins() {
|
|
180
|
+
if (!editable) return [];
|
|
181
|
+
var ZERO_WIDTH_SPACE = "\u200B";
|
|
182
|
+
var isSafari = function () {
|
|
183
|
+
if (typeof navigator === 'undefined') return false;
|
|
184
|
+
var ua = navigator.userAgent;
|
|
185
|
+
var isAppleMobile = /iP(ad|hone|od)/.test(ua);
|
|
186
|
+
var isMacSafari = /Safari\//.test(ua) && !/Chrome\//.test(ua);
|
|
187
|
+
return isAppleMobile || isMacSafari;
|
|
188
|
+
}();
|
|
189
|
+
if (!isSafari) return [];
|
|
190
|
+
|
|
191
|
+
// 注意:这里不能使用上面从 ProseMirror 导入的 Node 类型,需判断 DOM 文本节点
|
|
192
|
+
var isTextNode = function isTextNode(node) {
|
|
193
|
+
return !!node && node.nodeType === 3;
|
|
194
|
+
};
|
|
195
|
+
return [new Plugin({
|
|
196
|
+
props: {
|
|
197
|
+
handleDOMEvents: {
|
|
198
|
+
beforeinput: function beforeinput(_view, event) {
|
|
199
|
+
// 仅处理 Safari 在中文合成结束后触发的删除合成文本行为
|
|
200
|
+
if (event.inputType !== 'deleteCompositionText') {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
var selection = window.getSelection();
|
|
204
|
+
if (!selection || selection.rangeCount === 0) return false;
|
|
205
|
+
var range = selection.getRangeAt(0);
|
|
206
|
+
var startContainer = range.startContainer,
|
|
207
|
+
endContainer = range.endContainer,
|
|
208
|
+
startOffset = range.startOffset,
|
|
209
|
+
endOffset = range.endOffset;
|
|
210
|
+
if (isTextNode(startContainer) && startContainer === endContainer && startOffset === 0 && endOffset === startContainer.length) {
|
|
211
|
+
var _startContainer$paren;
|
|
212
|
+
(_startContainer$paren = startContainer.parentElement) === null || _startContainer$paren === void 0 || _startContainer$paren.insertBefore(document.createTextNode(ZERO_WIDTH_SPACE), startContainer);
|
|
213
|
+
}
|
|
214
|
+
// 让 ProseMirror 照常处理
|
|
215
|
+
return false;
|
|
216
|
+
},
|
|
217
|
+
input: function input(_view, event) {
|
|
218
|
+
if (event.inputType !== 'deleteCompositionText') {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
var selection = window.getSelection();
|
|
222
|
+
if (!selection || selection.rangeCount === 0) return false;
|
|
223
|
+
var range = selection.getRangeAt(0);
|
|
224
|
+
var node = range.startContainer;
|
|
225
|
+
var parentEl = (node === null || node === void 0 ? void 0 : node.parentElement) || null;
|
|
226
|
+
if (!parentEl) return false;
|
|
227
|
+
var textNodes = Array.from(parentEl.childNodes).filter(isTextNode);
|
|
228
|
+
var _iterator = _createForOfIteratorHelper(textNodes),
|
|
229
|
+
_step;
|
|
230
|
+
try {
|
|
231
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
232
|
+
var textNode = _step.value;
|
|
233
|
+
if (textNode.textContent === ZERO_WIDTH_SPACE) {
|
|
234
|
+
textNode.remove();
|
|
235
|
+
} else if (textNode.textContent && textNode.textContent.includes(ZERO_WIDTH_SPACE)) {
|
|
236
|
+
textNode.textContent = textNode.textContent.split(ZERO_WIDTH_SPACE).join('');
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
} catch (err) {
|
|
240
|
+
_iterator.e(err);
|
|
241
|
+
} finally {
|
|
242
|
+
_iterator.f();
|
|
243
|
+
}
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
})];
|
|
249
|
+
}
|
|
172
250
|
})];
|
|
173
251
|
};
|
|
174
252
|
export default TableExtension;
|
package/dist/index.css
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
margin-top: 0 !important;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
.tiptap.ProseMirror :last-child {
|
|
18
|
+
margin-bottom: 0 !important;
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
.tiptap.ProseMirror a {
|
|
18
22
|
text-decoration: underline;
|
|
19
23
|
}
|
|
@@ -25,7 +29,8 @@
|
|
|
25
29
|
margin-bottom: 20px;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
.tiptap.ProseMirror blockquote p
|
|
32
|
+
.tiptap.ProseMirror blockquote p,
|
|
33
|
+
.tiptap.ProseMirror .node-alert p {
|
|
29
34
|
margin: 0;
|
|
30
35
|
}
|
|
31
36
|
|
|
@@ -124,11 +124,6 @@ export function buildNodeFromLines(editor, lines, target) {
|
|
|
124
124
|
});
|
|
125
125
|
return schema.nodes.blockquote.create(undefined, Fragment.fromArray(paragraphs));
|
|
126
126
|
}
|
|
127
|
-
case 'codeBlock':
|
|
128
|
-
{
|
|
129
|
-
var text = lines.join('\n');
|
|
130
|
-
return schema.nodes.codeBlock.create(undefined, text ? schema.text(text) : undefined);
|
|
131
|
-
}
|
|
132
127
|
case 'alert':
|
|
133
128
|
{
|
|
134
129
|
var attrs = target.attrs || {
|
|
@@ -154,17 +149,73 @@ export function buildNodeFromLines(editor, lines, target) {
|
|
|
154
149
|
}
|
|
155
150
|
}
|
|
156
151
|
|
|
152
|
+
/**
|
|
153
|
+
* 通用替换与派发
|
|
154
|
+
*/
|
|
155
|
+
function replaceRange(editor, from, to, content) {
|
|
156
|
+
var tr = editor.state.tr;
|
|
157
|
+
tr.replaceWith(from, to, content);
|
|
158
|
+
editor.view.dispatch(tr);
|
|
159
|
+
editor.view.focus();
|
|
160
|
+
}
|
|
161
|
+
function isContainerNode(node) {
|
|
162
|
+
var name = node.type.name;
|
|
163
|
+
return name === 'blockquote' || name === 'alert';
|
|
164
|
+
}
|
|
165
|
+
function isContainerTarget(target) {
|
|
166
|
+
return target.type === 'blockquote' || target.type === 'alert';
|
|
167
|
+
}
|
|
168
|
+
function createContainerWithContent(editor, target, content) {
|
|
169
|
+
var schema = editor.schema;
|
|
170
|
+
if (target.type === 'blockquote') {
|
|
171
|
+
return schema.nodes.blockquote.create(undefined, content);
|
|
172
|
+
}
|
|
173
|
+
if (target.type === 'alert') {
|
|
174
|
+
var attrs = target.attrs || {
|
|
175
|
+
variant: 'info',
|
|
176
|
+
type: 'icon'
|
|
177
|
+
};
|
|
178
|
+
return schema.nodes.alert.create(attrs, content);
|
|
179
|
+
}
|
|
180
|
+
throw new Error('createContainerWithContent: invalid container target');
|
|
181
|
+
}
|
|
182
|
+
|
|
157
183
|
/**
|
|
158
184
|
* 将给定位置的节点转换为目标类型(按行规则)。
|
|
159
185
|
*/
|
|
160
186
|
export function convertNodeAt(editor, pos, node, target) {
|
|
161
|
-
var lines = extractLinesFromNode(node);
|
|
162
|
-
var replacement = buildNodeFromLines(editor, lines, target);
|
|
163
187
|
var from = pos;
|
|
164
188
|
var to = pos + node.nodeSize;
|
|
165
|
-
var
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
189
|
+
var nodeType = node.type.name;
|
|
190
|
+
|
|
191
|
+
// 规则 1:目标为容器(blockquote/alert)
|
|
192
|
+
if (isContainerTarget(target)) {
|
|
193
|
+
// 再次点击同容器 -> 拆包
|
|
194
|
+
if (target.type === 'blockquote' && nodeType === 'blockquote' || target.type === 'alert' && nodeType === 'alert') {
|
|
195
|
+
replaceRange(editor, from, to, node.content);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// 容器互转:用内部内容构造目标容器,避免嵌套
|
|
199
|
+
var content = isContainerNode(node) ? node.content : Fragment.from(node);
|
|
200
|
+
var wrapper = createContainerWithContent(editor, target, content);
|
|
201
|
+
replaceRange(editor, from, to, wrapper);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 规则 2:当前为容器,且目标为非容器 -> 子节点逐个转换
|
|
206
|
+
if (isContainerNode(node)) {
|
|
207
|
+
var nodesToInsert = [];
|
|
208
|
+
node.forEach(function (child) {
|
|
209
|
+
var built = buildNodeFromLines(editor, extractLinesFromNode(child), target);
|
|
210
|
+
Fragment.from(built).forEach(function (n) {
|
|
211
|
+
nodesToInsert.push(n);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
replaceRange(editor, from, to, Fragment.fromArray(nodesToInsert));
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 其他:按行构建单节点替换
|
|
219
|
+
var replacement = buildNodeFromLines(editor, extractLinesFromNode(node), target);
|
|
220
|
+
replaceRange(editor, from, to, replacement);
|
|
170
221
|
}
|
package/package.json
CHANGED