mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
dom: Calculate the viewport size of iframes when they are first added to the tree.
This commit is contained in:
parent
38e4ae0833
commit
fd260f78c8
10 changed files with 72 additions and 11 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -4221,6 +4221,7 @@ dependencies = [
|
|||
"servo_atoms",
|
||||
"servo_url",
|
||||
"style",
|
||||
"style_traits",
|
||||
"webrender_api",
|
||||
]
|
||||
|
||||
|
|
|
@ -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<TypedSize2D<f32, CSSPixel>>,
|
||||
}
|
||||
|
||||
pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>);
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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<Size2D<f32, CSSPixel>>,
|
||||
}
|
||||
|
||||
pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>);
|
||||
|
@ -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>> {
|
||||
|
|
|
@ -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 => {},
|
||||
}
|
||||
|
|
|
@ -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 => {},
|
||||
}
|
||||
|
|
|
@ -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::<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));
|
||||
|
|
|
@ -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<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())) {
|
||||
|
@ -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",
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -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"]}
|
||||
|
|
|
@ -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<PseudoElement>, 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,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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<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>>);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue