Reputation: 23
I am fairly new to JS and creating a chrome extension where i have use Array.filter function, But for some website, website owner has created their own Array.filter function whose behavior is not same as built in function. Is there any way to override this user defined function and get the native behavior of this function. Any Help will be appreciated.
Upvotes: 2
Views: 778
Reputation: 42736
To save the original Array#filter method you just save it to a variable and then use it when needed by using call()
:
//Saving the original method
var ArrayFilter = Array.prototype.filter;
//Then whenever needing to use it, call it by using call()
var someArray = [1,2,3];
var filteredArray = ArrayFilter.call(someArray,function(){ /* your filter callback */ });
Now you need to make this run before the script that creates the modified filter()
method. You are going to have to do this by changing at which point your content script is loaded so it can load the other code. This is done by setting the run_at setting in the manifest:
manifest:
"content_scripts": [
{
"matches": ["http://*.example.com/*"],
"run_at": "document_start",
"js": ["contentScript.js"]
}
],
contentScript.js
//injecting the script into the page
//or however you are currently doing it
var yourScript = document.createElement('script');
document.head.appendChild(yourScript);
yourScript.textContent = "/* your js code */";
Upvotes: 2
Reputation: 73556
Run your code before the page scripts and use Object.defineProperty to redefine the method and forbid subsequent changes. You need to put that code in a DOM script
element so that it runs in the page context (more info), using a literal string, not src
property, to ensure it precedes any other page scripts (more info).
manifest.json:
"content_scripts": [{
"matches": ["https://foo.bar/*"],
"js": ["content.js"],
"run_at": "document_start",
"all_frames": true
}]
content.js:
const script = document.createElement("script");
script.textContent = `
Object.defineProperty(Array.prototype, 'filter', {
value: Array.prototype.filter,
configurable: false,
writable: false,
});
`;
document.documentElement.appendChild(script);
script.remove();
Upvotes: 2