How to add a custom item into the chrome context menu? - google-chrome

Is there any API to be used to add a custom item into the chrome context menu?
For example:
Now, I wanna add a "send to ..." item to context menu(right click), when it is clicked the contents selected in the webpage will be sent to someone.
I searched the chrome APIS and found that chrome.experimental.contextMenu is competent for my requirement, however it is experimental API so something like "path_to_chrome.exe --enable-experimental-extension-apis" will be added.
Any other solutions?

Now (for long time) you have an option.
Add this permission to your manifest.json file
"permissions": ["contextMenus"]
Then, something like that will do the trick:
chrome.contextMenus.create({
'title' : 'Open this select text %s',
'contexts' : ['selection'],
'onclick' : function(info, tab) {
console.log('Selected link: ' + info.selectionText);
}
});
Good luck.

Using contextMenu is the one and only way (outside of hacking on the Chromium source), but the API should be graduating from experimental when Google Chrome 6 gets released to the stable channel.

Related

How to open a new tab after the user click on a button

I'm new in development of Google Chrome extensions.
In my extension, I want to open a new tab after the user click on a button. How I do?
https://developer.chrome.com/extensions/tabs#method-create
This took me a single Google search, a single click on one link, and a single Ctrl-F command. It might be a good idea to look for the answers yourself before posting your questions here.
You can use chrome.tabs.create() for that.
Source: Google Chrome Extensions API
You can use it like this:
<script>
// Uses the Chrome API to create a tab.
function maketab() {
chrome.tabs.create();
}
</script>
<button onclick="maketab()">Click me to make a tab!</button>

How can I open my extension's pop-up with JavaScript?

I am trying to write a JavaScript function that will open my extension like when the extension icon is clicked. I know how to open my extension in a new tab:
var url = "chrome-extension://kelodmiboakdjlbcdfoceeiafckgojel/login.html";
window.open(url);
But I want to open a pop-up in the upper right corner of the browser, like when the extension icon is clicked.
The Chromium dev team has explicitly said they will not enable this functionality. See Feature request: open extension popup bubble programmatically :
The philosophy for browser and page action popups is that they must be triggered by user action. Our suggestion is to use the new html notifications feature...
Desktop notifications can be used progammatically to present the user with a small HTML page much like your popup. It's not a perfect substitution, but it might provide the type of functionality you need.
Chrome team did create a method to open the popup programmatically, but it's only enabled as a private API, and plans to make it generally available have stalled due to security concerns.
So, as of March 2018 as of now, you still can't do it.
Short answer is that you cannot open browserAction programmatically. But you can create a dialog with your content script which emulates your browserAction and display that isntead (programmatically). However you won't be able to access your extension's background page from this popup directly as you can from your popup.html. You will have to pass message instead to your extension.
As mentioned there is no public API for this.
One workaround I have come up with is launching the extension as an iframe inside a content script with a button click. Whereby the background script emits the extension URL to the content script to be set as the iframe's src, something like below.
background.js
browser.runtime.onMessage.addListener((request) => {
if (request.open) {
return new Promise(resolve => {
chrome.browserAction.getPopup({}, (popup) => {
return resolve(popup)
})
})
}
})
content-scipt.js
const i = document.createElement('iframe')
const b = document.createElement('button')
const p = document.getElementById('some-id')
b.innerHTML = 'Open'
b.addEventListener('click', (evt) => {
evt.preventDefault()
chrome.runtime.sendMessage({ open: true }, (response) => {
i.src = response
p.appendChild(i)
})
})
p.appendChild(b)
This opens the extension in the DOM of the page the script is running on. You will also need to add the below to the manifest.
manifest.json
....
"web_accessible_resources": [
"popup.html"
]
....
You could emulate the popup by displaying a fixed html element on the page in the same location the popup would be and style it to look like the popup.
I had the same requirement: When the user clicks on the extension icon a small popup should open. In my case, I was writing an extension which will give updates on selective stocks whenever the icon is clicked. This is how my popup looked.
If you were having the same requirement then please read the answer below.
This is how my manifest.json file looked.
All the heavy lifting was handled by manifest.json file only. There is a section browser_action inside which there is a key called default_popup, just put the name of the HTML file that you want the popup to display.
I wanted my extension to work on all the pages that's why I added the attribute matches under content_scripts. I really didn't need to put the jquery file jquery-3.2.1.js inside the js array but the extension manager was not allowing me to keep that array empty.
Hope this helps, do comment if you have any doubt regarding the answer.

How can I specify a sidebar in Chrome extension?

