/** * 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