Unable to replace Alert in injected script - google-chrome-extension

I'm writing an extension for this site. In my injected script(injected using chrome.tabs.executeScript) which runs at "document_end" everything seems to be working fine but I want to remove site's "alert" prompts.
To do I've placed this code in the injected script but it does not work:
window.alert = function(msg){
console.log("bypassed");
}
Also tried this from the injected script:
$('<script>window.alert = function (msg){}</' + 'script>').appendTo(document.body);
I've even tried this in the background page but this too doesn't:
chrome.tabs.executeScript({
code: 'window.alert=function(msg){}' //while alert("hello") works
});
What am I missing? I've written another extension for another site and this method does override the alert function.
UPDATE: I'm unable to call native functions in the downloaded web page from the injected script which will happen when called from content script. But my injected script is loaded using chrome.tabs.executeScript

I am guessing that your issue is with your manifest.json file, where you have specified to "run_at": "document_end".
From the documentation:
In the case of "document_start", the files are injected after any files from css, but before any other DOM is constructed or any other script is run.
but,
In the case of "document_end", the files are injected immediately after the DOM is complete, but before subresources like images and frames have loaded.
Referencing this answer, in the case of document_end, the overwrite cannot take place as the functions are already loaded, therefore you should have the javascript be injected at document_start.

Related

How to run setup code before extension loaded in puppeteer?

I am testing the behavior of a chrome extension using puppeteer.
Upon installation, the extension opens a page. I would like to do initial setup in the browser before the extension is loaded (for example, setting local storage or injecting a jest mock).
The problem I have now is that the extension gets loaded upon browser start, so I don't know of any way to execute setup code before the extension is loaded.
This is how I load the extension currently (which resides in the dist/chrome folder):
const browser = await puppeteer.launch({
args: [
'--disable-extensions-except=dist/chrome',
'--load-extension=dist/chrome',
],
headless: false,
ignoreDefaultArgs: ['--disable-extensions'],
});
How can I do initial setup before the extension is loaded?
Some options I can think of are: 1) load the extension after the browser is launched 2) intercept the extension installation and execute setup code before the extension initializes
I came searching for an answer and I found it reading your question, so I'm leaving it here in case I have to search for it again in the future ...
The trick is to create a "launcher" extension with the sole purpose running the setup code, before the actual extension is ran. It would look like:
'--disable-extensions-except=dist/launcher,dist/chrome',
'--load-extension=dist/launcher,dist/chrome',

Extension loading a content script triggers a warning when published to the chrome web store

I'd like to split my Chrome extension's script into several files. For this purpose, as far as I understand, I need to add a "content_scripts" property to the manifest file. When I publish to the Chrome Web Store, I get a warning message that my extension requires extensive permissions and that reviewing the extension will take more time, and that I'd better do it differently.
Originally, I had one single js file including data and functions. I don't like that, so I wanted to have separate js files for data and functions. So I took the data to a new data.js file and the only way I've found to make it work is to have a "content_script" property inside the manifest file.
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["data.js"]
}
],
The "matches" property seems to be required. My understanding is that this <all_url> value causes the Chrome Store to warn me that this is too much of a permission. They advise me to use "permissions": ["activeTab"] instead. But I already have that in my manifest. So I'm a bit confused as to how I could just add a content script without requiring additional permission, since it's just another embedded js file, and I don't see why that would require more permission than the original background javascript file.
Finally, I managed using several separate js files by referencing them from the background script :
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {file:"script1.js"});
chrome.tabs.executeScript(tab.id, {file:"script2.js"});
});
It works fine, and doesn't cause the Chrome Web Store to prompt a permission warning. So it seems a much better way for what I intended to do.

Safari App Extensions: Can the injected script load resources from the app bundle?

I have a Safari App Extension that injects a script into the host page. From that injected script, is it possible to load resources such as images or stylesheets from the main app bundle? (I mean directly, without sending messages between the two.)
I suppose yes. In your injected script, the path to an asset called "gigou.css" located in your extension's bundle should be accessible with safari.extension.baseURI + 'gigou.css'. Then you should be able to write dynamically a link or script tag and inject it into the document.

is require.js the right tool (for the job) for "normal" web sites"

I have started building a web site and have used Require.js for selectively loading scripts which I require to implement functionality. What I am experiencing is:
the "main" script has not finished executing (or even downloading) before some of my code uses "require" to load dependencies. What this means is that the require.js config has not run and does not know the locations of my scripts.
because the require.js config has not run by the time my code needs to use it, the "shim" mechanism has not been initialised and cannot be used.
The Common Errors page along with a lot of the issues I seem to be reading about online while trying to solve my own problems seem to suggest that this is not the right tool for the job.
This seems to be useful for single page applications or node.js applications, but not traditional sites where other scripts could be running before require.js has been initialised.
If require.js is not the right tool for the job, is there a right tool for this job? If so then what is?
Are you loading the require.js script asynchronously (with an async='async')? You want requirejs to load synchronously. Once it's loaded, it will load further scripts, like your main.js file, asynchronously. They may all load out of order, but the code will actually get executed in the right order (respecting the declared dependencies).
So in your page template, you would have this:
<script src="/Scripts/require.js" type="text/javascript" data-main="main.js"></script>
That will load RequireJS, and once it's loaded it starts loading your main.js asynchronously. Typically main.js does not define any modules, it just makes use of modules defined in other files. These dependencies are listed in the require() call:
require(["moduleA", "moduleB"], function(A, B){
// Do something with A and B
A.someFunction();
B.someOtherFunction();
});
The files moduleA.js and moduleB.js must wrap their contents inside a define(). In moduleA.js (which depends on module C):
define(["moduleC"], function () {
// Build up an A
var A = ....;
return A;
});
I wonder now if you're wrapping your modules in a define call. Not doing that could explain the out-of-order execution you're experiencing.
RequireJS is a perfectly valid tool on a traditional site, not just on a single-page site.

accessing extension stylesheets via extension javascript

I have a chrome content script extension that includes a css file (mystyle.css) which is bundled into the extenstion CRX. As far as I can tell, there are two ways to inject this this stylesheet into the content of a page.
No matter which way the stylesheet is injected into the page, I cannot access the CSS rules associated with that stylesheet.
Injection method #1:
// From a script running in the context of background.html:
chrome.tabs.insertCSS(tab.id, {file: 'mystyle.css'});
Injection method #2:
// From a script running in the context of the content, already
// injected by the background page via chrome.tabs.executeScript.
var fileref = document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href",
chrome.extension.getURL('mystyle.css'));
From JavaScript running in the context of the content, injected by the background page, I cannot see the stylesheet in the list of those listed in document.styleSheets, when it is injected using method #1. When injected using method #2, it is listed with a chrome-extension:// href, but the cssRules property of that the sheet is always null.
I would expect this for CSS sheets that are linked to the document from other domains, but my script should have access to chrome-extension:// URIs that pertain to my extension.
The avenue that I'm currently investigating is raw string access to the resource contents of the CSS file that I can construct a chrome-extension:// URI for. I have no idea if this will work better than the other attempts, but it seems like it should.

Resources