Adding complex HTML using a Chrome content script Adding complex HTML using a Chrome content script google-chrome google-chrome

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:

  1. Place the *.htm or *.html files in your extension's source folder(s).

  2. Place any *.css and *.js files, that the HTML uses, in the extension folder(s) too.

  3. Declare the HTML file(s) as resources. EG:

    "web_accessible_resources": ["Embedded_Hello_world.htm"]


  4. Do not use any inline, or external server, javascript in your HTML files. This avoids problems with the Content Security Policy (CSP).

  5. 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:

  1. Creating a new extension folder.
  2. Download jQuery into it.
  3. Create the 5 files as specified below.
  4. Load the unpacked extension (You can see similar steps in this answer.)
  5. 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 the web_accessible_resources as in the the above answer^^
  • access templates.html from content.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>});