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 2019/07/05 05:38:27 UTC

[royale-asjs] 01/02: Fix to EventHandler after last change. Improvements to stage events emulation, to get close to SWF behavior

This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch feature/Crux
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit ad71467dfb33a2d7684fd7a311edf1d7e4e8b5be
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Jul 5 17:24:30 2019 +1200

    Fix to EventHandler after last change.
    Improvements to stage events emulation, to get close to SWF behavior
---
 .../royale/org/apache/royale/crux/BeanFactory.as   | 101 ++++++++++++++++-----
 .../org/apache/royale/crux/beads/JSStageEvents.as  |  32 +++++--
 .../apache/royale/crux/utils/event/EventHandler.as |   9 +-
 3 files changed, 107 insertions(+), 35 deletions(-)

diff --git a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/BeanFactory.as b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/BeanFactory.as
index 3d8fa52..ccceea2 100644
--- a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/BeanFactory.as
+++ b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/BeanFactory.as
@@ -23,6 +23,7 @@ package org.apache.royale.crux
 	}
 	COMPILE::JS{
 		import org.apache.royale.events.Event;
+		import goog.events;
 	}
 	
     import org.apache.royale.events.EventDispatcher;
@@ -122,17 +123,41 @@ package org.apache.royale.crux
 			if( crux.catchViews == false )
 			 	return;
 			
