[OpenLayers-Commits] r11749 - in trunk/openlayers: lib/OpenLayers/Handler tests/Handler tests/manual

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Tue Mar 29 09:44:09 EDT 2011


Author: ahocevar
Date: 2011-03-29 06:44:04 -0700 (Tue, 29 Mar 2011)
New Revision: 11749

Added:
   trunk/openlayers/tests/manual/box-quirks.html
   trunk/openlayers/tests/manual/box-strict.html
Modified:
   trunk/openlayers/lib/OpenLayers/Handler/Box.js
   trunk/openlayers/tests/Handler/Box.html
Log:
fixed box sizing and positioning. r=sbrunner (closes #2910)

Modified: trunk/openlayers/lib/OpenLayers/Handler/Box.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Handler/Box.js	2011-03-29 13:28:01 UTC (rev 11748)
+++ trunk/openlayers/lib/OpenLayers/Handler/Box.js	2011-03-29 13:44:04 UTC (rev 11749)
@@ -32,11 +32,11 @@
     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 @@
              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 @@
         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 @@
     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 @@
     },
     
     /**
-     * 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"
 });

Modified: trunk/openlayers/tests/Handler/Box.html
===================================================================
--- trunk/openlayers/tests/Handler/Box.html	2011-03-29 13:28:01 UTC (rev 11748)
+++ trunk/openlayers/tests/Handler/Box.html	2011-03-29 13:44:04 UTC (rev 11749)
@@ -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>

Added: trunk/openlayers/tests/manual/box-quirks.html
===================================================================
--- trunk/openlayers/tests/manual/box-quirks.html	                        (rev 0)
+++ trunk/openlayers/tests/manual/box-quirks.html	2011-03-29 13:44:04 UTC (rev 11749)
@@ -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>

Added: trunk/openlayers/tests/manual/box-strict.html
===================================================================
--- trunk/openlayers/tests/manual/box-strict.html	                        (rev 0)
+++ trunk/openlayers/tests/manual/box-strict.html	2011-03-29 13:44:04 UTC (rev 11749)
@@ -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>



More information about the Commits mailing list