Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Fix html exporting and improve output size (#7312)
Browse files Browse the repository at this point in the history
  • Loading branch information
t3chguy authored Dec 9, 2021
1 parent 40b2a90 commit 3f4b5df
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 26 deletions.
9 changes: 8 additions & 1 deletion src/utils/exportUtils/HtmlExport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -419,11 +419,18 @@ export default class HTMLExporter extends Exporter {
this.updateProgress(`Fetched ${res.length} events in ${(fetchEnd - fetchStart)/1000}s`, true, false);

this.updateProgress("Creating HTML...");

const usedClasses = new Set<string>();
for (let page = 0; page < res.length / 1000; page++) {
const html = await this.createHTML(res, page * 1000);
const document = new DOMParser().parseFromString(html, "text/html");
document.querySelectorAll("*").forEach(element => {
element.classList.forEach(c => usedClasses.add(c));
});
this.addFile(`messages${page ? page + 1 : ""}.html`, new Blob([html]));
}
const exportCSS = await getExportCSS();

const exportCSS = await getExportCSS(usedClasses);
this.addFile("css/style.css", new Blob([exportCSS]));
this.addFile("js/script.js", new Blob([exportJS]));

Expand Down
67 changes: 43 additions & 24 deletions src/utils/exportUtils/exportCSS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,52 @@ limitations under the License.

import customCSS from "!!raw-loader!./exportCustomCSS.css";

const getExportCSS = async (): Promise<string> => {
const stylesheets: string[] = [];
document.querySelectorAll('link[rel="stylesheet"]').forEach((e: any) => {
if (e.href.endsWith("bundle.css") || e.href.endsWith("theme-light.css")) {
stylesheets.push(e.href);
}
const cssSelectorTextClassesRegex = /\.[\w-]+/g;

function mutateCssText(css: string): string {
// replace used fonts so that we don't have to bundle Inter & Inconsalata
return css
.replace(
/font-family: ?(Inter|'Inter'|"Inter")/g,
`font-family: -apple-system, BlinkMacSystemFont, avenir next,
avenir, segoe ui, helvetica neue, helvetica, Ubuntu, roboto, noto, arial, sans-serif`,
)
.replace(
/font-family: ?Inconsolata/g,
"font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace",
);
}

// 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<string>): Promise<string> => {
// 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 === "light";
});
let CSS = "";

let css = "";
for (const stylesheet of stylesheets) {
const res = await fetch(stylesheet);
const innerText = await res.text();
CSS += innerText;
for (const rule of stylesheet.cssRules) {
if (rule instanceof CSSFontFaceRule) continue; // we don't want to bundle any fonts

const selectorText = (rule as CSSStyleRule).selectorText;

// only skip the rule if all branches (,) of the selector are redundant
if (selectorText?.split(",").every(selector => {
const classes = selector.match(cssSelectorTextClassesRegex);
if (classes && !classes.every(c => usedClasses.has(c.substring(1)))) {
return true; // signal as a redundant selector
}
})) {
continue; // skip this rule as it is redundant
}

css += mutateCssText(rule.cssText) + "\n";
}
}
const fontFaceRegex = /@font-face {.*?}/sg;

CSS = CSS.replace(fontFaceRegex, '');
CSS = CSS.replace(
/font-family: (Inter|'Inter')/g,
`font-family: -apple-system, BlinkMacSystemFont, avenir next,
avenir, segoe ui, helvetica neue, helvetica, Ubuntu, roboto, noto, arial, sans-serif`,
);
CSS = CSS.replace(
/font-family: Inconsolata/g,
"font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace",
);

return CSS + customCSS;

return css + customCSS;
};

export default getExportCSS;
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"declaration": true,
"jsx": "react",
"lib": [
"es2019",
"es2020",
"dom",
"dom.iterable"
],
Expand Down

0 comments on commit 3f4b5df

Please sign in to comment.