@@ -91,12 +91,45 @@ export interface CssNodeCommon {
9191 clone ( options ?: CloneOptions ) : PlainCSSNode
9292}
9393
94+ /**
95+ * Maps a CssNodeCommon subtype interface to its plain-object equivalent,
96+ * as returned by clone().
97+ *
98+ * The result is always a subtype of PlainCSSNode (the intersection starts
99+ * with PlainCSSNode), with two additions:
100+ * - `type` is narrowed to T's specific literal (enables discriminated unions)
101+ * - subtype-specific properties (those not on CssNodeCommon) are added with
102+ * CssNodeCommon references replaced by PlainCSSNode
103+ *
104+ * Traversal properties (first_child, next_sibling, etc.) are excluded since
105+ * they live on CssNodeCommon and are never serialised by clone().
106+ *
107+ * const rule = root.first_child as Rule
108+ * rule.clone().prelude // PlainCSSNode | null — not PlainCSSNode | undefined
109+ * rule.clone().block // PlainCSSNode | null
110+ */
111+ export type ToPlain < T extends CssNodeCommon > = PlainCSSNode &
112+ { type : T [ 'type' ] } & {
113+ [ K in Exclude <
114+ keyof T ,
115+ keyof CssNodeCommon | symbol | 'attr_operator' | 'attr_flags'
116+ > as T [ K ] extends ( ...args : any [ ] ) => any ? never : K ] : T [ K ] extends
117+ | CssNodeCommon
118+ | null
119+ | undefined
120+ ? PlainCSSNode | Exclude < T [ K ] , CssNodeCommon >
121+ : T [ K ] extends CssNodeCommon [ ]
122+ ? PlainCSSNode [ ]
123+ : T [ K ]
124+ }
125+
94126// ---------------------------------------------------------------------------
95127// Structural nodes
96128// ---------------------------------------------------------------------------
97129
98130export interface StyleSheet extends CssNodeCommon {
99131 readonly type : typeof STYLESHEET
132+ clone ( options ?: CloneOptions ) : ToPlain < StyleSheet >
100133}
101134
102135export interface Rule extends CssNodeCommon {
@@ -108,6 +141,7 @@ export interface Rule extends CssNodeCommon {
108141 readonly has_prelude : boolean
109142 readonly has_block : boolean
110143 readonly has_declarations : boolean
144+ clone ( options ?: CloneOptions ) : ToPlain < Rule >
111145}
112146
113147export interface Atrule extends CssNodeCommon {
@@ -120,6 +154,7 @@ export interface Atrule extends CssNodeCommon {
120154 readonly has_prelude : boolean
121155 readonly has_block : boolean
122156 readonly has_declarations : boolean
157+ clone ( options ?: CloneOptions ) : ToPlain < Atrule >
123158}
124159
125160export interface Declaration extends CssNodeCommon {
@@ -130,27 +165,33 @@ export interface Declaration extends CssNodeCommon {
130165 readonly value : Value | Raw | null
131166 readonly is_important : boolean
132167 readonly is_browserhack : boolean
168+ clone ( options ?: CloneOptions ) : ToPlain < Declaration >
133169}
134170
135171export interface Selector extends CssNodeCommon {
136172 readonly type : typeof SELECTOR
173+ clone ( options ?: CloneOptions ) : ToPlain < Selector >
137174}
138175
139176export interface SelectorList extends CssNodeCommon {
140177 readonly type : typeof SELECTOR_LIST
178+ clone ( options ?: CloneOptions ) : ToPlain < SelectorList >
141179}
142180
143181export interface Block extends CssNodeCommon {
144182 readonly type : typeof BLOCK
145183 readonly is_empty : boolean
184+ clone ( options ?: CloneOptions ) : ToPlain < Block >
146185}
147186
148187export interface Comment extends CssNodeCommon {
149188 readonly type : typeof COMMENT
189+ clone ( options ?: CloneOptions ) : ToPlain < Comment >
150190}
151191
152192export interface Raw extends CssNodeCommon {
153193 readonly type : typeof RAW
194+ clone ( options ?: CloneOptions ) : ToPlain < Raw >
154195}
155196
156197// ---------------------------------------------------------------------------
@@ -160,26 +201,31 @@ export interface Raw extends CssNodeCommon {
160201export interface Identifier extends CssNodeCommon {
161202 readonly type : typeof IDENTIFIER
162203 readonly name : string
204+ clone ( options ?: CloneOptions ) : ToPlain < Identifier >
163205}
164206
165207export interface Number extends CssNodeCommon {
166208 readonly type : typeof NUMBER
167209 readonly value : number
210+ clone ( options ?: CloneOptions ) : ToPlain < Number >
168211}
169212
170213export interface Dimension extends CssNodeCommon {
171214 readonly type : typeof DIMENSION
172215 readonly value : number
173216 /** Unit string, e.g. "px", "%" */
174217 readonly unit : string
218+ clone ( options ?: CloneOptions ) : ToPlain < Dimension >
175219}
176220
177221export interface String extends CssNodeCommon {
178222 readonly type : typeof STRING
223+ clone ( options ?: CloneOptions ) : ToPlain < String >
179224}
180225
181226export interface Hash extends CssNodeCommon {
182227 readonly type : typeof HASH
228+ clone ( options ?: CloneOptions ) : ToPlain < Hash >
183229}
184230
185231export interface Function extends CssNodeCommon {
@@ -188,30 +234,36 @@ export interface Function extends CssNodeCommon {
188234 readonly name : string
189235 /** Function arguments as raw text, e.g. "255, 0, 0" for rgb(255, 0, 0) */
190236 readonly value : string | null
237+ clone ( options ?: CloneOptions ) : ToPlain < Function >
191238}
192239
193240export interface Operator extends CssNodeCommon {
194241 readonly type : typeof OPERATOR
195242 /** The operator character(s), e.g. ",", "+", "-" */
196243 readonly value : string
244+ clone ( options ?: CloneOptions ) : ToPlain < Operator >
197245}
198246
199247export interface Parenthesis extends CssNodeCommon {
200248 readonly type : typeof PARENTHESIS
249+ clone ( options ?: CloneOptions ) : ToPlain < Parenthesis >
201250}
202251
203252export interface Url extends CssNodeCommon {
204253 readonly type : typeof URL
205254 /** URL content, e.g. '"image.png"' (with quotes) or 'mycursor.cur' (unquoted) */
206255 readonly value : string | null
256+ clone ( options ?: CloneOptions ) : ToPlain < Url >
207257}
208258
209259export interface UnicodeRange extends CssNodeCommon {
210260 readonly type : typeof UNICODE_RANGE
261+ clone ( options ?: CloneOptions ) : ToPlain < UnicodeRange >
211262}
212263
213264export interface Value extends CssNodeCommon {
214265 readonly type : typeof VALUE
266+ clone ( options ?: CloneOptions ) : ToPlain < Value >
215267}
216268
217269// ---------------------------------------------------------------------------
@@ -222,18 +274,21 @@ export interface TypeSelector extends CssNodeCommon {
222274 readonly type : typeof TYPE_SELECTOR
223275 /** Element type, e.g. "div", "span" */
224276 readonly name : string
277+ clone ( options ?: CloneOptions ) : ToPlain < TypeSelector >
225278}
226279
227280export interface ClassSelector extends CssNodeCommon {
228281 readonly type : typeof CLASS_SELECTOR
229282 /** Class name without dot, e.g. "foo" from ".foo" */
230283 readonly name : string
284+ clone ( options ?: CloneOptions ) : ToPlain < ClassSelector >
231285}
232286
233287export interface IdSelector extends CssNodeCommon {
234288 readonly type : typeof ID_SELECTOR
235289 /** Id without hash, e.g. "bar" from "#bar" */
236290 readonly name : string
291+ clone ( options ?: CloneOptions ) : ToPlain < IdSelector >
237292}
238293
239294export interface AttributeSelector extends CssNodeCommon {
@@ -244,40 +299,56 @@ export interface AttributeSelector extends CssNodeCommon {
244299 readonly attr_operator : number
245300 /** One of the ATTR_FLAG_* constants */
246301 readonly attr_flags : number
302+ clone (
303+ options ?: CloneOptions ,
304+ ) : PlainCSSNode & {
305+ type : typeof ATTRIBUTE_SELECTOR
306+ name : string
307+ /** Operator as a string, e.g. "=", "~=", "|=" */
308+ attr_operator : string
309+ /** Flags as a string, e.g. "i", "s", or "" */
310+ attr_flags : string
311+ }
247312}
248313
249314export interface PseudoClassSelector extends CssNodeCommon {
250315 readonly type : typeof PSEUDO_CLASS_SELECTOR
251316 /** Pseudo-class name without colon, e.g. "hover" */
252317 readonly name : string
318+ clone ( options ?: CloneOptions ) : ToPlain < PseudoClassSelector >
253319}
254320
255321export interface PseudoElementSelector extends CssNodeCommon {
256322 readonly type : typeof PSEUDO_ELEMENT_SELECTOR
257323 /** Pseudo-element name without colons, e.g. "before" */
258324 readonly name : string
325+ clone ( options ?: CloneOptions ) : ToPlain < PseudoElementSelector >
259326}
260327
261328export interface Combinator extends CssNodeCommon {
262329 readonly type : typeof COMBINATOR
263330 /** Combinator character(s), e.g. " ", ">", "~", "+", "||", "/deep/" */
264331 readonly name : string
332+ clone ( options ?: CloneOptions ) : ToPlain < Combinator >
265333}
266334
267335export interface UniversalSelector extends CssNodeCommon {
268336 readonly type : typeof UNIVERSAL_SELECTOR
269- /** Namespace qualifier (e.g. 'ns' in 'ns|*'), null if no namespace */
270- readonly name : string | null
337+ /** Namespace qualifier (e.g. 'ns' in 'ns|*'), undefined if no namespace */
338+ readonly name : string | undefined
339+ clone ( options ?: CloneOptions ) : ToPlain < UniversalSelector >
271340}
272341
273342export interface NestingSelector extends CssNodeCommon {
274343 readonly type : typeof NESTING_SELECTOR
344+ clone ( options ?: CloneOptions ) : ToPlain < NestingSelector >
275345}
276346
277347export interface NthSelector extends CssNodeCommon {
278348 readonly type : typeof NTH_SELECTOR
279349 readonly nth_a : string | undefined
280350 readonly nth_b : string | undefined
351+ clone ( options ?: CloneOptions ) : ToPlain < NthSelector >
281352}
282353
283354export interface NthOfSelector extends CssNodeCommon {
@@ -286,10 +357,12 @@ export interface NthOfSelector extends CssNodeCommon {
286357 readonly nth : NthSelector | null
287358 /** The selector list from :nth-child(An+B of <selector>) */
288359 readonly selector : SelectorList | null
360+ clone ( options ?: CloneOptions ) : ToPlain < NthOfSelector >
289361}
290362
291363export interface LangSelector extends CssNodeCommon {
292364 readonly type : typeof LANG_SELECTOR
365+ clone ( options ?: CloneOptions ) : ToPlain < LangSelector >
293366}
294367
295368// ---------------------------------------------------------------------------
@@ -298,55 +371,65 @@ export interface LangSelector extends CssNodeCommon {
298371
299372export interface AtrulePrelude extends CssNodeCommon {
300373 readonly type : typeof AT_RULE_PRELUDE
374+ clone ( options ?: CloneOptions ) : ToPlain < AtrulePrelude >
301375}
302376
303377export interface MediaQuery extends CssNodeCommon {
304378 readonly type : typeof MEDIA_QUERY
379+ clone ( options ?: CloneOptions ) : ToPlain < MediaQuery >
305380}
306381
307382export interface MediaFeature extends CssNodeCommon {
308383 readonly type : typeof MEDIA_FEATURE
309384 /** Feature name, e.g. "min-width" */
310385 readonly property : string
386+ clone ( options ?: CloneOptions ) : ToPlain < MediaFeature >
311387}
312388
313389export interface MediaType extends CssNodeCommon {
314390 readonly type : typeof MEDIA_TYPE
315391 /** Media type text, e.g. "screen", "print" */
316392 readonly value : string
393+ clone ( options ?: CloneOptions ) : ToPlain < MediaType >
317394}
318395
319396export interface ContainerQuery extends CssNodeCommon {
320397 readonly type : typeof CONTAINER_QUERY
398+ clone ( options ?: CloneOptions ) : ToPlain < ContainerQuery >
321399}
322400
323401export interface SupportsQuery extends CssNodeCommon {
324402 readonly type : typeof SUPPORTS_QUERY
325403 /** The supports condition text, e.g. "display: flex" from "supports(display: flex)" */
326404 readonly value : string
405+ clone ( options ?: CloneOptions ) : ToPlain < SupportsQuery >
327406}
328407
329408export interface LayerName extends CssNodeCommon {
330409 readonly type : typeof LAYER_NAME
331410 readonly name : string
332411 /** Alias for name — the layer name string, e.g. "base" from "layer(base)" */
333412 readonly value : string
413+ clone ( options ?: CloneOptions ) : ToPlain < LayerName >
334414}
335415
336416export interface PreludeSelectorList extends CssNodeCommon {
337417 readonly type : typeof PRELUDE_SELECTORLIST
338418 /** The selector text inside the parentheses, e.g. ".parent" from "(.parent)" */
339419 readonly value : string
420+ clone ( options ?: CloneOptions ) : ToPlain < PreludeSelectorList >
340421}
341422
342423export interface PreludeOperator extends CssNodeCommon {
343424 readonly type : typeof PRELUDE_OPERATOR
425+ clone ( options ?: CloneOptions ) : ToPlain < PreludeOperator >
344426}
345427
346428export interface FeatureRange extends CssNodeCommon {
347429 readonly type : typeof FEATURE_RANGE
348430 /** The feature name in a range comparison, e.g. "width" from "(width >= 400px)" */
349431 readonly name : string
432+ clone ( options ?: CloneOptions ) : ToPlain < FeatureRange >
350433}
351434
352435// ---------------------------------------------------------------------------
0 commit comments