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.
+
+
+
+
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 @@