You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ha...@apache.org on 2019/12/24 21:25:59 UTC
[royale-asjs] branch develop updated: Fixed event bubbling and
stopImmediatePropogation
This is an automated email from the ASF dual-hosted git repository.
harbs 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 86c08f7 Fixed event bubbling and stopImmediatePropogation
86c08f7 is described below
commit 86c08f7b6b8d4f4f328b4434ebb748598bbce136
Author: Harbs <ha...@in-tools.com>
AuthorDate: Tue Dec 24 23:25:45 2019 +0200
Fixed event bubbling and stopImmediatePropogation
---
.../main/royale/org/apache/royale/events/Event.as | 12 ++-
.../org/apache/royale/events/EventDispatcher.as | 119 ++++++++++++++++-----
.../reflection/ReflectionTesterTest.as | 4 +-
3 files changed, 106 insertions(+), 29 deletions(-)
diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/Event.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/Event.as
index c2689f2..d146568 100644
--- a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/Event.as
+++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/Event.as
@@ -174,12 +174,18 @@ package org.apache.royale.events
* Google Closure doesn't seem to support stopImmediatePropagation, but
* actually the ElementWrapper fireListener override sends a
* BrowserEvent in most/all cases where folks need stopImmediatePropagation
- * so we put this in here for compile time since it will exist in
- * the BrowserEvent that does get sent around.
+ * We're re-writing the goog behavior to stop immmediate propogation in EventDispatcher
*/
+ private var _immediatePropogationStopped:Boolean;
+
+ public function get immediatePropogationStopped():Boolean
+ {
+ return _immediatePropogationStopped;
+ }
+
public function stopImmediatePropagation():void
{
- throw new Error("stopImmediatePropagation");
+ _immediatePropogationStopped = true;
}
public function cloneEvent():IRoyaleEvent
diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/EventDispatcher.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/EventDispatcher.as
index fd27682..34871d5 100644
--- a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/EventDispatcher.as
+++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/EventDispatcher.as
@@ -21,8 +21,10 @@ package org.apache.royale.events
COMPILE::JS
{
import goog.events;
+ import goog.events.Listener;
import goog.events.EventTarget;
import org.apache.royale.core.IChild;
+ import org.apache.royale.events.Event;
}
COMPILE::SWF
@@ -74,31 +76,22 @@ package org.apache.royale.events
override public function dispatchEvent(event1:Object):Boolean
{
- try
- {
- //we get quite a few string events here, "initialize" etc
- //so this general approach doesn't work:
- //event.target = _dispatcher;
- if (event1) {
- if (typeof event1 == "string") {
- event1 = new Event("" + event1);
- event1.target = _dispatcher;
- //console.log("created event from string ",event);
- }
- else if ("target" in event1) {
- event1.target = _dispatcher;
- //console.log("assigned target to event ",event);
- }
- } else return false;
+ //we get quite a few string events here, "initialize" etc
+ //so this general approach doesn't work:
+ //event.target = _dispatcher;
+ if (event1) {
+ if (typeof event1 == "string") {
+ event1 = new Event("" + event1);
+ event1.target = _dispatcher;
+ //console.log("created event from string ",event);
+ }
+ else if ("target" in event1) {
+ event1.target = _dispatcher;
+ //console.log("assigned target to event ",event);
+ }
+ } else return false;
- return super.dispatchEvent(event1);
- }
- catch (e:Error)
- {
- if (e.name != "stopImmediatePropagation")
- throw e;
- }
- return false;
+ return super.dispatchEvent(event1);
}
/**
* @royaleignorecoercion org.apache.royale.core.IChild
@@ -107,10 +100,88 @@ package org.apache.royale.events
override public function getParentEventTarget():goog.events.EventTarget{
return (this as IChild).parent as EventDispatcher;
}
+ override public function fireListeners(type:Object, capture:Boolean, eventObject:Object):Boolean{
+ var listenerArray:Array = getListeners(type, capture);
+ if (!listenerArray) {
+ return true;
+ }
+ listenerArray = listenerArray.concat();
+
+ var rv:Boolean = true;
+ for (var i:int = 0; i < listenerArray.length; ++i) {
+ if(eventObject.immediatePropogationStopped){
+ break;
+ }
+ var listener:goog.events.Listener = listenerArray[i];
+ // We might not have a listener if the listener was removed.
+ if (listener && !listener.removed && listener.capture == capture) {
+ var listenerFn:Object = listener.listener;
+ var listenerHandler:Object = listener.handler || listener.src;
+
+ if (listener.callOnce) {
+ this.unlistenByKey(listener);
+ }
+ rv = listenerFn.call(listenerHandler, eventObject) !== false && rv;
+ }
+ }
+
+ return rv && eventObject.returnValue_ != false;
+ }
public function toString():String
{
return "[object Object]";
}
+ private static function installOverride():Boolean{
+ goog.events.EventTarget.dispatchEventInternal_ = dispatchEventInternal;
+ return true;
+ }
+ private static var overrideInstalled:Boolean = installOverride();
+ /**
+ * Dispatches the given event on the ancestorsTree.
+ *
+ * @param {!Object} target The target to dispatch on.
+ * @param {goog.events.Event|Object|string} e The event object.
+ * @param {Array<goog.events.Listenable>=} opt_ancestorsTree The ancestors
+ * tree of the target, in reverse order from the closest ancestor
+ * to the root event target. May be null if the target has no ancestor.
+ * @return {boolean} If anyone called preventDefault on the event object (or
+ * if any of the listeners returns false) this will also return false.
+ * @private
+ */
+private static function dispatchEventInternal(target:EventDispatcher, e:org.apache.royale.events.Event, opt_ancestorsTree:Array):Boolean {
+ /** @suppress {missingProperties} */
+ var type:String = e.type;
+
+ var rv:Boolean = true, currentTarget:Object;
+
+ // Executes all capture listeners on the ancestors, if any.
+ if (opt_ancestorsTree) {
+ for (var i:int = opt_ancestorsTree.length - 1; !e.propagationStopped_ && i >= 0;
+ i--) {
+ currentTarget = e.currentTarget = opt_ancestorsTree[i];
+ rv = currentTarget.fireListeners(type, true, e) && rv;
+ }
+ }
+
+ // Executes capture and bubble listeners on the target.
+ if (!e.propagationStopped_) {
+ currentTarget = e.currentTarget = target;
+ rv = currentTarget.fireListeners(type, true, e) && rv;
+ if (!e.propagationStopped_) {
+ rv = currentTarget.fireListeners(type, false, e) && rv;
+ }
+ }
+
+ // Executes all bubble listeners on the ancestors, if any.
+ if (opt_ancestorsTree && e.bubbles) {
+ for (i = 0; !e.propagationStopped_ && i < opt_ancestorsTree.length; i++) {
+ currentTarget = e.currentTarget = opt_ancestorsTree[i];
+ rv = currentTarget.fireListeners(type, false, e) && rv;
+ }
+ }
+
+ return rv;
+};
}
}
diff --git a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as
index 3eefc5e..cbf235c 100644
--- a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as
+++ b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as
@@ -144,7 +144,7 @@ package flexUnitTests.reflection
assertEquals( 3, variables.length, "unexpected instance variables length");
//there is a difference based on the EventDispatcher inheritance chain differences between js and swf:
- expected = isJS ? 5 : 7;
+ expected = isJS ? 6 : 7;
var methods:Array = def.methods;
assertEquals( expected, methods.length, "unexpected instance methods length");
@@ -177,7 +177,7 @@ package flexUnitTests.reflection
assertEquals( 3, variables.length, "unexpected instance variables length");
//there is a difference based on the EventDispatcher inheritance chain differences between js and swf:
- expected = isJS ? 5 : 7;
+ expected = isJS ? 6 : 7;
var methods:Array = def.methods;
assertEquals( expected, methods.length, "unexpected instance methods length");