1/* 2 * leaflet.fullscreen 3 * (c) Bruno B.; MIT License 4 * Uses fragments from the package 'screenfull' 5 */ 6(function(root, factory) { 7 if (typeof define === 'function' && define.amd) { 8 // define an AMD module that requires 'leaflet' 9 // and resolve to an object containing leaflet 10 define('leafletFullScreen', ['leaflet'], factory); 11 } else if (typeof module === 'object' && module.exports) { 12 // define a CommonJS module that requires 'leaflet' 13 module.exports = factory(require('leaflet')); 14 } else { 15 // Assume 'leaflet' are loaded into global variable already 16 factory(root.L); 17 } 18}(typeof self !== 'undefined' 19 ? self 20 : this, (leaflet) => { 21 'use strict'; 22 23 if (typeof document === 'undefined') { 24 console.warn('"window.document" is undefined; leaflet.fullscreen requires this object to access the DOM'); 25 return false; 26 } 27 28 const nativeAPI = (() => { 29 const methodMap = [ 30 // Standard 31 [ 32 'requestFullscreen', 33 'exitFullscreen', 34 'fullscreenElement', 35 'fullscreenEnabled', 36 'fullscreenchange', 37 'fullscreenerror' 38 ], 39 // New WebKit 40 [ 41 'webkitRequestFullscreen', 42 'webkitExitFullscreen', 43 'webkitFullscreenElement', 44 'webkitFullscreenEnabled', 45 'webkitfullscreenchange', 46 'webkitfullscreenerror' 47 ] 48 ]; 49 50 const baseList = methodMap[0]; 51 const ret = {}; 52 53 for (const methodList of methodMap) { 54 if (methodList[1] in document) { 55 for (let i = 0; i < methodList.length; i++) { 56 ret[baseList[i]] = methodList[i]; 57 } 58 return ret; 59 } 60 } 61 62 return false; 63 })(); 64 65 const eventNameMap = { 66 change: nativeAPI.fullscreenchange, 67 error: nativeAPI.fullscreenerror, 68 }; 69 70 const fullscreenAPI = { 71 request(element, options) { 72 return new Promise((resolve, reject) => { 73 const onFullScreenEntered = function() { 74 this.off('change', onFullScreenEntered); 75 resolve(); 76 }.bind(this); 77 78 this.on('change', onFullScreenEntered); 79 element = element || document.documentElement; 80 const returnPromise = element[nativeAPI.requestFullscreen](options); 81 if (returnPromise instanceof Promise) { 82 returnPromise.then(onFullScreenEntered).catch(reject); 83 } 84 }); 85 }, 86 exit() { 87 return new Promise((resolve, reject) => { 88 if (!this.isFullscreen) { 89 resolve(); 90 return; 91 } 92 93 const onFullScreenExit = function() { 94 this.off('change', onFullScreenExit); 95 resolve(); 96 }.bind(this); 97 98 this.on('change', onFullScreenExit); 99 const returnPromise = document[nativeAPI.exitFullscreen](); 100 if (returnPromise instanceof Promise) { 101 returnPromise.then(onFullScreenExit).catch(reject); 102 } 103 }); 104 }, 105 on(event, callback) { 106 const eventName = eventNameMap[event]; 107 if (eventName) { 108 document.addEventListener(eventName, callback, false); 109 } 110 }, 111 off(event, callback) { 112 const eventName = eventNameMap[event]; 113 if (eventName) { 114 document.removeEventListener(eventName, callback, false); 115 } 116 }, 117 nativeAPI: nativeAPI 118 }; 119 120 Object.defineProperties(fullscreenAPI, { 121 isFullscreen: { 122 get() { 123 return Boolean(document[nativeAPI.fullscreenElement]); 124 } 125 }, 126 isEnabled: { 127 enumerable: true, 128 get() { 129 // Coerce to boolean in case of old WebKit 130 return Boolean(document[nativeAPI.fullscreenEnabled]); 131 } 132 } 133 }); 134 135 leaflet.Control.FullScreen = leaflet.Control.extend({ 136 options: { 137 position: 'topleft', 138 title: 'Full Screen', 139 titleCancel: 'Exit Full Screen',
140 forceSeparateButton: false, 141 forcePseudoFullscreen: false, 142 fullscreenElement: false 143 }, 144 145 _screenfull: fullscreenAPI, 146 147 onAdd(map) { 148 let className = 'leaflet-control-zoom-fullscreen'; 149 let container; 150 let content = ''; 151 152 if (map.zoomControl && !this.options.forceSeparateButton) { 153 container = map.zoomControl._container; 154 } else { 155 container = leaflet.DomUtil.create('div', 'leaflet-bar'); 156 } 157 158 if (this.options.content) { 159 content = this.options.content; 160 } else { 161 className += ' fullscreen-icon'; 162 } 163 164 this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this); 165 this._map.fullscreenControl = this; 166 167 this._map.on('enterFullscreen exitFullscreen', this._toggleState, this); 168 169 return container; 170 }, 171 172 onRemove() { 173 leaflet.DomEvent 174 .off(this.link, 'click', leaflet.DomEvent.stop) 175 .off(this.link, 'click', this.toggleFullScreen, this); 176 177 if (this._screenfull.isEnabled) { 178 leaflet.DomEvent 179 .off(this._container, this._screenfull.nativeAPI.fullscreenchange, leaflet.DomEvent.stop) 180 .off(this._container, this._screenfull.nativeAPI.fullscreenchange, this._handleFullscreenChange, this); 181 182 leaflet.DomEvent 183 .off(document, this._screenfull.nativeAPI.fullscreenchange, leaflet.DomEvent.stop) 184 .off(document, this._screenfull.nativeAPI.fullscreenchange, this._handleFullscreenChange, this); 185 } 186 }, 187 188 _createButton(title, className, content, container, fn, context) { 189 this.link = leaflet.DomUtil.create('a', className, container); 190 this.link.href = '#'; 191 this.link.title = title; 192 this.link.innerHTML = content; 193 194 this.link.setAttribute('role', 'button'); 195 this.link.setAttribute('aria-label', title); 196 197 L.DomEvent.disableClickPropagation(container); 198 199 leaflet.DomEvent 200 .on(this.link, 'click', leaflet.DomEvent.stop) 201 .on(this.link, 'click', fn, context); 202 203 if (this._screenfull.isEnabled) { 204 leaflet.DomEvent 205 .on(container, this._screenfull.nativeAPI.fullscreenchange, leaflet.DomEvent.stop) 206 .on(container, this._screenfull.nativeAPI.fullscreenchange, this._handleFullscreenChange, context); 207 208 leaflet.DomEvent 209 .on(document, this._screenfull.nativeAPI.fullscreenchange, leaflet.DomEvent.stop) 210 .on(document, this._screenfull.nativeAPI.fullscreenchange, this._handleFullscreenChange, context); 211 } 212 213 return this.link; 214 }, 215 216 toggleFullScreen() { 217 const map = this._map; 218 map._exitFired = false; 219 if (map._isFullscreen) { 220 if (this._screenfull.isEnabled && !this.options.forcePseudoFullscreen) { 221 this._screenfull.exit().then(() => map.invalidateSize()); 222 } else { 223 leaflet.DomUtil.removeClass(this.options.fullscreenElement 224 ? this.options.fullscreenElement 225 : map._container, 'leaflet-pseudo-fullscreen'); 226 map.invalidateSize(); 227 } 228 map.fire('exitFullscreen'); 229 map._exitFired = true; 230 map._isFullscreen = false; 231 } else { 232 if (this._screenfull.isEnabled && !this.options.forcePseudoFullscreen) { 233 this._screenfull.request(this.options.fullscreenElement 234 ? this.options.fullscreenElement 235 : map._container).then(() => map.invalidateSize()); 236 } else { 237 leaflet.DomUtil.addClass(this.options.fullscreenElement 238 ? this.options.fullscreenElement 239 : map._container, 'leaflet-pseudo-fullscreen'); 240 map.invalidateSize(); 241 } 242 map.fire('enterFullscreen'); 243 map._isFullscreen = true; 244 } 245 }, 246 247 _toggleState() { 248 this.link.title = this._map._isFullscreen 249 ? this.options.title 250 : this.options.titleCancel; 251 this._map._isFullscreen 252 ? L.DomUtil.removeClass(this.link, 'leaflet-fullscreen-on') 253 : L.DomUtil.addClass(this.link, 'leaflet-fullscreen-on'); 254 }, 255 256 _handleFullscreenChange(ev) { 257 const map = this._map; 258 if (ev.target === map.getContainer() && !this._screenfull.isFullscreen && !map._exitFired) { 259 this._screenfull.exit().then(() => map.invalidateSize()); 260 map.fire('exitFullscreen'); 261 map._exitFired = true; 262 map._isFullscreen = false; 263 } 264 } 265 }); 266 267 leaflet.Map.include({ 268 toggleFullscreen() { 269 this.fullscreenControl.toggleFullScreen(); 270 } 271 }); 272 273 leaflet.Map.addInitHook(function() { 274 if (this.options.fullscreenControl) { 275 this.addControl(leaflet.control.fullscreen(this.options.fullscreenControlOptions)); 276 } 277 }); 278 279 leaflet.control.fullscreen = function(options) { 280 return new leaflet.Control.FullScreen(options); 281 }; 282 283 return { leaflet }; 284}));
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.