Skip to content

Commit

Permalink
fix: avoid chromium issue with dispatching blur on element removal (#…
Browse files Browse the repository at this point in the history
…13694)

* fix: avoid chromium issue with dispatching blur on element removal

* fix: avoid chromium issue with dispatching blur on element removal

* fix: avoid chromium issue with dispatching blur on element removal

* active effect too

* try/finally
  • Loading branch information
trueadm authored Oct 19, 2024
1 parent 793a8de commit bb491f1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/seven-dancers-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: avoid chromium issue with dispatching blur on element removal
26 changes: 20 additions & 6 deletions packages/svelte/src/internal/client/reactivity/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
set_is_destroying_effect,
set_is_flushing_effect,
set_signal_status,
untrack
untrack,
set_active_effect
} from '../runtime.js';
import {
DIRTY,
Expand Down Expand Up @@ -375,13 +376,26 @@ export function destroy_effect(effect, remove_dom = true) {
/** @type {TemplateNode | null} */
var node = effect.nodes_start;
var end = effect.nodes_end;
var previous_reaction = active_reaction;
var previous_effect = active_effect;

while (node !== null) {
/** @type {TemplateNode | null} */
var next = node === end ? null : /** @type {TemplateNode} */ (get_next_sibling(node));
// Really we only need to do this in Chromium because of https://chromestatus.com/feature/5128696823545856,
// as removal of the DOM can cause sync `blur` events to fire, which can cause logic to run inside
// the current `active_reaction`, which isn't what we want at all. Additionally, the blur event handler
// might create a derived or effect and they will be incorrectly attached to the wrong thing
set_active_reaction(null);
set_active_effect(null);
try {
while (node !== null) {
/** @type {TemplateNode | null} */
var next = node === end ? null : /** @type {TemplateNode} */ (get_next_sibling(node));

node.remove();
node = next;
node.remove();
node = next;
}
} finally {
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}

removed = true;
Expand Down

0 comments on commit bb491f1

Please sign in to comment.