Intercept browserAction.onClicked to prevent display of extension page - google-chrome-extension

When the browserAction icon is clicked for my Chrome extension, I want to prevent it from showing the browserAction popup. I'm trying to use the browserAction icon to trigger the loading of a content script instead.
How would I do this?
The following doesn't prevent it from opening:
chrome.browserAction.onClicked.addListener(function (tab) {
alert('browserAction clicked');
return false;
});
Here is my manifest.json entry for this:
"browser_action": {
"default_icon": {
"19": "images/icon-19.png",
"38": "images/icon-38.png"
},
"default_title": "My extension"
}
The docs say This event will not fire if the browser action has a popup, however, as you can see I don't have a popup defined but it still doesn't work.

When you press the extension button, the following happens.
If you have a popup defined for the current tab (e.g. by the default_popup key in the manifest or chrome.browserAction.setPopup), it is shown. The chrome.browserAction.onClicked is not raised.
If the popup is not set (or set as empty) for the current tab, chrome.browserAction.onClicked is dispatched.
So, to disable this permanently, you just need to remove default_popup from the manifest. To disable it programmatically, you need to unset it:
chrome.browserAction.setPopup({
popup: "",
// tabId: id // optional, restrict to a single tab
});

Related

Don't want grayed out Chrome extension

I'm developing a Chome extension. When you click on the extension icon, the contextMenu is accessible by a right-click and a left-click.
Actually, I don't have a browserAction in my manifest.json, so my problem is my icon is grayed out. The solution is to add a browserAction. But if I add a browserAction, the left-click don't show the default menu, but shows nothing.
What I want is a colored icon and when I left-click that the default Chrome extension popup is opened.
Default Chrome Extension popup example:
My manifest.json
{
"manifest_version": 2,
"name": "Awesome app",
"version": "0.1",
"background": {
"scripts": ["background.js"],
"persistent": true
},
"permissions": [
"storage",
"contextMenus"
],
"icons": {
"16": "icons/se16.png",
"32": "icons/se32.png",
"158": "icons/se158.png"
}
}
Can someone help me?
It's not possible to have the default menu AND a colorful icon because the very presence of "browser_action" key means the extension wants to interact with the user and instructs the browser to either delegate icon click event to background page script in chrome.browserAction.onClicked listener or show a popup window if "default_popup" is declared in manifest or the popup was set programmatically via chrome.browserAction.setPopup.
The only way to "ignore" the click event in browserAction API is to disable the icon via chrome.browserAction.disable which will gray it out thus defeating the initial goal.
Well, you can show/do something useful on click. The default menu isn't very useful, anyway.

How find to whether my Chrome extension was called by shortcut?

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.

How can I instruct Chrome Extension to NOT reload my HTML each time it is opened?

I am working on a Chrome Extension and I need it to maintain its state each time it is opened.
For example, I have an input element that needs to stay filled-in after I close and re-open the extension.
On this page, I found an example of the manifest. It lead me to add the following to my manifest, but it didn't work:
"background": {
"persistent": true,
"page": "popup.html"
}
Is there a way to maintain the extensions state between openings?
First things first, read the Architecture Overview of Chrome extensions.
A popup page is a "throwaway" page that only exists as long as the popup is open; you cannot influence that. As soon as the popup loses focus, its HTML document will be destroyed.
In contrast, a background "page" (which usually has no HTML markup, hence the typical use of "scripts" instead of "page") with "persistent": true exists as long as Chrome runs. As such, it can hold state information. But it's an invisible page.
The right approach would be to make the popup page dynamic, save its state to background and/or various storage APIs, and restore state when opening.
Minimal example:
// popup.js
// Suppose #myInput is a text input
document.addEventListener('DOMContentLoaded', function() {
chrome.storage.local.get({setting: "default value"}, function(data) {
var inputElement = document.getElementById("myInput");
inputElement.value = data.setting;
inputElement.addEventListener("input", function(e) {
chrome.storage.local.set({setting: e.target.value});
});
});
});

Adding icon menus to Chrome extensions

I successfully created my first Chrome extension. It now runs only when the extension icon is clicked instead of on the background, and that is great. However, I would like to add more actions to my extension I have been trying to use an extension popup to run other functions but I can't make it work. It doesn't have to be like that, so I am open for suggestions. I do not want to use context menus. I want people to click on the extension icon and show them a "menu".
Right now my extension only alerts a message when it finds a valid page (from mydomain.com), and it finds a hidden field with the name "returnURL". It alerts the value.
I would like to be able to add the ability to click on the icon but instead show an options menu with multiple options.
Something like this:
Click on the extension icon and show two options
Get Response URL (this option will run the current functionality I have now)
Do something else (So I could have another function to execute on the
loaded page)
...and more options if I needed to add them on future versions of my extension.
How do I modify my extension to do that.
Here is my code:
manifest.json
{
"name": "Get Response URL",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"default_icon": "mkto_icon.png",
"name": "Click to get URL"
},
"background":{
"scripts":["background.js"]
},
"permissions":["http://mydomain.com/*"]
}
background.js
chrome.browserAction.onClicked.addListener(function (tab) { //Fired when User Clicks ICON
if (tab.url.indexOf("http://mydomain.com/") != -1) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id, {
"file": "contentscript.js"
}, function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
}
});
contentscript.js
if (document.getElementsByName("returnURL")){
alert("\nThe Response URL on this form is:\n\n" + document.getElementsByName("returnURL")[0].value);
}
I followed the documentation I found on the Google Extensions developer site but I couldn't make it work. Your help is much appreciated.
You cannot have a real menu with a Chrome extension. You can however show an HTML page when the button is clicked (a pop-up). You can style this HTML page in a way that looks similar to a menu:
"browser_action": {
"default_icon": "mkto_icon.png",
"default_title": "Click here to open menu",
"default_popup": "popup.html"
},
Add a file popup.html to you extension and whatever content you want to show up. Scripts loaded by the pop-up page can load content scripts and communicate with them just like the background page.
For reference: browser actions documentation.

Adding an option to the right click menu for a Chrome extension

Does anyone know if it's possible to add to the mouse right click menu in Chrome another option which would communicate with an extension?
I mean, after installing an extension, another option would appear in the mouse's right click menu which will send to a listener opened by the extension the data.
Here is the solution:
rightClickHandler = function(){
//Do your stuff over that selected context menu
};
chrome.contextMenus.create({
title: "Bitly Short Link",
contexts:["link","selection"], // ContextType
onclick: rightClickHandler // A callback function
});
In manifest.json, have this permission:
{ "permissions": ["...", "contextMenus"], }
Hope it helps!

Resources