UNPKG

@dark-engine/platform-desktop

Version:

Dark renderer to desktop platforms like Windows, Linux, macOS via Nodegui and Qt

173 lines (172 loc) 6.16 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); exports.toggle = exports.runAtTheEndOfCommit = exports.finishCommit = exports.commit = exports.createNativeElement = void 0; const core_1 = require('@dark-engine/core'); const native_element_1 = require('../native-element'); const events_1 = require('../events'); const constants_1 = require('../constants'); let moves = []; let callbacks = []; function createNativeElement(vNode) { switch (vNode.type) { case core_1.NodeType.TAG: return new native_element_1.TagNativeElement(vNode.name); case core_1.NodeType.TEXT: return new native_element_1.TextNativeElement(vNode.value); case core_1.NodeType.COMMENT: return new native_element_1.CommentNativeElement(vNode.value); } } exports.createNativeElement = createNativeElement; function applyRef(ref, element) { (0, core_1.applyRef)(ref, element.getNativeView()); } function addAttributes(element, vNode) { const tagElement = element; for (const attrName in vNode.attrs) { const attrValue = vNode.attrs[attrName]; if (attrName === core_1.REF_ATTR) { applyRef(attrValue, tagElement); continue; } if ((0, events_1.detectIsEvent)(attrName)) { attrValue && (0, core_1.detectIsObject)(attrValue) && addEvents(tagElement, attrValue); } else if (!(0, core_1.detectIsUndefined)(attrValue) && !core_1.ATTR_BLACK_LIST[attrName]) { tagElement.setAttribute(attrName, attrValue); } } } function updateAttributes(element, prevVNode, nextVNode) { const attrNames = getAttributeNames(prevVNode, nextVNode); const tagElement = element; for (const attrName of attrNames) { const prevAttrValue = prevVNode.attrs[attrName]; const nextAttrValue = nextVNode.attrs[attrName]; if (attrName === core_1.REF_ATTR) { applyRef(prevAttrValue, tagElement); continue; } if (!(0, core_1.detectIsUndefined)(nextAttrValue)) { if ((0, events_1.detectIsEvent)(attrName)) { nextAttrValue && (0, core_1.detectIsObject)(nextAttrValue) && prevAttrValue !== nextAttrValue && addEvents(tagElement, nextAttrValue); } else if (!core_1.ATTR_BLACK_LIST[attrName] && prevAttrValue !== nextAttrValue) { tagElement.setAttribute(attrName, nextAttrValue); } } else { if ((0, events_1.detectIsEvent)(attrName)) { prevAttrValue && (0, core_1.detectIsObject)(prevAttrValue) && removeEvents(tagElement, prevAttrValue); } else { tagElement.removeAttribute(attrName); } } } } function addEvents(tagElement, value) { for (const key in value) { tagElement.addEventListener(key, value[key]); } } function removeEvents(tagElement, value) { for (const key in value) { tagElement.removeEventListener(key); } } function commitCreation(fiber) { const parent = (0, core_1.getFiberWithElement)(fiber.parent); const parentElement = parent.el; const children = parentElement.children; if (children.length === 0 || fiber.eidx > children.length - 1) { appendNativeElement(fiber.el, parentElement); } else { insertNativeElement(fiber.el, parentElement.children[fiber.eidx], parentElement); } (0, core_1.detectIsTagVirtualNode)(fiber.inst) && addAttributes(fiber.el, fiber.inst); } function commitUpdate(fiber) { const element = fiber.el; const prevInst = fiber.alt.inst; const nextInst = fiber.inst; (0, core_1.detectIsPlainVirtualNode)(nextInst) ? prevInst.value !== nextInst.value && (element.value = nextInst.value) : updateAttributes(element, prevInst, nextInst); } function commitDeletion(fiber) { const parent = (0, core_1.getFiberWithElement)(fiber.parent); (0, core_1.walk)(fiber, onWalkInCommitDeletion(parent.el)); } const onWalkInCommitDeletion = parentElement => (fiber, skip) => { if (fiber.el) { removeNativeElement(fiber.el, parentElement); return skip(); } }; function move(fiber) { const sourceNodes = (0, core_1.collectElements)(fiber, x => x.el); const sourceNode = sourceNodes[0]; const parentElement = sourceNode.parentElement; const elementIdx = fiber.eidx; const move = () => { for (let i = 0; i < sourceNodes.length; i++) { insertNativeElement(sourceNodes[i], parentElement.children[elementIdx + i], parentElement); removeNativeElement(parentElement.children[elementIdx + i + 1], parentElement); } }; for (let i = 0; i < sourceNodes.length; i++) { const node = sourceNodes[i]; insertNativeElement(new native_element_1.CommentNativeElement(`${elementIdx}:${i}`), node, parentElement); removeNativeElement(node, parentElement); } moves.push(move); } function getAttributeNames(prevVNode, nextVNode) { const attrNames = new Set(); const prevAttrs = Object.keys(prevVNode.attrs); const nextAttrs = Object.keys(nextVNode.attrs); const size = Math.max(prevAttrs.length, nextAttrs.length); for (let i = 0; i < size; i++) { attrNames.add(prevAttrs[i] || nextAttrs[i]); } return attrNames; } function commit(fiber) { switch (fiber.tag) { case core_1.CREATE_EFFECT_TAG: fiber.el && commitCreation(fiber); break; case core_1.UPDATE_EFFECT_TAG: fiber.mask & core_1.MOVE_MASK && (move(fiber), (fiber.mask &= ~core_1.MOVE_MASK)); fiber.el && commitUpdate(fiber); break; case core_1.DELETE_EFFECT_TAG: commitDeletion(fiber); break; default: break; } } exports.commit = commit; function finishCommit() { callbacks.forEach(x => x()); moves.forEach(x => x()); callbacks = []; moves = []; } exports.finishCommit = finishCommit; function runAtTheEndOfCommit(cb) { callbacks.push(cb); } exports.runAtTheEndOfCommit = runAtTheEndOfCommit; const appendNativeElement = (element, parent) => parent.appendChild(element); const insertNativeElement = (element, sibling, parent) => parent.insertBefore(element, sibling); const removeNativeElement = (element, parent) => parent.removeChild(element); const toggle = (element, isVisible) => element.setAttribute(constants_1.HIDDEN_ATTR, isVisible); exports.toggle = toggle; //# sourceMappingURL=dom.js.map