mirror of
https://github.com/servo/servo.git
synced 2025-06-25 17:44:33 +01:00
Implement GeckoChildrenIterator to traverse anonymous children.
This commit is contained in:
parent
1799b0a5df
commit
122df8ca60
2 changed files with 39 additions and 8 deletions
|
@ -168,6 +168,7 @@ pub enum RawServoStyleSheet { }
|
||||||
pub enum RawServoStyleSet { }
|
pub enum RawServoStyleSet { }
|
||||||
pub enum nsHTMLCSSStyleSheet { }
|
pub enum nsHTMLCSSStyleSheet { }
|
||||||
pub enum ServoDeclarationBlock { }
|
pub enum ServoDeclarationBlock { }
|
||||||
|
pub enum StyleChildrenIterator { }
|
||||||
pub type ThreadSafePrincipalHolder = nsMainThreadPtrHolder<nsIPrincipal>;
|
pub type ThreadSafePrincipalHolder = nsMainThreadPtrHolder<nsIPrincipal>;
|
||||||
pub type ThreadSafeURIHolder = nsMainThreadPtrHolder<nsIURI>;
|
pub type ThreadSafeURIHolder = nsMainThreadPtrHolder<nsIURI>;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -190,6 +191,11 @@ extern "C" {
|
||||||
-> *mut RawGeckoElement;
|
-> *mut RawGeckoElement;
|
||||||
pub fn Gecko_GetDocumentElement(document: *mut RawGeckoDocument)
|
pub fn Gecko_GetDocumentElement(document: *mut RawGeckoDocument)
|
||||||
-> *mut RawGeckoElement;
|
-> *mut RawGeckoElement;
|
||||||
|
pub fn Gecko_MaybeCreateStyleChildrenIterator(node: *mut RawGeckoNode)
|
||||||
|
-> *mut StyleChildrenIterator;
|
||||||
|
pub fn Gecko_DropStyleChildrenIterator(it: *mut StyleChildrenIterator);
|
||||||
|
pub fn Gecko_GetNextStyleChild(it: *mut StyleChildrenIterator)
|
||||||
|
-> *mut RawGeckoNode;
|
||||||
pub fn Gecko_ElementState(element: *mut RawGeckoElement) -> u8;
|
pub fn Gecko_ElementState(element: *mut RawGeckoElement) -> u8;
|
||||||
pub fn Gecko_IsHTMLElementInHTMLDocument(element: *mut RawGeckoElement)
|
pub fn Gecko_IsHTMLElementInHTMLDocument(element: *mut RawGeckoElement)
|
||||||
-> bool;
|
-> bool;
|
||||||
|
|
|
@ -10,10 +10,11 @@ use gecko_bindings::bindings::Gecko_GetNodeData;
|
||||||
use gecko_bindings::bindings::Gecko_GetStyleContext;
|
use gecko_bindings::bindings::Gecko_GetStyleContext;
|
||||||
use gecko_bindings::bindings::ServoNodeData;
|
use gecko_bindings::bindings::ServoNodeData;
|
||||||
use gecko_bindings::bindings::{Gecko_CalcStyleDifference, Gecko_StoreStyleDifference};
|
use gecko_bindings::bindings::{Gecko_CalcStyleDifference, Gecko_StoreStyleDifference};
|
||||||
|
use gecko_bindings::bindings::{Gecko_DropStyleChildrenIterator, Gecko_MaybeCreateStyleChildrenIterator};
|
||||||
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentElement};
|
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentElement};
|
||||||
use gecko_bindings::bindings::{Gecko_GetFirstChild, Gecko_GetFirstChildElement};
|
use gecko_bindings::bindings::{Gecko_GetFirstChild, Gecko_GetFirstChildElement};
|
||||||
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetLastChildElement};
|
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetLastChildElement};
|
||||||
use gecko_bindings::bindings::{Gecko_GetNextSibling, Gecko_GetNextSiblingElement};
|
use gecko_bindings::bindings::{Gecko_GetNextSibling, Gecko_GetNextSiblingElement, Gecko_GetNextStyleChild};
|
||||||
use gecko_bindings::bindings::{Gecko_GetNodeFlags, Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
|
use gecko_bindings::bindings::{Gecko_GetNodeFlags, Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
|
||||||
use gecko_bindings::bindings::{Gecko_GetParentElement, Gecko_GetParentNode};
|
use gecko_bindings::bindings::{Gecko_GetParentElement, Gecko_GetParentNode};
|
||||||
use gecko_bindings::bindings::{Gecko_GetPrevSibling, Gecko_GetPrevSiblingElement};
|
use gecko_bindings::bindings::{Gecko_GetPrevSibling, Gecko_GetPrevSiblingElement};
|
||||||
|
@ -164,8 +165,11 @@ impl<'ln> TNode for GeckoNode<'ln> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn children(self) -> GeckoChildrenIterator<'ln> {
|
fn children(self) -> GeckoChildrenIterator<'ln> {
|
||||||
GeckoChildrenIterator {
|
let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.node) };
|
||||||
current: self.first_child(),
|
if !maybe_iter.is_null() {
|
||||||
|
GeckoChildrenIterator::GeckoIterator(maybe_iter)
|
||||||
|
} else {
|
||||||
|
GeckoChildrenIterator::Current(self.first_child())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,16 +345,37 @@ impl<'ln> TNode for GeckoNode<'ln> {
|
||||||
unsafe fn set_dirty_on_viewport_size_changed(&self) {}
|
unsafe fn set_dirty_on_viewport_size_changed(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GeckoChildrenIterator<'a> {
|
// We generally iterate children by traversing the siblings of the first child
|
||||||
current: Option<GeckoNode<'a>>,
|
// like Servo does. However, for nodes with anonymous children, we use a custom
|
||||||
|
// (heavier-weight) Gecko-implemented iterator.
|
||||||
|
pub enum GeckoChildrenIterator<'a> {
|
||||||
|
Current(Option<GeckoNode<'a>>),
|
||||||
|
GeckoIterator(*mut bindings::StyleChildrenIterator),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for GeckoChildrenIterator<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let GeckoChildrenIterator::GeckoIterator(it) = *self {
|
||||||
|
unsafe {
|
||||||
|
Gecko_DropStyleChildrenIterator(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for GeckoChildrenIterator<'a> {
|
impl<'a> Iterator for GeckoChildrenIterator<'a> {
|
||||||
type Item = GeckoNode<'a>;
|
type Item = GeckoNode<'a>;
|
||||||
fn next(&mut self) -> Option<GeckoNode<'a>> {
|
fn next(&mut self) -> Option<GeckoNode<'a>> {
|
||||||
let node = self.current;
|
match *self {
|
||||||
self.current = node.and_then(|node| node.next_sibling());
|
GeckoChildrenIterator::Current(curr) => {
|
||||||
node
|
let next = curr.and_then(|node| node.next_sibling());
|
||||||
|
*self = GeckoChildrenIterator::Current(next);
|
||||||
|
curr
|
||||||
|
},
|
||||||
|
GeckoChildrenIterator::GeckoIterator(it) => unsafe {
|
||||||
|
Gecko_GetNextStyleChild(it).as_ref().map(|n| GeckoNode::from_ref(n))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue