unplugin-cheetah-grid-icon-svg 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -0
- package/dist/esbuild.cjs +4 -0
- package/dist/esbuild.d.mts +6 -0
- package/dist/esbuild.mjs +5 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.mjs +2 -0
- package/dist/index2.d.mts +2 -0
- package/dist/rolldown.cjs +4 -0
- package/dist/rolldown.d.mts +7 -0
- package/dist/rolldown.mjs +5 -0
- package/dist/rollup.cjs +4 -0
- package/dist/rollup.d.mts +6 -0
- package/dist/rollup.mjs +5 -0
- package/dist/rspack.cjs +4 -0
- package/dist/rspack.d.mts +6 -0
- package/dist/rspack.mjs +5 -0
- package/dist/src.cjs +374 -0
- package/dist/src.mjs +369 -0
- package/dist/vite.cjs +4 -0
- package/dist/vite.d.mts +7 -0
- package/dist/vite.mjs +5 -0
- package/dist/webpack.cjs +4 -0
- package/dist/webpack.d.mts +6 -0
- package/dist/webpack.mjs +5 -0
- package/package.json +137 -0
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# unplugin-cheetah-grid-icon-svg
|
|
2
|
+
|
|
3
|
+
Unplugin that loads the icon module for Cheetah Grid from SVG.
|
|
4
|
+
|
|
5
|
+
This package is the Vite-friendly replacement for `cheetah-grid-icon-svg-loader`.
|
|
6
|
+
It uses the same SVG-to-icon conversion logic and also exposes Rollup, Rolldown,
|
|
7
|
+
Webpack, Rspack, and esbuild adapters through `unplugin`.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install --save-dev unplugin-cheetah-grid-icon-svg
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage with Vite
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import cheetahGridIconSvg from "unplugin-cheetah-grid-icon-svg/vite";
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
plugins: [
|
|
22
|
+
cheetahGridIconSvg(),
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import gridOn from "material-design-icons/image/svg/production/ic_grid_on_24px.svg?cheetah-grid-icon";
|
|
29
|
+
|
|
30
|
+
const icons = {
|
|
31
|
+
gridOn,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
cheetahGrid.register.icons(icons);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Transform a Set of SVG Files
|
|
38
|
+
|
|
39
|
+
If you want imports from a known icon directory to behave like the old webpack
|
|
40
|
+
loader without adding a query to every import, pass `include`.
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
import cheetahGridIconSvg from "unplugin-cheetah-grid-icon-svg/vite";
|
|
44
|
+
|
|
45
|
+
export default {
|
|
46
|
+
plugins: [
|
|
47
|
+
cheetahGridIconSvg({
|
|
48
|
+
include: /material-design-icons\/.+\.svg$/,
|
|
49
|
+
}),
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Font SVG
|
|
55
|
+
|
|
56
|
+
Font SVG files are converted to an object whose keys are glyph unicode values,
|
|
57
|
+
matching `cheetah-grid-icon-svg-loader`.
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
import materialIcons from "material-design-icons/iconfont/MaterialIcons-Regular.svg?cheetah-grid-icon";
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
You can also load a single glyph.
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
import add from "material-design-icons/iconfont/MaterialIcons-Regular.svg?cheetah-grid-icon&glyph-name=add";
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Other Bundlers
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
const cheetahGridIconSvg = require("unplugin-cheetah-grid-icon-svg/webpack");
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
plugins: [
|
|
76
|
+
cheetahGridIconSvg(),
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
import cheetahGridIconSvg from "unplugin-cheetah-grid-icon-svg/rollup";
|
|
83
|
+
|
|
84
|
+
export default {
|
|
85
|
+
plugins: [
|
|
86
|
+
cheetahGridIconSvg(),
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
import cheetahGridIconSvg from "unplugin-cheetah-grid-icon-svg/rolldown";
|
|
93
|
+
|
|
94
|
+
export default {
|
|
95
|
+
plugins: [
|
|
96
|
+
cheetahGridIconSvg(),
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Options
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
interface Options {
|
|
105
|
+
include?: string | RegExp | ((id: string) => boolean) | Array<string | RegExp | ((id: string) => boolean)>;
|
|
106
|
+
exclude?: string | RegExp | ((id: string) => boolean) | Array<string | RegExp | ((id: string) => boolean)>;
|
|
107
|
+
query?: string | string[] | false;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- `include` transforms matching SVG imports without requiring a query.
|
|
112
|
+
- `exclude` prevents matching SVG imports from being transformed.
|
|
113
|
+
- `query` changes the query names that opt in to transformation. The default is
|
|
114
|
+
`["cheetah-grid-icon", "cg-icon"]`. Set `query: false` to transform every
|
|
115
|
+
SVG matched by `include`, or every SVG import when `include` is omitted.
|
package/dist/esbuild.cjs
ADDED
package/dist/esbuild.mjs
ADDED
package/dist/index.cjs
ADDED
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as unplugin0 from "unplugin";
|
|
2
|
+
|
|
3
|
+
//#region src/core/transform.d.ts
|
|
4
|
+
type FilterPattern = string | RegExp | ((id: string) => boolean) | FilterPattern[];
|
|
5
|
+
interface Options {
|
|
6
|
+
include?: FilterPattern;
|
|
7
|
+
exclude?: FilterPattern;
|
|
8
|
+
query?: string | string[] | false;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/index.d.ts
|
|
12
|
+
declare const unplugin: unplugin0.UnpluginInstance<Options | undefined, boolean>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { FilterPattern as n, Options as r, unplugin as t };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { r as Options } from "./index.mjs";
|
|
2
|
+
import * as rolldown0 from "rolldown";
|
|
3
|
+
|
|
4
|
+
//#region src/rolldown.d.ts
|
|
5
|
+
declare const _default: (options?: Options | undefined) => rolldown0.Plugin<any> | rolldown0.Plugin<any>[];
|
|
6
|
+
//#endregion
|
|
7
|
+
export { _default as default };
|
package/dist/rollup.cjs
ADDED
package/dist/rollup.mjs
ADDED
package/dist/rspack.cjs
ADDED
package/dist/rspack.mjs
ADDED
package/dist/src.cjs
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
let unplugin = require("unplugin");
|
|
2
|
+
let node_module = require("node:module");
|
|
3
|
+
let _xmldom_xmldom = require("@xmldom/xmldom");
|
|
4
|
+
//#region src/core/svg-data.ts
|
|
5
|
+
const ELEMENT_NODE = 1;
|
|
6
|
+
const parser = new (typeof window !== "undefined" && window.DOMParser ? window.DOMParser : _xmldom_xmldom.DOMParser)();
|
|
7
|
+
function isElementNode(node) {
|
|
8
|
+
return node.nodeType === ELEMENT_NODE && typeof node.tagName === "string";
|
|
9
|
+
}
|
|
10
|
+
function findElement(el, test) {
|
|
11
|
+
const { childNodes } = el;
|
|
12
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
13
|
+
const child = childNodes[i];
|
|
14
|
+
if (!isElementNode(child)) continue;
|
|
15
|
+
if (test(child)) return child;
|
|
16
|
+
const result = findElement(child, test);
|
|
17
|
+
if (result) return result;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
var Svg = class {
|
|
22
|
+
constructor(svgCode) {
|
|
23
|
+
this.glyphs = {};
|
|
24
|
+
this.glyphUnicodes = {};
|
|
25
|
+
const document = parser.parseFromString(svgCode, "image/svg+xml");
|
|
26
|
+
this.svg = document.documentElement;
|
|
27
|
+
}
|
|
28
|
+
findElement(test) {
|
|
29
|
+
return findElement(this.svg, test);
|
|
30
|
+
}
|
|
31
|
+
get fontFaceElement() {
|
|
32
|
+
if (this.cachedFontFaceElement === void 0) this.cachedFontFaceElement = this.findElement((child) => child.tagName.toLowerCase() === "font-face");
|
|
33
|
+
return this.cachedFontFaceElement;
|
|
34
|
+
}
|
|
35
|
+
get fontElement() {
|
|
36
|
+
if (this.cachedFontElement === void 0) this.cachedFontElement = this.findElement((child) => child.tagName.toLowerCase() === "font");
|
|
37
|
+
return this.cachedFontElement;
|
|
38
|
+
}
|
|
39
|
+
findGlyph(glyphName) {
|
|
40
|
+
if (!(glyphName in this.glyphs)) this.glyphs[glyphName] = this.findElement((child) => child.getAttribute("glyph-name") === glyphName);
|
|
41
|
+
return this.glyphs[glyphName] || null;
|
|
42
|
+
}
|
|
43
|
+
findGlyphByUnicode(unicode) {
|
|
44
|
+
if (!(unicode in this.glyphUnicodes)) this.glyphUnicodes[unicode] = this.findElement((child) => child.getAttribute("unicode") === unicode);
|
|
45
|
+
return this.glyphUnicodes[unicode] || null;
|
|
46
|
+
}
|
|
47
|
+
walkAllGlyph(callback) {
|
|
48
|
+
const walkGlyph = (el) => {
|
|
49
|
+
const { childNodes } = el;
|
|
50
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
51
|
+
const child = childNodes[i];
|
|
52
|
+
if (!isElementNode(child)) continue;
|
|
53
|
+
const unicode = child.getAttribute("unicode");
|
|
54
|
+
if (unicode && child.getAttribute("d")) {
|
|
55
|
+
if (!this.glyphUnicodes[unicode]) this.glyphUnicodes[unicode] = child;
|
|
56
|
+
const glyphName = child.getAttribute("glyph-name");
|
|
57
|
+
if (glyphName && !this.glyphs[glyphName]) this.glyphs[glyphName] = child;
|
|
58
|
+
callback(child);
|
|
59
|
+
} else walkGlyph(child);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
walkGlyph(this.svg);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const cache = {};
|
|
66
|
+
function get(svgCode) {
|
|
67
|
+
const cacheKey = `font:${svgCode}`;
|
|
68
|
+
cache[cacheKey] = cache[cacheKey] || new Svg(svgCode);
|
|
69
|
+
return cache[cacheKey];
|
|
70
|
+
}
|
|
71
|
+
(0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
72
|
+
function attr(el, name) {
|
|
73
|
+
return el.getAttribute(name) || "";
|
|
74
|
+
}
|
|
75
|
+
function polygonToPath(polygon) {
|
|
76
|
+
return `M${attr(polygon, "points")}z`;
|
|
77
|
+
}
|
|
78
|
+
function polylineToPath(polyline) {
|
|
79
|
+
return `M${attr(polyline, "points")}`;
|
|
80
|
+
}
|
|
81
|
+
function circleToPath(circle) {
|
|
82
|
+
const cx = Number(attr(circle, "cx"));
|
|
83
|
+
const cy = Number(attr(circle, "cy"));
|
|
84
|
+
const r = Number(attr(circle, "r"));
|
|
85
|
+
const segments = 8;
|
|
86
|
+
const angle = 2 * Math.PI / segments;
|
|
87
|
+
const anchorX = (theta) => r * Math.cos(theta);
|
|
88
|
+
const anchorY = (theta) => r * Math.sin(theta);
|
|
89
|
+
const controlX = (theta) => anchorX(theta) + r * Math.tan(angle / 2) * Math.cos(theta - Math.PI / 2);
|
|
90
|
+
const controlY = (theta) => anchorY(theta) + r * Math.tan(angle / 2) * Math.sin(theta - Math.PI / 2);
|
|
91
|
+
let paths = `M${cx + r} ${cy}`;
|
|
92
|
+
for (let index = 1; index <= segments; index++) {
|
|
93
|
+
const theta = index * angle;
|
|
94
|
+
paths += `Q${controlX(theta) + cx} ${controlY(theta) + cy} ${anchorX(theta) + cx} ${anchorY(theta) + cy}`;
|
|
95
|
+
}
|
|
96
|
+
return paths;
|
|
97
|
+
}
|
|
98
|
+
function rectToPath(rect) {
|
|
99
|
+
const x = Number(attr(rect, "x"));
|
|
100
|
+
const y = Number(attr(rect, "y"));
|
|
101
|
+
const width = Number(attr(rect, "width"));
|
|
102
|
+
return `M${x},${y} h${width} v${Number(attr(rect, "height"))} h${-width}z`;
|
|
103
|
+
}
|
|
104
|
+
function getD(path) {
|
|
105
|
+
if (path.getAttribute("fill") === "none") return "";
|
|
106
|
+
return attr(path, "d").replace(/[\n\r]/gu, "");
|
|
107
|
+
}
|
|
108
|
+
function elementToPaths(el, resource) {
|
|
109
|
+
switch (el.tagName.toLowerCase()) {
|
|
110
|
+
case "path":
|
|
111
|
+
case "glyph": return getD(el);
|
|
112
|
+
case "circle": return circleToPath(el);
|
|
113
|
+
case "polygon": return polygonToPath(el);
|
|
114
|
+
case "polyline": return polylineToPath(el);
|
|
115
|
+
case "rect": return rectToPath(el);
|
|
116
|
+
case "g": {
|
|
117
|
+
let path = "";
|
|
118
|
+
const { childNodes } = el;
|
|
119
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
120
|
+
const child = childNodes[i];
|
|
121
|
+
if (!isElementNode(child)) continue;
|
|
122
|
+
if (!child.getAttribute("fill")) child.setAttribute("fill", el.getAttribute("fill"));
|
|
123
|
+
path += elementToPaths(child, resource);
|
|
124
|
+
}
|
|
125
|
+
return path;
|
|
126
|
+
}
|
|
127
|
+
default: console.warn(`unsupported:${el.tagName}`, `@ ${resource}\n${el.innerHTML}`);
|
|
128
|
+
}
|
|
129
|
+
return "";
|
|
130
|
+
}
|
|
131
|
+
function buildScript({ offsetX = 0, offsetY = 0, width, height, d, isGlyph, html, resource }) {
|
|
132
|
+
let flags = "";
|
|
133
|
+
if (isGlyph) flags += `ud: 1,
|
|
134
|
+
`;
|
|
135
|
+
if (offsetX !== 0) flags += `x: ${offsetX},
|
|
136
|
+
`;
|
|
137
|
+
if (offsetY !== 0) flags += `y: ${offsetY},
|
|
138
|
+
`;
|
|
139
|
+
return `{
|
|
140
|
+
/*
|
|
141
|
+
original svg
|
|
142
|
+
${html}
|
|
143
|
+
@ ${resource}
|
|
144
|
+
*/
|
|
145
|
+
d: '${d}',
|
|
146
|
+
width: ${width},
|
|
147
|
+
height: ${height},
|
|
148
|
+
${flags}
|
|
149
|
+
}`;
|
|
150
|
+
}
|
|
151
|
+
function glyphToJSON(svgString, { glyphName, unicode }, resource) {
|
|
152
|
+
const svg = get(svgString);
|
|
153
|
+
const findGlyph = () => {
|
|
154
|
+
if (glyphName && glyphName !== true) return svg.findGlyph(glyphName);
|
|
155
|
+
return unicode && unicode !== true ? svg.findGlyphByUnicode(unicode) : null;
|
|
156
|
+
};
|
|
157
|
+
const emptyElement = { getAttribute: () => "" };
|
|
158
|
+
const fontFace = svg.fontFaceElement || emptyElement;
|
|
159
|
+
const font = svg.fontElement || emptyElement;
|
|
160
|
+
const glyph = findGlyph();
|
|
161
|
+
if (!glyph) throw new Error(`Glyph not found: ${glyphName && glyphName !== true ? glyphName : unicode && unicode !== true ? unicode : ""}`);
|
|
162
|
+
const fontHorizAdvX = Number(font.getAttribute("horiz-adv-x")) || 0;
|
|
163
|
+
const fontVertAdvX = Number(font.getAttribute("vert-adv-x")) || 0;
|
|
164
|
+
const horizAdvX = Number(glyph.getAttribute("horiz-adv-x")) || fontHorizAdvX || 0;
|
|
165
|
+
const vertAdvX = Number(glyph.getAttribute("vert-adv-x")) || fontVertAdvX || 0;
|
|
166
|
+
const unitsPerEm = Number(fontFace.getAttribute("units-per-em")) || 1e3;
|
|
167
|
+
const descent = Number(fontFace.getAttribute("descent")) || vertAdvX;
|
|
168
|
+
let size = unitsPerEm;
|
|
169
|
+
const contentSize = {
|
|
170
|
+
width: horizAdvX || unitsPerEm,
|
|
171
|
+
height: vertAdvX || unitsPerEm
|
|
172
|
+
};
|
|
173
|
+
if (horizAdvX > size) size = horizAdvX;
|
|
174
|
+
if (vertAdvX > size) size = vertAdvX;
|
|
175
|
+
let offsetX = 0;
|
|
176
|
+
let offsetY = -descent;
|
|
177
|
+
offsetX += Math.round((size - contentSize.width) / 2);
|
|
178
|
+
offsetY += Math.round((size - contentSize.height) / 2);
|
|
179
|
+
return buildScript({
|
|
180
|
+
offsetX,
|
|
181
|
+
offsetY,
|
|
182
|
+
width: size,
|
|
183
|
+
height: size,
|
|
184
|
+
d: elementToPaths(glyph, resource),
|
|
185
|
+
isGlyph: true,
|
|
186
|
+
html: glyph.outerHTML,
|
|
187
|
+
resource
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function svgToJSON(svgString, resource) {
|
|
191
|
+
const { svg } = get(svgString);
|
|
192
|
+
const viewBox = attr(svg, "viewBox").split(" ");
|
|
193
|
+
const width = Number(attr(svg, "width") || viewBox[2]) || 0;
|
|
194
|
+
const height = Number(attr(svg, "height") || viewBox[3]) || 0;
|
|
195
|
+
const offsetX = 0 - Number(viewBox[0]) || 0;
|
|
196
|
+
const offsetY = 0 - Number(viewBox[1]) || 0;
|
|
197
|
+
let d = "";
|
|
198
|
+
const { childNodes } = svg;
|
|
199
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
200
|
+
const el = childNodes[i];
|
|
201
|
+
if (!isElementNode(el)) continue;
|
|
202
|
+
d += elementToPaths(el, resource);
|
|
203
|
+
}
|
|
204
|
+
return buildScript({
|
|
205
|
+
offsetX,
|
|
206
|
+
offsetY,
|
|
207
|
+
width,
|
|
208
|
+
height,
|
|
209
|
+
d,
|
|
210
|
+
html: svgString,
|
|
211
|
+
resource
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function normalizeResource$1(resource) {
|
|
215
|
+
let index = resource.indexOf("\\node_modules\\");
|
|
216
|
+
if (index === -1) index = resource.indexOf("/node_modules/");
|
|
217
|
+
if (index >= 0) return resource.slice(index + 14);
|
|
218
|
+
return resource;
|
|
219
|
+
}
|
|
220
|
+
function sourceToIconJsObject$1(svgCode, opt = {}) {
|
|
221
|
+
const resource = normalizeResource$1(opt.resource || "");
|
|
222
|
+
if (opt["glyph-name"] || opt.unicode) return glyphToJSON(svgCode, {
|
|
223
|
+
glyphName: opt["glyph-name"],
|
|
224
|
+
unicode: opt.unicode
|
|
225
|
+
}, resource);
|
|
226
|
+
return svgToJSON(svgCode, resource);
|
|
227
|
+
}
|
|
228
|
+
(0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
229
|
+
function toGlyphs(svgCode) {
|
|
230
|
+
const svg = get(svgCode);
|
|
231
|
+
const glyphs = [];
|
|
232
|
+
svg.walkAllGlyph((el) => glyphs.push(el));
|
|
233
|
+
return glyphs;
|
|
234
|
+
}
|
|
235
|
+
function transform(glyphUnicode, svgCode, svgfile) {
|
|
236
|
+
return sourceToIconJsObject$1(svgCode, {
|
|
237
|
+
unicode: glyphUnicode,
|
|
238
|
+
resource: svgfile
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function charToHexCodeStr(char) {
|
|
242
|
+
if (/[!#-&(-[\]-_a-~]/u.test(char)) return char;
|
|
243
|
+
return `\\u${`0000${char.charCodeAt(0).toString(16)}`.slice(-4)}`;
|
|
244
|
+
}
|
|
245
|
+
function toCodeString(code) {
|
|
246
|
+
let result = "";
|
|
247
|
+
for (let i = 0; i < code.length; i++) result += charToHexCodeStr(code[i]);
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
function buildObjectCode(svgCode, resource, { name = "unicode" } = {}) {
|
|
251
|
+
let script = "{\n";
|
|
252
|
+
toGlyphs(svgCode).forEach((glyph) => {
|
|
253
|
+
const unicode = glyph.getAttribute("unicode") || "";
|
|
254
|
+
const targetName = glyph.getAttribute(name) || "";
|
|
255
|
+
script += `
|
|
256
|
+
'${toCodeString(targetName)}': ${transform(unicode, svgCode, resource).replace(/\r?\n|\r/gu, `
|
|
257
|
+
`)},`;
|
|
258
|
+
});
|
|
259
|
+
script += "\n}";
|
|
260
|
+
return script;
|
|
261
|
+
}
|
|
262
|
+
function normalizeResource(resource) {
|
|
263
|
+
let index = resource.indexOf("\\node_modules\\");
|
|
264
|
+
if (index === -1) index = resource.indexOf("/node_modules/");
|
|
265
|
+
if (index >= 0) return resource.slice(index + 14);
|
|
266
|
+
return resource;
|
|
267
|
+
}
|
|
268
|
+
function sourceToIconsJsObject(svgCode, opt = {}) {
|
|
269
|
+
return buildObjectCode(svgCode, normalizeResource(opt.resource || ""), opt);
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/core/transform.ts
|
|
273
|
+
const DEFAULT_QUERY_NAMES = ["cheetah-grid-icon", "cg-icon"];
|
|
274
|
+
const SVG_EXT_RE = /\.svg$/iu;
|
|
275
|
+
function parseId(id) {
|
|
276
|
+
const queryIndex = id.indexOf("?");
|
|
277
|
+
if (queryIndex < 0) return {
|
|
278
|
+
filename: id,
|
|
279
|
+
query: {}
|
|
280
|
+
};
|
|
281
|
+
return {
|
|
282
|
+
filename: id.slice(0, queryIndex),
|
|
283
|
+
query: parseQuery(id.slice(queryIndex + 1))
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function parseQuery(queryText) {
|
|
287
|
+
const query = {};
|
|
288
|
+
if (!queryText) return query;
|
|
289
|
+
queryText.split("&").forEach((part) => {
|
|
290
|
+
if (!part) return;
|
|
291
|
+
const equalIndex = part.indexOf("=");
|
|
292
|
+
const rawKey = equalIndex < 0 ? part : part.slice(0, equalIndex);
|
|
293
|
+
const rawValue = equalIndex < 0 ? true : part.slice(equalIndex + 1);
|
|
294
|
+
query[decode(rawKey)] = rawValue === true ? true : decode(rawValue);
|
|
295
|
+
});
|
|
296
|
+
return query;
|
|
297
|
+
}
|
|
298
|
+
function decode(value) {
|
|
299
|
+
try {
|
|
300
|
+
return decodeURIComponent(value.replace(/\+/gu, " "));
|
|
301
|
+
} catch (_err) {
|
|
302
|
+
return value;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function normalizeQueryNames(query) {
|
|
306
|
+
if (query === false) return [];
|
|
307
|
+
if (query == null) return DEFAULT_QUERY_NAMES;
|
|
308
|
+
return Array.isArray(query) ? query : [query];
|
|
309
|
+
}
|
|
310
|
+
function hasOwn(object, key) {
|
|
311
|
+
return Object.prototype.hasOwnProperty.call(object, key);
|
|
312
|
+
}
|
|
313
|
+
function matchesPattern(pattern, value) {
|
|
314
|
+
if (pattern == null) return false;
|
|
315
|
+
if (Array.isArray(pattern)) return pattern.some((item) => matchesPattern(item, value));
|
|
316
|
+
if (pattern instanceof RegExp) {
|
|
317
|
+
pattern.lastIndex = 0;
|
|
318
|
+
return pattern.test(value);
|
|
319
|
+
}
|
|
320
|
+
if (typeof pattern === "function") return Boolean(pattern(value));
|
|
321
|
+
return value.indexOf(String(pattern)) >= 0;
|
|
322
|
+
}
|
|
323
|
+
function matchesFilter(pattern, id, filename) {
|
|
324
|
+
return matchesPattern(pattern, id) || matchesPattern(pattern, filename);
|
|
325
|
+
}
|
|
326
|
+
function hasPluginQuery(query, options = {}) {
|
|
327
|
+
return normalizeQueryNames(options.query).some((queryName) => hasOwn(query, queryName));
|
|
328
|
+
}
|
|
329
|
+
function shouldTransform(id, options = {}) {
|
|
330
|
+
const { filename, query } = parseId(id);
|
|
331
|
+
if (!SVG_EXT_RE.test(filename)) return false;
|
|
332
|
+
if (matchesFilter(options.exclude, id, filename)) return false;
|
|
333
|
+
if (hasPluginQuery(query, options)) return true;
|
|
334
|
+
if (options.include != null) return matchesFilter(options.include, id, filename);
|
|
335
|
+
return options.query === false;
|
|
336
|
+
}
|
|
337
|
+
function buildParams(id, options = {}) {
|
|
338
|
+
const { filename, query } = parseId(id);
|
|
339
|
+
const queryNames = normalizeQueryNames(options.query);
|
|
340
|
+
const params = { resource: filename };
|
|
341
|
+
for (const key in query) if (queryNames.indexOf(key) < 0) params[key] = query[key];
|
|
342
|
+
return params;
|
|
343
|
+
}
|
|
344
|
+
function sourceToIconJsObject(source, id, options = {}) {
|
|
345
|
+
const params = buildParams(id, options);
|
|
346
|
+
if (source.indexOf("<font-face") >= 0 && !params["glyph-name"] && !params.unicode) return sourceToIconsJsObject(source, params);
|
|
347
|
+
return sourceToIconJsObject$1(source, params);
|
|
348
|
+
}
|
|
349
|
+
function transformSvg(source, id, options = {}) {
|
|
350
|
+
return {
|
|
351
|
+
code: `export default ${sourceToIconJsObject(source, id, options)};\n`,
|
|
352
|
+
map: { mappings: "" }
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region src/index.ts
|
|
357
|
+
const unplugin$1 = (0, unplugin.createUnplugin)((options = {}) => ({
|
|
358
|
+
name: "unplugin-cheetah-grid-icon-svg",
|
|
359
|
+
enforce: "pre",
|
|
360
|
+
transformInclude(id) {
|
|
361
|
+
return shouldTransform(id, options);
|
|
362
|
+
},
|
|
363
|
+
transform(source, id) {
|
|
364
|
+
if (!shouldTransform(id, options)) return null;
|
|
365
|
+
return transformSvg(source, id, options);
|
|
366
|
+
}
|
|
367
|
+
}));
|
|
368
|
+
//#endregion
|
|
369
|
+
Object.defineProperty(exports, "unplugin", {
|
|
370
|
+
enumerable: true,
|
|
371
|
+
get: function() {
|
|
372
|
+
return unplugin$1;
|
|
373
|
+
}
|
|
374
|
+
});
|
package/dist/src.mjs
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { createUnplugin } from "unplugin";
|
|
3
|
+
import { DOMParser } from "@xmldom/xmldom";
|
|
4
|
+
//#region src/core/svg-data.ts
|
|
5
|
+
const ELEMENT_NODE = 1;
|
|
6
|
+
const parser = new (typeof window !== "undefined" && window.DOMParser ? window.DOMParser : DOMParser)();
|
|
7
|
+
function isElementNode(node) {
|
|
8
|
+
return node.nodeType === ELEMENT_NODE && typeof node.tagName === "string";
|
|
9
|
+
}
|
|
10
|
+
function findElement(el, test) {
|
|
11
|
+
const { childNodes } = el;
|
|
12
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
13
|
+
const child = childNodes[i];
|
|
14
|
+
if (!isElementNode(child)) continue;
|
|
15
|
+
if (test(child)) return child;
|
|
16
|
+
const result = findElement(child, test);
|
|
17
|
+
if (result) return result;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
var Svg = class {
|
|
22
|
+
constructor(svgCode) {
|
|
23
|
+
this.glyphs = {};
|
|
24
|
+
this.glyphUnicodes = {};
|
|
25
|
+
const document = parser.parseFromString(svgCode, "image/svg+xml");
|
|
26
|
+
this.svg = document.documentElement;
|
|
27
|
+
}
|
|
28
|
+
findElement(test) {
|
|
29
|
+
return findElement(this.svg, test);
|
|
30
|
+
}
|
|
31
|
+
get fontFaceElement() {
|
|
32
|
+
if (this.cachedFontFaceElement === void 0) this.cachedFontFaceElement = this.findElement((child) => child.tagName.toLowerCase() === "font-face");
|
|
33
|
+
return this.cachedFontFaceElement;
|
|
34
|
+
}
|
|
35
|
+
get fontElement() {
|
|
36
|
+
if (this.cachedFontElement === void 0) this.cachedFontElement = this.findElement((child) => child.tagName.toLowerCase() === "font");
|
|
37
|
+
return this.cachedFontElement;
|
|
38
|
+
}
|
|
39
|
+
findGlyph(glyphName) {
|
|
40
|
+
if (!(glyphName in this.glyphs)) this.glyphs[glyphName] = this.findElement((child) => child.getAttribute("glyph-name") === glyphName);
|
|
41
|
+
return this.glyphs[glyphName] || null;
|
|
42
|
+
}
|
|
43
|
+
findGlyphByUnicode(unicode) {
|
|
44
|
+
if (!(unicode in this.glyphUnicodes)) this.glyphUnicodes[unicode] = this.findElement((child) => child.getAttribute("unicode") === unicode);
|
|
45
|
+
return this.glyphUnicodes[unicode] || null;
|
|
46
|
+
}
|
|
47
|
+
walkAllGlyph(callback) {
|
|
48
|
+
const walkGlyph = (el) => {
|
|
49
|
+
const { childNodes } = el;
|
|
50
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
51
|
+
const child = childNodes[i];
|
|
52
|
+
if (!isElementNode(child)) continue;
|
|
53
|
+
const unicode = child.getAttribute("unicode");
|
|
54
|
+
if (unicode && child.getAttribute("d")) {
|
|
55
|
+
if (!this.glyphUnicodes[unicode]) this.glyphUnicodes[unicode] = child;
|
|
56
|
+
const glyphName = child.getAttribute("glyph-name");
|
|
57
|
+
if (glyphName && !this.glyphs[glyphName]) this.glyphs[glyphName] = child;
|
|
58
|
+
callback(child);
|
|
59
|
+
} else walkGlyph(child);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
walkGlyph(this.svg);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const cache = {};
|
|
66
|
+
function get(svgCode) {
|
|
67
|
+
const cacheKey = `font:${svgCode}`;
|
|
68
|
+
cache[cacheKey] = cache[cacheKey] || new Svg(svgCode);
|
|
69
|
+
return cache[cacheKey];
|
|
70
|
+
}
|
|
71
|
+
createRequire(import.meta.url);
|
|
72
|
+
function attr(el, name) {
|
|
73
|
+
return el.getAttribute(name) || "";
|
|
74
|
+
}
|
|
75
|
+
function polygonToPath(polygon) {
|
|
76
|
+
return `M${attr(polygon, "points")}z`;
|
|
77
|
+
}
|
|
78
|
+
function polylineToPath(polyline) {
|
|
79
|
+
return `M${attr(polyline, "points")}`;
|
|
80
|
+
}
|
|
81
|
+
function circleToPath(circle) {
|
|
82
|
+
const cx = Number(attr(circle, "cx"));
|
|
83
|
+
const cy = Number(attr(circle, "cy"));
|
|
84
|
+
const r = Number(attr(circle, "r"));
|
|
85
|
+
const segments = 8;
|
|
86
|
+
const angle = 2 * Math.PI / segments;
|
|
87
|
+
const anchorX = (theta) => r * Math.cos(theta);
|
|
88
|
+
const anchorY = (theta) => r * Math.sin(theta);
|
|
89
|
+
const controlX = (theta) => anchorX(theta) + r * Math.tan(angle / 2) * Math.cos(theta - Math.PI / 2);
|
|
90
|
+
const controlY = (theta) => anchorY(theta) + r * Math.tan(angle / 2) * Math.sin(theta - Math.PI / 2);
|
|
91
|
+
let paths = `M${cx + r} ${cy}`;
|
|
92
|
+
for (let index = 1; index <= segments; index++) {
|
|
93
|
+
const theta = index * angle;
|
|
94
|
+
paths += `Q${controlX(theta) + cx} ${controlY(theta) + cy} ${anchorX(theta) + cx} ${anchorY(theta) + cy}`;
|
|
95
|
+
}
|
|
96
|
+
return paths;
|
|
97
|
+
}
|
|
98
|
+
function rectToPath(rect) {
|
|
99
|
+
const x = Number(attr(rect, "x"));
|
|
100
|
+
const y = Number(attr(rect, "y"));
|
|
101
|
+
const width = Number(attr(rect, "width"));
|
|
102
|
+
return `M${x},${y} h${width} v${Number(attr(rect, "height"))} h${-width}z`;
|
|
103
|
+
}
|
|
104
|
+
function getD(path) {
|
|
105
|
+
if (path.getAttribute("fill") === "none") return "";
|
|
106
|
+
return attr(path, "d").replace(/[\n\r]/gu, "");
|
|
107
|
+
}
|
|
108
|
+
function elementToPaths(el, resource) {
|
|
109
|
+
switch (el.tagName.toLowerCase()) {
|
|
110
|
+
case "path":
|
|
111
|
+
case "glyph": return getD(el);
|
|
112
|
+
case "circle": return circleToPath(el);
|
|
113
|
+
case "polygon": return polygonToPath(el);
|
|
114
|
+
case "polyline": return polylineToPath(el);
|
|
115
|
+
case "rect": return rectToPath(el);
|
|
116
|
+
case "g": {
|
|
117
|
+
let path = "";
|
|
118
|
+
const { childNodes } = el;
|
|
119
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
120
|
+
const child = childNodes[i];
|
|
121
|
+
if (!isElementNode(child)) continue;
|
|
122
|
+
if (!child.getAttribute("fill")) child.setAttribute("fill", el.getAttribute("fill"));
|
|
123
|
+
path += elementToPaths(child, resource);
|
|
124
|
+
}
|
|
125
|
+
return path;
|
|
126
|
+
}
|
|
127
|
+
default: console.warn(`unsupported:${el.tagName}`, `@ ${resource}\n${el.innerHTML}`);
|
|
128
|
+
}
|
|
129
|
+
return "";
|
|
130
|
+
}
|
|
131
|
+
function buildScript({ offsetX = 0, offsetY = 0, width, height, d, isGlyph, html, resource }) {
|
|
132
|
+
let flags = "";
|
|
133
|
+
if (isGlyph) flags += `ud: 1,
|
|
134
|
+
`;
|
|
135
|
+
if (offsetX !== 0) flags += `x: ${offsetX},
|
|
136
|
+
`;
|
|
137
|
+
if (offsetY !== 0) flags += `y: ${offsetY},
|
|
138
|
+
`;
|
|
139
|
+
return `{
|
|
140
|
+
/*
|
|
141
|
+
original svg
|
|
142
|
+
${html}
|
|
143
|
+
@ ${resource}
|
|
144
|
+
*/
|
|
145
|
+
d: '${d}',
|
|
146
|
+
width: ${width},
|
|
147
|
+
height: ${height},
|
|
148
|
+
${flags}
|
|
149
|
+
}`;
|
|
150
|
+
}
|
|
151
|
+
function glyphToJSON(svgString, { glyphName, unicode }, resource) {
|
|
152
|
+
const svg = get(svgString);
|
|
153
|
+
const findGlyph = () => {
|
|
154
|
+
if (glyphName && glyphName !== true) return svg.findGlyph(glyphName);
|
|
155
|
+
return unicode && unicode !== true ? svg.findGlyphByUnicode(unicode) : null;
|
|
156
|
+
};
|
|
157
|
+
const emptyElement = { getAttribute: () => "" };
|
|
158
|
+
const fontFace = svg.fontFaceElement || emptyElement;
|
|
159
|
+
const font = svg.fontElement || emptyElement;
|
|
160
|
+
const glyph = findGlyph();
|
|
161
|
+
if (!glyph) throw new Error(`Glyph not found: ${glyphName && glyphName !== true ? glyphName : unicode && unicode !== true ? unicode : ""}`);
|
|
162
|
+
const fontHorizAdvX = Number(font.getAttribute("horiz-adv-x")) || 0;
|
|
163
|
+
const fontVertAdvX = Number(font.getAttribute("vert-adv-x")) || 0;
|
|
164
|
+
const horizAdvX = Number(glyph.getAttribute("horiz-adv-x")) || fontHorizAdvX || 0;
|
|
165
|
+
const vertAdvX = Number(glyph.getAttribute("vert-adv-x")) || fontVertAdvX || 0;
|
|
166
|
+
const unitsPerEm = Number(fontFace.getAttribute("units-per-em")) || 1e3;
|
|
167
|
+
const descent = Number(fontFace.getAttribute("descent")) || vertAdvX;
|
|
168
|
+
let size = unitsPerEm;
|
|
169
|
+
const contentSize = {
|
|
170
|
+
width: horizAdvX || unitsPerEm,
|
|
171
|
+
height: vertAdvX || unitsPerEm
|
|
172
|
+
};
|
|
173
|
+
if (horizAdvX > size) size = horizAdvX;
|
|
174
|
+
if (vertAdvX > size) size = vertAdvX;
|
|
175
|
+
let offsetX = 0;
|
|
176
|
+
let offsetY = -descent;
|
|
177
|
+
offsetX += Math.round((size - contentSize.width) / 2);
|
|
178
|
+
offsetY += Math.round((size - contentSize.height) / 2);
|
|
179
|
+
return buildScript({
|
|
180
|
+
offsetX,
|
|
181
|
+
offsetY,
|
|
182
|
+
width: size,
|
|
183
|
+
height: size,
|
|
184
|
+
d: elementToPaths(glyph, resource),
|
|
185
|
+
isGlyph: true,
|
|
186
|
+
html: glyph.outerHTML,
|
|
187
|
+
resource
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function svgToJSON(svgString, resource) {
|
|
191
|
+
const { svg } = get(svgString);
|
|
192
|
+
const viewBox = attr(svg, "viewBox").split(" ");
|
|
193
|
+
const width = Number(attr(svg, "width") || viewBox[2]) || 0;
|
|
194
|
+
const height = Number(attr(svg, "height") || viewBox[3]) || 0;
|
|
195
|
+
const offsetX = 0 - Number(viewBox[0]) || 0;
|
|
196
|
+
const offsetY = 0 - Number(viewBox[1]) || 0;
|
|
197
|
+
let d = "";
|
|
198
|
+
const { childNodes } = svg;
|
|
199
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
200
|
+
const el = childNodes[i];
|
|
201
|
+
if (!isElementNode(el)) continue;
|
|
202
|
+
d += elementToPaths(el, resource);
|
|
203
|
+
}
|
|
204
|
+
return buildScript({
|
|
205
|
+
offsetX,
|
|
206
|
+
offsetY,
|
|
207
|
+
width,
|
|
208
|
+
height,
|
|
209
|
+
d,
|
|
210
|
+
html: svgString,
|
|
211
|
+
resource
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function normalizeResource$1(resource) {
|
|
215
|
+
let index = resource.indexOf("\\node_modules\\");
|
|
216
|
+
if (index === -1) index = resource.indexOf("/node_modules/");
|
|
217
|
+
if (index >= 0) return resource.slice(index + 14);
|
|
218
|
+
return resource;
|
|
219
|
+
}
|
|
220
|
+
function sourceToIconJsObject$1(svgCode, opt = {}) {
|
|
221
|
+
const resource = normalizeResource$1(opt.resource || "");
|
|
222
|
+
if (opt["glyph-name"] || opt.unicode) return glyphToJSON(svgCode, {
|
|
223
|
+
glyphName: opt["glyph-name"],
|
|
224
|
+
unicode: opt.unicode
|
|
225
|
+
}, resource);
|
|
226
|
+
return svgToJSON(svgCode, resource);
|
|
227
|
+
}
|
|
228
|
+
createRequire(import.meta.url);
|
|
229
|
+
function toGlyphs(svgCode) {
|
|
230
|
+
const svg = get(svgCode);
|
|
231
|
+
const glyphs = [];
|
|
232
|
+
svg.walkAllGlyph((el) => glyphs.push(el));
|
|
233
|
+
return glyphs;
|
|
234
|
+
}
|
|
235
|
+
function transform(glyphUnicode, svgCode, svgfile) {
|
|
236
|
+
return sourceToIconJsObject$1(svgCode, {
|
|
237
|
+
unicode: glyphUnicode,
|
|
238
|
+
resource: svgfile
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function charToHexCodeStr(char) {
|
|
242
|
+
if (/[!#-&(-[\]-_a-~]/u.test(char)) return char;
|
|
243
|
+
return `\\u${`0000${char.charCodeAt(0).toString(16)}`.slice(-4)}`;
|
|
244
|
+
}
|
|
245
|
+
function toCodeString(code) {
|
|
246
|
+
let result = "";
|
|
247
|
+
for (let i = 0; i < code.length; i++) result += charToHexCodeStr(code[i]);
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
function buildObjectCode(svgCode, resource, { name = "unicode" } = {}) {
|
|
251
|
+
let script = "{\n";
|
|
252
|
+
toGlyphs(svgCode).forEach((glyph) => {
|
|
253
|
+
const unicode = glyph.getAttribute("unicode") || "";
|
|
254
|
+
const targetName = glyph.getAttribute(name) || "";
|
|
255
|
+
script += `
|
|
256
|
+
'${toCodeString(targetName)}': ${transform(unicode, svgCode, resource).replace(/\r?\n|\r/gu, `
|
|
257
|
+
`)},`;
|
|
258
|
+
});
|
|
259
|
+
script += "\n}";
|
|
260
|
+
return script;
|
|
261
|
+
}
|
|
262
|
+
function normalizeResource(resource) {
|
|
263
|
+
let index = resource.indexOf("\\node_modules\\");
|
|
264
|
+
if (index === -1) index = resource.indexOf("/node_modules/");
|
|
265
|
+
if (index >= 0) return resource.slice(index + 14);
|
|
266
|
+
return resource;
|
|
267
|
+
}
|
|
268
|
+
function sourceToIconsJsObject(svgCode, opt = {}) {
|
|
269
|
+
return buildObjectCode(svgCode, normalizeResource(opt.resource || ""), opt);
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/core/transform.ts
|
|
273
|
+
const DEFAULT_QUERY_NAMES = ["cheetah-grid-icon", "cg-icon"];
|
|
274
|
+
const SVG_EXT_RE = /\.svg$/iu;
|
|
275
|
+
function parseId(id) {
|
|
276
|
+
const queryIndex = id.indexOf("?");
|
|
277
|
+
if (queryIndex < 0) return {
|
|
278
|
+
filename: id,
|
|
279
|
+
query: {}
|
|
280
|
+
};
|
|
281
|
+
return {
|
|
282
|
+
filename: id.slice(0, queryIndex),
|
|
283
|
+
query: parseQuery(id.slice(queryIndex + 1))
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function parseQuery(queryText) {
|
|
287
|
+
const query = {};
|
|
288
|
+
if (!queryText) return query;
|
|
289
|
+
queryText.split("&").forEach((part) => {
|
|
290
|
+
if (!part) return;
|
|
291
|
+
const equalIndex = part.indexOf("=");
|
|
292
|
+
const rawKey = equalIndex < 0 ? part : part.slice(0, equalIndex);
|
|
293
|
+
const rawValue = equalIndex < 0 ? true : part.slice(equalIndex + 1);
|
|
294
|
+
query[decode(rawKey)] = rawValue === true ? true : decode(rawValue);
|
|
295
|
+
});
|
|
296
|
+
return query;
|
|
297
|
+
}
|
|
298
|
+
function decode(value) {
|
|
299
|
+
try {
|
|
300
|
+
return decodeURIComponent(value.replace(/\+/gu, " "));
|
|
301
|
+
} catch (_err) {
|
|
302
|
+
return value;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function normalizeQueryNames(query) {
|
|
306
|
+
if (query === false) return [];
|
|
307
|
+
if (query == null) return DEFAULT_QUERY_NAMES;
|
|
308
|
+
return Array.isArray(query) ? query : [query];
|
|
309
|
+
}
|
|
310
|
+
function hasOwn(object, key) {
|
|
311
|
+
return Object.prototype.hasOwnProperty.call(object, key);
|
|
312
|
+
}
|
|
313
|
+
function matchesPattern(pattern, value) {
|
|
314
|
+
if (pattern == null) return false;
|
|
315
|
+
if (Array.isArray(pattern)) return pattern.some((item) => matchesPattern(item, value));
|
|
316
|
+
if (pattern instanceof RegExp) {
|
|
317
|
+
pattern.lastIndex = 0;
|
|
318
|
+
return pattern.test(value);
|
|
319
|
+
}
|
|
320
|
+
if (typeof pattern === "function") return Boolean(pattern(value));
|
|
321
|
+
return value.indexOf(String(pattern)) >= 0;
|
|
322
|
+
}
|
|
323
|
+
function matchesFilter(pattern, id, filename) {
|
|
324
|
+
return matchesPattern(pattern, id) || matchesPattern(pattern, filename);
|
|
325
|
+
}
|
|
326
|
+
function hasPluginQuery(query, options = {}) {
|
|
327
|
+
return normalizeQueryNames(options.query).some((queryName) => hasOwn(query, queryName));
|
|
328
|
+
}
|
|
329
|
+
function shouldTransform(id, options = {}) {
|
|
330
|
+
const { filename, query } = parseId(id);
|
|
331
|
+
if (!SVG_EXT_RE.test(filename)) return false;
|
|
332
|
+
if (matchesFilter(options.exclude, id, filename)) return false;
|
|
333
|
+
if (hasPluginQuery(query, options)) return true;
|
|
334
|
+
if (options.include != null) return matchesFilter(options.include, id, filename);
|
|
335
|
+
return options.query === false;
|
|
336
|
+
}
|
|
337
|
+
function buildParams(id, options = {}) {
|
|
338
|
+
const { filename, query } = parseId(id);
|
|
339
|
+
const queryNames = normalizeQueryNames(options.query);
|
|
340
|
+
const params = { resource: filename };
|
|
341
|
+
for (const key in query) if (queryNames.indexOf(key) < 0) params[key] = query[key];
|
|
342
|
+
return params;
|
|
343
|
+
}
|
|
344
|
+
function sourceToIconJsObject(source, id, options = {}) {
|
|
345
|
+
const params = buildParams(id, options);
|
|
346
|
+
if (source.indexOf("<font-face") >= 0 && !params["glyph-name"] && !params.unicode) return sourceToIconsJsObject(source, params);
|
|
347
|
+
return sourceToIconJsObject$1(source, params);
|
|
348
|
+
}
|
|
349
|
+
function transformSvg(source, id, options = {}) {
|
|
350
|
+
return {
|
|
351
|
+
code: `export default ${sourceToIconJsObject(source, id, options)};\n`,
|
|
352
|
+
map: { mappings: "" }
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region src/index.ts
|
|
357
|
+
const unplugin = createUnplugin((options = {}) => ({
|
|
358
|
+
name: "unplugin-cheetah-grid-icon-svg",
|
|
359
|
+
enforce: "pre",
|
|
360
|
+
transformInclude(id) {
|
|
361
|
+
return shouldTransform(id, options);
|
|
362
|
+
},
|
|
363
|
+
transform(source, id) {
|
|
364
|
+
if (!shouldTransform(id, options)) return null;
|
|
365
|
+
return transformSvg(source, id, options);
|
|
366
|
+
}
|
|
367
|
+
}));
|
|
368
|
+
//#endregion
|
|
369
|
+
export { unplugin as t };
|
package/dist/vite.cjs
ADDED
package/dist/vite.d.mts
ADDED
package/dist/vite.mjs
ADDED
package/dist/webpack.cjs
ADDED
package/dist/webpack.mjs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "unplugin-cheetah-grid-icon-svg",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Unplugin that loads the icon module for Cheetah Grid from SVG.",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.mts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"require": "./dist/index.cjs",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"./vite": {
|
|
15
|
+
"types": "./dist/vite.d.mts",
|
|
16
|
+
"require": "./dist/vite.cjs",
|
|
17
|
+
"import": "./dist/vite.mjs"
|
|
18
|
+
},
|
|
19
|
+
"./rollup": {
|
|
20
|
+
"types": "./dist/rollup.d.mts",
|
|
21
|
+
"require": "./dist/rollup.cjs",
|
|
22
|
+
"import": "./dist/rollup.mjs"
|
|
23
|
+
},
|
|
24
|
+
"./rolldown": {
|
|
25
|
+
"types": "./dist/rolldown.d.mts",
|
|
26
|
+
"require": "./dist/rolldown.cjs",
|
|
27
|
+
"import": "./dist/rolldown.mjs"
|
|
28
|
+
},
|
|
29
|
+
"./webpack": {
|
|
30
|
+
"types": "./dist/webpack.d.mts",
|
|
31
|
+
"require": "./dist/webpack.cjs",
|
|
32
|
+
"import": "./dist/webpack.mjs"
|
|
33
|
+
},
|
|
34
|
+
"./rspack": {
|
|
35
|
+
"types": "./dist/rspack.d.mts",
|
|
36
|
+
"require": "./dist/rspack.cjs",
|
|
37
|
+
"import": "./dist/rspack.mjs"
|
|
38
|
+
},
|
|
39
|
+
"./esbuild": {
|
|
40
|
+
"types": "./dist/esbuild.d.mts",
|
|
41
|
+
"require": "./dist/esbuild.cjs",
|
|
42
|
+
"import": "./dist/esbuild.mjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"pretest": "npm run lint",
|
|
50
|
+
"test:base": "vitest run",
|
|
51
|
+
"test": "npm run build && vitest run --coverage",
|
|
52
|
+
"test:nyc": "npm run test",
|
|
53
|
+
"test:d": "vitest --inspect-brk",
|
|
54
|
+
"watch": "vitest",
|
|
55
|
+
"build": "npm run build:tsdown",
|
|
56
|
+
"build:tsdown": "tsdown",
|
|
57
|
+
"prepack": "npm run build",
|
|
58
|
+
"lint": "npm run eslint && npm run tsc",
|
|
59
|
+
"eslint": "eslint . --ext .js,.ts",
|
|
60
|
+
"eslint:fix": "eslint . --fix --ext .js,.ts",
|
|
61
|
+
"tsc": "tsc --project ./tsconfig.json"
|
|
62
|
+
},
|
|
63
|
+
"repository": {
|
|
64
|
+
"type": "git",
|
|
65
|
+
"url": "https://github.com/future-architect/cheetah-grid.git"
|
|
66
|
+
},
|
|
67
|
+
"keywords": [
|
|
68
|
+
"svg",
|
|
69
|
+
"vite",
|
|
70
|
+
"rollup",
|
|
71
|
+
"rolldown",
|
|
72
|
+
"webpack",
|
|
73
|
+
"unplugin",
|
|
74
|
+
"icon",
|
|
75
|
+
"cheetah-grid"
|
|
76
|
+
],
|
|
77
|
+
"author": {
|
|
78
|
+
"name": "yosuke ota",
|
|
79
|
+
"email": "otameshiyo23@gmail.com",
|
|
80
|
+
"url": "https://www.npmjs.com/~ota-meshi"
|
|
81
|
+
},
|
|
82
|
+
"license": "MIT",
|
|
83
|
+
"bugs": {
|
|
84
|
+
"url": "https://github.com/future-architect/cheetah-grid/issues"
|
|
85
|
+
},
|
|
86
|
+
"homepage": "https://github.com/future-architect/cheetah-grid/tree/master/packages/unplugin-cheetah-grid-icon-svg",
|
|
87
|
+
"dependencies": {
|
|
88
|
+
"@xmldom/xmldom": "^0.9.10",
|
|
89
|
+
"unplugin": "^2.3.10"
|
|
90
|
+
},
|
|
91
|
+
"devDependencies": {
|
|
92
|
+
"@types/node": "^24.12.4",
|
|
93
|
+
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
|
94
|
+
"@typescript-eslint/parser": "^4.0.0",
|
|
95
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
96
|
+
"eslint": "^7.11.0",
|
|
97
|
+
"eslint-config-prettier": "^6.11.0",
|
|
98
|
+
"eslint-plugin-node": "^11.1.0",
|
|
99
|
+
"eslint-plugin-prettier": "^3.1.4",
|
|
100
|
+
"font-awesome": "^4.7.0",
|
|
101
|
+
"prettier": "^2.5.1",
|
|
102
|
+
"tsdown": "^0.14.1",
|
|
103
|
+
"typescript": "^5.9.2",
|
|
104
|
+
"vitest": "^4.1.6"
|
|
105
|
+
},
|
|
106
|
+
"engines": {
|
|
107
|
+
"node": "^22.12.0 || ^24.11.0"
|
|
108
|
+
},
|
|
109
|
+
"peerDependencies": {
|
|
110
|
+
"@rspack/core": ">=0.5.0",
|
|
111
|
+
"esbuild": ">=0.14.0",
|
|
112
|
+
"rolldown": ">=1.0.0-beta.0",
|
|
113
|
+
"rollup": ">=2.0.0",
|
|
114
|
+
"vite": ">=2.0.0",
|
|
115
|
+
"webpack": ">=4.0.0"
|
|
116
|
+
},
|
|
117
|
+
"peerDependenciesMeta": {
|
|
118
|
+
"vite": {
|
|
119
|
+
"optional": true
|
|
120
|
+
},
|
|
121
|
+
"webpack": {
|
|
122
|
+
"optional": true
|
|
123
|
+
},
|
|
124
|
+
"rollup": {
|
|
125
|
+
"optional": true
|
|
126
|
+
},
|
|
127
|
+
"rolldown": {
|
|
128
|
+
"optional": true
|
|
129
|
+
},
|
|
130
|
+
"esbuild": {
|
|
131
|
+
"optional": true
|
|
132
|
+
},
|
|
133
|
+
"@rspack/core": {
|
|
134
|
+
"optional": true
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|