Skip to content

Commit

Permalink
reactive transform improvements (ternaries)
Browse files Browse the repository at this point in the history
  • Loading branch information
benStre committed Sep 29, 2024
1 parent a1a68b9 commit 3f7ac55
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 30 deletions.
62 changes: 40 additions & 22 deletions datex-bindings/dom-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -945,9 +945,9 @@ export class DOMUtils {
newNode = value;
}

// unsupported value - create text node
// unsupported value - create text/content node
if (!(newNode instanceof this.context.Node || newNode instanceof this.context.DocumentFragment || newNode instanceof this.context.Comment)) {
newNode = this.getTextNode(newNode);
newNode = this.getNode(newNode);
}

return {
Expand All @@ -956,56 +956,74 @@ export class DOMUtils {
}
}

getTextNode(content:any) {
const textNode = this.document.createTextNode("") as unknown as Text;
(textNode as any)[DX_VALUE] = content;
getNode(content:any) {
const contentVal = val(content);
// either use existing node or create new text node
const node = contentVal instanceof Node ? contentVal : this.document.createTextNode("") as unknown as Text;
(node as any)[DX_VALUE] = content;

// lazy pointer or lazy pointer property
if (
content instanceof LazyPointer ||
(content instanceof PointerProperty && content.lazy_pointer)
) {
content.onLoad(() => {
this.bindTextNode(textNode, content)
this.bindNode(node, content)
})
}
// ref
else if (content instanceof Datex.ReactiveValue) {
this.bindTextNode(textNode, content)
this.bindNode(node, content)
}

else {
textNode.textContent = (content!=undefined && content!==false) ? (<any>content).toString() : ''
node.textContent = (content!=undefined && content!==false) ? (<any>content).toString() : ''
}

return textNode;
return node;
}

bindTextNode(textNode: Text, ref:Datex.RefLike<unknown>) {
weakAction({textNode, ref},
({textNode, ref}) => {
bindNode(node: Node, ref:Datex.RefLike<unknown>) {

weakAction({node, ref},
({node, ref}) => {
use (logger, Datex, isolatedScope);

let prevNode:{node?:WeakRef<Node>} = {node};

// TODO: dont reference 'ref' in handler, use args from handler
const handler = isolatedScope((...args:any[]) => {
use (logger, ref, textNode);
use (logger, ref, prevNode);

let prevNodeDeref = prevNode.node?.deref()!;

const deref = ref.deref();
if (!deref) {
logger.warn("Undetected garbage collection (uix-w0001)");
return;
}
const textNodeDeref = textNode.deref();
if (!textNodeDeref) {
logger.warn("Undetected garbage collection (uix-w0001)");
return;
}

try {
const val = deref.val;
textNodeDeref.textContent = (val!=undefined && val!==false) ? (<any>val).toString() : ''

// replace previous node if it is a node, otherwise update text content
if (val instanceof Node) {
prevNode.node = new WeakRef(val);
prevNodeDeref.replaceWith(val);
}
else {
if (!(prevNodeDeref instanceof Text)) {
const node = document.createTextNode("");
prevNode.node = new WeakRef(node);
prevNodeDeref.replaceWith(node);
prevNodeDeref = node;
}
prevNodeDeref.textContent = (val!=undefined && val!==false) ? (<any>val).toString() : ''
}

}
catch {
textNodeDeref.textContent = ""
catch (e) {
console.error(e)
prevNodeDeref.textContent = ""
}
});

Expand Down
10 changes: 5 additions & 5 deletions datex-bindings/transform-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ function appendToFragment(domUtils: DOMUtils, context: DOMContext, fragment: HTM
export function getTransformWrapper(domUtils: DOMUtils, context: DOMContext) {
return {
// special uix-fragment wrapper for transforms
wrap_transform(val:any) {
const fragment = context.document.createElement("uix-fragment");
appendToFragment(domUtils, context, fragment, val);
return fragment;
},
// wrap_transform(val:any) {
// const fragment = context.document.createElement("uix-fragment");
// appendToFragment(domUtils, context, fragment, val);
// return fragment;
// },

allow_transform_value(type: Datex.Type) {
return allDomTypes.has(type.root_type) || type.root_type.name == "uix" || "must be a DOM element"
Expand Down
4 changes: 2 additions & 2 deletions datex-bindings/type-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function loadDefinitions(context: DOMContext, domUtils: DOMUtils, options
console.log(element)
throw new Error("element has no dataset, todo");
}
if (!element.hasAttribute("uix-ptr")) element.setAttribute("uix-ptr", pointer.id);
if (!element.hasAttribute("uix-ptr") && client_type == "deno") element.setAttribute("uix-ptr", pointer.id);

// @ts-ignore
if (element[OBSERVER]) return;
Expand Down Expand Up @@ -402,7 +402,7 @@ export function loadDefinitions(context: DOMContext, domUtils: DOMUtils, options
},

create_proxy(val, pointer) {
if (!val.hasAttribute("uix-ptr")) val.setAttribute("uix-ptr", pointer.id);
if (!val.hasAttribute("uix-ptr") && client_type == "deno") val.setAttribute("uix-ptr", pointer.id);

const cloneNodeOriginal = val.cloneNode.bind(val);

Expand Down
2 changes: 1 addition & 1 deletion html-template-strings/html-template-strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export function getHTMLGenerator(context: DOMContext, domUtils: DOMUtils, jsx: R
const isTemplate = template?.raw instanceof Array && template instanceof Array;
// non template value - convert to HTML node
if (!isTemplate) {
return domUtils.getTextNode(template);
return domUtils.getNode(template);
}
// templatee
else {
Expand Down

0 comments on commit 3f7ac55

Please sign in to comment.