diff --git a/css/ol.css b/css/ol.css
index 13232a0105..79d5385efe 100644
--- a/css/ol.css
+++ b/css/ol.css
@@ -1,17 +1,32 @@
.ol-attribution {
position: absolute;
text-align: right;
- color: #eeeeee;
bottom: 0;
right: 0;
- background: rgba(0,60,136,0.3);
font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
padding: 6px;
}
.ol-attribution a {
- color: white;
text-decoration: none;
}
+
+/* rgba is not supported on IE <= 8, fall back to black text so that it's readable */
+.ol-attribution {
+ color: #000000;
+}
+.ol-attribution:not([ie8andbelow]) {
+ color: #eeeeee;
+ background: rgba(0,60,136,0.3);
+}
+
+/* white links are unreadable on IE <= 8 with no background, fall back to blue links */
+.ol-attribution a {
+ color: #7b98bc;
+}
+.ol-attribution a:not([ie8andbelow]) {
+ color: white;
+}
+
.ol-attribution ul {
margin: 0;
padding: 0;
@@ -32,20 +47,26 @@
white-space: nowrap;
}
.ol-full-screen {
- background: rgba(255,255,255,0.4);
+ /* IE <= 8 doesn't support rgba, fall back to a light grey */
+ background: #eee;
border-radius: 4px;
padding: 2px;
position: absolute;
right: 8px;
top: 8px;
}
+.ol-full-screen:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a light grey */
+ background: rgba(255,255,255,0.4);
+}
@media print {
.ol-full-screen {
display: none;
}
}
.ol-full-screen a {
- background: rgba(0,60,136,0.5);
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
+ background: #7b98bc;
color: white;
display: block;
font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
@@ -59,6 +80,10 @@
text-decoration: none;
width: 22px;
}
+.ol-full-screen a:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
+ background: rgba(0,60,136,0.5);
+}
a.ol-full-screen-false:after {
content: "\2194";
}
@@ -73,6 +98,11 @@ a.ol-full-screen-true:after {
border-radius: 2px;
}
.ol-full-screen a:hover {
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
+ background: #4c6079;
+}
+.ol-full-screen a:hover:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
background: rgba(0,60,136,0.7);
}
.ol-logo {
@@ -92,17 +122,22 @@ a.ol-full-screen-true:after {
.ol-mouse-position {
top: 8px;
right: 8px;
- position: absolute;
+ position: absolute;
}
.ol-scale-line {
- background: rgba(0,60,136,0.3);
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
+ background: #95b9e6;
border-radius: 4px;
bottom: 8px;
left: 8px;
padding: 2px;
position: absolute;
}
+.ol-scale-line:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
+ background: rgba(0,60,136,0.3);
+}
.ol-scale-line-inner {
border: 1px solid #eeeeee;
border-top: none;
@@ -124,15 +159,25 @@ a.ol-full-screen-true:after {
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
+
+ cursor: default;
+}
+.ol-viewport .ol-unselectable:not([ie8andbelow]) {
+ cursor: auto;
}
.ol-zoom {
position: absolute;
top: 8px;
left: 8px;
- background: rgba(255,255,255,0.4);
+ /* IE <= 8 doesn't support rgba, fall back to a light grey */
+ background-color: #eee;
border-radius: 4px;
padding: 2px;
}
+/* IE <= 8 doesn't support rgba, fall back to a light grey */
+.ol-zoom:not([ie8andbelow]) {
+ background-color: rgba(255,255,255,0.4);
+}
@media print {
.ol-zoom {
display: none;
@@ -152,7 +197,12 @@ a.ol-full-screen-true:after {
height: 22px;
width: 22px;
line-height: 19px;
- background: rgba(0,60,136,0.5);
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
+ background-color: #7b98bc;
+}
+.ol-zoom a:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a light blue */
+ background-color: rgba(0,60,136,0.5);
}
.ol-touch .ol-zoom a {
font-size: 20px;
@@ -163,28 +213,28 @@ a.ol-full-screen-true:after {
.ol-zoom a:hover {
color: #fff;
text-decoration: none;
- background: rgba(0,60,136,0.7);
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
+ background-color: #4c6079;
+}
+.ol-zoom a:hover:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
+ background-color: rgba(0,60,136,0.7);
}
.ol-zoom-in {
border-radius: 2px 2px 0 0;
}
-.ol-zoom-in:before {
- content: "+";
-}
.ol-zoom-out {
border-radius: 0 0 2px 2px;
}
-.ol-zoom-out:before {
- content: "\2212";
-}
.ol-zoomslider {
position: absolute;
top: 67px;
left: 8px;
- background: rgba(255, 255, 255, 0.4);
+ /* IE <= 8 doesn't support rgba, fall back to a light grey */
+ background: #eee;
border-radius: 4px;
width: 28px;
height: 200px;
@@ -193,26 +243,40 @@ a.ol-full-screen-true:after {
padding: 0;
margin: 0;
}
+.ol-zoomslider:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a light grey */
+ background: rgba(255, 255, 255, 0.4);
+}
.ol-zoomslider-thumb {
position: absolute;
display: block;
padding: 0;
margin: 2px;
- background: rgba(0,60,136,0.5);
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
+ background: #7b98bc;
border-radius: 2px;
outline: none;
overflow: hidden;
height: 20px;
width: 24px;
}
+.ol-zoomslider-thumb:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
+ background: rgba(0,60,136,0.5);
+}
.ol-zoom-extent {
position: absolute;
- background: rgba(255,255,255,0.4);
+ /* IE <= 8 doesn't support rgba, fall back to a light grey */
+ background: #eee;
border-radius: 4px;
left: 8px;
padding: 2px;
top: 65px;
}
+.ol-zoom-extent:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a light grey */
+ background: rgba(255,255,255,0.4);
+}
@media print {
.ol-zoom-extent {
display: none;
@@ -230,9 +294,14 @@ a.ol-full-screen-true:after {
text-align: center;
height: 22px;
width: 22px;
- background-color: rgba(0, 60, 136, 0.5);
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
+ background-color: #7b98bc;
border-radius: 2px;
}
+.ol-zoom-extent a:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
+ background-color: rgba(0, 60, 136, 0.5);
+}
.ol-touch .ol-zoom-extent a {
font-size: 20px;
height: 30px;
@@ -240,6 +309,11 @@ a.ol-full-screen-true:after {
line-height: 26px;
}
.ol-zoom-extent a:hover {
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
+ background-color: #4c6079;
+}
+.ol-zoom-extent a:hover:not([ie8andbelow]) {
+ /* IE <= 8 doesn't support rgba, fall back to a lighter blue */
background-color: rgba(0, 60, 136, 0.7);
}
.ol-zoom-extent a:after {
diff --git a/examples/accessible.html b/examples/accessible.html
index 3cdaf170b0..4ca8f48fa5 100644
--- a/examples/accessible.html
+++ b/examples/accessible.html
@@ -52,6 +52,7 @@
+
diff --git a/examples/animation.html b/examples/animation.html
index abedf3c0fe..a2457641ad 100644
--- a/examples/animation.html
+++ b/examples/animation.html
@@ -55,6 +55,7 @@
+
diff --git a/examples/bind-input.html b/examples/bind-input.html
index d45f73b874..4bcb50ee93 100644
--- a/examples/bind-input.html
+++ b/examples/bind-input.html
@@ -80,6 +80,7 @@
+
diff --git a/examples/brightness-contrast.html b/examples/brightness-contrast.html
index de9ec3fb24..63189a0acd 100644
--- a/examples/brightness-contrast.html
+++ b/examples/brightness-contrast.html
@@ -65,6 +65,7 @@
+
diff --git a/examples/canvas-tiles.html b/examples/canvas-tiles.html
index 7b817b74fd..639d7d3ef6 100644
--- a/examples/canvas-tiles.html
+++ b/examples/canvas-tiles.html
@@ -43,6 +43,7 @@
+
diff --git a/examples/custom-controls.html b/examples/custom-controls.html
index 563757a222..d1133e6baf 100644
--- a/examples/custom-controls.html
+++ b/examples/custom-controls.html
@@ -81,6 +81,7 @@
+
diff --git a/examples/d3.html b/examples/d3.html
index bc19211ad8..7d56ff152b 100644
--- a/examples/d3.html
+++ b/examples/d3.html
@@ -43,6 +43,7 @@
+
diff --git a/examples/device-orientation.html b/examples/device-orientation.html
index 54942cca60..069e77687d 100644
--- a/examples/device-orientation.html
+++ b/examples/device-orientation.html
@@ -49,6 +49,7 @@
+
diff --git a/examples/drag-rotate-and-zoom.html b/examples/drag-rotate-and-zoom.html
index 7573e373b8..4dc8775023 100644
--- a/examples/drag-rotate-and-zoom.html
+++ b/examples/drag-rotate-and-zoom.html
@@ -43,6 +43,7 @@
+
diff --git a/examples/draw-features.html b/examples/draw-features.html
index d2bdf15e1a..5b75037fe4 100644
--- a/examples/draw-features.html
+++ b/examples/draw-features.html
@@ -51,6 +51,7 @@
+
diff --git a/examples/dynamic-data.html b/examples/dynamic-data.html
index 89fb754092..2f5edf1bbf 100644
--- a/examples/dynamic-data.html
+++ b/examples/dynamic-data.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/epsg-4326.html b/examples/epsg-4326.html
index 36b4ef918e..96995c3b90 100644
--- a/examples/epsg-4326.html
+++ b/examples/epsg-4326.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/export-map.html b/examples/export-map.html
index 56b21b05b3..a53cbbd384 100644
--- a/examples/export-map.html
+++ b/examples/export-map.html
@@ -47,6 +47,7 @@
+
diff --git a/examples/full-screen-drag-rotate-and-zoom.html b/examples/full-screen-drag-rotate-and-zoom.html
index acdf4b94a6..ab47d82c0d 100644
--- a/examples/full-screen-drag-rotate-and-zoom.html
+++ b/examples/full-screen-drag-rotate-and-zoom.html
@@ -55,6 +55,7 @@
+
diff --git a/examples/full-screen.html b/examples/full-screen.html
index a7e8963129..be4e885553 100644
--- a/examples/full-screen.html
+++ b/examples/full-screen.html
@@ -55,6 +55,7 @@
+
diff --git a/examples/geojson.html b/examples/geojson.html
index 26135d4e76..24aaa51ce5 100644
--- a/examples/geojson.html
+++ b/examples/geojson.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/getfeatureinfo.html b/examples/getfeatureinfo.html
index 8d4b054528..4d7bd3b6f7 100644
--- a/examples/getfeatureinfo.html
+++ b/examples/getfeatureinfo.html
@@ -48,6 +48,7 @@
+
diff --git a/examples/hue-saturation.html b/examples/hue-saturation.html
index 087ed33496..f9c7b79869 100644
--- a/examples/hue-saturation.html
+++ b/examples/hue-saturation.html
@@ -65,6 +65,7 @@
+
diff --git a/examples/layer-clipping-webgl.html b/examples/layer-clipping-webgl.html
index 36f869e78c..97a58d91a9 100644
--- a/examples/layer-clipping-webgl.html
+++ b/examples/layer-clipping-webgl.html
@@ -47,6 +47,7 @@
+
diff --git a/examples/layer-clipping.html b/examples/layer-clipping.html
index 90077e3166..0db4de0d6c 100644
--- a/examples/layer-clipping.html
+++ b/examples/layer-clipping.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/layer-swipe.html b/examples/layer-swipe.html
index 48303a95bf..a3f1281986 100644
--- a/examples/layer-swipe.html
+++ b/examples/layer-swipe.html
@@ -43,6 +43,7 @@
+
diff --git a/examples/localized-openstreetmap.html b/examples/localized-openstreetmap.html
index 769f29591f..5cb6ef7d23 100644
--- a/examples/localized-openstreetmap.html
+++ b/examples/localized-openstreetmap.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/mapguide-untiled.html b/examples/mapguide-untiled.html
index 3aed063b9b..ac111b1926 100644
--- a/examples/mapguide-untiled.html
+++ b/examples/mapguide-untiled.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/min-max-resolution.html b/examples/min-max-resolution.html
index a0e4c32ef8..59af04e66b 100644
--- a/examples/min-max-resolution.html
+++ b/examples/min-max-resolution.html
@@ -51,6 +51,7 @@
+
diff --git a/examples/mouse-position.html b/examples/mouse-position.html
index 4d739fd45f..990b88f828 100644
--- a/examples/mouse-position.html
+++ b/examples/mouse-position.html
@@ -50,6 +50,7 @@
+
diff --git a/examples/moveend.html b/examples/moveend.html
index d0ab0d623a..aa9484b59f 100644
--- a/examples/moveend.html
+++ b/examples/moveend.html
@@ -45,6 +45,7 @@
+
diff --git a/examples/navigation-controls.html b/examples/navigation-controls.html
index 46a6944043..fbf1129649 100644
--- a/examples/navigation-controls.html
+++ b/examples/navigation-controls.html
@@ -47,6 +47,7 @@
+
diff --git a/examples/popup.html b/examples/popup.html
index 95e1bac848..97f1e9ac6c 100644
--- a/examples/popup.html
+++ b/examples/popup.html
@@ -97,6 +97,7 @@
+
diff --git a/examples/preload.html b/examples/preload.html
index 771e952b1e..81e2f998ec 100644
--- a/examples/preload.html
+++ b/examples/preload.html
@@ -46,6 +46,7 @@
+
diff --git a/examples/rotation.html b/examples/rotation.html
index 9636f063ca..14f62a60cf 100644
--- a/examples/rotation.html
+++ b/examples/rotation.html
@@ -43,6 +43,7 @@
+
diff --git a/examples/rtree.html b/examples/rtree.html
index 80f1f8e21c..89f1e99432 100644
--- a/examples/rtree.html
+++ b/examples/rtree.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/scale-line.html b/examples/scale-line.html
index a41b33ea4b..f284b30607 100644
--- a/examples/scale-line.html
+++ b/examples/scale-line.html
@@ -47,6 +47,7 @@
+
diff --git a/examples/select-features.html b/examples/select-features.html
index a764084d44..a6e12c207f 100644
--- a/examples/select-features.html
+++ b/examples/select-features.html
@@ -43,6 +43,7 @@
+
diff --git a/examples/semi-transparent-layer.html b/examples/semi-transparent-layer.html
index 002c58fa82..1a877e35ab 100644
--- a/examples/semi-transparent-layer.html
+++ b/examples/semi-transparent-layer.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/side-by-side.html b/examples/side-by-side.html
index d3ffb744f3..7df539fc64 100644
--- a/examples/side-by-side.html
+++ b/examples/side-by-side.html
@@ -54,6 +54,7 @@
+
diff --git a/examples/simple.html b/examples/simple.html
index c46005de82..860ac484ee 100644
--- a/examples/simple.html
+++ b/examples/simple.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/stamen.html b/examples/stamen.html
index 0f146407f5..acf7cb1e8c 100644
--- a/examples/stamen.html
+++ b/examples/stamen.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/static-image.html b/examples/static-image.html
index c7ca702969..29c8d08290 100644
--- a/examples/static-image.html
+++ b/examples/static-image.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/synthetic-lines.html b/examples/synthetic-lines.html
index a129e66ce9..9065c02cfe 100644
--- a/examples/synthetic-lines.html
+++ b/examples/synthetic-lines.html
@@ -100,6 +100,7 @@
+
diff --git a/examples/teleport.html b/examples/teleport.html
index b26a4d7f1d..b67dda04b8 100644
--- a/examples/teleport.html
+++ b/examples/teleport.html
@@ -52,6 +52,7 @@
+
diff --git a/examples/tilejson.html b/examples/tilejson.html
index 58610c3751..d534c699ce 100644
--- a/examples/tilejson.html
+++ b/examples/tilejson.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/topojson.html b/examples/topojson.html
index 0afee83db1..e8bcd3e597 100644
--- a/examples/topojson.html
+++ b/examples/topojson.html
@@ -44,6 +44,7 @@
+
diff --git a/examples/wms-capabilities.html b/examples/wms-capabilities.html
index 6aec2b9a03..acc12dad11 100644
--- a/examples/wms-capabilities.html
+++ b/examples/wms-capabilities.html
@@ -40,6 +40,7 @@
+
diff --git a/examples/wms-custom-proj.html b/examples/wms-custom-proj.html
index 3ddd07df23..6641ff0b51 100644
--- a/examples/wms-custom-proj.html
+++ b/examples/wms-custom-proj.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/wms-image-custom-proj.html b/examples/wms-image-custom-proj.html
index e7478fb829..8d32132257 100644
--- a/examples/wms-image-custom-proj.html
+++ b/examples/wms-image-custom-proj.html
@@ -43,6 +43,7 @@
+
diff --git a/examples/wms-image.html b/examples/wms-image.html
index 72d6cca182..7707eb5768 100644
--- a/examples/wms-image.html
+++ b/examples/wms-image.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/wms-no-proj.html b/examples/wms-no-proj.html
index ece1dfbf38..dc6e01b906 100644
--- a/examples/wms-no-proj.html
+++ b/examples/wms-no-proj.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/wms-tiled.html b/examples/wms-tiled.html
index 8a0f52a068..1bc78e2527 100644
--- a/examples/wms-tiled.html
+++ b/examples/wms-tiled.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/wmts.html b/examples/wmts.html
index cd093454de..1d03468dc1 100644
--- a/examples/wmts.html
+++ b/examples/wmts.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/xyz-esri.html b/examples/xyz-esri.html
index 0846616cf6..0e096fd533 100644
--- a/examples/xyz-esri.html
+++ b/examples/xyz-esri.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/zoomify.html b/examples/zoomify.html
index 940467aa1d..11aed4215f 100644
--- a/examples/zoomify.html
+++ b/examples/zoomify.html
@@ -42,6 +42,7 @@
+
diff --git a/examples/zoomslider.html b/examples/zoomslider.html
index 1b431caba6..dd270449de 100644
--- a/examples/zoomslider.html
+++ b/examples/zoomslider.html
@@ -106,6 +106,7 @@
+
diff --git a/resources/example-behaviour.js b/resources/example-behaviour.js
index 28b0785469..eb0e264a15 100644
--- a/resources/example-behaviour.js
+++ b/resources/example-behaviour.js
@@ -2,7 +2,7 @@
if (window.location.host === 'localhost:3000') {
return;
}
- var container = document.querySelector('.navbar .navbar-inner .container'),
+ var container = $('.navbar .navbar-inner .container')[0],
form = document.createElement('form'),
select = document.createElement('select'),
possibleModes = {
@@ -54,7 +54,7 @@
}
}
- select.addEventListener('change', modeChangedMethod);
+ $(select).change(modeChangedMethod);
select.className = 'input-medium';
form.className = 'navbar-form pull-right';
diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc
index 86ba8617c4..7fdbd6e09f 100644
--- a/src/objectliterals.jsdoc
+++ b/src/objectliterals.jsdoc
@@ -245,6 +245,8 @@
* @typedef {Object} olx.control.ZoomOptions
* @property {number|undefined} duration Animation duration in milliseconds. Default is `250`.
* @property {string|undefined} className CSS class name. Default is `ol-zoom`.
+ * @property {string|undefined} zoomInLabel Text label to use for the zoom-in button. Default is `+`
+ * @property {string|undefined} zoomOutLabel Text label to use for the zoom-out button. Default is `-`
* @property {number|undefined} delta The zoom delta applied on each click.
* @property {Element|undefined} target Target.
* @todo stability experimental
diff --git a/src/ol/browserfeature.js b/src/ol/browserfeature.js
index e03792b08a..c5802a3e48 100644
--- a/src/ol/browserfeature.js
+++ b/src/ol/browserfeature.js
@@ -2,6 +2,7 @@ goog.provide('ol.BrowserFeature');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
+goog.require('goog.userAgent');
goog.require('ol.webgl');
@@ -47,6 +48,21 @@ ol.ENABLE_VECTOR = true;
ol.ENABLE_WEBGL = true;
+/**
+ * @define {boolean} Whether to support legacy IE (7-8).
+ */
+ol.LEGACY_IE_SUPPORT = false;
+
+
+/**
+ * Whether the current browser is legacy IE
+ * @const
+ * @type {boolean}
+ */
+ol.IS_LEGACY_IE = goog.userAgent.IE &&
+ !goog.userAgent.isVersionOrHigher('9.0') && goog.userAgent.VERSION !== '';
+
+
/**
* The ratio between physical pixels and device-independent pixels
* (dips) on the device (`window.devicePixelRatio`).
diff --git a/src/ol/control/zoomcontrol.js b/src/ol/control/zoomcontrol.js
index 5c8fe4ca4a..1cce5fc6a8 100644
--- a/src/ol/control/zoomcontrol.js
+++ b/src/ol/control/zoomcontrol.js
@@ -32,10 +32,14 @@ ol.control.Zoom = function(opt_options) {
var delta = goog.isDef(options.delta) ? options.delta : 1;
+ var zoomInLabel = goog.isDef(options.zoomInLabel) ? options.zoomInLabel : '+',
+ zoomOutLabel =
+ goog.isDef(options.zoomOutLabel) ? options.zoomOutLabel : '-';
+
var inElement = goog.dom.createDom(goog.dom.TagName.A, {
'href': '#zoomIn',
'class': className + '-in'
- });
+ }, zoomInLabel);
goog.events.listen(inElement, [
goog.events.EventType.TOUCHEND,
goog.events.EventType.CLICK
@@ -44,7 +48,7 @@ ol.control.Zoom = function(opt_options) {
var outElement = goog.dom.createDom(goog.dom.TagName.A, {
'href': '#zoomOut',
'class': className + '-out'
- });
+ }, zoomOutLabel);
goog.events.listen(outElement, [
goog.events.EventType.TOUCHEND,
goog.events.EventType.CLICK
diff --git a/src/ol/dom/dom.js b/src/ol/dom/dom.js
index 44d86b8b43..9b9dea6990 100644
--- a/src/ol/dom/dom.js
+++ b/src/ol/dom/dom.js
@@ -4,15 +4,85 @@ goog.provide('ol.dom');
goog.provide('ol.dom.BrowserFeature');
goog.require('goog.asserts');
+goog.require('goog.dom');
+goog.require('goog.dom.TagName');
+goog.require('goog.style');
+goog.require('goog.userAgent');
goog.require('goog.vec.Mat4');
/**
+ * http://caniuse.com/#feat=transforms2d
+ * http://caniuse.com/#feat=transforms3d
* @enum {boolean}
*/
ol.dom.BrowserFeature = {
- CAN_USE_CSS_TRANSFORM: false,
- CAN_USE_CSS_TRANSFORM3D: true
+ CAN_USE_CSS_TRANSFORM: (
+ /**
+ * Detect 2d transform.
+ * Adapted from http://stackoverflow.com/q/5661671/130442
+ * @return {boolean}
+ */
+ function() {
+ if (!window.getComputedStyle) {
+ // this browser is ancient
+ return false;
+ }
+ var el = goog.dom.createElement(goog.dom.TagName.P),
+ has2d,
+ transforms = {
+ 'webkitTransform': '-webkit-transform',
+ 'OTransform': '-o-transform',
+ 'msTransform': '-ms-transform',
+ 'MozTransform': '-moz-transform',
+ 'transform': 'transform'
+ };
+ goog.dom.appendChild(document.body, el);
+ for (var t in transforms) {
+ if (t in el.style) {
+ el.style[t] = 'translate(1px,1px)';
+ has2d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
+ }
+ }
+ goog.dom.removeNode(el);
+
+ return (goog.isDefAndNotNull(has2d) && has2d.length > 0 &&
+ has2d !== 'none');
+ })(),
+ CAN_USE_CSS_TRANSFORM3D: (
+ /**
+ * Detect 3d transform.
+ * Adapted from http://stackoverflow.com/q/5661671/130442
+ * @return {boolean}
+ */
+ function() {
+ if (!window.getComputedStyle) {
+ // this browser is ancient
+ return false;
+ }
+ var el = goog.dom.createElement(goog.dom.TagName.P),
+ has3d,
+ transforms = {
+ 'webkitTransform': '-webkit-transform',
+ 'OTransform': '-o-transform',
+ 'msTransform': '-ms-transform',
+ 'MozTransform': '-moz-transform',
+ 'transform': 'transform'
+ };
+ goog.dom.appendChild(document.body, el);
+ for (var t in transforms) {
+ if (t in el.style) {
+ el.style[t] = 'translate3d(1px,1px,1px)';
+ has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
+ }
+ }
+ goog.dom.removeNode(el);
+
+ return (goog.isDefAndNotNull(has3d) && has3d.length > 0 &&
+ has3d !== 'none');
+ })(),
+ USE_MS_MATRIX_TRANSFORM: ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE,
+ USE_MS_ALPHA_FILTER: ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE
};
@@ -25,21 +95,97 @@ ol.dom.setTransform = function(element, value) {
style.WebkitTransform = value;
style.MozTransform = value;
style.OTransform = value;
+ style.msTransform = value;
style.transform = value;
+
+ // IE 9+ seems to assume transform-origin: 100% 100%; for some unknown reason
+ if (goog.userAgent.IE && !ol.IS_LEGACY_IE) {
+ element.style.transformOrigin = '0 0';
+ }
};
/**
- * @param {Element} element Element.
+ * Sets the opacity of an element, in an IE-compatible way
+ * @param {!Element} element Element
+ * @param {number} value Opacity, [0..1]
+ */
+ol.dom.setOpacity = function(element, value) {
+ if (ol.dom.BrowserFeature.USE_MS_ALPHA_FILTER) {
+ /** @type {string} */
+ var filter = element.currentStyle.filter;
+
+ /** @type {RegExp} */
+ var regex;
+
+ /** @type {string} */
+ var alpha;
+
+ if (goog.userAgent.VERSION == '8.0') {
+ regex = /progid:DXImageTransform\.Microsoft\.Alpha\(.*?\)/i,
+ alpha = 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' +
+ (value * 100) + ')';
+ } else {
+ regex = /alpha\(.*?\)/i;
+ alpha = 'alpha(opacity=' + (value * 100) + ')';
+ }
+
+ var newFilter = filter.replace(regex, alpha);
+ if (newFilter === filter) {
+ // no replace was made? just append the new alpha filter instead
+ newFilter += ' ' + alpha;
+ }
+
+ element.style.filter = newFilter;
+
+ // Fix to apply filter to absolutely-positioned children element
+ if (element.currentStyle.zIndex === 'auto') {
+ element.style.zIndex = 0;
+ }
+ } else {
+ goog.style.setOpacity(element, value);
+ }
+};
+
+
+/**
+ * Sets the IE matrix transform without replacing other filters
+ * @private
+ * @param {!Element} element Element
+ * @param {string} value The new progid string
+ */
+ol.dom.setIEMatrix_ = function(element, value) {
+ var filter = element.currentStyle.filter;
+ var newFilter =
+ filter.replace(/progid:DXImageTransform.Microsoft.Matrix\(.*?\)/i, value);
+
+ if (newFilter === filter) {
+ newFilter = ' ' + value;
+ }
+
+ element.style.filter = newFilter;
+
+ // Fix to apply filter to absolutely-positioned children element
+ if (element.currentStyle.zIndex === 'auto') {
+ element.style.zIndex = 0;
+ }
+};
+
+
+/**
+ * @param {!Element} element Element.
* @param {goog.vec.Mat4.Number} transform Matrix.
* @param {number=} opt_precision Precision.
+ * @param {Element=} opt_translationElement Required for IE7-8
*/
-ol.dom.transformElement2D = function(element, transform, opt_precision) {
+ol.dom.transformElement2D =
+ function(element, transform, opt_precision, opt_translationElement) {
// using matrix() causes gaps in Chrome and Firefox on Mac OS X, so prefer
// matrix3d()
var i;
if (ol.dom.BrowserFeature.CAN_USE_CSS_TRANSFORM3D) {
var value3D;
+
if (goog.isDef(opt_precision)) {
/** @type {Array.} */
var strings3D = new Array(16);
@@ -73,10 +219,46 @@ ol.dom.transformElement2D = function(element, transform, opt_precision) {
value2D = transform2D.join(',');
}
ol.dom.setTransform(element, 'matrix(' + value2D + ')');
+ } else if (ol.dom.BrowserFeature.USE_MS_MATRIX_TRANSFORM) {
+ var m11 = goog.vec.Mat4.getElement(transform, 0, 0),
+ m12 = goog.vec.Mat4.getElement(transform, 0, 1),
+ m21 = goog.vec.Mat4.getElement(transform, 1, 0),
+ m22 = goog.vec.Mat4.getElement(transform, 1, 1),
+ dx = goog.vec.Mat4.getElement(transform, 0, 3),
+ dy = goog.vec.Mat4.getElement(transform, 1, 3);
+
+ // See: http://msdn.microsoft.com/en-us/library/ms533014(v=vs.85).aspx
+ // and: http://extremelysatisfactorytotalitarianism.com/blog/?p=1002
+ // @TODO: fix terrible IE bbox rotation issue.
+ var s = 'progid:DXImageTransform.Microsoft.Matrix(';
+ s += 'sizingMethod="auto expand"';
+ s += ',M11=' + m11.toFixed(opt_precision || 20);
+ s += ',M12=' + m12.toFixed(opt_precision || 20);
+ s += ',M21=' + m21.toFixed(opt_precision || 20);
+ s += ',M22=' + m22.toFixed(opt_precision || 20);
+ s += ')';
+ ol.dom.setIEMatrix_(element, s);
+
+ // scale = m11 = m22 = target resolution [m/px] / current res [m/px]
+ // dx = (viewport width [px] / 2) * scale
+ // + (layer.x [m] - view.x [m]) / target resolution [m / px]
+ // except that we're positioning the child element relative to the
+ // viewport, not the map.
+ // dividing by the scale factor isn't the exact correction, but it's
+ // close enough that you can barely tell unless you're looking for it
+ dx /= m11;
+ dy /= m22;
+
+ opt_translationElement.style.left = Math.round(dx) + 'px';
+ opt_translationElement.style.top = Math.round(dy) + 'px';
} else {
- // FIXME check this code!
- var style = element.style;
- style.left = Math.round(goog.vec.Mat4.getElement(transform, 0, 3)) + 'px';
- style.top = Math.round(goog.vec.Mat4.getElement(transform, 1, 3)) + 'px';
+ element.style.left =
+ Math.round(goog.vec.Mat4.getElement(transform, 0, 3)) + 'px';
+ element.style.top =
+ Math.round(goog.vec.Mat4.getElement(transform, 1, 3)) + 'px';
+
+ // TODO: Add scaling here. This isn't quite as simple as multiplying
+ // width/height, because that only changes the container size, not the
+ // content size.
}
};
diff --git a/src/ol/imagetile.js b/src/ol/imagetile.js
index dd7098f00e..1fa5c9b866 100644
--- a/src/ol/imagetile.js
+++ b/src/ol/imagetile.js
@@ -115,6 +115,11 @@ ol.ImageTile.prototype.handleImageError_ = function() {
* @private
*/
ol.ImageTile.prototype.handleImageLoad_ = function() {
+ if (!goog.isDef(this.image_.naturalWidth)) {
+ this.image_.naturalWidth = this.image_.width;
+ this.image_.naturalHeight = this.image_.height;
+ }
+
if (this.image_.naturalWidth && this.image_.naturalHeight) {
this.state = ol.TileState.LOADED;
} else {
diff --git a/src/ol/interaction/drawinteraction.js b/src/ol/interaction/drawinteraction.js
index 1ee25f8872..c2d19aded1 100644
--- a/src/ol/interaction/drawinteraction.js
+++ b/src/ol/interaction/drawinteraction.js
@@ -148,18 +148,15 @@ ol.interaction.Draw = function(options) {
*/
this.overlay_ = new ol.FeatureOverlay();
this.overlay_.setStyleFunction(goog.isDef(options.styleFunction) ?
- options.styleFunction : ol.interaction.Draw.defaultStyleFunction
- );
+ options.styleFunction : ol.interaction.Draw.getDefaultStyleFunction());
};
goog.inherits(ol.interaction.Draw, ol.interaction.Interaction);
/**
- * @param {ol.Feature} feature Feature.
- * @param {number} resolution Resolution.
- * @return {Array.} Styles.
+ * @return {ol.feature.StyleFunction} Styles.
*/
-ol.interaction.Draw.defaultStyleFunction = (function() {
+ol.interaction.Draw.getDefaultStyleFunction = function() {
/** @type {Object.>} */
var styles = {};
styles[ol.geom.GeometryType.POLYGON] = [
@@ -210,7 +207,7 @@ ol.interaction.Draw.defaultStyleFunction = (function() {
return function(feature, resolution) {
return styles[feature.getGeometry().getType()];
};
-})();
+};
/**
diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js
index bfd7088cd3..326505f967 100644
--- a/src/ol/mapbrowserevent.js
+++ b/src/ol/mapbrowserevent.js
@@ -8,6 +8,7 @@ goog.require('goog.events');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
+goog.require('goog.object');
goog.require('ol.Coordinate');
goog.require('ol.FrameState');
goog.require('ol.MapEvent');
@@ -132,6 +133,14 @@ ol.MapBrowserEventHandler = function(map) {
*/
this.touchstartListenerKey_ = null;
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ /**
+ * @type {goog.events.Key}
+ * @private
+ */
+ this.ieDblclickListenerKey_ = null;
+ }
+
/**
* @type {goog.events.BrowserEvent}
* @private
@@ -161,6 +170,10 @@ ol.MapBrowserEventHandler = function(map) {
goog.events.EventType.TOUCHSTART,
this.handleTouchStart_, false, this);
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ this.ieDblclickListenerKey_ = goog.events.listen(element,
+ goog.events.EventType.DBLCLICK, this.emulateClick_, false, this);
+ }
};
goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget);
@@ -190,12 +203,28 @@ ol.MapBrowserEventHandler.prototype.emulateClick_ = function(browserEvent) {
this.dispatchEvent(newEvent);
} else {
// click
- this.clickTimeoutId_ = goog.global.setTimeout(goog.bind(function() {
- this.clickTimeoutId_ = 0;
- var newEvent = new ol.MapBrowserEvent(
- ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_, browserEvent);
- this.dispatchEvent(newEvent);
- }, this), 250);
+
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ // In IE 7-8, referring to the original event object after the current
+ // call stack causes "member not found" exceptions, such as in the timeout
+ // we use here.
+ var ev = /** @type {Event} */ (
+ goog.object.clone(browserEvent.getBrowserEvent()));
+ this.clickTimeoutId_ = goog.global.setTimeout(goog.bind(function() {
+ this.clickTimeoutId_ = 0;
+ var newEvent = new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_,
+ new goog.events.BrowserEvent(ev, browserEvent.currentTarget));
+ this.dispatchEvent(newEvent);
+ }, this), 250);
+ } else {
+ this.clickTimeoutId_ = goog.global.setTimeout(goog.bind(function() {
+ this.clickTimeoutId_ = 0;
+ var newEvent = new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_, browserEvent);
+ this.dispatchEvent(newEvent);
+ }, this), 250);
+ }
}
};
@@ -446,6 +475,11 @@ ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
this.dragListenerKeys_ = null;
}
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE &&
+ !goog.isNull(this.ieDblclickListenerKey_)) {
+ goog.events.unlistenByKey(this.ieDblclickListenerKey_);
+ this.ieDblclickListenerKey_ = null;
+ }
goog.base(this, 'disposeInternal');
};
diff --git a/src/ol/renderer/dom/dommaprenderer.js b/src/ol/renderer/dom/dommaprenderer.js
index e680a02fd2..0eaa8410bb 100644
--- a/src/ol/renderer/dom/dommaprenderer.js
+++ b/src/ol/renderer/dom/dommaprenderer.js
@@ -3,6 +3,7 @@ goog.provide('ol.renderer.dom.Map');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
+goog.require('goog.functions');
goog.require('goog.style');
goog.require('ol.css');
goog.require('ol.layer.Image');
@@ -36,6 +37,14 @@ ol.renderer.dom.Map = function(container, map) {
style.width = '100%';
style.height = '100%';
+ // in IE < 9, we need to return false from ondragstart to cancel the default
+ // behavior of dragging images, which is interfering with the custom handler
+ // in the Drag interaction subclasses
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ this.layersPane_.ondragstart = goog.functions.FALSE;
+ this.layersPane_.onselectstart = goog.functions.FALSE;
+ }
+
goog.dom.insertChildAt(container, this.layersPane_, 0);
/**
@@ -61,7 +70,6 @@ ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
goog.asserts.fail();
return null;
}
- goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
return layerRenderer;
};
@@ -79,12 +87,45 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) {
return;
}
+ /**
+ * @this {ol.renderer.dom.Map}
+ * @param {Element} elem
+ * @param {number} i
+ */
+ var addChild;
+
+ // appendChild is actually more performant than insertBefore
+ // in IE 7 and 8. http://jsperf.com/reattaching-dom-nodes
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ addChild =
+ /**
+ * @this {ol.renderer.dom.Map}
+ * @param {Element} elem
+ */ (
+ function(elem) {
+ goog.dom.appendChild(this.layersPane_, elem);
+ });
+ } else {
+ addChild =
+ /**
+ * @this {ol.renderer.dom.Map}
+ * @param {Element} elem
+ * @param {number} i
+ */ (
+ function(elem, i) {
+ goog.dom.insertChildAt(this.layersPane_, elem, i);
+ });
+ }
+
var layerStates = frameState.layerStates;
var layersArray = frameState.layersArray;
var i, ii, layer, layerRenderer, layerState;
for (i = 0, ii = layersArray.length; i < ii; ++i) {
layer = layersArray[i];
- layerRenderer = this.getLayerRenderer(layer);
+ layerRenderer = /** @type {ol.renderer.dom.Layer} */ (
+ this.getLayerRenderer(layer));
+ goog.asserts.assertInstanceof(layerRenderer, ol.renderer.dom.Layer);
+ addChild.call(this, layerRenderer.getTarget(), i);
layerState = frameState.layerStates[goog.getUid(layer)];
if (layerState.sourceState == ol.source.State.READY) {
layerRenderer.prepareFrame(frameState, layerState);
diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js
index a2b9974a16..a8d7b42b0a 100644
--- a/src/ol/renderer/dom/domtilelayerrenderer.js
+++ b/src/ol/renderer/dom/domtilelayerrenderer.js
@@ -17,6 +17,7 @@ goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.ViewHint');
goog.require('ol.dom');
+goog.require('ol.dom.BrowserFeature');
goog.require('ol.extent');
goog.require('ol.layer.Tile');
goog.require('ol.renderer.dom.Layer');
@@ -37,6 +38,12 @@ ol.renderer.dom.TileLayer = function(mapRenderer, tileLayer) {
var target = goog.dom.createElement(goog.dom.TagName.DIV);
target.style.position = 'absolute';
+ // Needed for IE7-8 to render a transformed element correctly
+ if (ol.dom.BrowserFeature.USE_MS_MATRIX_TRANSFORM) {
+ target.style.width = '100%';
+ target.style.height = '100%';
+ }
+
goog.base(this, mapRenderer, tileLayer, target);
/**
@@ -229,7 +236,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
}
if (layerState.opacity != this.renderedOpacity_) {
- goog.style.setOpacity(this.target, layerState.opacity);
+ ol.dom.setOpacity(this.target, layerState.opacity);
this.renderedOpacity_ = layerState.opacity;
}
@@ -261,6 +268,23 @@ ol.renderer.dom.TileLayerZ_ = function(tileGrid, tileCoordOrigin) {
*/
this.target = goog.dom.createElement(goog.dom.TagName.DIV);
this.target.style.position = 'absolute';
+ this.target.style.width = '100%';
+ this.target.style.height = '100%';
+
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ /**
+ * Needed due to issues with IE7-8 clipping of transformed elements
+ * Solution is to translate separately from the scaled/rotated elements
+ * @private
+ * @type {!Element}
+ */
+ this.translateTarget_ = goog.dom.createElement(goog.dom.TagName.DIV);
+ this.translateTarget_.style.position = 'absolute';
+ this.translateTarget_.style.width = '100%';
+ this.translateTarget_.style.height = '100%';
+
+ goog.dom.appendChild(this.target, this.translateTarget_);
+ }
/**
* @private
@@ -364,7 +388,11 @@ ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile, tileGutter) {
*/
ol.renderer.dom.TileLayerZ_.prototype.finalizeAddTiles = function() {
if (!goog.isNull(this.documentFragment_)) {
- goog.dom.appendChild(this.target, this.documentFragment_);
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ goog.dom.appendChild(this.translateTarget_, this.documentFragment_);
+ } else {
+ goog.dom.appendChild(this.target, this.documentFragment_);
+ }
this.documentFragment_ = null;
}
};
@@ -418,7 +446,12 @@ ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent =
*/
ol.renderer.dom.TileLayerZ_.prototype.setTransform = function(transform) {
if (!ol.vec.Mat4.equals2D(transform, this.transform_)) {
- ol.dom.transformElement2D(this.target, transform, 6);
+ if (ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE) {
+ ol.dom.transformElement2D(this.target, transform, 6,
+ this.translateTarget_);
+ } else {
+ ol.dom.transformElement2D(this.target, transform, 6);
+ }
goog.vec.Mat4.setFromArray(this.transform_, transform);
}
};