Don't let button controls interfer with handlers.

This change involves removal of the map's eventsDiv and introduces an OpenLayers.Events.buttonclick component that adds a buttonclick event which makes sure that only events that are not related to clicking a button propagate. This allows button controls to be on the map's viewPortDiv again.
This commit is contained in:
ahocevar
2012-01-20 03:37:11 +01:00
parent e68acfe91a
commit 05de2b5109
22 changed files with 520 additions and 224 deletions

View File

@@ -168,22 +168,26 @@
//up
var delta = [0, -50];
var dir = "up";
control.buttonDown.call(buttons[0], evt);
evt.button = buttons[0];
control.onButtonClick.call(control, evt);
//left
var delta = [-125, 0];
var dir = "left";
control.buttonDown.call(buttons[1], evt);
evt.button = buttons[1];
control.onButtonClick.call(control, evt);
//right
var delta = [125, 0];
var dir = "right";
control.buttonDown.call(buttons[2], evt);
evt.button = buttons[2];
control.onButtonClick.call(control, evt);
//down
var delta = [0, 50];
var dir = "down";
control.buttonDown.call(buttons[3], evt);
evt.button = buttons[3];
control.onButtonClick.call(control, evt);
map.destroy();
}

View File

@@ -82,7 +82,7 @@
"activated one tool control, the other one is inactive and the toggle & button controls also.");
panel.activateControl(toggleControl);
t.eq(toggleControl.panel_div.className,"mbControlTestToggleItemActive",
t.eq(toggleControl.panel_div.className,"mbControlTestToggleItemActive olButton",
"className of icon div for toggle control is active.");
t.ok(toolControl.active && !anotherToolControl.active && toggleControl.active,
"activated the toggle control, which has no influence on the tool & togggle controls.");
@@ -96,9 +96,9 @@
"activated the button control, which has no influence on the tool & togggle controls.");
panel.activateControl(anotherToolControl);
t.eq(anotherToolControl.panel_div.className,"mbControlTestToolItemActive",
t.eq(anotherToolControl.panel_div.className,"mbControlTestToolItemActive olButton",
"className of icon div for anotherToolControl is active.");
t.eq(toolControl.panel_div.className,"olControlZoomBoxItemInactive",
t.eq(toolControl.panel_div.className,"olControlZoomBoxItemInactive olButton",
"className of icon div for toolControl is inactive.");
t.ok(!toolControl.active && anotherToolControl.active && toggleControl.active,
"activated the other tool control, the first one is inactive and the toggle control still active.");

View File

@@ -82,7 +82,7 @@
function test_Events_register_unregister(t) {
t.plan(19);
t.plan(20);
var mapDiv = OpenLayers.Util.getElement('map');
var obj = {result: 0};
@@ -165,6 +165,9 @@
} catch (err) {
t.fail("unregistering for an event with no registered listeners causes trouble: " + err);
}
events.register("buttonclick", obj, func);
t.ok(events.extensions.buttonclick, "buttonclick extension registered");
}

View File

@@ -0,0 +1,133 @@
<html>
<head>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
var log, buttonClick, events, element, button;
function init() {
element = document.getElementById("map");
button = document.getElementById("button");
}
function trigger(evt) {
OpenLayers.Util.applyDefaults(evt, {
button: 1,
target: button
});
buttonClick._buttonClick(evt);
events.handleBrowserEvent(evt);
}
function logEvent(evt) {
log.push(evt);
}
function test_ButtonClick(t) {
t.plan(2);
events = new OpenLayers.Events({}, document.getElementById("map"));
buttonClick = new OpenLayers.Events.buttonclick({target: events});
t.ok(buttonClick.target === events, "target set from options argument");
buttonClick = new OpenLayers.Events.buttonclick(events);
t.ok(buttonClick.target === events, "target set from constructor arg");
buttonClick.destroy();
events.destroy();
}
function test_ButtonClick_buttonClick(t) {
t.plan(23);
events = new OpenLayers.Events({}, element);
events.on({
"buttonclick": logEvent,
"mousedown": logEvent,
"mouseup": logEvent,
"click": logEvent,
"dblclick": logEvent,
"touchstart": logEvent,
"touchend": logEvent
});
buttonClick = events.extensions["buttonclick"];
// a complete click
log = [];
trigger({type: "mousedown"});
trigger({type: "mouseup"});
t.eq(log.length, 1, "one event fired for mousedown-mouseup");
t.eq(log[0].type, "buttonclick", "buttonclick event fired");
// a complete tap
log = [];
trigger({type: "touchstart"});
trigger({type: "touchend"});
t.eq(log.length, 1, "one event fired for touchstart-touchend");
t.eq(log[0].type, "buttonclick", "buttonclick event fired");
// mouse sequence started on button
log = [];
trigger({type: "mousedown"});
trigger({type: "mouseup", target: element});
t.eq(log.length, 1, "one event fired for mousedown-(leave)-mouseup");
t.eq(log[0].type, "mouseup", "mouseup event goes through when sequence not finished on button");
// touch sequence started on button
log = [];
trigger({type: "touchstart"});
trigger({type: "touchmove"});
trigger({type: "touchend"});
t.eq(log.length, 1, "one event fired for touchstart-(leave)-touchend");
t.eq(log[0].type, "touchend", "touchend event goes through when sequence not finished on button");
// mouse sequence finished on button
log = [];
trigger({type: "mousedown", target: element});
trigger({type: "mouseup"});
t.eq(log.length, 2, "two event fired for mousedown-(enter)-mouseup");
t.eq(log[0].type, "mousedown", "mousedown unrelated to button goes through");
t.eq(log[1].type, "mouseup", "mouseup goes through when sequence started outside button");
// touch sequence finished on button
log = [];
trigger({type: "touchstart", target: element});
trigger({type: "touchend"});
t.eq(log.length, 2, "two event fired for touchstart-(enter)-touchend");
t.eq(log[0].type, "touchstart", "touchstart unrelated to button goes through");
t.eq(log[1].type, "touchend", "touchend goes through when sequence started outside button");
// dblclick
log = [];
trigger({type: "mousedown"});
trigger({type: "mouseup"});
trigger({type: "click"});
trigger({type: "mousedown"});
trigger({type: "mouseup"});
trigger({type: "click"});
trigger({type: "dblclick"});
t.eq(log.length, 2, "two events fired for doubleclick");
t.eq(log[0].type, "buttonclick", "buttonclick for 1st click");
t.eq(log[1].type, "buttonclick", "buttonclick for 2nd click");
// dblclick - IE
log = [];
trigger({type: "mousedown"});
trigger({type: "mouseup"});
trigger({type: "mouseup"});
trigger({type: "dblclick"});
t.eq(log.length, 2, "two events fired for dblclick in IE");
t.eq(log[0].type, "buttonclick", "buttonclick for 1st click in IE");
t.eq(log[1].type, "buttonclick", "buttonclick for 2nd click IE");
// rightclick
log = []
trigger({type: "mousedown", button: 2});
trigger({type: "mouseup", button: 2});
t.eq(log.length, 2, "two events fired for rightclick");
t.eq(log[0].type, "mousedown", "mousedown from rightclick goes through");
t.eq(log[1].type, "mouseup", "mouseup from rightclick goes through");
}
</script>
</head>
<body onload="init()">
<div id="map" style="width: 600px; height: 300px;">
<div id="button" class="olButton">
<img class="olAlphaImg">
</div>
</div>
</body>
</html>

View File

@@ -252,7 +252,7 @@
t.ok(evt.xy.x == testEvents.done.xy.x &&
evt.xy.y == testEvents.done.xy.y,
"mouseout calls Util.mouseLeft with the correct event");
t.eq(element.id, map.eventsDiv.id,
t.eq(element.id, map.viewPortDiv.id,
"mouseout calls Util.mouseLeft with the correct element");
return true;
}

View File

@@ -94,9 +94,9 @@
if (document.createEvent) { // Mozilla
var evObj = document.createEvent('MouseEvents');
evObj.initEvent('mousemove', true, false);
map.eventsDiv.dispatchEvent(evObj);
map.viewPortDiv.dispatchEvent(evObj);
} else if(document.createEventObject) { // IE
map.eventsDiv.fireEvent('onmousemove');
map.viewPortDiv.fireEvent('onmousemove');
}
t.eq(log.length, 1, "got one event");

View File

@@ -46,6 +46,7 @@
<li>Control/PanPanel.html</li>
<li>Control/SLDSelect.html</li>
<li>Events.html</li>
<li>Events/buttonclick.html</li>
<li>Extras.html</li>
<li>Feature.html</li>
<li>Feature/Vector.html</li>