GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 4ae00e...0ca11f )
by Jesus
01:28
created

tinymce/js/bowser.js   F

Complexity

Total Complexity 170
Complexity/F 12.14

Size

Lines of Code 595
Function Count 14

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
c 1
b 0
f 0
nc 0
dl 0
loc 595
rs 1.5789
wmc 170
mnd 34
bc 95
fnc 14
bpm 6.7857
cpm 12.1428
noi 10

1 Function

Rating   Name   Duplication   Size   Complexity  
B bowser.js ➔ ?!? 0 591 3

How to fix   Complexity   

Complexity

Complex classes like tinymce/js/bowser.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
/*!
2
 * Bowser - a browser detector
3
 * https://github.com/ded/bowser
4
 * MIT License | (c) Dustin Diaz 2015
5
 */
6
7
!function (root, name, definition) {
8
  if (typeof module != 'undefined' && module.exports) module.exports = definition()
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
9
  else if (typeof define == 'function' && define.amd) define(name, definition)
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ 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...
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
10
  else root[name] = definition()
11
}(this, 'bowser', function () {
12
  /**
13
    * See useragents.js for examples of navigator.userAgent
14
    */
15
16
  var t = true
17
18
  function detect(ua) {
19
20
    function getFirstMatch(regex) {
21
      var match = ua.match(regex);
22
      return (match && match.length > 1 && match[1]) || '';
23
    }
24
25
    function getSecondMatch(regex) {
26
      var match = ua.match(regex);
27
      return (match && match.length > 1 && match[2]) || '';
28
    }
29
30
    var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()
31
      , likeAndroid = /like android/i.test(ua)
32
      , android = !likeAndroid && /android/i.test(ua)
33
      , nexusMobile = /nexus\s*[0-6]\s*/i.test(ua)
34
      , nexusTablet = !nexusMobile && /nexus\s*[0-9]+/i.test(ua)
35
      , chromeos = /CrOS/.test(ua)
36
      , silk = /silk/i.test(ua)
37
      , sailfish = /sailfish/i.test(ua)
38
      , tizen = /tizen/i.test(ua)
39
      , webos = /(web|hpw)os/i.test(ua)
40
      , windowsphone = /windows phone/i.test(ua)
41
      , samsungBrowser = /SamsungBrowser/i.test(ua)
42
      , windows = !windowsphone && /windows/i.test(ua)
43
      , mac = !iosdevice && !silk && /macintosh/i.test(ua)
44
      , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua)
45
      , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i)
46
      , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i)
47
      , tablet = /tablet/i.test(ua)
48
      , mobile = !tablet && /[^-]mobi/i.test(ua)
49
      , xbox = /xbox/i.test(ua)
50
      , result
51
52
    if (/opera/i.test(ua)) {
53
      //  an old Opera
54
      result = {
55
        name: 'Opera'
56
      , opera: t
57
      , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i)
58
      }
59
    } else if (/opr|opios/i.test(ua)) {
60
      // a new Opera
61
      result = {
62
        name: 'Opera'
63
        , opera: t
64
        , version: getFirstMatch(/(?:opr|opios)[\s\/](\d+(\.\d+)?)/i) || versionIdentifier
65
      }
66
    }
67
    else if (/SamsungBrowser/i.test(ua)) {
68
      result = {
69
        name: 'Samsung Internet for Android'
70
        , samsungBrowser: t
71
        , version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\s\/](\d+(\.\d+)?)/i)
72
      }
73
    }
74
    else if (/coast/i.test(ua)) {
75
      result = {
76
        name: 'Opera Coast'
77
        , coast: t
78
        , version: versionIdentifier || getFirstMatch(/(?:coast)[\s\/](\d+(\.\d+)?)/i)
79
      }
80
    }
81
    else if (/yabrowser/i.test(ua)) {
82
      result = {
83
        name: 'Yandex Browser'
84
      , yandexbrowser: t
85
      , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)
86
      }
87
    }
88
    else if (/ucbrowser/i.test(ua)) {
89
      result = {
90
          name: 'UC Browser'
91
        , ucbrowser: t
92
        , version: getFirstMatch(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i)
93
      }
94
    }
