Permalink
Browse files

A few fixes to goog.events+goog.events.EventTarget:

1) Adds reallyDisposed_ to goog.events.EventTarget. Use this
to bypass dispatchEvent/fireListeners instead of this.isDisposed().
Reason: this.isDisposed() returns true when dispose() is called,
even when disposeInternal has not been executed. Many classes
(including goog.ui.Component) wants to fire events in
disposeInternal, which should be allowed. Added test.

2) wrapListener_ now returns the value from handleEvent call
correctly + added tests.

R=nicksantos
DELTA=70 (65 added, 0 deleted, 5 changed)


Revision created by MOE tool push_codebase.
MOE_MIGRATION=6221


git-svn-id: http://closure-library.googlecode.com/svn/trunk@2484 0b95b8e8-c90f-11de-9d4f-f947ee5921c8
  • Loading branch information...
chrishenry@google.com
chrishenry@google.com committed Jan 30, 2013
1 parent 62473f3 commit 191b910555fd5845b35c08244e69aeddf47711f1
@@ -1244,7 +1244,7 @@ goog.events.wrapListener_ = function(listener) {
return listener[goog.events.LISTENER_WRAPPER_PROP_] ||
(listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) {
- listener.handleEvent(e);
+ return listener.handleEvent(e);
});
};
@@ -17,6 +17,7 @@
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
+ goog.require('goog.events.Listenable');
goog.require('goog.functions');
goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.jsunit');
@@ -176,6 +177,11 @@
}
function testBubbleShortCircuit() {
+ // Short-circuit no longer works with listenable.
+ if (goog.events.Listenable.USE_LISTENABLE_INTERFACE) {
+ return;
+ }
+
var et1 = new goog.events.EventTarget();
var et2 = new goog.events.EventTarget();
@@ -430,7 +436,11 @@
goog.removeUid(target);
target.dispatchEvent('foo');
- assertEquals(0, listener.getCallCount());
+ if (goog.events.Listenable.USE_LISTENABLE_INTERFACE) {
+ assertEquals(1, listener.getCallCount());
+ } else {
+ assertEquals(0, listener.getCallCount());
+ }
}
/**
@@ -90,6 +90,16 @@ goog.events.EventTarget = function() {
* @private
*/
this.eventTargetListeners_ = {};
+
+ /**
+ * Whether the EventTarget has been disposed. This is only true
+ * when disposeInternal of EventTarget is completed (whereas
+ * this.isDisposed() is true the moment obj.dispose() is called,
+ * even before calling its disposeInternal).
+ * @type {boolean}
+ * @private
+ */
+ this.reallyDisposed_ = false;
}
};
goog.inherits(goog.events.EventTarget, goog.Disposable);
@@ -185,7 +195,7 @@ goog.events.EventTarget.prototype.removeEventListener = function(
/** @override */
goog.events.EventTarget.prototype.dispatchEvent = function(e) {
if (goog.events.Listenable.USE_LISTENABLE_INTERFACE) {
- if (this.isDisposed()) {
+ if (this.reallyDisposed_) {
return true;
}
@@ -223,6 +233,7 @@ goog.events.EventTarget.prototype.disposeInternal = function() {
if (goog.events.Listenable.USE_LISTENABLE_INTERFACE) {
this.removeAllListeners();
+ this.reallyDisposed_ = true;
} else {
goog.events.removeAll(this);
}
@@ -271,7 +282,8 @@ goog.events.EventTarget.prototype.listenOnce = function(
*/
goog.events.EventTarget.prototype.listenInternal_ = function(
type, listener, callOnce, opt_useCapture, opt_listenerScope) {
- goog.asserts.assert(!this.isDisposed());
+ goog.asserts.assert(
+ !this.reallyDisposed_, 'Can not listen on disposed object.');
var listenerArray = this.eventTargetListeners_[type] ||
(this.eventTargetListeners_[type] = []);
@@ -357,7 +369,9 @@ goog.events.EventTarget.prototype.removeAllListeners = function(
/** @override */
goog.events.EventTarget.prototype.fireListeners = function(
type, capture, eventObject) {
- goog.asserts.assert(!this.isDisposed());
+ goog.asserts.assert(
+ !this.reallyDisposed_,
+ 'Can not fire listeners after dispose() completed.');
if (!(type in this.eventTargetListeners_)) {
return true;
@@ -72,6 +72,21 @@
assertEquals(0, goog.object.getCount(goog.events.listeners_))
}
+function testListenWithObject() {
+ var obj = {};
+ obj.handleEvent = goog.testing.recordFunction();
+ goog.events.listen(eventTargets[0], EventType.A, obj);
+ eventTargets[0].dispatchEvent(EventType.A);
+ assertEquals(1, obj.handleEvent.getCallCount());
+}
+
+function testListenWithObjectHandleEventReturningFalse() {
+ var obj = {};
+ obj.handleEvent = function() { return false; };
+ goog.events.listen(eventTargets[0], EventType.A, obj);
+ assertFalse(eventTargets[0].dispatchEvent(EventType.A));
+}
+
</script>
</body>
</html>
@@ -978,3 +978,29 @@ function testHasListener() {
assertFalse(hasListener(eventTargets[0], EventType.B, true));
assertFalse(hasListener(eventTargets[1]));
}
+
+
+function testFiringEventBeforeDisposeInternalWorks() {
+ /**
+ * @extends {goog.events.EventTarget}
+ * @constructor
+ */
+ var MockTarget = function() {
+ goog.base(this);
+ };
+ goog.inherits(MockTarget, goog.events.EventTarget);
+
+ MockTarget.prototype.disposeInternal = function() {
+ dispatchEvent(this, EventType.A);
+ goog.base(this, 'disposeInternal');
+ };
+
+ var t = new MockTarget();
+ try {
+ listen(t, EventType.A, listeners[0]);
+ t.dispose();
+ assertListenerIsCalled(listeners[0], times(1));
+ } catch (e) {
+ goog.dispose(t);
+ }
+}

0 comments on commit 191b910

Please sign in to comment.