/**
 * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module ui/template
 */
import View from './view.js';
import ViewCollection from './viewcollection.js';
import { type ArrayOrItem, type Emitter, type Observable } from '@ckeditor/ckeditor5-utils';
declare const Template_base: {
    new (): Emitter;
    prototype: Emitter;
};
/**
 * A basic Template class. It renders a DOM HTML element or text from a
 * {@link module:ui/template~TemplateDefinition definition} and supports element attributes, children,
 * bindings to {@link module:utils/observablemixin~Observable observables} and DOM event propagation.
 *
 * A simple template can look like this:
 *
 * ```ts
 * const bind = Template.bind( observable, emitter );
 *
 * new Template( {
 * 	tag: 'p',
 * 	attributes: {
 * 		class: 'foo',
 * 		style: {
 * 			backgroundColor: 'yellow'
 * 		}
 * 	},
 * 	on: {
 * 		click: bind.to( 'clicked' )
 * 	},
 * 	children: [
 * 		'A paragraph.'
 * 	]
 * } ).render();
 * ```
 *
 * and it will render the following HTML element:
 *
 * ```html
 * <p class="foo" style="background-color: yellow;">A paragraph.</p>
 * ```
 *
 * Additionally, the `observable` will always fire `clicked` upon clicking `<p>` in the DOM.
 *
 * See {@link module:ui/template~TemplateDefinition} to know more about templates and complex
 * template definitions.
 */