95
    else if (/mxios/i.test(ua)) {
96
      result = {
97
        name: 'Maxthon'
98
        , maxthon: t
99
        , version: getFirstMatch(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i)
100
      }
101
    }
102
    else if (/epiphany/i.test(ua)) {
103
      result = {
104
        name: 'Epiphany'
105
        , epiphany: t
106
        , version: getFirstMatch(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i)
107
      }
108
    }
109
    else if (/puffin/i.test(ua)) {
110
      result = {
111
        name: 'Puffin'
112
        , puffin: t
113
        , version: getFirstMatch(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i)
114
      }
115
    }
116
    else if (/sleipnir/i.test(ua)) {
117
      result = {
118
        name: 'Sleipnir'
119
        , sleipnir: t
120
        , version: getFirstMatch(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i)
121
      }
122
    }
123
    else if (/k-meleon/i.test(ua)) {
124
      result = {
125
        name: 'K-Meleon'
126
        , kMeleon: t
127
        , version: getFirstMatch(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i)
128
      }
129
    }
130
    else if (windowsphone) {
131
      result = {
132
        name: 'Windows Phone'
133
      , windowsphone: t
134
      }
135
      if (edgeVersion) {
136
        result.msedge = t
137
        result.version = edgeVersion
138
      }
139
      else {
140
        result.msie = t
141
        result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
142
      }
143
    }
144
    else if (/msie|trident/i.test(ua)) {
145
      result = {
146
        name: 'Internet Explorer'
147
      , msie: t
148
      , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i)
149
      }
150
    } else if (chromeos) {
151
      result = {
152
        name: 'Chrome'
153
      , chromeos: t
154
      , chromeBook: t
155
      , chrome: t
156
      , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
157
      }
158
    } else if (/chrome.+? edge/i.test(ua)) {
159
      result = {
160
        name: 'Microsoft Edge'
161
      , msedge: t
162
      , version: edgeVersion
163
      }
164
    }
165
    else if (/vivaldi/i.test(ua)) {
166
      result = {
167
        name: 'Vivaldi'
168
        , vivaldi: t
169
        , version: getFirstMatch(/vivaldi\/(\d+(\.\d+)?)/i) || versionIdentifier
170
      }
171
    }
172
    else if (sailfish) {
173
      result = {
174
        name: 'Sailfish'
175
      , sailfish: t
176
      , version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i)
177
      }
178
    }
179
    else if (/seamonkey\//i.test(ua)) {
180
      result = {
181
        name: 'SeaMonkey'
182
      , seamonkey: t
183
      , version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i)
184
      }
185
    }
186
    else if (/firefox|iceweasel|fxios/i.test(ua)) {
187
      result = {
188
        name: 'Firefox'
189
      , firefox: t
190
      , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i)
191
      }
192
      if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) {
193
        result.firefoxos = t
194
      }
195
    }
196
    else if (silk) {
197
      result =  {
198
        name: 'Amazon Silk'
199
      , silk: t
200
      , version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i)
201
      }
202
    }
203
    else if (/phantom/i.test(ua)) {
204
      result = {
205
        name: 'PhantomJS'
206
      , phantom: t
207
      , version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i)
208
      }
209
    }
210
    else if (/slimerjs/i.test(ua)) {
211
      result = {
212
        name: 'SlimerJS'
213
        , slimer: t
214
        , version: getFirstMatch(/slimerjs\/(\d+(\.\d+)?)/i)
215
      }
216
    }
217
    else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) {
218
      result = {
219
        name: 'BlackBerry'
220
      , blackberry: t
221
      , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
222
      }
223
    }
224
    else if (webos) {
225
      result = {
226
        name: 'WebOS'
227
      , webos: t
228
      , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)
229
      };
230
      /touchpad\//i.test(ua) && (result.touchpad = t)
231
    }
232
    else if (/bada/i.test(ua)) {
233
      result = {
234
        name: 'Bada'
235
      , bada: t
236
      , version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i)
237
      };
238
    }
