aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorVen <vendicated@riseup.net>2022-12-25 20:47:35 +0100
committerGitHub <noreply@github.com>2022-12-25 20:47:35 +0100
commit2e5d27b6b63097e96e25819df7a8cdd667c521b3 (patch)
tree082b0f1c7cb0210d208c7cb8017e9da97b3b4196 /scripts
parent2172cae779fb24f9bcc8c54a0b6538da0b52bafd (diff)
downloadVencord-2e5d27b6b63097e96e25819df7a8cdd667c521b3.tar.gz
Vencord-2e5d27b6b63097e96e25819df7a8cdd667c521b3.tar.bz2
Vencord-2e5d27b6b63097e96e25819df7a8cdd667c521b3.zip
feat: Proper CSS api & css bundle (#269)
Co-authored-by: Vap0r1ze <superdash993@gmail.com>
Diffstat (limited to 'scripts')
-rw-r--r--[-rwxr-xr-x]scripts/build/buildWeb.mjs74
-rw-r--r--scripts/build/common.mjs41
-rw-r--r--scripts/build/module/style.js26
3 files changed, 106 insertions, 35 deletions
diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs
index c85d8aa..3ad43b2 100755..100644
--- a/scripts/build/buildWeb.mjs
+++ b/scripts/build/buildWeb.mjs
@@ -20,13 +20,13 @@
import esbuild from "esbuild";
import { zip } from "fflate";
-import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
-import { readFile } from "fs/promises";
-import { join, resolve } from "path";
+import { readFileSync } from "fs";
+import { appendFile, mkdir, readFile, rm, writeFile } from "fs/promises";
+import { join } from "path";
// wtf is this assert syntax
import PackageJSON from "../../package.json" assert { type: "json" };
-import { commonOpts, fileIncludePlugin, gitHashPlugin, gitRemotePlugin, globPlugins, watch } from "./common.mjs";
+import { commonOpts, globPlugins, watch } from "./common.mjs";
/**
* @type {esbuild.BuildOptions}
@@ -39,9 +39,7 @@ const commonOptions = {
external: ["plugins", "git-hash"],
plugins: [
globPlugins,
- gitHashPlugin,
- gitRemotePlugin,
- fileIncludePlugin
+ ...commonOpts.plugins,
],
target: ["esnext"],
define: {
@@ -77,9 +75,13 @@ await Promise.all(
]
);
+/**
+ * @type {(target: string, files: string[], shouldZip: boolean) => Promise<void>}
+ */
async function buildPluginZip(target, files, shouldZip) {
const entries = {
- "dist/Vencord.js": readFileSync("dist/browser.js"),
+ "dist/Vencord.js": await readFile("dist/browser.js"),
+ "dist/Vencord.css": await readFile("dist/browser.css"),
...Object.fromEntries(await Promise.all(files.map(async f => [
(f.startsWith("manifest") ? "manifest.json" : f),
await readFile(join("browser", f))
@@ -87,29 +89,47 @@ async function buildPluginZip(target, files, shouldZip) {
};
if (shouldZip) {
- zip(entries, {}, (err, data) => {
- if (err) {
- console.error(err);
- process.exitCode = 1;
- } else {
- writeFileSync("dist/" + target, data);
- console.info("Extension written to dist/" + target);
- }
+ return new Promise((resolve, reject) => {
+ zip(entries, {}, (err, data) => {
+ if (err) {
+ reject(err);
+ } else {
+ const out = join("dist", target);
+ writeFile(out, data).then(() => {
+ console.info("Extension written to " + out);
+ resolve();
+ }).catch(reject);
+ }
+ });
});
} else {
- if (existsSync(target))
- rmSync(target, { recursive: true });
- for (const entry in entries) {
- const destination = "dist/" + target + "/" + entry;
- const parentDirectory = resolve(destination, "..");
- mkdirSync(parentDirectory, { recursive: true });
- writeFileSync(destination, entries[entry]);
- }
+ await rm(target, { recursive: true, force: true });
+ await Promise.all(Object.entries(entries).map(async ([file, content]) => {
+ const dest = join("dist", target, file);
+ const parentDirectory = join(dest, "..");
+ await mkdir(parentDirectory, { recursive: true });
+ await writeFile(dest, content);
+ }));
+
console.info("Unpacked Extension written to dist/" + target);
}
}
-await buildPluginZip("extension-v3.zip", ["modifyResponseHeaders.json", "content.js", "manifestv3.json"], true);
-await buildPluginZip("extension-v2.zip", ["background.js", "content.js", "manifestv2.json"], true);
-await buildPluginZip("extension-v2-unpacked", ["background.js", "content.js", "manifestv2.json"], false);
+const cssText = "`" + readFileSync("dist/Vencord.user.css", "utf-8").replaceAll("`", "\\`") + "`";
+const cssRuntime = `
+;document.addEventListener("DOMContentLoaded", () => document.documentElement.appendChild(
+ Object.assign(document.createElement("style"), {
+ textContent: ${cssText},
+ id: "vencord-css-core"
+ }),
+ { once: true }
+));
+`;
+
+await Promise.all([
+ appendFile("dist/Vencord.user.js", cssRuntime),
+ buildPluginZip("extension-v3.zip", ["modifyResponseHeaders.json", "content.js", "manifestv3.json"], true),
+ buildPluginZip("extension-v2.zip", ["background.js", "content.js", "manifestv2.json"], true),
+ buildPluginZip("extension-v2-unpacked", ["background.js", "content.js", "manifestv2.json"], false),
+]);
diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs
index 11aaa81..2743c70 100644
--- a/scripts/build/common.mjs
+++ b/scripts/build/common.mjs
@@ -17,9 +17,9 @@
*/
import { exec, execSync } from "child_process";
-import { existsSync } from "fs";
+import { existsSync, readFileSync } from "fs";
import { readdir, readFile } from "fs/promises";
-import { join } from "path";
+import { join, relative } from "path";
import { promisify } from "util";
export const watch = process.argv.includes("--watch");
@@ -35,7 +35,7 @@ export const banner = {
// https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
/**
- * @type {esbuild.Plugin}
+ * @type {import("esbuild").Plugin}
*/
export const makeAllPackagesExternalPlugin = {
name: "make-all-packages-external",
@@ -46,7 +46,7 @@ export const makeAllPackagesExternalPlugin = {
};
/**
- * @type {esbuild.Plugin}
+ * @type {import("esbuild").Plugin}
*/
export const globPlugins = {
name: "glob-plugins",
@@ -87,7 +87,7 @@ export const globPlugins = {
};
/**
- * @type {esbuild.Plugin}
+ * @type {import("esbuild").Plugin}
*/
export const gitHashPlugin = {
name: "git-hash-plugin",
@@ -103,7 +103,7 @@ export const gitHashPlugin = {
};
/**
- * @type {esbuild.Plugin}
+ * @type {import("esbuild").Plugin}
*/
export const gitRemotePlugin = {
name: "git-remote-plugin",
@@ -125,7 +125,7 @@ export const gitRemotePlugin = {
};
/**
- * @type {esbuild.Plugin}
+ * @type {import("esbuild").Plugin}
*/
export const fileIncludePlugin = {
name: "file-include-plugin",
@@ -147,6 +147,31 @@ export const fileIncludePlugin = {
}
};
+const styleModule = readFileSync("./scripts/build/module/style.js", "utf-8");
+/**
+ * @type {import("esbuild").Plugin}
+ */
+export const stylePlugin = {
+ name: "style-plugin",
+ setup: ({ onResolve, onLoad }) => {
+ onResolve({ filter: /\.css\?managed$/, namespace: "file" }, ({ path, resolveDir }) => ({
+ path: relative(process.cwd(), join(resolveDir, path.replace("?managed", ""))),
+ namespace: "managed-style",
+ }));
+ onLoad({ filter: /\.css$/, namespace: "managed-style" }, async ({ path }) => {
+ const css = await readFile(path, "utf-8");
+ const name = relative(process.cwd(), path).replaceAll("\\", "/");
+
+ return {
+ loader: "js",
+ contents: styleModule
+ .replaceAll("STYLE_SOURCE", JSON.stringify(css))
+ .replaceAll("STYLE_NAME", JSON.stringify(name))
+ };
+ });
+ }
+};
+
/**
* @type {import("esbuild").BuildOptions}
*/
@@ -158,7 +183,7 @@ export const commonOpts = {
sourcemap: watch ? "inline" : "",
legalComments: "linked",
banner,
- plugins: [fileIncludePlugin, gitHashPlugin, gitRemotePlugin],
+ plugins: [fileIncludePlugin, gitHashPlugin, gitRemotePlugin, stylePlugin],
external: ["~plugins", "~git-hash", "~git-remote"],
inject: ["./scripts/build/inject/react.mjs"],
jsxFactory: "VencordCreateElement",
diff --git a/scripts/build/module/style.js b/scripts/build/module/style.js
new file mode 100644
index 0000000..5981a3d
--- /dev/null
+++ b/scripts/build/module/style.js
@@ -0,0 +1,26 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+(window.VencordStyles ??= new Map()).set(STYLE_NAME, {
+ name: STYLE_NAME,
+ source: STYLE_SOURCE,
+ classNames: {},
+ dom: null,
+});
+
+export default STYLE_NAME;