diff --git a/lib/OpenLayers/Handler/Box.js b/lib/OpenLayers/Handler/Box.js index 4b84825309..187d51466c 100644 --- a/lib/OpenLayers/Handler/Box.js +++ b/lib/OpenLayers/Handler/Box.js @@ -32,11 +32,11 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { boxDivClassName: 'olHandlerBoxZoomBox', /** - * Property: boxCharacteristics - * {Object} Caches some box characteristics from css. This is used - * by the getBoxCharacteristics method. + * Property: boxOffsets + * {Object} Caches box offsets from css. This is used by the getBoxOffsets + * method. */ - boxCharacteristics: null, + boxOffsets: null, /** * Constructor: OpenLayers.Handler.Box @@ -96,7 +96,13 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { new OpenLayers.Pixel(-9999, -9999)); this.zoomBox.className = this.boxDivClassName; this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; + this.map.eventsDiv.appendChild(this.zoomBox); + + var offset = this.getBoxOffsets(); + var pos = this.dragHandler.start; + this.zoomBox.style.left = (pos.x - offset.left) + "px"; + this.zoomBox.style.top = (pos.y - offset.top) + "px"; OpenLayers.Element.addClass( this.map.eventsDiv, "olDrawBox" @@ -111,24 +117,14 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { var startY = this.dragHandler.start.y; var deltaX = Math.abs(startX - xy.x); var deltaY = Math.abs(startY - xy.y); - this.zoomBox.style.width = Math.max(1, deltaX) + "px"; - this.zoomBox.style.height = Math.max(1, deltaY) + "px"; - this.zoomBox.style.left = xy.x < startX ? xy.x+"px" : startX+"px"; - this.zoomBox.style.top = xy.y < startY ? xy.y+"px" : startY+"px"; - // depending on the box model, modify width and height to take borders - // of the box into account - var box = this.getBoxCharacteristics(); - if (box.newBoxModel) { - if (xy.x > startX) { - this.zoomBox.style.width = - Math.max(1, deltaX - box.xOffset) + "px"; - } - if (xy.y > startY) { - this.zoomBox.style.height = - Math.max(1, deltaY - box.yOffset) + "px"; - } - } + var offset = this.getBoxOffsets(); + this.zoomBox.style.width = (deltaX + offset.width + 1) + "px"; + this.zoomBox.style.height = (deltaY + offset.height + 1) + "px"; + this.zoomBox.style.left = (xy.x < startX ? + startX - deltaX - offset.left : startX - offset.left) + "px"; + this.zoomBox.style.top = (xy.y < startY ? + startY - deltaY - offset.top : startY - offset.top) + "px"; }, /** @@ -159,7 +155,7 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { removeBox: function() { this.map.eventsDiv.removeChild(this.zoomBox); this.zoomBox = null; - this.boxCharacteristics = null; + this.boxOffsets = null; OpenLayers.Element.removeClass( this.map.eventsDiv, "olDrawBox" ); @@ -195,34 +191,53 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { }, /** - * Method: getCharacteristics - * Determines offset and box model for a box. + * Method: getBoxOffsets + * Determines border offsets for a box, according to the box model. * * Returns: - * {Object} a hash with the following properties: - * - xOffset - Corner offset in x-direction - * - yOffset - Corner offset in y-direction - * - newBoxModel - true for all browsers except IE in quirks mode + * {Object} an object with the following offsets: + * - left + * - right + * - top + * - bottom + * - width + * - height */ - getBoxCharacteristics: function() { - if (!this.boxCharacteristics) { - var xOffset = parseInt(OpenLayers.Element.getStyle(this.zoomBox, - "border-left-width")) + parseInt(OpenLayers.Element.getStyle( - this.zoomBox, "border-right-width")) + 1; - var yOffset = parseInt(OpenLayers.Element.getStyle(this.zoomBox, - "border-top-width")) + parseInt(OpenLayers.Element.getStyle( - this.zoomBox, "border-bottom-width")) + 1; - // all browsers use the new box model, except IE in quirks mode - var newBoxModel = OpenLayers.BROWSER_NAME == "msie" ? - document.compatMode != "BackCompat" : true; - this.boxCharacteristics = { - xOffset: xOffset, - yOffset: yOffset, - newBoxModel: newBoxModel - }; - } - return this.boxCharacteristics; + getBoxOffsets: function() { + if (!this.boxOffsets) { + // Determine the box model. If the testDiv's clientWidth is 3, then + // the borders are outside and we are dealing with the w3c box + // model. Otherwise, the browser uses the traditional box model and + // the borders are inside the box bounds, leaving us with a + // clientWidth of 1. + var testDiv = document.createElement("div"); + testDiv.style.visibility = "hidden"; + testDiv.style.position = "absolute"; + testDiv.style.border = "1px solid black"; + testDiv.style.width = "3px"; + document.body.appendChild(testDiv); + var w3cBoxModel = testDiv.clientWidth == 3; + document.body.removeChild(testDiv); + + var left = parseInt(OpenLayers.Element.getStyle(this.zoomBox, + "border-left-width")); + var right = parseInt(OpenLayers.Element.getStyle( + this.zoomBox, "border-right-width")); + var top = parseInt(OpenLayers.Element.getStyle(this.zoomBox, + "border-top-width")); + var bottom = parseInt(OpenLayers.Element.getStyle( + this.zoomBox, "border-bottom-width")); + this.boxOffsets = { + left: left, + right: right, + top: top, + bottom: bottom, + width: w3cBoxModel === false ? left + right : 0, + height: w3cBoxModel === false ? top + bottom : 0 + }; + } + return this.boxOffsets; }, - + CLASS_NAME: "OpenLayers.Handler.Box" }); diff --git a/tests/Handler/Box.html b/tests/Handler/Box.html index b517dd9bb2..60ce9f85f0 100644 --- a/tests/Handler/Box.html +++ b/tests/Handler/Box.html @@ -2,6 +2,49 @@
- +