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


The following commit(s) were added to refs/heads/develop by this push:
     new 51c2b1b  Fix for native events arriving at listeners when they were 
dispatched as Royale Events (includes tests). Fixes #1170
     new 06e3df1  Merge branch 'develop' of 
https://github.com/apache/royale-asjs into develop
51c2b1b is described below

commit 51c2b1bc0c5984aea36e4bb1f7e26a492c1da783
Author: greg-dove <[email protected]>
AuthorDate: Mon Dec 20 07:26:54 2021 +1300

    Fix for native events arriving at listeners when they were dispatched as 
Royale Events (includes tests). Fixes #1170
---
 .../org/apache/royale/core/ElementWrapper.as       |  11 +-
 .../org/apache/royale/events/utils/EventUtils.as   |  35 ++++++
 .../src/test/royale/FlexUnitRoyaleApplication.mxml |  16 +++
 .../src/test/royale/flexUnitTests/CoreTester.as    |   2 +
 .../src/test/royale/flexUnitTests/EventsTest.as    | 119 +++++++++++++++++++++
 5 files changed, 180 insertions(+), 3 deletions(-)

diff --git 
a/frameworks/projects/Core/src/main/royale/org/apache/royale/core/ElementWrapper.as
 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/core/ElementWrapper.as
index 2386007..f6ee842 100644
--- 
a/frameworks/projects/Core/src/main/royale/org/apache/royale/core/ElementWrapper.as
+++ 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/core/ElementWrapper.as
@@ -195,8 +195,11 @@ package org.apache.royale.core
                 e = converter(nativeEvent,eventObject);
             else
             {
-                e = new org.apache.royale.events.BrowserEvent();
-                e.wrapEvent(eventObject);
+                e = EventUtils.retrieveEvent(nativeEvent) as IBrowserEvent;
+                if (e == nativeEvent) {
+                    e = new org.apache.royale.events.BrowserEvent();
+                    e.wrapEvent(eventObject);
+                }
             }
                        return ElementWrapper.googFireListener(listener, e);
                }
@@ -365,7 +368,9 @@ package org.apache.royale.core
                 eventType = e.type;
                 if (ElementEvents.elementEvents[eventType])
                 {
-                    e = EventUtils.createEvent(eventType, e["bubbles"]);
+                    var orig:Object = e;
+                    e = 
EventUtils.tagNativeEvent(EventUtils.createEvent(eventType, e["bubbles"]), 
orig);
+                    orig.target = orig.currentTarget = this;
                 }
             }
             var source:Object = this.getActualDispatcher_(eventType);
diff --git 
a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/utils/EventUtils.as
 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/utils/EventUtils.as
index acf0b40..d504045 100644
--- 
a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/utils/EventUtils.as
+++ 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/utils/EventUtils.as
@@ -21,6 +21,8 @@ package org.apache.royale.events.utils
 COMPILE::JS
 {
     import org.apache.royale.conversions.createEventInit;
+    import goog.events.Event;
+    import org.apache.royale.events.getTargetWrapper;
     import window.Event;
 }
 
@@ -31,6 +33,8 @@ COMPILE::JS
      *  @playerversion Flash 10.2
      *  @playerversion AIR 2.6
      *  @productversion Royale 0.0
+     *
+     *  @royalesupressexport
         */
     COMPILE::JS
        public class EventUtils
@@ -57,5 +61,36 @@ COMPILE::JS
 
            return customEvent;
        }
+
+        /**
+         * A way to let a Royale Event 'hitch a ride' on a native browser 
event.
+         *  Encapsulates the tagging/untagging support in this Utils class
+         * @param nativeEvent the native event to tag with the Royale Event
+         * @param royaleEvent the Royale Event to accompany the native event 
(expected as a org.apache.royale.events.Event here)
+         * @return the native event passed it
+         */
+       public static function tagNativeEvent(nativeEvent:Object, 
royaleEvent:Object):Object{
+           nativeEvent['_RYL_ORIG'] = royaleEvent;
+           return nativeEvent;
+       }
+
+        /**
+         * A way to retrieve a RoyaleEvent from a native browser event,
+         * if present. Encapsulates the tagging/untagging support in this 
Utils class
+         * @param nativeEvent
+         * @return the resolved event instance
+         *
+         * @royaleignorecoercion goog.events.Event
+         */
+        public static function retrieveEvent(nativeEvent:Object):Object{
+            if (nativeEvent['_RYL_ORIG']) {
+                var rlyEvt:goog.events.Event = nativeEvent['_RYL_ORIG'] as 
goog.events.Event;
+                //retrieve it with the currentTarget updated
+                rlyEvt.currentTarget = 
getTargetWrapper(nativeEvent.currentTarget)
+                return rlyEvt;
+            }
+            return nativeEvent;
+        }
+
     }
 }
diff --git 
a/frameworks/projects/Core/src/test/royale/FlexUnitRoyaleApplication.mxml 
b/frameworks/projects/Core/src/test/royale/FlexUnitRoyaleApplication.mxml
index a736f2b..0687904 100644
--- a/frameworks/projects/Core/src/test/royale/FlexUnitRoyaleApplication.mxml
+++ b/frameworks/projects/Core/src/test/royale/FlexUnitRoyaleApplication.mxml
@@ -40,6 +40,16 @@ limitations under the License.
             import org.apache.royale.test.listeners.BrowserConsoleListener;
             import org.apache.royale.test.Runtime;
 
