mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +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
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue