diff options
author | Vijay A <avijayr@protonmail.com> | 2021-08-21 09:03:32 +0530 |
---|---|---|
committer | Vijay A <avijayr@protonmail.com> | 2021-08-21 09:16:59 +0530 |
commit | 16d8de38b74c298fda27c22c804850a999183d57 (patch) | |
tree | 6c869677e3bb8472f5b86c92908bb256ec0c5be5 /scripts/build-theme-info.js | |
parent | chore: typescript conversion (diff) | |
download | ferdium-app-16d8de38b74c298fda27c22c804850a999183d57.tar.gz ferdium-app-16d8de38b74c298fda27c22c804850a999183d57.tar.zst ferdium-app-16d8de38b74c298fda27c22c804850a999183d57.zip |
chore: move build-time js files out of 'src' and into 'scripts'
so that they not packaged into final deployable artefact
Diffstat (limited to 'scripts/build-theme-info.js')
-rw-r--r-- | scripts/build-theme-info.js | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/scripts/build-theme-info.js b/scripts/build-theme-info.js new file mode 100644 index 000000000..4058be942 --- /dev/null +++ b/scripts/build-theme-info.js | |||
@@ -0,0 +1,97 @@ | |||
1 | /** | ||
2 | * Script to get information on which selectors use the brand color. | ||
3 | * This is needed to provide the accent color feature - the feature will create CSS rules | ||
4 | * to overwrite the color of these selectors. | ||
5 | */ | ||
6 | const css = require('css'); | ||
7 | const fs = require('fs-extra'); | ||
8 | const path = require('path'); | ||
9 | const theme = require('@meetfranz/theme'); | ||
10 | |||
11 | // Colors that should be replaced with the accent color | ||
12 | const accentColors = [ | ||
13 | theme.DEFAULT_ACCENT_COLOR.toLowerCase(), | ||
14 | '#7367f0', | ||
15 | '#5e50ee', | ||
16 | ]; | ||
17 | |||
18 | const cssFile = path.join(__dirname, '..', '..', 'build', 'styles', 'main.css'); | ||
19 | const outputFile = path.join(__dirname, '..', 'assets', 'themeInfo.json'); | ||
20 | |||
21 | // Parse and extract the rules from a CSS stylesheet file | ||
22 | async function getRulesFromCssFile(file) { | ||
23 | const cssSrc = (await fs.readFile(file)).toString(); | ||
24 | const cssTree = css.parse(cssSrc); | ||
25 | |||
26 | return cssTree.stylesheet.rules; | ||
27 | } | ||
28 | |||
29 | /** | ||
30 | * Get all selectors from a list of parsed CSS rules that set any property to one of the specified | ||
31 | * values. | ||
32 | * | ||
33 | * This function will output an object in this format: | ||
34 | * { | ||
35 | * 'property-name': [ array of selectors ] | ||
36 | * } | ||
37 | * | ||
38 | * e.g. | ||
39 | * { | ||
40 | * 'background-color': [ | ||
41 | * '.background', | ||
42 | * '.input-dark' | ||
43 | * ] | ||
44 | * } | ||
45 | * | ||
46 | * @param {Array} rules Rules as outputted by the `css` module | ||
47 | * @param {Array} values Array of values that should be searched for | ||
48 | */ | ||
49 | function getSelectorsDeclaringValues(rules, values) { | ||
50 | const output = {}; | ||
51 | |||
52 | rules.forEach((rule) => { | ||
53 | if (rule.declarations) { | ||
54 | rule.declarations.forEach((declaration) => { | ||
55 | if (declaration.type === 'declaration' | ||
56 | && values.includes(declaration.value.toLowerCase())) { | ||
57 | if (!output[declaration.property]) { | ||
58 | output[declaration.property] = []; | ||
59 | } | ||
60 | output[declaration.property] = output[declaration.property].concat(rule.selectors); | ||
61 | } | ||
62 | }); | ||
63 | } | ||
64 | }); | ||
65 | |||
66 | return output; | ||
67 | } | ||
68 | |||
69 | async function generateThemeInfo() { | ||
70 | if (!await fs.pathExists(cssFile)) { | ||
71 | console.log('Please make sure to build the project first.'); | ||
72 | return; | ||
73 | } | ||
74 | |||
75 | // Read and parse css bundle | ||
76 | const rules = await getRulesFromCssFile(cssFile); | ||
77 | |||
78 | console.log(`Found ${rules.length} rules`); | ||
79 | |||
80 | // Get rules specifying the brand colors | ||
81 | const brandRules = getSelectorsDeclaringValues(rules, accentColors); | ||
82 | |||
83 | console.log(`Found ${Object.keys(brandRules).join(', ')} properties that set color to brand color`); | ||
84 | |||
85 | // Join array of declarations into a single string | ||
86 | Object.keys(brandRules).forEach((rule) => { | ||
87 | brandRules[rule] = brandRules[rule].join(', '); | ||
88 | }); | ||
89 | |||
90 | // Write object with theme info to file | ||
91 | fs.writeFile( | ||
92 | outputFile, | ||
93 | JSON.stringify(brandRules), | ||
94 | ); | ||
95 | } | ||
96 | |||
97 | generateThemeInfo(); | ||