@bokeh/bokehjs
Version:
Interactive, novel data visualization
106 lines • 3.72 kB
JavaScript
import { DOMNode, DOMNodeView } from "./dom_node";
import { StylesLike } from "../ui/styled_element";
import { UIElement } from "../ui/ui_element";
import { build_views, remove_views } from "../../core/build_views";
import { isString } from "../../core/util/types";
import { apply_styles } from "../../core/css";
import { empty, bounding_box } from "../../core/dom";
export class DOMElementView extends DOMNodeView {
static __name__ = "DOMElementView";
get bbox() {
return bounding_box(this.el).relative();
}
get self_target() {
return this.el;
}
child_views = new Map();
children_views() {
return [...super.children_views(), ...this.child_views.values()];
}
async lazy_initialize() {
await super.lazy_initialize();
const children = this.model.children.filter((obj) => !isString(obj));
await build_views(this.child_views, children, { parent: this });
}
remove() {
remove_views(this.child_views);
super.remove();
}
connect_signals() {
super.connect_signals();
const { children, style } = this.model.properties;
this.on_change(children, async () => {
await this._update_children();
});
this.on_change(style, () => {
this.el.removeAttribute("style");
apply_styles(this.el.style, this.model.style);
});
}
async _build_children() {
const children = this.model.children.filter((obj) => !isString(obj));
return await build_views(this.child_views, children, { parent: this });
}
async _update_children() {
const { created } = await this._build_children();
const created_views = new Set(created);
// Since appending to a DOM node will move the node to the end if it has
// already been added appending all the children in order will result in
// correct ordering.
for (const child of this.model.children) {
if (isString(child)) {
const node = document.createTextNode(child);
this.self_target.append(node);
}
else {
const view = this.child_views.get(child);
if (view == null) {
continue;
}
const is_new = created_views.has(view);
const target = view.rendering_target() ?? this.self_target;
if (is_new) {
view.render_to(target);
}
else {
target.append(view.el);
}
}
}
this.r_after_render();
}
render() {
empty(this.el);
apply_styles(this.el.style, this.model.style);
for (const child of this.model.children) {
if (isString(child)) {
const node = document.createTextNode(child);
this.el.append(node);
}
else {
const child_view = this.child_views.get(child);
if (child_view == null) {
continue;
}
const target = child_view.rendering_target() ?? this.self_target;
child_view.render_to(target);
}
}
this.finish();
}
}
export class DOMElement extends DOMNode {
static __name__ = "DOMElement";
constructor(attrs) {
super(attrs);
}
static {
this.define(({ Str, List, Or, Ref }) => {
return {
style: [StylesLike, {}],
children: [List(Or(Str, Ref(DOMNode), Ref(UIElement))), []],
};
});
}
}
//# sourceMappingURL=dom_element.js.map