-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsource.patch
More file actions
116 lines (114 loc) · 5.3 KB
/
Copy pathsource.patch
File metadata and controls
116 lines (114 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
diff --git a/src/components/text-editor/prosemirror-adapter/editor-config.ts b/src/components/text-editor/prosemirror-adapter/editor-config.ts
--- a/src/components/text-editor/prosemirror-adapter/editor-config.ts
+++ b/src/components/text-editor/prosemirror-adapter/editor-config.ts
@@ -128,6 +128,13 @@
}),
keymap(menuCommandFactory.buildKeymap()),
createTriggerPlugin(triggerCharacters, contentConverter),
+ // Paste ownership: structural table rules, then explicit cell-grid
+ // replacement, own table-bearing slices. The link/image shortcuts
+ // decline those slices; ordinary image files and URL text keep their
+ // existing handlers, with accepted image files ahead of URL text.
+ // Image transformPasted still enforces a configured
+ // no-upload policy, removing image leaves without removing their table.
+ // Other event and keyboard handlers retain their registration order.
createLinkPlugin(onNewLinkSelection),
createImageInserterPlugin(onImagePasted, inlineImages),
createImageViewPlugin(language),
diff --git a/src/components/text-editor/prosemirror-adapter/plugins/image/inserter.ts b/src/components/text-editor/prosemirror-adapter/plugins/image/inserter.ts
--- a/src/components/text-editor/prosemirror-adapter/plugins/image/inserter.ts
+++ b/src/components/text-editor/prosemirror-adapter/plugins/image/inserter.ts
@@ -1,3 +1,4 @@
+import { containsPastedTable } from '../table-paste-plugin';
import { Plugin, PluginKey } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import { createFileInfo } from '../../../../../util/files';
@@ -15,6 +16,36 @@
type ImagePastedCallback = (data: ImageInserter) => CustomEvent<ImageInserter>;
+/** Use the existing image-file predicate, including its Excel/table exclusions. */
+export const hasPastedImageFile = (clipboardData: DataTransfer | null): boolean => {
+ return !!clipboardData && [...clipboardData.files].some((file) =>
+ isImageFile(file, clipboardData)
+ );
+};
+
+/** Preserve table wrappers while enforcing the host's no-new-image setting. */
+const filterPastedTableImages = (
+ slice: Slice,
+ inlineImages?: InlineImages
+): Slice => {
+ if (!containsPastedTable(slice) || !inlineImages || inlineImages.upload) {
+ return slice;
+ }
+ const withoutImages = (fragment: Fragment): Fragment => {
+ const children: Node[] = [];
+ // eslint-disable-next-line unicorn/no-array-for-each
+ fragment.forEach((child) => {
+ if (child.type.name !== 'image') {
+ children.push(
+ child.isLeaf ? child : child.copy(withoutImages(child.content))
+ );
+ }
+ });
+ return Fragment.fromArray(children);
+ };
+ return new Slice(withoutImages(slice.content), slice.openStart, slice.openEnd);
+};
+
export const createImageInserterPlugin = (
imagePastedCallback: ImagePastedCallback,
inlineImages?: InlineImages
@@ -22,7 +53,13 @@
return new Plugin({
key: pluginKey,
props: {
+ transformPasted: (slice) => {
+ return filterPastedTableImages(slice, inlineImages);
+ },
handlePaste: (view, event, slice) => {
+ if (containsPastedTable(slice)) {
+ return false;
+ }
return processPasteEvent(view, event, slice, inlineImages);
},
handleDOMEvents: {
diff --git a/src/components/text-editor/prosemirror-adapter/plugins/link/link-plugin.ts b/src/components/text-editor/prosemirror-adapter/plugins/link/link-plugin.ts
--- a/src/components/text-editor/prosemirror-adapter/plugins/link/link-plugin.ts
+++ b/src/components/text-editor/prosemirror-adapter/plugins/link/link-plugin.ts
@@ -1,3 +1,5 @@
+import { hasPastedImageFile } from '../image/inserter';
+import { containsPastedTable } from '../table-paste-plugin';
import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import { Mark, Fragment, Node, Schema } from 'prosemirror-model';
@@ -418,7 +420,10 @@
return new Plugin({
key: linkPluginKey,
props: {
- handlePaste: (view, event) => {
+ handlePaste: (view, event, slice) => {
+ if (containsPastedTable(slice) || hasPastedImageFile(event.clipboardData)) {
+ return false;
+ }
return processPasteEvent(view, event);
},
handleDOMEvents: {
diff --git a/src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts b/src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts
--- a/src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts
+++ b/src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts
@@ -141,3 +141,15 @@
(block) => block.type.spec.tableRole === 'table'
);
};
+
+/** Detect table, row and cell slices before content-specific paste shortcuts. */
+export const containsPastedTable = (slice: Slice): boolean => {
+ let found = false;
+ slice.content.descendants((node) => {
+ if (node.type.spec.tableRole) {
+ found = true;
+ }
+ return !found;
+ });
+ return found;
+};