UNPKG

mapbox-gl

Version:
107 lines (98 loc) 3.77 kB
// @flow const window = require('./window'); class AJAXError extends Error { status: number; constructor(message: string, status: number) { super(message); this.status = status; } } exports.getJSON = function(url: string, callback: Callback<mixed>) { const xhr: XMLHttpRequest = new window.XMLHttpRequest(); xhr.open('GET', url, true); xhr.setRequestHeader('Accept', 'application/json'); xhr.onerror = function() { callback(new Error(xhr.statusText)); }; xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300 && xhr.response) { let data; try { data = JSON.parse(xhr.response); } catch (err) { return callback(err); } callback(null, data); } else { callback(new AJAXError(xhr.statusText, xhr.status)); } }; xhr.send(); return xhr; }; exports.getArrayBuffer = function(url: string, callback: Callback<{data: ArrayBuffer, cacheControl: ?string, expires: ?string}>) { const xhr: XMLHttpRequest = new window.XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'arraybuffer'; xhr.onerror = function() { callback(new Error(xhr.statusText)); }; xhr.onload = function() { const response: ArrayBuffer = xhr.response; if (response.byteLength === 0 && xhr.status === 200) { return callback(new Error('http status 200 returned without content.')); } if (xhr.status >= 200 && xhr.status < 300 && xhr.response) { callback(null, { data: response, cacheControl: xhr.getResponseHeader('Cache-Control'), expires: xhr.getResponseHeader('Expires') }); } else { callback(new AJAXError(xhr.statusText, xhr.status)); } }; xhr.send(); return xhr; }; function sameOrigin(url) { const a: HTMLAnchorElement = window.document.createElement('a'); a.href = url; return a.protocol === window.document.location.protocol && a.host === window.document.location.host; } const transparentPngUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII='; exports.getImage = function(url: string, callback: Callback<HTMLImageElement>) { // request the image with XHR to work around caching issues // see https://github.com/mapbox/mapbox-gl-js/issues/1470 return exports.getArrayBuffer(url, (err, imgData) => { if (err) { callback(err); } else if (imgData) { const img: HTMLImageElement = new window.Image(); const URL = window.URL || window.webkitURL; img.onload = () => { callback(null, img); URL.revokeObjectURL(img.src); }; const blob: Blob = new window.Blob([new Uint8Array(imgData.data)], { type: 'image/png' }); (img : any).cacheControl = imgData.cacheControl; (img : any).expires = imgData.expires; img.src = imgData.data.byteLength ? URL.createObjectURL(blob) : transparentPngUrl; } }); }; exports.getVideo = function(urls: Array<string>, callback: Callback<HTMLVideoElement>) { const video: HTMLVideoElement = window.document.createElement('video'); video.onloadstart = function() { callback(null, video); }; for (let i = 0; i < urls.length; i++) { const s: HTMLSourceElement = window.document.createElement('source'); if (!sameOrigin(urls[i])) { video.crossOrigin = 'Anonymous'; } s.src = urls[i]; video.appendChild(s); } return video; };