Adds a new "class:" control-target kind (save_element_controls.py, _visible_attrs.py) alongside the existing content/attr/style ones, so a widget can carry CSS classes built from independent named slots (color, size, shape...) without them overwriting each other. Bouton and Titre get their Bulma base class (button/title) via fixed_attrs; Conteneur gets an opt-in "Carte (Bulma)" preset instead of a forced default, since it's also used as an invisible layout wrapper. Bouton's font-size/border-radius sliders no longer freeze their default value into inline style at creation (new c_slider no_freeze flag), so Bulma's own button styling shows through until a user actually customizes it — inline style still wins over any class the moment it's set, exactly like today. Loads bulma.min.css via CDN in screen_edit.html and play.html, same pattern as animate.css.
35 lines
1.7 KiB
Python
35 lines
1.7 KiB
Python
from .apply_ctx import _apply_ctx
|
|
from .auto_id import _auto_id
|
|
|
|
|
|
def _visible_attrs(el, meta, ctx=None):
|
|
raw_attrs = el.get("attributes") or {}
|
|
attrs = {
|
|
k: (_apply_ctx(v, ctx) if isinstance(v, str) else v)
|
|
for k, v in raw_attrs.items() if not k.startswith("_")
|
|
}
|
|
attrs.update(meta.get("fixed_attrs", {}))
|
|
# Classes externes (ex. Bulma) réglées via un contrôle "class:xxx" — voir
|
|
# save_element_controls.py — chacune mémorisée sous "_class_xxx" pour ne
|
|
# pas s'écraser entre elles ; assemblées ici avec la classe de base du
|
|
# widget (posée via fixed_attrs, ex. "button"/"box"/"title") pour former
|
|
# l'attribut class final. Une classe personnalisée éventuellement tapée
|
|
# à la main (peu probable ici, mais possible via fixed_attrs) est gardée
|
|
# en tête.
|
|
extra_classes = [v for k, v in raw_attrs.items() if k.startswith("_class_") and v]
|
|
if extra_classes:
|
|
base_class = attrs.get("class", "")
|
|
attrs["class"] = " ".join(([base_class] if base_class else []) + extra_classes)
|
|
attrs.setdefault("id", _auto_id(el))
|
|
attrs["data-element-id"] = el["id"]
|
|
if el.get("parent_id"):
|
|
# Élément posé à l'intérieur d'un conteneur/répéteur/groupe de
|
|
# champs : pas de cadre de positionnement séparé autour de lui (voir
|
|
# element_style_filter.py) — sa propre balise EST déjà tout
|
|
# l'élément, donc c'est elle que la timeline d'animation doit viser.
|
|
# Un élément posé directement sur un écran, lui, porte ce marqueur
|
|
# sur son cadre (.canvasElement / .playElement) à la place — voir
|
|
# les gabarits screen_edit.html et play.html.
|
|
attrs["data-anim-target"] = el["id"]
|
|
return attrs
|