Packagecom.actiontad.javascript
Classpublic class DOMEx

DOMEx

Document Object Model External Interface use and other useful JavaScript support.

Author Tad Green

An ActionScript 3.0 Class, suitable for Flex, pure ActionScript, or as part of a Document Class.
Just about all methods use the ExternalInterface. It is wise to be sure that javaScript is ready in the DOM before making DOMEx or ExternalInterface calls.
You can do so via javaScript by waiting for the onload event of the body before giving the page the swf object.
Or by setting up a callback and Timer to get and wait for onload information from javaScript.
Or by placing the swf object as the very last thing on the page before the end of the body tag.
Or by being sure the swf is the last thing that gets loaded on the page.

Please also see the comments in sampleUsage.as for more info. (included in the zip)



This class uses JavaScript stored in XML variables to do things on the DOM.
    var myJavaScriptXML:XML = 
    <script>
    <![CDATA[
    function () {
      alert("javascript inside actionscript");
    }
    ]]>
    </script>;
    ExternalInterface.call(myJavaScriptXML);
    

This zip file contains this documentation, the DOMEx.as Class file, and sampleUsage files:
www.actiontad.com/DOMEx/DOMEx.zip

I've tried to make this documentation very helpful, please read it over before using the class. - Tad



Public Properties
 PropertyDefined by
  a : Boolean
[static][read-only] static read-only variable that returns wheather or not the external interface is available
DOMEx
  blankTheWindowStatus : XML
[static] A JavaScript function in XML that can be used to clear the browser window status.
DOMEx
  getHash : XML
[static] A JavaScript function in XML that can be used to retreve the current browser location hash value.
If there is no hash the JavaScript will return an empty string.
DOMEx
  marshall : Boolean
[static] marshallExceptions switcher with a test for if available.
If not available or marshallExceptions is false returns false otherwise true.
read-write
DOMEx
  objectID : String
[static][read-only] Same as the ExternalInterface.objectID except also tests for if available.
If the ExternalInterface is not available this will return an empty string.
read-only

note: via the idGet method you can specify which objects id to get, by tag index.
DOMEx
  statChange : XML
[static][read-only] read-only variable statChange

JavaScript in XML used to change the browser window status.

DOMEx
Public Methods
 MethodDefined by
  
DOMEx(object:* = null)
The constructor only needs to be used when setting up a javaScript to swf public function invoker.
DOMEx
  
addCall(callBack:String, callBackFunction:Function):Boolean
[static] Adds a ExternalInterface callback if possible.
DOMEx
  
alert(thiser:String):void
[static] Alerts a string via the browser, if possible.
DOMEx
  
appendTextTo(anElement:String, theText:String, how:String = "byId", elementNumber:Number = 0):Boolean
[static] Appends text to an html element.
DOMEx
  
call(toCall:*, ... args):*
[static] Same as normal ExternalInterface.call, except a test for if the ExternalInterface is available is also done.
DOMEx
  
eget(fromThis:*, ... args):*
[static] Same as external interface call but also checks for if available.
DOMEx
  
idGet(index:Number = 0):*
[static] Attempts to get the id of the swf object (by tag index) that is in the wrapper.
DOMEx
  
invokeViaJavaScript(publicMethodName:*, ... args):*
The only non-static method.
DOMEx
  
makeJavaScript(innerBody:String):XML
[static] JavaScript XML Variable Creation Method

You can use simple javaScript commands such as "alert('hello world')"
Or full functions with paramaters.

DOMEx
  
makeMasterTalk(nameToBe:String = null, funcIs:String = null, idIs:String = null):void
[static] A useful function that assigns a chosen javaScript function name (on the DOM)
to an external callBack function you have already set up.
The resulting javaScript function acts as if it is the Actionscript callBack method itself.

Versus having to manually script for the swf file object then call the callBack as follows:
document.getElementById(mySWFfileId).callBackFunctionName(args); //this way does not always work to refernce the swf file.

