4

I have a strange problem with a web app for WP7 (7.1).

The code that works with Chrome, Safari, etc.:

$.each(val, function(sub_key, sub_val) {

                $("."+sub_key).html(sub_val);                       

});

Examples for the variables in use:

sub_key : title-home
sub_val : This is home

This does not work on WP7 (v. 7.1). I tried endless combinations but the only way to get the selector working is to define a static string inside the selector. Like so:

$.each(val, function(sub_key, sub_val) {

                $(".title-home").html(sub_val);                     

});

This is of course not an option. Is there some kind of bug in IE when joining strings like I did?

BTW I think WP7 is using the IE 7 engine.

Cheers Johe

j7nn7k
  • 17,995
  • 19
  • 78
  • 88
  • Do you have a way to print out `typeof sub_key`, `typeof ("." + sub_key)`? That might help with troubleshooting. Have you tried other methods like `[".", sub_key].join('')`? – qingbo Sep 11 '11 at 02:05
  • IE7 for pre-Mango, IE9 for Mango. – Claus Jørgensen Sep 11 '11 at 05:32
  • @qingbo the types are "string". I also tried concat() nothing works. It is not that IE does not join the strings. He does... But when I try within or outside the jquery selector the code instantly fails and the loop stops. – j7nn7k Sep 11 '11 at 11:45
  • The Problem persisted mainly due to the strange wp7 browser caching. Even if ie updates some parts of the code, some parts are not being reloaded... this made the trial and error even harder. Anyway the term $("."+sub_key).html(sub_val); works... IE had problems with an operation trying to replace the text of a tag. Which was obviously an error in the code, but ingnored by Chrome, Moz and Safari. – j7nn7k Sep 11 '11 at 14:39

2 Answers2

2

--edit: If you have problems with on-page javascripts not running at all: make sure to check my findings on the subject that I've posted at http://social.msdn.microsoft.com/Forums/en-AU/jscript/thread/bac9f056-e0de-449e-a1b6-36e745fa59c6 - maybe your problems are related to some unlucky timings or property-setter ordering. it turns out that if you hardcode the URL in XAML, then you must ensure that in that XAML the IsScriptEnabled is set BEFORE the SOURCE property, or else you will have lots of failures depedent on what doctype your pages have. the same applies to setting the Source or Navigate'ing in the code, but that's quite obvious there. on the other hand, at first glance, bindings seem to work properly either way. --/edit

It may be not very helpful for you, but I'll post it anyways, as it may help many other people with WP7 and jQuery:

Please, ensure that you are using the newest JQ that is marked by its team as ok-with-wp7. I recently was interoperating with a website, where the pulisher constantly mixed up different versions of the JQ. From my humble experiments, only the current jQuery 1.6.2 was working properly inside WebBrowser control, also the jQueryMobile was doing well. Versions 1.4.x and 1.5.x that was commonly used on that site I worked with - completely failed to parse somewhere at the jQ.js core script, saying shortly - jQuery and $ symbols were 'undefined' after the page loaded. BTW. If I recall correctly, that was on 7.0 (from MS: "something between IE7 and IE8") and on the 7.1 (overheard somewhere: "something between IE8 and IE9") the compatibility is a bit better, but not perfect.. If you can, try jQmobile first.

About the failed js code -- you have to be extra-uber-careful when scanning the page. You say about WP7.1 app - so I assume you are working inside WebBrowser control. If so - then cut your JS script off the page, copy it down as a string somewhere in you app, and then, on the WebBrowser.NavigationCompleted - try to execute that script manually through WebBroweser.InvokeScript. If there's whatever actual error - you will get an exception, most probably "ComException 0x80020101. You know.. the WebBrowser is strange on that thing, it's its beloved error code returned for so many different causes.. anyways:

If that error occurs, the JS is instantly aborted, and your code will get an except that you will be able to catch. Inside that except object you will get ... no information at all. Pity. But with some tricks, you can play minesweeper with the JS code and cut it down to the minimal examples that either work properly or crash - and maybe you will deduce what's up.

Some errors, for example:
- trying to use a name that is unknown, may return "undefined" but also, may crash, especially at global scope
- trying to accidentially stringify window, window.external, and other natives, may somtimes cause crash
- trying to touch the BODY of the document, before it loads completely, may cause crash
- ... and so on. Please note, that the "before the page loads" is just my guess. I assume you try to play with your page AFTER you have received the 'webbrowser.navigated' event, as it is the first sane point to do so, as the Browser notifies you the page has been loaded. Yet, still, even with that, you can still get that error, and it's may just be all about unfotunate timing. If you retry to invoke exactly the same code just a bit later, you may succeed without any exceptions.

Forgive me, but I'll repeat: most of the times, if anything bad occurs, you will get a "Name not found/COM0x80020101" error, that will cause the JS code or file to silently abort and be skipped. It usually does not mean what the exception name stands for. Thats just an generic-fault in the JS. Occasionally you will get a few other exceptions, but thats 95%-to-5%. Btw. other exceptions usually also have quite unmeaningful data inside them.

Now, I mentioned some tricks.