export default class Template extends Template_base {
    ns?: string;
    /**
     * The tag (`tagName`) of this template, e.g. `div`. It also indicates that the template
     * renders to an HTML element.
     */
    tag?: string;
    /**
     * The text of the template. It also indicates that the template renders to a DOM text node.
     */
    text?: Array<TemplateSimpleValue | TemplateBinding>;
    /**
     * The attributes of the template, e.g. `{ id: [ 'ck-id' ] }`, corresponding with
     * the attributes of an HTML element.
     *
     * **Note**: This property only makes sense when {@link #tag} is defined.
     */
    attributes?: Record<string, AttributeValues>;
    /**
     * The children of the template. They can be either:
     * * independent instances of {@link ~Template} (sub–templates),
     * * native DOM Nodes.
     *
     * **Note**: This property only makes sense when {@link #tag} is defined.
     */
    children?: Array<ViewCollection | View | Node | Template>;
    /**
     * The DOM event listeners of the template.
     */
    eventListeners?: Record<string, Array<TemplateToBinding>>;
    /**
     * Indicates whether this particular Template instance has been
     * {@link #render rendered}.
     */
    private _isRendered;
    /**
     * The data used by the {@link #revert} method to restore a node to its original state.
     *
     * See: {@link #apply}.
     */
    private _revertData;
    /**
     * Creates an instance of the {@link ~Template} class.
     *
     * @param def The definition of the template.
     */
    constructor(def: TemplateDefinition);
    /**
     * Renders a DOM Node (an HTML element or text) out of the template.
     *
     * ```ts
     * const domNode = new Template( { ... } ).render();
     * ```
     *
     * See: {@link #apply}.
     */
    render(): HTMLElement | Text;
    /**
     * Applies the template to an existing DOM Node, either HTML element or text.
     *
     * **Note:** No new DOM nodes will be created. Applying extends:
     *
     * {@link module:ui/template~TemplateDefinition attributes},
     * {@link module:ui/template~TemplateDefinition event listeners}, and
     * `textContent` of {@link module:ui/template~TemplateDefinition children} only.
     *
     * **Note:** Existing `class` and `style` attributes are extended when a template
     * is applied to an HTML element, while other attributes and `textContent` are overridden.
     *
     * **Note:** The process of applying a template can be easily reverted using the
     * {@link module:ui/template~Template#revert} method.
     *
     * ```ts
     * const element = document.createElement( 'div' );
     * const observable = new Model( { divClass: 'my-div' } );
     * const emitter = Object.create( EmitterMixin );
     * const bind = Template.bind( observable, emitter );
     *
     * new Template( {
     * 	attributes: {
     * 		id: 'first-div',
     * 		class: bind.to( 'divClass' )
     * 	},
     * 	on: {
     * 		click: bind( 'elementClicked' ) // Will be fired by the observable.
     * 	},
     * 	children: [
     * 		'Div text.'
     * 	]
     * } ).apply( element );
     *
     * console.log( element.outerHTML ); // -> '<div id="first-div" class="my-div"></div>'
     * ```
     *
     * @see module:ui/template~Template#render
     * @see module:ui/template~Template#revert
     * @param node Root node for the template to apply.
     */
    apply(node: HTMLElement | Text): HTMLElement | Text;
    /**
     * Reverts a template {@link module:ui/template~Template#apply applied} to a DOM node.
     *
     * @param node The root node for the template to revert. In most of the cases, it is the
     * same node used by {@link module:ui/template~Template#apply}.
     */
    revert(node: HTMLElement | Text): void;
    /**
     * Returns an iterator which traverses the template in search of {@link module:ui/view~View}
     * instances and returns them one by one.
     *
     * ```ts
     * const viewFoo = new View();
     * const viewBar = new View();
     * const viewBaz = new View();
     * const template = new Template( {
     * 	tag: 'div',
     * 	children: [
     * 		viewFoo,
     * 		{
     * 			tag: 'div',
     * 			children: [
     * 				viewBar
     * 			]
     * 		},
     * 		viewBaz
     * 	]
     * } );
     *
     * // Logs: viewFoo, viewBar, viewBaz
     * for ( const view of template.getViews() ) {
     * 	console.log( view );
     * }
     * ```
     */
    getViews(): IterableIterator<View>;
    /**
     * An entry point to the interface which binds DOM nodes to
     * {@link module:utils/observablemixin~Observable observables}.
     * There are two types of bindings:
     *
     * * HTML element attributes or text `textContent` synchronized with attributes of an
     * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}
     * and {@link module:ui/template~BindChain#if}.
     *
     * ```ts
     * const bind = Template.bind( observable, emitter );
     *
     * new Template( {
     * 	attributes: {
     * 		// Binds the element "class" attribute to observable#classAttribute.
     * 		class: bind.to( 'classAttribute' )
     * 	}
     * } ).render();
     * ```
     *
     * * DOM events fired on HTML element propagated through
     * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}.
     *
     * ```ts
     * const bind = Template.bind( observable, emitter );
     *
     * new Template( {
     * 	on: {
     * 		// Will be fired by the observable.
     * 		click: bind( 'elementClicked' )
     * 	}
     * } ).render();
     * ```
     *
     * Also see {@link module:ui/view~View#bindTemplate}.
     *
     * @param observable An observable which provides boundable attributes.
     * @param emitter An emitter that listens to observable attribute
     * changes or DOM Events (depending on the kind of the binding). Usually, a {@link module:ui/view~View} instance.
     */
    static bind<TObservable extends Observable>(observable: TObservable, emitter: Emitter): BindChain<TObservable>;
    /**
     * Extends an existing {@link module:ui/template~Template} instance with some additional content
     * from another {@link module:ui/template~TemplateDefinition}.
     *
     * ```ts
     * const bind = Template.bind( observable, emitter );
     *
     * const template = new Template( {
     * 	tag: 'p',
     * 	attributes: {
     * 		class: 'a',
     * 		data-x: bind.to( 'foo' )
     * 	},
     * 	children: [
     * 		{
     * 			tag: 'span',
     * 			attributes: {
     * 				class: 'b'
     * 			},
     * 			children: [
     * 				'Span'
     * 			]
     * 		}
     * 	]
     *  } );
     *
     * // Instance-level extension.
     * Template.extend( template, {
     * 	attributes: {
     * 		class: 'b',
     * 		data-x: bind.to( 'bar' )
     * 	},
     * 	children: [
     * 		{
     * 			attributes: {
     * 				class: 'c'
     * 			}
     * 		}
     * 	]
     * } );
     *
     * // Child extension.
     * Template.extend( template.children[ 0 ], {
     * 	attributes: {
     * 		class: 'd'
     * 	}
     * } );
     * ```
     *
     * the `outerHTML` of `template.render()` is:
     *
     * ```html
     * <p class="a b" data-x="{ observable.foo } { observable.bar }">
     * 	<span class="b c d">Span</span>
     * </p>
     * ```
     *
     * @param template An existing template instance to be extended.
     * @param def Additional definition to be applied to a template.
     */
    static extend(template: Template, def: Partial<TemplateDefinition>): void;
    /**
     * Renders a DOM Node (either an HTML element or text) out of the template.
     *
     * @param data Rendering data.
     */
    private _renderNode;
    /**
     * Renders an HTML element out of the template.
     *
     * @param data Rendering data.
     */
    private _renderElement;
    /**
     * Renders a text node out of {@link module:ui/template~Template#text}.
     *
     * @param data Rendering data.
     */
    private _renderText;
    /**
     * Renders HTML element attributes out of {@link module:ui/template~Template#attributes}.
     *
     * @param data Rendering data.
     */
    private _renderAttributes;
    /**
     * Renders the `style` attribute of an HTML element based on
     * {@link module:ui/template~Template#attributes}.
     *
     * A style attribute is an object with static values:
     *
     * ```ts
     * attributes: {
     * 	style: {
     * 		color: 'red'
     * 	}
     * }
     * ```
     *
     * or values bound to {@link module:ui/model~Model} properties:
     *
     * ```ts
     * attributes: {
     * 	style: {
     * 		color: bind.to( ... )
     * 	}
     * }
     * ```
     *
     * Note: The `style` attribute is rendered without setting the namespace. It does not seem to be
     * needed.
     *
     * @param styles Styles located in `attributes.style` of {@link module:ui/template~TemplateDefinition}.
     * @param data Rendering data.
     */
    private _renderStyleAttribute;
    /**
     * Recursively renders HTML element's children from {@link module:ui/template~Template#children}.
     *
     * @param data Rendering data.
     */
    private _renderElementChildren;
    /**
     * Activates `on` event listeners from the {@link module:ui/template~TemplateDefinition}
     * on an HTML element.
     *
     * @param data Rendering data.
     */
    private _setUpListeners;
    /**
     * For a given {@link module:ui/template~TemplateValueSchema} containing {@link module:ui/template~TemplateBinding}
     * activates the binding and sets its initial value.
     *
     * Note: {@link module:ui/template~TemplateValueSchema} can be for HTML element attributes or
     * text node `textContent`.
     *
     * @param options Binding options.
     * @param options.updater A function which updates the DOM (like attribute or text).
     * @param options.data Rendering data.
     */
    private _bindToObservable;
    /**
     * Reverts {@link module:ui/template~RenderData#revertData template data} from a node to
     * return it to the original state.
     *
     * @param node A node to be reverted.
     * @param revertData An object that stores information about what changes have been made by
     * {@link #apply} to the node. See {@link module:ui/template~RenderData#revertData} for more information.
     */
    private _revertTemplateFromNode;
}
type AttributeValues = Array<TemplateSimpleValue | TemplateBinding> | [
    NamespacedValue<Array<TemplateSimpleValue | TemplateBinding>>
];
/**
 * Describes a binding created by the {@link module:ui/template~Template.bind} interface.
 *
 * @internal
 */
