From 7dd7e4f69962b20c7e3a48b5441800534628ee2b Mon Sep 17 00:00:00 2001 From: oslek Date: Mon, 14 Jan 2013 14:04:50 -0800 Subject: [PATCH] Robust array type check for cross-frame support In a multi-frame DOM environment, if setView is called with an array for the first parameter, a subsequent call to getBounds raises "Invalid LatLng object" exception. This is the case if the array passed to setView was created outside the iFrame that contains the map. It causes the array test using "instanceof" in L.latLng to fail, and _initialTopLeftPoint to not being properly initialized. Thank you to Juriy Zaytsev for the full explaination: http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ John Resig and Dean Edwards post comments and concur. --- src/core/Util.js | 4 ++++ src/geo/LatLng.js | 2 +- src/geometry/Point.js | 2 +- src/layer/GeoJSON.js | 2 +- src/layer/vector/Polygon.js | 2 +- src/layer/vector/Polyline.js | 2 +- src/map/Map.js | 2 +- 7 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/Util.js b/src/core/Util.js index d6a8c230..efb797a4 100644 --- a/src/core/Util.js +++ b/src/core/Util.js @@ -97,6 +97,10 @@ L.Util = { }); }, + isArray: function (obj) { + return (Object.prototype.toString.call(obj) === '[object Array]'); + }, + emptyImageUrl: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' }; diff --git a/src/geo/LatLng.js b/src/geo/LatLng.js index c39d3986..94ab9bf6 100644 --- a/src/geo/LatLng.js +++ b/src/geo/LatLng.js @@ -74,7 +74,7 @@ L.latLng = function (a, b) { // (LatLng) or ([Number, Number]) or (Number, Numbe if (a instanceof L.LatLng) { return a; } - if (a instanceof Array) { + if (L.Util.isArray(a)) { return new L.LatLng(a[0], a[1]); } if (isNaN(a)) { diff --git a/src/geometry/Point.js b/src/geometry/Point.js index a976e1b4..a34b8a0f 100644 --- a/src/geometry/Point.js +++ b/src/geometry/Point.js @@ -100,7 +100,7 @@ L.point = function (x, y, round) { if (x instanceof L.Point) { return x; } - if (x instanceof Array) { + if (L.Util.isArray(x)) { return new L.Point(x[0], x[1]); } if (isNaN(x)) { diff --git a/src/layer/GeoJSON.js b/src/layer/GeoJSON.js index 2834c8d5..0d618a75 100644 --- a/src/layer/GeoJSON.js +++ b/src/layer/GeoJSON.js @@ -15,7 +15,7 @@ L.GeoJSON = L.FeatureGroup.extend({ }, addData: function (geojson) { - var features = geojson instanceof Array ? geojson : geojson.features, + var features = L.Util.isArray(geojson) ? geojson : geojson.features, i, len; if (features) { diff --git a/src/layer/vector/Polygon.js b/src/layer/vector/Polygon.js index c8b28a60..44665593 100644 --- a/src/layer/vector/Polygon.js +++ b/src/layer/vector/Polygon.js @@ -10,7 +10,7 @@ L.Polygon = L.Polyline.extend({ initialize: function (latlngs, options) { L.Polyline.prototype.initialize.call(this, latlngs, options); - if (latlngs && (latlngs[0] instanceof Array) && (typeof latlngs[0][0] !== 'number')) { + if (latlngs && L.Util.isArray(latlngs[0]) && (typeof latlngs[0][0] !== 'number')) { this._latlngs = this._convertLatLngs(latlngs[0]); this._holes = latlngs.slice(1); } diff --git a/src/layer/vector/Polyline.js b/src/layer/vector/Polyline.js index 45bdd80d..767f26f2 100644 --- a/src/layer/vector/Polyline.js +++ b/src/layer/vector/Polyline.js @@ -88,7 +88,7 @@ L.Polyline = L.Path.extend({ _convertLatLngs: function (latlngs) { var i, len; for (i = 0, len = latlngs.length; i < len; i++) { - if (latlngs[i] instanceof Array && typeof latlngs[i][0] !== 'number') { + if (L.Util.isArray(latlngs[i]) && typeof latlngs[i][0] !== 'number') { return; } latlngs[i] = L.latLng(latlngs[i]); diff --git a/src/map/Map.js b/src/map/Map.js index 61482531..b6787738 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -466,7 +466,7 @@ L.Map = L.Class.extend({ }, _initLayers: function (layers) { - layers = layers ? (layers instanceof Array ? layers : [layers]) : []; + layers = layers ? (L.Util.isArray(layers) ? layers : [layers]) : []; this._layers = {}; this._zoomBoundLayers = {};