Updated
Thanks #kofifus for the info, Chrome as of 61 explicitly forbids content scripts on its default new tab page
Previous
Say I have the following sample extension, it will output test in console.
manifest.json
{
"name": "Test",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"content.js"
]
}
]
}
content.js
console.log('test');
Will above extension work well in chrome://newtab page?
Some helpful info:
I know by default chrome extension can't access to chrome:// pages, and we could change this behavior through chrome://flags/#extensions-on-chrome-urls
chrome://newtab in fact is a url like https://www.google.co.jp/_/chrome/newtab?espv=2&ie=UTF-8, so it shouldn't be blocked by above restriction.
There are many mouse gestures extension available, like crxMouse, they work well on chrome://newtab page
There are also some voices saying it's not allowed to inject content scripts in chrome://newtab, for example, #Xan's comments below this answer
and this author's case
So it looks weird as its different behavior across different devices( or settings?). Is there any official statements about whether content scripts can run in chrome://newtab pages? Or is there a setting we could change this behavior?
Chrome as of 61 explicitly forbids content scripts on its default new tab page
Q: Is there any official statements about whether content scripts can run in chrome://newtab pages?
A: Not really, but Google's documentation states that:
Host permissions and content script matching are based on a set of URLs defined by match patterns. A match pattern is essentially a URL that begins with a permitted scheme (http, https, file, or ftp, and that can contain '*' characters. The special pattern matches any URL that starts with a permitted scheme.
chrome://newtab only redirects the user to whatever url is set as the new tab page. Usually it will redirect the user to https://<your local google domain>/_/chrome/newtab(a permitted match pattern). But if another extension sets the new tab page to customNewTab.html, then chrome://newtab will redirect the user to chrome-extension://chrome-id/customNewTab.html, and any other extension's content scripts will not be able to run on the new tab.
This SA question also confirms this. If you try adding "exclude_matches": ["*://*/_/chrome/newtab*"], to your manifest, the content script will stop working on the new tab page.
Q: Is there a setting that could change this behavior?
None beside an override page set by another extension. (Note that themes only change the appearance of the new tab, and won't override the new tab url)
Q: Will above extension work well in chrome://newtab page?
A: yes, unless that tab was overriden by another extension.
I have a 30,000 user extension called Screen Shader on the extension store with a huge variety of different chrome versions and a few different browsers, and so far no one has complained about it not working on the new tab page, when they complain a lot about other things.
I'm not too sure why other people think it shouldn't work on the new tab page, but hopefully this answered all the questions you were having.
On a sidenote: Keypress problems with the new tab page
On his blogpost at http://www.toptip.ca/2010/01/google-chrome-content-script.html the developer of "Boss Key and Button" complains about issues with running a content script in the new tab page. His extension minimizes all chrome windows and opens the one you are currently on in a new tab whenever you press F9. He thought the content script didn't work on the new tab page because whenever he used his shortcut in the new tab page, nothing happened. He failed to realize that the reason it wasn't working on the new tab page was because chrome redirects any keypresses to the browser bar so his content script could not capture the keypress.
Try using his extension and pressing F9 on a random page. All chrome windows will be minimized. go back to that random page, and click in the address bar and try pressing F9. This time nothing will happen.
Related
I'm writing a web extension at the moment that should have a toolbar button, but should be disabled except for a handful of frequently visited sites. However, I can't find a way to indicate to the browser that it should enable the toolbar button selectively based on domain matching.
While I can restrict the content_scripts section using the "matches": [...] syntax, the background script will (of course) load universally, but there does not appear to be a way to specify in the manifest.json that there should be domain restrictions.
Alternatively, is there a simple way to tell the browser to disable a toolbar button (or swap out its graphic) unless the active tab's location matches a domain for running the extension's actions are meaningful? Looking at something like NoScript this should be possible, but I can't find any mention, let alone example, of how that might be done on MDN.
Whenever I open a new tab in Google Chrome I see the Google search bar plus 8 thumbnails of recently visited (or most visited) sites. I never click on the thumbnails and find them to be annoying. Is there anyway to disable this in Chrome?
I can think of a hacky workaround like creating a blank page someplace and setting that to be the new tab page, but there must be a better way. Any ideas?
Since nobody answered I thought I would post and answer to my question:
Use the Empty New Tab Page extension for a new blank tab instead of the default new tab.
There are also some redirect extensions such as Momentum, which loads a different full screen image each day.
type chrome://flags then Disable "Top Sites from Site Engagement"
Chrome allows extensions to run on chrome:// urls so one such possible future solution is if AdBlock explicitly requests the permission to run on chrome://newtab then you can just block the div with id most-visited. But currently AdBlock does not request this permission.
You could edit the manifest of AdBlock manually to include this permission or suggest it as a future feature.
The default new tap page's url is chrome-search://local-ntp/local-ntp.html. You can press F12 to check it. It's a local resource located in
C:\Program Files (x86)\Google\Chrome\Application\{Version}\resources.pak
or
C:\Users\%username%\AppData\Local\Google\Chrome\Application\{Version}\resources.pak
Open it with a HEX editor, search text
cur.style.opacity = 1.0
, and replace it with
cur.style.opacity = 0.0
Tested on Chrome 77.0.3865.90 .
I'm trying to list other extensions from my Chrome extension, and show their icons.
Another extension (Zenmate VPN) shows other's icons easily. I figured out that it has management permission in it's manifest.
I add "management" to optional_permissions and ask user to enable it after a click.
After that, I can list extensions, but the icons are still unaccessible in the page.
When I add management to permissions section, everything works fine. The problem is that we don't want to add this permission there, because Chrome will disable the extension by default if the updated version asks for more permisssions.
Is there a way to somehow refresh permissions in a page, in order to make icon URLs work (chrome://extension-icon/*), like they work in ZenMate?
If you already have chrome://favicon permission you can use it to display an extension favicon:
<img src="chrome://favicon/chrome-extension://igiofjhpmpihnifddepnpngfjhkfenbp/">
In case you didn't have chrome://favicon permission initially, try adding it in optional_permissions. If it won't work, try adding to permissions but first test if it'll disable your extension on update.
Other icon sizes may be specified (in the absence of an actual big icon the default 16x16px is scaled):
Retina 2x DPI: chrome://favicon/size/16#2x/chrome-extension://.......
48px: chrome://favicon/size/48/chrome-extension://.......
I checked if I could go with wOxxOm's answer, and mostly extensions did not have bigger favicons, nor I can request chrome://favicon/* permission: Chrome throws an exeption:
Unchecked runtime.lastError while running permissions.request: 'chrome://favicon/*' is not a recognized permission.
So I found a simple and robust solution: I just close the current tab and create a new one:
permissionsAchieved = function(allowed) {
chrome.tabs.create({ url: "<write current url here>" });
window.close();
},
Done. In the newly opened tab, the icon is shown correctly.
But thanks for a suggestion!
Branching off my Other Question, a user successfully got me to serve a stylesheet but that is the wrong way; it is not what I needed to do.
So I have come up with a more accurate question:
Basically, you can make an extension permanently modify a web page by defining a content script in manifest.json.
I need the ability to, on the click of a button within popup.html, toggle a stylesheet on or off.
The answer to my other question I linked to, only allows my to serve a stylesheet, but that is removed again as soon as the page is reloaded.
I want to basically set the option for the extension to permenantly turn on a stylesheet for a web page, or to turn it off, by clicking the toggle button located in the browser icon popup.html.
See the screenshot:
I think what I need is for the button to change a setting in the extension which will either turn on or turn off a css stylesheet content script, or swap with a different css stylesheet content script.
I hope I have made this clear enough to understand.
Why do you want to re-invent the wheel?
Have a look at Stylish for Chrome, a UserScript manager (originated from Stylish for Firefox).
If you still want to continue development of such an extension, the following methods can be used, on top of the one I described in my previous answer:
chrome.tabs.onUpdated - Detect tab state changes (place this code in your background page):
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.executeScript(tab.id, {code:
'document.documentElement.setAttribute("RWchooseStyle", "style1.css");'
});
// myscript.js defined in https://stackoverflow.com/a/9647059
chrome.tabs.executeScript(tab.id, {file: 'myscript.js'});
});
localStorage - For persistence (so that preferences can be "remembered" in your extension):
localStorage.getItem('name') to retrieve preferences, localStorage.setItem('name','value') to set preferences.
Only strings can be remembered, so string = JSON.stringify(some_variable) and original_variable = JSON.parse(string) can be used in order to save numbers, arrays and other primitives.
According to the docs I have made an Google Chrome Extension that I would describe as a "browser action" because it is present on all pages. However, my extension doesn't require any interaction so having a badge next to the omnibox is pretty wasteful. I have installed extensions that do not appear anywhere (except maybe in the context menu). How is that done and is that best practice?
Having page action or browser action icons is totally optional if you don't have any popup attached to them, so just remove the whole browser_action section from your manifest file.