TL;DR, link to an example extension at the bottom ;)
Ok, your question is a bit broad but I'll try to explain the approach I would take if I wanted to do this.
First, I'd drop the iFrame. I can't see any reason to use one here and I just dont like them personally.
I would:
- have a content script that is injected into all pages (or specific one if needed, whatever)
- the script would have a javascript class that adds a
chrome.runtime.onMessage.addListener
to the page
- this class would listen for messages from the extension
- messages would be sent to this class to trigger functions and send back a response
- for example a message like
{pageAction:"getImages"}
would trigger the getImages
function in the injected class
getImages
would get all the images and send them back to the extension
One note here, I prefer to work with images encoded as base64 strings with stuff like this rather than image urls from a whole bunch of different domains and all the CORRs, link protection,....etc. For that reason, I would have the getImages
make an ajax call to encodeImagesToBase64.php
a server passing an array of image urls. encodeImagesToBase64.php
would return an array of base64 images which are then sent to the extension.
- Now that the extension has an array of base64 images, Id save them to
chrome.storage.local
in the extension's storage area.
- Now you can show them in the popup, show them in a new tab for editing, or whatever
- If you want to show them on the page in an overlay, just make a function to do that in the javascript listener class we made and send a message to it with the images to display
To get you started, here is a javascript listener class I use to do similar things in my extensions.
(note that this relies on John Resig's Simple JavaScript Inheritance which I highly recommend using when writing Classes )
// IMPORTANT NOTE you must reload your extension via chrome://extensions
// AND reload the browser tab in order for changes to this file to be seen!!
var PageActionListener = Class.extend({
/**
* This class is meant to be injected into a webpage
* once there, it listens for messages from an extension
* messages must pass like {pageAction:"someAction", ... }
* where someAction should map to a function in this class
* responses should take the form
* {success:true, pageAction:"someAction", data:"someData", ... }
*/
attachListener: function() {
/**
* Attaches a chrome message listener to the current page
* this allows the extension to call
* the functions in this class from the context of the page
* and receive responses from those functions via messaging
*/
var _this=this;
// Listen for messages from the popup
chrome.runtime.onMessage.addListener(function (msg, sender, extensionCallback) {
// First, validate the message links to a function
if (msg.pageAction) {
// then make sure its a legit function in this class
if(typeof _this[msg.pageAction] === "function"){
// call that fucntion
_this[msg.pageAction](msg,function(response){
extensionCallback(response);
});
}
else extensionCallback({success:false,msg:msg,error:"Action not found"});
return true;
}
});
},
getImages:function(msg,callback){
/**
* Traverses the DOM looking for images and returning them
* as an array of base64 strings
* @param object msg The message that triggered this action
* @param function callback A function to be called when the action below is complete
* passes to callback the images gathered from the page
*/
var images = [];
var $images= $('img');
$images.each(function(){
var url = this.src;
images.push(url);
});
// convert images to base64
$.ajax({
type: "POST",
url: "https://somedomain.com/shared-resources/php/encodeImagesToBase64.php", // you'll need to update this to your path
data: {urls:images},
success: function(response) {
response.msg=msg;
send the response back to the extension
callback(response);
},
error: function(xhr, status, error) {
callback({success:false,msg:msg,error:error.Message})
}
});
},
// add other functions that need to be called by the extension here
});
And here is the contents of encodeImagesToBase64.php
to convert the images to base64:
<?php
if (isset($_POST['urls']) ){
$imageStrings=[];
foreach($_POST['urls'] as $url){
$imageStrings[]=base64_encode(file_get_contents($url));
}
echo json_encode(['success'=>true,'images'=>$imageStrings]);
}else{
echo json_encode(['success'=>false,'error'=>'Error: No images to encode']);;
}
It'll need a ways to go to meet your actual needs but, it should be enough for you to understand the concepts and the approach Ive proposed above.
NOTE the example extension uses a copy of encodeImagesToBase64.php
that is hosted on my server, you'll need to host your own and update the ajax call with the path to it. Ill leave mine up for now so you can test it out, but dont count on it being around forever :)