Version Description
[2014-12-24] =
* fixed: maps broken when hidden in tabs / accordions (not for IE 10 and earlier; uses MutationObserver)
* fixed: strip spaces from map coordinates
* fixed: suppress border radius on images within map containers
* added: server-side lookup of address, to reduce the number of Google Maps queries when only an address is given
* added: support for custom map types (inc. styled maps)
* added: maptypes
attribute for selecting which map types can be picked by visitors
* changed: refactored JavaScript for localised strings
Download this release
Release Info
Developer | webaware |
Plugin | Flexible Map |
Version | 1.9.0 |
Comparing to | |
See all releases |
Code changes from version 1.8.3 to 1.9.0
- css/styles.css +1 -0
- flexible-map.php +2 -2
- includes/class.FlxMapPlugin.php +107 -7
- js/flexible-map.js +160 -44
- js/flexible-map.min.js +1 -1
- readme.txt +39 -20
css/styles.css
CHANGED
@@ -12,6 +12,7 @@
|
|
12 |
-moz-box-shadow: none !important;
|
13 |
box-shadow: none !important;
|
14 |
background-color: transparent !important;
|
|
|
15 |
}
|
16 |
|
17 |
.site-content .flxmap-directions img.adp-marker,
|
12 |
-moz-box-shadow: none !important;
|
13 |
box-shadow: none !important;
|
14 |
background-color: transparent !important;
|
15 |
+
border-radius: 0px !important;
|
16 |
}
|
17 |
|
18 |
.site-content .flxmap-directions img.adp-marker,
|
flexible-map.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Flexible Map
|
4 |
Plugin URI: http://flexible-map.webaware.net.au/
|
5 |
Description: Embed Google Maps in pages and posts, either by centre coodinates or street address, or by URL to a Google Earth KML file.
|
6 |
-
Version: 1.
|
7 |
Author: WebAware
|
8 |
Author URI: http://webaware.com.au/
|
9 |
Text Domain: flexible-map
|
@@ -36,7 +36,7 @@ if (!defined('ABSPATH')) {
|
|
36 |
define('FLXMAP_PLUGIN_FILE', __FILE__);
|
37 |
define('FLXMAP_PLUGIN_ROOT', dirname(__FILE__) . '/');
|
38 |
define('FLXMAP_PLUGIN_NAME', basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
39 |
-
define('FLXMAP_PLUGIN_VERSION', '1.
|
40 |
|
41 |
// shortcode tags
|
42 |
define('FLXMAP_PLUGIN_TAG_MAP', 'flexiblemap');
|
3 |
Plugin Name: Flexible Map
|
4 |
Plugin URI: http://flexible-map.webaware.net.au/
|
5 |
Description: Embed Google Maps in pages and posts, either by centre coodinates or street address, or by URL to a Google Earth KML file.
|
6 |
+
Version: 1.9.0
|
7 |
Author: WebAware
|
8 |
Author URI: http://webaware.com.au/
|
9 |
Text Domain: flexible-map
|
36 |
define('FLXMAP_PLUGIN_FILE', __FILE__);
|
37 |
define('FLXMAP_PLUGIN_ROOT', dirname(__FILE__) . '/');
|
38 |
define('FLXMAP_PLUGIN_NAME', basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
39 |
+
define('FLXMAP_PLUGIN_VERSION', '1.9.0');
|
40 |
|
41 |
// shortcode tags
|
42 |
define('FLXMAP_PLUGIN_TAG_MAP', 'flexiblemap');
|
includes/class.FlxMapPlugin.php
CHANGED
@@ -6,7 +6,8 @@ class FlxMapPlugin {
|
|
6 |
public $urlBase; // string: base URL path to files in plugin
|
7 |
|
8 |
protected $locale; // locale of current website
|
9 |
-
protected $locales
|
|
|
10 |
|
11 |
/**
|
12 |
* static method for getting the instance of this singleton object
|
@@ -103,7 +104,7 @@ class FlxMapPlugin {
|
|
103 |
}
|
104 |
|
105 |
/**
|
106 |
-
* load any enqueued locales as localisations on the main script
|
107 |
*/
|
108 |
public function justInTimeLocalisation() {
|
109 |
if (!empty($this->locales)) {
|
@@ -144,6 +145,11 @@ class FlxMapPlugin {
|
|
144 |
// TODO: handle plurals (not yet needed, don't have any)
|
145 |
$strings = array();
|
146 |
foreach ($mo->entries as $original => $translation) {
|
|
|
|
|
|
|
|
|
|
|
147 |
$strings[$original] = $translation->translations[0];
|
148 |
}
|
149 |
$i18n[$locale] = $strings;
|
@@ -153,8 +159,17 @@ class FlxMapPlugin {
|
|
153 |
}
|
154 |
}
|
155 |
|
|
|
|
|
156 |
if (!empty($i18n)) {
|
157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
159 |
}
|
160 |
}
|
@@ -178,9 +193,12 @@ class FlxMapPlugin {
|
|
178 |
public function getMap($attrs) {
|
179 |
$html = '';
|
180 |
|
181 |
-
// allow
|
182 |
$attrs = apply_filters('flexmap_shortcode_attrs', $attrs);
|
183 |
|
|
|
|
|
|
|
184 |
if (!empty($attrs['src']) || !empty($attrs['center']) || !empty($attrs['address'])) {
|
185 |
$this->loadScripts = true;
|
186 |
if (empty($attrs['id'])) {
|
@@ -324,6 +342,10 @@ HTML;
|
|
324 |
$script .= " f.mapTypeId = \"{$this->str2js($attrs['maptype'])}\";\n";
|
325 |
}
|
326 |
|
|
|
|
|
|
|
|
|
327 |
if (isset($attrs['region'])) {
|
328 |
$script .= " f.region = \"{$this->str2js($attrs['region'])}\";\n";
|
329 |
}
|
@@ -339,11 +361,20 @@ HTML;
|
|
339 |
$this->enqueueLocale($locale);
|
340 |
}
|
341 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
// add map based on coordinates, with optional marker coordinates
|
343 |
if (isset($attrs['center']) && self::isCoordinates($attrs['center'])) {
|
344 |
-
$marker = self::str2js($attrs['center']);
|
345 |
if (isset($attrs['marker']) && self::isCoordinates($attrs['marker']))
|
346 |
-
$marker = self::str2js($attrs['marker']);
|
347 |
|
348 |
if (isset($attrs['zoom']))
|
349 |
$script .= " f.zoom = " . preg_replace('/\D/', '', $attrs['zoom']) . ";\n";
|
@@ -489,6 +520,63 @@ HTML;
|
|
489 |
return $units;
|
490 |
}
|
491 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
492 |
/**
|
493 |
* test string to see if contents equate to yes/true
|
494 |
* @param string $text
|
@@ -513,7 +601,19 @@ HTML;
|
|
513 |
* @return boolean
|
514 |
*/
|
515 |
public static function isCoordinates($text) {
|
516 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
517 |
}
|
518 |
|
519 |
/**
|
6 |
public $urlBase; // string: base URL path to files in plugin
|
7 |
|
8 |
protected $locale; // locale of current website
|
9 |
+
protected $locales = array(); // list of locales enqueued for localisation of maps
|
10 |
+
protected $mapTypes = array(); // custom Google Maps map types to be loaded with maps, keyed by mapTypeId
|
11 |
|
12 |
/**
|
13 |
* static method for getting the instance of this singleton object
|
104 |
}
|
105 |
|
106 |
/**
|
107 |
+
* load any enqueued locales and map types as localisations on the main script
|
108 |
*/
|
109 |
public function justInTimeLocalisation() {
|
110 |
if (!empty($this->locales)) {
|
145 |
// TODO: handle plurals (not yet needed, don't have any)
|
146 |
$strings = array();
|
147 |
foreach ($mo->entries as $original => $translation) {
|
148 |
+
// skip admin-side strings, identified by context
|
149 |
+
if ($translation->context == 'plugin details links') {
|
150 |
+
continue;
|
151 |
+
}
|
152 |
+
|
153 |
$strings[$original] = $translation->translations[0];
|
154 |
}
|
155 |
$i18n[$locale] = $strings;
|
159 |
}
|
160 |
}
|
161 |
|
162 |
+
// build and enqueue localisations for map script
|
163 |
+
$localise = array();
|
164 |
if (!empty($i18n)) {
|
165 |
+
$localise['i18n'] = $i18n;
|
166 |
+
}
|
167 |
+
if (!empty($this->mapTypes)) {
|
168 |
+
$localise['mapTypes'] = $this->mapTypes;
|
169 |
+
}
|
170 |
+
|
171 |
+
if (!empty($localise)) {
|
172 |
+
wp_localize_script('flxmap', 'flxmap', $localise);
|
173 |
}
|
174 |
}
|
175 |
}
|
193 |
public function getMap($attrs) {
|
194 |
$html = '';
|
195 |
|
196 |
+
// allow plugins / themes to change the shortcode attributes used
|
197 |
$attrs = apply_filters('flexmap_shortcode_attrs', $attrs);
|
198 |
|
199 |
+
// allow plugins / themes to register custom Google Maps map types
|
200 |
+
$this->mapTypes = apply_filters('flexmap_custom_map_types', $this->mapTypes, $attrs);
|
201 |
+
|
202 |
if (!empty($attrs['src']) || !empty($attrs['center']) || !empty($attrs['address'])) {
|
203 |
$this->loadScripts = true;
|
204 |
if (empty($attrs['id'])) {
|
342 |
$script .= " f.mapTypeId = \"{$this->str2js($attrs['maptype'])}\";\n";
|
343 |
}
|
344 |
|
345 |
+
if (isset($attrs['maptypes'])) {
|
346 |
+
$script .= " f.mapTypeIds = \"{$this->str2js($attrs['maptypes'])}\";\n";
|
347 |
+
}
|
348 |
+
|
349 |
if (isset($attrs['region'])) {
|
350 |
$script .= " f.region = \"{$this->str2js($attrs['region'])}\";\n";
|
351 |
}
|
361 |
$this->enqueueLocale($locale);
|
362 |
}
|
363 |
|
364 |
+
// if have address but not coordinates, attempt to retrieve coordinates for address
|
365 |
+
if (empty($attrs['center']) && !empty($attrs['address'])) {
|
366 |
+
$region = empty($attrs['region']) ? '' : $attrs['region'];
|
367 |
+
$center = self::getAddressCoordinates($attrs['address'], $region);
|
368 |
+
if ($center) {
|
369 |
+
$attrs['center'] = implode(',', $center);
|
370 |
+
}
|
371 |
+
}
|
372 |
+
|
373 |
// add map based on coordinates, with optional marker coordinates
|
374 |
if (isset($attrs['center']) && self::isCoordinates($attrs['center'])) {
|
375 |
+
$marker = self::str2js(self::getCoordinates($attrs['center']));
|
376 |
if (isset($attrs['marker']) && self::isCoordinates($attrs['marker']))
|
377 |
+
$marker = self::str2js(self::getCoordinates($attrs['marker']));
|
378 |
|
379 |
if (isset($attrs['zoom']))
|
380 |
$script .= " f.zoom = " . preg_replace('/\D/', '', $attrs['zoom']) . ";\n";
|
520 |
return $units;
|
521 |
}
|
522 |
|
523 |
+
/**
|
524 |
+
* get coordinate for given address
|
525 |
+
* @param string $address
|
526 |
+
* @param string $region
|
527 |
+
* @return array|false
|
528 |
+
*/
|
529 |
+
protected static function getAddressCoordinates($address, $region) {
|
530 |
+
// try to get a cached answer first
|
531 |
+
$cacheKey = 'flxmap_' . md5("$address|$region");
|
532 |
+
$coords = get_transient($cacheKey);
|
533 |
+
|
534 |
+
if ($coords === false) {
|
535 |
+
// build Google Maps geocoding query
|
536 |
+
$args = array('address' => urlencode($address));
|
537 |
+
if (!empty($region)) {
|
538 |
+
$args['region'] = urlencode($region);
|
539 |
+
}
|
540 |
+
$url = add_query_arg($args, 'https://maps.googleapis.com/maps/api/geocode/json');
|
541 |
+
|
542 |
+
try {
|
543 |
+
// fetch coordinates
|
544 |
+
$response = wp_remote_get($url);
|
545 |
+
|
546 |
+
if (is_wp_error($response)) {
|
547 |
+
throw new Exception('http error = ' . $response->get_error_message());
|
548 |
+
}
|
549 |
+
|
550 |
+
$result = json_decode($response['body']);
|
551 |
+
if (!$result) {
|
552 |
+
throw new Exception("error decoding JSON\n" . $response['body']);
|
553 |
+
}
|
554 |
+
|
555 |
+
if ($result->status != 'OK') {
|
556 |
+
throw new Exception("error retrieving address: " . $result->status);
|
557 |
+
}
|
558 |
+
|
559 |
+
// success, return array with latitude and longitude
|
560 |
+
$location = $result->results[0]->geometry->location;
|
561 |
+
$coords = array($location->lat, $location->lng);
|
562 |
+
}
|
563 |
+
catch (Exception $e) {
|
564 |
+
$coords = "address: $address; " . $e->getMessage();
|
565 |
+
error_log(__METHOD__ . ': ' . $coords);
|
566 |
+
}
|
567 |
+
|
568 |
+
// save coordinates to prevent unnecessary requery
|
569 |
+
set_transient($cacheKey, $coords, WEEK_IN_SECONDS);
|
570 |
+
}
|
571 |
+
|
572 |
+
// handle failure to map address to coordinates by returning false
|
573 |
+
if (!is_array($coords)) {
|
574 |
+
$coords = false;
|
575 |
+
}
|
576 |
+
|
577 |
+
return $coords;
|
578 |
+
}
|
579 |
+
|
580 |
/**
|
581 |
* test string to see if contents equate to yes/true
|
582 |
* @param string $text
|
601 |
* @return boolean
|
602 |
*/
|
603 |
public static function isCoordinates($text) {
|
604 |
+
// TODO: handle degrees minutes seconds, degrees minutes.decimal, NSEW
|
605 |
+
return preg_match('/^-?[0-9]+(?:\.[0-9]+),\s*-?[0-9]+(?:\.[0-9]+)$/', $text);
|
606 |
+
}
|
607 |
+
|
608 |
+
/**
|
609 |
+
* return standardised coordinates from text
|
610 |
+
* NB: assumes text passes isCoordinates() above
|
611 |
+
* @param string $text
|
612 |
+
* @return boolean
|
613 |
+
*/
|
614 |
+
protected static function getCoordinates($text) {
|
615 |
+
// TODO: handle degrees minutes seconds, degrees minutes.decimal, NSEW
|
616 |
+
return str_replace(' ', '', $text);
|
617 |
}
|
618 |
|
619 |
/**
|
js/flexible-map.js
CHANGED
@@ -10,6 +10,8 @@ function FlexibleMap() {
|
|
10 |
var map, // google.maps.Map object
|
11 |
centre, // google.maps.LatLng object for map centre
|
12 |
markerLocation, // google.maps.LatLng object for single marker, when using showMarker()
|
|
|
|
|
13 |
kmlLayer, // if map has a KML layer, this is the layer object
|
14 |
hasRedrawn = false; // boolean, whether map has been asked to redrawOnce() already
|
15 |
|
@@ -54,6 +56,38 @@ function FlexibleMap() {
|
|
54 |
return markerLocation;
|
55 |
};
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
/**
|
58 |
* get the map's KML layer if set
|
59 |
* @return {google.maps.KmlLayer}
|
@@ -81,35 +115,49 @@ function FlexibleMap() {
|
|
81 |
this.showMap = function(divID, latLng) {
|
82 |
centre = new google.maps.LatLng(latLng[0], latLng[1]);
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
"
|
88 |
-
"
|
|
|
89 |
};
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
if (this.zoomControlStyle in zoomControlStyles) {
|
92 |
-
zoomControlStyle = zoomControlStyles[this.zoomControlStyle];
|
93 |
}
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
|
98 |
// create a map
|
99 |
-
map = new google.maps.Map(document.getElementById(divID),
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
zoomControl: this.zoomControl,
|
106 |
-
zoomControlOptions: { style: zoomControlStyle },
|
107 |
-
draggable: this.draggable,
|
108 |
-
disableDoubleClickZoom: !this.dblclickZoom,
|
109 |
-
scrollwheel: this.scrollwheel,
|
110 |
-
center: centre,
|
111 |
-
zoom: this.zoom
|
112 |
-
});
|
113 |
|
114 |
return map;
|
115 |
};
|
@@ -132,6 +180,11 @@ function FlexibleMap() {
|
|
132 |
return kmlLayer;
|
133 |
};
|
134 |
|
|
|
|
|
|
|
|
|
|
|
135 |
// set map defaults
|
136 |
this.mapTypeId = google.maps.MapTypeId.ROADMAP;
|
137 |
this.mapTypeControl = true; // no control for changing map type
|
@@ -163,14 +216,14 @@ function FlexibleMap() {
|
|
163 |
this.dirShowSearch = true; // show the directions form for searching directions
|
164 |
this.region = "";
|
165 |
this.locale = "en";
|
166 |
-
this.localeActive =
|
167 |
this.kmlcache = "none";
|
168 |
}
|
169 |
|
170 |
FlexibleMap.prototype = (function() {
|
171 |
"use strict";
|
172 |
|
173 |
-
var addEventListener, stopEvent;
|
174 |
|
175 |
// detect standard event model
|
176 |
if (document.addEventListener) {
|
@@ -196,6 +249,41 @@ FlexibleMap.prototype = (function() {
|
|
196 |
};
|
197 |
}
|
198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
/**
|
200 |
* encode special JavaScript characters, so text is safe when building JavaScript/HTML dynamically
|
201 |
* NB: conservatively assumes that HTML special characters are unsafe, and encodes them too
|
@@ -279,15 +367,39 @@ FlexibleMap.prototype = (function() {
|
|
279 |
/**
|
280 |
* collection of locale / phrase mapping for internationalisation of messages
|
281 |
*/
|
282 |
-
i18n: {
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
}
|
|
|
|
|
289 |
},
|
290 |
-
i18n_loaded: false, // set to true once localisations have been loaded
|
291 |
|
292 |
/**
|
293 |
* set the locale used for i18n phrase lookup, picking the best match
|
@@ -297,14 +409,6 @@ FlexibleMap.prototype = (function() {
|
|
297 |
setlocale: function(localeWanted) {
|
298 |
this.locale = localeWanted;
|
299 |
|
300 |
-
// load localisations if they haven't already been loaded
|
301 |
-
if (!this.i18n_loaded && "flxmap" in window) {
|
302 |
-
for (var locale in flxmap.i18n) {
|
303 |
-
this.i18n[locale] = flxmap.i18n[locale];
|
304 |
-
}
|
305 |
-
FlexibleMap.prototype.i18n_loaded = true;
|
306 |
-
}
|
307 |
-
|
308 |
// attempt to set this locale as active
|
309 |
if (localeWanted in this.i18n) {
|
310 |
this.localeActive = localeWanted;
|
@@ -316,8 +420,8 @@ FlexibleMap.prototype = (function() {
|
|
316 |
this.localeActive = localeWanted;
|
317 |
}
|
318 |
else {
|
319 |
-
// still not found
|
320 |
-
this.localeActive =
|
321 |
}
|
322 |
}
|
323 |
|
@@ -330,10 +434,11 @@ FlexibleMap.prototype = (function() {
|
|
330 |
* @return {String}
|
331 |
*/
|
332 |
gettext: function(key) {
|
333 |
-
var
|
334 |
|
335 |
-
if (key in
|
336 |
-
return
|
|
|
337 |
|
338 |
return key;
|
339 |
},
|
@@ -354,6 +459,8 @@ FlexibleMap.prototype = (function() {
|
|
354 |
map = this.showMap(divID, [0, 0]),
|
355 |
kmlLayer = this.loadKmlMap(kmlCacheBuster(kmlFileURL, this.kmlcache));
|
356 |
|
|
|
|
|
357 |
// set zoom if specified
|
358 |
if (typeof zoom != "undefined") {
|
359 |
// listen for zoom changing to fit markers on KML layer, force it back to what we asked for
|
@@ -423,8 +530,10 @@ FlexibleMap.prototype = (function() {
|
|
423 |
icon: this.markerIcon
|
424 |
});
|
425 |
|
|
|
426 |
this.setMarkerLocation(markerLocation);
|
427 |
|
|
|
428 |
|
429 |
if (!this.markerTitle) {
|
430 |
this.markerTitle = this.markerAddress;
|
@@ -505,6 +614,7 @@ FlexibleMap.prototype = (function() {
|
|
505 |
}
|
506 |
|
507 |
infowin = new google.maps.InfoWindow({content: container});
|
|
|
508 |
|
509 |
if (this.markerShowInfo) {
|
510 |
// open after map is loaded, so that infowindow will auto-pan and won't be cropped at top
|
@@ -594,6 +704,12 @@ FlexibleMap.prototype = (function() {
|
|
594 |
else {
|
595 |
map.setCenter(this.getCenter());
|
596 |
map.setZoom(this.zoom);
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
}
|
598 |
},
|
599 |
|
10 |
var map, // google.maps.Map object
|
11 |
centre, // google.maps.LatLng object for map centre
|
12 |
markerLocation, // google.maps.LatLng object for single marker, when using showMarker()
|
13 |
+
markerPoint, // google.maps.Marker object for single marker, when using showMarker()
|
14 |
+
markerInfowin, // google.maps.InfoWindow object for single marker, when using showMarker()
|
15 |
kmlLayer, // if map has a KML layer, this is the layer object
|
16 |
hasRedrawn = false; // boolean, whether map has been asked to redrawOnce() already
|
17 |
|
56 |
return markerLocation;
|
57 |
};
|
58 |
|
59 |
+
/**
|
60 |
+
* record the single marker point
|
61 |
+
* @param {google.maps.Marker} point
|
62 |
+
*/
|
63 |
+
this.setMarkerPoint = function(point) {
|
64 |
+
markerPoint = point;
|
65 |
+
};
|
66 |
+
|
67 |
+
/**
|
68 |
+
* get the single marker point
|
69 |
+
* @return {google.maps.Marker}
|
70 |
+
*/
|
71 |
+
this.getMarkerPoint = function() {
|
72 |
+
return markerPoint;
|
73 |
+
};
|
74 |
+
|
75 |
+
/**
|
76 |
+
* record the single marker infowindow
|
77 |
+
* @param {google.maps.InfoWindow} infowin
|
78 |
+
*/
|
79 |
+
this.setMarkerInfowin = function(infowin) {
|
80 |
+
markerInfowin = infowin;
|
81 |
+
};
|
82 |
+
|
83 |
+
/**
|
84 |
+
* get the single marker infowindow
|
85 |
+
* @return {google.maps.InfoWindow}
|
86 |
+
*/
|
87 |
+
this.getMarkerInfowin = function() {
|
88 |
+
return markerInfowin;
|
89 |
+
};
|
90 |
+
|
91 |
/**
|
92 |
* get the map's KML layer if set
|
93 |
* @return {google.maps.KmlLayer}
|
115 |
this.showMap = function(divID, latLng) {
|
116 |
centre = new google.maps.LatLng(latLng[0], latLng[1]);
|
117 |
|
118 |
+
var mapOptions,
|
119 |
+
zoomControlStyle,
|
120 |
+
zoomControlStyles = {
|
121 |
+
"small" : google.maps.ZoomControlStyle.SMALL,
|
122 |
+
"large" : google.maps.ZoomControlStyle.LARGE,
|
123 |
+
"default" : google.maps.ZoomControlStyle.DEFAULT
|
124 |
};
|
125 |
|
126 |
+
// basic options
|
127 |
+
mapOptions = {
|
128 |
+
mapTypeId: this.mapTypeId,
|
129 |
+
mapTypeControl: this.mapTypeControl,
|
130 |
+
scaleControl: this.scaleControl,
|
131 |
+
panControl: this.panControl,
|
132 |
+
streetViewControl: this.streetViewControl,
|
133 |
+
zoomControl: zoomControlStyles.small,
|
134 |
+
zoomControlOptions: { style: zoomControlStyle },
|
135 |
+
draggable: this.draggable,
|
136 |
+
disableDoubleClickZoom: !this.dblclickZoom,
|
137 |
+
scrollwheel: this.scrollwheel,
|
138 |
+
center: centre,
|
139 |
+
zoom: this.zoom
|
140 |
+
};
|
141 |
+
|
142 |
+
// style the zoom control
|
143 |
if (this.zoomControlStyle in zoomControlStyles) {
|
144 |
+
mapOptions.zoomControlStyle = zoomControlStyles[this.zoomControlStyle];
|
145 |
}
|
146 |
+
|
147 |
+
// select which map types for map type control, if specified as comma-separated list of map type IDs
|
148 |
+
if (this.mapTypeIds) {
|
149 |
+
mapOptions.mapTypeControlOptions = {
|
150 |
+
mapTypeIds: this.mapTypeIds.split(",")
|
151 |
+
};
|
152 |
}
|
153 |
|
154 |
// create a map
|
155 |
+
map = new google.maps.Map(document.getElementById(divID), mapOptions);
|
156 |
+
|
157 |
+
// set custom map type if specified
|
158 |
+
if (this.mapTypeId in this.mapTypes) {
|
159 |
+
map.mapTypes.set(this.mapTypeId, this.mapTypes[this.mapTypeId]._styled_map);
|
160 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
|
162 |
return map;
|
163 |
};
|
180 |
return kmlLayer;
|
181 |
};
|
182 |
|
183 |
+
// load localisations if they haven't already been loaded
|
184 |
+
if (!this.localised && "flxmap" in window) {
|
185 |
+
this.localise();
|
186 |
+
}
|
187 |
+
|
188 |
// set map defaults
|
189 |
this.mapTypeId = google.maps.MapTypeId.ROADMAP;
|
190 |
this.mapTypeControl = true; // no control for changing map type
|
216 |
this.dirShowSearch = true; // show the directions form for searching directions
|
217 |
this.region = "";
|
218 |
this.locale = "en";
|
219 |
+
this.localeActive = false;
|
220 |
this.kmlcache = "none";
|
221 |
}
|
222 |
|
223 |
FlexibleMap.prototype = (function() {
|
224 |
"use strict";
|
225 |
|
226 |
+
var addEventListener, stopEvent, handleHiddenMap;
|
227 |
|
228 |
// detect standard event model
|
229 |
if (document.addEventListener) {
|
249 |
};
|
250 |
}
|
251 |
|
252 |
+
// handle hidden maps, trigger a resize on first display
|
253 |
+
if (typeof MutationObserver !== "undefined") {
|
254 |
+
handleHiddenMap = function(flxmap, divID) {
|
255 |
+
var mapDiv = document.getElementById(divID),
|
256 |
+
container = mapDiv.parentNode,
|
257 |
+
observer;
|
258 |
+
|
259 |
+
function isHidden(element) {
|
260 |
+
var style = window.getComputedStyle(element);
|
261 |
+
return style.display === "none";
|
262 |
+
}
|
263 |
+
|
264 |
+
// only need to watch and act if the parent container is hidden from display
|
265 |
+
if (isHidden(container)) {
|
266 |
+
observer = new MutationObserver(function(mutations, self) {
|
267 |
+
// only proceed if map is visible now
|
268 |
+
if (!isHidden(container)) {
|
269 |
+
flxmap.redrawOnce();
|
270 |
+
|
271 |
+
// stop observing, we're done
|
272 |
+
self.disconnect();
|
273 |
+
}
|
274 |
+
});
|
275 |
+
|
276 |
+
observer.observe(container, {
|
277 |
+
attributes: true,
|
278 |
+
attributeFilter: ["style"]
|
279 |
+
});
|
280 |
+
}
|
281 |
+
};
|
282 |
+
}
|
283 |
+
else {
|
284 |
+
handleHiddenMap = function() { };
|
285 |
+
}
|
286 |
+
|
287 |
/**
|
288 |
* encode special JavaScript characters, so text is safe when building JavaScript/HTML dynamically
|
289 |
* NB: conservatively assumes that HTML special characters are unsafe, and encodes them too
|
367 |
/**
|
368 |
* collection of locale / phrase mapping for internationalisation of messages
|
369 |
*/
|
370 |
+
i18n: { },
|
371 |
+
|
372 |
+
/**
|
373 |
+
* collection of custom Google Maps map types for styling maps
|
374 |
+
*/
|
375 |
+
mapTypes: { },
|
376 |
+
|
377 |
+
localised: false, // set to true once localisations have been loaded
|
378 |
+
|
379 |
+
/**
|
380 |
+
* load localisations into class prototype
|
381 |
+
*/
|
382 |
+
localise: function() {
|
383 |
+
var key, mapTypes;
|
384 |
+
|
385 |
+
// load translations
|
386 |
+
if ("i18n" in flxmap) {
|
387 |
+
FlexibleMap.prototype.i18n = flxmap.i18n;
|
388 |
+
}
|
389 |
+
|
390 |
+
// load custom map types
|
391 |
+
if ("mapTypes" in flxmap) {
|
392 |
+
mapTypes = flxmap.mapTypes;
|
393 |
+
|
394 |
+
for (key in mapTypes) {
|
395 |
+
mapTypes[key]._styled_map = new google.maps.StyledMapType(mapTypes[key].styles, mapTypes[key].options);
|
396 |
+
}
|
397 |
+
|
398 |
+
FlexibleMap.prototype.mapTypes = mapTypes;
|
399 |
}
|
400 |
+
|
401 |
+
FlexibleMap.prototype.localised = true;
|
402 |
},
|
|
|
403 |
|
404 |
/**
|
405 |
* set the locale used for i18n phrase lookup, picking the best match
|
409 |
setlocale: function(localeWanted) {
|
410 |
this.locale = localeWanted;
|
411 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
412 |
// attempt to set this locale as active
|
413 |
if (localeWanted in this.i18n) {
|
414 |
this.localeActive = localeWanted;
|
420 |
this.localeActive = localeWanted;
|
421 |
}
|
422 |
else {
|
423 |
+
// still not found
|
424 |
+
this.localeActive = false;
|
425 |
}
|
426 |
}
|
427 |
|
434 |
* @return {String}
|
435 |
*/
|
436 |
gettext: function(key) {
|
437 |
+
var locale = this.localeActive;
|
438 |
|
439 |
+
if (locale && key in this.i18n[locale]) {
|
440 |
+
return this.i18n[locale][key];
|
441 |
+
}
|
442 |
|
443 |
return key;
|
444 |
},
|
459 |
map = this.showMap(divID, [0, 0]),
|
460 |
kmlLayer = this.loadKmlMap(kmlCacheBuster(kmlFileURL, this.kmlcache));
|
461 |
|
462 |
+
handleHiddenMap(this, divID);
|
463 |
+
|
464 |
// set zoom if specified
|
465 |
if (typeof zoom != "undefined") {
|
466 |
// listen for zoom changing to fit markers on KML layer, force it back to what we asked for
|
530 |
icon: this.markerIcon
|
531 |
});
|
532 |
|
533 |
+
this.setMarkerPoint(point);
|
534 |
this.setMarkerLocation(markerLocation);
|
535 |
|
536 |
+
handleHiddenMap(this, divID);
|
537 |
|
538 |
if (!this.markerTitle) {
|
539 |
this.markerTitle = this.markerAddress;
|
614 |
}
|
615 |
|
616 |
infowin = new google.maps.InfoWindow({content: container});
|
617 |
+
this.setMarkerInfowin(infowin);
|
618 |
|
619 |
if (this.markerShowInfo) {
|
620 |
// open after map is loaded, so that infowindow will auto-pan and won't be cropped at top
|
704 |
else {
|
705 |
map.setCenter(this.getCenter());
|
706 |
map.setZoom(this.zoom);
|
707 |
+
|
708 |
+
// redraw the marker's infowindow if it has one
|
709 |
+
var infowin = this.getMarkerInfowin();
|
710 |
+
if (infowin) {
|
711 |
+
infowin.open(map, this.getMarkerPoint());
|
712 |
+
}
|
713 |
}
|
714 |
},
|
715 |
|
js/flexible-map.min.js
CHANGED
@@ -2,4 +2,4 @@
|
|
2 |
JavaScript for the WordPress plugin wp-flexible-map
|
3 |
copyright (c) 2011-2014 WebAware Pty Ltd, released under LGPL v2.1
|
4 |
*/
|
5 |
-
;function FlexibleMap(){var e,c,a,d,b=false;this.getMap=function(){return e};this.getCenter=function(){return c};this.setCenter=function(f){c=f;e.setCenter(c)};this.setMarkerLocation=function(f){a=f};this.getMarkerLocation=function(){return a};this.getKmlLayer=function(){return d};this.redrawOnce=function(){if(!b){b=true;this.redraw()}};this.showMap=function(f,h){c=new google.maps.LatLng(h[0],h[1]);var i,g={small:google.maps.ZoomControlStyle.SMALL,large:google.maps.ZoomControlStyle.LARGE,"default":google.maps.ZoomControlStyle.DEFAULT};if(this.zoomControlStyle in g){i=g[this.zoomControlStyle]}else{i=g.small}e=new google.maps.Map(document.getElementById(f),{mapTypeId:this.mapTypeId,mapTypeControl:this.mapTypeControl,scaleControl:this.scaleControl,panControl:this.panControl,streetViewControl:this.streetViewControl,zoomControl:this.zoomControl,zoomControlOptions:{style:i},draggable:this.draggable,disableDoubleClickZoom:!this.dblclickZoom,scrollwheel:this.scrollwheel,center:c,zoom:this.zoom});return e};this.loadKmlMap=function(f){d=new google.maps.KmlLayer({map:e,url:f});google.maps.event.addListenerOnce(d,"defaultviewport_changed",function(){c=d.getDefaultViewport().getCenter()});return d};this.mapTypeId=google.maps.MapTypeId.ROADMAP;this.mapTypeControl=true;this.scaleControl=false;this.panControl=false;this.zoomControl=true;this.zoomControlStyle="small";this.streetViewControl=false;this.scrollwheel=false;this.draggable=true;this.dblclickZoom=true;this.zoom=16;this.markerTitle="";this.markerDescription="";this.markerHTML="";this.markerLink="";this.markerIcon="";this.markerShowInfo=true;this.markerDirections=false;this.markerDirectionsShow=false;this.markerDirectionsDefault="";this.markerAddress="";this.targetFix=true;this.dirService=false;this.dirRenderer=false;this.dirDraggable=false;this.dirSuppressMarkers=false;this.dirShowSteps=true;this.dirShowSearch=true;this.region="";this.locale="en";this.localeActive="en";this.kmlcache="none"}FlexibleMap.prototype=(function(){var d,b;if(document.addEventListener){d=function(f,e,g){f.addEventListener(e,g,false)};b=function(e){e.stopPropagation();e.preventDefault()}}else{if(document.attachEvent){d=function(e,f,g){e.attachEvent("on"+f,function(){g.call(e,window.event)})};b=function(e){e.cancelBubble=true;e.returnValue=0}}}var a=(function(){function e(g){var h=g.charCodeAt(0),f=h.toString(16);if(h<256){return"\\x"+("00"+f).slice(-2)}return"\\u"+("0000"+f).slice(-4)}return function(f){return f.replace(/[\\\/"'&<>\x00-\x1f\x7f-\xa0\u2000-\u200f\u2028-\u202f]/g,e)}})();function c(f,i){var e,g,j,h=/^(\d+)\s*(minute|hour|day)s?$/.exec(i);if(h){e=(new Date()).getTime();j=+h[1];switch(h[2]){case"minute":if(j<5){j=5}g=e/(60000*j);break;case"hour":g=e/(3600000*j);break;case"day":g=e/(86400000*j);break;default:g=false;break}if(g){g=Math.floor(g);f+=(f.indexOf("?")>-1?"&":"?")+"nocache="+g}}return f}return{constructor:FlexibleMap,i18n:{en:{"Click for details":"Click for details",Directions:"Directions",From:"From","Get directions":"Get directions"}},i18n_loaded:false,setlocale:function(f){this.locale=f;if(!this.i18n_loaded&&"flxmap" in window){for(var e in flxmap.i18n){this.i18n[e]=flxmap.i18n[e]}FlexibleMap.prototype.i18n_loaded=true}if(f in this.i18n){this.localeActive=f}else{f=f.substr(0,2);if(f in this.i18n){this.localeActive=f}else{this.localeActive="en"}}return this.localeActive},gettext:function(f){var e=this.i18n[this.localeActive];if(f in e){return e[f]}return f},showKML:function(e,h,i){if(typeof i!="undefined"){this.zoom=i}var g=this,f=document.getElementById(e),l=f.getAttribute("data-flxmap"),k=this.showMap(e,[0,0]),j=this.loadKmlMap(c(h,this.kmlcache));if(typeof i!="undefined"){google.maps.event.addListenerOnce(k,"zoom_changed",function(){k.setZoom(i);g.zoom=i})}if(this.markerDirections||this.markerDirectionsShow){this.startDirService(k)}google.maps.event.addListener(j,"click",function(r){var p=r.featureData;if(!p._flxmapOnce){p._flxmapOnce=true;if(g.targetFix){var o=/ target="_blank"/ig;p.description=p.description.replace(o,"");p.infoWindowHtml=p.infoWindowHtml.replace(o,"")}if(g.markerDirections){var n=r.latLng,q=n.lat()+","+n.lng()+",'"+a(p.name)+"',true",m='<br /><a href="#" data-flxmap-fix-opera="1" onclick="'+l+".showDirections("+q+'); return false;">'+g.gettext("Directions")+"</a>";p.infoWindowHtml=p.infoWindowHtml.replace(/<\/div><\/div>$/i,m+"</div></div>")}}});if(window.opera&&this.markerDirections){d(f,"click",function(m){if(m.target.getAttribute("data-flxmap-fix-opera")){b(m)}})}},showMarker:function(j,h,n){var g=this.showMap(j,h),e=new google.maps.LatLng(n[0],n[1]),r=new google.maps.Marker({map:g,position:e,icon:this.markerIcon});this.setMarkerLocation(e);if(!this.markerTitle){this.markerTitle=this.markerAddress}if(this.markerTitle){var m,o,t,k,l,q,s=this,f=document.createElement("DIV");f.className="flxmap-infowin";r.setTitle(this.markerTitle);l=document.createElement("DIV");l.className="flxmap-marker-title";l.appendChild(document.createTextNode(this.markerTitle));f.appendChild(l);if(this.markerHTML){l=document.createElement("DIV");l.innerHTML=this.markerHTML;f.appendChild(l)}if(this.markerDescription||this.markerLink){l=document.createElement("DIV");l.className="flxmap-marker-link";if(this.markerDescription){t=this.markerDescription.split("\n");for(m=0,o=t.length;m<o;m++){if(m>0){l.appendChild(document.createElement("BR"))}l.appendChild(document.createTextNode(t[m]))}if(this.markerLink){l.appendChild(document.createElement("BR"))}}if(this.markerLink){q=document.createElement("A");q.href=this.markerLink;q.appendChild(document.createTextNode(this.gettext("Click for details")));l.appendChild(q)}f.appendChild(l)}if(this.markerDirections){l=document.createElement("DIV");l.className="flxmap-directions-link";q=document.createElement("A");q.href="#";q.dataLatitude=n[0];q.dataLongitude=n[1];q.dataTitle=this.markerTitle;d(q,"click",function(i){b(i);s.showDirections(this.dataLatitude,this.dataLongitude,this.dataTitle,true)});q.appendChild(document.createTextNode(this.gettext("Directions")));l.appendChild(q);f.appendChild(l)}if(this.markerDirections||this.markerDirectionsShow){this.startDirService(g);if(this.markerDirectionsShow){this.showDirections(n[0],n[1],this.markerTitle,false)}}k=new google.maps.InfoWindow({content:f});if(this.markerShowInfo){google.maps.event.addListenerOnce(g,"tilesloaded",function(){k.open(g,r)})}google.maps.event.addListener(r,"click",function(){k.open(g,r)});var p=function(){s.updateGoogleLink()};google.maps.event.addListener(g,"idle",p);google.maps.event.addListener(g,"center_changed",p);google.maps.event.addListenerOnce(g,"tilesloaded",p)}},showAddress:function(e,f){var g=this,h=new google.maps.Geocoder();this.markerAddress=f;if(this.markerTitle===""){this.markerTitle=f}h.geocode({address:f,region:this.region},function(k,j){if(j==google.maps.GeocoderStatus.OK){var i=k[0].geometry.location,l=[i.lat(),i.lng()];g.showMarker(e,l,l)}else{window.alert("Map address returns error: "+j)}})},updateGoogleLink:function(){if("querySelectorAll" in document){try{var m=this.getMap().getDiv(),g=this.getMarkerLocation(),j=m.querySelectorAll("a[href*='maps.google.com/maps']:not([href*='mps_dialog']):not([href*='&q='])"),h=0,f=j.length,k=encodeURIComponent((this.markerAddress?this.markerAddress:this.markerTitle)+" @"+g.lat()+","+g.lng());for(;h<f;h++){j[h].href+="&mrt=loc&iwloc=A&q="+k}}catch(l){}}},redraw:function(){var f=this.getMap(),e=this.getKmlLayer();google.maps.event.trigger(f,"resize");if(e){f.fitBounds(e.getDefaultViewport())}else{f.setCenter(this.getCenter());f.setZoom(this.zoom)}},startDirService:function(e){if(!this.dirService){this.dirService=new google.maps.DirectionsService()}if(!this.dirRenderer){this.dirRenderer=new google.maps.DirectionsRenderer({map:e,draggable:this.dirDraggable,suppressMarkers:this.dirSuppressMarkers,panel:this.dirShowSteps?document.getElementById(this.markerDirectionsDiv):null})}},showDirections:function(l,h,k,e){var f=this;function j(){var m=document.getElementById(f.markerDirectionsDiv),o=document.createElement("form"),n,q,r;while(!!(q=m.lastChild)){m.removeChild(q)}q=document.createElement("p");q.appendChild(document.createTextNode(f.gettext("From")+": "));r=document.createElement("input");r.type="text";r.name="from";r.value=f.markerDirectionsDefault;q.appendChild(r);n=document.createElement("input");n.type="submit";n.value=f.gettext("Get directions");q.appendChild(n);o.appendChild(q);m.appendChild(o);if(typeof o.elements.from=="undefined"){o.elements.from=r}if(e){r.focus()}d(o,"submit",function(p){b(p);var s=this.elements.from.value;if(/\S/.test(s)){i(s)}})}function i(o){var m=(f.markerAddress==="")?new google.maps.LatLng(l,h):f.markerAddress,n={origin:o,region:f.region||"",destination:m,travelMode:google.maps.DirectionsTravelMode.DRIVING};f.dirService.route(n,g)}function g(o,m){var n=google.maps.DirectionsStatus;switch(m){case n.OK:f.dirRenderer.setDirections(o);break;case n.ZERO_RESULTS:window.alert("No route could be found between the origin and destination.");break;case n.OVER_QUERY_LIMIT:window.alert("The webpage has gone over the requests limit in too short a period of time.");break;case n.REQUEST_DENIED:window.alert("The webpage is not allowed to use the directions service.");break;case n.INVALID_REQUEST:window.alert("Invalid directions request.");break;case n.NOT_FOUND:window.alert("Origin or destination was not found.");break;default:window.alert("A directions request could not be processed due to a server error. The request may succeed if you try again.");break}}if(this.markerDirectionsDiv&&this.dirShowSearch){j()}if(this.markerDirectionsDefault){i(this.markerDirectionsDefault)}}}})();
|
2 |
JavaScript for the WordPress plugin wp-flexible-map
|
3 |
copyright (c) 2011-2014 WebAware Pty Ltd, released under LGPL v2.1
|
4 |
*/
|
5 |
+
;function FlexibleMap(){var f,d,b,g,a,e,c=false;this.getMap=function(){return f};this.getCenter=function(){return d};this.setCenter=function(h){d=h;f.setCenter(d)};this.setMarkerLocation=function(h){b=h};this.getMarkerLocation=function(){return b};this.setMarkerPoint=function(h){g=h};this.getMarkerPoint=function(){return g};this.setMarkerInfowin=function(h){a=h};this.getMarkerInfowin=function(){return a};this.getKmlLayer=function(){return e};this.redrawOnce=function(){if(!c){c=true;this.redraw()}};this.showMap=function(h,k){d=new google.maps.LatLng(k[0],k[1]);var i,l,j={small:google.maps.ZoomControlStyle.SMALL,large:google.maps.ZoomControlStyle.LARGE,"default":google.maps.ZoomControlStyle.DEFAULT};i={mapTypeId:this.mapTypeId,mapTypeControl:this.mapTypeControl,scaleControl:this.scaleControl,panControl:this.panControl,streetViewControl:this.streetViewControl,zoomControl:j.small,zoomControlOptions:{style:l},draggable:this.draggable,disableDoubleClickZoom:!this.dblclickZoom,scrollwheel:this.scrollwheel,center:d,zoom:this.zoom};if(this.zoomControlStyle in j){i.zoomControlStyle=j[this.zoomControlStyle]}if(this.mapTypeIds){i.mapTypeControlOptions={mapTypeIds:this.mapTypeIds.split(",")}}f=new google.maps.Map(document.getElementById(h),i);if(this.mapTypeId in this.mapTypes){f.mapTypes.set(this.mapTypeId,this.mapTypes[this.mapTypeId]._styled_map)}return f};this.loadKmlMap=function(h){e=new google.maps.KmlLayer({map:f,url:h});google.maps.event.addListenerOnce(e,"defaultviewport_changed",function(){d=e.getDefaultViewport().getCenter()});return e};if(!this.localised&&"flxmap" in window){this.localise()}this.mapTypeId=google.maps.MapTypeId.ROADMAP;this.mapTypeControl=true;this.scaleControl=false;this.panControl=false;this.zoomControl=true;this.zoomControlStyle="small";this.streetViewControl=false;this.scrollwheel=false;this.draggable=true;this.dblclickZoom=true;this.zoom=16;this.markerTitle="";this.markerDescription="";this.markerHTML="";this.markerLink="";this.markerIcon="";this.markerShowInfo=true;this.markerDirections=false;this.markerDirectionsShow=false;this.markerDirectionsDefault="";this.markerAddress="";this.targetFix=true;this.dirService=false;this.dirRenderer=false;this.dirDraggable=false;this.dirSuppressMarkers=false;this.dirShowSteps=true;this.dirShowSearch=true;this.region="";this.locale="en";this.localeActive=false;this.kmlcache="none"}FlexibleMap.prototype=(function(){var d,b,e;if(document.addEventListener){d=function(g,f,h){g.addEventListener(f,h,false)};b=function(f){f.stopPropagation();f.preventDefault()}}else{if(document.attachEvent){d=function(f,g,h){f.attachEvent("on"+g,function(){h.call(f,window.event)})};b=function(f){f.cancelBubble=true;f.returnValue=0}}}if(typeof MutationObserver!=="undefined"){e=function(k,f){var i=document.getElementById(f),g=i.parentNode,h;function j(l){var m=window.getComputedStyle(l);return m.display==="none"}if(j(g)){h=new MutationObserver(function(l,m){if(!j(g)){k.redrawOnce();m.disconnect()}});h.observe(g,{attributes:true,attributeFilter:["style"]})}}}else{e=function(){}}var a=(function(){function f(h){var i=h.charCodeAt(0),g=i.toString(16);if(i<256){return"\\x"+("00"+g).slice(-2)}return"\\u"+("0000"+g).slice(-4)}return function(g){return g.replace(/[\\\/"'&<>\x00-\x1f\x7f-\xa0\u2000-\u200f\u2028-\u202f]/g,f)}})();function c(g,j){var f,h,k,i=/^(\d+)\s*(minute|hour|day)s?$/.exec(j);if(i){f=(new Date()).getTime();k=+i[1];switch(i[2]){case"minute":if(k<5){k=5}h=f/(60000*k);break;case"hour":h=f/(3600000*k);break;case"day":h=f/(86400000*k);break;default:h=false;break}if(h){h=Math.floor(h);g+=(g.indexOf("?")>-1?"&":"?")+"nocache="+h}}return g}return{constructor:FlexibleMap,i18n:{},mapTypes:{},localised:false,localise:function(){var g,f;if("i18n" in flxmap){FlexibleMap.prototype.i18n=flxmap.i18n}if("mapTypes" in flxmap){f=flxmap.mapTypes;for(g in f){f[g]._styled_map=new google.maps.StyledMapType(f[g].styles,f[g].options)}FlexibleMap.prototype.mapTypes=f}FlexibleMap.prototype.localised=true},setlocale:function(f){this.locale=f;if(f in this.i18n){this.localeActive=f}else{f=f.substr(0,2);if(f in this.i18n){this.localeActive=f}else{this.localeActive=false}}return this.localeActive},gettext:function(g){var f=this.localeActive;if(f&&g in this.i18n[f]){return this.i18n[f][g]}return g},showKML:function(f,i,j){if(typeof j!="undefined"){this.zoom=j}var h=this,g=document.getElementById(f),m=g.getAttribute("data-flxmap"),l=this.showMap(f,[0,0]),k=this.loadKmlMap(c(i,this.kmlcache));e(this,f);if(typeof j!="undefined"){google.maps.event.addListenerOnce(l,"zoom_changed",function(){l.setZoom(j);h.zoom=j})}if(this.markerDirections||this.markerDirectionsShow){this.startDirService(l)}google.maps.event.addListener(k,"click",function(s){var q=s.featureData;if(!q._flxmapOnce){q._flxmapOnce=true;if(h.targetFix){var p=/ target="_blank"/ig;q.description=q.description.replace(p,"");q.infoWindowHtml=q.infoWindowHtml.replace(p,"")}if(h.markerDirections){var o=s.latLng,r=o.lat()+","+o.lng()+",'"+a(q.name)+"',true",n='<br /><a href="#" data-flxmap-fix-opera="1" onclick="'+m+".showDirections("+r+'); return false;">'+h.gettext("Directions")+"</a>";q.infoWindowHtml=q.infoWindowHtml.replace(/<\/div><\/div>$/i,n+"</div></div>")}}});if(window.opera&&this.markerDirections){d(g,"click",function(n){if(n.target.getAttribute("data-flxmap-fix-opera")){b(n)}})}},showMarker:function(k,j,o){var h=this.showMap(k,j),f=new google.maps.LatLng(o[0],o[1]),s=new google.maps.Marker({map:h,position:f,icon:this.markerIcon});this.setMarkerPoint(s);this.setMarkerLocation(f);e(this,k);if(!this.markerTitle){this.markerTitle=this.markerAddress}if(this.markerTitle){var n,p,u,l,m,r,t=this,g=document.createElement("DIV");g.className="flxmap-infowin";s.setTitle(this.markerTitle);m=document.createElement("DIV");m.className="flxmap-marker-title";m.appendChild(document.createTextNode(this.markerTitle));g.appendChild(m);if(this.markerHTML){m=document.createElement("DIV");m.innerHTML=this.markerHTML;g.appendChild(m)}if(this.markerDescription||this.markerLink){m=document.createElement("DIV");m.className="flxmap-marker-link";if(this.markerDescription){u=this.markerDescription.split("\n");for(n=0,p=u.length;n<p;n++){if(n>0){m.appendChild(document.createElement("BR"))}m.appendChild(document.createTextNode(u[n]))}if(this.markerLink){m.appendChild(document.createElement("BR"))}}if(this.markerLink){r=document.createElement("A");r.href=this.markerLink;r.appendChild(document.createTextNode(this.gettext("Click for details")));m.appendChild(r)}g.appendChild(m)}if(this.markerDirections){m=document.createElement("DIV");m.className="flxmap-directions-link";r=document.createElement("A");r.href="#";r.dataLatitude=o[0];r.dataLongitude=o[1];r.dataTitle=this.markerTitle;d(r,"click",function(i){b(i);t.showDirections(this.dataLatitude,this.dataLongitude,this.dataTitle,true)});r.appendChild(document.createTextNode(this.gettext("Directions")));m.appendChild(r);g.appendChild(m)}if(this.markerDirections||this.markerDirectionsShow){this.startDirService(h);if(this.markerDirectionsShow){this.showDirections(o[0],o[1],this.markerTitle,false)}}l=new google.maps.InfoWindow({content:g});this.setMarkerInfowin(l);if(this.markerShowInfo){google.maps.event.addListenerOnce(h,"tilesloaded",function(){l.open(h,s)})}google.maps.event.addListener(s,"click",function(){l.open(h,s)});var q=function(){t.updateGoogleLink()};google.maps.event.addListener(h,"idle",q);google.maps.event.addListener(h,"center_changed",q);google.maps.event.addListenerOnce(h,"tilesloaded",q)}},showAddress:function(f,g){var h=this,i=new google.maps.Geocoder();this.markerAddress=g;if(this.markerTitle===""){this.markerTitle=g}i.geocode({address:g,region:this.region},function(l,k){if(k==google.maps.GeocoderStatus.OK){var j=l[0].geometry.location,m=[j.lat(),j.lng()];h.showMarker(f,m,m)}else{window.alert("Map address returns error: "+k)}})},updateGoogleLink:function(){if("querySelectorAll" in document){try{var m=this.getMap().getDiv(),g=this.getMarkerLocation(),j=m.querySelectorAll("a[href*='maps.google.com/maps']:not([href*='mps_dialog']):not([href*='&q='])"),h=0,f=j.length,k=encodeURIComponent((this.markerAddress?this.markerAddress:this.markerTitle)+" @"+g.lat()+","+g.lng());for(;h<f;h++){j[h].href+="&mrt=loc&iwloc=A&q="+k}}catch(l){}}},redraw:function(){var h=this.getMap(),g=this.getKmlLayer();google.maps.event.trigger(h,"resize");if(g){h.fitBounds(g.getDefaultViewport())}else{h.setCenter(this.getCenter());h.setZoom(this.zoom);var f=this.getMarkerInfowin();if(f){f.open(h,this.getMarkerPoint())}}},startDirService:function(f){if(!this.dirService){this.dirService=new google.maps.DirectionsService()}if(!this.dirRenderer){this.dirRenderer=new google.maps.DirectionsRenderer({map:f,draggable:this.dirDraggable,suppressMarkers:this.dirSuppressMarkers,panel:this.dirShowSteps?document.getElementById(this.markerDirectionsDiv):null})}},showDirections:function(m,i,l,f){var g=this;function k(){var n=document.getElementById(g.markerDirectionsDiv),q=document.createElement("form"),o,r,s;while(!!(r=n.lastChild)){n.removeChild(r)}r=document.createElement("p");r.appendChild(document.createTextNode(g.gettext("From")+": "));s=document.createElement("input");s.type="text";s.name="from";s.value=g.markerDirectionsDefault;r.appendChild(s);o=document.createElement("input");o.type="submit";o.value=g.gettext("Get directions");r.appendChild(o);q.appendChild(r);n.appendChild(q);if(typeof q.elements.from=="undefined"){q.elements.from=s}if(f){s.focus()}d(q,"submit",function(p){b(p);var t=this.elements.from.value;if(/\S/.test(t)){j(t)}})}function j(p){var n=(g.markerAddress==="")?new google.maps.LatLng(m,i):g.markerAddress,o={origin:p,region:g.region||"",destination:n,travelMode:google.maps.DirectionsTravelMode.DRIVING};g.dirService.route(o,h)}function h(p,n){var o=google.maps.DirectionsStatus;switch(n){case o.OK:g.dirRenderer.setDirections(p);break;case o.ZERO_RESULTS:window.alert("No route could be found between the origin and destination.");break;case o.OVER_QUERY_LIMIT:window.alert("The webpage has gone over the requests limit in too short a period of time.");break;case o.REQUEST_DENIED:window.alert("The webpage is not allowed to use the directions service.");break;case o.INVALID_REQUEST:window.alert("Invalid directions request.");break;case o.NOT_FOUND:window.alert("Origin or destination was not found.");break;default:window.alert("A directions request could not be processed due to a server error. The request may succeed if you try again.");break}}if(this.markerDirectionsDiv&&this.dirShowSearch){k()}if(this.markerDirectionsDefault){j(this.markerDirectionsDefault)}}}})();
|
readme.txt
CHANGED
@@ -7,7 +7,7 @@ Donate link: http://shop.webaware.com.au/downloads/flexible-map/
|
|
7 |
Tags: google, map, maps, google maps, shortcode, google maps shortcode, kml
|
8 |
Requires at least: 3.2.1
|
9 |
Tested up to: 4.1
|
10 |
-
Stable tag: 1.
|
11 |
License: GPLv2 or later
|
12 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
13 |
|
@@ -34,7 +34,7 @@ Flexible Map allows you to add Google Maps to your WordPress website.
|
|
34 |
* directions can be dropped into any div element with an ID
|
35 |
* minimal dependencies -- just WordPress and the Google Maps API
|
36 |
|
37 |
-
|
38 |
|
39 |
= Sponsorships =
|
40 |
|
@@ -55,7 +55,7 @@ Many thanks to the generous efforts of our translators:
|
|
55 |
* Norwegian: Bokmål (nb_NO) -- [neonnero](http://www.neonnero.com/)
|
56 |
* Norwegian: Nynorsk (nn_NO) -- [neonnero](http://www.neonnero.com/)
|
57 |
* Spanish (es) -- [edurramos](http://profiles.wordpress.org/edurramos/)
|
58 |
-
* Welsh (cy) --
|
59 |
|
60 |
The initial translations for all other languages were made using Google Translate, so it's likely that some will be truly awful! If you'd like to help out by translating this plugin, please [sign up for an account and dig in](http://translate.webaware.com.au/projects/flexible-map).
|
61 |
|
@@ -108,6 +108,7 @@ Either the center or the address paramater is required. If you provide both, the
|
|
108 |
* **id**: the CSS id of the container div (instead of a random generated unique ID), e.g. *id="my_map"*
|
109 |
* **zoom**: zoom level as an integer, larger is closer, e.g. *zoom="16"*
|
110 |
* **maptype**: type of map to show, from [roadmap, satellite, hybrid, terrain], e.g. *maptype="satellite"*; default=roadmap
|
|
|
111 |
* **hidemaptype**: hide the map type controls, from [true, false], e.g. *hidemaptype="true"*; default=false
|
112 |
* **hidepanning**: hide the panning controls, from [true, false], e.g. *hidepanning="true"*; default=true
|
113 |
* **hidezooming**: hide the zoom controls, from [true, false], e.g. *hidezooming="true"*; default=false
|
@@ -147,14 +148,15 @@ There is a PHP function `flexmap_show_map()` for theme and plugin developers. Al
|
|
147 |
|
148 |
There are also some filter hooks that allow you to change the behaviour of the plugin.
|
149 |
|
150 |
-
*
|
151 |
-
*
|
152 |
-
*
|
153 |
-
*
|
154 |
-
*
|
155 |
-
*
|
|
|
156 |
|
157 |
-
For more information and examples, see [the website](http://flexible-map.webaware.net.au/).
|
158 |
|
159 |
== Frequently Asked Questions ==
|
160 |
|
@@ -214,22 +216,30 @@ function force_flexmap_map_language($args) {
|
|
214 |
|
215 |
The initial translations were made using Google Translate, so it's likely that some will be truly awful! If you'd like to help out by translating this plugin, please [sign up for an account and dig in](http://translate.webaware.com.au/projects/flexible-map).
|
216 |
|
217 |
-
= The map is broken in
|
218 |
|
219 |
-
When you hide the map in a tab, and then click on the tab to reveal its contents, the map doesn't know how big to draw until it is revealed.
|
|
|
|
|
220 |
|
221 |
`<script>
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
flxmap.
|
227 |
-
|
|
|
|
|
|
|
228 |
}
|
229 |
-
|
|
|
|
|
|
|
230 |
</script>`
|
231 |
|
232 |
-
For jQuery versions 1.8 or older:
|
233 |
|
234 |
`<script>
|
235 |
jQuery("body").bind("tabsshow", function(event, ui) {
|
@@ -296,6 +306,15 @@ Either turn off CloudFlare Rocketscript :) or install the [Flxmap No Rocketscrip
|
|
296 |
|
297 |
== Changelog ==
|
298 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
= 1.8.3 [2014-12-17] =
|
300 |
* fixed: CSS for directions in twentyfifteen theme and others that toss table-layout:fixed around willy nilly
|
301 |
|
7 |
Tags: google, map, maps, google maps, shortcode, google maps shortcode, kml
|
8 |
Requires at least: 3.2.1
|
9 |
Tested up to: 4.1
|
10 |
+
Stable tag: 1.9.0
|
11 |
License: GPLv2 or later
|
12 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
13 |
|
34 |
* directions can be dropped into any div element with an ID
|
35 |
* minimal dependencies -- just WordPress and the Google Maps API
|
36 |
|
37 |
+
[Try WP Flexible Map online](http://flexible-map.webaware.net.au/).
|
38 |
|
39 |
= Sponsorships =
|
40 |
|
55 |
* Norwegian: Bokmål (nb_NO) -- [neonnero](http://www.neonnero.com/)
|
56 |
* Norwegian: Nynorsk (nn_NO) -- [neonnero](http://www.neonnero.com/)
|
57 |
* Spanish (es) -- [edurramos](http://profiles.wordpress.org/edurramos/)
|
58 |
+
* Welsh (cy) -- [Dylan](https://profiles.wordpress.org/dtom-ct-wp/)
|
59 |
|
60 |
The initial translations for all other languages were made using Google Translate, so it's likely that some will be truly awful! If you'd like to help out by translating this plugin, please [sign up for an account and dig in](http://translate.webaware.com.au/projects/flexible-map).
|
61 |
|
108 |
* **id**: the CSS id of the container div (instead of a random generated unique ID), e.g. *id="my_map"*
|
109 |
* **zoom**: zoom level as an integer, larger is closer, e.g. *zoom="16"*
|
110 |
* **maptype**: type of map to show, from [roadmap, satellite, hybrid, terrain], e.g. *maptype="satellite"*; default=roadmap
|
111 |
+
* **maptypes**: types of maps in the map type controls, e.g. *maptypes="custom_type,satellite"*
|
112 |
* **hidemaptype**: hide the map type controls, from [true, false], e.g. *hidemaptype="true"*; default=false
|
113 |
* **hidepanning**: hide the panning controls, from [true, false], e.g. *hidepanning="true"*; default=true
|
114 |
* **hidezooming**: hide the zoom controls, from [true, false], e.g. *hidezooming="true"*; default=false
|
148 |
|
149 |
There are also some filter hooks that allow you to change the behaviour of the plugin.
|
150 |
|
151 |
+
* `flexmap_google_maps_api_args`: filter the array of arguments that will be passed to the Google Maps API, e.g. `'v'=>'3.exp'`, `'sensor'=>'false'`
|
152 |
+
* `flexmap_google_maps_api_url`: filter the Google Maps API URL, as a string
|
153 |
+
* `flexmap_shortcode_attrs`: filter the array of shortcode attributes, e.g. change the width and height
|
154 |
+
* `flexmap_shortcode_styles`: filter the array of inline styles applied to the div wrapping the map, e.g. remove width and height so that it can be specified in the theme's stylesheets
|
155 |
+
* `flexmap_shortcode_html`: filter the generated HTML, e.g. wrap another div around it, add a link to Google Maps, add some additonal script, etc.
|
156 |
+
* `flexmap_shortcode_script`: filter the generated JavaScript
|
157 |
+
* `flexmap_custom_map_types`: register custom Google Maps map types
|
158 |
|
159 |
+
For more information and examples, see [the reference website](http://flexible-map.webaware.net.au/).
|
160 |
|
161 |
== Frequently Asked Questions ==
|
162 |
|
216 |
|
217 |
The initial translations were made using Google Translate, so it's likely that some will be truly awful! If you'd like to help out by translating this plugin, please [sign up for an account and dig in](http://translate.webaware.com.au/projects/flexible-map).
|
218 |
|
219 |
+
= The map is broken in tabs / accordions =
|
220 |
|
221 |
+
When you hide the map in a tab, and then click on the tab to reveal its contents, sometimes the map doesn't know how big to draw until it is revealed. Since v1.9.0 most such problems are automatically resolved for modern browsers, including Internet Explorer 11 or later. If you need to support earlier versions that don't support [MutationObserver](http://caniuse.com/#feat=mutationobserver), add some script to your website to handle this yourself.
|
222 |
+
|
223 |
+
For jQuery UI tabs and accordions, download the .php file from [this gist](https://gist.github.com/webaware/05b27e3a99ccb00200f5), and install / activate it. If you'd prefer to add the jQuery code yourself, add this somewhere on the page (e.g. in your theme's footer):
|
224 |
|
225 |
`<script>
|
226 |
+
(function($) {
|
227 |
+
|
228 |
+
function mapRedraw(event, ui) {
|
229 |
+
if (ui.newPanel.length) {
|
230 |
+
$("#" + ui.newPanel[0].id + " div.flxmap-container").each(function() {
|
231 |
+
var flxmap = window[this.getAttribute("data-flxmap")];
|
232 |
+
flxmap.redrawOnce();
|
233 |
+
});
|
234 |
+
}
|
235 |
}
|
236 |
+
|
237 |
+
$("body").on("accordionactivate", mapRedraw).on("tabsactivate", mapRedraw);
|
238 |
+
|
239 |
+
})(jQuery);
|
240 |
</script>`
|
241 |
|
242 |
+
For jQuery UI tabs versions 1.8 or older:
|
243 |
|
244 |
`<script>
|
245 |
jQuery("body").bind("tabsshow", function(event, ui) {
|
306 |
|
307 |
== Changelog ==
|
308 |
|
309 |
+
= 1.9.0 [2014-12-24] =
|
310 |
+
* fixed: maps broken when hidden in tabs / accordions (not for IE 10 and earlier; uses MutationObserver)
|
311 |
+
* fixed: strip spaces from map coordinates
|
312 |
+
* fixed: suppress border radius on images within map containers
|
313 |
+
* added: server-side lookup of address, to reduce the number of Google Maps queries when only an address is given
|
314 |
+
* added: support for custom map types (inc. styled maps)
|
315 |
+
* added: `maptypes` attribute for selecting which map types can be picked by visitors
|
316 |
+
* changed: refactored JavaScript for localised strings
|
317 |
+
|
318 |
= 1.8.3 [2014-12-17] =
|
319 |
* fixed: CSS for directions in twentyfifteen theme and others that toss table-layout:fixed around willy nilly
|
320 |
|