laraview/compatibility.js   F
last analyzed

Complexity

Total Complexity 137
Complexity/F 2.25

Size

Lines of Code 559
Function Count 61

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 137
c 3
b 0
f 0
dl 0
loc 559
rs 3.12
cc 2
nc 1749024768
mnd 4
bc 126
fnc 61
bpm 2.0655
cpm 2.2458
noi 23

19 Functions

Rating   Name   Duplication   Size   Complexity  
A compatibility.js ➔ checkOnBlobSupport 0 6 2
C compatibility.js ➔ checkSetPresenceInImageData 0 45 7
B compatibility.js ➔ checkDatasetProperty 0 35 2
B compatibility.js ➔ checkRangeRequests 0 24 4
A compatibility.js ➔ checkOnClickCompatibility 0 16 2
A compatibility.js ➔ checkFunctionPrototypeBindCompatibility 0 14 2
B compatibility.js ➔ checkWindowAtobCompatibility 0 31 2
C compatibility.js ➔ checkWindowBtoaCompatibility 0 24 2
A compatibility.js ➔ checkClassListProperty 0 61 2
A compatibility.js ➔ checkFullscreenSupport 0 7 2
B compatibility.js ➔ checkXMLHttpRequestResponseCompatibility 0 61 4
A compatibility.js ➔ checkConsoleCompatibility 0 20 3
A compatibility.js ➔ checkNavigatorLanguage 0 6 2
A compatibility.js ➔ checkHistoryManipulation 0 8 3
A compatibility.js ➔ checkRequestAnimationFrame 0 19 3
B compatibility.js ➔ checkObjectDefinePropertyCompatibility 0 39 4
A compatibility.js ➔ normalizeURLObject 0 5 2
B compatibility.js ➔ checkTypedArrayCompatibility 0 70 4
A compatibility.js ➔ checkCanvasSizeLimitation 0 8 3

How to fix   Complexity   

Complexity

Complex classes like laraview/compatibility.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
3
/* Copyright 2012 Mozilla Foundation
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
/* globals VBArray, PDFJS */
18
19
'use strict';
20
21
// Initializing PDFJS global object here, it case if we need to change/disable
22
// some PDF.js features, e.g. range requests
23
if (typeof PDFJS === 'undefined') {
24
  (typeof window !== 'undefined' ? window : this).PDFJS = {};
25
}
26
27
// Checking if the typed arrays are supported
28
// Support: iOS<6.0 (subarray), IE<10, Android<4.0
29
(function checkTypedArrayCompatibility() {
30
  if (typeof Uint8Array !== 'undefined') {
31
    // Support: iOS<6.0
32
    if (typeof Uint8Array.prototype.subarray === 'undefined') {
33
        Uint8Array.prototype.subarray = function subarray(start, end) {
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Uint8Array. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
34
          return new Uint8Array(this.slice(start, end));
35
        };
36
        Float32Array.prototype.subarray = function subarray(start, end) {
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Float32Array. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
37
          return new Float32Array(this.slice(start, end));
38
        };
39
    }
40
41
    // Support: Android<4.1
42
    if (typeof Float64Array === 'undefined') {
43
      window.Float64Array = Float32Array;
44
    }
45
    return;
46
  }
47
48
  function subarray(start, end) {
0 ignored issues
show
introduced by
The function subarray does not seem to be used and can be removed.
Loading history...
49
    return new TypedArray(this.slice(start, end));
50
  }
51
52
  function setArrayOffset(array, offset) {
53
    if (arguments.length < 2) {
54
      offset = 0;
55
    }
56
    for (var i = 0, n = array.length; i < n; ++i, ++offset) {
57
      this[offset] = array[i] & 0xFF;
58
    }
59
  }
60
61
  function TypedArray(arg1) {
62
    var result, i, n;
63
    if (typeof arg1 === 'number') {
64
      result = [];
65
      for (i = 0; i < arg1; ++i) {
66
        result[i] = 0;
67
      }
68
    } else if ('slice' in arg1) {
69
      result = arg1.slice(0);
70
    } else {
71
      result = [];
72
      for (i = 0, n = arg1.length; i < n; ++i) {
73
        result[i] = arg1[i];
74
      }
75
    }
76
77
    result.subarray = subarray;
78
    result.buffer = result;
79
    result.byteLength = result.length;
80
    result.set = setArrayOffset;
81
82
    if (typeof arg1 === 'object' && arg1.buffer) {
83
      result.buffer = arg1.buffer;
84
    }
85
    return result;
86
  }
87
88
  window.Uint8Array = TypedArray;
89
  window.Int8Array = TypedArray;
90
91
  // we don't need support for set, byteLength for 32-bit array
92
  // so we can use the TypedArray as well
93
  window.Uint32Array = TypedArray;
94
  window.Int32Array = TypedArray;
95
  window.Uint16Array = TypedArray;
96
  window.Float32Array = TypedArray;
97
  window.Float64Array = TypedArray;
98
})();
99
100
// URL = URL || webkitURL
101
// Support: Safari<7, Android 4.2+
102
(function normalizeURLObject() {
103
  if (!window.URL) {
104
    window.URL = window.webkitURL;
105
  }
106
})();
107
108
// Object.defineProperty()?
109
// Support: Android<4.0, Safari<5.1
110
(function checkObjectDefinePropertyCompatibility() {
111
  if (typeof Object.defineProperty !== 'undefined') {
112
    var definePropertyPossible = true;
113
    try {
114
      // some browsers (e.g. safari) cannot use defineProperty() on DOM objects
115
      // and thus the native version is not sufficient
116
      Object.defineProperty(new Image(), 'id', { value: 'test' });
0 ignored issues
show
Bug introduced by
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
117
      // ... another test for android gb browser for non-DOM objects
118
      var Test = function Test() {};
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable Test already seems to be declared on line 118. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
119
      Test.prototype = { get id() { } };
120
      Object.defineProperty(new Test(), 'id',
121
        { value: '', configurable: true, enumerable: true, writable: false });
122
    } catch (e) {
123
      definePropertyPossible = false;
124
    }
125
    if (definePropertyPossible) {
126
      return;
127
    }
128
  }
129
130
  Object.defineProperty = function objectDefineProperty(obj, name, def) {
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Object. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
131
    delete obj[name];
132
    if ('get' in def) {
133
      obj.__defineGetter__(name, def['get']);
134
    }
135
    if ('set' in def) {
136
      obj.__defineSetter__(name, def['set']);
137
    }
138
    if ('value' in def) {
139
      obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
140
        this.__defineGetter__(name, function objectDefinePropertyGetter() {
141
          return value;
142
        });
143
        return value;
144
      });
145
      obj[name] = def.value;
146
    }
147
  };
