Chrome extension cannot inject content script into dynamically generated iframes - google-chrome-extension

I want to access performance.getEntries inside all iframes on a certain page (my aim is to create a deep understanding of what is going on inside banner tags). However, I cannot inject a content script inside dynamically generated iframes it seems.
Am I doing something wrong in the example below?
Or is there a possible other route of getting performance.getEntries for these dynamically generated frames?
Consider an extremely simple html like this:
<html>
<body>
<script>
var iframe = document.createElement('iframe');
var html = '<body><img src="http://dummyimage.com/100x200/333/fff&text=hey_2_1"><img src="http://dummyimage.com/100x200/555/fff&text=hey_2_2"></body>';
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);
document.body.appendChild(iframe);
</script>
<img src="http://dummyimage.com/100x200/333/fff&text=hey_1_1">
<img src="http://dummyimage.com/100x200/333/fff&text=hey_1_2">
</body>
</html>
And an extension like this
manifest.json
{
"manifest_version": 2,
"name": "Banner Spy 1",
"description": "Check all iframes",
"version": "1.0",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"run_at": "document_end",
"all_frames" : true,
"match_about_blank": true,
"matches": ["<all_urls>"],
"js": ["content_frame.js"]
}
],
"permissions": [
"tabs",
"activeTab",
"<all_urls>"
]
}
content_frame.js
setTimeout(function(){
var pe = performance.getEntries();
console.log(pe);
}, 1000);
Running this extension will only show performance entries for the top page, not the dynamic iframe.

Related

Chrome Extension Overlay Page

I create a Chrome Extension and would like to know:
How can I create an overlay over an existing webpage in a chrome extension?
I don't want to use a popup, I would rather prefer a banner at the top or bottom of the page.
I did read the Google Chrome Extension documentation but couldn't find the solution for my problem in it. Can you give me a hint?
You can create a content script that injects an on the top/bottom of the web page. That is on all http, and https websites.
Note: This code does not work on the local chrome:// and Chrome Web Store pages.
For example in your content.js:
var newiframe = document.createElement("iframe");
newiframe.setAttribute("src", chrome.runtime.getURL("html/panel.html"));
newiframe.style.width = "100%";
newiframe.style.top = "0";
newiframe.style.left = "0";
newiframe.style.right= "0";
newiframe.style.position = "absolute";
newiframe.style.zIndex = "500";
newiframe.style.height = "80px";
document.body.appendChild(newiframe);
And in your manifest.json:
{
"manifest_version": 3,
"name": "__MSG_name__",
"short_name": "Proper Menubar",
"version": "1.0",
"description": "__MSG_description__",
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["js/content.js"],
"run_at": "document_end"
}
],
"web_accessible_resources": [{
"resources": [ "html/panel.html",
"js/script.js",
"css/body.css"],
"matches": ["<all_urls>"],
"use_dynamic_url": true
}],
"permissions": [ "activeTab" ]
}
panel.html:
<html>
<head>
<style>body{background:red;color:white}</style>
</head>
<body>Hello there</body>
</html>

How do I use a localhost instead of .html in manifest.json [duplicate]

