progress on migrating to heex templates and font-icons

This commit is contained in:
Adam Piontek 2022-08-13 07:32:36 -04:00
commit 3eff955672
21793 changed files with 2161968 additions and 16895 deletions

102
assets_old/node_modules/svg-baker/lib/compiler.js generated vendored Normal file
View file

@ -0,0 +1,102 @@
const Promise = require('bluebird');
const merge = require('merge-options');
const FileRequest = require('./request');
const RuleSet = require('./rules');
const Sprite = require('./sprite');
const SpriteSymbol = require('./symbol');
const symbolFactory = require('./symbol-factory');
const spriteFactory = require('./sprite-factory');
const defaultConfig = {
rules: [
{ test: /\.svg$/, value: 'sprite.svg' }
],
symbolFactory,
spriteFactory
};
class Compiler {
static sortSymbols(symbols) {
symbols.sort((leftSymbol, rightSymbol) => {
const leftId = leftSymbol.id;
const rightId = rightSymbol.id;
if (leftId === rightId) {
return 0;
}
return leftId < rightId ? -1 : 1;
});
return symbols;
}
constructor(cfg = {}) {
const config = this.config = merge(defaultConfig, cfg);
this.rules = new RuleSet(config.rules);
this.symbols = [];
}
/**
* @param {string} content
* @param {string} path
* @param {string} [id]
* @return {Promise<SpriteSymbol>}
*/
addSymbol({ path, content, id }) {
const symbols = this.symbols;
const factory = this.config.symbolFactory;
const request = new FileRequest(path);
const options = { id, request, content, factory };
return SpriteSymbol.create(options).then((newSymbol) => {
const existing = symbols.find(s => s.request.equals(request));
if (!existing) {
symbols.push(newSymbol);
Compiler.sortSymbols(symbols);
return newSymbol;
}
const existingIndex = existing ? symbols.indexOf(existing) : -1;
const allExceptCurrent = symbols
.filter(s => s.request.fileEquals(request) && !s.request.queryEquals(request))
.map(symbol => ({ symbol, index: symbols.indexOf(symbol) }));
symbols[existingIndex] = newSymbol;
Compiler.sortSymbols(symbols);
return Promise.map(allExceptCurrent, ({ symbol, index }) => {
const opts = { id: symbol.id, request: symbol.request, content, factory };
return SpriteSymbol.create(opts).then(created => symbols[index] = created);
}).then(() => newSymbol);
});
}
/**
* @return {Promise<Array<Sprite>>}
*/
compile() {
const symbols = this.symbols;
const rules = this.rules.rules;
const factory = this.config.spriteFactory;
return Promise.map(rules, (rule) => {
const spriteSymbols = [];
const filename = rule.uri;
symbols.forEach((symbol) => {
const isMatch = rule.match(symbol.request.file);
if (isMatch) {
spriteSymbols.push(symbol);
}
});
return spriteSymbols.length > 0 ?
Sprite.create({ symbols: spriteSymbols, filename, factory }) :
null;
}).filter(result => result !== null);
}
}
module.exports = Compiler;
module.exports.defaultConfig = defaultConfig;

92
assets_old/node_modules/svg-baker/lib/request.js generated vendored Normal file
View file

@ -0,0 +1,92 @@
const queryUtils = require('query-string');
class FileRequest {
/**
* @param {string} request
*/
constructor(request) {
const { file, query } = FileRequest.parse(request);
this.file = file;
this.query = query;
}
/**
* @param {string} request
* @return {{file: string, query: Object}}
*/
static parse(request) {
const parts = request.split('?');
const file = parts[0];
const query = parts[1] ? queryUtils.parse(parts[1]) : null;
return { file, query };
}
/**
* @return {string}
*/
toString() {
const { file, query } = this;
const queryEncoded = query ? `?${queryUtils.stringify(query)}` : '';
return `${file}${queryEncoded}`;
}
/**
* @return {string}
*/
stringify() {
return this.toString();
}
/**
* @return {string}
*/
stringifyQuery() {
return queryUtils.stringify(this.query);
}
/**
* @param {FileRequest} request
* @return {boolean}
*/
equals(request) {
if (!(request instanceof FileRequest)) {
throw TypeError('request should be instance of FileRequest');
}
return this.toString() === request.toString();
}
/**
* @param {FileRequest} request
* @return {boolean}
*/
fileEquals(request) {
return this.file === request.file;
}
/**
* @param {FileRequest} request
* @return {boolean}
*/
queryEquals(request) {
return this.stringifyQuery() === request.stringifyQuery();
}
/**
* @param {string} param
* @return {boolean}
*/
hasParam(param) {
return this.query && param in this.query;
}
/**
* @param {string} param
* @return {string|null}
*/
getParam(param) {
return this.hasParam(param) ? this.query[param] : null;
}
}
module.exports = FileRequest;

