Skip to content

Commit

Permalink
dom: Calculate the viewport size of iframes when they are first added…
Browse files Browse the repository at this point in the history
… to the tree.
  • Loading branch information
jdm committed Nov 6, 2019
1 parent 38e4ae0 commit fd260f7
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 11 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion components/layout/query.rs
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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<TypedSize2D<f32, CSSPixel>>,
}

pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>);
Expand Down Expand Up @@ -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<TypedSize2D<f32, CSSPixel>> {
let &LayoutRPCImpl(ref rw_data) = self;
let rw_data = rw_data.lock().unwrap();
rw_data.inner_window_dimensions_response.clone()
}
}

struct UnioningFragmentBorderBoxIterator {
Expand Down
11 changes: 11 additions & 0 deletions components/layout_2020/query.rs
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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<Size2D<f32, CSSPixel>>,
}

pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>);
Expand Down Expand Up @@ -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<Size2D<f32, CSSPixel>> {
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<Rect<Au>> {
Expand Down
11 changes: 11 additions & 0 deletions components/layout_thread/lib.rs
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 => {},
}
Expand Down Expand Up @@ -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 => {},
}
Expand Down
9 changes: 9 additions & 0 deletions components/layout_thread_2020/lib.rs
Expand Up @@ -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()
Expand Down Expand Up @@ -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 => {},
}
Expand Down Expand Up @@ -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 => {},
}
Expand Down
16 changes: 8 additions & 8 deletions components/script/dom/htmliframeelement.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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();
Expand All @@ -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::<Node>().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));
Expand Down
13 changes: 12 additions & 1 deletion components/script/dom/window.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -1829,6 +1829,16 @@ impl Window {
DOMString::from(resolved)
}

pub fn inner_window_dimensions_query(
&self,
browsing_context: BrowsingContextId,
) -> Option<Size2D<f32, CSSPixel>> {
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<DomRoot<Element>>, UntypedRect<Au>) {
if !self.layout_reflow(QueryMsg::OffsetParentQuery(node.to_opaque())) {
Expand Down Expand Up @@ -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",
},
});

Expand Down
1 change: 1 addition & 0 deletions components/script_layout_interface/Cargo.toml
Expand Up @@ -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"]}
5 changes: 4 additions & 1 deletion components/script_layout_interface/message.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -128,6 +128,7 @@ pub enum QueryMsg {
ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, PropertyId),
StyleQuery(TrustedNodeAddress),
ElementInnerTextQuery(TrustedNodeAddress),
InnerWindowDimensionsQuery(BrowsingContextId),
}

/// Any query to perform with this reflow.
Expand All @@ -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(_) |
Expand Down Expand Up @@ -176,6 +178,7 @@ impl ReflowGoal {
QueryMsg::NodeScrollIdQuery(_) |
QueryMsg::ResolvedStyleQuery(..) |
QueryMsg::OffsetParentQuery(_) |
QueryMsg::InnerWindowDimensionsQuery(_) |
QueryMsg::StyleQuery(_) => false,
},
}
Expand Down
4 changes: 4 additions & 0 deletions components/script_layout_interface/rpc.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -39,6 +41,8 @@ pub trait LayoutRPC {
fn nodes_from_point_response(&self) -> Vec<UntrustedNodeAddress>;
/// 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<Size2D<f32, CSSPixel>>;
}

pub struct ContentBoxResponse(pub Option<Rect<Au>>);
Expand Down

0 comments on commit fd260f7

Please sign in to comment.