http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/states/AddItems.as ---------------------------------------------------------------------- diff --cc frameworks/projects/MX/src/main/flex/mx/states/AddItems.as index 3254346,0000000..b04e00e mode 100644,000000..100644 --- a/frameworks/projects/MX/src/main/flex/mx/states/AddItems.as +++ b/frameworks/projects/MX/src/main/flex/mx/states/AddItems.as @@@ -1,1205 -1,0 +1,1205 @@@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.states +{ - COMPILE::AS3 ++COMPILE::SWF +{ + import flash.display.DisplayObject; +} +COMPILE::JS +{ + import flex.display.DisplayObject; +} +import org.apache.flex.events.Event; +import org.apache.flex.events.IEventDispatcher; + +import mx.binding.BindingManager; +import mx.collections.IList; +import mx.core.ContainerCreationPolicy; +import mx.core.IChildList; +import mx.core.IDeferredContentOwner; +import mx.core.IMXMLObject; +import mx.core.ITransientDeferredInstance; +import mx.core.IUIComponent; +import org.apache.flex.core.IVisualElement; +import mx.core.IVisualElementContainer; +import mx.core.UIComponent; + +[DefaultProperty("itemsFactory")] + +/** + * Documentation is not currently available. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ +public class AddItems extends OverrideBase implements IMXMLObject +{ + include "../core/Version.as"; + + //-------------------------------------------------------------------------- + // + // Class Constants + // + //-------------------------------------------------------------------------- + + /** + * Documentation is not currently available. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public static const FIRST:String = "first"; + + /** + * Documentation is not currently available. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public static const LAST:String = "last"; + + /** + * Documentation is not currently available. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public static const BEFORE:String = "before"; + + /** + * Documentation is not currently available. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public static const AFTER:String = "after"; + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Constructor. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function AddItems() + { + super(); + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + private var document:Object; + + /** + * @private + */ + private var added:Boolean = false; + + /** + * @private + */ + private var startIndex:int; + + /** + * @private + */ + private var numAdded:int; + + /** + * @private + */ + private var instanceCreated:Boolean = false; + + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + //------------------------------------ + // creationPolicy + //------------------------------------ + + /** + * @private + * Storage for the creationPolicy property. + */ + private var _creationPolicy:String = ContainerCreationPolicy.AUTO; + + [Inspectable(category="General")] + + /** + * The creation policy for the items. + * This property determines when the <code>itemsFactory</code> will create + * the instance of the items. + * Flex uses this property only if you specify an <code>itemsFactory</code> property. + * The following values are valid: + * + * <p></p> + * <table class="innertable"> + * <tr><th>Value</th><th>Meaning</th></tr> + * <tr><td><code>auto</code></td><td>(default)Create the instance the + * first time it is needed.</td></tr> + * <tr><td><code>all</code></td><td>Create the instance when the + * application started up.</td></tr> + * <tr><td><code>none</code></td><td>Do not automatically create the instance. + * You must call the <code>createInstance()</code> method to create + * the instance.</td></tr> + * </table> + * + * @default "auto" + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function get creationPolicy():String + { + return _creationPolicy; + } + + /** + * @private + */ + public function set creationPolicy(value:String):void + { + _creationPolicy = value; + + if (_creationPolicy == ContainerCreationPolicy.ALL) + createInstance(); + } + + //------------------------------------ + // destructionPolicy + //------------------------------------ + + /** + * @private + * Storage for the destructionPolicy property. + */ + private var _destructionPolicy:String = "never"; + + [Inspectable(category="General")] + + /** + * The destruction policy for the items. + * This property determines when the <code>itemsFactory</code> will destroy + * the deferred instances it manages. By default once instantiated, all + * instances are cached (destruction policy of 'never'). + * Flex uses this property only if you specify an <code>itemsFactory</code> property. + * The following values are valid: + * + * <p></p> + * <table class="innertable"> + * <tr><th>Value</th><th>Meaning</th></tr> + * <tr><td><code>never</code></td><td>(default)Once created never destroy + * the instance.</td></tr> + * <tr><td><code>auto</code></td><td>Destroy the instance when the override + * no longer applies.</td></tr> + * </table> + * + * @default "never" + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function get destructionPolicy():String + { + return _destructionPolicy; + } + + /** + * @private + */ + public function set destructionPolicy(value:String):void + { + _destructionPolicy = value; + } + + //------------------------------------ + // destination + //------------------------------------ + + /** + * The object relative to which the child is added. This property is used + * in conjunction with the <code>position</code> property. + * This property is optional; if + * you omit it, Flex uses the immediate parent of the <code>State</code> + * object, that is, the component that has the <code>states</code> + * property, or <code><mx:states></code>tag that specifies the State + * object. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public var destination:Object; + + //------------------------------------ + // items + //------------------------------------ + + /** + * @private + * Storage for the items property + */ + private var _items:*; + + [Inspectable(category="General")] + + /** + * + * The items to be added. + * If you set this property, the items are created at app startup. + * Setting this property is equivalent to setting a <code>itemsFactory</code> + * property with a <code>creationPolicy</code> of <code>"all"</code>. + * + * <p>Do not set this property if you set the <code>itemsFactory</code> + * property.</p> + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function get items():* + { + if (!_items && creationPolicy != ContainerCreationPolicy.NONE) + createInstance(); + + return _items; + } + + /** + * @private + */ + public function set items(value:*):void + { + _items = value; + } + + //------------------------------------ + // itemsDescriptor + //------------------------------------ + + /** + * @private + * Storage for the itemsDescriptor property. + */ + private var _itemsDescriptor:Array; + + [Inspectable(category="General")] + + /** + * + * The descriptor that describes the items. + * + * <p>If you set this property, the items are instantiated at the time + * determined by the <code>creationPolicy</code> property.</p> + * + * <p>Do not set this property if you set the <code>items</code> + * property. + * This propety is the <code>AddItems</code> class default property. + * Setting this property with a <code>creationPolicy</code> of "all" + * is equivalent to setting a <code>items</code> property.</p> + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function get itemsDescriptor():Array + { + return _itemsDescriptor; + } + + /** + * @private + */ + public function set itemsDescriptor(value:Array):void + { + _itemsDescriptor = value; + + if (creationPolicy == ContainerCreationPolicy.ALL) + createInstance(); + } + + //------------------------------------ + // itemsFactory + //------------------------------------ + + /** + * @private + * Storage for the itemsFactory property. + */ + private var _itemsFactory:ITransientDeferredInstance; + + [Inspectable(category="General")] + + /** + * + * The factory that creates the items. + * + * <p>If you set this property, the items are instantiated at the time + * determined by the <code>creationPolicy</code> property.</p> + * + * <p>Do not set this property if you set the <code>items</code> + * property. + * This propety is the <code>AddItems</code> class default property. + * Setting this property with a <code>creationPolicy</code> of "all" + * is equivalent to setting a <code>items</code> property.</p> + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function get itemsFactory():ITransientDeferredInstance + { + return _itemsFactory; + } + + /** + * @private + */ + public function set itemsFactory(value:ITransientDeferredInstance):void + { + _itemsFactory = value; + + if (creationPolicy == ContainerCreationPolicy.ALL) + createInstance(); + } + + //------------------------------------ + // position + //------------------------------------ + + [Inspectable(category="General")] + + /** + * The position of the child in the display list, relative to the + * object specified by the <code>relativeTo</code> property. + * + * @default AddItems.LAST + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public var position:String = AddItems.LAST; + + //------------------------------------ + // isStyle + //------------------------------------ + + [Inspectable(category="General")] + + /** + * Denotes whether or not the collection represented by the + * target property is a style. + * + * @default false + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public var isStyle:Boolean = false; + + //------------------------------------ + // isArray + //------------------------------------ + + [Inspectable(category="General")] + + /** + * Denotes whether or not the collection represented by the + * target property is to be treated as a single array instance + * instead of a collection of items (the default). + * + * @default false + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public var isArray:Boolean = false; + + //------------------------------------ + // vectorClass + //------------------------------------ + + [Inspectable(category="General")] + + /** + * When the collection represented by the target property is a + * Vector, vectorClass is the type of the target. It is used to + * initialize the target property. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4.5 + */ + public var vectorClass:Class; + + //------------------------------------ + // propertyName + //------------------------------------ + + [Inspectable(category="General")] + + /** + * The name of the Array property that is being modified. If the <code>destination</code> + * property is a Group or Container, this property is optional. If not defined, the + * items will be added as children of the Group/Container. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public var propertyName:String; + + //------------------------------------ + // relativeTo + //------------------------------------ + + [Inspectable(category="General")] + + /** + * The object relative to which the child is added. This property is only + * used when the <code>position</code> property is <code>AddItems.BEFORE</code> + * or <code>AddItems.AFTER</code>. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public var relativeTo:Object; + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * Creates the items instance from the factory. + * You must use this method only if you specify a <code>targetItems</code> + * property and a <code>creationPolicy</code> value of <code>"none"</code>. + * Flex automatically calls this method if the <code>creationPolicy</code> + * property value is <code>"auto"</code> or <code>"all"</code>. + * If you call this method multiple times, the items instance is + * created only on the first call. + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + public function createInstance():void + { + if (!instanceCreated && !_items && itemsFactory && !_itemsDescriptor) + { + instanceCreated = true; + items = itemsFactory.getInstance(); + } + else if (!instanceCreated && !_items && !itemsFactory && _itemsDescriptor) + { + instanceCreated = true; + items = generateMXMLArray(document, itemsDescriptor, false); + } + } + + protected function generateMXMLObject(document:Object, data:Array):Object + { + var i:int = 0; + var cls:Class = data[i++]; + var comp:Object = new cls(); + + var m:int; + var j:int; + var name:String; + var simple:*; + var value:Object; + var id:String; + + m = data[i++]; // num props + for (j = 0; j < m; j++) + { + name = data[i++]; + simple = data[i++]; + value = data[i++]; + if (simple === null) + value = generateMXMLArray(document, value as Array); + else if (simple === undefined) + value = generateMXMLVector(document, value as Array); + else if (simple == false) + value = generateMXMLObject(document, value as Array); + if (name == "id") + { + document[value] = comp; + id = value as String; + if (comp is IMXMLObject) + continue; // skip assigment to comp + if (!("id" in comp)) + continue; + } + else if (name == "_id") + { + document[value] = comp; + id = value as String; + continue; // skip assignment to comp + } + comp[name] = value; + } + m = data[i++]; // num styles + for (j = 0; j < m; j++) + { + name = data[i++]; + simple = data[i++]; + value = data[i++]; + if (simple == null) + value = generateMXMLArray(document, value as Array); + else if (simple == false) + value = generateMXMLObject(document, value as Array); + comp.setStyle(name, value); + } + + m = data[i++]; // num effects + for (j = 0; j < m; j++) + { + name = data[i++]; + simple = data[i++]; + value = data[i++]; + if (simple == null) + value = generateMXMLArray(document, value as Array); + else if (simple == false) + value = generateMXMLObject(document, value as Array); + comp.setStyle(name, value); + } + + m = data[i++]; // num events + for (j = 0; j < m; j++) + { + name = data[i++]; + value = data[i++]; + comp.addEventListener(name, value); + } + + if (comp is IUIComponent) + { + if (comp.document == null) + comp.document = document; + } + var children:Array = data[i++]; + if (children) + { + comp.generateMXMLInstances(document, children); + } + + if (id) + { + document[id] = comp; + mx.binding.BindingManager.executeBindings(document, id, comp); + } + if (comp is IMXMLObject) + comp.initialized(document, id); + return comp; + } + + public function generateMXMLVector(document:Object, data:Array, recursive:Boolean = true):* + { + var comps:Array; + + var n:int = data.length; + var hint:* = data.shift(); + var generatorFunction:Function = data.shift(); + comps = generateMXMLArray(document, data, recursive); + return generatorFunction(comps); + } + + public function generateMXMLArray(document:Object, data:Array, recursive:Boolean = true):Array + { + var comps:Array = []; + + var n:int = data.length; + var i:int = 0; + while (i < n) + { + var cls:Class = data[i++]; + var comp:Object = new cls(); + + var m:int; + var j:int; + var name:String; + var simple:*; + var value:Object; + var id:String = null; + + m = data[i++]; // num props + for (j = 0; j < m; j++) + { + name = data[i++]; + simple = data[i++]; + value = data[i++]; + if (simple === null) + value = generateMXMLArray(document, value as Array, recursive); + else if (simple === undefined) + value = generateMXMLVector(document, value as Array, recursive); + else if (simple == false) + value = generateMXMLObject(document, value as Array); + if (name == "id") + { + document[value] = comp; + id = value as String; + if (comp is IMXMLObject) + continue; // skip assigment to comp + try { + if (!("id" in comp)) + continue; + } + catch (e:Error) + { + continue; // proxy subclasses might throw here + } + } + if (name == "document" && !comp.document) + comp.document = document; + else if (name == "_id") + id = value as String; // and don't assign to comp + else + comp[name] = value; + } + m = data[i++]; // num styles + for (j = 0; j < m; j++) + { + name = data[i++]; + simple = data[i++]; + value = data[i++]; + if (simple == null) + value = generateMXMLArray(document, value as Array, recursive); + else if (simple == false) + value = generateMXMLObject(document, value as Array); + comp.setStyle(name, value); + } + + m = data[i++]; // num effects + for (j = 0; j < m; j++) + { + name = data[i++]; + simple = data[i++]; + value = data[i++]; + if (simple == null) + value = generateMXMLArray(document, value as Array, recursive); + else if (simple == false) + value = generateMXMLObject(document, value as Array); + comp.setStyle(name, value); + } + + m = data[i++]; // num events + for (j = 0; j < m; j++) + { + name = data[i++]; + value = data[i++]; + comp.addEventListener(name, value); + } + + if (comp is IUIComponent) + { + if (comp.document == null) + comp.document = document; + } + var children:Array = data[i++]; + if (children) + { + if (recursive) + comp.generateMXMLInstances(document, children, recursive); + else + comp.setMXMLDescriptor(children); + } + + if (id) + { + document[id] = comp; + mx.binding.BindingManager.executeBindings(document, id, comp); + } + if (comp is IMXMLObject) + comp.initialized(document, id); + comps.push(comp); + } + return comps; + } + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + override public function initialize():void + { + if (creationPolicy == ContainerCreationPolicy.AUTO) + createInstance(); + } + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + override public function apply(parent:UIComponent):void + { + var dest:* = getOverrideContext(destination, parent); + var localItems:Array; + + added = false; + parentContext = parent; + + // Early exit if destination is null. + if (!dest) + { + if (destination != null && !applied) + { + // Our destination context is unavailable so we attempt to register + // a listener on our parent document to detect when/if it becomes + // valid. + addContextListener(destination); + } + applied = true; + return; + } + + applied = true; + destination = dest; + + // Coerce to array if not already an array, or we wish + // to treat the array as *the* item to add (isArray == true) + if (items is Array && !isArray) + localItems = items; + else + localItems = [items]; + + switch (position) + { + case FIRST: + startIndex = 0; + break; + case LAST: + startIndex = -1; + break; + case BEFORE: + startIndex = getRelatedIndex(parent, dest); + break; + case AFTER: + startIndex = getRelatedIndex(parent, dest) + 1; + break; + } + + if ( (propertyName == null || propertyName == "mxmlContent") && (dest is IVisualElementContainer)) + { + if (!addItemsToContentHolder(dest as IVisualElementContainer, localItems)) + return; + } + else if (propertyName == null && dest is IChildList) + { + addItemsToContainer(dest as IChildList, localItems); + } + else if (propertyName != null && !isStyle && dest[propertyName] is IList) + { + addItemsToIList(dest[propertyName], localItems); + } + else if (vectorClass) + { + addItemsToVector(dest, propertyName, localItems); + } + else + { + addItemsToArray(dest, propertyName, localItems); + } + + added = true; + numAdded = localItems.length; + } + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ + override public function remove(parent:UIComponent):void + { + var dest:* = getOverrideContext(destination, parent); + var localItems:Array; + var i:int; + + if (!added) + { + if (dest == null) + { + // It seems our override is no longer active, but we were never + // able to successfully apply ourselves, so remove our context + // listener if applicable. + removeContextListener(); + } + else if (_waitingForDeferredContent) + { + // Or we were waiting around for deferred content of our target + // to be created and it never happened, so we'll stop listening + // for now. + removeCreationCompleteListener(); + } + applied = false; + parentContext = null; + return; + } + + // Coerce to array if not already an array, or we wish + // to treat the array as *the* item to add (isArray == true) + if (items is Array && !isArray) + localItems = items; + else + localItems = [items]; + + if ((propertyName == null || propertyName == "mxmlContent") && (dest is IVisualElementContainer)) + { + for (i = 0; i < numAdded; i++) + { + if (IVisualElementContainer(dest).numElements > startIndex) + IVisualElementContainer(dest).removeElementAt(startIndex); + } + } + else if (propertyName == null && dest is IChildList) + { + for (i = 0; i < numAdded; i++) + { + if (IChildList(dest).numChildren > startIndex) + IChildList(dest).removeChildAt(startIndex); + } + } + else if (propertyName != null && !isStyle && dest[propertyName] is IList) + { + removeItemsFromIList(dest[propertyName] as IList); + } + else if (vectorClass) + { + var tempVector:Object = isStyle ? dest.getStyle(propertyName) : dest[propertyName]; + + if (numAdded < tempVector.length) + { + tempVector.splice(startIndex, numAdded); + assign(dest, propertyName, tempVector); + } + else + { + // For destinations like ArrayCollection we don't want to + // affect the vector in-place in some cases, as ListCollectionView a + // attempts to compare the "before" and "after" state of the vector + assign(dest, propertyName, new vectorClass()); + } + } + else + { + var tempArray:Array = isStyle ? dest.getStyle(propertyName) : dest[propertyName]; + + if (numAdded < tempArray.length) + { + tempArray.splice(startIndex, numAdded); + assign(dest, propertyName, tempArray); + } + else + { + // For destinations like ArrayCollection we don't want to + // affect the array in-place in some cases, as ListCollectionView a + // attempts to compare the "before" and "after" state of the array + assign(dest, propertyName, []); + } + } + + if (destructionPolicy == "auto") + destroyInstance(); + + // Clear our flags and override context. + added = false; + applied = false; + parentContext = null; + } + + /** + * @private + */ + private function destroyInstance():void + { + if (_itemsFactory) + { + instanceCreated = false; + items = null; + _itemsFactory.reset(); + } + } + + /** + * @private + */ + protected function getObjectIndex(object:Object, dest:Object):int + { + try + { + if ((propertyName == null || propertyName == "mxmlContent") && (dest is IVisualElementContainer)) + return IVisualElementContainer(dest).getElementIndex(object as IVisualElement); + + if (propertyName == null && dest is IChildList) + return IChildList(dest).getChildIndex(DisplayObject(object)); + + if (propertyName != null && !isStyle && dest[propertyName] is IList) + return IList(dest[propertyName].list).getItemIndex(object); + + if (propertyName != null && isStyle) + return dest.getStyle(propertyName).indexOf(object); + + return dest[propertyName].indexOf(object); + } + catch(e:Error) {} + return -1; + } + + /** + * @private + * Find the index of the relative object. If relativeTo is an array, + * search for the first valid item's index. This is used for stateful + * documents where one or more relative siblings of the newly inserted + * item may not be realized within the current state. + */ + protected function getRelatedIndex(parent:UIComponent, dest:Object):int + { + var index:int = -1; + if (relativeTo is Array) + { + for (var i:int = 0; ((i < relativeTo.length) && index < 0); i++) + { + var relativeObject:Object = getOverrideContext(relativeTo[i], parent); + index = getObjectIndex(relativeObject, dest); + } + } + else + { + relativeObject = getOverrideContext(relativeTo, parent); + index = getObjectIndex(relativeObject, dest); + } + return index; + } + + private var _waitingForDeferredContent:Boolean = false; + + /** + * @private + */ + protected function addItemsToContentHolder(dest:IVisualElementContainer, items:Array):Boolean + { + // If we are being asked to add more children to a deferred content owner, + // but the deferred content has yet to be created, we will defer application + // until it is safe to do so. + if (dest is IDeferredContentOwner && dest is IEventDispatcher) + { + var dco:IDeferredContentOwner= dest as IDeferredContentOwner; + if (!dco.deferredContentCreated) + { + IEventDispatcher(dest).addEventListener("contentCreationComplete", onDestinationContentCreated); + _waitingForDeferredContent = true; + return false; + } + } + + if (startIndex == -1) + startIndex = dest.numElements; + + for (var i:int = 0; i < items.length; i++) + dest.addElementAt(items[i], startIndex + i); + + return true; + } + + /** + * @private + */ + protected function addItemsToContainer(dest:IChildList, items:Array):void + { + if (startIndex == -1) + startIndex = dest.numChildren; + + for (var i:int = 0; i < items.length; i++) + dest.addChildAt(items[i], startIndex + i); + } + + /** + * @private + */ + protected function addItemsToArray(dest:Object, propertyName:String, items:Array):void + { + var tempArray:Array = isStyle ? dest.getStyle(propertyName) : dest[propertyName]; + + if (!tempArray) + tempArray = []; + + if (startIndex == -1) + startIndex = tempArray.length; + + for (var i:int = 0; i < items.length; i++) + tempArray.splice(startIndex + i, 0, items[i]); + + assign(dest, propertyName, tempArray); + } + + /** + * @private + */ + protected function addItemsToVector(dest:Object, propertyName:String, items:Array):void + { + var tempVector:Object = isStyle ? dest.getStyle(propertyName) : dest[propertyName]; + + if (!tempVector) + tempVector = new vectorClass(); + + if (startIndex == -1) + startIndex = tempVector.length; + + for (var i:int = 0; i < items.length; i++) + tempVector.splice(startIndex + i, 0, items[i]); + + assign(dest, propertyName, tempVector); + } + + /** + * @private + */ + protected function addItemsToIList(list:IList, items:Array):void + { + if (startIndex == -1) + startIndex = list.length; + + for (var i:int = 0; i < items.length; i++) + list.addItemAt(items[i], startIndex + i); + } + + /** + * @private + */ + protected function removeItemsFromIList(list:IList):void + { + for (var i:int = 0; i < numAdded; i++) + list.removeItemAt(startIndex); + + } + + /** + * @private + */ + protected function assign(dest:Object, propertyName:String, value:Object):void + { + if (isStyle) + { + dest.setStyle(propertyName, value); + dest.styleChanged(propertyName); + dest.notifyStyleChangeInChildren(propertyName, true); + } + else + { + dest[propertyName] = value; + } + } + + /** + * @private + * We've detected that our IDeferredContentOwnder target has created its + * content, so it's safe to apply our override content now. + */ + private function onDestinationContentCreated(e:Event):void + { + if (parentContext) + { + removeCreationCompleteListener(); + apply(parentContext); + } + } + + /** + * @private + * Remove our contentCreationComplete listener. + */ + private function removeCreationCompleteListener():void + { + if (parentContext) + { + parentContext.removeEventListener("contentCreationComplete", onDestinationContentCreated); + _waitingForDeferredContent = false; + } + } + + /** + * IMXMLObject support + */ + public function initialized(document:Object, id:String):void + { + this.document = document; + } + +} + +}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/states/InterruptionBehavior.as ---------------------------------------------------------------------- diff --cc frameworks/projects/MX/src/main/flex/mx/states/InterruptionBehavior.as index 642f006,0000000..f44d8a9 mode 100644,000000..100644 --- a/frameworks/projects/MX/src/main/flex/mx/states/InterruptionBehavior.as +++ b/frameworks/projects/MX/src/main/flex/mx/states/InterruptionBehavior.as @@@ -1,62 -1,0 +1,62 @@@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.states +{ + /** + * The InterruptionBehavior class defines constants for use with the + * <code>interruptionBehavior</code> property of the mx.states.Transition class. + * + * @see Transition#interruptionBehavior + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.5 + * @productversion Flex 4.5 + */ + public final class InterruptionBehavior + { + /** + * Specifies that a transition that interrupts another running + * transition ends that other transition before starting. + * The transition ends by calling the <code>end()</code> method + * on all effects in the transition. + * The <code>end()</code> method causes all effects + * to snap to their end state. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.5 + * @productversion Flex 4.5 + */ + public static const END:String = "end"; + + /** + * Specifies that a transition that interrupts another running + * transition stops that other transition in place before starting. + * The transition stops by calling the <code>stop()</code> method + * on all effects in the transition. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.5 + * @productversion Flex 4.5 + */ + public static const STOP:String = "stop"; + } - } ++} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/states/OverrideBase.as ---------------------------------------------------------------------- diff --cc frameworks/projects/MX/src/main/flex/mx/states/OverrideBase.as index b34ad52,0000000..702b261 mode 100644,000000..100644 --- a/frameworks/projects/MX/src/main/flex/mx/states/OverrideBase.as +++ b/frameworks/projects/MX/src/main/flex/mx/states/OverrideBase.as @@@ -1,222 -1,0 +1,222 @@@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.states +{ + +import mx.binding.BindingManager; +import mx.core.UIComponent; +import mx.core.mx_internal; +import mx.events.PropertyChangeEvent; +import mx.utils.OnDemandEventDispatcher; + +/** + * The OverrideBase class is the base class for the + * override classes used by view states. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ +public class OverrideBase extends OnDemandEventDispatcher implements IOverride +{ + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + /** + * Constructor. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function OverrideBase() {} + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + /** + * @private + * Flag which tracks if we're actively overriding a property. + */ + protected var applied:Boolean = false; + + /** + * @private + * Our most recent parent context. + */ + protected var parentContext:UIComponent; + + /** + * @private + */ + private var targetProperty:String; + + /** + * @private + * Specifies whether or not a property-centric + * state override's base value is data bound. + * + * This value is intended for use by the MXML + * compiler only. + */ + public var isBaseValueDataBound:Boolean; + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * IOverride interface method; this class implements it as an empty method. + * + * @copy IOverride#initialize() + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function initialize():void {} + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function apply(parent:UIComponent):void {} + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function remove(parent:UIComponent):void {} + + /** + * @private + * Initialize this object from a descriptor. + */ + public function initializeFromObject(properties:Object):Object + { + for (var p:String in properties) + { + this[p] = properties[p]; + } + + return Object(this); + } + + /** + * @private + * @param parent The document level context for this override. + * @param target The component level context for this override. + */ + protected function getOverrideContext(target:Object, parent:UIComponent):Object + { + if (target == null) + return parent; + + if (target is String) + return parent[target]; + + return target; + } + + /** + * @private + * If the target of our override is a String (representing a property), + * we register a PROPERTY_CHANGE listener to determine when/if our target + * context becomes available or changes. + */ + protected function addContextListener(target:Object):void + { + if (target is String && parentContext != null) + { + targetProperty = target as String; + parentContext.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, + context_propertyChangeHandler); + } + } + + /** + * @private + * Unregister our PROPERTY_CHANGE listener. + */ + protected function removeContextListener():void + { + if (parentContext != null) + { + parentContext.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, + context_propertyChangeHandler); + } + } + + /** + * @private + * Called when our target context is set. We re-apply our override + * if appropriate. + */ + protected function context_propertyChangeHandler(event:PropertyChangeEvent):void + { + if (event.property == targetProperty && event.newValue != null) + { + apply(parentContext); + removeContextListener(); + } + } + + /** + * @private + * Disables or enables binding associated with a property override. + */ + protected function enableBindings(target:Object, parent:UIComponent, property:String, enable:Boolean=true):void + { + if (isBaseValueDataBound && target && parent && property) + { + var document:Object = target.hasOwnProperty("document") ? target.document : null; + document = !document && parent.hasOwnProperty("document") ? parent.document : document; + + var name:String = target.hasOwnProperty("id") ? target.id : null; + name = !name && target.hasOwnProperty("name") ? target.name : name; + + if (document && name) + { + var root:String = (document == target) ? "this" : name; + BindingManager.enableBindings(document, root + "." + property, enable); + } + } + } +} + - } ++} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/states/RemoveChild.as ---------------------------------------------------------------------- diff --cc frameworks/projects/MX/src/main/flex/mx/states/RemoveChild.as index c98b88a,0000000..9a6f7fa mode 100644,000000..100644 --- a/frameworks/projects/MX/src/main/flex/mx/states/RemoveChild.as +++ b/frameworks/projects/MX/src/main/flex/mx/states/RemoveChild.as @@@ -1,218 -1,0 +1,218 @@@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.states +{ - COMPILE::AS3 ++COMPILE::SWF +{ + import flash.display.DisplayObject; + import flash.display.DisplayObjectContainer; +} +COMPILE::JS +{ + import flex.display.DisplayObject; + import flex.display.DisplayObjectContainer; +} + +import mx.core.UIComponent; +import mx.core.mx_internal; + +use namespace mx_internal; + +/** + * + * The RemoveChild class removes a child display object, such as a component, + * from a container as part of a view state. + * The child is only removed from the display list, it is not deleted. + * You use this class in the <code>overrides</code> property of the State class. + * + * @mxml + * + * <p>The <code><mx:RemoveChild></code> tag + * has the following attributes:</p> + * + * <pre> + * <mx:RemoveChild + * <b>Properties</b> + * target="null" + * /> + * </pre> + * + * @see mx.states.State + * @see mx.states.AddChild + * @see mx.states.Transition + * @see mx.effects.RemoveChildAction + * + * @includeExample examples/StatesExample.mxml + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ +public class RemoveChild extends OverrideBase +{ + include "../core/Version.as"; + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Constructor. + * + * @param target The child to remove from the view. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function RemoveChild(target:DisplayObject = null) + { + super(); + + this.target = target; + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + /** + * @private + * Parent of the removed child. + */ + private var oldParent:DisplayObjectContainer; + + /** + * @private + * Index of the removed child. + */ + private var oldIndex:int; + + /** + * @private + */ + private var removed:Boolean; + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + //---------------------------------- + // target + //---------------------------------- + + [Inspectable(category="General")] + + /** + * The child to remove from the view. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public var target:Object; + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + override public function apply(parent:UIComponent):void + { + parentContext = parent; + removed = false; + + var obj:* = getOverrideContext(target, parent); + if ((obj is DisplayObject) && obj.parent) + { + oldParent = obj.parent; + oldIndex = oldParent.getChildIndex(obj); + oldParent.removeChild(obj); + removed = true; + } + else if (obj == null && !applied) + { + // Our target context is unavailable so we attempt to register + // a listener on our parent document to detect when/if it becomes + // valid. + addContextListener(target); + } + + // Save state in case our value or target is changed while applied. This + // can occur when our value property is databound or when a target is + // deferred instantiated. + applied = true; + } + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + override public function remove(parent:UIComponent):void + { + var obj:* = getOverrideContext(target, parent); + if (removed && (obj is DisplayObject)) + { + oldParent.addChildAt(obj, oldIndex); + + // Make sure any changes made while the child was removed are reflected + // properly. + if (obj is UIComponent) + UIComponent(target).updateCallbacks(); + + removed = false; + } + else if (obj == null) + { + // It seems our override is no longer active, but we were never + // able to successfully apply ourselves, so remove our context + // listener if applicable. + removeContextListener(); + } + + // Clear our flags and override context. + applied = false; + parentContext = null; + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/states/SetEventHandler.as ---------------------------------------------------------------------- diff --cc frameworks/projects/MX/src/main/flex/mx/states/SetEventHandler.as index 531b6e1,0000000..757c303 mode 100644,000000..100644 --- a/frameworks/projects/MX/src/main/flex/mx/states/SetEventHandler.as +++ b/frameworks/projects/MX/src/main/flex/mx/states/SetEventHandler.as @@@ -1,407 -1,0 +1,407 @@@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.states +{ + +import org.apache.flex.events.EventDispatcher; +import flash.utils.Dictionary; +import mx.core.ComponentDescriptor; +import mx.core.UIComponent; +import mx.states.OverrideBase; +import mx.core.IStateClient2; + +/** + * The event handler function to execute in response to the event that is + * specified by the <code>name</code> property. + * + * <p>Do not specify the <code>handler</code> property and the <code>handlerFunction</code> + * property in a single <code><mx:SetEventHandler></code> tag.</p> + * + * <p>Flex does <i>not</i> dispatch a <code>handler</code> event. + * You use the <code>handler</code> key word only as an MXML attribte. + * When you use the <code>handler</code> handler attribute, you can specify a + * method that takes multiple parameters, not just the Event object; + * also, you can specify the handler code in-line in the MXML tag.</p> + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ +[Event(name="handler", type="Object")] + +/** + * The SetEventHandler class specifies an event handler that is active + * only during a particular view state. + * For example, you might define a Button control that uses one event handler + * in the base view state, but uses a different event handler when you change view state. + * + * <p> You use this class in the <code>overrides</code> property of the State class.</p> + * + * @mxml + * + * <p>The <code><mx:SetEventHanlder></code> tag + * has the following attributes:</p> + * + * <pre> + * <mx:SetEventHandler + * <b>Properties</b> + * name="null" + * handlerFunction="null" + * target="null" + * + * <b>Events</b> + * handler=<i>No default</i> + * /> + * </pre> + * + * @see mx.states.State + * @see mx.states.SetProperty + * @see mx.states.SetStyle + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ +public class SetEventHandler extends OverrideBase +{ + include "../core/Version.as"; + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Constructor. + * + * @param target The object that dispatches the event to be handled. + * By default, Flex uses the immediate parent of the State object. + * + * @param event The event type for which to set the handler. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function SetEventHandler( + target:EventDispatcher = null, + name:String = null) + { + super(); + + this.target = target; + this.name = name; + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + /** + * @private + * Storage for the old event handler value. + */ + private var oldHandlerFunction:Function; + + /** + * @private + * Dictionary of installed event handlers. + */ + COMPILE::LATER + private static var installedHandlers:Dictionary; + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + //---------------------------------- + // name + //---------------------------------- + + [Inspectable(category="General")] + + /** + * The name of the event whose handler is being set. + * You must set this property, either in + * the SetEventHandler constructor or by setting + * the property value directly. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public var name:String; + + /** + * The handler function for the event. + * This property is intended for developers who use ActionScript to + * create and access view states. + * In MXML, you can use the equivalent <code>handler</code> + * event attribute; do not use both in a single MXML tag. + * + * @default null + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public var handlerFunction:Function; + + /** + * The handler function to remove prior to applying our override. + * + * @default null + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 4.5 + */ + public var originalHandlerFunction:Function; + + //---------------------------------- + // target + //---------------------------------- + + [Inspectable(category="General")] + + /** + * The component that dispatches the event. + * If the property value is <code>null</code>, Flex uses the + * immediate parent of the <code><mx:states></code> tag. + * + * @default null + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public var target:Object; + + /** + * The cached target for which we applied our override. + * We keep track of the applied target while applied since + * our target may be swapped out in the owning document and + * we want to make sure we roll back the correct (original) + * element. + * + * @private + */ + private var appliedTarget:Object; + + //-------------------------------------------------------------------------- + // + // Overridden methods: EventDispatcher + // + //-------------------------------------------------------------------------- + + /** + * @private + */ - COMPILE::AS3 ++ COMPILE::SWF + override public function addEventListener( + type:String, listener:Function, + useCapture:Boolean = false, + priority:int = 0, + useWeakReference:Boolean = false):void + { + if (type == "handler") + handlerFunction = listener; + + super.addEventListener(type, listener, useCapture, + priority, useWeakReference); + } + + COMPILE::JS + override public function addEventListener( + type:String, listener:Function, + useCapture:Boolean = false, handlerScope:Object = null):void + { + if (type == "handler") + handlerFunction = listener; + + super.addEventListener(type, listener, useCapture); + } + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + override public function apply(parent:UIComponent):void + { + parentContext = parent; + var obj:* = getOverrideContext(target, parent); + if (obj != null) + { + appliedTarget = obj; + var uiObj:UIComponent = obj as UIComponent; + + COMPILE::LATER + { + if (!installedHandlers) + installedHandlers = new Dictionary(true); + + // Remember the current handler so it can be restored + if (installedHandlers[obj] && installedHandlers[obj][name]) + { + oldHandlerFunction = installedHandlers[obj][name]; + obj.removeEventListener(name, oldHandlerFunction); + } + else if (originalHandlerFunction != null) + { + oldHandlerFunction = originalHandlerFunction; + obj.removeEventListener(name, oldHandlerFunction); + } + else if (uiObj && uiObj.descriptor) + { + var descriptor:ComponentDescriptor = uiObj.descriptor; + + if (descriptor.events && descriptor.events[name]) + { + oldHandlerFunction = uiObj.document[descriptor.events[name]]; + obj.removeEventListener(name, oldHandlerFunction); + } + } + } + + // Set new handler as weak reference + if (handlerFunction != null) + { + obj.addEventListener(name, handlerFunction, false, 0, true); + + // Add this handler to our installedHandlers list so it can + // be removed if needed by a state based on this state. We + // only do so for legacy MXML documents that support hierarchical + // states. + COMPILE::LATER + { + if (!(parent.document is IStateClient2)) + { + if (installedHandlers[obj] == undefined) + installedHandlers[obj] = {}; + + installedHandlers[obj][name] = handlerFunction; + } + } + + // Disable bindings for the base event handler if appropriate. If the binding + // fires while our override is applied, the correct value will automatically + // be applied when the binding is later enabled. + enableBindings(obj, parent, name, false); + } + } + else if (!applied) + { + // Our target context is unavailable so we attempt to register + // a listener on our parent document to detect when/if it becomes + // valid. + addContextListener(target); + } + + // Save state in case our value or target is changed while applied. This + // can occur when our value property is databound or when a target is + // deferred instantiated. + applied = true; + } + + /** + * @inheritDoc + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + override public function remove(parent:UIComponent):void + { + var obj:* = getOverrideContext(appliedTarget, parent); + if (obj != null && appliedTarget) + { + if (handlerFunction != null) + obj.removeEventListener(name, handlerFunction); + + // Restore the old value + if (oldHandlerFunction != null) + obj.addEventListener(name, oldHandlerFunction, false, 0, true); + + COMPILE::LATER + { + if (installedHandlers[obj]) + { + var deleteObj:Boolean = true; + + // Remove this handler + delete installedHandlers[obj][name]; + + // If no other handlers are installed for this object, delete + // this object from the installedHandlers dictionary + for (var i:String in installedHandlers[obj]) + { + // Found one - don't delete this object + deleteObj = false; + break; + } + + if (deleteObj) + delete installedHandlers[obj]; + } + } + // Re-enable bindings for the base event handler if appropriate. If the binding + // fired while our override was applied, the current value will automatically + // be applied once enabled. + enableBindings(obj, parent, name); + } + else + { + // It seems our override is no longer active, but we were never + // able to successfully apply ourselves, so remove our context + // listener if applicable. + removeContextListener(); + } + + // Clear our flags and override context. + applied = false; + parentContext = null; + appliedTarget = null; + } +} + +}
