Reliable way to override javascript globals - javascript

I'm trying to mock the date on a CefSharp browser by injecting MockDate and setting it to some fixed date before every other script runs. Every window object, on any frame, at any time, should only have access to the mocked date, so the ideal would be to internally redefine the JavaScript Date object, but I don't think CefSharp or probably even Chromium has this option. I'm also going to mock some other functions like setTimeout and Math.rand, to prevent the browser from having any side effects (this is part of a larger project whose aim is to be able to record/replay browsing activity), so messing with OS's time wouldn't solve it.
I considered using RegisterJsObject since it can actually overwrite existing globals, but I don't think there is a way to pass a JavaScript constructor.
What I've tried so far is to handle the FrameLoadStart event:
private static string Inject = File.ReadAllText("Inject.js");
private void ChromeBrowser_FrameLoadStart(object sender, FrameLoadStartEventArgs e)
{
e.Frame.ExecuteJavaScriptAsync(Inject);
}
Where "Inject.js" contains the mock date code. But I've noticed that, randomly, sometimes it'll work and sometimes it won't. I guess because the function is async and the javascript context sometimes haven't been created, since according to the documentations you shouldn't run scripts here. The documentation recommends handling OnContextCreated instead, but it only runs for the main frame, which wouldn't let me inject the code on any iframe. So I wonder if I have any alternative.

In case anyone else need this, the solution was to modify the actual C++ CefSharp code by adding a line to the end of CefAppUnmanagedWrapper::OnContextCreated:
frame->ExecuteJavaScript(CodeToInject, "something://something", 1);
This won't work if injected on the C# side, I believe because these calls are async so you may be injecting it too late, after scripts on the page have already run.

If you can edit HTML entry points then you can just add window.Date = MockDate before any other scripts. For example:
<html>
<body>
<script src="mockdate.js"></script>
<script>
window.Date = MockDate
</script>
<script src="myscript.js"></script>
</body>
</html>
So the idea is you can tune script loading order in your HTML. It can be done in any browser.
If you can not or do not want to edit HTML then it's much trickier. You could use CefLoadHandler in CEF C++ or its alternative in CefSharp.
UPD
Actually i'm not sure about CefLoadHandler. The reliable way would be to implement your own CefRenderProcessHandler But you already mentioned it. If it doesn't work then it's a bug in CefSharp or CEF C++ itself. In that case it would be better to write about it on http://magpcss.org/ceforum/

Related

How to avoid function overrides in dart html (dart web)?

Let's say I call window.alert('my message') in dart code. But what if (exactly my case) there is a script which did override alert function before my script. Now if I try to call window.alert('message') It executes overridden alert function instead of initial one.
Is there a mechanism to ensure that all functions are not overridden in described way? Or should I always make sure that dart script is the first to execute on page to ensure that no undesirable overrides are done and behavior is stable and it's the only way to go?
Here is basic github repo if you would like to see the issue live.
EDIT 1:
main.dart
import 'dart:html';
void main() {
window.alert('alert');
}
index.html
<html>
<head>
<title>test</title>
<script>
alert = (variable) => confirm("hehe it's jinxed");
</script>
<script defer src="main.dart.js"></script>
</head>
</html>
That does not sound possible.
If something "overrides" the JavaScript alert function, it actually overwrites the alert property of the window object. The old value is completely lost at that point, and it's not (easily) possible to even detect that this has happened.
If your code doesn't run first in a web browser, you can't protect yourself from this. If your code does run first, you can use Object.freeze or similar functionality to lock down the original properties, or take copies of them into your own variables. Simply running first is not a guarantee, if your code just uses window.alert directly later. You have to make an effort to prevent later code from overwriting it too.
This is really a JavaScript issue, there is nothing special about dart:html or Dart compiled code in this, it affects any JavaScript code which doesn't run first in a browser.

Chrome doesn't take new CSS and Javascript programming

