Add Servo page zoom support
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
path::PathBuf,
|
||||
rc::Rc,
|
||||
@@ -14,21 +14,19 @@ use std::{
|
||||
use dpi::PhysicalSize;
|
||||
use ely_domain::{ProfileId, TabId, WebViewId};
|
||||
use servo::{
|
||||
DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, DeviceVector2D, LoadStatus, Opts,
|
||||
RenderingContext, Scroll, Servo, ServoBuilder, WebView, WebViewBuilder, WebViewDelegate,
|
||||
WebViewPoint, WebViewVector,
|
||||
DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, DeviceVector2D, Opts,
|
||||
RenderingContext, Scroll, Servo, ServoBuilder, WebViewBuilder, WebViewPoint, WebViewVector,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
KeyboardTextRequest, MouseClickRequest, MouseDragRequest, NavigationRequest,
|
||||
KeyboardTextRequest, MouseClickRequest, MouseDragRequest, NavigationRequest, PageZoomRequest,
|
||||
PermissionDecision, PermissionRequest, RenderedFrame, ResizeRequest, ScreenshotRequest,
|
||||
ScrollRequest, ServoHost, ServoHostError, TouchTapRequest, WebViewSnapshot, WebViewState,
|
||||
runtime_input::{send_keyboard_text, send_mouse_click, send_mouse_drag, send_touch_tap},
|
||||
runtime_permissions::{
|
||||
PermissionStore, permission_decision_for_webview, set_permission_decision,
|
||||
},
|
||||
runtime_permissions::{PermissionStore, set_permission_decision},
|
||||
runtime_waker::ServoWakeFlag,
|
||||
runtime_webview::{HostWebView, HostWebViewDelegate},
|
||||
};
|
||||
|
||||
static SERVO_RUNTIME_STARTED: AtomicBool = AtomicBool::new(false);
|
||||
@@ -194,6 +192,16 @@ impl ServoHost for SoftwareServoHost {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_page_zoom(&mut self, request: PageZoomRequest) -> Result<(), ServoHostError> {
|
||||
let webview = self
|
||||
.webviews
|
||||
.get(&request.webview_id)
|
||||
.ok_or_else(|| ServoHostError::WebViewNotFound { id: request.webview_id.clone() })?;
|
||||
|
||||
webview.webview.set_page_zoom(request.zoom_factor);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn click(&mut self, request: MouseClickRequest) -> Result<(), ServoHostError> {
|
||||
let webview = self
|
||||
.webviews
|
||||
@@ -356,141 +364,3 @@ impl SoftwareServoHost {
|
||||
Ok(RenderedFrame::from_rgba_bytes(size.width, size.height, image.into_raw()))
|
||||
}
|
||||
}
|
||||
|
||||
struct HostWebView {
|
||||
tab_id: TabId,
|
||||
profile_id: ProfileId,
|
||||
webview: WebView,
|
||||
delegate: Rc<HostWebViewDelegate>,
|
||||
requested_url: Option<String>,
|
||||
}
|
||||
|
||||
impl HostWebView {
|
||||
fn snapshot(&self, webview_id: &WebViewId) -> WebViewSnapshot {
|
||||
WebViewSnapshot::new(
|
||||
webview_id.clone(),
|
||||
self.tab_id.clone(),
|
||||
self.profile_id.clone(),
|
||||
self.state(),
|
||||
self.current_url(),
|
||||
self.current_title(),
|
||||
self.delegate.has_pending_frame(),
|
||||
)
|
||||
}
|
||||
|
||||
fn state(&self) -> WebViewState {
|
||||
let state = self.delegate.state();
|
||||
if matches!(state, WebViewState::Crashed | WebViewState::Sleeping) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if let Some(requested_url) = &self.requested_url
|
||||
&& self.current_url().as_deref() != Some(requested_url.as_str())
|
||||
{
|
||||
return WebViewState::Loading;
|
||||
}
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
fn current_url(&self) -> Option<String> {
|
||||
self.webview.url().map(|url| url.to_string()).or_else(|| self.delegate.url())
|
||||
}
|
||||
|
||||
fn current_title(&self) -> Option<String> {
|
||||
self.webview.page_title().or_else(|| self.delegate.title())
|
||||
}
|
||||
}
|
||||
|
||||
struct HostWebViewDelegate {
|
||||
profile_id: ProfileId,
|
||||
permissions: PermissionStore,
|
||||
state: RefCell<WebViewState>,
|
||||
url: RefCell<Option<String>>,
|
||||
title: RefCell<Option<String>>,
|
||||
has_pending_frame: Cell<bool>,
|
||||
}
|
||||
|
||||
impl HostWebViewDelegate {
|
||||
fn new(profile_id: ProfileId, permissions: PermissionStore) -> Self {
|
||||
Self {
|
||||
profile_id,
|
||||
permissions,
|
||||
state: RefCell::new(WebViewState::Created),
|
||||
url: RefCell::new(None),
|
||||
title: RefCell::new(None),
|
||||
has_pending_frame: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_state(&self, state: WebViewState) {
|
||||
self.state.replace(state);
|
||||
}
|
||||
|
||||
fn state(&self) -> WebViewState {
|
||||
self.state.borrow().clone()
|
||||
}
|
||||
|
||||
fn url(&self) -> Option<String> {
|
||||
self.url.borrow().clone()
|
||||
}
|
||||
|
||||
fn title(&self) -> Option<String> {
|
||||
self.title.borrow().clone()
|
||||
}
|
||||
|
||||
fn has_pending_frame(&self) -> bool {
|
||||
self.has_pending_frame.get()
|
||||
}
|
||||
|
||||
fn mark_frame_presented(&self) {
|
||||
self.has_pending_frame.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
impl WebViewDelegate for HostWebViewDelegate {
|
||||
fn notify_url_changed(&self, _webview: WebView, url: Url) {
|
||||
self.url.replace(Some(url.to_string()));
|
||||
}
|
||||
|
||||
fn notify_page_title_changed(&self, _webview: WebView, title: Option<String>) {
|
||||
self.title.replace(title);
|
||||
}
|
||||
|
||||
fn notify_load_status_changed(&self, _webview: WebView, status: LoadStatus) {
|
||||
let state = match status {
|
||||
LoadStatus::Started | LoadStatus::HeadParsed => WebViewState::Loading,
|
||||
LoadStatus::Complete => WebViewState::Complete,
|
||||
};
|
||||
self.set_state(state);
|
||||
}
|
||||
|
||||
fn notify_new_frame_ready(&self, _webview: WebView) {
|
||||
self.has_pending_frame.set(true);
|
||||
}
|
||||
|
||||
fn notify_crashed(&self, _webview: WebView, _reason: String, _backtrace: Option<String>) {
|
||||
self.set_state(WebViewState::Crashed);
|
||||
}
|
||||
|
||||
fn request_navigation(&self, _webview: WebView, navigation_request: servo::NavigationRequest) {
|
||||
navigation_request.allow();
|
||||
}
|
||||
|
||||
fn request_permission(&self, webview: WebView, permission_request: servo::PermissionRequest) {
|
||||
match permission_decision_for_webview(
|
||||
&self.permissions,
|
||||
&self.profile_id,
|
||||
&webview,
|
||||
self.url(),
|
||||
permission_request.feature(),
|
||||
) {
|
||||
Some(PermissionDecision::AllowOnce | PermissionDecision::AllowAlways) => {
|
||||
permission_request.allow();
|
||||
}
|
||||
Some(PermissionDecision::DenyAlways) | None => {
|
||||
permission_request.deny();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user