I'm trying to close the Options page of the extension.
I have a Cancel button and I'm using this code:
chrome.tabs.getCurrent(null, function(tab) {
chrome.tabs.remove(tab.id, function() {});
});
When I'm trying to use it, it always gives this error:
Uncaught TypeError: Cannot call method 'getCurrent' of undefined
What's wrong with the code?
It works for me with one little fix:
chrome.tabs.getCurrent(function(tab) {
chrome.tabs.remove(tab.id, function() { });
});
Just make sure you're really running this code in options page of your extension and not just some HTML page, because chrome.tabs API is available only for extensions.
Most likely you're running your code from a content script, where chrome.tabs is undefined. If this is the case, you can instead send a message to the background page and have the background page (which has access to chrome.tabs) make the call.
Note that from a background page, you would use chrome.tabs.getSelected since getCurrent will return undefined.
In the options page, you can just do:
window.close()
If you wanted to use chrome.tabs.getCurrent, do you have tabs defined in the permissions section within the manifest?
I have time to continue my extension after a very long time. I checked the documentation again. So it was a inline script, that I had probably blocked with Content Security Policy in the manifest, because I hadn't read the documentation precisely.
Now Chrome blocks inline scripts by default, so I'll have to fix it anyway.
Only this worked for me:
chrome.tabs.query({ active: true }, function(tabs) {
chrome.tabs.remove(tabs[0].id);
});
Related
I was up till 1 am last night trying to find an example of how to do this. My theory is that I'd write a function that would comment out all javascript.
The second option would be to add the url to the list of javascript settings.
Right now my extension is very simple:
function linkOnClick(info, tab) {
window.open(info.linkUrl)
}
chrome.contextMenus.create(
{title: "Load with no Javascript", contexts:["link"], onclick: linkOnClick});
This is my first extension and I'm kind of lost.
edit: let me know if I should also post the manifest.json.
edit: I can't mark this as solved for 2 days (why? who knows.), so I'll probably not remember to mark this as solved. So accept this as the official making: SOLVED.
chrome.contentSettings.javascript.set is the thing that disables javascript.
Here's the part that disables javascript.
(Google, here's what an actual example should look like):
chrome.contentSettings.javascript.set(
{'primaryPattern':AnyDomainName, /*this is a string with the domain*/
'setting': "block", /* block the domain. Can be switched to "allow" */
'scope':'regular'}, /*it's either regular or incognito*/
function(){
/*optional action you want to
take place AFTER something's been blocked'*/
});
Here's the script I used to import into my json script for my chrome extension.
var link=""
var pattern=""
function linkOnClick(info, tab) {
r = /:\/\/(.[^/]+)/;
link=info.linkUrl
pattern="http://"+link.match(r)[1]+"/*"
chrome.contentSettings.javascript.set(
{'primaryPattern':pattern,
'setting': "block",
'scope':'regular'},
function(){
window.open(link)
});
}
chrome.contextMenus.create({title: "Load with no Javascript", contexts:["link"], onclick: linkOnClick});
I couldn't tell how any of this worked by reading the developer.chrome.com page! They really need add complete working examples or allow a way for users to add examples. I can't even use it. The git hub link is what saved me.
I have a google chrome extension that shares some code between it's content script and background process / popup. If it some easy and straightforward way for this code to check if it's executed as content script or not? (message passing behavior differs).
I can include additional "marker" javascript in manifest or call some chrome fnction unavailable from content script and check for exceptions - but these methods looks awkward to be. Maybe it's some easy and clean way to make this check?
To check whether or not your script is running as a content script, check if it is not being executed on a chrome-extension scheme.
if (location.protocol == 'chrome-extension:') {
// Running in the extension's process
// Background-specific code (actually, it could also be a popup/options page)
} else {
// Content script code
}
If you further want to know if you're running in a background page, use chrome.extension.getBackgroundPage()=== window. If it's true, the code is running in the background. If not, you're running in the context of a popup / options page / ...
(If you want to detect if the code is running in the context of an extension, ie not in the context of a regular web page, check if chrome.extension exists.)
Explanation of revised answer
Previously, my answer suggested to check whether background-specific APIs such as chrome.tabs were defined. Since Chrome 27 / Opera 15, this approach comes with an unwanted side-effect: Even if you don't use the method, the following error is logged to the console (at most once per page load per API):
chrome.tabs is not available: You do not have permission to access this API. Ensure that the required permission or manifest property is included in your manifest.json.
This doesn't affect your code (!!chrome.tabs will still be false), but users (developers) may get annoyed, and uninstall your extension.
The function chrome.extension.getBackgroundPage is not defined at all in content scripts, so alone it can be used to detect whether the code is running in a content script:
if (chrome.extension.getBackgroundPage) {
// background page, options page, popup, etc
} else {
// content script
}
There are more robust ways to detect each context separately in a module I wrote
function runningScript() {
// This function will return the currently running script of a Chrome extension
if (location.protocol == 'chrome-extension:') {
if (location.pathname == "/_generated_background_page.html")
return "background";
else
return location.pathname; // Will return "/popup.html" if that is the name of your popup
}
else
return "content";
}
I've been searching for examples and reference and have come up with nothing. I found a note in offscreenTab source code mentioning it cannot be instantiated from a background page (it doesn't have a tab for the offscreenTab to relate to). Elsewhere I found mention that popup also has no tie to a tab.
How do you successfully create an offscreenTab in a Chrome extension?
According to the documentation, offscreenTabs.create won't function in a background page. Although not explicitly mentioned, the API cannot be used in a Content script either. Through a simple test, it seems that the popup has the same limitation as a background page.
The only leftover option is a tab which runs in the context of a Chrome extension. The easiest way to do that is by using the following code in the background/popup:
chrome.tabs.create({url: chrome.extension.getURL('ost.htm'), active:false});
// active:false, so that the window do not jump to the front
ost.htm is a helper page, which creates the tab:
chrome.experimental.offscreenTabs.create({url: '...'}, function(offscreenTab) {
// Do something with offscreenTab.id !
});
To change the URL, use chrome.experimental.offscreenTabs.update.
offscreenTab.id is a tabId, which ought to be used with the chrome.tabs API. However, at least in Chrome 20.0.1130.1, this is not the case. All methods of the tabs API do not recognise the returned tabID.
A work-around is to inject a content script using a manifest file, eg:
{"content_scripts": {"js":["contentscript.js"], "matches":["<all_urls>"]}}
// contentscript.js:
chrome.extension.sendMessage({ .. any request .. }, function(response) {
// Do something with response.
});
Appendum to the background page:
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
// Instead of checking for index == -1, you can also see if the ID matches
// the ID of a previously created offscreenTab
if (sender.tab && sender.tab.index === -1) {
// index is negative if the tab is invisible
// ... do something (logic) ...
sendResponse( /* .. some response .. */ );
}
});
With content scripts, you've got full access to a page's DOM. But not to the global object. You'll have to inject scripts (see this answer) if you want to run code in the context of the page.
Another API which might be useful is the chrome.webRequest API. It can be used to modify headers/abort/redirect requests. Note: It cannot be used to read or modify the response.
Currently, the offscreenTabs API is experimental. To play with it, you have to enable the experimental APIs via chrome://flags, and add "permissions":["experimental"] to your manifest file. Once it's not experimental any more, use "permissions":["offscreenTabs"].
I'm developing a Chrome extension and have a strange problem with icon change on-the-fly.
In my popup.html I have a button by clicking on which I want to change the icon of the extension in the browser. E.g. from colored one to black and white (when application is inactive).
So the function which is responsible for this:
function toggleActivated(){
localStorage.isActive = toBool(localStorage.isActive) ? false : true;
$('#activate-disactivate span').text(toBool(localStorage.isActive) == false ? 'Включить' : 'Выключить');
chrome.browserAction.setIcon({path: toBool(localStorage.isActive) ? '48.png' : '48_bw.png'});
//window.close();
}
But the problem is that I want to close popup after the icon changed. If I use the window.close() at the end - then the icon is not changed, but if it is commented out - then the icon is changed fine.
Why is there a conflict between chrome.browserAction.setIcon() and window.close()?
It sounds like chrome.browserAction.setIcon is getting fired asynchronously but the popup is getting closed before it finishes. You could try adding a 500ms setTimeout before closing.
You should also file a bug report at new.crbug.com.
I know this is old, but I was having the same problem and abraham was right when he said that chrome.browserAction.setIcon was being called asynchronously. But I don't think that setting a timeout is the best answer.
If you check the setIcon documentation you can see that this method takes a function callback as parameter. That's where you should call window.close(). Like this:
chrome.browserAction.setIcon({ path: icon_path }, function() {
window.close();
});
UPDATE:
As niraj.nijju pointed in the comment below, you can pass a tabId param to the setIcon function to limit the scope of the change.
I'm in the process of making a Google Chrome extension, and encountered a problem.
I'm trying to upload and search through the DOM inside the popup.html.
Here is how I get the current tab (I found the script somewhere, credit doesn't belong to me):
chrome.windows.getCurrent(function(w) {
chrome.tabs.getSelected(w.id,function (response){
)};
My problem is this: I need to traverse through the DOM of the response. When trying to do so manually, I couldn't, as the response variable was now undefined for some reason, so using the Console isn't an option.
When trying to alert the response in the html file, it came as a object. Then, I tried to navigate through the response as if it has been the 'document' object, but no luck either.
Any help will be appreciated greatly.
You can get the selected tab for your popup by passing null as the window id to getSelected. () In your popup you can listen for extension events and execute a script to push the content to your popup:
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
if (request.action == "content")
{
console.log('content is ' + request.content.length + ' bytes');
}
});
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.executeScript(tab.id, { file: 'scripts/SendContent.js' } );
});
And finally the content script... I have it as "scripts/SendContent.js" in my extension folder, but the script is simple enough you could execute it by putting the code in the code property instead of the name in the file property of the object you pass to executeScript:
console.log('SendContent.js');
chrome.extension.sendRequest( {
action: "content",
host: document.location.hostname,
content: document.body.innerHTML
}, function(response) { }
);
Result:
POPUP: content is 67533 bytes
If you're having trouble, use console.log() and right-click on your page or browser action to inspect it and read your messages on the console (or debug your script from there).
I believe popups are sandboxed the same way that background pages are, so you'll need to use a content script to access the page DOM.
You can inject a content script with chrome.tabs.executeScript, handle your DOM traversal in the content script, then pass back the information you need from the content script to the popup using the message passing API.
I can try to elaborate on this if you give more information about the problem you're trying to solve.