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

@ -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 {