//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.core { /** * ComponentDescriptor is the base class for the UIComponentDescriptor class, * which encapsulates the information that you specified in an MXML tag * for an instance of a visual component. * In Flex, non-visual components are treated differently and do not * have descriptors, but in a future version the ComponentDescriptor * base class may be used for them as well. * *

Most of the tags in an MXML file describe a tree of UIComponent objects. * For example, the <mx:Application> tag represents a * UIComponent object, and its child containers and controls are all * UIComponent objects.

* *

The MXML compiler compiles each of these MXML tags into a * UIComponentDescriptor instance. * To be precise, the MXML compiler autogenerates an ActionScript * data structure which is a tree of UIComponentDescriptor objects.

* *

At runtime, the createComponentsFromDescriptors() method * of the Container class uses the information in the UIComponentDescriptor * objects in the container's childDescriptors array to create * the actual UIComponent objects that are the container's children, * plus deeper descendants as well. * Depending on the value of the container's creationPolicy, * property, the descendants might be created at application startup, * when some part of the component is about to become visible, * or when the application developer manually calls * the createComponentsFromDescriptors() method.

* *

You do not typically create ComponentDescriptor or UIComponentDescriptor * instances yourself; you can access the ones that the MXML compiler * autogenerates, via the childDescriptors array * of the Container class.

* * @see mx.core.UIComponentDescriptor * @see mx.core.Container#childDescriptors * @see mx.core.Container#creationPolicy * @see mx.core.Container#createComponentsFromDescriptors() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class ComponentDescriptor { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @param descriptorProperties An Object containing name/value pairs * for the properties of the ComponentDescriptor object, such as its * type, id, propertiesFactory * and events. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function ComponentDescriptor(descriptorProperties:Object) { super(); for (var p:String in descriptorProperties) { this[p] = descriptorProperties[p]; } } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // document //---------------------------------- /** * A reference to the document Object in which the component * is to be created. * * @see mx.core.IUIComponent#document * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var document:Object; //---------------------------------- // events //---------------------------------- /** * An Object containing name/value pairs for the component's * event handlers, as specified in MXML. * *

For example, if you write

* *
     *  <mx:DataGrid id="dg" initialize="fetchData(); initDataGrid();"  change="changeHandler(event);"/>
     *  
* *

then the descriptor's events property is the Object

* *
     *  { initialize: "__dg_initialize", change: "__dg_change" }
     *  
* *

The eventproperty is null * if no MXML event handlers were specified for the component

* *

The strings "__dg_initialize" * and "__dg_change" are the names of event handler * methods that the MXML compiler autogenerates. * The body of these methods contain the ActionScript statements * that you specified as the values of the event attributes. * For example, the autogenerated initialize handler is

* *
     *  public function __dg_initialize(event:mx.events.FlexEvent):void
     *  {
     *      fetchData();
     *      initDataGrid();
     *  }
     *  
* *

You should not assume that the autogenerated event handlers * will always be specified by name; this may change in a future * version of Flex.

* *

This property is used by the Container method * createComponentsFromDescriptors() * to register the autogenerated event handlers * using the addEventListener() method.

* * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var events:Object; //---------------------------------- // id //---------------------------------- /** * The identifier for the component, as specified in MXML. * *

For example, if you write

* *
     *  <mx:TextInput id="firstName" text="Enter your first name here"/>
     *  
* *

then the descriptor's id property is the String * "firstName".

* *

The id property is null * if no MXML id was specified for the component.

* *

The value of the id property becomes the name * of a public variable in the MXML document object, * autogenerated by the MXML compiler. * The value of this variable is a reference to the UIComponent object * created from this descriptor. * This is why you can, for example, reference the TextInput control's * text property as firstName.text * from anywhere within the document containing this TextInput instance.

* *

If an id is specified, and it isn't the empty string, * it also becomes the name of the DisplayObject object. * If an id is not specified or is empty, the DisplayObject * object's name remains an autogenerated string, * such as "Button3", as returned by the * NameUtil.createUniqueName() method. * The name is used in generating the string returned * by the toString() method. * It can also be used to find the component from its parent * by calling getChildByName().

