Can chrome.tabs.executeScript() be called from within a content script? [duplicate] - google-chrome-extension

This question already has answers here:
"Cannot read property of undefined" when using chrome.tabs or other chrome API in content script
(4 answers)
Closed 1 year ago.
I tried to look for this in the chrome documentation but I didn't see anything, especially in the "Security" section in the chrome.tabs documentation. The typical approach in examples I've seen is to send a message to the background page. The background page then calls chrome.tabs.executeScript(). If I can do it from the content script that would be a little easier.

Content scripts cannot call any Chrome API methods except couple from chrome.extension.* package.
Unless you are doing this to save content script filesize, why not just have that code you are planning to execute in a content script from the beginning?

Related

jQuery text() function not working on twitter when using CJS chrome extension [duplicate]

This question already has answers here:
Using jQuery $(this) with ES6 Arrow Functions (lexical this binding)
(5 answers)
Closed 2 years ago.
I am using a google chrome extension called CJS which allows you to run javascript code on websites.
I have it injecting jQuery, and then running this code on twitter's stream
setInterval(()=>{
jQuery('article').each(index=>{
console.log( index + ": " + jQuery( this ).text() );
})
}, 1000)
The ultimate goal is to hide tweets that are retweets.
Twitter does have a DOM article wrapped around each of the tweets, so the plan was to get those, iterate over them, and if the text includes "retweet", hide the article.
It is able to iterate over them, and in the console it just shows the indexes of the items, but the text of jQuery(this) ends up being an empty string, even when the content is fully loaded.
The issue is with using a fat arrow function (index)=>{... instead of function(index){... in the each section. This means that the this referred to the scope of the calling function rather than the scope for the jQuery dom element.

Using chrome.runtime.sendMessage in an imported javascript file

I'm currently using jQuery's $.getScript within my content script to import more Javascript files into my content script. This works very well for me to get all my Javascript files imported, but I am running into an issue where I can't use chrome.runtime.sendMessage inside the imported javascript files to communicate with my background scripts, presumably because the function isn't recognized within a script that's been processed by $.getScript (please do correct me if I'm wrong).
In content.js (injected directly via the manifest file), I have the following code:
$.getScript(chrome.extension.getURL('js/angular-1.2.26-min.js'), function(data) {
$.getScript(chrome.extension.getURL('app/app.js'), function(data) {
$.getScript(chrome.extension.getURL('app/overview/overview-controller.js'), function(data) {
$.getScript(chrome.extension.getURL('js/angular-bootstrap.js'), function(data) {
})
})
})
})
And inside app/app.js (or any of the injected files), I try putting a sendMessage call anywhere, but nothing gets sent. (I log the onMessage event listener in the background)
chrome.runtime.sendMessage({msg: 'test'}, function(response) { alert('done') })
Note: I have also tried importing the Javascript files by sending a message to the background script to use chrome.tabs.executeScrip instead, but I need to be able to inject the javascript files only at a specific time and in a specific frame, so that doesn't help. I've also tried using the 3rd party executeScriptInFrame library but that doesn't seem to be working either. I run into "Blocked script execution in '{{URL}}' because the document's frame is sandboxed and the 'allow-scripts' permission is not set"
My questions:
Is there an effective solution to using chrome.runtime.sendMessage inside a script that's been injected using $.getScript?
Is there a way to use executeScript inside a content script?
Is there an effective way to inject content scripts into a particular frame? Again, from above -- I tried a third party library but ran into an issue regarding the frame's sandboxing. But this is strange since I am able to successfully inject content scripts to that frame when using the manifest to do it directly.
Thanks!
Well, that's an interesting question.
Most methods rely <script> injection, which adds code to the wrong (page) context that has no access to Chrome APIs. I assume this is how $.getScript works. So, this will not work as intended.
Another method is using eval(). According to the documentation, eval() is allowed (but discouraged) in Content Scripts. So you can, in principle, load the script file in a XHR / jQuery AJAX request and then eval() its contents. This should work.
Lastly, you could modify your content scripts only to execute if some condition is met (say, a variable is set), and so injecting into all frames of a tab should be less of a problem. This could potentially be messy though. Note that a content script can find itself in the iframe hierarchy, which may be useful.

Chrome Extension sandbox and message passing

I have an old Chrome extension that I want to update for manifest version 2. I noticed I have an eval function call that I cannot get rid of. I'm trying to understand the new Chrome sandbox feature that lets me do an eval call inside of it. The question is: by loading a sandbox page in the background, can I pass it a string containing something to execute, then have it executing the script, outputting the result on the popup page?
At first I thought this was possible but looking at the examples apparently the script to be evaluated has to be already in the sandbox page.
Thanks

Returning an element value from chrome.tabs to a background script

I would like to send a value from the tab html content to my chrome extension background script.
Right now I'm using a workaround, that is
chrome.tabs.executeScript() to send a code to retrieve data and then send it to my web server via Ajax, and then my background script checks to see if its there in my server. But that's obviously not the right way.
Is there a way to get element values and then send it back to the background script? so I can keep working with the value?
Thanks!
chrome.extension.sendRequest() has a counterpart chrome.extension.onRequest.addListener()
If it's not obvious you can read all about message passing here:
http://code.google.com/chrome/extensions/messaging.html

Tracking Chrome extension events in Analytics

Google Chrome Extension documentation has some good information here:
http://code.google.com/chrome/extensions/tut_analytics.html
I put the analytics tracking code in my background.html file.
However I tried putting the _gaq.push call inside a script that runs on the page and got an error saying that the variable _gaq is not defined.
So I have to put onclick events in every element on the page I want to track and from there, call a function in background.html? Is there a better way to track events?
You can do this with chrome.extension.sendRequest in the content script and chrome.extension.onRequest.addListener in the background.html page. See here for more details: http://code.google.com/chrome/extensions/messaging.html. Also be sure your manifest.json is correct; I ran into problems when I had a hyphen character instead of an underscore.

Resources