Sanitized mirror from private repository - 2026-04-19 08:20:38 UTC
This commit is contained in:
107
hosts/physical/concord-nuc/homeassistant/www/assist-fix.js
Normal file
107
hosts/physical/concord-nuc/homeassistant/www/assist-fix.js
Normal file
@@ -0,0 +1,107 @@
|
||||
// Force-readable input fields across all shadow DOMs (Assist dialog + anywhere else).
|
||||
// Monkey-patches Element.attachShadow so every new shadow root receives a <style>
|
||||
// that overrides the Material "filled" textfield / textarea colors using the
|
||||
// active theme's CSS variables.
|
||||
(function () {
|
||||
if (window.__assistFixLoaded) return;
|
||||
window.__assistFixLoaded = true;
|
||||
|
||||
const CSS = `
|
||||
/* Filled variants — the default Material style HA uses */
|
||||
.mdc-text-field--filled,
|
||||
.mdc-text-field,
|
||||
mwc-textfield,
|
||||
mwc-textarea,
|
||||
ha-textfield,
|
||||
ha-textarea {
|
||||
--mdc-text-field-fill-color: var(--card-background-color, rgba(22, 24, 40, 0.92)) !important;
|
||||
--mdc-text-field-ink-color: var(--primary-text-color, #e7e9f4) !important;
|
||||
--mdc-text-field-label-ink-color: var(--secondary-text-color, #9a9cb8) !important;
|
||||
--mdc-text-field-idle-line-color: var(--divider-color, rgba(255,255,255,0.18)) !important;
|
||||
--mdc-text-field-hover-line-color: var(--primary-color, #a78bfa) !important;
|
||||
--mdc-text-field-focused-label-color: var(--primary-color, #a78bfa) !important;
|
||||
--mdc-text-field-outlined-idle-border-color: var(--divider-color, rgba(255,255,255,0.18)) !important;
|
||||
--mdc-text-field-outlined-hover-border-color: var(--primary-color, #a78bfa) !important;
|
||||
--mdc-text-field-disabled-fill-color: var(--secondary-background-color, rgba(22, 24, 40, 0.60)) !important;
|
||||
--mdc-text-field-disabled-ink-color: var(--secondary-text-color, #9a9cb8) !important;
|
||||
}
|
||||
|
||||
/* Direct color overrides for the input element inside shadow roots */
|
||||
.mdc-text-field__input,
|
||||
.mdc-text-area__input,
|
||||
input, textarea {
|
||||
color: var(--primary-text-color, #e7e9f4) !important;
|
||||
caret-color: var(--primary-text-color, #e7e9f4) !important;
|
||||
}
|
||||
.mdc-text-field__input::placeholder,
|
||||
.mdc-text-area__input::placeholder,
|
||||
input::placeholder, textarea::placeholder {
|
||||
color: var(--secondary-text-color, #9a9cb8) !important;
|
||||
opacity: 0.7 !important;
|
||||
}
|
||||
.mdc-floating-label,
|
||||
.mdc-text-field__affix {
|
||||
color: var(--secondary-text-color, #9a9cb8) !important;
|
||||
}
|
||||
.mdc-text-field--filled:not(.mdc-text-field--disabled) {
|
||||
background-color: var(--card-background-color, rgba(22, 24, 40, 0.92)) !important;
|
||||
}
|
||||
`;
|
||||
|
||||
// Adopted stylesheet (modern approach — one stylesheet object, many shadow roots)
|
||||
let sheet;
|
||||
try {
|
||||
sheet = new CSSStyleSheet();
|
||||
sheet.replaceSync(CSS);
|
||||
} catch (e) {
|
||||
// Older browser fallback — we'll append <style> tags instead
|
||||
sheet = null;
|
||||
}
|
||||
|
||||
function inject(root) {
|
||||
if (!root || root.__assistFixDone) return;
|
||||
root.__assistFixDone = true;
|
||||
try {
|
||||
if (sheet && root.adoptedStyleSheets !== undefined) {
|
||||
root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];
|
||||
} else {
|
||||
const style = document.createElement('style');
|
||||
style.textContent = CSS;
|
||||
root.appendChild(style);
|
||||
}
|
||||
} catch (e) { /* ignore cross-origin or read-only roots */ }
|
||||
}
|
||||
|
||||
// 1) Inject into document first (catches non-shadow inputs)
|
||||
inject(document.head || document.documentElement);
|
||||
|
||||
// 2) Walk all existing shadow roots
|
||||
function walk(root) {
|
||||
if (!root) return;
|
||||
inject(root);
|
||||
try {
|
||||
root.querySelectorAll('*').forEach(el => {
|
||||
if (el.shadowRoot) walk(el.shadowRoot);
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
walk(document);
|
||||
|
||||
// 3) Monkey-patch attachShadow so every future shadow root gets the style
|
||||
const origAttach = Element.prototype.attachShadow;
|
||||
Element.prototype.attachShadow = function (init) {
|
||||
const root = origAttach.call(this, init);
|
||||
queueMicrotask(() => inject(root));
|
||||
return root;
|
||||
};
|
||||
|
||||
// 4) Periodic sweep for 60s to catch any stragglers (e.g., roots created via
|
||||
// declarative shadow DOM before our patch applied)
|
||||
let passes = 0;
|
||||
const iv = setInterval(() => {
|
||||
walk(document);
|
||||
if (++passes > 60) clearInterval(iv);
|
||||
}, 1000);
|
||||
|
||||
console.log('[assist-fix] v2 loaded; adopted stylesheets =', !!sheet);
|
||||
})();
|
||||
Reference in New Issue
Block a user