···334334+ ScriptToConstellationMessage::EmbeddedWebViewSetPageZoom(embedded_webview_id, zoom) => {
335335+ // Validate this is a known embedded webview
336336+ let ctx_id = BrowsingContextId::from(embedded_webview_id);
337337-+ if self.browsing_contexts.get(&ctx_id).is_none() {
337337++ if !self.browsing_contexts.contains_key(&ctx_id) {
338338+ return warn!(
339339+ "EmbeddedWebViewSetPageZoom for unknown browsing context {:?}",
340340+ embedded_webview_id
···6464 /// Returns the [`PipelineDetails`] for the given [`PipelineId`], creating it if needed.
6565 pub(crate) fn ensure_pipeline_details(
6666 &mut self,
6767-@@ -364,10 +391,9 @@
6767+@@ -359,16 +386,14 @@
6868+ .map(|point| point.as_device_point(self.device_pixels_per_page_pixel()));
6969+ let hit_test_result = match event_point {
7070+ Some(point) => {
7171+- let hit_test_result = match event.event {
7272++ // Even if WebRender hit test returns empty, we still send the event to
7373++ // the script thread for DOM hit testing. The script thread will use the
7474++ // original event point for DOM hit testing when hit_test_result is None.
7575++ match event.event {
7676+ InputEvent::Touch(_) => self.touch_handler.get_hit_test_result_cache_value(),
6877 _ => None,
6978 }
7070- .or_else(|| self.hit_test(render_api, point).into_iter().nth(0));
7979+- .or_else(|| self.hit_test(render_api, point).into_iter().nth(0));
7180- if hit_test_result.is_none() {
7281- warn!("Empty hit test result for input event, ignoring.");
7382- return false;
7483- }
7575-+ // Even if WebRender hit test returns empty, we still send the event to
7676-+ // the script thread for DOM hit testing. The script thread will use the
7777-+ // original event point for DOM hit testing when hit_test_result is None.
7878- hit_test_result
8484+- hit_test_result
8585++ .or_else(|| self.hit_test(render_api, point).into_iter().nth(0))
7986 },
8087 None => None,
8181-@@ -699,6 +725,88 @@
8888+ };
8989+@@ -699,6 +724,88 @@
8290 self.on_scroll_window_event(scroll, point);
8391 }
8492···167175 fn on_scroll_window_event(&mut self, scroll: Scroll, cursor: DevicePoint) {
168176 self.pending_scroll_zoom_events
169177 .push(ScrollZoomEvent::Scroll(ScrollEvent {
170170-@@ -708,18 +816,25 @@
178178+@@ -708,18 +815,25 @@
171179 }));
172180 }
173181···198206 }
199207200208 // Batch up all scroll events and changes to pinch zoom into a single change, or
201201-@@ -773,15 +888,24 @@
209209+@@ -773,15 +887,24 @@
202210 }
203211 }
204212···229237230238 let scroll_result = combined_scroll_event.and_then(|combined_event| {
231239 self.scroll_node_at_device_point(
232232-@@ -790,6 +914,21 @@
240240+@@ -790,6 +913,21 @@
233241 combined_event.scroll,
234242 )
235243 });
···251259 if let Some(ref scroll_result) = scroll_result {
252260 self.send_scroll_positions_to_layout_for_pipeline(
253261 scroll_result.hit_test_result.pipeline_id,
254254-@@ -805,7 +944,11 @@
262262+@@ -805,7 +943,11 @@
255263 self.send_pinch_zoom_infos_to_script();
256264 }
257265···264272 }
265273266274 /// Perform a hit test at the given [`DevicePoint`] and apply the [`Scroll`]
267267-@@ -812,7 +955,7 @@
275275+@@ -812,7 +954,7 @@
268276 /// scrolling to the applicable scroll node under that point. If a scroll was
269277 /// performed, returns the hit test result contains [`PipelineId`] of the node
270278 /// scrolled, the id, and the final scroll delta.
···273281 &mut self,
274282 render_api: &RenderApi,
275283 cursor: DevicePoint,
276276-@@ -840,7 +983,10 @@
284284+@@ -840,7 +982,10 @@
277285 // its ancestor pipelines.
278286 let mut previous_pipeline_id = None;
279287 for hit_test_result in hit_test_results {
···285293 if previous_pipeline_id.replace(hit_test_result.pipeline_id) !=
286294 Some(hit_test_result.pipeline_id)
287295 {
288288-@@ -867,7 +1013,11 @@
296296+@@ -867,7 +1012,11 @@
289297 }
290298 }
291299 }
···298306 }
299307300308 /// Scroll the viewport (root pipeline, root scroll node) of this WebView, but first
301301-@@ -1006,20 +1156,45 @@
309309+@@ -1006,20 +1155,45 @@
302310 }
303311304312 fn send_window_size_message(&self) {
···356364 }
357365358366 /// Set the `hidpi_scale_factor` for this renderer, returning `true` if the value actually changed.
359359-@@ -1085,8 +1260,21 @@
367367+@@ -1085,8 +1259,21 @@
360368 if let Some(wheel_event) = self.pending_wheel_events.remove(&id) {
361369 if !result.contains(InputEventResult::DefaultPrevented) {
362370 // A scroll delta for a wheel event is the inverse of the wheel delta.
···182182+
183183+ // Convert iframe position from document coords to viewport coords by subtracting scroll offset.
184184+ let scroll_offset = self.window.scroll_offset();
185185-+ let iframe_viewport_x = iframe_border_box.origin.x.to_f32_px() - scroll_offset.x as f32;
186186-+ let iframe_viewport_y = iframe_border_box.origin.y.to_f32_px() - scroll_offset.y as f32;
185185++ let iframe_viewport_x = iframe_border_box.origin.x.to_f32_px() - scroll_offset.x;
186186++ let iframe_viewport_y = iframe_border_box.origin.y.to_f32_px() - scroll_offset.y;
187187+
188188+ // Get device pixel ratio for converting between CSS and device pixels
189189+ let device_pixel_ratio = self.window.device_pixel_ratio().get();
···300300+
301301+ // Convert iframe position from document coords to viewport coords
302302+ let scroll_offset = self.window.scroll_offset();
303303-+ let iframe_viewport_x = iframe_border_box.origin.x.to_f32_px() - scroll_offset.x as f32;
304304-+ let iframe_viewport_y = iframe_border_box.origin.y.to_f32_px() - scroll_offset.y as f32;
303303++ let iframe_viewport_x = iframe_border_box.origin.x.to_f32_px() - scroll_offset.x;
304304++ let iframe_viewport_y = iframe_border_box.origin.y.to_f32_px() - scroll_offset.y;
305305+
306306+ // Get device pixel ratio for coordinate conversion
307307+ let device_pixel_ratio = self.window.device_pixel_ratio().get();