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:
Martin Robinson 2024-04-04 13:34:35 +02:00 committed by GitHub
parent df457c43c8
commit 24c3a2df1e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 105 additions and 281 deletions

View file

@ -2,9 +2,6 @@
* 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/. */
use std::marker::PhantomData;
use script_layout_interface::wrapper_traits::LayoutDataTrait;
use selectors::matching::QuirksMode;
use style::dom::{TDocument, TNode};
use style::shared_lock::{
@ -18,25 +15,14 @@ use crate::dom::node::{LayoutNodeHelpers, Node, NodeFlags};
use crate::layout_dom::{ServoLayoutElement, ServoLayoutNode, ServoShadowRoot};
// 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
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> {
fn clone(&self) -> Self {
*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>;
impl<'ld> ::style::dom::TDocument for ServoLayoutDocument<'ld> {
type ConcreteNode = ServoLayoutNode<'ld>;
fn as_node(&self) -> Self::ConcreteNode {
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> {
pub fn root_element(&self) -> Option<ServoLayoutElement<'ld, LayoutDataType>> {
impl<'ld> ServoLayoutDocument<'ld> {
pub fn root_element(&self) -> Option<ServoLayoutElement<'ld>> {
self.as_node()
.dom_children()
.flat_map(|n| n.as_element())
@ -75,7 +61,7 @@ impl<'ld, LayoutDataType: LayoutDataTrait> ServoLayoutDocument<'ld, LayoutDataTy
self.document.style_shared_lock()
}
pub fn shadow_roots(&self) -> Vec<ServoShadowRoot<LayoutDataType>> {
pub fn shadow_roots(&self) -> Vec<ServoShadowRoot> {
unsafe {
self.document
.shadow_roots()
@ -104,10 +90,7 @@ impl<'ld, LayoutDataType: LayoutDataTrait> ServoLayoutDocument<'ld, LayoutDataTy
}
}
pub fn from_layout_js(doc: LayoutDom<'ld, Document>) -> Self {
ServoLayoutDocument {
document: doc,
phantom: PhantomData,
}
pub fn from_layout_js(document: LayoutDom<'ld, Document>) -> Self {
ServoLayoutDocument { document }
}
}

View file

@ -3,14 +3,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::fmt;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::hash::Hash;
use std::sync::atomic::Ordering;
use atomic_refcell::{AtomicRef, AtomicRefMut};
use html5ever::{local_name, namespace_url, ns, LocalName, Namespace};
use script_layout_interface::wrapper_traits::{
LayoutDataTrait, LayoutNode, PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
LayoutNode, PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
};
use script_layout_interface::{LayoutNodeType, StyleData};
use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
@ -49,39 +48,13 @@ use crate::dom::node::{LayoutNodeHelpers, NodeFlags};
use crate::layout_dom::{ServoLayoutNode, ServoShadowRoot, ServoThreadSafeLayoutNode};
/// 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.
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.
// 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>
{
impl<'dom> fmt::Debug for ServoLayoutElement<'dom> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{}", self.element.local_name())?;
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 {
ServoLayoutElement {
element: el,
phantom: PhantomData,
}
ServoLayoutElement { element: el }
}
#[inline]
@ -152,13 +122,11 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ServoLayoutElement<'dom, LayoutDataT
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TElement
for ServoLayoutElement<'dom, LayoutDataType>
{
type ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
impl<'dom> style::dom::TElement for ServoLayoutElement<'dom> {
type ConcreteNode = ServoLayoutNode<'dom>;
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())
}
@ -413,14 +381,14 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TElement
}
/// 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
.get_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
/// 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
.upcast()
.containing_shadow_root_for_layout()
@ -458,9 +426,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TElement
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> ::selectors::Element
for ServoLayoutElement<'dom, LayoutDataType>
{
impl<'dom> ::selectors::Element for ServoLayoutElement<'dom> {
type Impl = SelectorImpl;
fn opaque(&self) -> ::selectors::OpaqueElement {
@ -496,7 +462,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ::selectors::Element
None
}
fn next_sibling_element(&self) -> Option<ServoLayoutElement<'dom, LayoutDataType>> {
fn next_sibling_element(&self) -> Option<ServoLayoutElement<'dom>> {
let mut node = self.as_node();
while let Some(sibling) = node.next_sibling() {
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
/// ever access safe properties and cannot race on elements.
pub struct ServoThreadSafeLayoutElement<'dom, LayoutDataType: LayoutDataTrait> {
pub(super) element: ServoLayoutElement<'dom, LayoutDataType>,
#[derive(Clone, Copy, Debug)]
pub struct ServoThreadSafeLayoutElement<'dom> {
pub(super) element: ServoLayoutElement<'dom>,
/// The pseudo-element type, with (optionally)
/// a specified display value to override the stylesheet.
pub(super) pseudo: PseudoElementType,
}
// These impls are required because `derive` has trouble with PhantomData.
// See https://github.com/rust-lang/rust/issues/52079
impl<'dom, LayoutDataType: LayoutDataTrait> Clone
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> ThreadSafeLayoutElement<'dom> for ServoThreadSafeLayoutElement<'dom> {
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom>;
type ConcreteElement = ServoLayoutElement<'dom>;
impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutElement<'dom>
for ServoThreadSafeLayoutElement<'dom, LayoutDataType>
{
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom, LayoutDataType>;
type ConcreteElement = ServoLayoutElement<'dom, LayoutDataType>;
fn as_node(&self) -> ServoThreadSafeLayoutNode<'dom, LayoutDataType> {
fn as_node(&self) -> ServoThreadSafeLayoutNode<'dom> {
ServoThreadSafeLayoutNode {
node: self.element.as_node(),
pseudo: self.pseudo,
@ -746,7 +690,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutElement<'dom>
self.as_node().type_id()
}
fn unsafe_get(self) -> ServoLayoutElement<'dom, LayoutDataType> {
fn unsafe_get(self) -> ServoLayoutElement<'dom> {
self.element
}
@ -787,9 +731,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutElement<'dom>
///
/// Note that the element implementation is needed only for selector matching,
/// not for inheritance (styles are inherited appropriately).
impl<'dom, LayoutDataType: LayoutDataTrait> ::selectors::Element
for ServoThreadSafeLayoutElement<'dom, LayoutDataType>
{
impl<'dom> ::selectors::Element for ServoThreadSafeLayoutElement<'dom> {
type Impl = SelectorImpl;
fn opaque(&self) -> ::selectors::OpaqueElement {

View file

@ -6,7 +6,6 @@
use std::borrow::Cow;
use std::fmt;
use std::marker::PhantomData;
use std::sync::Arc as StdArc;
use gfx_traits::ByteIndex;
@ -44,12 +43,10 @@ use crate::dom::text::Text;
/// 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
/// threads use ServoThreadSafeLayoutNode.
pub struct ServoLayoutNode<'dom, LayoutDataType: LayoutDataTrait> {
#[derive(Clone, Copy, PartialEq)]
pub struct ServoLayoutNode<'dom> {
/// The wrapped private 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
@ -58,25 +55,10 @@ pub struct ServoLayoutNode<'dom, LayoutDataType: LayoutDataTrait> {
///
/// FIXME(mrobinson): These are required because Layout 2020 sends non-threadsafe
/// nodes to different threads. This should be adressed in a comprehensive way.
unsafe impl<LayoutDataType: LayoutDataTrait> Send for ServoLayoutNode<'_, LayoutDataType> {}
unsafe impl<LayoutDataType: LayoutDataTrait> Sync for ServoLayoutNode<'_, LayoutDataType> {}
unsafe impl Send for ServoLayoutNode<'_> {}
unsafe impl Sync for ServoLayoutNode<'_> {}
// These impls are required because `derive` has trouble with PhantomData.
// 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> {
impl<'dom> fmt::Debug for ServoLayoutNode<'dom> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(el) = self.as_element() {
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 {
ServoLayoutNode {
node: n,
phantom: PhantomData,
}
ServoLayoutNode { node: n }
}
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
for ServoLayoutNode<'dom, LayoutDataType>
{
impl<'dom> style::dom::NodeInfo for ServoLayoutNode<'dom> {
fn is_element(&self) -> bool {
self.node.is_element_for_layout()
}
@ -123,12 +100,10 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::NodeInfo
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
for ServoLayoutNode<'dom, LayoutDataType>
{
type ConcreteDocument = ServoLayoutDocument<'dom, LayoutDataType>;
type ConcreteElement = ServoLayoutElement<'dom, LayoutDataType>;
type ConcreteShadowRoot = ServoShadowRoot<'dom, LayoutDataType>;
impl<'dom> style::dom::TNode for ServoLayoutNode<'dom> {
type ConcreteDocument = ServoLayoutDocument<'dom>;
type ConcreteElement = ServoLayoutElement<'dom>;
type ConcreteShadowRoot = ServoShadowRoot<'dom>;
fn parent_node(&self) -> Option<Self> {
self.node
@ -156,7 +131,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
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()?;
if let Some(shadow) = parent.as_shadow_root() {
return Some(shadow.host());
@ -172,17 +147,17 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
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)
}
fn as_document(&self) -> Option<ServoLayoutDocument<'dom, LayoutDataType>> {
fn as_document(&self) -> Option<ServoLayoutDocument<'dom>> {
self.node
.downcast()
.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)
}
@ -191,10 +166,8 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::TNode
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> LayoutNode<'dom>
for ServoLayoutNode<'dom, LayoutDataType>
{
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom, LayoutDataType>;
impl<'dom> LayoutNode<'dom> for ServoLayoutNode<'dom> {
type ConcreteThreadSafeLayoutNode = ServoThreadSafeLayoutNode<'dom>;
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode {
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.
/// It's very important that this never mutate anything except this wrapped node and
/// 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`.
pub(super) node: ServoLayoutNode<'dom, LayoutDataType>,
pub(super) node: ServoLayoutNode<'dom>,
/// The pseudo-element type, with (optionally)
/// a specified display value to override the stylesheet.
pub(super) pseudo: PseudoElementType,
}
// These impls are required because `derive` has trouble with PhantomData.
// 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> {
impl<'dom> ServoThreadSafeLayoutNode<'dom> {
/// Creates a new `ServoThreadSafeLayoutNode` from the given `ServoLayoutNode`.
pub fn new(node: ServoLayoutNode<'dom, LayoutDataType>) -> Self {
pub fn new(node: ServoLayoutNode<'dom>) -> Self {
ServoThreadSafeLayoutNode {
node,
pseudo: PseudoElementType::Normal,
@ -312,9 +256,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ServoThreadSafeLayoutNode<'dom, Layo
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::NodeInfo
for ServoThreadSafeLayoutNode<'dom, LayoutDataType>
{
impl<'dom> style::dom::NodeInfo for ServoThreadSafeLayoutNode<'dom> {
fn is_element(&self) -> bool {
self.node.is_element()
}
@ -324,13 +266,11 @@ impl<'dom, LayoutDataType: LayoutDataTrait> style::dom::NodeInfo
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutNode<'dom>
for ServoThreadSafeLayoutNode<'dom, LayoutDataType>
{
type ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'dom, LayoutDataType>;
type ConcreteElement = ServoLayoutElement<'dom, LayoutDataType>;
type ChildrenIterator = ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType>;
impl<'dom> ThreadSafeLayoutNode<'dom> for ServoThreadSafeLayoutNode<'dom> {
type ConcreteNode = ServoLayoutNode<'dom>;
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'dom>;
type ConcreteElement = ServoLayoutElement<'dom>;
type ChildrenIterator = ServoThreadSafeLayoutNodeChildrenIterator<'dom>;
fn opaque(&self) -> style::dom::OpaqueNode {
unsafe { self.get_jsmanaged().opaque() }
@ -363,7 +303,7 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutNode<'dom>
style::dom::LayoutIterator(ServoThreadSafeLayoutNodeChildrenIterator::new(*self))
}
fn as_element(&self) -> Option<ServoThreadSafeLayoutElement<'dom, LayoutDataType>> {
fn as_element(&self) -> Option<ServoThreadSafeLayoutElement<'dom>> {
self.node
.as_element()
.map(|el| ServoThreadSafeLayoutElement {
@ -494,15 +434,13 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ThreadSafeLayoutNode<'dom>
}
}
pub struct ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType: LayoutDataTrait> {
current_node: Option<ServoThreadSafeLayoutNode<'dom, LayoutDataType>>,
parent_node: ServoThreadSafeLayoutNode<'dom, LayoutDataType>,
pub struct ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
current_node: Option<ServoThreadSafeLayoutNode<'dom>>,
parent_node: ServoThreadSafeLayoutNode<'dom>,
}
impl<'dom, LayoutDataType: LayoutDataTrait>
ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType>
{
pub fn new(parent: ServoThreadSafeLayoutNode<'dom, LayoutDataType>) -> Self {
impl<'dom> ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
pub fn new(parent: ServoThreadSafeLayoutNode<'dom>) -> Self {
let first_child = match parent.get_pseudo_element_type() {
PseudoElementType::Normal => parent
.get_before_pseudo()
@ -520,11 +458,9 @@ impl<'dom, LayoutDataType: LayoutDataTrait>
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> Iterator
for ServoThreadSafeLayoutNodeChildrenIterator<'dom, LayoutDataType>
{
type Item = ServoThreadSafeLayoutNode<'dom, LayoutDataType>;
fn next(&mut self) -> Option<ServoThreadSafeLayoutNode<'dom, LayoutDataType>> {
impl<'dom> Iterator for ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
type Item = ServoThreadSafeLayoutNode<'dom>;
fn next(&mut self) -> Option<ServoThreadSafeLayoutNode<'dom>> {
use selectors::Element;
match self.parent_node.get_pseudo_element_type() {
PseudoElementType::Before | PseudoElementType::After => None,

View file

@ -3,9 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::fmt;
use std::marker::PhantomData;
use script_layout_interface::wrapper_traits::LayoutDataTrait;
use style::dom::TShadowRoot;
use style::shared_lock::SharedRwLockReadGuard as StyleSharedRwLockReadGuard;
use style::stylist::{CascadeData, Stylist};
@ -14,44 +12,26 @@ use crate::dom::bindings::root::LayoutDom;
use crate::dom::shadowroot::{LayoutShadowRootHelpers, ShadowRoot};
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.
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> {
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> {
impl<'dom> fmt::Debug for ServoShadowRoot<'dom> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_node().fmt(f)
}
}
impl<'dom, LayoutDataType: LayoutDataTrait> ::style::dom::TShadowRoot
for ServoShadowRoot<'dom, LayoutDataType>
{
type ConcreteNode = ServoLayoutNode<'dom, LayoutDataType>;
impl<'dom> TShadowRoot for ServoShadowRoot<'dom> {
type ConcreteNode = ServoLayoutNode<'dom>;
fn as_node(&self) -> Self::ConcreteNode {
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())
}
@ -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 {
ServoShadowRoot {
shadow_root,
phantom: PhantomData,
}
ServoShadowRoot { shadow_root }
}
pub unsafe fn flush_stylesheets(
@ -77,6 +54,6 @@ impl<'dom, LayoutDataType: LayoutDataTrait> ServoShadowRoot<'dom, LayoutDataType
guard: &StyleSharedRwLockReadGuard,
) {
self.shadow_root
.flush_stylesheets::<ServoLayoutElement<LayoutDataType>>(stylist, guard)
.flush_stylesheets::<ServoLayoutElement>(stylist, guard)
}
}