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');
+ }
+
+
+ }
+}