style: expose methods to get ::before, ::after, and the other NAC.

Reviewed-By: heycam
Bug: 1371130

MozReview-Commit-ID: JVeQevmjI3j
This commit is contained in:
Emilio Cobos Álvarez 2017-06-18 19:39:57 +02:00
parent a7ac9214f2
commit b894c361e0
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
2 changed files with 74 additions and 0 deletions

View file

@ -332,6 +332,23 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
self.parent_element()
}
/// The ::before pseudo-element of this element, if it exists.
fn before_pseudo_element(&self) -> Option<Self> {
None
}
/// The ::after pseudo-element of this element, if it exists.
fn after_pseudo_element(&self) -> Option<Self> {
None
}
/// Execute `f` for each anonymous content child (apart from ::before and
/// ::after) whose originating element is `self`.
fn each_anonymous_content_child<F>(&self, _f: F)
where
F: FnMut(Self),
{}
/// For a given NAC element, return the closest non-NAC ancestor, which is
/// guaranteed to exist.
fn closest_non_native_anonymous_ancestor(&self) -> Option<Self> {

View file

@ -557,6 +557,25 @@ impl<'le> GeckoElement<'le> {
self.as_node().get_bool_flag(nsINode_BooleanFlag::ElementMayHaveClass)
}
#[inline]
fn has_properties(&self) -> bool {
use gecko_bindings::structs::NODE_HAS_PROPERTIES;
(self.flags() & NODE_HAS_PROPERTIES as u32) != 0
}
#[inline]
fn get_before_or_after_pseudo(&self, is_before: bool) -> Option<Self> {
if !self.has_properties() {
return None;
}
unsafe {
bindings::Gecko_GetBeforeOrAfterPseudo(self.0, is_before)
.map(GeckoElement)
}
}
#[inline]
fn may_have_style_attribute(&self) -> bool {
self.as_node().get_bool_flag(nsINode_BooleanFlag::ElementMayHaveStyle)
@ -689,6 +708,40 @@ impl<'le> TElement for GeckoElement<'le> {
}
}
fn before_pseudo_element(&self) -> Option<Self> {
self.get_before_or_after_pseudo(/* is_before = */ true)
}
fn after_pseudo_element(&self) -> Option<Self> {
self.get_before_or_after_pseudo(/* is_before = */ false)
}
/// Execute `f` for each anonymous content child element (apart from
/// ::before and ::after) whose originating element is `self`.
fn each_anonymous_content_child<F>(&self, mut f: F)
where
F: FnMut(Self),
{
let array: *mut structs::nsTArray<*mut nsIContent> =
unsafe { bindings::Gecko_GetAnonymousContentForElement(self.0) };
if array.is_null() {
return;
}
for content in unsafe { &**array } {
let node = GeckoNode::from_content(unsafe { &**content });
let element = match node.as_element() {
Some(e) => e,
None => continue,
};
f(element);
}
unsafe { bindings::Gecko_DestroyAnonymousContentList(array) };
}
fn closest_non_native_anonymous_ancestor(&self) -> Option<Self> {
debug_assert!(self.is_native_anonymous());
let mut parent = match self.parent_element() {
@ -868,6 +921,10 @@ impl<'le> TElement for GeckoElement<'le> {
return None;
}
if !self.has_properties() {
return None;
}
let pseudo_type =
unsafe { bindings::Gecko_GetImplementedPseudo(self.0) };
PseudoElement::from_pseudo_type(pseudo_type)