PageSourceSearch

https://dgh-odense.dk/scripts/Blob.js

js dgh-odense.dk collected 2026-10-02 13:09:32 UTC 20,611 bytes, 684 lines download raw bytes

1/* Blob.js
2 * A Blob, File, FileReader & URL implementation.
3 * 2019-04-19
4 *
5 * By Eli Grey, http://eligrey.com
6 * By Jimmy Wärting, https://github.com/jimmywarting
7 * License: MIT
8 *   See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
9 */
10
11;(function () {
12  var global = typeof window === 'object'
13      ? window : typeof self === 'object'
14      ? self : this
15
16  var BlobBuilder = global.BlobBuilder
17    || global.WebKitBlobBuilder
18    || global.MSBlobBuilder
19    || global.MozBlobBuilder
20
21  global.URL = global.URL || global.webkitURL || function (href, a) {
22  	a = document.createElement('a')
23  	a.href = href
24  	return a
25  }
26
27  var origBlob = global.Blob
28  var createObjectURL = URL.createObjectURL
29  var revokeObjectURL = URL.revokeObjectURL
30  var strTag = global.Symbol && global.Symbol.toStringTag
31  var blobSupported = false
32  var blobSupportsArrayBufferView = false
33  var arrayBufferSupported = !!global.ArrayBuffer
34  var blobBuilderSupported = BlobBuilder
35    && BlobBuilder.prototype.append
36    && BlobBuilder.prototype.getBlob
37
38  try {
39    // Check if Blob constructor is supported
40    blobSupported = new Blob(['ä']).size === 2
41
42    // Check if Blob constructor supports ArrayBufferViews
43    // Fails in Safari 6, so we need to map to ArrayBuffers there.
44    blobSupportsArrayBufferView = new Blob([new Uint8Array([1, 2])]).size === 2
45  } catch (e) {}
46
47  /**
48   * Helper function that maps ArrayBufferViews to ArrayBuffers
49   * Used by BlobBuilder constructor and old browsers that didn't
50   * support it in the Blob constructor.
51   */
52  function mapArrayBufferViews (ary) {
53    return ary.map(function (chunk) {
54      if (chunk.buffer instanceof ArrayBuffer) {
55        var buf = chunk.buffer
56
57        // if this is a subarray, make a copy so we only
58        // include the subarray region from the underlying buffer
59        if (chunk.byteLength !== buf.byteLength) {
60          var copy = new Uint8Array(chunk.byteLength)
61          copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength))
62          buf = copy.buffer
63        }
64
65        return buf
66      }
67
68      return chunk
69    })
70  }
71
72  function BlobBuilderConstructor (ary, options) {
73    options = options || {}
74
75    var bb = new BlobBuilder()
76    mapArrayBufferViews(ary).forEach(function (part) {
77      bb.append(part)
78    })
79
80    return options.type ? bb.getBlob(options.type) : bb.getBlob()
81  }
82
83  function BlobConstructor (ary, options) {
84    return new origBlob(mapArrayBufferViews(ary), options || {})
85  }
86
87  if (global.Blob) {
88    BlobBuilderConstructor.prototype = Blob.prototype
89    BlobConstructor.prototype = Blob.prototype
90  }
91
92
93
94  /********************************************************/
95  /*               String Encoder fallback                */
96  /********************************************************/
97  function stringEncode (string) {
98    var pos = 0
99    var len = string.length
100    var Arr = global.Uint8Array || Array // Use byte array when possible
101
102    var at = 0  // output position
103    var tlen = Math.max(32, len + (len >> 1) + 7)  // 1.5x size
104    var target = new Arr((tlen >> 3) << 3)  // ... but at 8 byte offset
105
106    while (pos < len) {
107      var value = string.charCodeAt(pos++)
108      if (value >= 0xd800 && value <= 0xdbff) {
109        // high surrogate
110        if (pos < len) {
111          var extra = string.charCodeAt(pos)
112          if ((extra & 0xfc00) === 0xdc00) {
113            ++pos
114            value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000
115          }
116        }
117        if (value >= 0xd800 && value <= 0xdbff) {
118          continue  // drop lone surrogate
119        }
120      }
121
122      // expand the buffer if we couldn't write 4 bytes
123      if (at + 4 > target.length) {
124        tlen += 8  // minimum extra
125        tlen *= (1.0 + (pos / string.length) * 2)  // take 2x the remaining
126        tlen = (tlen >> 3) << 3  // 8 byte offset
127
128        var update = new Uint8Array(tlen)
129        update.set(target)
130        target = update
131      }
132
133      if ((value & 0xffffff80) === 0) {  // 1-byte
134        target[at++] = value  // ASCII
135        continue
136      } else if ((value & 0xfffff800) === 0) {  // 2-byte
137        target[at++] = ((value >> 6) & 0x1f) | 0xc0
138      } else if ((value & 0xffff0000) === 0) {  // 3-byte
139        target[at++] = ((value >> 12) & 0x0f) | 0xe0
140        target[at++] = ((value >> 6) & 0x3f) | 0x80
141      } else if ((value & 0xffe00000) === 0) {  // 4-byte
142        target[at++] = ((value >> 18) & 0x07) | 0xf0
143        target[at++] = ((value >> 12) & 0x3f) | 0x80
144        target[at++] = ((value >> 6) & 0x3f) | 0x80
145      } else {
146        // FIXME: do we care
147        continue
148      }
149
150      target[at++] = (value & 0x3f) | 0x80
151    }
152
153    return target.slice(0, at)
154  }
155
156  /********************************************************/
157  /*               String Decoder fallback                */
158  /********************************************************/
159  function stringDecode (buf) {
160    var end = buf.length
161    var res = []
162
163    var i = 0
164    while (i < end) {
165      var firstByte = buf[i]
166      var codePoint = null
167      var bytesPerSequence = (firstByte > 0xEF) ? 4
168        : (firstByte > 0xDF) ? 3
169          : (firstByte > 0xBF) ? 2
170            : 1
171
172      if (i + bytesPerSequence <= end) {
173        var secondByte, thirdByte, fourthByte, tempCodePoint
174
175        switch (bytesPerSequence) {
176          case 1:
177            if (firstByte < 0x80) {
178              codePoint = firstByte
179            }
180            break
181          case 2:
182            secondByte = buf[i + 1]
183            if ((secondByte & 0xC0) === 0x80) {
184              tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
185              if (tempCodePoint > 0x7F) {
186                codePoint = tempCodePoint
187              }
188            }
189            break
190          case 3:
191            secondByte = buf[i + 1]
192            thirdByte = buf[i + 2]
193            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
194              tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
195              if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
196                codePoint = tempCodePoint
197              }
198            }
199            break
200          case 4:
201            secondByte = buf[i + 1]
202            thirdByte = buf[i + 2]
203            fourthByte = buf[i + 3]
204            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
205              tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
206              if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
207                codePoint = tempCodePoint
208              }
209            }
210        }
211      }
212
213      if (codePoint === null) {
214        // we did not generate a valid codePoint so insert a
215        // replacement char (U+FFFD) and advance only 1 byte
216        codePoint = 0xFFFD
217        bytesPerSequence = 1
218      } else if (codePoint > 0xFFFF) {
219        // encode to utf16 (surrogate pair dance)
220        codePoint -= 0x10000
221        res.push(codePoint >>>
221 10 & 0x3FF | 0xD800)
222        codePoint = 0xDC00 | codePoint & 0x3FF
223      }
224
225      res.push(codePoint)
226      i += bytesPerSequence
227    }
228
229    var len = res.length
230    var str = ''
231    var i = 0
232
233    while (i < len) {
234      str += String.fromCharCode.apply(String, res.slice(i, i += 0x1000))
235    }
236
237    return str
238  }
239
240  // string -> buffer
241  var textEncode = typeof TextEncoder === 'function'
242    ? TextEncoder.prototype.encode.bind(new TextEncoder())
243    : stringEncode
244
245  // buffer -> string
246  var textDecode = typeof TextDecoder === 'function'
247    ? TextDecoder.prototype.decode.bind(new TextDecoder())
248    : stringDecode
249
250  function FakeBlobBuilder () {
251    function isDataView (obj) {
252      return obj && DataView.prototype.isPrototypeOf(obj)
253    }
254    function bufferClone (buf) {
255      var view = new Array(buf.byteLength)
256      var array = new Uint8Array(buf)
257      var i = view.length
258      while (i--) {
259        view[i] = array[i]
260      }
261      return view
262    }
263    function array2base64 (input) {
264      var byteToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
265
266      var output = []
267
268      for (var i = 0; i < input.length; i += 3) {
269        var byte1 = input[i]
270        var haveByte2 = i + 1 < input.length
271        var byte2 = haveByte2 ? input[i + 1] : 0
272        var haveByte3 = i + 2 < input.length
273        var byte3 = haveByte3 ? input[i + 2] : 0
274
275        var outByte1 = byte1 >> 2
276        var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4)
277        var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6)
278        var outByte4 = byte3 & 0x3F
279
280        if (!haveByte3) {
281          outByte4 = 64
282
283          if (!haveByte2) {
284            outByte3 = 64
285          }
286        }
287
288        output.push(
289          byteToCharMap[outByte1], byteToCharMap[outByte2],
290          byteToCharMap[outByte3], byteToCharMap[outByte4]
291        )
292      }
293
294      return output.join('')
295    }
296
297    var create = Object.create || function (a) {
298      function c () {}
299      c.prototype = a
300      return new c()
301    }
302
303    if (arrayBufferSupported) {
304      var viewClasses = [
305        '[object Int8Array]',
306        '[object Uint8Array]',
307        '[object Uint8ClampedArray]',
308        '[object Int16Array]',
309        '[object Uint16Array]',
310        '[object Int32Array]',
311        '[object Uint32Array]',
312        '[object Float32Array]',
313        '[object Float64Array]'
314      ]
315
316      var isArrayBufferView = ArrayBuffer.isView || function (obj) {
317        return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
318      }
319    }
320
321    function concatTypedarrays (chunks) {
322      var size = 0
323      var i = chunks.length
324      while (i--) { size += chunks[i].length }
325      var b = new Uint8Array(size)
326      var offset = 0
327      for (i = 0, l = chunks.length; i < l; i++) {
328        var chunk = chunks[i]
329        b.set(chunk, offset)
330        offset += chunk.byteLength || chunk.length
331      }
332
333      return b
334    }
335
336    /********************************************************/
337    /*                   Blob constructor                   */
338    /********************************************************/
339    function Blob (chunks, opts) {
340      chunks = chunks || []
341      opts = opts == null ? {} : opts
342      for (var i = 0, len = chunks.length; i < len; i++) {
343        var chunk = chunks[i]
344        if (chunk instanceof Blob) {
345          chunks[i] = chunk._buffer
346        } else if (typeof chunk === 'string') {
347          chunks[i] = textEncode(chunk)
348        } else if (arrayBufferSupported && (ArrayBuffer.prototype.isPrototypeOf(chunk) || isArrayBufferView(chunk))) {
349          chunks[i] = bufferClone(chunk)
350        } else if (arrayBufferSupported && isDataView(chunk)) {
351          chunks[i] = bufferClone(chunk.buffer)
352        } else {
353          chunks[i] = textEncode(String(chunk))
354        }
355      }
356
357      this._buffer = global.Uint8Array
358        ? concatTypedarrays(chunks)
359        : [].concat.apply([], chunks)
360      this.size = this._buffer.length
361
362      this.type = opts.type || ''
363      if (/[^\u0020-\u007E]/.test(this.type)) {
364        this.type = ''
365      } else {
366        this.type = this.type.toLowerCase()
367      }
368    }
369
370    Blob.prototype.arrayBuffer = function () {
371      return Promise.resolve(this._buffer)
372    }
373
374    Blob.prototype.text = function () {
375      return Promise.resolve(textDecode(this._buffer))
376    }
377
378    Blob.prototype.slice = function (start, end, type) {
379      var slice = this._buffer.slice(start || 0, end || this._buffer.length)
380      return new Blob([slice], {type: type})
381    }
382
383    Blob.prototype.toString = function () {
384      return '[object Blob]'
385    }
386
387    /********************************************************/
388    /*                   File constructor                   */
389    /********************************************************/
390    function File (chunks, name, opts) {
391      opts = opts || {}
392      var a = Blob.call(this, chunks, opts) || this
393      a.name = name.replace(/\//g, ':')
394      a.lastModifiedDate = opts.lastModified ? new Date(opts.lastModified) : new Date()
395      a.lastModified = +a.lastModifiedDate
396
397      return a
398    }
399
400    File.prototype = create(Blob.prototype)
401    File.prototype.constructor = File
402
403    if (Object.setPrototypeOf) {
404      Object.setPrototypeOf(File, Blob)
405    } else {
406      try { File.__proto__ = Blob } catch (e) {}
407    }
408
409    File.prototype.toString = function () {
410      return '[object File]'
411    }
412
413    /********************************************************/
414    /*                FileReader constructor                */
415    /********************************************************/
416    function FileReader () {
417    	if (!(this instanceof FileReader)) {
418        throw new TypeError("Failed to construct 'FileReader': Please use the 'new' operator, this DOM object constructor cannot be called as a function.")
419      }
420
421    	var delegate = document.createDocumentFragment()
422    	this.addEventListener = delegate.addEventListener
423    	this.dispatchEvent = function (evt) {
424    		var local = this['on' + evt.type]
425    		if (typeof local === 'function') local(evt)
426    		delegate.dispatchEvent(evt)
427    	}
428    	this.removeEventListener = delegate.removeEventListener
429    }
430
431    function _read (fr, blob, kind) {
432    	if (!(blob instanceof Blob)) {
433        throw new TypeError("Failed to execute '" + kind + "' on 'FileReader': parameter 1 is not of type 'Blob'.")
434      }
435
436    	fr.result = ''
437
438    	setTimeout(function () {
439    		this.readyState = FileReader.LOADING
440    		fr.dispatchEvent(new Event('load'))
441    		fr.dispatchEvent(new Event('loadend'))
442    	})
443    }
444
445    FileReader.EMPTY = 0
446    FileReader.LOADING = 1
447    FileReader.DONE = 2
448    FileReader.prototype.error = null
449    FileReader.prototype.onabort = null
450    FileReader.prototype.onerror = null
451    FileReader.prototype.onload = null
452    FileReader.prototype.onloadend = null
453    FileReader.prototype.onloadstart = null
454    FileReader.prototype.onprogress = null
455
456    FileReader.prototype.readAsDataURL = function (blob) {
457    	_read(this, blob, 'readAsDataURL')
458    	this.result = 'data:' + blob.type + ';base64,' + array2base64(blob._buffer)
459    }
460
461    FileReader.prototype.readAsText = function (blob) {
462    	_read(this, blob, 'readAsText')
463    	this.result = textDecode(blob._buffer)
464    }
465
466    FileReader.prototype.readAsArrayBuffer = function (blob) {
467      _read(this, blob, 'readAsText')
468       // return ArrayBuffer when possible
469      this.result = (blob._buffer.buffer || blob._buffer).slice()
470    }
471
472    FileReader.prototype.abort = function () {}
473
474    /********************************************************/
475    /*                         URL                          */
476    /********************************************************/
477    URL.createObjectURL = function (blob) {
478      return blob instanceof Blob
479        ? 'data:' + blob.type + ';base64,' + array2base64(blob._buffer)
480        : createObjectURL.call(URL, blob)
481    }
482
483    URL.revokeObjectURL = function (url) {
484      revokeObjectURL && revokeObjectURL.call(URL, url)
485    }
486
487    /********************************************************/
488    /*                         XHR                          */
489    /********************************************************/
490    var _send = global.XMLHttpRequest && global.XMLHttpRequest.prototype.send
491    if (_send) {
492      XMLHttpRequest.prototype.send = function (data) {
493        if (data instanceof Blob) {
494          this.setRequestHeader('Content-Type', data.type)
495          _send.call(this, textDecode(data._buffer))
496        } else {
497          _send.call(this, data)
498        }
499      }
500    }
501
502    global.FileReader = FileReader
503    global.File = File
504    global.Blob = Blob
505  }
506
507  function fixFileAndXHR () {
508    var isIE = !!global.ActiveXObject || (
509      '-ms-scroll-limit' in document.documentElement.style &&
510      '-ms-ime-align' in document.documentElement.style
511    )
512
513    // Monkey patched
514    // IE don't set Content-Type header on XHR whose body is a typed Blob
515    // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6047383
516    var _send = global.XMLHttpRequest && global.XMLHttpRequest.prototype.send
517    if (isIE && _send) {
518      XMLHttpRequest.prototype.send = function (data) {
519        if (data instanceof Blob) {
520          this.setRequestHeader('Content-Type', data.type)
521          _send.call(this, data)
522        } else {
523          _send.call(this, data)
524        }
525      }
526    }
527
528    try {
529      new File([], '')
530    } catch (e) {
531      try {
532        var klass = new Function('class File extends Blob {' +
533          'constructor(chunks, name, opts) {' +
534            'opts = opts || {};' +
535            'super(chunks, opts || {});' +
536            'this.name = name.replace(/\//g, ":");' +
537            'this.lastModifiedDate = opts.lastModified ? new Date(opts.lastModified) : new Date();' +
538            'this.lastModified = +this.lastModifiedDate;' +
539          '}};' +
540          'return new File([], ""), File'
541        )()
542        global.File = klass
543      } catch (e) {
544        var klass = function (b, d, c) {
545          var blob = new Blob(b, c)
546          var t = c && void 0 !== c.lastModified ? new Date(c.lastModified) : new Date()
547
548          blob.name = d.replace(/\//g, ':')
549          blob.lastModifiedDate = t
550          blob.lastModified = +t
551          blob.toString = function () {
552            return '[object File]'
553          }
554
555          if (strTag) {
556            blob[strTag] = 'File'
557          }
558
559          return blob
560        }
561        global.File = klass
562      }
563    }
564  }
565
566  if (blobSupported) {
567    fixFileAndXHR()
568    global.Blob = blobSupportsArrayBufferView ? global.Blob : BlobConstructor
569  } else if (blobBuilderSupported) {
570    fixFileAndXHR()
571    global.Blob = BlobBuilderConstructor
572  } else {
573    FakeBlobBuilder()
574  }
575
576  if (strTag) {
577    File.prototype[strTag] = 'File'
578    Blob.prototype[strTag] = 'Blob'
579    FileReader.prototype[strTag] = 'FileReader'
580  }
581
582  var blob = global.Blob.prototype
583  var stream
584
585  function promisify(obj) {
586    return new Promise(function(resolve, reject) {
587      obj.onload =
588      obj.onerror = function(evt) {
589        obj.onload =
590        obj.onerror = null
591
592        evt.type === 'load'
593          ? resolve(obj.result || obj)
594          : reject(new Error('Failed to read the blob/file'))
595      }
596    })
597  }
598
599
600  try {
601    new ReadableStream({ type: 'bytes' })
602    stream = function stream() {
603      var position = 0
604      var blob = this
605
606      return new ReadableStream({
607        type: 'bytes',
608        autoAllocateChunkSize: 524288,
609
610        pull: function (controller) {
611          var v = controller.byobRequest.view
612          var chunk = blob.slice(position, position + v.byteLength)
613          return chunk.arrayBuffer()
614          .then(function (buffer) {
615            var uint8array = new Uint8Array(buffer)
616            var bytesRead = uint8array.byteLength
617
618            position += bytesRead
619            v.set(uint8array)
620              controller.byobRequest.respond(bytesRead)
621
622            if(position >= blob.size)
623              controller.close()
624          })
625        }
626      })
627    }
628  } catch (e) {
629    try {
630      new ReadableStream({})
631      stream = function stream(blob){
632        var position = 0
633        var blob = this
634
635        return new ReadableStream({
636          pull: function (controller) {
637            var chunk = blob.slice(position, position + 524288)
638
639            return chunk.arrayBuffer().then(function (buffer) {
640              position += buffer.byteLength
641              var uint8array = new Uint8Array(buffer)
642              controller.enqueue(uint8array)
643
644              if (position == blob.size)
645                controller.close()
646            })
647          }
648        })
649      }
650    } catch (e) {
651      try {
652        new Response('').body.getReader().read()
653        stream = function stream() {
654          return (new Response(this)).body
655        }
656      } catch (e) {
657        stream = function stream() {
658          throw new Error('Include https://github.com/MattiasBuelens/web-streams-polyfill')
659        }
660      }
661    }
662  }
663
664
665  if (!blob.arrayBuffer) {
666    blob.arrayBuffer = function arrayBuffer() {
667      var fr = new FileReader()
668      fr.readAsArrayBuffer(this)
669      return promisify(fr)
670    }
671  }
672
673  if (!blob.text) {
674    blob.text = function text() {
675      var fr = new FileReader()
676      fr.readAsText(this)
677      return promisify(fr)
678    }
679  }
680
681  if (!blob.stream) {
682    blob.stream = stream
683  }
684})()

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.