Updated Branches: refs/heads/develop 246600d16 -> 3c3d2c01f
fix up new MXML codegen and Databinding codegen handling Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/3c3d2c01 Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/3c3d2c01 Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/3c3d2c01 Branch: refs/heads/develop Commit: 3c3d2c01f26dbb15d6d15d83f295490bfa3c9a05 Parents: 246600d Author: Alex Harui <aha...@apache.org> Authored: Wed Oct 30 23:52:34 2013 -0700 Committer: Alex Harui <aha...@apache.org> Committed: Thu Oct 31 10:30:00 2013 -0700 ---------------------------------------------------------------------- .../framework/src/mx/core/UIComponent.as | 457 +++++++++++++++---- .../src/spark/components/SkinnableContainer.as | 11 +- mustella/as3/src/mustella/UnitTester.as | 427 ++++++++++++++++- 3 files changed, 782 insertions(+), 113 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3c3d2c01/frameworks/projects/framework/src/mx/core/UIComponent.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/framework/src/mx/core/UIComponent.as b/frameworks/projects/framework/src/mx/core/UIComponent.as index 822b49c..d181000 100644 --- a/frameworks/projects/framework/src/mx/core/UIComponent.as +++ b/frameworks/projects/framework/src/mx/core/UIComponent.as @@ -53,7 +53,13 @@ import flash.utils.Dictionary; import flash.utils.getQualifiedClassName; import mx.automation.IAutomationObject; +import mx.binding.Binding; import mx.binding.BindingManager; +import mx.binding.FunctionReturnWatcher; +import mx.binding.PropertyWatcher; +import mx.binding.StaticPropertyWatcher; +import mx.binding.Watcher; +import mx.binding.XMLWatcher; import mx.controls.IFlexContextMenu; import mx.core.LayoutDirection; import mx.effects.EffectManager; @@ -1724,10 +1730,6 @@ public class UIComponent extends FlexSprite _width = super.width; _height = super.height; - var attributes:Array = this.MXMLProperties; - if (attributes) - generateMXMLAttributes(attributes); - } //-------------------------------------------------------------------------- @@ -7814,9 +7816,9 @@ public class UIComponent extends FlexSprite protected function addMXMLChildren(comps:Array):void { - for each (var i:DisplayObject in comps) + for each (var i:Object in comps) { - addChild(i); + addChild(i as DisplayObject); } } @@ -7839,14 +7841,20 @@ public class UIComponent extends FlexSprite name = data[i++]; simple = data[i++]; value = data[i++]; - if (simple == null) - value = generateMXMLArray(document, value as Array); + 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") { @@ -7856,107 +7864,194 @@ public class UIComponent extends FlexSprite } comp[name] = value; } - if (comp is IMXMLObject) - comp.initialized(document, id); - return comp; + 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 generateMXMLArray(document:Object, data:Array, recursive:Boolean = true):Array + public function generateMXMLVector(document:Object, data:Array, recursive:Boolean = true):* { - var comps: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 == false) - value = generateMXMLObject(document, value as Array); - if (name == "id") - id = value as String; - 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); - } - - 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; + 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; + } + protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void { var comps:Array = generateMXMLArray(document, data, recursive); - addMXMLChildren(comps); + var children:Array = []; + for each (var comp:Object in comps) + { + if (comp is DisplayObject || comp is IVisualElement) + children.push(comp); + } + addMXMLChildren(children); } protected function generateMXMLAttributes(data:Array):void @@ -7975,8 +8070,10 @@ public class UIComponent extends FlexSprite name = data[i++]; simple = data[i++]; value = data[i++]; - if (simple == null) - value = generateMXMLArray(this, value as Array, false); + if (simple === null) + value = generateMXMLArray(this, value as Array); + else if (simple === undefined) + value = generateMXMLVector(this, value as Array); else if (simple == false) value = generateMXMLObject(this, value as Array); if (name == "id") @@ -8020,6 +8117,164 @@ public class UIComponent extends FlexSprite this.addEventListener(name, value as Function); } } + + mx_internal function setupBindings():void + { + var fieldWatcher:Object; + var bindingData:Array = this["_bindings"]; + var n:int = bindingData[0]; + var bindings:Array = []; + var i:int; + var index:int = 1; + for (i = 0; i < n; i++) + { + var source:Object = bindingData[index++]; + var destination:Object = bindingData[index++]; + var binding:Binding = new Binding(this, + (source is Function) ? source as Function : null, + (destination is Function) ? destination as Function : null, + (destination is Function) ? null : (destination is String) ? destination as String : destination.join("."), + (source is Function) ? null : (source is String) ? source as String : source.join(".")); + bindings.push(binding); + } + var watchers:Object = decodeWatcher(this, bindingData.slice(index), bindings); + this["_bindings"] = bindings; + this["_watchers"] = watchers; + + } + + private function decodeWatcher(target:Object, bindingData:Array, bindings:Array):Array + { + var watcherMap:Object = {}; + var watchers:Array = []; + var n:int = bindingData.length; + var index:int = 0; + var watcherData:Object; + var theBindings:Array; + var bindingIndices:Array; + var bindingIndex:int; + var propertyName:String; + var eventNames:Array; + var eventName:String; + var eventObject:Object; + var getterFunction:Function; + var value:*; + var w:Watcher; + + while (index < n) + { + var watcherIndex:int = bindingData[index++]; + var type:int = bindingData[index++]; + switch (type) + { + case 0: + { + var functionName:String = bindingData[index++]; + var paramFunction:Function = bindingData[index++]; + value = bindingData[index++]; + if (value is String) + eventNames = [ value ]; + else + eventNames = value; + eventObject = {}; + for each (eventName in eventNames) + eventObject[eventName] = true; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + w = new FunctionReturnWatcher(functionName, + this, + paramFunction, + eventObject, + theBindings); + break; + } + case 1: + { + propertyName = bindingData[index++]; + value = bindingData[index++]; + if (value is String) + eventNames = [ value ]; + else + eventNames = value; + eventObject = {}; + for each (eventName in eventNames) + eventObject[eventName] = true; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + getterFunction = bindingData[index++]; + w = new StaticPropertyWatcher(propertyName, + eventObject, theBindings, getterFunction); + break; + } + case 2: + { + propertyName = bindingData[index++]; + value = bindingData[index++]; + if (value is String) + eventNames = [ value ]; + else + eventNames = value; + eventObject = {}; + for each (eventName in eventNames) + eventObject[eventName] = true; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + getterFunction = bindingData[index++]; + w = new PropertyWatcher(propertyName, + eventObject, theBindings, getterFunction); + break; + } + case 3: + { + propertyName = bindingData[index++]; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + w = new XMLWatcher(propertyName, theBindings); + break; + } + } + watchers.push(w); + w.updateParent(target); + if (target is Watcher) + { + if (w is FunctionReturnWatcher) + FunctionReturnWatcher(w).parentWatcher = Watcher(target); + Watcher(target).addChild(w); + } + + var children:Array = bindingData[index++]; + if (children != null) + { + children = decodeWatcher(w, children, bindings); + } + } + return watchers; + } + /** * Performs any final processing after child objects are created. * This is an advanced method that you might override http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3c3d2c01/frameworks/projects/spark/src/spark/components/SkinnableContainer.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/spark/src/spark/components/SkinnableContainer.as b/frameworks/projects/spark/src/spark/components/SkinnableContainer.as index edff9c6..cdd6652 100644 --- a/frameworks/projects/spark/src/spark/components/SkinnableContainer.as +++ b/frameworks/projects/spark/src/spark/components/SkinnableContainer.as @@ -881,13 +881,16 @@ public class SkinnableContainer extends SkinnableContainerBase // //-------------------------------------------------------------------------- - private var creatingChildren:Boolean; + private var creatingDeferredContent:Boolean; override protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void { // don't generate children during super.createChildren - if (creatingChildren) + if (!creatingDeferredContent) + { + setMXMLDescriptor(data); return; + } super.generateMXMLInstances(document, data, recursive); } @@ -903,9 +906,7 @@ public class SkinnableContainer extends SkinnableContainerBase */ override protected function createChildren():void { - creatingChildren = true; super.createChildren(); - creatingChildren = false; // TODO (rfrishbe): When navigator support is added, this is where we would // determine if content should be created now, or wait until @@ -1072,7 +1073,9 @@ public class SkinnableContainer extends SkinnableContainerBase var children:Array = this.MXMLDescriptor; if (children) { + creatingDeferredContent = true; generateMXMLInstances(document, children); + creatingDeferredContent = false; mxmlContentCreated = true; // keep the code from recursing back into here. _deferredContentCreated = true; dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE)); http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3c3d2c01/mustella/as3/src/mustella/UnitTester.as ---------------------------------------------------------------------- diff --git a/mustella/as3/src/mustella/UnitTester.as b/mustella/as3/src/mustella/UnitTester.as index fa3c774..24c3918 100644 --- a/mustella/as3/src/mustella/UnitTester.as +++ b/mustella/as3/src/mustella/UnitTester.as @@ -23,30 +23,39 @@ import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; import flash.display.InteractiveObject; import flash.display.Stage; -import flash.events.Event; import flash.events.ErrorEvent; -import flash.events.FocusEvent; +import flash.events.Event; import flash.events.EventDispatcher; +import flash.events.FocusEvent; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.events.UncaughtErrorEvent; -import flash.geom.Point; import flash.geom.Matrix; +import flash.geom.Point; import flash.geom.Rectangle; import flash.net.Socket; +import flash.net.URLLoader; +import flash.net.URLLoaderDataFormat; +import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.Security; import flash.system.fscommand; import flash.utils.Dictionary; -import flash.utils.getQualifiedClassName; import flash.utils.Timer; +import flash.utils.getQualifiedClassName; import flash.utils.setTimeout; -import flash.net.URLRequest; -import flash.net.URLLoader; -import flash.net.URLLoaderDataFormat; +import mx.binding.Binding; +import mx.binding.BindingManager; +import mx.binding.FunctionReturnWatcher; +import mx.binding.PropertyWatcher; +import mx.binding.StaticPropertyWatcher; +import mx.binding.Watcher; +import mx.binding.XMLWatcher; +import mx.core.IMXMLObject; import mx.core.mx_internal; + use namespace mx_internal; [Mixin] @@ -1474,10 +1483,47 @@ public class UnitTester extends EventDispatcher scriptName = getQualifiedClassName(this); if (scriptName.indexOf("::") >= 0) scriptName = scriptName.substring(scriptName.indexOf("::") + 2); - } + //---------------------------------- + // MXML Descriptor + //---------------------------------- + + /** + * The descriptor of MXML children. + */ + private var _MXMLDescriptor:Array; + + public function get MXMLDescriptor():Array + { + return _MXMLDescriptor; + } + + public function setMXMLDescriptor(value:Array):void + { + _MXMLDescriptor = value; + } + + //---------------------------------- + // MXML Properties + //---------------------------------- + + /** + * The attributes of MXML top tag. + */ + private var _MXMLProperties:Array; + + public function get MXMLProperties():Array + { + return _MXMLProperties; + } + + public function setMXMLProperties(value:Array):void + { + _MXMLProperties = value; + } + /** * The name of the script */ @@ -1794,6 +1840,10 @@ public class UnitTester extends EventDispatcher */ public function startTests():void { + var children:Array = this.MXMLDescriptor; + if (children) + generateMXMLInstances(this, children); + var r:Object = _root; r = r["topLevelSystemManager"]; r = r.rawChildren; @@ -2014,6 +2064,367 @@ public class UnitTester extends EventDispatcher } + protected function addMXMLChildren(comps:Array):void + { + } + + 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 == false) + value = generateMXMLObject(document, value as Array); + if (name == "id") + { + document[value] = comp; + id = value as String; + } + else if (name == "_id") + { + document[value] = comp; + id = value as String; + continue; // skip assignment to comp + } + comp[name] = value; + } + if (comp is IMXMLObject) + comp.initialized(document, id); + return comp; + } + + 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 == false) + value = generateMXMLObject(document, value as Array); + if (name == "id") + id = value as String; + 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); + } + + 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; + } + + protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void + { + var comps:Array = generateMXMLArray(document, data, recursive); + addMXMLChildren(comps); + } + + protected function generateMXMLAttributes(data:Array):void + { + var i:int = 0; + 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(this, value as Array, false); + else if (simple == false) + value = generateMXMLObject(this, value as Array); + if (name == "id") + id = value as String; + if (name == "_id") + id = value as String; // and don't assign + else + this[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(this, value as Array, false); + else if (simple == false) + value = generateMXMLObject(this, value as Array); + // this.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(this, value as Array, false); + else if (simple == false) + value = generateMXMLObject(this, value as Array); + // this.setStyle(name, value); + } + + m = data[i++]; // num events + for (j = 0; j < m; j++) + { + name = data[i++]; + value = data[i++]; + this.addEventListener(name, value as Function); + } + } + + mx_internal function setupBindings():void + { + var fieldWatcher:Object; + var bindingData:Array = this["_bindings"]; + var n:int = bindingData[0]; + var bindings:Array = []; + var i:int; + var index:int = 1; + for (i = 0; i < n; i++) + { + var source:Object = bindingData[index++]; + var destination:Object = bindingData[index++]; + var binding:Binding = new Binding(this, + (source is Function) ? source as Function : null, + (destination is Function) ? destination as Function : null, + (destination is Function) ? null : (destination is String) ? destination as String : destination.join("."), + (source is Function) ? null : (source is String) ? source as String : source.join(".")); + bindings.push(binding); + } + var watchers:Object = decodeWatcher(this, bindingData.slice(index), bindings); + this["_bindings"] = bindings; + this["_watchers"] = watchers; + } + + private function decodeWatcher(target:Object, bindingData:Array, bindings:Array):Array + { + var watcherMap:Object = {}; + var watchers:Array = []; + var n:int = bindingData.length; + var index:int = 0; + var watcherData:Object; + var theBindings:Array; + var bindingIndices:Array; + var bindingIndex:int; + var propertyName:String; + var eventNames:Array; + var eventName:String; + var eventObject:Object; + var getterFunction:Function; + var value:*; + var w:Watcher; + + while (index < n) + { + var watcherIndex:int = bindingData[index++]; + var type:int = bindingData[index++]; + switch (type) + { + case 0: + { + var functionName:String = bindingData[index++]; + var paramFunction:Function = bindingData[index++]; + value = bindingData[index++]; + if (value is String) + eventNames = [ value ]; + else + eventNames = value; + eventObject = {}; + for each (eventName in eventNames) + eventObject[eventName] = true; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + w = new FunctionReturnWatcher(functionName, + this, + paramFunction, + eventObject, + theBindings); + break; + } + case 1: + { + propertyName = bindingData[index++]; + value = bindingData[index++]; + if (value is String) + eventNames = [ value ]; + else + eventNames = value; + eventObject = {}; + for each (eventName in eventNames) + eventObject[eventName] = true; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + getterFunction = bindingData[index++]; + w = new StaticPropertyWatcher(propertyName, + eventObject, theBindings, getterFunction); + break; + } + case 2: + { + propertyName = bindingData[index++]; + value = bindingData[index++]; + if (value is String) + eventNames = [ value ]; + else + eventNames = value; + eventObject = {}; + for each (eventName in eventNames) + eventObject[eventName] = true; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + getterFunction = bindingData[index++]; + w = new PropertyWatcher(propertyName, + eventObject, theBindings, getterFunction); + break; + } + case 3: + { + propertyName = bindingData[index++]; + value = bindingData[index++]; + if (value is Array) + bindingIndices = value; + else + bindingIndices = [ value ]; + theBindings = []; + for each (bindingIndex in bindingIndices) + theBindings.push(bindings[bindingIndex]); + w = new XMLWatcher(propertyName, theBindings); + break; + } + } + watchers.push(w); + w.updateParent(target); + if (target is Watcher) + { + if (w is FunctionReturnWatcher) + FunctionReturnWatcher(w).parentWatcher = Watcher(target); + Watcher(target).addChild(w); + } + + var children:Array = bindingData[index++]; + if (children != null) + { + children = decodeWatcher(w, children, bindings); + } + } + return watchers; + } + private static function callLaterErrorDefaultHandler(event:Event):void { var o:Object = event;