feat(servo): upgrade to latest secure upstream snapshot
This commit is contained in:
@@ -47,9 +47,6 @@ pub struct SoftwareServoHost {
|
||||
default_surface_size: ServoSurfaceSize,
|
||||
rendering_context_kind: RenderingContextKind,
|
||||
webviews: HashMap<WebViewId, HostWebView>,
|
||||
// Servo 0.1.0 can still run script tasks after a remote page moves away.
|
||||
// Retain hidden about:blank WebViews until host shutdown releases them together.
|
||||
retired_webviews: Vec<HostWebView>,
|
||||
permissions: PermissionStore,
|
||||
wake_requested: Arc<AtomicBool>,
|
||||
last_rendered_frame: Option<RenderedFrame>,
|
||||
@@ -112,27 +109,7 @@ impl SoftwareServoHost {
|
||||
}
|
||||
|
||||
pub fn close_webview(&mut self, webview_id: &WebViewId) -> bool {
|
||||
let Some(webview) = self.webviews.remove(webview_id) else {
|
||||
return false;
|
||||
};
|
||||
self.retire_webview(webview);
|
||||
true
|
||||
}
|
||||
|
||||
fn retire_webview(&mut self, webview: HostWebView) {
|
||||
webview.webview.hide();
|
||||
if let Ok(blank_url) = Url::parse("about:blank") {
|
||||
webview.webview.load(blank_url);
|
||||
}
|
||||
for _ in 0..32 {
|
||||
self.servo.spin_event_loop();
|
||||
if webview.current_url().as_deref() == Some("about:blank")
|
||||
&& matches!(webview.state(), WebViewState::Complete)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.retired_webviews.push(webview);
|
||||
self.webviews.remove(webview_id).is_some()
|
||||
}
|
||||
|
||||
fn new_started(
|
||||
@@ -155,7 +132,6 @@ impl SoftwareServoHost {
|
||||
default_surface_size: size,
|
||||
rendering_context_kind,
|
||||
webviews: HashMap::new(),
|
||||
retired_webviews: Vec::new(),
|
||||
permissions: Rc::new(RefCell::new(HashMap::new())),
|
||||
wake_requested,
|
||||
last_rendered_frame: None,
|
||||
@@ -399,11 +375,7 @@ impl ServoHost for SoftwareServoHost {
|
||||
|
||||
impl Drop for SoftwareServoHost {
|
||||
fn drop(&mut self) {
|
||||
let webviews = std::mem::take(&mut self.webviews);
|
||||
for webview in webviews.into_values() {
|
||||
self.retire_webview(webview);
|
||||
}
|
||||
self.retired_webviews.clear();
|
||||
self.webviews.clear();
|
||||
self.drain_after_webview_close();
|
||||
SERVO_RUNTIME_STARTED.store(false, Ordering::Release);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use servo::{
|
||||
DevicePoint, InputEvent, KeyState, KeyboardEvent, Location, Modifiers, MouseButton,
|
||||
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, TouchEvent, TouchEventType, TouchId,
|
||||
WebView, WebViewPoint,
|
||||
TouchPointerType, WebView, WebViewPoint,
|
||||
};
|
||||
|
||||
use crate::keyboard::key_and_code_for_character;
|
||||
@@ -30,7 +30,12 @@ pub(super) fn send_touch_tap(webview: &WebView, x: u32, y: u32) {
|
||||
let point = point(x, y);
|
||||
let touch_id = TouchId(1);
|
||||
for event_type in [TouchEventType::Down, TouchEventType::Up] {
|
||||
webview.notify_input_event(InputEvent::Touch(TouchEvent::new(event_type, touch_id, point)));
|
||||
webview.notify_input_event(InputEvent::Touch(TouchEvent::new(
|
||||
event_type,
|
||||
touch_id,
|
||||
point,
|
||||
TouchPointerType::Touch,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,11 +75,13 @@ fn site_permission_feature_for_servo(
|
||||
servo::PermissionFeature::PersistentStorage => {
|
||||
Some(SitePermissionFeature::StoragePersistence)
|
||||
}
|
||||
servo::PermissionFeature::Push
|
||||
servo::PermissionFeature::ScreenWakeLock(_)
|
||||
| servo::PermissionFeature::Push
|
||||
| servo::PermissionFeature::Midi
|
||||
| servo::PermissionFeature::Speaker
|
||||
| servo::PermissionFeature::DeviceInfo
|
||||
| servo::PermissionFeature::BackgroundSync
|
||||
| servo::PermissionFeature::Gamepad
|
||||
| servo::PermissionFeature::Bluetooth => None,
|
||||
}
|
||||
}
|
||||
@@ -90,7 +92,20 @@ mod tests {
|
||||
|
||||
use crate::{PermissionDecision, PermissionRequest};
|
||||
|
||||
use super::{PermissionStore, set_permission_decision, take_permission_decision};
|
||||
use super::{
|
||||
PermissionStore, set_permission_decision, site_permission_feature_for_servo,
|
||||
take_permission_decision,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn keeps_disabled_servo_permissions_out_of_site_settings() {
|
||||
for feature in [
|
||||
servo::PermissionFeature::ScreenWakeLock(servo::WakeLockType::Screen),
|
||||
servo::PermissionFeature::Gamepad,
|
||||
] {
|
||||
assert_eq!(site_permission_feature_for_servo(feature), None);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_once_is_consumed_after_one_matching_origin_request()
|
||||
|
||||
@@ -28,7 +28,7 @@ const SOFTWARE_HOST_CHILD_ENV: &str = "ELY_SERVO_SOFTWARE_HOST_CHILD";
|
||||
const DPR_VIEWPORT_CHILD_ENV: &str = "ELY_SERVO_DPR_VIEWPORT_CHILD";
|
||||
const CLICK_PROBE_URL: &str = "data:text/html,%3C!doctype%20html%3E%3Ctitle%3EClick%20Probe%3C%2Ftitle%3E%3Cstyle%3Ebody%7Bmargin%3A0%3Bbackground%3A%23f7f7f7%3B%7Dbutton%7Bposition%3Aabsolute%3Bleft%3A80px%3Btop%3A80px%3Bwidth%3A220px%3Bheight%3A90px%3Bfont%3A28px%20sans-serif%3Bbackground%3A%23ffffff%3Bcolor%3A%23111111%3B%7D%3C%2Fstyle%3E%3Cbutton%20onclick%3D%22document.body.style.background%3D%27%230039ff%27%3Bdocument.title%3D%27Clicked%27%3Bthis.textContent%3D%27Clicked%27%3B%22%3ETap%3C%2Fbutton%3E";
|
||||
const DRAG_PROBE_URL: &str = "data:text/html,%3C%21doctype%20html%3E%3Ctitle%3EDrag%20Probe%3C%2Ftitle%3E%3Cstyle%3Ebody%7Bmargin%3A0%3Bbackground%3A%23f7f7f7%3B%7Dbutton%7Bposition%3Aabsolute%3Bleft%3A80px%3Btop%3A80px%3Bwidth%3A220px%3Bheight%3A90px%3Bfont%3A28px%20sans-serif%3Bbackground%3A%23ffffff%3Bcolor%3A%23111111%3B%7D%3C%2Fstyle%3E%3Cbutton%20id%3Dbox%3EDrag%3C%2Fbutton%3E%3Cscript%3Elet%20dragging%3Dfalse%3Bconst%20box%3Ddocument.getElementById%28%27box%27%29%3BaddEventListener%28%27mousedown%27%2Cevent%3D%3E%7Bif%28event.target%3D%3D%3Dbox%29%7Bdragging%3Dtrue%3B%7D%7D%29%3BaddEventListener%28%27mousemove%27%2Cevent%3D%3E%7Bif%28dragging%26%26event.clientX%3E280%29%7Bdocument.body.style.background%3D%27%230039ff%27%3Bdocument.title%3D%27Dragged%27%3Bbox.textContent%3D%27Dragged%27%3B%7D%7D%29%3BaddEventListener%28%27mouseup%27%2C%28%29%3D%3E%7Bdragging%3Dfalse%3B%7D%29%3B%3C%2Fscript%3E";
|
||||
const TOUCH_PROBE_URL: &str = "data:text/html,%3C%21doctype%20html%3E%3Ctitle%3ETouch%20Probe%3C%2Ftitle%3E%3Cstyle%3Ebody%7Bmargin%3A0%3Bbackground%3A%23f7f7f7%3B%7Dbutton%7Bposition%3Aabsolute%3Bleft%3A80px%3Btop%3A80px%3Bwidth%3A220px%3Bheight%3A90px%3Bfont%3A28px%20sans-serif%3Bbackground%3A%23ffffff%3Bcolor%3A%23111111%3Btouch-action%3Amanipulation%3B%7D%3C%2Fstyle%3E%3Cbutton%20ontouchstart%3D%22document.body.dataset.touch%3D%27start%27%3B%22%20onclick%3D%22document.body.style.background%3D%27%230039ff%27%3Bdocument.title%3D%27Touched%27%3Bthis.textContent%3D%27Touched%27%3B%22%3ETap%3C%2Fbutton%3E";
|
||||
const TOUCH_PROBE_URL: &str = "data:text/html,%3C%21doctype%20html%3E%3Ctitle%3ETouch%20Probe%3C%2Ftitle%3E%3Cstyle%3Ebody%7Bmargin%3A0%3Bbackground%3A%23f7f7f7%3B%7Dbutton%7Bposition%3Aabsolute%3Bleft%3A80px%3Btop%3A80px%3Bwidth%3A220px%3Bheight%3A90px%3Bfont%3A28px%20sans-serif%3Bbackground%3A%23ffffff%3Bcolor%3A%23111111%3Btouch-action%3Amanipulation%3B%7D%3C%2Fstyle%3E%3Cbutton%20ontouchstart%3D%22document.body.dataset.touch%3D%27start%27%3B%22%20onpointerdown%3D%22if%28%21document.body.dataset.pointerType%29%7Bdocument.body.dataset.pointerType%3Devent.pointerType%3B%7D%22%20onclick%3D%22if%28document.body.dataset.pointerType%21%3D%3D%27touch%27%29%7Bdocument.title%3Ddocument.body.dataset.pointerType%3Breturn%3B%7Ddocument.body.style.background%3D%27%230039ff%27%3Bdocument.title%3D%27Touched%27%3Bthis.textContent%3D%27Touched%27%3B%22%3ETap%3C%2Fbutton%3E";
|
||||
const TEXT_PROBE_URL: &str = "data:text/html,%3C!doctype%20html%3E%3Ctitle%3EText%20Probe%3C%2Ftitle%3E%3Cstyle%3Ebody%7Bmargin%3A0%3Bbackground%3A%23f7f7f7%3Bfont%3A28px%20sans-serif%3B%7Dinput%7Bposition%3Aabsolute%3Bleft%3A80px%3Btop%3A80px%3Bwidth%3A260px%3Bheight%3A70px%3Bfont%3A28px%20sans-serif%3B%7Doutput%7Bposition%3Aabsolute%3Bleft%3A80px%3Btop%3A180px%3Bfont%3A32px%20sans-serif%3B%7D%3C%2Fstyle%3E%3Cinput%20id%3Dq%20autofocus%20oninput%3D%22document.body.style.background%3D%27%230039ff%27%3Bdocument.getElementById%28%27out%27%29.textContent%3Dthis.value%3B%22%3E%3Coutput%20id%3Dout%3Eempty%3C%2Foutput%3E";
|
||||
const TEXT_PROBE_VALUE: &str = "ely42";
|
||||
|
||||
@@ -294,6 +294,7 @@ fn exercise_real_servo_webview_lifecycle() -> Result<(), Box<dyn Error>> {
|
||||
host.touch_tap(TouchTapRequest { webview_id: webview_id.clone(), x: 160, y: 120 })?;
|
||||
let snapshot = wait_for_rendered_webview(&mut host, &webview_id, Some(previous_frame_hash))?;
|
||||
assert_eq!(snapshot.state(), &WebViewState::Complete, "snapshot: {snapshot:?}");
|
||||
assert_eq!(snapshot.title(), Some("Touched"), "snapshot: {snapshot:?}");
|
||||
assert_rendered_frame_has_content(&host, "data:text/html touched", 1)?;
|
||||
assert_ne!(host.last_rendered_frame()?.sample_hash(), previous_frame_hash);
|
||||
|
||||
@@ -368,6 +369,20 @@ fn exercise_real_servo_webview_lifecycle() -> Result<(), Box<dyn Error>> {
|
||||
)?;
|
||||
assert_ne!(host.last_rendered_frame()?.sample_hash(), previous_frame_hash);
|
||||
|
||||
assert!(host.close_webview(&webview_id));
|
||||
assert!(!host.close_webview(&webview_id));
|
||||
assert!(matches!(host.snapshot(&webview_id), Err(ServoHostError::WebViewNotFound { .. })));
|
||||
|
||||
let replacement_tab_id = TabId::new();
|
||||
let replacement_id = host.create_webview(replacement_tab_id.clone(), profile_id)?;
|
||||
host.navigate(NavigationRequest {
|
||||
webview_id: replacement_id.clone(),
|
||||
tab_id: replacement_tab_id,
|
||||
url: UrlText::parse(CLICK_PROBE_URL)?,
|
||||
})?;
|
||||
let replacement = wait_for_rendered_webview(&mut host, &replacement_id, None)?;
|
||||
assert_eq!(replacement.state(), &WebViewState::Complete, "replacement: {replacement:?}");
|
||||
|
||||
assert!(matches!(
|
||||
SoftwareServoHost::new(ServoSurfaceSize::new(INITIAL_WIDTH, INITIAL_HEIGHT)),
|
||||
Err(ServoHostError::RuntimeAlreadyStarted)
|
||||
|
||||
Reference in New Issue
Block a user