@domql/element
v3.8.9
Published
Takes object and creates DOMQL element.
Readme
DOMQL Element
Takes object and creates DOMQL element.
Example:
import DOM from 'domql'
const Poster = {
extends: [Link, Img],
boxSize: [100, 200],
borderRadius: 12,
padding: 16,
background: '#fff'
}
DOM.create(Poster, document.body)html mixin
The html mixin sets raw HTML content on an element. It supports both direct assignment and props:
// Direct assignment (el.html)
const MyComponent = {
html: '<strong>Hello</strong>'
}
// Via props (el.props.html) — works as an alias
const MyComponent = {
props: { html: '<strong>Hello</strong>' }
}el.html takes priority when both are set. props.html is used as a fallback when el.html is not defined.
REGISTRY (mixins/registry.js)
The REGISTRY object defines which keys are recognized as framework properties (rather than child elements). Any key not in REGISTRY and starting with an uppercase letter is treated as a child element.
Every framework-level key must be listed here. If a key like childExtend is missing from REGISTRY, it gets interpreted as a child element name, causing silent rendering failures (e.g., cart components not rendering in Archy).
Current framework keys that must remain in REGISTRY:
extends, children, content,
childExtend (deprecated), childExtends,
childExtendRecursive (deprecated), childExtendsRecursive,
props, if, define,
__name, __ref, __hash, __text, key, tag, query, parent, node,
variables, on, component, contextPlus mixin handlers: attr, style, text, html, data, classlist, state, scope, deps.
Scope and globalScope
During create(), createScope(element, parent) establishes a prototype chain:
el.scope → parent.scope → ... → root.scope → context.globalScope- Elements without a
scopeproperty inherit their parent's scope (same reference) - Elements with
scope: { ... }get their own scope with parent's scope as prototype context.globalScopeis auto-initialized as{}and sits at the chain's root
This enables serialized functions to access module-scoped values (constants, helpers) via el.scope.X without closures or imports — the values are placed in globalScope by the serialization pipeline and are accessible through prototype lookup.
v3 note:
childExtend(singular) is deprecated v2 syntax — usechildExtends(plural) in new code. The singular forms remain in REGISTRY for backwards compatibility with older projects. If a key is missing from REGISTRY, it gets interpreted as a child element name, causing silent rendering failures.
set.js — Content Setting
Fragment forwarding
When set() receives content with tag: 'fragment', the fragment itself doesn't create a DOM node — its children are inserted directly. This means:
childExtends forwarding — The parent's
childExtendsmust be forwarded to the fragment's params so that fragment children inherit the correct extends:if (tag === 'fragment') { const elementChildExtends = element.childExtends || element.childExtend if (!childExtends && elementChildExtends) { params.childExtends = elementChildExtends } }(Also checks deprecated
childExtendfor backwards compatibility with v2 projects.)childProps forwarding — Similarly,
childPropsfrom the parent must be explicitly passed through the fragment to its children.ignoreChildProps — When forwarding
childPropsthrough a fragment, setprops.ignoreChildProps = trueon the fragment itself to prevent the fragment from inheriting the parent'schildPropsviainheritParentProps. ThechildPropsare already forwarded explicitly for the fragment's children.
Infinite loop guard
set() includes a re-entrancy guard via ref.__settingContent. Without this, define handlers (like $router) that call el.set() can trigger infinite recursion when content-setting triggers another content-set cycle.
if (ref.__settingContent) return element
ref.__settingContent = true
try {
return _setInner(params, options, element)
} finally {
ref.__settingContent = false
}