I have an extension that implements a browser action.
Of course, the browser action is allways visible, but it has a special significance in certain urls. So, I use filtered events to listen to those urls and set the proper badge
chrome.webNavigation.onDOMContentLoaded.addListener(
function(tab){
chrome.browserAction.setBadgeText({
text:'bdge',
tabId: tab
});
},
{'url':[{hostSuffix: 'somedomain.com', pathPrefix: 'somePath/'}]}
);
Is there some "elegant" way to reset the badge when the user navigates out from that page, without listening every single tab navigation?
Should I execute a content script to hang on some exiting event and send a message?
Thank you very much,
It seems to me that a good solution would be to use chrome.tabs.onUpdated.
In your background page, you would have something like that:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
// using a regex or however else you want to test the URL
if (/somedomain\.com\/somePath\//.test(changeInfo.url)) {
chrome.browserAction.setBadgeText({
text: 'bdge',
tabId: tabId
});
} else {
chrome.browserAction.setBadgeText({
text: '',
tabId: tabId
});
}
});
I know you wrote "without listening every single tab navigation" but I'm not sure why you want to avoid this.
This is what documentation doesn't tell you: Chrome actually resets badge automatically when user navigates away.
When you set a browser action's badge only to a specific tab, like
chrome.browserAction.setBadgeText({
text: 'ABCD', // My badge's text should be only 4 characters long
tabId: 1234 // Any tab, ussually a var here, not a constant
});
Chrome shows the badge on the browser action button only when that tab is the active tab in the window. Its text resets to '' when the user navigates away in that tab. No need for special action to reset it.
Related
I'm new to chrome extension development but I'm running into issues debugging and with the extension itself. I currently have a form with a submit button and after the user hits submit I change the html to show the data that was just submitted.
document.addEventListener('DOMContentLoaded', function() {
console.log("1");
document.getElementById("submitButton").addEventListener('click', myFunction);
console.log("2");
//getCurrentTabUrl(function(url) {
// renderStatus(url);
//});
});
function myFunction() {
document.getElementById("formOutput").innerHTML = document.getElementById("formInput").value;
alert("hi");
console.log("test");
);
}
In this, 1 and 2 are displayed to the extension debugging console and the alert runs as well when the button is clicked. The test shows up very briefly and then it disappears.The formoutput value changes very briefly as well and then changes back to the default value I have. Does anyone know why my code/the chrome extension would be doing this?
Thanks!
When button with type submit (This is the default if the attribute is not specified) is clicked, the form data will be sent to server and page will be redirected to new page. Then your content script will be injected again, that's why the it changes back to default value.
To avoid this, you could change button with other types, or calling e.preventDefault to prevent default behavior. Then you would want to use Ajax to send data to server, which ensure the whole page won't be redirected and only parts of UI can be updated.
I have a Chrome extension with a popup that can also be opened by a shortcut. When the popup gets opened, can I find out whether the user has used the shortcut or whether they have clicked on the extension icon?
The reason is that I'd like to hint users to use the shortcut, but I don't want to show that hint to users who already know and use the shortcut.
Popup and shortcut are defined like this in manifest.json:
"browser_action": {
"default_icon": "images/icon48.png",
"default_popup": "popup.html",
"default_title": "__MSG_tooltip__"
},
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Ctrl+Shift+Space"
}
}
},
chrome.browserAction.onClicked.addListener
Not available, because:
Fired when a browser action icon is clicked. This event will not fire
if the browser action has a popup.
We has popup.
chrome.commands.onCommand.addListener
Not available, because:
The '_execute_browser_action' and '_execute_page_action' commands are
reserved for the action of opening your extension's popups. They won't
normally generate events that you can handle.
May try inject press listener to some page and track pressed of keys (on each page).
var isPressed;
document.body.addEventListener("keydown", function (e) {
if (!(e.keyCode != 17) || !(e.keyCode != 16) || !(e.keyCode != 32)) return;
isPressed = true;
});
From popup in moment expand send message to content_scripts:
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, {action: "isPressed"}, function (responce) {
if (responce) {
}
});
});
After message receiving, listener in content scripts send variable isPressed as response:
chrome.runtime.onMessage.addListener(function (message, sender, response) {
if (message.action == "isPressed") {
response(isPressed);
}
});
If variable is true, means called via keystrokes, else on click on icon.
can I find out whether the user has used the shortcut or whether they
have clicked on the extension icon?
There seems to be no clean direct way of detecting that.
Since I put some effort into trying to find a workaround, I would like to share what I have considered/tried and reasons why it doesn't work:
Attach the keyboard shortcut to some custom command, modify popup page and then open it programmatically.
Doesn't work because there is no way to open the popup programmatically, at least not in current stable version of Chrome (v50).
Create a custom command with the same shortcut as "_execute_browser_action" and use it to send a message to the popup.
Doesn't work because two commands cannot share the same shortcut.
Try to capture keyup in the popup page immediately after loading.
I tested this and it seemed to work at first, but it is definitely not reliable. If the user only presses the keyboard shortcut very briefly, the keyup event is fired before the popup page gets a chance to register a listener for it.
Capture keydown on pages using a content script and then send a message to the popup page to let it know that the keyboard shortcut was pressed (as suggested by UserName above).
This should work on most pages, but the content script won't be able to capture the keypress in address bar and on certain pages (chrome://, chrome-extension://).
Difficult to implement because you need to take into account the fact that users can customize the shortcut on chrome://extensions page. Finding the currently assigned shortcut programmatically to test against it in the content script is surprisingly difficult, because chrome.commands.getAll() provides localized key names (eg. "Ctrl+Shift+Space" in English, but "Ctrl+Shift+Mezera" in Czech) There are languages where even Ctrl and Shift don't stay in English.
I'm working on a chrome extension that manipulates certain cookies. Most of the manipulation takes place in the background service, but I need to update the icon and pass data to the browser action for the current tab.
I'm looking for an action similar to the AdBlock extension. AdBlock loads a small number in the bottom right of the icon for the number of ads blocked, so it varies from tab to tab.
When I perform this action from the background service, it seems to change across all browsing tabs. Can someone with experience in extensions point me in the right direction for this one?
This should get you started.
setInterval(function(){//every second
chrome.tabs.getSelected(null,function(tab) {//on the current tab,
chrome.browserAction.getBadgeText({tabId:tab.id}, function(badgeText){//get the tab's badge text
if(badgeText.length<1){
badgeText="0";//set the text if its empty
}
chrome.browserAction.setBadgeText({tabId:tab.id,text:badgeText/1+1+""});//and add one.
});
});
},1000);
make sure you don't run this in the console, because chrome will get the developer tool window id, and since no valid tab has that id, it will change every single tab's badgeText.
You just need to include the tab id when you set it, such as:
chrome.browserAction.setBadgeText({ text: "5", tabId: tab.id })
background.html:
// Called when the url of a tab changes.
function checkForValidUrl(tabId, changeInfo, tab) {
if(changeInfo.status === "loading") {
if (tab.url.indexOf('google.com') > -1) {
// ... show the page action.
chrome.pageAction.show(tabId);
chrome.pageAction.onClicked.addListener(function(tab){
chrome.tabs.create({url: "facebook.com", "active":true});
});
}
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);
So, I go on google, click page action, in new tab opens facebook. I make new tab with google again, click page action and it opens 2 facebook-tabs. Its strange, because I need - 1 click on page action - 1 new tab. How to fix it?
Thanks.
The problem is that you're adding an event listener every time your tab changes.
Since you're calling checkForValidUrl every time a tab changes, chrome.pageAction.onClicked.addListener is also called every time a tab changes. Now your pageAction has two event listeners doing the same thing. You can verify this by changing tabs multiple times and see that it will open as many Facebook tabs as you have changed tabs.
To fix this, of course, you should remove the following from checkForValidUrl:
chrome.pageAction.onClicked.addListener(function(tab){
chrome.tabs.create({url: "facebook.com", "active":true});
});
and put it outside, for example, after you set up your listener for chrome.tabs.onUpdated.
google-chrome-extension
I´m having trouble with an extension I´m trying to build.
The thing is that I want to allow a user to highlight a word in some tab and get a translation of that word in another window by calling a Translator web page.
The part I have so far and works, is roughly as follows:
I created a context menu item which user selects to get the translation, calling a translate function.
chrome.contextMenus.create({
title: 'Translate',
contexts: [context],
onclick: translate
});
In the translate function I create window and send over the selected word.
chrome.windows.create({
url: 'http://www.TranslatingPage.com/index.asp?Translateword=' + info.selectionText
});
The question is: How do I update the newly created window? e.g. If I want to translate another word.
Do I fetch all windows or tabs and check if the part of the url holds the value
'http://www.TranslateExamplePage.com/index.asp?Translateword='
or do i update LastFocused tab?
Any ideas greatly appreciated.
Best regards
Hal
You can store the tabId of the tab in the new window you created for easy access.
chrome.windows.create() passes a Window object to the callback function. Among other things, this object contains an array of the tabs in it. Since you have just created this window, it will only have one tab. So:
var theTab;
chrome.windows.create({ url: 'http://www.TranslatingPage.com/index.asp?Translateword=' + info.selectionText }, function(window) {
theTab = window.tabs[0]
});
When you want to modify this tab again, use chrome.tabs.update():
chrome.tabs.update(theTab, { url: 'http://www.TranslatingPage.com/index.asp?Translateword=' + info.selectionText });