export declare abstract class TemplateBinding {
    /**
     * The name of the {@link module:ui/template~TemplateBinding#observable observed attribute}.
     */
    readonly attribute: string;
    /**
     * An observable instance of the binding. It either:
     *
     * * provides the attribute with the value,
     * * or passes the event when a corresponding DOM event is fired.
     */
    readonly observable: Observable;
    /**
     * An {@link module:utils/emittermixin~Emitter} used by the binding to:
     *
     * * listen to the attribute change in the {@link module:ui/template~TemplateBinding#observable},
     * * or listen to the event in the DOM.
     */
    readonly emitter: Emitter;
    /**
     * A custom function to process the value of the {@link module:ui/template~TemplateBinding#attribute}.
     */
    readonly callback?: (value: any, node: Node) => TemplateSimpleValue;
    /**
     * Creates an instance of the {@link module:ui/template~TemplateBinding} class.
     *
     * @param def The definition of the binding.
     */
    constructor(def: {
        attribute: string;
        observable: Observable;
        emitter: Emitter;
        callback?: (value: any, node: Node) => TemplateSimpleValue;
    });
    /**
     * Returns the value of the binding. It is the value of the {@link module:ui/template~TemplateBinding#attribute} in
     * {@link module:ui/template~TemplateBinding#observable}. The value may be processed by the
     * {@link module:ui/template~TemplateBinding#callback}, if such has been passed to the binding.
     *
     * @param node A native DOM node, passed to the custom {@link module:ui/template~TemplateBinding#callback}.
     * @returns The value of {@link module:ui/template~TemplateBinding#attribute} in
     * {@link module:ui/template~TemplateBinding#observable}.
     */
    getValue(node: Node): TemplateSimpleValue;
    /**
     * Activates the listener which waits for changes of the {@link module:ui/template~TemplateBinding#attribute} in
     * {@link module:ui/template~TemplateBinding#observable}, then updates the DOM with the aggregated
     * value of {@link module:ui/template~TemplateValueSchema}.
     *
     * @param schema A full schema to generate an attribute or text in the DOM.
     * @param updater A DOM updater function used to update the native DOM attribute or text.
     * @param data Rendering data.
     * @returns A function to sever the listener binding.
     */
    activateAttributeListener(schema: Array<TemplateSimpleValue | TemplateBinding>, updater: Updater, data: RenderData): () => void;
}
/**
 * Describes either:
 *
 * * a binding to an {@link module:utils/observablemixin~Observable},
 * * or a native DOM event binding.
 *
 * It is created by the {@link module:ui/template~BindChain#to} method.
 *
 * @internal
 */
