Is it possible to access the contents of iframe via chrome extension? - google-chrome-extension

I want to ask is there ANY way or extension that can pre-highlight text within the iframe whenever a new window is opened containing iframe? I have tried many extension but none of them works.
I need to filter out content based on certain keywords and the content is within iframe. I can do it with CTRL+F but there are many keywords like 10-15 within each article to be found. So it makes my job very tough and time consuming. Few extensions that I have tried from chrome are multi highlighter, pearls, FF but none of them seems to work.
I also know the reason why these extension can't access content within the iframe i.e. due to cross origin policies.
But I also remember around an year ago I worked with chrome extension named 'Autofill' that could pre-select form elements whenever I opened new chrome window containing iframe.
So is there any work around?

You can set your extension permission to run content scripts in all frames as document at http://developer.chrome.com/extensions/content_scripts.html#registration by setting all_frames to true in the content scripts section of your manifest file. Adding to Google's example from that page, part of your manifest file might look like
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mystyles.css"],
"js": ["jquery.js", "myscript.js"],
"all_frames": true
}
],
...
}
You'll need to be careful since your content scripts are going to be inject into the page once for the parent page and one for each iFrame on the page. Once your content script is injected into all frames on the page you can work your magic with finding and highlighting text.
if (window === top) {
console.log('Running inside the main document', location.href);
} else {
console.log('Running inside the frame document', location.href,
[...document.querySelectorAll('*')]);
}

Related

Chrome extension page action appearing outside of address bar

I wrote a Chrome Extension page action, with the following implementation:
In manifest.json:
"permissions" : [
"declarativeContent"
],
In background.js:
chrome.runtime.onInstalled.addListener(function() {
// Replace all rules ...
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
// With a new rule ...
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlMatches: 'www\.somewebsite\.com/(translate|revise)/' },
})
],
// And shows the extension's page action.
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
I noticed that in most Chrome browsers, the page action icon appears correctly inside the address and only appears when the matching page is met:
However, in some browsers recently page actions started appearing as enabled/disabled browser actions, i.e. outside the address bar, which is a lot clumsier because the whole idea around page actions icons is that they appear if and only if the page is relevant to them. There is no point showing a disabled page action for most of the time. Actually, it happened to browsers where it used to work well days ago, like if a Chrome update had some side effects.
I presume this is related to some Chrome setting that now shows all extensions there, but is there any way I can force the page action to appear consistently in the address bar and only appear when it can be really useful?
It appears like this is the result of a new update to Chrome, with the developers probably reasoning that most users would not know that they had extensions installed otherwise.
Link to announcement: https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-extensions/upcoming/chromium-extensions/7As9MKhav5E/dNiZDoSCCQAJ
It doesn't look like extension developers can do anything about this, but I really hope Google reverts this change.

Firefox addon development - tabs api - blacklist url patterns from inject the exstension code (like in chrome)

