diff --git a/build/build.py b/build/build.py index ebb07d358f..0ca2a74a0e 100755 --- a/build/build.py +++ b/build/build.py @@ -51,10 +51,14 @@ def build(config_file = None, output_file = None, options = None): outputFilename = output_file print "Merging libraries." - if use_compressor == "closure": - sourceFiles = mergejs.getNames(sourceDirectory, configFilename) - else: - merged = mergejs.run(sourceDirectory, None, configFilename) + try: + if use_compressor == "closure": + sourceFiles = mergejs.getNames(sourceDirectory, configFilename) + else: + merged = mergejs.run(sourceDirectory, None, configFilename) + except mergejs.MissingImport, E: + print "\nAbnormal termination." + sys.exit("ERROR: %s" % E) print "Compressing using %s" % use_compressor if use_compressor == "jsmin": diff --git a/build/mobile.cfg b/build/mobile.cfg index 0fe32aaa6a..7bba251270 100644 --- a/build/mobile.cfg +++ b/build/mobile.cfg @@ -1,5 +1,4 @@ [first] -OpenLayers/SingleFile.js [last] diff --git a/examples/all-overlays-google.html b/examples/all-overlays-google.html index 55fa828acf..9d2527098d 100644 --- a/examples/all-overlays-google.html +++ b/examples/all-overlays-google.html @@ -8,7 +8,7 @@ - + diff --git a/examples/cross-origin-xml.html b/examples/cross-origin-xml.html new file mode 100644 index 0000000000..b811bf72c1 --- /dev/null +++ b/examples/cross-origin-xml.html @@ -0,0 +1,32 @@ + + + + OpenLayers Script Protocol XML Example + + + + + + + + +

Script Protocol With XML

+
+ protocol, script, cross origin, xml, advanced +
+

+ Demonstrates how, with a custom parseFeatures method, the script protocol can be used with YQL for cross-origin loading of files in any of the XML formats supported by OpenLayers. +

+
+
+

+ YQL can wrap a jsonp callback around an XML file, which effectively means Yahoo's servers are acting as a proxy for cross-origin feature loading. This example uses a GPX file, but the same technique can be used for other formats such as KML. +

+

+ View the cross-origin-xml.js + source to see how this is done +

+
+ + + diff --git a/examples/cross-origin-xml.js b/examples/cross-origin-xml.js new file mode 100644 index 0000000000..a97cc1fdb6 --- /dev/null +++ b/examples/cross-origin-xml.js @@ -0,0 +1,25 @@ +var map = new OpenLayers.Map({ + div: "map", + layers: [ + new OpenLayers.Layer.OSM(), + new OpenLayers.Layer.Vector("Vectors", { + projection: new OpenLayers.Projection("EPSG:4326"), + strategies: [new OpenLayers.Strategy.Fixed()], + protocol: new OpenLayers.Protocol.Script({ + url: "http://query.yahooapis.com/v1/public/yql", + params: { + q: "select * from xml where url='http://www.topografix.com/fells_loop.gpx'" + }, + format: new OpenLayers.Format.GPX(), + parseFeatures: function(data) { + return this.format.read(data.results[0]); + } + }), + eventListeners: { + "featuresadded": function () { + this.map.zoomToExtent(this.getDataExtent()); + } + } + }) + ] +}); diff --git a/examples/google-v3.html b/examples/google-v3.html index c074bb62f5..849d7cd273 100644 --- a/examples/google-v3.html +++ b/examples/google-v3.html @@ -8,7 +8,7 @@ - + diff --git a/examples/mapbox.html b/examples/mapbox.html new file mode 100644 index 0000000000..3ccbffe776 --- /dev/null +++ b/examples/mapbox.html @@ -0,0 +1,73 @@ + + + + + + + OpenLayers MapBox Example + + + + + +

Basic MapBox OSM Example

+
mapbox xyz osm
+ +
Shows how to use MapBox tiles in an OpenLayers map.
+ +
+ +
+

This example demonstrates the use of an XYZ layer that accesses tiles from MapBox.

+

+ See the mapbox.js source + for details. Make sure to read the Terms of Service + before using MapBox tiles in your application. +

+
+ + + + diff --git a/examples/mapbox.js b/examples/mapbox.js new file mode 100644 index 0000000000..ee57d66e0c --- /dev/null +++ b/examples/mapbox.js @@ -0,0 +1,34 @@ +var streets = new OpenLayers.Layer.XYZ( + "MapBox Streets", + [ + "http://a.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png", + "http://b.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png", + "http://c.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png", + "http://d.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png" + ], { + attribution: "Tiles © MapBox | " + + "Data © OpenStreetMap " + + "and contributors, CC-BY-SA", + sphericalMercator: true, + transitionEffect: "resize", + buffer: 1, + numZoomLevels: 16 + } +); + +var map = new OpenLayers.Map({ + div: "map", + layers: [streets], + controls: [ + new OpenLayers.Control.Attribution(), + new OpenLayers.Control.Navigation({ + dragPanOptions: { + enableKinetic: true + } + }), + new OpenLayers.Control.ZoomPanel(), + new OpenLayers.Control.Permalink({anchor: true}) + ], + center: [0, 0], + zoom: 1 +}); diff --git a/examples/osm-google.html b/examples/osm-google.html index 3578246ccb..39c31dd910 100644 --- a/examples/osm-google.html +++ b/examples/osm-google.html @@ -8,7 +8,7 @@ - + diff --git a/examples/spherical-mercator.html b/examples/spherical-mercator.html index ea6c2246d5..409a8e232f 100644 --- a/examples/spherical-mercator.html +++ b/examples/spherical-mercator.html @@ -22,7 +22,7 @@ } - + diff --git a/examples/zoom.html b/examples/zoom.html new file mode 100644 index 0000000000..7b15297d05 --- /dev/null +++ b/examples/zoom.html @@ -0,0 +1,68 @@ + + + + + + + OpenLayers Zoom Example + + + + + +

Zoom Control Example

+
zoom control
+ +
Shows how to use a simple zoom control.
+ +
+

The map above uses the default control configuration and style.

+

The map below uses the custom zoom elements and styling.