export declare class TemplateToBinding extends TemplateBinding {
    readonly eventNameOrFunction: string | ((domEvent: Event) => void);
    constructor(def: ConstructorParameters<typeof TemplateBinding>[0] & {
        eventNameOrFunction: string | ((domEvent: Event) => void);
    });
    /**
     * Activates the listener for the native DOM event, which when fired, is propagated by
     * the {@link module:ui/template~TemplateBinding#emitter}.
     *
     * @param domEvtName The name of the native DOM event.
     * @param domSelector The selector in the DOM to filter delegated events.
     * @param data Rendering data.
     * @returns A function to sever the listener binding.
     */
    activateDomEventListener(domEvtName: string, domSelector: string, data: {
        node: any;
    }): () => void;
}
/**
 * Describes a binding to {@link module:utils/observablemixin~Observable} created by the {@link module:ui/template~BindChain#if}
 * method.
 *
 * @internal
 */
export declare class TemplateIfBinding extends TemplateBinding {
    /**
     * The value of the DOM attribute or text to be set if the {@link module:ui/template~TemplateBinding#attribute} in
     * {@link module:ui/template~TemplateBinding#observable} is `true`.
     */
    readonly valueIfTrue?: string;
    constructor(def: ConstructorParameters<typeof TemplateBinding>[0] & {
        valueIfTrue?: string;
    });
    /**
     * @inheritDoc
     */
    getValue(node: Node): TemplateSimpleValue;
}
interface Updater {
    set(value: any): void;
    remove(): void;
}
/**
 * A definition of the {@link module:ui/template~Template}. It describes what kind of
 * node a template will render (HTML element or text), attributes of an element, DOM event
 * listeners and children.
 *
 * Also see:
 * * {@link module:ui/template~TemplateValueSchema} to learn about HTML element attributes,
 * * {@link module:ui/template~TemplateListenerSchema} to learn about DOM event listeners.
 *
 * A sample definition on an HTML element can look like this:
 *
 * ```ts
 * new Template( {
 * 	tag: 'p',
 * 	children: [
 * 		{
 * 			tag: 'span',
 * 			attributes: { ... },
 * 			children: [ ... ],
 * 		},
 * 		{
 * 			text: 'static–text'
 * 		},
 * 		'also-static–text',
 * 	],
 * 	attributes: {
 * 		class: {@link module:ui/template~TemplateValueSchema},
 * 		id: {@link module:ui/template~TemplateValueSchema},
 * 		style: {@link module:ui/template~TemplateValueSchema}
 *
 * 		// ...
 * 	},
 * 	on: {
 * 		'click': {@link module:ui/template~TemplateListenerSchema}
 *
 * 		// Document.querySelector format is also accepted.
 * 		'keyup@a.some-class': {@link module:ui/template~TemplateListenerSchema}
 *
 * 		// ...
 * 	}
 * } );
 * ```
 *
 * A {@link module:ui/view~View}, another {@link module:ui/template~Template} or a native DOM node
 * can also become a child of a template. When a view is passed, its {@link module:ui/view~View#element} is used:
 *
 * ```ts
 * const view = new SomeView();
 * const childTemplate = new Template( { ... } );
 * const childNode = document.createElement( 'b' );
 *
 * new Template( {
 * 	tag: 'p',
 *
 * 	children: [
 * 		// view#element will be added as a child of this <p>.
 * 		view,
 *
 * 		// The output of childTemplate.render() will be added here.
 * 		childTemplate,
 *
 * 		// Native DOM nodes are included directly in the rendered output.
 * 		childNode
 * 	]
 * } );
 * ```
 *
 * An entire {@link module:ui/viewcollection~ViewCollection} can be used as a child in the definition:
 *
 * ```ts
 * const collection = new ViewCollection();
 * collection.add( someView );
 *
 * new Template( {
 * 	tag: 'p',
 *
 * 	children: collection
 * } );
 * ```
 */
