I am working with Chrome extension's content script to create a complex display that is added on web pages.
I have first tested it directly integrated on a website, but now I need to put it in an extension.
The thing is that the content script API for Chrome only allows to inject javascript. That means that, to inject complex HTML layouts I would need to write it entirely with JS objects, which is long to write, hard to maintain and absolutely not designer-friendly.
I'm wondering if anyone know or can think of a clever way to get a better workflow on this.
Page Edit is an extension that let you make changes to any HTML webpage. To work with this add-on, simply open the toolbar popup UI and then click on the big toggle button at the left side.
A content script is a part of your extension that runs in the context of a particular web page (as opposed to background scripts which are part of the extension, or scripts which are part of the website itself, such as those loaded using the <script> element).
You can use the chrome. scripting API to inject JavaScript and CSS into websites. This is similar to what you can do with content scripts, but by using the chrome.
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.
You can see this in action by:
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:
templates.html
to store script templates intemplates.html
to the web_accessible_resources
as in the the above answer^^templates.html
from content.js
with xhr and parse with jQuery"web_accessible_resources": ["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>
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>
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With