For Chrome Extensions I would specifically use sandboxingEval which allows the loading of sandboxed files that can be accessed within an iframe that the extension hosts. The only message passing would be through normal iframe messaging.
For example, declare within the manifest.json
which page to sandbox:
{
...
"sandbox": {
"pages": [
"plugin.html"
]
"content_security_policy":
"sandbox allow-scripts; script-src 'self' https://plugin.com/"
],
...
}
Make sure the external domain is white-listed so it could be embedded. In the CSP policy, allow-scripts
is there if embedding <scripts>
is needed.
Now within the sandboxed page plugin.html
, do anything with the external script. In this case, the external plugin is downloaded, and passing messages back to the extension process through messaging.
<!doctype html>
<html>
<head>
<script src="https://plugin.com/mohamedmansour/plugin.js"></script>
</head>
<body>
<script>
// Whatever my plugin contract is, lets send something back to our extension
// that the plugin initialized.
Plugin.do.something.here(() => {
window.postMessage({
name: 'CustomInitEvent',
data: 'initializing'
}, *);
});
// Listen from your extension plugin.html page some events.
window.addEventListener('message', (event) => {
var command = event.data.command;
switch(command) {
case 'CustomCommandA':
event.source.postMessage({
command: 'CustomCommandHello',
data: 'pong command a'
}, event.origin);
break;
}
});
</script>
</body>
</html>
Now within the popup or anywhere, just embed the plugin.html
. In this case, popup.html looks like this
<html>
<head>
<script src="plugin-manager.js"></script>
</head>
<body>
<iframe id="theFrame" src="plugin.html"></iframe>
</body>
</html>
Then your plugin-manager.js
is responsible of controlling plugin.
const iframe = document.getElementById('theFrame');
window.addEventListener('message', function(event) {
switch(event.name) {
case 'CustomInitEvent':
console.log('Plugin Initialized');
break;
case 'CustomCommandHello':
console.log('Hey!');
break;
}
});
iframe.contentWindow.postMessage({
command: 'CustomCommandA'
});
iframe.contentWindow.postMessage({
command: 'CustomCommandB'
});
Something along those lines. If dynamic plugins is what is needed, just add query parameters to the iframe. Within plugin.html
, just dynamically add the script element, and just call it this way:
<iframe id="theFrame" src="plugin.html?id=121212"></iframe>