Monthly Archives: August 2007

Yahoo! launches Flash library and blog (and I helped!)

Today and over the last week, I’ve been a part of several big launches and redesigns at Yahoo!, and I thought I’d share a little about each with you. We’ve got exciting things happening on the Flash Platform team on the Sunnyvale campus, and hopefully, this week’s activities will only be the start.

First, I highly recommend that you check out what’s new at the Flash Developer Center on the Yahoo! Developer Network. We’ve got a brand new library up for download that adds some cool user interface components to Flash CS3. You’ll find an AutoComplete component, a Menu, a Tree, a TabBar, and my personal favorite, four different Charting components. All free and available under the terms of terms of the BSD license.

That’s not all, of course. In no particular order, here’s everything I’ve been involved with that has either launched for the first time or gone through big changes this week.

Like I said, I’m excited about all the changes made in the last week. Flash is a great web technology, and many folks at Yahoo! certainly enjoy developing with ActionScript. Don’t worry, we definitely have Flex on our radar too. Expect to see more cool libraries for Flash technologies in the future. Now, quit reading, go download the Astra Flash Library, play with the cool new components, and join the ydn-flash group to discuss it. We’d love to hear about any bugs you discover (it’s still beta, after all), and please don’t be afraid to ask us for new features (or even entirely new components!).

Runtime Enforcement of Abstract Classes in AS3

As you probably know, abstract classes are not a language feature of ActionScript 3. If you are unfamiliar with the concept of an abstract class, let me explain. Think of an abstract class as a super-powered interface. It defines a series of functions that must be implemented, and it cannot be instantiated directly. It goes a step beyond an interface because it also defines some functions that are already fully implemented.

To use an analogy, all electronic devices generally have the same connector to plug into the wall. However, not all electronics have the same purpose. A coffee maker and a DVD player do very different things. We could make an interface IElectronicDevice to make sure they all have a plugIntoWall() function, but then every device will need to re-implement the common wall plug functionality that doesn’t differ very often. By making a class AbstractElectronicDevice, we can implement the wall plug functionality once, and all subclasses of AbstractElectronicDevice will be able to use it without re-implementing the same code.

The problem, of course, is that the coffee maker and DVD player have different controls for turning power on and off. The coffee maker might have a switch, while the DVD player has a button. We can’t implement the togglePower() function in AbstractElectronicDevice because many electronics will have different controls, so we need some way to force all subclasses of AbstractElectronicDevice to implement this function themselves. Using the methods developed to enforce Singletons in ActionScript 3 as a guide, I’ve found a way to enforce the abstractness of a class at runtime upon instantiation.

There are two main parts to enforcing an abstract class. First, we must stop a developer from instantiating the abstract class directly. To do this, the constructor needs a little special sauce. Since anyone can create an instance of a public class by simply using the new keyword, we need the constructor of our abstract class to require a parameter that only subclasses will be able to pass. Second, we must ensure that a developer implements functions that the abstract class has defined, but not implemented.

Stopping Direct Instantiation of an Abstract Class

The magic bean to stop a developer from instantiating a class directly is one keyword: this. You don’t have access to an instance of a class until after you call a constructor, so only an instance of a subclass will be able to pass a reference to itself to the super class. Let’s look at some code to help make things clearer.

The instance of MyAbstractType expects to receive a reference to itself as the first parameter in the constructor. If it does not, an error will be thrown.

package com.joshtynjala.abstract
{
	import flash.errors.IllegalOperationError;

	public class MyAbstractType
	{
		public function MyAbstractType(self:MyAbstractType)
		{
			if(self != this)
			{
				//only a subclass can pass a valid reference to self
				throw new IllegalOperationError("Abstract class did not receive reference to self. MyAbstractType cannot be instantiated directly.");
			}
		}
	}
}

Only MyConcreteType and other subclasses of MyAbstractType will be able to pass a reference to the instance to their super() constructors. Notice that users of MyConcreteType don’t need to know that it extends an abstract class. The signature of the MyConcreteType’s constructor can be completely different than MyAbstractType.

package com.joshtynjala.abstract
{
	public class MyConcreteType extends MyAbstractType
	{
		public function MyConcreteType()
		{
			//pass "this" to clear the abstract check
			super(this);
		}
	}
}

Forcing Implementation of Functions in Subclasses

