1/* Built: 2025-06-17T07:52:07.373Z */ 2 3(function (factory, window) { 4 // define an AMD module that relies on 'leaflet' 5 if (typeof define === 'function' && define.amd) { // eslint-disable-line no-undef 6 define(['leaflet'], factory); // eslint-disable-line no-undef 7 8 // define a Common JS module that relies on 'leaflet' 9 } else if (typeof exports === 'object') { 10 module.exports = factory(require('leaflet')); 11 } 12 13 // attach your plugin to the global 'L' variable 14 if (typeof window !== 'undefined' && window.L) { 15 // Was: window.L.a11y = factory(L); // eslint-disable-line no-undef 16 factory(L); 17 } 18 }(function (L) { 19 20 const externalData = {}; 21 22 (function createPlugin(L) { 23 console.assert(L && L.Class && L.Map && L.LatLng && L.Util, 'Leaflet'); 24 25 /** 26 * L._: Translation function, or a dummy/placeholder. 27 * @see GH Issue: Leaflet/Leaflet/issues/9092 28 */ 29 L._ = L._ || function (stringKey, placeholders) { 30 let translatedString = stringKey; // Fallback to the original string 31 32 // Use WordPress translations if available 33 if (typeof window.wpLeafletTranslations !== 'undefined' && window.wpLeafletTranslations.hasOwnProperty(stringKey)) { 34 translatedString = window.wpLeafletTranslations[stringKey]; 35 } 36 37 // Replace placeholders in the translated string 38 if (placeholders && typeof translatedString === 'string') { 39 for (const key in placeholders) { 40 if (placeholders.hasOwnProperty(key)) { 41 const regex = new RegExp('{' + key + '}', 'g'); 42 translatedString = translatedString.replace(regex, placeholders[key]); 43 } 44 } 45 } 46 47 return translatedString; 48 }; 49 50 class AccessibilityPlugin { 51 constructor(MAP) { 52 console.assert(MAP && MAP._leaflet_id && MAP.getContainer && MAP.on, 'map'); 53 this._map = MAP; 54 this._initialized = false; 55 } 56 57 get locale() { return L.locale || ''; } 58 get map() { return this._map; } 59 get mapElem() { return this._map.getContainer(); } 60 61 /** Load: was "onLoad(event)" 62 */ 63 load() { 64 let layer = 0; 65 this.map.on('layeradd', (ev) => { 66 // Initialize after the tile layer is added. 67 if (layer === 1) { 68 this.initialize(); 69 } 70 layer++; 71 }); 72 73 this._fixMarkers(); 74 } 75 76 initialize() { 77 if (this._initialized) return; 78 this._initialized = true; 79 80 this.mapElem.lang = document.documentElement.lang || 'de'; 81 82 this._localizeControls(); 83 this._localizePopups(); 84 85 this._fixMapContainer(); 86 this._managePopupFocus(); 87 } 88 89 /** Translate default controls - Zoom in/out, Attribution. 90 */ 91 _localizeControls() { 92 this._qt('.leaflet-control-zoom-in', 'aria-label', L._('Zoom in')); // src/control/Control.Zoom.js#L30 93 this._qt('.leaflet-control-zoom-in', 'title', L._('Zoom in')); 94 95 this._qt('.leaflet-control-zoom-out', 'aria-label', L._('Zoom out')); 96 this._qt('.leaflet-control-zoom-out', 'title', L._('Zoom out')); 97 98 this._qt('.leaflet-control-attribution a[href $= "leafletjs.com"]', 'aria-label', L._('Leaflet ist eine JavaScript-Bibliothek für interaktive Karten')); 99 this._qt('.leaflet-control-attribution a[href $= "leafletjs.com"]', 'title', L._('Eine JavaScript-Bibliothek für interaktive Karten')); 100 } 101 102 /** Only translate the default marker ALT text, for now. 103 * @see https://github.com/Leaflet/Leaflet/blob/main/src/layer/marker/Marker.js#L49 104 */ 105 _localizeMarker(PIN_EL) { 106 // const MARKER_PANE = MAP.getPane('markerPane'); // Was: MAP_EL.querySelector('.leaflet-marker-pane'); 107 108 // [...MARKER_PANE.children].forEach(PIN_EL => { 109 if (PIN_EL.alt === 'Marker') { 110 PIN_EL.alt = L._('Marker'); 111 PIN_EL.title = L._('Marker'); 112 } 113 // }); 114 } 115 116 _localizePopups() { 117 this.map.on('popupopen', (ev) => { 118 ev.popup._closeButton.title = L._('Popup schlieÃen'); // src/layer/Popup.js#L102 119 ev.popup._closeButton.setAttribute('aria-label', L._('Popup schlieÃen')); 120 }); 121 } 122 123 /** 124 * Set a role and role on the map container. 125 * @see GH Issue: Leaflet/Leaflet/issues/7193. 126 * @see SC 4.1.2: https://w3.org/TR/WCAG21/#name-role-value 127 */ 128 _fixMapContainer() { 129 if (!this.mapElem.hasAttribute('role')) this.mapElem.setAttribute('role', 'region'); 130 if (!this.mapElem.hasAttribute('aria-label')) this.mapElem.setAttribute('aria-label', L._('Karte')); 131 this.mapElem.setAttribute('aria-roledescription', L._('Karte')); 132 } 133 134 /** 135 * Fix for non-interactive markers. 136 * @see GH Issue: Leaflet/Leaflet/issues/8116 137 */ 138 _fixMarkers(MAP) { 139 let layerIdx = 0; 140 this.map.on('layeradd', (ev) => { 141 const markerEl = ev.layer._icon || null; 142 const isInteractive = (markerEl && markerEl.classList.contains('leaflet-interactive')) || false; 143 144 if (markerEl && !isInteractive) { 145 markerEl.tabIndex = -1; 146 markerEl.setAttribute('role', undefined); 147 markerEl.classList.add('x-static-marker'); 148 } 149 if (markerEl) { 150 this._localizeMarker(markerEl); 151 } 152 layerIdx++; 153 });
154 } 155 156 /** 157 * Move keyboard focus when a popup is opened and closed. 158 * @see GH Issue: Leaflet/Leaflet/issues/8115 (also: #8113, #8114) 159 * @see SC 2.4.3: https://w3.org/TR/WCAG21/#focus-order 160 */ 161 _managePopupFocus(MAP) { 162 this.map.on('popupopen', (ev) => { 163 ev.popup._container.setAttribute('role', 'dialog'); // Not modal! 164 ev.popup._container.tabIndex = -1; 165 166 const SOURCE = ev.popup._source; 167 if (SOURCE) { 168 SOURCE._icon.ariaExpanded = true; 169 // Only set focus when opened by a trigger element. 170 ev.popup._container.focus(); // Was: ev.popup._closeButton.focus(); 171 } 172 }); 173 174 this.map.on('popupclose', (ev) => { 175 // Find the marker or element that triggered the popup. 176 const SOURCE = ev.popup._source; 177 if (SOURCE) { 178 SOURCE._icon.focus(); 179 SOURCE._icon.ariaExpanded = 'false'; 180 } 181 }); 182 } 183 184 /** _qt: Find element within map container, and set a property on it, translated with '_()' (i18n plugin). 185 */ 186 _qt(selector, attribute, value) { 187 const ELEM = this.mapElem.querySelector(selector); 188 console.assert(ELEM, `ELEM.querySelector(${selector})`); 189 190 if (ELEM) { 191 ELEM.setAttribute(attribute, value); // Was: ELEM[property] = str; 192 } 193 } 194 } // End: class. 195 196 /** 197 * L.Map.addInitHook 198 * Param needs to be a "function" (not an arrow function), so that "this" is correct! 199 */ 200 L.Map.addInitHook(function () { 201 const MAP = this; 202 if (MAP.options.accessibilityPlugin || MAP.options.a11yPlugin) { 203 MAP.a11y = new AccessibilityPlugin(MAP); 204 205 MAP.a11y.load(); 206 } 207 }); 208 209 L.A11yPlugin = AccessibilityPlugin; 210 211 return AccessibilityPlugin; 212 })(L, externalData); 213 214 }, window));
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.