zemion 0c7736dbc3
Verify / verify (push) Canceled after 0s
Release SVG Tools 0.2.0
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00
2026-09-02 04:48:12 +02:00

SVG Tools

SVG Tools is a static, local-first SVG workbench. It keeps the original SVG source as the persistent document, then derives a semantic tree, a sanitized editing projection, a canvas overlay and inspectors from that source. Files are processed in the browser; the app has no backend, upload endpoint, telemetry or runtime CDN dependency.

Version 0.2.0 delivers the structured viewer/editor milestone (MVP 1) and tested vertical slices of the path, transform, reference, optimization, security, accessibility, animation and export milestones. The later milestone lists below remain a roadmap, not a claim of complete vector-editor coverage.

Working model

  • The CodeMirror XML document is canonical. Visual changes create exact source patches and one application-level undo transaction.
  • The semantic model records element and attribute source ranges, stable in-memory keys, source preferences, metrics and diagnostics.
  • Tree, source cursor and canvas selection are synchronized.
  • Invalid edits remain visible in the source editor while the tree and canvas retain the last valid revision. Visual editing is disabled until parsing succeeds again.
  • Comments, whitespace and unrelated source remain unchanged for targeted edits. Prettify, sanitize and optimize are explicit whole-document previews.
  • No editor namespace or persistent editor attribute is added to normal SVG exports.

Implemented in 0.2.0

  • open, drop and paste SVG; magic-byte SVGZ import; new-document templates;
  • XML editor, ranged diagnostics, structure tree, filtering and synchronized selection;
  • safe canvas, zoom, pan, grid, selected bounds and last-valid state;
  • document dimensions, viewBox, preserveAspectRatio, arbitrary attributes, fill, stroke, opacity, rotate, flip, translate, scale and skew;
  • undoable subtree duplicate/delete for ID-free nodes, with duplicate-ID and external-reference guards rather than silently breaking the document;
  • exact undo/redo and explicit source-diff previews;
  • parsing of M L H V C S Q T A Z, absolute/relative and repeated groups;
  • anchors, cubic and quadratic controls, derived smooth controls, arc controls, nested-transform coordinate mapping, keyboard nudging, 50% segment splitting and path reversal;
  • transform-list parsing, ancestor matrices, invertibility diagnostics, preview overlay, and atomic baking for paths, lines, polylines, polygons, rectangles, circles and ellipses with disclosed conversion/stroke warnings;
  • ID/reference indexing, broken/ambiguous/cyclic reference diagnostics and atomic ID rename for local URL, href and ARIA references;
  • SVGO 4.0.2 in a cancelable worker with conservative, balanced and aggressive profiles, explicit optional plugins, sizes and source diff;
  • non-destructive sanitization, geometry diagnostics, accessible-name audit and undoable root title/description fixes;
  • app-owned, validated CSS opacity animation preview in the isolated canvas and explicit source application;
  • exact SVG, deterministic SVGZ, sanitized SVG, optimized SVG, selected-object SVG, symbol sprite, PNG, WebP, JPEG and deterministic project export.

Well-formed SVG/XML content that the semantic model does not understand is preserved in canonical source. The editing projection deliberately excludes active or externally loading content. Standard rendering still follows the browser's SVG implementation, so font, filter and text layout can differ across browsers.

Path controls

Explicit cubic controls are solid; controls reflected by S are dashed and labelled derived. Quadratic commands show their single control, while T derives the reflection of the preceding quadratic control. Arcs expose endpoint, center and radius controls plus their flags in the command table. Moving a derived control intentionally expands shorthand to explicit normalized geometry. Visual path edits currently serialize the selected d attribute in normalized absolute form; surrounding source is untouched.

Not yet implemented: multi-node modes, path join/break/combine, subpath-start changes, a pen tool, snapping, simplification, boolean operations, round corners and stroke-to-path.

Transform model and limits

