From 21c818ce76692eb4de480009e5925c2f61e4371a Mon Sep 17 00:00:00 2001 From: hackademix Date: Sat, 19 Oct 2024 23:32:46 +0200 Subject: [PATCH] Improved prompts factory. --- src/ui/Prompts.js | 94 ++++++++++++++++++++++++++++++------------- src/ui/prompt.js | 3 +- src/ui/resize_hack.js | 13 ++++-- 3 files changed, 76 insertions(+), 34 deletions(-) diff --git a/src/ui/Prompts.js b/src/ui/Prompts.js index cbcd731..37ad00e 100644 --- a/src/ui/Prompts.js +++ b/src/ui/Prompts.js @@ -37,58 +37,94 @@ var Prompts = (() => { async open(data) { promptData = data; this.close(); + + let url = browser.runtime.getURL("ui/prompt.html"); let {width, height, left, top, parent } = data.features; let options = { - url: browser.runtime.getURL("ui/prompt.html"), + url, type: "popup", - width, - height, - }; + } + + if (!parent) { + parent = await browser.windows.getCurrent(); + } + if (UA.isMozilla) { options.allowScriptsToClose = true; } + if (!("windows" in browser)) { // Android, most likely - this.currentTab = await browser.tabs.create({url: options.url}); + this.currentTab = await browser.tabs.create({url}); return; } - if (!parent) parent = await browser.windows.getCurrent() - let popup = this.currentWindow = await browser.windows.create(options); + + const centerOnParent = (dim) => { + const { width, height } = dim; + dim.left = + left === undefined + ? Math.round(parent.left + (parent.width - width) / 2) + : left; + dim.top = + top === undefined + ? Math.round(parent.top + (parent.height - height) / 2) + : top; + return dim; + }; + + if (width && height) { + let size = { width, height }; + url += `?size=${JSON.stringify(size)}`; + if (parent) { + ({ left, top } = Object.assign(options, centerOnParent(size))); + } + } + debug("Prompt pre-opening options", options, left, top, width, height); // DEV_ONLY + let popup = (this.currentWindow = await browser.windows.create(options)); if (parent) { - // center to the given parent window (default last focused browser tab) - if (left === undefined) left = Math.round(parent.left + (parent.width - popup.width) / 2); - if (top === undefined) top = Math.round(parent.top + (parent.height - popup.height) / 2); + ({ left, top } = centerOnParent({ + width: width || popup.width, + height: height || popup.height, + })); } else { - // features.parent explicitly nulled: use given left & top or default to auto-centering on main screen - if (left === undefined) ({left} = popup); - if (top === undefined) ({top} = popup); + // use given left & top or default to auto-centering on main screen + if (left === undefined) ({ left } = popup); + if (top === undefined) ({ top } = popup); } - // work around for letterboxing changes (https://bugzilla.mozilla.org/show_bug.cgi?id=1330882) - let {width: popupWidth, height: popupHeight} = popup; - if (width && height && (popupWidth !== width || popupHeight !== height)) { - left += Math.round((popupWidth - width) / 2); - top += Math.round((popupHeight - height) / 2); - await browser.windows.update(popup.id, - {left, top, width, height, focused: false}); - } + debug("Prompt post-opening options", popup, options, left, top, width, height); - for (let attempts = 2; attempts-- > 0;) { - // position gets set only 2nd time, moz bug? - await browser.windows.update(popup.id, - {left, top, focused: false}); - } - if (parent) { - await browser.windows.update(parent.id, {focused: true}); + // work around for resistFingerprinting new window rounding (https://bugzilla.mozilla.org/show_bug.cgi?id=1330882) + if ( + width && + height && + (popup.width !== width || + popup.height !== height || + popup.left !== left || + popup.top !== top) + ) { + popup = await browser.windows.update(popup.id, { + left, + top, + width, + height, + }); + for (let attempts = 2; attempts-- > 0; ) { + debug("Resizing", popup, { left, top, width, height }); // DEV_ONY + popup = await browser.windows.update(popup.id, { width, height }); + if (popup.width == width || popup.height == height) { + break; + } + } } } + async close() { if (this.currentWindow) { try { await browser.windows.remove(this.currentWindow.id); } catch (e) { - debug(e); } this.currentWindow = null; } else if (this.currentTab) { diff --git a/src/ui/prompt.js b/src/ui/prompt.js index e052d2f..a4dc802 100644 --- a/src/ui/prompt.js +++ b/src/ui/prompt.js @@ -19,9 +19,8 @@ */ (async () => { - document.documentElement.classList.toggle("mobile", !!UA.mobile); let data = await Messages.send("getPromptData"); - debug(data); + debug("Prompt data", data); if (!data) { error("Missing promptData"); window.close(); diff --git a/src/ui/resize_hack.js b/src/ui/resize_hack.js index a393ca7..525cfcc 100644 --- a/src/ui/resize_hack.js +++ b/src/ui/resize_hack.js @@ -24,12 +24,19 @@ if ("windows" in browser) document.addEventListener("DOMContentLoaded", async e // See https://bugzilla.mozilla.org/show_bug.cgi?id=1402110 let win = await browser.windows.getCurrent({populate: true}); if (win.tabs[0].url === document.URL) { - debug("Resize hack"); + let size = decodeURIComponent(location.search).match(/\bsize=(\{\s*"width":[^}]+\})/); + try { + size = size && JSON.parse(size[1]); + } catch (e) { + size = null; + } + let {width, height} = size || win; + debug("Resize hack", win, size, width, height); // DEV_ONLY await browser.windows.update(win.id, { - width: win.width + 1 + width: width + 1, height }); await browser.windows.update(win.id, { - width: win.width + width, height }); } });