fixed box sizing and positioning. r=sbrunner (closes #2910)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@11749 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
ahocevar
2011-03-29 13:44:04 +00:00
parent 54b58e3faf
commit c5dfe37bd4
4 changed files with 204 additions and 48 deletions

View File

@@ -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,8 +96,14 @@ 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,33 +191,52 @@ 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"

View File

@@ -2,6 +2,49 @@
<head>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
function test_Handler_Box_constructor(t) {
t.plan(4);
var control = new OpenLayers.Control();
control.id = Math.random();
var callbacks = {done: "bar"};
var options = {bar: "foo"};
var handler = new OpenLayers.Handler.Box(control, callbacks, options);
t.eq(handler.control.id, control.id, "handler created with the correct control");
t.eq(handler.callbacks.done, "bar", "handler created with the correct callback");
t.eq(handler.bar, "foo", "handler created with the correct options");
t.ok(handler.dragHandler instanceof OpenLayers.Handler.Drag, "drag handler created");
}
function test_Handler_Box_draw(t) {
t.plan(12);
var map = new OpenLayers.Map('map');
var control = new OpenLayers.Control();
map.addControl(control);
var handler = new OpenLayers.Handler.Box(control, {done: function(e) {
t.ok(e.equals(new OpenLayers.Bounds(5, 11, 11, 5)), "box result correct");
}});
handler.activate();
handler.dragHandler.start = {x: 5, y: 5};
handler.startBox({x: 5, y: 5});
var offset = handler.getBoxOffsets();
t.eq(parseInt(handler.zoomBox.style.left), 5 - offset.left, "x position of box correct");
t.eq(parseInt(handler.zoomBox.style.top), 5 - offset.top, "y position of box correct");
handler.moveBox({x: 10, y: 10});
t.eq(parseInt(handler.zoomBox.style.left), 5 - offset.left, "x position of box still correct");
t.eq(parseInt(handler.zoomBox.style.top), 5 - offset.top, "y position of box still correct");
t.eq(parseInt(handler.zoomBox.style.width), 5 + offset.width + 1, "x dimension of box correct");
t.eq(parseInt(handler.zoomBox.style.height), 5 + offset.height + 1, "y dimension of box correct");
handler.moveBox({x: 0, y: 0});
t.eq(parseInt(handler.zoomBox.style.left), 0 - offset.left, "new x position of box correct");
t.eq(parseInt(handler.zoomBox.style.top), 0 - offset.top, "new y position of box correct");
t.eq(parseInt(handler.zoomBox.style.width), 5 + offset.width + 1, "x dimension of box still correct");
t.eq(parseInt(handler.zoomBox.style.height), 5 + offset.height + 1, "y dimension of box still correct");
handler.endBox({x: 11, y: 11});
t.eq(handler.zoomBox, null, "box removed after endBox");
}
function test_Handler_Box_destroy(t) {
t.plan(1);
var map = new OpenLayers.Map('map');
@@ -21,6 +64,6 @@
</script>
</head>
<body>
<div id="map" style="width: 300px; height: 150px;"/>
<div id="map" style="width: 300px; height: 150px;"></div>
</body>
</html>

View File

@@ -0,0 +1,52 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Box Handler Quirks Mode Test</title>
<link rel="stylesheet" href="../../theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="../../examples/style.css" type="text/css" />
<style type="text/css">
/* simulate quirks mode (traditional box model) in browsers other than IE */
div {
box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.olHandlerBoxZoomBox {
border: 20px solid red;
border-left-width: 10px;
border-bottom-width: 30px;
}
</style>
<script src="../../lib/OpenLayers.js"></script>
<script type="text/javascript">
var map, layer;
function init(){
map = new OpenLayers.Map( 'map' );
layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0",
{layers: 'basic'} );
map.addLayer(layer);
map.zoomToMaxExtent();
}
</script>
</head>
<body onload="init()">
<h1 id="title">Box handler Quirks Mode Test</h1>
<div id="shortdesc">Test the correct appearance of the ZoomBox in quirks mode</div>
<div id="map" class="smallmap"></div>
<div id="docs">
<p>For the box to be positioned correctly, we need to know the
width of the borders.</p>
<p>Shift-click on the map. A red box should be visible around the mouse
cursor position, with 20 pixels to the top and right, 10 pixels to
the left and 30 pixels to the bottom edge of the box.</p>
<p>Drag the box both to the top-left and the bottom-right. The cursor
should always be at the top-left or bottom-right inner corner of
the box.</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Box Handler Strict Mode Test</title>
<link rel="stylesheet" href="../../theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="../../examples/style.css" type="text/css" />
<style type="text/css">
.olHandlerBoxZoomBox {
border: 20px solid red;
border-left-width: 10px;
border-bottom-width: 30px;
}
</style>
<script src="../../lib/OpenLayers.js"></script>
<script type="text/javascript">
var map, layer;
function init(){
map = new OpenLayers.Map( 'map' );
layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0",
{layers: 'basic'} );
map.addLayer(layer);
map.zoomToMaxExtent();
}
</script>
</head>
<body onload="init()">
<h1 id="title">Box Handler Strict Mode Test</h1>
<div id="shortdesc">Test the correct appearance of the ZoomBox in strict mode</div>
<div id="map" class="smallmap"></div>
<div id="docs">
<p>For the box to be positioned correctly, we need to know the
width of the borders.</p>
<p>Shift-click on the map. A red box should be visible around the mouse
cursor position, with 20 pixels to the top and right, 10 pixels to
the left and 30 pixels to the bottom edge of the box.</p>
<p>Drag the box both to the top-left and the bottom-right. The cursor
should always be at the top-left or bottom-right inner corner of
the box.</p>
</div>
</body>
</html>