1

I am creating a chrome extension that needs to open a blank page and then depending upon some injected script open 1/2 iframes inside this blank window.

My issue is how do I open a blank window that I can inject and run JS from?

I have attempted this by opening a page with the url of about:blank but I can not inject the script onto this page because of the following error:

chrome.tabs.create({
    url: 'about:blank'
}, function(tab) {
    chrome.tabs.executeScript(null, {
        file: 'jquery/jquery.js'
    }, function() {
        console.log('done', arguments);
    });
});

tabs.executeScript: Cannot access contents of url "about:blank".
Extension manifest must request permission to access this host.

Obviously this error message makes me think that I don't have permission to access this url and updated my manifest to allow access to all urls but I have the same issue.

"permissions": [
    "tabs",
    "*://*/*"
],

Extra Info

The reason why I am not opening a url directly is because I have 2 urls that I need to access one after the other. These files are upgrade scripts that I will need to see the results from.

The best way to do this would be to open a page and have an iframe of the left and right hand sides of the window that I can control using my injected script.

Undefined
  • 11,234
  • 5
  • 37
  • 62

1 Answers1

2

You can just make a dummy upgrade page in your extension's package, lets call it upgrade.html

use it to make your structure and add the 2 iframes that you want. If you want to control it, you can use message passing using a background script to communicate between 2 javascript pages. To communicate from parent page to iframe, just look at any answer in Invoking JavaScript code in an iframe from the parent page

If you don't know the logic that you want to run beforehand - although you should - then you can just pass along whole strings between the pages and and eval them on the other side - although this is not something you generally want to do. Here's the docs for message passing: http://developer.chrome.com/extensions/messaging.html


In a nutshell: you have page A with your contentscript, page B is your background page and page C is the update page with the 2 iframes, then:

// A.js
var port = chrome.runtime.connect({name: "content-script"});
port.postMessage({ runScript: 'yahoo(); function yahoo; () { alert("Yahoo!"); }' });

// B.js
// The background page is only used as a proxy
var upgrade_port = null;
chrome.runtime.onConnect.addListener(function(port) {
  switch (port.name) {
    case 'content-script':
       // Also you need to query for the upgrade page and open it if it does not exist
       port.onMessage.addListener(function(msg) {
         upgrade_port.sendMessage(msg);
       });
       break;
    case 'upgrade-page':
      upgrade_port = port;
      break;
    default:
      console.warn('Unknown port name: ' + port.name);
  }
});

// C.js
var port = chrome.runtime.connect({name: "upgrade-page"});
port.onMessage.addListener(function (message) {
  if (message.runScript) {
    eval(message.runScript);
  }
});

You need to use port otherwise you can't communicate from one page to the other. Also, it's a lot better if you just insert the JS in page C beforehand and have it static and just pass along the arguments to the functions RPC-style (Remote Procedural Call), aka:

// A.js
port.postMessage({action:'RPC', name:'yahoo', args:['hello', 'world', 3]});

// C.js
var RPCs = {
  yahoo: function (str1, str2, no) {
    alert(str1 + ',\n' + str2 + '\nThis is a number: ' + no);
  }
};

port.onMessage.addListener(function (msg) {
  switch (msg.action) {
    case 'RPC':
      if (!RPC[msg.name]) { console.warn('Unknown RPC: ' + msg.name); return; }
      RPC[msg.name].apply(RPC, msg.args || []);
      break;
    default:
      console.warn('Unknown action: ' + msg.action);
  }
});
Community
  • 1
  • 1
Stefan
  • 3,962
  • 4
  • 34
  • 39
  • 1
    Thanks for the answer, the biggest help for me was the realization that I can open a html page from my extension. That allows me to completely control it in the ways that I need – Undefined Oct 12 '13 at 23:09