Adds a new ShinyRemovedObserver class that's conceptually similar to ShinyResizeObserver but instead calls a callback function on matching elements when they're removed from the DOM.
In this case, we instantiate a static cardRemovedObserver on the Card class that watches the ~card's parent element~ the document.body for changes and exits full screen mode when a full-screen card is removed.
Note that we can't watch the parent element because the card might be in a layout_columns() in a renderUI() (this is pretty common). The ShinyRemovedObserver is careful to do as little work as needed to find the matching elements, and I think the abstraction is still worth it. We might want to use it in other places and the callback in the Card class is easier to read and understand without the boilerplate of MutationObserver.
Example app
This example app contains a card that is dynamically rendered inside a renderUI(). When the card is modified in full screen mode, the currently-full-screen card is removed from the DOM and replaced with a new card (or not replaced at all, it's dynamic UI!).
Previously, we were not cleaning up the full screen state when a full-screen card was removed. Now, we see the old, full-screen card was removed and we call the exit full screen methods to reset the full screen state.
Fixes #1003
Adds a new
ShinyRemovedObserver
class that's conceptually similar toShinyResizeObserver
but instead calls a callback function on matching elements when they're removed from the DOM.In this case, we instantiate a static
cardRemovedObserver
on theCard
class that watches the ~card's parent element~ thedocument.body
for changes and exits full screen mode when a full-screen card is removed.Note that we can't watch the parent element because the card might be in a
layout_columns()
in arenderUI()
(this is pretty common). TheShinyRemovedObserver
is careful to do as little work as needed to find the matching elements, and I think the abstraction is still worth it. We might want to use it in other places and the callback in theCard
class is easier to read and understand without the boilerplate ofMutationObserver
.Example app
This example app contains a card that is dynamically rendered inside a
renderUI()
. When the card is modified in full screen mode, the currently-full-screen card is removed from the DOM and replaced with a new card (or not replaced at all, it's dynamic UI!).Previously, we were not cleaning up the full screen state when a full-screen card was removed. Now, we see the old, full-screen card was removed and we call the exit full screen methods to reset the full screen state.