You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
1.4 KiB

/**
* `apply` / `remove` — the only mutation surface of `ActiveDom`.
*
* `ActiveDom` doesn't know product frameworks. It receives instructions
* already resolved by upper layers and applies them to the DOM. Nothing else.
*
* Contract:
* - `string | number` → `setAttribute(name, String(value))`
* - `true` → `setAttribute(name, '')` (presence flag, e.g. `data-disabled`)
* - `false | null | undefined` → `removeAttribute(name)`
*
* No event dispatch, no batching, no observation. Pure mutations.
*/
import { isBrowser } from '$libs/dom';
export type DomAttrValue = string | number | boolean | null | undefined;
export type StructuralChange = {
target: HTMLElement;
attrs: Record<string, DomAttrValue>;
};
function writeAttr(target: HTMLElement, name: string, value: DomAttrValue): void {
if (value === false || value === null || value === undefined) {
target.removeAttribute(name);
return;
}
if (value === true) {
target.setAttribute(name, '');
return;
}
target.setAttribute(name, String(value));
}
export function applyChange(change: StructuralChange): void {
if (!isBrowser) return;
for (const name in change.attrs) {
writeAttr(change.target, name, change.attrs[name]);
}
}
export function removeAttrs(target: HTMLElement, names: readonly string[]): void {
if (!isBrowser) return;
for (const name of names) {
target.removeAttribute(name);
}
}

Powered by TurnKey Linux.