Next, like with an interface, we need to force subclasses of our abstract class to implement specific functions. Ideally, we want this enforcement to happen immediately when the object is created (to make bugs visible as early as possible). After we check that the user isn’t trying to instantiate the abstract class directly, we should check to be sure the unimplemented methods are overridden. We can do by checking the results from the flash.utils.describeType() function against a list of unimplemented methods in the abstract class. Again, a little code should give us a clearer picture.

In MyAbstractType, after we check for a reference to the self parameter, we build a list of unimplemented functions in an Array. Next, we use describeType() to get a list of the methods declared in the instance. If a subclass of MyAbstractType overrides a method, the declaredBy attribute in the method XML will specify the name of the subclass rather than MyAbstractType.

package com.joshtynjala.abstract
{
	import flash.errors.IllegalOperationError;
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;

	public class MyAbstractType
	{
		public function MyAbstractType(self:MyAbstractType)
		{
			if(self != this)
			{
				//only a subclass can pass a valid reference to self
				throw new IllegalOperationError("Abstract class did not receive reference to self. MyAbstractType cannot be instantiated directly.");
			}

			//these functions MUST be implemented in subclasses
			var unimplemented:Array = [mustBeOverridden];

			//get the fully-qualified name the abstract class
			var abstractTypeName:String = getQualifiedClassName(MyAbstractType);

			//get a list of all the methods declared by the abstract class
			//if a subclass overrides a function, declaredBy will contain the subclass name
			var selfDescription:XML = describeType(this);
			var methods:XMLList = selfDescription.method.(@declaredBy == abstractTypeName && unimplemented.indexOf(this[@name]) >= 0);

			if(methods.length() > 0)
			{
				//we'll only get here if the function is still unimplemented
				var concreteTypeName:String = getQualifiedClassName(this);
				throw new IllegalOperationError("Function " + methods[0].@name + " from abstract class " + abstractTypeName + " has not been implemented by subclass " + concreteTypeName);
			}
		}

		//implemented
		public function alreadyImplemented():void
		{
			trace("Don't forget to list me in the Array of valid functions.");
		}

		//unimplemented
		public function mustBeOverridden(param:String):void {};
	}
}

Now, in MyConcreteType, we can implement the mustBeOverridden() function. If we do not, an error will be thrown. To be certain, try commenting out the implementation of mustBeOverridden() in MyConcreteClass. If you instantiate it, you will receive a runtime error.

package com.joshtynjala.abstract
{
	public class MyConcreteType extends MyAbstractType
	{
		public function MyConcreteType()
		{
			//pass "this" to clear the abstract check
			super(this);
		}

		//implemented
		override public function mustBeOverridden(param:String):void
		{
			trace("param:", param);
		}
	}
}

Conclusions

As you probably noticed, the first part of implementing an abstract class is very simple. Making the abstract class receive a reference to itself enforces subclassing, and it can be done in only a few lines of code. The second part, making an abstract class work like an interface, requires a lot more code, and it may be more prone to errors. You, as a developer, must remember to add all the unimplemented methods to the Array in the constructor. Additionally, if the class gets large, I can imagine that calling describeType() often enough could lead to performance problems. In most cases, as long as you keep your classes clean, it should work well. I highly recommend the subclass enforcement, but I wouldn’t be heartbroken if you feel that checking for unimplemented methods is overkill.

Source code for this tutorial is available for download. It includes all the code above plus an extra implementation (for comparison) of the “electronic device” example I described at the beginning. It’s all under the terms of the MIT license.

Frustration with accessibility in Flash and Flex

After adding accessibility support to some Flash components I’ve been developing recently, I wanted to give them a test drive. To my surprise, I discovered that Flex and Flash components that Adobe claims are accessible aren’t very usable in a screen reader environment. I have always pointed out to people who claim that Flash isn’t accessible that Flash Player supports screen readers, but it must be specifically enabled by the developer. Until I see better results (even from the official Flex components!), I will no longer make that argument.

I started my adventure by installing a trial of JAWS, the most popular screen reading software on the market. The trial will run for 40 minutes at a time, and if you restart your computer, the counter will reset and you can use it again. It’s a pretty decent solution for software developers who want to test their work. It gets kind of annoying to wait while my messenger and email programs start every time I restart my computer, but it’s better than paying $900-$1100 for a full version of JAWS.

Testing JAWS with Flex

My first test of JAWS is with a simple Flex project with a single TabBar component. I turn on accessibility for the TabBar with the creationComplete event, and I give the it three tabs, “Web”, “Images”, and “Local” (like you might see on a search engine). I start up my browser, but the screen reader doesn’t have much to read.