Instead, using the makeMasterTalk function makes it possible to simply call:
choosenNameForTheCallBackCall(...args) in your wrapper to invoke the callBack.
note: The function that is set up for you by makeMasterTalk works 90% of the time.

DOMEx
  
resizeMakeAbleHorizontal(elements:String):Boolean
[static] Makes one kind of html element horizontally resizeable (cross-browser).

Resizability is signified by a hand curcor at about the last 90% of the element and a title of "drag to resize" when the pointer cursor is active.

DOMEx
  
updateInnerHTML(actualElement:String, theString:String, how:String = "byId", elementNumber:Number = 0, replaceIt:Boolean = false):Boolean
[static] Updates or replaces the innerHTML of an element.
DOMEx
Property detail
aproperty
a:Boolean  [read-only]

static read-only variable that returns wheather or not the external interface is available

Implementation
    public static function get a():Boolean
blankTheWindowStatusproperty 
public static var blankTheWindowStatus:XML

A JavaScript function in XML that can be used to clear the browser window status.

See also


Example
 DOMEx.call(DOMEx.blankTheWindowStatus); 

getHashproperty 
public static var getHash:XML

A JavaScript function in XML that can be used to retreve the current browser location hash value.
If there is no hash the JavaScript will return an empty string.

See also


Example
 var theHash:String = DOMEx.eget(DOMEx.getHash); 

marshallproperty 
marshall:Boolean  [read-write]

marshallExceptions switcher with a test for if available.
If not available or marshallExceptions is false returns false otherwise true.
read-write

Implementation
    public static function get marshall():Boolean
    public function set marshall(value:Boolean):void
objectIDproperty 
objectID:String  [read-only]

Same as the ExternalInterface.objectID except also tests for if available.
If the ExternalInterface is not available this will return an empty string.
read-only

note: via the idGet method you can specify which objects id to get, by tag index.

Implementation
    public static function get objectID():String

See also

statChangeproperty 
statChange:XML  [read-only]

read-only variable statChange

JavaScript in XML used to change the browser window status.

Implementation
    public static function get statChange():XML

Example
DOMEx.call(DOMEx.statChange, "statusString");

Constructor detail
DOMEx()constructor
public function DOMEx(object:* = null)

The constructor only needs to be used when setting up a javaScript to swf public function invoker.

Parameters
object:* (default = null) — The DisplayObject with public methods/properties you want made available to the wrapper.

See also

Method detail
addCall()method
public static function addCall(callBack:String, callBackFunction:Function):Boolean

Adds a ExternalInterface callback if possible.

Parameters
callBack:String — The callback to add.
 
callBackFunction:Function — The function to associate with the callback.

Returns
Boolean — Returns true if the callback was added. false otherwise.
alert()method 
public static function alert(thiser:String):void

Alerts a string via the browser, if possible. If the ExternalInterface is available.

Parameters
thiser:String — The string to alert.
appendTextTo()method 
public static function appendTextTo(anElement:String, theText:String, how:String = "byId", elementNumber:Number = 0):Boolean

Appends text to an html element.

You can specify how to get the element, by ID or by Tag Name, if by Tag Name last param is which Tag index.

Special Errors:
Alerts DOM errors via the wrapper.

If the ExternalInterface is not available this method just returns false.

Parameters
anElement:String — The html element to append text to. either its ID or TagName.
 
theText:String — The text to append.
 
how:String (default = "byId") — The way to reference the element, "byID" or "byTagName"
 
elementNumber:Number (default = 0) — If how is "byTagName", then you can specify its tag index. Default is 0.

Returns
Boolean — Returns true if the ExternalInterface call was made.

Example

DOMEx.appendTextTo("elementsID", "textToAdd"); //by ID
DOMEx.appendTextTo("elementsTagName", "textToAdd", "byTagName", 0); //by tag name

call()method 
public static function call(toCall:*, ... args):*

