42176e8b1f29
broaden modal detection to form ancestor + position:fixed fallback (v3.6.132)
- time
- 2026-05-29 17:10 UTC · 5 months ago
- machine
- koh2
- parent
- 91ca0c3fee4e
↓ peach-browser-42176e8b.tar.gzatlas at this save
files changed4 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/content/inject.ts+23 −7manifest.firefox.json+1 −1
@@ -2,7 +2,7 @@22 "_comment_audio_capture": "Firefox does not honor the Chrome 'audioCapture' optional_permission — getUserMedia in WebExtensions is gated solely by the runtime permission prompt. Microphone access for chirp pairing works from the popup under the existing '<all_urls>' host permission; no manifest entry is required or accepted here.",33 "manifest_version": 3,44 "name": "Peach Password Manager",5- "version": "3.6.131",5+ "version": "3.6.132",66 "description": "Zero-knowledge password manager",77 "browser_specific_settings": {88 "gecko": {manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "3.6.131",4+ "version": "3.6.132",55 "description": "Zero-knowledge password manager",66 "action": {77 "default_popup": "src/popup/index.html",package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "peach",3- "version": "3.6.131",3+ "version": "3.6.132",44 "description": "Zero-knowledge password manager",55 "type": "module",66 "scripts": {src/content/inject.ts+23 −7
@@ -1253,14 +1253,30 @@12531253 options: SelectorOptions = {}12541254 ): () => void {12551255 const host = document.createElement("div");1256- // When anchorEl is inside a focus-trapping modal (aria-modal, role=dialog, <dialog>),1257- // the modal's JS focus trap fires when Peach's internal inputs gain focus (they are1258- // outside the modal in the DOM), immediately blurring them and closing the identity1259- // suggest list. Fix: detect the modal ancestor and append the host inside it so focus1256+ // When anchorEl is inside a focus-trapping modal the modal's JS focus trap fires1257+ // when Peach's internal inputs gain focus (they are outside the modal's DOM subtree),1258+ // immediately blurring them and closing the identity suggest list.1259+ // Fix: detect the containing form or modal and append the host INSIDE it so focus12601260 // traps see Peach as within the modal. Use position:fixed so the popup positions1261- // correctly relative to the viewport — overflow and transforms on the modal cannot1262- // clip or misplace a fixed child.1263- const modalAncestor = anchorEl.closest<HTMLElement>('dialog, [aria-modal="true"], [role="dialog"]');1261+ // correctly relative to the viewport regardless of the container's CSS context —1262+ // overflow:hidden and most transforms do not affect fixed children.1263+ //1264+ // Detection priority:1265+ // 1. <form> ancestor — always inside any focus-trap container wrapping the form1266+ // 2. ARIA modal (dialog / aria-modal / role=dialog)1267+ // 3. position:fixed ancestor — catches modals that omit ARIA attributes1268+ const modalAncestor = (1269+ anchorEl.closest<HTMLElement>('form') ??1270+ anchorEl.closest<HTMLElement>('dialog, [aria-modal="true"], [role="dialog"]') ??1271+ (() => {1272+ let cur: HTMLElement | null = anchorEl.parentElement;1273+ while (cur && cur !== document.body) {1274+ if (window.getComputedStyle(cur).position === 'fixed') return cur;1275+ cur = cur.parentElement;1276+ }1277+ return null;1278+ })()1279+ );12641280 host.style.cssText = `position: ${modalAncestor ? "fixed" : "absolute"}; z-index: 2147483647;`;12651281 host.style.setProperty("--peach-accent", accentHex);12661282 host.style.setProperty("--peach-accent-dim", withAlpha(accentHex, "28"));