Styles: Inject into popouts

This commit is contained in:
Sqaaakoi 2025-01-20 07:33:11 +13:00
parent 487c5338d6
commit 494681477f
No known key found for this signature in database
2 changed files with 44 additions and 20 deletions

View file

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { PopoutWindowStore } from "@webpack/common";
export const styleMap = window.VencordStyles ??= new Map(); export const styleMap = window.VencordStyles ??= new Map();
export interface Style { export interface Style {
@ -31,9 +33,9 @@ export function requireStyle(name: string) {
return style; return style;
} }
// TODO: Implement popouts
function findDocuments() { function findDocuments() {
return [document]; const popouts = PopoutWindowStore?.getWindowKeys()?.map(k => PopoutWindowStore?.getWindow(k)?.document) ?? [];
return [document, ...popouts];
} }
/** /**
@ -163,25 +165,39 @@ export const setStyleClassNames = (style: Style | string, classNames: Record<str
}; };
/** /**
* Updates the stylesheet after doing the following to the sourcecode: * Updates the style in a document. This should only be called by {@link compileStyle} or when a new popout is created.
* - Interpolate style classnames * @param style A style object
* @param style **_Must_ be a style with a DOM element**
* @see {@link setStyleClassNames} for more info on style classnames * @see {@link setStyleClassNames} for more info on style classnames
*/ */
export const compileStyle = (style: Style) => { export function updateStyleInDocument(style: Style, doc: Document) {
findDocuments().forEach(doc => { let styleElement = [...doc.head.querySelectorAll<HTMLStyleElement>("style[data-vencord-name]")].find(e => e.dataset.vencordName === style.name);
let styleElement = [...doc.head.querySelectorAll<HTMLStyleElement>("style[data-vencord-name]")].find(e => e.dataset.vencordName === style.name); if (style.enabled) {
if (style.enabled) { if (!styleElement) {
if (!styleElement) { styleElement = doc.createElement("style");
styleElement = doc.createElement("style"); styleElement.dataset.vencordName = style.name;
styleElement.dataset.vencordName = style.name; doc.documentElement.appendChild(styleElement);
document.head.appendChild(styleElement); }
} styleElement.textContent = style.edit ? style.edit(style.source) : style.source;
styleElement.textContent = style.edit ? style.edit(style.source) : style.source; } else styleElement?.remove();
} else styleElement?.remove(); }
});
}; /**
* Updates styles in the DOM of all documents
* @param style A style object
* @see {@link setStyleClassNames} for more info on style classnames
*/
export function compileStyle(style: Style) {
findDocuments().forEach(doc => updateStyleInDocument(style, doc));
}
/**
* Updates styles in the DOM of all documents
* @param doc The document to add styles to
* @see {@link setStyleClassNames} for more info on style classnames
*/
export function addStylesToDocument(doc: Document) {
styleMap.forEach(style => updateStyleInDocument(style, doc));
}
/** /**
* @param name The classname * @param name The classname

View file

@ -17,8 +17,8 @@
*/ */
import { Settings, SettingsStore } from "@api/Settings"; import { Settings, SettingsStore } from "@api/Settings";
import { createStyle, setStyle } from "@api/Styles"; import { addStylesToDocument, createStyle, setStyle } from "@api/Styles";
import { ThemeStore } from "@webpack/common"; import { PopoutWindowStore, ThemeStore } from "@webpack/common";
async function initSystemValues() { async function initSystemValues() {
const values = await VencordNative.themes.getSystemValues(); const values = await VencordNative.themes.getSystemValues();
@ -86,4 +86,12 @@ document.addEventListener("DOMContentLoaded", () => {
if (!IS_WEB) if (!IS_WEB)
VencordNative.quickCss.addThemeChangeListener(initThemes); VencordNative.quickCss.addThemeChangeListener(initThemes);
window.addEventListener("message", event => {
const { discordPopoutEvent } = event.data || {};
if (discordPopoutEvent?.type !== "loaded") return;
const popoutWindow = PopoutWindowStore.getWindow(discordPopoutEvent.key);
if (!popoutWindow?.document) return;
addStylesToDocument(popoutWindow.document);
});
}); });