Same as normal ExternalInterface.call, except a test for if the ExternalInterface is available is also done. If not available, nothing happens.
This function is surrounded by a try catch, to catch any marshelled exceptions.
eget is not. That's their only difference.

Parameters
toCall:* — The JavaScript to be called.
 
... args — Any optional args for the call.

Returns
* — The result of the call if any.

See also

eget()method 
public static function eget(fromThis:*, ... args):*

Same as external interface call but also checks for if available.

Parameters
fromThis:* — The javaScript to call.
 
... args — Any optional args for the call.

Returns
* — The result of the call if any.

See also

idGet()method 
public static function idGet(index:Number = 0):*

Attempts to get the id of the swf object (by tag index) that is in the wrapper. (cross-browser)

Parameters
index:Number (default = 0) — The tag index number of the swf object.
If it is the first or only swf object, the index is 0, which is the default.

Returns
* — The id of the specified swf object element in the html wrapper, an empty string if no id found, or undefined if no external interface.

Example
var swfsId:String = DOMEx.idGet();
Or if the swf object you want to get the id of is not the first:
(example html)
<object type="application/x-shockwave-flash"....></object>
<div> some content </div>
<object type="application/x-shockwave-flash"....></object>
<div> more content </div>
<object type="application/x-shockwave-flash"....></object>
...
If we want to target the middle swf object of the above example:
var swfsId:String = DOMEx.idGet(1);

invokeViaJavaScript()method 
public function invokeViaJavaScript(publicMethodName:*, ... args):*

The only non-static method. Needs the DisplayObject instance
(the one with the public methods/variables you wish to call/get/set) passed to an instantiated DOMEx.

Used to create a javaScript to swf public function invoker/variable getter and setter.

Use this as the function you make a master talk of, and you will be able to call any public function in the swf via javaScript in the wrapper.
You will also have the ability to get public variables from the swf, and set public variables in the swf.
This method can also be used to invoke any function, when used inside the swf, but its purpose is for javaScript to swf communication.

Setup is a three step proccess.
See the examples below.


Special Errors: Attempts to catch any errors and alerts them via the wrapper.

Parameters
publicMethodName:* — The name of the public method/property in the swf to call/get/set.
 
... args — Any optional comma separated args for the call.

Returns
*

See also


Example

One: A public method or property in the swf to be called by javaScript:
//public getter assignment:
public function get getterNameYoullCall():Function {
   
   return ActualFunction;
}
private function ActualFunction(...args):*
{
     //things to do in the swf
}

// and/or just plain getters:
      
private var myVar:Boolean = true;
public function get avar():Boolean { return myVar; }
      
    
//and plain public vars:
    
public var someArray:Array = [1,2,3];
       
           
//and public setters:
       
public function set myArray(toThis:Array):void
{
      someArray = toThis;
      someArray.push("setter magic");
}
     
public function get myArray():Array
{
       return someArray;
}
     
// and/or just plain public functions:
      
public function functionNameYoullCall(...args):*
{
      
       //things to do in the swf

}
         
public function addThese(numOne:Number, numTwo:Number):Number
{
       return numOne + numTwo;
}
Two: A callBack for invokeViaJavScript is established:
DOMEx.addCall("callForFunction", new DOMEx(this).invokeViaJavScript);
Three: callBack made Level 1 masterTalkable:
DOMEx.makeMasterTalk("masterFunctionName", "callForFunction", DOMEx.idGet());
note: your swf must have an id.


Then, to invoke the public function from javaScript and pass it any args:

masterFunctionName("functionNameYoullCall", ...args);


To get the value of a public var:

alert(masterFunctionName("someArray")[2]); //would alert "3"


To set the value of a public var you need to use "=" in the middle and only pass three args:

masterFunctionName("someArray", "=", ["cat", "dog", "mouse"]);

alert(masterFunctionName("someArray")); //would alert "cat,dog,mouse"



Setters, just the same:

