/*!
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
import { Context } from './rvx.js';
import { Component } from './rvx.js';

/**
 * Check if rvx dom is used in the current context.
 */
declare function isRvxDom(): boolean;

declare const WINDOW_MARKER: unique symbol;

declare const NODE_LENGTH: unique symbol;
declare const NODE_APPEND_HTML_TO: unique symbol;
declare const NODE_CLONE_CHILDREN: unique symbol;
declare const INIT_CLONED_FROM: unique symbol;
declare class NodeList {
	#private;
	constructor(node: Node);
	get length(): number;
	forEach(cb: (node: Node, index: number, list: NodeList) => void, thisArg?: unknown): void;
	[Symbol.iterator](): Iterator<Node>;
	values(): Iterator<Node>;
}
declare class Event {
}
declare class EventTarget {
	addEventListener(): void;
	removeEventListener(): void;
	dispatchEvent(): void;
}
declare class Document extends EventTarget {
	get body(): Element | null;
	get activeElement(): Element | null;
	createTextNode(data: string): Text;
	createComment(data: string): Comment;
	createDocumentFragment(): DocumentFragment;
	createElementNS(namespaceURI: string, tagName: string): Element;
	createElement(tagName: string): Element;
}
declare class Node extends EventTarget {
	#private;
	get parentNode(): Node | null;
	get firstChild(): Node | null;
	get lastChild(): Node | null;
	get previousSibling(): Node | null;
	get nextSibling(): Node | null;
	get childNodes(): NodeList;
	/**
	 * Get the direct number of child nodes.
	 */
	[NODE_LENGTH](): number;
	/**
	 * Append the HTML representation of this node to the specified HTML string.
	 *
	 * @param html An existing HTML string.
	 * @returns The concatenated HTML string.
	 */
	[NODE_APPEND_HTML_TO](html: string): string;
	/**
	 * Deeply clone and append all children of this node to the specified target.
	 */
	[NODE_CLONE_CHILDREN](target: Node): void;
	cloneNode(_deep: boolean): Node;
	contains(node: Node | null): boolean;
	hasChildNodes(): boolean;
	removeChild(node: Node): Node;
	appendChild(node: Node): Node;
	insertBefore(node: Node, ref: Node): Node;
	replaceChild(node: Node, ref: Node): Node;
	remove(): void;
	append(...nodes: (Node | string)[]): void;
	replaceChildren(...nodes: (Node | string)[]): void;
	get textContent(): string;
	get outerHTML(): string;
}
interface Node {
	nodeType: number;
	nodeName: string;
}
declare class DocumentFragment extends Node {
	cloneNode(deep: boolean): Node;
}
/**
 * A context that controls if newly created comment nodes are visible in rendered html.
 *
 * **SECURITY:** Comment data is not escaped when rendering and can be used to produce invalid or malicious HTML.
 *
 * @default false
 */
declare const VISIBLE_COMMENTS: Context<boolean>;
declare class Comment extends Node {
	#private;
	constructor(data: string);
	/**
	 * Get or set comment data.
	 *
	 * **SECURITY:** Comment data is not escaped when rendering and can be used to produce invalid or malicious HTML.
	 */
	get textContent(): string;
	set textContent(data: string);
	cloneNode(_deep: boolean): Node;
	[NODE_APPEND_HTML_TO](html: string): string;
}
declare class Text extends Node {
	#private;
	constructor(data: string);
	get textContent(): string;
	set textContent(data: string);
	cloneNode(_deep: boolean): Node;
	[NODE_APPEND_HTML_TO](html: string): string;
}
declare const ATTR_CHANGED: unique symbol;
interface Attribute {
	name: string;
	value: string;
	stale: boolean;
}
declare class ElementClassList {
	#private;
	constructor(attrs: Attribute[]);
	[INIT_CLONED_FROM](from: ElementClassList): void;
	get length(): number;
	get value(): string;
	[ATTR_CHANGED](attr: Attribute | null): void;
	add(...tokens: string[]): void;
	contains(token: string): boolean;
	remove(...tokens: string[]): void;
	replace(oldToken: string, newToken: string): boolean;
	toggle(token: string, force?: boolean): boolean;
	values(): IterableIterator<string>;
	[Symbol.iterator](): IterableIterator<string>;
}
declare class ElementStyles {
	#private;
	constructor(attrs: Attribute[]);
	[INIT_CLONED_FROM](from: ElementStyles): void;
	get cssText(): string;
	[ATTR_CHANGED](attr: Attribute | null): void;
	setProperty(name: string, value: unknown, priority?: "" | "important"): void;
	removeProperty(name: string): string;
	getPropertyValue(name: string): string;
}
declare class Element extends Node {
	#private;
	constructor(namespaceURI: string, tagName: string);
	get tagName(): string;
	get nodeName(): string;
	get namespaceURI(): string;
	/**
	 * Get or set inner HTML of this element.
	 *
	 * When set to a non-empty string, all children are replaced with a {@link RawHTML} node.
	 */
	get innerHTML(): string;
	set innerHTML(html: string);
	get classList(): ElementClassList;
	get style(): ElementStyles;
	cloneNode(deep: boolean): Node;
	focus(): void;
	blur(): void;
	setAttribute(name: string, value: string): void;
	removeAttribute(name: string): void;
	toggleAttribute(name: string, force?: boolean): void;
	getAttribute(name: string): string | null;
	hasAttribute(name: string): boolean;
	[NODE_APPEND_HTML_TO](html: string): string;
}
declare class RawHTML extends Node {
	#private;
	constructor(html: string);
	cloneNode(_deep: boolean): Node;
	[NODE_APPEND_HTML_TO](html: string): string;
}
declare class Window extends EventTarget {
	window: this;
	document: Document;
}
interface Window {
	[WINDOW_MARKER]: boolean;
	Comment: typeof Comment;
	CustomEvent: typeof Event;
	Document: typeof Document;
	DocumentFragment: typeof DocumentFragment;
	Element: typeof Element;
	Event: typeof Event;
	Node: typeof Node;
	Text: typeof Text;
}
/**
 * A global default rvxdom window instance.
 */
declare const WINDOW: Window;

/**
 * Render a component to HTML using rvx dom.
 */
declare function renderToString(component: Component): string;
declare function renderToString<P>(component: Component<P>, props: P): string;
/**
 * Render a component to HTML using rvx dom.
 *
 * This provides a new {@link AsyncContext} to wait for rendering to complete.
 */
declare function renderToStringAsync(component: Component): Promise<string>;
declare function renderToStringAsync<P>(component: Component<P>, props: P): Promise<string>;

export { Comment, Document, DocumentFragment, Element, ElementClassList, ElementStyles, Event, EventTarget, Node, NodeList, RawHTML, Text, VISIBLE_COMMENTS, WINDOW, Window, isRvxDom, renderToString, renderToStringAsync };