+
+
+ in + out +
+
+ +
+

This example demonstrates the use of a Zoom control.

+

+ See the zoom.js source + for details. +

+
+ + + + diff --git a/examples/zoom.js b/examples/zoom.js new file mode 100644 index 0000000000..08694ccad4 --- /dev/null +++ b/examples/zoom.js @@ -0,0 +1,34 @@ +var map = new OpenLayers.Map({ + div: "map", + layers: [new OpenLayers.Layer.OSM()], + controls: [ + new OpenLayers.Control.Navigation({ + dragPanOptions: { + enableKinetic: true + } + }), + new OpenLayers.Control.Attribution(), + new OpenLayers.Control.Zoom() + ], + center: [0, 0], + zoom: 1 +}); + +var map2 = new OpenLayers.Map({ + div: "map2", + layers: [new OpenLayers.Layer.OSM()], + controls: [ + new OpenLayers.Control.Navigation({ + dragPanOptions: { + enableKinetic: true + } + }), + new OpenLayers.Control.Attribution(), + new OpenLayers.Control.Zoom({ + zoomInId: "customZoomIn", + zoomOutId: "customZoomOut" + }) + ], + center: [0, 0], + zoom: 1 +}); diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index b67381d4b5..fdc91bd366 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -204,6 +204,7 @@ "OpenLayers/Control/Graticule.js", "OpenLayers/Control/TransformFeature.js", "OpenLayers/Control/SLDSelect.js", + "OpenLayers/Control/Zoom.js", "OpenLayers/Geometry.js", "OpenLayers/Geometry/Collection.js", "OpenLayers/Geometry/Point.js", diff --git a/lib/OpenLayers/BaseTypes.js b/lib/OpenLayers/BaseTypes.js index 241f43437a..d2e5711ca8 100644 --- a/lib/OpenLayers/BaseTypes.js +++ b/lib/OpenLayers/BaseTypes.js @@ -3,6 +3,10 @@ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the * full text of the license. */ +/** + * @requires OpenLayers/SingleFile.js + */ + /** * Header: OpenLayers Base Types * OpenLayers custom string, number and function functions are described here. @@ -60,6 +64,28 @@ OpenLayers.String = { return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }, + /** + * APIFunction: camelize + * Camel-case a hyphenated string. + * Ex. "chicken-head" becomes "chickenHead", and + * "-chicken-head" becomes "ChickenHead". + * + * Parameters: + * str - {String} The string to be camelized. The original is not modified. + * + * Returns: + * {String} The string, camelized + */ + camelize: function(str) { + var oStringList = str.split('-'); + var camelizedString = oStringList[0]; + for (var i=1, len=oStringList.length; i} The sketch feature. */ measureImmediate : function(point, feature, drawing) { - if (drawing && this.delayedTrigger === null && - !this.handler.freehandMode(this.handler.evt)) { + if (drawing && !this.handler.freehandMode(this.handler.evt)) { + this.cancelDelay(); this.measure(feature.geometry, "measurepartial"); } }, diff --git a/lib/OpenLayers/Control/ModifyFeature.js b/lib/OpenLayers/Control/ModifyFeature.js index 6e78184efc..30d6fad0cd 100644 --- a/lib/OpenLayers/Control/ModifyFeature.js +++ b/lib/OpenLayers/Control/ModifyFeature.js @@ -246,7 +246,6 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, { // configure the drag control var dragOptions = { geometryTypes: ["OpenLayers.Geometry.Point"], - snappingOptions: this.snappingOptions, onStart: function(feature, pixel) { control.dragStart.apply(control, [feature, pixel]); }, diff --git a/lib/OpenLayers/Control/OverviewMap.js b/lib/OpenLayers/Control/OverviewMap.js index f338867f02..29fefeb5b2 100644 --- a/lib/OpenLayers/Control/OverviewMap.js +++ b/lib/OpenLayers/Control/OverviewMap.js @@ -493,14 +493,14 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, { this.ovmap.zoomToMaxExtent(); // check extent rectangle border width this.wComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle, - 'borderLeftWidth')) + + 'border-left-width')) + parseInt(OpenLayers.Element.getStyle(this.extentRectangle, - 'borderRightWidth')); + 'border-right-width')); this.wComp = (this.wComp) ? this.wComp : 2; this.hComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle, 'border-top-width')) + parseInt(OpenLayers.Element.getStyle(this.extentRectangle, - 'borderBottomWidth')); + 'border-bottom-width')); this.hComp = (this.hComp) ? this.hComp : 2; this.handlers.drag = new OpenLayers.Handler.Drag( diff --git a/lib/OpenLayers/Control/Permalink.js b/lib/OpenLayers/Control/Permalink.js index 5686f1f8b6..4a2112c552 100644 --- a/lib/OpenLayers/Control/Permalink.js +++ b/lib/OpenLayers/Control/Permalink.js @@ -94,12 +94,13 @@ OpenLayers.Control.Permalink = OpenLayers.Class(OpenLayers.Control, { * APIMethod: destroy */ destroy: function() { - if (this.element.parentNode == this.div) { + if (this.element && this.element.parentNode == this.div) { this.div.removeChild(this.element); + this.element = null; + } + if (this.map) { + this.map.events.unregister('moveend', this, this.updateLink); } - this.element = null; - - this.map.events.unregister('moveend', this, this.updateLink); OpenLayers.Control.prototype.destroy.apply(this, arguments); }, diff --git a/lib/OpenLayers/Control/WMSGetFeatureInfo.js b/lib/OpenLayers/Control/WMSGetFeatureInfo.js index 9348a9d542..86e9423060 100644 --- a/lib/OpenLayers/Control/WMSGetFeatureInfo.js +++ b/lib/OpenLayers/Control/WMSGetFeatureInfo.js @@ -341,6 +341,7 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, { service: "WMS", version: firstLayer.params.VERSION, request: "GetFeatureInfo", + exceptions: firstLayer.params.EXCEPTIONS, bbox: this.map.getExtent().toBBOX(null, firstLayer.reverseAxisOrder()), feature_count: this.maxFeatures, diff --git a/lib/OpenLayers/Control/Zoom.js b/lib/OpenLayers/Control/Zoom.js new file mode 100644 index 0000000000..2913cf3e48 --- /dev/null +++ b/lib/OpenLayers/Control/Zoom.js @@ -0,0 +1,142 @@ +/* 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/Control.js + * @requires OpenLayers/Events/buttonclick.js + */ + +/** + * Class: OpenLayers.Control.Zoom + * The Zoom control is a pair of +/- links for zooming in and out. + * + * Inherits from: + * - + */ +OpenLayers.Control.Zoom = OpenLayers.Class(OpenLayers.Control, { + + /** + * APIProperty: zoomInText + * {String} + * Text for zoom-in link. Default is "+". + */ + zoomInText: "+", + + /** + * APIProperty: zoomInId + * {String} + * Instead of having the control create a zoom in link, you can provide + * the identifier for an anchor element already added to the document. + * By default, an element with id "olZoomInLink" will be searched for + * and used if it exists. + */ + zoomInId: "olZoomInLink", + + /** + * APIProperty: zoomOutText + * {String} + * Text for zoom-out link. Default is "-". + */ + zoomOutText: "-", + + /** + * APIProperty: zoomOutId + * {String} + * Instead of having the control create a zoom out link, you can provide + * the identifier for an anchor element already added to the document. + * By default, an element with id "olZoomOutLink" will be searched for + * and used if it exists. + */ + zoomOutId: "olZoomOutLink", + + /** + * Method: draw + * + * Returns: + * {DOMElement} A reference to the DOMElement containing the zoom links. + */ + draw: function() { + var div = OpenLayers.Control.prototype.draw.apply(this), + links = this.getOrCreateLinks(div), + zoomIn = links.zoomIn, + zoomOut = links.zoomOut, + bind = OpenLayers.Function.bind; + + this.events.register("buttonclick", this, this.onZoomClick); + this.zoomInLink = zoomIn; + this.zoomOutLink = zoomOut; + return div; + }, + + /** + * Method: getOrCreateLinks + * + * Parameters: + * el - {DOMElement} + * + * Return: + * {Object} Object with zoomIn and zoomOut properties referencing links. + */ + getOrCreateLinks: function(el) { + var zoomIn = document.getElementById(this.zoomInId), + zoomOut = document.getElementById(this.zoomOutId), + eventElement = zoomOut ? zoomOut.parentNode : this.div; + this.events.attachToElement(eventElement); + if (!zoomIn) { + zoomIn = document.createElement("a"); + zoomIn.href = "#zoomIn"; + zoomIn.appendChild(document.createTextNode(this.zoomInText)); + zoomIn.className = "olControlZoomIn"; + el.appendChild(zoomIn); + } + OpenLayers.Element.addClass(zoomIn, "olButton"); + if (!zoomOut) { + zoomOut = document.createElement("a"); + zoomOut.href = "#zoomOut"; + zoomOut.appendChild(document.createTextNode(this.zoomOutText)); + zoomOut.className = "olControlZoomOut"; + el.appendChild(zoomOut); + } + OpenLayers.Element.addClass(zoomOut, "olButton"); + return { + zoomIn: zoomIn, zoomOut: zoomOut + }; + }, + + /** + * Method: onZoomClick + * Called when zoomin/out link is clicked. + */ + onZoomClick: function(evt) { + var propagate = true, + button = evt.buttonElement; + if (button === this.zoomInLink) { + this.map.zoomIn(); + propagate = false; + } else if (button === this.zoomOutLink) { + this.map.zoomOut(); + propagate = false; + } + return propagate; + }, + + /** + * Method: destroy + * Clean up. + */ + destroy: function() { + if (this.zoomInLink) { + this.zoomInLink.onclick = null; + delete this.zoomInLink; + } + if (this.zoomOutLink) { + this.zoomOutLink.onclick = null; + delete this.zoomOutLink; + } + OpenLayers.Control.prototype.destroy.apply(this); + }, + + CLASS_NAME: "OpenLayers.Control.Zoom" +}); diff --git a/lib/OpenLayers/Format/KML.js b/lib/OpenLayers/Format/KML.js index 1754fd8eb5..b814eece5a 100644 --- a/lib/OpenLayers/Format/KML.js +++ b/lib/OpenLayers/Format/KML.js @@ -64,9 +64,25 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, { * APIProperty: extractAttributes * {Boolean} Extract attributes from KML. Default is true. * Extracting styleUrls requires this to be set to true + * Note that currently only Data and SimpleData + * elements are handled. */ extractAttributes: true, + /** + * APIProperty: kvpAttributes + * {Boolean} Only used if extractAttributes is true. + * If set to true, attributes will be simple + * key-value pairs, compatible with other formats, + * Any displayName elements will be ignored. + * If set to false, attributes will be objects, + * retaining any displayName elements, but not + * compatible with other formats. Any CDATA in + * displayName will be read in as a string value. + * Default is false. + */ + kvpAttributes: false, + /** * Property: extractStyles * {Boolean} Extract styles from KML. Default is false. @@ -1078,12 +1094,16 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, { var valueNode = data.getElementsByTagName("value"); if (valueNode.length) { ed['value'] = this.getChildValue(valueNode[0]); - } - var nameNode = data.getElementsByTagName("displayName"); - if (nameNode.length) { - ed['displayName'] = this.getChildValue(nameNode[0]); } - attributes[key] = ed; + if (this.kvpAttributes) { + attributes[key] = ed['value']; + } else { + var nameNode = data.getElementsByTagName("displayName"); + if (nameNode.length) { + ed['displayName'] = this.getChildValue(nameNode[0]); + } + attributes[key] = ed; + } } var simpleDataNodes = node.getElementsByTagName("SimpleData"); for (i = 0, len = simpleDataNodes.length; i < len; i++) { @@ -1091,8 +1111,12 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, { data = simpleDataNodes[i]; key = data.getAttribute("name"); ed['value'] = this.getChildValue(data); - ed['displayName'] = key; - attributes[key] = ed; + if (this.kvpAttributes) { + attributes[key] = ed['value']; + } else { + ed['displayName'] = key; + attributes[key] = ed; + } } return attributes; @@ -1209,7 +1233,14 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, { var geometryNode = this.buildGeometryNode(feature.geometry); placemarkNode.appendChild(geometryNode); - // TBD - deal with remaining (non name/description) attributes. + // output attributes as extendedData + if (feature.attributes) { + var edNode = this.buildExtendedData(feature.attributes); + if (edNode) { + placemarkNode.appendChild(edNode); + } + } + return placemarkNode; }, @@ -1440,5 +1471,48 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, { return point.x + "," + point.y; }, + /** + * Method: buildExtendedData + * + * Parameters: + * attributes - {Object} + * + * Returns + * {DOMElement} A KML ExtendedData node or {null} if no attributes. + */ + buildExtendedData: function(attributes) { + var extendedData = this.createElementNS(this.kmlns, "ExtendedData"); + for (var attributeName in attributes) { + // empty, name, description, styleUrl attributes ignored + if (attributes[attributeName] && attributeName != "name" && attributeName != "description" && attributeName != "styleUrl") { + var data = this.createElementNS(this.kmlns, "Data"); + data.setAttribute("name", attributeName); + var value = this.createElementNS(this.kmlns, "value"); + if (typeof attributes[attributeName] == "object") { + // cater for object attributes with 'value' properties + // other object properties will output an empty node + if (attributes[attributeName].value) { + value.appendChild(this.createTextNode(attributes[attributeName].value)); + } + if (attributes[attributeName].displayName) { + var displayName = this.createElementNS(this.kmlns, "displayName"); + // displayName always written as CDATA + displayName.appendChild(this.getXMLDoc().createCDATASection(attributes[attributeName].displayName)); + data.appendChild(displayName); + } + } else { + value.appendChild(this.createTextNode(attributes[attributeName])); + } + data.appendChild(value); + extendedData.appendChild(data); + } + } + if (this.isSimpleContent(extendedData)) { + return null; + } else { + return extendedData; + } + }, + CLASS_NAME: "OpenLayers.Format.KML" }); diff --git a/lib/OpenLayers/Format/SLD/v1.js b/lib/OpenLayers/Format/SLD/v1.js index cd32810be9..20d95266ed 100644 --- a/lib/OpenLayers/Format/SLD/v1.js +++ b/lib/OpenLayers/Format/SLD/v1.js @@ -570,7 +570,7 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, { break; } } - return format || this.defautlGraphicFormat; + return format || this.defaultGraphicFormat; }, /** diff --git a/lib/OpenLayers/Handler/Box.js b/lib/OpenLayers/Handler/Box.js index 4040ea5ff2..76aad7386f 100644 --- a/lib/OpenLayers/Handler/Box.js +++ b/lib/OpenLayers/Handler/Box.js @@ -221,13 +221,13 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, { document.body.removeChild(testDiv); var left = parseInt(OpenLayers.Element.getStyle(this.zoomBox, - "borderLeftWidth")); + "border-left-width")); var right = parseInt(OpenLayers.Element.getStyle( - this.zoomBox, "borderRightWidth")); + this.zoomBox, "border-right-width")); var top = parseInt(OpenLayers.Element.getStyle(this.zoomBox, - "borderTopWidth")); + "border-top-width")); var bottom = parseInt(OpenLayers.Element.getStyle( - this.zoomBox, "borderBottomWidth")); + this.zoomBox, "border-bottom-width")); this.boxOffsets = { left: left, right: right, diff --git a/lib/OpenLayers/Layer/ArcGISCache.js b/lib/OpenLayers/Layer/ArcGISCache.js index 9c500e4533..27173392c4 100644 --- a/lib/OpenLayers/Layer/ArcGISCache.js +++ b/lib/OpenLayers/Layer/ArcGISCache.js @@ -452,7 +452,9 @@ OpenLayers.Layer.ArcGISCache = OpenLayers.Class(OpenLayers.Layer.XYZ, { // Write the values into our formatted url url = OpenLayers.String.format(url, {'x': x, 'y': y, 'z': z}); - return url; + return OpenLayers.Util.urlAppend( + url, OpenLayers.Util.getParameterString(this.params) + ); }, /** diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 1e767f75dd..e84411cee9 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -202,6 +202,10 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { * track of the loading progress. Listeners are called with an object * with a tile property as first argument, making the loded tile * available to the listener. + * tileerror - Triggered before the tileloaded event (i.e. when the tile is + * still hidden) if a tile failed to load. Listeners receive an object + * as first argument, which has a tile property that references the + * tile that could not be loaded. */ /** @@ -969,7 +973,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } this.numLoadingTiles++; }; - tile.events.register("loadstart", this, tile.onLoadStart); tile.onLoadEnd = function() { this.numLoadingTiles--; @@ -987,8 +990,18 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } } }; - tile.events.register("loadend", this, tile.onLoadEnd); - tile.events.register("unload", this, tile.onLoadEnd); + + tile.onLoadError = function() { + this.events.triggerEvent("tileerror", {tile: tile}); + }; + + tile.events.on({ + "loadstart": tile.onLoadStart, + "loadend": tile.onLoadEnd, + "unload": tile.onLoadEnd, + "loaderror": tile.onLoadError, + scope: this + }); }, /** @@ -1005,6 +1018,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { "loadstart": tile.onLoadStart, "loadend": tile.onLoadEnd, "unload": tile.onLoadEnd, + "loaderror": tile.onLoadError, scope: this }); }, diff --git a/lib/OpenLayers/Layer/HTTPRequest.js b/lib/OpenLayers/Layer/HTTPRequest.js index 7855cb6b03..d1e9bf2219 100644 --- a/lib/OpenLayers/Layer/HTTPRequest.js +++ b/lib/OpenLayers/Layer/HTTPRequest.js @@ -60,7 +60,9 @@ OpenLayers.Layer.HTTPRequest = OpenLayers.Class(OpenLayers.Layer, { initialize: function(name, url, params, options) { OpenLayers.Layer.prototype.initialize.apply(this, [name, options]); this.url = url; - this.params = OpenLayers.Util.extend( {}, params); + if (!this.params) { + this.params = OpenLayers.Util.extend({}, params); + } }, /** diff --git a/lib/OpenLayers/Layer/OSM.js b/lib/OpenLayers/Layer/OSM.js index 04e7b04454..264687644f 100644 --- a/lib/OpenLayers/Layer/OSM.js +++ b/lib/OpenLayers/Layer/OSM.js @@ -34,7 +34,7 @@ OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { /** * APIProperty: url * {String} The tileset URL scheme. Defaults to - * : http://tile.openstreetmap.org/${z}/${x}/${y}.png + * : http://[a|b|c].tile.openstreetmap.org/${z}/${x}/${y}.png * (the official OSM tileset) if the second argument to the constructor * is null or undefined. To use another tileset you can have something * like this: @@ -43,7 +43,11 @@ OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { * "http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"); * (end) */ - url: 'http://tile.openstreetmap.org/${z}/${x}/${y}.png', + url: [ + 'http://a.tile.openstreetmap.org/${z}/${x}/${y}.png', + 'http://b.tile.openstreetmap.org/${z}/${x}/${y}.png', + 'http://c.tile.openstreetmap.org/${z}/${x}/${y}.png' + ], /** * Property: attribution diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index f861721c59..016c4110b8 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -496,13 +496,16 @@ OpenLayers.Map = OpenLayers.Class({ this.projection.projCode : this.projection; OpenLayers.Util.applyDefaults(this, OpenLayers.Projection.defaults[projCode]); - // allow extents to be arrays + // allow extents and center to be arrays if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) { this.maxExtent = new OpenLayers.Bounds(this.maxExtent); } if (this.restrictedExtent && !(this.restrictedExtent instanceof OpenLayers.Bounds)) { this.restrictedExtent = new OpenLayers.Bounds(this.restrictedExtent); } + if (this.center && !(this.center instanceof OpenLayers.LonLat)) { + this.center = new OpenLayers.LonLat(this.center); + } // initialize layers array this.layers = []; @@ -625,9 +628,9 @@ OpenLayers.Map = OpenLayers.Class({ * be properly set below. */ delete this.center; - this.addLayers(options.layers); + this.addLayers(options.layers); // set center (and optionally zoom) - if (options.center) { + if (options.center && !this.getCenter()) { // zoom can be undefined here this.setCenter(options.center, options.zoom); } diff --git a/lib/OpenLayers/Popup.js b/lib/OpenLayers/Popup.js index 50274d5c2d..774ecb8c03 100644 --- a/lib/OpenLayers/Popup.js +++ b/lib/OpenLayers/Popup.js @@ -685,7 +685,9 @@ OpenLayers.Popup = OpenLayers.Class({ // 'img' properties in the context. // var onImgLoad = function() { - + if (this.popup.id === null) { // this.popup has been destroyed! + return; + } this.popup.updateSize(); if ( this.popup.visible() && this.popup.panMapIfOutOfView ) { @@ -845,10 +847,10 @@ OpenLayers.Popup = OpenLayers.Class({ //read the padding settings from css, put them in an OL.Bounds contentDivPadding = new OpenLayers.Bounds( - OpenLayers.Element.getStyle(this.contentDiv, "paddingLeft"), - OpenLayers.Element.getStyle(this.contentDiv, "paddingBottom"), - OpenLayers.Element.getStyle(this.contentDiv, "paddingRight"), - OpenLayers.Element.getStyle(this.contentDiv, "paddingTop") + OpenLayers.Element.getStyle(this.contentDiv, "padding-left"), + OpenLayers.Element.getStyle(this.contentDiv, "padding-bottom"), + OpenLayers.Element.getStyle(this.contentDiv, "padding-right"), + OpenLayers.Element.getStyle(this.contentDiv, "padding-top") ); //cache the value diff --git a/lib/OpenLayers/Protocol/HTTP.js b/lib/OpenLayers/Protocol/HTTP.js index e7414d8e99..d5c822c7d2 100644 --- a/lib/OpenLayers/Protocol/HTTP.js +++ b/lib/OpenLayers/Protocol/HTTP.js @@ -114,7 +114,7 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, { * Valid options include: * url - {String} * headers - {Object} - * params - {Object} + * params - {Object} URL parameters for GET requests * format - {} * callback - {Function} * scope - {Object} diff --git a/lib/OpenLayers/Protocol/Script.js b/lib/OpenLayers/Protocol/Script.js index 49e332b7f0..b298845586 100644 --- a/lib/OpenLayers/Protocol/Script.js +++ b/lib/OpenLayers/Protocol/Script.js @@ -135,7 +135,7 @@ OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, { }); this.filterToParams = function(filter, params) { return format.write(filter, params); - } + }; } }, diff --git a/lib/OpenLayers/Renderer/Canvas.js b/lib/OpenLayers/Renderer/Canvas.js index ee90db4e38..74ae40b768 100644 --- a/lib/OpenLayers/Renderer/Canvas.js +++ b/lib/OpenLayers/Renderer/Canvas.js @@ -434,28 +434,6 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, { } }, - /** - * Method: setCanvasStyle - * Prepare the canvas for drawing by setting various global settings. - * - * Parameters: - * type - {String} one of 'stroke', 'fill', or 'reset' - * style - {Object} Symbolizer hash - */ - setCanvasStyle: function(type, style) { - if (type === "fill") { - this.canvas.globalAlpha = style['fillOpacity']; - this.canvas.fillStyle = style['fillColor']; - } else if (type === "stroke") { - this.canvas.globalAlpha = style['strokeOpacity']; - this.canvas.strokeStyle = style['strokeColor']; - this.canvas.lineWidth = style['strokeWidth']; - } else { - this.canvas.globalAlpha = 0; - this.canvas.lineWidth = 1; - } - }, - /** * Method: featureIdToHex * Convert a feature ID string into an RGB hex string. diff --git a/lib/OpenLayers/Spherical.js b/lib/OpenLayers/Spherical.js index 4a8956a5b7..b3957d4910 100644 --- a/lib/OpenLayers/Spherical.js +++ b/lib/OpenLayers/Spherical.js @@ -3,6 +3,10 @@ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the * full text of the license. */ +/** + * @requires OpenLayers/SingleFile.js + */ + /** * Namespace: Spherical * The OpenLayers.Spherical namespace includes utility functions for diff --git a/lib/OpenLayers/Tile.js b/lib/OpenLayers/Tile.js index d1d11eef8f..56c49c6320 100644 --- a/lib/OpenLayers/Tile.js +++ b/lib/OpenLayers/Tile.js @@ -40,6 +40,8 @@ OpenLayers.Tile = OpenLayers.Class({ * to call (true) to actually draw the tile. * loadstart - Triggered when tile loading starts. * loadend - Triggered when tile loading ends. + * loaderror - Triggered before the loadend event (i.e. when the tile is + * still hidden) if the tile could not be loaded. * reload - Triggered when an already loading tile is reloaded. * unload - Triggered before a tile is unloaded. */ diff --git a/lib/OpenLayers/Tile/Image.js b/lib/OpenLayers/Tile/Image.js index aef46ff49e..778ececc92 100644 --- a/lib/OpenLayers/Tile/Image.js +++ b/lib/OpenLayers/Tile/Image.js @@ -425,6 +425,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, { this.setImgSrc(this.layer.getURL(this.bounds)); } else { OpenLayers.Element.addClass(img, "olImageLoadError"); + this.events.triggerEvent("loaderror"); this.onImageLoad(); } } diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index 5ca8c35201..880e3435ab 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -560,8 +560,10 @@ OpenLayers.Util.urlAppend = function(url, paramStr) { }; /** - * Property: ImgPath - * {String} Default is ''. + * APIProperty: ImgPath + * {String} Set this to the path where control images are stored. + * If set to '' OpenLayers will use script location + "img/" + * Default is ''. */ OpenLayers.ImgPath = ''; diff --git a/lib/deprecated.js b/lib/deprecated.js index a86fcdaa8b..c22b849216 100644 --- a/lib/deprecated.js +++ b/lib/deprecated.js @@ -105,30 +105,6 @@ OpenLayers.Util.clearArray = function(array) { array.length = 0; }; - -/** - * APIFunction: camelize - * Camel-case a hyphenated string. - * Ex. "chicken-head" becomes "chickenHead", and - * "-chicken-head" becomes "ChickenHead". - * - * Parameters: - * str - {String} The string to be camelized. The original is not modified. - * - * Returns: - * {String} The string, camelized - */ - -OpenLayers.String.camelize = function(str) { - var oStringList = str.split('-'); - var camelizedString = oStringList[0]; - for (var i=1, len=oStringList.length; i` tag after OpenLayers.js). @@ -144,7 +150,6 @@ A number of properties, methods, and constructors have been marked as deprecated * OpenLayers.Util.setOpacity * OpenLayers.Util.safeStopPropagation * OpenLayers.Util.getArgs - * OpenLayers.Sring.camelize * OpenLayers.nullHandler * OpenLayers.loadURL * OpenLayers.parseXMLString diff --git a/readme.md b/readme.md index 074556beb6..edcd4e9dcd 100644 --- a/readme.md +++ b/readme.md @@ -48,7 +48,7 @@ As an example, using bash (with the release files in ~/openlayers): The [examples directory](http://openlayers.org/dev/examples/) is full of useful examples. Documentation is available at http://trac.osgeo.org/openlayers/wiki/Documentation. -You can generate the API documentation with http://www.naturaldocs.org/: +You can generate the API documentation with http://www.naturaldocs.org/ As an example, using bash (with the release files in ~/openlayers): $ cd ~/openlayers/ diff --git a/tests/Animation.html b/tests/Animation.html index 75cd4434f8..f113690933 100644 --- a/tests/Animation.html +++ b/tests/Animation.html @@ -17,12 +17,22 @@ function test_all(t) { t.plan(8); t.ok(OpenLayers.Animation.isNative !== undefined, "isNative is set."); - t.open_window("Animation.html", function(win) { + + function doIt(win) { win.requestFrame(t); win.start(t); win.startDuration(t); win.stop(t); - }); + } + + // Test in an extra window in Firefox, and directly in other browsers. + // This is needed because requestAnimationFrame does not work + // correctly in Firefox in a hidden IFrame. + if (window.mozRequestAnimationFrame) { + t.open_window("Animation.html", doIt); + } else { + doIt(window); + } } function requestFrame(t) { diff --git a/tests/BaseTypes.html b/tests/BaseTypes.html index 772cc7bdc9..c264d4a54f 100644 --- a/tests/BaseTypes.html +++ b/tests/BaseTypes.html @@ -59,7 +59,34 @@ str = " "; t.eq(OpenLayers.String.trim(str), "", "whitespace string is trimmed correctly"); } + + function test_String_camelize(t) { + t.plan(7); + + var str = "chickenhead"; + t.eq(OpenLayers.String.camelize(str), "chickenhead", "string with no hyphens is left alone"); + str = "chicken-head"; + t.eq(OpenLayers.String.camelize(str), "chickenHead", "string with one middle hyphen is camelized correctly"); + + str = "chicken-head-man"; + t.eq(OpenLayers.String.camelize(str), "chickenHeadMan", "string with multiple middle hyphens is camelized correctly"); + + str = "-chickenhead"; + t.eq(OpenLayers.String.camelize(str), "Chickenhead", "string with starting hyphen is camelized correctly (capitalized)"); + + str = "-chicken-head-man"; + t.eq(OpenLayers.String.camelize(str), "ChickenHeadMan", "string with starting hypen and multiple middle hyphens is camelized correctly"); + + str = "chicken-"; + t.eq(OpenLayers.String.camelize(str), "chicken", "string ending in hyphen is camelized correctly (hyphen dropped)"); + + str = "chicken-head-man-"; + t.eq(OpenLayers.String.camelize(str), "chickenHeadMan", "string with multiple middle hyphens and end hyphen is camelized correctly (end hyphen dropped)"); + + + } + function test_String_format(t) { var unchanged = [ "", "${ ", "${", " ${", "${${", "${}", "${${}}", " ${ ${", diff --git a/tests/Control/Measure.html b/tests/Control/Measure.html index 4d060ea97d..ee6d192b5a 100644 --- a/tests/Control/Measure.html +++ b/tests/Control/Measure.html @@ -289,16 +289,16 @@ // move 10 pixels trigger("mousemove", 0, 10); - t.eq(log.length, 0, "a) no event fired yet"); + t.eq(log.length, 1, "a) has fired an event"); t.delay_call( delay, function() { // confirm measurepartial is fired - t.eq(log.length, 1, "a) event logged"); + t.eq(log.length, 1, "a) one event logged"); t.ok(log[0] && log[0].type == "measurepartial", "a) correct type"); // mousemove within the partialDelay fires no event, so the // measure below is the one of the initial point - t.ok(log[0] && log[0].measure == 0, "a) correct measure"); + t.eq(log[0]?log[0].measure:-1 , 10, "a) correct measure"); // b) move 10 pixels trigger("mousemove", 0, 20); diff --git a/tests/Control/Permalink.html b/tests/Control/Permalink.html index 4b07d3e2bb..b398adf148 100644 --- a/tests/Control/Permalink.html +++ b/tests/Control/Permalink.html @@ -11,6 +11,7 @@ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct"); t.eq(control.base, document.location.href, "base is correct"); t.ok(!control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink('permalink', 'test.html'); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); @@ -18,6 +19,7 @@ t.eq(control.base, 'test.html', "base is correct"); t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object"); t.ok(!control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink('permalink'); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); @@ -25,6 +27,7 @@ t.eq(control.base, document.location.href, "base is correct"); t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object"); t.ok(!control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink(OpenLayers.Util.getElement('permalink')); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); @@ -32,6 +35,7 @@ t.eq(control.base, document.location.href, "base is correct"); t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object"); t.ok(!control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink({anchor: true}); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); @@ -39,18 +43,21 @@ t.eq(control.base, document.location.href, "base is correct"); t.ok(control.element == null, "element is null"); t.ok(control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink({anchor: false}); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); t.eq(control.displayClass, "olControlPermalink", "displayClass is correct"); t.eq(control.base, document.location.href, "base is correct"); t.ok(!control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink({}); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); t.eq(control.displayClass, "olControlPermalink", "displayClass is correct"); t.eq(control.base, document.location.href, "base is correct"); t.ok(!control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink({element: 'permalink', base: 'test.html'}); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); @@ -58,6 +65,7 @@ t.eq(control.base, 'test.html', "base is correct"); t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object"); t.ok(!control.anchor, "anchor is correct"); + control.destroy(); control = new OpenLayers.Control.Permalink({element: 'permalink', base: 'test.html', anchor: true}); t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object"); @@ -65,6 +73,7 @@ t.eq(control.base, 'test.html', "base is correct"); t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object"); t.ok(control.anchor, "anchor is correct"); + control.destroy(); } function test_Control_Permalink_uncentered (t) { t.plan( 1 ); @@ -74,12 +83,14 @@ map.addControl(control); map.events.triggerEvent("changelayer", {}); t.ok(true, "permalink didn't bomb out."); + map.destroy(); } function test_Control_Permalink_initwithelem (t) { t.plan( 1 ); control = new OpenLayers.Control.Permalink(OpenLayers.Util.getElement('permalink')); t.ok(true, "If the above line doesn't throw an error, we're safe."); + control.destroy(); } function test_Control_Permalink_updateLinks (t) { t.plan( 3 ); @@ -100,6 +111,7 @@ map.layers[1].setVisibility(false); t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+"?zoom=2&lat=0&lon=1.75781&layers=BF"), 'setVisibility sets permalink'); + map.destroy(); } function test_Control_Permalink_updateLinksBase (t) { t.plan( 2 ); @@ -114,6 +126,7 @@ map.pan(5, 0, {animate:false}); OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B'; t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base"); + map.destroy(); } function test_Control_Permalink_noElement (t) { t.plan( 2 ); @@ -122,6 +135,7 @@ map = new OpenLayers.Map('map'); map.addControl(control); t.eq(map.controls[4].div.firstChild.nodeName, "A", "Permalink control creates div with 'a' inside." ); + map.destroy(); } function test_Control_Permalink_base_with_query (t) { t.plan( 3 ); @@ -147,6 +161,7 @@ map.pan(5, 0, {animate:false}); map.pan(-5, 0, {animate:false}); t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and querystring ending with '?'"); + map.destroy(); } @@ -163,6 +178,7 @@ map.pan(5, 0, {animate:false}); OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B'; t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with existing zoom in base"); + map.destroy(); } function test_Control_Permalink_customized(t) { @@ -189,6 +205,7 @@ t.eq(this.map.controls[this.map.controls.length-1].CLASS_NAME, "CustomArgParser", "Custom ArgParser added correctly."); t.eq(control.div.firstChild.getAttribute("href"), "./edit.html?zoom=2&lat=0&lon=1.75781&layers=B&customParam=foo", "Custom parameter encoded correctly."); + map.destroy(); } function test_Control_Permalink_createParams(t) { @@ -300,6 +317,7 @@ map.layers[1].setVisibility(false); t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getParameterString(control.createParams()), "zoom=2&lat=0&lon=1.75781&layers=BF"), 'setVisibility sets permalink'); + map.destroy(); } function test_Control_Permalink_AnchorBaseElement (t) { @@ -320,7 +338,80 @@ map.layers[1].setVisibility(false); t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+"#zoom=2&lat=0&lon=1.75781&layers=BF"), 'setVisibility sets permalink'); + map.destroy(); } + + function test_center_from_map(t) { + t.plan(7); + + var previous = window.location.hash; + window.location.hash = ""; + + var err; + try { + var map = new OpenLayers.Map({ + layers: [new OpenLayers.Layer(null, {isBaseLayer: true})], + controls: [ + new OpenLayers.Control.Permalink({anchor: true}) + ], + center: [1, 2], + zoom: 3 + }); + } catch (e) { + err = e; + } + if (err) { + t.fail("Map construction failure: " + err.message); + } else { + t.ok(true, "Map construction works"); + } + + // confirm that map center is correctly set + var center = map.getCenter(); + t.eq(center.lon, 1, "map x"); + t.eq(center.lat, 2, "map y") + t.eq(map.getZoom(), 3, "map z"); + + // confirm that location from map options has been added to url + var params = OpenLayers.Util.getParameters(window.location.hash.replace("#", "?")); + t.eq(params.lon, "1", "url x"); + t.eq(params.lat, "2", "url y"); + t.eq(params.zoom, "3", "url z"); + + map.destroy(); + window.location.hash = previous; + } + + function test_center_from_url(t) { + t.plan(6); + + // In cases where the location is specified in the URL and given in + // the map options, we respect the location in the URL. + var previous = window.location.hash; + window.location.hash = "#zoom=6&lat=5&lon=4&layers=B" + + var map = new OpenLayers.Map({ + layers: [new OpenLayers.Layer(null, {isBaseLayer: true})], + controls: [new OpenLayers.Control.Permalink({anchor: true})], + center: [0, 0], + zoom: 0 + }); + + // confirm that map center is correctly set + var center = map.getCenter(); + t.eq(center.lon, 4, "map x"); + t.eq(center.lat, 5, "map y") + t.eq(map.getZoom(), 6, "map z"); + + var params = OpenLayers.Util.getParameters(window.location.hash.replace("#", "?")); + t.eq(params.lon, "4", "x set"); + t.eq(params.lat, "5", "y set"); + t.eq(params.zoom, "6", "z set"); + + map.destroy(); + window.location.hash = previous; + } + diff --git a/tests/Control/WMSGetFeatureInfo.html b/tests/Control/WMSGetFeatureInfo.html index 5e7801b036..b5e6d5db80 100644 --- a/tests/Control/WMSGetFeatureInfo.html +++ b/tests/Control/WMSGetFeatureInfo.html @@ -475,6 +475,35 @@ } + function test_exceptions(t) { + t.plan(1); + var map = new OpenLayers.Map("map", { + getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));} + } + ); + + var a = new OpenLayers.Layer.WMS("dummy","http://myhost/wms", { + layers: "x", + exceptions: "text/xml" + }); + + map.addLayer(a); + + var click = new OpenLayers.Control.WMSGetFeatureInfo({ + }); + + map.addControl(click); + + var _request = OpenLayers.Request.GET; + OpenLayers.Request.GET = function(options) { + t.eq(options.params["EXCEPTIONS"], "text/xml", "Exceptions parameter taken from the WMS layer if provided"); + }; + click.activate(); + click.getInfoForClick({xy: {x: 50, y: 50}}); + OpenLayers.Request.GET = _request; + map.destroy(); + } + function test_drillDown(t) { t.plan(6); var map = new OpenLayers.Map("map", { diff --git a/tests/Control/Zoom.html b/tests/Control/Zoom.html new file mode 100644 index 0000000000..724fe4a5df --- /dev/null +++ b/tests/Control/Zoom.html @@ -0,0 +1,74 @@ + + + + + + + +
+ + diff --git a/tests/Format/KML.html b/tests/Format/KML.html index 42b6fe6e0d..a7dfd976c2 100644 --- a/tests/Format/KML.html +++ b/tests/Format/KML.html @@ -198,21 +198,35 @@ t.ok(style.t, "getStyle returns copy of style rather than reference"); } function test_Format_KML_extendedData(t) { - t.plan(2); + t.plan(6); var f = new OpenLayers.Format.KML(); var features = f.read(OpenLayers.Util.getElement("kml_extendeddata").value); - t.eq(features[0].attributes.all_bridges.value, "3030", "read value from extendeddata correctly."); - t.eq(features[0].attributes.all_bridges.displayName, "all bridges", "read displayName from extendeddata correctly."); + t.eq(features[0].attributes.holeYardage.value, "234", "read value from extendeddata correctly."); + t.eq(features[0].attributes.holeYardage.displayName, "The yardage is ", "read displayName from extendeddata correctly."); + t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage.value, features[0].attributes.holeYardage.value, "attribute value written correctly"); + t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage.displayName, features[0].attributes.holeYardage.displayName, "attribute displayName written correctly"); + f.kvpAttributes = true; + features = f.read(OpenLayers.Util.getElement("kml_extendeddata").value); + t.eq(features[0].attributes.holeYardage, "234", "read kvp value from extendeddata correctly."); + t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage, features[0].attributes.holeYardage, "kvp attribute value written correctly"); } function test_Format_KML_extendedData_SchemaData(t) { - t.plan(4); + t.plan(10); var f = new OpenLayers.Format.KML(); var features = f.read(OpenLayers.Util.getElement("kml_extendeddata2").value); t.eq(features[0].attributes.TrailHeadName.value, "Pi in the sky", "read value from extendeddata (schema data) correctly."); t.eq(features[0].attributes.TrailHeadName.displayName, "TrailHeadName", "read displayName from extendeddata correctly"); t.eq(features[0].attributes.ElevationGain.value, "10", "read value from extendeddata (schema data) correctly."); t.eq(features[0].attributes.ElevationGain.displayName, "ElevationGain", "read displayName from extendeddata correctly"); + t.eq(f.read(f.write(features[0]))[0].attributes.TrailHeadName.value, features[0].attributes.TrailHeadName.value, "attribute value from extendeddata (schema data) written correctly"); + t.eq(f.read(f.write(features[0]))[0].attributes.ElevationGain.value, features[0].attributes.ElevationGain.value, "attribute value from extendeddata (schema data) written correctly"); + f.kvpAttributes = true; + features = f.read(OpenLayers.Util.getElement("kml_extendeddata2").value); + t.eq(features[0].attributes.TrailHeadName, "Pi in the sky", "read kvp value from extendeddata (schema data) correctly."); + t.eq(features[0].attributes.ElevationGain, "10", "read kvp value from extendeddata (schema data) correctly."); + t.eq(f.read(f.write(features[0]))[0].attributes.TrailHeadName, features[0].attributes.TrailHeadName, "kvp attribute value from extendeddata (schema data) written correctly"); + t.eq(f.read(f.write(features[0]))[0].attributes.ElevationGain, features[0].attributes.ElevationGain, "kvp attribute value from extendeddata (schema data) written correctly"); } function test_Format_KML_placemarkName(t) { @@ -287,49 +301,61 @@