reactronic-dom
Version:
Reactronic DOM - Transactional Reactive Front-End Development Framework
97 lines (96 loc) • 3.31 kB
JavaScript
import { Rx } from 'reactronic';
import { RxNode, NodeFactory } from '../core/api';
export class ElementNodeFactory extends NodeFactory {
initialize(node, element) {
element = this.createElement(node);
if (Rx.isLogging)
element.id = node.name;
super.initialize(node, element);
}
finalize(node, isLeader) {
var _a;
const e = node.element;
if (e) {
(_a = e.resizeObserver) === null || _a === void 0 ? void 0 : _a.unobserve(e);
if (isLeader)
e.remove();
}
super.finalize(node, isLeader);
return false;
}
arrange(node, strict) {
const e = node.element;
if (e) {
const nativeParent = ElementNodeFactory.findNearestParentHtmlElementNode(node).element;
if (nativeParent) {
if (strict) {
const after = ElementNodeFactory.findPrevSiblingHtmlElementNode(node.item);
if (after === undefined) {
if (nativeParent !== e.parentNode || !e.previousSibling)
nativeParent.prepend(e);
}
else if (after.self.parent.element === nativeParent) {
const nativeAfter = after.self.element;
if (nativeAfter instanceof Element) {
if (nativeAfter.nextSibling !== e)
nativeParent.insertBefore(e, nativeAfter.nextSibling);
}
}
}
else
nativeParent.appendChild(e);
}
}
}
render(node) {
const result = super.render(node);
if (gBlinkingEffect)
blink(node.element, node.stamp);
return result;
}
static get blinkingEffect() {
return gBlinkingEffect;
}
static set blinkingEffect(value) {
if (value === undefined) {
const effect = gBlinkingEffect;
RxNode.forAllNodesDo((e) => {
if (e instanceof HTMLElement)
e.classList.remove(`${effect}-0`, `${effect}-1`);
});
}
gBlinkingEffect = value;
}
static findNearestParentHtmlElementNode(node) {
let p = node.parent;
while (p.element instanceof Element === false && p !== node)
p = p.parent;
return p;
}
static findPrevSiblingHtmlElementNode(item) {
let p = item.prev;
while (p && !(p.self.element instanceof Element))
p = p.prev;
return p;
}
}
export class HtmlElementNodeFactory extends ElementNodeFactory {
createElement(node) {
return document.createElement(node.factory.name);
}
}
export class SvgElementNodeFactory extends ElementNodeFactory {
createElement(node) {
return document.createElementNS('http://www.w3.org/2000/svg', node.factory.name);
}
}
function blink(e, revision) {
if (e !== undefined) {
const n1 = revision % 2;
const n2 = 1 >> n1;
const effect = gBlinkingEffect;
e.classList.toggle(`${effect}-${n1}`, true);
e.classList.toggle(`${effect}-${n2}`, false);
}
}
let gBlinkingEffect = undefined;