google-fonts-plugin
Version:
Webpack plugin that downloads fonts from Google Fonts and encodes them to base64.
96 lines • 3.85 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = require("axios");
const Cache_1 = require("../Cache/Cache");
const Options_1 = require("../Options/Options");
class Fonts {
constructor(format, options) {
this.createRequestUrls = () => {
const { fonts, encode, fontDisplay } = this.options;
if (fonts.length === 0) {
return [];
}
return Object.values(fonts)
.map((item) => {
const { family, variants, text, subsets } = item;
if (!family) {
return '';
}
let requestString = `https://fonts.googleapis.com/css?family=${family.replace(/\s/gi, '+')}`;
if (variants) {
requestString += `:${Object.values(variants).join(',')}`;
}
if (text) {
requestString += `&text=${text}`;
}
else if (subsets) {
requestString += `&subset=${Object.values(subsets).join(',')}`;
}
if (!encode && typeof fontDisplay === 'string' && fontDisplay.length > 0) {
requestString += `&display=${fontDisplay}`;
}
return requestString;
})
.filter((url) => url.length > 0);
};
this.requestFont = async (requestUrl, encoding) => {
let response = '';
const cacheKey = Cache_1.default.key(requestUrl, this.format);
if (this.options.cache) {
response = Cache_1.default.get(cacheKey, encoding);
}
if (response.length > 0) {
return response;
}
response = (await axios_1.default({
url: requestUrl,
responseType: 'arraybuffer',
headers: {
'User-Agent': this.options.getAgent(this.format)
}
})).data;
Cache_1.default.save(cacheKey, response, encoding);
return response;
};
this.requestFontsCSS = async () => {
const urls = this.createRequestUrls();
const promises = urls.map((url) => this.requestFont(url, 'utf8'));
const fonts = await Promise.all(promises);
return fonts.join('');
};
this.requestFontFiles = async (fontUrls) => {
const promises = fontUrls.map(this.requestFontFile);
return Promise.all(promises);
};
this.requestFontFile = async (fontUrl) => {
if (!fontUrl.startsWith('http')) {
return fontUrl;
}
const font = await this.requestFont(fontUrl, 'binary');
return `"data:application/x-font-${this.format};base64,${Buffer.from(font, 'binary').toString('base64')}"`;
};
this.encode = async (css) => {
if (!this.options.encode) {
return css;
}
const regex = /url\((.+?)\)/gi;
const matches = css.match(regex);
if (!matches) {
return css;
}
const fontUrls = matches.map((url) => url.replace(regex, '$1'));
const fontsEncoded = await this.requestFontFiles(fontUrls);
fontsEncoded.forEach((font, index) => {
css = css.replace(fontUrls[index], font);
});
return css;
};
if (!options) {
options = new Options_1.default();
}
this.options = options;
this.format = format;
}
}
exports.default = Fonts;
//# sourceMappingURL=Fonts.js.map