From db88d8be8958eda1c2f494de2aeb9300f26dd6aa Mon Sep 17 00:00:00 2001 From: "YUKI \"Piro\" Hiroshi" Date: Wed, 1 Jun 2022 02:51:00 +0900 Subject: [PATCH] Shrink confirmation dialog for grouped tabs to smaller than the owner window #3136 --- webextensions/background/background.js | 91 +---------------- .../background/handle-tab-bunches.js | 7 +- webextensions/common/dialog.js | 97 ++++++++++++++++++- 3 files changed, 103 insertions(+), 92 deletions(-) diff --git a/webextensions/background/background.js b/webextensions/background/background.js index a4202b58d..c3c1dd5f5 100644 --- a/webextensions/background/background.js +++ b/webextensions/background/background.js @@ -542,24 +542,12 @@ export async function confirmToCloseTabs(tabs, { windowId, configKey, messageKey const win = await browser.windows.get(windowId); const listing = configs.warnOnCloseTabsWithListing ? - tabsToHTMLList(tabs, { + Dialog.tabsToHTMLList(tabs, { maxHeight: Math.round(win.height * 0.8), maxWidth: Math.round(win.width * 0.75) }) : ''; - browser.runtime.onMessage.addListener(function onMessage(message, sender) { - switch (message.type) { - case Constants.kNOTIFY_CONFIRMATION_DIALOG_READY: - browser.runtime.onMessage.removeListener(onMessage); - tryRepositionDialogToCenterOfOwner({ - ...message, - dialogWindowId: sender.tab.windowId, - }); - break; - } - }); - const result = await Dialog.show(win, { content: `
${sanitizeForHTMLText(browser.i18n.getMessage(messageKey || 'warnOnCloseTabs_message', [count]))}
${listing} @@ -574,11 +562,7 @@ export async function confirmToCloseTabs(tabs, { windowId, configKey, messageKey type: 'common-dialog', // for popup url: '/resources/blank.html', // for popup, required on Firefox ESR68 title: browser.i18n.getMessage(titleKey || 'warnOnCloseTabs_title'), // for popup - inject: { - type: Constants.kNOTIFY_CONFIRMATION_DIALOG_READY, - windowId, - }, - onShownInPopup(container, { type, windowId }) { + onShownInPopup(container) { setTimeout(() => { // this need to be done on the next tick, to use the height of // the box for calculation of dialog size @@ -586,16 +570,6 @@ export async function confirmToCloseTabs(tabs, { windowId, configKey, messageKey style.height = '0px'; // this makes the box shrinkable style.maxHeight = 'none'; style.minHeight = '0px'; - // We cannot move this window by this callback function, thus I just send - // a request to update window position. - browser.runtime.sendMessage({ - type, - ownerWindowId: windowId, - availLeft: screen.availLeft, - availTop: screen.availTop, - availWidth: screen.availWidth, - availHeight: screen.availHeight, - }); }, 0); } }); @@ -617,67 +591,6 @@ Commands.onTabsClosing.addListener((tabIds, options = {}) => { return confirmToCloseTabs(tabIds.map(Tab.get), options); }); -async function tryRepositionDialogToCenterOfOwner({ dialogWindowId, ownerWindowId, availLeft, availTop, availWidth, availHeight }) { - const [dialogWin, ownerWin] = await Promise.all([ - browser.windows.get(dialogWindowId), - browser.windows.get(ownerWindowId), - ]); - const placedOnOwner = ( - dialogWin.left + dialogWin.width - (dialogWin.width / 2) < ownerWin.left && - dialogWin.top + dialogWin.height - (dialogWin.height / 2) < ownerWin.top && - dialogWin.left + (dialogWin.width / 2) < ownerWin.left + ownerWin.width && - dialogWin.top + (dialogWin.height / 2) < ownerWin.top + ownerWin.height - ); - const placedInsideViewArea = ( - dialogWin.left >= availLeft && - dialogWin.top >= availTop && - dialogWin.left + dialogWin.width <= availLeft + availWidth && - dialogWin.top + dialogWin.height <= availTop + availHeight - ); - if (placedOnOwner && placedInsideViewArea) - return; - - const top = ownerWin.top + Math.round((ownerWin.height - dialogWin.height) / 2); - const left = ownerWin.left + Math.round((ownerWin.width - dialogWin.width) / 2); - return browser.windows.update(dialogWin.id, { - left: Math.min(availLeft + availWidth - dialogWin.width, Math.max(availLeft, left)), - top: Math.min(availTop + availHeight - dialogWin.height, Math.max(availTop, top)), - }); -} - -export function tabsToHTMLList(tabs, { maxHeight, maxWidth }) { - const rootLevelOffset = tabs.map(tab => parseInt(tab.$TST.getAttribute(Constants.kLEVEL) || 0)).sort()[0]; - return ( - `` - ); -} - function reserveToClearGrantedRemovingTabs() { const lastGranted = configs.grantedRemovingTabIds.join(','); setTimeout(() => { diff --git a/webextensions/background/handle-tab-bunches.js b/webextensions/background/handle-tab-bunches.js index 2b1d86b84..10f10784e 100644 --- a/webextensions/background/handle-tab-bunches.js +++ b/webextensions/background/handle-tab-bunches.js @@ -24,7 +24,6 @@ import Tab from '/common/Tab.js'; import * as TabsGroup from './tabs-group.js'; import * as TabsOpen from './tabs-open.js'; import * as Tree from './tree.js'; -import * as Background from './background.js'; function log(...args) { internalLogger('background/handle-tab-bunches', ...args); @@ -245,7 +244,11 @@ async function confirmToAutoGroupNewTabsFromOthers(tabs) { const win = await browser.windows.get(windowId); const listing = configs.warnOnAutoGroupNewTabsWithListing ? - Background.tabsToHTMLList(tabs, { maxRows: configs.warnOnAutoGroupNewTabsWithListingMaxRows }) : + Dialog.tabsToHTMLList(tabs, { + maxRows: configs.warnOnAutoGroupNewTabsWithListingMaxRows, + maxHeight: Math.round(win.height * 0.8), + maxWidth: Math.round(win.width * 0.75) + }) : ''; const result = await Dialog.show(win, { content: ` diff --git a/webextensions/common/dialog.js b/webextensions/common/dialog.js index 7e379a3d3..3cccc5e98 100644 --- a/webextensions/common/dialog.js +++ b/webextensions/common/dialog.js @@ -11,6 +11,7 @@ import { log as internalLogger, configs, isMacOS, + sanitizeForHTMLText, } from '/common/common.js'; import * as Constants from './constants.js'; @@ -79,9 +80,42 @@ export async function show(ownerWindow, dialogParams) { else { log('showDialog: show in a popup window on ', ownerWindow.id); UserOperationBlocker.blockIn(ownerWindow.id, { throbber: false }); + browser.runtime.onMessage.addListener(function onMessage(message, sender) { + switch (message.type) { + case Constants.kNOTIFY_CONFIRMATION_DIALOG_READY: + browser.runtime.onMessage.removeListener(onMessage); + tryRepositionDialogToCenterOfOwner({ + ...message, + dialogWindowId: sender.tab.windowId, + }); + break; + } + }); + const callback = dialogParams.onShownInPopup || dialogParams.onShown; result = await RichConfirm.showInPopup(ownerWindow.id, { ...dialogParams, - onShown: dialogParams.onShownInPopup || dialogParams.onShown, + inject: { + ...(dialogParams.inject || {}), + __dialog__reportScreenMessageType: Constants.kNOTIFY_CONFIRMATION_DIALOG_READY, + __dialog__ownerWindowId: ownerWindow.id, + }, + onShown: [ + ...(Array.isArray(callback) ? callback : [callback]), + (container, { __dialog__reportScreenMessageType, __dialog__ownerWindowId }) => { + setTimeout(() => { + // We cannot move this window by this callback function, thus I just send + // a request to update window position. + browser.runtime.sendMessage({ + type: __dialog__reportScreenMessageType, + ownerWindowId: __dialog__ownerWindowId, + availLeft: screen.availLeft, + availTop: screen.availTop, + availWidth: screen.availWidth, + availHeight: screen.availHeight, + }); + }, 0); + }, + ], onHidden(...params) { UserOperationBlocker.unblockIn(ownerWindow.id, { throbber: false }); unblocked = true; @@ -100,3 +134,64 @@ export async function show(ownerWindow, dialogParams) { } return result; } + +async function tryRepositionDialogToCenterOfOwner({ dialogWindowId, ownerWindowId, availLeft, availTop, availWidth, availHeight }) { + const [dialogWin, ownerWin] = await Promise.all([ + browser.windows.get(dialogWindowId), + browser.windows.get(ownerWindowId), + ]); + const placedOnOwner = ( + dialogWin.left + dialogWin.width - (dialogWin.width / 2) < ownerWin.left && + dialogWin.top + dialogWin.height - (dialogWin.height / 2) < ownerWin.top && + dialogWin.left + (dialogWin.width / 2) < ownerWin.left + ownerWin.width && + dialogWin.top + (dialogWin.height / 2) < ownerWin.top + ownerWin.height + ); + const placedInsideViewArea = ( + dialogWin.left >= availLeft && + dialogWin.top >= availTop && + dialogWin.left + dialogWin.width <= availLeft + availWidth && + dialogWin.top + dialogWin.height <= availTop + availHeight + ); + if (placedOnOwner && placedInsideViewArea) + return; + + const top = ownerWin.top + Math.round((ownerWin.height - dialogWin.height) / 2); + const left = ownerWin.left + Math.round((ownerWin.width - dialogWin.width) / 2); + return browser.windows.update(dialogWin.id, { + left: Math.min(availLeft + availWidth - dialogWin.width, Math.max(availLeft, left)), + top: Math.min(availTop + availHeight - dialogWin.height, Math.max(availTop, top)), + }); +} + +export function tabsToHTMLList(tabs, { maxHeight, maxWidth }) { + const rootLevelOffset = tabs.map(tab => parseInt(tab.$TST.getAttribute(Constants.kLEVEL) || 0)).sort()[0]; + return ( + `` + ); +}