UNPKG

@lynx-js/offscreen-document

Version:

Offscreen Document allows developers to use particular DOM in WebWorker

94 lines 3.49 kB
// Copyright 2023 The Lynx Authors. All rights reserved. // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. import { OperationType } from '../types/ElementOperation.js'; import { _attributes, _children, ancestorDocument, OffscreenElement, } from './OffscreenElement.js'; import { eventPhase, OffscreenEvent, propagationStopped, } from './OffscreenEvent.js'; export const operations = Symbol('operations'); export const enableEvent = Symbol('enableEvent'); export const getElementByUniqueId = Symbol('getElementByUniqueId'); export const _onEvent = Symbol('_onEvent'); const _uniqueIdInc = Symbol('uniqueIdInc'); const _uniqueIdToElement = Symbol('_uniqueIdToElement'); export class OffscreenDocument extends OffscreenElement { _callbacks; /** * @private */ [_uniqueIdInc] = 1; /** * @private */ [_uniqueIdToElement] = []; /** * @private */ [operations] = []; /** * @private * @param uniqueId * @returns */ [getElementByUniqueId](uniqueId) { return this[_uniqueIdToElement][uniqueId]?.deref(); } [enableEvent]; constructor(_callbacks) { const enableEventImpl = (eventType, uid) => { this[operations].push(OperationType.EnableEvent, uid, eventType); }; super('', 0); this._callbacks = _callbacks; this[ancestorDocument] = this; this[enableEvent] = enableEventImpl; } commit() { const currentOperations = this[operations]; this[operations] = []; this._callbacks.onCommit(currentOperations); } createElement(tagName) { const uniqueId = this[_uniqueIdInc]++; const element = new OffscreenElement(tagName, uniqueId); element[ancestorDocument] = this; this[_uniqueIdToElement][uniqueId] = new WeakRef(element); this[operations].push(OperationType.CreateElement, uniqueId, tagName); return element; } [_onEvent] = (eventType, targetUniqueId, bubbles, otherProperties) => { const target = this[getElementByUniqueId](targetUniqueId); if (target) { const bubblePath = []; let tempTarget = target; while (tempTarget.parentElement) { bubblePath.push(tempTarget.parentElement); tempTarget = tempTarget.parentElement; } const event = new OffscreenEvent(eventType, target); Object.assign(event, otherProperties); // capture phase event[eventPhase] = Event.CAPTURING_PHASE; for (let ii = bubblePath.length - 1; ii >= 0; ii--) { const currentPhaseTarget = bubblePath[ii]; currentPhaseTarget.dispatchEvent(event); if (event[propagationStopped]) { return; } } // target phase event[eventPhase] = Event.AT_TARGET; target.dispatchEvent(event); // bubble phase if (bubbles) { event[eventPhase] = Event.BUBBLING_PHASE; for (const currentPhaseTarget of bubblePath) { currentPhaseTarget.dispatchEvent(event); if (event[propagationStopped]) { return; } } } } }; } //# sourceMappingURL=OffscreenDocument.js.map