Bug 1548848 - Moving assigned nodes caused by slot removal should properly invalidate layout; r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D30194

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Edgar Chen 2019-05-08 10:39:40 +00:00
Родитель ab5e4d5362
Коммит f551bbe0a8
2 изменённых файлов: 35 добавлений и 8 удалений

Просмотреть файл

@ -267,17 +267,20 @@ void ShadowRoot::RemoveSlot(HTMLSlotElement* aSlot) {
const bool wasFirstSlot = currentSlots->ElementAt(0) == aSlot;
currentSlots.RemoveElement(*aSlot);
// Move assigned nodes from removed slot to the next slot in
// tree order with the same name.
if (!wasFirstSlot) {
return;
}
// Move assigned nodes from removed slot to the next slot in
// tree order with the same name.
InvalidateStyleAndLayoutOnSubtree(aSlot);
HTMLSlotElement* replacementSlot = currentSlots->ElementAt(0);
const nsTArray<RefPtr<nsINode>>& assignedNodes = aSlot->AssignedNodes();
bool slottedNodesChanged = !assignedNodes.IsEmpty();
if (assignedNodes.IsEmpty()) {
return;
}
InvalidateStyleAndLayoutOnSubtree(replacementSlot);
while (!assignedNodes.IsEmpty()) {
nsINode* assignedNode = assignedNodes[0];
@ -285,10 +288,8 @@ void ShadowRoot::RemoveSlot(HTMLSlotElement* aSlot) {
replacementSlot->AppendAssignedNode(assignedNode);
}
if (slottedNodesChanged) {
aSlot->EnqueueSlotChangeEvent();
replacementSlot->EnqueueSlotChangeEvent();
}
aSlot->EnqueueSlotChangeEvent();
replacementSlot->EnqueueSlotChangeEvent();
}
// FIXME(emilio): There's a bit of code duplication between this and the

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Scoping: Dynamic reassignment of a slot.</title>
<link rel="author" title="Edgar Chen" href="mailto:echen@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1548848">
<link rel="match" href="reference/green-box.html"/>
<div id="host">
<div id="green" style="background: green"></div>
<div>
<script>
let root = host.attachShadow({mode: 'open'});
root.innerHTML = `
<style>::slotted(div),div { width: 100px; height: 100px }</style>
<p>Test passes if you see a single 100px by 100px green box below.</p>
<slot id="slot"></slot>
<slot>
<div style="background: red"></div>
</slot>
`;
onload = function () {
root.offsetTop; // Update layout
root.getElementById('slot').remove();
};
</script>