I'm having an issue with updating a web application in Chrome. It’s an ASPX site, but I don’t believe it’s relevant to this conversation. The issue is that our clients don’t get the latest programming in Chrome, because most of the time, it fails to release Javascript and CSS programming from memory, then proceeds to cause all kinds of mayhem while in use.
I tried placing this piece of code in the <head>, like many have suggested, but it doesn’t work all the time.
<script type="text/javascript">
function reload_js(par_src) {
src = $('script[src$="' + par_src + '"]').attr("src");
$('script[src$="' + par_src + '"]').remove();
$('<script/>').attr('src', par_src).appendTo('body');
}
reload_js("../../global/scripts/global_scripts.js");
reload_js("scripts/main.js");
reload_js("scripts/tabs/jquery.ui.core.js");
reload_js("scripts/tabs/jquery.ui.widget.js");
reload_js("scripts/tabs/jquery.ui.mouse.js");
reload_js("scripts/tabs/jquery.ui.sortable.js");
reload_js("scripts/tabs/jquery.ui.tabs.js");
reload_js("scripts/chat_room.js");
</script>
And I use this Javascript file to refresh my css's. One that I found here.
<script src="../../global/scripts/css_refresh.js" type="text/javascript"></script>
I'm scared that these methods cause unnecessary overhead, because they run every time a page is loaded.
Could one of you experts please tell me if this is the most efficient method for updating? Or perhaps recommend a better method to keep these files up to date?
Simplest way to fix this is to add an identifier to the script/style-files. Just add something like ?version=12 (and update the number for each release) then the browser will fetch the newest file. You can also use some sort of server-side date-option after the ?of course, to force a new fetch every day or similar.

Strange Javascript/vbscript behavior when opening file from browser

An old web application I recently have to work with is having an issue. There is an input element that contains the following:
onClick="javascript:Run('**SomeFilePath.mdb**');"
What this is supposed to do is open a users respective .mdb file.
First off, there is no javascript Run function defined anywhere. I searched online because I thought maybe it's an old javascript built-in, but I couldn't find anything.
Second off, there IS a vbscript Run() function, that implements the described behavior, defined in the source code, but as far as I know javascript can't call that other than via ajax, which as you can see isn't what is happening.
The strange part is this works for some users!
If anyone could shed some light as to why I'd appreciate it!
EDIT: The only browser I'm dealing with is IE. I know there is an active-x way to open a file, which is what the vbscript Run() function I mentioned above is using.
Update: So after more investigation/research, it would seem like when IE doesn't find the javascript Run() function it defaults to the vbscript Run() function that IS defined. However this only occurs on some versions of IE. Can anyone confirm this behavior?
Research links:
Comment referring to how IE defaults w/ scripting
Msdn article about using both script types in same page
Yes, you can run vbscript from javascript and vice-versa, i do it sometimes when one language doesn't support something the other does.
You can indicate in your script which is the default language in case you don't specify it like .
You can also specify it while calling the function like vbscript:functionname("..") or javascript:functionname("..")
As you noticed there are cases where the browser gets confused and doesn't find the function because he searches/executes the function in the wrong language.
This behavior is influenced i suppose by version also but surely by in which order the logic flows in your script, if the browser first executes a javascript he tends to go further in this language in case of doubt.
So to evade this
don't mix the two unless realy necessary, translate your vbscript function in javascript)
try to always use javascript, vbscript is less good at handling DOM etc
in case they are mixed, specify the correct scriptlanguage when you call a function
when opening a script tag, also give the correct language like or
So, specific, to solve your problem translate the vbsripts function to javascript and if not possible, call your function like onClick="vbscript:Run('**SomeFilePath.mdb**')"

initialization of dojo widget

