The best way to do this is to insert a custom iframe using the contents of the script, which will contain the same scripts / html as a regular popup. The IFrame allows you to isolate html and stylesheets from interacting with an existing website page.
The iframe html file must be listed as available web resources in manifest.json.
The contents of the script will handle the display of the iframe when you click on the browser icon.
For example, the Evernote web clipper uses this approach.
Code examples that may help you:
1) Define the browser action in your file manifest.json(do not specify the popup property) and make it popup.htmlavailable for the website:
{
"name": "My extension",
...
"browser_action": {
"default_icon": {
"19": "images/icon19.png",
"38": "images/icon38.png"
}
},
"web_accessible_resources": ["popup.html"]
}
2) Create a file popup.htmlthat contains the html and css of your popup;
3) background.js script, script:
chrome.browserAction.onClicked.addListener(function (tab){
chrome.tabs.sendMessage(tab.id, 'browser_action_click', function(callback_data) {
});
})
4) content_script.js / iframe:
var show = false;
var controller = {
insertIframe: function (){
var iFrame = document.createElement("iframe");
iFrame.setAttribute('style', '');
iFrame.setAttribute('id', 'popup_iframe');
iFrame.src = chrome.extension.getURL ("popup.html");
if (document.body) {
document.body.insertBefore(iFrame, document.body.firstChild);
}
},
getIframe: function() {
return document.getElementById('popup_iframe');
},
hideIframe: function() {
var iframe = this.getIframe();
iframe.style.display = 'none';
},
showIframe: function() {
var iframe = this.getIframe();
iframe.style.display = 'block';
},
listenForMessages: function() {
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
switch(request) {
case 'browser_action_click':
show = !show;
show ? this.showIframe() : this.hideIframe();
}
return true;
}.bind(this));
}
};
controller.insertIframe();
controller.listenForMessages();