Debugging Frontal
From Frontal Wiki
We know how frustrating it can be to have a problem and not know how to solve it. In this section, we share some of our problem-solving techniques, with the hope that you might find them valuable. Also, remember to check out the FAQs, which is where we've tried to collect a lot of the "gotchas" we've come across so far. And finally, definitely use the forums. As long as you do your due diligence before asking a question, you'll be surprised at how helpful a community of users can be.
Contents |
XML Parsing Errors
The Frontal document must be a valid XML file for the Frontal renderer to read it. But it can be aggravating trying to find where the problem lies when all you're told is that an error has occurred. Luckily, there are many tools available to help you out.
First, be sure to check out the section Frontal Markup to understand what valid XML is.
Next, if you have an editor like BBEdit or jEdit that understands XML, load your Frontal document into it. Often, the editor can pinpoint where you may have forgotten to close a tag, or where you included an entity like "&" that is invalid. Also, if one part of the document has nicely colored syntax and another part doesn't, then it probably means that you've mismatched double or single quotes somewhere.
You can also use Firefox or IE to test the validity of your XML. In this case we need to do a little tweaking to the Frontal document. Remember from Accessing Frontal Tags for Scripting#The Document Object and Element that every Frontal document has an implied start and end 'document' tag. So when testing the validity of our Frontal document in Firefox or IE, we need to manually add these tags. Add this to the start of your file:
<?xml version="1.0" ?> <document xmlns="http://frontalcode.com/">
And this to the end:
</document>
Then drag and drop the file into one of these browsers and see if it reports any errors. Often they will report the exact line and letter where the problem occurred.
And finally, if you're still having problems, use the #Divide and Conquer Method described next.
Divide and Conquer Method
The most frustrating bugs occur when you're staring at a massive XML document and you have no idea where to begin to try to solve the problem. This is where the "divide and conquer" technique comes into play. The idea is to begin stripping out (deleting) as much of your Frontal document as you can, while keeping the code that contains whatever problem it is that you're trying to solve. (Be sure to save a copy of your document first!)
Now we have to be a little smart about deleting. We want to remove chunks of code that are independent, or that we feel are unrelated to the problem. After we delete a chunk, we want to be sure we're still seeing the problem that we're trying to solve, and not a new problem we've inadvertently introduced.
By continuing to do this, one of two things will happen. Either we'll end up with a much smaller and more manageable Frontal document to debug, or we'll have deleted something and seen the problem go away. In the former case, we know the problem lies in what we haven't removed, and in the latter case, we know it lies in what we just removed.
At this point, the problem often becomes clear. But if not, our work hasn't been in vain. The reason is that we're now in a good position to seek help from the Frontal forum. If you'd posted your original, massive document, no one would've wanted to help you (they'd feel like you hadn't done any of the work yourself). But if you post a concise Frontal document that contains your problem, then you're far more likely to receive useful assistance.
Using the Frontal Console
The Frontal Console is a small utility built into the Frontal renderer that we can use to examine the run-time state of our Frontal content/app/site. There are two ways to access it. The first is to right click some visual element on the stage and choose "View Frontal Source". The second way is to click anywhere on the Flash stage and type ctrl, ctrl, ctrl, 4, 1, 1 if you use a PC, or command, command, command, 4, 1, 1 if you use a Mac. Either way, the Frontal Console will appear.
In the Frontal Console, there are two tabs that are useful for debugging. The first is the Log View. This view will show us any errors or warnings that the Frontal renderer has issued. It's also a place where we can view our own messages.
The Log View
One of the most tried and true methods for debugging a program is to print messages when certain events happen and when the values of certain variables occur. This helps us see the story that is unfolding in our program, and understand where our assumptions may have gone awry. In Frontal, this technique is very useful. To print a message we use the command com.frontalcode.Debugger.msg, like in this example:
<div onClick='com.frontalcode.Debugger.msg( "Hello, world." );' style="width: 200px; height: 200px; background-color: gray;">click me</div>
You can assign as many parameters as you like, each will be separated by a space when printed out, and the output will be displayed in the Log View of the Frontal Console.
The Log View is a Flash TextField with HTML enabled, so printing out things like XML will result in a whole lot of nothing. Anytime you want to print some markup, be sure to use the htmlEscape utility. You can use the following script to print out the document's source in the Frontal Console:
<script><![CDATA[ com.frontalcode.Debugger.msg ( com.frontalcode.Util.htmlEscape ( document.source ) ); ]]></script>
Another useful utility function is objectToString. This will attempt to convert a complex object into a string. It takes four parameters:
- object: The object to convert.
- depth: This is used to track the recursion of the function and should be zero.
- maxDepth: How far down to go in the object before stopping. (Large numbers here for complex objects could bog things down tremendously. The default is 2.)
- isHTML: Whether the result string should be HTML safe or not. The default is false.
Here's an example:
<script><![CDATA[ com.frontalcode.Debugger.msg ( com.frontalcode.Debugger.objectToString ( { red: "apple", yellow: "banana" } ) ); ]]></script>
And if you have lots of messages being printed out, you can categorize them using the "com.frontalcode.Debugger.logMessage" function. It takes these parameters:
- level: One of the following: com.frontalcode.Debugger.DEBUG, com.frontalcode.Debugger.INFO, com.frontalcode.Debugger.WARNING, or com.frontalcode.Debugger.ERROR. The level will cause the text to be color coded in the Log View.
- category: Any string you'd like to use to categorize this message.
- message: The message to log.
You may then set com.frontalcode.Debugger.gI().logLevel to the lowest level of message that you would like to appear in the Log View. That is, setting it to com.frontalcode.Debugger.DEBUG would show all messages, while setting it to com.frontalcode.Debugger.ERROR would show only errors.
You may also filter messages based on the category that you specified when calling logMessage with the function com.frontalcode.Debugger.gI().setCategoryFilter. It takes two parameters:
- category: The name of the category.
- show: True or false depending on whether or not you want these categorized messages to appear in the Log View.
<script><![CDATA[ com.frontalcode.Debugger.gI().logLevel = com.frontalcode.Debugger.WARNING; com.frontalcode.Debugger.gI().setCategoryFilter ( "boring", false ); com.frontalcode.Debugger.gI().setCategoryFilter ( "interesting", true ); com.frontalcode.Debugger.msg ( "Can't see me - I'm DEBUG level." ); com.frontalcode.Debugger.logMessage ( com.frontalcode.Debugger.ERROR, "boring", "Can't see me - I'm boring." ); com.frontalcode.Debugger.logMessage ( com.frontalcode.Debugger.WARNING, "interesting", "I'm an interesting warning so you can see me." ); ]]></script>
And finally, you can disable the Frontal Console altogether by setting com.frontalcode.Debugger.gI().enabled to false.
Command Line
The Command Line tab of the Frontal Console allows you to run Frontal scripts at any time. This can be handy. For example, it allows you to look at what styles and attributes have been applied to an element. One thing to note though is that it runs in the context of the Frontal Console, which is its own separate document. So the first thing to familiarize yourself with is how to find your document instance.
For this we use the instance of the DocumentManager that is available to all elements via the "mgr" property. (See Accessing Frontal Tags for Scripting for details.) It provides us with a method to search through open documents either via a 1-based index (set in the order that the document was created), or by document title. Your document is very likely the first and so you can get it with the following script. Paste it into the Command Line input and click "Go".
mgr.gD(1)
You'll see "{ }" in the output, which indicates that an object was found. (The last value of whatever script you run will appear above the input area.)
So now that we have our document, what can we do with it? Earlier, we mentioned that we can use the command line to see what attributes and styles have been applied to an element by our style sheets. How do we do that? Run the following code sample.
<style><![CDATA[ .test { width: 200px; height: 200px; background-color: blue; @onClick { com.frontalcode.Debugger.msg ( "Hello, world." ); } } ]]></style> <div id="div1" class="test" />
Now, open the Frontal Console by clicking the square. Go to the Command Line tab and paste in the following:
com.frontalcode.Util.htmlEscape(mgr.gD(1).gE("div1").toXMLString())
Here we get our document and then use the ubiquitous "gE()" operator (see Accessing Frontal Tags for Scripting for details) to find the 'div' with id "div1". We then use the toXMLString method to display it. (This method is handy because it inlines an element's styles and attributes.) So with this technique, we can verify that the ".test" ruleset was indeed applied to our 'div'.
Using Firebug to Monitor Network Traffic
Often, our problems stem from networking issues. Perhaps we've typed in an incorrect URL somewhere, or the image we're trying to download doesn't have a "crossdomain.xml" policy file associated with it. A very handy tool to see these problems is the Firebug plug-in for Firefox. This is a tool that let's you closely monitor the network activity of a web page.
To use Firebug, open up its network tab and watch as assets are downloaded. If there are any missing files, you'll see red entries marked 404. You'll also see policy files being downloaded, and you'll be able to view their contents to see if they're correct. Finally, if you're using any of the Networking in Frontal techniques, then you can use Firebug to watch the conversations between your scripts and the servers they're talking to.
Firebug is also handy when debugging Frontal script-to-JavaScript communications. Firebug allows you to put breakpoints in JavaScript code so you can verify that calls from Frontal are making it to the JavaScript environment.
Viewing Someone Else's Code
Another part of debugging is solving a problem. That is, you know what you want to achieve but how do you do it? A convenience of Frontal is that if you can find where someone else has solved the same problem, then you can view their code to see how they did it. Just right click their movie and choose "View Source".
Usually, to run someone else's code in your environment, you need to change the URLs of the content. We can do this with the base-url style. For example, to run an example posted on frontalcode.com on your own server, you might get away with adding the following to the Frontal document. (We say "might" because if absolute URLs are used throughout the document, then they'll need to be edited by hand.)
<style><![CDATA[ document { base-url: http://www.frontalcode.com; } ]]></style>
And for those providers who don't want anyone to do this with their content, the fix is to create a restrictive crossdomain.xml file on your server. See the Flash documentation for help.
Getting Help from Customer Support
Finally, if these techniques don't help, and you're a Frontal subscriber, assistance is available from customer support. However, to make that experience as effective as possible, it'd be useful to explore the techniques outlined above.