"""Resolve possibly-relative asset references to absolute URLs. All extractors funnel their raw `src`/`href` values through `:func:resolve` so the final result always has absolute URLs. """ from urllib.parse import urljoin, urlparse def resolve(base_url: str, ref: str) -> str | None: """Turn a raw reference into an absolute http(s) URL. Returns None for references we cannot safely absolutize, including `javascript:`/`mailto:`/`data:`/`#` when they carry no usable path. """ ref = (ref or "").strip().strip('"').strip("'") if not ref or ref.startswith("#"): return None scheme, netloc = urlparse(ref)[:2] if scheme and scheme not in ("http", "https"): # keep data: URIs only if explicitly requested by the caller if scheme == "data": return ref return None absolute = urljoin(base_url, ref) parsed = urlparse(absolute) if parsed.scheme not in ("http", "https") or not parsed.netloc: return None return absolute