@lofcz/platejs-core 52.3.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/LICENSE +21 -0
- package/README.md +11 -0
- package/dist/hotkeys-DI1HPO2Q.js +115 -0
- package/dist/hotkeys-DI1HPO2Q.js.map +1 -0
- package/dist/index-NTp--CEF.d.ts +4294 -0
- package/dist/index-NTp--CEF.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +387 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.d.ts +2056 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +2582 -0
- package/dist/react/index.js.map +1 -0
- package/dist/static/index.d.ts +2 -0
- package/dist/static/index.js +4 -0
- package/dist/static-CVN6JhaR.js +728 -0
- package/dist/static-CVN6JhaR.js.map +1 -0
- package/dist/withSlate-1B0SfAWG.js +2823 -0
- package/dist/withSlate-1B0SfAWG.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
import { Gt as getEditorPlugin, Z as DOMPlugin, dt as getPluginNodeProps, f as isEditOnly, ht as getInjectMatch, n as withSlate, pt as keyToDataAttribute, ut as getSlateClass, zt as getPluginByType } from "./withSlate-1B0SfAWG.js";
|
|
2
|
+
import { ElementApi, NodeApi, RangeApi, TextApi, createEditor, isElementDecorationsEqual, isTextDecorationsEqual } from "@platejs/slate";
|
|
3
|
+
import { isDefined } from "@udecode/utils";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import clsx$1, { clsx } from "clsx";
|
|
6
|
+
import { decode } from "html-entities";
|
|
7
|
+
|
|
8
|
+
//#region src/internal/plugin/pluginInjectNodeProps.ts
|
|
9
|
+
/**
|
|
10
|
+
* Return if `element`, `text`, `nodeKey` is defined. Return if `node.type` is
|
|
11
|
+
* not in `targetPlugins` (if defined). Return if `value = node[nodeKey]` is not
|
|
12
|
+
* in `validNodeValues` (if defined). If `classNames[value]` is defined,
|
|
13
|
+
* override `className` with it. If `styleKey` is defined, override `style` with
|
|
14
|
+
* `[styleKey]: value`.
|
|
15
|
+
*/
|
|
16
|
+
const pluginInjectNodeProps = (editor, plugin, nodeProps, getElementPath) => {
|
|
17
|
+
const { key, inject: { nodeProps: injectNodeProps } } = plugin;
|
|
18
|
+
const { element, text } = nodeProps;
|
|
19
|
+
const node = element ?? text;
|
|
20
|
+
if (!node) return;
|
|
21
|
+
if (!injectNodeProps) return;
|
|
22
|
+
const { classNames, defaultNodeValue, nodeKey = editor.getType(key), query, styleKey = nodeKey, transformClassName, transformNodeValue, transformProps, transformStyle, validNodeValues } = injectNodeProps;
|
|
23
|
+
if (!getInjectMatch(editor, plugin)(node, getElementPath(node))) return;
|
|
24
|
+
const queryResult = query?.({
|
|
25
|
+
...injectNodeProps,
|
|
26
|
+
...getEditorPlugin(editor, plugin),
|
|
27
|
+
nodeProps
|
|
28
|
+
});
|
|
29
|
+
if (query && !queryResult) return;
|
|
30
|
+
const nodeValue = node[nodeKey];
|
|
31
|
+
if (!transformProps && (!isDefined(nodeValue) || validNodeValues && !validNodeValues.includes(nodeValue) || nodeValue === defaultNodeValue)) return;
|
|
32
|
+
const transformOptions = {
|
|
33
|
+
...nodeProps,
|
|
34
|
+
...getEditorPlugin(editor, plugin),
|
|
35
|
+
nodeValue
|
|
36
|
+
};
|
|
37
|
+
const value = transformNodeValue?.(transformOptions) ?? nodeValue;
|
|
38
|
+
transformOptions.value = value;
|
|
39
|
+
let newProps = {};
|
|
40
|
+
if (element && nodeKey && nodeValue) newProps.className = `slate-${nodeKey}-${nodeValue}`;
|
|
41
|
+
if (classNames?.[nodeValue] || transformClassName) newProps.className = transformClassName?.(transformOptions) ?? classNames?.[value];
|
|
42
|
+
if (styleKey) newProps.style = transformStyle?.(transformOptions) ?? { [styleKey]: value };
|
|
43
|
+
if (transformProps) newProps = transformProps({
|
|
44
|
+
...transformOptions,
|
|
45
|
+
props: newProps
|
|
46
|
+
}) ?? newProps;
|
|
47
|
+
return newProps;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/internal/plugin/pipeInjectNodeProps.tsx
|
|
52
|
+
/** Inject plugin props, editor. */
|
|
53
|
+
const pipeInjectNodeProps = (editor, nodeProps, getElementPath, readOnly = false) => {
|
|
54
|
+
editor.meta.pluginCache.inject.nodeProps.forEach((key) => {
|
|
55
|
+
const plugin = editor.getPlugin({ key });
|
|
56
|
+
const newAttributes = pluginInjectNodeProps(editor, plugin, nodeProps, getElementPath);
|
|
57
|
+
if (isEditOnly(readOnly, plugin, "inject")) return;
|
|
58
|
+
if (!newAttributes) return;
|
|
59
|
+
const attributes = nodeProps.attributes;
|
|
60
|
+
nodeProps.attributes = {
|
|
61
|
+
...attributes,
|
|
62
|
+
...newAttributes,
|
|
63
|
+
className: clsx$1(attributes?.className, newAttributes.className) || void 0,
|
|
64
|
+
style: {
|
|
65
|
+
...attributes?.style,
|
|
66
|
+
...newAttributes.style
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
return nodeProps;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/static/utils/pipeDecorate.ts
|
|
75
|
+
/**
|
|
76
|
+
* @see {@link Decorate} .
|
|
77
|
+
* Optimization: return undefined if empty list so Editable uses a memo.
|
|
78
|
+
*/
|
|
79
|
+
const pipeDecorate = (editor, decorateProp) => {
|
|
80
|
+
if (editor.meta.pluginCache.decorate.length === 0 && !decorateProp) return;
|
|
81
|
+
return (entry) => {
|
|
82
|
+
let ranges = [];
|
|
83
|
+
const addRanges = (newRanges) => {
|
|
84
|
+
if (newRanges?.length) ranges = [...ranges, ...newRanges];
|
|
85
|
+
};
|
|
86
|
+
editor.meta.pluginCache.decorate.forEach((key) => {
|
|
87
|
+
const plugin = editor.getPlugin({ key });
|
|
88
|
+
addRanges(plugin.decorate({
|
|
89
|
+
...getEditorPlugin(editor, plugin),
|
|
90
|
+
entry
|
|
91
|
+
}));
|
|
92
|
+
});
|
|
93
|
+
if (decorateProp) addRanges(decorateProp({
|
|
94
|
+
editor,
|
|
95
|
+
entry
|
|
96
|
+
}));
|
|
97
|
+
return ranges;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/static/internal/getPlainText.tsx
|
|
103
|
+
const getDefaultView = (value) => value?.ownerDocument?.defaultView || null;
|
|
104
|
+
/** Check if a DOM node is an element node. */
|
|
105
|
+
const isDOMElement = (value) => isDOMNode(value) && value.nodeType === 1;
|
|
106
|
+
/** Check if a value is a DOM node. */
|
|
107
|
+
const isDOMNode = (value) => {
|
|
108
|
+
const window$1 = getDefaultView(value);
|
|
109
|
+
return !!window$1 && value instanceof window$1.Node;
|
|
110
|
+
};
|
|
111
|
+
/** Check if a DOM node is an element node. */
|
|
112
|
+
const isDOMText = (value) => isDOMNode(value) && value.nodeType === 3;
|
|
113
|
+
const getPlainText = (domNode) => {
|
|
114
|
+
let text = "";
|
|
115
|
+
if (isDOMText(domNode) && domNode.nodeValue) return domNode.nodeValue;
|
|
116
|
+
if (isDOMElement(domNode)) {
|
|
117
|
+
for (const childNode of Array.from(domNode.childNodes)) text += getPlainText(childNode);
|
|
118
|
+
const display = getComputedStyle(domNode).getPropertyValue("display");
|
|
119
|
+
if (display === "block" || display === "list" || domNode.tagName === "BR") text += "\n";
|
|
120
|
+
}
|
|
121
|
+
return text;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/static/utils/getSelectedDomFragment.tsx
|
|
126
|
+
const getSelectedDomFragment = (editor) => {
|
|
127
|
+
const selection = window.getSelection();
|
|
128
|
+
if (!selection || selection.rangeCount === 0) return [];
|
|
129
|
+
const _domBlocks = selection.getRangeAt(0).cloneContents().querySelectorAll("[data-slate-node=\"element\"][data-slate-id]");
|
|
130
|
+
const domBlocks = Array.from(_domBlocks);
|
|
131
|
+
if (domBlocks.length === 0) return [];
|
|
132
|
+
const nodes = [];
|
|
133
|
+
domBlocks.forEach((node, index) => {
|
|
134
|
+
const blockId = node.dataset.slateId;
|
|
135
|
+
const block = editor.api.node({
|
|
136
|
+
id: blockId,
|
|
137
|
+
at: []
|
|
138
|
+
});
|
|
139
|
+
if (!block || block[1].length !== 1) return;
|
|
140
|
+
/**
|
|
141
|
+
* If the selection don't cover the all first or last block, we need
|
|
142
|
+
* fallback to deserialize the block to get the correct fragment
|
|
143
|
+
*/
|
|
144
|
+
if ((index === 0 || index === domBlocks.length - 1) && node.textContent?.trim() !== NodeApi.string(block[0]) && ElementApi.isElement(block[0]) && !editor.api.isVoid(block[0])) {
|
|
145
|
+
const html = document.createElement("div");
|
|
146
|
+
html.append(node);
|
|
147
|
+
const results = editor.api.html.deserialize({ element: html });
|
|
148
|
+
nodes.push(results[0]);
|
|
149
|
+
} else nodes.push(block[0]);
|
|
150
|
+
});
|
|
151
|
+
return nodes;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/static/utils/getSelectedDomNode.ts
|
|
156
|
+
/** Get the DOM node from the DOM selection */
|
|
157
|
+
const getSelectedDomNode = () => {
|
|
158
|
+
const selection = window.getSelection();
|
|
159
|
+
if (!selection || selection.rangeCount === 0) return;
|
|
160
|
+
const htmlFragment = selection.getRangeAt(0).cloneContents();
|
|
161
|
+
const div = document.createElement("div");
|
|
162
|
+
div.append(htmlFragment);
|
|
163
|
+
return div;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/static/utils/isSelectOutside.ts
|
|
168
|
+
/** Check if the DOM selection is outside the editor */
|
|
169
|
+
const isSelectOutside = (html) => {
|
|
170
|
+
const domNodes = html ?? getSelectedDomNode();
|
|
171
|
+
if (!domNodes) return false;
|
|
172
|
+
return !!domNodes?.querySelector("[data-slate-editor=\"true\"]");
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/static/plugins/ViewPlugin.ts
|
|
177
|
+
const ViewPlugin = DOMPlugin.extendEditorApi(({ editor }) => ({ getFragment() {
|
|
178
|
+
return getSelectedDomFragment(editor);
|
|
179
|
+
} })).overrideEditor(({ editor, tf: { setFragmentData } }) => ({ transforms: { setFragmentData(data, originEvent) {
|
|
180
|
+
if (originEvent !== "copy") return setFragmentData(data, originEvent);
|
|
181
|
+
const fragment = getSelectedDomFragment(editor);
|
|
182
|
+
const html = getSelectedDomNode();
|
|
183
|
+
if (!html || !fragment) return;
|
|
184
|
+
if (isSelectOutside(html)) return;
|
|
185
|
+
if (fragment.length > 0) {
|
|
186
|
+
const string = JSON.stringify(fragment);
|
|
187
|
+
const encoded = window.btoa(encodeURIComponent(string));
|
|
188
|
+
data.setData("application/x-slate-fragment", encoded);
|
|
189
|
+
data.setData("text/html", html.innerHTML);
|
|
190
|
+
data.setData("text/plain", getPlainText(html));
|
|
191
|
+
}
|
|
192
|
+
} } }));
|
|
193
|
+
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/static/plugins/getStaticPlugins.ts
|
|
196
|
+
const getStaticPlugins = () => {
|
|
197
|
+
return [...[ViewPlugin]];
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/static/editor/withStatic.tsx
|
|
202
|
+
const withStatic = (editor, options = {}) => {
|
|
203
|
+
const { plugins = [], ..._rest } = options;
|
|
204
|
+
options.plugins = [...getStaticPlugins(), ...plugins];
|
|
205
|
+
return withSlate(editor, options);
|
|
206
|
+
};
|
|
207
|
+
const createStaticEditor = ({ editor = createEditor(), ...options } = {}) => withStatic(editor, options);
|
|
208
|
+
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region src/static/components/slate-nodes.tsx
|
|
211
|
+
const useNodeAttributes = (props, ref) => ({
|
|
212
|
+
...props.attributes,
|
|
213
|
+
className: clsx(props.attributes.className, props.className) || void 0,
|
|
214
|
+
ref,
|
|
215
|
+
style: {
|
|
216
|
+
...props.attributes.style,
|
|
217
|
+
...props.style
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
const SlateElement = React.forwardRef(function SlateElement$1({ as: Tag = "div", children, ...props }, ref) {
|
|
221
|
+
const attributes = useNodeAttributes(props, ref);
|
|
222
|
+
const block = !!props.element.id && !!props.editor.api.isBlock(props.element);
|
|
223
|
+
return /* @__PURE__ */ React.createElement(Tag, {
|
|
224
|
+
"data-slate-node": "element",
|
|
225
|
+
"data-slate-inline": attributes["data-slate-inline"],
|
|
226
|
+
"data-block-id": block ? props.element.id : void 0,
|
|
227
|
+
...attributes,
|
|
228
|
+
style: {
|
|
229
|
+
position: "relative",
|
|
230
|
+
...attributes?.style
|
|
231
|
+
}
|
|
232
|
+
}, children);
|
|
233
|
+
});
|
|
234
|
+
const SlateText = React.forwardRef(({ as: Tag = "span", children, ...props }, ref) => {
|
|
235
|
+
const attributes = useNodeAttributes(props, ref);
|
|
236
|
+
return /* @__PURE__ */ React.createElement(Tag, attributes, children);
|
|
237
|
+
});
|
|
238
|
+
const NonBreakingSpace = () => /* @__PURE__ */ React.createElement("span", {
|
|
239
|
+
style: {
|
|
240
|
+
fontSize: 0,
|
|
241
|
+
lineHeight: 0
|
|
242
|
+
},
|
|
243
|
+
contentEditable: false
|
|
244
|
+
}, String.fromCodePoint(160));
|
|
245
|
+
const SlateLeaf = React.forwardRef(({ as: Tag = "span", children, inset, ...props }, ref) => {
|
|
246
|
+
const attributes = useNodeAttributes(props, ref);
|
|
247
|
+
if (inset) return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(NonBreakingSpace, null), /* @__PURE__ */ React.createElement(Tag, attributes, children, /* @__PURE__ */ React.createElement(NonBreakingSpace, null)));
|
|
248
|
+
return /* @__PURE__ */ React.createElement(Tag, attributes, children);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/static/utils/createStaticString.ts
|
|
253
|
+
function createStaticString({ text }) {
|
|
254
|
+
return React.createElement("span", { "data-slate-string": true }, text === "" ? "" : text);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/static/utils/getNodeDataAttributes.ts
|
|
259
|
+
const getNodeDataAttributes = (editor, node, { isElement, isLeaf, isText }) => {
|
|
260
|
+
return Object.keys(node).reduce((acc, key) => {
|
|
261
|
+
if (typeof node[key] === "object") return acc;
|
|
262
|
+
if (isElement && key === "children") return acc;
|
|
263
|
+
if ((isLeaf || isText) && key === "text") return acc;
|
|
264
|
+
const plugin = editor.getPlugin({ key });
|
|
265
|
+
if (isLeaf && plugin?.node.isLeaf && plugin?.node.isDecoration !== true) return acc;
|
|
266
|
+
if (isText && plugin?.node.isLeaf && plugin?.node.isDecoration !== false) return acc;
|
|
267
|
+
const attributeName = keyToDataAttribute(key);
|
|
268
|
+
acc[attributeName] = node[key];
|
|
269
|
+
return acc;
|
|
270
|
+
}, {});
|
|
271
|
+
};
|
|
272
|
+
const getPluginDataAttributes = (editor, plugin, node) => {
|
|
273
|
+
const isElement = plugin.node.isElement;
|
|
274
|
+
const dataAttributes = getNodeDataAttributes(editor, node, {
|
|
275
|
+
isElement,
|
|
276
|
+
isLeaf: plugin.node.isLeaf && plugin.node.isDecoration === true,
|
|
277
|
+
isText: plugin.node.isLeaf && plugin.node.isDecoration === false
|
|
278
|
+
});
|
|
279
|
+
const customAttributes = plugin.node.toDataAttributes?.({
|
|
280
|
+
...plugin ? getEditorPlugin(editor, plugin) : {},
|
|
281
|
+
node
|
|
282
|
+
}) ?? {};
|
|
283
|
+
return {
|
|
284
|
+
...dataAttributes,
|
|
285
|
+
...customAttributes
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/static/utils/getRenderNodeStaticProps.ts
|
|
291
|
+
const getRenderNodeStaticProps = ({ attributes: nodeAttributes, editor, node, plugin, props }) => {
|
|
292
|
+
let newProps = {
|
|
293
|
+
...props,
|
|
294
|
+
...plugin ? getEditorPlugin(editor, plugin) : {
|
|
295
|
+
api: editor.api,
|
|
296
|
+
editor,
|
|
297
|
+
tf: editor.transforms
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
const { className } = props;
|
|
301
|
+
const pluginProps = getPluginNodeProps({
|
|
302
|
+
attributes: nodeAttributes,
|
|
303
|
+
node,
|
|
304
|
+
plugin,
|
|
305
|
+
props: newProps
|
|
306
|
+
});
|
|
307
|
+
newProps = {
|
|
308
|
+
...pluginProps,
|
|
309
|
+
attributes: {
|
|
310
|
+
...pluginProps.attributes,
|
|
311
|
+
className: clsx$1(getSlateClass(plugin?.node.type), className) || void 0
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
newProps = pipeInjectNodeProps(editor, newProps, (node$1) => editor.api.findPath(node$1));
|
|
315
|
+
if (newProps.style && Object.keys(newProps.style).length === 0) newProps.style = void 0;
|
|
316
|
+
return newProps;
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
//#endregion
|
|
320
|
+
//#region src/static/utils/getSelectedDomBlocks.ts
|
|
321
|
+
/** Get the slate nodes from the DOM selection */
|
|
322
|
+
/** @deprecated Use getSelectedDomFragment instead */
|
|
323
|
+
const getSelectedDomBlocks = () => {
|
|
324
|
+
const selection = window.getSelection();
|
|
325
|
+
if (!selection || selection.rangeCount === 0) return;
|
|
326
|
+
const domBlocks = selection.getRangeAt(0).cloneContents().querySelectorAll("[data-slate-node=\"element\"][data-slate-id]");
|
|
327
|
+
return Array.from(domBlocks);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
//#endregion
|
|
331
|
+
//#region src/static/utils/stripHtmlClassNames.ts
|
|
332
|
+
const classAttrRegExp = / class="([^"]*)"/g;
|
|
333
|
+
const whitespaceRegExp = /\s+/;
|
|
334
|
+
/**
|
|
335
|
+
* Remove all class names that do not start with one of preserveClassNames
|
|
336
|
+
* (`slate-` by default)
|
|
337
|
+
*/
|
|
338
|
+
const stripHtmlClassNames = (html, { preserveClassNames = ["slate-"] }) => {
|
|
339
|
+
if (preserveClassNames.length === 0) return html.replaceAll(classAttrRegExp, "");
|
|
340
|
+
const preserveRegExp = new RegExp(preserveClassNames.map((cn) => `^${cn}`).join("|"));
|
|
341
|
+
return html.replaceAll(classAttrRegExp, (_match, className) => {
|
|
342
|
+
const classesToKeep = className.split(whitespaceRegExp).filter((cn) => preserveRegExp.test(cn));
|
|
343
|
+
return classesToKeep.length === 0 ? "" : ` class="${classesToKeep.join(" ")}"`;
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
//#endregion
|
|
348
|
+
//#region src/static/utils/stripSlateDataAttributes.ts
|
|
349
|
+
const stripSlateDataAttributes = (rawHtml) => rawHtml.replaceAll(/ data-slate(?:-node|-type|-leaf|-string)="[^"]+"/g, "").replaceAll(/ data-testid="[^"]+"/g, "");
|
|
350
|
+
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region src/static/pluginRenderElementStatic.tsx
|
|
353
|
+
const pluginRenderElementStatic = (editor, plugin) => function render(nodeProps) {
|
|
354
|
+
const element = nodeProps.element;
|
|
355
|
+
const Component = editor.meta.components?.[plugin.key];
|
|
356
|
+
const Element = Component ?? SlateElement;
|
|
357
|
+
let { children } = nodeProps;
|
|
358
|
+
const dataAttributes = getPluginDataAttributes(editor, plugin, element);
|
|
359
|
+
nodeProps = getRenderNodeStaticProps({
|
|
360
|
+
attributes: {
|
|
361
|
+
...element.attributes,
|
|
362
|
+
...dataAttributes
|
|
363
|
+
},
|
|
364
|
+
editor,
|
|
365
|
+
node: element,
|
|
366
|
+
plugin,
|
|
367
|
+
props: nodeProps
|
|
368
|
+
});
|
|
369
|
+
editor.meta.pluginCache.render.belowNodes.forEach((key) => {
|
|
370
|
+
const hoc = editor.getPlugin({ key }).render.belowNodes({
|
|
371
|
+
...nodeProps,
|
|
372
|
+
key
|
|
373
|
+
});
|
|
374
|
+
if (hoc) children = hoc({
|
|
375
|
+
...nodeProps,
|
|
376
|
+
children
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
const defaultProps = Component ? {} : { as: plugin.render?.as };
|
|
380
|
+
let component = /* @__PURE__ */ React.createElement(Element, {
|
|
381
|
+
...defaultProps,
|
|
382
|
+
...nodeProps
|
|
383
|
+
}, children, editor.meta.pluginCache.render.belowRootNodes.map((key) => {
|
|
384
|
+
const Component$1 = editor.getPlugin({ key }).render.belowRootNodes;
|
|
385
|
+
return /* @__PURE__ */ React.createElement(Component$1, {
|
|
386
|
+
key,
|
|
387
|
+
...defaultProps,
|
|
388
|
+
...nodeProps
|
|
389
|
+
});
|
|
390
|
+
}));
|
|
391
|
+
editor.meta.pluginCache.render.aboveNodes.forEach((key) => {
|
|
392
|
+
const hoc = editor.getPlugin({ key }).render.aboveNodes({
|
|
393
|
+
...nodeProps,
|
|
394
|
+
key
|
|
395
|
+
});
|
|
396
|
+
if (hoc) component = hoc({
|
|
397
|
+
...nodeProps,
|
|
398
|
+
children: component
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
return component;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
//#endregion
|
|
405
|
+
//#region src/static/pipeRenderElementStatic.tsx
|
|
406
|
+
const pipeRenderElementStatic = (editor, { renderElement: renderElementProp } = {}) => function render(props) {
|
|
407
|
+
const plugin = getPluginByType(editor, props.element.type);
|
|
408
|
+
if (plugin?.node.isElement) return pluginRenderElementStatic(editor, plugin)(props);
|
|
409
|
+
if (renderElementProp) return renderElementProp(props);
|
|
410
|
+
const ctxProps = getRenderNodeStaticProps({
|
|
411
|
+
editor,
|
|
412
|
+
props: { ...props }
|
|
413
|
+
});
|
|
414
|
+
return /* @__PURE__ */ React.createElement(SlateElement, ctxProps, props.children, editor.meta.pluginCache.render.belowRootNodes.map((key) => {
|
|
415
|
+
const Component = editor.getPlugin({ key }).render.belowRootNodes;
|
|
416
|
+
return /* @__PURE__ */ React.createElement(Component, {
|
|
417
|
+
key,
|
|
418
|
+
...ctxProps
|
|
419
|
+
});
|
|
420
|
+
}));
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/static/pluginRenderTextStatic.tsx
|
|
425
|
+
const pluginRenderTextStatic = (editor, plugin) => function render(nodeProps) {
|
|
426
|
+
const { children, text } = nodeProps;
|
|
427
|
+
if (text[plugin.node.type ?? plugin.key]) {
|
|
428
|
+
const Component = editor.meta.components?.[plugin.key];
|
|
429
|
+
const Text = Component ?? SlateText;
|
|
430
|
+
const ctxProps = getRenderNodeStaticProps({
|
|
431
|
+
attributes: { ...text.attributes },
|
|
432
|
+
editor,
|
|
433
|
+
node: text,
|
|
434
|
+
plugin,
|
|
435
|
+
props: nodeProps
|
|
436
|
+
});
|
|
437
|
+
const defaultProps = Component ? {} : { as: plugin.render?.as };
|
|
438
|
+
return /* @__PURE__ */ React.createElement(Text, {
|
|
439
|
+
...defaultProps,
|
|
440
|
+
...ctxProps
|
|
441
|
+
}, children);
|
|
442
|
+
}
|
|
443
|
+
return children;
|
|
444
|
+
};
|
|
445
|
+
/** @see {@link RenderText} */
|
|
446
|
+
const pipeRenderTextStatic = (editor, { renderText: renderTextProp } = {}) => {
|
|
447
|
+
const renderTexts = [];
|
|
448
|
+
const textPropsPlugins = [];
|
|
449
|
+
editor.meta.pluginCache.node.isText.forEach((key) => {
|
|
450
|
+
const plugin = editor.getPlugin({ key });
|
|
451
|
+
if (plugin) renderTexts.push(pluginRenderTextStatic(editor, plugin));
|
|
452
|
+
});
|
|
453
|
+
editor.meta.pluginCache.node.textProps.forEach((key) => {
|
|
454
|
+
const plugin = editor.getPlugin({ key });
|
|
455
|
+
if (plugin) textPropsPlugins.push(plugin);
|
|
456
|
+
});
|
|
457
|
+
return function render({ attributes, ...props }) {
|
|
458
|
+
renderTexts.forEach((render$1) => {
|
|
459
|
+
const newChildren = render$1(props);
|
|
460
|
+
if (newChildren !== void 0) props.children = newChildren;
|
|
461
|
+
});
|
|
462
|
+
textPropsPlugins.forEach((plugin) => {
|
|
463
|
+
if (props.text[plugin.node.type ?? plugin.key]) {
|
|
464
|
+
const pluginTextProps = typeof plugin.node.textProps === "function" ? plugin.node.textProps(props) : plugin.node.textProps ?? {};
|
|
465
|
+
if (pluginTextProps.className) pluginTextProps.className = clsx$1(props.className, pluginTextProps.className);
|
|
466
|
+
attributes = {
|
|
467
|
+
...attributes,
|
|
468
|
+
...pluginTextProps
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
if (renderTextProp) return renderTextProp({
|
|
473
|
+
attributes,
|
|
474
|
+
...props
|
|
475
|
+
});
|
|
476
|
+
const ctxProps = getRenderNodeStaticProps({
|
|
477
|
+
editor,
|
|
478
|
+
props: {
|
|
479
|
+
attributes,
|
|
480
|
+
...props
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
const text = ctxProps.text;
|
|
484
|
+
const dataAttributes = getNodeDataAttributes(editor, text, { isText: true });
|
|
485
|
+
return /* @__PURE__ */ React.createElement(SlateText, {
|
|
486
|
+
...ctxProps,
|
|
487
|
+
attributes: {
|
|
488
|
+
...ctxProps.attributes,
|
|
489
|
+
...dataAttributes
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
};
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
//#endregion
|
|
496
|
+
//#region src/static/components/PlateStatic.tsx
|
|
497
|
+
function BaseElementStatic({ decorate, decorations, editor, element = {
|
|
498
|
+
children: [],
|
|
499
|
+
type: ""
|
|
500
|
+
} }) {
|
|
501
|
+
const renderElement = pipeRenderElementStatic(editor);
|
|
502
|
+
const attributes = {
|
|
503
|
+
"data-slate-node": "element",
|
|
504
|
+
ref: null
|
|
505
|
+
};
|
|
506
|
+
let children = /* @__PURE__ */ React.createElement(Children, {
|
|
507
|
+
decorate,
|
|
508
|
+
decorations,
|
|
509
|
+
editor
|
|
510
|
+
}, element.children);
|
|
511
|
+
if (editor.api.isVoid(element)) {
|
|
512
|
+
attributes["data-slate-void"] = true;
|
|
513
|
+
children = /* @__PURE__ */ React.createElement("span", {
|
|
514
|
+
style: {
|
|
515
|
+
color: "transparent",
|
|
516
|
+
height: "0",
|
|
517
|
+
outline: "none",
|
|
518
|
+
position: "absolute"
|
|
519
|
+
},
|
|
520
|
+
"data-slate-spacer": true
|
|
521
|
+
}, /* @__PURE__ */ React.createElement(Children, {
|
|
522
|
+
decorate,
|
|
523
|
+
decorations,
|
|
524
|
+
editor
|
|
525
|
+
}, element.children));
|
|
526
|
+
}
|
|
527
|
+
if (editor.api.isInline(element)) attributes["data-slate-inline"] = true;
|
|
528
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, renderElement?.({
|
|
529
|
+
attributes,
|
|
530
|
+
children,
|
|
531
|
+
element
|
|
532
|
+
}));
|
|
533
|
+
}
|
|
534
|
+
const ElementStatic = React.memo(BaseElementStatic, (prev, next) => (prev.element === next.element || prev.element._memo !== void 0 && prev.element._memo === next.element._memo) && isElementDecorationsEqual(prev.decorations, next.decorations));
|
|
535
|
+
function BaseLeafStatic({ decorations, editor, text = { text: "" } }) {
|
|
536
|
+
const renderLeaf = pipeRenderLeafStatic(editor);
|
|
537
|
+
const renderText = pipeRenderTextStatic(editor);
|
|
538
|
+
const leafElements = TextApi.decorations(text, decorations).map(({ leaf, position }, index) => {
|
|
539
|
+
const leafElement = renderLeaf({
|
|
540
|
+
attributes: { "data-slate-leaf": true },
|
|
541
|
+
children: /* @__PURE__ */ React.createElement("span", { "data-slate-string": true }, leaf.text === "" ? "" : leaf.text),
|
|
542
|
+
leaf,
|
|
543
|
+
leafPosition: position,
|
|
544
|
+
text: leaf
|
|
545
|
+
});
|
|
546
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, { key: index }, leafElement);
|
|
547
|
+
});
|
|
548
|
+
return renderText({
|
|
549
|
+
attributes: {
|
|
550
|
+
"data-slate-node": "text",
|
|
551
|
+
ref: null
|
|
552
|
+
},
|
|
553
|
+
children: leafElements,
|
|
554
|
+
text
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
const LeafStatic = React.memo(BaseLeafStatic, (prev, next) => {
|
|
558
|
+
return TextApi.equals(next.text, prev.text) && isTextDecorationsEqual(next.decorations, prev.decorations);
|
|
559
|
+
});
|
|
560
|
+
const defaultDecorate = () => [];
|
|
561
|
+
function Children({ children = [], decorate = defaultDecorate, decorations = [], editor }) {
|
|
562
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, children.map((child, i) => {
|
|
563
|
+
const p = editor.api.findPath(child);
|
|
564
|
+
let ds = [];
|
|
565
|
+
if (p) {
|
|
566
|
+
const range = editor.api.range(p);
|
|
567
|
+
ds = decorate([child, p]);
|
|
568
|
+
for (const dec of decorations) {
|
|
569
|
+
const d = RangeApi.intersection(dec, range);
|
|
570
|
+
if (d) ds.push(d);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return ElementApi.isElement(child) ? /* @__PURE__ */ React.createElement(ElementStatic, {
|
|
574
|
+
key: i,
|
|
575
|
+
decorate,
|
|
576
|
+
decorations: ds,
|
|
577
|
+
editor,
|
|
578
|
+
element: child
|
|
579
|
+
}) : /* @__PURE__ */ React.createElement(LeafStatic, {
|
|
580
|
+
key: i,
|
|
581
|
+
decorations: ds,
|
|
582
|
+
editor,
|
|
583
|
+
text: child
|
|
584
|
+
});
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
587
|
+
function PlateStatic(props) {
|
|
588
|
+
const { className, editor, value, ...rest } = props;
|
|
589
|
+
if (value) editor.children = value;
|
|
590
|
+
const decorate = pipeDecorate(editor);
|
|
591
|
+
let afterEditable = null;
|
|
592
|
+
let beforeEditable = null;
|
|
593
|
+
editor.meta.pluginCache.render.beforeEditable.forEach((key) => {
|
|
594
|
+
const BeforeEditable = editor.getPlugin({ key }).render.beforeEditable;
|
|
595
|
+
if (BeforeEditable) beforeEditable = /* @__PURE__ */ React.createElement(React.Fragment, null, beforeEditable, /* @__PURE__ */ React.createElement(BeforeEditable, null));
|
|
596
|
+
});
|
|
597
|
+
editor.meta.pluginCache.render.afterEditable.forEach((key) => {
|
|
598
|
+
const AfterEditable = editor.getPlugin({ key }).render.afterEditable;
|
|
599
|
+
if (AfterEditable) afterEditable = /* @__PURE__ */ React.createElement(React.Fragment, null, afterEditable, /* @__PURE__ */ React.createElement(AfterEditable, null));
|
|
600
|
+
});
|
|
601
|
+
const content = /* @__PURE__ */ React.createElement("div", {
|
|
602
|
+
className: clsx$1("slate-editor", className),
|
|
603
|
+
"data-slate-editor": true,
|
|
604
|
+
"data-slate-node": "value",
|
|
605
|
+
...rest
|
|
606
|
+
}, /* @__PURE__ */ React.createElement(Children, {
|
|
607
|
+
decorate,
|
|
608
|
+
decorations: [],
|
|
609
|
+
editor
|
|
610
|
+
}, editor.children));
|
|
611
|
+
let aboveEditable = /* @__PURE__ */ React.createElement(React.Fragment, null, beforeEditable, content, afterEditable);
|
|
612
|
+
editor.meta.pluginCache.render.aboveEditable.forEach((key) => {
|
|
613
|
+
const AboveEditable = editor.getPlugin({ key }).render.aboveEditable;
|
|
614
|
+
if (AboveEditable) aboveEditable = /* @__PURE__ */ React.createElement(AboveEditable, null, aboveEditable);
|
|
615
|
+
});
|
|
616
|
+
return aboveEditable;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
//#endregion
|
|
620
|
+
//#region src/static/pluginRenderLeafStatic.tsx
|
|
621
|
+
const pluginRenderLeafStatic = (editor, plugin) => function render(props) {
|
|
622
|
+
const { children, leaf } = props;
|
|
623
|
+
if (leaf[plugin.node.type]) {
|
|
624
|
+
const Component = plugin.render.leaf ?? editor.meta.components?.[plugin.key];
|
|
625
|
+
const Leaf = Component ?? SlateLeaf;
|
|
626
|
+
const ctxProps = getRenderNodeStaticProps({
|
|
627
|
+
attributes: { ...leaf.attributes },
|
|
628
|
+
editor,
|
|
629
|
+
node: leaf,
|
|
630
|
+
plugin,
|
|
631
|
+
props
|
|
632
|
+
});
|
|
633
|
+
const defaultProps = Component ? {} : { as: plugin.render?.as };
|
|
634
|
+
return /* @__PURE__ */ React.createElement(Leaf, {
|
|
635
|
+
...defaultProps,
|
|
636
|
+
...ctxProps
|
|
637
|
+
}, children);
|
|
638
|
+
}
|
|
639
|
+
return children;
|
|
640
|
+
};
|
|
641
|
+
/** @see {@link RenderLeaf} */
|
|
642
|
+
const pipeRenderLeafStatic = (editor, { renderLeaf: renderLeafProp } = {}) => {
|
|
643
|
+
const renderLeafs = [];
|
|
644
|
+
const leafPropsPlugins = [];
|
|
645
|
+
editor.meta.pluginCache.node.isLeaf.forEach((key) => {
|
|
646
|
+
const plugin = editor.getPlugin({ key });
|
|
647
|
+
if (plugin) renderLeafs.push(pluginRenderLeafStatic(editor, plugin));
|
|
648
|
+
});
|
|
649
|
+
editor.meta.pluginCache.node.leafProps.forEach((key) => {
|
|
650
|
+
const plugin = editor.getPlugin({ key });
|
|
651
|
+
if (plugin) leafPropsPlugins.push(plugin);
|
|
652
|
+
});
|
|
653
|
+
return function render({ attributes, ...props }) {
|
|
654
|
+
renderLeafs.forEach((render$1) => {
|
|
655
|
+
const newChildren = render$1(props);
|
|
656
|
+
if (newChildren !== void 0) props.children = newChildren;
|
|
657
|
+
});
|
|
658
|
+
leafPropsPlugins.forEach((plugin) => {
|
|
659
|
+
if (props.leaf[plugin.node.type]) {
|
|
660
|
+
const pluginLeafProps = typeof plugin.node.leafProps === "function" ? plugin.node.leafProps(props) : plugin.node.leafProps ?? {};
|
|
661
|
+
if (pluginLeafProps.className) pluginLeafProps.className = clsx$1(props.className, pluginLeafProps.className);
|
|
662
|
+
attributes = {
|
|
663
|
+
...attributes,
|
|
664
|
+
...pluginLeafProps
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
if (renderLeafProp) return renderLeafProp({
|
|
669
|
+
attributes,
|
|
670
|
+
...props
|
|
671
|
+
});
|
|
672
|
+
const ctxProps = getRenderNodeStaticProps({
|
|
673
|
+
editor,
|
|
674
|
+
props: {
|
|
675
|
+
attributes,
|
|
676
|
+
...props
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
const leaf = ctxProps.leaf;
|
|
680
|
+
const dataAttributes = getNodeDataAttributes(editor, leaf, { isLeaf: true });
|
|
681
|
+
return /* @__PURE__ */ React.createElement(SlateLeaf, {
|
|
682
|
+
...ctxProps,
|
|
683
|
+
attributes: {
|
|
684
|
+
...ctxProps.attributes,
|
|
685
|
+
...dataAttributes
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
};
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
//#endregion
|
|
692
|
+
//#region src/static/serializeHtml.tsx
|
|
693
|
+
const getReactDOMServer = async () => {
|
|
694
|
+
return (await import("react-dom/server")).default;
|
|
695
|
+
};
|
|
696
|
+
const renderComponentToHtml = (ReactDOMServer, Component, props) => decode(ReactDOMServer.renderToStaticMarkup(React.createElement(Component, props)));
|
|
697
|
+
/**
|
|
698
|
+
* Serialize the editor content to HTML. By default, uses `PlateStatic` as the
|
|
699
|
+
* editor component, but you can provide a custom component (e.g.
|
|
700
|
+
* `EditorStatic`).
|
|
701
|
+
*/
|
|
702
|
+
const serializeHtml = async (editor, { editorComponent: EditorComponent = PlateStatic, preserveClassNames, props = {}, stripClassNames = false, stripDataAttributes = false } = {}) => {
|
|
703
|
+
let htmlString = renderComponentToHtml(await getReactDOMServer(), EditorComponent, {
|
|
704
|
+
editor,
|
|
705
|
+
...props
|
|
706
|
+
});
|
|
707
|
+
if (stripClassNames) htmlString = stripHtmlClassNames(htmlString, { preserveClassNames });
|
|
708
|
+
if (stripDataAttributes) htmlString = stripSlateDataAttributes(htmlString);
|
|
709
|
+
return htmlString;
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
//#endregion
|
|
713
|
+
//#region src/static/deserialize/htmlStringToEditorDOM.ts
|
|
714
|
+
/**
|
|
715
|
+
* Convert HTML string exported from Plate into HTML element.
|
|
716
|
+
*
|
|
717
|
+
* @param html - The HTML string to convert exported from Plate.
|
|
718
|
+
* @returns The Editor element without head and body.
|
|
719
|
+
*/
|
|
720
|
+
const getEditorDOMFromHtmlString = (html) => {
|
|
721
|
+
const node = document.createElement("body");
|
|
722
|
+
node.innerHTML = html;
|
|
723
|
+
return node.querySelector("[data-slate-editor=\"true\"]");
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
//#endregion
|
|
727
|
+
export { pipeInjectNodeProps as A, createStaticEditor as C, getSelectedDomNode as D, isSelectOutside as E, getSelectedDomFragment as O, useNodeAttributes as S, ViewPlugin as T, getPluginDataAttributes as _, ElementStatic as a, SlateLeaf as b, pipeRenderTextStatic as c, pluginRenderElementStatic as d, stripSlateDataAttributes as f, getNodeDataAttributes as g, getRenderNodeStaticProps as h, pluginRenderLeafStatic as i, pipeDecorate as k, pluginRenderTextStatic as l, getSelectedDomBlocks as m, serializeHtml as n, LeafStatic as o, stripHtmlClassNames as p, pipeRenderLeafStatic as r, PlateStatic as s, getEditorDOMFromHtmlString as t, pipeRenderElementStatic as u, createStaticString as v, getStaticPlugins as w, SlateText as x, SlateElement as y };
|
|
728
|
+
//# sourceMappingURL=static-CVN6JhaR.js.map
|