42
assets_old/node_modules/svg-baker/lib/rules.js generated vendored Normal file
View file

@ -0,0 +1,42 @@
class Rule {
constructor({ test, value }) {
if (!(test instanceof RegExp)) {
throw new TypeError('`test` should be a regexp');
}
this.test = test;
this.value = value;
}
/**
* @param {string} value
* @return {boolean}
*/
match(value) {
return this.test.test(value);
}
}
class RuleSet {
/**
* @param {Array<{test: RegExp, uri: string}>} rules
*/
constructor(rules) {
if (!Array.isArray(rules)) {
throw new TypeError('`data` should be an array');
}
this.rules = rules.map(params => new Rule(params));
}
/**
* @param {string} value
* @return {Rule|null}
*/
getMatchedRule(value) {
return this.rules.find(rule => rule.match(value)) || null;
}
}
module.exports = RuleSet;
module.exports.Rule = Rule;

View file

@ -0,0 +1,84 @@
const merge = require('merge-options');
const processor = require('posthtml-svg-mode');
const extractNamespacesToRoot = require('./transformations/extract-namespaces-to-root');
const moveFromSymbolToRoot = require('./transformations/move-from-symbol-to-root');
const { svg, xlink } = require('../namespaces');
const defaultConfig = {
attrs: {
[svg.name]: svg.uri,
[xlink.name]: xlink.uri
},
styles: `
.sprite-symbol-usage {display: none;}
.sprite-symbol-usage:target {display: inline;}
`,
usages: true,
symbols: []
};
/**
* TODO simplify
* @param {Object} [config] {@see defaultConfig}
* @return {Function} PostHTML plugin
*/
function createSprite(config = {}) {
const cfg = merge(defaultConfig, config);
const symbols = cfg.symbols;
const trees = symbols.map(s => s.tree);
let usages = [];
if (cfg.usages) {
usages = symbols.map((symbol) => {
const { id, useId } = symbol;
return {
tag: 'use',
attrs: {
id: useId,
'xlink:href': `#${id}`,
class: 'sprite-symbol-usage'
}
};
});
}
let defsContent = [];
if (cfg.styles !== false) {
defsContent.push({
tag: 'style',
content: cfg.styles
});
}
defsContent = defsContent.concat(trees);
return (tree) => {
tree[0] = {
tag: 'svg',
attrs: cfg.attrs,
content: [{
tag: 'defs',
content: defsContent
}].concat(usages)
};
return tree;
};
}
/**
* @param {Object} options {@see defaultConfig}
* @return {Promise<PostHTMLProcessingResult>}
*/
function spriteFactory(options) {
const plugins = [
createSprite(options),
extractNamespacesToRoot(),
moveFromSymbolToRoot()
];
return processor(plugins).process('');
}
module.exports = spriteFactory;
module.exports.createSprite = createSprite;

30
assets_old/node_modules/svg-baker/lib/sprite.js generated vendored Normal file
View file

@ -0,0 +1,30 @@
const { renderer } = require('posthtml-svg-mode');
const defaultFactory = require('./sprite-factory');
class Sprite {
constructor({ tree, filename }) {
this.tree = tree;
this.filename = filename;
}
/**
* @param {Object} options
* @param {Array<SpriteSymbol>} options.symbols
* @param {string} options.filename Output sprite filename
* @param {Function<Promise<PostHTMLProcessingResult>>} [options.factory]
* @return {Promise<Sprite>}
*/
static create(options) {
const { symbols, filename, factory = defaultFactory } = options;
return factory({ symbols }).then(({ tree }) => new Sprite({ tree, filename }));
}
/**
* @return {string}
*/
render() {
return renderer(this.tree);
}
}
module.exports = Sprite;

View file