Transform drafts never change source. SVG Tools shows the local/ancestor chain, candidate matrix, diagnostics, before/after overlay and source diff before one atomic Apply. General rectangle and ellipse cases may convert to a path. Baking is refused for unsupported elements rather than partially rewriting them.

Stroke widths are not silently rewritten for non-conformal transforms; the preview reports the consequence. Paint servers, markers, filters, clips, masks, text and shared definitions are not flattened or cloned. Group flattening, text-to-path and complete paint-server coordinate remapping remain future work.

Security and privacy

Imported source is never inserted into the application DOM. DOMPurify plus an application policy produces a separate editing projection. Scripts, foreignObject, event handlers, native SVG animation, navigation and unsafe namespaces are removed; external/executable URLs and unsafe CSS resource forms are neutralized. Only unique local fragments and bounded raster data URLs are eligible for rendering.

The projection runs in an opaque-origin iframe (sandbox="allow-scripts") with a restrictive child CSP. Its small self-hosted controller accepts a random channel and messages from the parent window only, then removes its own script element. Production servers must return the two documented cross-origin headers for canvas-frame-controller.js; see docs/SECURITY.md. Original source always remains available. Sanitization and optimization require an explicit preview and Apply. These controls reduce the documented threat surface; they are not a universal SVG sanitizer for every embedding context.

Resource limits cover source bytes, decompressed SVGZ output, elements, depth, attributes, text, path commands, CSS, references, animation/filter counts, embedded data, history, optimization time and raster pixels.

Accessibility

The current evidence-based audit checks the root accessible name (title, aria-label or aria-labelledby), missing description, invalid/ambiguous ARIA references, focusable elements without names and selected contrast evidence. Safe root title/description fixes are undoable. This is not a complete browser accessible-name computation and does not establish WCAG conformance.

Projects and persistence

Normal work is memory-only. SVG Tools does not write source or recent-file data to browser storage. A .svgtools.json project is explicit, deterministic JSON containing canonical source, selection/expanded state, active panel, zoom, pan, grid and app-owned animation definitions. Import validates schema, sizes, numbers, arrays and every animation field before use.

Development

Node.js 22 or newer and npm are required.

npm ci
npm run dev
npm run typecheck
npm run lint
npm run format:check
npm test
npm run test:security
npm run test:browser
npm run build
npm run toolbox:check

vite.config.ts uses base: './'; the same build works standalone, in Toolbox context and below a nested path. npm run release:artifact performs the complete quality gate, creates a deterministic ZIP plus SHA-256 sidecar, and exercises a temporary Toolbox Portal assembly. Portal consumes that immutable ZIP; it does not build this repository.

For the opaque canvas controller, a production server must return:

Access-Control-Allow-Origin: *
Cross-Origin-Resource-Policy: cross-origin

only for the app-relative canvas-frame-controller.js. All other app resources should keep Cross-Origin-Resource-Policy: same-origin. The Toolbox Portal 0.10.0 Nginx policy contains this URI-scoped exception.

Source and licence

Corresponding source and inspected revisions are recorded in SOURCE.md and docs/REFERENCE_IMPLEMENTATIONS.md. Third-party packages and adoption decisions are recorded in THIRD_PARTY_NOTICES.md and LICENSES. Project-authored fixtures contain no third-party artwork or text.

SVG Tools is licensed under GPL-3.0-or-later. See LICENSE.

Roadmap

The smallest next slice is multi-node path editing: node selection and modes, shape-preserving deletion/insertion, segment conversion and open/join/break operations under nested transforms. Later slices add drawing tools, grouping, alignment/snapping, gradients/markers/filters, symbol management, advanced geometry and broader isolated SMIL/CSS animation inspection.

Detailed models and limitations live in docs.

S
Description
Local-first SVG workbench for the add·ideas Toolbox
Readme GPL-3.0
321 KiB
2026-09-02 04:48:12 +02:00
Languages
TypeScript 88.1%
CSS 6.2%
JavaScript 5.6%
HTML 0.1%