239
    else if (tizen) {
240
      result = {
241
        name: 'Tizen'
242
      , tizen: t
243
      , version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier
244
      };
245
    }
246
    else if (/qupzilla/i.test(ua)) {
247
      result = {
248
        name: 'QupZilla'
249
        , qupzilla: t
250
        , version: getFirstMatch(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || versionIdentifier
251
      }
252
    }
253
    else if (/chromium/i.test(ua)) {
254
      result = {
255
        name: 'Chromium'
256
        , chromium: t
257
        , version: getFirstMatch(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || versionIdentifier
258
      }
259
    }
260
    else if (/chrome|crios|crmo/i.test(ua)) {
261
      result = {
262
        name: 'Chrome'
263
        , chrome: t
264
        , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
265
      }
266
    }
267
    else if (android) {
268
      result = {
269
        name: 'Android'
270
        , version: versionIdentifier
271
      }
272
    }
273
    else if (/safari|applewebkit/i.test(ua)) {
274
      result = {
275
        name: 'Safari'
276
      , safari: t
277
      }
278
      if (versionIdentifier) {
279
        result.version = versionIdentifier
280
      }
281
    }
282
    else if (iosdevice) {
283
      result = {
284
        name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'
285
      }
286
      // WTF: version is not part of user agent in web apps
287
      if (versionIdentifier) {
288
        result.version = versionIdentifier
289
      }
290
    }
291
    else if(/googlebot/i.test(ua)) {
292
      result = {
293
        name: 'Googlebot'
294
      , googlebot: t
295
      , version: getFirstMatch(/googlebot\/(\d+(\.\d+))/i) || versionIdentifier
296
      }
297
    }
298
    else {
299
      result = {
300
        name: getFirstMatch(/^(.*)\/(.*) /),
301
        version: getSecondMatch(/^(.*)\/(.*) /)
302
     };
303
   }
304
305
    // set webkit or gecko flag for browsers based on these engines
306
    if (!result.msedge && /(apple)?webkit/i.test(ua)) {
307
      if (/(apple)?webkit\/537\.36/i.test(ua)) {
308
        result.name = result.name || "Blink"
309
        result.blink = t
310
      } else {
311
        result.name = result.name || "Webkit"
312
        result.webkit = t
313
      }
314
      if (!result.version && versionIdentifier) {
315
        result.version = versionIdentifier
316
      }
317
    } else if (!result.opera && /gecko\//i.test(ua)) {
318
      result.name = result.name || "Gecko"
319
      result.gecko = t
320
      result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i)
321
    }
322
323
    // set OS flags for platforms that have multiple browsers
324
    if (!result.windowsphone && !result.msedge && (android || result.silk)) {
325
      result.android = t
326
    } else if (!result.windowsphone && !result.msedge && iosdevice) {
327
      result[iosdevice] = t
328
      result.ios = t
329
    } else if (mac) {
330
      result.mac = t
331
    } else if (xbox) {
332
      result.xbox = t
333
    } else if (windows) {
334
      result.windows = t
335
    } else if (linux) {
336
      result.linux = t
337
    }
338
339
    function getWindowsVersion (s) {
340
      switch (s) {
341
        case 'NT': return 'NT'
342
        case 'XP': return 'XP'
343
        case 'NT 5.0': return '2000'
344
        case 'NT 5.1': return 'XP'
345
        case 'NT 5.2': return '2003'
346
        case 'NT 6.0': return 'Vista'
347
        case 'NT 6.1': return '7'
348
        case 'NT 6.2': return '8'
349
        case 'NT 6.3': return '8.1'
350
        case 'NT 10.0': return '10'
351
        default: return undefined
352
      }
353
    }
354
    
355
    // OS version extraction
356
    var osVersion = '';
357
    if (result.windows) {
358
      osVersion = getWindowsVersion(getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i))
359
    } else if (result.windowsphone) {
360
      osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
361
    } else if (result.mac) {
362
      osVersion = getFirstMatch(/Mac OS X (\d+([_\.\s]\d+)*)/i);
363
      osVersion = osVersion.replace(/[_\s]/g, '.');
364
    } else if (iosdevice) {
365
      osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
366
      osVersion = osVersion.replace(/[_\s]/g, '.');
367
    } else if (android) {
368
      osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i);
