URL and CSS value sanitization for Tiptapex.Renderer.
These allow-lists are the core XSS defense: link/image/video URLs must be http(s), mailto, or relative; iframes are only ever emitted for canonical YouTube embed URLs rebuilt from a validated video id; CSS values must match a strict grammar that cannot break out of a style attribute.
Summary
Functions
Coerces a width attribute to integer pixels.
Validates a CSS value for inline style emission (colors, font sizes,
font families, line heights). The grammar admits no ;, braces, quotes,
url(, or escapes, so a value can never break out of its declaration.
Validates a user-supplied URL for href/src attributes.
Validates a text-align value.
Normalizes any of the common YouTube URL shapes to the canonical embed
URL, validating the video id. This is the ONLY URL ever placed in an
iframe src; anything that doesn't resolve here drops the whole node.
Functions
@spec int_width(term()) :: {:ok, pos_integer()} | :error
Coerces a width attribute to integer pixels.
Validates a CSS value for inline style emission (colors, font sizes,
font families, line heights). The grammar admits no ;, braces, quotes,
url(, or escapes, so a value can never break out of its declaration.
Validates a user-supplied URL for href/src attributes.
Accepts absolute http/https/mailto URLs, protocol-relative URLs, and
relative paths/fragments. Rejects everything else — notably
javascript:, vbscript:, and data: — plus anything containing
control characters.
Validates a text-align value.
Normalizes any of the common YouTube URL shapes to the canonical embed
URL, validating the video id. This is the ONLY URL ever placed in an
iframe src; anything that doesn't resolve here drops the whole node.
Mirrors toYoutubeEmbed/1 in assets/js/tiptapex/extensions/video.js,
but rebuilds the URL from the extracted id instead of passing the
original through.