export type TemplateDefinition = string | Template | TemplateElementDefinition | TemplateTextDefinition;
export type TemplateElementDefinition = {
    /**
     * See the template {@link module:ui/template~Template#tag} property.
     */
    tag: string;
    /**
     * See the template {@link module:ui/template~Template#attributes} property.
     */
    attributes?: Record<string, TemplateValueSchema>;
    /**
     * See the template {@link module:ui/template~Template#children} property.
     */
    children?: Iterable<View | Node | Template | TemplateDefinition>;
    /**
     * See the template {@link module:ui/template~Template#eventListeners} property.
     */
    on?: Record<string, TemplateListenerSchema>;
};
export type TemplateTextDefinition = {
    /**
     * See the template {@link module:ui/template~Template#text} property.
     */
    text: ArrayOrItem<TemplateSimpleValueSchema>;
};
export type FalsyValue = false | null | undefined | '';
export type NamespacedValue<T> = {
    ns: string;
    value: T;
};
export type TemplateSimpleValue = string | boolean | number | null | undefined;
export type TemplateSimpleValueSchema = TemplateSimpleValue | AttributeBinding;
/**
 * Describes a value of an HTML element attribute or `textContent`. It allows combining multiple
 * data sources like static values and {@link module:utils/observablemixin~Observable} attributes.
 *
 * Also see:
 * * {@link module:ui/template~TemplateDefinition} to learn where to use it,
 * * {@link module:ui/template~Template.bind} to learn how to configure
 * {@link module:utils/observablemixin~Observable} attribute bindings,
 * * {@link module:ui/template~Template#render} to learn how to render a template,
 * * {@link module:ui/template~BindChain#to `to()`} and {@link module:ui/template~BindChain#if `if()`}
 * methods to learn more about bindings.
 *
 * Attribute values can be described in many different ways:
 *
 * ```ts
 * // Bind helper will create bindings to attributes of the observable.
 * const bind = Template.bind( observable, emitter );
 *
 * new Template( {
 * 	tag: 'p',
 * 	attributes: {
 * 		// A plain string schema.
 * 		'class': 'static-text',
 *
 * 		// An object schema, binds to the "foo" attribute of the
 * 		// observable and follows its value.
 * 		'class': bind.to( 'foo' ),
 *
 * 		// An array schema, combines the above.
 * 		'class': [
 * 			'static-text',
 * 			bind.to( 'bar', () => { ... } ),
 *
 * 			// Bindings can also be conditional.
 * 			bind.if( 'baz', 'class-when-baz-is-true' )
 * 		],
 *
 * 		// An array schema, with a custom namespace, e.g. useful for creating SVGs.
 * 		'class': {
 * 			ns: 'http://ns.url',
 * 			value: [
 * 				bind.if( 'baz', 'value-when-true' ),
 * 				'static-text'
 * 			]
 * 		},
 *
 * 		// An object schema, specific for styles.
 * 		style: {
 * 			color: 'red',
 * 			backgroundColor: bind.to( 'qux', () => { ... } )
 * 		}
 * 	}
 * } );
 * ```
 *
 * Text nodes can also have complex values:
 *
 * ```ts
 * const bind = Template.bind( observable, emitter );
 *
 * // Will render a "foo" text node.
 * new Template( {
 * 	text: 'foo'
 * } );
 *
 * // Will render a "static text: {observable.foo}" text node.
 * // The text of the node will be updated as the "foo" attribute changes.
 * new Template( {
 * 	text: [
 * 		'static text: ',
 * 		bind.to( 'foo', () => { ... } )
 * 	]
 * } );
 * ```
 */
