Chrome extension passing data from background.js to new tab - google-chrome-extension

In my chrome extension I want to show a page with some of the usager's usage statistics. I have been trying to go about this by creating a new tab from the background.js to display an HTML page:
chrome.tabs.create({
url: '/results.html',
active: true
});
where results.html looks like this:
<!DOCTYPE html>
<html lang='en'>
<head>
<script src='js/charts.js'></script>
</head>
<body>
<canvas id='myChart' style='height:400px; max-width:800px; background-color:red;'></canvas>
</body>
<script src='js/results.js'></script>
</html>
The problem is that I then need to pass the actual usage data from the background.js page to this new results.html page. The only thing I can think of is to add another content script that attaches to the results.html page.
"content_scripts": [
{
"matches": [
"*://*.results.html"
],
"js": ["js/results_content.js"],
"run_at": "document_idle"
}
]
This doesn't seem to work, otherwise, I could then have the background page send the data through the results_content.js script and display the charts.
The only other idea I can think of is to just open a new tab to obscurewebsite.com and have a content script that does something like document.body.innerHTML = "" and rebuild my page using only javascript. I don't love this solution.
Is there a way to pass information through the chrome.tabs reference? Or another way to pass the data? Any help is appreciated.

Related

How to make chrome extension work inside iframe and outside iframe?

Requirement is to find elements via chrome extension.
I have a chrome extension created to highlight web elements on dom.
Below is my manifest.json
"content_scripts": [
{
"run_at" : "document_idle",
"all_frames": true,
"matches":[
"<all_urls>"
],
"js":["jquery-3.1.1.min.js","content.js"]
}
],
content.js:
document.querySelector('#id'); //Works. Here element is inside iframe.
document.querySelector('.class'); //Fails. Here element is outside iframe.
When run, elements are highlighted only in iframes but not which are outside of iframe.
My sample dom structure is like below.
<html>
<head>
</head>
<body>
<div>
...
//elements here not highlighted
...
<iframe>
....
//elements here highlighted
....
</iframe>
</div>
</body>
</html>
How to make this chrome extension work for both i.e., inside iframe and outside iframe?

iframe-resizer js library: moveToAnchor from parent page

