extension wont work as soon as started - google-chrome

I am learning how to make chrome extensions and for my extension to work on every tab i have added the following event listeners in background.js:
tabs.onActivated, tabs.onCreated, tabs.onUpdated, and browserAction.onClicked(this one is used to change the flag am sending in message every time the extension button is pressed)
for all these events i send a message to one of the content script js file and that file changes some content according to the recieved message.
Problem is: If i start chrome and the extension isn't active yet, on activating the extension i need to refresh all the opened tabs for it to work otherwise it doesn't send any messages to the content script of the opened tabs, even on clicking the extension icon.
Is there a way by which the extension can start working immediately as i start it without the need of refresh?

Related

Chrome Extension Manifest V3 Screen Recording Ends When Changing the Tab

I am trying to migrate my extension which records screen/tab/window according to the chosen option from manifest V2 to V3. In manifest V2 I was able to use background script as persistent and reach html page objects such as mediaRecorder, navigator. However in manifest V3 background script works as a service worker. So, I have to start the screen record in content-scripts to be able to reach the html objects. When I start chrome.desktopCapture API from the background script, I have to start the screenRecord in one of the tabs (should give a tabid to chrome.desktopCapture.chooseDesktopMedia API call). I cannot start it on the background page and when the page was refreshed or changed to a new URL screen record stops. Is there any workaround for this?
I believe the best way to handle updates such as a URL change on a tab is to attach the onUpdated listener to the chrome tabs in the background script.
chrome.tabs.onUpdated.addListener(function(tabId, changes, tab) {
//Detect Type of Change and Handle Accordingly
});
There are quite a few other events that may be of use that are listed in the chrome documentation Chrome Tabs Events. It's also possible to inject inline JavaScript from the content script so you can access the pages window object directly and attach event listeners there to handle reloads or URL changes. Check this stack overflow post for more information Modify Window Object in Chrome Extension

How can I close tabs related to the extension when browser closes

I need to close tabs related to the extension, like tabs with url chrome-extension://<extension-id>/index.html, when a browser closes
In the background script, I tried to close tabs with chrome.tabs.remove function when chrome.windows.onRemoved event fired, but looks like it fires too late when tabs not available. Also, because Chrome doesn't open immediately, I tried to use chrome.windows.onCreated event, but turned out it only worked on my computer with Windows and didn't work on Mac.
Am I doing something wrong or maybe there is another way to close them, like adding a script on every page that will be executed when the browser closes?

Google Cloud Messaging for Chrome - a received message is not shown as a popup

I downloaded Google push-sample-app code, removed the key from the manifest, uploaded the app to the Chrome Web Store, then installed it in Chrome from the Web Store.
Now chrome://extensions/ lists the app as "Enabled", with "Inspect views: background page (Inactive)".
Chrome Task Manager doesn't list the app as currently running.
If at chrome://extensions/ tab, I click "background page (Inactive)" link for "Push Messaging Sample" app, then an inspect view shows up in a separate Chrome window, and a new entry appears in the Chrome Task Manager: "Background Page: Push Messaging Sample". As long as an inspect view Chrome window is open, an event page "background.js" doesn't get offloaded. And When a message is sent to the push messaging service, a popup window with the message text appears.
If I close the inspect view Chrome window, and send a message to the push messaging service, Chrome Task Manager shows that an event page "background.js" gets loaded, then offloaded in a few seconds disappearing from the Task manager. However, a popup window with a message does not appear.
How this app needs to be changed to show popup messages without any extra Chrome windows running?
The sample app does not show notification from "background page is inactive" state because when the background page is woken up, the event handler for chrome.pushMessaging.onMessage is not set up.
When user launches the app by clicking on its icon, the chrome.app.runtime.onLaunched() event is fired. But when background page is activated because of some incoming event (like push messaging or alarm), the onLaunched is not fired - instead, only the 'initial script', the JS code outside of functions, is executed. The initial script of background page must register event listeners so after initial load Chrome knows which handler to call. The sample app only registers the onMessage handler in onLaunched, but not from initial script.
It is easy to 'fix' the sample app - just move the call of setupPush() from onLaunched() handler to the very end of background.js file:
background.js:
....
// When a Push Message arrives, show it as a text notification (toast)
function showPushMessage(payload, subChannel) {
var notification = window.webkitNotifications.createNotification(
'icon.png', 'Push Message',
"Push message for you! " +
payload +" [" + subChannel + "]");
notification.show();
}
setupPush(); // <-- this executes every time page loads, not only in onLaunched
This will cause setupPush() to be executed every time background page is activated, whether user launched the app or the app is started in background in response to incoming push message.
This question / answer explained what is missing:
"Because the listeners themselves only exist in the context of the event page, you must use addListener each time the event page loads; only doing so at runtime.onInstalled by itself is insufficient."
To fix push-sample-app, all is needed is to add to background.js:
// Register with the Push Messaging system for the Push Message.
chrome.pushMessaging.onMessage.addListener(messageCallback);

