Replacing external scripts with Greasemonkey - greasemonkey

A web page uses an external script:
<script src="script/alerts.js" type="text/javascript"></script>
In this script file there is a function which I would like to modify/replace.
The function looks like this:
function SayHello(msg1, msg2){
alert(msg1);
alert(msg2;
// just saying hi and doing something i don't want to
}
I want to change it into something like this:
function SayHello(msg1, msg2){
// not saying hello
// but i'm doing everything i want to
}
How can i do this without using unsafeWindow?
Note: the function must be executed in the content page scope, rather than in the Greasemonkey sandbox.

As simple as that:
location.assign("javascript:void(SayHello = function () {})");
It works even if you need to use any GM_* function. (#grant)

you cannot do something against unsafeWindow unless you run your code within the unsafe window.
what you can do however is redefining the method like:
SayHello = function (msg1, msg2){
// not saying hello
// but i'm doing everything i want to
}
it will replace the original function with this one.
you should also keep in mind that you cannot break into closures just using greasemonkey and that you cannot replace methods that have been copied into local variables the moment the script first ran through.

Related

Command not found on a funciton calling from another [duplicate]

In the script below, does the order in which items are declared matter?
For example, if the add_action points to a function that has not yet been defined? Does it matter or should the function declaration always precede any code in which its called?
add_action('load-categories.php', 'my_admin_init');
function my_admin_init(){
//do something
}
That doesn't matter if the function is declared before or after the call but the function should be there in the script and should be loaded in.
This is the first method and it will work:
some_func($a,$b);
function some_func($a,$b)
{
echo 'Called';
}
This is the second method and will also work:
function some_func($a,$b)
{
echo 'Called';
}
some_func($a,$b);
From the PHP manual:
Functions need not be defined before they are referenced, except when a function is conditionally defined as shown in the two examples below.
However, while this is more of a personal preference, I would highly recommend including all the functions you actually use in an external functions.php file then using a require_once() or include_once() (depending on tastes) at the very top of your main PHP file. This makes more logical sense -- if someone else is reading your code, it is blindingly obvious that you are using custom functions and they are located in functions.php. Saves a lot of guesswork IMO.
you can call a function before it's defined, the file is first parsed and then executed.
No.
It is not C :P...
As you can see here , the whole file is first being parsed and then executed.
If a function that doesn't exist is being called, php will throw an error.
Fatal error: Call to undefined function
As per my personal experience, In some special cases (Like, passing array's in function or function inside a function and so on). It's best option to define the function above the call. Because of this sometimes neither function works nor PHP throw an error.
In normal php functions, it doesn't matter. You can use both of the types.
It does not matter, as long as it is declared somewhere on the page.
as seen here:
http://codepad.org/aYbO7TYh
Quoting the User-defined functions section of the manual :
Functions need not be defined before
they are referenced, except when a
function is conditionally defined
So, basically : you can call a function before its definition is written -- but, of course, PHP must be able to see that definition, when try to call it.

Passing variable from jade to ng-init not working

I'm trying to pass an object from jade to ng-init in angular
This: doesn't work:
ng-init='tables=!{JSON.stringify(tables)}'
This: expands but,
ng-init='tables=#{JSON.stringify(tables)}'
the output is unescaped and filled with "s
ng-init="tables={"12":{"id":....
and the view isn't updated in either of the cases. This article implies that first one should work, but like I said, it doesn't even expand,
ng-init='tables=!{JSON.stringify(tables)}'
in source code shows up exactly the same in the HTML source
ng-init='tables=!{JSON.stringify(tables)}'
Actually, the #{...} approach seems to work fine.
It is probably the way console.log prints attributes' values that confused you.
ng-init="tables=#{JSON.stringify(tables)}"
Take a look at this short demo.
In what use-case you want to pass data directly from Jade to angular? I think you could to this job in controller like this :
$scope.init = function () {
// init stuff
}
...and in your view :
ng-init = init()

RequireJS Dynamic Paths Replacement

I have a requirejs module which is used as a wrapper to an API that comes from a different JS file:
apiWrapper.js
define([], function () {
return {
funcA: apiFuncA,
funcB: apiFuncB
};
});
It works fine but now I have some new use cases where I need to replace the implementation, e.g. instead of apiFuncA invoke my own function. But I don't want to touch other places in my code, where I call the functions, like apiWrapper.funcA(param).
I can do something like the following:
define([], function () {
return {
funcA: function(){
if(regularUseCase){
return apiFuncA(arguments);
} else {
return (function myFuncAImplementation(params){
//my code, instead of the external API
})(arguments);
}
},
funcB: apiFuncB
};
});
But I feel like it doesn't look nice. What's a more elegant alternative? Is there a way to replace the module (apiWrapper) dynamically? Currently it's defined in my require.config paths definition. Can this path definition be changed at runtime so that I'll use a different file as a wrapper?
Well, first of all, if you use Require.js, you probably want to build it before production. As so, it is important you don't update paths dynamically at runtime or depends on runtime variables to defines path as this will prevent you from running r.js successfully.
There's a lot of tools (requirejs plugins) out there that can help you dynamically change the path to a module or conditionnaly load a dependency.
First, you could use require.replace that allow you to change parts (or all) of a module URL depending on a check you made without breaking the build.
If you're looking for polyfilling, there's requirejs feature
And there's a lot more listed here: https://github.com/jrburke/requirejs/wiki/Plugins

Is there any fast tool which performs constant substitution without stripping out comments in JavaScript source code?

For example, setting MYCONST = true would lead to the transformation of
if (MYCONST) {
console.log('MYCONST IS TRUE!'); // print important message
}
to
if (true) {
console.log('MYCONST IS TRUE!'); // print important message
}
This tool ideally has a fast node.js accessible API.
A better way to achieve what you want -
Settings.js
settings = {
MYCONST = true
};
MainCode.js
if (settings.MYCONST) {
console.log('MYCONST IS TRUE!'); // print important message
}
This way, you make a change to one single file.
google's closure compiler does, among other things, inlining of constants when annotated as such, leaving string content untouched but I am not sure if it's a viable option for you.
Patch a beautifier, for example
Get the JS Beautifier https://raw.github.com/einars/js-beautify/master/beautify.js written in JS.
Replace the last line of function print_token() by something like
output.push(token_text=="MYCONST"?"true":token_text);
Call js_beautify(your_code) from within nodejs.
The Apache Ant build system supports a replace task that could be used to achieve this.
Edit: Whoops. Gotta read title first. Ignore me.
Google Closure Compiler has such a feature:
You can combine the #define tag in your code with the --define parameter to change variables at "compile" time.
The closure compiler will also remove your if-statement, which is probably what you want.
Simply write your code like this:
/** #define {boolean} */
var MYCONST = false; // default value is necessary here
if (MYCONST) {
console.log('MYCONST IS TRUE!'); // print important message
}
And call the compiler with the parameter:
java -jar closure-compiler.jar --define=MYCONST=true --js pathto/file.js
Regarding you API request: Closure Compiler has a JSON API.

Perform GM_xmlhttpRequest() from eval

I have a little Greasemonkey script that communicates with a servlet on (my) server. The servlet is sending back JavaScript code, which I eval() in the onload handler of the GM_xmlhttpRequest.
So far, all is working fine. Now, I'd like to use send another GM_xmlhttpRequest from within that eval()ed code. and here I'm stuck. I do not see any error, but all GM_* functions appear not to be working from within the eval(responsetext).
If I hard code the GM_xmlhttpRequest in the onload handler (no eval()), it is working fine.
It is possible to work around this problem, you can call GM_* functions with setTimeout set to 0 from eval'ed code. Try something like:
function myFunction()
{
GMXmlHttpRequest(...)
}
eval('setTimeout(myFunction, 0)');
A better solution is to extend Function.prototype with a function called safeCall that does this for you. Whenever you have any eval'ed code that will call into GM_* functions you'll need to have safeCall somewhere in that call chain.
Greasemonkey (GM) is hosting the user script, which means that it can add functions and objects to the user script, when you call eval() the script runs unhosted (the vanilla JavaScript is running it) and you don't get the GM API inside of it.
There is another solution. I have the similar problem, I don't want to put all my logic in user script, because if I change them, user need to update them by themselves. So what I want to do is separating the main logic from loading logic, the main logic will be loaded at beginning by the user script and eval them.
So I made a function "sendRequest", which is a wrapper of GM_xmlhttpRequest(), I need it anyway, because the method, server url and onError callback are always same for my application, so I just put them into my "sendRequest" function to make the xmlhttprequest simple.
In the main logic javascript code, which is loaded from server, there is no greasemonkey function call at all. If I want to for example communicate with server, I will call sendRequest instead. It works.

Resources