export type TemplateValueSchema = ArrayOrItem<TemplateSimpleValueSchema | NamespacedValue<TemplateSimpleValueSchema>> | Record<string, TemplateSimpleValueSchema>;
/**
 * Describes an event listener attached to an HTML element. Such listener can propagate DOM events
 * through an {@link module:utils/observablemixin~Observable} instance, execute custom callbacks
 * or both, if necessary.
 *
 * Also see:
 * * {@link module:ui/template~TemplateDefinition} to learn more about template definitions,
 * * {@link module:ui/template~BindChain#to `to()`} method to learn more about bindings.
 *
 * Check out different ways of attaching event listeners below:
 *
 * ```ts
 * // Bind helper will propagate events through the observable.
 * const bind = Template.bind( observable, emitter );
 *
 * new Template( {
 * 	tag: 'p',
 * 	on: {
 * 		// An object schema. The observable will fire the "clicked" event upon DOM "click".
 * 		click: bind.to( 'clicked' )
 *
 * 		// An object schema. It will work for "click" event on "a.foo" children only.
 * 		'click@a.foo': bind.to( 'clicked' )
 *
 * 		// An array schema, makes the observable propagate multiple events.
 * 		click: [
 * 			bind.to( 'clicked' ),
 * 			bind.to( 'executed' )
 * 		],
 *
 * 		// An array schema with a custom callback.
 * 		'click@a.foo': {
 * 			bind.to( 'clicked' ),
 * 			bind.to( evt => {
 * 				console.log( `${ evt.target } has been clicked!` );
 * 			} }
 * 		}
 * 	}
 * } );
 * ```
 */
