Whenever an extension's popup is closed, its entire context is destroyed.
Given that I've got a React tree there, I don't want it to unmount and lose its state whenever the user closes the popup.
Is it possible to make the popup's context persistent?
Related
I am trying to create a Chrome extension that adds a panel to the DevTools console.
The extension will have permission to interact with all urls, so to respect my users, I want to ensure that nothing is running when the devtools panel is closed.
The only thing the DevTool panel needs from the attached page (and all of its iframes) is to listen to a custom event dispatched on the respective window (could also be a postMessage)
window.addEventListener('my-custom-event', e => console.log(e.detail))
I understand that you cannot attach listeners directly from the DevTools panel onto the page/frames and you need a content_script to shuttle the messages forward (as described here).
The issue is, the content_script is always appended to the page regardless of whether the panel is open or not. It sets a listener and basically doesn't run unless the listener transfers a port to communicate on.
I would feel irresponsible knowing that my content script runs on every page, potentially impacting the performance of that page so I'd like them to only be attached to the page when the devtools panel is open and the page reloaded.
Ideally I would like to implement a "recording" button which, only when enabled, the content_script is added to the page. This is to avoid noise when doing performance profiling.
So my question is:
Can you inject content_script only when the DevTools panel is open and
Are you able to programmatically toggle content_script injection?
I'm currently developing an extension that comes in different parts:
- background script (Chrome background.js
- content script (Chrome content-script.js)
- popup script (popup.js and loaded from the iFrame)
- iframe.html (iframe to be loaded when user activate the extension)
It works great except that I lose all the settings/context (used in the popup script to display info in the iframe) when the user change of page or reload the page in the tab.
Technically I want to isolate the extension per tab (each tab can have its own config) but when a user navigate in a same tab the context should be kept.
Question is: what is the best way to achieve that?
I'm thinking about persisting all the context in the content script and reload it when the event chrome.tabs.onUpdated is fired. Is it the right approach?
I recommend you to read about chrome.storage. You can store data there, both background and content script have access to it.
And probably you will need chrome.runtime.sendMessage and chrome.runtime.onMessage to have conversation between background and content. Each time content script runs in a tab it can request background whether this tab have some existing data or not.
I'm testing edge cases for my chrome extension; handling cases where the user has not yet granted the permissions I need.
My popup calls chrome.identity.getAuthToken and, as expected, the user is show the chrome permissions screen and asked to approve.
But, as a side-effect, this closes my popup. I'd like to either keep the popup open, or re-open it after permission has been granted. Is this possible?
'Popup' is ambiguous.
A page action can be triggered dynamically using chrome.pageAction.show(integer tabId).
A browser action cannot.
I don't know about chrome.identity.getAuthToken but e. g. chrome.permissions.request does not close a page action.
I don't think there is a way to stop it closing either. E. g. a beforeUnload event listener does not seem to work.
Any Xpages application update in design causes the application refresh which removes scope variables, session etc. When this occures and there is a page opened in users browser with some partial refresh action buttons ... such buttons simply do nothing when clicked which is quite confusing. No message that's warning the user that the page is stale or something. Is there a way how to detect such situation in general so I can inform user in browser with some dialog that he should reload the entire page?
For all scope variables above request (which gets initialized when you send a request and is always shiny and new) you never can take their existence for granted. Best example: user leaves a form open, locks the PC, goes for lunch, lets the session expire (which also deletes the view scope). (S)he comes back, opens a new tab and logs in - so there is a valid (new) session, hits submit in the first tab -> bum all your code fails.
This is the same scenario as an updated design short of the scenario Panu was pointing to.
So in your code check for the existence of your scoped variables and force a full refresh. Or (I like that better) add an error to the page so that gets displayed with an appropriate action.
I want to log text on any webpage (using content-script to handle selection) into a database that is popup's resource in order to collect text in one place.
what i am trying
I create a database in popup page and try to manage it from content-script though popup is not active (not opened) by using chrome messaging but cannot make the popup receives any message from content-script.
I'm not sure about using messaging to solve this problem.
Is there any better solution?
A content script cannot send a message to an invisible popup, because the popup's context is inactive (closed) when it's hidden.
There are several solutions to your problem.
Option 1: No message passing, use storage events
If your "database" is in fact a simple key-value store, switch to the chrome.storage API. This API is available to the Content script and the popup, and comes with an event to notify you of value changes.
Example:
// Get notified of changes (in the popup?)
chrome.storage.onChanged.addListener(function(changes, areaName) {
// Do whatever you want with the changes.
});
// Initialization of the popup (print initial information?)
chrome.storage.local.get({keyName: 'defaultValue'}, function(items) {
// Do something with items.keyName
});
// Content script, storage (remember document title?)
chrome.storage.local.set({keyName: document.title});
Option 2: Pass messages to the background/event page
The popup and the background / event page share the same process. Any database tied to the popup is also available to the background page, and vice versa. A high-level overview of this method:
Content script sends a message to the background page.
The background page stores the value in the database
If the popup is open, update the popup's view.
If the popup is opened (so it was closed before), it should read the database (either directly, or by reading data from the background page using chrome.runtime.getBackgroundPage) and handle the results.
I've provided the code corresponding to this flow in this answer.