I am using the addons sdk/tabs api to inject content scripts into tabs when they are loaded like this:
tabs.on(ready, function (tab) {
var worker = tab.attach({
contentScriptWhen: 'end',
contentScriptFile: myAwesomeArrayOfScripts
});
...
Is there an easy way i can prevent the attach on domain patterns?
Most importantly i need to prevent it to work on about: domains like the new tab page of firefox.
Obviously i'm able to control execution with code like this:
if (tab.url.indexOf('about:') === 0) return;
But it looks very unclear solution compared to chrome declarative manifest, where you can have this:
"content_scripts": [
{
"matches": [ "http://*/*", "https://*/*", "file://*/*" ],
Is there anything similar? Firefox documentation is confusing... too many things and too many versions and articles from the past.
Use the sdk/page-mod module instead of attaching content scripts via tabs events if you want to declare a content script. Then you can use the includeand exclude keys to specify URL patterns (exclude was introduced in Firefox 32).
Using Firefox's tab.attach is similar to chrome.tabs.executeScript, which should only be used to imperatively execute a content script.

Chrome Content Scripts not loading JS

I'm trying to work on a Chrome browser extension which does fun things on a contextmenu. The problem is, I can't get the JS files to load within the manifest.json content_scripts.
I don't receive an error, the files simply do not load.
The scripts are good, if I put them in my background page, they fire fine through that background page. The downside of that is it's restricted to only the background page.
{
"name": "Mini",
"description": "Mini",
"permissions": ["contextMenus","management","contentSettings","tabs","http://*/*","https://*/*","editable"],
"version": "0.1",
"manifest_version": 1,
"background_page": "mini.html",
"icons" : {"16" : "mini.png"},
"contexts" : ["link","tab","page"],
"content_scripts": [{"matches":["<all_urls>"],"js":["jquery172min.js","mini.js"]}]
}
I've tried all forms of matches, including "http://\*/\*", "https://\*/\*", "\*://\*/\*"
I've tried whitespaces, no whitespaces. I'm drawing a blank here.
Any help would be appreciated.
$(document).ready(function () {
alert("page is ready");
},true);
My apologies for that. This is a copy of the javascript/Jquery I'm using to test whether the extension has loaded or not. It's just a simple alert.
Content scripts cannot use the chrome.contextMenus API (in fact, these can only use some of the chrome.extension methods).
It's possible to apply match patterns to individual menu items, via chrome.contextMenus.create({title: 'Test', documentUrlPatterns: 'http://*/*'});.
Created menu items can also be modified (chrome.contextMenus.update) and removed (chrome.contextMenus.remove).
To communicate between a Content script and the background page, see Message passing.

append html elements to DOM by background script

I want to append the same html elements to the current TAB's document DOM.
I want these html extended elements to live "forever", so I want to built them once, and append them on every page load by the content script.
I was thinking to place the createElement commends at the background page.
Then for every web page load, I want the content script to communicate with the background script, so it will append them to the current TAB document DOM.
Is that good practice?
My problem is that I don’t know how to append html elements to the DOM from the background page.
Can you please help?
This cannot work. The background page lives in one process, the tab in the other - you cannot send objects from one to the other, only text data (objects sent are automatically converted to JSON). So your best chance is: build everything together in the background page, then get innerHTML of your element and send this text to the content script whenever necessary. The content script should then create a new element and set its innerHTML to the value it received.
You need to do it in content script because "content scripts" are scripts which run in an environment between a page and the Chrome extension. see this. remember these scripts will loaded on every page load and they won't affect already opened tabs.
as an example you can add external scripts like this
var theScript = document.createElement('script');
theScript.src = "http://mybwesite.com/static/js/myscript.js"
document.body.appendChild(theScript);
as long as you've added it's permissions in manifist:
"permissions": [
"activeTab",
"tabs",
"http://*/*", "https://*/*"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/contentscript.js"]
}
]

Function not defined creating a Chrome Extension Content Script

I'm writing a Chrome content script and when I inject this in the DOM:
"<a href='#' onclick='alert(\"Hi!\");return false;'>Hi</a>"
it works fine (the alert pops up when I click it), however if I create a function for the alert, it will say function undefined. Ex:
"<a href='#' onclick='alertPlease(\"Hi!\");return false;'>Hi</a>"
function alertPlease(x){
alert(x);
}
All my code is the same content script js file.
Do I have to place whatever code that can be used after loading in another js file in the background? I tried adding a background page with the 'alertPlease();' function, but that didn't work either.
Any hint will be greatly appreciated!
Thanks!
Content scripts run in an "isolated world." The webpage and content scripts can't see each other's JavaScript variables (although they can see the same DOM). When you add an onclick attribute within the DOM, the handler is created on the webpage's world, not your extension's world, so that code can't access the other function you defined. Instead of using an onclick handler, you should define your event listener in pure Javascript and then use addEventListener to attach it.
Isolated worlds are a feature to improve security and stability. Things are similar if you're developing within the Greasemonkey sandbox in Firefox.
Doing one of these today with manifest version 3, I learned:
I can't append a button to the page and use
<button type="button" onclick="myContentScriptFunction();">Call CS Function</div>
But, in the content script, I can do vanilla
let loadButton = document.createElement('button');
loadButton.innerText = 'Call CS Function';
loadButton.addEventListener('click', myContentScriptFunction);
document.querySelector('body').append(loadButton);
or jQuery
let loadButton = $("<button type="button">Call CS Function</button>")
loadButton.on("click", myContentScriptFunction)
$("body").append(loadButton);
And both worked as expected with all code in the content script
Info Source: Chrome Extension Samples Example
Specify any scripts in the manifest.json file under "content_scripts"
{
"name": "My Extension",
"content_scripts": [{
"matches": ["<all_urls>"],
"css": ["style.css"],
"js": ["jquery-1.5.js", "script.js"]
}]
}

Resources