masterFunctionName("myArray", "=", [3, 2, 1]);
alert(masterFunctionName("someArray")); //would alert "3,2,1,setter magic";



Use of a method that takes args and returns something:

alert(masterFunctionName("addThese", 7, 3)); //would alert "10"


makeJavaScript()method 
public static function makeJavaScript(innerBody:String):XML

JavaScript XML Variable Creation Method

You can use simple javaScript commands such as "alert('hello world')"
Or full functions with paramaters. See the examples below.

Parameters
innerBody:String — The actual JavaScript code as a string.

Returns
XML — JavaScript in XML ready to be called.

Throws
— An error if your javaScript function has a name and is not in the correct format,
must have () and at least one param.

Example
var myFunction:String = 
  "function changeinners(arg1, arg2) {document.getElementById(arg1).innerHTML=arg2;}"

Named functions must be in function name(arg, arg, arg) format and have at least one arg.
note: saying just - "function () {...}" without a name does not require args.

This method is used to create callable javaScript as follows:

var myJavascript:XML = DOMEx.makeJavaScript(myFunction);
DOMEx.call(myJavaScript, "divID", "<div>html content</div>");

makeMasterTalk()method 
public static function makeMasterTalk(nameToBe:String = null, funcIs:String = null, idIs:String = null):void

A useful function that assigns a chosen javaScript function name (on the DOM)
to an external callBack function you have already set up.
The resulting javaScript function acts as if it is the Actionscript callBack method itself.

Versus having to manually script for the swf file object then call the callBack as follows:
document.getElementById(mySWFfileId).callBackFunctionName(args); //this way does not always work to refernce the swf file.

Instead, using the makeMasterTalk function makes it possible to simply call:
choosenNameForTheCallBackCall(...args) in your wrapper to invoke the callBack.
note: The function that is set up for you by makeMasterTalk works 90% of the time. (just not IE Mac)
A javaScript file named MasterTalk.js is included in the zip for your reference.


The value of this method is that the only thing needed for use of a DOM based swf
that communicates back and forth with a javaScript enabled DOM based wrapper,
is this class, and to embed the swf with an id.

After you assign a function it can be called from both the wrapper and from your swf:
DOMEx.call(choosenNameForTheCallBackCall, args);
Doing such a thing would be like calling a function within, from without, but within !?
There may be times when you want to do that.
Perhaps if the choosen name is passed in by flashvars or in some other way user controlled.


Makes: A javaScript function of the name you choose,
or a javaScript function named "masterTalk" if no name is passed.
Also, marshallExpections will automatically be set to true.
note: to make it false declare DOMEx.marshall = false; after the makeMasterTalk call

Special Errors: If the name you want already has a value in the DOM (is not undefined),
a javaScript alert will alert you of the situation.
The makeMasterTalk function will not create a javaScript function with a name that is not undefined,
please see the examples.

Parameters

nameToBe:String (default = null) — The name you want for the javaScript function.
 
funcIs:String (default = null) — The callBack name.
 
idIs:String (default = null) — The (wrappers object id attribute) id of the swf.

Throws
— An error is thrown if the parameters are not in the correct order, you can't do null,not null,null

See also


Example

Level 1:
Pass all three params to makeMasterTalk, and the javaScript function created in the DOM
will be pretty much just as good as the actual ActionScript function:

In the swf:
if(DOMEx.addCall("callBacksName", myActionScriptFunction))
DOMEx.makeMasterTalk("nameYouWant", "callBacksName", "swfsID"); //you can use DOMEx.idGet() to get the id
private function myActionScriptFunction(...optional args):*{
   //do something in the swf
}

Then, in the wrappers javaScript:

nameYouWant(...optional args); //now this is just like calling myActionScriptFunction in the swf


Level 2:
Pass the name you want and the callback name, leaving off the id; and the javaScript function will still
be tied to the one callback but will be able to take a variable ID (and must be passed an ID as the first arg)

