steam-theming-utils 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,13 +22,12 @@ findUniqueKey = (key, index = 0) =>
22
22
  (mod) => findAllModules((mod2) => mod2[mod]).length === 1,
23
23
  );
24
24
 
25
- // TODO: sort classes
26
- result = {
25
+ classModules = {
27
26
  ...specialModules,
28
27
  ...parsedModules
29
28
  .map((e) => ({ [e[0]]: e[1] }))
30
29
  .reduce((a, b) => Object.assign(a, b)),
31
- ...classModules
30
+ ...exportedModules
32
31
  .flatMap((a) => {
33
32
  const mod = findFirstModule(a[1], a[0]);
34
33
  if (!mod) {
@@ -37,8 +36,9 @@ result = {
37
36
 
38
37
  return {
39
38
  [a[0]]: Object.keys(mod || {})
39
+ // Remove keys like "duration-app-launch"
40
40
  .filter((e) => !mod[e].match(/^\d+(\.\d+)?(\w{2})?$/))
41
- .map((e) => Object({ [e]: mod[e] }))
41
+ .map((e) => ({ [e]: mod[e] }))
42
42
  .reduce((a, b) => Object.assign(a, b)),
43
43
  };
44
44
  })
@@ -46,10 +46,4 @@ result = {
46
46
  };
47
47
 
48
48
  // return
49
- Object.keys(result)
50
- .sort()
51
- .reduce((obj, key) => {
52
- obj[key] = result[key];
53
-
54
- return obj;
55
- }, {});
49
+ classModules;
@@ -77,7 +77,7 @@ specialModules = {
77
77
  });
78
78
  })();
79
79
 
80
- classModules = [
80
+ exportedModules = [
81
81
  ["aboutsteamdialog", (e) => e.AboutSteamDialog],
82
82
  ["accountpanel", (e) => e.ChangePersonaNameContent],
83
83
  ["accountsettings", (e) => e.Avatar && e.EntryLabel],
@@ -485,7 +485,7 @@ classModules = [
485
485
  // May conflict with other broadcast modules in the future
486
486
  ["vodplayer", (e) => e.BroadcastCtn],
487
487
  ["voicechatheadersteamdeck", (e) => e.ActiveCall],
488
- ["voicesettings", (e) => e.HotkeySettingRow],
488
+ ["voicesettings", (e) => e.MicrophoneTest],
489
489
  // Generic, but returns 1 module
490
490
  ["vrdashboard", (e) => e.FadeRight],
491
491
  // Generic, but returns 1 module
@@ -0,0 +1,35 @@
1
+ function getNormalClass(className) {
2
+ for (const key of Object.keys(classModules)) {
3
+ const mod = classModules[key];
4
+ const keys = Object.keys(mod);
5
+ const name = keys.find((e) => mod[e] === className);
6
+ if (!name) {
7
+ continue;
8
+ }
9
+
10
+ return [key, name].join("_");
11
+ }
12
+ }
13
+
14
+ function normalizeElement(el) {
15
+ const readableClasses = [...el.classList]
16
+ .map(getNormalClass)
17
+ .filter(Boolean)
18
+ .map((e) => `\t${e}`)
19
+ .join("\n");
20
+ if (readableClasses === "") {
21
+ return;
22
+ }
23
+
24
+ el.setAttribute("data-readableclass", `\n${readableClasses}\n`);
25
+ }
26
+
27
+ focusedPopup = [...g_PopupManager.GetPopups()].find((e) => e.focused);
28
+ if (focusedPopup) {
29
+ const elements = [
30
+ ...focusedPopup.m_popup.document.querySelectorAll("[class]"),
31
+ ];
32
+ for (const el of elements) {
33
+ normalizeElement(el);
34
+ }
35
+ }
package/index.js CHANGED
@@ -2,19 +2,13 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
- import { connection, packagePath } from "./shared.js";
5
+ import { connection, readScript, SCRIPT_PATH } from "./shared.js";
6
6
 
7
- const scriptPath = path.join(packagePath, "lib");
8
- const files = fs
9
- .readdirSync(scriptPath)
10
- .filter((e) => e !== "shared.js")
11
- .map((e) => e.replace(".js", ""));
7
+ const files = fs.readdirSync(SCRIPT_PATH).map((e) => e.replace(".js", ""));
12
8
  if (!files.some((e) => process.argv[2] === e)) {
13
- console.error(
14
- "Usage: %s [%s]",
15
- path.basename(process.argv[1]),
16
- files.join("|"),
17
- );
9
+ console.error("Usage: %s <script>", path.basename(process.argv[1]));
10
+ console.error("Where <script>:\n%s", files.map((e) => `- ${e}`).join("\n"));
11
+ connection.close();
18
12
  process.exit(2);
19
13
  }
20
14
 
@@ -27,6 +21,6 @@ connection.Runtime.on("consoleAPICalled", (ev) => {
27
21
  console.error(...ev.args.map((e) => e.description || e.value));
28
22
  });
29
23
 
30
- const script = await import(path.join(scriptPath, `${process.argv[2]}.js`));
24
+ const script = await readScript(process.argv[2]);
31
25
  await script.execute();
32
26
  connection.close();
@@ -1,10 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import cp from "node:child_process";
3
3
  import path from "node:path";
4
- import { packagePath, readFile, run, runWithResult } from "../shared.js";
4
+ import { readFile, run, runCdpFile, runWithResult } from "../shared.js";
5
5
 
6
6
  const CLASS_MAP_FILE = "class_map.json";
7
- const CDP_FILES_PATH = path.join(packagePath, "cdp");
8
7
 
9
8
  export async function execute() {
10
9
  const dflRan = await runWithResult("!!webpackCache");
@@ -14,14 +13,19 @@ export async function execute() {
14
13
  readFile(
15
14
  path.join("node_modules", "decky-frontend-lib", "dist", "webpack.js"),
16
15
  ).replace(/export /g, ""),
16
+ ).catch((e) => {
17
+ // Fails on first launch sometimes
18
+ });
19
+
20
+ // Leave only the relevant modules
21
+ await run(
22
+ "allModules = findAllModules((e) => typeof e === 'object' && !e.__esModule);",
17
23
  );
18
24
  }
19
- await run(readFile(path.join(CDP_FILES_PATH, "class_modules_db.js")));
25
+ await runCdpFile("class_modules_db.js");
20
26
 
21
27
  const filePath = path.join(process.cwd(), CLASS_MAP_FILE);
22
- const output = await runWithResult(
23
- readFile(path.join(CDP_FILES_PATH, "class_modules.js")),
24
- );
28
+ const output = await runCdpFile("class_modules.js");
25
29
 
26
30
  fs.writeFileSync(filePath, JSON.stringify(output));
27
31
  cp.spawnSync("npx", ["@biomejs/biome", "format", "--write", filePath]);
@@ -0,0 +1,18 @@
1
+ import { readScript, runCdpFile, runWithResult, sleep } from "../shared.js";
2
+
3
+ const DELAY = 2;
4
+
5
+ export async function execute() {
6
+ const scriptRan = await runWithResult("!!classModules");
7
+ if (!scriptRan) {
8
+ const script = await readScript("build_class_modules");
9
+ await script.execute();
10
+ }
11
+
12
+ console.log("Waiting for focus in %s seconds...", DELAY);
13
+ await sleep(DELAY * 1_000);
14
+ await runCdpFile("make_readable_classes.js");
15
+
16
+ const focusedPopupName = await runWithResult("focusedPopup.m_strName");
17
+ console.log("Got target %o", focusedPopupName);
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "steam-theming-utils",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A collection of scripts for easier Steam theming",
5
5
  "repository": {
6
6
  "type": "git",
package/shared.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import cdp from "chrome-remote-interface";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import url from "node:url";
4
+ import { fileURLToPath } from "node:url";
5
5
 
6
6
  export const connection = await cdp({
7
7
  host: "127.0.0.1",
@@ -16,14 +16,22 @@ export const connection = await cdp({
16
16
  );
17
17
  process.exit(1);
18
18
  });
19
- export const packagePath = path.dirname(url.fileURLToPath(import.meta.url));
19
+ export const packagePath = path.dirname(fileURLToPath(import.meta.url));
20
+
21
+ export const CDP_FILES_PATH = path.join(packagePath, "cdp");
22
+ export const SCRIPT_PATH = path.join(packagePath, "lib");
20
23
 
21
24
  export const readFile = (file) => fs.readFileSync(file).toString();
25
+ export const readScript = async (name) =>
26
+ await import(path.join(SCRIPT_PATH, `${name}.js`));
22
27
  export const run = async (expression) =>
23
28
  await connection.Runtime.evaluate({
24
29
  expression,
25
30
  awaitPromise: true,
26
31
  returnByValue: true,
27
32
  });
33
+ export const runCdpFile = async (file) =>
34
+ await runWithResult(readFile(path.join(CDP_FILES_PATH, file)));
28
35
  export const runWithResult = async (expression) =>
29
36
  (await run(expression)).result.value;
37
+ export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));