Chrome Extension sandbox and message passing - google-chrome-extension

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

Related

How can one debug the Chrome extension "options" page using the new OptionsV2 method?

https://developer.chrome.com/extensions/optionsV2 tells me that I should be using options_ui in my manifest, rather than options_page, and recommends I start upgrading immediately.
However, I can't find any way to actually debug the script run by my options page when I use options_ui—the Options popup is in an tag, and the developer tools don't show me the source, or even the HTML content.
For now, I just comment out options_ui and let options_page take effect when I need to debug. I'm guessing that setting "options_ui": {"open_in_tab": true,...} would have the same effect, but it would be really nice to figure out how to actually debug the script when it's running the new way.
Auspex,
Teepeemm's comment is correct.
Other way, you can launch your options page from other tab using its full URL
like,
chrome-extension://{your extension id here}/{your options page path here, from the extension root}
e.g. say my extension id aaabbbcccdddeeefffggg, and say, my options page is located (from extension root) at app/html/options.html; then i can load up below URL in a new tab ---
chrome-extension://aaabbbcccdddeeefffggg/app/html/options.html
Now here, in this tab; you can do your regular debugging around HTML and javascript.
I hope this suffices your debugging requirement for 'new options UI' for chrome.
Teepeemm's comment is correct.
It's as simple as right-clicking inside the options page modal and selecting "Inspect element" - it will open the correct Dev Tools.

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 content script to access and modify window

I am writing a chrome extension that is a 'content script'
I want to inject a google map on to a webpage.
Problem:
It appears that i have no way to add functions on to the window object, thus i cannot define a callback function for googlemaps to call when it loads.
How do people usually go about mucking with the window?
--
someone on the interwebs suggested i do this:
You can do this easily with a JavaScript URL: window.location =
"javascript:obj.funcvar = function() {}; void(0);"
but when i did this i got an access denied error. it seems like a lot of search results about this problem are outdated.
Content scripts have a separate JavaScript execution ennvironment from the page they run on, so they cannot alter JS variables in the page itself. However, the content script shares the DOM with the page, so you can inject a <script> tag into the DOM which will be loaded and run in the actual page's execution environment.

Override downloading a file type with Chrome Extensions

I'm trying to build a chrome extension that overrides a download of a file and displays it in the browser. For example if you click on a link to a '.csv' file I'd like it to render in the browser instead of downloading it.
Chrome already does it for PDF's types and the Xml Tree extension also does exactly that for xml files.
So it should be possible, just not sure how to go about catching that event?
An implementation along the lines indicated by in the previous answers and specifically designed for CSV files can be found in this extension of mine on github:
https://github.com/rgrp/chrome-csv-viewer
Furthermore, with the new(ish) chrome webrequest API a direct approach is also now possible along the following lines:
Listen to onBeforeRequest (this has to be in a background script - see background.js)
Check if this is a CSV file (mimetype or file extension)
If so cancel the request and then display the data using xhr
A working version of this can be found in a branch of that extension: https://github.com/rgrp/chrome-csv-viewer/tree/4-webrequest-intercept
You could always look at the XML Tree code :).
If you only need to work with links, and not opening files from the address bar or File > Open, you could build a content script that adds a click event listener to every link.
In the event listener function:
Add e.preventDefault() in the first line to prevent the browser 'following' the link.
Using the link href value, get the data with XMLHttpRequest.
In the XMLHttpRequest callback, open a new tab and render content accordingly.
Obviously, in many ways, this is not a great solution:
you want 'normal' links to be handled as usual by the browser
how can you tell if a text file contains comma-separated values (for example) except by looking at the file extension which, of course, may not be reliable?
Are you specifically thinking of .csv files -- and/or other specific types of content?

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