In the swf:
if(DOMEx.addCall("callBacksName", myActionScriptFunction))
DOMEx.makeMasterTalk("nameYouWant", "callbacksName"); //id left out

Then in the javascript you would need to do:

nameYouWant("swfsID", ... optional args for callback method);//id required as first arg

Level 2 would be used in situations where multiple swfs on the same page
register the same callback name. You would just change the id to invoke the callback per swf.

Level 3
Pass only the name you want, and the resulting javaScript function will be able to call any
callback from any swf on the page.
if(DOMEx.addCall("callBacksName", myActionScriptFunction))
DOMEx.makeMasterTalk("nameYouWant");//id and callback name left out

Then in the javaScript you must pass the swfs id and callBack name:

nameYouWant("swfsID", "callBacksName", ... optional args for the callback); //id and callback required first
//notice you will be able to call any callback



Level 4 is when you just call makeMasterTalk() with no params.
It is the same as level 3, but the javaScript function created will have the name "masterTalk"


The makeMasterTalk DOM Error:
If you try to use a name that is already defined in the DOM the makeMasterTalk function will catch that and a javaScript alert box will show you the name in conflict.
Example:

function doSomething()
{
//something
}
If the above is already in the DOM and we try:
makeMasterTalk("doSomething" ...)

During run time in a browser, an alert box would alert the "doSomething" name conflict
and a master talk is not created for that name.
Any ActionScript code would continue, no ActionScript error is thrown.

Strict setup:
The way you should set up the name you want in the DOM is as follows:

var nameYouWant;
var nameYouWantDone;


That creates an undefined variable in the DOM that is ready to have a master talk applied to it.
The "Done" variable is created after the mastertalk is applied to help ensure that a rewrite does not happen.

If you don't set up the vars a strict error happens - assignment to an undeclared var.
But, it's not required for you to do this, however, it is best practice.

resizeMakeAbleHorizontal()method 
public static function resizeMakeAbleHorizontal(elements:String):Boolean

Makes one kind of html element horizontally resizeable (cross-browser).

Resizability is signified by a hand curcor at about the last 90% of the element and a title of "drag to resize" when the pointer cursor is active. The elements that are having this applied should not already have a title.


Special Errors:
Alerts an error in the wrapper if there are no elements of the type you specified.

If the ExternalInterface is not available this method just returns false.

Parameters
elements:String — The kind of element you want to make horizontally resizable: "div", "pre", "table" ect.

Returns
Boolean — Returns true if the external interface call was made.

Example

DOMEx.resizeMakeAbleHorizontal("pre"); //makes all pres in the wrapper horizontally resizeable.

updateInnerHTML()method 
public static function updateInnerHTML(actualElement:String, theString:String, how:String = "byId", elementNumber:Number = 0, replaceIt:Boolean = false):Boolean

Updates or replaces the innerHTML of an element.

This function should not be used until the DOM is fully loaded.
You can specify how to reference the element, by ID or by Tag Name.
If by Tag Name the second to last param is the Tag index.
The last param is a boolean for if replace or not.


Special Errors:
Alerts DOM errors via the wrapper.

If the ExternalInterface is not avialable this method just returns false.

Parameters
actualElement:String — The id or tagname of the element.
 
theString:String — The string of html or text.
 
how:String (default = "byId") — How to reference the element, "byId" (default) or "byTagName"
 
elementNumber:Number (default = 0) — If how is "byTagName" use this to specify which tag index.
 
replaceIt:Boolean (default = false) — Specifies whether or not to replace the innerHTML, true, or just add to it, false (default)

Returns
Boolean — Returns true if the ExternalInterface call was made.

Example

//updates the innerHTML of an element by ID:
DOMEx.updateInnerHTML("elementsID", "<div>some html</div>"); 

//replaces the innerHTML of the element by tag name that is at tag index 2:
DOMEx.updateInnerHTML("elemntsTagName", "<div>html</div>", "byTagName", 2, true);