Documentation
¶
Overview ¶
Command sprite injects an SVG sprite once and points the page's icons at it.
<img src="/icons/save.svg" alt="Save"> -> <svg class="icon" role="img" aria-label="Save"><use href="#i-save"></use></svg>
An icon per <img> is an HTTP request per icon; one sprite holding every symbol is one request, and each icon becomes a <use> pointing into it. The rewrite is two jobs: turn the references into <use> elements, and get the sprite into the document exactly once.
Where the sprite goes is decided by when the rewriter knows it is needed. At the top of the document that is not known yet - the first icon may be a screen down - so -at top injects the sprite whether the page has icons or not, and -at end (the default) injects it only when at least one reference was rewritten, at the one position still available once the evidence is in. A <use> is resolved after the document is parsed, so a sprite at the end is reachable from a reference above it.
The accessible name is where this program is careful, and the reason is that a value is only source for the context it came from. An alt attribute may hold a raw "<": it is an attribute value, where "<" is an ordinary character. Moved into an element's text - the <title> inside an <svg>, which is the obvious place for a name - it is markup, and an alt of "<img src=x onerror=alert(1)>" becomes a live element that the document itself had made inert. So the name stays in an attribute, aria-label, and the only character escaped on the way in is the double quote, which is exactly what the library escapes for an attribute it writes itself. Escaping more would be wrong in the other direction: lolhtml.EscapeAttribute escapes "&" as well, which turns a document's "&" into "&amp;".
See the package documentation on building markup, and differential/context_test.go for the measurements.