@ctzhian/tiptap 2.0.0 → 2.1.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/Editor/demo.js +151 -123
- package/dist/EditorToolbar/index.js +11 -9
- package/dist/asset/css/index.css +7 -9
- package/dist/component/ActionDropdown/index.d.ts +5 -0
- package/dist/component/ActionDropdown/index.js +8 -3
- package/dist/component/FloatingPopover/index.d.ts +2 -2
- package/dist/component/HoverPopover/index.d.ts +2 -0
- package/dist/component/HoverPopover/index.js +22 -3
- package/dist/component/Icons/{expand-horizontal-line.js → expand-horizontal-line-icon.js} +1 -1
- package/dist/component/Icons/index.d.ts +8 -2
- package/dist/component/Icons/index.js +9 -3
- package/dist/component/Icons/skip-down-icon.d.ts +6 -0
- package/dist/component/Icons/skip-down-icon.js +13 -0
- package/dist/component/Icons/skip-left-icon.d.ts +6 -0
- package/dist/component/Icons/skip-left-icon.js +13 -0
- package/dist/component/Icons/skip-right-icon.d.ts +6 -0
- package/dist/component/Icons/skip-right-icon.js +13 -0
- package/dist/component/Icons/skip-up-icon.d.ts +6 -0
- package/dist/component/Icons/skip-up-icon.js +13 -0
- package/dist/component/Icons/volume-down-line-icon.d.ts +6 -0
- package/dist/component/Icons/volume-down-line-icon.js +13 -0
- package/dist/extension/component/Alert/index.js +141 -137
- package/dist/extension/component/Attachment/AttachmentContent.d.ts +0 -1
- package/dist/extension/component/Attachment/AttachmentContent.js +33 -8
- package/dist/extension/component/Attachment/index.js +21 -12
- package/dist/extension/component/Audio/AudioPlayer.d.ts +8 -0
- package/dist/extension/component/Audio/{Readonly.js → AudioPlayer.js} +129 -175
- package/dist/extension/component/Audio/index.js +93 -462
- package/dist/extension/component/Flow/Edit.d.ts +1 -1
- package/dist/extension/component/Flow/Edit.js +3 -31
- package/dist/extension/component/Flow/index.js +20 -19
- package/dist/extension/component/Image/index.d.ts +1 -0
- package/dist/extension/component/Image/index.js +16 -2
- package/dist/extension/component/Link/LinkContent.js +2 -0
- package/dist/extension/component/Link/index.js +1 -1
- package/dist/extension/component/TableCellHandleMenu/index.js +60 -3
- package/dist/extension/component/TableHandle/TableHandleAddButton.d.ts +14 -0
- package/dist/extension/component/TableHandle/TableHandleAddButton.js +87 -0
- package/dist/extension/component/TableHandle/TableHandleMenu.css +0 -1
- package/dist/extension/component/TableHandle/TableHandleMenu.js +7 -6
- package/dist/extension/component/TableHandle/index.js +53 -3
- package/dist/extension/component/TableSelectionOverlay/index.js +4 -12
- package/dist/extension/component/UploadProgress/index.d.ts +1 -1
- package/dist/extension/component/Video/Insert.js +4 -2
- package/dist/extension/component/Video/Readonly.js +4 -11
- package/dist/extension/component/Video/index.d.ts +2 -1
- package/dist/extension/component/Video/index.js +456 -65
- package/dist/extension/extension/ImeComposition.d.ts +2 -0
- package/dist/extension/extension/ImeComposition.js +145 -0
- package/dist/extension/extension/index.d.ts +1 -0
- package/dist/extension/extension/index.js +1 -0
- package/dist/extension/index.js +2 -2
- package/dist/extension/node/CodeBlockLowlight.js +3 -2
- package/dist/extension/node/Flow/index.d.ts +0 -3
- package/dist/extension/node/Flow/index.js +7 -4
- package/dist/extension/node/Link/index.js +4 -3
- package/dist/extension/node/Table.js +18 -82
- package/dist/extension/node/TableOfContents/index.d.ts +5 -3
- package/dist/extension/node/TableOfContents/index.js +22 -2
- package/dist/extension/node/Video.d.ts +1 -0
- package/dist/extension/node/Video.js +38 -6
- package/dist/hook/index.js +1 -1
- package/dist/index.css +17 -20
- package/dist/util/index.d.ts +9 -0
- package/dist/util/index.js +26 -0
- package/package.json +1 -1
- package/dist/extension/component/Audio/Readonly.d.ts +0 -8
- /package/dist/component/Icons/{expand-horizontal-line.d.ts → expand-horizontal-line-icon.d.ts} +0 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
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; } } }; }
|
|
2
|
+
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); }
|
|
3
|
+
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; }
|
|
4
|
+
import { Extension } from '@tiptap/core';
|
|
5
|
+
import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extension to fix IME (Input Method Editor) composition issues
|
|
9
|
+
*
|
|
10
|
+
* This extension provides basic IME composition support by tracking composition state
|
|
11
|
+
* and preventing keyboard handlers from interrupting IME input.
|
|
12
|
+
*
|
|
13
|
+
* Also fixes Safari-specific issue where composition text is deleted after composition ends.
|
|
14
|
+
* This Safari bug occurs at any input position (not just in tables), so this extension
|
|
15
|
+
* provides a global fix for all editor instances.
|
|
16
|
+
*/
|
|
17
|
+
var imeCompositionPluginKey = new PluginKey('imeComposition');
|
|
18
|
+
export var ImeComposition = Extension.create({
|
|
19
|
+
name: 'imeComposition',
|
|
20
|
+
addProseMirrorPlugins: function addProseMirrorPlugins() {
|
|
21
|
+
var ZERO_WIDTH_SPACE = "\u200B";
|
|
22
|
+
|
|
23
|
+
// 检测是否为 Safari 浏览器
|
|
24
|
+
var isSafari = function () {
|
|
25
|
+
if (typeof navigator === 'undefined') return false;
|
|
26
|
+
var ua = navigator.userAgent;
|
|
27
|
+
var isAppleMobile = /iP(ad|hone|od)/.test(ua);
|
|
28
|
+
var isMacSafari = /Safari\//.test(ua) && !/Chrome\//.test(ua);
|
|
29
|
+
return isAppleMobile || isMacSafari;
|
|
30
|
+
}();
|
|
31
|
+
|
|
32
|
+
// 判断是否为文本节点
|
|
33
|
+
var isTextNode = function isTextNode(node) {
|
|
34
|
+
return !!node && node.nodeType === 3;
|
|
35
|
+
};
|
|
36
|
+
return [new Plugin({
|
|
37
|
+
key: imeCompositionPluginKey,
|
|
38
|
+
state: {
|
|
39
|
+
init: function init() {
|
|
40
|
+
return {
|
|
41
|
+
isComposing: false
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
apply: function apply(tr, value) {
|
|
45
|
+
// 从 transaction meta 中获取组合状态
|
|
46
|
+
var meta = tr.getMeta(imeCompositionPluginKey);
|
|
47
|
+
if (meta) {
|
|
48
|
+
return {
|
|
49
|
+
isComposing: meta.isComposing
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
props: {
|
|
56
|
+
handleKeyDown: function handleKeyDown(view, event) {
|
|
57
|
+
var pluginState = imeCompositionPluginKey.getState(view.state);
|
|
58
|
+
// 如果正在输入法组合中,不处理键盘事件
|
|
59
|
+
// 检查 event.isComposing 和插件状态,确保 IME 输入不被键盘处理器打断
|
|
60
|
+
if (event.isComposing || pluginState !== null && pluginState !== void 0 && pluginState.isComposing) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
},
|
|
65
|
+
handleDOMEvents: {
|
|
66
|
+
// 监听输入法组合开始事件
|
|
67
|
+
compositionstart: function compositionstart(view, event) {
|
|
68
|
+
var state = view.state,
|
|
69
|
+
dispatch = view.dispatch;
|
|
70
|
+
var tr = state.tr.setMeta(imeCompositionPluginKey, {
|
|
71
|
+
isComposing: true
|
|
72
|
+
}).setMeta('composition', true);
|
|
73
|
+
dispatch(tr);
|
|
74
|
+
return false;
|
|
75
|
+
},
|
|
76
|
+
// 监听输入法组合结束事件
|
|
77
|
+
compositionend: function compositionend(view, event) {
|
|
78
|
+
var state = view.state,
|
|
79
|
+
dispatch = view.dispatch;
|
|
80
|
+
var tr = state.tr.setMeta(imeCompositionPluginKey, {
|
|
81
|
+
isComposing: false
|
|
82
|
+
}).setMeta('composition', false);
|
|
83
|
+
dispatch(tr);
|
|
84
|
+
return false;
|
|
85
|
+
},
|
|
86
|
+
// Safari 特定的修复:处理中文合成结束后触发的删除合成文本行为
|
|
87
|
+
// 这个问题在 Safari 中会在任意输入位置出现,不仅仅是 table
|
|
88
|
+
beforeinput: isSafari ? function (view, event) {
|
|
89
|
+
// 仅处理 Safari 在中文合成结束后触发的删除合成文本行为
|
|
90
|
+
var inputEvent = event;
|
|
91
|
+
if (inputEvent.inputType !== 'deleteCompositionText') {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
var selection = window.getSelection();
|
|
95
|
+
if (!selection || selection.rangeCount === 0) return false;
|
|
96
|
+
var range = selection.getRangeAt(0);
|
|
97
|
+
var startContainer = range.startContainer,
|
|
98
|
+
endContainer = range.endContainer,
|
|
99
|
+
startOffset = range.startOffset,
|
|
100
|
+
endOffset = range.endOffset;
|
|
101
|
+
|
|
102
|
+
// 如果选中的是整个文本节点,在节点前插入零宽空格防止被删除
|
|
103
|
+
if (isTextNode(startContainer) && startContainer === endContainer && startOffset === 0 && endOffset === startContainer.length) {
|
|
104
|
+
var _startContainer$paren;
|
|
105
|
+
(_startContainer$paren = startContainer.parentElement) === null || _startContainer$paren === void 0 || _startContainer$paren.insertBefore(document.createTextNode(ZERO_WIDTH_SPACE), startContainer);
|
|
106
|
+
}
|
|
107
|
+
// 让 ProseMirror 照常处理
|
|
108
|
+
return false;
|
|
109
|
+
} : undefined,
|
|
110
|
+
// Safari 特定的修复:清理零宽空格
|
|
111
|
+
input: isSafari ? function (view, event) {
|
|
112
|
+
var inputEvent = event;
|
|
113
|
+
if (inputEvent.inputType !== 'deleteCompositionText') {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
var selection = window.getSelection();
|
|
117
|
+
if (!selection || selection.rangeCount === 0) return false;
|
|
118
|
+
var range = selection.getRangeAt(0);
|
|
119
|
+
var node = range.startContainer;
|
|
120
|
+
var parentEl = (node === null || node === void 0 ? void 0 : node.parentElement) || null;
|
|
121
|
+
if (!parentEl) return false;
|
|
122
|
+
var textNodes = Array.from(parentEl.childNodes).filter(isTextNode);
|
|
123
|
+
var _iterator = _createForOfIteratorHelper(textNodes),
|
|
124
|
+
_step;
|
|
125
|
+
try {
|
|
126
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
127
|
+
var textNode = _step.value;
|
|
128
|
+
if (textNode.textContent === ZERO_WIDTH_SPACE) {
|
|
129
|
+
textNode.remove();
|
|
130
|
+
} else if (textNode.textContent && textNode.textContent.includes(ZERO_WIDTH_SPACE)) {
|
|
131
|
+
textNode.textContent = textNode.textContent.split(ZERO_WIDTH_SPACE).join('');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
} catch (err) {
|
|
135
|
+
_iterator.e(err);
|
|
136
|
+
} finally {
|
|
137
|
+
_iterator.f();
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
} : undefined
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
})];
|
|
144
|
+
}
|
|
145
|
+
});
|
package/dist/extension/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { CharacterCount, Placeholder } from '@tiptap/extensions';
|
|
|
12
12
|
import { Markdown } from '@tiptap/markdown';
|
|
13
13
|
import StarterKit from '@tiptap/starter-kit';
|
|
14
14
|
import { PLACEHOLDER } from "../contants/placeholder";
|
|
15
|
-
import { AiWritingExtension, SlashCommands, StructuredDiffExtension } from "./extension";
|
|
15
|
+
import { AiWritingExtension, ImeComposition, SlashCommands, StructuredDiffExtension } from "./extension";
|
|
16
16
|
import { CodeExtension } from "./mark/Code";
|
|
17
17
|
import { AlertExtension, AudioExtension, BlockAttachmentExtension, BlockLinkExtension, CodeBlockLowlightExtension, CustomBlockMathExtension, CustomHorizontalRule, CustomInlineMathExtension, CustomSubscript, CustomSuperscript, DetailsContentExtension, DetailsExtension, DetailsSummaryExtension, EmojiExtension, FileHandlerExtension, FlowExtension, IframeExtension, ImageExtension, Indent, InlineAttachmentExtension, InlineLinkExtension, InlineUploadProgressExtension, ListExtension, MentionExtension, TableExtension, TableOfContentsExtension, UploadProgressExtension, VerticalAlign, VideoExtension, YamlFormat, YoutubeExtension } from "./node";
|
|
18
18
|
export var getExtensions = function getExtensions(_ref) {
|
|
@@ -30,7 +30,7 @@ export var getExtensions = function getExtensions(_ref) {
|
|
|
30
30
|
onAiWritingGetSuggestion = _ref.onAiWritingGetSuggestion,
|
|
31
31
|
onValidateUrl = _ref.onValidateUrl,
|
|
32
32
|
_placeholder = _ref.placeholder;
|
|
33
|
-
var defaultExtensions = [StarterKit.configure({
|
|
33
|
+
var defaultExtensions = [ImeComposition, StarterKit.configure({
|
|
34
34
|
link: false,
|
|
35
35
|
code: false,
|
|
36
36
|
codeBlock: false,
|
|
@@ -36,8 +36,9 @@ var CustomCodeBlock = CodeBlockLowlight.configure({
|
|
|
36
36
|
});
|
|
37
37
|
},
|
|
38
38
|
parseMarkdown: function parseMarkdown(token, helpers) {
|
|
39
|
-
var
|
|
40
|
-
|
|
39
|
+
var isFenced = token.codeBlockStyle === 'fenced' || token.raw && /^\s*```/.test(token.raw);
|
|
40
|
+
var isIndented = token.codeBlockStyle === 'indented';
|
|
41
|
+
if (!isFenced && !isIndented) {
|
|
41
42
|
return [];
|
|
42
43
|
}
|
|
43
44
|
if (token.lang === 'mermaid') {
|
|
@@ -16,6 +16,9 @@ export var FlowExtension = function FlowExtension(props) {
|
|
|
16
16
|
draggable: true,
|
|
17
17
|
addAttributes: function addAttributes() {
|
|
18
18
|
return {
|
|
19
|
+
class: {
|
|
20
|
+
default: 'flow-wrapper'
|
|
21
|
+
},
|
|
19
22
|
code: {
|
|
20
23
|
default: '',
|
|
21
24
|
parseHTML: function parseHTML(element) {
|
|
@@ -29,9 +32,9 @@ export var FlowExtension = function FlowExtension(props) {
|
|
|
29
32
|
}
|
|
30
33
|
},
|
|
31
34
|
width: {
|
|
32
|
-
default:
|
|
35
|
+
default: null,
|
|
33
36
|
parseHTML: function parseHTML(element) {
|
|
34
|
-
return element.getAttribute('data-width') ||
|
|
37
|
+
return element.getAttribute('data-width') || null;
|
|
35
38
|
},
|
|
36
39
|
renderHTML: function renderHTML(attributes) {
|
|
37
40
|
if (!attributes.width) return {};
|
|
@@ -48,7 +51,7 @@ export var FlowExtension = function FlowExtension(props) {
|
|
|
48
51
|
getAttrs: function getAttrs(dom) {
|
|
49
52
|
if (!(dom instanceof HTMLElement)) return false;
|
|
50
53
|
var code = dom.getAttribute('data-code') || '';
|
|
51
|
-
var width = dom.getAttribute('data-width') ||
|
|
54
|
+
var width = dom.getAttribute('data-width') || null;
|
|
52
55
|
return {
|
|
53
56
|
code: code,
|
|
54
57
|
width: width
|
|
@@ -84,7 +87,7 @@ export var FlowExtension = function FlowExtension(props) {
|
|
|
84
87
|
type: _this.name,
|
|
85
88
|
attrs: {
|
|
86
89
|
code: options.code || '',
|
|
87
|
-
width: options.width ||
|
|
90
|
+
width: options.width || null
|
|
88
91
|
}
|
|
89
92
|
});
|
|
90
93
|
};
|
|
@@ -4,7 +4,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
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; }
|
|
5
5
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
6
6
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
-
import { getLinkTitle } from "../../../util";
|
|
7
|
+
import { getLinkAttributesWithSelectedText, getLinkTitle } from "../../../util";
|
|
8
8
|
import { mergeAttributes, Node, nodePasteRule } from '@tiptap/core';
|
|
9
9
|
import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
10
10
|
import { ReactNodeViewRenderer } from '@tiptap/react';
|
|
@@ -361,10 +361,11 @@ export var InlineLinkExtension = Node.create({
|
|
|
361
361
|
var _this6 = this;
|
|
362
362
|
return {
|
|
363
363
|
'Mod-1': function Mod1() {
|
|
364
|
-
|
|
364
|
+
var linkAttributes = getLinkAttributesWithSelectedText(_this6.editor);
|
|
365
|
+
return _this6.editor.commands.setInlineLink(_objectSpread({
|
|
365
366
|
href: '',
|
|
366
367
|
type: 'icon'
|
|
367
|
-
});
|
|
368
|
+
}, linkAttributes));
|
|
368
369
|
}
|
|
369
370
|
};
|
|
370
371
|
},
|
|
@@ -1,5 +1,4 @@
|
|
|
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
2
|
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; }
|
|
4
3
|
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; }
|
|
5
4
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
@@ -27,7 +26,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
27
26
|
|
|
28
27
|
import { Extension } from '@tiptap/core';
|
|
29
28
|
import { Table, TableCell, TableHeader, TableRow } from '@tiptap/extension-table';
|
|
30
|
-
import {
|
|
29
|
+
import { TextSelection } from '@tiptap/pm/state';
|
|
31
30
|
import { TableView } from '@tiptap/pm/tables';
|
|
32
31
|
import { TableHandleExtension } from "./TableHandler";
|
|
33
32
|
export var TableExtension = function TableExtension(_ref) {
|
|
@@ -48,11 +47,13 @@ export var TableExtension = function TableExtension(_ref) {
|
|
|
48
47
|
_defineProperty(_assertThisInitialized(_this2), "tableWrapper", void 0);
|
|
49
48
|
_defineProperty(_assertThisInitialized(_this2), "innerTableContainer", void 0);
|
|
50
49
|
_defineProperty(_assertThisInitialized(_this2), "widgetsContainer", void 0);
|
|
50
|
+
_defineProperty(_assertThisInitialized(_this2), "selectionOverlayContainer", void 0);
|
|
51
51
|
_defineProperty(_assertThisInitialized(_this2), "containerAttributes", void 0);
|
|
52
52
|
_this2.containerAttributes = containerAttributes !== null && containerAttributes !== void 0 ? containerAttributes : {};
|
|
53
53
|
_this2.tableWrapper = _this2.createTableWrapper();
|
|
54
54
|
_this2.innerTableContainer = _this2.createInnerTableContainer();
|
|
55
55
|
_this2.widgetsContainer = _this2.createWidgetsContainer();
|
|
56
|
+
_this2.selectionOverlayContainer = _this2.createSelectionOverlayContainer();
|
|
56
57
|
_this2.setupDOMStructure();
|
|
57
58
|
return _this2;
|
|
58
59
|
}
|
|
@@ -60,7 +61,7 @@ export var TableExtension = function TableExtension(_ref) {
|
|
|
60
61
|
key: "createTableWrapper",
|
|
61
62
|
value: function createTableWrapper() {
|
|
62
63
|
var container = document.createElement('div');
|
|
63
|
-
container.
|
|
64
|
+
container.setAttribute("data-content-type", "table");
|
|
64
65
|
this.applyContainerAttributes(container);
|
|
65
66
|
return container;
|
|
66
67
|
}
|
|
@@ -79,6 +80,14 @@ export var TableExtension = function TableExtension(_ref) {
|
|
|
79
80
|
container.style.position = 'relative';
|
|
80
81
|
return container;
|
|
81
82
|
}
|
|
83
|
+
}, {
|
|
84
|
+
key: "createSelectionOverlayContainer",
|
|
85
|
+
value: function createSelectionOverlayContainer() {
|
|
86
|
+
var container = document.createElement('div');
|
|
87
|
+
container.className = 'table-selection-overlay-container';
|
|
88
|
+
container.style.position = 'relative';
|
|
89
|
+
return container;
|
|
90
|
+
}
|
|
82
91
|
}, {
|
|
83
92
|
key: "applyContainerAttributes",
|
|
84
93
|
value: function applyContainerAttributes(element) {
|
|
@@ -96,13 +105,11 @@ export var TableExtension = function TableExtension(_ref) {
|
|
|
96
105
|
value: function setupDOMStructure() {
|
|
97
106
|
var originalTable = this.dom;
|
|
98
107
|
var tableElement = originalTable.firstChild;
|
|
99
|
-
|
|
100
|
-
// Move table into inner container
|
|
101
108
|
this.innerTableContainer.appendChild(tableElement);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.tableWrapper.appendChild(
|
|
109
|
+
originalTable.appendChild(this.innerTableContainer);
|
|
110
|
+
originalTable.appendChild(this.widgetsContainer);
|
|
111
|
+
originalTable.appendChild(this.selectionOverlayContainer);
|
|
112
|
+
this.tableWrapper.appendChild(originalTable);
|
|
106
113
|
this.dom = this.tableWrapper;
|
|
107
114
|
}
|
|
108
115
|
}, {
|
|
@@ -133,6 +140,8 @@ export var TableExtension = function TableExtension(_ref) {
|
|
|
133
140
|
class: 'table-container'
|
|
134
141
|
}, originalRender], ['div', {
|
|
135
142
|
class: 'table-controls'
|
|
143
|
+
}], ['div', {
|
|
144
|
+
class: 'table-selection-overlay-container'
|
|
136
145
|
}]];
|
|
137
146
|
return wrapper;
|
|
138
147
|
},
|
|
@@ -357,79 +366,6 @@ export var TableExtension = function TableExtension(_ref) {
|
|
|
357
366
|
}
|
|
358
367
|
}), editable ? TableHandleExtension : Extension.create({
|
|
359
368
|
name: 'tableHandleExtension'
|
|
360
|
-
}), Extension.create({
|
|
361
|
-
name: 'safariCompositionDeleteFix',
|
|
362
|
-
addProseMirrorPlugins: function addProseMirrorPlugins() {
|
|
363
|
-
if (!editable) return [];
|
|
364
|
-
var ZERO_WIDTH_SPACE = "\u200B";
|
|
365
|
-
var isSafari = function () {
|
|
366
|
-
if (typeof navigator === 'undefined') return false;
|
|
367
|
-
var ua = navigator.userAgent;
|
|
368
|
-
var isAppleMobile = /iP(ad|hone|od)/.test(ua);
|
|
369
|
-
var isMacSafari = /Safari\//.test(ua) && !/Chrome\//.test(ua);
|
|
370
|
-
return isAppleMobile || isMacSafari;
|
|
371
|
-
}();
|
|
372
|
-
if (!isSafari) return [];
|
|
373
|
-
|
|
374
|
-
// 注意:这里不能使用上面从 ProseMirror 导入的 Node 类型,需判断 DOM 文本节点
|
|
375
|
-
var isTextNode = function isTextNode(node) {
|
|
376
|
-
return !!node && node.nodeType === 3;
|
|
377
|
-
};
|
|
378
|
-
return [new Plugin({
|
|
379
|
-
props: {
|
|
380
|
-
handleDOMEvents: {
|
|
381
|
-
beforeinput: function beforeinput(_view, event) {
|
|
382
|
-
// 仅处理 Safari 在中文合成结束后触发的删除合成文本行为
|
|
383
|
-
if (event.inputType !== 'deleteCompositionText') {
|
|
384
|
-
return false;
|
|
385
|
-
}
|
|
386
|
-
var selection = window.getSelection();
|
|
387
|
-
if (!selection || selection.rangeCount === 0) return false;
|
|
388
|
-
var range = selection.getRangeAt(0);
|
|
389
|
-
var startContainer = range.startContainer,
|
|
390
|
-
endContainer = range.endContainer,
|
|
391
|
-
startOffset = range.startOffset,
|
|
392
|
-
endOffset = range.endOffset;
|
|
393
|
-
if (isTextNode(startContainer) && startContainer === endContainer && startOffset === 0 && endOffset === startContainer.length) {
|
|
394
|
-
var _startContainer$paren;
|
|
395
|
-
(_startContainer$paren = startContainer.parentElement) === null || _startContainer$paren === void 0 || _startContainer$paren.insertBefore(document.createTextNode(ZERO_WIDTH_SPACE), startContainer);
|
|
396
|
-
}
|
|
397
|
-
// 让 ProseMirror 照常处理
|
|
398
|
-
return false;
|
|
399
|
-
},
|
|
400
|
-
input: function input(_view, event) {
|
|
401
|
-
if (event.inputType !== 'deleteCompositionText') {
|
|
402
|
-
return false;
|
|
403
|
-
}
|
|
404
|
-
var selection = window.getSelection();
|
|
405
|
-
if (!selection || selection.rangeCount === 0) return false;
|
|
406
|
-
var range = selection.getRangeAt(0);
|
|
407
|
-
var node = range.startContainer;
|
|
408
|
-
var parentEl = (node === null || node === void 0 ? void 0 : node.parentElement) || null;
|
|
409
|
-
if (!parentEl) return false;
|
|
410
|
-
var textNodes = Array.from(parentEl.childNodes).filter(isTextNode);
|
|
411
|
-
var _iterator = _createForOfIteratorHelper(textNodes),
|
|
412
|
-
_step;
|
|
413
|
-
try {
|
|
414
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
415
|
-
var textNode = _step.value;
|
|
416
|
-
if (textNode.textContent === ZERO_WIDTH_SPACE) {
|
|
417
|
-
textNode.remove();
|
|
418
|
-
} else if (textNode.textContent && textNode.textContent.includes(ZERO_WIDTH_SPACE)) {
|
|
419
|
-
textNode.textContent = textNode.textContent.split(ZERO_WIDTH_SPACE).join('');
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
} catch (err) {
|
|
423
|
-
_iterator.e(err);
|
|
424
|
-
} finally {
|
|
425
|
-
_iterator.f();
|
|
426
|
-
}
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
})];
|
|
432
|
-
}
|
|
433
369
|
})];
|
|
434
370
|
};
|
|
435
371
|
export default TableExtension;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { TocList } from "../../../type";
|
|
2
|
-
|
|
3
|
-
onTocUpdate?: (
|
|
4
|
-
}
|
|
2
|
+
interface TableOfContentsOptions {
|
|
3
|
+
onTocUpdate?: (toc: TocList) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare const TableOfContentsExtension: ({ onTocUpdate }: TableOfContentsOptions) => import("@tiptap/core").Extension<import("@tiptap/extension-table-of-contents").TableOfContentsOptions, import("@tiptap/extension-table-of-contents").TableOfContentsStorage>;
|
|
6
|
+
export {};
|
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
import { getHierarchicalIndexes, TableOfContents } from '@tiptap/extension-table-of-contents';
|
|
2
|
+
import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
2
3
|
export var TableOfContentsExtension = function TableOfContentsExtension(_ref) {
|
|
3
4
|
var onTocUpdate = _ref.onTocUpdate;
|
|
4
|
-
return TableOfContents.
|
|
5
|
+
return TableOfContents.extend({
|
|
6
|
+
addProseMirrorPlugins: function addProseMirrorPlugins() {
|
|
7
|
+
var imeCompositionPluginKey = new PluginKey('imeComposition');
|
|
8
|
+
return [new Plugin({
|
|
9
|
+
key: new PluginKey('tableOfContentImeFix'),
|
|
10
|
+
appendTransaction: function appendTransaction(transactions, _oldState, newState) {
|
|
11
|
+
if (transactions.some(function (tr) {
|
|
12
|
+
return tr.getMeta('composition');
|
|
13
|
+
})) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
var imePluginState = imeCompositionPluginKey.getState(newState);
|
|
17
|
+
if (imePluginState !== null && imePluginState !== void 0 && imePluginState.isComposing) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
})];
|
|
23
|
+
}
|
|
24
|
+
}).configure({
|
|
5
25
|
getIndex: getHierarchicalIndexes,
|
|
6
26
|
onUpdate: function onUpdate(data) {
|
|
7
27
|
setTimeout(function () {
|
|
@@ -17,7 +37,7 @@ export var TableOfContentsExtension = function TableOfContentsExtension(_ref) {
|
|
|
17
37
|
textContent: content.textContent
|
|
18
38
|
};
|
|
19
39
|
}));
|
|
20
|
-
},
|
|
40
|
+
}, 60);
|
|
21
41
|
}
|
|
22
42
|
});
|
|
23
43
|
};
|
|
@@ -107,16 +107,33 @@ export var VideoExtension = function VideoExtension(props) {
|
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
width: {
|
|
110
|
-
default:
|
|
110
|
+
default: null,
|
|
111
111
|
parseHTML: function parseHTML(element) {
|
|
112
112
|
var width = element.getAttribute('width');
|
|
113
|
-
|
|
113
|
+
if (width) {
|
|
114
|
+
if (width.endsWith('%')) return width;
|
|
115
|
+
var numWidth = parseInt(width, 10);
|
|
116
|
+
return isNaN(numWidth) ? null : numWidth;
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
114
119
|
},
|
|
115
120
|
renderHTML: function renderHTML(attributes) {
|
|
116
121
|
return {
|
|
117
122
|
width: attributes.width
|
|
118
123
|
};
|
|
119
124
|
}
|
|
125
|
+
},
|
|
126
|
+
align: {
|
|
127
|
+
default: null,
|
|
128
|
+
parseHTML: function parseHTML(element) {
|
|
129
|
+
return element.getAttribute('data-align');
|
|
130
|
+
},
|
|
131
|
+
renderHTML: function renderHTML(attributes) {
|
|
132
|
+
if (!attributes.align) return {};
|
|
133
|
+
return {
|
|
134
|
+
'data-align': attributes.align
|
|
135
|
+
};
|
|
136
|
+
}
|
|
120
137
|
}
|
|
121
138
|
};
|
|
122
139
|
},
|
|
@@ -127,6 +144,18 @@ export var VideoExtension = function VideoExtension(props) {
|
|
|
127
144
|
if (!(dom instanceof HTMLElement)) return false;
|
|
128
145
|
var src = dom.getAttribute('src');
|
|
129
146
|
if (!src) return false;
|
|
147
|
+
var widthAttr = dom.getAttribute('width');
|
|
148
|
+
var width = 760;
|
|
149
|
+
if (widthAttr) {
|
|
150
|
+
// 如果是百分比,保留字符串格式
|
|
151
|
+
if (widthAttr.endsWith('%')) {
|
|
152
|
+
width = widthAttr;
|
|
153
|
+
} else {
|
|
154
|
+
// 否则解析为数字
|
|
155
|
+
var numWidth = parseInt(widthAttr, 10);
|
|
156
|
+
width = isNaN(numWidth) ? 760 : numWidth;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
130
159
|
return {
|
|
131
160
|
src: src,
|
|
132
161
|
controls: dom.hasAttribute('controls'),
|
|
@@ -134,7 +163,8 @@ export var VideoExtension = function VideoExtension(props) {
|
|
|
134
163
|
loop: dom.hasAttribute('loop'),
|
|
135
164
|
muted: dom.hasAttribute('muted'),
|
|
136
165
|
poster: dom.getAttribute('poster'),
|
|
137
|
-
width:
|
|
166
|
+
width: width,
|
|
167
|
+
align: dom.getAttribute('data-align') || dom.getAttribute('align')
|
|
138
168
|
};
|
|
139
169
|
}
|
|
140
170
|
}];
|
|
@@ -151,9 +181,10 @@ export var VideoExtension = function VideoExtension(props) {
|
|
|
151
181
|
autoplay = _ref2.autoplay,
|
|
152
182
|
loop = _ref2.loop,
|
|
153
183
|
muted = _ref2.muted,
|
|
154
|
-
poster = _ref2.poster
|
|
184
|
+
poster = _ref2.poster,
|
|
185
|
+
align = _ref2['data-align'];
|
|
155
186
|
if (!src) return '';
|
|
156
|
-
return "<video src=\"".concat(src, "\" ").concat(width ? "width=\"".concat(width, "\"") : '', " ").concat(controls ? 'controls' : '', " ").concat(autoplay ? 'autoplay' : '', " ").concat(loop ? 'loop' : '', " ").concat(muted ? 'muted' : '', " ").concat(poster ? "poster=\"".concat(poster, "\"") : '', "></video>");
|
|
187
|
+
return "<video src=\"".concat(src, "\" ").concat(width ? "width=\"".concat(width, "\"") : '', " ").concat(controls ? 'controls' : '', " ").concat(autoplay ? 'autoplay' : '', " ").concat(loop ? 'loop' : '', " ").concat(muted ? 'muted' : '', " ").concat(poster ? "poster=\"".concat(poster, "\"") : '', " ").concat(align ? "data-align=\"".concat(align, "\"") : '', "></video>");
|
|
157
188
|
},
|
|
158
189
|
addCommands: function addCommands() {
|
|
159
190
|
var _this2 = this;
|
|
@@ -170,7 +201,8 @@ export var VideoExtension = function VideoExtension(props) {
|
|
|
170
201
|
autoplay: options.autoplay || false,
|
|
171
202
|
loop: options.loop || false,
|
|
172
203
|
muted: options.muted || false,
|
|
173
|
-
poster: options.poster || null
|
|
204
|
+
poster: options.poster || null,
|
|
205
|
+
align: options.align || null
|
|
174
206
|
}
|
|
175
207
|
});
|
|
176
208
|
};
|
package/dist/hook/index.js
CHANGED
|
@@ -50,7 +50,7 @@ var useTiptap = function useTiptap(_ref) {
|
|
|
50
50
|
editorProps: {
|
|
51
51
|
handleKeyDown: function handleKeyDown(view, event) {
|
|
52
52
|
// 编辑模式下保存
|
|
53
|
-
if (event.key === 's' && (event.metaKey || event.ctrlKey) && editable) {
|
|
53
|
+
if (event.key === 's' && (event.metaKey || event.ctrlKey) && editable && onSave) {
|
|
54
54
|
event.preventDefault();
|
|
55
55
|
onSave === null || onSave === void 0 || onSave(editor);
|
|
56
56
|
return true;
|