I have an extension that generates content in the built-in chrome sidebar on click of an element in the current page. I also am using a content script to add some highlighting to the clicked element so that it can be kept in context. However, on closing of the sidepanel I'd like to remove this highlighting as it is no longer relevant. But I can't seem to find an onClose event for the sidepanel's 'x' button that would fire when the panel is not visible.
Searched through the documentation. I found chrome.runtime.onSuspend but that didn't seem to work in my case - I tried calling it from my contentscript but that wasn't a recognized event in chrome.runtime in that context.
I have an extension that generates content in the built-in chrome sidebar on click of an element in the current page. I also am using a content script to add some highlighting to the clicked element so that it can be kept in context. However, on closing of the sidepanel I'd like to remove this highlighting as it is no longer relevant. But I can't seem to find an onClose event for the sidepanel's 'x' button that would fire when the panel is not visible.
Searched through the documentation. I found chrome.runtime.onSuspend but that didn't seem to work in my case - I tried calling it from my contentscript but that wasn't a recognized event in chrome.runtime in that context.
Share Improve this question asked Sep 8, 2023 at 1:59 Kate RKate R 4256 silver badges16 bronze badges 5- Does this answer your question? Find out whether Chrome console is open – Ilja KO Commented Sep 8, 2023 at 2:05
- Kind of. The hack with window size works for the sidePanel as well, though it's not ideal. The rest of that question only applies to the Chrome console, not the sidepanel. – Kate R Commented Sep 8, 2023 at 15:42
- Following up on this - the window size works but is unreliable. It doesn't work if the user has the browser zoomed. – Kate R Commented Sep 26, 2023 at 16:45
- for zooming there is other options with the screen pixel ratios. Just multiply everything you get with that number -> developer.mozilla/en-US/docs/Web/API/Window/… – Ilja KO Commented Oct 10, 2023 at 4:14
- Unless I'm missing something, using device pixel ratio doesn't work across different devices. The base device pixel ratio at 100% on my mac is 2, but if I then use an external monitor or an older laptop it is 1. how do I differentiate these scenarios? – Kate R Commented Oct 16, 2023 at 18:23
3 Answers
Reset to default 14There is no close event for the side panel but with a little trick you can detect if the sidepanel was closed:
You can simulate the event by opening a permanent connection between the side panel and the background script. This connection fires an onDisconnect event if the side panel gets closed.
sidepanel.js:
chrome.runtime.connect({ name: 'mySidepanel' });
The background script can add a listener and react accordingly.
background.js:
chrome.runtime.onConnect.addListener(function (port) {
if (port.name === 'mySidepanel') {
port.onDisconnect.addListener(async () => {
console.log('Sidepanel closed.');
});
}
});
This is what i do in my extension and it works perfect with me
this utility open a window and await until it's closed, you can also export the popup variable if you need it in your code, also you can change the height and width logic to be passed as params.
import { Tabs, Windows } from "webextension-polyfill";
import WindowType = Tabs.WindowType;
let popup: Windows.Window | undefined;
let popupRequestId: string | undefined;
const closePopup = async () => {
// try to close the popup if possible
try {
if (popup?.id) {
await windows.remove(popup.id);
}
} catch {
// ignore
}
};
export const openPopup = async (type: WindowType = "popup", requestId: string = "") => {
const lastFocused = await windows.getLastFocused();
const { top = 0, left = 0, width = 0 } = lastFocused;
if (popupRequestId === requestId) {
if (popup?.id) {
await windows.update(popup.id, {
focused: true,
drawAttention: true,
});
}
} else {
popupRequestId = requestId;
if (popup) {
await closePopup();
}
popup = await windows.create({
type,
url: `./index.html?requestId=${requestId}`,
width: 360,
height: 628, // +28 (the toolbar height)
focused: true,
left: Math.max(left + width - 360 - 20, 0),
top: top + 20,
});
return new Promise(resolve => {
const onRemoved = (windowId: number) => {
if (popup && windowId === popup.id) {
popup = undefined;
popupRequestId = undefined;
windows.onRemoved.removeListener(onRemoved);
}
resolve(true);
};
windows.onRemoved.addListener(onRemoved);
});
}
};
here is how to use it:
const test = async () => {
await openPopup("panel", "unique id");
// popup is closed :)
};
You have window.innerWidth
which tells us the effective size of our HTML page and window.outerWidth
, which gives us our page size + UI elements of the browser, such as the side bar. You can get the difference and pare it to a threshold.
Note that some people have toolbars or vertical tabs and it might interfere, but in most cases it's good
You might be able to detect the changes in the window UI like this:
window.outerWidth - window.innerWidth > threshold
And you can also track it's changes which signals opening and closing of UI elements if you want more accuracy and detecting when it is opened by listening to the resize
event.