Auto merge of #17541 - heycam:is-needed, r=emilio

style: Make GeckoElement::traversal_children faster.

From https://bugzilla.mozilla.org/show_bug.cgi?id=1372061.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17541)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-06-28 11:59:31 -07:00 committed by GitHub
commit a40e5353b3
7 changed files with 4663 additions and 4139 deletions

View file

@ -187,12 +187,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
self.children() self.children()
} }
fn children_and_traversal_children_might_differ(&self) -> bool {
// Servo doesn't have to worry about nodes being rearranged in the
// flattened tree like Gecko does (for XBL and Shadow DOM). Yet.
false
}
fn opaque(&self) -> OpaqueNode { fn opaque(&self) -> OpaqueNode {
unsafe { self.get_jsmanaged().opaque() } unsafe { self.get_jsmanaged().opaque() }
} }

View file

@ -127,10 +127,6 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo {
/// Get this node's children from the perspective of a restyle traversal. /// Get this node's children from the perspective of a restyle traversal.
fn traversal_children(&self) -> LayoutIterator<Self::ConcreteChildrenIterator>; fn traversal_children(&self) -> LayoutIterator<Self::ConcreteChildrenIterator>;
/// Returns whether `children()` and `traversal_children()` might return
/// iterators over different nodes.
fn children_and_traversal_children_might_differ(&self) -> bool;
/// Converts self into an `OpaqueNode`. /// Converts self into an `OpaqueNode`.
fn opaque(&self) -> OpaqueNode; fn opaque(&self) -> OpaqueNode;

View file

@ -986,6 +986,8 @@ cfg_if! {
pub static nsGkAtoms_handlers: *mut nsIAtom; pub static nsGkAtoms_handlers: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms4HARDE"] #[link_name = "_ZN9nsGkAtoms4HARDE"]
pub static nsGkAtoms_HARD: *mut nsIAtom; pub static nsGkAtoms_HARD: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms8haspopupE"]
pub static nsGkAtoms_haspopup: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms11hasSameNodeE"] #[link_name = "_ZN9nsGkAtoms11hasSameNodeE"]
pub static nsGkAtoms_hasSameNode: *mut nsIAtom; pub static nsGkAtoms_hasSameNode: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms4hboxE"] #[link_name = "_ZN9nsGkAtoms4hboxE"]
@ -1562,6 +1564,8 @@ cfg_if! {
pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom; pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms10oncheckingE"] #[link_name = "_ZN9nsGkAtoms10oncheckingE"]
pub static nsGkAtoms_onchecking: *mut nsIAtom; pub static nsGkAtoms_onchecking: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms21onCheckboxStateChangeE"]
pub static nsGkAtoms_onCheckboxStateChange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms7onclickE"] #[link_name = "_ZN9nsGkAtoms7onclickE"]
pub static nsGkAtoms_onclick: *mut nsIAtom; pub static nsGkAtoms_onclick: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms16onclirmodechangeE"] #[link_name = "_ZN9nsGkAtoms16onclirmodechangeE"]
@ -1898,6 +1902,8 @@ cfg_if! {
pub static nsGkAtoms_onptychange: *mut nsIAtom; pub static nsGkAtoms_onptychange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms18onradiostatechangeE"] #[link_name = "_ZN9nsGkAtoms18onradiostatechangeE"]
pub static nsGkAtoms_onradiostatechange: *mut nsIAtom; pub static nsGkAtoms_onradiostatechange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms18onRadioStateChangeE"]
pub static nsGkAtoms_onRadioStateChange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms13onrdsdisabledE"] #[link_name = "_ZN9nsGkAtoms13onrdsdisabledE"]
pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom; pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms12onrdsenabledE"] #[link_name = "_ZN9nsGkAtoms12onrdsenabledE"]
@ -4208,6 +4214,8 @@ cfg_if! {
pub static nsGkAtoms_paintRequestTime: *mut nsIAtom; pub static nsGkAtoms_paintRequestTime: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms14pseudoPropertyE"] #[link_name = "_ZN9nsGkAtoms14pseudoPropertyE"]
pub static nsGkAtoms_pseudoProperty: *mut nsIAtom; pub static nsGkAtoms_pseudoProperty: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms17manualNACPropertyE"]
pub static nsGkAtoms_manualNACProperty: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms8JapaneseE"] #[link_name = "_ZN9nsGkAtoms8JapaneseE"]
pub static nsGkAtoms_Japanese: *mut nsIAtom; pub static nsGkAtoms_Japanese: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms7ChineseE"] #[link_name = "_ZN9nsGkAtoms7ChineseE"]
@ -6099,6 +6107,8 @@ cfg_if! {
pub static nsGkAtoms_handlers: *mut nsIAtom; pub static nsGkAtoms_handlers: *mut nsIAtom;
#[link_name = "?HARD@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?HARD@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_HARD: *mut nsIAtom; pub static nsGkAtoms_HARD: *mut nsIAtom;
#[link_name = "?haspopup@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_haspopup: *mut nsIAtom;
#[link_name = "?hasSameNode@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?hasSameNode@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_hasSameNode: *mut nsIAtom; pub static nsGkAtoms_hasSameNode: *mut nsIAtom;
#[link_name = "?hbox@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?hbox@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -6675,6 +6685,8 @@ cfg_if! {
pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom; pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom;
#[link_name = "?onchecking@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onchecking@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onchecking: *mut nsIAtom; pub static nsGkAtoms_onchecking: *mut nsIAtom;
#[link_name = "?onCheckboxStateChange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onCheckboxStateChange: *mut nsIAtom;
#[link_name = "?onclick@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onclick@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onclick: *mut nsIAtom; pub static nsGkAtoms_onclick: *mut nsIAtom;
#[link_name = "?onclirmodechange@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onclirmodechange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -7011,6 +7023,8 @@ cfg_if! {
pub static nsGkAtoms_onptychange: *mut nsIAtom; pub static nsGkAtoms_onptychange: *mut nsIAtom;
#[link_name = "?onradiostatechange@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onradiostatechange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onradiostatechange: *mut nsIAtom; pub static nsGkAtoms_onradiostatechange: *mut nsIAtom;
#[link_name = "?onRadioStateChange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onRadioStateChange: *mut nsIAtom;
#[link_name = "?onrdsdisabled@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onrdsdisabled@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom; pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom;
#[link_name = "?onrdsenabled@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onrdsenabled@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -9321,6 +9335,8 @@ cfg_if! {
pub static nsGkAtoms_paintRequestTime: *mut nsIAtom; pub static nsGkAtoms_paintRequestTime: *mut nsIAtom;
#[link_name = "?pseudoProperty@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?pseudoProperty@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_pseudoProperty: *mut nsIAtom; pub static nsGkAtoms_pseudoProperty: *mut nsIAtom;
#[link_name = "?manualNACProperty@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_manualNACProperty: *mut nsIAtom;
#[link_name = "?Japanese@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?Japanese@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_Japanese: *mut nsIAtom; pub static nsGkAtoms_Japanese: *mut nsIAtom;
#[link_name = "?Chinese@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?Chinese@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -11212,6 +11228,8 @@ cfg_if! {
pub static nsGkAtoms_handlers: *mut nsIAtom; pub static nsGkAtoms_handlers: *mut nsIAtom;
#[link_name = "\x01?HARD@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?HARD@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_HARD: *mut nsIAtom; pub static nsGkAtoms_HARD: *mut nsIAtom;
#[link_name = "\x01?haspopup@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_haspopup: *mut nsIAtom;
#[link_name = "\x01?hasSameNode@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?hasSameNode@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_hasSameNode: *mut nsIAtom; pub static nsGkAtoms_hasSameNode: *mut nsIAtom;
#[link_name = "\x01?hbox@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?hbox@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -11788,6 +11806,8 @@ cfg_if! {
pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom; pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom;
#[link_name = "\x01?onchecking@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onchecking@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onchecking: *mut nsIAtom; pub static nsGkAtoms_onchecking: *mut nsIAtom;
#[link_name = "\x01?onCheckboxStateChange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onCheckboxStateChange: *mut nsIAtom;
#[link_name = "\x01?onclick@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onclick@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onclick: *mut nsIAtom; pub static nsGkAtoms_onclick: *mut nsIAtom;
#[link_name = "\x01?onclirmodechange@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onclirmodechange@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -12124,6 +12144,8 @@ cfg_if! {
pub static nsGkAtoms_onptychange: *mut nsIAtom; pub static nsGkAtoms_onptychange: *mut nsIAtom;
#[link_name = "\x01?onradiostatechange@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onradiostatechange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onradiostatechange: *mut nsIAtom; pub static nsGkAtoms_onradiostatechange: *mut nsIAtom;
#[link_name = "\x01?onRadioStateChange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onRadioStateChange: *mut nsIAtom;
#[link_name = "\x01?onrdsdisabled@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onrdsdisabled@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom; pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom;
#[link_name = "\x01?onrdsenabled@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onrdsenabled@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -14434,6 +14456,8 @@ cfg_if! {
pub static nsGkAtoms_paintRequestTime: *mut nsIAtom; pub static nsGkAtoms_paintRequestTime: *mut nsIAtom;
#[link_name = "\x01?pseudoProperty@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?pseudoProperty@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_pseudoProperty: *mut nsIAtom; pub static nsGkAtoms_pseudoProperty: *mut nsIAtom;
#[link_name = "\x01?manualNACProperty@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_manualNACProperty: *mut nsIAtom;
#[link_name = "\x01?Japanese@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?Japanese@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_Japanese: *mut nsIAtom; pub static nsGkAtoms_Japanese: *mut nsIAtom;
#[link_name = "\x01?Chinese@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?Chinese@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -16328,6 +16352,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_handlers as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_handlers as *mut _) } };
("HARD") => ("HARD") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_HARD as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_HARD as *mut _) } };
("haspopup") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_haspopup as *mut _) } };
("has-same-node") => ("has-same-node") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_hasSameNode as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_hasSameNode as *mut _) } };
("hbox") => ("hbox") =>
@ -16904,6 +16930,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onchargingtimechange as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onchargingtimechange as *mut _) } };
("onchecking") => ("onchecking") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onchecking as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onchecking as *mut _) } };
("onCheckboxStateChange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onCheckboxStateChange as *mut _) } };
("onclick") => ("onclick") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onclick as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onclick as *mut _) } };
("onclirmodechange") => ("onclirmodechange") =>
@ -17240,6 +17268,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onptychange as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onptychange as *mut _) } };
("onradiostatechange") => ("onradiostatechange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onradiostatechange as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onradiostatechange as *mut _) } };
("onRadioStateChange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onRadioStateChange as *mut _) } };
("onrdsdisabled") => ("onrdsdisabled") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onrdsdisabled as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onrdsdisabled as *mut _) } };
("onrdsenabled") => ("onrdsenabled") =>
@ -19550,6 +19580,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_paintRequestTime as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_paintRequestTime as *mut _) } };
("PseudoProperty") => ("PseudoProperty") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_pseudoProperty as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_pseudoProperty as *mut _) } };
("ManualNACProperty") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_manualNACProperty as *mut _) } };
("ja") => ("ja") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_Japanese as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_Japanese as *mut _) } };
("zh-CN") => ("zh-CN") =>

