Skip to content

Commit

Permalink
Bug 1874705: Run invalidation on appended elements even if the first …
Browse files Browse the repository at this point in the history
…node is not an element. r=firefox-style-system-reviewers,emilio

Differential Revision: https://phabricator.services.mozilla.com/D198604
  • Loading branch information
dshin-moz committed Jan 16, 2024
1 parent fd25a02 commit fd910dd
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 19 deletions.
4 changes: 1 addition & 3 deletions layout/base/RestyleManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,7 @@ void RestyleManager::ContentAppended(nsIContent* aFirstNewContent) {
}
}
#endif
if (aFirstNewContent->IsElement()) {
StyleSet()->MaybeInvalidateForElementAppend(*aFirstNewContent->AsElement());
}
StyleSet()->MaybeInvalidateForElementAppend(*aFirstNewContent);

const auto selectorFlags = container->GetSelectorFlags() &
NodeSelectorFlags::AllSimpleRestyleFlagsForAppend;
Expand Down
5 changes: 3 additions & 2 deletions layout/style/ServoStyleSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1435,9 +1435,10 @@ void ServoStyleSet::MaybeInvalidateForElementInsertion(
&aElement);
}

void ServoStyleSet::MaybeInvalidateForElementAppend(const Element& aElement) {
void ServoStyleSet::MaybeInvalidateForElementAppend(
const nsIContent& aFirstContent) {
Servo_StyleSet_MaybeInvalidateRelativeSelectorForAppend(mRawData.get(),
&aElement);
&aFirstContent);
}

void ServoStyleSet::MaybeInvalidateForElementRemove(
Expand Down
7 changes: 4 additions & 3 deletions layout/style/ServoStyleSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,11 @@ class ServoStyleSet {
void MaybeInvalidateForElementInsertion(const dom::Element&);

/**
* Maybe invalidate if a DOM element append might require us to restyle
* the relative selector to ancestors/previous siblings.
* Maybe invalidate if a series of nodes is appended, among which may
* be element(s) that might require us to restyle the relative selector
* to ancestors/previous siblings.
*/
void MaybeInvalidateForElementAppend(const dom::Element&);
void MaybeInvalidateForElementAppend(const nsIContent&);

/**
* Maybe invalidate if a DOM element removal might require us to restyle
Expand Down
28 changes: 17 additions & 11 deletions servo/ports/geckolib/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6948,11 +6948,11 @@ fn add_relative_selector_attribute_dependency<'a>(
}

fn inherit_relative_selector_search_direction(
element: &GeckoElement,
parent: Option<GeckoElement>,
prev_sibling: Option<GeckoElement>,
) -> ElementSelectorFlags {
let mut inherited = ElementSelectorFlags::empty();
if let Some(parent) = element.parent_element() {
if let Some(parent) = parent {
if let Some(direction) = parent.relative_selector_search_direction() {
inherited |= direction
.intersection(ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_ANCESTOR);
Expand Down Expand Up @@ -7271,7 +7271,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForInsertion(
let quirks_mode: QuirksMode = data.stylist.quirks_mode();

let inherited =
inherit_relative_selector_search_direction(&element, element.prev_sibling_element());
inherit_relative_selector_search_direction(element.parent_element(), element.prev_sibling_element());
// Technically, we're not handling breakouts, where the anchor is a (later-sibling) descendant.
// For descendant case, we're ok since it's a descendant of an element yet to be styled.
// For later-sibling descendant, `HAS_SLOW_SELECTOR_LATER_SIBLINGS` is set anyway.
Expand Down Expand Up @@ -7349,19 +7349,25 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForInsertion(
#[no_mangle]
pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForAppend(
raw_data: &PerDocumentStyleData,
first_element: &RawGeckoElement,
first_node: &RawGeckoNode,
) {
let first_element = GeckoElement(first_element);
let data = raw_data.borrow();
let quirks_mode: QuirksMode = data.stylist.quirks_mode();

let first_node = GeckoNode(first_node);
let inherited = inherit_relative_selector_search_direction(
&first_element,
first_element.prev_sibling_element(),
first_node.parent_element(),
first_node.prev_sibling_element(),
);
if inherited.is_empty() {
return;
}
let first_element = if let Some(e) = first_node.as_element() {
e
} else if let Some(e) = first_node.next_sibling_element() {
e
} else {
return;
};
let data = raw_data.borrow();
let quirks_mode: QuirksMode = data.stylist.quirks_mode();

let mut element = Some(first_element);
while let Some(e) = element {
Expand Down Expand Up @@ -7418,7 +7424,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForRemoval(
let data = raw_data.borrow();
let quirks_mode: QuirksMode = data.stylist.quirks_mode();

let inherited = inherit_relative_selector_search_direction(&element, prev_sibling);
let inherited = inherit_relative_selector_search_direction(element.parent_element(), prev_sibling);
if inherited.is_empty() {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html class="reftest-wait">
<link rel="author" title="David Shin" href="mailto:[email protected]">
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874705">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<style>
#dut {
width: 100px;
height: 100px;
background: red;
}
#dut:has(span) {
background: green;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="dut"></div>
<script>
function raf() {
return new Promise(resolve => {
requestAnimationFrame(resolve);
});
}

async function go() {
await raf();
await raf();
const df = document.createDocumentFragment();
const t = document.createTextNode('\n');
df.appendChild(t);
const s = document.createElement("span");
df.appendChild(s);
dut.appendChild(df);
document.documentElement.className = '';
}

go();
</script>
</html>

0 comments on commit fd910dd

Please sign in to comment.