How to include HTML and CSS files in a chrome extension? - html

I am creating a chrome extension. I have a small extension which includes CSS, javascript and HTML files. I want to run this extension on any web page, but content_script only allows me to run a script file. When I add css or html file extensions it doesn't work. It doesn't show the HTML page that I created for the extension, just script.js. How can I add and HTML file in content_script?
This is my manifest.json file:
{
"manifest_version":2,
"name":"News Plugin",
"description": "This extension will show you the latest news with headlines and small description",
"version":"1.0",
"browser_action":{
"default_icon":"news_icon.png",
"default_popup":"NewsApp.html"
},
//"chrome_url_overrides":{
//"newtab":"NewsApp.html"
//},
"content_scripts":[
{
"matches":["http://*/*","https://*/*"],
"js":["news.js"],
"html":["news.js"],
"css":["style.js"]
}
],
"permissions":[
"activeTab"
]
}

See https://developer.chrome.com/extensions/content_scripts for the specification of the content_scripts property in manifest.json. There's no "html" property in content_scripts. If it did allow injecting HTML, where would it put it, since the original page already has its own HTML? You can only add Javascript and CSS.
If you want to add HTML to the page, you'll need to do it in your Javascript, using DOM manipulation functions, which allow you to specify where the new elements should go.

Related

Why can't you create Custom Elements in content scripts?

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.

Registering Native Client modules to handle MIME types doesn't work on ajax or sub request

I am writing a new image format decoder for Chrome with a Native Client module.
I use this manifest to create a chrome extension :
{
"name": "paver-jbig2",
"manifest_version": 2,
"version": "0.1.0",
"minimum_chrome_version": "35",
"web_accessible_resources": [
"paver-jbig2.nmf",
"paver-jbig2_arm.nexe",
"paver-jbig2_x86_32.nexe",
"paver-jbig2_x86_64.nexe"
],
"nacl_modules": [
{
"path": "paver-jbig2.nmf",
"mime_type": "image/jbig2"
}
]
}
When I call an URL http://my.company.com/myimage.jbig2, I can see that the nacl module is called without error.
But when I call this URL inside an HTML page with ajax, or in JavaScript with image.src=“http://.../myimage.jbig2”, the NaCl module is not called.
What’s wrong ?
As I suggested here, I believe what you are trying to do is not possible. A NaCl module can only be loaded in an embed element.
The reason it works when you type it as a URL is that a HTML page is automatically created for you with an embed element that fills the page.
Here is a potential workaround: modify your Chrome extension to use a content script. This content script can read the contents of the page and look for all img elements of type jbig2. If one is found, you can send the URL to your NaCl module (in your extension's background page), which will decompress the image and send the decompressed image back to JavaScript via an ArrayBuffer. Now you can create a Blob from this ArrayBuffer, and create a Blob URL from the Blob. This URL can now be used in place of the original URL in the src attribute of the img element.

Tool to replace URL with custom content

Is there a development tool or Chrome / Firefox extension that lets you replace the contents of a specific URL with my own custom content?
I'm not looking for a simple /etc/hosts file change, because I want to replace a URL, not just a domain.
In a Chrome extension, the webRequest API can be used to redirect URLs to a different URL. This other URL can be another online page, but also a page within your Chrome extension.
A simple example for the webRequest API, and a list of other options can be found in this answer.
Note: If you just want to add / change something on a specific page, Content scripts may be more suitable. You can then change the content of a specific page by standard DOM methods.
In Firefox, you can use the page-mod module of the Addon SDK to implement the Content script.
chrome.tab API will let you to make any related changes to a tab in a window.
References:
a) Tabs API
b) Basic Chrome Extension architecture.
You can refer this Sample Extension for changing all URL's in a current tab to Google.co.in
manifest.json
This is a core file where we register all chrome extension content, ensure it is with all permissions.
{
"name":"Tabs Demo",
"description":"This Demonstrates Demo of Tabs",
"browser_action":{
"default_icon":"screen.png",
"default_popup":"popup.html"
},
"permissions":["tabs"],
"manifest_version":2,
"version":"1"
}
popup.html
Trivial HTML file referring to a JS file to pass CSP.
<!doctype html>
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
popup.js
function tabsfunction() {
//fetching all tabs in window
chrome.tabs.getAllInWindow(function (tabs) {
// Iterating through tabs
for (tab in tabs) {
//Updating each tab URL to custom url
chrome.tabs.update(tabs[tab].id, {
"url": /*You can place any URL you want here*/
"https://www.google.co.in/"
}, function () {
//Call back
console.log("Completed");
});
}
});
}
//Binging a function on document events
document.addEventListener("DOMContentLoaded", tabsfunction);
Let me know if you need more information.

Could I make a Google Chrome extension for chrome pages (downloads, extensions etc)?

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

Google Chrome extension relative path

I'm developing a google chrome extension and I'm running into a relative path problem.
If I give a relative path to an image and open the plugin in a certain page it will look for that image in the website's path rather than the extension's.
Any ideas?
If you're using CSS in your extension pages (background, popup, infobar, etc) then you can use relative paths with a slash (/):
background-image:url("/sprites.png");
The above should work, everyone uses it. But, if your using it for content scripts and you can do the same for any css, you would need to use the predefined message like:
background-image:url('chrome-extension://__MSG_##extension_id__/sprites.png');
If you want to programmatically set it, you can use the chrome.extension.getURL syntax as following:
var url = chrome.extension.getURL('sprites.png');
These are the ways that you can refer to a specific url/image.
In addition, as mentioned in this answer, if you place your image assets in a directory, these files are not accessible in the web page DOM automatically. The developer should specify the resources that can be loaded the page by using the "web_accessible_resources" setting in the manifest.json file:
#mohamed's answer worked for me but it took my a while to put it all together. I've answered this else where but here is the solution that worked for me.
My solution.
With Menifest v2 you need to add web_accessible_resources to the file and then use chrome-extension://__MSG_##extension_id__/images/pattern.png as the url in your css file.
CSS:
#selector {
background: #fff url('chrome-extension://__MSG_##extension_id__/images/pattern.png');
}
Manifest.json
{
"manifest_version": 2,
"name": "My Extension Name",
"description": "My Description",
"version": "1.0",
"content_scripts": [
{
"matches": ["https://mydomain.com/*"],
"css": ["style.css"]
}
],
"permissions": [
"https://mydomain.com/"
],
"browser_action": {
"default_icon": {
"19": "images/icon19.png",
"38": "images/icon38.png"
},
"default_title": "My Extension Name"
},
"web_accessible_resources": [
"images/pattern.png"
]
}
p.s. Your manifest.json might look different to this one.
In some cases you might even use inline base64 encoding of the image. For example,
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB..." />
Same you can apply to your CSS. You can find image encoders all over the web.