From 05de2b5109f8bf94da423c98cec2e676232e3de6 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 20 Jan 2012 03:37:11 +0100 Subject: [PATCH] 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. --- lib/OpenLayers.js | 1 + lib/OpenLayers/Control/LayerSwitcher.js | 110 ++++++----------- lib/OpenLayers/Control/OverviewMap.js | 62 +++++----- lib/OpenLayers/Control/PanZoom.js | 85 ++++++-------- lib/OpenLayers/Control/Panel.js | 47 ++++---- lib/OpenLayers/Events.js | 86 ++++++++++++-- lib/OpenLayers/Events/buttonclick.js | 150 ++++++++++++++++++++++++ lib/OpenLayers/Handler/Box.js | 8 +- lib/OpenLayers/Handler/Drag.js | 2 +- lib/OpenLayers/Handler/Hover.js | 2 +- lib/OpenLayers/Handler/Point.js | 2 +- lib/OpenLayers/Layer/EventPane.js | 2 +- lib/OpenLayers/Map.js | 13 +- lib/OpenLayers/Util.js | 1 + lib/deprecated.js | 10 +- tests/Control/PanZoom.html | 12 +- tests/Control/Panel.html | 6 +- tests/Events.html | 5 +- tests/Events/buttonclick.html | 133 +++++++++++++++++++++ tests/Handler/Drag.html | 2 +- tests/Layer/EventPane.html | 4 +- tests/list-tests.html | 1 + 22 files changed, 520 insertions(+), 224 deletions(-) create mode 100644 lib/OpenLayers/Events/buttonclick.js create mode 100644 tests/Events/buttonclick.html diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index c8bab14984..3ffa1b6a84 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -111,6 +111,7 @@ "Rico/Corner.js", "Rico/Color.js", "OpenLayers/Events.js", + "OpenLayers/Events/buttonclick.js", "OpenLayers/Request.js", "OpenLayers/Request/XMLHttpRequest.js", "OpenLayers/Projection.js", diff --git a/lib/OpenLayers/Control/LayerSwitcher.js b/lib/OpenLayers/Control/LayerSwitcher.js index 3f81b3bfdc..552b650155 100644 --- a/lib/OpenLayers/Control/LayerSwitcher.js +++ b/lib/OpenLayers/Control/LayerSwitcher.js @@ -7,6 +7,7 @@ * @requires OpenLayers/Control.js * @requires OpenLayers/Lang.js * @requires OpenLayers/Console.js + * @requires OpenLayers/Events/buttonclick.js */ /** @@ -130,20 +131,16 @@ OpenLayers.Control.LayerSwitcher = */ destroy: function() { - OpenLayers.Event.stopObservingElement(this.div); - - OpenLayers.Event.stopObservingElement(this.minimizeDiv); - OpenLayers.Event.stopObservingElement(this.maximizeDiv); - //clear out layers info and unregister their events this.clearLayersArray("base"); this.clearLayersArray("data"); this.map.events.un({ - "addlayer": this.redraw, - "changelayer": this.redraw, - "removelayer": this.redraw, - "changebaselayer": this.redraw, + buttonclick: this.onButtonClick, + addlayer: this.redraw, + changelayer: this.redraw, + removelayer: this.redraw, + changebaselayer: this.redraw, scope: this }); @@ -160,10 +157,11 @@ OpenLayers.Control.LayerSwitcher = OpenLayers.Control.prototype.setMap.apply(this, arguments); this.map.events.on({ - "addlayer": this.redraw, - "changelayer": this.redraw, - "removelayer": this.redraw, - "changebaselayer": this.redraw, + buttonclick: this.onButtonClick, + addlayer: this.redraw, + changelayer: this.redraw, + removelayer: this.redraw, + changebaselayer: this.redraw, scope: this }); }, @@ -192,6 +190,20 @@ OpenLayers.Control.LayerSwitcher = return this.div; }, + /** + * Method: onButtonClick + * + * Parameters: + * evt - {Event} + */ + onButtonClick: function(evt) { + if (evt.button === this.minimizeDiv) { + this.minimizeControl(); + } else if (evt.button === this.maximizeDiv) { + this.maximizeControl(); + }; + }, + /** * Method: clearLayersArray * User specifies either "base" or "data". we then clear all the @@ -317,10 +329,11 @@ OpenLayers.Control.LayerSwitcher = 'layer': layer, 'layerSwitcher': this }; - OpenLayers.Event.observe(inputElem, "mouseup", - OpenLayers.Function.bindAsEventListener(this.onInputClick, - context) + var onInputClick = OpenLayers.Function.bindAsEventListener( + this.onInputClick, context ); + OpenLayers.Event.observe(inputElem, "mousedown", onInputClick); + OpenLayers.Event.observe(inputElem, "touchstart", onInputClick); // create span var labelSpan = document.createElement("span"); @@ -331,10 +344,8 @@ OpenLayers.Control.LayerSwitcher = labelSpan.innerHTML = layer.name; labelSpan.style.verticalAlign = (baseLayer) ? "bottom" : "baseline"; - OpenLayers.Event.observe(labelSpan, "click", - OpenLayers.Function.bindAsEventListener(this.onInputClick, - context) - ); + OpenLayers.Event.observe(labelSpan, "click", onInputClick); + OpenLayers.Event.observe(labelSpan, "touchstart", onInputClick); // create line break var br = document.createElement("br"); @@ -500,16 +511,6 @@ OpenLayers.Control.LayerSwitcher = */ loadContents: function() { - //configure main div - - OpenLayers.Event.observe(this.div, "mouseup", - OpenLayers.Function.bindAsEventListener(this.mouseUp, this)); - OpenLayers.Event.observe(this.div, "click", - this.ignoreEvent); - OpenLayers.Event.observe(this.div, "mousedown", - OpenLayers.Function.bindAsEventListener(this.mouseDown, this)); - OpenLayers.Event.observe(this.div, "dblclick", this.ignoreEvent); - // layers list div this.layersDiv = document.createElement("div"); this.layersDiv.id = this.id + "_layersDiv"; @@ -561,11 +562,8 @@ OpenLayers.Control.LayerSwitcher = null, img, "absolute"); - OpenLayers.Element.addClass(this.maximizeDiv, "maximizeDiv"); + OpenLayers.Element.addClass(this.maximizeDiv, "maximizeDiv olButton"); this.maximizeDiv.style.display = "none"; - OpenLayers.Event.observe(this.maximizeDiv, "click", - OpenLayers.Function.bindAsEventListener(this.maximizeControl, this) - ); this.div.appendChild(this.maximizeDiv); @@ -577,53 +575,11 @@ OpenLayers.Control.LayerSwitcher = null, img, "absolute"); - OpenLayers.Element.addClass(this.minimizeDiv, "minimizeDiv"); + OpenLayers.Element.addClass(this.minimizeDiv, "minimizeDiv olButton"); this.minimizeDiv.style.display = "none"; - OpenLayers.Event.observe(this.minimizeDiv, "click", - OpenLayers.Function.bindAsEventListener(this.minimizeControl, this) - ); this.div.appendChild(this.minimizeDiv); }, - /** - * Method: ignoreEvent - * - * Parameters: - * evt - {Event} - */ - ignoreEvent: function(evt) { - OpenLayers.Event.stop(evt); - }, - - /** - * Method: mouseDown - * Register a local 'mouseDown' flag so that we'll know whether or not - * to ignore a mouseUp event - * - * Parameters: - * evt - {Event} - */ - mouseDown: function(evt) { - this.isMouseDown = true; - this.ignoreEvent(evt); - }, - - /** - * Method: mouseUp - * If the 'isMouseDown' flag has been set, that means that the drag was - * started from within the LayerSwitcher control, and thus we can - * ignore the mouseup. Otherwise, let the Event continue. - * - * Parameters: - * evt - {Event} - */ - mouseUp: function(evt) { - if (this.isMouseDown) { - this.isMouseDown = false; - this.ignoreEvent(evt); - } - }, - CLASS_NAME: "OpenLayers.Control.LayerSwitcher" }); diff --git a/lib/OpenLayers/Control/OverviewMap.js b/lib/OpenLayers/Control/OverviewMap.js index 4c92522bb0..ee21cc4b26 100644 --- a/lib/OpenLayers/Control/OverviewMap.js +++ b/lib/OpenLayers/Control/OverviewMap.js @@ -6,7 +6,7 @@ /** * @requires OpenLayers/Control.js * @requires OpenLayers/BaseTypes.js - * @requires OpenLayers/Events.js + * @requires OpenLayers/Events/buttonclick.js */ /** @@ -157,7 +157,7 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, { this.handlers.drag.destroy(); } - this.ovmap && this.ovmap.eventsDiv.removeChild(this.extentRectangle); + this.ovmap && this.ovmap.viewPortDiv.removeChild(this.extentRectangle); this.extentRectangle = null; if (this.rectEvents) { @@ -177,20 +177,19 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, { this.element = null; if (this.maximizeDiv) { - OpenLayers.Event.stopObservingElement(this.maximizeDiv); this.div.removeChild(this.maximizeDiv); this.maximizeDiv = null; } if (this.minimizeDiv) { - OpenLayers.Event.stopObservingElement(this.minimizeDiv); this.div.removeChild(this.minimizeDiv); this.minimizeDiv = null; } this.map.events.un({ - "moveend": this.update, - "changebaselayer": this.baseLayerDraw, + buttonclick: this.onButtonClick, + moveend: this.update, + changebaselayer: this.baseLayerDraw, scope: this }); @@ -247,11 +246,7 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, { img, 'absolute'); this.maximizeDiv.style.display = 'none'; - this.maximizeDiv.className = this.displayClass + 'MaximizeButton'; - OpenLayers.Event.observe(this.maximizeDiv, 'click', - OpenLayers.Function.bindAsEventListener(this.maximizeControl, - this) - ); + this.maximizeDiv.className = this.displayClass + 'MaximizeButton olButton'; this.div.appendChild(this.maximizeDiv); // minimize button div @@ -263,26 +258,8 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, { img, 'absolute'); this.minimizeDiv.style.display = 'none'; - this.minimizeDiv.className = this.displayClass + 'MinimizeButton'; - OpenLayers.Event.observe(this.minimizeDiv, 'click', - OpenLayers.Function.bindAsEventListener(this.minimizeControl, - this) - ); - this.div.appendChild(this.minimizeDiv); - - var eventsToStop = ['dblclick','mousedown']; - - for (var i=0, len=eventsToStop.length; i} + */ + setMap: function(map) { + OpenLayers.Control.prototype.setMap.apply(this, arguments); + this.map.events.register("buttonclick", this, this.onButtonClick); + }, + /** * Method: draw * @@ -126,30 +141,9 @@ OpenLayers.Control.PanZoom = OpenLayers.Class(OpenLayers.Control, { btn.style.cursor = "pointer"; //we want to add the outer div this.div.appendChild(btn); - - OpenLayers.Event.observe(btn, "mousedown", - OpenLayers.Function.bindAsEventListener(this.buttonDown, btn)); - OpenLayers.Event.observe(btn, "dblclick", - OpenLayers.Function.bindAsEventListener(this.doubleClick, btn)); - OpenLayers.Event.observe(btn, "click", - OpenLayers.Function.bindAsEventListener(this.doubleClick, btn)); btn.action = id; - btn.map = this.map; + btn.className = "olButton"; - if(!this.slideRatio){ - var slideFactorPixels = this.slideFactor; - var getSlideFactor = function() { - return slideFactorPixels; - }; - } else { - var slideRatio = this.slideRatio; - var getSlideFactor = function(dim) { - return this.map.getSize()[dim] * slideRatio; - }; - } - - btn.getSlideFactor = getSlideFactor; - //we want to remember/reference the outer div this.buttons.push(btn); return btn; @@ -162,9 +156,6 @@ OpenLayers.Control.PanZoom = OpenLayers.Class(OpenLayers.Control, { * btn - {Object} */ _removeButton: function(btn) { - OpenLayers.Event.stopObservingElement(btn); - btn.map = null; - btn.getSlideFactor = null; this.div.removeChild(btn); OpenLayers.Util.removeItem(this.buttons, btn); }, @@ -179,31 +170,14 @@ OpenLayers.Control.PanZoom = OpenLayers.Class(OpenLayers.Control, { }, /** - * Method: doubleClick + * Method: onButtonClick * * Parameters: - * evt - {Event} - * - * Returns: - * {Boolean} + * evt - {Event} */ - doubleClick: function (evt) { - OpenLayers.Event.stop(evt); - return false; - }, - - /** - * Method: buttonDown - * - * Parameters: - * evt - {Event} - */ - buttonDown: function (evt) { - if (!OpenLayers.Event.isLeftClick(evt)) { - return; - } - - switch (this.action) { + onButtonClick: function(evt) { + var btn = evt.button; + switch (btn.action) { case "panup": this.map.pan(0, -this.getSlideFactor("h")); break; @@ -226,8 +200,21 @@ OpenLayers.Control.PanZoom = OpenLayers.Class(OpenLayers.Control, { this.map.zoomToMaxExtent(); break; } - - OpenLayers.Event.stop(evt); + }, + + /** + * Method: getSlideFactor + * + * Parameters: + * dim - {String} "w" or "h" (for width or height). + * + * Returns: + * {Number} The slide factor for panning in the requested direction. + */ + getSlideFactor: function(dim) { + return this.slideRatio ? + this.map.getSize()[dim] * this.slideRatio : + this.slideFactor; }, CLASS_NAME: "OpenLayers.Control.PanZoom" diff --git a/lib/OpenLayers/Control/Panel.js b/lib/OpenLayers/Control/Panel.js index 4c6e7e6183..8b77c5272f 100644 --- a/lib/OpenLayers/Control/Panel.js +++ b/lib/OpenLayers/Control/Panel.js @@ -5,6 +5,7 @@ /** * @requires OpenLayers/Control.js + * @requires OpenLayers/Events/buttonclick.js */ /** @@ -103,6 +104,9 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, { * APIMethod: destroy */ destroy: function() { + if (this.map) { + this.map.events.unregister("buttonclick", this, this.onButtonClick); + } OpenLayers.Control.prototype.destroy.apply(this, arguments); for (var ctl, i = this.controls.length - 1; i >= 0; i--) { ctl = this.controls[i]; @@ -112,7 +116,6 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, { deactivate: this.iconOff }); } - OpenLayers.Event.stopObservingElement(ctl.panel_div); ctl.panel_div = null; } this.activeState = null; @@ -166,6 +169,12 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, { */ draw: function() { OpenLayers.Control.prototype.draw.apply(this, arguments); + if (this.div.parentNode === this.map.viewPortDiv) { + map.events.register("buttonclick", this, this.onButtonClick); + } else { + this.events.element = this.div; + this.events.register("buttonclick", this, this.onButtonClick); + } this.addControlsToMap(this.controls); return this.div; }, @@ -184,7 +193,7 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, { } } }, - + /** * APIMethod: activateControl * This method is called when the user click on the icon representing a @@ -244,17 +253,11 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, { // since they need to pass through. for (var i=0, len=controls.length; i=0; --i) { + if (controls[i].panel_div === button) { + this.activateControl(controls[i]); + break; + } + } }, /** diff --git a/lib/OpenLayers/Events.js b/lib/OpenLayers/Events.js index d3c96ae13e..c6ab5592c9 100644 --- a/lib/OpenLayers/Events.js +++ b/lib/OpenLayers/Events.js @@ -155,13 +155,18 @@ OpenLayers.Event = { * Parameters: * event - {Event} * allowDefault - {Boolean} If true, we stop the event chain but - * still allow the default browser - * behaviour (text selection, radio-button - * clicking, etc) - * Default false + * still allow the default browser behaviour (text selection, + * radio-button clicking, etc). Default is false. + * terminate - {Boolean} If true, no more listeners registered through an + * instance on the same event on the same element + * will receive this event. Extensions that call should set + * this to true. Default is false. */ - stop: function(event, allowDefault) { + stop: function(event, allowDefault, terminate) { + if (terminate) { + event._terminated = true; + } if (!allowDefault) { if (event.preventDefault) { event.preventDefault(); @@ -450,6 +455,26 @@ OpenLayers.Events = OpenLayers.Class({ * the location of the element in the page changes */ includeXY: false, + + /** + * Property: extensions + * {Object} Event extensions registered with this instance. Keys are + * event types, values are extension instances. + * + * Extensions create an event in addition to browser events, which usually + * fires when a sequence of browser events is completed. Extensions are + * automatically instantiated when a listener is registered for an event + * provided by an extension. + * + * Extesions are created in the namespace using + * , and named after the event they provide. + * The constructor recieves the target instance as + * argument. Extensions are expected to have an "observe" method, which is + * called to register its sequence events on the target's dom element, + * using . See + * for a reference implementation. + */ + extensions: null, /** * Method: clearMouseListener @@ -478,6 +503,7 @@ OpenLayers.Events = OpenLayers.Class({ this.object = object; this.fallThrough = fallThrough; this.listeners = {}; + this.extensions = {}; // if a dom element is specified, add a listeners list // for browser events on the element and register them @@ -500,6 +526,12 @@ OpenLayers.Events = OpenLayers.Class({ * APIMethod: destroy */ destroy: function () { + for (var e in this.extensions) { + if (typeof this.extensions[e].destroy === "function") { + this.extensions[e].destroy(); + } + } + this.extensions = null; if (this.element) { OpenLayers.Event.stopObservingElement(this.element); if(this.element.hasScrollEvent) { @@ -531,9 +563,15 @@ OpenLayers.Events = OpenLayers.Class({ * * Parameters: * element - {HTMLDOMElement} a DOM element to attach browser events to + * options - {Object} Additional options for his method. + * + * Valid options: + * keepElement - {Boolean} If set to true, the instance will not stop + * observing events on an element it was previously attached to. */ - attachToElement: function (element) { - if(this.element) { + attachToElement: function (element, options) { + options = options || {}; + if(this.element && !options.keepElement) { OpenLayers.Event.stopObservingElement(this.element); } this.element = element; @@ -547,6 +585,33 @@ OpenLayers.Events = OpenLayers.Class({ OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop); }, + /** + * Method: addExtension + * Adds an extension event to this instance. + * + * Parameters: + * type - {String} the name of the extension event type to add + */ + addExtension: function(type) { + if (this.element.attachEvent && !this.element.addEventListener) { + // old IE - last registered, first triggered. No need to + // re-register the events to get them in a working order + this.extensions[type] = new OpenLayers.Events[type](this); + } else { + // Other browsers - last registered, last triggered. We stop + // observing the element, let the extensions register their browser + // events, and then we attach this instance to the element again. + OpenLayers.Event.stopObservingElement(this.element); + for (var t in this.extensions) { + if (typeof this.extensions[t].observe === "function") { + this.extensions[t].observe(); + } + } + this.extensions[type] = new OpenLayers.Events[type](this); + this.attachToElement(this.element, {keepElement: true}); + } + }, + /** * APIMethod: on * Convenience method for registering listeners with a common scope. @@ -612,6 +677,9 @@ OpenLayers.Events = OpenLayers.Class({ * the events queue instead of to the end. */ register: function (type, obj, func, priority) { + if (type in OpenLayers.Events && !this.extensions[type]) { + this.addExtension(type); + } if (func != null) { if (obj == null) { obj = this.object; @@ -784,8 +852,8 @@ OpenLayers.Events = OpenLayers.Class({ */ handleBrowserEvent: function (evt) { var type = evt.type, listeners = this.listeners[type]; - if(!listeners || listeners.length == 0) { - // noone's listening, bail out + if(!listeners || listeners.length == 0 || evt._terminated) { + // noone's listening or event was terminated through , bail out return; } // add clientX & clientY to all events - corresponds to average x, y diff --git a/lib/OpenLayers/Events/buttonclick.js b/lib/OpenLayers/Events/buttonclick.js new file mode 100644 index 0000000000..79b0403bdc --- /dev/null +++ b/lib/OpenLayers/Events/buttonclick.js @@ -0,0 +1,150 @@ +/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for + * full list of contributors). Published under the Clear BSD license. + * See http://svn.openlayers.org/trunk/openlayers/license.txt for the + * full text of the license. */ + +/** + * @requires OpenLayers/Events.js + */ + +/** + * Class: OpenLayers.Events.buttonclick + * Extension event type for handling buttons on top of a dom element. This + * event type fires "buttonclick" on its when a button was + * clicked. Buttons are detected by the "olButton" class. + * + * This event type makes sure that button clicks do not interfer with other + * events that are registered on the same . + */ +OpenLayers.Events.buttonclick = OpenLayers.Class({ + + /** + * APIProperty: target + * {} The events instance that the buttonclick event will + * be triggered on. + */ + target: null, + + /** + * Property: events + * {Array} Events to observe and conditionally stop from propagating when + * an element with the olButton (or its olAlphaImg child) is clicked. + */ + events: [ + 'mousedown', 'mouseup', 'click', 'dblclick', + 'touchstart', 'touchmove', 'touchend' + ], + + /** + * Property: startRegEx + * {RegExp} Regular expression to test Event.type for events that start + * a buttonclick sequence. + */ + startRegEx: /^mousedown|touchstart$/, + + /** + * Property: cancelRegEx + * {RegExp} Regular expression to test Event.type for events that cancel + * a buttonclick sequence. + */ + cancelRegEx: /^touchmove$/, + + /** + * Property: completeRegEx + * {RegExp} Regular expression to test Event.type for events that complete + * a buttonclick sequence. + */ + completeRegEx: /^mouseup|touchend$/, + + /** + * Constructor: OpenLayers.Events.buttonclick + * Construct a buttonclick event type. Applications are not supposed to + * create instances of this class - they are created on demand by + * instances. + * + * Parameters: + * options - {|Object} Target instance of + * or configuration properties for this + * instance. + * + * Required configuration properties: + * target - {} The events instance that the buttonclick + * event will be triggered on. + */ + initialize: function(options) { + if (options instanceof OpenLayers.Events) { + options = {target: options}; + } + OpenLayers.Util.extend(this, options); + + this._buttonClick = OpenLayers.Function.bindAsEventListener( + this.buttonClick, this + ); + this.observe(); + }, + + /** + * Method: observe + */ + observe: function() { + for (var i=this.events.length-1; i>=0; --i) { + OpenLayers.Event.observe( + this.target.element, this.events[i], this._buttonClick + ); + }; + }, + + /** + * Method: stopObserving + */ + stopObserving: function() { + for (var i=this.events.length-1; i>=0; --i) { + OpenLayers.Event.stopObserving( + this.target.element, this.events[i], this._buttonClick + ); + } + }, + + /** + * Method: destroy + */ + destroy: function() { + this.stopObserving() + }, + + /** + * Method: buttonClick + * Check if a button was clicked, and fire the buttonclick event + * + * Parameters: + * evt - {Event} + */ + buttonClick: function(evt) { + if (OpenLayers.Event.isLeftClick(evt) || !~evt.type.indexOf("mouse")) { + var element = OpenLayers.Event.element(evt); + if (OpenLayers.Element.hasClass(element, "olAlphaImg")) { + element = element.parentNode; + } + if (OpenLayers.Element.hasClass(element, "olButton")) { + if (this._buttonStarted) { + if (this.completeRegEx.test(evt.type)) { + this.target.triggerEvent("buttonclick", { + button: element + }); + } + if (this.cancelRegEx.test(evt.type)) { + delete this._buttonStarted; + } + OpenLayers.Event.stop(evt, false, true); + } + if (this.startRegEx.test(evt.type)) { + this._buttonStarted = true; + OpenLayers.Event.stop(evt, false, true); + } + } else { + delete this._buttonStarted; + } + } + } + +}); \ No newline at end of file diff --git a/lib/OpenLayers/Handler/Box.js b/lib/OpenLayers/Handler/Box.js index bbefce8679..76aad7386f 100644 --- a/lib/OpenLayers/Handler/Box.js +++ b/lib/OpenLayers/Handler/Box.js @@ -103,10 +103,10 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { this.zoomBox.className = this.boxDivClassName; this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.eventsDiv.appendChild(this.zoomBox); + this.map.viewPortDiv.appendChild(this.zoomBox); OpenLayers.Element.addClass( - this.map.eventsDiv, "olDrawBox" + this.map.viewPortDiv, "olDrawBox" ); }, @@ -154,11 +154,11 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { * Remove the zoombox from the screen and nullify our reference to it. */ removeBox: function() { - this.map.eventsDiv.removeChild(this.zoomBox); + this.map.viewPortDiv.removeChild(this.zoomBox); this.zoomBox = null; this.boxOffsets = null; OpenLayers.Element.removeClass( - this.map.eventsDiv, "olDrawBox" + this.map.viewPortDiv, "olDrawBox" ); }, diff --git a/lib/OpenLayers/Handler/Drag.js b/lib/OpenLayers/Handler/Drag.js index 01e539a945..a2adf66ed0 100644 --- a/lib/OpenLayers/Handler/Drag.js +++ b/lib/OpenLayers/Handler/Drag.js @@ -442,7 +442,7 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, { * {Boolean} Let the event propagate. */ mouseout: function (evt) { - if (this.started && OpenLayers.Util.mouseLeft(evt, this.map.eventsDiv)) { + if (this.started && OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) { if(this.documentDrag === true) { this.addDocumentEvents(); } else { diff --git a/lib/OpenLayers/Handler/Hover.js b/lib/OpenLayers/Handler/Hover.js index 05eff52e28..b1bf58b860 100644 --- a/lib/OpenLayers/Handler/Hover.js +++ b/lib/OpenLayers/Handler/Hover.js @@ -107,7 +107,7 @@ OpenLayers.Handler.Hover = OpenLayers.Class(OpenLayers.Handler, { * {Boolean} Continue propagating this event. */ mouseout: function(evt) { - if (OpenLayers.Util.mouseLeft(evt, this.map.eventsDiv)) { + if (OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) { this.clearTimer(); this.callback('move', [evt]); } diff --git a/lib/OpenLayers/Handler/Point.js b/lib/OpenLayers/Handler/Point.js index f0d5c5ff93..0b9ddb9dd4 100644 --- a/lib/OpenLayers/Handler/Point.js +++ b/lib/OpenLayers/Handler/Point.js @@ -545,7 +545,7 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { * evt - {Event} The browser event */ mouseout: function(evt) { - if(OpenLayers.Util.mouseLeft(evt, this.map.eventsDiv)) { + if(OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) { this.stoppedDown = this.stopDown; this.mouseDown = false; } diff --git a/lib/OpenLayers/Layer/EventPane.js b/lib/OpenLayers/Layer/EventPane.js index 8358b3f888..ae984356dd 100644 --- a/lib/OpenLayers/Layer/EventPane.js +++ b/lib/OpenLayers/Layer/EventPane.js @@ -108,7 +108,7 @@ OpenLayers.Layer.EventPane = OpenLayers.Class(OpenLayers.Layer, { } if (this.isFixed) { - this.map.eventsDiv.appendChild(this.pane); + this.map.viewPortDiv.appendChild(this.pane); } else { this.map.layerContainerDiv.appendChild(this.pane); } diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index d440ce6a16..d24bee2882 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -513,17 +513,8 @@ OpenLayers.Map = OpenLayers.Class({ this.viewPortDiv.className = "olMapViewport"; this.div.appendChild(this.viewPortDiv); - // the eventsDiv is where we listen for all map events - var eventsDiv = document.createElement("div"); - eventsDiv.id = this.id + "_events"; - eventsDiv.style.position = "absolute"; - eventsDiv.style.width = "100%"; - eventsDiv.style.height = "100%"; - eventsDiv.style.zIndex = this.Z_INDEX_BASE.Control - 1; - this.viewPortDiv.appendChild(eventsDiv); - this.eventsDiv = eventsDiv; this.events = new OpenLayers.Events( - this, this.eventsDiv, null, this.fallThrough, + this, this.viewPortDiv, null, this.fallThrough, {includeXY: true} ); @@ -534,7 +525,7 @@ OpenLayers.Map = OpenLayers.Class({ this.layerContainerDiv.style.height = '100px'; this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE['Popup']-1; - this.eventsDiv.appendChild(this.layerContainerDiv); + this.viewPortDiv.appendChild(this.layerContainerDiv); this.updateSize(); if(this.eventListeners instanceof Object) { diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index b9f92c6c04..2458a54b67 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -416,6 +416,7 @@ OpenLayers.Util.createAlphaImageDiv = function(id, px, sz, imgURL, var div = OpenLayers.Util.createDiv(); var img = OpenLayers.Util.createImage(null, null, null, null, null, null, null, delayDisplay); + img.className = "olAlphaImg"; div.appendChild(img); OpenLayers.Util.modifyAlphaImageDiv(div, id, px, sz, imgURL, position, diff --git a/lib/deprecated.js b/lib/deprecated.js index dd6c0bcf57..c22b849216 100644 --- a/lib/deprecated.js +++ b/lib/deprecated.js @@ -1202,7 +1202,7 @@ OpenLayers.Control.MouseDefaults = OpenLayers.Class(OpenLayers.Control, { this.zoomBox.style.opacity = "0.50"; this.zoomBox.style.fontSize = "1px"; this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.eventsDiv.appendChild(this.zoomBox); + this.map.viewPortDiv.appendChild(this.zoomBox); } document.onselectstart = OpenLayers.Function.False; OpenLayers.Event.stop(evt); @@ -1275,7 +1275,7 @@ OpenLayers.Control.MouseDefaults = OpenLayers.Class(OpenLayers.Control, { */ defaultMouseOut: function (evt) { if (this.mouseDragStart != null && - OpenLayers.Util.mouseLeft(evt, this.map.eventsDiv)) { + OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) { if (this.zoomBox) { this.removeZoomBox(); } @@ -1339,7 +1339,7 @@ OpenLayers.Control.MouseDefaults = OpenLayers.Class(OpenLayers.Control, { * Remove the zoombox from the screen and nullify our reference to it. */ removeZoomBox: function() { - this.map.eventsDiv.removeChild(this.zoomBox); + this.map.viewPortDiv.removeChild(this.zoomBox); this.zoomBox = null; }, @@ -1602,7 +1602,7 @@ OpenLayers.Control.MouseToolbar = OpenLayers.Class( this.zoomBox.style.opacity = "0.50"; this.zoomBox.style.fontSize = "1px"; this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.eventsDiv.appendChild(this.zoomBox); + this.map.viewPortDiv.appendChild(this.zoomBox); this.performedDrag = true; break; case "measure": @@ -1769,7 +1769,7 @@ OpenLayers.Control.MouseToolbar = OpenLayers.Class( */ defaultMouseOut: function (evt) { if (this.mouseDragStart != null - && OpenLayers.Util.mouseLeft(evt, this.map.eventsDiv)) { + && OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) { if (this.zoomBox) { this.removeZoomBox(); if (this.startViaKeyboard) { diff --git a/tests/Control/PanZoom.html b/tests/Control/PanZoom.html index 41eab09deb..2e9a68b388 100644 --- a/tests/Control/PanZoom.html +++ b/tests/Control/PanZoom.html @@ -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(); } diff --git a/tests/Control/Panel.html b/tests/Control/Panel.html index d74526bda2..d88a7a2abe 100644 --- a/tests/Control/Panel.html +++ b/tests/Control/Panel.html @@ -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."); diff --git a/tests/Events.html b/tests/Events.html index e15e8488ff..485c53818f 100644 --- a/tests/Events.html +++ b/tests/Events.html @@ -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"); } diff --git a/tests/Events/buttonclick.html b/tests/Events/buttonclick.html new file mode 100644 index 0000000000..d03205e68f --- /dev/null +++ b/tests/Events/buttonclick.html @@ -0,0 +1,133 @@ + + + + + + +
+
+ +
+
+ + diff --git a/tests/Handler/Drag.html b/tests/Handler/Drag.html index 533e1bb647..4be1df9e6d 100644 --- a/tests/Handler/Drag.html +++ b/tests/Handler/Drag.html @@ -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; } diff --git a/tests/Layer/EventPane.html b/tests/Layer/EventPane.html index f846614a2b..8d8e180d58 100644 --- a/tests/Layer/EventPane.html +++ b/tests/Layer/EventPane.html @@ -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"); diff --git a/tests/list-tests.html b/tests/list-tests.html index 196a4d2219..1421c2b6dc 100644 --- a/tests/list-tests.html +++ b/tests/list-tests.html @@ -46,6 +46,7 @@
  • Control/PanPanel.html
  • Control/SLDSelect.html
  • Events.html
  • +
  • Events/buttonclick.html
  • Extras.html
  • Feature.html
  • Feature/Vector.html