-			crux.dispatcher.addEventListener( crux.config.setUpEventType,
-													setUpEventHandler, 
-													(crux.config.setUpEventPhase == 1), //EventPhase.CAPTURING_PHASE ),
-													crux.config.setUpEventPriority ); //, true - weak refernce
-					
-			crux.dispatcher.addEventListener( crux.config.tearDownEventType,
-													tearDownEventHandler, 
-													(crux.config.tearDownEventPhase == 1), //EventPhase.CAPTURING_PHASE )
-													crux.config.tearDownEventPriority);//, true ); - weak refernce
+			var className:String = getQualifiedClassName(crux.dispatcher);
+
+			
+			COMPILE::JS {
+				//support for capture phase
+				goog.events.listen( crux.dispatcher,
+						crux.config.setUpEventType,
+						setUpEventHandler,
+						(crux.config.setUpEventPhase == 1));
+				goog.events.listen( crux.dispatcher,
+						crux.config.tearDownEventType,
+						tearDownEventHandler,
+						(crux.config.tearDownEventPhase == 1));
+			}
+			
+			COMPILE::SWF{
+				crux.dispatcher.addEventListener( crux.config.setUpEventType,
+						setUpEventHandler,
+						(crux.config.setUpEventPhase == 1), //EventPhase.CAPTURING_PHASE ),
+						crux.config.setUpEventPriority ); //, true - weak refernce
+				
+				crux.dispatcher.addEventListener( crux.config.tearDownEventType,
+						tearDownEventHandler,
+						(crux.config.tearDownEventPhase == 1), //EventPhase.CAPTURING_PHASE )
+						crux.config.tearDownEventPriority);//, true ); - weak refernce
+			}
 			
 			
+			/**
+			 * override public function addEventListener(type:String, handler:Function, opt_capture:Boolean = false, opt_handlerScope:Object = null):void
+			 {
+            var source:Object = getActualDispatcher_(type);
+            goog.events.listen(source, type, handler);
+        }
+			 */
 			//@todo...
 			/*if(crux.dispatcher)
 			{
@@ -164,8 +189,26 @@ package org.apache.royale.crux
 			crux.dispatcher.removeEventListener( BeanEvent.TEAR_DOWN_BEAN, handleBeanEvent );
 			crux.dispatcher.removeEventListener( BeanEvent.REMOVE_BEAN, handleBeanEvent );
 			
-			crux.dispatcher.removeEventListener( crux.config.setUpEventType, setUpEventHandler, ( crux.config.setUpEventPhase == 0));//EventPhase.CAPTURING_PHASE ) );
-			crux.dispatcher.removeEventListener( crux.config.tearDownEventType, tearDownEventHandler, ( crux.config.tearDownEventPhase == 0));//EventPhase.CAPTURING_PHASE ) );
+			
+			COMPILE::JS {
+				//support for capture phase
+				goog.events.unlisten(crux.dispatcher,
+						crux.config.setUpEventType,
+						setUpEventHandler,
+						(crux.config.setUpEventPhase == 0))
+				
+				goog.events.unlisten(crux.dispatcher,
+						crux.config.tearDownEventType,
+						tearDownEventHandler,
+						(crux.config.tearDownEventPhase == 0))
+			}
+			
+			COMPILE::SWF{
+				
+				crux.dispatcher.removeEventListener( crux.config.setUpEventType, setUpEventHandler, ( crux.config.setUpEventPhase == 0));//EventPhase.CAPTURING_PHASE ) );
+				crux.dispatcher.removeEventListener( crux.config.tearDownEventType, tearDownEventHandler, ( crux.config.tearDownEventPhase == 0));//EventPhase.CAPTURING_PHASE ) );
+				
+			}
 			
 		}
 		
@@ -432,7 +475,6 @@ package org.apache.royale.crux
 		protected function isPotentialInjectionTarget( instance:Object ):Boolean
 		{
 			var className:String = getQualifiedClassName( instance );
-
 			
 			if( crux.config.viewPackages.length > 0 ) {
 				for each( var viewPackage:String in crux.config.viewPackages ) {
@@ -451,7 +493,7 @@ package org.apache.royale.crux
 		 */
 		protected function setUpEventHandler( event:Event ):void
 		{
-			trace('BeanFactory setUpEventHandler', event);
+			//tracer('BeanFactory setUpEventHandler',event.type,event.bubbles, getQualifiedClassName(event.target), getQualifiedClassName(event.currentTarget));
 			if( event.target is ISetUpValidator && !( ISetUpValidator( event.target ).allowSetUp() ) )
 				return;
 			
@@ -497,12 +539,27 @@ package org.apache.royale.crux
 		 */
 		protected function tearDownEventHandler( event:Event ):void
 		{
+
 			if( event.target is ITearDownValidator && !( ITearDownValidator( event.target ).allowTearDown() ) )
 				return;
-
+			
+			//tracer('BeanFactory tearDownEventHandler',event.type,event.bubbles, getQualifiedClassName(event.target), getQualifiedClassName(event.currentTarget));
+			
 			// only views previously processed can be torn down
-			if( CruxManager.wiredViews[ event.target ] )
-				addRemovedDisplayObject( UIBase( event.target ) );
+			
+			COMPILE::SWF{
+				if( CruxManager.wiredViews[ event.target ] ) {
+					//tracer('addRemovedDisplayObject::', getQualifiedClassName(event.target));
+					addRemovedDisplayObject( UIBase( event.target ) );
+				}
+				
+			}
+			COMPILE::JS{
+				if( CruxManager.wiredViews.get(event.target)) {
+					//tracer('addRemovedDisplayObject::', getQualifiedClassName(event.target));
+					addRemovedDisplayObject( UIBase( event.target ) );
+				}
+			}
 		}
 		
 		protected function addRemovedDisplayObject( displayObject:UIBase ):void
@@ -539,24 +596,24 @@ package org.apache.royale.crux
 		 */
 		public static function constructBean(obj:*, name:String):Bean
 		{
-			trace("constructBean", obj, name);
+			//tracer("constructBean", getQualifiedClassName(obj), name);
 			var bean:Bean;
 			
 			if(obj is Bean)
 			{
-				trace("obj is Bean");
+				//trace("obj is Bean");
 				bean = Bean(obj);
 			}
 			else
 			{
-				trace("obj is not Bean, create a Bean from the obj");
+				//trace("obj is not Bean, create a Bean from the obj");
 				bean = new Bean();
 				bean.source = obj;
 			}
-			trace("Bean ", bean);
-			trace("bean.name ", bean.name);
+			//trace("Bean ", bean);
+			//trace("bean.name ", bean.name);
 			bean.name ||= name;
-			trace("after ||=", bean.name);
+			//trace("after ||=", bean.name);
 			bean.typeDescriptor = TypeCache.getTypeDescriptor(bean.type);
 			
 			return bean;
diff --git a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/beads/JSStageEvents.as b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/beads/JSStageEvents.as
index dd7020d..13136bb 100644
--- a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/beads/JSStageEvents.as
+++ b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/beads/JSStageEvents.as
@@ -34,17 +34,18 @@ package org.apache.royale.crux.beads
     COMPILE::JS {
         import org.apache.royale.core.HTMLElementWrapper;
         import org.apache.royale.core.WrappedHTMLElement;
+        import goog.events.EventTarget;
     }
     
     /**
      *  The JSStageEvents class provides a way to simulate 'addedToStage' and 'removedFromStage' events in javascript.
      *
-     *  'addedToStage' events can bubble in a way that is similar to Flash Player/Adobe Air.
-     *  'removedFromStage' events do not (they are dispatched after 'removal' so must be listened for directly on the target instance)
-     *  If using bubbling, and you want to check for 'removedFromStage' a common pattern would be to add the 'removedFromStage' listener directly to instances
-     *  as they are handled in the upper level (e.g. application level) event handler, and in the 'removedFromStage' listener, to also remove the 'removedFromStage' listener itself.
+     *  'addedToStage' and 'removedFromStage' events do not bubble, but can be caught on the strand for anything in the child hierarchy
+     *  with capture phase listeners in a way that is similar to Flash Player/Adobe Air.
      *
-     *  For performance reasons, it is possible to filter out packages of view classes that will not have 'stage' events dispatched.
+     *  It is also possible specify a root dispatcher other than the strand.
+     *
+     *  For performance reasons, it is possible to filter out packages of view classes that will not need these events dispatched.
      *
      *  @langversion 3.0
      *  @playerversion Flash 10.2
@@ -77,6 +78,13 @@ package org.apache.royale.crux.beads
         }
         
 
+        private var _dispatcher:IEventDispatcher;
+        public function get dispatcher():IEventDispatcher{
+            return _dispatcher ;
+        }
+        public function set dispatcher(value:IEventDispatcher):void{
+            _dispatcher = value;
+        }
         
        
         
@@ -100,6 +108,7 @@ package org.apache.royale.crux.beads
                     trace('[IGNORING] there is already an active instance of JSStageEvents at ', _activeInstance.host);
                 } else {
                     _activeInstance = this;
+                    if (!_dispatcher) _dispatcher = value as IEventDispatcher;
                     var observer:MutationObserver = new MutationObserver(mutationDetected);
                     observer.observe(HTMLElementWrapper(value).element, {'childList': true, 'subtree': true});
                     trace('Activating JSStageEvents')
@@ -153,7 +162,12 @@ package org.apache.royale.crux.beads
                 var mutationRecord:MutationRecord = mutationsList[j] as MutationRecord;
 
                 var removedElements:NodeList = mutationRecord.removedNodes as NodeList;
-                for (var i:int = 0; i < removedElements.length; i++)
+                var l:uint = removedElements.length;
+                var fakeAncestors:Array;
+                if (l && _dispatcher) {
+                    fakeAncestors = [_dispatcher];
+                }
+                for (var i:int = 0; i < l; i++)
                 {
                     var element:WrappedHTMLElement = removedElements[i] as WrappedHTMLElement;
                     royaleInstance = element.royale_wrapper;
@@ -165,7 +179,8 @@ package org.apache.royale.crux.beads
                                 continue;
                             }
                         }
-                        royaleInstance.dispatchEvent(new Event('removedFromStage', true));
+                        //use the dispatcher (upper display list item) as a fake ancestor for capture phase listening
+                        goog.events.EventTarget.dispatchEventInternal_(royaleInstance, new Event('removedFromStage', false), fakeAncestors);
                     }
                 }
                 var addedElements:NodeList = mutationRecord.addedNodes as NodeList;
@@ -181,7 +196,8 @@ package org.apache.royale.crux.beads
                                 continue;
                             }
                         }
-                        royaleInstance.dispatchEvent(new Event('addedToStage', true));
+                        //dispatch a non-bubbling event, but support capture phase listeners
+                        royaleInstance.dispatchBubblingEvent(royaleInstance,new Event('addedToStage', false));
                     }
                 }
             }
diff --git a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/utils/event/EventHandler.as b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/utils/event/EventHandler.as
index 4143e78..0122b49 100644
--- a/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/utils/event/EventHandler.as
+++ b/frameworks/projects/Crux/src/main/royale/org/apache/royale/crux/utils/event/EventHandler.as
@@ -66,6 +66,8 @@ package org.apache.royale.crux.utils.event
 		 */
 		protected var _eventClass:Class;
 		
+		protected var _eventClassName:String;
+		
 		/**
 		 * Backing variable for <code>domain</code> property.
 		 */
@@ -217,7 +219,7 @@ package org.apache.royale.crux.utils.event
 				accessChains = {};
 				var eventClassDescriptor:TypeDescriptor = TypeCache.getTypeDescriptor( eventClass );
 				var eventDefinition:TypeDefinition = eventClassDescriptor.typeDefinition;
-				
+				_eventClassName = eventDefinition.qualifiedName;
 				for each( var property:String in metadataTag.properties )
 				{
 					var chain:Array = property.split( "." );
@@ -240,19 +242,17 @@ package org.apache.royale.crux.utils.event
 					accessChains[property] = accessChain;
 				}
 			}
-			
 			//now validate it
 			for each( property in metadataTag.properties )
 			{
 				accessChain = accessChains[property];
 				var o:Object = event;
-				var defName:String = eventDefinition.qualifiedName;
 				if (accessChain.length > 1) {
 					var index:int = 0;
 					var l:int = accessChain.length-1;
 					while (index<l) {
 						if (o == null) {
-							throw new Error( "Unable to handle event: " + varDef.name + " is null as a property of " + defName + " as defined in " + metadataTag.asTag + "." );
+							throw new Error( "Unable to handle event: " + varDef.name + " is null as a property of " + _eventClassName + " as defined in " + metadataTag.asTag + "." );
 						}
 						varDef = accessChain[index];
 						o = varDef.getValue(o)
@@ -292,7 +292,6 @@ package org.apache.royale.crux.utils.event
 				}
 				
 			}
-			//trace('EventHandler... args', args)
 			return args;
 		}