spire_core/backend/document.rs
1//! Optional link observations from a rendered document.
2
3use ::http::Uri;
4use futures::future::BoxFuture;
5
6use crate::Result;
7
8/// A live rendered document, separate from a fetched response snapshot.
9///
10/// Methods return boxed futures to make this optional capability object
11/// safe. Ordinary HTTP sessions do not implement it or allocate these
12/// futures. Captures observe the current DOM and must not scroll or mutate it.
13pub trait Document: Send + Sync {
14 /// Captures links and their visibility together, in document order.
15 /// `selector` narrows `<a href>` and `<area href>` links using CSS.
16 ///
17 /// # Errors
18 ///
19 /// Returns an error if the selector is invalid, no page has been
20 /// fetched, or the document cannot be read.
21 fn links<'a>(&'a self, selector: Option<&'a str>) -> BoxFuture<'a, Result<DocumentLinks>>;
22}
23
24/// What a session knows about whether a visitor can follow a link.
25#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
26#[non_exhaustive]
27pub enum Visibility {
28 /// The rendered link has a usable area and is not hidden or clipped.
29 Visible,
30 /// Attributes, styles or layout hide the link.
31 Hidden,
32 /// The session cannot establish visibility, e.g. without CSS and layout.
33 #[default]
34 Unknown,
35}
36
37/// The element a document link comes from.
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
39#[non_exhaustive]
40pub enum LinkKind {
41 /// An `<a href>`.
42 Anchor,
43 /// An `<area href>` of an image map.
44 Area,
45}
46
47/// A link and its visibility, observed together from one rendered document.
48#[derive(Debug, Clone, PartialEq, Eq)]
49pub struct DocumentLink {
50 /// The `href` as written in the document.
51 pub href: String,
52 /// The link's `rel` tokens.
53 pub rel: Vec<String>,
54 /// The anchor's text, or an area's `alt` text.
55 pub text: String,
56 /// The element the link comes from.
57 pub kind: LinkKind,
58 /// Visibility at the time the link was observed.
59 pub visibility: Visibility,
60}
61
62/// Links captured together from a rendered document, in document order.
63///
64/// The page URI, base URI, link attributes and visibility must all come
65/// from the same DOM capture. Duplicate URLs are separate link records.
66#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct DocumentLinks {
68 /// The document's current URI, after navigation or script changes.
69 pub uri: Uri,
70 /// The document's base URI, including its `<base href>`, if any.
71 pub base_uri: String,
72 /// The observed links, including hidden and unknown links.
73 pub links: Vec<DocumentLink>,
74}