I'm trying to add a sidebar (experimental) to my extension.
I've enabled the "Experimental Extension APIs" in Chrome.
When I invoke:
chrome.experimental.sidebar.show(cTab);
method, (where cTab is current tab) I get an error:
Error during experimental.sidebar.show: This extension has no sidebar
specified.
When I invoke:
chrome.experimental.sidebar.getState(cTab, function (state) { alert(state); });
I get "undefined" in the alert box.
I read the specs of chrome.experimental.sidebar and I have no clue how to add a sidebar to Chrome.
How can I specify a sidebar for my extension? Please help.
First declare sidebar in your manifest:
{
...
"sidebar": {},
...
}
Then to display sidebar.html in a current tab:
chrome.experimental.sidebar.show();
chrome.experimental.sidebar.expand();
chrome.experimental.sidebar.navigate({path: "sidebar.html"});
Here is example extension.
This is no longer supported unfortunately. See:
How to create a sidebar(right-side) in google chrome?
Chrome.experimental.sidebar gone?
http://code.google.com/p/chromium/issues/detail?id=51084
Hopefully they'll add it back new and improved in a future release.
You'll need to use the DOM injection approach.

Chrome extension, focus on the page instead of omnibox after selected tab is updated?

I created an extension called quickmarks which will open bookmark by keyword at currently selected tab. I am
using omnibox to select the bookmark (chrome.omnibox.onInputEntered),
and chrome.tabs.update API to open bookmark's url in current tab, by
providing the url in updateProperties. However after the tab is
updated, focus still remains in omnibox, which make the user-
experience not as good as I desired. So is there a way to set the
focus to the page, instead of the omnibox.
Btw, I have tried to open a new tab by using chrome.tabs.create. The
page will be focused instead of omnibox, which is my desired
behaviour.
Thanks.
Using chrome.tabs.update(tab.id, {url: url, selected: true}); does the trick for me.
The accepted answer no longer works in Chrome 31. I had hoped it was a simple matter of the selected property being deprecated but the replacement highlighted property did not assign focus to the tab's content either.
I was only able to steal focus from the Omnibox by closing the current tab and then creating a new tab in its place. Here's the code that works in Chrome 31:
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.remove(tab.id, function() {
chrome.tabs.create({url:url, active:true});
});
});
While this is certainly not ideal, the current tab is closed and a new one opened so fast you barely notice any difference.
Dave Teare is right that this no longer works in current version of Chrome, however his method did not work for me. It seemed like the chrome.tabs.create did not get called after the tab was removed.
I use the Chrome extension iChrome and I wanted it to be selected when I created a new tab, so I installed another extension that redirects new tabs to iChrome. It unfortunately used the same deprecated "selected:true" method.
From what I can tell there is currently no way to do this cleanly, you cannot have Chrome make the updated tab's input focused nor can you have it select the text in onmibar so you cant just start searching after creating a new tab. So this is what I came up with:
chrome.tabs.create({url:url, active:true}, function(){
chrome.tabs.remove(tab.id);
});
Definitely still not ideal, and you can see a flash when it closes old tab, but it works. The input is focused.

Is it possible to determine a tab's opener within a Google Chrome extension?

I am looking for a way to determine a given tab's opener (parent tab) within a Google Chrome extension.
I've looked at the documention for Tab but there doesn't really seem to be anything that would yield this information. http://code.google.com/chrome/extensions/tabs.html
I've tried injecting this content script into pages (thinking I could pass the value to my background page):
alert(window.opener);
.. but it just yields null.
The best thing I've come up with so far is to keep track of the currently focused tab, and whenever a new tab is created, just assume that the focused tab is the opener/parent of the new tab. I believe this would de facto identify the parent tab correctly most of the time since background tabs rarely (are allowed to) open new pages. However, it seems kludgey and potentially inaccurate at times -- for example, if another extension opened a new tab, this method may misidentify the new tab's opener.
Update: it is now possible to reliably determine a tab's opener tab within a Chrome extension natively using the newly added webNavigation API, and specifically by hooking the onCreatedNavigationTarget event.
https://code.google.com/chrome/extensions/trunk/webNavigation.html
Chrome has added an experimental extension API which can accomplish this -- specifically webNavigation.onBeforeRetarget. http://code.google.com/chrome/extensions/experimental.webNavigation.html
However since this is still experimental (not usable in Chrome stable versions or releasable on the Chrome Web Store) I have ended up using another approach.
Basically:
In content_script.js:
chrome.extension.sendRequest({
request: {
op: "pageLoadStarted",
url: document.location.href,
referrer: document.referrer
}
});
In background.html:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
console.log('onRequest: ' + JSON.stringify(request));
console.log(JSON.stringify(sender));
});
This approach allows me to obtain the referrer of a tab, which I can then correlate with an existing tab's url. This isn't always a one-to-one mapping, so I do some additional magic such as preferring the currently selected tab as the opener if its url matches the new tab's referrer.
This really is just a hack to approximate the functionality that would be provided more simply and accurately by webNavigation.onBeforeRetarget or window.opener.
Further investigation has revealed that onCreatedNavigationTarget() does not always fire when you think it would to indicate an opener-opened relationship.
An additional hint can sometimes be found in the Tab object returned by chrome.tabs.onCreated/onUpdated in the .openerTabId parameter.
A comprehensive solution will probably have to rely on multiple of the methods described in these answers.
port.onMessage.addListener(
function(msg) {
var tabid = port.sender.tab.openerTabId;
console.log("Received message from tab that was opened by tab id : " + tabid);
// reliably shows the tab id of the tab that opened
// the tab sending the message
});