webservice.htc, moz-behaviors and Firefox 3 - javascript

Whilst trying to get our app working in Firefox (I'm a big proponent of X-Browser support but our lead dev is resisting me saying IE is good enough). So I'm doing a little side project to see how much work it is to convert.
I've hit a problem straight away.
The main.aspx page binds to a webservice using the IE only method of adding behaviour through a htc file, which is auto-generated by VS I beleive.
Firefox doesn't support this but there is an xml bindings file which can be used to enable htc support (see here: http://dean.edwards.name/moz-behaviors/overview/). The examples work in FF3 but when I use my webservice.htc as I normally would e.g.:
//Main.aspx
/*SNIP*/
<style type="text/css" media="all">
#webservice
{
behavior:url(webservice.htc);
-moz-binding:url(bindings.xml#webservice.htc);
}
</style>
</head>
<body>
<div id="webservice"></div> <!-- we use this div to load the webservice stuff -->
/*SNIP*/
//Main.js
webservice.useService(url + asmpath + "/WebServiceWrapper.asmx?WSDL","WebServiceWrapper");
I get webservice is not defined (works fine in IE), I obviously tried
var webservice = document.getElementById("webservice")
and
$("#webservice").useService(url + asmpath + "/WebServiceWrapper.asmx?WSDL","WebServiceWrapper");
as well which just gives me "useService is not defined" in Firebug. Which leads me to beleive that the binding is not working. However I can see that webservice.htc is being loaded by Firefox in the Firebug console window.
Anyone got any experience of this?
Am I going to have to rewrite how the webservice is called?
Cheers,
Rob

I don't think that you are on the right way for achieving real cross-browser compatibility. Adding support for IE-specific features for Firefox is definitely not the way to go. What about Opera, Safari, Chrome...? If the app you're working on is used strictly on the intranet then supporting Firefox may be enough however...
IMHO, the code should be refactored, but in an other way. If you are working with ASP.NET 2.0 (in this case you'd need ASP.NET Ajax) or newer, you can create proxy between Ajax and SOAP web services. In that case you would need to rewrite all your behaviors as a JavaScript code which may not be a small feat.
On a side note: AFAIK VS.NET does not generate behaviors.
Sorry if this is not too helpful :(

Your jQuery snippet has an error: since useService is a method defined on the node itself, not the jQuery object, you'd have to do:
$("#webservice")[0].useService(url + asmpath +
"/WebServiceWrapper.asmx?WSDL","WebServiceWrapper");

Related

Flash v11.8.800.168 function call fails in Internet Explorer

Company recently upgraded to Flash v11.8.800.168 and a flash movie which is loaded using SWFObject (1.1) is not working correctly in Internet Explorer (Firefox works fine). The movie is loaded dynamically using a jquery document.ready method using the "new SWFObject(...); so.write("ID")" method (again SWFObject 1.1).\
The movie on load calls a JavaScript function (which is built dynamically using server scripting). The function is being called correctly as checked by a debugger. The JavaScript function calls a method in the flash movie passing it some XML (which is used to render some user and navigation items).
Something like this:
function calledFromFlash() {
document.getElementById("FlashMovie").renderUsingXml('<?xml version 1.0"?><lotsofxml></lotsofxml>');
}
Like I said, this all works still in Firefox with the new Flash version.
When I step through the function above, using step into with the IE Debugger, I get the following steps:
function anonymous() {
return eval(this.CallFunction("<invoke name=\"renderUsingXml\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments, 0) + "</invoke>"));
}
At this point, I checked the arguments variable and it contains the XML as one would expect. After the next step into, I get this:
try { __flash__toXML(calledFromFlash(undefined)); } catch (e) { "<undefined/>"; }
At this point the debugger is already on the catch, yet one more step into take the code into the "<undefined/>" section and I can see that e is Object Expected
What I've tried:
Static implementation without SWFObject. This works. But then Firefox doesn't process the XML properly (and it seems to be the same issue as IE)
Upgrading to SWFObject 2.2. Using dynamic implementation it fails still. Using static implementation it works in IE but not Firefox
This is NOT my flash movie, the source is... well, I don't know. The guy that wrote it has left the company. That said, this seems like such a crazy issue.
My proposed fix is simply to use SWFObject for Firefox and use a static implementation for IE, but I really want to know what is wrong.
This was caused by a bug in Flash Player 11.8.800.168. It has been fixed in 11.8.800.175.
Bug fixes:
3630443 - [External][Windows][IE] ExternalInterface.call() method with non-ASCII text as a parameter corrupts the characters on the Javascript side

What do I get an error with highcharts, only in IE8

The charts are working ok in most browsers, including firefox and Opera. However in IE I am getting:
Object doesn't support this property or method
report_graph.js
Code: 0
URI: http://10.11.4.92:5000/assets/report_graph.js?body=1
It's possible that you're calling the javascript file along with a query-string attached. Check out: Passing Querystring style parameters into Javascript file and Passing parameters to JavaScript files for possible solutions.
It wa all due to a `.trim() at the end of some of the code !
e.g. I had $('some selectors).text().trim()
Changing it to $('some selectors).text().trim() fixed it.
As it actually has worked ok in some browsers this seems to suggest an actual issue with the javascript engine in IE. Either it doesn't support the method that other browsers do... or it does not handle the error as gracefully, causing a runtime exception for a error that other browser ignore.

Is it possible changing DOM of an iframe from the parent frame (same document.domain)?

I want a simple and light-weighted way of making cross-domain requests to my api address (api.example.com) which is a subdomain of my main domain (example.com).
I've read A LOT about techniques and hacks to deal with XDRs and their incompatibilities with each used browser but XDR is still very complicated for me. I don't need a complete/complex solution as easyXDM, which I have implemented and worked perfectly.
So, I decided to 'enable CORS' which solved the problem for modern Webkit and Gecko browsers. But as always, there is the IE (and in this case Opera too) which is not compatible with CORS yet.
As I wanted to continue using jQuery AJAX methods, I searched for a solution that would allow XDR with jQuery methods. Then, I implemented a very nice solution by benvinegar which replaces jQuery.ajax() method and therefore all its dependent methods: https://gist.github.com/859940. His script is based on the document.domain/iframe trick.
Before calling the function proposed by Ben, I tested for CORS support with jQuery.support.cors (using jQuery 1.6.2). Everything is okay, working perfectly.
The only thing I'm not happy with the above linked script is that I need to load the jQuery library from api.example.com and I don't want that. I've made a bundle of minified javascript libraries/plugins/scripts in one file which is used by example.com; that gives me me 2 options (for using jQuery in api.example.com): load the entire bundle again or load a non-cached version of jQuery only. I don't like either.
My question is: is it possible to change the DOM of an iframe from the parent frame when both frames have the same document.domain? If so, could I clone jQuery from example.com into the child-iframe (api.example.com)? How? Or I'm just being crazy about this and there is a better solution taking in consideration what I described?
Thank you all in advance,
Leonardo.
file test.htm
<iframe name='my-iframe' src='test2.htm' onload="child();"></iframe>
<script>
function child(){
alert(window.frames['my-iframe'].my_var);
window.frames['my-iframe'].my_var = 'bye';
window.frames['my-iframe'].show_var();
}
</script>
file test2.htm
<script>
window.my_var = 'hi';
function show_var(){
alert(my_var);
}
</script>
The code above will alert 'hi' and then 'bye'

Retrieving the source code of JavaScript script

I've been doing some scraping and at some websites I found references to JS like this:
<script type="text/javascript">
unescape("%3Cscript src='Scriptdir/pr.asp?id=123456' language='javascript'%3E%3C/script%3E"));
</script>
In such cases, it is trivial to retrieve the script code (just go to the link). But how do I retrieve the code in cases like this:
<select ID="Spinner" class="text" onchange="javascript:IWantTheCodeOfThis();">
Is it even possible, or are they stored server-side without an acces for the client?
JavaScript is always stored server-side but executed client-side, so the browser has to get hold of it at some time (unlike to e.g. PHP-code).
What you posted is a JS-function-call so the function "IWantTheCodeOfThis" must be in one of the include-files which are "trivial to retrieve" :)
You could use Chrome or Safari to use the console and look at the resources. You could also type IWantTheCodeOfThis (without ()) in the console, and you will probably see the source code for the function.
Not at all. Any access to Javascript has to be on the client already.
To lookup where the function is located, it's a good idea to use a debugger like Firebug or the Chrome developer tools. Both explicitly show you all available javascript sources on the current site.
JavaScript is executed on the client side. Always.
IWantTheCodeOfThis() is a function that would be in one of the JavaScript downloaded by the browser. Most of the new browsers has some time of "inspector", "develop menu", or "developer tools" from which you can see all of the scripts that were loaded and even search them. Safari, Chrome and Internet Explorer 8/9 all have this. In Firefox, you can use Firebug.
You could go through the scripts by hand but that would be difficult as some websites may load some of their JavaScripts dynamically.

alternative when an older browser does not accept jquery

I have just been altered to the fact that a user of my website is using a very old browser which does not run jquery (in this case Safari 1.x) and as a result can not access the login panel which uses jquery's slideToggle function.
Can anyone think of a fix which detects whether a browser is able to use jquery - and if not make that link go to a different page rather than showing the login panel?
You could a little conditional check like
if(!'jQuery' in window) {
// jQuery is not available
}
or, if Safari 1.x doesn't know about the IN operator (I'm not sure) use
if(!window.jQuery) {
}
I think there are alternative answers to this, but for me, I would have to weigh up the time it will take you to support his obsolete browser (I'm sure there may be other things inside the site), versus the payback to you...
In the plain HTML source code for the the href= of the login link, set that to a plain HTML login page.
Using jQuery, attach the click handler to the link, if this part fails, thats ok, the browser will just follow the href in the link to the plain login page, allowing your old-browser-user to login still.
$(document).ready(function(){
$('#login_link_id').click(function(){
// Your code here
});
});
If you use javascript/jQuery you should ALWAYS ensure your site works perfectly without it. In this case if you have a login popup box; you probably assign a click event assigned after the DOM has loaded.
What you should do is ensure that if jQuery isn't present the link loads a "normal" login webpage as opposed to the popupbox. I use something similar to this:
Log in
<script>
if(!'jQuery' in window) {
$(document).ready(function(){
//assign on click event to loginlink
});
}
</script>
If jQuery doesn't exist then login.html will be opened normally.
Wow, seriously?! Safari 1.x?? Anyhow, try this...
var isJQSupported = false;
$(function() { //shorthand for document.ready
isJQSupported = true;
//your usual code
});
if (!isJQSupported) {
window.location = "http://www.apple.com/safari/download/";
}
To me it sounds like safari 1.X has problems with jQuery internally. Which means simple checks like whether $ exists in the global space or whether $(function) does anything are not going to help.
The most likely root cause will be that javascript throws an error in loading of jQuery itself which will then stop the rest of your javascript code from execution.
There are four viable options here.
Either make the website work with noscript. Replace your login control with pure HTML and postbacks and ask the user to turn javascript off. This option is useful since you won't be fixing the issue for safari 1.x problems specifically.
You can make javascript check for safari 1.X and other non-supported browsers and only load jQuery through script tag injection or ajax if your user is using a supported browser. If the user is using a browser not compatible with jQuery then you can instead use plain javascript.
Get a copy of safari 1.x and see why jQuery breaks. Then fix it and ask for it to pulled into the release of jQuery 1.5. This relies on the fix being something that does can be done without hacking and that the jQuery team agrees is worth adding in.
Ask the user to use a compliant browser.
There might be some more options. I would personally lean towards asking the user to use a compliant browser because supporting Safari 1.x is ridiculous.
This seems like a case where progressive enhancement is needed.
You have to do multiple checks
see if $ exists
see if $.fn exists
[not sure if needed] check if $.support is a function
check for feature support as needed with $.support() http://api.jquery.com/jQuery.support/
At the end of the check, when jQuery reports that features you need are present - the rest of the script can run.
If you're not sure which features mentioned in the support you use, then this might need a single test on Safari 1.x to see what are the values returned by $.support(), but that is what your nasty old-browser-user can do for you (if you prepare code and publish) and report the resulting text. Then you compare the list with other [old] browsers that are accessible and determine features that are required.
The easy way would be to require everything and cancel all scripts if suport for any feature is missing. This will also rule out IE6 and IE7 and opera below 9.something and firefox below 2.0 or including - I'm not sure.
Use a server side language to detect if it's the old safari based on user-agent and load a different javascript file

Categories