141 lines
4.2 KiB
JavaScript
141 lines
4.2 KiB
JavaScript
// @ts-check
|
|
import path from 'node:path';
|
|
|
|
import less from 'less';
|
|
|
|
import {getDestDir, absolutePath} from './paths.js';
|
|
import {PLATFORM} from './platform.js';
|
|
import * as reload from './reload.js';
|
|
import {createTask} from './task.js';
|
|
import {readFile, writeFile} from './utils.js';
|
|
|
|
/** @typedef {import('chokidar').FSWatcher} FSWatcher */
|
|
/** @typedef {import('./types.d.ts').CSSEntry} CSSEntry */
|
|
|
|
/** @type {CSSEntry[]} */
|
|
const cssEntries = [
|
|
{
|
|
src: 'src/ui/devtools/style.less',
|
|
dest: 'ui/devtools/style.css',
|
|
},
|
|
{
|
|
src: 'src/ui/options/style.less',
|
|
dest: 'ui/options/style.css',
|
|
},
|
|
{
|
|
src: 'src/ui/popup/style.less',
|
|
dest: 'ui/popup/style.css',
|
|
},
|
|
{
|
|
src: 'src/ui/stylesheet-editor/style.less',
|
|
dest: 'ui/stylesheet-editor/style.css',
|
|
},
|
|
];
|
|
|
|
async function bundleCSSEntry(entry, plus) {
|
|
const src = absolutePath(entry.src);
|
|
const srcDir = path.dirname(src);
|
|
|
|
let input = await readFile(src);
|
|
if (!plus) {
|
|
const startToken = '/* @plus-start */';
|
|
const endToken = '/* @plus-end */';
|
|
const startIndex = input.indexOf(startToken);
|
|
const endIndex = input.indexOf(endToken, startIndex);
|
|
if (startIndex >= 0 && endIndex >= 0) {
|
|
input = input.substring(0, startIndex) + input.substring(endIndex + endToken.length);
|
|
}
|
|
}
|
|
|
|
const output = await less.render(input, {paths: [srcDir], math: 'always'});
|
|
entry.watchFiles = output.imports;
|
|
return output.css;
|
|
}
|
|
|
|
async function writeFiles(dest, platforms, debug, css) {
|
|
const enabledPlatforms = Object.values(PLATFORM).filter((platform) => platform !== PLATFORM.API && platforms[platform]);
|
|
for (const platform of enabledPlatforms) {
|
|
const dir = getDestDir({debug, platform});
|
|
await writeFile(`${dir}/${dest}`, css);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {CSSEntry} entry
|
|
* @returns {string}
|
|
*/
|
|
function getEntryFile(entry) {
|
|
return absolutePath(entry.src);
|
|
}
|
|
|
|
/**
|
|
* @param {CSSEntry[]} cssEntries
|
|
* @returns {ReturnType<typeof createTask>}
|
|
*/
|
|
export function createBundleCSSTask(cssEntries) {
|
|
/** @type {string[]} */
|
|
let currentWatchFiles;
|
|
|
|
const getWatchFiles = () => {
|
|
const watchFiles = new Set();
|
|
cssEntries.forEach((entry) => {
|
|
entry.watchFiles?.forEach((file) => watchFiles.add(file));
|
|
const entryFile = getEntryFile(entry);
|
|
if (!watchFiles.has(entryFile)) {
|
|
watchFiles.add(entryFile);
|
|
}
|
|
});
|
|
currentWatchFiles = Array.from(watchFiles);
|
|
return currentWatchFiles;
|
|
};
|
|
|
|
const bundleCSS = async ({platforms, debug}) => {
|
|
for (const entry of cssEntries) {
|
|
for (const platform in platforms) {
|
|
if (!platforms[platform]) {
|
|
continue;
|
|
}
|
|
const css = await bundleCSSEntry(entry, platform === PLATFORM.CHROMIUM_MV2_PLUS);
|
|
await writeFiles(entry.dest, {[platform]: true}, debug, css);
|
|
}
|
|
}
|
|
};
|
|
|
|
/** @type {(changedFiles: string[], watcher: FSWatcher, platforms: any) => Promise<void>} */
|
|
const onChange = async (changedFiles, watcher, platforms) => {
|
|
const entries = cssEntries.filter((entry) => {
|
|
const entryFile = getEntryFile(entry);
|
|
return changedFiles.some((changed) => {
|
|
return entry.watchFiles?.includes(changed) || changed === entryFile;
|
|
});
|
|
});
|
|
for (const entry of entries) {
|
|
const css = await bundleCSSEntry(entry, true);
|
|
await writeFiles(entry.dest, platforms, true, css);
|
|
}
|
|
|
|
const newWatchFiles = getWatchFiles();
|
|
watcher.unwatch(
|
|
currentWatchFiles.filter((oldFile) => !newWatchFiles.includes(oldFile))
|
|
);
|
|
watcher.add(
|
|
newWatchFiles.filter((newFile) => currentWatchFiles.includes(newFile))
|
|
);
|
|
|
|
reload.reload({type: reload.CSS});
|
|
};
|
|
|
|
return createTask(
|
|
'bundle-css',
|
|
bundleCSS,
|
|
).addWatcher(
|
|
() => {
|
|
currentWatchFiles = getWatchFiles();
|
|
return currentWatchFiles;
|
|
},
|
|
onChange,
|
|
);
|
|
}
|
|
|
|
export default createBundleCSSTask(cssEntries);
|