Flash Movie Start. Flash Movie End.

It seems Flash Player doesn’t fully support accessibility within Firefox. Unfortunate. I wonder if it’s a browser problem or Adobe’s problem? Annoyed, but still open-minded, I ran the SWF in IE instead. JAWS gave me much more information, but I found some bugs with the component almost immediately. Here’s what JAWS read to me.

Flash Movie Start. Web Tab. Active Tab. Images Tab. Tab. Local Tab. Tab. Flash Movie End.

It says “Tab” twice for every Tab that it encounters. Navigating around tabs in native Windows applications doesn’t give me that problem. It’s not a big deal, but I definitely got a good first taste of unpolished accessibility features. Next, I start testing keyboard navigation. I press the Down arrow key.

Images Tab. Tab.

So far, so good. The “Images” tab has been highlighted, but not yet selected. I press the spacebar to select the tab.

Space.

Hmmm… did it work? I can see that it did because the Tab is now selected, but a blind user only knows that they pressed the spacebar. Maybe screen readers just automatically assume that the default action is successful. Sounds potentially confusing. I’d hate to be a blind developer with buggy code. I press the Up arrow key to go back to the “Web” tab.

Web Tab. Active Tab. Images Tab. Tab. Local Tab. Tab.

Uh oh. That seems wrong. First, the behavior has changed. Instead of simply telling me that the “Web” tab has been highlighted, JAWS has decided to read off the full contents of the TabBar again. Moreover, the TabBar has the “Images” tab selected now, but the screen reader is still reporting that the “Web” tab is active. That single bug is bad enough to make TabBar completely unusable to a blind user.

I tried testing a couple more components from Flash and Flex. The most potentially embarrassing for Adobe is that I can’t seem to figure out how to press Flash CS3’s Button component. I can use the Tab key or the Down arrow to navigate between them, and JAWS will read the labels, but the spacebar won’t press them. Also, in a Windows operating system dialog, the screen reader will say “To activate, press spacebar” when a button is highlighted. Why isn’t this more consistent?

My conclusion from several tests is that the official Flash and Flex components are hardly worthy of the title “accessible”. That’s only half the battle, unfortunately. Actually trying to build a custom component that supports screen readers is even more frustrating.

Implementing Accessibility

It didn’t take me long to discover that Adobe implements accessibility for their components differently than the officially suggested methods. Outlined on the Flash CS3 Accessibility pages (by comparison, the Flex accessibility information on Adobe’s site is completely out of date), accessibility should be handled through the Accessibility panel or with the “accessibilityProperties” property on DisplayObject. It is of type flash.accessibility.AccessibilityProperties. It seems pretty straightforward to use, but I haven’t played with it much yet. Why? Well, it’s because Adobe doesn’t use it for their components, and I want to handle accessibility the way they did it.

If you look in flash.accessibility.* package in the Flex 2 LiveDocs, you’ll see two classes, AccessibilityProperties and the main Accessibility class. You might also notice that the mx.accessibility.* package doesn’t get listed at all. This package contains the accessibility implementations for each of the Flex components, like Button, List, ComboBox, TabBar and everything else. Not a big deal, I guess, but now I have to dig into my file system and open these classes directly to learn more about them. When I started exploring this area, I discovered some very strange things.

The base accessibility class in Flex is named mx.accessibility.AccImpl. The equivalent in Flash CS3 is fl.accessibility.AccImpl. All the concrete implementations, like ButtonAccImpl for the Button component or TabBarAccImpl for TabBar, extend this class. Here’s where things get intersting: AccImpl itself extends another class named flash.accessibility.AccessibilityImplementation. “But wait,” the observant reader says, “I don’t remember seeing that class in the flash.accessibility.* package when I checked the LiveDocs.” Me either. This has led me to a lot of frustration because the functions from this class that get overridden in classes like ButtonAccImpl aren’t explained very well.

Adobe has chosen to hide what appears to be the most important class for implementing accessibility in components from the rest of world. Both the Flash CS3 components and the Flex components use this class, so it must be useful and important. Why isn’t it documented? Is there some reason why I wouldn’t want to use this class in my own component framework?

Much to my dismay, I also discovered the following comment from the source code for the Flash CS3 accessibility classes:

Nivesh says: I don’t think we should document the constructors for the accessibility classes.