369
    } else if (result.webos) {
370
      osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
371
    } else if (result.blackberry) {
372
      osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i);
373
    } else if (result.bada) {
374
      osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i);
375
    } else if (result.tizen) {
376
      osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i);
377
    }
378
    if (osVersion) {
379
      result.osversion = osVersion;
380
    }
381
382
    // device type extraction
383
    var osMajorVersion = !result.windows && osVersion.split('.')[0];
384
    if (
385
         tablet
386
      || nexusTablet
387
      || iosdevice == 'ipad'
388
      || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile)))
389
      || result.silk
390
    ) {
391
      result.tablet = t
392
    } else if (
393
         mobile
394
      || iosdevice == 'iphone'
395
      || iosdevice == 'ipod'
396
      || android
397
      || nexusMobile
398
      || result.blackberry
399
      || result.webos
400
      || result.bada
401
    ) {
402
      result.mobile = t
403
    }
404
405
    // Graded Browser Support
406
    // http://developer.yahoo.com/yui/articles/gbs
407
    if (result.msedge ||
408
        (result.msie && result.version >= 10) ||
409
        (result.yandexbrowser && result.version >= 15) ||
410
		    (result.vivaldi && result.version >= 1.0) ||
411
        (result.chrome && result.version >= 20) ||
412
        (result.samsungBrowser && result.version >= 4) ||
413
        (result.firefox && result.version >= 20.0) ||
414
        (result.safari && result.version >= 6) ||
415
        (result.opera && result.version >= 10.0) ||
416
        (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) ||
417
        (result.blackberry && result.version >= 10.1)
418
        || (result.chromium && result.version >= 20)
419
        ) {
420
      result.a = t;
421
    }
422
    else if ((result.msie && result.version < 10) ||
423
        (result.chrome && result.version < 20) ||
424
        (result.firefox && result.version < 20.0) ||
425
        (result.safari && result.version < 6) ||
426
        (result.opera && result.version < 10.0) ||
427
        (result.ios && result.osversion && result.osversion.split(".")[0] < 6)
428
        || (result.chromium && result.version < 20)
429
        ) {
430
      result.c = t
431
    } else result.x = t
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
432
433
    return result
434
  }
435
436
  var bowser = detect(typeof navigator !== 'undefined' ? 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...
437
438
  bowser.test = function (browserList) {
439
    for (var i = 0; i < browserList.length; ++i) {
440
      var browserItem = browserList[i];
441
      if (typeof browserItem=== 'string') {
442
        if (browserItem in bowser) {
443
          return true;
444
        }
445
      }
446
    }
447
    return false;
448
  }
449
450
  /**
451
   * Get version precisions count
452
   *
453
   * @example
454
   *   getVersionPrecision("1.10.3") // 3
455
   *
456
   * @param  {string} version
457
   * @return {number}
458
   */
459
  function getVersionPrecision(version) {
460
    return version.split(".").length;
461
  }
462
463
  /**
464
   * Array::map polyfill
465
   *
466
   * @param  {Array} arr
467
   * @param  {Function} iterator
468
   * @return {Array}
469
   */
470
  function map(arr, iterator) {
471
    var result = [], i;
472
    if (Array.prototype.map) {
473
      return Array.prototype.map.call(arr, iterator);
474
    }
475
    for (i = 0; i < arr.length; i++) {
476
      result.push(iterator(arr[i]));
477
    }
478
    return result;
479
  }
480
481
  /**
482
   * Calculate browser version weight
483
   *
484
   * @example
485
   *   compareVersions(['1.10.2.1',  '1.8.2.1.90'])    // 1
486
   *   compareVersions(['1.010.2.1', '1.09.2.1.90']);  // 1
487
   *   compareVersions(['1.10.2.1',  '1.10.2.1']);     // 0
488
   *   compareVersions(['1.10.2.1',  '1.0800.2']);     // -1
489
   *
490
   * @param  {Array<String>} versions versions to compare
491
   * @return {Number} comparison result
492
   */
493
  function compareVersions(versions) {
494
    // 1) get common precision for both versions, for example for "10.0" and "9" it should be 2
495
    var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1]));
