Adding complex HTML using a Chrome content script
It's relatively easy to add whole web pages by having your content script inject them in an iframe. Just follow these guidelines:
Place the
*.htm
or*.html
files in your extension's source folder(s).Place any
*.css
and*.js
files, that the HTML uses, in the extension folder(s) too.Declare the HTML file(s) as resources. EG:
"web_accessible_resources": ["Embedded_Hello_world.htm"]
Do not use any inline, or external server, javascript in your HTML files. This avoids problems with the Content Security Policy (CSP).
This question doesn't cover communicating with the page/iframe, but if you want to do that, it is a bit more involved. Search here on SO; it's been covered many times.
Example:
You can see this in action by:
- Creating a new extension folder.
- Download jQuery into it.
- Create the 5 files as specified below.
- Load the unpacked extension (You can see similar steps in this answer.)
- Reload this page in Chrome; you'll see the "Hello World" page, embedded at the top.
Create these files in the extension folder:
manifest.json:
{ "manifest_version": 2, "content_scripts": [ { "js": [ "iframeInjector.js" ], "matches": [ "https://stackoverflow.com/questions/*" ] } ], "description": "Inject a complete, premade web page", "name": "Inject whole web page", "version": "1", "web_accessible_resources": ["Embedded_Hello_world.htm"]}
iframeInjector.js:
var iFrame = document.createElement ("iframe");iFrame.src = chrome.extension.getURL ("Embedded_Hello_world.htm");document.body.insertBefore (iFrame, document.body.firstChild);
Embedded_Hello_world.htm:
<!DOCTYPE html><html><head> <title>Embedded Hello World</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link href="HelloWorld.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="HelloWorld.js"></script></head><body><p>Hello World!</p></body></html>
HelloWorld.css:
body { color: red; background-color: lightgreen;}
HelloWorld.js:
$(document).ready (jQueryMain);function jQueryMain () { $("body").append ('<p>Added by jQuery</p>');}
This may be better, no external library and no iframe. Is nearly the same as iautomation solution.
var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var div = document.createElement('div'); div.innerHTML = this.responseText; document.body.insertBefore(div, document.body.firstChild); } else { console.log('files not found'); }};xhttp.open("GET", chrome.extension.getURL("/content.htm"), true);xhttp.send();
I had the same issue, that my extension heavily relies on script templates
Here's what I did:
- create
templates.html
to store script templates in - add
templates.html
to theweb_accessible_resources
as in the the above answer^^ - access
templates.html
fromcontent.js
with xhr and parse with jQuery
manifest.json
"web_accessible_resources": ["templates.html"]
templates.html
<script id="template1" type="text/template"> <div class="template1">template1</div></script><script id="template2" type="text/template"> <div class="template2">template2</div></script>
content.js
function getTemplates(){ return new Promise(function(resolve){ $.ajax({ url: chrome.extension.getURL('/templates.html'), success: function(data) { var $templates = $('<div></div>').append($.parseHTML(data)).find('script'), templates = {}; $templates.each(function(){ templates[this.id] = this.innerHTML; }); return resolve(templates); } }); });}getTemplates().then(function(templates){ console.log(templates.template1); //<div class="template1">template1</div>});