View file

@ -29,6 +29,7 @@ use gecko_bindings::structs::RawServoStyleRule;
use gecko_bindings::structs::RawGeckoPresContext; use gecko_bindings::structs::RawGeckoPresContext;
use gecko_bindings::structs::RawGeckoPresContextOwned; use gecko_bindings::structs::RawGeckoPresContextOwned;
use gecko_bindings::structs::RawGeckoStyleAnimationList; use gecko_bindings::structs::RawGeckoStyleAnimationList;
use gecko_bindings::structs::RawGeckoStyleChildrenIteratorBorrowedMut;
use gecko_bindings::structs::RawGeckoServoStyleRuleList; use gecko_bindings::structs::RawGeckoServoStyleRuleList;
use gecko_bindings::structs::RawGeckoURLExtraData; use gecko_bindings::structs::RawGeckoURLExtraData;
use gecko_bindings::structs::RawGeckoXBLBinding; use gecko_bindings::structs::RawGeckoXBLBinding;
@ -227,14 +228,6 @@ pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet;
pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>; pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>;
enum RawServoStyleSetVoid { } enum RawServoStyleSetVoid { }
pub struct RawServoStyleSet(RawServoStyleSetVoid); pub struct RawServoStyleSet(RawServoStyleSetVoid);
pub type StyleChildrenIteratorOwned = ::gecko_bindings::sugar::ownership::Owned<StyleChildrenIterator>;
pub type StyleChildrenIteratorOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<StyleChildrenIterator>;
pub type StyleChildrenIteratorBorrowed<'a> = &'a StyleChildrenIterator;
pub type StyleChildrenIteratorBorrowedOrNull<'a> = Option<&'a StyleChildrenIterator>;
pub type StyleChildrenIteratorBorrowedMut<'a> = &'a mut StyleChildrenIterator;
pub type StyleChildrenIteratorBorrowedMutOrNull<'a> = Option<&'a mut StyleChildrenIterator>;
enum StyleChildrenIteratorVoid { }
pub struct StyleChildrenIterator(StyleChildrenIteratorVoid);
pub type ServoElementSnapshotOwned = ::gecko_bindings::sugar::ownership::Owned<ServoElementSnapshot>; pub type ServoElementSnapshotOwned = ::gecko_bindings::sugar::ownership::Owned<ServoElementSnapshot>;
pub type ServoElementSnapshotOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<ServoElementSnapshot>; pub type ServoElementSnapshotOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<ServoElementSnapshot>;
pub type ServoElementSnapshotBorrowed<'a> = &'a ServoElementSnapshot; pub type ServoElementSnapshotBorrowed<'a> = &'a ServoElementSnapshot;
@ -532,14 +525,18 @@ extern "C" {
*mut nsTArray<*mut nsIContent>); *mut nsTArray<*mut nsIContent>);
} }
extern "C" { extern "C" {
pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed) pub fn Gecko_ConstructStyleChildrenIterator(aElement:
-> StyleChildrenIteratorOwnedOrNull; RawGeckoElementBorrowed,
aIterator:
RawGeckoStyleChildrenIteratorBorrowedMut);
} }
extern "C" { extern "C" {
pub fn Gecko_DropStyleChildrenIterator(it: StyleChildrenIteratorOwned); pub fn Gecko_DestroyStyleChildrenIterator(aIterator:
RawGeckoStyleChildrenIteratorBorrowedMut);
} }
extern "C" { extern "C" {
pub fn Gecko_GetNextStyleChild(it: StyleChildrenIteratorBorrowedMut) pub fn Gecko_GetNextStyleChild(it:
RawGeckoStyleChildrenIteratorBorrowedMut)
-> RawGeckoNodeBorrowedOrNull; -> RawGeckoNodeBorrowedOrNull;
} }
extern "C" { extern "C" {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,7 @@ use gecko::global_style_data::GLOBAL_STYLE_DATA;
use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement}; use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement};
use gecko::snapshot_helpers; use gecko::snapshot_helpers;
use gecko_bindings::bindings; use gecko_bindings::bindings;
use gecko_bindings::bindings::{Gecko_DropStyleChildrenIterator, Gecko_MaybeCreateStyleChildrenIterator}; use gecko_bindings::bindings::{Gecko_ConstructStyleChildrenIterator, Gecko_DestroyStyleChildrenIterator};
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme}; use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme};
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetNextStyleChild}; use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetNextStyleChild};
use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement, Gecko_Namespace}; use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement, Gecko_Namespace};
@ -227,6 +227,21 @@ impl<'ln> GeckoNode<'ln> {
fn contains_non_whitespace_content(&self) -> bool { fn contains_non_whitespace_content(&self) -> bool {
unsafe { Gecko_IsSignificantChild(self.0, true, false) } unsafe { Gecko_IsSignificantChild(self.0, true, false) }
} }
#[inline]
fn may_have_anonymous_children(&self) -> bool {
self.get_bool_flag(nsINode_BooleanFlag::ElementMayHaveAnonymousChildren)
}
/// This logic is duplicated in Gecko's nsIContent::IsInAnonymousSubtree.
#[inline]
fn is_in_anonymous_subtree(&self) -> bool {
use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use gecko_bindings::structs::NODE_IS_IN_SHADOW_TREE;
self.flags() & (NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE as u32) != 0 ||
((self.flags() & (NODE_IS_IN_SHADOW_TREE as u32) == 0) &&
self.as_element().map_or(false, |e| e.has_xbl_binding_parent()))
}
} }
impl<'ln> NodeInfo for GeckoNode<'ln> { impl<'ln> NodeInfo for GeckoNode<'ln> {
@ -267,19 +282,23 @@ impl<'ln> TNode for GeckoNode<'ln> {
} }
fn traversal_children(&self) -> LayoutIterator<GeckoChildrenIterator<'ln>> { fn traversal_children(&self) -> LayoutIterator<GeckoChildrenIterator<'ln>> {
let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.0) }; if let Some(element) = self.as_element() {
if let Some(iter) = maybe_iter.into_owned_opt() { // This condition is similar to the check that
LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter)) // StyleChildrenIterator::IsNeeded does, except that it might return
} else { // true if we used to (but no longer) have anonymous content from
LayoutIterator(self.dom_children()) // ::before/::after, XBL bindings, or nsIAnonymousContentCreators.
if self.is_in_anonymous_subtree() ||
element.has_xbl_binding_with_content() ||
self.may_have_anonymous_children() {
unsafe {
let mut iter: structs::StyleChildrenIterator = ::std::mem::zeroed();
Gecko_ConstructStyleChildrenIterator(element.0, &mut iter);
return LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter));
}
}
} }
}
fn children_and_traversal_children_might_differ(&self) -> bool { LayoutIterator(self.dom_children())
match self.as_element() {
Some(e) => e.xbl_binding_anonymous_content().is_some(),
None => false,
}
} }
fn opaque(&self) -> OpaqueNode { fn opaque(&self) -> OpaqueNode {
@ -343,14 +362,14 @@ pub enum GeckoChildrenIterator<'a> {
/// replaces it with the next sibling when requested. /// replaces it with the next sibling when requested.
Current(Option<GeckoNode<'a>>), Current(Option<GeckoNode<'a>>),
/// A Gecko-implemented iterator we need to drop appropriately. /// A Gecko-implemented iterator we need to drop appropriately.
GeckoIterator(bindings::StyleChildrenIteratorOwned), GeckoIterator(structs::StyleChildrenIterator),
} }
impl<'a> Drop for GeckoChildrenIterator<'a> { impl<'a> Drop for GeckoChildrenIterator<'a> {
fn drop(&mut self) { fn drop(&mut self) {
if let GeckoChildrenIterator::GeckoIterator(ref it) = *self { if let GeckoChildrenIterator::GeckoIterator(ref mut it) = *self {
unsafe { unsafe {
Gecko_DropStyleChildrenIterator(ptr::read(it as *const _)); Gecko_DestroyStyleChildrenIterator(it);
} }
} }
} }
@ -373,10 +392,11 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> {
} }
/// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer. /// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer.
#[derive(Clone, Copy)]
pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding); pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding);
impl<'lb> GeckoXBLBinding<'lb> { impl<'lb> GeckoXBLBinding<'lb> {
fn base_binding(&self) -> Option<GeckoXBLBinding> { fn base_binding(&self) -> Option<Self> {
unsafe { self.0.mNextBinding.mRawPtr.as_ref().map(GeckoXBLBinding) } unsafe { self.0.mNextBinding.mRawPtr.as_ref().map(GeckoXBLBinding) }
} }
@ -388,6 +408,21 @@ impl<'lb> GeckoXBLBinding<'lb> {
unsafe { bindings::Gecko_XBLBinding_InheritsStyle(self.0) } unsafe { bindings::Gecko_XBLBinding_InheritsStyle(self.0) }
} }
// This duplicates the logic in Gecko's
// nsBindingManager::GetBindingWithContent.
fn get_binding_with_content(&self) -> Option<Self> {
let mut binding = *self;
loop {
if !binding.anon_content().is_null() {
return Some(binding);
}
binding = match binding.base_binding() {
Some(b) => b,
None => return None,
};
}
}
// Implements Gecko's nsXBLBinding::WalkRules(). // Implements Gecko's nsXBLBinding::WalkRules().
fn get_declarations_for<E, V>(&self, fn get_declarations_for<E, V>(&self,
element: &E, element: &E,
@ -480,12 +515,71 @@ impl<'le> GeckoElement<'le> {
unsafe { slots.as_ref() } unsafe { slots.as_ref() }
} }
#[inline]
fn get_xbl_binding(&self) -> Option<GeckoXBLBinding> { fn get_xbl_binding(&self) -> Option<GeckoXBLBinding> {
if self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) == 0 {
return None;
}
unsafe { bindings::Gecko_GetXBLBinding(self.0).map(GeckoXBLBinding) } unsafe { bindings::Gecko_GetXBLBinding(self.0).map(GeckoXBLBinding) }
} }
#[inline]
fn get_xbl_binding_with_content(&self) -> Option<GeckoXBLBinding> {
self.get_xbl_binding().and_then(|b| b.get_binding_with_content())
}
#[inline]
fn has_xbl_binding_with_content(&self) -> bool {
!self.get_xbl_binding_with_content().is_none()
}
/// This and has_xbl_binding_parent duplicate the logic in Gecko's virtual
/// nsINode::GetBindingParent function, which only has two implementations:
/// one for XUL elements, and one for other elements. We just hard code in
/// our knowledge of those two implementations here.
fn get_xbl_binding_parent(&self) -> Option<Self> { fn get_xbl_binding_parent(&self) -> Option<Self> {
unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) } if self.is_xul_element() {
// FIXME(heycam): Having trouble with bindgen on nsXULElement,
// where the binding parent is stored in a member variable
// rather than in slots. So just get it through FFI for now.
unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) }
} else {
let binding_parent =
unsafe { self.get_non_xul_xbl_binding_parent_raw_content().as_ref() }
.map(GeckoNode::from_content)
.and_then(|n| n.as_element());
debug_assert!(binding_parent ==
unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) });
binding_parent
}
}
fn get_non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent {
debug_assert!(!self.is_xul_element());
match self.get_dom_slots() {
Some(slots) => unsafe { *slots.__bindgen_anon_1.mBindingParent.as_ref() },
None => ptr::null_mut(),
}
}
fn has_xbl_binding_parent(&self) -> bool {
if self.is_xul_element() {
// FIXME(heycam): Having trouble with bindgen on nsXULElement,
// where the binding parent is stored in a member variable
// rather than in slots. So just get it through FFI for now.
unsafe { bindings::Gecko_GetBindingParent(self.0).is_some() }
} else {
!self.get_non_xul_xbl_binding_parent_raw_content().is_null()
}
}
fn namespace_id(&self) -> i32 {
self.as_node().node_info().mInner.mNamespaceID
}
fn is_xul_element(&self) -> bool {
self.namespace_id() == (structs::root::kNameSpaceID_XUL as i32)
} }
/// Clear the element data for a given element. /// Clear the element data for a given element.
@ -1061,16 +1155,9 @@ impl<'le> TElement for GeckoElement<'le> {
} }
fn xbl_binding_anonymous_content(&self) -> Option<GeckoNode<'le>> { fn xbl_binding_anonymous_content(&self) -> Option<GeckoNode<'le>> {
if self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) == 0 { self.get_xbl_binding_with_content()
return None; .map(|b| unsafe { b.anon_content().as_ref() }.unwrap())
} .map(GeckoNode::from_content)
let anon_content = match self.get_xbl_binding() {
Some(binding) => binding.anon_content(),
None => return None,
};
unsafe { anon_content.as_ref().map(GeckoNode::from_content) }
} }
fn get_css_transitions_info(&self) fn get_css_transitions_info(&self)