The reason he says that is because the user of the class isn’t supposed to instantiate the accessibility implementations directly with the constructor. Instead, there’s a static enableAccessibility() function that needs to be called. Unfortunately, from that comment alone, I can’t help but wonder what other documentation is missing from these classes. In my opinion, the documentation for accessibility is the worst I’ve seen from Adobe, and after a week of messing with their stuff, I sent in a very long feature request for “extensive documentation”, and I gave up on one of my projects until I can spend a lot more time studying screen readers and Flash Player. Nivesh, please don’t remove anything that might be useful. Developers using ActionScript 3 will look closely at Adobe’s work to help pick up best practices and ideas, and you can bet that we want to know problems you run into and learn about things that we aren’t supposed to do. Document, document, document.

How Adobe can improve accessibility in Flash and Flex

  1. Update the online documentation for Flex accessibility or remove it. Information for Flex 1.5 doesn’t help me much when Flex 3 is just around the corner.

  2. Give me a walkthrough or two about how to make a real component accessible. Go through it step by step as if I’m an absolute novice. The fact is, most developers using any language or environment don’t know anything about accessibility. Include information on common problems we might encounter when trying to build accessible components. I’d love to see information about how to develop an accessible component that has subcomponents that are already accessible. What if I want to use their default behavior? What if I want to ignore the default behavior completely?

  3. Adobe, if you’re going to use flash.accessibility.AccessibilityImplementation, you can bet that everyone else will want to use it too. Either stop hiding it, or stop using it because it’s not fair to us. Put this class in the documentation and describe it in detail. Walk through every single function available on this class, and explain exactly what these functions do, along with how and when they will be used by the screen reader.

  4. Make accessibility subjects more visible in the documentation. At the very least, try to work the subject in more often. Developers don’t think of accessibility because we don’t encounter it often enough. For instance, for every component in Flex, there’s a page in the docs that offers a short introduction, it might have a bit of source code, and it describes how the component works. Is there a description of how each component appears to screen readers on those pages? There should be.

If you made it this far, thanks for listening to me vent. Accessibility is very important, and the need for it will only become more important in time as laws get stronger. Based on my short experience trying to make Flash and Flex components accessible, I’m a little embarrassed by the obviously untested components from Flex and the difficulties of setting it all up myself. I’m no accessibility expert, though, so please add comments below if you know of some good tricks that I may have missed, or if you have any insights about the undocumented AccessibilityImplementation class. I’d love to find links to good resources for Flash accessibility too. If you’re an Adobe employee, please make sure my comments go to the appropriate audience within the company. I’d love to see improvements based on my troubles. Thanks!

Open Source Flex Component: ZoomFrame

In the spirit of open source and sharing, I plan to release several free Flex components within the coming months. These components I’ve built in my free time, often just for fun or because I thought they would be useful. The first component I’m releasing is named ZoomFrame. Basically, it wraps a frame (styled like any other Flex border) around any DisplayObject. This frame lets you zoom in and out of and align the object it wraps along any of the frame’s edges, corners, or directly in the center. For a better idea of how this component behaves, play with all the controls in the ZoomFrame component demo.

Screenshot of Zoom Frame Component Example

The idea for ZoomFrame simply popped into my head one night, and I spent a couple of hours implementing it and perfecting its behavior. This component isn’t complex, but due to its simplicity, I would highly recommend digging into the source code if you’re just getting started developing Flex components with ActionScript. Important core pieces for building a custom component are there:

  • Invalidation and validation of properties, size, and the display list.

  • Initializing default styles and a styleChanged() function.

The only thing missing is a createChildren() function because I do not need to add any children to the display list when the component first initializes.

Of course, full source code for ZoomFrame is available, and it’s under the MIT license, so feel free to use this component in both commercial and open source projects. Stay tuned. This is the first component of many I plan to release.

How to make your hot new RIA friendly to search engines

Imagine you’re building a cool new Rich Internet Application with Flex or maybe Silverlight. Now, you want search engines to be able to find that application. How do you do this? What special sauce needs to be added to your application to make it SEO-friendly? Should your SWFs or XAML files include special optimizations? Let’s explore.

Consider the following situation. You’re looking for an online word processor that supports bulleted lists. Seems like a reasonable user need. What is the top search engine result going to be? To be more specific, which of the following pages makes the most sense for the user to find first?

What’s the Best Search Result?

  1. The login screen for Google Docs. There’s a short description of the application, but it doesn’t say anything about bulleted lists on this page.

  2. A list of features available in Google Docs from the official site. This page will tell you that the application supports bulleted lists and provides you ways to get more information about the app.

  3. A review by a third-party that tells you a bit about the features in Google Docs, and compares it to other word processors. Again, this page will tell you that Google Docs supports bulleted lists and it should provide you many links to get more information about the app.

  4. A documentation page describing how to use bulleted lists in Google Docs.