The WebBrowser.InvokeScript is erm.. let's say, unfriendly to use. It is designed only to invoke global functions registered by the javascript. The InvokeScript has 2 overloads: (string name) and (string name, object[] params). The important thing to know is, that the first parameter is the NAME of the function. It must be a name. It cannot be an arbitrary JS code, the InvokeScript looks for functions by name, and if it finds none, a .. 0x80020101 is thrown :) Arguments/strings - you may pass whatever.

I'm writing all of this to aid you with eventual manual debugging/minesweeping the JS code. If you set a breakpoint inside the WebBrowser.NavigationCompleted event handler, or wherever called afterwards, you may play with the JS quite interactively from within the debugger's watch window, with the mighty trick of a single, guaranteed-to-exist, js-core function: the eval

Although InvokeScript can invoke only a function, picked by name, with "eval" function, you may execute completely arbitrary code. I've (not once) injected/eval'ed whole JQuery1.6.2 library into the page, just to check whether it works or to fiddle with the contents on the page - because the page linked to ie. JQ1.4 that was broken on WP7.

Be warned though, even if foth of the InvokeScript overloads claim to return an "object", do not be fooled by that. At least when playing with eval, they are unable to do so. The only thing they are able to return is a pure string. Whatever else you will try to return, it will be returned as an "", an empty string. I've checked on 7.0, 7.1 and 7.5. The object[]params is dubious too. I've managed to pass strings only.

examples to type into the Watch window (assuming 'wb' is the WebBrowser control)

wb.InvokeScript("eval", " 'mom' "); // returns string, 'mom'
wb.InvokeScript("eval", " window "); // returns empty string
wb.InvokeScript("eval", " ' '+window "); // returns [object Object] -- note the ' '+ -- to stringify it before returning

wb.InvokeScript("window"); // 0x80020101
wb.InvokeScript(" 5+5 "); // 0x80020101 :)
wb.InvokeScript(" 'mom' "); // 0x80020101 :))
wb.InvokeScript("myfunction"); // 0x80020101 or calls your function from JS
wb.InvokeScript("function blah(){return 5+5}; ' '+blah() "); // 0x80020101

wb.InvokeScript("eval", " '5'+'5' "); // returns '55' - only with eval you may exec custom code
wb.InvokeScript("eval", "function blah(){return 5+5}; ' '+blah() "); // you can even define functions - returns 10
wb.InvokeScript("eval", " ' ' + blah() "); // what's more, whatever you do, it's permanent, functions is still there, returns 10

// JQ works too:
wb.InvokeScript("eval", " ' ' + $ "); // if you see" undefined", the JQ failed to load
wb.InvokeScript("eval", " ' ' + jQuery "); // the same as above
wb.InvokeScript("eval", myVariable_withCached_JQueryCoreCode); // works! (at least on 7.1 and JQ162)
wb.InvokeScript("eval", " ' ' + jQuery "); // jq dump, if it was loaded properly
wb.InvokeScript("eval", " ' ' + $ "); // the same
wb.InvokeScript("eval", " ' ' + $(document.body)[0] ");

the last line in my case, sometimes threw, and sometimes did not. If it threw, I usually was able to re-call it once again successfully for example, 250ms later, set with a timer _in_the_app_code_, but was unable to do the same in a setTimeout! When I was trying to perform a similar delay-call from within the JS, it sometimes worked, but sometimes even crashed the whole application.. I bet that the exception was 80020101, but I've just became mad about that after spending 5+ hours on tracing that thing.. Funnily, but if the same line referred to document.head instead of document.body - no exceptions thrown, ever.

I think I've again written a bit too much, sorry about that :)

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
  • Thanks for this post. You just helped me sort out my own problem that I posted yesterday as http://stackoverflow.com/questions/9188063/how-to-call-a-jquery-function-from-net-webbrowser-control-using-invokescript – GuyWithDogs Feb 08 '12 at 19:10
0

quetzalcoatl, two things:

  1. How do you know that a JQuery version is OK to Windows Phone? I've not seen anything official about this.
  2. How about the debugger thing? If I set a breakpoint at Navigated's handler, the page I wish to display doesn't load correctly and I cannot use the Watch successfully.
Cesar
  • 497
  • 5
  • 15
  • 1
    1) JQ is does not officially support ANY of the mobile devices. the library is provided as-is, and it's 'targets' are the major big-desktop-computers' browsers. On the other hand, the JQueryMobile targets to provide support for the mobiles, and quite recently they have announced support for WP7 too. – quetzalcoatl Oct 16 '11 at 09:55
  • 1
    1-continued) I've written about JQ+WP7 because I've noticed that the latest versions of the main JQ library are 100% properly working on the wp7's browser! – quetzalcoatl Oct 16 '11 at 09:57
  • 2) At least at my computer, there are absolutely NO problems in setting breakpoints inside the Navigated event handler. I can set a break there, step, use watch, and it does not impact the page loading. I usually debug on-device, not in emulator, but I dont recall having any problems with the emu either. Maybe you have something broken at your site.. Is this happening from the very beginning? Maybe you've got some of the old beta sdk? – quetzalcoatl Oct 16 '11 at 09:59