@symbo.ls/utils
@domql/utils
Core utility functions for the DOMQL element system.
Propertization (props.js)
The propertization system normalizes element definitions by classifying keys into child elements, framework keys, and CSS/design-token properties.
In v3.14, properties go directly on the element (no props: wrapper needed). The propertization system operates internally to route properties to the atomic CSS engine (@symbo.ls/css).
Two-phase process
pickupPropsFromElement— Scans element root keys and classifies non-element, non-builtin keys for CSS processingpickupElementFromProps— Scans classified keys and moves element-like or builtin keys back to the element root
Key classification rules
In v3.14, properties go directly on the element (no props: wrapper needed). The propertization system still operates internally for the CSS engine.
| Pattern | Classification | Example |
|---|---|---|
| Starts with uppercase | Child element | Header, Button, Nav |
| Numeric key | Child element | 0, 1, 2 |
In DOMQ_PROPERTIES |
Framework builtin | tag, extends, state |
In CSS_SELECTOR_PREFIXES |
CSS-in-props | :hover, @mobileS, $isActive |
| Has define handler | Define key (stays at root) | $router, deprecated: $propsCollection |
childProps |
Always in props | childProps |
onXxx + function |
Event/lifecycle handler | onClick, onSubmit, onInit, onRender |
| Everything else | CSS/design token prop | padding, theme, color |
CSS_SELECTOR_PREFIXES
const CSS_SELECTOR_PREFIXES = new Set([
':', '@', '[', '*', '+', '~', '&', '>', '
These single-character prefixes identify keys that should be processed by css-in-props via transformersByPrefix. When a key starts with one of these characters, it gets moved into props.
Define-awareness
The $ prefix is shared between css-in-props conditionals ($isActive) and define handlers (built-in $router). The propertization checks for define handlers before applying prefix rules to ensure define keys stay at the element root.
childProps handling
childProps is a framework property that configures child element properties. Its value may contain uppercase keys that look like child elements but are not:
// childProps: { Icon: { name: 'star' }, Hgroup: { ... } }
// The uppercase keys inside are NOT child elements — they target named children
ignoreChildProps
When set on element.props, prevents the element from inheriting childProps from its parent via inheritParentProps. Used by fragment elements to avoid double-application of childProps (since fragments explicitly forward childProps to their children).
Scope (scope.js)
createScope(element, parent)
Creates the scope for an element with prototype-chain inheritance:
el.scope → parent.scope → grandparent.scope → ... → root.scope → context.globalScope
Behavior:
- No own scope — element inherits
parent.scope directly (same reference)
- Own scope defined (
scope: { myVar: 1 }) — prototype is set to parent's scope, chaining up to globalScope
- No parent/root scope — new scope created with
Object.create(context.globalScope)
- No context — plain
{}
globalScope
Automatically initialized as context.globalScope = {} if context exists. Sits at the bottom of every scope prototype chain, making its properties accessible from any element via el.scope.X.
// In context or set by the serialization pipeline:
context.globalScope = {
API_URL: 'https://api.example.com',
helpers: { capitalize: (s) => s[0].toUpperCase() + s.slice(1) }
}
// Accessible from any element — no import needed:
onClick: (e, el) => fetch(el.scope.API_URL)
// Also directly accessible:
el.context.globalScope.API_URL
When a component defines its own scope, properties shadow parent/global values but the chain remains walkable:
// Parent: scope = { theme: 'dark' }
// Child: scope = { count: 0 }
// el.scope.count → 0 (own)
// el.scope.theme → 'dark' (parent, via prototype)
// el.scope.API_URL → '...' (globalScope, via prototype chain)
Key Sets (keys.js)
DOMQ_PROPERTIES — Framework-level keys that stay at element root
PROPS_METHODS — Keys on the props prototype (update, __element)
STATE_METHODS — State management methods (update, parse, set, toggle, etc.)
, '-', '.', '!'
])
These single-character prefixes identify keys that should be processed by __INLINE_CODE_32__ via __INLINE_CODE_33__. When a key starts with one of these characters, it gets moved into __INLINE_CODE_34__.
Define-awareness
The __INLINE_CODE_35__ prefix is shared between css-in-props conditionals (__INLINE_CODE_36__) and define handlers (built-in __INLINE_CODE_37__). The propertization checks for define handlers before applying prefix rules to ensure define keys stay at the element root.
childProps handling
__INLINE_CODE_38__ is a framework property that configures child element properties. Its value may contain uppercase keys that look like child elements but are not:
__CODE_BLOCK_1__ignoreChildProps
When set on __INLINE_CODE_39__, prevents the element from inheriting __INLINE_CODE_40__ from its parent via __INLINE_CODE_41__. Used by fragment elements to avoid double-application of childProps (since fragments explicitly forward childProps to their children).
Scope (__INLINE_CODE_42__)
__INLINE_CODE_43__
Creates the scope for an element with prototype-chain inheritance:
__CODE_BLOCK_2__Behavior:
- No own scope — element inherits __INLINE_CODE_44__ directly (same reference)
- Own scope defined (__INLINE_CODE_45__) — prototype is set to parent's scope, chaining up to __INLINE_CODE_46__
- No parent/root scope — new scope created with __INLINE_CODE_47__
- No context — plain __INLINE_CODE_48__
__INLINE_CODE_49__
Automatically initialized as __INLINE_CODE_50__ if context exists. Sits at the bottom of every scope prototype chain, making its properties accessible from any element via __INLINE_CODE_51__.
__CODE_BLOCK_3__When a component defines its own scope, properties shadow parent/global values but the chain remains walkable:
__CODE_BLOCK_4__Key Sets (__INLINE_CODE_52__)
- __INLINE_CODE_53__ — Framework-level keys that stay at element root
- __INLINE_CODE_54__ — Keys on the props prototype (update, __element)
- __INLINE_CODE_55__ — State management methods (update, parse, set, toggle, etc.)