How is this JavaScript object created for this bookmarklet? - javascript

I am trying to reverse engineer a bookmarklet that uses CasperJS.
It creates an object called __utils__ that I can execute console commands with.
The link to the bookmarklet is here:-
http://casperjs.org/api.html#bookmarklet
Which references this JavaScript file:-
https://raw.github.com/n1k0/casperjs/master/modules/clientutils.js
I have searched through the whole source code and I cannot find a reference to how this object is created.
Any pointers would be appreciated.

The bookmarklet simply runs a small snippet of JavaScript code that appends a link to the clientutils.js to the document's end. After that, it will run an anonymous function every 50 milliseconds that checks if the script has loaded (and has made the ClientUtils function available), and if it has, it stops running the function and creates window.__utils__, thus making it available in the console. Here's the actual bookmarklet code in a more readable format. It should be pretty straightforward to understand:
(function () {
void(function () {
if (!document.getElementById('CasperUtils')) {
var CasperUtils = document.createElement('script');
CasperUtils.id = 'CasperUtils';
CasperUtils.src = 'https://raw.github.com/n1k0/casperjs/master/modules/clientutils.js';
document.documentElement.appendChild(CasperUtils);
var interval = setInterval(function () {
if (typeof ClientUtils === 'function') {
window.__utils__ = new window.ClientUtils();
clearInterval(interval);
}
}, 50);
}
}());
})();

Look at the source of api.html. After Just drag this link look at the JS in the href attribute. Near the end it contains:
window.__utils__=new%20window.clientUtils();

Related

Cannot instantiate a class when script is injected into document dynamically

I am experimenting with Classes available in javascript and have setup a simple test case as follows:
<script src="myclass.js></script>
<script>
var test = new MyClass();
</script>
myclass.js contains the following:
class MyClass {
constructor() {
}
}
This works as expected.
However, if I dynamically load "myclass.js" using jQuery.getScript() function the browser returns the following error:
Uncaught ReferenceError: MyClass is not defined
Things I have double checked are:
The code to instantiate the class is placed within the success callback of the getScript function
And also that the script is actually being loaded and executed (with a simple console log)
However I seem to have a brick wall with this. Is there any reason why a class cannot be instantiated from if the file containing the class is loaded from a javascript file using the jQuery.getScript function?
This is the code which does not work:
<script>
$(document).ready(function() {
$.getScript('myclass.js', function () {
var test = new MyClass();
});
});
</script>
Testing on Chrome Version 71.0.3578.98 (64-bit)
Have a look at this question and its answers as well as the documentation such says the success callback is run after loading but not necessarily after executing the script.
To sum up, it might suffice to run your code by appending a then (or done) handler:
$.getScript(url).then(function() {
var test = new MyClass();
});
If this is not enough you should fall back to use a setInterval-triggered check for the existence of the class (stop the interval after finding the class).
This way you are avoiding any dependency on the specific browser behavior when the script gets executed after loading it.
function afterScriptExecuted() {
var test = new MyClass();
}
function testScriptExecuted() {
return window.MyClass !== undefined;
}
$.getScript(url).then(function() {
var id = setInterval(function() {
if (testScriptExecuted()) {
clearInterval(id);
afterScriptExecuted();
}
}, 50);
});
In the end, only the following approach worked for me (rather than using jQuery.getScript)
var script = document.createElement('script');
script.onload = function () {
var test = new MyClass();
};
script.src = '/myclass.js';
document.head.appendChild(script);

Javascript replace code of function