I am new to chrome extensions and I am having trouble while writing my first extension for chrome. What I am trying to do is detect the new tab action and redirect to a pre-defined(my webpage) url.
I wrote the manifest.json and the background.html but it doesn't seem to work.
I went through the google papers on the functions and how to use them, but there must be something I've missed.
I do not understand quite a few things that I've done in here, for example the content-scripts in manifest.json.
Some help in fixing this would be appreciated.
EDIT
EDIT2
Here is the updated code
Now I don't have the background.html file.
manifest.json
{
"name": "Tabber",
"manifest_version" : 2,
"version": "1.0",
"description": "MyExtension",
"background" : {
"scripts": ["code.js"]
},
"chrome_url_overrides": {
"newtab": "code.js"
},
"permissions": [
"tabs"
]
}
code.js
<script>
chrome.browserAction.onClicked.addListener(function(tab){
var action_url = "www.xyz.com"
chrome.tabs.create({ url: action_url });
}
</script>
Now when I open a new tab, I get to see the source of the .js file displayed.
Screenshot:
Why isn't the script being executed ?
If you want to over ride a default page, you shoud use html file, not a js file.
And if you just want to over ride a page, you do not need any background page or content script.
Here is the sample code:
menifest.json:
{
"name": "Tabber",
"manifest_version" : 2,
"version": "1.0",
"description": "MyExtension",
"chrome_url_overrides": {
"newtab": "my.html"
},
"permissions": [
"tabs"
]
}
my.html:
<!DOCTYPE html>
<html>
<head>
<title>over ride page</title>
<script type="text/javascript" src="code.js">
</script>
</head>
<body>
</body>
</html>
code.js:
window.open("http://www.google.com", "_self");
Note: you can not write any js in your html file. You need to include js file in html file.
And, you even do not need any js file. just modify the my.html as this:
<head>
<meta http-equiv="refresh"content="0;URL=http://www.google.com">
</head>
With the new chrome extensions you should not put any script code in the background page.
Inline scripts and event handlers disallowed
Due to the use of Content Security Policy, you can no longer use
tags that are inline with the HTML content. These must be
moved to external JS files. In addition, inline event handlers are
also not supported. For example, suppose you had the following code in
your extension:
https://developer.chrome.com/extensions/tut_migration_to_manifest_v2.html#inline_scripts
What you should do is move your code to a js file, either set the
manifest background property to a js file or have a background page
that links to an external js file and put all you js code there...
Try using the background property: http://developer.chrome.com/extensions/background_pages.html
1)basically add to your manifest a background script (you do not need the background page for your extension right now)
background : {
"scripts": ["background.js"]
}
2) Then add a a background.js to your extension directory and put all your js code there..
Then try again, and see if the extension works :)
3) remove all html from the js file and put just you js in the background.js
chrome.browserAction.onClicked.addListener(function(tab){
var action_url = "www.xyz.com"
chrome.tabs.create({ url: action_url });
}
Add this guy to your manifest.json file.
"chrome_url_overrides": {
"newtab": "index.html"
}
with index.html being replaced with your page. This will make it so it will show index.html when you open a new tab instead of the default.
I have an extension that basically does the same thing. Here's my manifest.json that you can use as a reference.
{
"name": "appName",
"version": "0.1",
"manifest_version": 2,
"chrome_url_overrides": {
"newtab": "index.html"
},
"description": "Desc Here",
"icons": {
// "128": "icon128.png"
},
"content_scripts": [ {
"css": ["css/styles.css"],
"js": [ ],
"matches": [ "*://*/*" ],
"run_at": "document_start"
} ],
"minimum_chrome_version": "18",
"permissions": [ "http://*/*", "https://*/*", "cookies", "tabs", "notifications" ]
}

Trying to create chrome extension to hide iframe content from a page

im working to create a very simple chrome extension just to remove an annoying tag from a site here is my codes
my manifest.json file include those lines :
{
"manifest_version": 2,
"name": "RemoveMysatgoHelp",
"description": "Remove Mysatgo Help tag",
"version": "1.0",
"icons": {
"16": "imgs/16.png",
"32": "imgs/32.png",
"64": "imgs/64.png",
"128": "imgs/128.png"
},
"content_scripts": [
{
"matches": [
"*://*.mysatgo.com/*"
],
"js": [
"content.js"
],
"run_at": "document_idle"
}
]
}
my content.js file include this single line:
var elements0 = document.getElementById('launcher');
elements0.style.display='none';
i need to remove these "Help window"at the bottom of the page it disturbing the main player control, here is my illustration https://prnt.sc/qaeaf5
i believe it is a dynamic tag inside an anonymous div tag ,the only id name that we have is within the iframe tag and the idname is "launcher"
my question
the problem again the elements0 return null ,because it seems the page not fully loaded with all the sources
any solution ?
Thanks

Elements not showing in Background Page Inspector and getting addEventListener is null error

I'm trying to create a chrome extension, so I'm doing tutorials to learn and reading a bunch, but I'm struggling. I'm doing this tutorial. But long-term, from the extension I need users to be able to login to their account, then as they're browsing, send the url that they're at to their account.
popup.html
<!doctype html>
<html>
<head>
<title>Add a Snippet</title>
<script src="popup.js"></script>
<link rel="stylesheet" type="text/css" href="popup.css">
</head>
<body>
<h1>Add a Snippet</h1>
<form id="form">
<textarea id="code"></textarea>
<button type="submit" id="checkPage">Add Snippet</button>
</form>
</body>
</html>
popup.js
What I REALLY don't understand is that according to the console.log lines that I have in there and the error, it's loading the DOMContent, and it doesn't have any problem with finding the form by the id (let f = document.getElementById('form');). But it bombs when I try to attach an event listener?
document.addEventListener('DOMContentLoaded', function() {
console.log('the domcontentloaded');
let f = document.getElementById('form');
f.addEventListener('submit', function(e){
console.log('the form was submitted');
e.preventDefault();
})
}, false);
manifest.json
{
"name": "My Awesome Plugin",
"description": "This extension will be awesome",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "This is Awesome"
},
"background": {
"scripts": ["jquery-2.2.3.min.js", "background.js","popup.js"],
"persistent": false
},
"permissions": [
"activeTab",
"declarativeContent",
"https://ajax.googleapis.com/",
"storage",
"tabs",
"http://*/*",
"https://*/*"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["login.js"]
}
],
"manifest_version": 2
}
login.js
console.log('login.js is ready to party');
When I load, I get this in the background inspector (or whatever it's called). So it's not finding the form.
So I looked at the elements, and I'm confused because it's not showing the form or the textarea. But when I click on the chrome extension icon, it's there.
1/Remove popup.js from "background/scripts" section of your manifest.
2/Add popup.js as a script reference in your popup.html file.
This way, popup.js will operate in the context of the popup.html DOM.

content_script not running on GitHub when following links

I am writing a Chrome Extension mainly for Pull Requests on Github Enterprise and have ran into an issue. When the page is loaded via a refresh or direct entering of the url from your browser it runs, when it is ran from clicking a link within Github it does not.
For instance if you go to this page with Pull Requests and click into one of them it will not run. But if you refresh that same page it will run.
manifest.json
{
"name": "Github Sample",
"manifest_version": 2,
"version": "0.0.1",
"description": "Sample",
"permissions": [
"tabs", "<all_urls>",
"http://github.com/*"
],
"content_scripts": [
{
"matches": [ "https://github.com/*" ],
"js": ["github.sample.js"],
"run_at": "document_end"
}
]
}
github.sample.json
// ==UserScript==
// #author Jacob Schoen
// ==/UserScript==
alert("Extension has Ran");
To make this easier I have pushed this to github.
Any ideas on how to address this?
GitHub site uses jquery-pjax library (see How to make github style page transitions by pjax).
Basically you only need to run the content script once and attach pjax event handlers inside an injected <script> element code which will be reusing a jQueryor $ variable of the site.
In those handlers you can send a message with document.dispatchEvent to your content script that will receive it in its window.addEventListener("blabla", ...)
or you can allow the access to chrome.runtime.sendMessage on the github site in manifest.json so that page-injected code will be able to send a message that can be received by the extension in chrome.runtime.onMessageExternal listener.
Alternatively you can use chrome.webNavigation.onHistoryStateUpdated in the background script but that will cause a warning during the installation that the extension can "Read your browsing history" which is a global permission unlike the content script solution.
The working example I came up with, in case it helps anyone else.
manifest.json
{
"name": "Github Sample",
"manifest_version": 2,
"version": "0.0.1",
"description": "Sample",
"permissions": [
"activeTab",
"tabs", "<all_urls>",
"http://github.com/*"
],
"content_scripts": [
{
"matches": [ "https://github.com/*" ],
"js": ["github.sample.js"],
"run_at": "document_idle"
}
],
"web_accessible_resources": ["inject.js"]
}
github.sample.js
// ==UserScript==
// #author Jacob Schoen
// ==/UserScript==
function myAlert() {
alert("Extension has Ran");
}
window.addEventListener("pageLoadTransition", myAlert);
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('inject.js');
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
//still have to load this one for direct page loads
myAlert();
inject.js
$(document).on('pjax:success', function() {
var evt=document.createEvent("CustomEvent");
evt.initCustomEvent("pageLoadTransition", true, true, null);
document.dispatchEvent(evt);
})
I also updated the Github repository with the working example.

Resources