quick-actions css fix; tooltips in plugins

Alessandro committed Feb 17, 2026 at 14:12 UTC addd0abeeeb13edc536af6c0f3c6a6dc26c04a61
2 files changed +28 -17
webui/components/sidebar/top-section/quick-actions.html
+6 -10
@@ -131,7 +131,7 @@
131 .config-button {
132 background-color: var(--color-panel);
133 border: 0.05rem solid var(--color-border);
134 - border-radius: 6px;
134 + border-radius: 0;
135 cursor: pointer;
136 display: flex;
137 align-items: center;
@@ -158,18 +158,14 @@
158 border-right: 1px solid var(--color-border);
159 }
160
161 - .config-button:first-child {
162 - border-top-right-radius: 0;
163 - border-bottom-right-radius: 0;
161 + .config-button:first-of-type {
162 + border-top-left-radius: 6px !important;
163 + border-bottom-left-radius: 6px !important;
164 }
165
166 .config-button:last-child {
167 - border-top-left-radius: 0;
168 - border-bottom-left-radius: 0;
169 - }
170 -
171 - .config-button:not(:first-child):not(:last-child) {
172 - border-radius: 0;
167 + border-top-right-radius: 6px !important;
168 + border-bottom-right-radius: 6px !important;
169 }
170
171 .config-button:hover {
webui/components/tooltips/tooltip-store.js
+22 -7
@@ -38,9 +38,12 @@ function ensureBootstrapTooltip(element) {
38
39 function initBootstrapTooltips(root = document) {
40 if (!globalThis.bootstrap?.Tooltip) return;
41 - const tooltipTargets = root.querySelectorAll(
42 - "[title]:not([data-bs-tooltip-initialized]), [data-bs-original-title]:not([data-bs-tooltip-initialized])"
43 - );
41 + const selector = "[title], [data-bs-original-title]";
42 + const rootIsElement = root instanceof Element;
43 + const tooltipTargets = [
44 + ...(rootIsElement && root.matches(selector) ? [root] : []),
45 + ...Array.from(root.querySelectorAll(selector)),
46 + ];
47 tooltipTargets.forEach((element) => ensureBootstrapTooltip(element));
48 }
49
@@ -52,7 +55,11 @@ function observeBootstrapTooltips() {
55
56 bootstrapTooltipObserver = new MutationObserver((mutations) => {
57 mutations.forEach((mutation) => {
55 - if (mutation.type === "attributes" && mutation.attributeName === "title") {
58 + if (
59 + mutation.type === "attributes" &&
60 + (mutation.attributeName === "title" ||
61 + mutation.attributeName === "data-bs-original-title")
62 + ) {
63 ensureBootstrapTooltip(mutation.target);
64 return;
65 }
@@ -61,8 +68,13 @@ function observeBootstrapTooltips() {
68 // Check removed nodes for tooltip cleanup
69 mutation.removedNodes.forEach((node) => {
70 if (!(node instanceof Element)) return;
64 - const tooltipElements = node.matches?.('[data-bs-tooltip-initialized]') ? [node] : Array.from(node.querySelectorAll?.('[data-bs-tooltip-initialized]') || []);
71 + const tooltipElements = node.matches?.("[data-bs-tooltip-initialized]")
72 + ? [node]
73 + : Array.from(
74 + node.querySelectorAll?.("[data-bs-tooltip-initialized]") || []
75 + );
76 tooltipElements.forEach((el) => {
77 + if (el.isConnected) return;
78 const instance = globalThis.bootstrap?.Tooltip?.getInstance(el);
79 if (instance) {
80 instance.dispose();
@@ -72,7 +84,10 @@ function observeBootstrapTooltips() {
84
85 mutation.addedNodes.forEach((node) => {
86 if (!(node instanceof Element)) return;
75 - if (node.matches("[title]") || node.querySelector("[title]")) {
87 + if (
88 + node.matches("[title], [data-bs-original-title]") ||
89 + node.querySelector("[title], [data-bs-original-title]")
90 + ) {
91 initBootstrapTooltips(node);
92 }
93 });
@@ -84,7 +99,7 @@ function observeBootstrapTooltips() {
99 childList: true,
100 subtree: true,
101 attributes: true,
87 - attributeFilter: ["title"],
102 + attributeFilter: ["title", "data-bs-original-title"],
103 });
104 }
105