Bug 1792501: Part 5 - :has DOM mutation invalidation. r=emilio,layout-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D185678
This commit is contained in:
@@ -80,6 +80,9 @@ RestyleManager::RestyleManager(nsPresContext* aPresContext)
|
||||
|
||||
void RestyleManager::ContentInserted(nsIContent* aChild) {
|
||||
MOZ_ASSERT(aChild->GetParentNode());
|
||||
if (aChild->IsElement()) {
|
||||
StyleSet()->MaybeInvalidateForElementInsertion(*aChild->AsElement());
|
||||
}
|
||||
RestyleForInsertOrChange(aChild);
|
||||
}
|
||||
|
||||
@@ -95,6 +98,10 @@ void RestyleManager::ContentAppended(nsIContent* aFirstNewContent) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (aFirstNewContent->IsElement()) {
|
||||
StyleSet()->MaybeInvalidateForElementAppend(*aFirstNewContent->AsElement());
|
||||
}
|
||||
|
||||
const auto selectorFlags = container->GetSelectorFlags() &
|
||||
NodeSelectorFlags::AllSimpleRestyleFlagsForAppend;
|
||||
if (!selectorFlags) {
|
||||
@@ -412,6 +419,19 @@ void RestyleManager::ContentRemoved(nsIContent* aOldChild,
|
||||
IncrementUndisplayedRestyleGeneration();
|
||||
}
|
||||
|
||||
if (aOldChild->IsElement()) {
|
||||
Element* nextSibling =
|
||||
aFollowingSibling ? aFollowingSibling->IsElement()
|
||||
? aFollowingSibling->AsElement()
|
||||
: aFollowingSibling->GetNextElementSibling()
|
||||
: nullptr;
|
||||
Element* prevSibling = aFollowingSibling
|
||||
? aFollowingSibling->GetPreviousElementSibling()
|
||||
: container->GetLastElementChild();
|
||||
StyleSet()->MaybeInvalidateForElementRemove(*aOldChild->AsElement(),
|
||||
prevSibling, nextSibling);
|
||||
}
|
||||
|
||||
const auto selectorFlags =
|
||||
container->GetSelectorFlags() & NodeSelectorFlags::AllSimpleRestyleFlags;
|
||||
if (!selectorFlags) {
|
||||
|
||||
@@ -1408,6 +1408,24 @@ void ServoStyleSet::MaybeInvalidateRelativeSelectorStateDependency(
|
||||
mRawData.get(), &aElement, aState.GetInternalValue());
|
||||
}
|
||||
|
||||
void ServoStyleSet::MaybeInvalidateForElementInsertion(
|
||||
const Element& aElement) {
|
||||
Servo_StyleSet_MaybeInvalidateRelativeSelectorForInsertion(mRawData.get(),
|
||||
&aElement);
|
||||
}
|
||||
|
||||
void ServoStyleSet::MaybeInvalidateForElementAppend(const Element& aElement) {
|
||||
Servo_StyleSet_MaybeInvalidateRelativeSelectorForAppend(mRawData.get(),
|
||||
&aElement);
|
||||
}
|
||||
|
||||
void ServoStyleSet::MaybeInvalidateForElementRemove(
|
||||
const Element& aElement, const Element* aPrevSibling,
|
||||
const Element* aNextSibling) {
|
||||
Servo_StyleSet_MaybeInvalidateRelativeSelectorForRemoval(
|
||||
mRawData.get(), &aElement, aPrevSibling, aNextSibling);
|
||||
}
|
||||
|
||||
bool ServoStyleSet::MightHaveNthOfAttributeDependency(
|
||||
const Element& aElement, nsAtom* aAttribute) const {
|
||||
return Servo_StyleSet_MightHaveNthOfAttributeDependency(
|
||||
|
||||
@@ -490,6 +490,26 @@ class ServoStyleSet {
|
||||
void MaybeInvalidateRelativeSelectorStateDependency(const dom::Element&,
|
||||
dom::ElementState);
|
||||
|
||||
/**
|
||||
* Maybe invalidate if a DOM element insertion might require us to restyle
|
||||
* the relative selector to ancestors/previous siblings.
|
||||
*/
|
||||
void MaybeInvalidateForElementInsertion(const dom::Element&);
|
||||
|
||||
/**
|
||||
* Maybe invalidate if a DOM element append might require us to restyle
|
||||
* the relative selector to ancestors/previous siblings.
|
||||
*/
|
||||
void MaybeInvalidateForElementAppend(const dom::Element&);
|
||||
|
||||
/**
|
||||
* Maybe invalidate if a DOM element removal might require us to restyle
|
||||
* the relative selector to ancestors/previous siblings.
|
||||
*/
|
||||
void MaybeInvalidateForElementRemove(const dom::Element& aElement,
|
||||
const dom::Element* aPrevSibling,
|
||||
const dom::Element* aNextSibling);
|
||||
|
||||
/**
|
||||
* Returns true if a change in event state on an element might require
|
||||
* us to restyle the element.
|
||||
|
||||
@@ -187,6 +187,32 @@ impl Dependency {
|
||||
}
|
||||
DependencyInvalidationKind::Normal(self.normal_invalidation_kind())
|
||||
}
|
||||
|
||||
/// Is the combinator to the right of this dependency's compound selector
|
||||
/// the next sibling combinator? This matters for insertion/removal in between
|
||||
/// two elements connected through next sibling, e.g. `.foo:has(> .a + .b)`
|
||||
/// where an element gets inserted between `.a` and `.b`.
|
||||
pub fn right_combinator_is_next_sibling(&self) -> bool {
|
||||
if self.selector_offset == 0 {
|
||||
return false;
|
||||
}
|
||||
matches!(
|
||||
self.selector.combinator_at_match_order(self.selector_offset - 1),
|
||||
Combinator::NextSibling
|
||||
)
|
||||
}
|
||||
|
||||
/// Is this dependency's compound selector a single compound in `:has`
|
||||
/// with the next sibling relative combinator i.e. `:has(> .foo)`?
|
||||
/// This matters for insertion between an anchor and an element
|
||||
/// connected through next sibling, e.g. `.a:has(> .b)`.
|
||||
pub fn dependency_is_relative_with_single_next_sibling(&self) -> bool {
|
||||
match self.invalidation_kind() {
|
||||
DependencyInvalidationKind::Normal(_) => false,
|
||||
DependencyInvalidationKind::Relative(kind) =>
|
||||
kind == RelativeDependencyInvalidationKind::PrevSibling,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The same, but for state selectors, which can track more exactly what state
|
||||
@@ -224,8 +250,8 @@ pub struct DocumentStateDependency {
|
||||
pub type IdOrClassDependencyMap = MaybeCaseInsensitiveHashMap<Atom, SmallVec<[Dependency; 1]>>;
|
||||
/// Dependency mapping for pseudo-class states.
|
||||
pub type StateDependencyMap = SelectorMap<StateDependency>;
|
||||
/// Dependency mapping for attributes.
|
||||
pub type AttributeDependencyMap = PrecomputedHashMap<LocalName, SmallVec<[Dependency; 1]>>;
|
||||
/// Dependency mapping for local names.
|
||||
pub type LocalNameDependencyMap = PrecomputedHashMap<LocalName, SmallVec<[Dependency; 1]>>;
|
||||
|
||||
/// A map where we store invalidations.
|
||||
///
|
||||
@@ -248,7 +274,7 @@ pub struct InvalidationMap {
|
||||
/// A list of document state dependencies in the rules we represent.
|
||||
pub document_state_selectors: Vec<DocumentStateDependency>,
|
||||
/// A map of other attribute affecting selectors.
|
||||
pub other_attribute_affecting_selectors: AttributeDependencyMap,
|
||||
pub other_attribute_affecting_selectors: LocalNameDependencyMap,
|
||||
}
|
||||
|
||||
/// A map to store all relative selector invalidations.
|
||||
@@ -256,6 +282,10 @@ pub struct InvalidationMap {
|
||||
pub struct RelativeSelectorInvalidationMap {
|
||||
/// Portion common to the normal invalidation map, except that this is for relative selectors and their inner selectors.
|
||||
pub map: InvalidationMap,
|
||||
/// A map from a given type name to all the relative selector dependencies with that type.
|
||||
pub type_to_selector: LocalNameDependencyMap,
|
||||
/// All relative selector dependencies that specify `*`.
|
||||
pub any_to_selector: SmallVec<[Dependency; 1]>,
|
||||
/// Flag indicating if any relative selector is used.
|
||||
pub used: bool,
|
||||
/// Flag indicating if invalidating a relative selector requires ancestor traversal.
|
||||
@@ -267,6 +297,8 @@ impl RelativeSelectorInvalidationMap {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
map: InvalidationMap::new(),
|
||||
type_to_selector: LocalNameDependencyMap::default(),
|
||||
any_to_selector: SmallVec::default(),
|
||||
used: false,
|
||||
needs_ancestors_traversal: false,
|
||||
}
|
||||
@@ -280,11 +312,14 @@ impl RelativeSelectorInvalidationMap {
|
||||
/// Clears this map, leaving it empty.
|
||||
pub fn clear(&mut self) {
|
||||
self.map.clear();
|
||||
self.type_to_selector.clear();
|
||||
self.any_to_selector.clear();
|
||||
}
|
||||
|
||||
/// Shrink the capacity of hash maps if needed.
|
||||
pub fn shrink_if_needed(&mut self) {
|
||||
self.map.shrink_if_needed();
|
||||
self.type_to_selector.shrink_if_needed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +331,7 @@ impl InvalidationMap {
|
||||
id_to_selector: IdOrClassDependencyMap::new(),
|
||||
state_affecting_selectors: StateDependencyMap::new(),
|
||||
document_state_selectors: Vec::new(),
|
||||
other_attribute_affecting_selectors: AttributeDependencyMap::default(),
|
||||
other_attribute_affecting_selectors: LocalNameDependencyMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +437,7 @@ trait Collector {
|
||||
fn id_map(&mut self) -> &mut IdOrClassDependencyMap;
|
||||
fn class_map(&mut self) -> &mut IdOrClassDependencyMap;
|
||||
fn state_map(&mut self) -> &mut StateDependencyMap;
|
||||
fn attribute_map(&mut self) -> &mut AttributeDependencyMap;
|
||||
fn attribute_map(&mut self) -> &mut LocalNameDependencyMap;
|
||||
fn update_states(&mut self, element_state: ElementState, document_state: DocumentState);
|
||||
}
|
||||
|
||||
@@ -440,6 +475,14 @@ fn on_id_or_class<C: Collector>(
|
||||
fn add_attr_dependency<C: Collector>(name: LocalName, collector: &mut C) -> Result<(), AllocErr> {
|
||||
let dependency = collector.dependency();
|
||||
let map = collector.attribute_map();
|
||||
add_local_name(name, dependency, map)
|
||||
}
|
||||
|
||||
fn add_local_name(
|
||||
name: LocalName,
|
||||
dependency: Dependency,
|
||||
map: &mut LocalNameDependencyMap,
|
||||
) -> Result<(), AllocErr> {
|
||||
map.try_reserve(1)?;
|
||||
let vec = map.entry(name).or_default();
|
||||
vec.try_reserve(1)?;
|
||||
@@ -574,7 +617,7 @@ impl<'a> Collector for SelectorDependencyCollector<'a> {
|
||||
&mut self.map.state_affecting_selectors
|
||||
}
|
||||
|
||||
fn attribute_map(&mut self) -> &mut AttributeDependencyMap {
|
||||
fn attribute_map(&mut self) -> &mut LocalNameDependencyMap {
|
||||
&mut self.map.other_attribute_affecting_selectors
|
||||
}
|
||||
|
||||
@@ -699,7 +742,7 @@ impl<'a> SelectorVisitor for SelectorDependencyCollector<'a> {
|
||||
combinator_count: RelativeSelectorCombinatorCount::new(relative_selector),
|
||||
parent_selectors: &mut *self.parent_selectors,
|
||||
quirks_mode: self.quirks_mode,
|
||||
compound_state: PerCompoundState::new(0),
|
||||
compound_state: RelativeSelectorPerCompoundState::new(0),
|
||||
alloc_error: &mut *self.alloc_error,
|
||||
};
|
||||
if !nested.visit_whole_selector() {
|
||||
@@ -744,6 +787,20 @@ impl<'a> SelectorVisitor for SelectorDependencyCollector<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
struct RelativeSelectorPerCompoundState {
|
||||
state: PerCompoundState,
|
||||
added_entry: bool,
|
||||
}
|
||||
|
||||
impl RelativeSelectorPerCompoundState {
|
||||
fn new(offset: usize) -> Self {
|
||||
Self {
|
||||
state: PerCompoundState::new(offset),
|
||||
added_entry: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct that collects invalidations for a given compound selector.
|
||||
struct RelativeSelectorDependencyCollector<'a> {
|
||||
map: &'a mut RelativeSelectorInvalidationMap,
|
||||
@@ -770,13 +827,48 @@ struct RelativeSelectorDependencyCollector<'a> {
|
||||
quirks_mode: QuirksMode,
|
||||
|
||||
/// State relevant to a given compound selector.
|
||||
compound_state: PerCompoundState,
|
||||
compound_state: RelativeSelectorPerCompoundState,
|
||||
|
||||
/// The allocation error, if we OOM.
|
||||
alloc_error: &'a mut Option<AllocErr>,
|
||||
}
|
||||
|
||||
impl<'a> RelativeSelectorDependencyCollector<'a> {
|
||||
fn add_non_unique_info(&mut self) -> Result<(), AllocErr> {
|
||||
// Go through this compound again.
|
||||
for ss in self
|
||||
.selector
|
||||
.selector
|
||||
.iter_from(self.compound_state.state.offset)
|
||||
{
|
||||
match ss {
|
||||
Component::LocalName(ref name) => {
|
||||
let dependency = self.dependency();
|
||||
add_local_name(
|
||||
name.name.clone(),
|
||||
dependency,
|
||||
&mut self.map.type_to_selector,
|
||||
)?;
|
||||
if name.name != name.lower_name {
|
||||
let dependency = self.dependency();
|
||||
add_local_name(
|
||||
name.lower_name.clone(),
|
||||
dependency,
|
||||
&mut self.map.type_to_selector,
|
||||
)?;
|
||||
}
|
||||
return Ok(());
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
// Ouch. Add one for *.
|
||||
self.map.any_to_selector.try_reserve(1)?;
|
||||
let dependency = self.dependency();
|
||||
self.map.any_to_selector.push(dependency);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_whole_selector(&mut self) -> bool {
|
||||
let mut iter = self.selector.selector.iter_skip_relative_selector_anchor();
|
||||
let mut index = 0;
|
||||
@@ -789,7 +881,7 @@ impl<'a> RelativeSelectorDependencyCollector<'a> {
|
||||
};
|
||||
loop {
|
||||
// Reset the compound state.
|
||||
self.compound_state = PerCompoundState::new(index);
|
||||
self.compound_state = RelativeSelectorPerCompoundState::new(index);
|
||||
|
||||
// Visit all the simple selectors in this sequence.
|
||||
for ss in &mut iter {
|
||||
@@ -800,7 +892,7 @@ impl<'a> RelativeSelectorDependencyCollector<'a> {
|
||||
}
|
||||
|
||||
if let Err(err) = add_pseudo_class_dependency(
|
||||
self.compound_state.element_state,
|
||||
self.compound_state.state.element_state,
|
||||
self.quirks_mode,
|
||||
self,
|
||||
) {
|
||||
@@ -808,6 +900,14 @@ impl<'a> RelativeSelectorDependencyCollector<'a> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if !self.compound_state.added_entry {
|
||||
// Not great - we didn't add any uniquely identifiable information.
|
||||
if let Err(err) = self.add_non_unique_info() {
|
||||
*self.alloc_error = Some(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let combinator = iter.next_sequence();
|
||||
if let Some(c) = combinator {
|
||||
match c {
|
||||
@@ -832,7 +932,7 @@ impl<'a> Collector for RelativeSelectorDependencyCollector<'a> {
|
||||
let parent = parent_dependency(self.parent_selectors);
|
||||
Dependency {
|
||||
selector: self.selector.selector.clone(),
|
||||
selector_offset: self.compound_state.offset,
|
||||
selector_offset: self.compound_state.state.offset,
|
||||
relative_kind: Some(match self.combinator_count.get_match_hint() {
|
||||
RelativeSelectorMatchHint::InChild => RelativeDependencyInvalidationKind::Parent,
|
||||
RelativeSelectorMatchHint::InSubtree => RelativeDependencyInvalidationKind::Ancestors,
|
||||
@@ -865,12 +965,12 @@ impl<'a> Collector for RelativeSelectorDependencyCollector<'a> {
|
||||
&mut self.map.map.state_affecting_selectors
|
||||
}
|
||||
|
||||
fn attribute_map(&mut self) -> &mut AttributeDependencyMap {
|
||||
fn attribute_map(&mut self) -> &mut LocalNameDependencyMap {
|
||||
&mut self.map.map.other_attribute_affecting_selectors
|
||||
}
|
||||
|
||||
fn update_states(&mut self, element_state: ElementState, document_state: DocumentState) {
|
||||
self.compound_state.element_state |= element_state;
|
||||
self.compound_state.state.element_state |= element_state;
|
||||
*self.document_state |= document_state;
|
||||
}
|
||||
}
|
||||
@@ -897,6 +997,7 @@ impl<'a> SelectorVisitor for RelativeSelectorDependencyCollector<'a> {
|
||||
fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
|
||||
match *s {
|
||||
Component::ID(..) | Component::Class(..) => {
|
||||
self.compound_state.added_entry = true;
|
||||
if let Err(err) = on_id_or_class(s, self.quirks_mode, self) {
|
||||
*self.alloc_error = Some(err.into());
|
||||
return false;
|
||||
@@ -904,12 +1005,20 @@ impl<'a> SelectorVisitor for RelativeSelectorDependencyCollector<'a> {
|
||||
true
|
||||
},
|
||||
Component::NonTSPseudoClass(ref pc) => {
|
||||
if !pc
|
||||
.state_flag()
|
||||
.intersects(ElementState::VISITED_OR_UNVISITED)
|
||||
{
|
||||
// Visited/Unvisited styling doesn't take the usual state invalidation path.
|
||||
self.compound_state.added_entry = true;
|
||||
}
|
||||
if let Err(err) = on_pseudo_class(pc, self) {
|
||||
*self.alloc_error = Some(err.into());
|
||||
return false;
|
||||
}
|
||||
true
|
||||
},
|
||||
Component::RelativeSelectorAnchor => unreachable!("Should not visit this far"),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
@@ -920,6 +1029,7 @@ impl<'a> SelectorVisitor for RelativeSelectorDependencyCollector<'a> {
|
||||
local_name: &LocalName,
|
||||
local_name_lower: &LocalName,
|
||||
) -> bool {
|
||||
self.compound_state.added_entry = true;
|
||||
if let Err(err) = on_attribute(local_name, local_name_lower, self) {
|
||||
*self.alloc_error = Some(err);
|
||||
return false;
|
||||
|
||||
@@ -5,15 +5,27 @@
|
||||
//! Invalidation of element styles relative selectors.
|
||||
|
||||
use crate::data::ElementData;
|
||||
use crate::dom::TElement;
|
||||
use crate::dom::{TElement, TNode};
|
||||
use crate::invalidation::element::invalidation_map::{
|
||||
Dependency, DependencyInvalidationKind, RelativeDependencyInvalidationKind, NormalDependencyInvalidationKind, RelativeSelectorInvalidationMap,
|
||||
};
|
||||
use crate::invalidation::element::invalidator::{
|
||||
DescendantInvalidationLists, Invalidation, InvalidationProcessor, InvalidationResult,
|
||||
InvalidationVector, SiblingTraversalMap, TreeStyleInvalidator,
|
||||
};
|
||||
use crate::invalidation::element::restyle_hints::RestyleHint;
|
||||
use crate::invalidation::element::invalidator::{TreeStyleInvalidator, InvalidationResult, InvalidationProcessor, InvalidationVector, DescendantInvalidationLists, Invalidation, SiblingTraversalMap,};
|
||||
use crate::invalidation::element::invalidation_map::{Dependency, RelativeDependencyInvalidationKind, DependencyInvalidationKind, NormalDependencyInvalidationKind};
|
||||
use crate::invalidation::element::state_and_attributes::{invalidated_descendants, invalidated_self, invalidated_sibling, should_process_descendants, push_invalidation, dependency_may_be_relevant};
|
||||
use crate::invalidation::element::state_and_attributes::{
|
||||
dependency_may_be_relevant, invalidated_descendants, invalidated_self, invalidated_sibling,
|
||||
push_invalidation, should_process_descendants,
|
||||
};
|
||||
use crate::stylist::{CascadeData, Stylist};
|
||||
use dom::ElementState;
|
||||
use fxhash::FxHashMap;
|
||||
use selectors::matching::{
|
||||
ElementSelectorFlags, MatchingContext, MatchingForInvalidation, MatchingMode,
|
||||
NeedsSelectorFlags, QuirksMode, SelectorCaches, VisitedHandlingMode,
|
||||
};
|
||||
use selectors::OpaqueElement;
|
||||
use selectors::matching::{QuirksMode, ElementSelectorFlags, MatchingContext, SelectorCaches, MatchingForInvalidation, MatchingMode, VisitedHandlingMode, NeedsSelectorFlags};
|
||||
use selectors::parser::SelectorKey;
|
||||
use smallvec::SmallVec;
|
||||
use std::ops::DerefMut;
|
||||
@@ -29,6 +41,8 @@ where
|
||||
pub quirks_mode: QuirksMode,
|
||||
/// Callback to trigger when the subject element is invalidated.
|
||||
pub invalidated: fn(E, &InvalidationResult),
|
||||
/// The traversal map that should be used to process invalidations.
|
||||
pub sibling_traversal_map: SiblingTraversalMap<E>,
|
||||
/// Marker for 'a lifetime.
|
||||
pub _marker: ::std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
@@ -89,13 +103,16 @@ where
|
||||
outer: &'a Dependency,
|
||||
host: Option<E>,
|
||||
) {
|
||||
self.invalidations.entry(key).and_modify(|(h, o, d)| {
|
||||
// Just keep one.
|
||||
if *o <= offset {
|
||||
return;
|
||||
}
|
||||
(*h, *o, *d) = (host, offset, outer);
|
||||
}).or_insert_with(|| (host, offset, outer));
|
||||
self.invalidations
|
||||
.entry(key)
|
||||
.and_modify(|(h, o, d)| {
|
||||
// Just keep one.
|
||||
if *o <= offset {
|
||||
return;
|
||||
}
|
||||
(*h, *o, *d) = (host, offset, outer);
|
||||
})
|
||||
.or_insert_with(|| (host, offset, outer));
|
||||
}
|
||||
|
||||
/// Add this dependency, if it is unique (i.e. Different outer dependency or same outer dependency
|
||||
@@ -159,6 +176,87 @@ where
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn collect_all_dependencies_for_element(
|
||||
&mut self,
|
||||
element: E,
|
||||
scope: &Option<E>,
|
||||
quirks_mode: QuirksMode,
|
||||
map: &'a RelativeSelectorInvalidationMap,
|
||||
accept: fn(&Dependency) -> bool,
|
||||
) {
|
||||
element
|
||||
.id()
|
||||
.map(|v| match map.map.id_to_selector.get(v, quirks_mode) {
|
||||
Some(v) => {
|
||||
for dependency in v {
|
||||
if !accept(dependency) {
|
||||
continue;
|
||||
}
|
||||
self.add_dependency(dependency, element, *scope);
|
||||
}
|
||||
},
|
||||
None => (),
|
||||
});
|
||||
element.each_class(|v| match map.map.class_to_selector.get(v, quirks_mode) {
|
||||
Some(v) => {
|
||||
for dependency in v {
|
||||
if !accept(dependency) {
|
||||
continue;
|
||||
}
|
||||
self.add_dependency(dependency, element, *scope);
|
||||
}
|
||||
},
|
||||
None => (),
|
||||
});
|
||||
element.each_attr_name(
|
||||
|v| match map.map.other_attribute_affecting_selectors.get(v) {
|
||||
Some(v) => {
|
||||
for dependency in v {
|
||||
if !accept(dependency) {
|
||||
continue;
|
||||
}
|
||||
self.add_dependency(dependency, element, *scope);
|
||||
}
|
||||
},
|
||||
None => (),
|
||||
},
|
||||
);
|
||||
let state = element.state();
|
||||
map.map.state_affecting_selectors.lookup_with_additional(
|
||||
element,
|
||||
quirks_mode,
|
||||
None,
|
||||
&[],
|
||||
ElementState::empty(),
|
||||
|dependency| {
|
||||
if !dependency.state.intersects(state) {
|
||||
return true;
|
||||
}
|
||||
if !accept(&dependency.dep) {
|
||||
return true;
|
||||
}
|
||||
self.add_dependency(&dependency.dep, element, *scope);
|
||||
true
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(v) = map.type_to_selector.get(element.local_name()) {
|
||||
for dependency in v {
|
||||
if !accept(dependency) {
|
||||
continue;
|
||||
}
|
||||
self.add_dependency(dependency, element, *scope);
|
||||
}
|
||||
}
|
||||
|
||||
for dependency in &map.any_to_selector {
|
||||
if !accept(dependency) {
|
||||
continue;
|
||||
}
|
||||
self.add_dependency(dependency, element, *scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E> RelativeSelectorInvalidator<'a, E>
|
||||
@@ -196,6 +294,45 @@ where
|
||||
self.invalidate_from_dependencies(collector.get());
|
||||
}
|
||||
|
||||
/// Gather relative selector dependencies for the given element (And its subtree) that mutated, and invalidate as necessary.
|
||||
pub fn invalidate_relative_selectors_for_dom_mutation(
|
||||
self,
|
||||
subtree: bool,
|
||||
stylist: &'a Stylist,
|
||||
inherited_search_path: ElementSelectorFlags,
|
||||
accept: fn(&Dependency) -> bool,
|
||||
) {
|
||||
let mut collector = RelativeSelectorDependencyCollector::<'a, E>::new(self.element);
|
||||
let mut traverse_subtree = false;
|
||||
self.element.apply_selector_flags(inherited_search_path);
|
||||
stylist.for_each_cascade_data_with_scope(self.element, |data, scope| {
|
||||
let map = data.relative_selector_invalidation_map();
|
||||
if !map.used {
|
||||
return;
|
||||
}
|
||||
traverse_subtree |= map.needs_ancestors_traversal;
|
||||
collector.collect_all_dependencies_for_element(self.element, &scope, self.quirks_mode, map, accept);
|
||||
});
|
||||
|
||||
if subtree && traverse_subtree {
|
||||
for node in self.element.as_node().dom_descendants() {
|
||||
let descendant = match node.as_element() {
|
||||
Some(e) => e,
|
||||
None => continue,
|
||||
};
|
||||
descendant.apply_selector_flags(inherited_search_path);
|
||||
stylist.for_each_cascade_data_with_scope(descendant, |data, scope| {
|
||||
let map = data.relative_selector_invalidation_map();
|
||||
if !map.used {
|
||||
return;
|
||||
}
|
||||
collector.collect_all_dependencies_for_element(descendant, &scope, self.quirks_mode, map, accept);
|
||||
});
|
||||
}
|
||||
}
|
||||
self.invalidate_from_dependencies(collector.get());
|
||||
}
|
||||
|
||||
/// Carry out complete invalidation triggered by a relative selector invalidation.
|
||||
/// Updates the relative selector search path if provided.
|
||||
fn invalidate_from_dependencies(&self, to_invalidate: ToInvalidate<'a, E>) {
|
||||
@@ -235,15 +372,17 @@ where
|
||||
}
|
||||
},
|
||||
RelativeDependencyInvalidationKind::PrevSibling => {
|
||||
self.element.prev_sibling_element().map(|e| {
|
||||
if !Self::in_search_direction(
|
||||
&e,
|
||||
ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_SIBLING,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
self.handle_anchor(e, outer_dependency, host);
|
||||
});
|
||||
self.sibling_traversal_map
|
||||
.prev_sibling_for(&self.element)
|
||||
.map(|e| {
|
||||
if !Self::in_search_direction(
|
||||
&e,
|
||||
ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_SIBLING,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
self.handle_anchor(e, outer_dependency, host);
|
||||
});
|
||||
},
|
||||
RelativeDependencyInvalidationKind::AncestorPrevSibling => {
|
||||
let mut parent = self.element.parent_element();
|
||||
@@ -267,7 +406,7 @@ where
|
||||
}
|
||||
},
|
||||
RelativeDependencyInvalidationKind::EarlierSibling => {
|
||||
let mut sibling = self.element.prev_sibling_element();
|
||||
let mut sibling = self.sibling_traversal_map.prev_sibling_for(&self.element);
|
||||
while let Some(sib) = sibling {
|
||||
if !Self::in_search_direction(
|
||||
&sib,
|
||||
|
||||
@@ -10,7 +10,7 @@ use cssparser::{Parser, ParserInput, SourceLocation, UnicodeRange};
|
||||
use dom::{DocumentState, ElementState};
|
||||
use malloc_size_of::MallocSizeOfOps;
|
||||
use nsstring::{nsCString, nsString};
|
||||
use selectors::matching::{MatchingForInvalidation, SelectorCaches};
|
||||
use selectors::matching::{ElementSelectorFlags, MatchingForInvalidation, SelectorCaches};
|
||||
use selectors::Element;
|
||||
use servo_arc::{Arc, ArcBorrow};
|
||||
use smallvec::SmallVec;
|
||||
@@ -97,7 +97,7 @@ use style::global_style_data::{
|
||||
GlobalStyleData, PlatformThreadHandle, StyleThreadPool, GLOBAL_STYLE_DATA, STYLE_THREAD_POOL,
|
||||
};
|
||||
use style::invalidation::element::invalidation_map::RelativeSelectorInvalidationMap;
|
||||
use style::invalidation::element::invalidator::InvalidationResult;
|
||||
use style::invalidation::element::invalidator::{InvalidationResult, SiblingTraversalMap};
|
||||
use style::invalidation::element::relative_selector::{
|
||||
RelativeSelectorDependencyCollector, RelativeSelectorInvalidator,
|
||||
};
|
||||
@@ -6783,6 +6783,28 @@ fn add_relative_selector_attribute_dependency<'a>(
|
||||
};
|
||||
}
|
||||
|
||||
fn inherit_relative_selector_search_direction(
|
||||
element: &GeckoElement,
|
||||
prev_sibling: Option<GeckoElement>,
|
||||
) -> ElementSelectorFlags {
|
||||
let mut inherited = ElementSelectorFlags::empty();
|
||||
if let Some(parent) = element.parent_element() {
|
||||
if let Some(direction) = parent.relative_selector_search_direction() {
|
||||
inherited |= direction
|
||||
.intersection(ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_ANCESTOR);
|
||||
}
|
||||
}
|
||||
if let Some(sibling) = prev_sibling {
|
||||
if let Some(direction) = sibling.relative_selector_search_direction() {
|
||||
// Inherit both, for e.g. a sibling with `:has(~.sibling .descendant)`
|
||||
inherited |= direction.intersection(
|
||||
ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_ANCESTOR_SIBLING,
|
||||
);
|
||||
}
|
||||
}
|
||||
inherited
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorIDDependency(
|
||||
raw_data: &PerDocumentStyleData,
|
||||
@@ -6798,6 +6820,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorIDDependency(
|
||||
element,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map: SiblingTraversalMap::default(),
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
@@ -6838,6 +6861,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorClassDependency(
|
||||
element,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map: SiblingTraversalMap::default(),
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
@@ -6881,6 +6905,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorAttributeDepende
|
||||
element,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map: SiblingTraversalMap::default(),
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
@@ -6919,6 +6944,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorStateDependency(
|
||||
element,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map: SiblingTraversalMap::default(),
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
@@ -6940,6 +6966,201 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorStateDependency(
|
||||
);
|
||||
}
|
||||
|
||||
fn invalidate_relative_selector_prev_sibling_side_effect(
|
||||
prev_sibling: GeckoElement,
|
||||
quirks_mode: QuirksMode,
|
||||
sibling_traversal_map: SiblingTraversalMap<GeckoElement>,
|
||||
stylist: &Stylist,
|
||||
) {
|
||||
let invalidator = RelativeSelectorInvalidator {
|
||||
element: prev_sibling,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map,
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
invalidator.invalidate_relative_selectors_for_dom_mutation(
|
||||
false,
|
||||
&stylist,
|
||||
ElementSelectorFlags::empty(),
|
||||
|d| d.right_combinator_is_next_sibling(),
|
||||
);
|
||||
}
|
||||
|
||||
fn invalidate_relative_selector_next_sibling_side_effect(
|
||||
next_sibling: GeckoElement,
|
||||
quirks_mode: QuirksMode,
|
||||
sibling_traversal_map: SiblingTraversalMap<GeckoElement>,
|
||||
stylist: &Stylist,
|
||||
) {
|
||||
let invalidator = RelativeSelectorInvalidator {
|
||||
element: next_sibling,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map,
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
invalidator.invalidate_relative_selectors_for_dom_mutation(
|
||||
false,
|
||||
&stylist,
|
||||
ElementSelectorFlags::empty(),
|
||||
|d| d.dependency_is_relative_with_single_next_sibling(),
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForInsertion(
|
||||
raw_data: &PerDocumentStyleData,
|
||||
element: &RawGeckoElement,
|
||||
) {
|
||||
let element = GeckoElement(element);
|
||||
let data = raw_data.borrow();
|
||||
let quirks_mode: QuirksMode = data.stylist.quirks_mode();
|
||||
|
||||
let inherited =
|
||||
inherit_relative_selector_search_direction(&element, element.prev_sibling_element());
|
||||
if inherited.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ok, we could've been inserted between two sibling elements that were connected
|
||||
// through next sibling. This can happen in two ways:
|
||||
// * `.a:has(+ .b)`
|
||||
// * `:has(.. .a + .b ..)`
|
||||
// Note that the previous sibling may be the anchor, and not part of the invalidation chain.
|
||||
// Either way, there must be siblings to both sides of the element being inserted
|
||||
// to consider it.
|
||||
match (element.prev_sibling_element(), element.next_sibling_element()) {
|
||||
(Some(prev_sibling), Some(next_sibling)) => {
|
||||
invalidate_relative_selector_prev_sibling_side_effect(
|
||||
prev_sibling,
|
||||
quirks_mode,
|
||||
SiblingTraversalMap::new(
|
||||
prev_sibling,
|
||||
prev_sibling.prev_sibling_element(),
|
||||
element.next_sibling_element(),
|
||||
), // Pretend this inserted element isn't here.
|
||||
&data.stylist,
|
||||
);
|
||||
invalidate_relative_selector_next_sibling_side_effect(
|
||||
next_sibling,
|
||||
quirks_mode,
|
||||
SiblingTraversalMap::new(
|
||||
next_sibling,
|
||||
Some(prev_sibling),
|
||||
next_sibling.next_sibling_element(),
|
||||
),
|
||||
&data.stylist,
|
||||
);
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
|
||||
|
||||
let invalidator = RelativeSelectorInvalidator {
|
||||
element,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map: SiblingTraversalMap::default(),
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
invalidator.invalidate_relative_selectors_for_dom_mutation(
|
||||
true,
|
||||
&data.stylist,
|
||||
inherited,
|
||||
|_| true,
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForAppend(
|
||||
raw_data: &PerDocumentStyleData,
|
||||
first_element: &RawGeckoElement,
|
||||
) {
|
||||
let first_element = GeckoElement(first_element);
|
||||
let data = raw_data.borrow();
|
||||
let quirks_mode: QuirksMode = data.stylist.quirks_mode();
|
||||
|
||||
let inherited = inherit_relative_selector_search_direction(
|
||||
&first_element,
|
||||
first_element.prev_sibling_element(),
|
||||
);
|
||||
if inherited.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut element = Some(first_element);
|
||||
while let Some(e) = element {
|
||||
let invalidator = RelativeSelectorInvalidator {
|
||||
element: e,
|
||||
quirks_mode,
|
||||
sibling_traversal_map: SiblingTraversalMap::default(),
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
invalidator.invalidate_relative_selectors_for_dom_mutation(
|
||||
true,
|
||||
&data.stylist,
|
||||
inherited,
|
||||
|_| true,
|
||||
);
|
||||
element = e.next_sibling_element();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForRemoval(
|
||||
raw_data: &PerDocumentStyleData,
|
||||
element: &RawGeckoElement,
|
||||
prev_sibling: Option<&RawGeckoElement>,
|
||||
next_sibling: Option<&RawGeckoElement>,
|
||||
) {
|
||||
let element = GeckoElement(element);
|
||||
|
||||
let next_sibling = next_sibling.map(|e| GeckoElement(e));
|
||||
let prev_sibling = prev_sibling.map(|e| GeckoElement(e));
|
||||
let data = raw_data.borrow();
|
||||
let quirks_mode: QuirksMode = data.stylist.quirks_mode();
|
||||
|
||||
let inherited = inherit_relative_selector_search_direction(&element, prev_sibling);
|
||||
if inherited.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Same comment as insertion applies.
|
||||
match (prev_sibling, next_sibling) {
|
||||
(Some(prev_sibling), Some(next_sibling)) => {
|
||||
invalidate_relative_selector_prev_sibling_side_effect(
|
||||
prev_sibling,
|
||||
quirks_mode,
|
||||
SiblingTraversalMap::default(),
|
||||
&data.stylist
|
||||
);
|
||||
invalidate_relative_selector_next_sibling_side_effect(
|
||||
next_sibling,
|
||||
quirks_mode,
|
||||
SiblingTraversalMap::default(),
|
||||
&data.stylist,
|
||||
);
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
let invalidator = RelativeSelectorInvalidator {
|
||||
element,
|
||||
quirks_mode,
|
||||
sibling_traversal_map: SiblingTraversalMap::new(element, prev_sibling, next_sibling),
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
invalidator.invalidate_relative_selectors_for_dom_mutation(
|
||||
true,
|
||||
&data.stylist,
|
||||
inherited,
|
||||
|_| true,
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_HasStateDependency(
|
||||
raw_data: &PerDocumentStyleData,
|
||||
@@ -7155,6 +7376,7 @@ fn process_relative_selector_invalidations(
|
||||
element: *element,
|
||||
quirks_mode,
|
||||
invalidated: relative_selector_invalidated_at,
|
||||
sibling_traversal_map: SiblingTraversalMap::default(),
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
[attribute-or-elemental-selectors-in-has.html]
|
||||
[add descendant to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[add "div > descendant" to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[add div.child to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[add "div > div.descendant" to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[add div#div_descendant to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[add "div#div_descendant" to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[add div[attrname\] to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[add "div > div[attrname\]" to #div_subject: div#div_subject.color]
|
||||
expected: FAIL
|
||||
@@ -1,46 +1,4 @@
|
||||
[child-indexed-pseudo-classes-in-has.html]
|
||||
[Prepend #div1.green: #only_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div1.green: #first_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div1.green: #last_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div1.green: #nth_child_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #first_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #last_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #nth_child_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #nth_child_3n_2]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #first_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #last_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #nth_child_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #nth_child_3n_2]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #nth_child_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div4: #last_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div4: #nth_child_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
@@ -50,9 +8,6 @@
|
||||
[Prepend #div4: #nth_child_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div5: #last_child]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div5: #nth_child_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
@@ -62,20 +17,8 @@
|
||||
[Prepend #div5: #nth_child_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div1: #last_child]
|
||||
[Prepend #div4: #first_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div1: #nth_child_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div1: #nth_child_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div2: #last_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div2: #nth_child_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div4: #only_child]
|
||||
[Prepend #div5: #first_child]
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
[dir-pseudo-class-in-has.html]
|
||||
expected: FAIL
|
||||
@@ -1,8 +0,0 @@
|
||||
[empty-pseudo-in-has.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Insert div#child to #subject]
|
||||
expected: FAIL
|
||||
|
||||
[Insert div to div.#child]
|
||||
expected: FAIL
|
||||
@@ -1,3 +0,0 @@
|
||||
[fullscreen-pseudo-class-in-has.html]
|
||||
[:fullscreen pseudo-class invalidation with requestFullscreen + remove]
|
||||
expected: FAIL
|
||||
@@ -1,264 +0,0 @@
|
||||
[has-in-adjacent-position.html]
|
||||
[insert element div.test before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
@@ -1,362 +0,0 @@
|
||||
[has-in-ancestor-position.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[insert element div.test before subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject_ancestor]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before subject_parent]
|
||||
expected: FAIL
|
||||
@@ -1,170 +0,0 @@
|
||||
[has-in-parent-position.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[insert element div.test before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject_parent]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject_descendant]
|
||||
expected: FAIL
|
||||
@@ -1,264 +0,0 @@
|
||||
[has-in-sibling-position.html]
|
||||
[insert element div.test before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div[test_attr\] after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element in the tree inserted after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element in the tree inserted again after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div>div[test_attr\] after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again before next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after previous_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after previous_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after subject]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' again to the element inserted after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[add the class 'test' to the element inserted again after next_sibling_descendant]
|
||||
expected: FAIL
|
||||
@@ -1,5 +0,0 @@
|
||||
[has-invalidation-after-removing-non-first-element.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[remove descendant: div#subject.color]
|
||||
expected: FAIL
|
||||
@@ -1,6 +0,0 @@
|
||||
[has-invalidation-for-wiping-an-element.html]
|
||||
[color after inserting text and div > .descendant: div#subject.color]
|
||||
expected: FAIL
|
||||
|
||||
[color after inserting text and #child > .descendant: div#subject.color]
|
||||
expected: FAIL
|
||||
@@ -1,86 +0,0 @@
|
||||
[has-sibling.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[insert element div.test before first_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before second_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before third_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before first_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before first_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before third_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test before third_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after first_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after second_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after third_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after first_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after first_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after third_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div.test after third_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before first_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before second_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before third_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before first_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before first_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before third_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test before third_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after first_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after second_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after third_sibling]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after first_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after first_sibling_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after third_sibling_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div.test after third_sibling_descendant]
|
||||
expected: FAIL
|
||||
@@ -1,26 +0,0 @@
|
||||
[has-with-not.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[insert element div before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert element div after subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div before subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div>div before subject_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div.test after subject_child]
|
||||
expected: FAIL
|
||||
|
||||
[insert tree div.test after subject_descendant]
|
||||
expected: FAIL
|
||||
@@ -1,6 +0,0 @@
|
||||
[has-with-nth-child.html]
|
||||
[:nth-child() no longer matching after removal]
|
||||
expected: FAIL
|
||||
|
||||
[:nth-child() in non-subject no longer matching after removal]
|
||||
expected: FAIL
|
||||
@@ -1,29 +0,0 @@
|
||||
[input-pseudo-classes-in-has.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[:checked & :indeterminate invalidation on <input>]
|
||||
expected: FAIL
|
||||
|
||||
[:indeterminate invalidation on <progress>]
|
||||
expected: FAIL
|
||||
|
||||
[:disabled invalidation]
|
||||
expected: FAIL
|
||||
|
||||
[:read-only invalidation]
|
||||
expected: FAIL
|
||||
|
||||
[:valid invalidation]
|
||||
expected: FAIL
|
||||
|
||||
[:default invalidation with input[type=radio\]]
|
||||
expected: FAIL
|
||||
|
||||
[:required invalidation]
|
||||
expected: FAIL
|
||||
|
||||
[:out-of-range invalidation]
|
||||
expected: FAIL
|
||||
|
||||
[:placeholder-shown invalidation]
|
||||
expected: FAIL
|
||||
@@ -1,62 +1,17 @@
|
||||
[is-pseudo-containing-sibling-relationship-in-has.html]
|
||||
[sibling selector enclosed by :is() no longer matching after removal (1)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector enclosed by :is() no longer matching after removal (2)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector enclosed by :is() no longer matching after removal (3)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector enclosed by :is() no longer matching after removal (4)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector in non-subject enclosed by :is() no longer matching after removal (1)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector in non-subject enclosed by :is() no longer matching after removal (2)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector in non-subject enclosed by :is() no longer matching after removal (3)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector in non-subject enclosed by :is() no longer matching after removal (4)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector in non-subject enclosed by :is() no longer matching after removal (5)]
|
||||
expected:
|
||||
if not asan and tsan: [FAIL, PASS]
|
||||
if asan: [FAIL, PASS]
|
||||
FAIL
|
||||
|
||||
[:nth-child() enclosed by :is() no longer matching after removal (1)]
|
||||
expected:
|
||||
if not asan and tsan: [FAIL, PASS]
|
||||
if asan: [FAIL, PASS]
|
||||
FAIL
|
||||
|
||||
[:nth-child() enclosed by :is() no longer matching after removal (2)]
|
||||
expected: FAIL
|
||||
|
||||
[:nth-last-child() enclosed by :is() no longer matching after removal (2)]
|
||||
expected: FAIL
|
||||
|
||||
[:nth-child() in non-subject enclosed by :is() no longer matching after removal (1)]
|
||||
expected: FAIL
|
||||
|
||||
[:nth-child() in non-subject enclosed by :is() no longer matching after removal (2)]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector in parent selector enclosed by :is() no longer matching after removal]
|
||||
expected: FAIL
|
||||
|
||||
[sibling selector in parent selector non-subject position enclosed by :is() no longer matching after removal (1)]
|
||||
expected:
|
||||
if tsan: [FAIL, PASS]
|
||||
FAIL
|
||||
|
||||
[sibling selector in parent selector non-subject position enclosed by :is() no longer matching after removal (2)]
|
||||
expected: FAIL
|
||||
|
||||
[Initially red]
|
||||
expected:
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
[link-pseudo-in-has.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[CSS Selectors Invalidation: :link, :visited :any-link, pseudo-class in :has() argument]
|
||||
expected: FAIL
|
||||
@@ -1,11 +0,0 @@
|
||||
[modal-pseudo-class-in-has.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [ERROR, TIMEOUT, OK]
|
||||
[:modal pseudo-class invalidation with showModal + remove]
|
||||
expected: FAIL
|
||||
|
||||
[:modal pseudo-class invalidation with requestFullscreen + exitFullscreen]
|
||||
expected: FAIL
|
||||
|
||||
[:modal pseudo-class invalidation with requestFullscreen + remove]
|
||||
expected: FAIL
|
||||
@@ -1,3 +0,0 @@
|
||||
[not-pseudo-containing-sibling-relationship-in-has.html]
|
||||
[:nth-child() enclosed by :not() matching after insertion]
|
||||
expected: FAIL
|
||||
@@ -1,87 +1,6 @@
|
||||
[typed-child-indexed-pseudo-classes-in-has.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Prepend #div1.green: #only_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div1.green: #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div1.green: #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div1.green: #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (2): #only_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (2): #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (2): #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (2): #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div2.yellow: #nth_of_type_3n_2]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (3): #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (3): #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (3): #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (3): #nth_of_type_3n_2]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #nth_of_type_3n_2]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div3.orange: #nth_of_type_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (4): #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (4): #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (4): #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (4): #nth_of_type_3n_2]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (4): #nth_of_type_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div4: #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div4: #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
@@ -91,9 +10,6 @@
|
||||
[Prepend #div4: #nth_of_type_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (5): #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (5): #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
@@ -103,9 +19,6 @@
|
||||
[Prepend span (5): #nth_of_type_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div5: #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend #div5: #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
@@ -115,9 +28,6 @@
|
||||
[Prepend #div5: #nth_of_type_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (6): #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Prepend span (6): #nth_of_type_3n_1]
|
||||
expected: FAIL
|
||||
|
||||
@@ -127,20 +37,14 @@
|
||||
[Prepend span (6): #nth_of_type_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div1: #last_of_type]
|
||||
[Prepend #div4: #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div1: #nth_of_type_3n_1]
|
||||
[Prepend span (5): #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div1: #nth_of_type_3n]
|
||||
[Prepend #div5: #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div2: #last_of_type]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div2: #nth_of_type_3n]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #div4: #only_of_type]
|
||||
[Prepend span (6): #first_of_type]
|
||||
expected: FAIL
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selector Invalidation: Invalidate :has() as result of insertion/removal</title>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
|
||||
<style>
|
||||
div, main { color: grey }
|
||||
#subject:has(+ #next_sibling) { color: red; }
|
||||
#prev_sibling:has(+ #subject + #next_sibling) { color: green; }
|
||||
</style>
|
||||
|
||||
<main id=main>
|
||||
<div id=prev_sibling></div>
|
||||
<div id=subject></div>
|
||||
<div id=blocks_match></div>
|
||||
<div id=next_sibling></div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const grey = 'rgb(128, 128, 128)';
|
||||
const red = 'rgb(255, 0, 0)';
|
||||
const green = 'rgb(0, 128, 0)';
|
||||
|
||||
function testColors(test_name, subject_color, prev_sibling_color) {
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(subject).color, subject_color);
|
||||
assert_equals(getComputedStyle(prev_sibling).color, prev_sibling_color);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
testColors('Initial colors', grey, grey);
|
||||
|
||||
const d = blocks_match;
|
||||
d.remove();
|
||||
|
||||
testColors('Matches after #blocks_match removed', red, green);
|
||||
subject.after(d);
|
||||
|
||||
testColors('Does not match after #blocks_match added', grey, grey);
|
||||
</script>
|
||||
Reference in New Issue
Block a user