I am writing a Chrome extension, and I want a login window to be popped up when users click on the context menu so that user can input username and password. In Chrome extension, I only found chrome.pageAction.setPopup and chrome.browserAction.setPopup can be used to show popup windows, but they show popups only when the page action's icon or browser action's icon is clicked, not the context menu. Of course, I can use javascript prompt box to do this, but the problem is the password cannot be masked in the prompt box. So I am wondering if there are some other ways to create a popup window in Chrome extension.
Thanks!
Pick and choose:
showModalDialog(<String url> [, <object arguments>])
Opens a dialog-like window, in which you can load a page within your chrome extension. HTML can be used.
Do not use showModalDialog, it is going to be removed from Chrome.
window.open(<String url> [, <String window_name>[, <String windowFeatures>]])
Opens a window, which, unlike the previous method, does not appear as a dialog. The user can minimize the window, and continue with something else.
chrome.windows.create(<object createData [, <function callback>]>)
(Specific to Chrome extensions) Create a new window, with given arguments (size, url, position, ...).
All of these methods allows you (your extension) to open a new window/dialog, and handle the logic from that page. This page should be packaged with your extension.
See Message passing to pass the entered data to your extension.
Demo
Tabs within your extension have direct access to the background page using chrome.runtime.getBackgroundPage. I'll demonstrate this feature in this demo, as well as a conventional way of message passing:
manifest.json
{
"name": "Dialog tester",
"version": "1.0",
"manifest_version": 2,
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["open-dialog.js"]
}]
}
background.js
// Handle requests for passwords
chrome.runtime.onMessage.addListener(function(request) {
if (request.type === 'request_password') {
chrome.tabs.create({
url: chrome.extension.getURL('dialog.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
// incognito, top, left, ...
});
});
}
});
function setPassword(password) {
// Do something, eg..:
console.log(password);
};
open-dialog.js
if (confirm('Open dialog for testing?'))
chrome.runtime.sendMessage({type:'request_password'});
dialog.html
<!DOCTYPE html><html><head><title>Dialog test</title></head><body>
<form>
<input id="pass" type="password">
<input type="submit" value="OK">
</form>
<script src="dialog.js"></script>
</body></html>
dialog.js
document.forms[0].onsubmit = function(e) {
e.preventDefault(); // Prevent submission
var password = document.getElementById('pass').value;
chrome.runtime.getBackgroundPage(function(bgWindow) {
bgWindow.setPassword(password);
window.close(); // Close dialog
});
};
Documentation for used methods
chrome.runtime.sendMessage(<request>, <function callback>) and chrome.runtime.onMessage.addListener(<function listener>)
chrome.extension.getURL(<String path>)
chrome.runtime.getBackgroundPage(<function callback>)
chrome.tabs.create(<object createData> [, <function callback>])
chrome.windows.create(<object createProperties> [, <function callback>])
Related
I'm trying to build a somehow dummy Chrome extension. I want it to run only in specific pages, so I'm using a Page Action.
Let's say I want the page action to run on the Instagram website, then (accordingly the docs), I would need something like this on my manifest.json right?
{
"manifest_version": 2,
"name": "Some name",
"version": "0.0.3",
"description": "Some description",
"content_scripts": [
{
"matches": [
"https://www.instagram.com/*"
],
"js": ["content.js"]
}
],
"page_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
}
}
while the content script runs only on instagram pages as one would expect, the browser extension is not clickable (gray look, and when I click most options are not clickable).
this makes impossible to act upon extension button click. In my background.js I have:
function click(tab) {
console.log('click from ' + tab);
}
chrome.pageAction.onClicked.addListener(click);
that never gets called.
So, what's wrong that makes impossible to act upon extension click on some pages?
Note: I saw this question/answer, but couldn't find the problem/solution How can I add a click for pageAction?
You have to call pageAction.show in order for your pageAction button to be enabled (clickable).
The pageAction documentation says (emphasis mine):
You make a page action appear and be grayed out using the pageAction.show and pageAction.hide methods, respectively. By default, a page action appears grayed out. When you show it, you specify the tab in which the icon should appear. The icon remains visible until the tab is closed or starts displaying a different URL (because the user clicks a link, for example).
With a manifest.json content_scripts entry
Because you already have a content script that runs on the page you desire to have this function on, probably the easiest way to do this is to have your content script send a message to your background script telling it to show the page-action button for that tab.
Your content script could look something like:
chrome.runtime.sendMessage({type: showPageAction});
Your background script could look something like:
chrome.runtime.onMessage(function(message, sender, sendResponse) {
if(typeof message === 'object' && message.type === 'showPageAction') {
chrome.pageAction.show(sender.tab.id);
}
});
Without a manifest.json content_scripts entry
If you did not have a content script, you would probably want to use a webNavigation.onCompleted listener, or tabs.onUpdated listener, to listen for a change in the tab's URL in order to determine that the page-action button should be shown. Obviously, the trigger for calling pageAction.show() does not have to be the URL which is currently displayed in the tab, but that is the most common.
I am trying to make a simple chrome extension.
It is supposed to add an item "Open new tab" in the 'windows system tray chrome icon context menu' (similar to how the checker plus for gmail extension has done; see the second image given below).
when I click the option, chrome is supposed to (check if any window is open. If yes, then it is supposed to) open a new tab page. If no windows are open, then it is supposed to open a new chrome window with the new tab page showing.
What I have done till now:
manifest.json
{
"manifest_version": 2,
"name": "Open New Tab",
"description": "This extension open a new tab page",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"background":{
"scripts":["background.js"],
"persistent": false
},
"permissions": [
"background",
"activeTab"
]
}
background.js
chrome.browserAction.onClicked.addListener(function(tab)
{
chrome.tabs.create({ url: "chrome://newtab" });
}
);
background.html
<html>
<head>
<script>
chrome.browserAction.onClicked.addListener(function(window)
{
chrome.windows.create({url: "chrome://newtab", type: "normal"});
}
);
</script>
</head>
</html>
I have already loaded this extension.
The effects of my extension on chrome so far:
1) Chrome window is already open.
My icon shows up in the list of extensions and is clickable.
On clicking, a 'new tab' page is opened in the same window. This is correct. (Though I don't need this. For now, let it be.)
2) Chrome window is closed, and chrome is allowed to run in the background. Rightclick the chrome tray icon. My extension menu 'Open a new tab' shows up in the menu.
This is also correct. On clicking it, a new chrome window is created. (Currently, I have not yet checked if a window already exists. That is to come later.).
The problem is that, in the new window that opens, instead of the 'new tab' page, chrome automatically opens the 'chrome://extensions' URL. This is wrong, and I cannot understand why the extensions page is opening. I want to open the new tab page, and i am passing the 'chrome://newtab' URL. How do I make chrome open the new tab page from here? Chrome works correctly when I start it from my desktop icon or windows start menu. So, the problem seems to be something with my code.
Any help is appreciated.
Listen to chrome.windows.onCreated event, when right clicking chrome tray icon, a new window would be launched, then you could create a new tab in the event handler.
chrome.windows.onCreated.addListener(function(window) {
chrome.windows.getAll(function(windows) {
if (windows.length === 1) {
chrome.tabs.create({windowId: window.id, url: "chrome://newtab"});
}
});
});
I've wanted to try a Chrome Extension for a while, and one thing that always bugged me about Chrome is that clicking on an active mailto: link opens GMail (if it's your handler) in the same tab, navigating away from the page.
When you click on a mailto: link using the Gmail handler, it takes the linked email address and appends it to the Compose window:
https://mail.google.com/mail/?view=cm&fs=1&tf=1&source=mailto&to=youremail#somesite.com
What I want to do is create an extension that gives me a context menu option to compose a new email. I've got the basics down (see below) but I cannot figure out how to get the recipients email address automatically included in the popup.
manifest.json:
"background": {
"scripts": [ "background.js" ]
},
"description": "Creates a context menu option which copies the selected address into a new Gmail compose window.",
"manifest_version": 2,
"name": "New Gmail Window",
"permissions": [ "tabs", "contextMenus" ],
"version": "0.1"
}
background.js
function getEmail(info, tab) {
chrome.windows.create({
url: "https://mail.google.com/mail/?ui=2&view=cm&fs=1&tf=1&shva=1&", // This is the URL I need to figure out.
width: 640,
height: 700,
focused: true,
type: "popup",
})
}
chrome.contextMenus.create({
title: "Send Email",
contexts: ["selection"],
targetUrlPatterns: ["mailto:* "],
onclick: getEmail,
});
You're 99% of the way there. This is the simple fix to get the email address in there:
url: "https://mail.google.com/mail/?ui=2&view=cm&fs=1&tf=1&shva=1&to="+info.linkUrl.substr(7),
info.linkUrl grabs the whole "mailto:someone#domain.com", and the .substr(7) just cuts off the "mailto:" portion.
Additional Notes:
Who wants to have to select (i.e., highlight) the email link? I recommend including links in the context (contexts: ["selection", "link"]).
You have a space at the end of you targetUrlPatterns (["mailto:* "). I'm not sure why it isn't messing anything up on the selections I've tried. But it does mess things up when you add "link" to the contexts to be able to email with just a right-click.
I am writing a chrome extension to allow users to login to social media sites from a single page. I am able to create a new incognito window but am unable to manipulate anything inside of the window that I created. I want to create an onload function for the new window to execute jquery. Thanks for getting me pointed in the right direction!
Refer the following demonstration for manipulation of new incognito window created and injecting some jquery into it.
References
Windows API
Tabs API
Background Pages
Content Scripts
Manifest file.
manifest file
This is used to bind permissions and register background pages to extension.Ensure it has all permissions needed.
{
"name":"Hanlder for Incognito window",
"description":"http://stackoverflow.com/questions/14044338",
"version":"1",
"manifest_version":2,
"background":{
"scripts":["background.js"]
},
"permissions":["tabs","http://www.google.co.in/"]
}
background.js
Inject jquery into new incognito window, from background page.
var _tabId_To_Look_For;
// Create a new incognito Window with some arbitary URL and give it focus
chrome.windows.create({
"url": "http://www.google.co.in/",
"focused": true,
"incognito": true
}, function (window) {
// Trace tab id which is created with this query
_tabId_To_Look_For = window.tabs[0].id
});
// Add an event Listener for new tab created
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
// Inject script into chosen tab after it is loaded completely
if (tabId == _tabId_To_Look_For && changeInfo.status == "complete") {
// Inject Jquery and in current tab
chrome.tabs.executeScript(tabId, {
"file": "jquery.js"
}, function () {
// I am in call back
console.log("Injected some jquery ");
});
}
});
Ensure you have enabled incognito access.
Output
You will observe a new window with jquery injected.
I have a chrome extension and its popup.html has a link to a oauth/openid login page. To be exact to a page like this
I need this login page to be opened in a popup browser window with only an address bar. There should not be any other tool/menu bars. I tried window.open chrome.windows.create and window.showModalDialog methods.
All of them create a popup tab the way I wanted but none shows the address bar no matter what. When the popup.html is directly browsed via the browser, it shows the address bar, when the link is clicked. But not when the popup is loaded through the extension.
Since this page shows an oauth/openid login page, it is absolutely imperative that the user sees the address of the current page shown in the popup. No one would supply their facebook/google credentials to a page that does not have the address bar.
Any help is really appriciated.
I had a look around and it seems this is a known bug....
http://code.google.com/p/chromium/issues/detail?id=108875&q=popup%20bar&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20OS%20Area%20Feature%20Status%20Owner%20Summary
You should star that for future updates and I think you should probably comment on your situation aswell.
The only way you could get the popup you want from your extensions code is to open a tab, get it to open the popup and then close the tab.....far from ideal.
But incase thats good enough for you here's some sample code....
manifest.json
{
"name": "Popup with adresse bar",
"version": "1.0",
"permissions": [
"tabs", "<all_urls>"
],
"browser_action": {
"default_title": "Popup with adresse bar.",
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"manifest_version" : 2
}
popup.html
<!doctype html>
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
<a id='clicky' href='#'>clicky</a>
</body>
</html>
popup.js
clicky = function() {
chrome.tabs.create({
url: 'open.html#' + 'http://www.google.com',
active: false
});
}
onload = function() {
document.querySelector('#clicky').onclick = clicky;
}
window.onload = onload;
open.html
<script src='open.js'></script>
open.js
window.close();
window.open(window.location.hash.substr(1), '…', '…');
Ok I am going to give this question a try. I understand what you are talking about with the address bar being hidden. For instance, my rem-i-con extension. If the user hasn't registered it will open a new tab, that will then ask them to create a account or login. But the address bar is blank.
However, in my popup.html file, I have a few links that do open a new tab with the address shown in the window. I understand you want a model type window but I am not sure that can be done. Here is something you can try.
Have a regular link asdd
When clicked you can have listener that watches the tab that has just been opened. This you could do easily by scanning the active tabs.
Then once the tab is closed, you could then have your popup.html file reload. You will need to use a background.html file for this.
If this works, then you could just automate the tag click.