@ -0,0 +1,32 @@
const processor = require('posthtml-svg-mode');
const renameId = require('posthtml-rename-id');
const normalizeViewBox = require('./transformations/normalize-viewbox');
const rasterToSVG = require('./transformations/raster-to-svg');
const prefixStyleSelectors = require('./transformations/prefix-style-selectors');
const svgToSymbol = require('./transformations/svg-to-symbol');
/**
* @param {Object} options
* @param {string} [options.id]
* @param {string} options.content
* @param {FileRequest} options.request
* @return {Promise<PostHTMLProcessingResult>}
*/
function symbolFactory(options) {
const { id } = options;
const plugins = [];
// convert raster image to svg
const content = Buffer.isBuffer(options.content)
? rasterToSVG(options.content)
: options.content;
plugins.push(normalizeViewBox());
plugins.push(prefixStyleSelectors(`#${id}`));
plugins.push(renameId(`${id}_[id]`));
plugins.push(svgToSymbol({ id }));
return processor(plugins).process(content);
}
module.exports = symbolFactory;

58
assets_old/node_modules/svg-baker/lib/symbol.js generated vendored Normal file
View file

@ -0,0 +1,58 @@
const { renderer } = require('posthtml-svg-mode');
const { getRoot, getHash } = require('./utils');
const defaultFactory = require('./symbol-factory');
const FileRequest = require('./request');
const clone = require('clone');
class SpriteSymbol {
constructor({ id, tree, request }) {
this.id = id;
this._tree = tree;
this.request = request;
}
/**
* @param {Object} options
* @param {string} options.id
* @param {string} options.content
* @param {string|FileRequest} options.request
* @param {Function<Promise<PostHTMLProcessingResult>>} [options.factory]
* @return {Promise<SpriteSymbol>}
*/
static create(options) {
const { content, factory = defaultFactory } = options;
const request = typeof options.request === 'string' ? new FileRequest(options.request) : options.request;
const id = typeof options.id === 'undefined' ? getHash(`${request.toString()}_${content}`) : options.id;
return factory({ content, request, id })
.then(({ tree }) => new SpriteSymbol({ id, request, tree }));
}
/**
* @return {string}
*/
get viewBox() {
const root = getRoot(this.tree);
return root.attrs ? root.attrs.viewBox : null;
}
get tree() {
return clone(this._tree);
}
/**
* @return {string}
*/
get useId() {
return `${this.id}-usage`;
}
/**
* @return {string}
*/
render() {
return renderer(this.tree);
}
}
module.exports = SpriteSymbol;

View file

@ -0,0 +1,35 @@
const { getRoot } = require('../utils');
/**
* @return {Function} PostHTML plugin
*/
function extractNamespacesToRoot() {
return (tree) => {
const namespaces = {};
tree.match({ tag: /.*/ }, (node) => {
const attrs = node.attrs || {};
Object.keys(attrs).forEach((attr) => {
if (attr.startsWith('xmlns')) {
if (attr in namespaces === false) {
namespaces[attr] = attrs[attr];
}
delete node.attrs[attr];
}
});
return node;
});
const root = getRoot(tree);
root.attrs = root.attrs || {};
Object.keys(namespaces).forEach(name => root.attrs[name] = namespaces[name]);
return tree;
};
}
module.exports = extractNamespacesToRoot;

View file

@ -0,0 +1,38 @@
const traverse = require('traverse');
const clone = require('clone');
// Fixes Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=353575
const defaultConfig = {
tags: ['linearGradient', 'radialGradient', 'pattern', 'clipPath', 'mask']
};
function moveFromSymbolToRoot(config = null) {
const cfg = Object.assign({}, defaultConfig, config);
return (tree) => {
traverse(tree).forEach(function (node) {
if (!this.isLeaf && node.tag && node.tag === 'symbol') {
const symbol = this.parent.node;
const nodesToRemove = [];
traverse(node.content).forEach(function (n) {
if (!this.isLeaf && n.tag && cfg.tags.indexOf(n.tag) !== -1) {
const parent = this.parent.node;
const cloned = clone(this.node);
symbol.push(cloned);
nodesToRemove.push({ parent, node: n });
}
});
nodesToRemove.forEach((item) => {
const nodeIndex = item.parent.indexOf(item.node);
item.parent.splice(nodeIndex, 1);
});
}
});
return tree;
};
}
module.exports = moveFromSymbolToRoot;

View file

