@qooxdoo/framework
Version:
The JS Framework for Coders
484 lines (404 loc) • 11.7 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2007-2008 1&1 Internet AG, Germany, http://www.1und1.de
License:
MIT: https://opensource.org/licenses/MIT
See the LICENSE file in the project's top-level directory for details.
Authors:
* Fabian Jakobs (fjakobs)
************************************************************************ */
/**
* @use(qx.test.event.MockBubblingHandler)
*/
qx.Class.define("qx.test.event.Bubbling", {
extend: qx.dev.unit.TestCase,
events: {
nonBubble: "qx.event.type.Event"
},
members: {
setUp() {
var root = qx.dom.Element.create("div", { id: "root" });
document.body.appendChild(root);
// root
// c_1
// c_1_1
// c_2
root.innerHTML =
"<div id='c_1'>" +
"<div id='c_1_1'></div>" +
"</div>" +
"<div id='c_2'>";
this.c_1 = document.getElementById("c_1");
this.c_1_1 = document.getElementById("c_1_1");
this.c_2 = document.getElementById("c_2");
},
tearDown() {
var Reg = qx.event.Registration;
Reg.removeAllListeners(this.c_1);
Reg.removeAllListeners(this.c_1_1);
Reg.removeAllListeners(this.c_2);
document.body.removeChild(document.getElementById("root"));
},
testBubbling() {
var Reg = qx.event.Registration;
var called;
Reg.addListener(
this.c_1,
"bubble",
function () {
called.push("c_1a");
},
this
);
Reg.addListener(
this.c_1,
"bubble",
function () {
called.push("c_1b");
},
this
);
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1a");
},
this
);
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1b");
},
this
);
Reg.addListener(
this.c_2,
"bubble",
function () {
called.push("c_2a");
},
this
);
Reg.addListener(
this.c_2,
"bubble",
function () {
called.push("c_2b");
},
this
);
// fire event on c_1
called = [];
Reg.fireEvent(this.c_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a", "c_1b"], called);
// fire event on c_1_1
called = [];
Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1_1a", "c_1_1b", "c_1a", "c_1b"], called);
// fire event on c_2
called = [];
Reg.fireEvent(this.c_2, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_2a", "c_2b"], called);
},
testContext() {
var Reg = qx.event.Registration;
var called;
var contexts;
Reg.addListener(this.c_1, "bubble", function () {
called.push("c_1");
contexts.push(this);
});
Reg.addListener(this.c_1_1, "bubble", function () {
called.push("c_1_1a");
contexts.push(this);
});
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1b");
contexts.push(this);
},
this
);
called = [];
contexts = [];
Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1_1a", "c_1_1b", "c_1"], called);
this.assertEquals(3, contexts.length);
this.assertEquals(this.c_1_1, contexts[0]);
this.assertEquals(this, contexts[1]);
this.assertEquals(this.c_1, contexts[2]);
},
testCapture() {
var Reg = qx.event.Registration;
var called;
Reg.addListener(
this.c_1,
"bubble",
function () {
called.push("c_1a");
},
this,
true
);
Reg.addListener(
this.c_1,
"bubble",
function () {
called.push("c_1b");
},
this
);
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1a");
},
this,
true
);
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1b");
},
this
);
Reg.addListener(
this.c_2,
"bubble",
function () {
called.push("c_2a");
},
this,
true
);
Reg.addListener(
this.c_2,
"bubble",
function () {
called.push("c_2b");
},
this
);
// fire event on c_1
called = [];
Reg.fireEvent(this.c_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a", "c_1b"], called);
// fire event on c_1_1
called = [];
Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a", "c_1_1a", "c_1_1b", "c_1b"], called);
// fire event on c_2
called = [];
Reg.fireEvent(this.c_2, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_2a", "c_2b"], called);
},
_stopPropagation(e) {
e.stopPropagation();
},
testStopPropagation() {
var Reg = qx.event.Registration;
var called;
// stop is first handler (capturing) -> handlers on the same level must be called
Reg.addListener(this.c_1, "bubble", this._stopPropagation, this, true);
Reg.addListener(
this.c_1,
"bubble",
function () {
called.push("c_1a");
},
this,
true
);
Reg.addListener(
this.c_1,
"bubble",
function () {
called.push("c_1b");
},
this
);
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1a");
},
this,
true
);
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1b");
},
this
);
Reg.addListener(
this.c_2,
"bubble",
function () {
called.push("c_2a");
},
this,
true
);
Reg.addListener(
this.c_2,
"bubble",
function () {
called.push("c_2b");
},
this
);
// fire event on c_1
called = [];
Reg.fireEvent(this.c_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a"], called);
// fire event on c_1_1
called = [];
Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a"], called);
// fire event on c_2
called = [];
Reg.fireEvent(this.c_2, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_2a", "c_2b"], called);
// stop is on target (capturing)
Reg.removeListener(this.c_1, "bubble", this._stopPropagation, this, true);
Reg.addListener(this.c_1_1, "bubble", this._stopPropagation, this, true);
// fire event on c_1
called = [];
Reg.fireEvent(this.c_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a", "c_1b"], called);
// fire event on c_1_1
called = [];
Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a", "c_1_1a"], called);
// fire event on c_2
called = [];
Reg.fireEvent(this.c_2, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_2a", "c_2b"], called);
// stop is on target (bubbling)
Reg.removeListener(
this.c_1_1,
"bubble",
this._stopPropagation,
this,
true
);
Reg.addListener(this.c_1_1, "bubble", this._stopPropagation, this, false);
// fire event on c_1
called = [];
Reg.fireEvent(this.c_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a", "c_1b"], called);
// fire event on c_1_1
called = [];
Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_1a", "c_1_1a", "c_1_1b"], called);
// fire event on c_2
called = [];
Reg.fireEvent(this.c_2, "bubble", qx.event.type.Event, [true, true]);
this.assertJsonEquals(["c_2a", "c_2b"], called);
},
_preventDefault(e) {
e.preventDefault();
},
testPreventDefault() {
var Reg = qx.event.Registration;
var called;
// baseline: no prevent default
Reg.addListener(
this.c_1,
"bubble",
function () {
called.push("c_1a");
},
this
);
Reg.addListener(
this.c_1_1,
"bubble",
function () {
called.push("c_1_1a");
},
this
);
called = [];
var prevent = Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [
true,
true
]);
this.assertTrue(prevent);
this.assertJsonEquals(["c_1_1a", "c_1a"], called);
// prevent default on parent
Reg.addListener(this.c_1, "bubble", this._preventDefault, this);
called = [];
var prevent = Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [
true,
true
]);
this.assertFalse(prevent);
this.assertJsonEquals(["c_1_1a", "c_1a"], called);
// stop propagation before prevent default can be called
Reg.addListener(this.c_1_1, "bubble", this._stopPropagation, this);
called = [];
var prevent = Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [
true,
true
]);
this.assertTrue(prevent);
this.assertJsonEquals(["c_1_1a"], called);
Reg.removeListener(this.c_1_1, "bubble", this._stopPropagation, this);
// prevent default on target
Reg.removeListener(this.c_1, "bubble", this._preventDefault, this);
Reg.addListener(this.c_1_1, "bubble", this._preventDefault, this);
called = [];
var prevent = Reg.fireEvent(this.c_1_1, "bubble", qx.event.type.Event, [
true,
true
]);
this.assertFalse(prevent);
this.assertJsonEquals(["c_1_1a", "c_1a"], called);
// test on non bubbling events
this.addListener("nonBubble", this._preventDefault, this);
var prevent = Reg.fireEvent(this, "nonBubble", qx.event.type.Event, [
false,
true
]);
this.assertFalse(prevent);
this.removeListener("nonBubble", this._preventDefault, this);
// assert that non cancelable event raise an exception
this.addListener("nonBubble", this._preventDefault, this);
var self = this;
if (this.isDebugOn()) {
this.assertException(
function () {
Reg.fireEvent(self, "nonBubble", qx.event.type.Event, [
false,
false
]);
},
qx.core.AssertionError,
"Cannot prevent default action on a non cancelable event.*"
);
}
this.removeListener("nonBubble", this._preventDefault, this);
// fire event with no listener -> should never be prevented
var prevent = Reg.fireEvent(this, "nonBubble", qx.event.type.Event, [
false,
true
]);
this.assertTrue(prevent);
}
}
});