PageSourceSearch

https://ooms.com/dflip/js/libs/compatibility.js

js ooms.com collected 2026-10-07 19:36:25 UTC 19,370 bytes, 639 lines download raw bytes

vendor: 19,370 bytes, lines 1-639
1/* Copyright 2012 Mozilla Foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/* eslint strict: ["error", "function"] */
16/* eslint-disable no-extend-native */
17/* globals VBArray, PDFJS */
18
19(function compatibilityWrapper() {
20  'use strict';
21
22var userAgent = navigator.userAgent;
23
24var isAndroid = /Android/.test(userAgent);
25var isAndroidPre3 = /Android\s[0-2][^\d]/.test(userAgent);
26var isAndroidPre5 = /Android\s[0-4][^\d]/.test(userAgent);
27var isChrome = userAgent.indexOf('Chrom') >= 0;
28var isChromeWithRangeBug = /Chrome\/(39|40)\./.test(userAgent);
29var isIE = userAgent.indexOf('Trident') >= 0;
30var isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent);
31var isOpera = userAgent.indexOf('Opera') >= 0;
32var isSafari = /Safari\//.test(userAgent) &&
33               !/(Chrome\/|Android\s)/.test(userAgent);
34
35// Initializing PDFJS global object here, it case if we need to change/disable
36// some PDF.js features, e.g. range requests
37if (typeof PDFJS === 'undefined') {
38  (typeof window !== 'undefined' ? window : this).PDFJS = {};
39}
40
41// Checking if the typed arrays are supported
42// Support: iOS<6.0 (subarray), IE<10, Android<4.0
43(function checkTypedArrayCompatibility() {
44  if (typeof Uint8Array !== 'undefined') {
45    // Support: iOS<6.0
46    if (typeof Uint8Array.prototype.subarray === 'undefined') {
47      Uint8Array.prototype.subarray = function subarray(start, end) {
48        return new Uint8Array(this.slice(start, end));
49      };
50      Float32Array.prototype.subarray = function subarray(start, end) {
51        return new Float32Array(this.slice(start, end));
52      };
53    }
54
55    // Support: Android<4.1
56    if (typeof Float64Array === 'undefined') {
57      window.Float64Array = Float32Array;
58    }
59    return;
60  }
61
62  function subarray(start, end) {
63    return new TypedArray(this.slice(start, end));
64  }
65
66  function setArrayOffset(array, offset) {
67    if (arguments.length < 2) {
68      offset = 0;
69    }
70    for (var i = 0, n = array.length; i < n; ++i, ++offset) {
71      this[offset] = array[i] & 0xFF;
72    }
73  }
74
75  function TypedArray(arg1) {
76    var result, i, n;
77    if (typeof arg1 === 'number') {
78      result = [];
79      for (i = 0; i < arg1; ++i) {
80        result[i] = 0;
81      }
82    } else if ('slice' in arg1) {
83      result = arg1.slice(0);
84    } else {
85      result = [];
86      for (i = 0, n = arg1.length; i < n; ++i) {
87        result[i] = arg1[i];
88      }
89    }
90
91    result.subarray = subarray;
92    result.buffer = result;
93    result.byteLength = result.length;
94    result.set = setArrayOffset;
95
96    if (typeof arg1 === 'object' && arg1.buffer) {
97      result.buffer = arg1.buffer;
98    }
99    return result;
100  }
101
102  window.Uint8Array = TypedArray;
103  window.Int8Array = TypedArray;
104
105  // we don't need support for set, byteLength for 32-bit array
106  // so we can use the TypedArray as well
107  window.Uint32Array = TypedArray;
108  window.Int32Array = TypedArray;
109  window.Uint16Array = TypedArray;
110  window.Float32Array = TypedArray;
111  window.Float64Array = TypedArray;
112})();
113
114// URL = URL || webkitURL
115// Support: Safari<7, Android 4.2+
116(function normalizeURLObject() {
117  if (!window.URL) {
118    window.URL = window.webkitURL;
119  }
120})();
121
122// Object.defineProperty()?
123// Support: Android<4.0, Safari<5.1
124(function checkObjectDefinePropertyCompatibility() {
125  if (typeof Object.defineProperty !== 'undefined') {
126    var definePropertyPossible = true;
127    try {
128      // some browsers (e.g. safari) cannot use defineProperty() on DOM objects
129      // and thus the native version is not sufficient
130      Object.defineProperty(new Image(), 'id', { value: 'test' });
131      // ... another test for android gb browser for non-DOM objects
132      var Test = function Test() {};
133      Test.prototype = { get id() { } };
134      Object.defineProperty(new Test(), 'id',
135        { value: '', configurable: true, enumerable: true, writable: false });
136    } catch (e) {
137      definePropertyPossible = false;
138    }
139    if (definePropertyPossible) {
140      return;
141    }
142  }
143
144  Object.defineProperty = function objectDefineProperty(obj, name, def) {
145    delete obj[name];
146    if ('get' in def) {
147      obj.__defineGetter__(name, def['get']);
148    }
149    if ('set' in def) {
150      obj.__defineSetter__(name, def['set']);
151    }
152    if ('value' in def) {
153      obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
154        this.__defineGetter__(name, function objectDefinePropertyGetter() {
155          return value;
156        });
157        return value;
158      });
159      obj[name] = def.value;
160    }
161  };
162})();
163
164
165// No XMLHttpRequest#response?
166// Support: IE<11, Android <4.0
167(function checkXMLHttpRequestResponseCompatibility() {
168  var xhrPrototype = XMLHttpRequest.prototype;
169  var xhr = new XMLHttpRequest();
170  if (!('overrideMimeType' in xhr)) {
171    // IE10 might have response, but not overrideMimeType
172    // Support: IE10
173    Object.defineProperty(xhrPrototype, 'overrideMimeType', {
174      value: function xmlHttpRequestOverrideMimeType(mimeType) {}
175    });
176  }
177  if ('responseType' in xhr) {
178    return;
179  }
180
181  // The worker will be using XHR, so we can save time and disable worker.
182  PDFJS.disableWorker = true;
183
184  Object.defineProperty(xhrPrototype, 'responseType', {
185    get: function xmlHttpRequestGetResponseType() {
186      return this._responseType || 'text';
187    },
188    set: function xmlHttpRequestSetResponseType(value) {
189      if (value === 'text' || value === 'arraybuffer') {
190        this._responseType = value;
191        if (value === 'arraybuffer' &&
192            typeof this.overrideMimeType === 'function') {
193          this.overrideMimeType('text/plain; charset=x-user-defined');
194        }
195      }
196    }
197  });
198
199  // Support: IE9
200  if (typeof VBArray !== 'undefined') {
201    Object.defineProperty(xhrPrototype, 'response', {
202      get: function xmlHttpRequestResponseGet() {
203        if (this.responseType === 'arraybuffer') {
204          return new Uint8Array(new VBArray(this.responseBody).toArray());
205        }
206        return this.responseText;
207      }
208    });
209    return;
210  }
211
212  Object.defineProperty(xhrPrototype, 'response', {
213    get: function xmlHttpRequestResponseGet() {
214      if (this.responseType !== 'arraybuffer') {
215        return this.responseText;
216      }
217      var text = this.responseText;
218      var i, n = text.length;
219      var result = new Uint8Array(n);
220      for (i = 0; i < n; ++i) {
221        result[i] = text.charCodeAt(i) & 0xFF;
222      }
223      return result.buffer;
224    }
225  });
226})();
227
228// window.btoa (base64 encode function) ?
229// Support: IE<10
230(function checkWindowBtoaCompatibility() {
231  if ('btoa' in window) {
232    return;
233  }
234
235  var digits =
236    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
237
238  window.btoa = function windowBtoa(chars) {
239    var buffer = '';
240    var i, n;
241    for (i = 0, n = chars.length; i < n; i += 3) {
242      var b1 = chars.charCodeAt(i) & 0xFF;
243      var b2 = chars.charCodeAt(i + 1) & 0xFF;
244      var b3 = chars.charCodeAt(i + 2) & 0xFF;
245      var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
246      var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
247      var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
248      buffer += (digits.charAt(d1) + digits.charAt(d2) +
249                 digits.charAt(d3) + digits.charAt(d4));
250    }
251    return buffer;
252  };
253})();
254
255// window.atob (base64 encode function)?
256// Support: IE<10
257(function checkWindowAtobCompatibility() {
258  if ('atob' in window) {
259    return;
260  }
261
262  // https://github.com/davidchambers/Base64.js
263  var digits =
264    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
265  window.atob = function (input) {
266    input = input.replace(/=+$/, '');
267    if (input.length % 4 === 1) {
268      throw new Error('bad atob input');
269    }
270    for (
271      // initialize result and counters
272      var bc = 0, bs, buffer, idx = 0, output = '';
273      // get next character
274      (buffer = input.charAt(idx++));
275      // character found in table?
276      // initialize bit storage and add its ascii value
277      ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
278        // and if not first of each 4 characters,
279        // convert the first 8 bits to one ascii character
280        bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
281    ) {
282      // try to find character in table (0-63, not found => -1)
283      buffer = digits.indexOf(buffer);
284    }
285    return output;
286  };
287})();
288
289// Function.prototype.bind?
290// Support: Android<4.0, iOS<6.0
291(function checkFunctionPrototypeBindCompatibility() {
292  if (typeof Function.prototype.bind !== 'undefined') {
293    return;
294  }
295
296  Function.prototype.bind = function functionPrototypeBind(obj) {
297    var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
298    var bound = function functionPrototypeBindBound() {
299      var args = headArgs.concat(Array.prototype.slice.call(arguments));
300      return fn.apply(obj, args);
301    };
302    return bound;
303  };
304})();
305
306// HTMLElement dataset property
307// Support: IE<11, Safari<5.1, Android<4.0
308(function checkDatasetProperty() {
309  var div = document.createElement('div');
310  if ('dataset' in div) {
311    return; // dataset property exists
312  }
313
314  Object.defineProperty(HTMLElement.prototype, 'dataset', {
315    get: function() {
316      if (this._dataset) {
317        return this._dataset;
318      }
319
320      var dataset = {};
321      for (var j = 0, jj = this.attributes.length; j < jj; j++) {
322        var attribute = this.attributes[j];
323        if (attribute.name.substring(0, 5) !== 'data-') {
324          continue;
325        }
326        var key = attribute.name.substring(5).replace(/\-([a-z])/g,
327          function(all, ch) {
328            return ch.toUpperCase();
329          });
330        dataset[key] = attribute.value;
331      }
332
333      Object.defineProperty(this, '_dataset', {
334        value: dataset,
335        writable: false,
336        enumerable: false
337      });
338      return dataset;
339    },
340    enumerable: true
341  });
342})();
343
344// HTMLElement classList property
345// Support: IE<10, Android<4.0, iOS<5.0
346(function checkClassListProperty() {
347  var div = document.createElement('div');
348  if ('classList' in div) {
349    return; // classList property exists
350  }
351
352  function changeList(element, itemName, add, remove) {
353    var s = element.className || '';
354    var list = s.split(/\s+/g);
355    if (list[0] === '') {
356      list.shift();
357    }
358    var index = list.indexOf(itemName);
359    if (index < 0 && add) {
360      list.push(itemName);
361    }
362    if (index >= 0 && remove) {
363      list.splice(index, 1);
364    }
365    element.className = list.join(' ');
366    return (index >= 0);
367  }
368
369  var classListPrototype = {
370    add: function(name) {
371      changeList(this.element, name, true, false);
372    },
373    contains: function(name) {
374      return changeList(this.element, name, false, false);
375    },
376    remove: function(name) {
377      changeList(this.element, name, false, true);
378    },
379    toggle: function(name) {
380      changeList(this.element, name, true, true);
381    }
382  };
383
384  Object.defineProperty(HTMLElement.prototype, 'classList', {
385    get: function() {
386      if (this._classList) {
387        return this._classList;
388      }
389
390      var classList = Object.create(classListPrototype, {
391        element: {
392          value: this,
393          writable: false,
394          enumerable: true
395        }
396      });
397      Object.defineProperty(this, '_classList', {
398        value: classList,
399        writable: false,
400        enumerable: false
401      });
402      return classList;
403    },
404    enumerable: true
405  });
406})();
407
408// Check console compatibility
409// In older IE versions the console object is not available
410// unless console is open.
411// Support: IE<10
412(function checkConsoleCompatibility() {
413  if (!('console' in window)) {
414    window.console = {
415      log: function() {},
416      error: function() {},
417      warn: function() {}
418    };
419  } else if (!('bind' in console.log)) {
420    // native functions in IE9 might not have bind
421    console.log = (function(fn) {
422      return function(msg) { return fn(msg); };
423    })(console.log);
424    console.error = (function(fn) {
425      return function(msg) { return fn(msg); };
426    })(console.error);
427    console.warn = (function(fn) {
428      return function(msg) { return fn(msg); };
429    })(console.warn);
430  }
431})();
432
433// Check onclick compatibility in Opera
434// Support: Opera<15
435(function checkOnClickCompatibility() {
436  // workaround for reported Opera bug DSK-354448:
437  // onclick fires on disabled buttons with opaque content
438  function ignoreIfTargetDisabled(event) {
439    if (isDisabled(event.target)) {
440      event.stopPropagation();
441    }
442  }
443  function isDisabled(node) {
444    return node.disabled || (node.parentNode && isDisabled(node.parentNode));
445  }
446  if (isOpera) {
447    // use browser detection since we cannot feature-check this bug
448    document.addEventListener('click', ignoreIfTargetDisabled, true);
449  }
450})();
451
452// Checks if possible to use URL.createObjectURL()
453// Support: IE
454(function checkOnBlobSupport() {
455  // sometimes IE loosing the data created with createObjectURL(), see #3977
456  if (isIE) {
457    PDFJS.disableCreateObjectURL = true;
458  }
459})();
460
461// Checks if navigator.language is supported
462(function checkNavigatorLanguage() {
463  if ('language' in navigator) {
464    return;
465  }
466  PDFJS.locale = navigator.userLanguage || 'en-US';
467})();
468
469// Support: Safari 6.0+, Android<3.0, Chrome 39/40, iOS
470(function checkRangeRequests() {
471  // Safari has issues with cached range requests see:
472  // https://github.com/mozilla/pdf.js/issues/3260
473  // Last tested with version 6.0.4.
474
475  // Older versions of Android (pre 3.0) has issues with range requests, see:
476  // https://github.com/mozilla/pdf.js/issues/3381.
477  // Make sure that we only match webkit-based Android browsers,
478  // since Firefox/Fennec works as expected.
479
480  // Range requests are broken in Chrome 39 and 40, https://crbug.com/442318
481  if (isSafari || isAndroidPre3 || isChromeWithRangeBug || isIOS) {
482    PDFJS.disableRange = true;
483    PDFJS.disableStream = true;
484  }
485})();
486
487// Check if the browser supports manipulation of the history.
488// Support: IE<10, Android<4.2
489(function checkHistoryManipulation() {
490  // Android 2.x has so buggy pushState support that it was removed in
491  // Android 3.0 and restored as late as in Android 4.2.
492  // Support: Android 2.x
493  if (!history.pushState || isAndroidPre3) {
494    PDFJS.disableHistory = true;
495  }
496})();
497
498// Support: IE<11, Chrome<21, Android<4.4, Safari<6
499(function checkSetPresenceInImageData() {
500  // IE < 11 will use window.CanvasPixelArray which lacks set function.
501  if (window.CanvasPixelArray) {
502    if (typeof window.CanvasPixelArray.prototype.set !== 'function') {
503      window.CanvasPixelArray.prototype.set = function(arr) {
504        for (var i = 0, ii = this.length; i < ii; i++) {
505          this[i] = arr[i];
506        }
507      };
508    }
509  } else {
510    // Old Chrome and Android use an inaccessible CanvasPixelArray prototype.
511    // Because we cannot feature detect it, we rely on user agent parsing.
512    var polyfill = false, versionMatch;
513    if (isChrome) {
514      versionMatch = userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
515      // Chrome < 21 lacks the set function.
516      polyfill = versionMatch && parseInt(versionMatch[2]) < 21;
517    } else if (isAndroid) {
518      // Android < 4.4 lacks the set function.
519      // Android >= 4.4 will contain Chrome in the user agent,
520      // thus pass the Chrome check above and not reach this block.
521      polyfill = isAndroidPre5;
522    } else if (isSafari) {
523      versionMatch = userAgent.
524        match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//);
525      // Safari < 6 lacks the set function.
526      polyfill = versionMatch && parseInt(versionMatch[1]) < 6;
527    }
528
529    if (polyfill) {
530      var contextPrototype = window.CanvasRenderingContext2D.prototype;
531      var createImageData = contextPrototype.createImageData;
532      contextPrototype.createImageData = function(w, h) {
533        var imageData = createImageData.call(this, w, h);
534        imageData.data.set = function(arr) {
535          for (var i = 0, ii = this.length; i < ii; i++) {
536            this[i] = arr[i];
537          }
538        };
539        return imageData;
540      };
541      // this closure will be kept referenced, so clear its vars
542      contextPrototype = null;
543    }
544  }
545})();
546
547// Support: IE<10, Android<4.0, iOS
548(function checkRequestAnimationFrame() {
549  function fakeRequestAnimationFrame(callback) {
550    window.setTimeout(callback, 20);
551  }
552
553  if (isIOS) {
554    // requestAnimationFrame on iOS is broken, replacing with fake one.
555    window.requestAnimationFrame = fakeRequestAnimationFrame;
556    return;
557  }
558  if ('requestAnimationFrame' in window) {
559    return;
560  }
561  window.requestAnimationFrame =
562    window.mozRequestAnimationFrame ||
563    window.webkitRequestAnimationFrame ||
564    fakeRequestAnimationFrame;
565})();
566
567// Support: Android, iOS
568(function checkCanvasSizeLimitation() {
569  if (isIOS || isAndroid) {
570    // 5MP
571    PDFJS.maxCanvasPixels = 5242880;
572  }
573})();
574
575// Disable fullscreen support for certain problematic configurations.
576// Support: IE11+ (when embedded).
577(function checkFullscreenSupport() {
578  if (isIE && window.parent !== window) {
579    PDFJS.disableFullscreen = true;
580  }
581})();
582
583// Provides document.currentScript support
584// Support: IE, Chrome<29.
585(function checkCurrentScript() {
586  if ('currentScript' in document) {
587    return;
588  }
589  Object.defineProperty(document, 'currentScript', {
590    get: function () {
591      var scripts = document.getElementsByTagName('script');
592      return scripts[scripts.length - 1];
593    },
594    enumerable: true,
595    configurable: true
596  });
597})();
598
599// Provides `input.type = 'type'` runtime failure protection.
600// Support: IE9,10.
601(function checkInputTypeNumberAssign() {
602  var el = document.createElement('input');
603  try {
604    el.type = 'number';
605  } catch (ex) {
606    var inputProto = el.constructor.prototype;
607    var typeProperty = Object.getOwnPropertyDescriptor(inputProto, 'type');
608    Object.defineProperty(inputProto, 'type', {
609      get: function () { return typeProperty.get.call(this); },
610      set: function (value) {
611        typeProperty.set.call(this, value === 'number' ? 'text' : value);
612      },
613      enumerable: true,
614      configurable: true
615    });
616  }
617})();
618
619// Provides correct document.readyState value for legacy browsers.
620// Support: IE9,10.
621(function checkDocumentReadyState() {
622  if (!document.attachEvent) {
623    return;
624  }
625  var documentProto = document.constructor.prototype;
626  var readyStateProto = Object.getOwnPropertyDescriptor(documentProto,
627                                                        'readyState');
628  Object.defineProperty(documentProto, 'readyState', {
629    get: function () {
630      var value = readyStateProto.get.call(this);
631      return value === 'interactive' ? 'loading' : value;
632    },
633    set: function (value) { readyStateProto.set.call(this, value); },
634    enumerable: true,
635    configurable: true
636  });
637})();
638
639}).call((typeof window === 'undefined') ? this : 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.