496
    var chunks = map(versions, function (version) {
497
      var delta = precision - getVersionPrecision(version);
498
499
      // 2) "9" -> "9.0" (for precision = 2)
500
      version = version + new Array(delta + 1).join(".0");
501
502
      // 3) "9.0" -> ["000000000"", "000000009"]
503
      return map(version.split("."), function (chunk) {
504
        return new Array(20 - chunk.length).join("0") + chunk;
505
      }).reverse();
506
    });
507
508
    // iterate in reverse order by reversed chunks array
509
    while (--precision >= 0) {
510
      // 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true)
511
      if (chunks[0][precision] > chunks[1][precision]) {
512
        return 1;
513
      }
514
      else if (chunks[0][precision] === chunks[1][precision]) {
515
        if (precision === 0) {
516
          // all version chunks are same
517
          return 0;
518
        }
519
      }
520
      else {
521
        return -1;
522
      }
523
    }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
524
  }
525
526
  /**
527
   * Check if browser is unsupported
528
   *
529
   * @example
530
   *   bowser.isUnsupportedBrowser({
531
   *     msie: "10",
532
   *     firefox: "23",
533
   *     chrome: "29",
534
   *     safari: "5.1",
535
   *     opera: "16",
536
   *     phantom: "534"
537
   *   });
538
   *
539
   * @param  {Object}  minVersions map of minimal version to browser
540
   * @param  {Boolean} [strictMode = false] flag to return false if browser wasn't found in map
0 ignored issues
show
Documentation Bug introduced by
The parameter [strictMode does not exist. Did you maybe mean strictMode instead?
Loading history...
541
   * @param  {String}  [ua] user agent string
542
   * @return {Boolean}
543
   */
544
  function isUnsupportedBrowser(minVersions, strictMode, ua) {
545
    var _bowser = bowser;
546
547
    // make strictMode param optional with ua param usage
548
    if (typeof strictMode === 'string') {
549
      ua = strictMode;
550
      strictMode = void(0);
0 ignored issues
show
Coding Style introduced by
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
551
    }
552
553
    if (strictMode === void(0)) {
0 ignored issues
show
Coding Style introduced by
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
554
      strictMode = false;
555
    }
556
    if (ua) {
557
      _bowser = detect(ua);
558
    }
559
560
    var version = "" + _bowser.version;
561
    for (var browser in minVersions) {
562
      if (minVersions.hasOwnProperty(browser)) {
563
        if (_bowser[browser]) {
564
          if (typeof minVersions[browser] !== 'string') {
565
            throw new Error('Browser version in the minVersion map should be a string: ' + browser + ': ' + String(minVersions));
566
          }
567
568
          // browser version and min supported version.
569
          return compareVersions([version, minVersions[browser]]) < 0;
570
        }
571
      }
572
    }
573
574
    return strictMode; // not found
575
  }
576
577
  /**
578
   * Check if browser is supported
579
   *
580
   * @param  {Object} minVersions map of minimal version to browser
581
   * @param  {Boolean} [strictMode = false] flag to return false if browser wasn't found in map
0 ignored issues
show
Documentation Bug introduced by
The parameter [strictMode does not exist. Did you maybe mean strictMode instead?
Loading history...
582
   * @param  {String}  [ua] user agent string
583
   * @return {Boolean}
584
   */
585
  function check(minVersions, strictMode, ua) {
586
    return !isUnsupportedBrowser(minVersions, strictMode, ua);
587
  }
588
589
  bowser.isUnsupportedBrowser = isUnsupportedBrowser;
590
  bowser.compareVersions = compareVersions;
591
  bowser.check = check;
592
593
  /*
594
   * Set our detect method to the main bowser object so we can
595
   * reuse it to test other user agents.
596
   * This is needed to implement future tests.
597
   */
598
  bowser._detect = detect;
599
600
  return bowser
601
});
602