Show dialogs again when an extension moves them
Bitwarden moves elements around in <body>. A moved dialog stayed open but fell out of the top layer to the bottom of the page, so the Decoy confirmation seemed to vanish and the checkbox stayed ticked unsaved.
This commit is contained in:
@@ -257,13 +257,26 @@
|
|||||||
else if (okMsg) toast(okMsg);
|
else if (okMsg) toast(okMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dialog shows a modal dialog. Extensions such as Bitwarden move elements
|
||||||
|
// around in <body>; a moved dialog stays open but drops out of the top
|
||||||
|
// layer to the bottom of the page, so it is shown as a modal again. That
|
||||||
|
// goes through close(), whose close event arrives after the dialog is open
|
||||||
|
// again and is kept from the listeners added by callers.
|
||||||
function dialog(build) {
|
function dialog(build) {
|
||||||
const d = h('dialog');
|
const d = h('dialog');
|
||||||
const close = () => d.close();
|
const close = () => d.close();
|
||||||
d.addEventListener('close', () => d.remove());
|
const moved = new MutationObserver(() => {
|
||||||
|
if (d.open && d.isConnected && !d.matches(':modal')) { d.close(); d.showModal(); }
|
||||||
|
});
|
||||||
|
d.addEventListener('close', (e) => {
|
||||||
|
if (d.open) { e.stopImmediatePropagation(); return; }
|
||||||
|
moved.disconnect();
|
||||||
|
d.remove();
|
||||||
|
});
|
||||||
d.append(build(close));
|
d.append(build(close));
|
||||||
document.body.append(d);
|
document.body.append(d);
|
||||||
d.showModal();
|
d.showModal();
|
||||||
|
moved.observe(document.body, { childList: true, subtree: true });
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user