aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/element.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/element.rs')
-rw-r--r--components/script/dom/element.rs80
1 files changed, 60 insertions, 20 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 7a6936611df..dbdff1f5586 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -86,7 +86,7 @@ use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::DomObject;
-use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom};
+use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom, ToLayout};
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::bindings::xmlname::{
matches_name_production, namespace_from_domstring, validate_and_extract,
@@ -162,7 +162,7 @@ use crate::task::TaskOnce;
/// <https://dom.spec.whatwg.org/#element>
#[dom_struct]
-pub(crate) struct Element {
+pub struct Element {
node: Node,
#[no_trace]
local_name: LocalName,
@@ -203,12 +203,6 @@ impl fmt::Debug for Element {
}
}
-impl fmt::Debug for DomRoot<Element> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- (**self).fmt(f)
- }
-}
-
#[derive(MallocSizeOf, PartialEq)]
pub(crate) enum ElementCreator {
ParserCreated(u64),
@@ -3025,7 +3019,11 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
let quirks_mode = doc.quirks_mode();
let element = DomRoot::from_ref(self);
- Ok(dom_apis::element_matches(&element, &selectors, quirks_mode))
+ Ok(dom_apis::element_matches(
+ &SelectorWrapper::Borrowed(&element),
+ &selectors,
+ quirks_mode,
+ ))
}
// https://dom.spec.whatwg.org/#dom-element-webkitmatchesselector
@@ -3047,10 +3045,11 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
let quirks_mode = doc.quirks_mode();
Ok(dom_apis::element_closest(
- DomRoot::from_ref(self),
+ SelectorWrapper::Owned(DomRoot::from_ref(self)),
&selectors,
quirks_mode,
- ))
+ )
+ .map(SelectorWrapper::into_owned))
}
// https://dom.spec.whatwg.org/#dom-element-insertadjacentelement
@@ -3831,7 +3830,43 @@ impl VirtualMethods for Element {
}
}
-impl SelectorsElement for DomRoot<Element> {
+#[derive(Clone, PartialEq)]
+/// A type that wraps a DomRoot value so we can implement the SelectorsElement
+/// trait without violating the orphan rule. Since the trait assumes that the
+/// return type and self type of various methods is the same type that it is
+/// implemented against, we need to be able to represent multiple ownership styles.
+pub enum SelectorWrapper<'a> {
+ Borrowed(&'a DomRoot<Element>),
+ Owned(DomRoot<Element>),
+}
+
+impl fmt::Debug for SelectorWrapper<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.deref().fmt(f)
+ }
+}
+
+impl Deref for SelectorWrapper<'_> {
+ type Target = DomRoot<Element>;
+
+ fn deref(&self) -> &Self::Target {
+ match self {
+ SelectorWrapper::Owned(r) => r,
+ SelectorWrapper::Borrowed(r) => r,
+ }
+ }
+}
+
+impl SelectorWrapper<'_> {
+ fn into_owned(self) -> DomRoot<Element> {
+ match self {
+ SelectorWrapper::Owned(r) => r,
+ SelectorWrapper::Borrowed(r) => r.clone(),
+ }
+ }
+}
+
+impl SelectorsElement for SelectorWrapper<'_> {
type Impl = SelectorImpl;
#[allow(unsafe_code)]
@@ -3839,8 +3874,10 @@ impl SelectorsElement for DomRoot<Element> {
::selectors::OpaqueElement::new(unsafe { &*self.reflector().get_jsobject().get() })
}
- fn parent_element(&self) -> Option<DomRoot<Element>> {
- self.upcast::<Node>().GetParentElement()
+ fn parent_element(&self) -> Option<Self> {
+ self.upcast::<Node>()
+ .GetParentElement()
+ .map(SelectorWrapper::Owned)
}
fn parent_node_is_shadow_root(&self) -> bool {
@@ -3853,6 +3890,7 @@ impl SelectorsElement for DomRoot<Element> {
fn containing_shadow_host(&self) -> Option<Self> {
self.containing_shadow_root()
.map(|shadow_root| shadow_root.Host())
+ .map(SelectorWrapper::Owned)
}
fn is_pseudo_element(&self) -> bool {
@@ -3867,22 +3905,24 @@ impl SelectorsElement for DomRoot<Element> {
false
}
- fn prev_sibling_element(&self) -> Option<DomRoot<Element>> {
+ fn prev_sibling_element(&self) -> Option<Self> {
self.node
.preceding_siblings()
.filter_map(DomRoot::downcast)
.next()
+ .map(SelectorWrapper::Owned)
}
- fn next_sibling_element(&self) -> Option<DomRoot<Element>> {
+ fn next_sibling_element(&self) -> Option<Self> {
self.node
.following_siblings()
.filter_map(DomRoot::downcast)
.next()
+ .map(SelectorWrapper::Owned)
}
- fn first_element_child(&self) -> Option<DomRoot<Element>> {
- self.GetFirstElementChild()
+ fn first_element_child(&self) -> Option<Self> {
+ self.GetFirstElementChild().map(SelectorWrapper::Owned)
}
fn attr_matches(
@@ -4039,7 +4079,7 @@ impl SelectorsElement for DomRoot<Element> {
if !self_flags.is_empty() {
#[allow(unsafe_code)]
unsafe {
- Dom::from_ref(self.deref())
+ Dom::from_ref(&***self)
.to_layout()
.insert_selector_flags(self_flags);
}
@@ -4051,7 +4091,7 @@ impl SelectorsElement for DomRoot<Element> {
if let Some(p) = self.parent_element() {
#[allow(unsafe_code)]
unsafe {
- Dom::from_ref(p.deref())
+ Dom::from_ref(&**p)
.to_layout()
.insert_selector_flags(parent_flags);
}