183 lines
4.5 KiB
JavaScript
183 lines
4.5 KiB
JavaScript
// Adds configurable font size and family controls for multiline textareas across the ComfyUI interface.
|
|
// Applies font settings globally via DOM traversal and a MutationObserver for dynamically added elements.
|
|
|
|
import { app } from "../../../scripts/app.js";
|
|
import { $el } from "../../../scripts/ui.js";
|
|
import { ConfigSetting, addJNodesSetting } from "./common/SettingsManager.js"
|
|
|
|
class CustomizationConfigSetting extends ConfigSetting {
|
|
constructor(settingName, defaultValue) {
|
|
super("Customization." + settingName, defaultValue);
|
|
}
|
|
}
|
|
|
|
export let setting_bEnabled = new CustomizationConfigSetting("MultilineText.Font.Enabled", false);
|
|
export let setting_FontSize = new CustomizationConfigSetting("MultilineText.Font.Size", 80);
|
|
export let setting_FontFamily = new CustomizationConfigSetting("MultilineText.Font.Family", 'monospace');
|
|
|
|
function setFontSize(text, size) {
|
|
text.style.fontSize = size.toString() + "%";
|
|
}
|
|
|
|
function setFontFamily(text, fontFamily) {
|
|
text.style.fontFamily = fontFamily;
|
|
}
|
|
|
|
function setFontOnGivenElement(el, bForced = false) {
|
|
if (!el || !(el instanceof Element)) return;
|
|
|
|
if (!bForced && el.dataset?.jnodesFontApplied) return;
|
|
el.dataset.jnodesFontApplied = "true";
|
|
|
|
setFontSize(el, setting_FontSize.value);
|
|
setFontFamily(el, setting_FontFamily.value);
|
|
}
|
|
|
|
function setFontOnAllTexts(bForced = false) {
|
|
loopOverCollection(document.children, bForced);
|
|
}
|
|
|
|
function loopOverCollection(collection, bForced = false) {
|
|
|
|
if (!collection) { return; }
|
|
|
|
for (const node of collection) {
|
|
|
|
// Direct textarea
|
|
if (node.tagName === "TEXTAREA" ||
|
|
(node.tagName === "INPUT" && node.type === "text")) {
|
|
setFontOnGivenElement(node, bForced);
|
|
}
|
|
|
|
// Any text inside newly added subtree
|
|
const elements = node.querySelectorAll?.(
|
|
'textarea, input[type="text"]'
|
|
);
|
|
if (elements?.length) {
|
|
for (const element of elements) {
|
|
setFontOnGivenElement(element, bForced);
|
|
}
|
|
}
|
|
|
|
loopOverCollection(node.children, bForced);
|
|
}
|
|
}
|
|
|
|
app.registerExtension({
|
|
name: "JNodes.Customization.MultilineText.Font",
|
|
async loadedGraphNode(node) {
|
|
|
|
if (!setting_bEnabled.value) { return; }
|
|
|
|
for (const wid in node.widgets) {
|
|
const element = node.widgets[wid]?.element;
|
|
|
|
if (!element) { continue; }
|
|
|
|
if (element.tagName === "TEXTAREA" ||
|
|
(element.tagName === "INPUT" && element.type === "text")) {
|
|
setFontOnGivenElement(node);
|
|
}
|
|
}
|
|
},
|
|
async setup() {
|
|
|
|
// Font Control Enabled
|
|
{
|
|
const labelWidget = $el("label", {
|
|
textContent: "Text Font Control Enabled (requires page reload):",
|
|
});
|
|
|
|
const settingWidget = $el(
|
|
"input",
|
|
{
|
|
type: "checkbox",
|
|
checked: setting_bEnabled.value,
|
|
oninput: (e) => {
|
|
setting_bEnabled.value = e.target.checked;
|
|
},
|
|
},
|
|
);
|
|
|
|
const tooltip =
|
|
"Whether to affect font typeface and size used in text boxes. " +
|
|
"Requires page reload.";
|
|
addJNodesSetting(labelWidget, settingWidget, tooltip);
|
|
}
|
|
|
|
// Font Family Setting
|
|
{
|
|
const supportedTypefaces =
|
|
[
|
|
'monospace', 'Arial, sans-serif', 'Lora',
|
|
];
|
|
|
|
const labelWidget = $el("label", {
|
|
textContent: "Text Font Family:",
|
|
});
|
|
|
|
const settingWidget = $el(
|
|
"select",
|
|
{
|
|
oninput: (e) => {
|
|
setting_FontFamily.value = e.target.value;
|
|
setFontOnAllTexts(true /* bForced */);
|
|
},
|
|
},
|
|
supportedTypefaces.map((m) =>
|
|
$el("option", {
|
|
value: m,
|
|
textContent: m,
|
|
selected: setting_FontFamily.value === m,
|
|
})
|
|
)
|
|
);
|
|
|
|
const tooltip =
|
|
"The font typeface to use for text boxes";
|
|
addJNodesSetting(labelWidget, settingWidget, tooltip);
|
|
}
|
|
|
|
// Font Size Setting
|
|
{
|
|
const labelWidget = $el("label", {
|
|
textContent: "Text Font Size (%):",
|
|
});
|
|
|
|
const settingWidget = $el("input", {
|
|
type: "number",
|
|
min: "1",
|
|
value: setting_FontSize.value,
|
|
oninput: (e) => {
|
|
let value = e.target.valueAsNumber;
|
|
if (value <= 1.0) { value = 1.0; }
|
|
setting_FontSize.value = value;
|
|
setFontOnAllTexts(true /* bForced */);
|
|
},
|
|
});
|
|
|
|
const tooltip =
|
|
"The font size (expressed as a percentage) to use for text boxes";
|
|
addJNodesSetting(labelWidget, settingWidget, tooltip);
|
|
}
|
|
|
|
function observeNewTextAreas() {
|
|
|
|
const observer = new MutationObserver((mutations) => {
|
|
for (const mutation of mutations) {
|
|
|
|
loopOverCollection(mutation.addedNodes);
|
|
}
|
|
});
|
|
|
|
observer.observe(document.body, {
|
|
childList: true,
|
|
subtree: true,
|
|
});
|
|
}
|
|
|
|
if (!setting_bEnabled.value) { return; }
|
|
|
|
observeNewTextAreas();
|
|
}
|
|
}); |