@lexical/html 0.44.1-nightly.20260519.0 → 0.45.1-dev.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/{DOMRenderExtension.d.ts → dist/DOMRenderExtension.d.ts} +12 -1
- package/dist/DOMRenderRuntime.d.ts +51 -0
- package/dist/LexicalHtml.dev.js +3289 -0
- package/dist/LexicalHtml.dev.mjs +3242 -0
- package/{LexicalHtml.js.flow → dist/LexicalHtml.js.flow} +16 -16
- package/dist/LexicalHtml.mjs +57 -0
- package/dist/LexicalHtml.node.mjs +55 -0
- package/dist/LexicalHtml.prod.js +9 -0
- package/dist/LexicalHtml.prod.mjs +9 -0
- package/dist/RenderContext.d.ts +68 -0
- package/{compileDOMRenderConfigOverrides.d.ts → dist/compileDOMRenderConfigOverrides.d.ts} +1 -1
- package/{constants.d.ts → dist/constants.d.ts} +2 -0
- package/dist/domOverride.d.ts +23 -0
- package/dist/import/CoreImportExtension.d.ts +11 -0
- package/dist/import/DOMImportExtension.d.ts +82 -0
- package/dist/import/HorizontalRuleImportExtension.d.ts +28 -0
- package/dist/import/ImportContext.d.ts +208 -0
- package/dist/import/compileImportRules.d.ts +50 -0
- package/dist/import/coreImportRules.d.ts +25 -0
- package/dist/import/defineImportRule.d.ts +32 -0
- package/dist/import/defineOverlayRules.d.ts +66 -0
- package/dist/import/index.d.ts +38 -0
- package/dist/import/inlineStylesFromStyleSheets.d.ts +28 -0
- package/dist/import/parseCss.d.ts +18 -0
- package/dist/import/runImport.d.ts +19 -0
- package/dist/import/schemas.d.ts +106 -0
- package/dist/import/sel.d.ts +74 -0
- package/dist/import/types.d.ts +394 -0
- package/dist/index.d.ts +44 -0
- package/{types.d.ts → dist/types.d.ts} +96 -8
- package/package.json +33 -18
- package/src/ContextRecord.ts +243 -0
- package/src/DOMRenderExtension.ts +96 -0
- package/src/DOMRenderRuntime.ts +265 -0
- package/src/RenderContext.ts +168 -0
- package/src/compileDOMRenderConfigOverrides.ts +416 -0
- package/src/constants.ts +18 -0
- package/src/domOverride.ts +46 -0
- package/src/import/CoreImportExtension.ts +26 -0
- package/src/import/DOMImportExtension.ts +221 -0
- package/src/import/HorizontalRuleImportExtension.ts +52 -0
- package/src/import/ImportContext.ts +339 -0
- package/src/import/compileImportRules.ts +178 -0
- package/src/import/coreImportRules.ts +545 -0
- package/src/import/defineImportRule.ts +40 -0
- package/src/import/defineOverlayRules.ts +105 -0
- package/src/import/index.ts +97 -0
- package/src/import/inlineStylesFromStyleSheets.ts +104 -0
- package/src/import/parseCss.ts +219 -0
- package/src/import/runImport.ts +245 -0
- package/src/import/schemas.ts +280 -0
- package/src/import/sel.ts +314 -0
- package/src/import/types.ts +471 -0
- package/src/index.ts +561 -0
- package/src/types.ts +470 -0
- package/LexicalHtml.dev.js +0 -914
- package/LexicalHtml.dev.mjs +0 -900
- package/LexicalHtml.mjs +0 -24
- package/LexicalHtml.node.mjs +0 -22
- package/LexicalHtml.prod.js +0 -9
- package/LexicalHtml.prod.mjs +0 -9
- package/RenderContext.d.ts +0 -32
- package/domOverride.d.ts +0 -18
- package/index.d.ts +0 -32
- /package/{ContextRecord.d.ts → dist/ContextRecord.d.ts} +0 -0
- /package/{LexicalHtml.js → dist/LexicalHtml.js} +0 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type {DOMImportContextSymbol} from '../constants';
|
|
9
|
+
import type {
|
|
10
|
+
AnyContextConfigPairOrUpdater,
|
|
11
|
+
ContextConfig,
|
|
12
|
+
ContextRecord,
|
|
13
|
+
} from '../types';
|
|
14
|
+
import type {CompiledOverlayRules} from './defineOverlayRules';
|
|
15
|
+
import type {LexicalNode} from 'lexical';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Phantom-typed branding so consumers cannot construct or mutate a
|
|
19
|
+
* {@link CompiledSelector} directly; the only way to obtain one is via the
|
|
20
|
+
* {@link sel} builder or {@link parseSelector}. The actual runtime shape is
|
|
21
|
+
* an internal implementation detail (see `./sel`).
|
|
22
|
+
*
|
|
23
|
+
* @experimental
|
|
24
|
+
*/
|
|
25
|
+
export declare const NodeBrand: unique symbol;
|
|
26
|
+
/** @experimental */
|
|
27
|
+
export declare const CaptureBrand: unique symbol;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* An opaque, compiled selector used as the `match` field of a
|
|
31
|
+
* {@link DOMImportRule}. The two phantom type parameters carry the matched
|
|
32
|
+
* Node subtype (`N`) and a record of named regex captures (`C`) so the
|
|
33
|
+
* importer body gets correctly-typed `ctx` and `node` arguments without
|
|
34
|
+
* casts.
|
|
35
|
+
*
|
|
36
|
+
* @experimental
|
|
37
|
+
*/
|
|
38
|
+
export interface CompiledSelector<
|
|
39
|
+
N extends Node = Node,
|
|
40
|
+
C extends Record<string, RegExpMatchArray> = Record<string, RegExpMatchArray>,
|
|
41
|
+
> {
|
|
42
|
+
readonly [NodeBrand]?: N;
|
|
43
|
+
readonly [CaptureBrand]?: C;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The Node subtype matched by a selector (e.g. `HTMLAnchorElement` for
|
|
48
|
+
* `sel.tag('a')`, `Text` for `sel.text()`).
|
|
49
|
+
*
|
|
50
|
+
* @experimental
|
|
51
|
+
*/
|
|
52
|
+
export type NodeOfSelector<S> =
|
|
53
|
+
S extends CompiledSelector<infer N, Record<string, RegExpMatchArray>>
|
|
54
|
+
? N
|
|
55
|
+
: Node;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The named-capture map for a selector.
|
|
59
|
+
*
|
|
60
|
+
* @experimental
|
|
61
|
+
*/
|
|
62
|
+
export type CapturesOfSelector<S> =
|
|
63
|
+
S extends CompiledSelector<Node, infer C> ? C : Record<string, never>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Options bag for {@link ElementSelectorBuilder.attr} when the value is a
|
|
67
|
+
* regex. Future options will be added here without breaking existing
|
|
68
|
+
* call-sites.
|
|
69
|
+
*
|
|
70
|
+
* @experimental
|
|
71
|
+
*/
|
|
72
|
+
export interface AttrMatchOptions<K extends string = string> {
|
|
73
|
+
/**
|
|
74
|
+
* If provided, the {@link RegExpMatchArray} from the successful match is
|
|
75
|
+
* stored on `ctx.captures[capture]` for the importer to consume — saving
|
|
76
|
+
* a second regex execution.
|
|
77
|
+
*/
|
|
78
|
+
readonly capture?: K;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Options bag for {@link ElementSelectorBuilder.styleAny} when the value is a
|
|
83
|
+
* regex. See {@link AttrMatchOptions} for capture semantics.
|
|
84
|
+
*
|
|
85
|
+
* @experimental
|
|
86
|
+
*/
|
|
87
|
+
export interface StyleMatchOptions<K extends string = string> {
|
|
88
|
+
readonly capture?: K;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Fluent builder for an element selector. The two type parameters carry the
|
|
93
|
+
* matched element type and the named-capture map; each call refines them.
|
|
94
|
+
*
|
|
95
|
+
* The builder itself implements {@link CompiledSelector} so it can be used
|
|
96
|
+
* directly as the `match` field of a rule — no `.build()` call needed.
|
|
97
|
+
*
|
|
98
|
+
* @experimental
|
|
99
|
+
*/
|
|
100
|
+
export interface ElementSelectorBuilder<
|
|
101
|
+
E extends HTMLElement,
|
|
102
|
+
C extends Record<string, RegExpMatchArray> = Record<string, never>,
|
|
103
|
+
> extends CompiledSelector<E, C> {
|
|
104
|
+
/** Require every listed class to be present on the element. */
|
|
105
|
+
classAll(...classes: readonly string[]): ElementSelectorBuilder<E, C>;
|
|
106
|
+
/** Require at least one of the listed classes to be present. */
|
|
107
|
+
classAny(...classes: readonly string[]): ElementSelectorBuilder<E, C>;
|
|
108
|
+
/** Require the attribute to be present (any value). */
|
|
109
|
+
attr(name: string, value: true): ElementSelectorBuilder<E, C>;
|
|
110
|
+
/** Require the attribute to equal the given string. */
|
|
111
|
+
attr(name: string, value: string): ElementSelectorBuilder<E, C>;
|
|
112
|
+
/**
|
|
113
|
+
* Require the attribute to match the given regex. With
|
|
114
|
+
* `{capture: 'name'}` the match result is exposed on
|
|
115
|
+
* `ctx.captures.name`.
|
|
116
|
+
*/
|
|
117
|
+
attr<const O extends AttrMatchOptions>(
|
|
118
|
+
name: string,
|
|
119
|
+
value: RegExp,
|
|
120
|
+
options?: O,
|
|
121
|
+
): ElementSelectorBuilder<
|
|
122
|
+
E,
|
|
123
|
+
O extends {capture: infer K} ? C & Record<K & string, RegExpMatchArray> : C
|
|
124
|
+
>;
|
|
125
|
+
/** Require the inline-style declaration to equal `value`. */
|
|
126
|
+
styleAny(prop: string, value: string): ElementSelectorBuilder<E, C>;
|
|
127
|
+
/** Require the inline-style declaration to match `value`. */
|
|
128
|
+
styleAny<const O extends StyleMatchOptions>(
|
|
129
|
+
prop: string,
|
|
130
|
+
value: RegExp,
|
|
131
|
+
options?: O,
|
|
132
|
+
): ElementSelectorBuilder<
|
|
133
|
+
E,
|
|
134
|
+
O extends {capture: infer K} ? C & Record<K & string, RegExpMatchArray> : C
|
|
135
|
+
>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Argument to {@link DOMImportContext.branch} / `$importChildren({context})`
|
|
140
|
+
* — see {@link ContextConfigPair} / {@link ContextConfigUpdater}.
|
|
141
|
+
*
|
|
142
|
+
* @experimental
|
|
143
|
+
*/
|
|
144
|
+
export type ImportContextPairOrUpdater = AnyContextConfigPairOrUpdater<
|
|
145
|
+
typeof DOMImportContextSymbol
|
|
146
|
+
>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* A typed context-state key for the import pipeline. Create with
|
|
150
|
+
* {@link createImportState}.
|
|
151
|
+
*
|
|
152
|
+
* @experimental
|
|
153
|
+
*/
|
|
154
|
+
export type ImportStateConfig<V> = ContextConfig<
|
|
155
|
+
typeof DOMImportContextSymbol,
|
|
156
|
+
V
|
|
157
|
+
>;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* A mutable, document-order-shared store for the import pipeline. Lets a
|
|
161
|
+
* rule visited early in the document write information that rules visited
|
|
162
|
+
* later can read — e.g. parse `<style>` or `<meta>` and influence
|
|
163
|
+
* subsequent matching.
|
|
164
|
+
*
|
|
165
|
+
* Implemented as the root-layer {@link ContextRecord} of the import walk:
|
|
166
|
+
* `ctx.session.set(cfg, v)` mutates the slot on that root record, and
|
|
167
|
+
* every unshadowed `ctx.get(cfg)` read in any branch picks it up. A
|
|
168
|
+
* `$importChildren({context: [...]})` branch that explicitly writes the
|
|
169
|
+
* same slot shadows the session value for the duration of that branch.
|
|
170
|
+
*
|
|
171
|
+
* @experimental
|
|
172
|
+
*/
|
|
173
|
+
export interface ImportSession {
|
|
174
|
+
/** Read the current value, returning the config's default if unset. */
|
|
175
|
+
get<V>(cfg: ImportStateConfig<V>): V;
|
|
176
|
+
/** Write `value` into the slot. */
|
|
177
|
+
set<V>(cfg: ImportStateConfig<V>, value: V): void;
|
|
178
|
+
/** Read-modify-write. */
|
|
179
|
+
update<V>(cfg: ImportStateConfig<V>, updater: (prev: V) => V): void;
|
|
180
|
+
/** Returns `true` if the slot has been written since session creation. */
|
|
181
|
+
has<V>(cfg: ImportStateConfig<V>): boolean;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Context exposed to a rule's `$import` function. Mirrors the existing render
|
|
186
|
+
* context (see {@link RenderContext}) but is import-scoped.
|
|
187
|
+
*
|
|
188
|
+
* @experimental
|
|
189
|
+
*/
|
|
190
|
+
export interface DOMImportContext<
|
|
191
|
+
C extends Record<string, RegExpMatchArray> = Record<string, never>,
|
|
192
|
+
> {
|
|
193
|
+
/** Captures from this rule's selector. Fresh per rule invocation. */
|
|
194
|
+
readonly captures: Readonly<C>;
|
|
195
|
+
/**
|
|
196
|
+
* Mutable, document-order-shared store. Use to make information from
|
|
197
|
+
* earlier-visited nodes available to later-visited ones (e.g. a
|
|
198
|
+
* `<style>` or `<meta>` at the top of the document influencing how
|
|
199
|
+
* later elements are interpreted). One {@link ImportSession} instance
|
|
200
|
+
* is created per top-level `$generateNodesFromDOM` call and is shared
|
|
201
|
+
* across all recursive `$importChildren` / `$importOne` invocations.
|
|
202
|
+
*/
|
|
203
|
+
readonly session: ImportSession;
|
|
204
|
+
|
|
205
|
+
/** Read a typed context value. */
|
|
206
|
+
get<V>(cfg: ImportStateConfig<V>): V;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Recursively import every child of `parent` and return the produced
|
|
210
|
+
* lexical nodes, optionally enforcing a {@link ChildSchema} and/or
|
|
211
|
+
* branching the import context for the duration of the call (via
|
|
212
|
+
* `opts.context`).
|
|
213
|
+
*/
|
|
214
|
+
$importChildren(parent: ParentNode, opts?: ImportChildrenOpts): LexicalNode[];
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Recursively import a single DOM node.
|
|
218
|
+
*/
|
|
219
|
+
$importOne(node: Node, opts?: ImportNodeOpts): LexicalNode[];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Options accepted by {@link DOMImportContext.$importChildren}. The combination
|
|
224
|
+
* of `schema`, `$onChild`, and `$after` is sufficient to express every
|
|
225
|
+
* child-handling pattern in the legacy `forChild` / `after` / wrap-continuous
|
|
226
|
+
* machinery.
|
|
227
|
+
*
|
|
228
|
+
* @experimental
|
|
229
|
+
*/
|
|
230
|
+
export interface ImportChildrenOpts {
|
|
231
|
+
/**
|
|
232
|
+
* How to validate and (re)package produced children. Defaults to whichever
|
|
233
|
+
* schema the parent's importer passed; the top-level entry uses
|
|
234
|
+
* {@link BlockSchema}.
|
|
235
|
+
*/
|
|
236
|
+
readonly schema?: ChildSchema;
|
|
237
|
+
/**
|
|
238
|
+
* Called for each produced lexical child immediately after its rule
|
|
239
|
+
* returned, with the chance to substitute or drop it. Equivalent to the
|
|
240
|
+
* old `forChild` hook but scoped to one `$importChildren` call.
|
|
241
|
+
*/
|
|
242
|
+
readonly $onChild?: (child: LexicalNode) => LexicalNode | null | undefined;
|
|
243
|
+
/**
|
|
244
|
+
* Called once with the full child array after all DOM children have been
|
|
245
|
+
* recursively imported but before {@link ChildSchema.$packageRun} is
|
|
246
|
+
* applied. Equivalent to the old `after` hook.
|
|
247
|
+
*/
|
|
248
|
+
readonly $after?: (children: LexicalNode[]) => LexicalNode[];
|
|
249
|
+
/** Context overrides scoped to the children traversal. */
|
|
250
|
+
readonly context?: readonly ImportContextPairOrUpdater[];
|
|
251
|
+
/**
|
|
252
|
+
* Additional {@link DOMImportRule}s active only for this children
|
|
253
|
+
* traversal (and any nested `$importChildren` calls that don't push
|
|
254
|
+
* their own overlay). The overlay is checked BEFORE the main
|
|
255
|
+
* dispatcher, so its rules take precedence; calling `$next()` from an
|
|
256
|
+
* overlay rule falls through to the next overlay-or-main rule.
|
|
257
|
+
*
|
|
258
|
+
* Use this to scope cost-bearing rules to where they apply. For
|
|
259
|
+
* example, a GitHub code-table rule installs an overlay that
|
|
260
|
+
* unwraps `<tr>` / `<td>` inside the table, without paying that
|
|
261
|
+
* predicate cost on every other `<tr>` / `<td>` paste.
|
|
262
|
+
*
|
|
263
|
+
* The value must be produced by
|
|
264
|
+
* {@link defineOverlayRules}; this forces the dispatcher to be
|
|
265
|
+
* compiled once at module scope and reused across
|
|
266
|
+
* `$importChildren` calls, instead of being recompiled per invocation.
|
|
267
|
+
*/
|
|
268
|
+
readonly rules?: CompiledOverlayRules;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** @experimental */
|
|
272
|
+
export interface ImportNodeOpts {
|
|
273
|
+
readonly context?: readonly ImportContextPairOrUpdater[];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* A {@link ChildSchema} encodes which lexical nodes a parent accepts as
|
|
278
|
+
* children and how to package or reject the rest. The legacy
|
|
279
|
+
* `wrapContinuousInlines` / `ArtificialNode__DO_NOT_USE` logic is the
|
|
280
|
+
* `BlockSchema` and `NestedBlockSchema` cases of this primitive.
|
|
281
|
+
*
|
|
282
|
+
* A schema only controls how the *children* are assembled before being
|
|
283
|
+
* appended to the parent the calling rule already chose. It cannot
|
|
284
|
+
* change the parent itself. Cases where the parent's shape needs to
|
|
285
|
+
* change in response to its children — e.g. an inline `<a>` that
|
|
286
|
+
* encloses a block `<h1>`, which must be lifted so the heading takes
|
|
287
|
+
* the link's place and the link is redistributed onto the heading's
|
|
288
|
+
* inline contents — belong in the rule body, not the schema. See the
|
|
289
|
+
* "Lifting blocks out of an inline parent" section of the docs.
|
|
290
|
+
*
|
|
291
|
+
* @experimental
|
|
292
|
+
*/
|
|
293
|
+
export interface ChildSchema {
|
|
294
|
+
/** Optional name for debug output. */
|
|
295
|
+
readonly name?: string;
|
|
296
|
+
/**
|
|
297
|
+
* Returns `true` if `child` is a valid child of `parent` in this position.
|
|
298
|
+
*/
|
|
299
|
+
$accepts(child: LexicalNode, parent: LexicalNode | null): boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Package a maximal run of non-accepted siblings into zero or more
|
|
302
|
+
* accepted nodes. The returned nodes replace the rejected run at the
|
|
303
|
+
* same position in the child list and are not re-checked against
|
|
304
|
+
* `$accepts` — the caller is trusted to return valid children. If
|
|
305
|
+
* omitted, or if it returns an empty array, {@link ChildSchema.onReject}
|
|
306
|
+
* is consulted instead.
|
|
307
|
+
*/
|
|
308
|
+
$packageRun?(
|
|
309
|
+
rejected: LexicalNode[],
|
|
310
|
+
parent: LexicalNode | null,
|
|
311
|
+
domParent: Node | null,
|
|
312
|
+
): LexicalNode[];
|
|
313
|
+
/**
|
|
314
|
+
* Fallback strategy for a run of non-accepted children when
|
|
315
|
+
* `$packageRun` is missing or returns an empty array:
|
|
316
|
+
*
|
|
317
|
+
* - `'drop'` (default) — silently discards the run. Use when the
|
|
318
|
+
* schema is strict and rejected content is meaningless in this
|
|
319
|
+
* position (e.g. text between table rows).
|
|
320
|
+
* - `'hoist'` — emits the rejected nodes unchanged at the same
|
|
321
|
+
* position in the assembled child list. The caller's parent then
|
|
322
|
+
* receives them as-is, which is only useful if the calling rule
|
|
323
|
+
* intends to surface mixed content to *its* parent (a less common
|
|
324
|
+
* pattern; usually `$packageRun` should re-shape the run first).
|
|
325
|
+
*
|
|
326
|
+
* `'hoist'` does NOT lift the run all the way up out of the calling
|
|
327
|
+
* rule's parent — that requires the rule itself to detect the
|
|
328
|
+
* situation and emit a different parent structure (see the
|
|
329
|
+
* "Lifting blocks out of an inline parent" section).
|
|
330
|
+
*/
|
|
331
|
+
readonly onReject?: 'hoist' | 'drop';
|
|
332
|
+
/**
|
|
333
|
+
* Final pass over the assembled child list (after `$packageRun`). Returns
|
|
334
|
+
* the children to actually attach. Use to enforce structural invariants
|
|
335
|
+
* (e.g. drop empty runs, pad short table rows).
|
|
336
|
+
*/
|
|
337
|
+
$finalize?(
|
|
338
|
+
children: LexicalNode[],
|
|
339
|
+
parent: LexicalNode | null,
|
|
340
|
+
): LexicalNode[];
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* The middleware signature of an import rule. Call `$next()` to delegate to
|
|
345
|
+
* the next-matching rule for this node (returning its result, which may then
|
|
346
|
+
* be inspected or wrapped); return `[]` to drop the node.
|
|
347
|
+
*
|
|
348
|
+
* @experimental
|
|
349
|
+
*/
|
|
350
|
+
export type DOMImportFn<
|
|
351
|
+
E extends Node,
|
|
352
|
+
C extends Record<string, RegExpMatchArray> = Record<string, never>,
|
|
353
|
+
> = (
|
|
354
|
+
ctx: DOMImportContext<C>,
|
|
355
|
+
node: E,
|
|
356
|
+
$next: () => readonly LexicalNode[],
|
|
357
|
+
) => readonly LexicalNode[];
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* An importer for a DOM node, dispatched by `match` and implemented by
|
|
361
|
+
* `$import`.
|
|
362
|
+
*
|
|
363
|
+
* @experimental
|
|
364
|
+
*/
|
|
365
|
+
export interface DOMImportRule<S extends CompiledSelector = CompiledSelector> {
|
|
366
|
+
/**
|
|
367
|
+
* Optional identifier surfaced in dev-mode logs, error messages, and
|
|
368
|
+
* introspection devtools. Convention: `'@scope/package/rule-id'` for
|
|
369
|
+
* library rules.
|
|
370
|
+
*/
|
|
371
|
+
readonly name?: string;
|
|
372
|
+
/** A {@link CompiledSelector} produced by the {@link sel} builder. */
|
|
373
|
+
readonly match: S;
|
|
374
|
+
/** Middleware that converts the matched DOM node into lexical nodes. */
|
|
375
|
+
readonly $import: DOMImportFn<NodeOfSelector<S>, CapturesOfSelector<S>>;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** @experimental */
|
|
379
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
380
|
+
export type AnyDOMImportRule = DOMImportRule<any>;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Context exposed to a {@link DOMPreprocessFn}. Lets the preprocessor:
|
|
384
|
+
*
|
|
385
|
+
* - Write to the per-import {@link ImportSession} (the same
|
|
386
|
+
* `ctx.session` rules see during the walk). Writes mutate the
|
|
387
|
+
* root-layer context record, so they are visible to every scoped
|
|
388
|
+
* `ctx.get(cfg)` read that hasn't been shadowed by a branch.
|
|
389
|
+
*
|
|
390
|
+
* @experimental
|
|
391
|
+
*/
|
|
392
|
+
export interface DOMPreprocessContext {
|
|
393
|
+
/**
|
|
394
|
+
* Document-order-shared store, same instance as `ctx.session` in
|
|
395
|
+
* rules. Use to pass info from the DOM preprocess phase (e.g.
|
|
396
|
+
* inspected `<meta>` tags, collected `<style>` text) to the
|
|
397
|
+
* importer rules.
|
|
398
|
+
*/
|
|
399
|
+
readonly session: ImportSession;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* A middleware step in the DOM-preprocess chain. Runs before walking
|
|
404
|
+
* begins and may:
|
|
405
|
+
*
|
|
406
|
+
* - Mutate the input DOM in place (e.g. inline stylesheets, strip
|
|
407
|
+
* unsafe elements, normalize attributes).
|
|
408
|
+
* - Write to {@link DOMPreprocessContext.session} for rules to read
|
|
409
|
+
* (and for unshadowed scoped reads to pick up).
|
|
410
|
+
* - Call `$next()` to defer to the next-lower preprocessor in the
|
|
411
|
+
* stack; omit the call to short-circuit and skip the rest.
|
|
412
|
+
*
|
|
413
|
+
* The preprocess phase runs inside the same editor read / update
|
|
414
|
+
* context as the walk that follows, so a preprocess function may call
|
|
415
|
+
* `$`-prefixed Lexical APIs (e.g. `$getState`, `$getRoot`) as needed.
|
|
416
|
+
* The `$next` parameter is named with a `$` prefix to make that
|
|
417
|
+
* editor-context expectation visible to readers and lints.
|
|
418
|
+
*
|
|
419
|
+
* Append-style merge applies: an extension's preprocessors are appended
|
|
420
|
+
* to the existing stack, so later-registered preprocessors run first
|
|
421
|
+
* and may delegate to earlier (lower-priority) ones via `$next()`. Same
|
|
422
|
+
* convention as {@link ExportMimeTypeFunction} on the export side.
|
|
423
|
+
*
|
|
424
|
+
* @experimental
|
|
425
|
+
*/
|
|
426
|
+
export type DOMPreprocessFn = (
|
|
427
|
+
dom: Document | ParentNode,
|
|
428
|
+
ctx: DOMPreprocessContext,
|
|
429
|
+
$next: () => void,
|
|
430
|
+
) => void;
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Per-call options to the extension's `$generateNodesFromDOM`.
|
|
434
|
+
*
|
|
435
|
+
* @experimental
|
|
436
|
+
*/
|
|
437
|
+
export interface GenerateNodesFromDOMOptions {
|
|
438
|
+
/**
|
|
439
|
+
* Context pairs/updaters applied for the duration of this import only —
|
|
440
|
+
* use to communicate per-call info such as the {@link ImportSource}.
|
|
441
|
+
*/
|
|
442
|
+
readonly context?: readonly ImportContextPairOrUpdater[];
|
|
443
|
+
/**
|
|
444
|
+
* Additional preprocessors to run on this call only, on top of the
|
|
445
|
+
* extension's configured {@link DOMImportConfig.preprocess}. Per-call
|
|
446
|
+
* preprocessors run AFTER the configured ones.
|
|
447
|
+
*/
|
|
448
|
+
readonly preprocess?: readonly DOMPreprocessFn[];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Output of {@link DOMImportExtension}.
|
|
453
|
+
*
|
|
454
|
+
* @experimental
|
|
455
|
+
*/
|
|
456
|
+
export interface DOMImportExtensionOutput {
|
|
457
|
+
/**
|
|
458
|
+
* Convert a {@link Document} or {@link ParentNode} into lexical nodes,
|
|
459
|
+
* using the dispatcher compiled from this extension's configured
|
|
460
|
+
* {@link DOMImportRule}s.
|
|
461
|
+
*
|
|
462
|
+
* Must be called within an `editor.update()` or `editor.read()` because
|
|
463
|
+
* the importers may invoke `$create...` helpers.
|
|
464
|
+
*/
|
|
465
|
+
$generateNodesFromDOM(
|
|
466
|
+
dom: Document | ParentNode,
|
|
467
|
+
options?: GenerateNodesFromDOMOptions,
|
|
468
|
+
): LexicalNode[];
|
|
469
|
+
/** @internal */
|
|
470
|
+
readonly defaults: undefined | ContextRecord<typeof DOMImportContextSymbol>;
|
|
471
|
+
}
|