From 60bbfd2389cce7faddd4c7c0829fc14929a00cab Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 22 May 2025 17:40:47 -0500 Subject: initial commit --- index.js | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 index.js (limited to 'index.js') diff --git a/index.js b/index.js new file mode 100644 index 0000000..ce66b2e --- /dev/null +++ b/index.js @@ -0,0 +1,84 @@ +const fs = require("fs") +const path = require("path") +//const svgSprite = require("svg-sprite") +const { JSDOM } = require("jsdom") +//const { optimize } = require("svgo") +const { RawSource } = require("webpack-sources") + +// Generate 's for referencing sprites in css +function generateAtlasViews(svgFile) { + const dom = new JSDOM(svgFile) + const document = dom.window.document + const svg = document.querySelector("svg") + + const symbols = document.querySelectorAll("symbol") + const width = 24 + const height = 24 + let row = 0 + let col = 0 + const totalCols = Math.floor(Math.sqrt(symbols.length)) + for (const symbol of symbols) { + const x = col*width + const y = row*height + const id = symbol.getAttribute("id") + + // Create elements + const view = document.createElement("view") + view.setAttribute("id", `${id}-view`) + view.setAttribute("viewBox", `0 0 ${x} ${y}`) + const svgSprite = document.createElement("svg") + svgSprite.setAttribute("width", width) + svgSprite.setAttribute("height", height) + svgSprite.setAttribute("viewBox", "0 -960 960 960") + svgSprite.setAttribute("x", x) + svgSprite.setAttribute("y", y) + const svgUse = document.createElement("use") + svgUse.setAttribute("href", `#${id}`) + + // Append elements + svgSprite.appendChild(svgUse) + svg.appendChild(view) + svg.appendChild(svgSprite) + + // Adjust row/col + col++ + if (col > totalCols) { + col = 0 + row++ + } + } + svg.setAttribute("viewBox", `0 0 ${(totalCols+1)*width} ${(row+1)*height}`) + + return svg.outerHTML +} + + +class SVGSymbolAtlasViewPlugin { + constructor(options = {}) { + this.suffix = options.suffix || ".svg" + } + + apply(compiler) { + compiler.hooks.thisCompilation.tap("SVGSymbolAtlasViewPlugin", (compilation) => { + compilation.hooks.processAssets.tap( + { + name: "SVGSymbolAtlasViewPlugin", + stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE, + }, + (assets) => { + for (const assetName in assets) { + if (assetName.endsWith(this.suffix)) { + const originalSVG = assets[assetName].source().toString() + const atlasSVG = generateAtlasViews(originalSVG) + + // Replace old SVG asset with new SVG + compilation.updateAsset(assetName, new RawSource(atlasSVG)) + } + } + } + ) + }) + } +} + +module.exports = SVGSymbolAtlasViewPlugin -- cgit v1.2.3