I'm trying to create a chrome extension which detects if the user's page has been changed or has he switched to a new url. But whenever a new tab is created i then as well get the event. How can i avoid it?
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tabs) => {
if (changeInfo.url !== null && changeInfo.status == 'complete') {
console.log("URL CHANGED")
}
})
I want to log only when a website is loaded not the tab is created and loaded
Related
I'm trying to send the URL's of every tab in a window from background.js to another file (sketch.js). My background.js is sending every URL but my other files listener only picks up one URL (the current tab). In the end I want to be able to open a new tab and see a list of all the current open tabs and their URL's.
background.js:
chrome.browserAction.onClicked.addListener(buttonClicked)
function buttonClicked(){
chrome.tabs.query({currentWindow:true},function(tabs){
tabs.forEach(function(tab){
chrome.tabs.sendMessage(tab.id,tab.title);
console.log(tab.title)
});
});
}
sketch.js:
chrome.runtime.onMessage.addListener(gotMessage);
var messagesReceived = 0;
function gotMessage(message,sender,sendResponse){
console.log("\n");
console.log(message);
messagesReceived += 1;
console.log(messagesReceived);
}
I'm building a search app and when a user tries to navigate to the URL of a search result, I want to:
A) open a new tab with that URL if they don't already have that URL open in an existing tab, or
B) if they already have a tab with that URL open, make that existing tab active and refrain from opening another new tab with that same URL.
Separately from the code below, I have a currentTabs dict that's keeping track of the tabId and URL of each open tab so that I can compare the incoming URL to the already open URLs.
I'm trying to add a listener on
chrome.webRequest.onBeforeRequest
to accomplish this. I'm using a query string like ?from_my_app=true so that I only implement this behavior on links from my app rather than any time someone tries to navigate to a URL they already have open. My code looks like this:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
if (details.url.match(/?from_my_app=true/)) {
var strippedUrl = (details.url.split('?from_my_app=true')[0];
var matchedUrl;
if (currentTabs.tabs) {
// get the first pre-existing tab that has this url
matchedUrl = currentTabs.tabs.filter(x => x[1] == strippedUrl)[0];
}
if (matchedUrl) {
// make the pre-existing tab with this url active
// and cancel the opening of a new tab opening this url
chrome.tabs.update(matchedUrl[0], { active: true });
return { cancel: true }
} else {
// if this URL isn't already open in a tab, remove the
// ?from_my_app=true query string and open it in a new
// tab
return { redirectUrl: strippedUrl };
}
}
},
{ urls: ["<all_urls>"] },
["blocking"]
);
The issue I'm running into is that the
return { cancel: true }
executed when a URL is already open in another tab is causing the tab to not load at all and say " is blocked.
Requests to the server have been blocked by an extension." Clearly I'm using the API wrong - the behavior I'm looking for is for it to basically make the incoming request "fail silently" and just do the navigating to the existing tab while not opening a new tab at all. Is there a clean way to do this?
I have to make an extension that when clicked on text in the context menu, in callback opens the extension menu popup.
chrome.runtime.onInstalled.addListener(function() {
var context = "selection";
var title = "Google for Selected Text";
var id = chrome.contextMenus.create({"title": title, "contexts":["selection"],
"id": "context" + context});
});
// add click event
chrome.contextMenus.onClicked.addListener(onClickHandler);
// The onClicked callback function.
function onClickHandler(info, tab) {
var sText = info.selectionText;
var url = "https://www.google.com/search?q=" + encodeURIComponent(sText);
//what i have put here to open extension popup
};
In this case, when I click on the menu I open a new tab with this search.
There is no way of opening the default browser action popup programmatically. A work around is use content scripts to open a modal or a lightbox and show the contents of your popup.
Another way would be - within the clickhandler of your context menu item, create a new tab and make it inactive and then pass that tab to chrome.windows.create api to create a new popup window.
chrome.tabs.create({
url: chrome.extension.getURL('popup.html'),
active: false
}, function(tab) {
// After the tab has been created, open a window to inject the tab
chrome.windows.create({
tabId: tab.id,
type: 'popup',
focused: true
});
});
It is just a work around. Hope it helps.
It is now possible to open a browser action popup programmatically from inside the handler for a user action.
browser.menus.create({
id: "open-popup",
title: "open popup",
contexts: ["all"]
});
browser.menus.onClicked.addListener(() => {
browser.browserAction.openPopup();
});
You can read more about it here.
Edit:
This feature is only available as of Firefox 57. In Chrome, it is only available in the dev channel.
Sources: chrome/common/extensions/api/_api_features.json - chromium/src - Git at Google
Unfortunately, it cannot be done.
Chrome API doesn't provide a method to open extension popup programmatically. The Chromium team rejected the feature request for such an option with an explanation that:
The philosophy for browser and page action popups is that they must be
triggered by user action.
Here's the source.
You can use the chrome.window API (documentation here).
What you want is something like this :
chrome.windows.create({
url : "http://yourPopupUrl.com"
focused : true
type : "popup"});
This will open a new windows in popup mode (without the top menu bar) and load the "http://yourPopupUrl.com".
Hi—I'm not a student or a programmer by trade, but I'm trying to knock up a quick prototype to get an idea across. I've cobbled together some code from other StackOverflow questions, and I've almost got what I need, but I'm having trouble with one thing: the extension will run exactly once, but no more, until I refresh the extension via chrome://extensions. I'm guessing there's something wrong with the element of this program that listens for a new URL, but I can't figure out how to keep that element listening constantly. This code runs in background.js right now, though I've also tried it in background.html.
Basically, I'd like the extension to check the URL of a tab any time the user visits a new page (either by typing the URL herself or clicking through to one), and, if the URL appears in the plugin's internal URL list, to pop up a short notification. I have this so far:
// Called when the url of a tab changes.
// So we can notify users
var notification = webkitNotifications.createNotification(
'48.png',
'Alert!'
);
// Called when the url of a tab changes.
function checkForValidUrl(tab) {
// Compare with a the URL
if (tab.url.match(/google/)) {
//then
notification.show();
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status == "loading") {
checkForValidUrl(tab);
}
});
chrome.tabs.onSelectionChanged.addListener(function(tabId, selectInfo){
chrome.tabs.getSelected(null, function(tab){
checkForValidUrl(tab);
});
});
I fixed this after hacking it around a little bit -- I don't really have the vocabulary to explain what I did but I thought I'd post the code in case someone else has the same (simple) problem later.
function checkForValidUrl(tabId, changeInfo, tab) {
var notification = webkitNotifications.createNotification(
'48.png',
'Alert!',
'Watch out for your privacy!'
);
// Compare with the URL
if (tab.url.match(/google/)) {
//then
notification.show();
}
};
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status == "loading") {
checkForValidUrl(tabId, changeInfo, tab);
}
});
I am new to Chrome extension. I have a question about how to make the extension to open a "Help" page automatically after installation. Currently, I am able to check whether the extension is running the first time or not by saving a value into localStorage. But this checking is only carried out when using click the icon on the tool bar. Just wondering if there is a way that likes FF extension which uses the javascript in to open a help page after the installation. Thanks.
Edit:
Thanks for the answer from davgothic. I have solved this problem.
I have another question about the popup. My extension checks the url of current tab,
if OK(url){
//open a tab and do something
}
else{
//display popup
}
Is it possible to show the popup in this way?
Check this updated and most reliable solution provided by Chrome: chrome.runtime Event
chrome.runtime.onInstalled.addListener(function (object) {
let externalUrl = "http://yoursite.com/";
let internalUrl = chrome.runtime.getURL("views/onboarding.html");
if (object.reason === chrome.runtime.OnInstalledReason.INSTALL) {
chrome.tabs.create({ url: externalUrl }, function (tab) {
console.log("New tab launched with http://yoursite.com/");
});
}
});
Add this to your background.js I mean the the page you defined on manifest like following,
....
"background": {
"scripts": ["background.js"],
"persistent": false
}
...
UPDATE: This method is no longer recommended. Please see Nuhil's more recent answer below.
I believe what you need to do is put something like this into a script in the <head> section of your extension's background page, e.g. background.html
function install_notice() {
if (localStorage.getItem('install_time'))
return;
var now = new Date().getTime();
localStorage.setItem('install_time', now);
chrome.tabs.create({url: "installed.html"});
}
install_notice();
As of now (Aug 2022) the right way to execute code on first install or update of an extension using Manifest V3 is by using the runtime.onInstalled event.
This event is documented here: https://developer.chrome.com/extensions/runtime#event-onInstalled
There is one example for this exact case in the docs now:
https://developer.chrome.com/docs/extensions/reference/tabs/#opening-an-extension-page-in-a-new-tab
Note: This example above is wrong as the callback function parameter is Object with the key reason and not reason directly.
And another example here (this one is correct but does not open a tab):
https://developer.chrome.com/docs/extensions/reference/runtime/#example-uninstall-url
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) {
// Code to be executed on first install
// eg. open a tab with a url
chrome.tabs.create({
url: "https://google.com"
});
} else if (details.reason === chrome.runtime.OnInstalledReason.UPDATE) {
// When extension is updated
} else if (details.reason === chrome.runtime.OnInstalledReason.CHROME_UPDATE) {
// When browser is updated
} else if (details.reason === chrome.runtime.OnInstalledReason.SHARED_MODULE_UPDATE) {
// When a shared module is updated
}
});
This code can be added to a background service worker: https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/
It would be better to place a "version" number so you can know when an extension is updated or installed.
It has been answered here:
Detect Chrome extension first run / update
All you need to do is adding the snippet below to your background.js file
chrome.runtime.onInstalled.addListener(function (object) {
chrome.tabs.create({url: `chrome-extension://${chrome.runtime.id}/options.html`}, function (tab) {
console.log("options page opened");
});
});