mirror of
https://github.com/servo/servo.git
synced 2025-06-23 16:44:33 +01:00
Bug 1337068 - stylo: :empty, :-moz-first-node, :-moz-last-node, and :-moz-only-whitespace.
This commit is contained in:
parent
2fcbdb62f7
commit
dbfb3813f6
3 changed files with 56 additions and 5 deletions
|
@ -62,6 +62,10 @@ macro_rules! apply_non_ts_list {
|
||||||
("read-write", ReadWrite, _, IN_READ_WRITE_STATE, _),
|
("read-write", ReadWrite, _, IN_READ_WRITE_STATE, _),
|
||||||
("read-only", ReadOnly, _, IN_READ_WRITE_STATE, _),
|
("read-only", ReadOnly, _, IN_READ_WRITE_STATE, _),
|
||||||
|
|
||||||
|
("-moz-first-node", MozFirstNode, firstNode, _, _),
|
||||||
|
("-moz-last-node", MozLastNode, lastNode, _, _),
|
||||||
|
("-moz-only-whitespace", MozOnlyWhitespace, mozOnlyWhitespace, _, _),
|
||||||
|
|
||||||
("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_INTERNAL),
|
("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_INTERNAL),
|
||||||
("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_INTERNAL),
|
("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_INTERNAL),
|
||||||
],
|
],
|
||||||
|
|
|
@ -35,6 +35,7 @@ use gecko_bindings::bindings::Gecko_GetAnimationRule;
|
||||||
use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock;
|
use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock;
|
||||||
use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock;
|
use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock;
|
||||||
use gecko_bindings::bindings::Gecko_GetStyleContext;
|
use gecko_bindings::bindings::Gecko_GetStyleContext;
|
||||||
|
use gecko_bindings::bindings::Gecko_IsSignificantChild;
|
||||||
use gecko_bindings::bindings::Gecko_MatchStringArgPseudo;
|
use gecko_bindings::bindings::Gecko_MatchStringArgPseudo;
|
||||||
use gecko_bindings::bindings::Gecko_UpdateAnimations;
|
use gecko_bindings::bindings::Gecko_UpdateAnimations;
|
||||||
use gecko_bindings::structs;
|
use gecko_bindings::structs;
|
||||||
|
@ -52,7 +53,7 @@ use properties::animated_properties::AnimationValueMap;
|
||||||
use rule_tree::CascadeLevel as ServoCascadeLevel;
|
use rule_tree::CascadeLevel as ServoCascadeLevel;
|
||||||
use selector_parser::{ElementExt, Snapshot};
|
use selector_parser::{ElementExt, Snapshot};
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
use selectors::matching::{ElementSelectorFlags, StyleRelations, matches_complex_selector};
|
use selectors::matching::{ElementSelectorFlags, StyleRelations};
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use shared_lock::Locked;
|
use shared_lock::Locked;
|
||||||
|
@ -123,6 +124,12 @@ impl<'ln> GeckoNode<'ln> {
|
||||||
unsafe { self.0.mNextSibling.as_ref().map(GeckoNode::from_content) }
|
unsafe { self.0.mNextSibling.as_ref().map(GeckoNode::from_content) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simple iterator over all this node's children. Unlike `.children()`, this iterator does
|
||||||
|
/// not filter out nodes that don't need layout.
|
||||||
|
fn dom_children(self) -> GeckoChildrenIterator<'ln> {
|
||||||
|
GeckoChildrenIterator::Current(self.first_child())
|
||||||
|
}
|
||||||
|
|
||||||
/// WARNING: This logic is duplicated in Gecko's FlattenedTreeParentIsParent.
|
/// WARNING: This logic is duplicated in Gecko's FlattenedTreeParentIsParent.
|
||||||
/// Make sure to mirror any modifications in both places.
|
/// Make sure to mirror any modifications in both places.
|
||||||
fn flattened_tree_parent_is_parent(&self) -> bool {
|
fn flattened_tree_parent_is_parent(&self) -> bool {
|
||||||
|
@ -148,6 +155,9 @@ impl<'ln> GeckoNode<'ln> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn contains_non_whitespace_content(&self) -> bool {
|
||||||
|
unsafe { Gecko_IsSignificantChild(self.0, true, false) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ln> NodeInfo for GeckoNode<'ln> {
|
impl<'ln> NodeInfo for GeckoNode<'ln> {
|
||||||
|
@ -647,8 +657,9 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
// XXX(emilio): Implement this properly.
|
!self.as_node().dom_children().any(|child| unsafe {
|
||||||
false
|
Gecko_IsSignificantChild(child.0, true, true)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_local_name(&self) -> &WeakAtom {
|
fn get_local_name(&self) -> &WeakAtom {
|
||||||
|
@ -670,6 +681,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
-> bool
|
-> bool
|
||||||
where F: FnMut(&Self, ElementSelectorFlags),
|
where F: FnMut(&Self, ElementSelectorFlags),
|
||||||
{
|
{
|
||||||
|
use selectors::matching::*;
|
||||||
match *pseudo_class {
|
match *pseudo_class {
|
||||||
// https://github.com/servo/servo/issues/8718
|
// https://github.com/servo/servo/issues/8718
|
||||||
NonTSPseudoClass::AnyLink => unsafe { Gecko_IsLink(self.0) },
|
NonTSPseudoClass::AnyLink => unsafe { Gecko_IsLink(self.0) },
|
||||||
|
@ -701,7 +713,38 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
NonTSPseudoClass::ReadOnly => {
|
NonTSPseudoClass::ReadOnly => {
|
||||||
!self.get_state().contains(pseudo_class.state_flag())
|
!self.get_state().contains(pseudo_class.state_flag())
|
||||||
}
|
}
|
||||||
|
NonTSPseudoClass::MozFirstNode => {
|
||||||
|
flags_setter(self, HAS_EDGE_CHILD_SELECTOR);
|
||||||
|
let mut elem = self.as_node();
|
||||||
|
while let Some(prev) = elem.prev_sibling() {
|
||||||
|
if prev.contains_non_whitespace_content() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
elem = prev;
|
||||||
|
}
|
||||||
|
relations.insert(AFFECTED_BY_CHILD_INDEX);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
NonTSPseudoClass::MozLastNode => {
|
||||||
|
flags_setter(self, HAS_EDGE_CHILD_SELECTOR);
|
||||||
|
let mut elem = self.as_node();
|
||||||
|
while let Some(next) = elem.next_sibling() {
|
||||||
|
if next.contains_non_whitespace_content() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
elem = next;
|
||||||
|
}
|
||||||
|
relations.insert(AFFECTED_BY_CHILD_INDEX);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
NonTSPseudoClass::MozOnlyWhitespace => {
|
||||||
|
flags_setter(self, HAS_EMPTY_SELECTOR);
|
||||||
|
if self.as_node().dom_children().any(|c| c.contains_non_whitespace_content()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
relations.insert(AFFECTED_BY_EMPTY);
|
||||||
|
true
|
||||||
|
}
|
||||||
NonTSPseudoClass::MozTableBorderNonzero |
|
NonTSPseudoClass::MozTableBorderNonzero |
|
||||||
NonTSPseudoClass::MozBrowserFrame => unsafe {
|
NonTSPseudoClass::MozBrowserFrame => unsafe {
|
||||||
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
|
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
|
||||||
|
@ -720,7 +763,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
NonTSPseudoClass::MozEmptyExceptChildrenWithLocalname(ref s) |
|
NonTSPseudoClass::MozEmptyExceptChildrenWithLocalname(ref s) |
|
||||||
NonTSPseudoClass::Dir(ref s) |
|
NonTSPseudoClass::Dir(ref s) |
|
||||||
NonTSPseudoClass::Lang(ref s) => {
|
NonTSPseudoClass::Lang(ref s) => {
|
||||||
use selectors::matching::HAS_SLOW_SELECTOR;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut set_slow_selector = false;
|
let mut set_slow_selector = false;
|
||||||
let matches = Gecko_MatchStringArgPseudo(self.0,
|
let matches = Gecko_MatchStringArgPseudo(self.0,
|
||||||
|
|
|
@ -388,6 +388,11 @@ extern "C" {
|
||||||
pub fn Gecko_FlattenedTreeParentIsParent(node: RawGeckoNodeBorrowed)
|
pub fn Gecko_FlattenedTreeParentIsParent(node: RawGeckoNodeBorrowed)
|
||||||
-> bool;
|
-> bool;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_IsSignificantChild(node: RawGeckoNodeBorrowed,
|
||||||
|
text_is_significant: bool,
|
||||||
|
whitespace_is_significant: bool) -> bool;
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_GetParentNode(node: RawGeckoNodeBorrowed)
|
pub fn Gecko_GetParentNode(node: RawGeckoNodeBorrowed)
|
||||||
-> RawGeckoNodeBorrowedOrNull;
|
-> RawGeckoNodeBorrowedOrNull;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue