The AIR 1.5 Cookbook contains many useful recipes. I want to take some time to highlight some of the useful (and cool) recipes that are included in the book.
You can order your copy of the AIR 1.5 Cookbook from Amazon. You can also start to look for the book in your local bookstore over the next week.
The following ActionScript class accesses and manipulates the HTML DOM to dynamically change the elements of the HTML content that is loaded in an HTMLLoader object.
The class is a subclass of the Flex Framework’s UIComponent class and can, therefore, also be used in this environment:
package com.oreilly.aircookbook.ch5
{
import flash.events.Event;
import flash.html.HTMLLoader;
import flash.net.URLRequest;
import mx.core.UIComponent;
[Event(name="complete")]
public class AccessDOMElements extends UIComponent
{
private var _html:HTMLLoader;
public function AccessDOMElements()
{
super();
}
override protected function createChildren():void
{
_html = new HTMLLoader();
_html.width = 800;
_html.height = 600;
addChild(_html);
_html.addEventListener( Event.COMPLETE, onComplete );
}
override protected function measure():void
{
measuredWidth = 800;
measuredHeight= 600;
}
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
_html.width = unscaledWidth;
_html.height= unscaledHeight;
}
private function onComplete( event:Event ) : void
{
var newEvent:Event = new Event(Event.COMPLETE);
dispatchEvent( newEvent );
}
public function load( url:String ) : void
{
var request:URLRequest = new URLRequest(url);
_html.load(request);
}
public function htmlCodebyID():String
{
var htmlCode:String = _html.window.document.getElementById("container").innerHTML;
return htmlCode;
}
public function htmlCodebyTag():String
{
var htmlCode:Object = _html.window.document.getElementsByTagName("img");
var htmlStr:String;
if (htmlCode != null)
for (var i:Number = 0; i < htmlCode.length; i++)
{
if (htmlCode[i].getAttribute("class") == "logo")
{
htmlCode[i].src =
"http://livedocs.adobe.com/air/1/devappsflash/images/adobe.png";
htmlStr += htmlCode[i].src +"\n";
htmlStr += htmlCode[i].width +"\n";
htmlStr += htmlCode[i].height +"\n";
}
}
return htmlStr;
}
private function listElements(whichTag:String,
whichAttr:String="",
whichValue:String=""):Object
{
var startElement:Object = new Object();
var listElement_arr:Object= new Object();
if (whichTag) {
startElement =
_html.window.document.getElementsByTagName(whichTag);
} else {
startElement = (_html.window.document.all) ?
_html.window.document.all :
_html.window.document.getElementsByTagName("*");
}
if (whichAttr) {
for (var i:Number = 0; i < startElement.length; i++) {
if (startElement[i].getAttribute(whichAttr)) {
if (whichValue) {
if (startElement[i].getAttribute(whichAttr) ==
whichValue) {
listElement_arr[listElement_arr.length] =
startElement[i];
}
} else {
listElement_arr[listElement_arr.length] =
startElement[i];
}
}
}
} else {
listElement_arr= startElement;
}
return listElement_arr;
}
public function walkingTree(tagName:String):String
{
var DOMList:Object = listElements(tagName);
var walkingTreeList:String;
if (DOMList != null)
for (var i:Number = 0; i < DOMList.length; i++)
{
walkingTreeList += DOMList[i].innerHTML +"\n";
}
return walkingTreeList;
}
}
}
The AccessDOMElements class navigates through the DOM elements of the HTML page loaded into the HTMLLoader instance looking for an explicit image within the HTML code. Upon finding the image, the code switches to the new one.
The AccessDOMElements class has three public methods. The first, htmlCodebyID, is a public method and returns a String that contains HTML code in the tag that is specified by using the getElementById method.
The second public method, htmlCodebyTag, returns the HTML code contained in a certain HTML tag that is specified with the getElementsByTagName method. Furthermore, this method uses the DOM getAttribute method, which allows access to certain attributes of the selected node. That way, you are able to act on the single HTML element and change any of its values. With a loop, this function looks in all the img tags of the content, and when it verifies a condition on the attribute class of that tag, it changes its src attribute, loading a new image from a new pathway:
public function htmlCodebyTag():String
{
var htmlCode:Object = _html.window.document.getElementsByTagName("img");
var htmlStr:String;
if (htmlCode != null)
for (var i:Number = 0; i < htmlCode.length; i++)
{
if (htmlCode[i].getAttribute("class") == "logo")
{
htmlCode[i].src =
"http://livedocs.adobe.com/air/1/devappsflash/images/adobe.png";
htmlStr += htmlCode[i].src +"\n";
htmlStr += htmlCode[i].width +"\n";
htmlStr += htmlCode[i].height +"\n";
}
}
return htmlStr;
}
The third public function, walkingTree, returns the content of the HTML DOM elements that correspond to the search criteria; it returns the content with the innerHTML property. This criteria is specified in another method that is launched by the walking Tree: the private listElements method. The listElements method accepts three parameters:
whichTag (the name of the tag to point to), whichAttr (the attribute of the
specified tag to use), and whichValue (the value of the attribute to compare).
This method returns a collection of elements that verify the conditions of the parameters
sent to it. The property that is returned by the method is called listElement_arr. Even if in theory
this property contains an array of elements and if you assign them as data type Array,
the application will raise a Type coercion error:
Error #1034: Type Coercion failed: cannot convert __HTMLScriptObject@fb55b1 in
Array.
Instead, you must type the properties as Object classes that return the elements by using the getElementsByTagName method.
You can use the AccessDOMElements class in a simple MXML application that will then be packaged in AIR. You can use Flex Builder 3 as an environment to write the following code, or you can write it with any text editor and then compile it with the AIR adl command-line compiler (which you can find in the AIR SDK):
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">
<mx:Script>
<![CDATA[
private var list_arr:Array;
private function loadHTML():void
{
htmlComp.load("http://www.comtaste.com/en/training.htm");
}
]]>
</mx:Script>
<mx:TextArea width="800" height="300" id="myTA" />
<mx:HBox>
<mx:Button label="Show HTML Code" click="myTA.text =
htmlComp.htmlCodebyID()" />
<mx:Button label="Change Image" click="myTA.text =
htmlComp.htmlCodebyTag()" />
<mx:Label text="Insert the name of the Tag: " />
<mx:TextInput id="tagName" text="*" />
<mx:Button label="Navigate The DOM Tree by Tag"
click="myTA.text = htmlComp.walkingTree(tagName.text)" />
</mx:HBox>
<comp:AccessDOMElements xmlns:comp="com.oreilly.aircookbook.ch5.*"
id="htmlComp"
initialize="loadHTML()" />
</mx:WindowedApplication>
It is the AccessDOMElements component that creates the instance of the AccessDOMElements ActionScript class, created in the com.oreilly.aircookbook.ch5 package and associated to the namespace comp.
Once the AIR application has been compiled, it will load the content of the page http://www.comtaste.com/en/training.htm in the HTMLLoader object and will expose three buttons (Figure 5-2), which will launch the previously mentioned three public methods of the ActionScript class.
When the user inserts the name of an HTML tag in the TexInput, the walkingTree method will be called by clicking the Navigate button, and all the elements on the page that have been declared with that tag will be returned.
By clicking the Change Image button, the image of the Comtaste logo will be replaced with an image loaded from a remote source at the following URL: http://livedocs.adobe.com/air/1/devappsflash/images/adobe.png.
This exchange of images is made possible thanks to the htmlCodebyID method that accesses the DOM element with the img tag and verifies the following condition with the DOM getAttribute:
htmlCode[i].getAttribute("class") == "logo"
When the user inserts the name of an HTML tag in the TexInput, the walkingTree method will be called by clicking the Navigate button, and all the elements on the page that have been declared with that tag will be returned.
By clicking the Change Image button, the image of the Comtaste logo will be replaced with an image loaded from a remote source at the following URL: http://livedocs.adobe.com/air/1/devappsflash/images/adobe.png.
This exchange of images is made possible thanks to the htmlCodebyID method that accesses the DOM element with the img tag and verifies the following condition with the DOM getAttribute:
htmlCode[i].getAttribute("class") == "logo"
The ActionScript class created in this solution is tied to the Flex SDK. If, on the other hand, you want to use it in the Flash applications, you have to extend the Sprite class and delete all references to the Flex Framework (such as, for example, the [Event] or [Bindable] metatags).






















Comments