You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2020/05/22 10:30:54 UTC
[royale-asjs] 02/03: Binding overhaul. -Support for inherited
bindings (ancestor bindings get processed first) -slightly reduced release
build size for most users. -fix for #456
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 <gr...@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;
}
}