This is an automated email from the ASF dual-hosted git repository. gregdove pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit c3ed62dd1f6945aca48d2b52174f73111b1f3e23 Author: greg-dove <greg.d...@gmail.com> AuthorDate: Fri May 22 21:44:07 2020 +1200 Binding overhaul. -Support for inherited bindings (ancestor bindings get processed first) -slightly reduced release build size for most users. -fix for #456 --- .../royale/binding/ApplicationDataBinding.as | 39 ++------- .../apache/royale/binding/ContainerDataBinding.as | 70 +++++++--------- .../org/apache/royale/binding/DataBindingBase.as | 92 +++++++++++++++++++++- .../org/apache/royale/binding/GenericBinding.as | 2 + .../royale/binding/ItemRendererDataBinding.as | 34 +++----- .../royale/binding/MXMLBeadViewDataBinding.as | 34 +++----- .../org/apache/royale/binding/ViewDataBinding.as | 55 ++++++------- .../org/apache/royale/crux/binding/CruxBinding.as | 2 + 8 files changed, 172 insertions(+), 156 deletions(-) diff --git a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ApplicationDataBinding.as b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ApplicationDataBinding.as index 9e0ef8f..1e3e55d 100644 --- a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ApplicationDataBinding.as +++ b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ApplicationDataBinding.as @@ -59,39 +59,23 @@ package org.apache.royale.binding public function ApplicationDataBinding() { super(); + initEventType = 'viewChanged'; } - /** - * @copy org.apache.royale.core.IBead#strand - * - * @langversion 3.0 - * @playerversion Flash 10.2 - * @playerversion AIR 2.6 - * @productversion Royale 0.0 - * @royaleignorecoercion org.apache.royale.events.IEventDispatcher - */ - override public function set strand(value:IStrand):void - { - _strand = value; - IEventDispatcher(_strand).addEventListener("viewChanged", viewChangedHandler); - } + /** * @royaleignorecoercion org.apache.royale.core.IBinding * @royaleignorecoercion String + * @private */ - private function viewChangedHandler(event:Event):void - { - if (!("_bindings" in _strand)) - return; - + override protected function processBindingData(bindingData:Array, first:int):void{ var fieldWatcher:Object; var sb:SimpleBinding; - var bindingData:Array = _strand["_bindings"]; - var n:int = bindingData[0]; - var bindings:Array = []; var binding:Object = null; + var n:int = bindingData[first]; + var bindings:Array = []; var i:int; - var index:int = 1; + var index:int = first + 1; for (i = 0; i < n; i++) { binding = {}; @@ -159,14 +143,5 @@ package org.apache.royale.binding } } - private function makeGenericBinding(binding:Object, index:int, watchers:Object):void - { - var gb:GenericBinding = new GenericBinding(); - gb.setDocument(_strand); - gb.destinationData = binding.destination; - gb.destinationFunction = binding.destFunc; - gb.source = binding.source; - setupWatchers(gb, index, watchers.watchers, null); - } } } diff --git a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ContainerDataBinding.as b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ContainerDataBinding.as index e2c4ffe..4ad00cb 100644 --- a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ContainerDataBinding.as +++ b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ContainerDataBinding.as @@ -61,29 +61,25 @@ package org.apache.royale.binding } /** - * @royaleignorecoercion String * @royaleignorecoercion org.apache.royale.core.IBinding + * @royaleignorecoercion String + * @private */ - override protected function initBindingsHandler(event:Event):void - { - super.initBindingsHandler(event); - - if (!("_bindings" in _strand)) - return; + override protected function processBindingData(bindingData:Array, first:int):void{ var fieldWatcher:Object; var sb:SimpleBinding; var cb:ConstantBinding; - var bindingData:Array = _strand["_bindings"]; + var destinationObject:Object; var binding:Object = null; - var n:int = bindingData[0]; + var n:int = bindingData[first]; var bindings:Array = []; var i:int; - var index:int = 1; + var index:int = first + 1; for (i = 0; i < n; i++) { binding = {}; binding.source = bindingData[index++]; - binding.destFunc = bindingData[index++]; + binding.destFunc = bindingData[index++]; binding.destination = bindingData[index++]; bindings.push(binding); } @@ -96,7 +92,8 @@ package org.apache.royale.binding if (binding.source[0] in _strand) { var compWatcher:Object; - if (binding.source.length == 2 && binding.destination.length == 2) + var simpleDest:Boolean = typeof binding.destination == 'string'; + if (binding.source.length == 2 && (simpleDest || binding.destination.length == 2 )) { // simple component.property binding // can be simplebinding or constantbinding @@ -109,13 +106,20 @@ package org.apache.royale.binding if (fieldWatcher && fieldWatcher.eventNames is String) { sb = new SimpleBinding(); - sb.destinationPropertyName = binding.destination[1]; + + sb.destinationPropertyName = simpleDest ? binding.destination : binding.destination[1]; sb.eventName = fieldWatcher.eventNames as String; + if (simpleDest || binding.destination[0] == 'this') { + sb.destination = _strand; + } else { + //how do we detect if destination root changes in a simplebinding? + sb.destination = _strand[binding.destination[0]] + } sb.sourceID = binding.source[0]; sb.sourcePropertyName = binding.source[1]; sb.setDocument(_strand); - prepareCreatedBinding(sb as IBinding, binding); + prepareCreatedBinding(sb as IBinding, binding, destinationObject); } else if (fieldWatcher && fieldWatcher.eventNames == null) { @@ -140,14 +144,14 @@ package org.apache.royale.binding chb.setDocument(_strand); _strand.addBead(chb); } - } - else if (binding.destination is Array) - { - makeConstantBinding(binding); - } - else { - makeGenericBinding(binding, i, watchers); - } + } + else if (binding.destination is Array) + { + makeConstantBinding(binding); + } + else { + makeGenericBinding(binding, i, watchers); + } } else if (binding.source is String && binding.destination is Array) { @@ -158,7 +162,7 @@ package org.apache.royale.binding cb.destinationPropertyName = binding.destination[1]; cb.sourcePropertyName = binding.source; cb.setDocument(_strand); - var destinationObject:Object = null; + destinationObject = null; if (binding.destination[0] == "this") { destinationObject = _strand; @@ -181,6 +185,7 @@ package org.apache.royale.binding prepareCreatedBinding(sb as IBinding, binding); } + //else? is there anything missing here? tbc } else { makeGenericBinding(binding, i, watchers); @@ -190,24 +195,5 @@ package org.apache.royale.binding } } - private function makeGenericBinding(binding:Object, index:int, watchers:Object):void - { - var gb:GenericBinding = new GenericBinding(); - gb.setDocument(_strand); - gb.destinationData = binding.destination; - gb.destinationFunction = binding.destFunc; - gb.source = binding.source; - if (watchers.watchers.length) - { - setupWatchers(gb, index, watchers.watchers, null); - } - else - { - // should be a constant expression. - // the value doesn't matter as GenericBinding - // should get the value from the source - gb.valueChanged(null, true); - } - } } } diff --git a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/DataBindingBase.as b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/DataBindingBase.as index e7c3f5b..dd45b24 100644 --- a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/DataBindingBase.as +++ b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/DataBindingBase.as @@ -51,6 +51,28 @@ package org.apache.royale.binding protected var deferredBindings:Object; + protected var initEventType:String = "initBindings"; + + private var _initialized:Boolean; + + /** + * This method is a way to manually initialize the binding support at an earlier time than would + * happen by default ( this is usually the timing of 'initBindings' but could vary according to the + * timing of whatever initTypeEvent is for a particular sub-class) + * This can be useful in some cases when porting legacy code that expects bindings to be active + * at a certain alternate time, e.g. before mxml content is created and assigned, for example. + * + * This method will be dead-code-eliminated in js-release builds if not used in an application's code + * + * @royalesuppressexport + */ + public function initializeNow():void{ + if (!_initialized) { + IEventDispatcher(_strand).removeEventListener(initEventType, processBindings); + processBindings(null); + } + } + /** * @copy org.apache.royale.core.IBead#strand * @@ -63,11 +85,54 @@ package org.apache.royale.binding public function set strand(value:IStrand):void { _strand = value; - IEventDispatcher(_strand).addEventListener("initBindings", initBindingsHandler); + if (!_initialized) + IEventDispatcher(_strand).addEventListener(initEventType, processBindings); } - protected function initBindingsHandler(event:Event):void - { + private var _ancestry:Array; + protected function processBindings(event:Event):void{ + if (!("_bindings" in _strand) || _initialized) + return; + _initialized = true; + var bindingData:Array = _strand["_bindings"]; + var first:int = 0; + if (bindingData[0] is Array) { + _ancestry = []; + //process ancestor bindings + processAncestors(bindingData[0] as Array, _ancestry); + first = 1; + } + processBindingData(bindingData, first); + } + + /** + * + * @param array the binding data to process + * @param strongRefs, an array to push the ancestry items into, stored in the 'parent' DataBindingBase as a private var + * + * @royaleignorecoercion org.apache.royale.binding.DataBindingBase + * @royaleignorecoercion Class + */ + private function processAncestors(array:Array, strongRefs:Array):void{ + var first:int = 0; + var inst:DataBindingBase; + var bindingClass:Class = Object(this).constructor as Class; + if (array[0] is Array) { + //recurse into any more distant ancestors + inst = new bindingClass() as DataBindingBase; + inst._strand = _strand; + strongRefs.push(inst); + inst.processAncestors(array[0] as Array, strongRefs); + first = 1; + } + inst = new bindingClass() as DataBindingBase; + inst._strand = _strand; + strongRefs.push(inst); + inst.processBindingData(array, first) + } + + protected function processBindingData(array:Array, first:int):void{ + } /** @@ -324,6 +389,27 @@ package org.apache.royale.binding prepareCreatedBinding(cb as IBinding, binding); } + protected function makeGenericBinding(binding:Object, index:int, watchers:Object):void + { + var gb:GenericBinding = new GenericBinding(); + gb.setDocument(_strand); + gb.destinationData = binding.destination; + gb.destinationFunction = binding.destFunc; + gb.source = binding.source; + if (watchers.watchers.length) + { + setupWatchers(gb, index, watchers.watchers, null); + } + else + { + // should be a constant expression. + // the value doesn't matter as GenericBinding + // should get the value from the source + gb.valueChanged(null, true); + } + } + + /** */ private function deferredBindingsHandler(event:Event):void diff --git a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/GenericBinding.as b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/GenericBinding.as index e75d7ed..8217f15 100644 --- a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/GenericBinding.as +++ b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/GenericBinding.as @@ -220,6 +220,8 @@ package org.apache.royale.binding return; } obj[arr[n-1]] = value; + } else if (destinationData is String) { + document[destinationData] = value; } } diff --git a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ItemRendererDataBinding.as b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ItemRendererDataBinding.as index cac8186..19ad524 100644 --- a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ItemRendererDataBinding.as +++ b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ItemRendererDataBinding.as @@ -57,21 +57,20 @@ package org.apache.royale.binding super(); } - override protected function initBindingsHandler(event:Event):void - { - super.initBindingsHandler(event); - - if (!("_bindings" in _strand)) - return; - + /** + * @royaleignorecoercion org.apache.royale.core.IBinding + * @royaleignorecoercion String + * @private + */ + override protected function processBindingData(bindingData:Array, first:int):void{ var fieldWatcher:Object; var sb:SimpleBinding; - var bindingData:Array = _strand["_bindings"]; - var n:int = bindingData[0]; - var bindings:Array = []; + var cb:ConstantBinding; var binding:Object = null; + var n:int = bindingData[first]; + var bindings:Array = []; var i:int; - var index:int = 1; + var index:int = first + 1; for (i = 0; i < n; i++) { binding = {}; @@ -122,8 +121,8 @@ package org.apache.royale.binding if (compWatcher && fieldWatcher && (binding.source[0] == "data" || - (compWatcher.eventNames is String && - compWatcher.eventNames == "dataChange"))) + (compWatcher.eventNames is String && + compWatcher.eventNames == "dataChange"))) { var irsb:ItemRendererSimpleBinding = new ItemRendererSimpleBinding(); irsb.destinationID = binding.destination[0]; @@ -157,14 +156,5 @@ package org.apache.royale.binding } } - private function makeGenericBinding(binding:Object, index:int, watchers:Object):void - { - var gb:GenericBinding = new GenericBinding(); - gb.setDocument(_strand); - gb.destinationData = binding.destination; - gb.destinationFunction = binding.destFunc; - gb.source = binding.source; - setupWatchers(gb, index, watchers.watchers, null); - } } } diff --git a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/MXMLBeadViewDataBinding.as b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/MXMLBeadViewDataBinding.as index 2cd58f9..9cb7be3 100644 --- a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/MXMLBeadViewDataBinding.as +++ b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/MXMLBeadViewDataBinding.as @@ -57,30 +57,24 @@ package org.apache.royale.binding super(); } + /** - * @royaleignorecoercion String * @royaleignorecoercion org.apache.royale.core.IBinding + * @royaleignorecoercion String + * @private */ - override protected function initBindingsHandler(event:Event):void - { - super.initBindingsHandler(event); - - if (!("_bindings" in _strand)) - return; - + override protected function processBindingData(bindingData:Array, first:int):void { var fieldWatcher:Object; var sb:SimpleBinding; - var bindingData:Array = _strand["_bindings"]; - var n:int = bindingData[0]; - var bindings:Array = []; var binding:Object = null; + var n:int = bindingData[first]; + var bindings:Array = []; var i:int; - var index:int = 1; - for (i = 0; i < n; i++) - { + var index:int = first + 1; + for (i = 0; i < n; i++) { binding = {}; binding.source = bindingData[index++]; - binding.destFunc = bindingData[index++]; + binding.destFunc = bindingData[index++]; binding.destination = bindingData[index++]; bindings.push(binding); } @@ -147,16 +141,8 @@ package org.apache.royale.binding fieldWatcher = null; } - } - private function makeGenericBinding(binding:Object, index:int, watchers:Object):void - { - var gb:GenericBinding = new GenericBinding(); - gb.setDocument(_strand); - gb.destinationData = binding.destination; - gb.destinationFunction = binding.destFunc; - gb.source = binding.source; - setupWatchers(gb, index, watchers.watchers, null); } + } } diff --git a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ViewDataBinding.as b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ViewDataBinding.as index ded61fe..aedcad0 100644 --- a/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ViewDataBinding.as +++ b/frameworks/projects/Binding/src/main/royale/org/apache/royale/binding/ViewDataBinding.as @@ -58,26 +58,24 @@ package org.apache.royale.binding super(); } - override protected function initBindingsHandler(event:Event):void - { - super.initBindingsHandler(event); - - if (!("_bindings" in _strand)) - return; + /** + * @royaleignorecoercion org.apache.royale.core.IBinding + * @royaleignorecoercion String + * @private + */ + override protected function processBindingData(bindingData:Array, first:int):void { var fieldWatcher:Object; var sb:SimpleBinding; - var bindingData:Array = _strand["_bindings"]; - var n:int = bindingData[0]; - var bindings:Array = []; var binding:Object = null; + var n:int = bindingData[first]; + var bindings:Array = []; var i:int; - var index:int = 1; - for (i = 0; i < n; i++) - { + var index:int = first + 1; + for (i = 0; i < n; i++) { binding = {}; binding.source = bindingData[index++]; - binding.destFunc = bindingData[index++]; + binding.destFunc = bindingData[index++]; binding.destination = bindingData[index++]; bindings.push(binding); } @@ -114,7 +112,7 @@ package org.apache.royale.binding } } else if (binding.source is Array - && binding.source.length == 2 && binding.destination.length == 2) + && binding.source.length == 2 && binding.destination.length == 2) { // can be simplebinding or constantbinding compWatcher = watchers.watcherMap[binding.source[0]]; @@ -145,16 +143,16 @@ package org.apache.royale.binding prepareCreatedBinding(cb as IBinding, binding); } } - /* else if (binding.source is Array && binding.source[0] in _strand) - { - compWatcher = watchers.watcherMap[binding.source[0]]; - var chb:ChainBinding = new ChainBinding(); - chb.destination = binding.destination; - chb.source = binding.source; - chb.watcherChain = compWatcher; - chb.setDocument(_strand); - _strand.addBead(chb); - } */ + /* else if (binding.source is Array && binding.source[0] in _strand) + { + compWatcher = watchers.watcherMap[binding.source[0]]; + var chb:ChainBinding = new ChainBinding(); + chb.destination = binding.destination; + chb.source = binding.source; + chb.watcherChain = compWatcher; + chb.setDocument(_strand); + _strand.addBead(chb); + } */ else { makeGenericBinding(binding, i, watchers); @@ -164,14 +162,5 @@ package org.apache.royale.binding } } - private function makeGenericBinding(binding:Object, index:int, watchers:Object):void - { - var gb:GenericBinding = new GenericBinding(); - gb.setDocument(_strand); - gb.destinationData = binding.destination; - gb.destinationFunction = binding.destFunc; - gb.source = binding.source; - setupWatchers(gb, index, watchers.watchers, null); - } } } diff --git a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/binding/CruxBinding.as b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/binding/CruxBinding.as index 09d8e08..5972f66 100644 --- a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/binding/CruxBinding.as +++ b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/binding/CruxBinding.as @@ -133,6 +133,8 @@ package org.apache.royale.crux.binding return; } obj[arr[n-1]] = value; + } else if (destinationData is String) { + document[destinationData] = value; } }