ivi
Version:
Lightweight Embeddable Web UI Library.
109 lines • 3.79 kB
JavaScript
/**
* Creates an event dispatcher that finds the closest child DOM node and emits
* a CustomEvent with `EventTarget.dispatchEvent()` method.
*
* Event dispatcher invokes event handlers synchronously. All event handlers are
* invoked before event dispatcher returns.
*
* @typeparam T Data type.
* @param eventType Event type.
* @param options {@link DispatchEventOptions}.
* @returns `false` if event is cancelable, and at least one of the event
* handlers which received event called `Event.preventDefault()`. Otherwise
* `true`.
* @__NO_SIDE_EFFECTS__
*/
export const eventDispatcher = (eventType, options) => (component, detail) => (findDOMNode(component).dispatchEvent(new _CustomEvent(eventType, {
bubbles: true,
detail,
...options,
})));
const _CustomEvent = CustomEvent;
/**
* Finds the closest DOM node from a Stateful Tree {@link SNode}.
*
* @typeparam T DOM node type.
* @param sNode Stateful Tree {@link SNode}.
* @returns DOM node.
*/
export const findDOMNode = (sNode) => {
if (sNode === null) {
return null;
}
let flags = sNode.f; // polymorphic call-site
if (flags & (1 /* Flags.Template */ | 16 /* Flags.Text */)) {
return (flags & 1 /* Flags.Template */)
? sNode.s1[0]
: sNode.s1;
}
const children = sNode.c;
if (flags & (8 /* Flags.Array */ | 4 /* Flags.List */)) {
for (let i = 0; i < children.length; i++) {
const c = findDOMNode(children[i]);
if (c !== null) {
return c;
}
}
return null;
}
return findDOMNode(children);
};
/**
* Traverses stateful tree and invokes `visitor` function on each {@link SNode}.
*
* @param sNode {@link SNode}.
* @param visitor Visitor function.
* @returns {@link VisitNodesDirective}
*/
export const visitNodes = (sNode, visitor) => {
let i = visitor(sNode);
if (i !== 0 /* VisitNodesDirective.Continue */) {
return (i & 1 /* VisitNodesDirective.StopImmediate */);
}
const { f, c } = sNode; // polymorphic call-site
if (f & (8 /* Flags.Array */ | 4 /* Flags.List */)) {
for (i = 0; i < c.length; i++) {
if ((sNode = c[i]) !== null &&
(visitNodes(sNode, visitor) & 1 /* VisitNodesDirective.StopImmediate */)) {
return 1 /* VisitNodesDirective.StopImmediate */;
}
}
}
else if (c !== null) {
return visitNodes(c, visitor);
}
return 0 /* VisitNodesDirective.Continue */;
};
/**
* Checks if a Stateful Tree {@link SNode} contains a DOM element.
*
* @param node Stateful Tree {@link SNode}.
* @param element DOM element.
* @returns True when parent contains an element.
*/
export const containsDOMElement = (node, element) => {
var result = false;
visitNodes(node, (sNode) => ((sNode.f & 1 /* Flags.Template */) // polymorphic call-site
? ((sNode.s1[0].contains(element) === true)
? (result = true, 1 /* VisitNodesDirective.StopImmediate */)
: 2 /* VisitNodesDirective.Stop */)
: 0 /* VisitNodesDirective.Continue */));
return result;
};
/**
* Checks if a Stateful Tree {@link SNode} has a child DOM element.
*
* @param node Stateful Tree {@link SNode}.
* @param child DOM element.
* @returns True when parent has a DOM element child.
*/
export const hasDOMElement = (node, child) => {
var result = false;
visitNodes(node, (sNode) => ((sNode.f & 1 /* Flags.Template */) // polymorphic call-site
? ((sNode.s1[0] === child)
? (result = true, 1 /* VisitNodesDirective.StopImmediate */)
: 2 /* VisitNodesDirective.Stop */)
: 0 /* VisitNodesDirective.Continue */));
return result;
};
//# sourceMappingURL=utils.js.map