export type TemplateListenerSchema = ArrayOrItem<ListenerBinding>;
declare const AttributeBindingSymbol: unique symbol;
declare const ListenerBindingSymbol: unique symbol;
export interface AttributeBinding {
    _opaqueAttributeBinding: typeof AttributeBindingSymbol;
}
export interface ListenerBinding {
    _opaqueListenerBinding: typeof ListenerBindingSymbol;
}
/**
 * The return value of {@link ~Template.bind `Template.bind()`}. It provides `to()` and `if()`
 * methods to create the {@link module:utils/observablemixin~Observable observable} attribute and event bindings.
 */
export interface BindChain<TObservable> {
    /**
     * Binds an {@link module:utils/observablemixin~Observable observable} to either:
     *
     * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable
     * attribute as it changes,
     * * or an HTML element DOM event, so the DOM events are propagated through an observable.
     *
     * Some common use cases of `to()` bindings are presented below:
     *
     * ```ts
     * const bind = Template.bind( observable, emitter );
     *
     * new Template( {
     * 	tag: 'p',
     * 	attributes: {
     * 		// class="..." attribute gets bound to `observable#a`
     * 		class: bind.to( 'a' )
     * 	},
     * 	children: [
     * 		// <p>...</p> gets bound to observable#b; always `toUpperCase()`.
     * 		{
     * 			text: bind.to( 'b', ( value, node ) => value.toUpperCase() )
     * 		}
     * 	],
     * 	on: {
     * 		click: [
     * 			// An observable will fire "clicked" upon "click" in the DOM.
     * 			bind.to( 'clicked' ),
     *
     * 			// A custom callback will be executed upon "click" in the DOM.
     * 			bind.to( () => {
     * 				...
     * 			} )
     * 		]
     * 	}
     * } ).render();
     * ```
     *
     * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and
     * {@link module:ui/template~TemplateListenerSchema}.
     *
     * @label ATTRIBUTE
     * @param attribute An attribute name of {@link module:utils/observablemixin~Observable}.
     */
    to<TAttribute extends keyof TObservable & string>(attribute: TAttribute): AttributeBinding & ListenerBinding;
    /**
     * Binds an {@link module:utils/observablemixin~Observable observable} to either:
     *
     * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable
     * attribute as it changes,
     * * or an HTML element DOM event, so the DOM events are propagated through an observable.
     *
     * Some common use cases of `to()` bindings are presented below:
     *
     * ```ts
     * const bind = Template.bind( observable, emitter );
     *
     * new Template( {
     * 	tag: 'p',
     * 	attributes: {
     * 		// class="..." attribute gets bound to `observable#a`
     * 		class: bind.to( 'a' )
     * 	},
     * 	children: [
     * 		// <p>...</p> gets bound to observable#b; always `toUpperCase()`.
     * 		{
     * 			text: bind.to( 'b', ( value, node ) => value.toUpperCase() )
     * 		}
     * 	],
     * 	on: {
     * 		click: [
     * 			// An observable will fire "clicked" upon "click" in the DOM.
     * 			bind.to( 'clicked' ),
     *
     * 			// A custom callback will be executed upon "click" in the DOM.
     * 			bind.to( () => {
     * 				...
     * 			} )
     * 		]
     * 	}
     * } ).render();
     * ```
     *
     * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and
     * {@link module:ui/template~TemplateListenerSchema}.
     *
     * @label ATTRIBUTE_CALLBACK
     * @param attribute An attribute name of {@link module:utils/observablemixin~Observable}.
     * @param callback Allows for processing of the value. Accepts `Node` and `value` as arguments.
     */
    to<TAttribute extends keyof TObservable & string>(attribute: TAttribute, callback: (value: TObservable[TAttribute], node: Node) => (TemplateSimpleValue)): AttributeBinding;
    /**
     * Binds an {@link module:utils/observablemixin~Observable observable} to either:
     *
     * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable
     * attribute as it changes,
     * * or an HTML element DOM event, so the DOM events are propagated through an observable.
     *
     * Some common use cases of `to()` bindings are presented below:
     *
     * ```ts
     * const bind = Template.bind( observable, emitter );
     *
     * new Template( {
     * 	tag: 'p',
     * 	attributes: {
     * 		// class="..." attribute gets bound to `observable#a`
     * 		class: bind.to( 'a' )
     * 	},
     * 	children: [
     * 		// <p>...</p> gets bound to observable#b; always `toUpperCase()`.
     * 		{
     * 			text: bind.to( 'b', ( value, node ) => value.toUpperCase() )
     * 		}
     * 	],
     * 	on: {
     * 		click: [
     * 			// An observable will fire "clicked" upon "click" in the DOM.
     * 			bind.to( 'clicked' ),
     *
     * 			// A custom callback will be executed upon "click" in the DOM.
     * 			bind.to( () => {
     * 				...
     * 			} )
     * 		]
     * 	}
     * } ).render();
     * ```
     *
     * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and
     * {@link module:ui/template~TemplateListenerSchema}.
     *
     * @label EVENT
     * @param eventNameOrCallback A DOM event name or an event callback.
     */
    to(eventNameOrCallback: string | ((domEvent: Event) => void)): ListenerBinding;
    /**
     * Binds an {@link module:utils/observablemixin~Observable observable} to an HTML element attribute or a text
     * node `textContent` so it remains in sync with the observable attribute as it changes.
     *
     * Unlike {@link module:ui/template~BindChain#to}, it controls the presence of the attribute or `textContent`
     * depending on the "falseness" of an {@link module:utils/observablemixin~Observable} attribute.
     *
     * ```ts
     * const bind = Template.bind( observable, emitter );
     *
     * new Template( {
     * 	tag: 'input',
     * 	attributes: {
     * 		// <input checked> when `observable#a` is not undefined/null/false/''
     * 		// <input> when `observable#a` is undefined/null/false
     * 		checked: bind.if( 'a' )
     * 	},
     * 	children: [
     * 		{
     * 			// <input>"b-is-not-set"</input> when `observable#b` is undefined/null/false/''
     * 			// <input></input> when `observable#b` is not "falsy"
     * 			text: bind.if( 'b', 'b-is-not-set', ( value, node ) => !value )
     * 		}
     * 	]
     * } ).render();
     * ```
     *
     * Learn more about using `if()` in the {@link module:ui/template~TemplateValueSchema}.
     *
     * @param attribute An attribute name of {@link module:utils/observablemixin~Observable} used in the binding.
     * @param valueIfTrue Value set when the {@link module:utils/observablemixin~Observable} attribute is not
     * undefined/null/false/'' (empty string).
     * @param callback Allows for processing of the value. Accepts `Node` and `value` as arguments.
     */
    if<TAttribute extends keyof TObservable & string>(attribute: TAttribute, valueIfTrue?: unknown, callback?: (value: TObservable[TAttribute], node: Node) => (boolean | FalsyValue)): AttributeBinding;
}
/**
 * The {@link module:ui/template~Template#_renderNode} configuration.
 */
export interface RenderData {
    /**
     * A node which is being rendered.
     */
    node: HTMLElement | Text;
    /**
     * Tells {@link module:ui/template~Template#_renderNode} to render
     * children into `DocumentFragment` first and then append the fragment
     * to the parent element. It is a speed optimization.
     */
    intoFragment: boolean;
    /**
     * Indicates whether the {@link #node} has been provided by {@link module:ui/template~Template#apply}.
     */
    isApplying: boolean;
    /**
     * An object storing the data that helps {@link module:ui/template~Template#revert}
     * bringing back an element to its initial state, i.e. before
     * {@link module:ui/template~Template#apply} was called.
     */
    revertData?: RevertData;
}
interface RevertData {
    text?: string | null;
    children: Array<RevertData>;
    bindings: Array<Array<() => void>>;
    attributes: Record<string, string | null>;
}
export {};
