188 lines
6.5 KiB
JavaScript
188 lines
6.5 KiB
JavaScript
import resolve from '@rollup/plugin-node-resolve';
|
|
import terser from '@rollup/plugin-terser';
|
|
import copy from 'rollup-plugin-copy';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
import { version } from './package.json';
|
|
|
|
function install(options = {}) {
|
|
const sourcePath = options.sourcePath || 'source/';
|
|
const devPath = options.devPath || 'dev/';
|
|
const minPath = options.minPath || 'min/';
|
|
|
|
// Helper: parse CSS with variable substitutions
|
|
function parseCss(css, values) {
|
|
return css.replace(/\$(\w+)(\[\d+\])?/g, (match, key, index) => {
|
|
let value = values[key];
|
|
if (index) {
|
|
const idx = parseInt(index.slice(1, -1));
|
|
value = value[idx];
|
|
}
|
|
|
|
if (typeof value === 'string') {
|
|
return value;
|
|
}
|
|
|
|
// Handle numeric arrays (e.g., RGB or RGBA)
|
|
if (Array.isArray(value[0])) {
|
|
// Already nested arrays
|
|
return value
|
|
.map(vals => `rgb${vals.length === 4 ? 'a' : ''}(${vals.join(', ')})`)
|
|
.join(', ');
|
|
} else {
|
|
// Single array
|
|
return `rgb${value.length === 4 ? 'a' : ''}(${value.join(', ')})`;
|
|
}
|
|
});
|
|
}
|
|
|
|
function readJsonc(filePath) {
|
|
const jsoncText = fs.readFileSync(filePath, 'utf-8');
|
|
let text = jsoncText.replace(/\/\/.*$/gm, ''); // Remove single-line comments
|
|
text = text.replace(/\/\*[\s\S]*?\*\//g, ''); // Remove multi-line comments
|
|
text = text.replace(/,\s*(?=[}\]])/g, ''); // Remove trailing commas in objects and arrays
|
|
|
|
return JSON.parse(text);
|
|
}
|
|
|
|
function writeFile(filePath, data) {
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
fs.writeFileSync(filePath, typeof data === 'string' ? data : data.toString('utf-8'));
|
|
return data.length;
|
|
}
|
|
|
|
function formatColor(rgb) {
|
|
return '#' + rgb.map(c => c.toString(16).padStart(2, '0').toUpperCase()).join('');
|
|
}
|
|
|
|
function writeBundle() {
|
|
const themesDir = path.join(sourcePath, 'UI', 'themes');
|
|
const themes = fs.readdirSync(themesDir).filter(name => !['.', '_'].includes(name[0]));
|
|
|
|
const themeData = {};
|
|
for (const theme of themes) {
|
|
const themeJsonPath = path.join(themesDir, theme, 'json', 'theme.jsonc');
|
|
themeData[theme] = readJsonc(themeJsonPath);
|
|
themeData[theme].themeClass = 'OxTheme' + theme[0].toUpperCase() + theme.slice(1);
|
|
}
|
|
|
|
const cssPath = path.join(sourcePath, 'UI', 'css', 'theme.css');
|
|
const css = fs.readFileSync(cssPath, 'utf-8')
|
|
|
|
for (const theme of themes) {
|
|
let themeCss = parseCss(css, themeData[theme]);
|
|
themeCss = themeCss.replace(/\.png\)/g, `.png?${version})`);
|
|
|
|
writeFile(path.join(devPath, 'UI', 'themes', theme, 'css', 'theme.css'), themeCss);
|
|
writeFile(path.join(minPath, 'UI', 'themes', theme, 'css', 'theme.css'), themeCss);
|
|
}
|
|
|
|
const uiImages = {}
|
|
const svgDir = path.join(sourcePath, 'UI', 'svg');
|
|
const svgs = fs.readdirSync(svgDir).filter(name => !['.', '_'].includes(name[0]));
|
|
for (const filename of svgs) {
|
|
const svgPath = path.join(svgDir, filename);
|
|
let svg = fs.readFileSync(svgPath, 'utf-8')
|
|
svg = svg.replace(/\n\s*/g, '');
|
|
svg = svg.replace(/<!--.+?-->/g, '');
|
|
uiImages[filename.slice(0, -4)] = svg
|
|
if (filename.startsWith('symbolLoading')) {
|
|
for (const theme of themes) {
|
|
let themeSVG = svg.replace(/#808080/g, formatColor(themeData[theme]['symbolDefaultColor']))
|
|
writeFile(path.join(devPath, 'UI', 'themes', theme, 'svg', filename), themeSVG);
|
|
writeFile(path.join(minPath, 'UI', 'themes', theme, 'svg', filename), themeSVG);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
name: 'theme-plugin',
|
|
writeBundle
|
|
};
|
|
}
|
|
|
|
// TBD: get version
|
|
// TBD: add ' OxJS %s (c) %s 0x2620, dual-licensed GPL/MIT, see https://oxjs.org for details ' % (version, year)
|
|
//
|
|
/*
|
|
|
|
// kind of inline now, but missing cache busting!
|
|
# Ox.UI CSS
|
|
css = read_text(source_path + 'UI/css/UI.css')
|
|
css = css.replace('$import', '\n'.join([
|
|
'@import url("../themes/%s/css/theme.css?%s");' % (theme, version) for theme in themes
|
|
]))
|
|
write_file('%sUI/css/UI.css' % dev_path, css)
|
|
write_file('%sUI/css/UI.css' % min_path, css)
|
|
|
|
# Ox.UI SVGs
|
|
ui_images = {}
|
|
path = source_path + 'UI/svg/'
|
|
for filename in [filename for filename in os.listdir(path) if not filename[0] in '._']:
|
|
svg = read_text(path + filename)
|
|
svg = re.sub(r'\n\s*', '', svg)
|
|
svg = re.sub(r'<!--.+?-->', '', svg)
|
|
# end fix
|
|
ui_images[filename[:-4]] = svg
|
|
if filename.startswith('symbolLoading'):
|
|
for theme in themes:
|
|
theme_svg = re.sub(r'#808080', format_hex(theme_data[theme]['symbolDefaultColor']), svg)
|
|
write_file('%sUI/themes/%s/svg/%s' % (dev_path, theme, filename), theme_svg)
|
|
write_file('%sUI/themes/%s/svg/%s' % (min_path, theme, filename), theme_svg)
|
|
|
|
write_file(min_path + 'UI/json/UI.json', json.dumps({
|
|
'files': sorted(ui_files['min']),
|
|
'images': ui_images
|
|
}, sort_keys=True))
|
|
|
|
js = re.sub(
|
|
r'Ox.LOCALES = \{\}',
|
|
'Ox.LOCALES = ' + json.dumps(locales, indent=4, sort_keys=True),
|
|
js
|
|
)
|
|
js = re.sub(
|
|
r"Ox.VERSION = '([\d\.]+)'",
|
|
"Ox.VERSION = '%s'" % version,
|
|
js
|
|
)
|
|
*/
|
|
|
|
|
|
export default {
|
|
input: {
|
|
'Ox': 'source/Ox/Ox.js',
|
|
'UI': 'source/UI/UI.js',
|
|
'Unicode': 'source/Unicode/Unicode.js',
|
|
'Geo': 'source/Geo/Geo.js',
|
|
'Image': 'source/Image/Image.js',
|
|
},
|
|
output: {
|
|
dir: 'min',
|
|
format: 'es',
|
|
entryFileNames: '[name]/[name].js',
|
|
chunkFileNames: '[name]/[name].js',
|
|
},
|
|
plugins: [
|
|
resolve(),
|
|
terser(),
|
|
copy({
|
|
targets: [
|
|
{ src: "source/Ox.js", dest: 'min/' },
|
|
{ src: "source/Ox/json/locale.*.json", dest: 'min/Ox/json' },
|
|
{ src: "source/UI/css/*.css", dest: 'min/UI/css' },
|
|
{ src: "source/UI/json/locale.*.json", dest: 'min/UI/json' },
|
|
{ src: "source/UI/json/UI.json", dest: 'min/UI/json/' }, // FIXME: this one should be genreated first
|
|
{ src: "source/UI/png", dest: 'min/UI/' },
|
|
{ src: "source/UI/jquery/*.js", dest: 'min/UI/jquery' },
|
|
{ src: "source/UI/themes", dest: 'min/UI' },
|
|
{ src: "source/Unicode/json/*.json", dest: 'min/Unicode/json' },
|
|
{ src: "source/Geo/json/*.json", dest: 'min/Geo/json' },
|
|
{ src: "source/Geo/png/flags", dest: 'min/Geo/png/'}
|
|
],
|
|
hook: 'writeBundle'
|
|
}),
|
|
install()
|
|
]
|
|
};
|