+
+            private static var _instance:FlexUnitRoyaleApplication;
+            public static function getInstance():FlexUnitRoyaleApplication{
+                return _instance;
+            }
+
+            public function get eventsTestParent():Group{
+                return eventBubblingParent;
+            }
+
             //account for swf version variance in some test results due to 
fixed player bugs etc
             public function getSwfVersion():uint{
                 COMPILE::SWF{
@@ -71,6 +81,7 @@ limitations under the License.
             public function runTests():void
             {
                 Runtime.swfVersion = getSwfVersion();
+                _instance = this;
                 if (runLocal()) {
                     core.addListener(new BrowserConsoleListener());
                 } else{
@@ -94,5 +105,10 @@ limitations under the License.
         <!-- for such a simple app, we just set values to an empty array so it 
thinks it doesn't have any values -->
         <js:SimpleValuesImpl values="[]"/>
     </js:valuesImpl>
+    <js:initialView>
+        <js:View>
+            <js:Group id="eventBubblingParent" />
+        </js:View>
+    </js:initialView>
 
 </js:Application>
diff --git 
a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as 
b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
index c8adc02..9d2a16d 100644
--- a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
@@ -42,5 +42,7 @@ package flexUnitTests
         public var keyConverterTest:KeyConverterTest;
         public var keyboardEventConverterTest:KeyboardEventConverterTest;
         public var stringUtilsTest:StringUtilsTest;
+        public var eventsTest:EventsTest;
+
     }
 }
diff --git 
a/frameworks/projects/Core/src/test/royale/flexUnitTests/EventsTest.as 
b/frameworks/projects/Core/src/test/royale/flexUnitTests/EventsTest.as
new file mode 100644
index 0000000..753cd5e
--- /dev/null
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/EventsTest.as
@@ -0,0 +1,119 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flexUnitTests
+{
+    import org.apache.royale.core.IParent;
+    import org.apache.royale.utils.string.*;
+    import org.apache.royale.test.asserts.*;
+
+    import org.apache.royale.html.Group;
+    import org.apache.royale.core.UIBase;
+    import org.apache.royale.events.Event;
+    
+    public class EventsTest
+    {
+
+        private static var bubblingTopMostGroup:Group;
+        private static var deepestInstance:UIBase;
+        private static function createBubblingChain():void{
+            var currentParent:IParent = bubblingTopMostGroup;
+            var nesting:uint=10;
+            while (nesting) {
+                var child:UIBase = new UIBase();
+                child.id = 'nested_'+(11-nesting);
+                currentParent.addElement(child);
+                nesting--;
+                currentParent = child;
+            }
+            deepestInstance = child;
+        }
+
+
+        [Before]
+        public function setUp():void
+        {
+        }
+        
+        [After]
+        public function tearDown():void
+        {
+        }
+        
+        [BeforeClass]
+        public static function setUpBeforeClass():void
+        {
+            bubblingTopMostGroup = 
FlexUnitRoyaleApplication.getInstance().eventsTestParent;
+            createBubblingChain();
+        }
+        
+        [AfterClass]
+        public static function tearDownAfterClass():void
+        {
+            
bubblingTopMostGroup.removeElement(bubblingTopMostGroup.getElementAt(0));
+            deepestInstance = null;
+        }
+
+
+        
+        [Test]
+        public function testDispatchNonBubblingChangeResult():void{
+            var e:org.apache.royale.events.Event =  new 
org.apache.royale.events.Event(org.apache.royale.events.Event.CHANGE);
+            var received:org.apache.royale.events.Event ;
+            var receivedCurrentTarget:UIBase;
+            var receivedTarget:UIBase;
+            function localListener(e:org.apache.royale.events.Event):void{
+                received = e;
+                receivedTarget = e.target as UIBase;
+                receivedCurrentTarget = e.currentTarget as UIBase;
+            }
+            
deepestInstance.addEventListener(org.apache.royale.events.Event.CHANGE,localListener);
+            deepestInstance.dispatchEvent(e);
+            
deepestInstance.removeEventListener(org.apache.royale.events.Event.CHANGE,localListener);
+
+
+            assertEquals(received,e, 'the received event should be the same as 
the dispatched event');
+            assertEquals(deepestInstance,receivedTarget, 'the bubbling event 
currentTarget is wrong');
+            assertEquals(deepestInstance,receivedCurrentTarget, 'the bubbling 
event currentTarget is wrong');
+        }
+
+        [Test]
+        public function testDispatchBubblingChangeResult():void{
+            var e:org.apache.royale.events.Event =  new 
org.apache.royale.events.Event(org.apache.royale.events.Event.CHANGE,true);
+            var received:org.apache.royale.events.Event ;
+            var receivedCurrentTarget:UIBase;
+            var receivedTarget:UIBase;
+            function localListener(e:org.apache.royale.events.Event):void{
+                received = e;
+                receivedTarget = e.target as UIBase;
+                receivedCurrentTarget = e.currentTarget as UIBase;
+
+            }
+            
bubblingTopMostGroup.addEventListener(org.apache.royale.events.Event.CHANGE,localListener);
+            deepestInstance.dispatchEvent(e);
+            
bubblingTopMostGroup.removeEventListener(org.apache.royale.events.Event.CHANGE,localListener);
+
+
+            assertEquals(received,e, 'the received event should be the same as 
the dispatched event');
+            assertEquals(deepestInstance,receivedTarget, 'the bubbling event 
currentTarget is wrong');
+            assertEquals(bubblingTopMostGroup,receivedCurrentTarget, 'the 
bubbling event currentTarget is wrong');
+        }
+
+
+    }
+}

Reply via email to