I tried to create custom widget for my site. when I loaded page it says:
mixin #0 is not a callable constructor.
clsInfo.cls.prototype is undefined
I can't find any information about clsInfo, so I don't know what is it. maybe the problem that I use dojo from google:
and my own script is located on localhost. so when my dojo on page initializes something goes wrong with my script. I can't find any good info on dojo, maybe I search in wrong places?
please help me to resolve my problem
I ran into this when I was trying to override a dijit.Dialog so I could bind events to controls within it. We've yet to see if the binding part will work, but if you look at the source, this happens when one of the bases passed in as the second argument fails to resolve to an "[Object function]". In my case, I was passing a String in.
dojo.declare takes 3 arguments:
The name of the custom object "class" you're building
An array of base classes, parents to provide functionality (not the string names of those classes)
A hash of functions and declarations
So if I want to override dijit.Dialog, I have to do:
dojo.declare("myDialogType", [dijit.Dialog], {
function1() {/*Code*/},
function2() {/*Code*/}
}
I had ["dijit.Dialog"] as my second argument and that was the problem.
I strongly recommend using Web Inspector or Firebug with uncompressed local copies of the Dojo library rather than the CDN to figure out what's going on and debug these types of problems. Dojo's documentation is extensive but not complete in some areas and some behaviors have to be figured out by looking at what the code expects. That's not intended as a slight to the authors; once you get it going it's a pretty awesome product, and any documentation for volunteer work is appreciated.
Are you sure Dojo is loading? Did you put your code in a dojo.addOnLoad()? When using a CDN you sometimes run into issues with execution times. dojo.addOnLoad() will not only trigger when the DOM is loaded, it gets called when dojo resources have downloaded, such as dijit._Widget.
I've run into this problem when I screw up the order of my requires which makes _WidgetBase not what _WidgetBase really is. Seems like a simple spot to screw up.

How to help the debugger see my javascript, or how to best refactor my script to help make it debugger-friendly?

I have an ASP.NET MVC project that uses some simple AJAX functionality through jQuery's $.get method like so:
$.get(myUrl, null, function(result) {
$('#myselector').html(result);
});
The amount of content is relatively low here -- usually a single div with a short blurb of text. Sometimes, however, I am also injecting some javascript into the page. At some point when I dynamically include script into content that was itself dynamically added to the page, the script still runs, but it ceases to be available to the debugger. In VS2008, any breakpoints are ignored, and when I use the "debugger" statement, I get a messagebox saying that "no source code is available at this location." This fails both for the VS2008 debugger and the Firebug debugger in Firefox. I have tried both including the script inline in my dynamic content and also referencing a separate js file from this dynamic content -- both ways seemed to result in script that's unavailable to the debugger.
So, my question is twofold:
Is there any way to help the debugger recognize the existence of this script?
If not, what's the best way to include scripts that are used infrequently and in dynamically generated content in a way that is accessible to the debuggers?
I can not comment yet, but I can maybe help answer. As qwerty said, firefox console can be the way to go. I'd recommend going full bar and getting firebug. It hasn't ever missed code in my 3 years using it.
You could also change the way the injected javascript is added and see if that effects the debugger you're using. (I take it you're using Microsoft's IDE?).
In any case, I find the best way to inject javascript for IE is to put it as an appendChild in the head. In the case that isn't viable, the eval function (I hate using it as much as you do) can be used. Here is my AJAX IE fixer code I use. I use it for safari too since it has similar behavior. If you need that too just change the browser condition check (document.all for IE, Safari is navigator.userAgent.toLowerCase() == 'safari';).
function execajaxscripts(obj){
if(document.all){
var scripts = obj.getElementsByTagName('script');
for(var i=0; i<scripts.length; i++){
eval(scripts[i].innerHTML);
}
}
}
I've never used jquery, I preferred prototype then dojo but... I take it that it would look something like this:
$.get(myUrl, null, function(result) {
$('#myselector').html(result);
execajaxscripts(result);
});
The one problem is, eval debug errors may not be caught since it creates another instance of the interpreter. But it is worth trying.. and otherwise. Use a different debugger :D
This might be a long shot, but I don't have access to IE right now to test.
Try naming the anonymous function, e.g.:
$.get(myUrl, null, function anon_temp1(result) {
$('#myselector').html(result);
});
I'm surprised firebug is not catching the 'debugger' statement. I've never had any problems no matter how complicated the JS including method was
If this is javascript embedded within dynmically generated HTML, I can see where that might be a problem since the debugger would not see it in the initial load. I am surprised that you could put it into a seperate .js file and the debugger still failed to see the function.
It seems you could define a function in a seperate static file, nominally "get_and_show" (or whatever, possibly nested in a namespace of sorts) with a parameter of myUrl, and then call the function from the HTML. Why won't that trip the breakpoint (did you try something like this -- the question is unclear as to whether the reference to the .js in the dynamic HTML was just a func call, or the actual script/load reference as well)? Be sure to first load the external script file from a "hard coded" reference in the HTML file? (view source on roboprogs.com/index.html -- loads .js files, then runs a text insertion func)
We use firebug for debug javascript, profile requests, throw logs, etc.
You can download from http://getfirebug.com/
If firebug don't show your javascript source, post some url to test your example case.
I hope I've been of any help!
If you add // # sourceURL=foo.js to the end of the script that you're injecting then it should show up in the list of scripts in firebug and webkit inspector.
jQuery could be patched to do this automatically, but the ticket was rejected.
Here's a related question: Is possible to debug dynamic loading JavaScript by some debugger like WebKit, FireBug or IE8 Developer Tool?

Categories