@bendyline/squisq-editor-react 2.13.2 → 2.13.4
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/{chunk-NRJDPKOS.js → chunk-D77UNB6T.js} +6 -3
- package/dist/{chunk-S73OV74D.js → chunk-JMZ7RALZ.js} +5 -3
- package/dist/chunk-SINLDQ63.js +150 -0
- package/dist/index.js +3 -3
- package/dist/json-editor/index.js +2 -2
- package/dist/shell/index.js +2 -2
- package/package.json +6 -6
- package/dist/chunk-2D2VBYX7.js +0 -45
|
@@ -28,8 +28,9 @@ import {
|
|
|
28
28
|
import {
|
|
29
29
|
AlignedTableCell,
|
|
30
30
|
AlignedTableHeader,
|
|
31
|
-
MarkdownEscape
|
|
32
|
-
|
|
31
|
+
MarkdownEscape,
|
|
32
|
+
PlainTextClipboard
|
|
33
|
+
} from "./chunk-SINLDQ63.js";
|
|
33
34
|
import {
|
|
34
35
|
escapeLinkLabel,
|
|
35
36
|
formatLinkDestination,
|
|
@@ -14244,7 +14245,7 @@ function buildSceneTextExtensions(level) {
|
|
|
14244
14245
|
codeBlock: false,
|
|
14245
14246
|
horizontalRule: false
|
|
14246
14247
|
}) : level === "block" ? StarterKit.configure({ heading: false, horizontalRule: false }) : StarterKit.configure({ horizontalRule: false });
|
|
14247
|
-
return [starter, Link.configure({ openOnClick: false }), MarkdownEscape];
|
|
14248
|
+
return [starter, Link.configure({ openOnClick: false }), MarkdownEscape, PlainTextClipboard];
|
|
14248
14249
|
}
|
|
14249
14250
|
|
|
14250
14251
|
// src/scene/text/SceneTextOverlay.tsx
|
|
@@ -35726,6 +35727,7 @@ function WysiwygEditor({
|
|
|
35726
35727
|
Superscript,
|
|
35727
35728
|
Subscript,
|
|
35728
35729
|
MarkdownEscape,
|
|
35730
|
+
PlainTextClipboard,
|
|
35729
35731
|
BlockTagActivityExtension,
|
|
35730
35732
|
AsciiDiagramExtension.configure({ textChannel: sceneTextChannel }),
|
|
35731
35733
|
MermaidDiagramExtension.configure({ themeStore: mermaidThemeStore }),
|
|
@@ -35890,6 +35892,7 @@ function WysiwygEditor({
|
|
|
35890
35892
|
return true;
|
|
35891
35893
|
}
|
|
35892
35894
|
}
|
|
35895
|
+
if (clipboard.getData("text/html").includes("data-pm-slice")) return false;
|
|
35893
35896
|
if (!looksLikeMarkdown(text)) return false;
|
|
35894
35897
|
const html = markdownToTiptap(text);
|
|
35895
35898
|
if (!html) return false;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AlignedTableCell,
|
|
3
3
|
AlignedTableHeader,
|
|
4
|
-
MarkdownEscape
|
|
5
|
-
|
|
4
|
+
MarkdownEscape,
|
|
5
|
+
PlainTextClipboard
|
|
6
|
+
} from "./chunk-SINLDQ63.js";
|
|
6
7
|
import {
|
|
7
8
|
markdownToTiptap,
|
|
8
9
|
tiptapToMarkdown
|
|
@@ -95,7 +96,8 @@ function EmbeddedRichTextField(props) {
|
|
|
95
96
|
TaskList,
|
|
96
97
|
TaskItem.configure({ nested: true }),
|
|
97
98
|
Placeholder.configure({ placeholder: placeholder ?? "" }),
|
|
98
|
-
MarkdownEscape
|
|
99
|
+
MarkdownEscape,
|
|
100
|
+
PlainTextClipboard
|
|
99
101
|
],
|
|
100
102
|
content: markdownToTiptap(value),
|
|
101
103
|
onUpdate: ({ editor: ed, transaction }) => {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MARKDOWN_ESCAPE_ATTR
|
|
3
|
+
} from "./chunk-V7HUUMMB.js";
|
|
4
|
+
|
|
5
|
+
// src/MarkdownEscape.ts
|
|
6
|
+
import { Mark, mergeAttributes } from "@tiptap/core";
|
|
7
|
+
var MarkdownEscape = Mark.create({
|
|
8
|
+
name: "markdownEscape",
|
|
9
|
+
inclusive: false,
|
|
10
|
+
parseHTML() {
|
|
11
|
+
return [{ tag: `span[${MARKDOWN_ESCAPE_ATTR}]` }];
|
|
12
|
+
},
|
|
13
|
+
renderHTML({ HTMLAttributes }) {
|
|
14
|
+
return ["span", mergeAttributes(HTMLAttributes, { [MARKDOWN_ESCAPE_ATTR]: "" }), 0];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// src/PlainTextClipboard.ts
|
|
19
|
+
import { Extension, getTextSerializersFromSchema } from "@tiptap/core";
|
|
20
|
+
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
21
|
+
var LIST_TYPES = /* @__PURE__ */ new Set(["bulletList", "orderedList", "taskList"]);
|
|
22
|
+
var LIST_ITEM_TYPES = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
|
|
23
|
+
var isList = (node) => LIST_TYPES.has(node.type.name);
|
|
24
|
+
var isListItem = (node) => LIST_ITEM_TYPES.has(node.type.name);
|
|
25
|
+
var isTableRow = (node) => node.type.spec.tableRole === "row";
|
|
26
|
+
var isTableCell = (node) => node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell";
|
|
27
|
+
function sliceToPlainText(slice, serializers = {}) {
|
|
28
|
+
const textblock = soleOpenTextblock(slice);
|
|
29
|
+
if (textblock) return inlineText(textblock, serializers);
|
|
30
|
+
const first = slice.content.firstChild;
|
|
31
|
+
if (first?.isInline) {
|
|
32
|
+
const wrapper = first.type.schema.topNodeType.contentMatch.defaultType;
|
|
33
|
+
return wrapper ? inlineText(wrapper.create(null, slice.content), serializers) : "";
|
|
34
|
+
}
|
|
35
|
+
return blocksText(slice.content, serializers);
|
|
36
|
+
}
|
|
37
|
+
function soleOpenTextblock(slice) {
|
|
38
|
+
let content = slice.content;
|
|
39
|
+
for (let depth = 1; depth <= Math.min(slice.openStart, slice.openEnd); depth++) {
|
|
40
|
+
if (content.childCount !== 1) return null;
|
|
41
|
+
const node = content.child(0);
|
|
42
|
+
if (node.isTextblock) return node;
|
|
43
|
+
content = node.content;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function inlineText(textblock, serializers) {
|
|
48
|
+
const range = { from: 0, to: textblock.content.size };
|
|
49
|
+
let text = "";
|
|
50
|
+
textblock.forEach((node, pos, index) => {
|
|
51
|
+
const serialize = serializers[node.type.name];
|
|
52
|
+
text += serialize ? serialize({ node, pos, parent: textblock, index, range }) : node.textContent;
|
|
53
|
+
});
|
|
54
|
+
return text;
|
|
55
|
+
}
|
|
56
|
+
function blocksText(content, serializers, inListItem = false) {
|
|
57
|
+
let text = "";
|
|
58
|
+
let previous = null;
|
|
59
|
+
for (let i = 0; i < content.childCount; i++) {
|
|
60
|
+
const node = content.child(i);
|
|
61
|
+
const block = blockText(node, serializers);
|
|
62
|
+
if (!block && !isTableCell(node)) continue;
|
|
63
|
+
if (previous) text += separator(previous, node, inListItem);
|
|
64
|
+
text += block;
|
|
65
|
+
previous = node;
|
|
66
|
+
}
|
|
67
|
+
return text;
|
|
68
|
+
}
|
|
69
|
+
function separator(previous, next, inListItem) {
|
|
70
|
+
if (isTableCell(previous) && isTableCell(next)) return " ";
|
|
71
|
+
if (isListItem(previous) && isListItem(next)) return "\n";
|
|
72
|
+
if (isTableRow(previous) && isTableRow(next)) return "\n";
|
|
73
|
+
if (inListItem && isList(next)) return "\n";
|
|
74
|
+
return "\n\n";
|
|
75
|
+
}
|
|
76
|
+
function blockText(node, serializers) {
|
|
77
|
+
if (node.isTextblock) return inlineText(node, serializers);
|
|
78
|
+
if (isList(node)) return listText(node, serializers);
|
|
79
|
+
if (isListItem(node)) return listItemText(node, bulletMarker(node), serializers);
|
|
80
|
+
if (isTableCell(node)) return blocksText(node.content, serializers).replace(/\s*\n\s*/g, " ");
|
|
81
|
+
return blocksText(node.content, serializers);
|
|
82
|
+
}
|
|
83
|
+
function listText(list, serializers) {
|
|
84
|
+
const start = list.attrs.start;
|
|
85
|
+
const items = [];
|
|
86
|
+
list.forEach((item, _pos, index) => {
|
|
87
|
+
const marker = typeof start === "number" ? `${start + index}. ` : bulletMarker(item);
|
|
88
|
+
items.push(listItemText(item, marker, serializers));
|
|
89
|
+
});
|
|
90
|
+
return items.join("\n");
|
|
91
|
+
}
|
|
92
|
+
function bulletMarker(item) {
|
|
93
|
+
const checked = item.attrs.checked;
|
|
94
|
+
if (typeof checked !== "boolean") return "- ";
|
|
95
|
+
return checked ? "- [x] " : "- [ ] ";
|
|
96
|
+
}
|
|
97
|
+
function listItemText(item, marker, serializers) {
|
|
98
|
+
const body = blocksText(item.content, serializers, true);
|
|
99
|
+
const indent = " ".repeat(marker.length);
|
|
100
|
+
const lines = body.split("\n").map((line) => line ? indent + line : line);
|
|
101
|
+
if (item.firstChild && isList(item.firstChild)) return lines.join("\n");
|
|
102
|
+
lines[0] = body ? marker + lines[0].slice(indent.length) : marker.trimEnd();
|
|
103
|
+
return lines.join("\n");
|
|
104
|
+
}
|
|
105
|
+
var PlainTextClipboard = Extension.create({
|
|
106
|
+
name: "plainTextClipboard",
|
|
107
|
+
addProseMirrorPlugins() {
|
|
108
|
+
const serializers = getTextSerializersFromSchema(this.editor.schema);
|
|
109
|
+
return [
|
|
110
|
+
new Plugin({
|
|
111
|
+
key: new PluginKey("plainTextClipboard"),
|
|
112
|
+
props: {
|
|
113
|
+
// Tiptap runs a later extension's plugins first, so this prop wins
|
|
114
|
+
// over the core ClipboardTextSerializer's.
|
|
115
|
+
clipboardTextSerializer: (slice) => sliceToPlainText(slice, serializers)
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// src/tiptap/alignedTableCells.ts
|
|
123
|
+
import TableCell from "@tiptap/extension-table-cell";
|
|
124
|
+
import TableHeader from "@tiptap/extension-table-header";
|
|
125
|
+
var ALIGNMENTS = /* @__PURE__ */ new Set(["left", "center", "right"]);
|
|
126
|
+
var align = {
|
|
127
|
+
default: null,
|
|
128
|
+
parseHTML: (element) => {
|
|
129
|
+
const value = element.style.textAlign;
|
|
130
|
+
return ALIGNMENTS.has(value) ? value : null;
|
|
131
|
+
},
|
|
132
|
+
renderHTML: (attributes) => typeof attributes.align === "string" && ALIGNMENTS.has(attributes.align) ? { style: `text-align: ${attributes.align}` } : {}
|
|
133
|
+
};
|
|
134
|
+
var AlignedTableCell = TableCell.extend({
|
|
135
|
+
addAttributes() {
|
|
136
|
+
return { ...this.parent?.(), align };
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
var AlignedTableHeader = TableHeader.extend({
|
|
140
|
+
addAttributes() {
|
|
141
|
+
return { ...this.parent?.(), align };
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
MarkdownEscape,
|
|
147
|
+
PlainTextClipboard,
|
|
148
|
+
AlignedTableCell,
|
|
149
|
+
AlignedTableHeader
|
|
150
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -243,7 +243,7 @@ import {
|
|
|
243
243
|
videoEmbedParagraphJson,
|
|
244
244
|
viewStateFromBinding,
|
|
245
245
|
writeHeadingViewState
|
|
246
|
-
} from "./chunk-
|
|
246
|
+
} from "./chunk-D77UNB6T.js";
|
|
247
247
|
import {
|
|
248
248
|
EditorProvider,
|
|
249
249
|
applySourceEditsToText,
|
|
@@ -273,10 +273,10 @@ import {
|
|
|
273
273
|
import "./chunk-A2H3JOA5.js";
|
|
274
274
|
import {
|
|
275
275
|
JsonEditor
|
|
276
|
-
} from "./chunk-
|
|
276
|
+
} from "./chunk-JMZ7RALZ.js";
|
|
277
277
|
import {
|
|
278
278
|
MarkdownEscape
|
|
279
|
-
} from "./chunk-
|
|
279
|
+
} from "./chunk-SINLDQ63.js";
|
|
280
280
|
import {
|
|
281
281
|
markdownToTiptap,
|
|
282
282
|
tiptapToMarkdown
|
package/dist/shell/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
RawEditor,
|
|
6
6
|
WysiwygEditor,
|
|
7
7
|
useEditorContextMenuItems
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-D77UNB6T.js";
|
|
9
9
|
import {
|
|
10
10
|
EditorProvider,
|
|
11
11
|
useEditorContext,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "../chunk-OMSRCHQ4.js";
|
|
14
14
|
import "../chunk-DNEVUOBZ.js";
|
|
15
15
|
import "../chunk-A2H3JOA5.js";
|
|
16
|
-
import "../chunk-
|
|
16
|
+
import "../chunk-SINLDQ63.js";
|
|
17
17
|
import "../chunk-V7HUUMMB.js";
|
|
18
18
|
import "../chunk-HLU6ZBS7.js";
|
|
19
19
|
import "../chunk-LXGQA2SY.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/squisq-editor-react",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.4",
|
|
4
4
|
"description": "React editor shell with raw/WYSIWYG/preview modes for Squisq documents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bendyline",
|
|
@@ -102,12 +102,12 @@
|
|
|
102
102
|
}
|
|
103
103
|
},
|
|
104
104
|
"dependencies": {
|
|
105
|
-
"@bendyline/squisq": "2.13.
|
|
105
|
+
"@bendyline/squisq": "2.13.2",
|
|
106
106
|
"@bendyline/squisq-calc": "2.11.2",
|
|
107
|
-
"@bendyline/squisq-formats": "2.8.
|
|
108
|
-
"@bendyline/squisq-grid-react": "2.11.
|
|
109
|
-
"@bendyline/squisq-react": "2.12.
|
|
110
|
-
"@bendyline/squisq-video-react": "2.5.
|
|
107
|
+
"@bendyline/squisq-formats": "2.8.3",
|
|
108
|
+
"@bendyline/squisq-grid-react": "2.11.31",
|
|
109
|
+
"@bendyline/squisq-react": "2.12.11",
|
|
110
|
+
"@bendyline/squisq-video-react": "2.5.12",
|
|
111
111
|
"@fortawesome/fontawesome-free": "7.3.1",
|
|
112
112
|
"@tiptap/core": "2.27.3",
|
|
113
113
|
"@tiptap/extension-heading": "2.27.3",
|
package/dist/chunk-2D2VBYX7.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MARKDOWN_ESCAPE_ATTR
|
|
3
|
-
} from "./chunk-V7HUUMMB.js";
|
|
4
|
-
|
|
5
|
-
// src/MarkdownEscape.ts
|
|
6
|
-
import { Mark, mergeAttributes } from "@tiptap/core";
|
|
7
|
-
var MarkdownEscape = Mark.create({
|
|
8
|
-
name: "markdownEscape",
|
|
9
|
-
inclusive: false,
|
|
10
|
-
parseHTML() {
|
|
11
|
-
return [{ tag: `span[${MARKDOWN_ESCAPE_ATTR}]` }];
|
|
12
|
-
},
|
|
13
|
-
renderHTML({ HTMLAttributes }) {
|
|
14
|
-
return ["span", mergeAttributes(HTMLAttributes, { [MARKDOWN_ESCAPE_ATTR]: "" }), 0];
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
// src/tiptap/alignedTableCells.ts
|
|
19
|
-
import TableCell from "@tiptap/extension-table-cell";
|
|
20
|
-
import TableHeader from "@tiptap/extension-table-header";
|
|
21
|
-
var ALIGNMENTS = /* @__PURE__ */ new Set(["left", "center", "right"]);
|
|
22
|
-
var align = {
|
|
23
|
-
default: null,
|
|
24
|
-
parseHTML: (element) => {
|
|
25
|
-
const value = element.style.textAlign;
|
|
26
|
-
return ALIGNMENTS.has(value) ? value : null;
|
|
27
|
-
},
|
|
28
|
-
renderHTML: (attributes) => typeof attributes.align === "string" && ALIGNMENTS.has(attributes.align) ? { style: `text-align: ${attributes.align}` } : {}
|
|
29
|
-
};
|
|
30
|
-
var AlignedTableCell = TableCell.extend({
|
|
31
|
-
addAttributes() {
|
|
32
|
-
return { ...this.parent?.(), align };
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
var AlignedTableHeader = TableHeader.extend({
|
|
36
|
-
addAttributes() {
|
|
37
|
-
return { ...this.parent?.(), align };
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
export {
|
|
42
|
-
MarkdownEscape,
|
|
43
|
-
AlignedTableCell,
|
|
44
|
-
AlignedTableHeader
|
|
45
|
-
};
|