/**
* Why: a chainable, jQuery-shaped facade over the native DOM and the
* defuss-morph engine. It exists so terse imperative DOM code — select,
* mutate, listen — still routes every structural write through morph's
* parser, renderer, reconciler, and delegated-event substrate instead of
* growing a second DOM engine.
*
* Design decisions:
* - `DfQuery` subclasses `Array` with snapshot membership: a selection is
* plain data. Traversal returns a new selection; mutators return `this`
* for chaining. No hidden reactivity, no collection thenable.
* - `df$` is one symbol with two faces: calling it selects (`df$("a")`),
* while morph's functions live on it as properties (`df$.morph(...)`).
* - The factory never imports morph itself. `createDf$` receives the API by
* injection, so the CDN browser bundle can adopt the already-loaded morph
* namespace instead of embedding a second copy (see scripts/build.ts).
* - Element listeners belong to morph's delegated registry so morphing
* never detaches them; only non-element targets use a local WeakMap.
*/
import { type MorphDom } from "./dom.js";
import type { AsynchronousMorphOptions, DomContent, EventMapFor, Handler, MorphApi, MorphOptions, QueryEventOptions, QueryRoot, RenderInput, SynchronousMorphOptions, Value, VNode } from "./types.js";
export type * from "./types.js";
export { createDomAdapter } from "./dom.js";
export type { MorphDom } from "./dom.js";
/** Keep in sync with package.json; scripts/verify.ts gates on it. */
export declare const QUERY_VERSION = "0.2.0";
/**
* The call signature of `df$`. Every overload returns a snapshot selection:
*
* - `df$()` — empty selection.
* - `df$(fn)` — DOM-ready callback: queued as a microtask when the document
* is already parsed, else run once on DOMContentLoaded. Yields Document.
* - `df$("button")` / `df$(".x")` — CSS selector; tag-name overloads give
* precise element types.
* - `df$("
hi
")` — a leading `<` means markup: parse into new nodes.
* - `df$(target | targets)` — wrap one EventTarget or a collection.
* - `df$(vnode)` — render an intrinsic defuss VNode into new nodes.
* - `df$(null)` — empty selection, for ergonomic conditional code.
*/
export interface QueryFactory {
(): DfQuery;
(ready: (df$: DfDollar) => void, context?: QueryRoot): DfQuery;
(selector: K, context?: QueryRoot): DfQuery;
(markup: `<${string}`, context?: QueryRoot): DfQuery;
(targets: T | Iterable | ArrayLike, context?: QueryRoot): DfQuery;
(selector: string, context?: QueryRoot): DfQuery;
(vnode: VNode, context?: QueryRoot): DfQuery;
(empty: null | undefined, context?: QueryRoot): DfQuery;
}
/**
* `df$` itself: the callable factory merged with the injected morph API,
* plus query's reserved slots (`fn` for prototype extension, `dom` for the
* structural adapter, `queryVersion`).
*/
export type DfDollar = QueryFactory & M & {
readonly fn: DfQuery;
readonly queryVersion: string;
readonly dom: MorphDom;
};
interface Runtime {
api: DfDollar;
dom: MorphDom;
}
/**
* A snapshot selection: an `Array` subclass, so every native array method
* works on it. Membership is fixed at creation — traversal methods return a
* new `DfQuery`, while mutators change the DOM and return `this` for
* chaining. Nothing re-evaluates the selector behind your back.
*/
export declare class DfQuery extends Array {
#private;
static get [Symbol.species](): ArrayConstructor;
constructor(runtime: Runtime, items?: Iterable | ArrayLike);
/** The snapshot, or the item at `index` (negative counts from the end). */
get(): T[];
get(index: number): T | undefined;
/** Copy of the selection as a plain array. */
toArray(): T[];
/** Selection containing only the item at `index` (negative from end). */
eq(index: number): DfQuery;
/** Selection containing only the first item. */
first(): DfQuery;
/** Selection containing only the last item. */
last(): DfQuery;
/** Iterate with `this` bound to the item; `false` breaks early. */
each(callback: (this: T, index: number, element: T) => unknown): this;
find(predicate: (value: T, index: number, obj: T[]) => value is S, thisArg?: unknown): S | undefined;
find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: unknown): T | undefined;
find(selector: K): DfQuery;
find(selector: string): DfQuery;
/** Array.filter for predicates; a string keeps elements matching it. */
filter(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: unknown): DfQuery;
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: unknown): DfQuery;
filter(selector: string): DfQuery;
/** True when any element in the selection matches the selector. */
is(selector: string): boolean;
/** Unique parent elements of the selection. */
parent(): DfQuery;
/** Direct child elements, optionally narrowed by selector. */
children(selector?: string): DfQuery;
/** Nearest ancestor-or-self matching the selector, per element. */
closest(selector: string): DfQuery;
/** Next element siblings. */
next(): DfQuery;
/** Previous element siblings. */
prev(): DfQuery;
/** Read the first element's attribute, or set it on all (`null` removes). */
attr(name: string): string | null | undefined;
attr(name: string, value: string | number | boolean | null): this;
/**
* Read or write IDL properties. Structural properties (innerHTML & co.)
* are refused: those writes must go through morph — use html(), text(),
* or replaceWith() instead.
*/
prop(name: K): K extends keyof T ? T[K] | undefined : unknown;
prop(name: K, value: K extends keyof T ? T[K] : unknown): this;
/** Read or write `data-*` attributes via dataset (`null` deletes). */
data(name: string): string | undefined;
data(name: string, value: string | number | boolean | null): this;
/**
* Read the first element's computed style, or set inline styles on all
* elements (`null` removes a property; camelCase converts to kebab-case).
*/
css(name: string): string | undefined;
css(name: string, value: string | null): this;
css(values: Record): this;
/** Add class tokens to every element. */
addClass(names: string | readonly string[]): this;
/** Remove class tokens; no argument clears the whole class attribute. */
removeClass(names?: string | readonly string[]): this;
/** Toggle class tokens, optionally forced on or off. */
toggleClass(names: string | readonly string[], force?: boolean): this;
/** True when any element carries the class. */
hasClass(name: string): boolean;
/**
* Read or write form control values. Multi-selects read/set string
* arrays; an array on checkboxes/radios toggles `checked` by value.
*/
val(): string | string[] | undefined;
val(value: Value): this;
/**
* FormData for a selection that is exactly one form element. Uses the
* form's own realm constructor so cross-realm forms stay valid; an
* optional submitter contributes its name/value.
*/
form(submitter?: HTMLElement | null): FormData;
/** URL-encoded string of the form's string-valued entries. */
serialize(submitter?: HTMLElement | null): string;
/**
* Morph content into every element. Synchronous and chainable by default;
* passing `transition` is explicitly async and resolves to `this` once
* every element's transition settled. No hidden queue, no thenable.
*/
morph(content: RenderInput, options?: SynchronousMorphOptions): this;
morph(content: RenderInput, options: AsynchronousMorphOptions): Promise;
morph(content: RenderInput, options: MorphOptions): this | Promise;
/**
* First element's (shadow-aware) innerHTML, or morph content into all.
* Accepts the same options as morph(): synchronous and chainable by
* default; passing `transition` returns Promise once every element's
* transition settled.
*/
html(): string | undefined;
html(content: RenderInput, options?: SynchronousMorphOptions): this;
html(content: RenderInput, options: AsynchronousMorphOptions): Promise;
html(content: RenderInput, options: MorphOptions): this | Promise;
/** Concatenated text of the selection, or set literal text on all nodes. */
text(): string;
text(value: string | number | null): this;
/** Remove every child by morphing in an empty list. */
empty(): this;
/** Insert content as the last child of every target. */
append(content: DomContent): this;
/** Insert content as the first child of every target. */
prepend(content: DomContent): this;
/** Insert content before every target. */
before(content: DomContent): this;
/** Insert content after every target. */
after(content: DomContent): this;
/** Replace every target with the content. */
replaceWith(content: DomContent): this;
/** Insert this selection into target(s); selects the inserted nodes. */
appendTo(target: string | QueryRoot | Iterable | ArrayLike): DfQuery;
/** Detach every node, clearing its delegated listeners first. */
remove(): this;
/**
* Attach a handler for one or more event types with native
* addEventListener, so order, stopPropagation, non-bubbling events and
* currentTarget behave exactly as without the facade. Morphing an element
* in place keeps its listeners; morph removing or replacing it, or
* remove(), tears them down.
*/
on>(type: K, handler: Handler[K], Event>>, options?: boolean | QueryEventOptions): this;
on(type: string, handler: Handler, options?: boolean | QueryEventOptions): this;
/**
* Detach handlers registered through on(). No type clears every listener
* the facade registered on the target; no handler clears the whole type.
*/
off>(type: K, handler?: Handler[K], Event>>): this;
off(type?: string, handler?: Handler): this;
/** Dispatch a bubbling, cancelable CustomEvent on every target. */
trigger(type: string, detail?: unknown): this;
}
/**
* Build a `df$` around an injected morph API. Dependency injection keeps
* the query core free of globals and of a second morph copy: the npm entry
* passes the module namespace, the CDN bundle passes the global object that
* morph's own bundle already registered on `window.df$`.
*/
export declare function createDf$(morphApi: M): DfDollar;
/**
* Install `df$` on `target` (the CDN path). Can run before morph loads:
* selectors work immediately, morph capabilities resolve at call time.
*
* Coexistence contract for a pre-existing `df$`:
* - one this module installed before (brand match) is returned unchanged;
* - a plain object — typically the morph CDN bundle's namespace — is
* adopted: its entries are copied onto the callable, preserving morph
* function identities and any custom/symbol props placed there earlier;
* - an unrelated df$ *function* is refused: overwriting someone else's
* global would silently break that script.
*/
export declare function installGlobal(target?: object): DfDollar;
//# sourceMappingURL=query.d.ts.map