From 00912c0b506a7e32805adc4cdfd349b745b84a70 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 26 Jan 2022 16:04:25 +0000 Subject: [PATCH] Load light theme prior to HTML export to ensure it is present (#7643) --- src/utils/exportUtils/exportCSS.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/utils/exportUtils/exportCSS.ts b/src/utils/exportUtils/exportCSS.ts index ceafed174b..b85c2a9431 100644 --- a/src/utils/exportUtils/exportCSS.ts +++ b/src/utils/exportUtils/exportCSS.ts @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -/* eslint-disable max-len, camelcase */ - import customCSS from "!!raw-loader!./exportCustomCSS.css"; const cssSelectorTextClassesRegex = /\.[\w-]+/g; @@ -34,15 +32,36 @@ function mutateCssText(css: string): string { ); } +function isLightTheme(sheet: CSSStyleSheet): boolean { + return (sheet.ownerNode).dataset.mxTheme?.toLowerCase() === "light"; +} + +async function getRulesFromCssFile(path: string): Promise { + const doc = document.implementation.createHTMLDocument(""); + const styleElement = document.createElement("style"); + + const res = await fetch(path); + styleElement.textContent = await res.text(); + // the style will only be parsed once it is added to a document + doc.body.appendChild(styleElement); + + return styleElement.sheet; +} + // naively culls unused css rules based on which classes are present in the html, // doesn't cull rules which won't apply due to the full selector not matching but gets rid of a LOT of cruft anyway. const getExportCSS = async (usedClasses: Set): Promise => { // only include bundle.css and the data-mx-theme=light styling const stylesheets = Array.from(document.styleSheets).filter(s => { - return s.href?.endsWith("bundle.css") || - (s.ownerNode as HTMLStyleElement).dataset.mxTheme?.toLowerCase() === "light"; + return s.href?.endsWith("bundle.css") || isLightTheme(s); }); + // If the light theme isn't loaded we will have to fetch & parse it manually + if (!stylesheets.some(isLightTheme)) { + const href = document.querySelector('link[rel="stylesheet"][href$="theme-light.css"]').href; + stylesheets.push(await getRulesFromCssFile(href)); + } + let css = ""; for (const stylesheet of stylesheets) { for (const rule of stylesheet.cssRules) {