@ -0,0 +1,34 @@
const merge = require('merge-options');
const { getRoot } = require('../utils');
const defaultConfig = {
removeDimensions: false
};
/**
* @param {Object} [config] {@see defaultConfig}
* @return {Function} PostHTML plugin
*/
function normalizeViewBox(config = {}) {
const cfg = merge(defaultConfig, config);
return (tree) => {
const root = getRoot(tree);
root.attrs = root.attrs || {};
const attrs = root.attrs;
const { width, height, viewBox } = attrs;
if (!viewBox && width && height) {
attrs.viewBox = `0 0 ${parseFloat(width).toString()} ${parseFloat(height).toString()}`;
if (cfg.removeDimensions) {
delete attrs.width;
delete attrs.height;
}
}
return tree;
};
}
module.exports = normalizeViewBox;

View file

@ -0,0 +1,30 @@
const Promise = require('bluebird');
const decodeEntities = require('he').decode;
const postcss = require('postcss');
const prefixSelectors = require('postcss-prefix-selector');
/**
* @return {Function} PostHTML plugin
*/
function prefixStyleSelectors(prefix) {
return (tree) => {
const styleNodes = [];
tree.match({ tag: 'style' }, (node) => {
styleNodes.push(node);
return node;
});
return Promise.map(styleNodes, (node) => {
const content = node.content ? decodeEntities(node.content.join('')) : '';
return postcss()
.use(prefixSelectors({ prefix }))
.process(content)
.then(prefixedStyles => node.content = prefixedStyles.css);
}).then(() => tree);
};
}
module.exports = prefixStyleSelectors;

View file

@ -0,0 +1,23 @@
const getImageSize = require('image-size');
const { svg, xlink } = require('../../namespaces');
/**
* TODO rasterToSVG#getPixelRatioFromFilename
* @param {Buffer} buffer
* @return {string}
*/
function rasterToSVG(buffer) {
const info = getImageSize(buffer);
const { width, height, type } = info;
const defaultNS = `${svg.name}="${svg.uri}"`;
const xlinkNS = `${xlink.name}="${xlink.uri}"`;
const data = `data:image/${type};base64,${buffer.toString('base64')}`;
return [
`<svg ${defaultNS} ${xlinkNS} width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`,
`<image xlink:href="${data}" width="${width}" height="${height}" />`,
'</svg>'
].join('');
}
module.exports = rasterToSVG;

View file

@ -0,0 +1,52 @@
const micromatch = require('micromatch');
const { getRoot } = require('../utils');
const defaultConfig = {
id: undefined,
preserve: [
'viewBox',
'preserveAspectRatio',
'class',
'overflow',
'stroke?(-*)',
'fill?(-*)',
'xmlns?(:*)',
'role',
'aria-*'
]
};
/**
* @param {Object} [config] {@see defaultConfig}
* @return {Function} PostHTML plugin
*/
function svgToSymbol(config = null) {
const cfg = Object.assign({}, defaultConfig, config);
return (tree) => {
const root = getRoot(tree);
root.tag = 'symbol';
root.attrs = root.attrs || {};
const attrNames = Object.keys(root.attrs);
const attrNamesToPreserve = micromatch(attrNames, cfg.preserve);
attrNames.forEach((name) => {
if (!attrNamesToPreserve.includes(name)) {
delete root.attrs[name];
}
});
if (cfg.id) {
root.attrs.id = cfg.id;
}
// Remove all elements and add symbol node
tree.splice(0, tree.length, root);
return tree;
};
}
module.exports = svgToSymbol;

27
assets_old/node_modules/svg-baker/lib/utils.js generated vendored Normal file
View file

@ -0,0 +1,27 @@
const { interpolateName, getHashDigest } = require('loader-utils');
/**
* @param {PostHTMLTree} tree
* @return {Object} Node
*/
exports.getRoot = function getRoot(tree) {
return tree.find(node => typeof node === 'object' && 'tag' in node);
};
/**
* @param {string|Function} pattern
* @param {string} resourcePath
* @param {Object} [options]
* @param {string} options.context
* @param {string} options.content
* @param {string} options.regExp
*/
exports.interpolate = function interpolate(pattern, resourcePath, options = null) {
const opts = Object.assign({ context: process.cwd() }, options);
return interpolateName({ resourcePath }, pattern, opts);
};
exports.getHash = function getHash(content) {
return getHashDigest(content, 'md5', 'hex', 6);
};