Inconsistency with listeners - onUpdated on one machine and onReplaced on another machine

I'm using the next code in my eventPage.js (backgroundPage replacement by google) and I'm facing some weird inconsistency.
This is the scenario:
First Machine:
Opening new tab ->
onActivated
onUpdated
onUpdated
onUpdated
Entering URL ->
onUpdated
onUpdated
entering another URL ->
onUpdated
onUpdated
Second Machine:
Opening new tab ->
onActivated
Entering URL
onReplaced
onActivated
entering another URL
onReplaced
onActivated
This is my code:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab)
{
console.log("onUpdated");
});
chrome.tabs.onActivated.addListener(function(tabId, changeInfo, tab)
{
console.log("onActivated");
});
chrome.tabs.onReplaced.addListener(function(tabId, changeInfo, tab)
{
console.log("onReplaced");
});
After a lot of debugging I've found that the cause of this difference is the option "Predict network actions to improve page load performance" in Google Chrome Settings.
In the first machine the option above is not selected and is working as expected.
Is that expected behavior for the second machine?
From the documentation I can somehow understand the onReplaced status:
Fired when a tab is replaced with another tab due to prerendering or
instant.
Although it is very poorly documented and there's no way knowing that that option is somehow related to the onUpdated onReplaced statuses but I really don't understand the onActivated statuses in the second machine and why there's a difference between the first machine and the second machine.
I couldn't find any documentation about this behavior on the web. On stackoverflow I could hardly find one question that mentions the onReplaced listener but didn't had any info I can use.
Thanks
Having the "Predict network actions..." option checked, causes Chrome to try to predict your next action (i.e. what resource or page you are likely to request next) and load it in the background (before you make the request). As soon as you do actually request that resource or page, Chrome will not have to first load it and then serve it to you; rather it just serves the pre-loaded instance. This improves performance (as long as the prediction of your next actions is accurate).
To serve a pre-loaded page, Chrome replaces the current tab (that's when the onReplaced is triggered) with a tab that has the page already loaded in the background (the replacing tab becomes active, thus the onActivated event). Because the content has been loaded in the replacing tab beforehand, there is no onUpdated event.
From Chrome's whitepaper on prerender:
Prerendering extends the concept of prefetching. Instead of just downloading the top-level resource, it does all of the work necessary to show the page to the user—without actually showing it until the user clicks. Prerendering behaves similarly to if a user middle-clicked on a link on a page (opening it in a background tab) and then later switched to that tab. However, in prerendering, that “background tab” is totally hidden from the user, and when the user clicks, its contents are seamlessly swapped into the same tab the user was viewing. From the user’s perspective, the page simply loads much faster than before.
Web developers can trigger prerendering as described below. Beginning in Chrome 17, Chrome itself will initiate prerendering in some cases, based on the user's interactions with the address bar.

Chromium pass message to popup extension even if it is not active

I am developing a chrome extension. I am able to pass a message from background page to popup extension when a context menu is clicked if i open the popup page with "Inspect pop-up" selection. Because it stays open in this way.
But if I click the context menu when the popup page is not opened, no message received by it.
Do you have any suggestions to open popup automatically, make it stay open or send message to it when even if it is not active.
There is no way to pragmatically open a popup window. Popup windows are only active when the popup is open which is why you cant send messages to it when it is closed.
You could either queue messages in the background page and have them retrieved the next time the popup window is opened. Or depending on the functionality you might look into using HTML5 desktop notifications instead.
Instead of sending stuff to the popup, the popup should request what it needs when it is opened.
Because the popup is just an HTML page, it doesn't exist until it has been opened.
Basically, like abraham mentioned, you would store any information in the background, using localStorage or chrome.storage. When the popup opens, it should then use the chrome.extension.getBackgroundPage() function to get a reference to the background, which can provide access to the stored information.
If you are using localStorage or chrome.storage, you may be able to access it directly, without using the background, as storage is shared across the whole extension.