maandag 20 april 2009

Scrollable part above fixed part in html container

As a follow-up of the previous post, I also want to publish a solution for the next situation: what if there is no fixed part above the scrollable part? Problem here is that setting top undoes setting the bottom in IE.
So we have to make sure that the top is not set in IE6 (using ones of the infamous CSS hacks):

html>body .content{
/* this part is moved out of the common part,
and will only be taken into account if the browser is not IE6 */
top: 0;
}


Now we still have to make that the height is correct in IE6, as the height is set to auto by default:

height: expression((offsetHeight +offsetTop)+'px');

The problem is that we can't retrieve the bottom from javascript,
so we have to rely on the fact that the height is set automatically, and the top will be set accordingly. We want the following: newHeight = parentHeight - bottomOffset, while bottomOffset = parentHeight -topOffset.

Non-scrollable pages with fixed header/footer in CSS

I had a lot of trouble creating pages that don't have scrolling pages when the data on them gets too large. However, I think that it's an important asset if you're creating web applications: an application should always have all its functionality visible on loading (without having to scroll down). (I often refer to this as the dashboard feeling.).

This is how I did it:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title></title>
<style>
body, html{
height:100%;
margin: 0px;
position:relative;
}
.content{
top: 10em;
/*next line is here because IE6 ignores bottom when top is defined.
The line itself will be ignored by other browsers */
/*take care because the value for the bottom offset is calculated in function
of the top, because we want to be dependent on em units */
height:expression(offsetParent.offsetHeight - offsetTop*2 + 'px');
bottom: 10em;
width:40%;
position:absolute;
background-color:red;
}

</style>
</head>
<body style="background-color:yellow">
<div class="content">
test
</div>
</body>
</html>


Note the tricks I had to do for getting the thing working in IE6: since top and bottom are not working correctly together (see bug report on quirksmode), I had to use expression here, which introduces sone javascript in the css. Also important: the header and footer have fixed heights defined as em, so if the user chooses the increase/decreaase fonts, the header/footer scales along.

donderdag 2 april 2009

My Flex and Maven experiments

Trying to mavenize the as3mock project last days, as I need for a customer. However, flexmojos seems to be in some intermediate state now, meaning documentation is quite fuzzy now.
However, I got the archetype for libraries working using the following sequence:

  • mvn archetype:generate -DarchetypeRepository=http://repository.sonatype.org/content/groups/public -DarchetypeGroupId=org.sonatype.flexmojos -DarchetypeArtifactId=flexmojos-archetypes-library -DarchetypeVersion=3.1.0

    That is similar to the explanation on the flexmojo wiki, but with changed version number.

  • applied the changes as described on Carsten Schlipf's blog.

  • if you want to run the tests, you should also make sure that flashplayer is in the path

donderdag 26 maart 2009

Testing flash eventListeners

In a previous project, we had a lot of trouble in testing eventListeners: we used the asynchronous test features of flexunit, but that made the code very hard to read, and slow to execute. As an example: how do you know that an event hasn’t been fired? The only way to do that is through some reasonably timeout, but that comes with a price. Another thing is you have start using inline functions, which again obfuscates the code even more.
So how are we going to test then, if we’re not going to use asynchronous functions?
Let’s split the problem in two: validating if the object responds as wished to incoming events, and firing an event.
Let’s start with the last one:

Testing if an event has been fired by your application


The trick here is to use good coding practices on your object: since event dispatching is not the core functionality of your class anyway, you’re class should delegate this to a helper. Instead of extending your object from EventDispatcher or implementing IEventDispatcher, you should pass this IEventDispatcher from outside the code, whether through the constructor, or through some setter. That way, you can pass a test double (stub/fake/mock) as IEventDispatcher to the class, and so you can test if it has been called correctly with using asynchronous code.
However, there is a small caveat: upon receiving the Event, the target and currentTarget are no longer referring to your class, but to the IEventDispatcher you sent. If this is unwished behavior, there are two things you can do: create a subclass of Event that allows you to pass in the target, or create your own EventDispatcher that delegates its calls back to the original object that implement IEventDispatcher in some way or another.

package {
import flash.events.Event;
import flash.events.IEventDispatcher;
public class ClassThatDispatchesEvents {
private var eventDispatcher:IEventDispatcher;
public function ClassThatDispatchesEvents(eventDispatcher:IEventDispatcher) {
....
this.eventDispatcher = eventDispatcher;
}

....
eventDispatcher.dispatchEvent(new Event("test"));
....

}
}

Testing if your class responds to an incoming event


Again, the trick here is delegation: instead of subscribing your class yourself to the events, again pass an IEventDispatcher to the constructor. Instead of adding the eventListeners directly to you class, add them to the IEventDispatcher instead. In the test double (stub/fake/mock) implementation of the eventDispatcher, you have access to the the function that was subscribed to the event , and it can be called synchronously. Et voila, your listeners are tested synchronously, while it’s still possible to have them declared as private. I'm also planning to publish a helper class for this purpose somewhere...

woensdag 11 februari 2009

Flex 3 profiling without FlexBuilder Pro

Although you can't use the profiler UI from FlexBuilder if you have no professional license, you can get some profiler stuff working if you do the following:

  • find the ProfilerAgent.swf file in the .metadata\.plugins\com.adobe.flash.profiler folder of your eclipse workspace.

  • edit/create mm.cfg (to be found/created in %USERPROFILE% on win xp), and add the following line:
    PreloadSwf=\ProfilerAgent.swf?host=localhost&port=9999, where you replace the with the actual path found in the previous step.


From now on, you can start to use things from the flash.sampler library (included with FlexBuilder), and call inspection methods like getSize, startSampling etc. (see Flex help) if you start your application in debug mode...

By the way: the original post that helped me out is to be found here: http://arielsommeria.com/blog/?p=48

zondag 24 februari 2008

FlexUnit and Flex3

Since Flex3, some basic actionscript logic has changed which prevents the FlexUnit framework 0.85 (as it is available on Google Code) to find the test methods automatically. This is caused by the fact that since flex 3, for each does no longer iterate over the methods in an object.
I fixed the problem by creating an own TestCase class, which subclasses from the original one. In here, we override the getTestMethodNames function to work with DescribeType instead of for each.
This is also done in as3mock.

Here is what it looks like:


public override function getTestMethodNames():Array
{
var methodNames:Array = new Array();
var typeDesc:XML = describeType(this);
var item:XML;
for each (item in typeDesc.elements("method")){
var att:XML;
for each (att in item.attribute("name")){
var name:String = att.toXMLString();
if (0 ==name.indexOf("test")){
methodNames.push(name);
}
}
}
return methodNames;
}