I would like to create a chrome extension which changes my default tab in chrome browser.
Inside the page I will put my favorite websites, which I think I can handle using HTML + CSS. My difficult part is how to make it become a chrome extension because I have never done it before.
Can anyone give me some basic steps which I could start with?
You are looking for what's called Override Pages.
An extension can declare that it supplies a new newtab page. Here's a strictly minimal manifest for it:
{
"manifest_version": 2,
"name": "My awesome New Tab override",
"version": "1.0",
"chrome_url_overrides" : {
"newtab": "newtab.html"
}
}
Then you can use this manifest, together with a newtab.html and required resources, to make a simple extension.
There are many guides past that point; you can see the Learn Basics part of the official docs. Remember you can always ask a new question here if you run into specific implementation questions.
Related
Trying out Windows Terminal customization via settings.json. I found a profiles.json that follow the new conventions closely enough to work when pasted into settings.json, (I know it took because the theme changed). The problem is that changes to "fontFace" are not having any effect. I'm trying to use a nerd font for some powerline stuff, works in Powershell running in ConEmu but not in Windows Terminal. Here is the relevant portion of settings.json:
{
"$schema": "https://aka.ms/terminal-profiles-schema",
"defaultProfile": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
// You can add more global application settings here.
// To learn more about global settings, visit https://aka.ms/terminal-global-settings
// If enabled, selections are automatically copied to your clipboard.
"copyOnSelect": false,
// If enabled, formatted data is also copied to your clipboard
"copyFormatting": false,
// A profile specifies a command to execute paired with information about how it should look and feel.
// Each one of them will appear in the 'New Tab' dropdown,
// and can be invoked from the commandline with `wt.exe -p xxx`
// To learn more about profiles, visit https://aka.ms/terminal-profile-settings
"profiles":
{
"defaults":
{
// Put settings here that you want to apply to all profiles.
"cursorShape": "vintage",
"fontFace": "Iosevka Nerd Font"
},
"list":
[
{
// Make changes here to the powershell.exe profile.
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"hidden": false,
"fontFace": "Iosevka Nerd Font",
"colorScheme": "PowerShellTom",
"useAcrylic": true,
"acrylicOpacity": 0.8
},
{ ...
I get the same behavior in Windows Terminal Preview, which is supposed to be the least "bleeding edge" version.
Even trying non-nerd fonts for "fontFace" has no effect, however, "fontSize" will work.
For people who are coming from SCOTT HANSELMAN article (especially from the third step)
Install Cascadia Code for all users
Change the "fontFace" property in the settings.json like this
Shortcut to open settings.json: Ctrl+Shift+, (comma)
here is the code to copy
"profiles": {
"defaults": {
"fontFace": "Cascadia Code PL"
// Put settings here that you want to apply to all profiles.
}
}
This is the only way I made that work (after 2 hours or trying)
Change the fontFace from "Iosevka Nerd Font" to just "Iosevka"; the fontFace attribute expects a font family, as far as I'm aware this isn't in the documentation and I only found it out after reading this issue on the WT github
I wanted to install MesloLGS NF Regular as a recommended font for Powerlevel10k in WindowsTerminal for WSL:
https://github.com/romkatv/powerlevel10k/blob/master/font.md
To make it work I had to:
Install it for all users as #hakan-fıstık showed in his answer.
Change the "fontFace" in settings.json to "MesloLGS NF" (Supplying full names of fonts is not working as supposed to).
Be sure to change size of font (changing font may make it huge): https://learn.microsoft.com/en-us/windows/terminal/customize-settings/profile-appearance
From a comment to the Issue I opened on Windows Terminal's GitHub page, (#6606), I was directed to another fontFace problem where choosing another font would not stick if you reopened WT, (not quite the problem I was having).
Anyway, the current solution to that is to uninstall any font you want to use, then right-click and choose "Install for all users". Double-click the file to open the sample view, and use the font name found just below the the two buttons. use the spaces in the font name as is in your settings.json file.
This worked for MesloLGL NF, but not Iosevka NF.
In my experience, editing the 'settings.json' file manually creates more issues than it resolves. The easiest way to edit the default font of your terminal is as follows:
Open the settings
Select Ubuntu under the 'Profiles' header on the sidebar
Scroll down to 'Additional Settings' and select 'Appearance'
Under the text header, change the 'Font face' attribute to your preferred font
Open 'settings.json' to view changes
You should see the expected format for selecting a font - Should you wish to edit the json file manually, you should follow this format
Save changes and exit
I attempted to create a custom element in a Chrome extension content script but customElements.define is null.
customElements.define('customElement', class extends HTMLElement {
constructor() {
super();
}
...
});
So apparently Chrome doesn't want content scripts to create custom elements. But why? Is it a security risk?
I can't seem to find anything in Chrome's extension guide that says it's not allowed.
I found the solution reading this page but the information was so cumbersome I wanted to write this answer for future readers (I am using Manifest v3)
Firstly, install the polyfill :
npm install #webcomponents/webcomponentsjs -D
Then add the polyfill in your content_scripts block in your manifest file :
"content_scripts": [{
"matches": [ "..." ],
"js": [
"./node_modules/#webcomponents/webcomponentsjs/webcomponents-bundle.js",
"content.js"
]
}]
(important: you have to load it before your content script of course as the polyfill needs to load before you can use it)
Now it should works. Cheers
Note: the customElements feature is implemented in most modern browsers but for some reasons the interface is not available from a content script because the scripts are run in an isolated environment (not sharing the same window object space from the webpage the extension runs in).
As of now custom element can be used in chrome extensions UI. In Popup ui, option page ui and in the content script as well But it requires a polyfill which is this.
https://github.com/GoogleChromeLabs/ProjectVisBug - this is the one big custom element in the chrome extension.
How can I go about redirecting chrome in an extension when visiting a given URL?
For example: when I visit http://yahoo.com/ I want it to redirect to http://google.com/
NOTE: A former version of this question asked whether there is any Google chrome extension which automatically redirects the tab when it visits a certain URL. Accordingly, the (currently two) answers below address different questions.
There are many options, the one more convoluted than the other.
The webRequest API, specifically the onBeforeRequest event. (Even better, the upcoming declarativeWebRequest API).
Content scripts. Inject location.replace('http://example.com') in a page.
The tabs API. Use the onUpdated event to detect when a page has changed its location, and chrome.tabs.update to change its URL. Avoid an infinite loop though!
The first one is the best one, because it is activated before a page is even requested. The second one can be activated after the request has been fulfilled, but before the page is rendered ("run_at":"document_start") or after it's rendered ("run_at":"document_end"). I mentioned the last one for completeness, but you shouldn't use it, because the other options are way better.
Here's an example using the webRequest API, a simple extension which allows me to browse pages on the Pirate bay, even though the main hosts are taken down by my ISP (the actual list of URLs is much longer, but I have omitted them for the sake of the example).
See match patterns for an explanation on the URL formats.
manifest.json
{
"name": "The Pirate Bay",
"description": "Redirect The Pirate Bay to a different host",
"version": "1.0",
"manifest_version": 2,
"background": {"scripts":["background.js"]},
"permissions": [
"webRequest",
"*://thepiratebay.se/*",
"*://www.thepiratebay.se/*",
"webRequestBlocking"
]
}
background.js
var host = "http://tpb.pirateparty.org.uk";
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {redirectUrl: host + details.url.match(/^https?:\/\/[^\/]+([\S\s]*)/)[1]};
},
{
urls: [
"*://piratebay.se/*",
"*://www.piratebay.se/*"
],
types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
},
["blocking"]
);
I know I am a bit late in the game to answer this question Still I would like to answer this for future readers. Have a look at
Requestly - A Chrome Extension to modify Network Requests.
Currently, You can setup rules for
Redirect a request URL to another url.
Block some requests.
Replace some part in URL with another string
Modify Headers (Add/Remove/Modify Request and Response Headers)
Screenshots for more understanding:
List of Rules
Rule Type Cards
New Redirect Rule
Headers Modification Rule
There are lot of things in roadmap to be covered in requestly like
Switching User Agents
.. and a lot more.
PS: I have created this So you can blame me if you do not find this helpful :)
You could use my extension. Go to "Rewrite Rules" tab, click the "+" button and add a new rewrite rule. Note that the rewrite rule is actually an RegEx so characters like / must be escaped
https://chrome.google.com/webstore/detail/dev-helper/kbbgddcndpjnadfacanamniaomcohlcc?hl=en
I'm new to extension development, maybe someone has a small example ready for my problem.
I plan a more complicate code (that will execute chromium API functions), but solving this task should help me get started:
I want to create an extension that triggers a popup or alert() (just anyything) based on a website javascript call.
So for example my website has a button, when clicked on the button a javascript with a few parameters is executed.
My extension picks those parameters up and executes APIs (for my example just any popup) based on the parameters.
In my basic example I'd like to trigger some sort of popup/notification with the text supplied by the website javascript.
Also only my website domain should be allowed to trigger that, anything else should be rejected.
I'd really appreciate help.
Here is my "empty" manifest
{
"name": "Special API",
"version": "1.0",
"description": "API demo extension.",
"browser_action":
{
"default_icon": "gears.ico",
"popup": "show_credits.htm"
},
"permissions": [
"http://www.mywebsite.com/"
]
}
Here the example button in my website.com/example
<html>
<body>
<button onClick="extension_do_exec('Hellow world','abcabc')">Execute extension function</button>
</body>
</html>
The approach you described is problematic, bacause javascripts of web-pages, and javascripts of extensions are isolated from each other (there is a concept of isolated world). So it is not possible to get a value "supplied by the website javascript" directly into the extension's javascript. I'd suggest another approach. You possibly could exchange with some values by assigning them as properties to DOM objects. These properties can be accessed from a content script, injected into the web-page. Of course, the content script can determine domain of the page and work as appropriate. As for popups, these are internal pages of an extension, and you should implement some kind of messaging between them and your content script.
I'd like to make a very simple extensions that slightly alters how the Downloads page looks. Changing the History page might be interesting too, but that's for later.
Is there a way to do that?
I tried making a Content Script extension, with "chrome://downloads" as match in manifest.json. Chrome won't allow that and responds with an error when packaging the extension.
Is there another simple way? It has to be simple, because changes would be simple, because all chrome:// pages are built with HTML, JS and CSS.
edit
After trying with background scripts a little...
I can't get chrome.tabs.executeScript to work! I added in background.html:
chrome.browserAction.onClicked.addListener(function(tab) {
alert(this.document.body.innerHTML);
alert(chrome.tabs.executeScript(null, {
code : "document.body.style.backgroundColor = 'red';"
}));
});
And I added this in manifest.json to add a (invisible) 'browser action button':
,"browser_action": {
/* "popup": "background.html",*/
"name": "Alter page"
}
The onClicked event fires both alerts (first is background.html's body, second is undefined). But the code (a string with document.body.style.backgroundColor = 'red';) doesn't execute! And ofcourse there's no debugging for extensions like this =)
Any tips anyone? I'm trying to get a hold of the tab's window.document (not background.html's window.document!). An injected script (that's what chrome.tabs.executeScript is supposed to do) should do that.
PS
I'm stealing from make_page_red/manifest and make_page_red/background.html
The 'extension' I have so far: http://hotblocks.nl/js/downloads.rar
EDIT
I found out what I want to achieve is possible with just CSS. I don't need to inject javascript. Does that make it easier? Does that make it possible? =)
According to this documentation, chrome:// URLs are an invalid scheme so they won't be matched:
A match pattern is essentially a URL that begins with a permitted scheme (http, https, file, or ftp), and that can contain '*' characters.
I would look into using override pages instead.
As requested, here's my extension that can at least load when chrome://downloads is loaded, although as I said, I don't think you can modify the page even if you know that's the page you're viewing.
manifest.json
{
"name": "Test",
"version": "0.0.1",
"background_page": "background.html",
"permissions": [
"tabs"
]
}
background.html
<script>
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab)
{
if (tab.status == "complete")
{
alert(tab.url);
// should alert 'chrome://downloads' on that page. You can
// check for this url here and then do whatever you want
}
});
</script>
Update: Since Chrome 31 there is an API for extensions that allows access to Chrome's downloads: https://developer.chrome.com/extensions/downloads
There's also an API that allows access to list and manage other installed extensions: https://developer.chrome.com/extensions/management
(Previous Answer)
Unfortunately, there's not currently an API for Chrome extensions to access information about a user's downloads. It's a widely requested feature, though, and there's some discussion among Chrome developers here: http://code.google.com/p/chromium/issues/detail?id=12133
Star the issue if it's a feature that you'd like to see, and you'll receive email updates.
As this page shows, there is no API to override the downloads page... However, there is a way to make a file you have made replace the chrome://downloads/ page whenever it is loaded using javascript in your background page...
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status === "loading"){
if(tab.url === "chrome://downloads/"){
chrome.tabs.update(tab.id, {url: "REPLACEMENT.html"});
}
}
});
Essentially what this does is - As soon as the page chrome://downloads begins loading (using the tabs.onUpdated API), the page is redirected to REPLACEMENT.html (Using tabs.update API)... There is no visible delay in the tab update
as this script is run before the chrome://downloads page begins loading... You can use a similar code in your file by pressing CTRL + U on the downloads page to view and copy its source code