/**
* Helper to listen to multiple DOM events
*/
-export function onEvents(listenerElement: Element, events: string[], callback: (e: Event) => any): void {
- for (const eventName of events) {
- listenerElement.addEventListener(eventName, callback);
+export function onEvents(listenerElement: Element|null, events: string[], callback: (e: Event) => any): void {
+ if (listenerElement) {
+ for (const eventName of events) {
+ listenerElement.addEventListener(eventName, callback);
+ }
}
}
return firstChild;
}
+
+export function normalizeNodeTextOffsetToParent(node: Node, offset: number, parentElement: HTMLElement): number {
+ if (!parentElement.contains(node)) {
+ throw new Error('ParentElement must be a prent of element');
+ }
+
+ let normalizedOffset = offset;
+ let currentNode: Node|null = node.nodeType === Node.TEXT_NODE ?
+ node : node.childNodes[offset];
+
+ while (currentNode !== parentElement && currentNode) {
+ if (currentNode.previousSibling) {
+ currentNode = currentNode.previousSibling;
+ normalizedOffset += (currentNode.textContent?.length || 0);
+ } else {
+ currentNode = currentNode.parentNode;
+ }
+ }
+
+ return normalizedOffset;
+}