mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +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_atoms",
|
||||||
"servo_url",
|
"servo_url",
|
||||||
"style",
|
"style",
|
||||||
|
"style_traits",
|
||||||
"webrender_api",
|
"webrender_api",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ use crate::sequential;
|
||||||
use crate::wrapper::LayoutNodeLayoutData;
|
use crate::wrapper::LayoutNodeLayoutData;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::default::{Point2D, Rect, Size2D, Vector2D};
|
use euclid::default::{Point2D, Rect, Size2D, Vector2D};
|
||||||
|
use euclid::Size2D as TypedSize2D;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use script_layout_interface::rpc::TextIndexResponse;
|
use script_layout_interface::rpc::TextIndexResponse;
|
||||||
|
@ -40,7 +41,7 @@ use style::dom::TElement;
|
||||||
use style::logical_geometry::{BlockFlowDirection, InlineBaseDirection, WritingMode};
|
use style::logical_geometry::{BlockFlowDirection, InlineBaseDirection, WritingMode};
|
||||||
use style::properties::{style_structs, LonghandId, PropertyDeclarationId, PropertyId};
|
use style::properties::{style_structs, LonghandId, PropertyDeclarationId, PropertyId};
|
||||||
use style::selector_parser::PseudoElement;
|
use style::selector_parser::PseudoElement;
|
||||||
use style_traits::ToCss;
|
use style_traits::{CSSPixel, ToCss};
|
||||||
use webrender_api::ExternalScrollId;
|
use webrender_api::ExternalScrollId;
|
||||||
|
|
||||||
/// Mutable data belonging to the LayoutThread.
|
/// Mutable data belonging to the LayoutThread.
|
||||||
|
@ -90,6 +91,9 @@ pub struct LayoutThreadData {
|
||||||
|
|
||||||
/// A queued response for the inner text of a given element.
|
/// A queued response for the inner text of a given element.
|
||||||
pub element_inner_text_response: String,
|
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>>);
|
pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>);
|
||||||
|
@ -193,6 +197,12 @@ impl LayoutRPC for LayoutRPCImpl {
|
||||||
let rw_data = rw_data.lock().unwrap();
|
let rw_data = rw_data.lock().unwrap();
|
||||||
rw_data.element_inner_text_response.clone()
|
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 {
|
struct UnioningFragmentBorderBoxIterator {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::default::{Point2D, Rect};
|
use euclid::default::{Point2D, Rect};
|
||||||
|
use euclid::Size2D;
|
||||||
use euclid::Vector2D;
|
use euclid::Vector2D;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
|
@ -22,6 +23,7 @@ use std::sync::{Arc, Mutex};
|
||||||
use style::dom::OpaqueNode;
|
use style::dom::OpaqueNode;
|
||||||
use style::properties::PropertyId;
|
use style::properties::PropertyId;
|
||||||
use style::selector_parser::PseudoElement;
|
use style::selector_parser::PseudoElement;
|
||||||
|
use style_traits::CSSPixel;
|
||||||
use webrender_api::units::LayoutPixel;
|
use webrender_api::units::LayoutPixel;
|
||||||
use webrender_api::ExternalScrollId;
|
use webrender_api::ExternalScrollId;
|
||||||
|
|
||||||
|
@ -70,6 +72,9 @@ pub struct LayoutThreadData {
|
||||||
|
|
||||||
/// A queued response for the inner text of a given element.
|
/// A queued response for the inner text of a given element.
|
||||||
pub element_inner_text_response: String,
|
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>>);
|
pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>);
|
||||||
|
@ -150,6 +155,12 @@ impl LayoutRPC for LayoutRPCImpl {
|
||||||
let rw_data = rw_data.lock().unwrap();
|
let rw_data = rw_data.lock().unwrap();
|
||||||
rw_data.element_inner_text_response.clone()
|
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>> {
|
pub fn process_content_box_request(_requested_node: OpaqueNode) -> Option<Rect<Au>> {
|
||||||
|
|
|
@ -609,6 +609,7 @@ impl LayoutThread {
|
||||||
text_index_response: TextIndexResponse(None),
|
text_index_response: TextIndexResponse(None),
|
||||||
nodes_from_point_response: vec![],
|
nodes_from_point_response: vec![],
|
||||||
element_inner_text_response: String::new(),
|
element_inner_text_response: String::new(),
|
||||||
|
inner_window_dimensions_response: None,
|
||||||
})),
|
})),
|
||||||
webrender_image_cache: Arc::new(RwLock::new(FnvHashMap::default())),
|
webrender_image_cache: Arc::new(RwLock::new(FnvHashMap::default())),
|
||||||
timer: if pref!(layout.animations.test.enabled) {
|
timer: if pref!(layout.animations.test.enabled) {
|
||||||
|
@ -1333,6 +1334,9 @@ impl LayoutThread {
|
||||||
&QueryMsg::ElementInnerTextQuery(_) => {
|
&QueryMsg::ElementInnerTextQuery(_) => {
|
||||||
rw_data.element_inner_text_response = String::new();
|
rw_data.element_inner_text_response = String::new();
|
||||||
},
|
},
|
||||||
|
&QueryMsg::InnerWindowDimensionsQuery(_) => {
|
||||||
|
rw_data.inner_window_dimensions_response = None;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ReflowGoal::Full | ReflowGoal::TickAnimations => {},
|
ReflowGoal::Full | ReflowGoal::TickAnimations => {},
|
||||||
}
|
}
|
||||||
|
@ -1685,6 +1689,13 @@ impl LayoutThread {
|
||||||
rw_data.element_inner_text_response =
|
rw_data.element_inner_text_response =
|
||||||
process_element_inner_text_query(node, &rw_data.indexable_text);
|
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 => {},
|
ReflowGoal::Full | ReflowGoal::TickAnimations => {},
|
||||||
}
|
}
|
||||||
|
|
|
@ -523,6 +523,7 @@ impl LayoutThread {
|
||||||
text_index_response: TextIndexResponse(None),
|
text_index_response: TextIndexResponse(None),
|
||||||
nodes_from_point_response: vec![],
|
nodes_from_point_response: vec![],
|
||||||
element_inner_text_response: String::new(),
|
element_inner_text_response: String::new(),
|
||||||
|
inner_window_dimensions_response: None,
|
||||||
})),
|
})),
|
||||||
timer: if pref!(layout.animations.test.enabled) {
|
timer: if pref!(layout.animations.test.enabled) {
|
||||||
Timer::test_mode()
|
Timer::test_mode()
|
||||||
|
@ -937,6 +938,9 @@ impl LayoutThread {
|
||||||
&QueryMsg::ElementInnerTextQuery(_) => {
|
&QueryMsg::ElementInnerTextQuery(_) => {
|
||||||
rw_data.element_inner_text_response = String::new();
|
rw_data.element_inner_text_response = String::new();
|
||||||
},
|
},
|
||||||
|
&QueryMsg::InnerWindowDimensionsQuery(_) => {
|
||||||
|
rw_data.inner_window_dimensions_response = None;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ReflowGoal::Full | ReflowGoal::TickAnimations => {},
|
ReflowGoal::Full | ReflowGoal::TickAnimations => {},
|
||||||
}
|
}
|
||||||
|
@ -1189,6 +1193,11 @@ impl LayoutThread {
|
||||||
let node = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
rw_data.element_inner_text_response = process_element_inner_text_query(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 => {},
|
ReflowGoal::Full | ReflowGoal::TickAnimations => {},
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ use crate::dom::windowproxy::WindowProxy;
|
||||||
use crate::script_thread::ScriptThread;
|
use crate::script_thread::ScriptThread;
|
||||||
use crate::task_source::TaskSource;
|
use crate::task_source::TaskSource;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use euclid::Size2D;
|
|
||||||
use html5ever::{LocalName, Prefix};
|
use html5ever::{LocalName, Prefix};
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId};
|
use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId};
|
||||||
|
@ -173,6 +172,13 @@ impl HTMLIFrameElement {
|
||||||
replace: replace,
|
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 {
|
match nav_type {
|
||||||
NavigationType::InitialAboutBlank => {
|
NavigationType::InitialAboutBlank => {
|
||||||
let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap();
|
let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap();
|
||||||
|
@ -198,13 +204,7 @@ impl HTMLIFrameElement {
|
||||||
opener: None,
|
opener: None,
|
||||||
load_data: load_data,
|
load_data: load_data,
|
||||||
pipeline_port: pipeline_receiver,
|
pipeline_port: pipeline_receiver,
|
||||||
window_size: WindowSizeData {
|
window_size,
|
||||||
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(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.pipeline_id.set(Some(new_pipeline_id));
|
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::wrappers::JS_DefineProperty;
|
||||||
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
|
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
|
||||||
use media::WindowGLContext;
|
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::{ImageCache, ImageResponder, ImageResponse};
|
||||||
use net_traits::image_cache::{PendingImageId, PendingImageResponse};
|
use net_traits::image_cache::{PendingImageId, PendingImageResponse};
|
||||||
use net_traits::storage_thread::StorageType;
|
use net_traits::storage_thread::StorageType;
|
||||||
|
@ -1829,6 +1829,16 @@ impl Window {
|
||||||
DOMString::from(resolved)
|
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)]
|
#[allow(unsafe_code)]
|
||||||
pub fn offset_parent_query(&self, node: &Node) -> (Option<DomRoot<Element>>, UntypedRect<Au>) {
|
pub fn offset_parent_query(&self, node: &Node) -> (Option<DomRoot<Element>>, UntypedRect<Au>) {
|
||||||
if !self.layout_reflow(QueryMsg::OffsetParentQuery(node.to_opaque())) {
|
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::StyleQuery(_n) => "\tStyleQuery",
|
||||||
&QueryMsg::TextIndexQuery(..) => "\tTextIndexQuery",
|
&QueryMsg::TextIndexQuery(..) => "\tTextIndexQuery",
|
||||||
&QueryMsg::ElementInnerTextQuery(_) => "\tElementInnerTextQuery",
|
&QueryMsg::ElementInnerTextQuery(_) => "\tElementInnerTextQuery",
|
||||||
|
&QueryMsg::InnerWindowDimensionsQuery(_) => "\tInnerWindowDimensionsQuery",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -33,4 +33,5 @@ servo_arc = {path = "../servo_arc"}
|
||||||
servo_atoms = {path = "../atoms"}
|
servo_atoms = {path = "../atoms"}
|
||||||
servo_url = {path = "../url"}
|
servo_url = {path = "../url"}
|
||||||
style = {path = "../style", features = ["servo"]}
|
style = {path = "../style", features = ["servo"]}
|
||||||
|
style_traits = {path = "../style_traits", features = ["servo"]}
|
||||||
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use euclid::default::{Point2D, Rect};
|
||||||
use gfx_traits::Epoch;
|
use gfx_traits::Epoch;
|
||||||
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||||
use metrics::PaintTimeMetrics;
|
use metrics::PaintTimeMetrics;
|
||||||
use msg::constellation_msg::{BackgroundHangMonitorRegister, PipelineId};
|
use msg::constellation_msg::{BackgroundHangMonitorRegister, BrowsingContextId, PipelineId};
|
||||||
use net_traits::image_cache::ImageCache;
|
use net_traits::image_cache::ImageCache;
|
||||||
use profile_traits::mem::ReportsChan;
|
use profile_traits::mem::ReportsChan;
|
||||||
use script_traits::Painter;
|
use script_traits::Painter;
|
||||||
|
@ -128,6 +128,7 @@ pub enum QueryMsg {
|
||||||
ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, PropertyId),
|
ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, PropertyId),
|
||||||
StyleQuery(TrustedNodeAddress),
|
StyleQuery(TrustedNodeAddress),
|
||||||
ElementInnerTextQuery(TrustedNodeAddress),
|
ElementInnerTextQuery(TrustedNodeAddress),
|
||||||
|
InnerWindowDimensionsQuery(BrowsingContextId),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any query to perform with this reflow.
|
/// Any query to perform with this reflow.
|
||||||
|
@ -147,6 +148,7 @@ impl ReflowGoal {
|
||||||
ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg {
|
ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg {
|
||||||
QueryMsg::NodesFromPointQuery(..) |
|
QueryMsg::NodesFromPointQuery(..) |
|
||||||
QueryMsg::TextIndexQuery(..) |
|
QueryMsg::TextIndexQuery(..) |
|
||||||
|
QueryMsg::InnerWindowDimensionsQuery(_) |
|
||||||
QueryMsg::ElementInnerTextQuery(_) => true,
|
QueryMsg::ElementInnerTextQuery(_) => true,
|
||||||
QueryMsg::ContentBoxQuery(_) |
|
QueryMsg::ContentBoxQuery(_) |
|
||||||
QueryMsg::ContentBoxesQuery(_) |
|
QueryMsg::ContentBoxesQuery(_) |
|
||||||
|
@ -176,6 +178,7 @@ impl ReflowGoal {
|
||||||
QueryMsg::NodeScrollIdQuery(_) |
|
QueryMsg::NodeScrollIdQuery(_) |
|
||||||
QueryMsg::ResolvedStyleQuery(..) |
|
QueryMsg::ResolvedStyleQuery(..) |
|
||||||
QueryMsg::OffsetParentQuery(_) |
|
QueryMsg::OffsetParentQuery(_) |
|
||||||
|
QueryMsg::InnerWindowDimensionsQuery(_) |
|
||||||
QueryMsg::StyleQuery(_) => false,
|
QueryMsg::StyleQuery(_) => false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::default::Rect;
|
use euclid::default::Rect;
|
||||||
|
use euclid::Size2D;
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
|
use style_traits::CSSPixel;
|
||||||
use webrender_api::ExternalScrollId;
|
use webrender_api::ExternalScrollId;
|
||||||
|
|
||||||
/// Synchronous messages that script can send to layout.
|
/// Synchronous messages that script can send to layout.
|
||||||
|
@ -39,6 +41,8 @@ pub trait LayoutRPC {
|
||||||
fn nodes_from_point_response(&self) -> Vec<UntrustedNodeAddress>;
|
fn nodes_from_point_response(&self) -> Vec<UntrustedNodeAddress>;
|
||||||
/// Query layout to get the inner text for a given element.
|
/// Query layout to get the inner text for a given element.
|
||||||
fn element_inner_text(&self) -> String;
|
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>>);
|
pub struct ContentBoxResponse(pub Option<Rect<Au>>);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue