web-component-wrapper
Version:
Generic web-component base class and framework specific wrapper.
411 lines (410 loc) • 18.8 kB
TypeScript
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;