I have been developing a silverlight page using just xaml, javascript and html (I literally only have a .html, .js and .xaml file). The problem is, I just realized that it isn't working in any browser EXCEPT Internet Explorer (7 for sure).
I have too many lines of code to want to add vb.net or visual c code behind and use the html bridge. I just want the xaml mouse events to work directly as before. In other words, when the xaml's MouseLeftButtonDown says "highlightMe" I want that highlightMe function to be a javascript function. But I also want my page to work in any browser.
Now, I've played around with creating a brand new visual studio project with vb.net or visual c.net but the xaml file events seem to point to code behind events. Also, it compiles the silverlight into a .XAP file. The XAP file is actually a .ZIP file with a compiled dll and an appmanifest.xaml.
So, how do I configure my appManifest.xaml to handle a silverlight page that has only javascript and xaml (and an html file pointing to the .XAP as the source). The html part, I THINK I understand. AppManifest is a different story and I definitely need help with that one.
I think it has something to do with creating an app.xaml and page.xaml and using the x:Class value of the main tag.
Since I asked this question I found a page...
http://pagebrooks.com/archive/2009/02/19/custom-loading-screens-in-silverlight.aspx
...that 1) showed people recently using a similar model of .js, .xaml and .html for their silverlight page and 2) someone in the comments recommended using firebug to track down issues with silverlight javascript errors.
This proved to me it's ok to use this model of silverlight and that it should work in other browsers. This also made me go try firebug. Firebug is AWESOME. If you enable the console tab, you can see exactly where the javascript was hanging up. And now that it's working, I can see the result of my gets/posts to google app engine.
Firebug showed that I was using if then else statements in a way that only internet explorer allows. For example,
if (blah == 1) { blah2 = 3}
else { blah2 = 5};
works in every browser, but this doesn't:
if (blah == 1) { blah2 = 3} ;
else { blah2 = 5};
Firefox and chrome and safari all apparently need there to NOT be a ; end statement character between the else and if.
So, for the moment, I appear to have fixed my problem with cross-browser compatibility, but I'd still like to know more about appmanifest.xaml and how to make a .xap file with only javascript. I might need it later.
Related
Alright so this is a weird one, I'm not entirely sure if this is the right SE site, but I think it is because it regards web code/browser compatibility. If not, someone tell me in the comments I'll move it.
So basically, I have my game's source code on github. I also am hosting the game itself on github pages. This game should (I believe) function on Firefox and Chrome browsers. The source code has nothing unique to either browser.
The game runs fine on chrome. However, on Firefox this is not the case. None of the assets (images, sounds) are showing up/working on the github pages link. The weird thing is this though: on my local file system, when I open the html file with FF it runs/renders the assets just fine. Also, when I download the zip of my project and try it w/ FF, it also works fine. Why is this the case?
(Note, if you want to see the problem, click on the github pages link, then click on "Start Game", this will open it up to the game where the problem is occuring)
Edit:
Forgot to mention, the error I get in the FF console is NS_ERROR_NOT_AVAILABLE: it leads to line 421 which is this: g2d.drawImage(playerSprite, spriteLoc[0], spriteLoc[1]); where I draw the image onto the canvas. g2d is supposed to be ctx btw, thats a bad java habbit.
try changing the path of the resources.
you call the sound files, and image files this way:
laserSound = new Audio("resources\\Sounds\\laserblast.wav");
playerSprite.src = "resources\\Sprites\\Sprite.png";
you need to change the path to this:
laserSound = new Audio("resources/Sounds/laserblast.wav");
playerSprite.src = "resources/Sprites/Sprite.png";
that is change this \ to this /
the current way you are getting it, Firefox does not find where you files are at.
also, why dont you put init(); at the bottom of the JS file, its just to make sure, that the JS parser already knows that certain functions you will be calling are defined, like update() and initBackground() (this does not seem to be a problem, but just to be on the safe side.)
Well here's a problem.
I've got a website with large javascript backend. This backend talks to a server over a socket with a socket bridge using http://blog.deconcept.com/swfobject/
The socket "bridge" is a Flex/Flash .swf application/executable/plugin/thing for which the source is missing.
I've got to change it.
More facts:
file appExePluginThing.swf
appExePluginThing.swf Macromedia Flash data (compressed), version 9
I've used https://www.free-decompiler.com/flash/ to decompile the .swf file and I think I've sorted out what's the original code vs the libraries and things Flash/Flex built into it.
I've used FDT (the free version) to rebuild the decompiled code into MYappExePluginThing.swf so I can run it with the javascript code and see what happens.
I'm here because what happens isn't good. Basically, my javascript code (MYjavascript.js) gets to the point where it does
window.log("init()");
var so = new SWFObject("flash/MYappExePluginThing.swf"", socketObjectId, "0", "0", "9", "#FFFFFF");
window.log("init() created MYappExecPluginThing!!!");
so.addParam("allowScriptAccess", "always");
log("init() added Param!!");
so.write(elId);
log("init() wrote!");
IE9's console (yeah, you read that right) shows
init()
created MYappExecPluginThing!!!
init() added Param!!
init() wrote!
but none of the debugging i've got in MYappExePluginThing.as displays and nothing else happens.
I'm trying to figure out what I've screwed up/what's going on? Is MYappExePluginThing.as running? Is it waiting on something? Did it fail? Why aren't the log messages in MYappExePluginThing.as showing up?
The first most obvious thing is I'm using FDT which, I suspect, was not used to build the original. Is there some kind of magic "build javascript accessible swf thing" in FlashBuilder or some other IDE?
First noteworthy thing I find is:
file MYappExePluginThing.swf
MYappExePluginThing.swf Macromedia Flash data (compressed), version 14
I'm using Flex 4.6 which, for all I know, may have a completely different mechanism for allowing javascript communication than was used in appExePluginThing.swf
Does anyone know if that's true?
For example, when FDT runs this thing (I can compile but FDT does not create a .swf unless i run it) I get a warning in the following method:
private function init() : void
{
Log.log("console.log", "MYappExePluginThing init()");
//var initCallback:String = Application.application.parameters.initCallback?Application.application.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";
var initCallback:String = FlexGlobals.topLevelApplication.parameters.initCallback?FlexGlobals.topLevelApplication.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";
try
{
ExternalInterface.addCallback("method1Callback",method1);
ExternalInterface.addCallback("method2Callback",method2);
ExternalInterface.call(initCallback);
}
catch(err:Error)
{
Log.log("console.log", "MYappExePluginThing init() ERROR err="+err);
}
}
I got a warning that Application.application was deprecated and I should change:
var initCallback:String = Application.application.parameters.initCallback?Application.application.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";
to:
var initCallback:String = FlexGlobals.topLevelApplication.parameters.initCallback?FlexGlobals.topLevelApplication.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";
which I did but which had no effect on making the thing work.
(FYI Log.log() is something I added:
public class Log{
public static function log(dest:String, mssg:String):void{
if(ExternalInterface.available){
try{
ExternalInterface.call(dest, mssg);
}
catch(se:SecurityError){
}
catch(e:Error){
}
}
trace(mssg);
}
}
)
Additionally, in MYjavascript.js MYappExePluginThing_init looks like this:
this.MYappExePluginThing_init = function () {
log("MYjavascript.js - MYappExePluginThing_init:");
};
Its supposed to be executed when MYappExePluginThing finishes initializing itself.
Except its not. The message is NOT displaying on the console.
Unfortunately, I cannot find any references explaining how you allow javascript communication in Flex 4.6 so I can check if I've got this structured correctly.
Is it a built in kind of thing all Flex/Flash apps can do? Is my swf getting accessed? Is it having some kind of error? Is it unable to communicate back to my javascript?
Does anyone have any links to references?
If this was YOUR problem, what would you do next?
(Not a full solution but I ran out of room in the comment section.)
To answer your basic question, there's nothing special you should need to do to allow AS3-to-JS communication beyond what you've shown. However, you may have sandbox security issues on localhost; to avoid problems, set your SWFs as local-trusted (right-click Flash Player > Global Settings > Advanced > Trusted Location Settings). I'm guessing this not your problem, though, because you'd normally get a sandbox violation error.
More likely IMO is that something is broken due to decompilation and recompilation. SWFs aren't meant to do that, it's basically a hack made mostly possible due to SWF being an open format.
What I suggest is that you debug your running SWF. Using break-points and stepping through the code you should be able to narrow down where things are going wrong. You can also more easily see any errors your SWF is throwing.
Not really an answer, but an idea to get you started is to start logging everything on the Flash side to see where the breakage is.
Since you're using IE, I recommend getting the Debug flash player, installing it, then running Vizzy along side to show your traces.
Should give you a good idea of where the app is breaking down.
Vizzy
Debug Player
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
I am writing a small application with Qt 4.6 (64-bit Arch Linux, though that shouldn't matter) which lets the user edit a document using a QWebView with contentEditable turned on. However, for some reason embedding an image does not work. Here is a code snippet:
void LeafEditView::onInsertImage()
{
// bring up a dialog, ask for an image
QString imagePath = QFileDialog::getOpenFileName(this,tr("Open Image File"),"/",tr("Images (*.png *.xpm *.jpg)"));
ui->leafEditor->page()->mainFrame()->documentElement().evaluateJavaScript("document.execCommand('insertImage',null,'"+imagePath+"');");
}
The test image does in fact exist and yet absolutely nothing happens. Bold / italics / underline all work fine via JavaScript, just not images. Thoughts?
Check that QWebSettings::AutoLoadImages is enabled.
You could also try:
document.execCommand('insertImage',false,'"+imagePath+"');
Try using relative vs absolute paths to the image.
Last but not least, poke around this sample application -- they are using a similar method of Javascript execCommand(), they do some things in a slightly different way such as using QUrl::fromLocalFile.
Best of luck!
It turns out that WebKit has a policy of not loading resources from the local filesystem without some massaging. In my code, I have a WebKit view which I'm using to edit leaves in a notebook. The following one-liner solved my issue:
ui->leafEditor->page()->mainFrame()->setHtml("<html><head></head><body></body></html>",QUrl("file:///"));
From what I gleaned by lurking around the WebKit mailing list archives, in order to load files from the local filesystem one must set the URI to be file:, and this does the job.
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?