/** * Presentation styling for annotations. * * Two jobs that have to stay separate. Reading: an imported annotation may * carry an Annotation-level stylesheet, which is CSS a stranger wrote, and * nothing here may hand it to the browser — it is parsed into a small set of * presentation hints and everything outside an allowlist is discarded. Writing: * Mango's layer colours become a `CssStylesheet` plus a target `styleClass`, * the one representation of colour that survives a round trip through a * conformant consumer. * * The line this file exists to hold: colour is a hint. It never carries * motivation, purpose, ownership, visibility, or layer membership. A consumer * that loses the stylesheet loses the colour and nothing else. */ import { type CanonicalAnnotation, type CanonicalStylesheet } from '@mango-iiif/w3c-parser'; /** Presentation hints, in the form the canvas package's theme expects. */ export type PresentationHints = { strokeColor?: string; fillColor?: string; strokeWidth?: number; opacity?: number; }; export type StyleRule = { /** Bare class name, without the leading dot. */ className: string; declarations: Record; }; export type StylesheetParseResult = { rules: StyleRule[]; /** Declarations and selectors refused, for the advanced/diagnostic panel. */ rejected: string[]; }; /** * Parses CSS into class rules. * * Deliberately not a general CSS parser and deliberately not the browser's: * handing this text to a stylesheet object — even a constructed one — is what * the sanitizing exists to avoid, and the accepted grammar here is one flat * class selector with simple declarations. Anything more expressive is refused * rather than approximated, because an approximation is how a selector escapes * the annotation root. */ export declare const parseAnnotationCss: (css: string) => StylesheetParseResult; /** * Reads the presentation hints an annotation's own stylesheet defines for a * class. * * External stylesheet references are recognised and ignored: resolving one * means fetching a URL a stranger supplied, and that decision belongs to the * host, not to a render pass. The class then has no applicable stylesheet, the * shape renders in the normal theme, and the caller reports the diagnostic. */ export declare const hintsForStyleClass: (annotation: CanonicalAnnotation, styleClass: string | undefined) => { hints?: PresentationHints; rejected: string[]; unresolved: boolean; }; /** Layer colour, and nothing about what the layer means. */ export type LayerAppearance = { id: string; color: string; }; export type AnnotationAppearance = { className: string; strokeColor: string; fillColor: string; strokeWidth?: number; }; /** * CSS class name for a layer. * * The layer's own id when it is a usable CSS identifier, which keeps Mango's * output identical to what the parser's migration helper produces for legacy * documents — two paths to the same class name rather than two class names for * the same layer. Ids that are not valid identifiers get a stable escaped form. */ export declare const styleClassForLayer: (layerId: string) => string; export declare const rgbaFromHex: (color: string, alpha: number) => string; /** * Restricts application-authored colours before interpolating them into CSS. * Story documents and host-provided layer definitions are input, not trusted * code; accepting a semicolon here would let data escape its declaration even * though imported stylesheets themselves are parsed safely. */ export declare const safeAnnotationColor: (color: string, fallback?: string) => string; /** Builds one portable stylesheet rule for an authored annotation shape. */ export declare const buildAnnotationStylesheet: (appearance: AnnotationAppearance) => CanonicalStylesheet; /** * Builds the Annotation-level stylesheet for the layers an annotation uses. * * Only the layers actually referenced: a stylesheet listing every layer in the * application would leak the full layer set into every exported annotation, * which is organisation metadata rather than presentation. */ export declare const buildLayerStylesheet: (layers: readonly LayerAppearance[]) => CanonicalStylesheet | null; /** * Reads a colour back out of a legacy inline `target.style` value. * * Retained only for migration: Mango wrote this convention, so documents in * user stores carry it, and the colour is recoverable even though the property * itself is not portable. */ export declare const colorFromInlineStyle: (style: string | undefined) => string | null; /** Parses a legacy inline `target.style` value into presentation hints. */ export declare const hintsFromInlineStyle: (style: string | undefined) => PresentationHints | undefined;