accounts-frontend/packages/webpack-utils/fontgen-loader.js
2020-05-24 02:08:24 +03:00

191 lines
5.4 KiB
JavaScript

/* eslint-disable @typescript-eslint/no-var-requires */
// @ts-nocheck
/* eslint-env node */
/**
* Forked from
*
* https://github.com/DragonsInn/fontgen-loader
*/
const loaderUtils = require('loader-utils');
const fontgen = require('webfonts-generator');
const path = require('path');
const glob = require('glob');
const mimeTypes = {
eot: 'application/vnd.ms-fontobject',
svg: 'image/svg+xml',
ttf: 'application/x-font-ttf',
woff: 'application/font-woff',
};
function absolute(from, to) {
if (arguments.length < 2) {
return function (to) {
return path.resolve(from, to);
};
}
return path.resolve(from, to);
}
function getFilesAndDeps(patterns, context) {
let files = [];
const filesDeps = [];
let directoryDeps = [];
function addFile(file) {
filesDeps.push(file);
files.push(absolute(context, file));
}
function addByGlob(globExp) {
const globOptions = { cwd: context };
const foundFiles = glob.sync(globExp, globOptions);
files = files.concat(foundFiles.map(absolute(context)));
const globDirs = glob.sync(`${path.dirname(globExp)}/`, globOptions);
directoryDeps = directoryDeps.concat(globDirs.map(absolute(context)));
}
// Re-work the files array.
patterns.forEach((pattern) => {
if (glob.hasMagic(pattern)) {
addByGlob(pattern);
} else {
addFile(pattern);
}
});
return {
files,
dependencies: {
directories: directoryDeps,
files: filesDeps,
},
};
}
module.exports = function (content) {
this.cacheable();
const params = loaderUtils.getOptions(this) || {};
let config;
try {
config = JSON.parse(content);
} catch (ex) {
config = this.exec(content, this.resourcePath);
}
config.__dirname = path.dirname(this.resourcePath);
// Sanity check
/*
if(typeof config.fontName != "string" || typeof config.files != "array") {
this.reportError("Typemismatch in your config. Verify your config for correct types.");
return false;
}
*/
const filesAndDeps = getFilesAndDeps(config.files, this.context);
filesAndDeps.dependencies.files.forEach(this.addDependency.bind(this));
filesAndDeps.dependencies.directories.forEach(this.addContextDependency.bind(this));
config.files = filesAndDeps.files;
// With everything set up, let's make an ACTUAL config.
let formats = config.types || ['eot', 'woff', 'ttf', 'svg'];
if (formats.constructor !== Array) {
formats = [formats];
}
const fontconf = {
files: config.files,
fontName: config.fontName,
types: formats,
order: formats,
fontHeight: config.fontHeight || 1000, // Fixes conversion issues with small svgs
templateOptions: {
baseClass: config.baseClass || 'icon',
classPrefix: 'classPrefix' in config ? config.classPrefix : 'icon-',
},
dest: '',
writeFiles: false,
formatOptions: config.formatOptions || {},
};
// This originally was in the object notation itself.
// Unfortunately that actually broke my editor's syntax-highlighting...
// ... what a shame.
if (typeof config.rename === 'function') {
fontconf.rename = config.rename;
} else {
fontconf.rename = function (filePath) {
return path.basename(filePath, '.svg');
};
}
if (config.cssTemplate) {
fontconf.cssTemplate = absolute(this.context, config.cssTemplate);
}
for (const option in config.templateOptions) {
if (config.templateOptions.hasOwnProperty(option)) {
fontconf.templateOptions[option] = config.templateOptions[option];
}
}
// svgicons2svgfont stuff
const keys = ['fixedWidth', 'centerHorizontally', 'normalize', 'fontHeight', 'round', 'descent'];
for (const x in keys) {
if (typeof config[keys[x]] !== 'undefined') {
fontconf[keys[x]] = config[keys[x]];
}
}
const cb = this.async();
const opts = this._compiler.options;
const pub = opts.output.publicPath || '/';
const embed = !!params.embed;
if (fontconf.cssTemplate) {
this.addDependency(fontconf.cssTemplate);
}
fontgen(fontconf, (err, res) => {
if (err) {
return cb(err);
}
const urls = {};
for (const i in formats) {
if (!formats.hasOwnProperty(i)) {
continue;
}
const format = formats[i];
if (embed) {
urls[format] = `data:${mimeTypes[format]};charset=utf-8;base64,${new Buffer(res[format]).toString(
'base64',
)}`;
} else {
let filename = config.fileName || params.fileName || '[hash]-[fontname][ext]';
filename = filename.replace('[fontname]', fontconf.fontName).replace('[ext]', `.${format}`);
const url = loaderUtils.interpolateName(this.context, filename, {
content: res[format],
});
urls[format] = path.join(pub, url).replace(/\\/g, '/');
this.emitFile(url, res[format]);
}
}
const code = res.generateCss(urls);
cb(null, `module.exports = ${JSON.stringify(code)}`);
});
};