1/** 2 * Frontend for maps. 3 * 4 * @author Mikhail Kobzarev <[email protected]> 5 * @package mihdan-elementor-yandex-maps 6 */ 7 8( function( $, w, d ) { 9 'use strict'; 10 var map = { 11 init: function ( $scope, $ ) { 12 13 let 14 $map = $scope.find( '.mihdan-elementor-yandex-maps' ), 15 map_id = $map.data( 'map_id' ), 16 config = $map.data( 'map_config' ), 17 device = w.elementorFrontend.getCurrentDeviceMode() || 'desktop', 18 timeout = w.elementorFrontend.isEditMode() ? 100 : 5000, 19 mapType = config.type, 20 zoom = config.zoom, 21 api_key = w.mihdan_elementor_yandex_maps_config.api_key, 22 map_lat = config.lat, 23 map_lng = config.lng, 24 language = config.language || 'ru', 25 region = config.region || 'RU', 26 ruler_control = config.rulerControl, 27 search_control = config.searchControl, 28 traffic_control = config.trafficControl, 29 type_selector = config.typeSelector, 30 zoom_control = config.zoomControl, 31 geolocation_control = config.geolocationControl, 32 route_editor = config.routeEditor, 33 fullscreen_control = config.fullscreenControl, 34 route_button_control = config.routeButtonControl, 35 route_panel_control = config.routePanelControl, 36 enable_save_map = config.enableSaveMap, 37 disable_scroll_zoom = config.disableScrollZoom, 38 disable_dbl_click_zoom = config.disableDblClickZoom, 39 disable_drag = config.disableDrag, 40 disable_left_mouse_button_magnifier = config.disableLeftMouseButtonMagnifier, 41 disable_right_mouse_button_magnifier = config.disableRightMouseButtonMagnifier, 42 disable_multi_touch = config.disableMultiTouch, 43 disable_route_editor = config.disableRouteEditor, 44 disable_ruler = config.disableRuler, 45 disable_lazy_load = config.disableLazyLoad, 46 enable_object_manager = config.enableObjectManager, 47 enable_balloon_panel = config.enableBalloonPanel === 'yes', 48 infowindow_max_width = parseInt( config.infoWindowMaxWidth, 10 ), 49 controls = [], 50 ns = 'mihdan_elementor_yandex_maps_ns_' + map_id, // ÐеймÑÐ¿ÐµÐ¹Ñ Ð´Ð»Ñ ÐºÐ°ÑÑÑ. 51 map = 'mihdan_elementor_yandex_maps_map_' + map_id, 52 loaded = false; 53 54 // ÐÑклÑÑÐ°ÐµÑ Ð»ÐµÐ½Ð¸Ð²ÑÑ Ð·Ð°Ð³ÑÑÐ·ÐºÑ ÐºÐ°ÑÑÑ, 55 // когда каÑÑа в Ñапке ÑайÑа или на Ñоне ÑекÑии. 56 if ( disable_lazy_load === 'yes' ) { 57 timeout = 0; 58 } 59 60 // ÐÐµÐ½Ð¸Ð²Ð°Ñ Ð·Ð°Ð³ÑÑзка API каÑÑ. 61 const lazyLoad = function () { 62 63 if ( loaded ) { 64 return; 65 } 66 67 const 68 script_id = 'mihdan_elementor_yandex_maps_script_' + map_id, 69 script = document.getElementById( script_id ); 70 71 // СкÑÐ¸Ð¿Ñ Ñже подгÑÑжен Ð´Ð»Ñ ÑÑой каÑÑÑ. 72 if ( script ) { 73 script.parentNode.removeChild( script ); 74 } 75 76 const 77 f = d.getElementsByTagName( 'script' )[0], 78 j = d.createElement( 'script' ); 79 80 j.async = true; 81 j.id = script_id; 82 j.src = 'https://api-maps.yandex.ru/2.1/?lang=' + language + '_' + region + '&source=admin&apikey=' + api_key + '&onload=ymaps_ready_' + map_id + '&ns=' + ns; 83 f.parentNode.insertBefore( j, f ); 84 85 loaded = true; 86 }; 87 88 const event_options = { 89 once: true, 90 passive: true, 91 capture: true 92 }; 93 94 // ÐодклÑÑим API под дейÑÑвием полÑзоваÑелÑ. 95 document.addEventListener( 'scroll', lazyLoad, event_options ); 96 document.addEventListener( 'mouseover', lazyLoad, event_options ); 97 document.addEventListener( 'mousemove', lazyLoad, event_options ); 98 document.addEventListener( 'touchstart', lazyLoad, event_options ); 99 document.addEventListener( 'touchmove', lazyLoad, event_options ); 100 101 // Фолбек загÑÑзки каÑÑÑ, еÑли ÑÐ·ÐµÑ Ð½Ðµ Ñделал Ð½Ð¸ÐºÐ°ÐºÐ¸Ñ ÑобÑÑий. 102 setTimeout( lazyLoad, timeout ); 103 104 if (w['ymaps_ready_' + map_id]) { 105 return; 106 } 107 108 w['ymaps_ready_' + map_id] = function () { 109 110 if ( 'yes' === ruler_control ) { 111 controls.push( 'rulerControl' ); 112 } 113 114 if ( 'yes' === search_control ) { 115 controls.push( 'searchControl' ); 116 } 117 118 if ( 'yes' === traffic_control ) { 119 controls.push( 'trafficControl' ); 120 } 121 122 if ( 'yes' === type_selector ) { 123 controls.push( 'typeSelector' ); 124 } 125
126 if ( 'yes' === zoom_control ) { 127 controls.push( 'zoomControl' ); 128 } 129 130 if ( 'yes' === geolocation_control ) { 131 controls.push( 'geolocationControl' ); 132 } 133 134 if ( 'yes' === route_editor ) { 135 controls.push( 'routeEditor' ); 136 } 137 138 if ( 'yes' === fullscreen_control ) { 139 controls.push( 'fullscreenControl' ); 140 } 141 142 if ( 'yes' === route_button_control ) { 143 controls.push( 'routeButtonControl' ); 144 } 145 146 if ( 'yes' === route_panel_control ) { 147 controls.push( 'routePanelControl' ); 148 } 149 150 w[ map ] = new w[ ns ].Map( 151 $map.attr( 'id' ), 152 { 153 center: [ parseFloat( map_lat ), parseFloat( map_lng ) ], 154 zoom: parseInt( zoom[ device ] || 10 ), 155 type: 'yandex#' + mapType, 156 controls: controls 157 }, 158 { 159 searchControlProvider: 'yandex#search' 160 } 161 ); 162 163 let lastOpenedBalloon = false; 164 165 // ÐÑклÑÑиÑÑ Ð¿ÑокÑÑÑÐºÑ ÐºÐ¾Ð»ÐµÑом мÑÑи 166 if ( 'yes' === disable_scroll_zoom ) { 167 w[ map ].behaviors.disable( 'scrollZoom' ); 168 } 169 170 // ÐÑклÑÑиÑÑ Ð¼Ð°ÑÑÑабиÑование каÑÑÑ Ð´Ð²Ð¾Ð¹Ð½Ñм ÑелÑком кнопки мÑÑи 171 if ( 'yes' === disable_dbl_click_zoom ) { 172 w[ map ].behaviors.disable( 'dblClickZoom' ); 173 } 174 175 // ÐÑклÑÑиÑÑ Ð¿ÐµÑеÑаÑкивание каÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼ÑÑи либо одиноÑного каÑÐ°Ð½Ð¸Ñ 176 if ( 'yes' === disable_drag ) { 177 w[ map ].behaviors.disable( 'drag' ); 178 } 179 180 // ÐÑклÑÑиÑÑ Ð¼Ð°ÑÑÑабиÑование каÑÑÑ Ð¿Ñи вÑделении облаÑÑи левой кнопкой мÑÑи 181 if ( 'yes' === disable_left_mouse_button_magnifier ) { 182 w[ map ].behaviors.disable( 'leftMouseButtonMagnifier' ); 183 } 184 185 // ÐÑклÑÑиÑÑ Ð¼Ð°ÑÑÑабиÑование каÑÑÑ Ð¿Ñи вÑделении облаÑÑи пÑавой кнопкой мÑÑи 186 if ( 'yes' === disable_right_mouse_button_magnifier ) { 187 w[ map ].behaviors.disable( 'rightMouseButtonMagnifier' ); 188 } 189 190 // ÐÑклÑÑиÑÑ Ð¼Ð°ÑÑÑабиÑование каÑÑÑ Ð¼ÑлÑÑиÑенÑоÑнÑм каÑанием 191 if ( 'yes' === disable_multi_touch ) { 192 w[ map ].behaviors.disable( 'multiTouch' ); 193 } 194 195 // ÐÑклÑÑиÑÑ ÑедакÑÐ¾Ñ Ð¼Ð°ÑÑÑÑÑов 196 if ( 'yes' === disable_route_editor ) { 197 w[ map ].behaviors.disable( 'routeEditor' ); 198 } 199 200 // ÐÑклÑÑиÑÑ Ð»Ð¸Ð½ÐµÐ¹ÐºÑ 201 if ( 'yes' === disable_ruler ) { 202 w[ map ].behaviors.disable( 'ruler' ); 203 } 204 205 var markersLocations = config.locations; 206 207 // ÐÑли вклÑÑена клаÑÑеÑизаÑиÑ. 208 if ( 'yes' === enable_object_manager ) { 209 // Создание менеджеÑа обÑекÑов. 210 var objectManager = new w[ ns ].ObjectManager( 211 { 212 clusterize: true, 213 preset: markersLocations.clusterPreset, 214 geoObjectBalloonMaxWidth: infowindow_max_width, 215 } 216 ); 217 218 // ÐÑклÑÑиÑÑ ÑÑ Ð»Ð¾Ð¿Ñвание балÑна в Ð¿Ð°Ð½ÐµÐ»Ñ 219 // на маленÑком ÑкÑане. 220 if ( enable_balloon_panel === false ) { 221 objectManager.objects.options.set( 'balloonPanelMaxMapArea', 0 ); 222 } 223 224 // ÐоÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑа ÐµÐ¼Ñ ÑледÑÐµÑ Ð¿ÐµÑедаÑÑ JSON-опиÑание обÑекÑов. 225 objectManager.add( markersLocations ); 226 227 // ÐÑобÑазим обÑекÑÑ Ð½Ð° каÑÑе. 228 w[ map ].geoObjects.add( objectManager ); 229 230 } else { 231 /** 232 * ÐеÑки без клаÑÑеÑов. 233 * 234 * @link https://tech.yandex.ru/maps/jsbox/2.1/icon_customImage 235 * @link https://tech.yandex.ru/maps/jsapi/doc/2.1/dg/concepts/geoobjects-docpage/#geoobjects__icon-style 236 */ 237 $.each( 238 markersLocations.features, 239 function ( index, Element ) { 240 var options = {}; 241 242 // Custom icon. 243 if ( Element.options.iconImage ) { 244 const icon_size = parseInt( Element.options.iconImageWidth, 10 ); 245 246 options.iconLayout = 'default#imageWithContent'; 247 options.iconImageHref = Element.options.iconImage; 248 options.iconImageSize = [ 249 icon_size, 250 icon_size 251 ]; 252 options.iconImageOffset = [ 253 -( icon_size / 2 ), 254 -( icon_size / 2 ) 255 ]; 256 } else { 257 options.preset = Element.options.preset; 258 } 259 260 options.balloonMaxWidth = infowindow_max_width; 261 262 // ÐÑклÑÑиÑÑ ÑÑ Ð»Ð¾Ð¿Ñвание балÑна в Ð¿Ð°Ð½ÐµÐ»Ñ 263 // на маленÑком ÑкÑане. 264 if ( enable_balloon_panel === false ) { 265 options.balloonPanelMaxMapArea = 0; 266 } 267 268 var placemark = new w[ ns ].Placemark( 269 [ 270 parseFloat( Element.geometry.coordinates[0] ), 271 parseFloat( Element.geometry.coordinates[1] ) 272 ], 273 { 274 hintContent: Element.properties.hintContent, 275 balloonContentHeader: Element.properties.balloonContentHeader, 276 balloonContentBody: Element.properties.balloonContentBody,
277 balloonContentFooter: Element.properties.balloonContentFooter, 278 iconContent: Element.properties.iconContent, 279 iconCaption: Element.properties.iconCaption 280 }, 281 options 282 ); 283 284 w[ map ].geoObjects.add( placemark ); 285 286 // ÐоказаÑÑ Ð±Ð°Ð»Ñн пÑи загÑÑзке меÑки. 287 if ( 'yes' === Element.options.balloonIsOpened ) { 288 placemark.balloon.open(); 289 } 290 } 291 ); 292 } 293 294 /** 295 * ÐолÑÑÐ°ÐµÑ Ð·Ð½Ð°Ñение паÑамеÑÑа name из адÑеÑной ÑÑÑоки бÑаÑзеÑа. 296 * 297 * @param {string} name ÐÐ¼Ñ Ð¿Ð°ÑамеÑÑа Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка. 298 * @param location 299 * @returns {string|boolean} 300 */ 301 const getParam = function ( name, location ) { 302 location = location || window.location.hash; 303 const res = location.match( new RegExp( '[#&]' + name + '=([^&]*)', 'i' ) ); 304 return ( res && res[1] ? res[1] : false ); 305 }; 306 307 /** 308 * ÐеÑедаÑа паÑамеÑÑов, опиÑÑваÑÑÐ¸Ñ ÑоÑÑоÑние каÑÑÑ, в адÑеÑнÑÑ ÑÑÑÐ¾ÐºÑ Ð±ÑаÑзеÑа. 309 */ 310 const setLocationHash = function () { 311 var params = [ 312 'type=' + w[ map ].getType().split( '#' )[1], 313 'center=' + w[ map ].getCenter(), 314 'zoom=' + w[ map ].getZoom() 315 ]; 316 317 if ( w[ map ].balloon.isOpen() ) { 318 params.push( 'open=' + lastOpenedBalloon ); 319 } 320 321 window.location.hash = params.join( '&' ); 322 }; 323 324 /** 325 * УÑÑановка ÑоÑÑоÑÐ½Ð¸Ñ ÐºÐ°ÑÑÑ Ð² ÑооÑвеÑÑÑвии Ñ Ð¿ÐµÑеданнÑми в адÑеÑной ÑÑÑоке бÑаÑзеÑа паÑамеÑÑами. 326 */ 327 const setMapStateByHash = function () { 328 const hashType = getParam( 'type' ), 329 hashCenter = getParam( 'center' ), 330 hashZoom = getParam( 'zoom' ), 331 open = getParam( 'open' ); 332 333 if (hashType) { 334 w[ map ].setType( 'yandex#' + hashType ); 335 } 336 if (hashCenter) { 337 w[ map ].setCenter( hashCenter.split( ',' ) ); 338 } 339 if (hashZoom) { 340 w[ map ].setZoom( hashZoom ); 341 } 342 if (open) { 343 /*markersLocations.each(function (geoObj) { 344 var id = geoObj.properties.get('myId'); 345 if (id == open) { 346 geoObj.balloon.open(); 347 348 } 349 });*/ 350 } 351 }; 352 353 // ÐклÑÑиÑÑ ÑÐ¾Ñ Ñанение каÑÑÑ. 354 if ( 'yes' === enable_save_map ) { 355 w[ map ].events.add( 356 [ 'boundschange', 'typechange', 'balloonclose' ], 357 setLocationHash 358 ); 359 360 setMapStateByHash(); 361 } 362 }; 363 } 364 }; 365 366 // Make sure you run this code under Elementor.. 367 $( w ).on( 368 'elementor/frontend/init', 369 function() { 370 elementorFrontend.hooks.addAction( 'frontend/element_ready/yandex-maps.default', map.init ); 371 } 372 ); 373 374} )( window.jQuery, window, document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.