* * @see flash.display.DisplayObject#name * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var id:String; //---------------------------------- // properties //---------------------------------- /** * @private */ private var _properties:Object; /** * An Object containing name/value pairs for the component's properties, * as specified in MXML. * *

For example, if you write

* *
     *  <mx:TextInput width="150" text="Hello"/>
     *  
* *

then the descriptor's properties property * is the Object

* *
     *  { width: 150, text: "Hello" }
     *  
* *

The properties property is null * if no MXML properties were specified for the component. * In this case, the component will use default property values.

* *

This Object is produced by calling the function specified by the * propertiesFactory property, and then cached * for subsequent access. * However, when a Repeater produces multiple instances of a component * from the same descriptor, a fresh copy of the properties * Object should be produced for each component instance so that they * don't share property values which are Arrays or Object references. * The Repeater accomplishes this by calling the * invalidateProperties() method on the descriptor.

* * @see #propertiesFactory * @see #invalidateProperties() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get properties():Object { if (_properties) return _properties; if (propertiesFactory != null) _properties = propertiesFactory.call(document); // Propagate the 'document' property, set by the MXML compiler // on the document descriptor, down to all descendant descriptors. if (_properties) { var cd:Array = _properties.childDescriptors; if (cd) { var n:int = cd.length; for (var i:int = 0; i < n; i++) { cd[i].document = document; } } } else { _properties = {}; } return _properties; } //---------------------------------- // propertiesFactory //---------------------------------- /** * A Function that returns an Object containing name/value pairs * for the component's properties, as specified in MXML. * *

For example, if you write

* *
     *  <mx:TextInput width="150" text="Hello">
     *  
* *

then the descriptor's propertiesFactory property * is the Function:

* *
     *  function():Object { return { width: 150, text: "Hello" }; }
     *  
* *

The propertiesFactoryproperty is null * if no MXML properties were specified for the component. * In this case, the component will use default property values.

* *

The reason that propertyFactory is a * Function returning an Object rather than an actual Object * is to allow the tree of ComponentDescriptor objects * to "unfold" incrementally. * If all the descriptors in the descriptor tree for the document * were created at launch time, the time to launch would be greater.

* *

The properties property returns a cached Object * that was produced by this factory function.

* *

Note: Event handlers such as click="doSomething();" * appear in the events Object, * not in the properties Object.

* * @see #properties * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var propertiesFactory:Function; //---------------------------------- // type //---------------------------------- /** * The Class of the component, as specified in MXML. * *

For example, if you write

* *
     *  <mx:TextInput/>
     *  
* *

then the descriptor's type property * the Class mx.controls.TextInput.

* *

The property is never null for the * ComponentDescriptor objects created by the MXML compiler, * because every MXML tag has a tag name such as mx:TextInput.

* *

The mapping between an MXML tag and its corresponding class * is determined by the XML namespace and the "manifest" file, * if any, that is associated with that namespace. * For example, the standard Flex namespace * http://www.adobe.com/2006/mxml * represented by the mx: prefix is associated (in the flex-config.xml * file) with the manifest file mxml-manifest.xml, * and this file has the tag

* *
     *  <component id="TextInput" class="mx.controls.TextInput"/>
     *  
* *

which maps the tag name mx:TextInput * to the Class mx.controls.TextInput. * Note that the use of a manifest file allows components in single * XML namespace to map to classes in multiple ActionScript packages.

* * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var type:Class; //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * Invalidates the cached properties property. * The next time you read the properties property, * the properties are regenerated from the function specified by the * value of the propertiesFactory property. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function invalidateProperties():void { _properties = null; } /** * Returns the string "ComponentDescriptor_" plus the value of the * id property. * * @return The string "ComponentDescriptor_" plus the value of the * id property. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function toString():String { return "ComponentDescriptor_" + id; } } }