mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
script: Make layout DOM wrappers not generic on layout data (#31994)
Remove the type parameter from the layout DOM wrappers. This is possible now that style and layout data are separate and the `Any` nature of the layout data is exposed in the wrappers. Removing the phantom data member of the wrappers also allows using the default `derive` implementations for things like `Clone`, `Copy`, and `PartialEq`.
This commit is contained in:
parent
df457c43c8
commit
24c3a2df1e
6 changed files with 105 additions and 281 deletions
|
@ -48,7 +48,7 @@ use layout::traversal::{
|
||||||
RecalcStyleAndConstructFlows,
|
RecalcStyleAndConstructFlows,
|
||||||
};
|
};
|
||||||
use layout::wrapper::ThreadSafeLayoutNodeHelpers;
|
use layout::wrapper::ThreadSafeLayoutNodeHelpers;
|
||||||
use layout::{layout_debug, layout_debug_scope, parallel, sequential, LayoutData};
|
use layout::{layout_debug, layout_debug_scope, parallel, sequential};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::{debug, error, trace, warn};
|
use log::{debug, error, trace, warn};
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
@ -331,7 +331,7 @@ impl Layout for LayoutThread {
|
||||||
&self,
|
&self,
|
||||||
node: script_layout_interface::TrustedNodeAddress,
|
node: script_layout_interface::TrustedNodeAddress,
|
||||||
) -> String {
|
) -> String {
|
||||||
let node: ServoLayoutNode<LayoutData> = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
process_element_inner_text_query(node, &self.indexable_text.borrow())
|
process_element_inner_text_query(node, &self.indexable_text.borrow())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ impl Layout for LayoutThread {
|
||||||
animations: DocumentAnimationSet,
|
animations: DocumentAnimationSet,
|
||||||
animation_timeline_value: f64,
|
animation_timeline_value: f64,
|
||||||
) -> String {
|
) -> String {
|
||||||
let node: ServoLayoutNode<LayoutData> = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
let document = node.owner_doc();
|
let document = node.owner_doc();
|
||||||
let document_shared_lock = document.style_shared_lock();
|
let document_shared_lock = document.style_shared_lock();
|
||||||
let guards = StylesheetGuards {
|
let guards = StylesheetGuards {
|
||||||
|
@ -421,7 +421,7 @@ impl Layout for LayoutThread {
|
||||||
animations: DocumentAnimationSet,
|
animations: DocumentAnimationSet,
|
||||||
animation_timeline_value: f64,
|
animation_timeline_value: f64,
|
||||||
) -> Option<ServoArc<Font>> {
|
) -> Option<ServoArc<Font>> {
|
||||||
let node: ServoLayoutNode<LayoutData> = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
let document = node.owner_doc();
|
let document = node.owner_doc();
|
||||||
let document_shared_lock = document.style_shared_lock();
|
let document_shared_lock = document.style_shared_lock();
|
||||||
let guards = StylesheetGuards {
|
let guards = StylesheetGuards {
|
||||||
|
@ -450,7 +450,7 @@ impl Layout for LayoutThread {
|
||||||
&self,
|
&self,
|
||||||
node: script_layout_interface::TrustedNodeAddress,
|
node: script_layout_interface::TrustedNodeAddress,
|
||||||
) -> webrender_api::ExternalScrollId {
|
) -> webrender_api::ExternalScrollId {
|
||||||
let node: ServoLayoutNode<LayoutData> = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
process_node_scroll_id_request(self.id, node)
|
process_node_scroll_id_request(self.id, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,7 +877,7 @@ impl LayoutThread {
|
||||||
&self,
|
&self,
|
||||||
data: &Reflow,
|
data: &Reflow,
|
||||||
reflow_goal: &ReflowGoal,
|
reflow_goal: &ReflowGoal,
|
||||||
document: Option<&ServoLayoutDocument<LayoutData>>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
layout_root: &mut dyn Flow,
|
layout_root: &mut dyn Flow,
|
||||||
layout_context: &mut LayoutContext,
|
layout_context: &mut LayoutContext,
|
||||||
) {
|
) {
|
||||||
|
@ -1085,16 +1085,11 @@ impl LayoutThread {
|
||||||
let elements_with_snapshot: Vec<_> = restyles
|
let elements_with_snapshot: Vec<_> = restyles
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|r| r.1.snapshot.is_some())
|
.filter(|r| r.1.snapshot.is_some())
|
||||||
.map(|r| unsafe {
|
.map(|r| unsafe { ServoLayoutNode::new(&r.0).as_element().unwrap() })
|
||||||
ServoLayoutNode::<LayoutData>::new(&r.0)
|
|
||||||
.as_element()
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for (el, restyle) in restyles {
|
for (el, restyle) in restyles {
|
||||||
let el: ServoLayoutElement<LayoutData> =
|
let el = unsafe { ServoLayoutNode::new(&el).as_element().unwrap() };
|
||||||
unsafe { ServoLayoutNode::new(&el).as_element().unwrap() };
|
|
||||||
|
|
||||||
// If we haven't styled this node yet, we don't need to track a
|
// If we haven't styled this node yet, we don't need to track a
|
||||||
// restyle.
|
// restyle.
|
||||||
|
@ -1145,9 +1140,10 @@ impl LayoutThread {
|
||||||
|
|
||||||
let traversal = RecalcStyleAndConstructFlows::new(layout_context);
|
let traversal = RecalcStyleAndConstructFlows::new(layout_context);
|
||||||
let token = {
|
let token = {
|
||||||
let shared = <RecalcStyleAndConstructFlows as DomTraversal<
|
let shared =
|
||||||
ServoLayoutElement<LayoutData>,
|
<RecalcStyleAndConstructFlows as DomTraversal<ServoLayoutElement>>::shared_context(
|
||||||
>>::shared_context(&traversal);
|
&traversal,
|
||||||
|
);
|
||||||
RecalcStyleAndConstructFlows::pre_traverse(dirty_root, shared)
|
RecalcStyleAndConstructFlows::pre_traverse(dirty_root, shared)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1160,7 +1156,7 @@ impl LayoutThread {
|
||||||
|| {
|
|| {
|
||||||
// Perform CSS selector matching and flow construction.
|
// Perform CSS selector matching and flow construction.
|
||||||
let root = driver::traverse_dom::<
|
let root = driver::traverse_dom::<
|
||||||
ServoLayoutElement<LayoutData>,
|
ServoLayoutElement,
|
||||||
RecalcStyleAndConstructFlows,
|
RecalcStyleAndConstructFlows,
|
||||||
>(&traversal, token, thread_pool);
|
>(&traversal, token, thread_pool);
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -1310,7 +1306,7 @@ impl LayoutThread {
|
||||||
root_flow: &mut FlowRef,
|
root_flow: &mut FlowRef,
|
||||||
data: &Reflow,
|
data: &Reflow,
|
||||||
reflow_goal: &ReflowGoal,
|
reflow_goal: &ReflowGoal,
|
||||||
document: Option<&ServoLayoutDocument<LayoutData>>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
context: &mut LayoutContext,
|
context: &mut LayoutContext,
|
||||||
thread_pool: Option<&rayon::ThreadPool>,
|
thread_pool: Option<&rayon::ThreadPool>,
|
||||||
) {
|
) {
|
||||||
|
@ -1404,7 +1400,7 @@ impl LayoutThread {
|
||||||
data: &Reflow,
|
data: &Reflow,
|
||||||
mut root_flow: &mut FlowRef,
|
mut root_flow: &mut FlowRef,
|
||||||
reflow_goal: &ReflowGoal,
|
reflow_goal: &ReflowGoal,
|
||||||
document: Option<&ServoLayoutDocument<LayoutData>>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
layout_context: &mut LayoutContext,
|
layout_context: &mut LayoutContext,
|
||||||
) {
|
) {
|
||||||
// Build the display list if necessary, and send it to the painter.
|
// Build the display list if necessary, and send it to the painter.
|
||||||
|
|
|
@ -28,7 +28,6 @@ use ipc_channel::ipc::{self, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list::{DisplayList, WebRenderImageInfo};
|
use layout::display_list::{DisplayList, WebRenderImageInfo};
|
||||||
use layout::dom::DOMLayoutData;
|
|
||||||
use layout::query::{
|
use layout::query::{
|
||||||
process_content_box_request, process_content_boxes_request, process_element_inner_text_query,
|
process_content_box_request, process_content_boxes_request, process_element_inner_text_query,
|
||||||
process_node_geometry_request, process_node_scroll_area_request,
|
process_node_geometry_request, process_node_scroll_area_request,
|
||||||
|
@ -293,7 +292,7 @@ impl Layout for LayoutThread {
|
||||||
&self,
|
&self,
|
||||||
node: script_layout_interface::TrustedNodeAddress,
|
node: script_layout_interface::TrustedNodeAddress,
|
||||||
) -> String {
|
) -> String {
|
||||||
let node = unsafe { ServoLayoutNode::<DOMLayoutData>::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
process_element_inner_text_query(node)
|
process_element_inner_text_query(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +339,7 @@ impl Layout for LayoutThread {
|
||||||
animations: DocumentAnimationSet,
|
animations: DocumentAnimationSet,
|
||||||
animation_timeline_value: f64,
|
animation_timeline_value: f64,
|
||||||
) -> String {
|
) -> String {
|
||||||
let node: ServoLayoutNode<DOMLayoutData> = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
let document = node.owner_doc();
|
let document = node.owner_doc();
|
||||||
let document_shared_lock = document.style_shared_lock();
|
let document_shared_lock = document.style_shared_lock();
|
||||||
let guards = StylesheetGuards {
|
let guards = StylesheetGuards {
|
||||||
|
@ -374,7 +373,7 @@ impl Layout for LayoutThread {
|
||||||
animations: DocumentAnimationSet,
|
animations: DocumentAnimationSet,
|
||||||
animation_timeline_value: f64,
|
animation_timeline_value: f64,
|
||||||
) -> Option<ServoArc<Font>> {
|
) -> Option<ServoArc<Font>> {
|
||||||
let node: ServoLayoutNode<DOMLayoutData> = unsafe { ServoLayoutNode::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
let document = node.owner_doc();
|
let document = node.owner_doc();
|
||||||
let document_shared_lock = document.style_shared_lock();
|
let document_shared_lock = document.style_shared_lock();
|
||||||
let guards = StylesheetGuards {
|
let guards = StylesheetGuards {
|
||||||
|
@ -403,7 +402,7 @@ impl Layout for LayoutThread {
|
||||||
&self,
|
&self,
|
||||||
node: script_layout_interface::TrustedNodeAddress,
|
node: script_layout_interface::TrustedNodeAddress,
|
||||||
) -> ExternalScrollId {
|
) -> ExternalScrollId {
|
||||||
let node = unsafe { ServoLayoutNode::<DOMLayoutData>::new(&node) };
|
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||||
process_node_scroll_id_request(self.id, node)
|
process_node_scroll_id_request(self.id, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +661,7 @@ impl LayoutThread {
|
||||||
|
|
||||||
/// The high-level routine that performs layout.
|
/// The high-level routine that performs layout.
|
||||||
fn handle_reflow(&mut self, data: &mut ScriptReflowResult) {
|
fn handle_reflow(&mut self, data: &mut ScriptReflowResult) {
|
||||||
let document = unsafe { ServoLayoutNode::<DOMLayoutData>::new(&data.document) };
|
let document = unsafe { ServoLayoutNode::new(&data.document) };
|
||||||
let document = document.as_document().unwrap();
|
let document = document.as_document().unwrap();
|
||||||
let Some(root_element) = document.root_element() else {
|
let Some(root_element) = document.root_element() else {
|
||||||
debug!("layout: No root node: bailing");
|
debug!("layout: No root node: bailing");
|
||||||
|
@ -726,19 +725,11 @@ impl LayoutThread {
|
||||||
let elements_with_snapshot: Vec<_> = restyles
|
let elements_with_snapshot: Vec<_> = restyles
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|r| r.1.snapshot.is_some())
|
.filter(|r| r.1.snapshot.is_some())
|
||||||
.map(|r| unsafe {
|
.map(|r| unsafe { ServoLayoutNode::new(&r.0).as_element().unwrap() })
|
||||||
ServoLayoutNode::<DOMLayoutData>::new(&r.0)
|
|
||||||
.as_element()
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for (el, restyle) in restyles {
|
for (el, restyle) in restyles {
|
||||||
let el = unsafe {
|
let el = unsafe { ServoLayoutNode::new(&el).as_element().unwrap() };
|
||||||
ServoLayoutNode::<DOMLayoutData>::new(&el)
|
|
||||||
.as_element()
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we haven't styled this node yet, we don't need to track a
|
// If we haven't styled this node yet, we don't need to track a
|
||||||
// restyle.
|
// restyle.
|
||||||
|
@ -779,20 +770,19 @@ impl LayoutThread {
|
||||||
);
|
);
|
||||||
|
|
||||||
let dirty_root = unsafe {
|
let dirty_root = unsafe {
|
||||||
ServoLayoutNode::<DOMLayoutData>::new(&data.dirty_root.unwrap())
|
ServoLayoutNode::new(&data.dirty_root.unwrap())
|
||||||
.as_element()
|
.as_element()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let traversal = RecalcStyle::new(layout_context);
|
let traversal = RecalcStyle::new(layout_context);
|
||||||
let token = {
|
let token = {
|
||||||
let shared =
|
let shared = DomTraversal::<ServoLayoutElement>::shared_context(&traversal);
|
||||||
DomTraversal::<ServoLayoutElement<DOMLayoutData>>::shared_context(&traversal);
|
|
||||||
RecalcStyle::pre_traverse(dirty_root, shared)
|
RecalcStyle::pre_traverse(dirty_root, shared)
|
||||||
};
|
};
|
||||||
|
|
||||||
if token.should_traverse() {
|
if token.should_traverse() {
|
||||||
let dirty_root: ServoLayoutNode<DOMLayoutData> =
|
let dirty_root: ServoLayoutNode =
|
||||||
driver::traverse_dom(&traversal, token, rayon_pool).as_node();
|
driver::traverse_dom(&traversal, token, rayon_pool).as_node();
|
||||||
|
|
||||||
let root_node = root_element.as_node();
|
let root_node = root_element.as_node();
|
||||||
|
@ -908,7 +898,7 @@ impl LayoutThread {
|
||||||
&self,
|
&self,
|
||||||
fragment_tree: Arc<FragmentTree>,
|
fragment_tree: Arc<FragmentTree>,
|
||||||
reflow_goal: &ReflowGoal,
|
reflow_goal: &ReflowGoal,
|
||||||
document: Option<&ServoLayoutDocument<DOMLayoutData>>,
|
document: Option<&ServoLayoutDocument>,
|
||||||
context: &mut LayoutContext,
|
context: &mut LayoutContext,
|
||||||
) {
|
) {
|
||||||
Self::cancel_animations_for_nodes_not_in_fragment_tree(
|
Self::cancel_animations_for_nodes_not_in_fragment_tree(
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use script_layout_interface::wrapper_traits::LayoutDataTrait;
|
|
||||||
use selectors::matching::QuirksMode;
|
use selectors::matching::QuirksMode;
|
||||||
use style::dom::{TDocument, TNode};
|
use style::dom::{TDocument, TNode};
|
||||||
use style::shared_lock::{
|
use style::shared_lock::{
|
||||||
|
@ -18,25 +15,14 @@ use crate::dom::node::{LayoutNodeHelpers, Node, NodeFlags};
|
||||||
use crate::layout_dom::{ServoLayoutElement, ServoLayoutNode, ServoShadowRoot};
|
use crate::layout_dom::{ServoLayoutElement, ServoLayoutNode, ServoShadowRoot};
|
||||||
|
|
||||||
// A wrapper around documents that ensures ayout can only ever access safe properties.
|
// A wrapper around documents that ensures ayout can only ever access safe properties.
|
||||||
pub struct ServoLayoutDocument<'dom, LayoutDataType: LayoutDataTrait> {
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ServoLayoutDocument<'dom> {
|
||||||
/// The wrapped private DOM Document
|
/// The wrapped private DOM Document
|
||||||
document: LayoutDom<'dom, Document>,
|
document: LayoutDom<'dom, Document>,
|
||||||
|
|
||||||
/// A PhantomData that is used to track the type of the stored layout data.
|
|
||||||
phantom: PhantomData<LayoutDataType>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Clone for ServoLayoutDocument<'dom, LayoutDataType> {
|
impl<'ld> ::style::dom::TDocument for ServoLayoutDocument<'ld> {
|
||||||
fn clone(&self) -> Self {
|
type ConcreteNode = ServoLayoutNode<'ld>;
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Copy for ServoLayoutDocument<'dom, LayoutDataType> {}
|
|
||||||
|
|
||||||
impl<'ld, LayoutDataType: LayoutDataTrait> ::style::dom::TDocument
|
|
||||||
for ServoLayoutDocument<'ld, LayoutDataType>
|
|
||||||
{
|
|
||||||
type ConcreteNode = ServoLayoutNode<'ld, LayoutDataType>;
|
|
||||||
|
|
||||||
fn as_node(&self) -> Self::ConcreteNode {
|
fn as_node(&self) -> Self::ConcreteNode {
|
||||||
ServoLayoutNode::from_layout_js(self.document.upcast())
|
ServoLayoutNode::from_layout_js(self.document.upcast())
|
||||||
|
@ -55,8 +41,8 @@ impl<'ld, LayoutDataType: LayoutDataTrait> ::style::dom::TDocument
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ld, LayoutDataType: LayoutDataTrait> ServoLayoutDocument<'ld, LayoutDataType> {
|
impl<'ld> ServoLayoutDocument<'ld> {
|
||||||
pub fn root_element(&self) -> Option<ServoLayoutElement<'ld, LayoutDataType>> {
|
pub fn root_element(&self) -> Option<ServoLayoutElement<'ld>> {
|
||||||
self.as_node()
|
self.as_node()
|
||||||
.dom_children()
|
.dom_children()
|
||||||
.flat_map(|n| n.as_element())
|
.flat_map(|n| n.as_element())
|
||||||
|
@ -75,7 +61,7 @@ impl<'ld, LayoutDataType: LayoutDataTrait> ServoLayoutDocument<'ld, LayoutDataTy
|
||||||
self.document.style_shared_lock()
|
self.document.style_shared_lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shadow_roots(&self) -> Vec<ServoShadowRoot<LayoutDataType>> {
|
pub fn shadow_roots(&self) -> Vec<ServoShadowRoot> {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.document
|
self.document
|
||||||
.shadow_roots()
|
.shadow_roots()
|
||||||
|
@ -104,10 +90,7 @@ impl<'ld, LayoutDataType: LayoutDataTrait> ServoLayoutDocument<'ld, LayoutDataTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_layout_js(doc: LayoutDom<'ld, Document>) -> Self {
|
pub fn from_layout_js(document: LayoutDom<'ld, Document>) -> Self {
|
||||||
ServoLayoutDocument {
|
ServoLayoutDocument { document }
|
||||||
document: doc,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,13 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::Hash;
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use atomic_refcell::{AtomicRef, AtomicRefMut};
|
use atomic_refcell::{AtomicRef, AtomicRefMut};
|
||||||
use html5ever::{local_name, namespace_url, ns, LocalName, Namespace};
|
use html5ever::{local_name, namespace_url, ns, LocalName, Namespace};
|
||||||
use script_layout_interface::wrapper_traits::{
|
use script_layout_interface::wrapper_traits::{
|
||||||
LayoutDataTrait, LayoutNode, PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
|
LayoutNode, PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
|
||||||
};
|
};
|
||||||
use script_layout_interface::{LayoutNodeType, StyleData};
|
use script_layout_interface::{LayoutNodeType, StyleData};
|
||||||
use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
|
use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
|
||||||
|
@ -49,39 +48,13 @@ use crate::dom::node::{LayoutNodeHelpers, NodeFlags};
|
||||||
use crate::layout_dom::{ServoLayoutNode, ServoShadowRoot, ServoThreadSafeLayoutNode};
|
use crate::layout_dom::{ServoLayoutNode, ServoShadowRoot, ServoThreadSafeLayoutNode};
|
||||||
|
|
||||||
/// A wrapper around elements that ensures layout can only ever access safe properties.
|
/// A wrapper around elements that ensures layout can only ever access safe properties.
|
||||||
pub struct ServoLayoutElement<'dom, LayoutDataType: LayoutDataTrait> {
|
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||||
|
pub struct ServoLayoutElement<'dom> {
|
||||||
/// The wrapped private DOM Element.
|
/// The wrapped private DOM Element.
|
||||||
element: LayoutDom<'dom, Element>,
|
element: LayoutDom<'dom, Element>,
|
||||||
|
|
||||||
/// A PhantomData that is used to track the type of the stored layout data.
|
|
||||||
phantom: PhantomData<LayoutDataType>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These impls are required because `derive` has trouble with PhantomData.
|
impl<'dom> fmt::Debug for ServoLayoutElement<'dom> {
|
||||||
// See https://github.com/rust-lang/rust/issues/52079
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Clone for ServoLayoutElement<'dom, LayoutDataType> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Copy for ServoLayoutElement<'dom, LayoutDataType> {}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> PartialEq for ServoLayoutElement<'dom, LayoutDataType> {
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.as_node() == other.as_node()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// `Hash` + `Eq` + `Debug` are required by ::style::dom::TElement.
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Eq for ServoLayoutElement<'dom, LayoutDataType> {}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Hash for ServoLayoutElement<'dom, LayoutDataType> {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.element.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> fmt::Debug
|
|
||||||
for ServoLayoutElement<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "<{}", self.element.local_name())?;
|
write!(f, "<{}", self.element.local_name())?;
|
||||||
if let Some(id) = self.id() {
|
if let Some(id) = self.id() {
|
||||||
|
@ -91,12 +64,9 @@ impl<'dom, LayoutDataType: LayoutDataTrait> fmt::Debug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ServoLayoutElement<'dom, LayoutDataType> {
|
impl<'dom> ServoLayoutElement<'dom> {
|
||||||
pub(super) fn from_layout_js(el: LayoutDom<'dom, Element>) -> Self {
|
pub(super) fn from_layout_js(el: LayoutDom<'dom, Element>) -> Self {
|
||||||
ServoLayoutElement {
|
ServoLayoutElement { element: el }
|
||||||
element: el,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -152,13 +122,11 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ServoLayoutElement<'dom, LayoutDataT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TElement
|
impl<'dom> style::dom::TElement for ServoLayoutElement<'dom> {
|
||||||
for ServoLayoutElement<'dom, LayoutDataType>
|
type ConcreteNode = ServoLayoutNode<'dom>;
|
||||||
{
|
|
||||||
type ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
|
|
||||||
type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>;
|
type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>;
|
||||||
|
|
||||||
fn as_node(&self) -> ServoLayoutNode<'dom, LayoutDataType> {
|
fn as_node(&self) -> ServoLayoutNode<'dom> {
|
||||||
ServoLayoutNode::from_layout_js(self.element.upcast())
|
ServoLayoutNode::from_layout_js(self.element.upcast())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,14 +381,14 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TElement
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The shadow root this element is a host of.
|
/// The shadow root this element is a host of.
|
||||||
fn shadow_root(&self) -> Option<ServoShadowRoot<'dom, LayoutDataType>> {
|
fn shadow_root(&self) -> Option<ServoShadowRoot<'dom>> {
|
||||||
self.element
|
self.element
|
||||||
.get_shadow_root_for_layout()
|
.get_shadow_root_for_layout()
|
||||||
.map(ServoShadowRoot::from_layout_js)
|
.map(ServoShadowRoot::from_layout_js)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The shadow root which roots the subtree this element is contained in.
|
/// The shadow root which roots the subtree this element is contained in.
|
||||||
fn containing_shadow(&self) -> Option<ServoShadowRoot<'dom, LayoutDataType>> {
|
fn containing_shadow(&self) -> Option<ServoShadowRoot<'dom>> {
|
||||||
self.element
|
self.element
|
||||||
.upcast()
|
.upcast()
|
||||||
.containing_shadow_root_for_layout()
|
.containing_shadow_root_for_layout()
|
||||||
|
@ -458,9 +426,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ::selectors::Element
|
impl<'dom> ::selectors::Element for ServoLayoutElement<'dom> {
|
||||||
for ServoLayoutElement<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
type Impl = SelectorImpl;
|
type Impl = SelectorImpl;
|
||||||
|
|
||||||
fn opaque(&self) -> ::selectors::OpaqueElement {
|
fn opaque(&self) -> ::selectors::OpaqueElement {
|
||||||
|
@ -496,7 +462,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ::selectors::Element
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_sibling_element(&self) -> Option<ServoLayoutElement<'dom, LayoutDataType>> {
|
fn next_sibling_element(&self) -> Option<ServoLayoutElement<'dom>> {
|
||||||
let mut node = self.as_node();
|
let mut node = self.as_node();
|
||||||
while let Some(sibling) = node.next_sibling() {
|
while let Some(sibling) = node.next_sibling() {
|
||||||
if let Some(element) = sibling.as_element() {
|
if let Some(element) = sibling.as_element() {
|
||||||
|
@ -689,42 +655,20 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ::selectors::Element
|
||||||
|
|
||||||
/// A wrapper around elements that ensures layout can only
|
/// A wrapper around elements that ensures layout can only
|
||||||
/// ever access safe properties and cannot race on elements.
|
/// ever access safe properties and cannot race on elements.
|
||||||
pub struct ServoThreadSafeLayoutElement<'dom, LayoutDataType: LayoutDataTrait> {
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub(super) element: ServoLayoutElement<'dom, LayoutDataType>,
|
pub struct ServoThreadSafeLayoutElement<'dom> {
|
||||||
|
pub(super) element: ServoLayoutElement<'dom>,
|
||||||
|
|
||||||
/// The pseudo-element type, with (optionally)
|
/// The pseudo-element type, with (optionally)
|
||||||
/// a specified display value to override the stylesheet.
|
/// a specified display value to override the stylesheet.
|
||||||
pub(super) pseudo: PseudoElementType,
|
pub(super) pseudo: PseudoElementType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// These impls are required because `derive` has trouble with PhantomData.
|
impl<'dom> ThreadSafeLayoutElement<'dom> for ServoThreadSafeLayoutElement<'dom> {
|
||||||
// See https://github.com/rust-lang/rust/issues/52079
|
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom>;
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Clone
|
type ConcreteElement = ServoLayoutElement<'dom>;
|
||||||
for ServoThreadSafeLayoutElement<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Copy
|
|
||||||
for ServoThreadSafeLayoutElement<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> fmt::Debug
|
|
||||||
for ServoThreadSafeLayoutElement<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self.element.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutElement<'dom>
|
fn as_node(&self) -> ServoThreadSafeLayoutNode<'dom> {
|
||||||
for ServoThreadSafeLayoutElement<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom, LayoutDataType>;
|
|
||||||
type ConcreteElement = ServoLayoutElement<'dom, LayoutDataType>;
|
|
||||||
|
|
||||||
fn as_node(&self) -> ServoThreadSafeLayoutNode<'dom, LayoutDataType> {
|
|
||||||
ServoThreadSafeLayoutNode {
|
ServoThreadSafeLayoutNode {
|
||||||
node: self.element.as_node(),
|
node: self.element.as_node(),
|
||||||
pseudo: self.pseudo,
|
pseudo: self.pseudo,
|
||||||
|
@ -746,7 +690,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutElement<'dom>
|
||||||
self.as_node().type_id()
|
self.as_node().type_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unsafe_get(self) -> ServoLayoutElement<'dom, LayoutDataType> {
|
fn unsafe_get(self) -> ServoLayoutElement<'dom> {
|
||||||
self.element
|
self.element
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,9 +731,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutElement<'dom>
|
||||||
///
|
///
|
||||||
/// Note that the element implementation is needed only for selector matching,
|
/// Note that the element implementation is needed only for selector matching,
|
||||||
/// not for inheritance (styles are inherited appropriately).
|
/// not for inheritance (styles are inherited appropriately).
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ::selectors::Element
|
impl<'dom> ::selectors::Element for ServoThreadSafeLayoutElement<'dom> {
|
||||||
for ServoThreadSafeLayoutElement<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
type Impl = SelectorImpl;
|
type Impl = SelectorImpl;
|
||||||
|
|
||||||
fn opaque(&self) -> ::selectors::OpaqueElement {
|
fn opaque(&self) -> ::selectors::OpaqueElement {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::sync::Arc as StdArc;
|
use std::sync::Arc as StdArc;
|
||||||
|
|
||||||
use gfx_traits::ByteIndex;
|
use gfx_traits::ByteIndex;
|
||||||
|
@ -44,12 +43,10 @@ use crate::dom::text::Text;
|
||||||
/// several style and selectors traits for use during layout. This version
|
/// several style and selectors traits for use during layout. This version
|
||||||
/// should only be used on a single thread. If you need to use nodes across
|
/// should only be used on a single thread. If you need to use nodes across
|
||||||
/// threads use ServoThreadSafeLayoutNode.
|
/// threads use ServoThreadSafeLayoutNode.
|
||||||
pub struct ServoLayoutNode<'dom, LayoutDataType: LayoutDataTrait> {
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub struct ServoLayoutNode<'dom> {
|
||||||
/// The wrapped private DOM node.
|
/// The wrapped private DOM node.
|
||||||
pub(super) node: LayoutDom<'dom, Node>,
|
pub(super) node: LayoutDom<'dom, Node>,
|
||||||
|
|
||||||
/// A PhantomData that is used to track the type of the stored layout data.
|
|
||||||
pub(super) phantom: PhantomData<LayoutDataType>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Those are supposed to be sound, but they aren't because the entire system
|
/// Those are supposed to be sound, but they aren't because the entire system
|
||||||
|
@ -58,25 +55,10 @@ pub struct ServoLayoutNode<'dom, LayoutDataType: LayoutDataTrait> {
|
||||||
///
|
///
|
||||||
/// FIXME(mrobinson): These are required because Layout 2020 sends non-threadsafe
|
/// FIXME(mrobinson): These are required because Layout 2020 sends non-threadsafe
|
||||||
/// nodes to different threads. This should be adressed in a comprehensive way.
|
/// nodes to different threads. This should be adressed in a comprehensive way.
|
||||||
unsafe impl<LayoutDataType: LayoutDataTrait> Send for ServoLayoutNode<'_, LayoutDataType> {}
|
unsafe impl Send for ServoLayoutNode<'_> {}
|
||||||
unsafe impl<LayoutDataType: LayoutDataTrait> Sync for ServoLayoutNode<'_, LayoutDataType> {}
|
unsafe impl Sync for ServoLayoutNode<'_> {}
|
||||||
|
|
||||||
// These impls are required because `derive` has trouble with PhantomData.
|
impl<'dom> fmt::Debug for ServoLayoutNode<'dom> {
|
||||||
// See https://github.com/rust-lang/rust/issues/52079
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Clone for ServoLayoutNode<'dom, LayoutDataType> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Copy for ServoLayoutNode<'dom, LayoutDataType> {}
|
|
||||||
impl<'a, LayoutDataType: LayoutDataTrait> PartialEq for ServoLayoutNode<'a, LayoutDataType> {
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.node == other.node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> fmt::Debug for ServoLayoutNode<'dom, LayoutDataType> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if let Some(el) = self.as_element() {
|
if let Some(el) = self.as_element() {
|
||||||
el.fmt(f)
|
el.fmt(f)
|
||||||
|
@ -88,12 +70,9 @@ impl<'dom, LayoutDataType: LayoutDataTrait> fmt::Debug for ServoLayoutNode<'dom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ServoLayoutNode<'dom, LayoutDataType> {
|
impl<'dom> ServoLayoutNode<'dom> {
|
||||||
pub(super) fn from_layout_js(n: LayoutDom<'dom, Node>) -> Self {
|
pub(super) fn from_layout_js(n: LayoutDom<'dom, Node>) -> Self {
|
||||||
ServoLayoutNode {
|
ServoLayoutNode { node: n }
|
||||||
node: n,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn new(address: &TrustedNodeAddress) -> Self {
|
pub unsafe fn new(address: &TrustedNodeAddress) -> Self {
|
||||||
|
@ -110,9 +89,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ServoLayoutNode<'dom, LayoutDataType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::NodeInfo
|
impl<'dom> style::dom::NodeInfo for ServoLayoutNode<'dom> {
|
||||||
for ServoLayoutNode<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
fn is_element(&self) -> bool {
|
fn is_element(&self) -> bool {
|
||||||
self.node.is_element_for_layout()
|
self.node.is_element_for_layout()
|
||||||
}
|
}
|
||||||
|
@ -123,12 +100,10 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::NodeInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
|
impl<'dom> style::dom::TNode for ServoLayoutNode<'dom> {
|
||||||
for ServoLayoutNode<'dom, LayoutDataType>
|
type ConcreteDocument = ServoLayoutDocument<'dom>;
|
||||||
{
|
type ConcreteElement = ServoLayoutElement<'dom>;
|
||||||
type ConcreteDocument = ServoLayoutDocument<'dom, LayoutDataType>;
|
type ConcreteShadowRoot = ServoShadowRoot<'dom>;
|
||||||
type ConcreteElement = ServoLayoutElement<'dom, LayoutDataType>;
|
|
||||||
type ConcreteShadowRoot = ServoShadowRoot<'dom, LayoutDataType>;
|
|
||||||
|
|
||||||
fn parent_node(&self) -> Option<Self> {
|
fn parent_node(&self) -> Option<Self> {
|
||||||
self.node
|
self.node
|
||||||
|
@ -156,7 +131,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
|
||||||
ServoLayoutDocument::from_layout_js(self.node.owner_doc_for_layout())
|
ServoLayoutDocument::from_layout_js(self.node.owner_doc_for_layout())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traversal_parent(&self) -> Option<ServoLayoutElement<'dom, LayoutDataType>> {
|
fn traversal_parent(&self) -> Option<ServoLayoutElement<'dom>> {
|
||||||
let parent = self.parent_node()?;
|
let parent = self.parent_node()?;
|
||||||
if let Some(shadow) = parent.as_shadow_root() {
|
if let Some(shadow) = parent.as_shadow_root() {
|
||||||
return Some(shadow.host());
|
return Some(shadow.host());
|
||||||
|
@ -172,17 +147,17 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
|
||||||
self.opaque().0
|
self.opaque().0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_element(&self) -> Option<ServoLayoutElement<'dom, LayoutDataType>> {
|
fn as_element(&self) -> Option<ServoLayoutElement<'dom>> {
|
||||||
self.node.downcast().map(ServoLayoutElement::from_layout_js)
|
self.node.downcast().map(ServoLayoutElement::from_layout_js)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_document(&self) -> Option<ServoLayoutDocument<'dom, LayoutDataType>> {
|
fn as_document(&self) -> Option<ServoLayoutDocument<'dom>> {
|
||||||
self.node
|
self.node
|
||||||
.downcast()
|
.downcast()
|
||||||
.map(ServoLayoutDocument::from_layout_js)
|
.map(ServoLayoutDocument::from_layout_js)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_shadow_root(&self) -> Option<ServoShadowRoot<'dom, LayoutDataType>> {
|
fn as_shadow_root(&self) -> Option<ServoShadowRoot<'dom>> {
|
||||||
self.node.downcast().map(ServoShadowRoot::from_layout_js)
|
self.node.downcast().map(ServoShadowRoot::from_layout_js)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,10 +166,8 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> LayoutNode<'dom>
|
impl<'dom> LayoutNode<'dom> for ServoLayoutNode<'dom> {
|
||||||
for ServoLayoutNode<'dom, LayoutDataType>
|
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom>;
|
||||||
{
|
|
||||||
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom, LayoutDataType>;
|
|
||||||
|
|
||||||
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode {
|
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode {
|
||||||
ServoThreadSafeLayoutNode::new(*self)
|
ServoThreadSafeLayoutNode::new(*self)
|
||||||
|
@ -239,48 +212,19 @@ impl<'dom, LayoutDataType: LayoutDataTrait> LayoutNode<'dom>
|
||||||
/// A wrapper around a `ServoLayoutNode` that can be used safely on different threads.
|
/// A wrapper around a `ServoLayoutNode` that can be used safely on different threads.
|
||||||
/// It's very important that this never mutate anything except this wrapped node and
|
/// It's very important that this never mutate anything except this wrapped node and
|
||||||
/// never access any other node apart from its parent.
|
/// never access any other node apart from its parent.
|
||||||
pub struct ServoThreadSafeLayoutNode<'dom, LayoutDataType: LayoutDataTrait> {
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub struct ServoThreadSafeLayoutNode<'dom> {
|
||||||
/// The wrapped `ServoLayoutNode`.
|
/// The wrapped `ServoLayoutNode`.
|
||||||
pub(super) node: ServoLayoutNode<'dom, LayoutDataType>,
|
pub(super) node: ServoLayoutNode<'dom>,
|
||||||
|
|
||||||
/// The pseudo-element type, with (optionally)
|
/// The pseudo-element type, with (optionally)
|
||||||
/// a specified display value to override the stylesheet.
|
/// a specified display value to override the stylesheet.
|
||||||
pub(super) pseudo: PseudoElementType,
|
pub(super) pseudo: PseudoElementType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// These impls are required because `derive` has trouble with PhantomData.
|
impl<'dom> ServoThreadSafeLayoutNode<'dom> {
|
||||||
// See https://github.com/rust-lang/rust/issues/52079
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Clone
|
|
||||||
for ServoThreadSafeLayoutNode<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Copy
|
|
||||||
for ServoThreadSafeLayoutNode<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
impl<'a, LayoutDataType: LayoutDataTrait> PartialEq
|
|
||||||
for ServoThreadSafeLayoutNode<'a, LayoutDataType>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.node == other.node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'lr, LayoutDataType: LayoutDataTrait> fmt::Debug
|
|
||||||
for ServoThreadSafeLayoutNode<'lr, LayoutDataType>
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self.node.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ServoThreadSafeLayoutNode<'dom, LayoutDataType> {
|
|
||||||
/// Creates a new `ServoThreadSafeLayoutNode` from the given `ServoLayoutNode`.
|
/// Creates a new `ServoThreadSafeLayoutNode` from the given `ServoLayoutNode`.
|
||||||
pub fn new(node: ServoLayoutNode<'dom, LayoutDataType>) -> Self {
|
pub fn new(node: ServoLayoutNode<'dom>) -> Self {
|
||||||
ServoThreadSafeLayoutNode {
|
ServoThreadSafeLayoutNode {
|
||||||
node,
|
node,
|
||||||
pseudo: PseudoElementType::Normal,
|
pseudo: PseudoElementType::Normal,
|
||||||
|
@ -312,9 +256,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ServoThreadSafeLayoutNode<'dom, Layo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::NodeInfo
|
impl<'dom> style::dom::NodeInfo for ServoThreadSafeLayoutNode<'dom> {
|
||||||
for ServoThreadSafeLayoutNode<'dom, LayoutDataType>
|
|
||||||
{
|
|
||||||
fn is_element(&self) -> bool {
|
fn is_element(&self) -> bool {
|
||||||
self.node.is_element()
|
self.node.is_element()
|
||||||
}
|
}
|
||||||
|
@ -324,13 +266,11 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::NodeInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutNode<'dom>
|
impl<'dom> ThreadSafeLayoutNode<'dom> for ServoThreadSafeLayoutNode<'dom> {
|
||||||
for ServoThreadSafeLayoutNode<'dom, LayoutDataType>
|
type ConcreteNode = ServoLayoutNode<'dom>;
|
||||||
{
|
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'dom>;
|
||||||
type ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
|
type ConcreteElement = ServoLayoutElement<'dom>;
|
||||||
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'dom, LayoutDataType>;
|
type ChildrenIterator = ServoThreadSafeLayoutNodeChildrenIterator<'dom>;
|
||||||
type ConcreteElement = ServoLayoutElement<'dom, LayoutDataType>;
|
|
||||||
type ChildrenIterator = ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType>;
|
|
||||||
|
|
||||||
fn opaque(&self) -> style::dom::OpaqueNode {
|
fn opaque(&self) -> style::dom::OpaqueNode {
|
||||||
unsafe { self.get_jsmanaged().opaque() }
|
unsafe { self.get_jsmanaged().opaque() }
|
||||||
|
@ -363,7 +303,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutNode<'dom>
|
||||||
style::dom::LayoutIterator(ServoThreadSafeLayoutNodeChildrenIterator::new(*self))
|
style::dom::LayoutIterator(ServoThreadSafeLayoutNodeChildrenIterator::new(*self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_element(&self) -> Option<ServoThreadSafeLayoutElement<'dom, LayoutDataType>> {
|
fn as_element(&self) -> Option<ServoThreadSafeLayoutElement<'dom>> {
|
||||||
self.node
|
self.node
|
||||||
.as_element()
|
.as_element()
|
||||||
.map(|el| ServoThreadSafeLayoutElement {
|
.map(|el| ServoThreadSafeLayoutElement {
|
||||||
|
@ -494,15 +434,13 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutNode<'dom>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType: LayoutDataTrait> {
|
pub struct ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
|
||||||
current_node: Option<ServoThreadSafeLayoutNode<'dom, LayoutDataType>>,
|
current_node: Option<ServoThreadSafeLayoutNode<'dom>>,
|
||||||
parent_node: ServoThreadSafeLayoutNode<'dom, LayoutDataType>,
|
parent_node: ServoThreadSafeLayoutNode<'dom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait>
|
impl<'dom> ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
|
||||||
ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType>
|
pub fn new(parent: ServoThreadSafeLayoutNode<'dom>) -> Self {
|
||||||
{
|
|
||||||
pub fn new(parent: ServoThreadSafeLayoutNode<'dom, LayoutDataType>) -> Self {
|
|
||||||
let first_child = match parent.get_pseudo_element_type() {
|
let first_child = match parent.get_pseudo_element_type() {
|
||||||
PseudoElementType::Normal => parent
|
PseudoElementType::Normal => parent
|
||||||
.get_before_pseudo()
|
.get_before_pseudo()
|
||||||
|
@ -520,11 +458,9 @@ impl<'dom, LayoutDataType: LayoutDataTrait>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Iterator
|
impl<'dom> Iterator for ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
|
||||||
for ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType>
|
type Item = ServoThreadSafeLayoutNode<'dom>;
|
||||||
{
|
fn next(&mut self) -> Option<ServoThreadSafeLayoutNode<'dom>> {
|
||||||
type Item = ServoThreadSafeLayoutNode<'dom, LayoutDataType>;
|
|
||||||
fn next(&mut self) -> Option<ServoThreadSafeLayoutNode<'dom, LayoutDataType>> {
|
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
match self.parent_node.get_pseudo_element_type() {
|
match self.parent_node.get_pseudo_element_type() {
|
||||||
PseudoElementType::Before | PseudoElementType::After => None,
|
PseudoElementType::Before | PseudoElementType::After => None,
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use script_layout_interface::wrapper_traits::LayoutDataTrait;
|
|
||||||
use style::dom::TShadowRoot;
|
use style::dom::TShadowRoot;
|
||||||
use style::shared_lock::SharedRwLockReadGuard as StyleSharedRwLockReadGuard;
|
use style::shared_lock::SharedRwLockReadGuard as StyleSharedRwLockReadGuard;
|
||||||
use style::stylist::{CascadeData, Stylist};
|
use style::stylist::{CascadeData, Stylist};
|
||||||
|
@ -14,44 +12,26 @@ use crate::dom::bindings::root::LayoutDom;
|
||||||
use crate::dom::shadowroot::{LayoutShadowRootHelpers, ShadowRoot};
|
use crate::dom::shadowroot::{LayoutShadowRootHelpers, ShadowRoot};
|
||||||
use crate::layout_dom::{ServoLayoutElement, ServoLayoutNode};
|
use crate::layout_dom::{ServoLayoutElement, ServoLayoutNode};
|
||||||
|
|
||||||
pub struct ServoShadowRoot<'dom, LayoutDataType: LayoutDataTrait> {
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub struct ServoShadowRoot<'dom> {
|
||||||
/// The wrapped private DOM ShadowRoot.
|
/// The wrapped private DOM ShadowRoot.
|
||||||
shadow_root: LayoutDom<'dom, ShadowRoot>,
|
shadow_root: LayoutDom<'dom, ShadowRoot>,
|
||||||
|
|
||||||
/// A PhantomData that is used to track the type of the stored layout data.
|
|
||||||
phantom: PhantomData<LayoutDataType>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Clone for ServoShadowRoot<'dom, LayoutDataType> {
|
impl<'dom> fmt::Debug for ServoShadowRoot<'dom> {
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> Copy for ServoShadowRoot<'dom, LayoutDataType> {}
|
|
||||||
|
|
||||||
impl<'a, LayoutDataType: LayoutDataTrait> PartialEq for ServoShadowRoot<'a, LayoutDataType> {
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.shadow_root == other.shadow_root
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> fmt::Debug for ServoShadowRoot<'dom, LayoutDataType> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.as_node().fmt(f)
|
self.as_node().fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ::style::dom::TShadowRoot
|
impl<'dom> TShadowRoot for ServoShadowRoot<'dom> {
|
||||||
for ServoShadowRoot<'dom, LayoutDataType>
|
type ConcreteNode = ServoLayoutNode<'dom>;
|
||||||
{
|
|
||||||
type ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
|
|
||||||
|
|
||||||
fn as_node(&self) -> Self::ConcreteNode {
|
fn as_node(&self) -> Self::ConcreteNode {
|
||||||
ServoLayoutNode::from_layout_js(self.shadow_root.upcast())
|
ServoLayoutNode::from_layout_js(self.shadow_root.upcast())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn host(&self) -> ServoLayoutElement<'dom, LayoutDataType> {
|
fn host(&self) -> ServoLayoutElement<'dom> {
|
||||||
ServoLayoutElement::from_layout_js(self.shadow_root.get_host_for_layout())
|
ServoLayoutElement::from_layout_js(self.shadow_root.get_host_for_layout())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,12 +43,9 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ::style::dom::TShadowRoot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, LayoutDataType: LayoutDataTrait> ServoShadowRoot<'dom, LayoutDataType> {
|
impl<'dom> ServoShadowRoot<'dom> {
|
||||||
pub(super) fn from_layout_js(shadow_root: LayoutDom<'dom, ShadowRoot>) -> Self {
|
pub(super) fn from_layout_js(shadow_root: LayoutDom<'dom, ShadowRoot>) -> Self {
|
||||||
ServoShadowRoot {
|
ServoShadowRoot { shadow_root }
|
||||||
shadow_root,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn flush_stylesheets(
|
pub unsafe fn flush_stylesheets(
|
||||||
|
@ -77,6 +54,6 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ServoShadowRoot<'dom, LayoutDataType
|
||||||
guard: &StyleSharedRwLockReadGuard,
|
guard: &StyleSharedRwLockReadGuard,
|
||||||
) {
|
) {
|
||||||
self.shadow_root
|
self.shadow_root
|
||||||
.flush_stylesheets::<ServoLayoutElement<LayoutDataType>>(stylist, guard)
|
.flush_stylesheets::<ServoLayoutElement>(stylist, guard)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue