| """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"): |
| |
| 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 |
|
|