UNPKG

@lynx-js/web-core

Version:

This is an internal experimental package, do not use

151 lines 6.21 kB
import { createCrossThreadEvent } from './createCrossThreadEvent.js'; import { LynxEventNameToW3cCommon, uniqueIdSymbol, } from '../../../constants.js'; import { __GetElementUniqueID } from './pureElementPAPIs.js'; export class WASMJSBinding { lynxViewInstance; wasmContext; disposeWasmContext; #addedEventListeners = new Set(); toBeEnabledElement = new Set(); toBeDisabledElement = new Set(); constructor(lynxViewInstance) { this.lynxViewInstance = lynxViewInstance; } markExposureRelatedElementByUniqueId(element, toEnable) { if (element) { if (toEnable) { this.toBeDisabledElement.delete(element); this.toBeEnabledElement.add(element); } else { this.toBeEnabledElement.delete(element); this.toBeDisabledElement.add(element); } } } generateTargetObject(element, dataset) { const uniqueId = element[uniqueIdSymbol]; return { dataset: Object.assign(Object.create(null), dataset), id: element.id || null, uid: uniqueId, }; } getClassList(elementRef) { const element = elementRef.deref(); if (element) { return [...element.classList]; } return []; } getElementByUniqueId(uniqueId) { return this.wasmContext?.get_dom_by_unique_id(uniqueId)?.deref(); } getElementByComponentId(componentId) { const uniqueId = this.wasmContext?.get_unique_id_by_component_id(componentId); if (uniqueId != undefined) { return this.getElementByUniqueId(uniqueId); } return undefined; } runWorklet(handler, eventObject, targetUniqueId, targetDataset, currentTargetUniqueId, currentTargetDataset) { const target = this.getElementByUniqueId(targetUniqueId); const currentTarget = this.getElementByUniqueId(currentTargetUniqueId); eventObject.target = this.generateTargetObject(target, targetDataset); eventObject.currentTarget = this.generateTargetObject(currentTarget, currentTargetDataset); // @ts-expect-error eventObject.target.elementRefptr = target; // @ts-expect-error eventObject.currentTarget.elementRefptr = currentTarget; this.lynxViewInstance.mainThreadGlobalThis.runWorklet?.(handler.value, [ eventObject, ]); } publishEvent(handlerName, parentComponentId, eventObject, targetUniqueId, targetDataset, currentTargetUniqueId, currentTargetDataset) { const target = this.getElementByUniqueId(targetUniqueId); const currentTarget = this.getElementByUniqueId(currentTargetUniqueId); eventObject.target = this.generateTargetObject(target, targetDataset); eventObject.currentTarget = this.generateTargetObject(currentTarget, currentTargetDataset); if (parentComponentId) { this.lynxViewInstance?.backgroundThread.publicComponentEvent(parentComponentId, handlerName, eventObject); } else { this.lynxViewInstance.backgroundThread.publishEvent(handlerName, eventObject); } } #commonEventHandler = (event) => { const target = event.target; let bubblePath = new Uint32Array(32); let bubblePathLength = 0; bubblePath; let currentTarget = target; while (currentTarget) { if (currentTarget === this.lynxViewInstance.rootDom) { break; } const uniqueId = __GetElementUniqueID(currentTarget); bubblePath[bubblePathLength++] = uniqueId; if (bubblePathLength >= bubblePath.length) { const newBubblePath = new Uint32Array(bubblePath.length * 2); newBubblePath.set(bubblePath); bubblePath = newBubblePath; } currentTarget = currentTarget.parentElement; } const eventObject = createCrossThreadEvent(event); this.wasmContext?.common_event_handler(eventObject, bubblePath.slice(0, bubblePathLength), eventObject.type, event.bubbles); }; addEventListener(eventName) { const w3cEventName = LynxEventNameToW3cCommon[eventName] ?? eventName; if (this.#addedEventListeners.has(w3cEventName)) return; this.#addedEventListeners.add(w3cEventName); this.lynxViewInstance.rootDom.addEventListener(w3cEventName, this.#commonEventHandler, { passive: true, capture: true, }); } dispose() { for (const eventName of this.#addedEventListeners) { this.lynxViewInstance.rootDom.removeEventListener(eventName, this.#commonEventHandler, true); } this.#addedEventListeners.clear(); this.toBeEnabledElement.clear(); this.toBeDisabledElement.clear(); this.disposeWasmContext?.(); this.wasmContext = undefined; } postTimingFlags(flags, pipelineId) { this.lynxViewInstance.backgroundThread.postTimingFlags(flags, pipelineId); } updateExposureStatus(enabledExposureElements, disabledExposureElements) { this.lynxViewInstance.exposureServices.updateExposureStatus(enabledExposureElements, disabledExposureElements); } enableElementEvent(elementRef, eventName) { const element = elementRef.deref(); if (element) { // @ts-expect-error element.enableEvent?.(LynxEventNameToW3cCommon[eventName] ?? eventName); } } disableElementEvent(elementRef, eventName) { const element = elementRef.deref(); if (element) { // @ts-expect-error element.disableEvent?.(LynxEventNameToW3cCommon[eventName] ?? eventName); } } setAttribute(elementRef, name, value) { const element = elementRef.deref(); if (element) { element.setAttribute(name, value); } } removeAttribute(elementRef, name) { const element = elementRef.deref(); if (element) { element.removeAttribute(name); } } } //# sourceMappingURL=WASMJSBinding.js.map