@mdxeditor/editor 1.10.2 → 1.11.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/exportMarkdownFromLexical.d.ts +4 -0
- package/dist/exportMarkdownFromLexical.js +34 -0
- package/dist/gurx/realmFactory.d.ts +1 -1
- package/dist/importMarkdownToLexical.d.ts +4 -0
- package/dist/importMarkdownToLexical.js +1 -0
- package/dist/index.js +4 -0
- package/dist/plugins/core/GenericHTMLNode.d.ts +38 -0
- package/dist/plugins/core/GenericHTMLNode.js +117 -0
- package/dist/plugins/core/LexicalGenericHTMLNodeVisitor.d.ts +4 -0
- package/dist/plugins/core/LexicalGenericHTMLNodeVisitor.js +15 -0
- package/dist/plugins/core/LexicalTextVisitor.js +17 -1
- package/dist/plugins/core/MdastHTMLNode.d.ts +13 -0
- package/dist/plugins/core/MdastHTMLNode.js +122 -0
- package/dist/plugins/core/MdastHTMLVisitor.d.ts +3 -0
- package/dist/plugins/core/MdastHTMLVisitor.js +12 -0
- package/dist/plugins/core/index.d.ts +1 -1
- package/dist/plugins/core/index.js +15 -0
- package/dist/plugins/diff-source/SourceEditor.js +7 -1
- package/dist/style.css +3 -0
- package/dist/utils/mergeStyleAttributes.d.ts +1 -0
- package/dist/utils/mergeStyleAttributes.js +22 -0
- package/package.json +2 -1
|
@@ -73,6 +73,10 @@ export interface LexicalExportVisitor<LN extends LexicalNode, UN extends Mdast.C
|
|
|
73
73
|
* For this to be called by the tree walk, shouldJoin must return true.
|
|
74
74
|
*/
|
|
75
75
|
join?<T extends Mdast.Content>(prevNode: T, currentNode: T): T;
|
|
76
|
+
/**
|
|
77
|
+
* Default 0, optional, sets the priority of the visitor. The higher the number, the earlier it will be called.
|
|
78
|
+
*/
|
|
79
|
+
priority?: number;
|
|
76
80
|
}
|
|
77
81
|
/**
|
|
78
82
|
* The "any" type for LexicalExportVisitor.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { $isElementNode } from "lexical";
|
|
2
2
|
import { toMarkdown } from "mdast-util-to-markdown";
|
|
3
|
+
import { isMdastHTMLNode } from "./plugins/core/MdastHTMLNode.js";
|
|
4
|
+
import { mergeStyleAttributes } from "./utils/mergeStyleAttributes.js";
|
|
3
5
|
function isParent(node) {
|
|
4
6
|
return node.children instanceof Array;
|
|
5
7
|
}
|
|
@@ -11,6 +13,7 @@ function exportLexicalTreeToMdast({
|
|
|
11
13
|
}) {
|
|
12
14
|
let unistRoot = null;
|
|
13
15
|
const referredComponents = /* @__PURE__ */ new Set();
|
|
16
|
+
visitors = visitors.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
14
17
|
visit(root, null);
|
|
15
18
|
function registerReferredComponent(componentName) {
|
|
16
19
|
referredComponents.add(componentName);
|
|
@@ -123,11 +126,42 @@ function exportLexicalTreeToMdast({
|
|
|
123
126
|
typedRoot.children.unshift(...imports);
|
|
124
127
|
}
|
|
125
128
|
fixWrappingWhitespace(typedRoot, []);
|
|
129
|
+
collapseNestedHtmlTags(typedRoot);
|
|
126
130
|
if (!jsxIsAvailable) {
|
|
127
131
|
convertUnderlineJsxToHtml(typedRoot);
|
|
128
132
|
}
|
|
129
133
|
return typedRoot;
|
|
130
134
|
}
|
|
135
|
+
function collapseNestedHtmlTags(node) {
|
|
136
|
+
if ("children" in node) {
|
|
137
|
+
if (isMdastHTMLNode(node) && node.children.length === 1) {
|
|
138
|
+
const onlyChild = node.children[0];
|
|
139
|
+
if (onlyChild.type === "mdxJsxTextElement" && onlyChild.name === "span") {
|
|
140
|
+
(onlyChild.attributes || []).forEach((attribute) => {
|
|
141
|
+
var _a;
|
|
142
|
+
if (attribute.type === "mdxJsxAttribute") {
|
|
143
|
+
const parentAttribute = (_a = node.attributes) == null ? void 0 : _a.find((attr) => attr.type === "mdxJsxAttribute" && attr.name === attribute.name);
|
|
144
|
+
if (parentAttribute) {
|
|
145
|
+
if (attribute.name === "className") {
|
|
146
|
+
const mergedClassesSet = /* @__PURE__ */ new Set([
|
|
147
|
+
...parentAttribute.value.split(" "),
|
|
148
|
+
...attribute.value.split(" ")
|
|
149
|
+
]);
|
|
150
|
+
parentAttribute.value = Array.from(mergedClassesSet).join(" ");
|
|
151
|
+
} else if (attribute.name === "style") {
|
|
152
|
+
parentAttribute.value = mergeStyleAttributes(parentAttribute.value, attribute.value);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
node.attributes.push(attribute);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
node.children = onlyChild.children;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
node.children.forEach((child) => collapseNestedHtmlTags(child));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
131
165
|
function convertUnderlineJsxToHtml(node) {
|
|
132
166
|
if (Object.hasOwn(node, "children")) {
|
|
133
167
|
const nodeAsParent = node;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Realm, RealmNode, Subscription, UnsubscribeHandle } from './realm';
|
|
2
2
|
/**
|
|
3
|
-
* The system interface is the runtime representation of a state management module, a
|
|
3
|
+
* The system interface is the runtime representation of a state management module, a record of nodes.
|
|
4
4
|
*/
|
|
5
5
|
export interface System {
|
|
6
6
|
[key: string]: RealmNode<any>;
|
|
@@ -59,6 +59,10 @@ export interface MdastImportVisitor<UN extends Mdast.Content> {
|
|
|
59
59
|
* The function that is called when the node is visited. See {@link MdastVisitParams} for details.
|
|
60
60
|
*/
|
|
61
61
|
visitNode(params: MdastVisitParams<UN>): void;
|
|
62
|
+
/**
|
|
63
|
+
* Default 0, optional, sets the priority of the visitor. The higher the number, the earlier it will be called.
|
|
64
|
+
*/
|
|
65
|
+
priority?: number;
|
|
62
66
|
}
|
|
63
67
|
/**
|
|
64
68
|
* The options of the tree import utility. Not meant to be used directly.
|
|
@@ -18,6 +18,7 @@ function importMarkdownToLexical({ root, markdown, visitors, syntaxExtensions, m
|
|
|
18
18
|
}
|
|
19
19
|
function importMdastTreeToLexical({ root, mdastRoot, visitors }) {
|
|
20
20
|
const formattingMap = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
visitors = visitors.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
21
22
|
function visitChildren(mdastNode, lexicalParent) {
|
|
22
23
|
if (!isParent(mdastNode)) {
|
|
23
24
|
throw new Error("Attempting to visit children of a non-parent");
|
package/dist/index.js
CHANGED
|
@@ -48,13 +48,16 @@ import { TooltipWrap } from "./plugins/toolbar/primitives/TooltipWrap.js";
|
|
|
48
48
|
import { Select, SelectButtonTrigger, SelectContent, SelectItem, SelectTrigger } from "./plugins/toolbar/primitives/select.js";
|
|
49
49
|
import { NestedEditorsContext, NestedLexicalEditor, useLexicalNodeRemove, useMdastNodeUpdater, useNestedEditorContext } from "./plugins/core/NestedLexicalEditor.js";
|
|
50
50
|
import { PropertyPopover } from "./plugins/core/PropertyPopover.js";
|
|
51
|
+
import { $createGenericHTMLNode, $isGenericHTMLNode, GenericHTMLNode } from "./plugins/core/GenericHTMLNode.js";
|
|
51
52
|
import { $createImageNode, $isImageNode, ImageNode } from "./plugins/image/ImageNode.js";
|
|
52
53
|
import { useCodeBlockEditorContext } from "./plugins/codeblock/CodeBlockNode.js";
|
|
53
54
|
import { RefCount, defaultComparator, realm } from "./gurx/realm.js";
|
|
54
55
|
import { RealmPluginInitializer, RequirePlugin, realmFactoryToComponent, realmPlugin, sysHooks, useHasPlugin } from "./gurx/react.js";
|
|
55
56
|
import { getRealmFactory, realmFactory, system } from "./gurx/realmFactory.js";
|
|
56
57
|
export {
|
|
58
|
+
$createGenericHTMLNode,
|
|
57
59
|
$createImageNode,
|
|
60
|
+
$isGenericHTMLNode,
|
|
58
61
|
$isImageNode,
|
|
59
62
|
ADMONITION_TYPES,
|
|
60
63
|
AdmonitionDirectiveDescriptor,
|
|
@@ -72,6 +75,7 @@ export {
|
|
|
72
75
|
DialogButton,
|
|
73
76
|
DiffSourceToggleWrapper,
|
|
74
77
|
GenericDirectiveEditor,
|
|
78
|
+
GenericHTMLNode,
|
|
75
79
|
GenericJsxEditor,
|
|
76
80
|
INSERT_IMAGE_COMMAND,
|
|
77
81
|
ImageNode,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DOMConversionMap, DOMExportOutput, ElementNode, LexicalEditor, LexicalNode, NodeKey, SerializedElementNode, Spread } from 'lexical';
|
|
2
|
+
import { MdxJsxAttribute } from 'mdast-util-mdx-jsx';
|
|
3
|
+
import { MDX_NODE_TYPES, htmlTags } from './MdastHTMLNode';
|
|
4
|
+
export type KnownHTMLTagType = (typeof htmlTags)[number];
|
|
5
|
+
declare const TYPE_NAME: "generic-html";
|
|
6
|
+
export type SerializedGenericHTMLNode = Spread<{
|
|
7
|
+
tag: KnownHTMLTagType;
|
|
8
|
+
type: typeof TYPE_NAME;
|
|
9
|
+
mdxType: MdxNodeType;
|
|
10
|
+
attributes: MdxJsxAttribute[];
|
|
11
|
+
version: 1;
|
|
12
|
+
}, SerializedElementNode>;
|
|
13
|
+
type MdxNodeType = (typeof MDX_NODE_TYPES)[number];
|
|
14
|
+
export declare class GenericHTMLNode extends ElementNode {
|
|
15
|
+
/** @internal */
|
|
16
|
+
__tag: KnownHTMLTagType;
|
|
17
|
+
__nodeType: MdxNodeType;
|
|
18
|
+
__attributes: MdxJsxAttribute[];
|
|
19
|
+
static getType(): string;
|
|
20
|
+
static clone(node: GenericHTMLNode): GenericHTMLNode;
|
|
21
|
+
constructor(tag: KnownHTMLTagType, type: MdxNodeType, attributes: MdxJsxAttribute[], key?: NodeKey);
|
|
22
|
+
getTag(): KnownHTMLTagType;
|
|
23
|
+
getNodeType(): MdxNodeType;
|
|
24
|
+
getAttributes(): MdxJsxAttribute[];
|
|
25
|
+
updateAttributes(attributes: MdxJsxAttribute[]): void;
|
|
26
|
+
getStyle(): string;
|
|
27
|
+
createDOM(): HTMLElement;
|
|
28
|
+
updateDOM(): boolean;
|
|
29
|
+
static importDOM(): DOMConversionMap | null;
|
|
30
|
+
exportDOM(editor: LexicalEditor): DOMExportOutput;
|
|
31
|
+
static importJSON(serializedNode: SerializedGenericHTMLNode): GenericHTMLNode;
|
|
32
|
+
exportJSON(): SerializedGenericHTMLNode;
|
|
33
|
+
extractWithChild(): boolean;
|
|
34
|
+
isInline(): boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare function $createGenericHTMLNode(tag: KnownHTMLTagType, type: MdxNodeType, attributes: MdxJsxAttribute[]): GenericHTMLNode;
|
|
37
|
+
export declare function $isGenericHTMLNode(node: LexicalNode | null | undefined): node is GenericHTMLNode;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => {
|
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
7
|
+
import { ElementNode, $applyNodeReplacement } from "lexical";
|
|
8
|
+
const TYPE_NAME = "generic-html";
|
|
9
|
+
class GenericHTMLNode extends ElementNode {
|
|
10
|
+
constructor(tag, type, attributes, key) {
|
|
11
|
+
super(key);
|
|
12
|
+
/** @internal */
|
|
13
|
+
__publicField(this, "__tag");
|
|
14
|
+
__publicField(this, "__nodeType");
|
|
15
|
+
__publicField(this, "__attributes");
|
|
16
|
+
this.__tag = tag;
|
|
17
|
+
this.__nodeType = type;
|
|
18
|
+
this.__attributes = attributes;
|
|
19
|
+
}
|
|
20
|
+
static getType() {
|
|
21
|
+
return TYPE_NAME;
|
|
22
|
+
}
|
|
23
|
+
static clone(node) {
|
|
24
|
+
return new GenericHTMLNode(node.__tag, node.__nodeType, node.__attributes, node.__key);
|
|
25
|
+
}
|
|
26
|
+
getTag() {
|
|
27
|
+
return this.__tag;
|
|
28
|
+
}
|
|
29
|
+
getNodeType() {
|
|
30
|
+
return this.__nodeType;
|
|
31
|
+
}
|
|
32
|
+
getAttributes() {
|
|
33
|
+
return this.__attributes;
|
|
34
|
+
}
|
|
35
|
+
updateAttributes(attributes) {
|
|
36
|
+
const self = this.getWritable();
|
|
37
|
+
self.__attributes = attributes;
|
|
38
|
+
}
|
|
39
|
+
getStyle() {
|
|
40
|
+
var _a;
|
|
41
|
+
return (_a = this.__attributes.find((attribute) => attribute.name === "style")) == null ? void 0 : _a.value;
|
|
42
|
+
}
|
|
43
|
+
// View
|
|
44
|
+
createDOM() {
|
|
45
|
+
const tag = this.__tag;
|
|
46
|
+
const element = document.createElement(tag);
|
|
47
|
+
this.__attributes.forEach((attribute) => {
|
|
48
|
+
element.setAttribute(attribute.name, attribute.value);
|
|
49
|
+
});
|
|
50
|
+
return element;
|
|
51
|
+
}
|
|
52
|
+
updateDOM() {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
static importDOM() {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
exportDOM(editor) {
|
|
59
|
+
const { element } = super.exportDOM(editor);
|
|
60
|
+
return {
|
|
61
|
+
element
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
static importJSON(serializedNode) {
|
|
65
|
+
const node = $createGenericHTMLNode(serializedNode.tag, serializedNode.mdxType, serializedNode.attributes);
|
|
66
|
+
node.setFormat(serializedNode.format);
|
|
67
|
+
node.setIndent(serializedNode.indent);
|
|
68
|
+
node.setDirection(serializedNode.direction);
|
|
69
|
+
return node;
|
|
70
|
+
}
|
|
71
|
+
exportJSON() {
|
|
72
|
+
return {
|
|
73
|
+
...super.exportJSON(),
|
|
74
|
+
tag: this.getTag(),
|
|
75
|
+
attributes: this.__attributes,
|
|
76
|
+
mdxType: this.__nodeType,
|
|
77
|
+
type: TYPE_NAME,
|
|
78
|
+
version: 1
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/*
|
|
82
|
+
// Mutation
|
|
83
|
+
insertNewAfter(selection?: RangeSelection, restoreSelection = true): ParagraphNode | GenericHTMLNode {
|
|
84
|
+
const anchorOffet = selection ? selection.anchor.offset : 0
|
|
85
|
+
const newElement =
|
|
86
|
+
anchorOffet > 0 && anchorOffet < this.getTextContentSize() ? $createHeadingNode(this.getTag()) : $createParagraphNode()
|
|
87
|
+
const direction = this.getDirection()
|
|
88
|
+
newElement.setDirection(direction)
|
|
89
|
+
this.insertAfter(newElement, restoreSelection)
|
|
90
|
+
return newElement
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
collapseAtStart(): true {
|
|
94
|
+
const newElement = !this.isEmpty() ? $createHeadingNode(this.getTag()) : $createParagraphNode()
|
|
95
|
+
const children = this.getChildren()
|
|
96
|
+
children.forEach((child) => newElement.append(child))
|
|
97
|
+
this.replace(newElement)
|
|
98
|
+
return true
|
|
99
|
+
}*/
|
|
100
|
+
extractWithChild() {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
isInline() {
|
|
104
|
+
return this.__nodeType === "mdxJsxTextElement";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function $createGenericHTMLNode(tag, type, attributes) {
|
|
108
|
+
return $applyNodeReplacement(new GenericHTMLNode(tag, type, attributes));
|
|
109
|
+
}
|
|
110
|
+
function $isGenericHTMLNode(node) {
|
|
111
|
+
return node instanceof GenericHTMLNode;
|
|
112
|
+
}
|
|
113
|
+
export {
|
|
114
|
+
$createGenericHTMLNode,
|
|
115
|
+
$isGenericHTMLNode,
|
|
116
|
+
GenericHTMLNode
|
|
117
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx';
|
|
2
|
+
import { GenericHTMLNode } from './GenericHTMLNode';
|
|
3
|
+
import { LexicalExportVisitor } from '../../exportMarkdownFromLexical';
|
|
4
|
+
export declare const LexicalGenericHTMLVisitor: LexicalExportVisitor<GenericHTMLNode, MdxJsxFlowElement | MdxJsxTextElement>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { $isGenericHTMLNode } from "./GenericHTMLNode.js";
|
|
2
|
+
const LexicalGenericHTMLVisitor = {
|
|
3
|
+
testLexicalNode: $isGenericHTMLNode,
|
|
4
|
+
visitLexicalNode({ actions, lexicalNode }) {
|
|
5
|
+
actions.addAndStepInto("mdxJsxTextElement", {
|
|
6
|
+
name: lexicalNode.getTag(),
|
|
7
|
+
type: lexicalNode.getNodeType(),
|
|
8
|
+
attributes: lexicalNode.getAttributes()
|
|
9
|
+
});
|
|
10
|
+
},
|
|
11
|
+
priority: -100
|
|
12
|
+
};
|
|
13
|
+
export {
|
|
14
|
+
LexicalGenericHTMLVisitor
|
|
15
|
+
};
|
|
@@ -5,7 +5,14 @@ function isMdastText(mdastNode) {
|
|
|
5
5
|
}
|
|
6
6
|
const LexicalTextVisitor = {
|
|
7
7
|
shouldJoin: (prevNode, currentNode) => {
|
|
8
|
-
|
|
8
|
+
if (["text", "emphasis", "strong"].includes(prevNode.type)) {
|
|
9
|
+
return prevNode.type === currentNode.type;
|
|
10
|
+
}
|
|
11
|
+
if (prevNode.type === "mdxJsxTextElement" && currentNode.type === "mdxJsxTextElement") {
|
|
12
|
+
const currentMdxNode = currentNode;
|
|
13
|
+
return prevNode.name === currentMdxNode.name && JSON.stringify(prevNode.attributes) === JSON.stringify(currentMdxNode.attributes);
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
9
16
|
},
|
|
10
17
|
join(prevNode, currentNode) {
|
|
11
18
|
if (isMdastText(prevNode) && isMdastText(currentNode)) {
|
|
@@ -26,6 +33,7 @@ const LexicalTextVisitor = {
|
|
|
26
33
|
const prevFormat = $isTextNode(previousSibling) ? previousSibling.getFormat() : 0;
|
|
27
34
|
const textContent = lexicalNode.getTextContent();
|
|
28
35
|
const format = lexicalNode.getFormat() ?? 0;
|
|
36
|
+
const style = lexicalNode.getStyle();
|
|
29
37
|
if (format & IS_CODE) {
|
|
30
38
|
actions.addAndStepInto("inlineCode", {
|
|
31
39
|
value: textContent
|
|
@@ -33,6 +41,14 @@ const LexicalTextVisitor = {
|
|
|
33
41
|
return;
|
|
34
42
|
}
|
|
35
43
|
let localParentNode = mdastParent;
|
|
44
|
+
if (style) {
|
|
45
|
+
localParentNode = actions.appendToParent(localParentNode, {
|
|
46
|
+
type: "mdxJsxTextElement",
|
|
47
|
+
name: "span",
|
|
48
|
+
children: [],
|
|
49
|
+
attributes: [{ type: "mdxJsxAttribute", name: "style", value: style }]
|
|
50
|
+
});
|
|
51
|
+
}
|
|
36
52
|
if (prevFormat & format & IS_ITALIC) {
|
|
37
53
|
localParentNode = actions.appendToParent(localParentNode, {
|
|
38
54
|
type: "emphasis",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as Mdast from 'mdast';
|
|
2
|
+
import { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx';
|
|
3
|
+
interface MdastBlockHTMLNode extends MdxJsxFlowElement {
|
|
4
|
+
name: (typeof htmlTags)[number];
|
|
5
|
+
}
|
|
6
|
+
interface MdastInlineHTMLNode extends MdxJsxTextElement {
|
|
7
|
+
name: (typeof htmlTags)[number];
|
|
8
|
+
}
|
|
9
|
+
export type MdastHTMLNode = MdastBlockHTMLNode | MdastInlineHTMLNode;
|
|
10
|
+
export declare const MDX_NODE_TYPES: readonly ["mdxJsxTextElement", "mdxJsxFlowElement"];
|
|
11
|
+
export declare function isMdastHTMLNode(node: Mdast.Parent | Mdast.Content | Mdast.Root): node is MdastHTMLNode;
|
|
12
|
+
export declare const htmlTags: readonly ["a", "abbr", "address", "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", "blockquote", "body", "br", "button", "canvas", "caption", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", "source", "span", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "u", "ul", "var", "video", "wbr"];
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const MDX_NODE_TYPES = ["mdxJsxTextElement", "mdxJsxFlowElement"];
|
|
2
|
+
function isMdastHTMLNode(node) {
|
|
3
|
+
var _a;
|
|
4
|
+
return MDX_NODE_TYPES.includes(node.type) && htmlTags.includes(((_a = node.name) == null ? void 0 : _a.toLowerCase()) ?? "");
|
|
5
|
+
}
|
|
6
|
+
const htmlTags = [
|
|
7
|
+
"a",
|
|
8
|
+
"abbr",
|
|
9
|
+
"address",
|
|
10
|
+
"area",
|
|
11
|
+
"article",
|
|
12
|
+
"aside",
|
|
13
|
+
"audio",
|
|
14
|
+
"b",
|
|
15
|
+
"base",
|
|
16
|
+
"bdi",
|
|
17
|
+
"bdo",
|
|
18
|
+
"blockquote",
|
|
19
|
+
"body",
|
|
20
|
+
"br",
|
|
21
|
+
"button",
|
|
22
|
+
"canvas",
|
|
23
|
+
"caption",
|
|
24
|
+
"cite",
|
|
25
|
+
"code",
|
|
26
|
+
"col",
|
|
27
|
+
"colgroup",
|
|
28
|
+
"data",
|
|
29
|
+
"datalist",
|
|
30
|
+
"dd",
|
|
31
|
+
"del",
|
|
32
|
+
"details",
|
|
33
|
+
"dfn",
|
|
34
|
+
"dialog",
|
|
35
|
+
"div",
|
|
36
|
+
"dl",
|
|
37
|
+
"dt",
|
|
38
|
+
"em",
|
|
39
|
+
"embed",
|
|
40
|
+
"fieldset",
|
|
41
|
+
"figcaption",
|
|
42
|
+
"figure",
|
|
43
|
+
"footer",
|
|
44
|
+
"form",
|
|
45
|
+
"h1",
|
|
46
|
+
"h2",
|
|
47
|
+
"h3",
|
|
48
|
+
"h4",
|
|
49
|
+
"h5",
|
|
50
|
+
"h6",
|
|
51
|
+
"head",
|
|
52
|
+
"header",
|
|
53
|
+
"hgroup",
|
|
54
|
+
"hr",
|
|
55
|
+
"html",
|
|
56
|
+
"i",
|
|
57
|
+
"iframe",
|
|
58
|
+
// 'img',
|
|
59
|
+
"input",
|
|
60
|
+
"ins",
|
|
61
|
+
"kbd",
|
|
62
|
+
"label",
|
|
63
|
+
"legend",
|
|
64
|
+
"li",
|
|
65
|
+
"link",
|
|
66
|
+
"main",
|
|
67
|
+
"map",
|
|
68
|
+
"mark",
|
|
69
|
+
"meta",
|
|
70
|
+
"meter",
|
|
71
|
+
"nav",
|
|
72
|
+
"noscript",
|
|
73
|
+
"object",
|
|
74
|
+
"ol",
|
|
75
|
+
"optgroup",
|
|
76
|
+
"option",
|
|
77
|
+
"output",
|
|
78
|
+
"p",
|
|
79
|
+
"param",
|
|
80
|
+
"picture",
|
|
81
|
+
"pre",
|
|
82
|
+
"progress",
|
|
83
|
+
"q",
|
|
84
|
+
"rp",
|
|
85
|
+
"rt",
|
|
86
|
+
"ruby",
|
|
87
|
+
"s",
|
|
88
|
+
"samp",
|
|
89
|
+
"script",
|
|
90
|
+
"section",
|
|
91
|
+
"select",
|
|
92
|
+
"small",
|
|
93
|
+
"source",
|
|
94
|
+
"span",
|
|
95
|
+
"strong",
|
|
96
|
+
"style",
|
|
97
|
+
"sub",
|
|
98
|
+
"summary",
|
|
99
|
+
"sup",
|
|
100
|
+
"table",
|
|
101
|
+
"tbody",
|
|
102
|
+
"td",
|
|
103
|
+
"template",
|
|
104
|
+
"textarea",
|
|
105
|
+
"tfoot",
|
|
106
|
+
"th",
|
|
107
|
+
"thead",
|
|
108
|
+
"time",
|
|
109
|
+
"title",
|
|
110
|
+
"tr",
|
|
111
|
+
"track",
|
|
112
|
+
"u",
|
|
113
|
+
"ul",
|
|
114
|
+
"var",
|
|
115
|
+
"video",
|
|
116
|
+
"wbr"
|
|
117
|
+
];
|
|
118
|
+
export {
|
|
119
|
+
MDX_NODE_TYPES,
|
|
120
|
+
htmlTags,
|
|
121
|
+
isMdastHTMLNode
|
|
122
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { $createGenericHTMLNode } from "./GenericHTMLNode.js";
|
|
2
|
+
import { isMdastHTMLNode } from "./MdastHTMLNode.js";
|
|
3
|
+
const MdastHTMLVisitor = {
|
|
4
|
+
testNode: isMdastHTMLNode,
|
|
5
|
+
visitNode: function({ mdastNode, actions }) {
|
|
6
|
+
actions.addAndStepInto($createGenericHTMLNode(mdastNode.name, mdastNode.type, mdastNode.attributes));
|
|
7
|
+
},
|
|
8
|
+
priority: -100
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
MdastHTMLVisitor
|
|
12
|
+
};
|
|
@@ -12,6 +12,7 @@ import type { SystemSpec, Realm, PluginConstructor, TypedRealm, ValueForKey, Sys
|
|
|
12
12
|
import { MdastImportVisitor } from '../../importMarkdownToLexical';
|
|
13
13
|
import type { JsxComponentDescriptor } from '../jsx';
|
|
14
14
|
import { type IconKey } from './Icon';
|
|
15
|
+
export * from './GenericHTMLNode';
|
|
15
16
|
/** @internal */
|
|
16
17
|
export type EditorSubscription = (activeEditor: LexicalEditor) => () => void;
|
|
17
18
|
/** @internal */
|
|
@@ -511,4 +512,3 @@ corePluginHooks: {
|
|
|
511
512
|
iconComponentFor: RealmNode<(name: IconKey) => React.ReactNode>;
|
|
512
513
|
}, K_2>) => void;
|
|
513
514
|
};
|
|
514
|
-
export {};
|
|
@@ -18,6 +18,12 @@ import { SharedHistoryPlugin } from "./SharedHistoryPlugin.js";
|
|
|
18
18
|
import { noop } from "../../utils/fp.js";
|
|
19
19
|
import { controlOrMeta } from "../../utils/detectMac.js";
|
|
20
20
|
import { MdastBreakVisitor } from "./MdastBreakVisitor.js";
|
|
21
|
+
import { mdxJsxFromMarkdown, mdxJsxToMarkdown } from "mdast-util-mdx-jsx";
|
|
22
|
+
import { mdxJsx } from "micromark-extension-mdx-jsx";
|
|
23
|
+
import { MdastHTMLVisitor } from "./MdastHTMLVisitor.js";
|
|
24
|
+
import { GenericHTMLNode } from "./GenericHTMLNode.js";
|
|
25
|
+
import { $createGenericHTMLNode, $isGenericHTMLNode } from "./GenericHTMLNode.js";
|
|
26
|
+
import { LexicalGenericHTMLVisitor } from "./LexicalGenericHTMLNodeVisitor.js";
|
|
21
27
|
import { system } from "../../gurx/realmFactory.js";
|
|
22
28
|
import { realmPlugin } from "../../gurx/react.js";
|
|
23
29
|
const NESTED_EDITOR_UPDATED_COMMAND = createCommand("NESTED_EDITOR_UPDATED_COMMAND");
|
|
@@ -400,22 +406,31 @@ const [
|
|
|
400
406
|
init(realm, params) {
|
|
401
407
|
realm.pubKey("initialMarkdown", params.initialMarkdown.trim());
|
|
402
408
|
realm.pubKey("iconComponentFor", params.iconComponentFor);
|
|
409
|
+
realm.pubKey("addMdastExtension", mdxJsxFromMarkdown());
|
|
410
|
+
realm.pubKey("addSyntaxExtension", mdxJsx());
|
|
411
|
+
realm.pubKey("addToMarkdownExtension", mdxJsxToMarkdown());
|
|
403
412
|
realm.pubKey("addImportVisitor", MdastRootVisitor);
|
|
404
413
|
realm.pubKey("addImportVisitor", MdastParagraphVisitor);
|
|
405
414
|
realm.pubKey("addImportVisitor", MdastTextVisitor);
|
|
406
415
|
realm.pubKey("addImportVisitor", MdastFormattingVisitor);
|
|
407
416
|
realm.pubKey("addImportVisitor", MdastInlineCodeVisitor);
|
|
408
417
|
realm.pubKey("addImportVisitor", MdastBreakVisitor);
|
|
418
|
+
realm.pubKey("addImportVisitor", MdastHTMLVisitor);
|
|
409
419
|
realm.pubKey("addLexicalNode", ParagraphNode);
|
|
410
420
|
realm.pubKey("addLexicalNode", TextNode);
|
|
421
|
+
realm.pubKey("addLexicalNode", GenericHTMLNode);
|
|
411
422
|
realm.pubKey("addExportVisitor", LexicalRootVisitor);
|
|
412
423
|
realm.pubKey("addExportVisitor", LexicalParagraphVisitor);
|
|
413
424
|
realm.pubKey("addExportVisitor", LexicalTextVisitor);
|
|
414
425
|
realm.pubKey("addExportVisitor", LexicalLinebreakVisitor);
|
|
426
|
+
realm.pubKey("addExportVisitor", LexicalGenericHTMLVisitor);
|
|
415
427
|
realm.pubKey("addComposerChild", SharedHistoryPlugin);
|
|
416
428
|
}
|
|
417
429
|
});
|
|
418
430
|
export {
|
|
431
|
+
$createGenericHTMLNode,
|
|
432
|
+
$isGenericHTMLNode,
|
|
433
|
+
GenericHTMLNode,
|
|
419
434
|
NESTED_EDITOR_UPDATED_COMMAND,
|
|
420
435
|
corePlugin,
|
|
421
436
|
corePluginHooks,
|
|
@@ -6,7 +6,13 @@ import { basicSetup } from "codemirror";
|
|
|
6
6
|
import React__default from "react";
|
|
7
7
|
import { diffSourcePluginHooks } from "./index.js";
|
|
8
8
|
import { corePluginHooks } from "../core/index.js";
|
|
9
|
-
const COMMON_STATE_CONFIG_EXTENSIONS = [
|
|
9
|
+
const COMMON_STATE_CONFIG_EXTENSIONS = [
|
|
10
|
+
basicSetup,
|
|
11
|
+
basicLight,
|
|
12
|
+
markdown(),
|
|
13
|
+
lineNumbers(),
|
|
14
|
+
EditorView.lineWrapping
|
|
15
|
+
];
|
|
10
16
|
const SourceEditor = () => {
|
|
11
17
|
const [markdown2, readOnly] = corePluginHooks.useEmitterValues("markdown", "readOnly");
|
|
12
18
|
const [cmExtensions] = diffSourcePluginHooks.useEmitterValues("cmExtensions");
|
package/dist/style.css
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function mergeStyleAttributes(style1: string, style2: string): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function mergeStyleAttributes(style1, style2) {
|
|
2
|
+
const styleObject1 = styleToObject(style1);
|
|
3
|
+
const styleObject2 = styleToObject(style2);
|
|
4
|
+
const mergedStyleObject = { ...styleObject1, ...styleObject2 };
|
|
5
|
+
const mergedStyleString = objectToStyle(mergedStyleObject);
|
|
6
|
+
return mergedStyleString;
|
|
7
|
+
}
|
|
8
|
+
function styleToObject(style) {
|
|
9
|
+
const styleObject = {};
|
|
10
|
+
const stylePairs = style.split(";").filter((pair) => pair.trim() !== "");
|
|
11
|
+
stylePairs.forEach((pair) => {
|
|
12
|
+
const [key, value] = pair.split(":").map((part) => part.trim());
|
|
13
|
+
styleObject[key] = value;
|
|
14
|
+
});
|
|
15
|
+
return styleObject;
|
|
16
|
+
}
|
|
17
|
+
function objectToStyle(styleObject) {
|
|
18
|
+
return Object.entries(styleObject).map(([key, value]) => `${key}: ${value}`).join("; ");
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
mergeStyleAttributes
|
|
22
|
+
};
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"private": false,
|
|
10
10
|
"sideEffects": false,
|
|
11
11
|
"type": "module",
|
|
12
|
-
"version": "1.
|
|
12
|
+
"version": "1.11.0",
|
|
13
13
|
"description": "React component for rich text markdown editing",
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "vite build",
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
"micromark-extension-frontmatter": "1.1.0",
|
|
80
80
|
"micromark-extension-gfm-table": "^1.0.6",
|
|
81
81
|
"micromark-extension-gfm-task-list-item": "1.0.5",
|
|
82
|
+
"micromark-extension-mdx-jsx": "^1.0.5",
|
|
82
83
|
"micromark-extension-mdxjs": "1.0.1",
|
|
83
84
|
"react-hook-form": "^7.44.2",
|
|
84
85
|
"unidiff": "^1.0.2"
|