diff --git a/lib/OpenLayers/Events.js b/lib/OpenLayers/Events.js index 22b063e4df..f02c88670e 100644 --- a/lib/OpenLayers/Events.js +++ b/lib/OpenLayers/Events.js @@ -450,7 +450,6 @@ OpenLayers.Events = OpenLayers.Class({ initialize: function (object, element, eventTypes, fallThrough, options) { OpenLayers.Util.extend(this, options); this.object = object; - this.element = element; this.fallThrough = fallThrough; this.listeners = {}; @@ -471,7 +470,7 @@ OpenLayers.Events = OpenLayers.Class({ // if a dom element is specified, add a listeners list // for browser events on the element and register them - if (this.element != null) { + if (element != null) { this.attachToElement(element); } }, @@ -514,6 +513,10 @@ OpenLayers.Events = OpenLayers.Class({ * element - {HTMLDOMElement} a DOM element to attach browser events to */ attachToElement: function (element) { + if(this.element) { + OpenLayers.Event.stopObservingElement(this.element); + } + this.element = element; for (var i=0, len=this.BROWSER_EVENTS.length; i constructor is called + * with two arguments, this should be provided as the first argument. + * Alternatively, the map constructor can be called with the options + * object as the only argument. In this case (one argument), a + * div property may or may not be provided. If the div property + * is not provided, the map can be rendered to a container later + * using the method. + * + * Note: If you calling after map construction, do not use + * auto. Instead, divide your by your + * maximum expected dimension. */ div: null, @@ -382,13 +393,16 @@ OpenLayers.Map = OpenLayers.Class({ /** * Constructor: OpenLayers.Map - * Constructor for a new OpenLayers.Map instance. + * Constructor for a new OpenLayers.Map instance. There are two possible + * ways to call the map constructor. See the examples below. * * Parameters: * div - {String} Id of an element in your page that will contain the map. + * May be omitted if the
option is provided or if you intend + * to use later. * options - {Object} Optional object with properties to tag onto the map. * - * Examples: + * Examples (method one): * (code) * // create a map with default options in an element with the id "map1" * var map = new OpenLayers.Map("map1"); @@ -402,8 +416,33 @@ OpenLayers.Map = OpenLayers.Class({ * }; * var map = new OpenLayers.Map("map2", options); * (end) + * + * Examples (method two - single argument): + * (code) + * // create a map with non-default options + * var map = new OpenLayers.Map({ + * div: "map_id", + * maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000), + * maxResolution: 156543, + * units: 'm', + * projection: "EPSG:41001" + * }); + * + * // create a map without a reference to a container - call render later + * var map = new OpenLayers.Map({ + * maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000), + * maxResolution: 156543, + * units: 'm', + * projection: "EPSG:41001" + * }); */ initialize: function (div, options) { + + // If only one argument is provided, check if it is an object. + if(arguments.length === 1 && typeof div === "object") { + options = div; + div = options && options.div; + } // Simple-type defaults are set in class definition. // Now set complex-type defaults @@ -423,6 +462,12 @@ OpenLayers.Map = OpenLayers.Class({ this.id = OpenLayers.Util.createUniqueID("OpenLayers.Map_"); this.div = OpenLayers.Util.getElement(div); + if(!this.div) { + this.div = document.createElement("div"); + this.div.style.height = "1px"; + this.div.style.width = "1px"; + } + OpenLayers.Element.addClass(this.div, 'olMap'); // the viewPortDiv is the outermost div we modify @@ -518,7 +563,23 @@ OpenLayers.Map = OpenLayers.Class({ // always call map.destroy() OpenLayers.Event.observe(window, 'unload', this.unloadDestroy); - + }, + + /** + * APIMethod: render + * Render the map to a specified container. + * + * Parameters: + * div - {String|DOMElement} The container that the map should be rendered + * to. If different than the current container, the map viewport + * will be moved from the current to the new container. + */ + render: function(div) { + this.div = OpenLayers.Util.getElement(div); + this.events.attachToElement(this.div); + this.viewPortDiv.parentNode.removeChild(this.viewPortDiv); + this.div.appendChild(this.viewPortDiv); + this.updateSize(); }, /** diff --git a/tests/Map.html b/tests/Map.html index 7f65778a43..855a7b7af4 100644 --- a/tests/Map.html +++ b/tests/Map.html @@ -34,6 +34,40 @@ t.ok( map.getMaxExtent() instanceof OpenLayers.Bounds, "map.maxExtent is an OpenLayers.Bounds" ); t.ok( map.getNumZoomLevels() > 0, "map has a default numZoomLevels" ); } + + function test_Map_constructor_late_rendering(t) { + t.plan( 4 ); + + map = new OpenLayers.Map(); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + + t.ok(map.div != null, "Map has a div even though none was specified."); + t.ok(map.viewPortDiv.parentNode == map.div, "Map is attached to a temporary div that holds the viewPortDiv."); + + var mapDiv = document.getElementById("map"); + map.render(mapDiv); // Can also take a string. + + t.ok(map.div == mapDiv, "Map is now rendered to the 'map' div.") + t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class"); + } + + function test_Map_constructor_renderTo(t) { + t.plan( 1 ); + + map = new OpenLayers.Map({ + div: "map" + }); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + + var mapDiv = document.getElementById("map"); + t.ok(map.div == mapDiv, "Map is rendered to the 'map' div.") + } function test_Map_setOptions(t) { t.plan(2);