Choice number one is mostly useless as the first result. What does a login screen tell you? It says, “You need to sign up for an account to use this mystery word processor. It may or may not have the feature you need.” Choice two, in my opinion is the best one, since it provides the answer, and it is most likely to provide leads to all sorts of useful information (including ways to sign up and login when you’re ready). The third choice would be a good one too, but Google would probably prefer one of their own pages to be number one. The fourth choice, the documentation page, is reasonable too. It gives you the answer you were looking for, but you might have to click a few links to find the app itself.

I should note that Google Docs is written in HTML and JavaScript, yet it is perfectly relevant to this discussion. In the example above, I searched for “online word processor bulleted lists” and I got several reviews of Google Docs on the first page. Google Docs itself was not in the top results. Interesting, don’t you think?

Let’s go a step further. What if your application doesn’t need authentication? If a complex user interface similar to Microsoft Word suddenly appears in your browser window, maybe with a loading screen or some whiz-bang animations, you’ll have a moment of complete confusion. Where do you start? Again, I say that it’s better for a potential user to see the list of features or some sort of sales pitch at this point. They’ll have to learn how to use this unexplained user interface before they even know that a feature they need is supported. I imagine that’s a poor investment, in many users’ opinions. They’ll probably leave pretty quickly if they don’t find bulleted lists within a couple clicks.

This leads to a closely-related argument. What’s so useful about that user interface to a search engine? Will a button for bulleted lists, hidden among other controls for formatting options, provide enough information to outweigh that third-party review about Google Docs? Unlikely. In fact, you might as well consider it useless for SEO. Ryan Stewart just posted about why Silverlight’s plain-text XAML isn’t more SEO-friendly than Flash’s binary SWF format for the exact same reason. To a search engine, the “semantic” content is what’s important. They don’t care about the presentation layer (is CSS very useful? only to catch people cheating the system). In this case, good semantic content for Google to offer to a crawler would be a page that tells their potential users about Google Docs and why they should use the application. People don’t specifically search for a page that has a button that says “bulleted list”, they want more detailed information.

Exposing Semantic Data

The feature list and documentation aren’t the only semantic data that one might want to expose for an RIA. Perhaps Google wants the documents created with Google Docs to be listed in search results. When a user finds a specific document, it could load directly into Google Docs. In another case, someone running an online directory of engineering consultants might want their listings available to search engines. Maybe they’d rather provide a rich user interface with all sorts of filtering and dynamic viewing options to visitors to help improve their experience using the list. The search engine should help them find the data they need, but the application greatly improves the way visitors can interact with it.

I mentioned the example of a directory because Adobe’s Ted Patrick wanted to create a listing of Flex consulting firms that is available in an application built with Flex. The aptly named Flex Directory is one of the more SEO-friendly applications running on Flash Player that I’ve encountered. If you load the app, and view the HTML page source, you’ll discover something very interesting. It’s the raw XML listing of company information, but there is no HTML declared and no SWF embedded in that data at all! To improve the experience for the search engine crawler, Ted found a way to load the data first, and place Flex Directory on top of it. The search engine will see the plain-text data, while the user will discover the user interface. The following line in the XML file is what makes it all happen.

<?xml-stylesheet type="text/xsl" href="http://directory.onflex.org/template002.xsl"?>

The browser’s capability of manipulating XML through XSL is the key. If you take a look at the XSL file, you’ll discover that Ted replaces the XML content with a very basic HTML page that embeds the Flex SWF file with SWFObject. He passes the page URL through FlashVars to the Flex application, and the app loads the raw XML without XSL manipulations, much like the search engine crawler.

var so = new SWFObject( "http://directory.onflex.org/template002.swf" , "fxtxsl" , "100%" , "100%" , "9" , "#191919");
so.addParam( "scale" , "noscale" );
so.addVariable("xmlurl", document.location );
so.useExpressInstall( "http://directory.onflex.org/expressinstall.swf" );
so.write( 'flexcontent' )

I imagine that it wouldn’t be too difficult to set up a similar method to load data into Silverlight or plain-jane AJAX applications. In all cases, a complex web application that works and looks nothing like a regular HTML document can easily be read and understood by a search engine designed to index those documents. Meanwhile, a user will discover a richer presentation that simple CSS can’t provide.