@llui/markdown-editor 0.2.13 → 0.3.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/editor.d.ts +7 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +66 -11
- package/dist/editor.js.map +1 -1
- package/dist/effects.d.ts +5 -4
- package/dist/effects.d.ts.map +1 -1
- package/dist/effects.js +11 -6
- package/dist/effects.js.map +1 -1
- package/dist/format.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/paste.d.ts.map +1 -1
- package/dist/paste.js +5 -0
- package/dist/paste.js.map +1 -1
- package/dist/plugins/_preview.js.map +1 -1
- package/dist/plugins/callout.d.ts.map +1 -1
- package/dist/plugins/callout.js +37 -45
- package/dist/plugins/callout.js.map +1 -1
- package/dist/plugins/context-menu.js.map +1 -1
- package/dist/plugins/core.js.map +1 -1
- package/dist/plugins/emoji.js.map +1 -1
- package/dist/plugins/floating-toolbar.js.map +1 -1
- package/dist/plugins/hr.d.ts.map +1 -1
- package/dist/plugins/hr.js +4 -7
- package/dist/plugins/hr.js.map +1 -1
- package/dist/plugins/image.d.ts.map +1 -1
- package/dist/plugins/image.js +28 -20
- package/dist/plugins/image.js.map +1 -1
- package/dist/plugins/inline.js.map +1 -1
- package/dist/plugins/link.d.ts.map +1 -1
- package/dist/plugins/link.js +16 -9
- package/dist/plugins/link.js.map +1 -1
- package/dist/plugins/math.d.ts.map +1 -1
- package/dist/plugins/math.js +25 -34
- package/dist/plugins/math.js.map +1 -1
- package/dist/plugins/mention.js.map +1 -1
- package/dist/plugins/mermaid.d.ts.map +1 -1
- package/dist/plugins/mermaid.js +25 -34
- package/dist/plugins/mermaid.js.map +1 -1
- package/dist/plugins/overlay.js.map +1 -1
- package/dist/plugins/single-block.js.map +1 -1
- package/dist/plugins/slash.js.map +1 -1
- package/dist/plugins/table.d.ts.map +1 -1
- package/dist/plugins/table.js +84 -19
- package/dist/plugins/table.js.map +1 -1
- package/dist/plugins/types.js.map +1 -1
- package/dist/plugins/ui.js.map +1 -1
- package/dist/security.d.ts +26 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +87 -0
- package/dist/security.js.map +1 -0
- package/dist/state.js.map +1 -1
- package/dist/styles/editor.css +0 -6
- package/dist/surfaces/link-dialog.js.map +1 -1
- package/dist/surfaces/toolbar.js.map +1 -1
- package/dist/theme.d.ts +2 -5
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +15 -11
- package/dist/theme.js.map +1 -1
- package/dist/transformers/gfm.d.ts +9 -1
- package/dist/transformers/gfm.d.ts.map +1 -1
- package/dist/transformers/gfm.js +9 -2
- package/dist/transformers/gfm.js.map +1 -1
- package/dist/transformers/registry.js.map +1 -1
- package/package.json +10 -8
- package/src/editor.ts +92 -11
- package/src/effects.ts +11 -7
- package/src/index.ts +3 -8
- package/src/paste.ts +5 -0
- package/src/plugins/callout.ts +44 -59
- package/src/plugins/hr.ts +4 -14
- package/src/plugins/image.ts +32 -29
- package/src/plugins/link.ts +20 -10
- package/src/plugins/math.ts +27 -41
- package/src/plugins/mermaid.ts +26 -45
- package/src/plugins/table.ts +94 -17
- package/src/security.ts +89 -0
- package/src/styles/editor.css +0 -6
- package/src/theme.ts +15 -11
- package/src/transformers/gfm.ts +10 -2
- package/dist/__llui_deps.json +0 -274
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type LexicalEditor, type LexicalNode } from 'lexical';
|
|
2
|
+
/** Schemes allowed for a hyperlink href. A click navigates, so this is the strict
|
|
3
|
+
* set — identical to the renderer's default (`http`/`https`/`mailto`/`tel`). */
|
|
4
|
+
export declare const LINK_PROTOCOLS: readonly string[];
|
|
5
|
+
/** Schemes allowed for an image `src`. Adds `data:` on top of the link set: a
|
|
6
|
+
* base64 image never executes when loaded through `<img>` (unlike a `data:`
|
|
7
|
+
* hyperlink, which can carry `text/html`), and inline data images are a
|
|
8
|
+
* first-class editor feature (paste / upload). */
|
|
9
|
+
export declare const IMAGE_PROTOCOLS: readonly string[];
|
|
10
|
+
/** Sanitize a hyperlink href. Returns the safe URL, or `null` when the scheme is
|
|
11
|
+
* not on {@link LINK_PROTOCOLS} (the link must then be dropped/unwrapped). */
|
|
12
|
+
export declare function sanitizeLinkUrl(url: string): string | null;
|
|
13
|
+
/** Sanitize an image `src`. Returns the safe URL, or `null` when the scheme is
|
|
14
|
+
* not on {@link IMAGE_PROTOCOLS} (the image must then be dropped). */
|
|
15
|
+
export declare function sanitizeImageUrl(url: string): string | null;
|
|
16
|
+
/** Walk `node` (depth-first) neutralizing every unsafe `LinkNode` beneath it. Must
|
|
17
|
+
* run inside an `editor.update`. Use right after importing untrusted markdown
|
|
18
|
+
* (e.g. paste) into a detached scratch tree, before it reaches the live document. */
|
|
19
|
+
export declare function $sanitizeLinkNodes(node: LexicalNode): void;
|
|
20
|
+
/** Register a global `LinkNode` transform that keeps every link's href on the
|
|
21
|
+
* allowlist — the single choke point covering the link dialog, pasted/imported
|
|
22
|
+
* markdown, AND the typed `[text](url)` shortcut. Returns a disposer. A no-op when
|
|
23
|
+
* `LinkNode` isn't registered on the editor (no links are possible then, e.g. the
|
|
24
|
+
* single-block preset), since `registerNodeTransform` requires a registered node. */
|
|
25
|
+
export declare function registerLinkSanitizer(editor: LexicalEditor): () => void;
|
|
26
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAA;AAE9E;gFACgF;AAChF,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAA4B,CAAA;AAExE;;;kDAGkD;AAClD,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAyC,CAAA;AAEtF;8EAC8E;AAC9E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1D;AAED;sEACsE;AACtE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE3D;AAkBD;;qFAEqF;AACrF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAY1D;AAED;;;;qFAIqF;AACrF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,IAAI,CAKvE"}
|
package/dist/security.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// URL-scheme policy for the editor.
|
|
2
|
+
//
|
|
3
|
+
// The read-only renderer (`@llui/markdown`) already refuses dangerous link/image
|
|
4
|
+
// schemes (`javascript:`, `vbscript:`, `data:text/html`, …) via `sanitizeUrl`.
|
|
5
|
+
// The EDITOR has additional ingress points that must enforce the SAME policy or
|
|
6
|
+
// an attacker-authored document becomes live/clickable inside it:
|
|
7
|
+
//
|
|
8
|
+
// 1. link commit — `$toggleLink` on a raw, user-typed URL,
|
|
9
|
+
// 2. image src — an `` inserted or imported,
|
|
10
|
+
// 3. markdown paste/import — `$convertFromMarkdownString` builds real
|
|
11
|
+
// `LinkNode`s (and image decorator nodes) from untrusted text,
|
|
12
|
+
// 4. the typed `[x](url)` markdown shortcut — builds a `LinkNode` live.
|
|
13
|
+
//
|
|
14
|
+
// Links are additionally guarded by a global `LinkNode` node transform
|
|
15
|
+
// ({@link registerLinkSanitizer}) so #1/#3/#4 all funnel through one enforcement
|
|
16
|
+
// point. Rather than hand-roll (and drift from) a second allowlist, this module
|
|
17
|
+
// reuses `@llui/markdown`'s exact `sanitizeUrl` and only differs in the
|
|
18
|
+
// allowed-scheme SET per surface — which is data, not a divergent implementation.
|
|
19
|
+
import { sanitizeUrl, defaultAllowedProtocols } from '@llui/markdown/security';
|
|
20
|
+
import { $isLinkNode, LinkNode } from '@lexical/link';
|
|
21
|
+
import { $isElementNode } from 'lexical';
|
|
22
|
+
/** Schemes allowed for a hyperlink href. A click navigates, so this is the strict
|
|
23
|
+
* set — identical to the renderer's default (`http`/`https`/`mailto`/`tel`). */
|
|
24
|
+
export const LINK_PROTOCOLS = defaultAllowedProtocols;
|
|
25
|
+
/** Schemes allowed for an image `src`. Adds `data:` on top of the link set: a
|
|
26
|
+
* base64 image never executes when loaded through `<img>` (unlike a `data:`
|
|
27
|
+
* hyperlink, which can carry `text/html`), and inline data images are a
|
|
28
|
+
* first-class editor feature (paste / upload). */
|
|
29
|
+
export const IMAGE_PROTOCOLS = [...defaultAllowedProtocols, 'data'];
|
|
30
|
+
/** Sanitize a hyperlink href. Returns the safe URL, or `null` when the scheme is
|
|
31
|
+
* not on {@link LINK_PROTOCOLS} (the link must then be dropped/unwrapped). */
|
|
32
|
+
export function sanitizeLinkUrl(url) {
|
|
33
|
+
return sanitizeUrl(url, LINK_PROTOCOLS);
|
|
34
|
+
}
|
|
35
|
+
/** Sanitize an image `src`. Returns the safe URL, or `null` when the scheme is
|
|
36
|
+
* not on {@link IMAGE_PROTOCOLS} (the image must then be dropped). */
|
|
37
|
+
export function sanitizeImageUrl(url) {
|
|
38
|
+
return sanitizeUrl(url, IMAGE_PROTOCOLS);
|
|
39
|
+
}
|
|
40
|
+
/** Neutralize one `LinkNode` in place (must run inside `editor.update`): rewrite a
|
|
41
|
+
* merely-normalized href, or — when the scheme is disallowed — UNWRAP the link so
|
|
42
|
+
* its visible text survives but the clickable `javascript:`/`data:` payload is
|
|
43
|
+
* gone. Returns true if the node was unwrapped/removed. */
|
|
44
|
+
function neutralizeLink(node) {
|
|
45
|
+
const url = node.getURL();
|
|
46
|
+
const safe = sanitizeLinkUrl(url);
|
|
47
|
+
if (safe === null) {
|
|
48
|
+
for (const child of node.getChildren())
|
|
49
|
+
node.insertBefore(child);
|
|
50
|
+
node.remove();
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (safe !== url)
|
|
54
|
+
node.setURL(safe);
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/** Walk `node` (depth-first) neutralizing every unsafe `LinkNode` beneath it. Must
|
|
58
|
+
* run inside an `editor.update`. Use right after importing untrusted markdown
|
|
59
|
+
* (e.g. paste) into a detached scratch tree, before it reaches the live document. */
|
|
60
|
+
export function $sanitizeLinkNodes(node) {
|
|
61
|
+
if ($isLinkNode(node)) {
|
|
62
|
+
// Snapshot children first: unwrapping lifts them out of the (removed) link,
|
|
63
|
+
// so recurse the snapshot to catch a defensively-nested inner link either way.
|
|
64
|
+
const children = node.getChildren();
|
|
65
|
+
neutralizeLink(node);
|
|
66
|
+
for (const child of children)
|
|
67
|
+
$sanitizeLinkNodes(child);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if ($isElementNode(node)) {
|
|
71
|
+
for (const child of node.getChildren())
|
|
72
|
+
$sanitizeLinkNodes(child);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Register a global `LinkNode` transform that keeps every link's href on the
|
|
76
|
+
* allowlist — the single choke point covering the link dialog, pasted/imported
|
|
77
|
+
* markdown, AND the typed `[text](url)` shortcut. Returns a disposer. A no-op when
|
|
78
|
+
* `LinkNode` isn't registered on the editor (no links are possible then, e.g. the
|
|
79
|
+
* single-block preset), since `registerNodeTransform` requires a registered node. */
|
|
80
|
+
export function registerLinkSanitizer(editor) {
|
|
81
|
+
if (!editor.hasNodes([LinkNode]))
|
|
82
|
+
return () => { };
|
|
83
|
+
return editor.registerNodeTransform(LinkNode, (node) => {
|
|
84
|
+
neutralizeLink(node);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,gFAAgF;AAChF,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,wEAAwE;AACxE,oEAAoE;AACpE,2EAA2E;AAC3E,EAAE;AACF,uEAAuE;AACvE,iFAAiF;AACjF,gFAAgF;AAChF,wEAAwE;AACxE,kFAAkF;AAElF,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,cAAc,EAAwC,MAAM,SAAS,CAAA;AAE9E;gFACgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAsB,uBAAuB,CAAA;AAExE;;;kDAGkD;AAClD,MAAM,CAAC,MAAM,eAAe,GAAsB,CAAC,GAAG,uBAAuB,EAAE,MAAM,CAAC,CAAA;AAEtF;8EAC8E;AAC9E,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,OAAO,WAAW,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;AACzC,CAAC;AAED;sEACsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;AAC1C,CAAC;AAED;;;2DAG2D;AAC3D,SAAS,cAAc,CAAC,IAAc;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAA;IACzB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAChE,IAAI,CAAC,MAAM,EAAE,CAAA;QACb,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,KAAK,GAAG;QAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACnC,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;qFAEqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,IAAiB;IAClD,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,4EAA4E;QAC5E,+EAA+E;QAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QACnC,cAAc,CAAC,IAAI,CAAC,CAAA;QACpB,KAAK,MAAM,KAAK,IAAI,QAAQ;YAAE,kBAAkB,CAAC,KAAK,CAAC,CAAA;QACvD,OAAM;IACR,CAAC;IACD,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE;YAAE,kBAAkB,CAAC,KAAK,CAAC,CAAA;IACnE,CAAC;AACH,CAAC;AAED;;;;qFAIqF;AACrF,MAAM,UAAU,qBAAqB,CAAC,MAAqB;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;IACjD,OAAO,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;QACrD,cAAc,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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","sourcesContent":["// The editor's TEA state, messages, effects, and pure reducer. Lexical owns the\n// live document; this state holds JSON-serializable mirrors/derivations only, so\n// `update` stays pure and DOM-free (fully unit-testable).\n\nimport type { Alignment } from '@llui/lexical'\n\n/** The block kind at the selection — base rich-text kinds plus list/code,\n * resolved by the markdown layer. */\nexport type BlockType =\n | 'paragraph'\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n | 'quote'\n | 'code'\n | 'bullet'\n | 'number'\n | 'check'\n | 'other'\n\n/** The toolbar-facing format surface at the current selection (all primitives). */\nexport interface FormatState {\n bold: boolean\n italic: boolean\n strikethrough: boolean\n code: boolean\n link: boolean\n blockType: BlockType\n alignment: Alignment\n canUndo: boolean\n canRedo: boolean\n}\n\nexport const EMPTY_FORMAT: FormatState = {\n bold: false,\n italic: false,\n strikethrough: false,\n code: false,\n link: false,\n blockType: 'paragraph',\n alignment: null,\n canUndo: false,\n canRedo: false,\n}\n\n/** Which floating surface is currently open. */\nexport type OverlayKind = 'none' | 'floating' | 'slash' | 'context' | 'link'\n\n/** Live collaborative-session status (mirror of the CRDT provider state).\n * `enabled` is false unless the editor was created with a `collab` factory. */\nexport interface CollabStatus {\n enabled: boolean\n connected: boolean\n synced: boolean\n /** Remote peers currently present (excludes this client). */\n peers: number\n}\n\nexport const COLLAB_OFF: CollabStatus = {\n enabled: false,\n connected: false,\n synced: false,\n peers: 0,\n}\n\nexport interface EditorState {\n /** Last serialized markdown (mirror of the live document). */\n value: string\n format: FormatState\n wordCount: number\n charCount: number\n ui: {\n activeOverlay: OverlayKind\n slashQuery: string\n menu: { x: number; y: number }\n }\n /** Per-plugin UI state slices, keyed by plugin name (see {@link PluginUI}). */\n plugins: Record<string, unknown>\n dirty: boolean\n readonly: boolean\n /** Collaborative-session status (always present; inert unless `collab` set). */\n collab: CollabStatus\n}\n\nexport type EditorMsg =\n | { type: 'markdownChanged'; value: string }\n | { type: 'formatChanged'; format: FormatState; wordCount: number; charCount: number }\n | { type: 'runCommand'; id: string }\n | { type: 'setValue'; value: string }\n | { type: 'openOverlay'; overlay: OverlayKind; x?: number; y?: number }\n | { type: 'closeOverlay' }\n | { type: 'slashQuery'; query: string }\n | { type: 'setReadOnly'; readonly: boolean }\n | { type: 'collabStatus'; connected: boolean }\n | { type: 'collabSync'; synced: boolean }\n | { type: 'collabPeers'; peers: number }\n /** Route a message to a plugin's UI reducer (see {@link PluginUI}). */\n | { type: 'plugin'; name: string; msg: unknown }\n\n/** The subset of messages a plugin may emit through its `PluginContext` (e.g. a\n * `register` listener routing an editor event into its own plugin UI). */\nexport type EditorOutMsg = Extract<\n EditorMsg,\n { type: 'openOverlay' | 'closeOverlay' | 'slashQuery' | 'plugin' }\n>\n\nexport type EditorEffect =\n | { type: 'execCommand'; id: string }\n | { type: 'applyValue'; value: string }\n | { type: 'emitChange'; value: string }\n | { type: 'emitFormat'; format: FormatState }\n /** An effect produced by a plugin's UI reducer (see {@link PluginUI}). */\n | { type: 'pluginEffect'; name: string; effect: unknown }\n\nexport interface InitOptions {\n value: string\n readonly: boolean\n /** Whether a collaborative session is wired (drives `collab.enabled`). */\n collab?: boolean\n}\n\nexport function init(opts: InitOptions): [EditorState, EditorEffect[]] {\n const wordCount = countWords(opts.value)\n return [\n {\n value: opts.value,\n format: EMPTY_FORMAT,\n wordCount,\n charCount: opts.value.length,\n ui: { activeOverlay: 'none', slashQuery: '', menu: { x: 0, y: 0 } },\n plugins: {},\n dirty: false,\n readonly: opts.readonly,\n collab: { ...COLLAB_OFF, enabled: opts.collab ?? false },\n },\n [],\n ]\n}\n\nexport function update(state: EditorState, msg: EditorMsg): [EditorState, EditorEffect[]] {\n switch (msg.type) {\n case 'markdownChanged': {\n // Idempotent: re-emitting the current value is a no-op (echo safety).\n if (msg.value === state.value) return [state, []]\n return [\n { ...state, value: msg.value, dirty: true },\n [{ type: 'emitChange', value: msg.value }],\n ]\n }\n case 'formatChanged': {\n return [\n { ...state, format: msg.format, wordCount: msg.wordCount, charCount: msg.charCount },\n [{ type: 'emitFormat', format: msg.format }],\n ]\n }\n case 'runCommand': {\n return [state, [{ type: 'execCommand', id: msg.id }]]\n }\n case 'setValue': {\n // External markdown push (via the component handle). Idempotent; does not\n // re-emit onChange (the consumer already owns this value).\n if (msg.value === state.value) return [state, []]\n return [\n { ...state, value: msg.value, dirty: true },\n [{ type: 'applyValue', value: msg.value }],\n ]\n }\n case 'openOverlay': {\n return [\n {\n ...state,\n ui: {\n ...state.ui,\n activeOverlay: msg.overlay,\n slashQuery: msg.overlay === 'slash' ? '' : state.ui.slashQuery,\n menu: { x: msg.x ?? state.ui.menu.x, y: msg.y ?? state.ui.menu.y },\n },\n },\n [],\n ]\n }\n case 'closeOverlay': {\n if (state.ui.activeOverlay === 'none') return [state, []]\n return [{ ...state, ui: { ...state.ui, activeOverlay: 'none', slashQuery: '' } }, []]\n }\n case 'slashQuery': {\n return [{ ...state, ui: { ...state.ui, slashQuery: msg.query } }, []]\n }\n case 'setReadOnly': {\n if (state.readonly === msg.readonly) return [state, []]\n return [{ ...state, readonly: msg.readonly }, []]\n }\n case 'collabStatus': {\n if (state.collab.connected === msg.connected) return [state, []]\n return [{ ...state, collab: { ...state.collab, connected: msg.connected } }, []]\n }\n case 'collabSync': {\n if (state.collab.synced === msg.synced) return [state, []]\n return [{ ...state, collab: { ...state.collab, synced: msg.synced } }, []]\n }\n case 'collabPeers': {\n if (state.collab.peers === msg.peers) return [state, []]\n return [{ ...state, collab: { ...state.collab, peers: msg.peers } }, []]\n }\n case 'plugin': {\n // Plugin messages are routed by the host's composed reducer (it holds the\n // plugin registry); the pure core reducer treats them as a no-op.\n return [state, []]\n }\n }\n}\n\n/** Count whitespace-delimited words (shared by init and the format handler). */\nexport function countWords(text: string): number {\n const trimmed = text.trim()\n return trimmed === '' ? 0 : trimmed.split(/\\s+/).length\n}\n"]}
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/styles/editor.css
CHANGED
|
@@ -83,12 +83,6 @@
|
|
|
83
83
|
[data-lexical-editor] .md-strikethrough {
|
|
84
84
|
text-decoration: line-through;
|
|
85
85
|
}
|
|
86
|
-
[data-lexical-editor] .md-underline {
|
|
87
|
-
text-decoration: underline;
|
|
88
|
-
}
|
|
89
|
-
[data-lexical-editor] .md-underline-strikethrough {
|
|
90
|
-
text-decoration: underline line-through;
|
|
91
|
-
}
|
|
92
86
|
|
|
93
87
|
/* Task-list items (li[role="checkbox"]) with a clickable checkbox. */
|
|
94
88
|
[data-lexical-editor] li[role='checkbox'] {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-dialog.js","sourceRoot":"","sources":["../../src/surfaces/link-dialog.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,+EAA+E;AAC/E,iFAAiF;AACjF,0BAA0B;AAE1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAA+B,MAAM,WAAW,CAAA;AACjF,OAAO,EACL,OAAO,IAAI,aAAa,EACxB,OAAO,IAAI,aAAa,GAGzB,MAAM,yBAAyB,CAAA;AAiBhC,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,IAAuB;IAChD,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE;QACtD,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,gBAAgB;QAC/B,UAAU,EAAE,QAAQ;KACrB,CAAC,CAAA;IAEF,OAAO,aAAa,CAAC;QACnB,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,IAAI,EAAE,IAAI,CAAC,QAAQ;QACnB,KAAK;QACL,aAAa,EAAE,IAAI;QACnB,mBAAmB,EAAE,IAAI;QACzB,OAAO,EAAE,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;gBAC/C,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBACvE,KAAK,CAAC;oBACJ,cAAc,EAAE,OAAO;oBACvB,IAAI,EAAE,KAAK;oBACX,WAAW,EAAE,qBAAqB;oBAClC,KAAK,EAAE,IAAI,CAAC,GAAG;oBACf,OAAO,EAAE,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAE,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;oBACzE,SAAS,EAAE,CAAC,CAAgB,EAAE,EAAE;wBAC9B,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;4BACtB,CAAC,CAAC,cAAc,EAAE,CAAA;4BAClB,IAAI,CAAC,QAAQ,EAAE,CAAA;wBACjB,CAAC;oBACH,CAAC;iBACF,CAAC;gBACF,GAAG,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE;oBACjC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAC7E,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE;wBAClF,IAAI,CAAC,OAAO,CAAC;qBACd,CAAC;iBACH,CAAC;aACH,CAAC;SACH;KACF,CAAC,CAAA;AACJ,CAAC"
|
|
1
|
+
{"version":3,"file":"link-dialog.js","sourceRoot":"","sources":["../../src/surfaces/link-dialog.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,+EAA+E;AAC/E,iFAAiF;AACjF,0BAA0B;AAE1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAA+B,MAAM,WAAW,CAAA;AACjF,OAAO,EACL,OAAO,IAAI,aAAa,EACxB,OAAO,IAAI,aAAa,GAGzB,MAAM,yBAAyB,CAAA;AAiBhC,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,IAAuB;IAChD,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE;QACtD,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,gBAAgB;QAC/B,UAAU,EAAE,QAAQ;KACrB,CAAC,CAAA;IAEF,OAAO,aAAa,CAAC;QACnB,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,IAAI,EAAE,IAAI,CAAC,QAAQ;QACnB,KAAK;QACL,aAAa,EAAE,IAAI;QACnB,mBAAmB,EAAE,IAAI;QACzB,OAAO,EAAE,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;gBAC/C,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBACvE,KAAK,CAAC;oBACJ,cAAc,EAAE,OAAO;oBACvB,IAAI,EAAE,KAAK;oBACX,WAAW,EAAE,qBAAqB;oBAClC,KAAK,EAAE,IAAI,CAAC,GAAG;oBACf,OAAO,EAAE,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAE,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;oBACzE,SAAS,EAAE,CAAC,CAAgB,EAAE,EAAE;wBAC9B,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;4BACtB,CAAC,CAAC,cAAc,EAAE,CAAA;4BAClB,IAAI,CAAC,QAAQ,EAAE,CAAA;wBACjB,CAAC;oBACH,CAAC;iBACF,CAAC;gBACF,GAAG,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE;oBACjC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAC7E,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE;wBAClF,IAAI,CAAC,OAAO,CAAC;qBACd,CAAC;iBACH,CAAC;aACH,CAAC;SACH;KACF,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/surfaces/toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["// Toolbar surface. `connectToolbar` returns a parts bag (the @llui/components\n// idiom) driven reactively by the format signal; `toolbar` is a ready-made\n// grouped toolbar Mountable for consumers who don't want to hand-render buttons.\n\nimport {\n button,\n div,\n option,\n select,\n span,\n text,\n tagSend,\n unsafeHtml,\n type Mountable,\n type Send,\n type Signal,\n} from '@llui/dom'\nimport type { CommandItem } from '../plugins/types.js'\nimport type { CollabStatus, EditorMsg, FormatState } from '../state.js'\n\nexport interface ToolbarItemParts {\n type: 'button'\n 'data-scope': 'md-toolbar'\n 'data-part': 'item'\n 'data-id': string\n 'aria-label': string\n title: string\n 'aria-pressed': Signal<'true' | 'false'>\n 'aria-disabled': Signal<'true' | undefined>\n disabled: Signal<boolean>\n 'data-active': Signal<'' | undefined>\n onClick: (e: MouseEvent) => void\n}\n\nexport interface ToolbarParts {\n root: {\n role: 'toolbar'\n 'aria-label': string\n 'data-scope': 'md-toolbar'\n 'data-part': 'root'\n }\n item: (id: string) => ToolbarItemParts\n}\n\n/** Build reactive toolbar parts from the format signal. Spread `item(id)` onto a\n * `<button>`; `aria-pressed` / `data-active` / `disabled` track the format. */\nexport function connectToolbar(\n format: Signal<FormatState>,\n send: Send<EditorMsg>,\n items: readonly CommandItem[],\n): ToolbarParts {\n const byId = new Map(items.map((i) => [i.id, i]))\n return {\n root: {\n role: 'toolbar',\n 'aria-label': 'Formatting',\n 'data-scope': 'md-toolbar',\n 'data-part': 'root',\n },\n item: (id) => {\n const item = byId.get(id)\n const label = item?.label ?? id\n return {\n type: 'button',\n 'data-scope': 'md-toolbar',\n 'data-part': 'item',\n 'data-id': id,\n 'aria-label': label,\n title: label,\n 'aria-pressed': format.map((f) => (item?.isActive?.(f) ? 'true' : 'false')),\n 'aria-disabled': format.map((f) => (item?.isDisabled?.(f) ? 'true' : undefined)),\n disabled: format.map((f) => item?.isDisabled?.(f) ?? false),\n 'data-active': format.map((f) => (item?.isActive?.(f) ? '' : undefined)),\n onClick: tagSend(send, ['runCommand'], () => send({ type: 'runCommand', id })),\n }\n },\n }\n}\n\n/** Inline SVG icon (monochrome, inherits `currentColor`) used where a glyph\n * reads poorly. A glyph string starting with `<svg` is rendered as markup. */\nconst LINK_ICON =\n '<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9.5 13.5a3.5 3.5 0 0 0 5 0l3-3a3.5 3.5 0 1 0-5-5l-1 1\"/><path d=\"M14.5 10.5a3.5 3.5 0 0 0-5 0l-3 3a3.5 3.5 0 1 0 5 5l1-1\"/></svg>'\n\nconst IMAGE_ICON =\n '<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"/><circle cx=\"9\" cy=\"9.5\" r=\"1.6\"/><path d=\"m4 18 5-5 4 4 3-3 4 4\"/></svg>'\n\n/** Compact glyphs so the default toolbar reads as a real toolbar without icon\n * assets. SVG strings render as icons; everything else as text. Override via\n * `ToolbarOptions.glyphs`. */\nexport const DEFAULT_GLYPHS: Readonly<Record<string, string>> = {\n bold: 'B',\n italic: 'I',\n strikethrough: 'S',\n code: '</>',\n link: LINK_ICON,\n image: IMAGE_ICON,\n hr: '—',\n table: '▦',\n paragraph: '¶',\n h1: 'H1',\n h2: 'H2',\n h3: 'H3',\n quote: '❝',\n codeBlock: '{ }',\n bulletList: '•',\n numberList: '1.',\n checkList: '☑',\n undo: '↺',\n redo: '↻',\n}\n\nconst GROUP_ORDER = ['inline', 'block', 'list', 'insert', 'history']\n\nfunction groupItems(items: readonly CommandItem[]): string[][] {\n const groups = new Map<string, string[]>()\n for (const item of items) {\n const key = item.group ?? 'other'\n const list = groups.get(key) ?? []\n list.push(item.id)\n groups.set(key, list)\n }\n const ordered: string[][] = []\n for (const key of GROUP_ORDER) {\n const list = groups.get(key)\n if (list) ordered.push(list)\n }\n for (const [key, list] of groups) {\n if (!GROUP_ORDER.includes(key)) ordered.push(list)\n }\n return ordered\n}\n\nexport interface ToolbarOptions {\n format: Signal<FormatState>\n send: Send<EditorMsg>\n items: readonly CommandItem[]\n /** Explicit grouped layout of ids; defaults to grouping by `item.group`. */\n groups?: readonly (readonly string[])[]\n /** Glyph overrides (id → text/emoji). Merged over {@link DEFAULT_GLYPHS}. */\n glyphs?: Readonly<Record<string, string>>\n /** Render the `block` group as a `<select>` dropdown instead of buttons\n * (default true). */\n blockSelect?: boolean\n /** Collaborative-session status. When supplied AND `enabled`, the toolbar\n * appends a presence indicator (connection dot + live peer count). */\n collab?: Signal<CollabStatus>\n 'aria-label'?: string\n}\n\n/** Connection/presence indicator for a collaborative session. */\nfunction presenceIndicator(collab: Signal<CollabStatus>): Mountable {\n const statusOf = (c: CollabStatus): string =>\n c.connected ? (c.synced ? 'synced' : 'connecting') : 'offline'\n return div({ 'data-scope': 'md-toolbar', 'data-part': 'presence' }, [\n span({\n 'data-part': 'presence-status',\n 'data-status': collab.map(statusOf),\n 'aria-hidden': 'true',\n title: collab.map(statusOf),\n }),\n span(\n {\n 'data-part': 'presence-peers',\n role: 'status',\n 'aria-live': 'polite',\n },\n [text(collab.map((c) => (c.peers === 0 ? 'Only you' : `${c.peers + 1} editing`)))],\n ),\n ])\n}\n\n/** Render the `block` group as a native `<select>` of block types. */\nfunction blockTypeSelect(\n format: Signal<FormatState>,\n send: Send<EditorMsg>,\n blockItems: readonly CommandItem[],\n): Mountable {\n return select(\n {\n 'data-scope': 'md-toolbar',\n 'data-part': 'block-select',\n 'aria-label': 'Block type',\n value: format.map((f) => blockItems.find((i) => i.isActive?.(f))?.id ?? ''),\n onChange: (e: Event) => {\n const id = (e.currentTarget as HTMLSelectElement).value\n if (id) send({ type: 'runCommand', id })\n },\n },\n [\n option({ value: '', hidden: true }, [text('—')]),\n ...blockItems.map((i) => option({ value: i.id }, [text(i.label)])),\n ],\n )\n}\n\n/** A ready-made grouped toolbar. Items not surfaced to `'toolbar'` are dropped. */\nexport function toolbar(opts: ToolbarOptions): Mountable {\n const surfaceItems = opts.items.filter((i) => i.surfaces?.includes('toolbar') ?? true)\n const byId = new Map(surfaceItems.map((i) => [i.id, i]))\n const parts = connectToolbar(opts.format, opts.send, surfaceItems)\n const glyphs = { ...DEFAULT_GLYPHS, ...(opts.glyphs ?? {}) }\n\n const useBlockSelect = opts.blockSelect !== false && !opts.groups\n const blockItems = useBlockSelect ? surfaceItems.filter((i) => i.group === 'block') : []\n const buttonItems = useBlockSelect\n ? surfaceItems.filter((i) => i.group !== 'block')\n : surfaceItems\n const groups = opts.groups ?? groupItems(buttonItems)\n\n const children: Mountable[] = []\n if (blockItems.length > 0) {\n children.push(\n div({ 'data-scope': 'md-toolbar', 'data-part': 'group' }, [\n blockTypeSelect(opts.format, opts.send, blockItems),\n ]),\n )\n }\n for (const ids of groups) {\n const present = ids.filter((id) => byId.has(id))\n if (present.length === 0) continue\n children.push(\n div(\n { 'data-scope': 'md-toolbar', 'data-part': 'group' },\n present.map((id) => {\n const item = byId.get(id)!\n const glyph = glyphs[id] ?? item.label\n const glyphNode = glyph.trimStart().startsWith('<svg') ? unsafeHtml(glyph) : text(glyph)\n return button({ ...parts.item(id) }, [\n span({ 'data-part': 'glyph', 'aria-hidden': 'true' }, [glyphNode]),\n ])\n }),\n ),\n )\n }\n\n // Presence indicator (constant `enabled` after init, so a one-shot peek is safe).\n if (opts.collab && opts.collab.peek().enabled) {\n children.push(presenceIndicator(opts.collab))\n }\n\n return div(\n { ...parts.root, ...(opts['aria-label'] ? { 'aria-label': opts['aria-label'] } : {}) },\n children,\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/surfaces/toolbar.ts"],"names":[],"mappings":"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"}
|
package/dist/theme.d.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import type { EditorThemeClasses } from 'lexical';
|
|
2
2
|
export declare const STRIKETHROUGH_CLASS = "md-strikethrough";
|
|
3
|
-
export declare const UNDERLINE_CLASS = "md-underline";
|
|
4
|
-
export declare const UNDERLINE_STRIKETHROUGH_CLASS = "md-underline-strikethrough";
|
|
5
3
|
/** The class hooks Lexical needs for text-decoration formats it renders as a
|
|
6
|
-
* plain <span>.
|
|
7
|
-
* the case where both apply — both want `text-decoration`.) */
|
|
4
|
+
* plain <span>. */
|
|
8
5
|
export declare const defaultTheme: EditorThemeClasses;
|
|
9
6
|
/** Merge a consumer theme over the default. `text` is merged per-key so a
|
|
10
|
-
* consumer overriding (say) `strikethrough` keeps the default
|
|
7
|
+
* consumer overriding (say) `strikethrough` keeps the other default entries.
|
|
11
8
|
*
|
|
12
9
|
* Always returns a FRESH theme (never the shared `defaultTheme` singleton):
|
|
13
10
|
* Lexical caches resolved class arrays by MUTATING the `text` object it is
|
package/dist/theme.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,eAAO,MAAM,mBAAmB,qBAAqB,CAAA;AAErD;mBACmB;AACnB,eAAO,MAAM,YAAY,EAAE,kBAI1B,CAAA;AAED;;;;;;;8EAO8E;AAC9E,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,CAIzE"}
|
package/dist/theme.js
CHANGED
|
@@ -2,28 +2,32 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Lexical styles most inline formats through semantic tags that carry
|
|
4
4
|
// browser-default styling — bold→<strong>, italic→<em>, code→<code>. But
|
|
5
|
-
// `strikethrough`
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
5
|
+
// `strikethrough` renders as a bare <span> whose ONLY styling hook is a
|
|
6
|
+
// `theme.text.strikethrough` class. With no theme the format is applied to the
|
|
7
|
+
// model but is visually invisible. This default theme supplies that class name;
|
|
8
|
+
// the bundled `styles/editor.css` gives it its `text-decoration`.
|
|
9
|
+
//
|
|
10
|
+
// `underline` is deliberately NOT themed here: the GFM markdown dialect this
|
|
11
|
+
// editor serializes has no underline representation (Lexical's text-format
|
|
12
|
+
// transformers require a SYMMETRIC delimiter, and there is no standard symmetric
|
|
13
|
+
// underline syntax), so an applied underline would be silently stripped on save.
|
|
14
|
+
// To keep the WYSIWYG surface and the serialized dialect in lock-step, the
|
|
15
|
+
// underline command is also intercepted at the editor seam (see editor.ts) — so
|
|
16
|
+
// underline can be neither applied nor lost. Add it back (theme + transformer +
|
|
17
|
+
// command) only alongside a dialect that can round-trip it.
|
|
9
18
|
//
|
|
10
19
|
// Consumers can override any entry via `markdownEditor({ theme })` — the user's
|
|
11
20
|
// theme is merged over this default (see `mergeTheme`).
|
|
12
21
|
export const STRIKETHROUGH_CLASS = 'md-strikethrough';
|
|
13
|
-
export const UNDERLINE_CLASS = 'md-underline';
|
|
14
|
-
export const UNDERLINE_STRIKETHROUGH_CLASS = 'md-underline-strikethrough';
|
|
15
22
|
/** The class hooks Lexical needs for text-decoration formats it renders as a
|
|
16
|
-
* plain <span>.
|
|
17
|
-
* the case where both apply — both want `text-decoration`.) */
|
|
23
|
+
* plain <span>. */
|
|
18
24
|
export const defaultTheme = {
|
|
19
25
|
text: {
|
|
20
26
|
strikethrough: STRIKETHROUGH_CLASS,
|
|
21
|
-
underline: UNDERLINE_CLASS,
|
|
22
|
-
underlineStrikethrough: UNDERLINE_STRIKETHROUGH_CLASS,
|
|
23
27
|
},
|
|
24
28
|
};
|
|
25
29
|
/** Merge a consumer theme over the default. `text` is merged per-key so a
|
|
26
|
-
* consumer overriding (say) `strikethrough` keeps the default
|
|
30
|
+
* consumer overriding (say) `strikethrough` keeps the other default entries.
|
|
27
31
|
*
|
|
28
32
|
* Always returns a FRESH theme (never the shared `defaultTheme` singleton):
|
|
29
33
|
* Lexical caches resolved class arrays by MUTATING the `text` object it is
|
package/dist/theme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,yEAAyE;AACzE,+EAA+E;AAC/E,gFAAgF;AAChF
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,yEAAyE;AACzE,wEAAwE;AACxE,+EAA+E;AAC/E,gFAAgF;AAChF,kEAAkE;AAClE,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,iFAAiF;AACjF,iFAAiF;AACjF,2EAA2E;AAC3E,gFAAgF;AAChF,gFAAgF;AAChF,4DAA4D;AAC5D,EAAE;AACF,gFAAgF;AAChF,wDAAwD;AAIxD,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAA;AAErD;mBACmB;AACnB,MAAM,CAAC,MAAM,YAAY,GAAuB;IAC9C,IAAI,EAAE;QACJ,aAAa,EAAE,mBAAmB;KACnC;CACF,CAAA;AAED;;;;;;;8EAO8E;AAC9E,MAAM,UAAU,UAAU,CAAC,KAA0B;IACnD,MAAM,IAAI,GAAG,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;IACrD,OAAQ,IAA8C,CAAC,uBAAuB,CAAA;IAC9E,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;AAC3B,CAAC"}
|
|
@@ -2,9 +2,17 @@ import type { Klass, LexicalNode } from 'lexical';
|
|
|
2
2
|
import { type Transformer } from '@lexical/markdown';
|
|
3
3
|
/** Node classes required to render the GFM superset. */
|
|
4
4
|
export declare const GFM_NODES: ReadonlyArray<Klass<LexicalNode>>;
|
|
5
|
+
/** The `==highlight==` transformer. NOT part of the default GFM set: `==..==` is
|
|
6
|
+
* not GFM, so exporting it produces non-standard markdown other renderers won't
|
|
7
|
+
* understand. Offered as an opt-in a consumer can add to a plugin's transformers. */
|
|
8
|
+
export declare const HIGHLIGHT_TRANSFORMER: Transformer;
|
|
5
9
|
/** Inline text-format transformers (no block nodes, no node registration). These
|
|
6
10
|
* are the only transformers a single-block / inline-only editor needs; `LINK` is
|
|
7
|
-
* kept separate since it requires `LinkNode` to be registered.
|
|
11
|
+
* kept separate since it requires `LinkNode` to be registered.
|
|
12
|
+
*
|
|
13
|
+
* `HIGHLIGHT` is deliberately excluded: it round-trips as the non-GFM `==..==`
|
|
14
|
+
* syntax, so it would silently emit markdown outside the editor's stated dialect.
|
|
15
|
+
* Opt in with {@link HIGHLIGHT_TRANSFORMER}. */
|
|
8
16
|
export declare const INLINE_TEXT_TRANSFORMERS: readonly Transformer[];
|
|
9
17
|
/** Markdown ↔ node transformers for the GFM superset. */
|
|
10
18
|
export declare const GFM_TRANSFORMERS: readonly Transformer[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gfm.d.ts","sourceRoot":"","sources":["../../src/transformers/gfm.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAOjD,OAAO,EACL,KAAK,WAAW,EAiBjB,MAAM,mBAAmB,CAAA;AAE1B,wDAAwD;AACxD,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAQvD,CAAA;AAED;;
|
|
1
|
+
{"version":3,"file":"gfm.d.ts","sourceRoot":"","sources":["../../src/transformers/gfm.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAOjD,OAAO,EACL,KAAK,WAAW,EAiBjB,MAAM,mBAAmB,CAAA;AAE1B,wDAAwD;AACxD,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAQvD,CAAA;AAED;;qFAEqF;AACrF,eAAO,MAAM,qBAAqB,EAAE,WAAuB,CAAA;AAE3D;;;;;;gDAMgD;AAChD,eAAO,MAAM,wBAAwB,EAAE,SAAS,WAAW,EAS1D,CAAA;AAED,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAWlD,CAAA"}
|
package/dist/transformers/gfm.js
CHANGED
|
@@ -17,9 +17,17 @@ export const GFM_NODES = [
|
|
|
17
17
|
CodeHighlightNode,
|
|
18
18
|
LinkNode,
|
|
19
19
|
];
|
|
20
|
+
/** The `==highlight==` transformer. NOT part of the default GFM set: `==..==` is
|
|
21
|
+
* not GFM, so exporting it produces non-standard markdown other renderers won't
|
|
22
|
+
* understand. Offered as an opt-in a consumer can add to a plugin's transformers. */
|
|
23
|
+
export const HIGHLIGHT_TRANSFORMER = HIGHLIGHT;
|
|
20
24
|
/** Inline text-format transformers (no block nodes, no node registration). These
|
|
21
25
|
* are the only transformers a single-block / inline-only editor needs; `LINK` is
|
|
22
|
-
* kept separate since it requires `LinkNode` to be registered.
|
|
26
|
+
* kept separate since it requires `LinkNode` to be registered.
|
|
27
|
+
*
|
|
28
|
+
* `HIGHLIGHT` is deliberately excluded: it round-trips as the non-GFM `==..==`
|
|
29
|
+
* syntax, so it would silently emit markdown outside the editor's stated dialect.
|
|
30
|
+
* Opt in with {@link HIGHLIGHT_TRANSFORMER}. */
|
|
23
31
|
export const INLINE_TEXT_TRANSFORMERS = [
|
|
24
32
|
BOLD_ITALIC_STAR,
|
|
25
33
|
BOLD_ITALIC_UNDERSCORE,
|
|
@@ -29,7 +37,6 @@ export const INLINE_TEXT_TRANSFORMERS = [
|
|
|
29
37
|
ITALIC_UNDERSCORE,
|
|
30
38
|
STRIKETHROUGH,
|
|
31
39
|
INLINE_CODE,
|
|
32
|
-
HIGHLIGHT,
|
|
33
40
|
];
|
|
34
41
|
/** Markdown ↔ node transformers for the GFM superset. */
|
|
35
42
|
export const GFM_TRANSFORMERS = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gfm.js","sourceRoot":"","sources":["../../src/transformers/gfm.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kFAAkF;AAGlF,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,gFAAgF;AAChF,wEAAwE;AACxE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAEL,OAAO,EACP,KAAK,EACL,cAAc,EACd,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,gBAAgB,EAChB,sBAAsB,EACtB,SAAS,EACT,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,SAAS,EACT,IAAI,GACL,MAAM,mBAAmB,CAAA;AAE1B,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAsC;IAC1D,WAAW;IACX,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,QAAQ;IACR,iBAAiB;IACjB,QAAQ;CACT,CAAA;AAED;;
|
|
1
|
+
{"version":3,"file":"gfm.js","sourceRoot":"","sources":["../../src/transformers/gfm.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kFAAkF;AAGlF,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,gFAAgF;AAChF,wEAAwE;AACxE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAEL,OAAO,EACP,KAAK,EACL,cAAc,EACd,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,gBAAgB,EAChB,sBAAsB,EACtB,SAAS,EACT,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,SAAS,EACT,IAAI,GACL,MAAM,mBAAmB,CAAA;AAE1B,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAsC;IAC1D,WAAW;IACX,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,QAAQ;IACR,iBAAiB;IACjB,QAAQ;CACT,CAAA;AAED;;qFAEqF;AACrF,MAAM,CAAC,MAAM,qBAAqB,GAAgB,SAAS,CAAA;AAE3D;;;;;;gDAMgD;AAChD,MAAM,CAAC,MAAM,wBAAwB,GAA2B;IAC9D,gBAAgB;IAChB,sBAAsB;IACtB,SAAS;IACT,eAAe;IACf,WAAW;IACX,iBAAiB;IACjB,aAAa;IACb,WAAW;CACZ,CAAA;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,OAAO;IACP,KAAK;IACL,4EAA4E;IAC5E,2EAA2E;IAC3E,UAAU;IACV,cAAc;IACd,YAAY;IACZ,IAAI;IACJ,GAAG,wBAAwB;IAC3B,IAAI;CACL,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/transformers/registry.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,+EAA+E;AAC/E,kDAAkD;AAKlD,6EAA6E;AAC7E,6EAA6E;AAC7E,mEAAmE;AACnE,MAAM,SAAS,GAA2B;IACxC,mBAAmB,EAAE,CAAC;IACtB,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC;CAChB,CAAA;AAED,+DAA+D;AAC/D,MAAM,UAAU,iBAAiB,CAAC,YAAoC;IACpE,OAAO,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE,CAAA;QAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACzD,qDAAqD;YACrD,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAA;QACpC,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;kCAEkC;AAClC,MAAM,UAAU,iBAAiB,CAAC,OAAkC;IAClE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAe,CAAA;IACnC,MAAM,SAAS,GAAkB,EAAE,CAAA;IACnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;gBACrB,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAA;AACrC,CAAC"
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/transformers/registry.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,+EAA+E;AAC/E,kDAAkD;AAKlD,6EAA6E;AAC7E,6EAA6E;AAC7E,mEAAmE;AACnE,MAAM,SAAS,GAA2B;IACxC,mBAAmB,EAAE,CAAC;IACtB,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC;CAChB,CAAA;AAED,+DAA+D;AAC/D,MAAM,UAAU,iBAAiB,CAAC,YAAoC;IACpE,OAAO,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE,CAAA;QAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACzD,qDAAqD;YACrD,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAA;QACpC,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;kCAEkC;AAClC,MAAM,UAAU,iBAAiB,CAAC,OAAkC;IAClE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAe,CAAA;IACnC,MAAM,SAAS,GAAkB,EAAE,CAAA;IACnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;gBACrB,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAA;AACrC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llui/markdown-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -24,9 +24,6 @@
|
|
|
24
24
|
"./styles/editor.css": "./dist/styles/editor.css"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@llui/dom": "^0.11.5",
|
|
28
|
-
"@llui/lexical": "^0.2.8",
|
|
29
|
-
"@llui/components": "^0.12.2",
|
|
30
27
|
"lexical": "^0.46.0",
|
|
31
28
|
"@lexical/markdown": "^0.46.0",
|
|
32
29
|
"@lexical/rich-text": "^0.46.0",
|
|
@@ -35,7 +32,11 @@
|
|
|
35
32
|
"@lexical/table": "^0.46.0",
|
|
36
33
|
"@lexical/selection": "^0.46.0",
|
|
37
34
|
"@lexical/utils": "^0.46.0",
|
|
38
|
-
"@lexical/code-core": "^0.46.0"
|
|
35
|
+
"@lexical/code-core": "^0.46.0",
|
|
36
|
+
"@llui/dom": "^0.12.0",
|
|
37
|
+
"@llui/markdown": "^0.12.0",
|
|
38
|
+
"@llui/lexical": "^0.3.0",
|
|
39
|
+
"@llui/components": "^0.13.0"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"lexical": "^0.46.0",
|
|
@@ -50,9 +51,10 @@
|
|
|
50
51
|
"typescript": "^6.0.0",
|
|
51
52
|
"vitest": "^4.1.2",
|
|
52
53
|
"@lexical/code-core": "^0.46.0",
|
|
53
|
-
"@llui/dom": "0.
|
|
54
|
-
"@llui/
|
|
55
|
-
"@llui/components": "0.
|
|
54
|
+
"@llui/dom": "0.12.0",
|
|
55
|
+
"@llui/markdown": "0.12.0",
|
|
56
|
+
"@llui/components": "0.13.0",
|
|
57
|
+
"@llui/lexical": "0.3.0"
|
|
56
58
|
},
|
|
57
59
|
"sideEffects": [
|
|
58
60
|
"./dist/styles/editor.css"
|