Removing Slotted Content Crashes Safari

It seems that removing slotted content *after* removing the slot is tripping Safari.

by David Iglesias

HTML

<div id="container">
  <div id="slotted" slot="something">Some content (DOM)</div>
</div>

<!-- The target DOM structure is:

div#container
  :shadowRoot
  |  div#bg
  |    slot[name=something]
  `
  div#slotted[slot=something]

-->

CSS

html, body {
  width: 100%;
  height: 100%;
  margin: 0px;
  padding: 0px;
}

body {
  background: red;
}

#container {
  width: 100%;
  height: 100%;
  background: yellow;
}

JavaScript

const slotName = 'something';
const timeoutMs = 1000;

// Removing this element later triggers the issue
const slotted = document.querySelector('#slotted');

// Attach shadow DOM on #container...
const container = document.querySelector('#container');
const shadow = container.attachShadow({
  mode: 'open',
});

// A named slot for the shadow DOM
const slot = document.createElement('slot');
slot.setAttribute('name', slotName);

// Populate the contents of the shadow DOM of #container.
window.setTimeout(() => {
  // Put slot into a green div...
  const bg = document.createElement('div');
  bg.style.backgroundColor = 'green';
  bg.style.width = '100%';
  bg.style.height = '100%';

  bg.appendChild(slot);

  // Append the green div into the shadow root.
  shadow.appendChild(bg);
}, timeoutMs);

// (You can also dynamically add the content, it doesn't seem to matter)
/*
let slotted = document.createElement('div');
slotted.innerText = 'Some content...';
slotted.setAttribute('slot', slotName);

container.appendChild(slotted);
*/

// This needs to happen first, in a separate tick.
window.setTimeout(() => {
  slot.remove();
}, 2 * timeoutMs);

// This will trigger the bug, and 
// make the whole #container lose layout/disappear.
window.setTimeout(() => {
  slotted.remove();
}, 3 * timeoutMs);

// If slot.remove and slotted.remove happen in the same timeout, the issue doesn't happen, regardless of their order
// If slotted.remove happens *before* slot.remove, the issue doesn't happen.
// If slotted is re-assigned to a different slot, and then both are deleted, the issue doesn't happen (this is our current workaround).