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