I am making a bookmarklet and need to change some code inside a page. For example, after page loaded it creates a function which is used 'onclick'. I need to replace a code inside a variable of this function. For example here is a function:
function openNewWindow(){
newWindow = window.open('http://www.example.org','params','width=200,height=200,resizable=0');
And I need to change this code into this:
function openNewWindow(){
newWindow = window.open('http://www.example.org','params','_blank');
How can I do it, taking in account, that the function is loaded by ajax?
Functions can be overwritting by being asigned a new refrence, if you only have access to the front end of the code after the fact. You can replace openNewWindow with a new function;
openNewWindow = function () {
newWindow = window.open('http://www.example.org','params','_blank');
}
However replacing functions that come from third parties are not recomended in a lot of cases because it can produce unexpected results.

Override/Rewrite a javascript library function

I am using an open source javascript library timeline.verite.co
It's a timeline library which works great on page load. But when I try to repaint the timeline on certain condition, it starts giving out weird errors
I would like to modify the init function in the library. But instead of changing it in the original library itself, I would like to rewrite/override this function in another separate .js file so that when this function is called, instead of going to the original function, it must use my modified function.
I'm not sure whether to use prototype/ inheritance and how to use it to solve this problem?
You only need to assign the new value for it. Here is an example:
obj = {
myFunction : function() {
alert('originalValue');
}
}
obj.myFunction();
obj.myFunction = function() {
alert('newValue');
}
obj.myFunction();

How to detect Javascript execution in WebBrowser control

I have a WebBrowser control in my C# application. The web browser is under the user's control, that is, he can load any web page his computer can access on the web (of course limited by proxy, hosts file and so on).
I need to know and to be notified when there is a Javascript call inside the page loaded in the web browser component.
First example: given a link like this
test
When the user clicks the link I need to know that the function "jsFunct" has been called.
Second example: given a call like
<script type="text/javascript">
window.setTimeout("jsFunct()", 1000);
</script>
I need to know that, 1 second after the execution of the script, the function jsFunct has been called.
The best thing would be to have an event fired when the function is called. It would also be great if the event could get the Javascript code executed, or at least the function name in the arguments.
EDIT:
Even if the question is related to the webbrowser component, anything that allows the user to detect javascript activation (even via js) would be fine, being able to inject a js that handles the javascript event and passes it to the wb control triggering some event that it can handle.
You can use window.external to call a C# method when a global function is fired in JavaScript. See WebBrowser Control Overview for details on window.external.
You'll need to set ObjectForScripting: Webbrowser control's window.external is ALWAYS null. for this to work.
Take #Krishna's answer to add the JavaScript (but drop jQuery because it won't be needed):
private void addScript(HtmlElement head, string scriptSource)
{
HtmlElement lhe_script = head.Document.CreateElement("script");
IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement;
script.src = scriptSource;
head.AppendChild(lhe_script);
}
addScript(WebBrowser.Head, #"InjectMonitor.js");
The JavaScript below (InjectMonitor.js) will find all global functions and attach your specified handler:
function augment(withFn) {
var name, fn;
for (name in window) {
fn = window[name];
if (typeof fn === 'function') {
window[name] = (function(name, fn) {
var args = arguments;
return function() {
withFn.apply(this, args);
fn.apply(this, arguments);
};
})(name, fn);
}
}
}
augment(function(name, fn) {
console.log("calling " + name, fn);
// window.external.yourC#method
});
In this example, taken from Adding Console Log to Every Function, it just logs the call to console; but using window.external you could send some message back to your C# application with details of what function was called from the client.
Finally, here's a JS Bin example (run it and don't forget the console): JS Bin Example
On the webbrowser load event,
Inject Jquery
Inject Monitor scripts
,
private void addScript(HtmlElement head, string scriptSource)
{
HtmlElement lhe_script = head.Document.CreateElement("script");
IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement;
script.src = scriptSource;
head.AppendChild(lhe_script);
}
addScript(Webbrowser.Head, #"<Change File Path here>jquery.min.js");
addScript(WebBrowser.Head, #"InjectMonitor.js");
your file InjectMonitor.js should be something like this
$(document).ready(function () {
//Add click event for every anchor on the page loaded- note this merely alerts text on click. you can however add your own function
$("a").click(function (e) { alert($(this).text()); return false;})
});
Well what krishna has answered is interms of pure javascript attaching to events, however i see that you might need to attach it to all the tags(a,p,div,input) etc and to all the events attached to each tag.
i believe the another way is to play around with the BHO(browser helper object) available to your in .net, and if not and you are good at VC++ and MFC you can also play around with Windows Hooks.

nodejs + jsdom, jQuery strange behavior

The code below is just a small snippet from my server.js file just to run the test provided by the jsdom documentation.
var window = jsdom.jsdom().createWindow();
jsdom.jQueryify(window, './jq.min.js' , function() {
console.log('inside');
window.$('body').append('<div class="testing">Hello World, It works</div>');
console.log(window.$('.testing').text());
console.log('end');
});
The output I get literally is just inside and then the server hangs and never returns. I've added a debug statement console.log(window); to see if the window object is truly being created, and I do end up with a fairly large output statement detailing the object's contents. One thing I did notice however is that the output does not show that $ is a defined method of the window object and in fact, console.log(window.$); renders undefined.
I understand jsdom is still in dev mode, but is there something I'm missing here?
Just as some background, I have tried several variations of the code, including using the jsdom.env() method and also building a document from existing HTML markup, neither of which rendered expected results either.
I hope this code snippet helps you:
createWindow = function(fn) {
var window = jsdom.jsdom().createWindow(),
script = window.document.createElement('script');
jsdom.jQueryify(window, function() {
script.src = 'file://' + __dirname + '/some.library.js';
script.onload = function() {
if (this.readyState === 'complete') {
fn(window);
}
}
});
}
createWindow(function(window) {
// Do your jQuery stuff:
window.$('body').hide();
});
from here

Categories