Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
# mangle-ids — Replace Element IDs with Short Sequential Identifiers
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`mangleIds` replaces verbose `id` attribute values with short sequential identifiers (`a`, `b`, ..., `z`, `A`, ..., `Z`, `aa`, `ab`, ...) and rewrites all `href` and `xlink:href` reference attributes that point to the old IDs. This significantly reduces the size of SVGs that use many named elements for gradients, patterns, clip paths, filters, or `<use>` references.
## Features
- Replaces `id` attribute values with the shortest possible unique identifier
- Rewrites `href="#originalId"` and `xlink:href="#originalId"` to point to the new mangled ID
- Stateful per-instance ID map — create a fresh instance per compression run via `createMangleIds()`
- The exported `mangleIds` singleton is suitable for single-pass use; use `createMangleIds()` in test or multi-run scenarios
- Only in `PRESET_AGGRESSIVE`; opt-in only because mangling IDs breaks external CSS selectors that target the SVG by ID
## Usage: Basic Example
```typescript
import { compressSvg } from '@suaveplan/compress-svg';
import { createMangleIds } from '@suaveplan/compress-svg/plugins/mangle-ids';
const svg = '<svg><defs><linearGradient id="myGradient"/></defs><rect fill="url(#myGradient)"/></svg>';
const result = compressSvg(svg, { plugins: [createMangleIds()] });
// IDs in result.data are short: id="a", not id="myGradient"
```
## Usage: Advanced Example
```typescript
import { createMangleIds } from '@suaveplan/compress-svg/plugins/mangle-ids';
const plugin = createMangleIds();
const opts = { floatPrecision: 3, transformPrecision: 5 };
const def = { type: 'element' as const, name: 'path', attributes: { id: 'clipPath1' }, children: [] };
const use = { type: 'element' as const, name: 'use', attributes: { href: '#clipPath1' }, children: [] };
const mangledDef = plugin.apply(def, opts);
const mangledUse = plugin.apply(use, opts);
const newId = mangledDef!.attributes!.id; // e.g. 'a'
// mangledUse.attributes.href === '#a'
```
## API Reference
### `createMangleIds(): SvgPlugin`
Factory function that returns a new stateful `mangleIds` plugin instance. Each call creates an independent ID counter and map, so multiple independent SVGs can be compressed without ID collisions.
### `mangleIds: SvgPlugin`
Pre-created singleton instance. Suitable for single-use scenarios where a fresh instance is created per module load.
| Property | Value |
|----------|-------|
| `name` | `"mangleIds"` |
| `apply` | `(node, options) => SvgNode \| null` |
**Rewrites `id`** on element nodes to the next sequential short identifier.
**Rewrites `href`** and `xlink:href`** on element nodes when the value is a fragment reference (`#...`).
## Implementation Notes
Short IDs are generated with a base-52 alphabet (lowercase `a–z` then uppercase `A–Z`). The sequence is 0→`a`, 1→`b`, ..., 25→`z`, 26→`A`, ..., 51→`Z`, 52→`aa`, 53→`ab`, etc. This avoids numeric IDs (which are invalid XML `id` values starting with a digit) and produces the shortest possible identifiers. The ID map is keyed by original ID string, so multiple nodes with the same original ID receive the same mangled ID — though well-formed SVG should not have duplicate IDs.