iced_webview/engines.rs
1use std::collections::HashMap;
2
3use crate::ImageInfo;
4use iced::keyboard;
5use iced::mouse::{self, Interaction};
6use iced::Point;
7use iced::Size;
8
9/// A Blitz implementation of Engine (Stylo + Taffy + Vello)
10#[cfg(feature = "blitz")]
11pub mod blitz;
12
13/// A litehtml implementation of Engine for HTML rendering
14#[cfg(feature = "litehtml")]
15pub mod litehtml;
16
17/// A Servo implementation of Engine (full browser: HTML5, CSS3, JS)
18#[cfg(feature = "servo")]
19pub mod servo;
20
21/// A CEF/Chromium implementation of Engine (full browser via cef-rs)
22#[cfg(feature = "cef")]
23pub mod cef_engine;
24
25/// Creation of new pages to be of a html type or a url
26#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
27pub enum PageType {
28 /// Allows visiting Url web pages
29 Url(String),
30 /// Allows custom html web pages
31 Html(String),
32}
33
34/// Enables browser engines to display their images in different formats
35pub enum PixelFormat {
36 /// RGBA
37 Rgba,
38 /// BGRA
39 Bgra,
40}
41
42/// Alias of usize used for controlling specific views
43/// Only used by advanced to get views, basic simply uses u32
44pub type ViewId = usize;
45
46/// Trait to handle multiple browser engines
47/// Currently only supports cpu renders via pixel_buffer
48/// Passing a View id that does not exist will cause a panic
49pub trait Engine {
50 /// Used to do work in the actual browser engine
51 fn update(&mut self);
52 /// Request a new render pass from the engine
53 fn render(&mut self, size: Size<u32>);
54 /// Flush a pending render for a specific view, if one is needed.
55 ///
56 /// This does **not** force an unconditional render. It only performs the
57 /// (potentially expensive) render work when the view has been marked dirty
58 /// by a prior state change (`goto`, `resize`, `refresh`, `update`, etc.).
59 /// Callers should treat this as a "render-if-dirty" flush point, not a
60 /// "render right now regardless" command.
61 fn request_render(&mut self, id: ViewId, size: Size<u32>);
62 /// Creates new a new (possibly blank) view and returns the ViewId to interact with it
63 fn new_view(&mut self, size: Size<u32>, content: Option<PageType>) -> ViewId;
64 /// Removes desired view
65 fn remove_view(&mut self, id: ViewId);
66 /// Whether a view with this id currently exists.
67 fn has_view(&self, _id: ViewId) -> bool {
68 false
69 }
70
71 /// Focuses webview
72 fn focus(&mut self);
73 /// Unfocuses webview
74 fn unfocus(&self);
75 /// Resizes webview
76 fn resize(&mut self, size: Size<u32>);
77 /// Set the display scale factor for HiDPI rendering. Default is no-op.
78 fn set_scale_factor(&mut self, _scale: f32) {}
79
80 /// Whether this engine can fetch and render URLs natively.
81 /// Engines that return `false` rely on the webview layer to fetch HTML.
82 fn handles_urls(&self) -> bool {
83 true
84 }
85
86 /// lets the engine handle keyboard events
87 fn handle_keyboard_event(&mut self, id: ViewId, event: keyboard::Event);
88 /// lets the engine handle mouse events
89 fn handle_mouse_event(&mut self, id: ViewId, point: Point, event: mouse::Event);
90 /// Handles scrolling on view
91 fn scroll(&mut self, id: ViewId, delta: mouse::ScrollDelta);
92
93 /// Go to a specific page type
94 fn goto(&mut self, id: ViewId, page_type: PageType);
95 /// Refresh specific view
96 fn refresh(&mut self, id: ViewId);
97 /// Moves forward on view
98 fn go_forward(&mut self, id: ViewId);
99 /// Moves back on view
100 fn go_back(&mut self, id: ViewId);
101
102 /// Gets current url from view
103 fn get_url(&self, id: ViewId) -> String;
104 /// Gets current title from view
105 fn get_title(&self, id: ViewId) -> String;
106 /// Gets current cursor status from view
107 fn get_cursor(&self, id: ViewId) -> Interaction;
108 /// Gets CPU-rendered webview
109 fn get_view(&self, id: ViewId) -> &ImageInfo;
110
111 /// Current vertical scroll offset (logical pixels).
112 fn get_scroll_y(&self, _id: ViewId) -> f32 {
113 0.0
114 }
115
116 /// Total content height (logical pixels). Zero means the engine manages scrolling.
117 fn get_content_height(&self, _id: ViewId) -> f32 {
118 0.0
119 }
120
121 /// Gets the currently selected text from a view, if any.
122 fn get_selected_text(&self, _id: ViewId) -> Option<String> {
123 None
124 }
125
126 /// Selection highlight rectangles for overlay rendering.
127 /// Returns `[x, y, width, height]` in logical coordinates, scroll-adjusted.
128 fn get_selection_rects(&self, _id: ViewId) -> &[[f32; 4]] {
129 &[]
130 }
131
132 /// Take the last anchor click URL from a view, if any.
133 /// Called after mouse events to detect link navigation.
134 fn take_anchor_click(&mut self, _id: ViewId) -> Option<String> {
135 None
136 }
137
138 /// Scroll to a named fragment (e.g. `"section2"` for `#section2`).
139 /// Returns `true` if the fragment was found and the view scrolled.
140 fn scroll_to_fragment(&mut self, _id: ViewId, _fragment: &str) -> bool {
141 false
142 }
143
144 /// Return image URLs discovered during layout that still need fetching.
145 /// Each entry is `(view_id, raw_src, baseurl, redraw_on_ready)` — the
146 /// consumer resolves URLs against baseurl and threads `redraw_on_ready`
147 /// back through `load_image_from_bytes`.
148 fn take_pending_images(&mut self) -> Vec<(ViewId, String, String, bool)> {
149 Vec::new()
150 }
151
152 /// Pre-load a CSS cache into a view's container so `import_css` can
153 /// resolve stylesheets without network access during parsing.
154 fn set_css_cache(&mut self, _id: ViewId, _cache: HashMap<String, String>) {}
155
156 /// Inject fetched image bytes into a view's container, keyed by the
157 /// raw `src` value from the HTML. When `redraw_on_ready` is true, the
158 /// image doesn't affect layout (CSS background or `<img>` with explicit
159 /// dimensions) so `doc.render()` can be skipped — only a redraw is needed.
160 fn load_image_from_bytes(
161 &mut self,
162 _id: ViewId,
163 _url: &str,
164 _bytes: &[u8],
165 _redraw_on_ready: bool,
166 ) {
167 }
168
169 /// Flush all staged images into the document and redraw.
170 /// Called when all in-flight image fetches have completed so the
171 /// full batch is processed in a single redraw.
172 fn flush_staged_images(&mut self, _id: ViewId, _size: Size<u32>) {}
173
174 /// Return all active view IDs.
175 fn view_ids(&self) -> Vec<ViewId> {
176 Vec::new()
177 }
178}