How can I scroll to a certain anchor tag inside the IFrame page?
Using the ingenious Iframe-Resizier Library by David J. Bradshaw
https://github.com/davidjbradshaw/iframe-resizer
I’m including an IFrame with a lot of content (=long page) inside the outer page. So if I link to the page, then much of the content isn't visible on the first screen and under certain circumstances I would like to jump to a specific anchor tag further down in the iframe.
<html>
<a href=“outer-page.html#somewhere_name” />
</html>
seems not to work
I am using "inPageLinks: true" like this:
<script type="text/javascript">
iFrameResize({
heightCalculationMethod: 'lowestElement',
inPageLinks: true
</script>
My question now is: How can I make the outer page scroll down to a certain anchor tag without the need to implement something new inside the iframe page? The anchor tag in this case is located inside the IFrame page.
When I include the IFrame page like
<html>
<iframe id=“strytl” src=“iframe-page.html#somewhere_name”></iframe
</html>
Then the (re)sizing of the IFrame seems not to work perfectly and contents at the top of the iframe are getting cut off.
But with moveToAnchor it works perfectly from inside the IFrame and the page is magically scrolling down to the anchor tag. So in the iframe page I can call:
<script type="text/javascript>
parentIFrame.moveToAnchor('somewhere_name’);
</script>
But how can I trigger this from the parent page?
<script type="text/javascript>
$('iframe#strytl').iFrameResize({moveToAnchor: 'somwhere_name'});
</script>
results in this error:
<script type=“text/javascript”>
[iFrameSizer][Host page: strytl] Ignored iFrame, already setup.and
</script>
And
<script type="text/javascript">
iFrameResize({
heightCalculationMethod: 'lowestElement',
inPageLinks: true,
moveToAnchor: 'somewhere_name'});
</script>
seems to have no effect at all.
(In this case the outer page and the iframe have different server names.)
<script type=“text/javascript”>
var myFrm = document.getElementById('strytl');
var myCw = myFrm.contentWindow;
myCw.parentIFrame.moveToAnchor(‘somewhere_name’);
</script>
result:
<script type=“text/javascript”>
Error: Permission denied to access property “parentIFrame"
</script>
Can I jump to an anchor in the iframe from the outer page at all?
Something like this.
<script type="text/javascript">
iFrameResize({
heightCalculationMethod : 'lowestElement',
inPageLinks : true,
initCallback : function (iFrame){
iFrame.iFrameResizer.moveToAnchor('someAnchor');
}
});
</script>

Page action to open new page

Can I use a page action to directly open a new page? I have a link in my popup.html, but it would be better to have the page open when they click the icon so that they would only need one click instead of two.
<!doctype html>
<html>
<head>
<title>Popup</title>
<link href="popup.css" rel="stylesheet" type="text/css">
</head>
<body>
click here
</body>
</html>
Yes, a way to achieve this would be as follows:
chrome.pageAction.onClicked.addListener(function(tab){
chrome.tabs.create({url: "http://www.domain.com/details.html", "active":true});
});
See Chrome Page Action | onClicked
Note that you will need to declare the tabs permission in your manifest file:
"permissions": ["tabs",...],
I don't think there is any elegant way to handle both the situations on page action click:
Open popup
Open a new page
If you always want to open a new tab with some URL whenever page action is clicked, just remove the popup. And use the code just like #Flo has mentioned.
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.tabs.create({url: "http://www.example.com", "active":true});
});
PS: To remove the popup, there are two options:
Remove the popup from manifest.json
Pragmatically like chrome.pageAction.setPopup('')

Including multiple JavaScript files in Chrome Extension's popup.html

UPDATE:
The problem is caused by including an old version of jQuery(1.4.2).
After I use 1.8.2 instead, the problem is just gone. But I still don't
know why.
I recently made a Chrome extension. Thanks to the post chrome extension insert content script on browser action I realized that I have to include a js file like:
<script src="popup.js"></script>
But later I figure out it seems you cannot include more than one file:
<html>
<head>
<script src="jquery.js"></script> <!-- NOT LOADED -->
<script src="popup.js"></script> <!-- LOADED -->
</head>
<body>
</body>
</html>
What's worse for me is that I cannot access the DOM of the popup HTML in the JS file. Like:
popup.html
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
<a id="intro" href="#" target="_blank">Intro</a>
</body>
</html>
popup.js
/*
... jQuery Codes here ...
jquery.js cannot be included via src="jquery.js"
but by copy and paste its source code here it works
*/
$("#intro").click(function(){
alert("clicked"); // Not fireing at all
});
I am wondering what I can do to fix this. Thanks very much!
Here is a basic example of what you could use to get it working. My best guess is that it only appeared that jQuery wasn't loading because of how your popup.js is set up (it is trying to attach the click functionality before the element has loaded). I'm no JS expert, so I'm sure others will have better ideas of how to wait for the DOM to load, but this works as a basic test (NOTE: this uses a local version of the latest version of jQuery (1.8.2 currently), as the new content policies in manifest 2 do not allow in-line scripts):
Manifest.json
{
"name": "Test Extension",
"version": "1.0",
"manifest_version": 2,
"description": "Testing",
"browser_action": {
"default_icon": "my_icon.png",
"default_title": "My Text Extension",
"default_popup": "popup.html"
},
"permissions": [
"tabs", "http://*/", "https://*/"
]
}
Popup.html
<html>
<head>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>
<a id="intro" href="#" target="_blank">Intro</a>
</body>
</html>
Popup.js
/*
Here we wait for the body of the popup to load before
attaching our functionality
*/
window.onload = function() {
$("#intro").click(function(){
alert("clicked"); // Should fire now
});
};
The reason this is happening, is because the page is being loaded in order, and the scripts are firing before the DOM is loaded. This means that the scripts are called before the DOM even exists, so it cannot see the DOM at all; it's loading after the script.
Using events to wait for the DOM is one method to get around this, but you can also add the scripts at the end or after the body tag to be loaded last, so that the DOM is loaded first. There are of course many people who will argue this is bad practice, as well as vice versa. The reason being that you may have scripts load while the DOM loads, or because there are many large scripts that cause a lag in the loading, and these are all valid points when discussing jQuery manipulated websites.
The opposing practice can be beneficial when working with Chrome Extensions. One reason is to always give some representational responsiveness, even with the most intensive extensions, as well as not having to worry about waiting for the DOM in the code. Really it depends on what you need, but it's always beneficial to know all of your options. You can see both practices used in the Sample Chrome Extensions.
With jQuery you may want to use the Ready method instead, as onload waits until everything on the page is loaded (images, video, links, scripts, etc). Unlike onload, the ready method is called when the DOM itself is done loading, regardless of the page actually being done loading. You can do this with:
$(document).ready(function() {
// jQuery code to execute after
});
You can also wait for the DOM in JavaScript using the DOMContentLoaded event:
document.addEventListener('DOMContentLoaded', function() {
// JavaScript code here
});

How can a button in an iframe open a new url in a chrome extension

I have an extension which adds a bar at the top of a webpage. i have inserted the iframe in the content script using
document.body.insertBefore(iframe, document.body.firstChild);
The iframe has a button
<button id="mybutton">Click to help</button>
When the user clicks the button I want to redirect them to a new url in the same window. Is this possible?
The reason I want to do this is on certain websites I would like to change the url to include an additional parameter. I chose the iframe option as it more visible than an extension in the bar. Therefore if there is an alternative way to do this I would be happy to learn about it.
Your iframe.....
<html>
<head>
</head>
<script type="text/javascript">
function changeParent(e){
parent.location="http://google.com.au";
}
function onLoad(){
document.querySelector("#mybutton").onclick = changeParent;
}
</script>
<body onload="onLoad()">
<a id="mybutton">Change Parents URL</a>
</body>
</html>
Would be a good case for info bars if they ever come out of experimental....
http://code.google.com/chrome/extensions/experimental.infobars.html

Resources