From fd260f78c80a070727ba88d7b5f7cc40eb7efb5a Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 6 Nov 2019 15:55:11 -0500 Subject: [PATCH] dom: Calculate the viewport size of iframes when they are first added to the tree. --- Cargo.lock | 1 + components/layout/query.rs | 12 +++++++++++- components/layout_2020/query.rs | 11 +++++++++++ components/layout_thread/lib.rs | 11 +++++++++++ components/layout_thread_2020/lib.rs | 9 +++++++++ components/script/dom/htmliframeelement.rs | 16 ++++++++-------- components/script/dom/window.rs | 13 ++++++++++++- components/script_layout_interface/Cargo.toml | 1 + components/script_layout_interface/message.rs | 5 ++++- components/script_layout_interface/rpc.rs | 4 ++++ 10 files changed, 72 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02e09f392cb2..f94aed2aa5d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4221,6 +4221,7 @@ dependencies = [ "servo_atoms", "servo_url", "style", + "style_traits", "webrender_api", ] diff --git a/components/layout/query.rs b/components/layout/query.rs index 8dfd1bab795c..4850b75009cb 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -16,6 +16,7 @@ use crate::sequential; use crate::wrapper::LayoutNodeLayoutData; use app_units::Au; use euclid::default::{Point2D, Rect, Size2D, Vector2D}; +use euclid::Size2D as TypedSize2D; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; use script_layout_interface::rpc::TextIndexResponse; @@ -40,7 +41,7 @@ use style::dom::TElement; use style::logical_geometry::{BlockFlowDirection, InlineBaseDirection, WritingMode}; use style::properties::{style_structs, LonghandId, PropertyDeclarationId, PropertyId}; use style::selector_parser::PseudoElement; -use style_traits::ToCss; +use style_traits::{CSSPixel, ToCss}; use webrender_api::ExternalScrollId; /// Mutable data belonging to the LayoutThread. @@ -90,6 +91,9 @@ pub struct LayoutThreadData { /// A queued response for the inner text of a given element. pub element_inner_text_response: String, + + /// A queued response for the viewport dimensions for a given browsing context. + pub inner_window_dimensions_response: Option>, } pub struct LayoutRPCImpl(pub Arc>); @@ -193,6 +197,12 @@ impl LayoutRPC for LayoutRPCImpl { let rw_data = rw_data.lock().unwrap(); rw_data.element_inner_text_response.clone() } + + fn inner_window_dimensions(&self) -> Option> { + let &LayoutRPCImpl(ref rw_data) = self; + let rw_data = rw_data.lock().unwrap(); + rw_data.inner_window_dimensions_response.clone() + } } struct UnioningFragmentBorderBoxIterator { diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs index 23816521c707..1317759b33b3 100644 --- a/components/layout_2020/query.rs +++ b/components/layout_2020/query.rs @@ -7,6 +7,7 @@ use crate::context::LayoutContext; use app_units::Au; use euclid::default::{Point2D, Rect}; +use euclid::Size2D; use euclid::Vector2D; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; @@ -22,6 +23,7 @@ use std::sync::{Arc, Mutex}; use style::dom::OpaqueNode; use style::properties::PropertyId; use style::selector_parser::PseudoElement; +use style_traits::CSSPixel; use webrender_api::units::LayoutPixel; use webrender_api::ExternalScrollId; @@ -70,6 +72,9 @@ pub struct LayoutThreadData { /// A queued response for the inner text of a given element. pub element_inner_text_response: String, + + /// A queued response for the viewport dimensions for a given browsing context. + pub inner_window_dimensions_response: Option>, } pub struct LayoutRPCImpl(pub Arc>); @@ -150,6 +155,12 @@ impl LayoutRPC for LayoutRPCImpl { let rw_data = rw_data.lock().unwrap(); rw_data.element_inner_text_response.clone() } + + fn inner_window_dimensions(&self) -> Option> { + let &LayoutRPCImpl(ref rw_data) = self; + let rw_data = rw_data.lock().unwrap(); + rw_data.inner_window_dimensions_response.clone() + } } pub fn process_content_box_request(_requested_node: OpaqueNode) -> Option> { diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 84ace1c1efee..6c94c34e99b3 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -609,6 +609,7 @@ impl LayoutThread { text_index_response: TextIndexResponse(None), nodes_from_point_response: vec![], element_inner_text_response: String::new(), + inner_window_dimensions_response: None, })), webrender_image_cache: Arc::new(RwLock::new(FnvHashMap::default())), timer: if pref!(layout.animations.test.enabled) { @@ -1333,6 +1334,9 @@ impl LayoutThread { &QueryMsg::ElementInnerTextQuery(_) => { rw_data.element_inner_text_response = String::new(); }, + &QueryMsg::InnerWindowDimensionsQuery(_) => { + rw_data.inner_window_dimensions_response = None; + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } @@ -1685,6 +1689,13 @@ impl LayoutThread { rw_data.element_inner_text_response = process_element_inner_text_query(node, &rw_data.indexable_text); }, + &QueryMsg::InnerWindowDimensionsQuery(browsing_context_id) => { + rw_data.inner_window_dimensions_response = self + .last_iframe_sizes + .borrow() + .get(&browsing_context_id) + .cloned(); + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 13cf35975ee1..6ab5768ad023 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -523,6 +523,7 @@ impl LayoutThread { text_index_response: TextIndexResponse(None), nodes_from_point_response: vec![], element_inner_text_response: String::new(), + inner_window_dimensions_response: None, })), timer: if pref!(layout.animations.test.enabled) { Timer::test_mode() @@ -937,6 +938,9 @@ impl LayoutThread { &QueryMsg::ElementInnerTextQuery(_) => { rw_data.element_inner_text_response = String::new(); }, + &QueryMsg::InnerWindowDimensionsQuery(_) => { + rw_data.inner_window_dimensions_response = None; + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } @@ -1189,6 +1193,11 @@ impl LayoutThread { let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.element_inner_text_response = process_element_inner_text_query(node); }, + &QueryMsg::InnerWindowDimensionsQuery(_browsing_context_id) => { + // TODO(jdm): port the iframe sizing code from layout2013's display + // builder in order to support query iframe sizing. + rw_data.inner_window_dimensions_response = None; + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index f5a820458c21..41ac20cc2ed0 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -28,7 +28,6 @@ use crate::dom::windowproxy::WindowProxy; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use dom_struct::dom_struct; -use euclid::Size2D; use html5ever::{LocalName, Prefix}; use ipc_channel::ipc; use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId}; @@ -173,6 +172,13 @@ impl HTMLIFrameElement { replace: replace, }; + let window_size = WindowSizeData { + initial_viewport: window + .inner_window_dimensions_query(browsing_context_id) + .unwrap_or_default(), + device_pixel_ratio: window.device_pixel_ratio(), + }; + match nav_type { NavigationType::InitialAboutBlank => { let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap(); @@ -198,13 +204,7 @@ impl HTMLIFrameElement { opener: None, load_data: load_data, pipeline_port: pipeline_receiver, - window_size: WindowSizeData { - initial_viewport: { - let rect = self.upcast::().bounding_content_box_or_zero(); - Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()) - }, - device_pixel_ratio: window.device_pixel_ratio(), - }, + window_size, }; self.pipeline_id.set(Some(new_pipeline_id)); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 70099ee58660..95326b463524 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -89,7 +89,7 @@ use js::jsval::{JSVal, NullValue}; use js::rust::wrappers::JS_DefineProperty; use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue}; use media::WindowGLContext; -use msg::constellation_msg::PipelineId; +use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse}; use net_traits::image_cache::{PendingImageId, PendingImageResponse}; use net_traits::storage_thread::StorageType; @@ -1829,6 +1829,16 @@ impl Window { DOMString::from(resolved) } + pub fn inner_window_dimensions_query( + &self, + browsing_context: BrowsingContextId, + ) -> Option> { + if !self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery(browsing_context)) { + return None; + } + self.layout_rpc.inner_window_dimensions() + } + #[allow(unsafe_code)] pub fn offset_parent_query(&self, node: &Node) -> (Option>, UntypedRect) { if !self.layout_reflow(QueryMsg::OffsetParentQuery(node.to_opaque())) { @@ -2359,6 +2369,7 @@ fn debug_reflow_events(id: PipelineId, reflow_goal: &ReflowGoal, reason: &Reflow &QueryMsg::StyleQuery(_n) => "\tStyleQuery", &QueryMsg::TextIndexQuery(..) => "\tTextIndexQuery", &QueryMsg::ElementInnerTextQuery(_) => "\tElementInnerTextQuery", + &QueryMsg::InnerWindowDimensionsQuery(_) => "\tInnerWindowDimensionsQuery", }, }); diff --git a/components/script_layout_interface/Cargo.toml b/components/script_layout_interface/Cargo.toml index 8ad33fc7d43f..2e436761dc84 100644 --- a/components/script_layout_interface/Cargo.toml +++ b/components/script_layout_interface/Cargo.toml @@ -33,4 +33,5 @@ servo_arc = {path = "../servo_arc"} servo_atoms = {path = "../atoms"} servo_url = {path = "../url"} style = {path = "../style", features = ["servo"]} +style_traits = {path = "../style_traits", features = ["servo"]} webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs index 01a589d53cbe..66e0e446cfa0 100644 --- a/components/script_layout_interface/message.rs +++ b/components/script_layout_interface/message.rs @@ -10,7 +10,7 @@ use euclid::default::{Point2D, Rect}; use gfx_traits::Epoch; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use metrics::PaintTimeMetrics; -use msg::constellation_msg::{BackgroundHangMonitorRegister, PipelineId}; +use msg::constellation_msg::{BackgroundHangMonitorRegister, BrowsingContextId, PipelineId}; use net_traits::image_cache::ImageCache; use profile_traits::mem::ReportsChan; use script_traits::Painter; @@ -128,6 +128,7 @@ pub enum QueryMsg { ResolvedStyleQuery(TrustedNodeAddress, Option, PropertyId), StyleQuery(TrustedNodeAddress), ElementInnerTextQuery(TrustedNodeAddress), + InnerWindowDimensionsQuery(BrowsingContextId), } /// Any query to perform with this reflow. @@ -147,6 +148,7 @@ impl ReflowGoal { ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg { QueryMsg::NodesFromPointQuery(..) | QueryMsg::TextIndexQuery(..) | + QueryMsg::InnerWindowDimensionsQuery(_) | QueryMsg::ElementInnerTextQuery(_) => true, QueryMsg::ContentBoxQuery(_) | QueryMsg::ContentBoxesQuery(_) | @@ -176,6 +178,7 @@ impl ReflowGoal { QueryMsg::NodeScrollIdQuery(_) | QueryMsg::ResolvedStyleQuery(..) | QueryMsg::OffsetParentQuery(_) | + QueryMsg::InnerWindowDimensionsQuery(_) | QueryMsg::StyleQuery(_) => false, }, } diff --git a/components/script_layout_interface/rpc.rs b/components/script_layout_interface/rpc.rs index 95d25082ed88..19da8fa6afc0 100644 --- a/components/script_layout_interface/rpc.rs +++ b/components/script_layout_interface/rpc.rs @@ -4,9 +4,11 @@ use app_units::Au; use euclid::default::Rect; +use euclid::Size2D; use script_traits::UntrustedNodeAddress; use servo_arc::Arc; use style::properties::ComputedValues; +use style_traits::CSSPixel; use webrender_api::ExternalScrollId; /// Synchronous messages that script can send to layout. @@ -39,6 +41,8 @@ pub trait LayoutRPC { fn nodes_from_point_response(&self) -> Vec; /// Query layout to get the inner text for a given element. fn element_inner_text(&self) -> String; + /// Get the dimensions of an iframe's inner window. + fn inner_window_dimensions(&self) -> Option>; } pub struct ContentBoxResponse(pub Option>);