@ribajs/core
Version:
Core module of Riba.js
44 lines (37 loc) • 1.32 kB
text/typescript
import { Binder } from "../binder.js";
import { setAttribute } from "@ribajs/utils";
import type { EventBinderChangedDetail } from "../types/index.js";
/**
* Sets the attribute on the element. If no binder above is matched it will fall
* back to using this binder.
*/
export class AttributeBinder<T = any, E = HTMLElement> extends Binder<T, E> {
static key = "attr-*";
routine(el: E, newValue: T) {
if (!this.type) {
throw new Error("Can't set attribute of " + this.type);
}
const {
newValue: newValueFormatted,
oldValue,
changed,
} = setAttribute(el as HTMLElement, this.type, newValue);
// If this is a source element, the parent a video element and the attribute is the `src`, start loading the video
if (
this.type === "src" &&
(el as HTMLSourceElement).tagName.toUpperCase() === "SOURCE" &&
(
(el as HTMLSourceElement).parentElement as HTMLVideoElement
)?.tagName.toUpperCase() === "VIDEO"
) {
((el as HTMLSourceElement).parentElement as HTMLVideoElement).load();
}
if (changed) {
(el as HTMLElement).dispatchEvent(
new CustomEvent<EventBinderChangedDetail>("binder-changed", {
detail: { name: this.type, newValue: newValueFormatted, oldValue },
}),
);
}
}
}