UNPKG

web-component-wrapper

Version:

Generic web-component base class and framework specific wrapper.

411 lines (410 loc) 18.8 kB
import { Mapping } from 'clientnode'; import { AttributesReflectionConfiguration, CompiledDomNodeTemplate, ComponentAdapter, EventCallbackMapping, EventToPropertyMapping, NormalizedAttributesReflectionConfiguration, PropertiesConfiguration, ScopeDeclaration, WebComponentAPI } from './type'; export declare const GenericHTMLElement: typeof HTMLElement; /** * Generic web component to render a content against instance specific values. * @property applyRootBinding - If determined itself as root declarative event * and property bindings will be applied to itself. * @property content - Content to render when changes happened. * @property determineRootBinding - If checked this component determines if it * is a root component (not wrapped by another web-component). * @property shadowDOM - Configures if a shadow dom should be used during * web-component instantiation. Can hold initialize configuration. * @property observedAttributes - Attribute names to observe for changes. * @property controllableProperties - A list of controllable property names. * @property eventToPropertyMapping - Explicitly defined output events (a * mapping of event names to a potential parameter to properties transformer). * @property propertyAliases - A mapping of property names to be treated as * equal. * @property propertyTypes - Configuration defining how to convert attributes * into properties and reflect property changes back to attributes. * @property propertiesToReflectAsAttributes - An item, list or mapping of * properties to reflect as attributes. * @property renderProperties - List of known render properties. * @property cloneSlots - Indicates whether to clone slot before to transclude * content into them. If a slot should be used multiple times (for example when * it works as a template node) they should be copied to avoid unexpected * mutations. * @property evaluateSlots - Indicates whether to evaluate slot content when * before rendering them. * @property renderSlots - Indicates whether determined slots should be * rendered into root node. * @property trimSlots - Ignore empty text nodes while applying slots. * @property renderUnsafe - Defines default render behavior. * @property _name - Name to access instance evaluated content or used * to derive default component name. This is also useful for logging. * @property _propertyAliasIndex - Internal alias index to quickly match * properties in both directions. * @property _propertiesToReflectAsAttributes - A mapping of property names to * set as attributes when they are set/updated. Uses a map to hold order and * determine if a property exists in constant runtime. * @property batchAttributeUpdates - Indicates whether to directly update dom * after each attribute mutation or to wait and batch mutations after current * queue has been finished. * @property batchPropertyUpdates - Indicates whether to directly update dom * after each property mutation or to wait and batch mutations after current * queue has been finished. * @property batchUpdates - Indicates whether to directly perform a * re-rendering after changes on properties have been made. * @property batchedAttributeUpdateRunning - A boolean indicator to identify if * an attribute update is currently batched. * @property batchedPropertyUpdateRunning - A boolean indicator to identify if * a property update is currently batched. * @property batchedUpdateRunning - Indicates whether a batched render update * is currently running. * @property parent - Parent component instance. * @property rootInstance - Root component instance. * @property scope - Render scope. * @property domNodeEventBindings - Holds a mapping from nodes with registered * event handlers mapped to their de-registration function. * @property domNodeTemplateCache - Caches template compilation results. * @property externalProperties - Holds currently evaluated or seen properties. * @property ignoreAttributeUpdateObservations - Indicates whether attribute * updates should be considered (usually only needed internally). * @property internalProperties - Holds currently evaluated properties which * are owned by this instance and should always be delegated. * @property outputEventNames - Set of determined output event names. * @property instance - Wrapped component instance. * @property isRoot - Indicates whether their exists another web derived * component up the tree or not. * @property root - Hosting dom node. * @property runDomConnectionAndRenderingInSameEventQueue - Indicates whether * we should render initial dom immediately after the component is connected to * dom. Deactivating this allows wrapped components to detect their parents * since their parent connected callback will be called before the children's * render method. * @property self - Back-reference to this class. * @property slots - Grabbed slots which where present in the connecting phase. */ export declare class Web<TElement = HTMLElement, ExternalProperties extends Mapping<unknown> = Mapping<unknown>, InternalProperties extends Mapping<unknown> = Mapping<unknown>> extends GenericHTMLElement { static applyRootBinding: boolean; static content: unknown; static determineRootBinding: boolean; static shadowDOM: (boolean | null | { delegateFocus?: boolean; mode: 'closed' | 'open'; }); static observedAttributes: Array<string>; static controllableProperties: Array<string>; static eventToPropertyMapping: EventToPropertyMapping | null; static propertyAliases: Mapping; static propertyTypes: PropertiesConfiguration; static propertiesToReflectAsAttributes: AttributesReflectionConfiguration; static renderProperties: Array<string>; static cloneSlots: boolean; static evaluateSlots: boolean; static renderSlots: boolean; static trimSlots: boolean; static renderUnsafe: boolean; static _name: string; static _propertyAliasIndex?: Mapping; static _propertiesToReflectAsAttributes?: NormalizedAttributesReflectionConfiguration; batchAttributeUpdates: boolean; batchPropertyUpdates: boolean; batchUpdates: boolean; batchedAttributeUpdateRunning: boolean; batchedPropertyUpdateRunning: boolean; batchedUpdateRunning: boolean; parent: null | Web; rootInstance: null | Web; scope: Mapping<unknown>; domNodeEventBindings: Map<Node, EventCallbackMapping>; domNodeTemplateCache: CompiledDomNodeTemplate; externalProperties: ExternalProperties; ignoreAttributeUpdateObservations: boolean; internalProperties: InternalProperties; outputEventNames: Set<string>; instance: null | { current?: ComponentAdapter; }; isRoot: boolean; root: ShadowRoot | Web<TElement, ExternalProperties, InternalProperties>; runDomConnectionAndRenderingInSameEventQueue: boolean; readonly self: typeof Web; slots: Mapping<HTMLElement | undefined> & { default?: Array<Node>; }; /** * Initializes host dom content and properties. * @returns Nothing. */ constructor(); /** * Triggered when ever a given attribute has changed and triggers to update * configured dom content. * @param name - Attribute name which was updates. * @param oldValue - Old attribute value. * @param newValue - New updated value. */ attributeChangedCallback(name: string, oldValue: string, newValue: string): void; /** * Updates given attribute representation. * @param name - Attribute name which was updates. * @param newValue - New updated value. */ onUpdateAttribute(name: string, newValue: string): void; /** * Triggered when this component is mounted into the document. * Attaches event handler, grabs given slots, reflects external properties * and enqueues first rendering. */ connectedCallback(): void; /** * Frees some memory. */ disconnectedCallback(): void; /** * Registers needed getter and setter to get notified about changes and * reflect them. */ defineGetterAndSetterInterface(): void; /** * Creates an index to match alias source and target against each other on * constant runtime. * @param name - Name to search an alternate name for. * @returns Found alias or "null". */ getPropertyAlias(name: string): null | string; /** * Generic property getter. Forwards properties from the "properties" * field. * @param name - Property name to retrieve. * @returns Retrieved property value. */ getPropertyValue(name: string): unknown; /** * External property setter. Respects configured aliases. * @param name - Property name to write. * @param value - New value to write. */ setExternalPropertyValue(name: string, value: unknown): void; /** * Internal property setter. Respects configured aliases. * @param name - Property name to write. * @param value - New value to write. */ setInternalPropertyValue(name: string, value: unknown): void; /** * Generic property setter. Forwards field writes into internal and * external property representations. * @param name - Property name to write. * @param value - New value to write. */ setPropertyValue(name: string, value: unknown): void; /** * Triggers a new rendering cycle and respects property specific state * connection. * @param name - Property name to write. * @param value - New value to write. */ triggerPropertySpecificRendering(name: string, value: unknown): void; /** * Binds properties and event handler to given dom node. * @param domNode - Node to start traversing from. * @param scope - Scope to render property value again. */ applyBinding(domNode: Node, scope: Mapping<unknown>): void; /** * Binds properties and event handler to given, sibling and nested nodes. * @param domNode - Node to start traversing from. * @param scope - Scope to render property value again. * @param renderSlots - Indicates whether to render nested elements of * slots (determined by an existing corresponding attribute). */ applyBindings(domNode: Node | null, scope: Mapping<unknown>, renderSlots?: boolean): void; /** * Compiles given node content and their children. Provides corresponding * map of compiled template functions connected to their (sub) nodes and * expected scope names. * @param domNode - Node to compile. * @param scope - Scope to extract names from. * @param options - Additional compile options. * @param options.filter - Callback to exclude some node from being * compiled. * @param options.ignoreComponents - Indicates if component properties * should be traversed or not. * @param options.ignoreNestedComponents - Indicates if nested components * should be traversed or not. * @param options.map - Yet compiled dom nodes to just reference instead of * recompiling. * @param options.unsafe - Indicates if full html generation should be * allowed. * @returns Map of compiled templates. */ compileDomNodeTemplate<NodeType extends Node = Node>(domNode: NodeType, scope?: ScopeDeclaration, options?: { filter?: (domNode: NodeType) => boolean; ignoreComponents?: boolean; ignoreNestedComponents?: boolean; map?: CompiledDomNodeTemplate; unsafe?: boolean; }): CompiledDomNodeTemplate<NodeType>; /** * Compiles and evaluates given node content and their children. Replaces * each node content with their evaluated representation. * @param domNode - Node to evaluate. * @param scope - Scope to render against. * @param options - Compile options. * @param options.applyBindings - Indicates whether to apply bindings to * given dom nodes. * @param options.filter - Callback to exclude some node from being * compiled. * @param options.ignoreComponents - Indicates if component properties * should be traversed or not. * @param options.ignoreNestedComponents - Indicates if nested components * should be traversed or not. * @param options.map - Yet compiled dom nodes to just reference instead of * recompiling. * @param options.unsafe - Indicates if full html generation should be * allowed. * @returns Map of compiled templates. */ evaluateDomNodeTemplate<NodeType extends Node = Node>(domNode: NodeType, scope?: Mapping<unknown>, options?: { applyBindings?: boolean; filter?: (domNode: NodeType) => boolean; ignoreComponents?: boolean; ignoreNestedComponents?: boolean; map?: CompiledDomNodeTemplate; unsafe?: boolean; }): CompiledDomNodeTemplate<NodeType>; /** * Replaces given dom node with given nodes. * @param domNode - Node to replace its children. * @param children - Element or array of elements to set as children. */ static replaceDomNodes(domNode: HTMLElement, children: Array<Node> | Node): void; /** * Moves content of given dom node one level up and removes given node. * @param domNode - Node to unwrap. * @returns List of unwrapped nodes. */ static unwrapDomNode(domNode: HTMLElement): Array<ChildNode>; /** * Determines initial root which initializes rendering digest. */ determineRootBinding(): void; /** * Checks if given content hast code (to compile and render). * @param content - Potential string with code inside. * @returns A boolean indicating whether given content has code. */ static hasCode(content: unknown): boolean; /** * Converts given list, item or map to a map (with ordering). * @param value - Attribute reflection configuration. * @returns Generated map. */ static normalizePropertyTypeList(value: AttributesReflectionConfiguration): NormalizedAttributesReflectionConfiguration; /** * Attaches event handler to keep in sync with nested components properties * states. */ attachEventHandler(): void; /** * Attach explicitly defined event handler to synchronize internal and * external property states. * @returns Returns "true" if there are some defined and "false" otherwise. */ attachExplicitDefinedOutputEventHandler(): boolean; /** * Attach implicitly defined event handler to synchronize internal and * external property states. * @param reflectProperties - Indicates whether implicitly determined * properties should be reflected. */ attachImplicitDefinedOutputEventHandler(reflectProperties?: boolean): void; /** * Triggers all identified events to communicate internal property / state * changes. */ triggerOutputEvents(): void; /** * Forwards given event as native web event. * @param name - Event name. * @param parameters - Event parameters. * @returns False if event is cancelable, and at least one of the event * handlers which received event called "Event.preventDefault()", * otherwise true will be returned. */ forwardEvent(name: string, parameters: Array<unknown>): boolean; /** * Renders component given slot contents into given dom node. If expected * slots are not given but a fallback is specified they will be loaded into * internal slot mapping. * @param targetDomNode - Target dom node to render slots into. * @param scope - Environment to render slots again if specified. */ applySlots(targetDomNode: HTMLElement, scope: Mapping<unknown>): void; /** * Determines slot content from given node. * @param slot - Node to grab slot content from. * @returns Determined slot. */ grabSlotContent(slot: Node): Node; /** * Saves given slots. */ grabGivenSlots(): void; /** * Determines if given property name exists in wrapped component state. * @param name - Property name to check if exists in state. * @returns Boolean result. */ isStateProperty(name: string): boolean; /** * Generates an alias to name and the other way around mapping if not * exists. */ generateAliasIndex(): void; /** * Reflects wrapped component state back to web-component's attributes. * @param properties - Properties to update in reflected attribute state. */ reflectExternalProperties(properties: Partial<ExternalProperties>): void; /** * Reflects wrapped component state back to web-component's attributes and * properties. * @param properties - Properties to update in reflected property state. */ reflectProperties(properties: Partial<ExternalProperties>): void; /** * Reflect given event handler call with given parameter back to current * properties state. * @param name - Event name. * @param parameters - List of parameter to given event handler call. * @returns Mapped properties or null if nothing could be mapped. */ reflectEventToProperties(name: string, parameters: Array<unknown>): Promise<Partial<ExternalProperties> | null>; /** * Evaluates given property value depending on its type specification and * registers in properties mapping object. * @param attributeName - Name of given value. * @param value - Value to evaluate. */ evaluateStringOrNullAndSetAsProperty(attributeName: string, value: null | string): void; /** * Triggers a new rendering cycle by respecting batch configuration. * @param reason - A description why rendering should be triggered. */ triggerRender(reason: string): void; /** * Creates shadow root if not created yet and assigns to current root * property. */ applyShadowRootIfNotExisting(): void; /** * Determines new scope object with useful default set of environment * values. * @param scope - To apply to generated scope. */ determineRenderScope(scope?: Mapping<unknown>): void; /** * Method which does the rendering job. Should be called when ever state * changes should be projected to the hosts dom content. * @param reason - Description why rendering is necessary. * @returns A promise resolving when rendering has finished. A promise may * be needed for classes inheriting from this class. */ render(reason?: string): Promise<void>; } export declare const api: WebComponentAPI<HTMLElement, Mapping<unknown>, Mapping<unknown>, typeof Web>; export default Web;