148
})();
149
150
151
// No XMLHttpRequest#response?
152
// Support: IE<11, Android <4.0
153
(function checkXMLHttpRequestResponseCompatibility() {
154
  var xhrPrototype = XMLHttpRequest.prototype;
0 ignored issues
show
Bug introduced by
The variable XMLHttpRequest seems to be never declared. If this is a global, consider adding a /** global: XMLHttpRequest */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
155
  var xhr = new XMLHttpRequest();
156
  if (!('overrideMimeType' in xhr)) {
157
    // IE10 might have response, but not overrideMimeType
158
    // Support: IE10
159
    Object.defineProperty(xhrPrototype, 'overrideMimeType', {
160
      value: function xmlHttpRequestOverrideMimeType(mimeType) {}
0 ignored issues
show
Unused Code introduced by
The parameter mimeType is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
161
    });
162
  }
163
  if ('responseType' in xhr) {
164
    return;
165
  }
166
167
  // The worker will be using XHR, so we can save time and disable worker.
168
  PDFJS.disableWorker = true;
169
170
  Object.defineProperty(xhrPrototype, 'responseType', {
171
    get: function xmlHttpRequestGetResponseType() {
172
      return this._responseType || 'text';
173
    },
174
    set: function xmlHttpRequestSetResponseType(value) {
175
      if (value === 'text' || value === 'arraybuffer') {
176
        this._responseType = value;
177
        if (value === 'arraybuffer' &&
178
            typeof this.overrideMimeType === 'function') {
179
          this.overrideMimeType('text/plain; charset=x-user-defined');
180
        }
181
      }
182
    }
183
  });
184
185
  // Support: IE9
186
  if (typeof VBArray !== 'undefined') {
187
    Object.defineProperty(xhrPrototype, 'response', {
188
      get: function xmlHttpRequestResponseGet() {
189
        if (this.responseType === 'arraybuffer') {
190
          return new Uint8Array(new VBArray(this.responseBody).toArray());
191
        } else {
192
          return this.responseText;
193
        }
194
      }
195
    });
196
    return;
197
  }
198
199
  Object.defineProperty(xhrPrototype, 'response', {
200
    get: function xmlHttpRequestResponseGet() {
201
      if (this.responseType !== 'arraybuffer') {
202
        return this.responseText;
203
      }
204
      var text = this.responseText;
205
      var i, n = text.length;
206
      var result = new Uint8Array(n);
207
      for (i = 0; i < n; ++i) {
208
        result[i] = text.charCodeAt(i) & 0xFF;
209
      }
210
      return result.buffer;
211
    }
212
  });
213
})();
214
215
// window.btoa (base64 encode function) ?
216
// Support: IE<10
217
(function checkWindowBtoaCompatibility() {
218
  if ('btoa' in window) {
219
    return;
220
  }
221
222
  var digits =
223
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
224
225
  window.btoa = function windowBtoa(chars) {
226
    var buffer = '';
227
    var i, n;
228
    for (i = 0, n = chars.length; i < n; i += 3) {
229
      var b1 = chars.charCodeAt(i) & 0xFF;
230
      var b2 = chars.charCodeAt(i + 1) & 0xFF;
231
      var b3 = chars.charCodeAt(i + 2) & 0xFF;
232
      var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
233
      var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
234
      var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
235
      buffer += (digits.charAt(d1) + digits.charAt(d2) +
236
                 digits.charAt(d3) + digits.charAt(d4));
237
    }
238
    return buffer;
239
  };
240
})();
241
242
// window.atob (base64 encode function)?
243
// Support: IE<10
244
(function checkWindowAtobCompatibility() {
245
  if ('atob' in window) {
246
    return;
247
  }
248
249
  // https://github.com/davidchambers/Base64.js
250
  var digits =
251
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
252
  window.atob = function (input) {
253
    input = input.replace(/=+$/, '');
254
    if (input.length % 4 === 1) {
255
      throw new Error('bad atob input');
256
    }
257
    for (
258
      // initialize result and counters
259
      var bc = 0, bs, buffer, idx = 0, output = '';
260
      // get next character
261
      buffer = input.charAt(idx++);
262
      // character found in table?
263
      // initialize bit storage and add its ascii value
264
      ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
0 ignored issues
show
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
Bug introduced by
The variable bs seems to not be initialized for all possible execution paths.
Loading history...
265
        // and if not first of each 4 characters,
266
        // convert the first 8 bits to one ascii character
267
        bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
268
    ) {
269
      // try to find character in table (0-63, not found => -1)
270
      buffer = digits.indexOf(buffer);
271
    }
272
    return output;
273
  };
274
})();
275
276
// Function.prototype.bind?
277
// Support: Android<4.0, iOS<6.0
278
(function checkFunctionPrototypeBindCompatibility() {
279
  if (typeof Function.prototype.bind !== 'undefined') {
280
    return;
281
  }
282
283
  Function.prototype.bind = function functionPrototypeBind(obj) {
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Function. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
284
    var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
285
    var bound = function functionPrototypeBindBound() {
286
      var args = headArgs.concat(Array.prototype.slice.call(arguments));
287
      return fn.apply(obj, args);
288
    };
289
    return bound;
290
  };
291
})();
292
293
// HTMLElement dataset property
294
// Support: IE<11, Safari<5.1, Android<4.0
295
(function checkDatasetProperty() {
296
  var div = document.createElement('div');
297
  if ('dataset' in div) {
298
    return; // dataset property exists
299
  }
300
301
  Object.defineProperty(HTMLElement.prototype, 'dataset', {
0 ignored issues
show
Bug introduced by
The variable HTMLElement seems to be never declared. If this is a global, consider adding a /** global: HTMLElement */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
302
    get: function() {
303
      if (this._dataset) {
304
        return this._dataset;
305
      }
306
307
      var dataset = {};
308
      for (var j = 0, jj = this.attributes.length; j < jj; j++) {
309
        var attribute = this.attributes[j];
310
        if (attribute.name.substring(0, 5) !== 'data-') {
311
          continue;
312
        }
313
        var key = attribute.name.substring(5).replace(/\-([a-z])/g,
314
          function(all, ch) {
315
            return ch.toUpperCase();
316
          });
317
        dataset[key] = attribute.value;
318
      }
319
320
      Object.defineProperty(this, '_dataset', {
321
        value: dataset,
322
        writable: false,
323
        enumerable: false
324
      });
325
      return dataset;
326
    },
327
    enumerable: true
328
  });
329
})();
330
331
// HTMLElement classList property
332
// Support: IE<10, Android<4.0, iOS<5.0
333
(function checkClassListProperty() {
334
  var div = document.createElement('div');
335
  if ('classList' in div) {
336
    return; // classList property exists
337
  }
338
339
  function changeList(element, itemName, add, remove) {
340
    var s = element.className || '';
341
    var list = s.split(/\s+/g);
342
    if (list[0] === '') {
343
      list.shift();
344
    }
345
    var index = list.indexOf(itemName);
346
    if (index < 0 && add) {
347
      list.push(itemName);
348
    }
349
    if (index >= 0 && remove) {
350
      list.splice(index, 1);
351
    }
352
    element.className = list.join(' ');
353
    return (index >= 0);
354
  }
355
356
  var classListPrototype = {
357
    add: function(name) {
358
      changeList(this.element, name, true, false);
359
    },
360
    contains: function(name) {
361
      return changeList(this.element, name, false, false);
362
    },
363
    remove: function(name) {
364
      changeList(this.element, name, false, true);
365
    },
366
    toggle: function(name) {
367
      changeList(this.element, name, true, true);
368
    }
369
  };
370
371
  Object.defineProperty(HTMLElement.prototype, 'classList', {
0 ignored issues
show
Bug introduced by
The variable HTMLElement seems to be never declared. If this is a global, consider adding a /** global: HTMLElement */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
372
    get: function() {
373
      if (this._classList) {
374
        return this._classList;
375
      }
376
377
      var classList = Object.create(classListPrototype, {
378
        element: {
379
          value: this,
380
          writable: false,
381
          enumerable: true
382
        }
383
      });
384
      Object.defineProperty(this, '_classList', {
385
        value: classList,
386
        writable: false,
387
        enumerable: false
388
      });
389
      return classList;
390
    },
391
    enumerable: true
392
  });
393
})();
394
395
// Check console compatibility
396
// In older IE versions the console object is not available
397
// unless console is open.
398
// Support: IE<10
399
(function checkConsoleCompatibility() {
400
  if (!('console' in window)) {
401
    window.console = {
402
      log: function() {},
403
      error: function() {},
404
      warn: function() {}
405
    };
406
  } else if (!('bind' in console.log)) {
407
    // native functions in IE9 might not have bind
408
    console.log = (function(fn) {
409
      return function(msg) { return fn(msg); };
410
    })(console.log);
411
    console.error = (function(fn) {
412
      return function(msg) { return fn(msg); };
413
    })(console.error);
414
    console.warn = (function(fn) {
415
      return function(msg) { return fn(msg); };
416
    })(console.warn);
417
  }
418
})();
419
420
// Check onclick compatibility in Opera
421
// Support: Opera<15
422
(function checkOnClickCompatibility() {
423
  // workaround for reported Opera bug DSK-354448:
424
  // onclick fires on disabled buttons with opaque content
425
  function ignoreIfTargetDisabled(event) {
426
    if (isDisabled(event.target)) {
427
      event.stopPropagation();
428
    }
429
  }
430
  function isDisabled(node) {
431
    return node.disabled || (node.parentNode && isDisabled(node.parentNode));
432
  }
433
  if (navigator.userAgent.indexOf('Opera') !== -1) {
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
434
    // use browser detection since we cannot feature-check this bug
435
    document.addEventListener('click', ignoreIfTargetDisabled, true);
436
  }
437
})();
438
439
// Checks if possible to use URL.createObjectURL()
440
// Support: IE
441
(function checkOnBlobSupport() {
442
  // sometimes IE loosing the data created with createObjectURL(), see #3977
443
  if (navigator.userAgent.indexOf('Trident') >= 0) {
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
444
    PDFJS.disableCreateObjectURL = true;
445
  }
446
})();
447
448
// Checks if navigator.language is supported
449
(function checkNavigatorLanguage() {
450
  if ('language' in navigator) {
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
451
    return;
452
  }
453
  PDFJS.locale = navigator.userLanguage || 'en-US';
454
})();
455
456
(function checkRangeRequests() {
457
  // Safari has issues with cached range requests see:
458
  // https://github.com/mozilla/pdf.js/issues/3260
459
  // Last tested with version 6.0.4.
460
  // Support: Safari 6.0+
461
  var isSafari = Object.prototype.toString.call(
462
                  window.HTMLElement).indexOf('Constructor') > 0;
463
464
  // Older versions of Android (pre 3.0) has issues with range requests, see:
465
  // https://github.com/mozilla/pdf.js/issues/3381.
466
  // Make sure that we only match webkit-based Android browsers,
467
  // since Firefox/Fennec works as expected.
468
  // Support: Android<3.0
469
  var regex = /Android\s[0-2][^\d]/;
470
  var isOldAndroid = regex.test(navigator.userAgent);
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
471
472
  // Range requests are broken in Chrome 39 and 40, https://crbug.com/442318
473
  var isChromeWithRangeBug = /Chrome\/(39|40)\./.test(navigator.userAgent);
474
475
  if (isSafari || isOldAndroid || isChromeWithRangeBug) {
476
    PDFJS.disableRange = true;
477
    PDFJS.disableStream = true;
478
  }
479
})();
480
481
// Check if the browser supports manipulation of the history.
482
// Support: IE<10, Android<4.2
483
(function checkHistoryManipulation() {
484
  // Android 2.x has so buggy pushState support that it was removed in
485
  // Android 3.0 and restored as late as in Android 4.2.
486
  // Support: Android 2.x
487
  if (!history.pushState || navigator.userAgent.indexOf('Android 2.') >= 0) {
0 ignored issues
show
Bug introduced by
The variable history seems to be never declared. If this is a global, consider adding a /** global: history */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
488
    PDFJS.disableHistory = true;
489
  }
490
})();
491
492
// Support: IE<11, Chrome<21, Android<4.4, Safari<6
493
(function checkSetPresenceInImageData() {
494
  // IE < 11 will use window.CanvasPixelArray which lacks set function.
495
  if (window.CanvasPixelArray) {
496
    if (typeof window.CanvasPixelArray.prototype.set !== 'function') {
497
      window.CanvasPixelArray.prototype.set = function(arr) {
498
        for (var i = 0, ii = this.length; i < ii; i++) {
499
          this[i] = arr[i];
500
        }
501
      };
502
    }
503
  } else {
504
    // Old Chrome and Android use an inaccessible CanvasPixelArray prototype.
505
    // Because we cannot feature detect it, we rely on user agent parsing.
506
    var polyfill = false, versionMatch;
507
    if (navigator.userAgent.indexOf('Chrom') >= 0) {
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
508
      versionMatch = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
509
      // Chrome < 21 lacks the set function.
510
      polyfill = versionMatch && parseInt(versionMatch[2]) < 21;
511
    } else if (navigator.userAgent.indexOf('Android') >= 0) {
512
      // Android < 4.4 lacks the set function.
513
      // Android >= 4.4 will contain Chrome in the user agent,
514
      // thus pass the Chrome check above and not reach this block.
515
      polyfill = /Android\s[0-4][^\d]/g.test(navigator.userAgent);
516
    } else if (navigator.userAgent.indexOf('Safari') >= 0) {
517
      versionMatch = navigator.userAgent.
518
        match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//);
519
      // Safari < 6 lacks the set function.
520
      polyfill = versionMatch && parseInt(versionMatch[1]) < 6;
521
    }
522
523
    if (polyfill) {
524
      var contextPrototype = window.CanvasRenderingContext2D.prototype;
525
      contextPrototype._createImageData = contextPrototype.createImageData;
526
      contextPrototype.createImageData = function(w, h) {
527
        var imageData = this._createImageData(w, h);
528
        imageData.data.set = function(arr) {
529
          for (var i = 0, ii = this.length; i < ii; i++) {
530
            this[i] = arr[i];
531
          }
532
        };
533
        return imageData;
534
      };
535
    }
536
  }
537
})();
538
539
// Support: IE<10, Android<4.0, iOS
540
(function checkRequestAnimationFrame() {
541
  function fakeRequestAnimationFrame(callback) {
542
    window.setTimeout(callback, 20);
543
  }
544
545
  var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
546
  if (isIOS) {
547
    // requestAnimationFrame on iOS is broken, replacing with fake one.
548
    window.requestAnimationFrame = fakeRequestAnimationFrame;
549
    return;
550
  }
551
  if ('requestAnimationFrame' in window) {
552
    return;
553
  }
554
  window.requestAnimationFrame =
555
    window.mozRequestAnimationFrame ||
556
    window.webkitRequestAnimationFrame ||
557
    fakeRequestAnimationFrame;
558
})();
559
560
(function checkCanvasSizeLimitation() {
561
  var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
562
  var isAndroid = /Android/g.test(navigator.userAgent);
563
  if (isIOS || isAndroid) {
564
    // 5MP
565
    PDFJS.maxCanvasPixels = 5242880;
566
  }
567
})();
568
569
// Disable fullscreen support for certain problematic configurations.
570
// Support: IE11+ (when embedded).
571
(function checkFullscreenSupport() {
572
  var isEmbeddedIE = (navigator.userAgent.indexOf('Trident') >= 0 &&
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
573
                      window.parent !== window);
574
  if (isEmbeddedIE) {
575
    PDFJS.disableFullscreen = true;
576
  }
577
})();
578