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 a confirmation seemed to vanish and its 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