@urso/core 0.8.20-dev → 0.9.0-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +227 -227
  3. package/build/js/index.js +77216 -2
  4. package/package.json +36 -50
  5. package/src/js/app.js +105 -104
  6. package/src/js/components/base/controller.js +76 -78
  7. package/src/js/components/debug/controller.js +39 -39
  8. package/src/js/components/debug/coords.js +23 -23
  9. package/src/js/components/debug/fps.js +36 -36
  10. package/src/js/components/debug/template.js +55 -55
  11. package/src/js/components/debug/timescale.js +60 -60
  12. package/src/js/components/deviceRotate/controller.js +95 -95
  13. package/src/js/components/editor/api.js +127 -127
  14. package/src/js/components/editor/controller.js +13 -13
  15. package/src/js/components/fullscreen/android.js +104 -104
  16. package/src/js/components/fullscreen/controller.js +76 -76
  17. package/src/js/components/fullscreen/desktop.js +49 -49
  18. package/src/js/components/fullscreen/ios.js +115 -115
  19. package/src/js/components/layersSwitcher/config.js +26 -26
  20. package/src/js/components/layersSwitcher/controller.js +36 -36
  21. package/src/js/components/loader/controller.js +66 -66
  22. package/src/js/components/loader/template.js +71 -71
  23. package/src/js/components/soundInitialPopup/controller.js +43 -43
  24. package/src/js/components/soundInitialPopup/template.js +110 -110
  25. package/src/js/components/stateDriven/controller.js +123 -123
  26. package/src/js/config/load.js +325 -194
  27. package/src/js/config/main.js +17 -17
  28. package/src/js/extra/browserEvents.js +57 -57
  29. package/src/js/extra/main.js +23 -25
  30. package/src/js/extra/pixiPatch.js +173 -171
  31. package/src/js/index.js +7 -7
  32. package/src/js/lib/cache.js +199 -125
  33. package/src/js/lib/composition.js +85 -85
  34. package/src/js/lib/device.js +1215 -1215
  35. package/src/js/lib/helper.js +678 -678
  36. package/src/js/lib/loader.js +216 -218
  37. package/src/js/lib/localData.js +29 -29
  38. package/src/js/lib/logger.js +69 -69
  39. package/src/js/lib/math.js +161 -161
  40. package/src/js/lib/objectPool.js +208 -208
  41. package/src/js/lib/time.js +19 -19
  42. package/src/js/lib/tween.js +153 -153
  43. package/src/js/modules/assets/baseModel.js +21 -21
  44. package/src/js/modules/assets/config.js +38 -38
  45. package/src/js/modules/assets/controller.js +65 -65
  46. package/src/js/modules/assets/models/atlas.js +19 -19
  47. package/src/js/modules/assets/models/audiosprite.js +28 -28
  48. package/src/js/modules/assets/models/bitmapFont.js +11 -11
  49. package/src/js/modules/assets/models/container.js +19 -19
  50. package/src/js/modules/assets/models/font.js +11 -11
  51. package/src/js/modules/assets/models/html.js +11 -11
  52. package/src/js/modules/assets/models/image.js +17 -17
  53. package/src/js/modules/assets/models/json.js +11 -11
  54. package/src/js/modules/assets/models/jsonAtlas.js +11 -11
  55. package/src/js/modules/assets/models/sound.js +17 -17
  56. package/src/js/modules/assets/models/spine.js +18 -17
  57. package/src/js/modules/assets/models/spineAtlas.js +11 -0
  58. package/src/js/modules/assets/service.js +564 -553
  59. package/src/js/modules/i18n/config.js +17 -17
  60. package/src/js/modules/i18n/controller.js +71 -71
  61. package/src/js/modules/instances/controller.js +357 -357
  62. package/src/js/modules/logic/config/sounds.js +23 -23
  63. package/src/js/modules/logic/controller.js +52 -52
  64. package/src/js/modules/logic/main.js +8 -8
  65. package/src/js/modules/logic/sounds.js +103 -103
  66. package/src/js/modules/objects/baseModel.js +205 -207
  67. package/src/js/modules/objects/cache.js +99 -99
  68. package/src/js/modules/objects/config.js +10 -10
  69. package/src/js/modules/objects/controller.js +139 -139
  70. package/src/js/modules/objects/find.js +58 -58
  71. package/src/js/modules/objects/models/bitmapText.js +56 -49
  72. package/src/js/modules/objects/models/button.js +208 -209
  73. package/src/js/modules/objects/models/buttonComposite.js +38 -38
  74. package/src/js/modules/objects/models/checkbox.js +100 -100
  75. package/src/js/modules/objects/models/collection.js +56 -54
  76. package/src/js/modules/objects/models/component.js +48 -48
  77. package/src/js/modules/objects/models/container.js +22 -22
  78. package/src/js/modules/objects/models/emitterFx.js +103 -114
  79. package/src/js/modules/objects/models/graphics.js +40 -40
  80. package/src/js/modules/objects/models/group.js +22 -22
  81. package/src/js/modules/objects/models/hitArea.js +187 -187
  82. package/src/js/modules/objects/models/image.js +36 -36
  83. package/src/js/modules/objects/models/imagesAnimation.js +115 -115
  84. package/src/js/modules/objects/models/mask.js +40 -40
  85. package/src/js/modules/objects/models/nineSlicePlane.js +32 -32
  86. package/src/js/modules/objects/models/slider.js +357 -357
  87. package/src/js/modules/objects/models/spine.js +354 -339
  88. package/src/js/modules/objects/models/text.js +70 -70
  89. package/src/js/modules/objects/models/toggle.js +186 -186
  90. package/src/js/modules/objects/models/world.js +22 -22
  91. package/src/js/modules/objects/pool.js +68 -68
  92. package/src/js/modules/objects/propertyAdapter.js +592 -592
  93. package/src/js/modules/objects/proxy.js +299 -298
  94. package/src/js/modules/objects/selector.js +136 -136
  95. package/src/js/modules/objects/service.js +255 -254
  96. package/src/js/modules/objects/styles.js +210 -210
  97. package/src/js/modules/observer/controller.js +168 -168
  98. package/src/js/modules/observer/events.js +51 -56
  99. package/src/js/modules/scenes/controller.js +126 -127
  100. package/src/js/modules/scenes/model.js +28 -28
  101. package/src/js/modules/scenes/pixiWrapper.js +359 -351
  102. package/src/js/modules/scenes/resolutions.js +173 -173
  103. package/src/js/modules/scenes/resolutionsConfig.js +73 -73
  104. package/src/js/modules/scenes/service.js +144 -146
  105. package/src/js/modules/soundManager/controller.js +103 -103
  106. package/src/js/modules/soundManager/soundSprite.js +314 -314
  107. package/src/js/modules/statesManager/action.js +97 -97
  108. package/src/js/modules/statesManager/all.js +23 -23
  109. package/src/js/modules/statesManager/configStates.js +77 -77
  110. package/src/js/modules/statesManager/controller.js +219 -219
  111. package/src/js/modules/statesManager/functionsStorage.js +83 -83
  112. package/src/js/modules/statesManager/helper.js +27 -27
  113. package/src/js/modules/statesManager/race.js +91 -91
  114. package/src/js/modules/statesManager/sequence.js +48 -48
  115. package/src/js/modules/template/controller.js +28 -28
  116. package/src/js/modules/template/model.js +11 -11
  117. package/src/js/modules/template/service.js +137 -137
  118. package/src/js/modules/template/types.js +50 -49
  119. package/src/js/modules/transport/baseConnectionType.js +25 -25
  120. package/src/js/modules/transport/config.js +13 -13
  121. package/src/js/modules/transport/connectionTypes/websocket.js +77 -77
  122. package/src/js/modules/transport/connectionTypes/xhr.js +47 -47
  123. package/src/js/modules/transport/controller.js +48 -48
  124. package/src/js/modules/transport/decorator.js +17 -17
  125. package/src/js/modules/transport/service.js +150 -150
  126. package/vite.config.js +31 -0
  127. package/.babelrc +0 -12
  128. package/build/js/index.js.LICENSE.txt +0 -227
  129. package/src/js/modules/objects/models/atlasImage.js +0 -52
  130. package/src/js/modules/objects/models/dragContainer.js +0 -665
  131. package/src/js/modules/objects/models/emitter.js +0 -69
  132. package/src/js/modules/objects/models/scrollbox.js +0 -67
  133. package/src/js/modules/objects/models/textInput.js +0 -68
  134. package/webpack.config.js +0 -47
@@ -1,1215 +1,1215 @@
1
- let LibDevice = function () {
2
-
3
- /**
4
- * The time the device became ready.
5
- * @property {integer} deviceReadyAt
6
- * @protected
7
- */
8
- this.deviceReadyAt = 0;
9
-
10
- /**
11
- * The time as which initialization has completed.
12
- * @property {boolean} initialized
13
- * @protected
14
- */
15
- this.initialized = false;
16
-
17
- // Browser / Host / Operating System
18
-
19
- /**
20
- * @property {boolean} desktop - Is running on a desktop?
21
- * @default
22
- */
23
- this.desktop = false;
24
-
25
- /**
26
- * @property {boolean} iOS - Is running on iOS?
27
- * @default
28
- */
29
- this.iOS = false;
30
-
31
- /**
32
- * @property {boolean} cocoonJS - Is the game running under CocoonJS?
33
- * @default
34
- */
35
- this.cocoonJS = false;
36
-
37
- /**
38
- * @property {boolean} cocoonJSApp - Is this game running with CocoonJS.App?
39
- * @default
40
- */
41
- this.cocoonJSApp = false;
42
-
43
- /**
44
- * @property {boolean} cordova - Is the game running under Apache Cordova?
45
- * @default
46
- */
47
- this.cordova = false;
48
-
49
- /**
50
- * @property {boolean} node - Is the game running under Node.js?
51
- * @default
52
- */
53
- this.node = false;
54
-
55
- /**
56
- * @property {boolean} nodeWebkit - Is the game running under Node-Webkit?
57
- * @default
58
- */
59
- this.nodeWebkit = false;
60
-
61
- /**
62
- * @property {boolean} electron - Is the game running under GitHub Electron?
63
- * @default
64
- */
65
- this.electron = false;
66
-
67
- /**
68
- * @property {boolean} ejecta - Is the game running under Ejecta?
69
- * @default
70
- */
71
- this.ejecta = false;
72
-
73
- /**
74
- * @property {boolean} crosswalk - Is the game running under the Intel Crosswalk XDK?
75
- * @default
76
- */
77
- this.crosswalk = false;
78
-
79
- /**
80
- * @property {boolean} android - Is running on android?
81
- * @default
82
- */
83
- this.android = false;
84
-
85
- /**
86
- * @property {boolean} chromeOS - Is running on chromeOS?
87
- * @default
88
- */
89
- this.chromeOS = false;
90
-
91
- /**
92
- * @property {boolean} linux - Is running on linux?
93
- * @default
94
- */
95
- this.linux = false;
96
-
97
- /**
98
- * @property {boolean} macOS - Is running on macOS?
99
- * @default
100
- */
101
- this.macOS = false;
102
-
103
- /**
104
- * @property {boolean} windows - Is running on windows?
105
- * @default
106
- */
107
- this.windows = false;
108
-
109
- /**
110
- * @property {boolean} windowsPhone - Is running on a Windows Phone?
111
- * @default
112
- */
113
- this.windowsPhone = false;
114
-
115
- // Features
116
-
117
- /**
118
- * @property {boolean} canvas - Is canvas available?
119
- * @default
120
- */
121
- this.canvas = false;
122
-
123
- /**
124
- * @property {?boolean} canvasBitBltShift - True if canvas supports a 'copy' bitblt onto itself when the source and destination regions overlap.
125
- * @default
126
- */
127
- this.canvasBitBltShift = null;
128
-
129
- /**
130
- * @property {boolean} webGL - Is webGL available?
131
- * @default
132
- */
133
- this.webGL = false;
134
-
135
- /**
136
- * @property {boolean} file - Is file available?
137
- * @default
138
- */
139
- this.file = false;
140
-
141
- /**
142
- * @property {boolean} fileSystem - Is fileSystem available?
143
- * @default
144
- */
145
- this.fileSystem = false;
146
-
147
- /**
148
- * @property {boolean} localStorage - Is localStorage available?
149
- * @default
150
- */
151
- this.localStorage = false;
152
-
153
- /**
154
- * @property {boolean} worker - Is worker available?
155
- * @default
156
- */
157
- this.worker = false;
158
-
159
- /**
160
- * @property {boolean} css3D - Is css3D available?
161
- * @default
162
- */
163
- this.css3D = false;
164
-
165
- /**
166
- * @property {boolean} pointerLock - Is Pointer Lock available?
167
- * @default
168
- */
169
- this.pointerLock = false;
170
-
171
- /**
172
- * @property {boolean} typedArray - Does the browser support TypedArrays?
173
- * @default
174
- */
175
- this.typedArray = false;
176
-
177
- /**
178
- * @property {boolean} vibration - Does the device support the Vibration API?
179
- * @default
180
- */
181
- this.vibration = false;
182
-
183
- /**
184
- * @property {boolean} getUserMedia - Does the device support the getUserMedia API?
185
- * @default
186
- */
187
- this.getUserMedia = true;
188
-
189
- /**
190
- * @property {boolean} quirksMode - Is the browser running in strict mode (false) or quirks mode? (true)
191
- * @default
192
- */
193
- this.quirksMode = false;
194
-
195
- /**
196
- * @property {boolean} webP - Is the browser support webP
197
- * @default
198
- */
199
- this.webP = false;
200
-
201
- /**
202
- * @property {boolean} _webPTestComplete - Is the webP test complete
203
- * @default
204
- */
205
- this._webPTestComplete = false;
206
-
207
- // Input
208
-
209
- /**
210
- * @property {boolean} touch - Is touch available?
211
- * @default
212
- */
213
- this.touch = false;
214
-
215
- /**
216
- * @property {boolean} mspointer - Is mspointer available?
217
- * @default
218
- */
219
- this.mspointer = false;
220
-
221
- /**
222
- * @property {?string} wheelType - The newest type of Wheel/Scroll event supported: 'wheel', 'mousewheel', 'DOMMouseScroll'
223
- * @default
224
- * @protected
225
- */
226
- this.wheelEvent = null;
227
-
228
- // Browser
229
-
230
- /**
231
- * @property {boolean} arora - Set to true if running in Arora.
232
- * @default
233
- */
234
- this.arora = false;
235
-
236
- /**
237
- * @property {boolean} chrome - Set to true if running in Chrome.
238
- * @default
239
- */
240
- this.chrome = false;
241
-
242
- /**
243
- * @property {number} chromeVersion - If running in Chrome this will contain the major version number.
244
- * @default
245
- */
246
- this.chromeVersion = 0;
247
-
248
- /**
249
- * @property {boolean} epiphany - Set to true if running in Epiphany.
250
- * @default
251
- */
252
- this.epiphany = false;
253
-
254
- /**
255
- * @property {boolean} firefox - Set to true if running in Firefox.
256
- * @default
257
- */
258
- this.firefox = false;
259
-
260
- /**
261
- * @property {number} firefoxVersion - If running in Firefox this will contain the major version number.
262
- * @default
263
- */
264
- this.firefoxVersion = 0;
265
-
266
- /**
267
- * @property {boolean} ie - Set to true if running in Internet Explorer.
268
- * @default
269
- */
270
- this.ie = false;
271
-
272
- /**
273
- * @property {number} ieVersion - If running in Internet Explorer this will contain the major version number. Beyond IE10 you should use Device.trident and Device.tridentVersion.
274
- * @default
275
- */
276
- this.ieVersion = 0;
277
-
278
- /**
279
- * @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+)
280
- * @default
281
- */
282
- this.trident = false;
283
-
284
- /**
285
- * @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See {@link http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx}
286
- * @default
287
- */
288
- this.tridentVersion = 0;
289
-
290
- /**
291
- * @property {boolean} mobileSafari - Set to true if running in Mobile Safari.
292
- * @default
293
- */
294
- this.mobileSafari = false;
295
-
296
- /**
297
- * @property {boolean} midori - Set to true if running in Midori.
298
- * @default
299
- */
300
- this.midori = false;
301
-
302
- /**
303
- * @property {boolean} opera - Set to true if running in Opera.
304
- * @default
305
- */
306
- this.opera = false;
307
-
308
- /**
309
- * @property {boolean} safari - Set to true if running in Safari.
310
- * @default
311
- */
312
- this.safari = false;
313
-
314
- /**
315
- * @property {boolean} webApp - Set to true if running as a WebApp, i.e. within a WebView
316
- * @default
317
- */
318
- this.webApp = false;
319
-
320
- /**
321
- * @property {boolean} silk - Set to true if running in the Silk browser (as used on the Amazon Kindle)
322
- * @default
323
- */
324
- this.silk = false;
325
-
326
- // Audio
327
-
328
- /**
329
- * @property {boolean} audioData - Are Audio tags available?
330
- * @default
331
- */
332
- this.audioData = false;
333
-
334
- /**
335
- * @property {boolean} webAudio - Is the WebAudio API available?
336
- * @default
337
- */
338
- this.webAudio = false;
339
-
340
- /**
341
- * @property {boolean} ogg - Can this device play ogg files?
342
- * @default
343
- */
344
- this.ogg = false;
345
-
346
- /**
347
- * @property {boolean} opus - Can this device play opus files?
348
- * @default
349
- */
350
- this.opus = false;
351
-
352
- /**
353
- * @property {boolean} mp3 - Can this device play mp3 files?
354
- * @default
355
- */
356
- this.mp3 = false;
357
-
358
- /**
359
- * @property {boolean} wav - Can this device play wav files?
360
- * @default
361
- */
362
- this.wav = false;
363
-
364
- /**
365
- * Can this device play m4a files?
366
- * @property {boolean} m4a - True if this device can play m4a files.
367
- * @default
368
- */
369
- this.m4a = false;
370
-
371
- /**
372
- * @property {boolean} webm - Can this device play webm files?
373
- * @default
374
- */
375
- this.webm = false;
376
-
377
- // Video
378
-
379
- /**
380
- * @property {boolean} oggVideo - Can this device play ogg video files?
381
- * @default
382
- */
383
- this.oggVideo = false;
384
-
385
- /**
386
- * @property {boolean} h264Video - Can this device play h264 mp4 video files?
387
- * @default
388
- */
389
- this.h264Video = false;
390
-
391
- /**
392
- * @property {boolean} mp4Video - Can this device play h264 mp4 video files?
393
- * @default
394
- */
395
- this.mp4Video = false;
396
-
397
- /**
398
- * @property {boolean} webmVideo - Can this device play webm video files?
399
- * @default
400
- */
401
- this.webmVideo = false;
402
-
403
- /**
404
- * @property {boolean} vp9Video - Can this device play vp9 video files?
405
- * @default
406
- */
407
- this.vp9Video = false;
408
-
409
- /**
410
- * @property {boolean} hlsVideo - Can this device play hls video files?
411
- * @default
412
- */
413
- this.hlsVideo = false;
414
-
415
- // Device
416
-
417
- /**
418
- * @property {boolean} iPhone - Is running on iPhone?
419
- * @default
420
- */
421
- this.iPhone = false;
422
-
423
- /**
424
- * @property {boolean} iPhone4 - Is running on iPhone4?
425
- * @default
426
- */
427
- this.iPhone4 = false;
428
-
429
- /**
430
- * @property {boolean} iPhone5 - Is running on iPhone5?
431
- * @default
432
- */
433
- this.iPhone5 = false;
434
-
435
- /**
436
- * @property {boolean} iPad - Is running on iPad?
437
- * @default
438
- */
439
- this.iPad = false;
440
-
441
- // Device features
442
-
443
- /**
444
- * @property {number} pixelRatio - PixelRatio of the host device?
445
- * @default
446
- */
447
- this.pixelRatio = 0;
448
-
449
- /**
450
- * @property {boolean} littleEndian - Is the device big or little endian? (only detected if the browser supports TypedArrays)
451
- * @default
452
- */
453
- this.littleEndian = false;
454
-
455
- /**
456
- * @property {boolean} LITTLE_ENDIAN - Same value as `littleEndian`.
457
- * @default
458
- */
459
- this.LITTLE_ENDIAN = false;
460
-
461
- /**
462
- * @property {boolean} support32bit - Does the device context support 32bit pixel manipulation using array buffer views?
463
- * @default
464
- */
465
- this.support32bit = false;
466
-
467
- /**
468
- * @property {boolean} fullscreen - Does the browser support the Full Screen API?
469
- * @default
470
- */
471
- this.fullscreen = false;
472
-
473
- /**
474
- * @property {string} requestFullscreen - If the browser supports the Full Screen API this holds the call you need to use to activate it.
475
- * @default
476
- */
477
- this.requestFullscreen = '';
478
-
479
- /**
480
- * @property {string} cancelFullscreen - If the browser supports the Full Screen API this holds the call you need to use to cancel it.
481
- * @default
482
- */
483
- this.cancelFullscreen = '';
484
-
485
- /**
486
- * @property {boolean} fullscreenKeyboard - Does the browser support access to the Keyboard during Full Screen mode?
487
- * @default
488
- */
489
- this.fullscreenKeyboard = false;
490
-
491
- /**
492
- * Enum for possible screen orientations.
493
- * @readonly
494
- * @enum {string}
495
- */
496
- this.ScreenOrientation = {
497
- LANDSCAPE: 'landscape',
498
- PORTRAIT: 'portrait'
499
- };
500
-
501
- };
502
-
503
- // Device is really a singleton/static entity; instantiate it
504
- // and add new methods directly sans-prototype.
505
- LibDevice = new LibDevice();
506
-
507
- /**
508
- * Add a device-ready handler and ensure the device ready sequence is started.
509
- *
510
- * Phaser.Device will _not_ activate or initialize until at least one `whenReady` handler is added,
511
- * which is normally done automatically be calling `new Phaser.Game(..)`.
512
- *
513
- * The handler is invoked when the device is considered "ready", which may be immediately
514
- * if the device is already "ready". See {@link Phaser.Device#deviceReadyAt deviceReadyAt}.
515
- *
516
- * @method
517
- * @param {Function} handler - Callback to invoke when the device is ready. It is invoked with the given context the Phaser.Device object is supplied as the first argument.
518
- * @param {Object} [context] - Context in which to invoke the handler
519
- * @param {Boolean} [nonPrimer=false] - If true the device ready check will not be started.
520
- */
521
- LibDevice.whenReady = function (callback, context, nonPrimer) {
522
-
523
- let readyCheck = this._readyCheck;
524
-
525
- if (this.deviceReadyAt || !readyCheck) {
526
- callback.call(context, this);
527
- }
528
- else if (readyCheck._monitor || nonPrimer) {
529
- readyCheck._queue = readyCheck._queue || [];
530
- readyCheck._queue.push([callback, context]);
531
- }
532
- else {
533
- readyCheck._monitor = readyCheck.bind(this);
534
- readyCheck._queue = readyCheck._queue || [];
535
- readyCheck._queue.push([callback, context]);
536
-
537
- let cordova = typeof window.cordova !== 'undefined';
538
- let cocoonJS = navigator['isCocoonJS'];
539
-
540
- if (document.readyState === 'complete' || document.readyState === 'interactive') {
541
- // Why is there an additional timeout here?
542
- window.setTimeout(readyCheck._monitor, 0);
543
- }
544
- else if (cordova && !cocoonJS) {
545
- // Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready
546
- // Cordova, but NOT Cocoon?
547
- document.addEventListener('deviceready', readyCheck._monitor, false);
548
- }
549
- else {
550
- document.addEventListener('DOMContentLoaded', readyCheck._monitor, false);
551
- window.addEventListener('load', readyCheck._monitor, false);
552
- }
553
- }
554
-
555
- };
556
-
557
- /**
558
- * Internal method used for checking when the device is ready.
559
- * This function is removed from Phaser.Device when the device becomes ready.
560
- *
561
- * @method
562
- * @private
563
- */
564
- LibDevice._readyCheck = function () {
565
-
566
- let readyCheck = this._readyCheck;
567
-
568
- if (!document.body || !this._webPTestComplete) {
569
- window.setTimeout(readyCheck._monitor, 20);
570
- }
571
- else if (!this.deviceReadyAt) {
572
- this.deviceReadyAt = Date.now();
573
-
574
- document.removeEventListener('deviceready', readyCheck._monitor);
575
- document.removeEventListener('DOMContentLoaded', readyCheck._monitor);
576
- window.removeEventListener('load', readyCheck._monitor);
577
-
578
- this._initialize();
579
- this.initialized = true;
580
-
581
- let item;
582
- while ((item = readyCheck._queue.shift())) {
583
- let callback = item[0];
584
- let context = item[1];
585
- callback.call(context, this);
586
- }
587
-
588
- // Remove no longer useful methods and properties.
589
- this._readyCheck = null;
590
- this._initialize = null;
591
- }
592
-
593
- };
594
-
595
- /**
596
- * Internal method to initialize the capability checks.
597
- * This function is removed from Phaser.Device once the device is initialized.
598
- *
599
- * @method
600
- * @private
601
- */
602
- LibDevice._initialize = function () {
603
-
604
- let device = this;
605
-
606
- /**
607
- * Check which OS is game running on.
608
- */
609
- function _checkOS() {
610
-
611
- let ua = navigator.userAgent;
612
-
613
- if (/Playstation Vita/.test(ua)) {
614
- device.vita = true;
615
- }
616
- else if (/Kindle/.test(ua) || /\bKF[A-Z][A-Z]+/.test(ua) || /Silk.*Mobile Safari/.test(ua)) {
617
- device.kindle = true;
618
- // This will NOT detect early generations of Kindle Fire, I think there is no reliable way...
619
- // E.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-80) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true"
620
- }
621
- else if (/Android/.test(ua)) {
622
- device.android = true;
623
- }
624
- else if (/CrOS/.test(ua)) {
625
- device.chromeOS = true;
626
- }
627
- else if (/iP[ao]d|iPhone/i.test(ua)) {
628
- device.iOS = true;
629
- }
630
- else if (/Linux/.test(ua)) {
631
- device.linux = true;
632
- }
633
- else if (/Mac OS/.test(ua)) {
634
- device.macOS = true;
635
- }
636
- else if (/Windows/.test(ua)) {
637
- device.windows = true;
638
- }
639
-
640
- if (/Windows Phone/i.test(ua) || /IEMobile/i.test(ua)) {
641
- device.android = false;
642
- device.iOS = false;
643
- device.macOS = false;
644
- device.windows = true;
645
- device.windowsPhone = true;
646
- }
647
-
648
- let silk = /Silk/.test(ua); // detected in browsers
649
-
650
- if (device.windows || device.macOS || (device.linux && !silk) || device.chromeOS) {
651
- device.desktop = true;
652
- }
653
-
654
- // Windows Phone / Table reset
655
- if (device.windowsPhone || ((/Windows NT/i.test(ua)) && (/Touch/i.test(ua)))) {
656
- device.desktop = false;
657
- }
658
-
659
- }
660
-
661
- /**
662
- * Check HTML5 features of the host environment.
663
- */
664
- function _checkFeatures() {
665
-
666
- device.canvas = !!window['CanvasRenderingContext2D'] || device.cocoonJS;
667
-
668
- try {
669
- device.localStorage = !!localStorage.getItem;
670
- } catch (error) {
671
- device.localStorage = false;
672
- }
673
-
674
- device.file = !!window['File'] && !!window['FileReader'] && !!window['FileList'] && !!window['Blob'];
675
- device.fileSystem = !!window['requestFileSystem'];
676
-
677
- device.webGL = (function () { try { let canvas = document.createElement('canvas'); /*Force screencanvas to false*/ canvas.screencanvas = false; return !!window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')); } catch (e) { return false; } })();
678
- device.webGL = !!device.webGL;
679
-
680
- device.worker = !!window['Worker'];
681
-
682
- device.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
683
-
684
- device.quirksMode = (document.compatMode === 'CSS1Compat') ? false : true;
685
-
686
- navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
687
-
688
- window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
689
-
690
- device.getUserMedia = device.getUserMedia && !!navigator.getUserMedia && !!window.URL;
691
-
692
- // Older versions of firefox (< 21) apparently claim support but user media does not actually work
693
- if (device.firefox && device.firefoxVersion < 21) {
694
- device.getUserMedia = false;
695
- }
696
-
697
- // Excludes iOS versions as they generally wrap UIWebView (eg. Safari WebKit) and it
698
- // is safer to not try and use the fast copy-over method.
699
- if (!device.iOS && (device.ie || device.firefox || device.chrome)) {
700
- device.canvasBitBltShift = true;
701
- }
702
-
703
- // Known not to work
704
- if (device.safari || device.mobileSafari) {
705
- device.canvasBitBltShift = false;
706
- }
707
-
708
- }
709
-
710
- /**
711
- * Checks/configures letious input.
712
- */
713
- function _checkInput() {
714
-
715
- if ('ontouchstart' in document.documentElement || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints >= 1)) {
716
- device.touch = true;
717
- }
718
-
719
- if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled) {
720
- device.mspointer = true;
721
- }
722
-
723
- if (!device.cocoonJS) {
724
- // See https://developer.mozilla.org/en-US/docs/Web/Events/wheel
725
- if ('onwheel' in window || (device.ie && 'WheelEvent' in window)) {
726
- // DOM3 Wheel Event: FF 17+, IE 9+, Chrome 31+, Safari 7+
727
- device.wheelEvent = 'wheel';
728
- }
729
- else if ('onmousewheel' in window) {
730
- // Non-FF legacy: IE 6-9, Chrome 1-31, Safari 5-7.
731
- device.wheelEvent = 'mousewheel';
732
- }
733
- else if (device.firefox && 'MouseScrollEvent' in window) {
734
- // FF prior to 17. This should probably be scrubbed.
735
- device.wheelEvent = 'DOMMouseScroll';
736
- }
737
- }
738
-
739
- }
740
-
741
- /**
742
- * Checks for support of the Full Screen API.
743
- */
744
- function _checkFullScreenSupport() {
745
-
746
- let fs = [
747
- 'requestFullscreen',
748
- 'requestFullScreen',
749
- 'webkitRequestFullscreen',
750
- 'webkitRequestFullScreen',
751
- 'msRequestFullscreen',
752
- 'msRequestFullScreen',
753
- 'mozRequestFullScreen',
754
- 'mozRequestFullscreen'
755
- ];
756
-
757
- let element = document.createElement('div');
758
-
759
- for (let i = 0; i < fs.length; i++) {
760
- if (element[fs[i]]) {
761
- device.fullscreen = true;
762
- device.requestFullscreen = fs[i];
763
- break;
764
- }
765
- }
766
-
767
- let cfs = [
768
- 'cancelFullScreen',
769
- 'exitFullscreen',
770
- 'webkitCancelFullScreen',
771
- 'webkitExitFullscreen',
772
- 'msCancelFullScreen',
773
- 'msExitFullscreen',
774
- 'mozCancelFullScreen',
775
- 'mozExitFullscreen'
776
- ];
777
-
778
- if (device.fullscreen) {
779
- for (let i = 0; i < cfs.length; i++) {
780
- if (document[cfs[i]]) {
781
- device.cancelFullscreen = cfs[i];
782
- break;
783
- }
784
- }
785
- }
786
-
787
- // Keyboard Input?
788
- if (window['Element'] && Element['ALLOW_KEYBOARD_INPUT']) {
789
- device.fullscreenKeyboard = true;
790
- }
791
-
792
- }
793
-
794
- /**
795
- * Check what browser is game running in.
796
- */
797
- function _checkBrowser() {
798
-
799
- let ua = navigator.userAgent;
800
-
801
- if (/Arora/.test(ua)) {
802
- device.arora = true;
803
- }
804
- else if (/Chrome\/(\d+)/.test(ua) && !device.windowsPhone) {
805
- device.chrome = true;
806
- device.chromeVersion = parseInt(RegExp.$1, 10);
807
- }
808
- else if (/Epiphany/.test(ua)) {
809
- device.epiphany = true;
810
- }
811
- else if (/Firefox\D+(\d+)/.test(ua)) {
812
- device.firefox = true;
813
- device.firefoxVersion = parseInt(RegExp.$1, 10);
814
- }
815
- else if (/AppleWebKit/.test(ua) && device.iOS) {
816
- device.mobileSafari = true;
817
- }
818
- else if (/MSIE (\d+\.\d+);/.test(ua)) {
819
- device.ie = true;
820
- device.ieVersion = parseInt(RegExp.$1, 10);
821
- }
822
- else if (/Midori/.test(ua)) {
823
- device.midori = true;
824
- }
825
- else if (/Opera/.test(ua)) {
826
- device.opera = true;
827
- }
828
- else if (/Safari/.test(ua) && !device.windowsPhone) {
829
- device.safari = true;
830
- }
831
- else if (/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/.test(ua)) {
832
- device.ie = true;
833
- device.trident = true;
834
- device.tridentVersion = parseInt(RegExp.$1, 10);
835
- device.ieVersion = parseInt(RegExp.$3, 10);
836
- }
837
-
838
- // Silk gets its own if clause because its ua also contains 'Safari'
839
- if (/Silk/.test(ua)) {
840
- device.silk = true;
841
- }
842
-
843
- // WebApp mode in iOS
844
- if (navigator['standalone']) {
845
- device.webApp = true;
846
- }
847
-
848
- if (typeof window.cordova !== "undefined") {
849
- device.cordova = true;
850
- }
851
-
852
- if (typeof process !== "undefined" && typeof require !== "undefined") {
853
- device.node = true;
854
- }
855
-
856
- if (device.node && typeof process.versions === 'object') {
857
- device.nodeWebkit = !!process.versions['node-webkit'];
858
-
859
- device.electron = !!process.versions.electron;
860
- }
861
-
862
- if (navigator['isCocoonJS']) {
863
- device.cocoonJS = true;
864
- }
865
-
866
- if (device.cocoonJS) {
867
- try {
868
- device.cocoonJSApp = (typeof CocoonJS !== "undefined");
869
- }
870
- catch (error) {
871
- device.cocoonJSApp = false;
872
- }
873
- }
874
-
875
- if (typeof window.ejecta !== "undefined") {
876
- device.ejecta = true;
877
- }
878
-
879
- if (/Crosswalk/.test(ua)) {
880
- device.crosswalk = true;
881
- }
882
-
883
- }
884
-
885
- /**
886
- * Check video support.
887
- */
888
- function _checkVideo() {
889
-
890
- let videoElement = document.createElement("video");
891
- let result = false;
892
-
893
- try {
894
- if (result = !!videoElement.canPlayType) {
895
- if (videoElement.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, '')) {
896
- device.oggVideo = true;
897
- }
898
-
899
- if (videoElement.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, '')) {
900
- // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
901
- device.h264Video = true;
902
- device.mp4Video = true;
903
- }
904
-
905
- if (videoElement.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, '')) {
906
- device.webmVideo = true;
907
- }
908
-
909
- if (videoElement.canPlayType('video/webm; codecs="vp9"').replace(/^no$/, '')) {
910
- device.vp9Video = true;
911
- }
912
-
913
- if (videoElement.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/, '')) {
914
- device.hlsVideo = true;
915
- }
916
- }
917
- } catch (e) { }
918
- }
919
-
920
- /**
921
- * Check audio support.
922
- */
923
- function _checkAudio() {
924
-
925
- device.audioData = !!(window['Audio']);
926
- device.webAudio = !!(window['AudioContext'] || window['webkitAudioContext']);
927
- let audioElement = document.createElement('audio');
928
- let result = false;
929
-
930
- try {
931
- if (result = !!audioElement.canPlayType) {
932
- if (audioElement.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '')) {
933
- device.ogg = true;
934
- }
935
-
936
- if (audioElement.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/, '') || audioElement.canPlayType('audio/opus;').replace(/^no$/, '')) {
937
- device.opus = true;
938
- }
939
-
940
- if (audioElement.canPlayType('audio/mpeg;').replace(/^no$/, '')) {
941
- device.mp3 = true;
942
- }
943
-
944
- // Mimetypes accepted:
945
- // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
946
- // bit.ly/iphoneoscodecs
947
- if (audioElement.canPlayType('audio/wav; codecs="1"').replace(/^no$/, '')) {
948
- device.wav = true;
949
- }
950
-
951
- if (audioElement.canPlayType('audio/x-m4a;') || audioElement.canPlayType('audio/aac;').replace(/^no$/, '')) {
952
- device.m4a = true;
953
- }
954
-
955
- if (audioElement.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, '')) {
956
- device.webm = true;
957
- }
958
- }
959
- } catch (e) {
960
- }
961
-
962
- }
963
-
964
- /**
965
- * Check PixelRatio, iOS device, Vibration API, ArrayBuffers and endianess.
966
- */
967
- function _checkDevice() {
968
-
969
- device.pixelRatio = window['devicePixelRatio'] || 1;
970
- device.iPhone = navigator.userAgent.toLowerCase().indexOf('iphone') != -1;
971
- device.iPhone4 = (device.pixelRatio == 2 && device.iPhone);
972
- device.iPhone5 = device.pixelRatio === 2 && device.iPhone &&
973
- ((screen.availWidth === 320 && screen.availHeight === 568) || (screen.availWidth === 568 && screen.availHeight === 320));
974
- device.iPad = navigator.userAgent.toLowerCase().indexOf('ipad') != -1;
975
-
976
- if (typeof Int8Array !== 'undefined') {
977
- device.typedArray = true;
978
- }
979
- else {
980
- device.typedArray = false;
981
- }
982
-
983
- if (typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined' && typeof Uint32Array !== 'undefined') {
984
- device.littleEndian = _checkIsLittleEndian();
985
- device.LITTLE_ENDIAN = device.littleEndian;
986
- }
987
-
988
- device.support32bit = (typeof ArrayBuffer !== "undefined" && typeof Uint8ClampedArray !== "undefined" && typeof Int32Array !== "undefined" && device.littleEndian !== null && _checkIsUint8ClampedImageData());
989
-
990
- navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
991
-
992
- if (navigator.vibrate) {
993
- device.vibration = true;
994
- }
995
-
996
- }
997
-
998
- /**
999
- * Check Little or Big Endian system.
1000
- *
1001
- * @author Matt DesLauriers (@mattdesl)
1002
- */
1003
- function _checkIsLittleEndian() {
1004
-
1005
- let a = new ArrayBuffer(4);
1006
- let b = new Uint8Array(a);
1007
- let c = new Uint32Array(a);
1008
-
1009
- b[0] = 0xa1;
1010
- b[1] = 0xb2;
1011
- b[2] = 0xc3;
1012
- b[3] = 0xd4;
1013
-
1014
- if (c[0] == 0xd4c3b2a1) {
1015
- return true;
1016
- }
1017
-
1018
- if (c[0] == 0xa1b2c3d4) {
1019
- return false;
1020
- }
1021
- else {
1022
- // Could not determine endianness
1023
- return null;
1024
- }
1025
-
1026
- }
1027
-
1028
- /**
1029
- * Test to see if ImageData uses CanvasPixelArray or Uint8ClampedArray.
1030
- *
1031
- * @author Matt DesLauriers (@mattdesl)
1032
- */
1033
- function _checkIsUint8ClampedImageData() {
1034
-
1035
- if (Uint8ClampedArray === undefined) {
1036
- return false;
1037
- }
1038
-
1039
- let elem = document.createElement('canvas');
1040
- let ctx = elem.getContext('2d');
1041
-
1042
- if (!ctx) {
1043
- return false;
1044
- }
1045
-
1046
- let image = ctx.createImageData(1, 1);
1047
-
1048
- return image.data instanceof Uint8ClampedArray;
1049
-
1050
- }
1051
-
1052
- /**
1053
- * Check whether the host environment support 3D CSS.
1054
- */
1055
- function _checkCSS3D() {
1056
-
1057
- let el = document.createElement('p');
1058
- let has3d;
1059
- let transforms = {
1060
- 'webkitTransform': '-webkit-transform',
1061
- 'OTransform': '-o-transform',
1062
- 'msTransform': '-ms-transform',
1063
- 'MozTransform': '-moz-transform',
1064
- 'transform': 'transform'
1065
- };
1066
-
1067
- // Add it to the body to get the computed style.
1068
- document.body.insertBefore(el, null);
1069
-
1070
- for (let t in transforms) {
1071
- if (el.style[t] !== undefined) {
1072
- el.style[t] = "translate3d(1px,1px,1px)";
1073
- has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
1074
- }
1075
- }
1076
-
1077
- document.body.removeChild(el);
1078
- device.css3D = (has3d !== undefined && has3d.length > 0 && has3d !== "none");
1079
-
1080
- }
1081
-
1082
- // Run the checks
1083
- _checkOS();
1084
- _checkAudio();
1085
- _checkVideo();
1086
- _checkBrowser();
1087
- _checkCSS3D();
1088
- _checkDevice();
1089
- _checkFeatures();
1090
- _checkFullScreenSupport();
1091
- _checkInput();
1092
-
1093
- };
1094
-
1095
- /**
1096
- * Check whether the host environment can play audio.
1097
- *
1098
- * @method canPlayAudio
1099
- * @memberof Phaser.Device.prototype
1100
- * @param {String} type - One of 'mp3, 'ogg', 'm4a', 'wav', 'webm' or 'opus'.
1101
- * @return {boolean} True if the given file type is supported by the browser, otherwise false.
1102
- */
1103
- LibDevice.canPlayAudio = function (type) {
1104
-
1105
- if (type === 'mp3' && this.mp3) {
1106
- return true;
1107
- }
1108
- else if (type === 'ogg' && (this.ogg || this.opus)) {
1109
- return true;
1110
- }
1111
- else if (type === 'm4a' && this.m4a) {
1112
- return true;
1113
- }
1114
- else if (type === 'opus' && this.opus) {
1115
- return true;
1116
- }
1117
- else if (type === 'wav' && this.wav) {
1118
- return true;
1119
- }
1120
- else if (type === 'webm' && this.webm) {
1121
- return true;
1122
- }
1123
-
1124
- return false;
1125
-
1126
- };
1127
-
1128
- /**
1129
- * Check whether the host environment can play video files.
1130
- *
1131
- * @method canPlayVideo
1132
- * @memberof Phaser.Device.prototype
1133
- * @param {String} type - One of 'mp4, 'ogg', 'webm' or 'mpeg'.
1134
- * @return {boolean} True if the given file type is supported by the browser, otherwise false.
1135
- */
1136
- LibDevice.canPlayVideo = function (type) {
1137
-
1138
- if (type === 'webm' && (this.webmVideo || this.vp9Video)) {
1139
- return true;
1140
- }
1141
- else if (type === 'mp4' && (this.mp4Video || this.h264Video)) {
1142
- return true;
1143
- }
1144
- else if ((type === 'ogg' || type === 'ogv') && this.oggVideo) {
1145
- return true;
1146
- }
1147
- else if (type === 'mpeg' && this.hlsVideo) {
1148
- return true;
1149
- }
1150
-
1151
- return false;
1152
-
1153
- };
1154
-
1155
- /**
1156
- * Check whether the console is open.
1157
- * Note that this only works in Firefox with Firebug and earlier versions of Chrome.
1158
- * It used to work in Chrome, but then they removed the ability: {@link http://src.chromium.org/viewvc/blink?view=revision&revision=151136}
1159
- *
1160
- * @method isConsoleOpen
1161
- * @memberof Phaser.Device.prototype
1162
- */
1163
- LibDevice.isConsoleOpen = function () {
1164
-
1165
- if (window.console && window.console['firebug']) {
1166
- return true;
1167
- }
1168
-
1169
- if (window.console) {
1170
- console.profile();
1171
- console.profileEnd();
1172
-
1173
- if (console.clear) {
1174
- console.clear();
1175
- }
1176
-
1177
- if (console['profiles']) {
1178
- return console['profiles'].length > 0;
1179
- }
1180
- }
1181
-
1182
- return false;
1183
-
1184
- };
1185
-
1186
- /**
1187
- * Detect if the host is a an Android Stock browser.
1188
- * This is available before the device "ready" event.
1189
- *
1190
- * Authors might want to scale down on effects and switch to the CANVAS rendering method on those devices.
1191
- *
1192
- * @example
1193
- * let defaultRenderingMode = Phaser.Device.isAndroidStockBrowser() ? Phaser.CANVAS : Phaser.AUTO;
1194
- *
1195
- * @method isAndroidStockBrowser
1196
- * @memberof Phaser.Device.prototype
1197
- */
1198
- LibDevice.isAndroidStockBrowser = function () {
1199
-
1200
- let matches = window.navigator.userAgent.match(/Android.*AppleWebKit\/([\d.]+)/);
1201
- return matches && matches[1] < 537;
1202
-
1203
- };
1204
-
1205
- //webP check
1206
- (function () {
1207
- const webP = new Image();
1208
- webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
1209
- webP.onload = webP.onerror = function () {
1210
- LibDevice.webP = (webP.height === 2);
1211
- LibDevice._webPTestComplete = true;
1212
- };
1213
- })();
1214
-
1215
- module.exports = LibDevice;
1
+ let LibDevice = function () {
2
+
3
+ /**
4
+ * The time the device became ready.
5
+ * @property {integer} deviceReadyAt
6
+ * @protected
7
+ */
8
+ this.deviceReadyAt = 0;
9
+
10
+ /**
11
+ * The time as which initialization has completed.
12
+ * @property {boolean} initialized
13
+ * @protected
14
+ */
15
+ this.initialized = false;
16
+
17
+ // Browser / Host / Operating System
18
+
19
+ /**
20
+ * @property {boolean} desktop - Is running on a desktop?
21
+ * @default
22
+ */
23
+ this.desktop = false;
24
+
25
+ /**
26
+ * @property {boolean} iOS - Is running on iOS?
27
+ * @default
28
+ */
29
+ this.iOS = false;
30
+
31
+ /**
32
+ * @property {boolean} cocoonJS - Is the game running under CocoonJS?
33
+ * @default
34
+ */
35
+ this.cocoonJS = false;
36
+
37
+ /**
38
+ * @property {boolean} cocoonJSApp - Is this game running with CocoonJS.App?
39
+ * @default
40
+ */
41
+ this.cocoonJSApp = false;
42
+
43
+ /**
44
+ * @property {boolean} cordova - Is the game running under Apache Cordova?
45
+ * @default
46
+ */
47
+ this.cordova = false;
48
+
49
+ /**
50
+ * @property {boolean} node - Is the game running under Node.js?
51
+ * @default
52
+ */
53
+ this.node = false;
54
+
55
+ /**
56
+ * @property {boolean} nodeWebkit - Is the game running under Node-Webkit?
57
+ * @default
58
+ */
59
+ this.nodeWebkit = false;
60
+
61
+ /**
62
+ * @property {boolean} electron - Is the game running under GitHub Electron?
63
+ * @default
64
+ */
65
+ this.electron = false;
66
+
67
+ /**
68
+ * @property {boolean} ejecta - Is the game running under Ejecta?
69
+ * @default
70
+ */
71
+ this.ejecta = false;
72
+
73
+ /**
74
+ * @property {boolean} crosswalk - Is the game running under the Intel Crosswalk XDK?
75
+ * @default
76
+ */
77
+ this.crosswalk = false;
78
+
79
+ /**
80
+ * @property {boolean} android - Is running on android?
81
+ * @default
82
+ */
83
+ this.android = false;
84
+
85
+ /**
86
+ * @property {boolean} chromeOS - Is running on chromeOS?
87
+ * @default
88
+ */
89
+ this.chromeOS = false;
90
+
91
+ /**
92
+ * @property {boolean} linux - Is running on linux?
93
+ * @default
94
+ */
95
+ this.linux = false;
96
+
97
+ /**
98
+ * @property {boolean} macOS - Is running on macOS?
99
+ * @default
100
+ */
101
+ this.macOS = false;
102
+
103
+ /**
104
+ * @property {boolean} windows - Is running on windows?
105
+ * @default
106
+ */
107
+ this.windows = false;
108
+
109
+ /**
110
+ * @property {boolean} windowsPhone - Is running on a Windows Phone?
111
+ * @default
112
+ */
113
+ this.windowsPhone = false;
114
+
115
+ // Features
116
+
117
+ /**
118
+ * @property {boolean} canvas - Is canvas available?
119
+ * @default
120
+ */
121
+ this.canvas = false;
122
+
123
+ /**
124
+ * @property {?boolean} canvasBitBltShift - True if canvas supports a 'copy' bitblt onto itself when the source and destination regions overlap.
125
+ * @default
126
+ */
127
+ this.canvasBitBltShift = null;
128
+
129
+ /**
130
+ * @property {boolean} webGL - Is webGL available?
131
+ * @default
132
+ */
133
+ this.webGL = false;
134
+
135
+ /**
136
+ * @property {boolean} file - Is file available?
137
+ * @default
138
+ */
139
+ this.file = false;
140
+
141
+ /**
142
+ * @property {boolean} fileSystem - Is fileSystem available?
143
+ * @default
144
+ */
145
+ this.fileSystem = false;
146
+
147
+ /**
148
+ * @property {boolean} localStorage - Is localStorage available?
149
+ * @default
150
+ */
151
+ this.localStorage = false;
152
+
153
+ /**
154
+ * @property {boolean} worker - Is worker available?
155
+ * @default
156
+ */
157
+ this.worker = false;
158
+
159
+ /**
160
+ * @property {boolean} css3D - Is css3D available?
161
+ * @default
162
+ */
163
+ this.css3D = false;
164
+
165
+ /**
166
+ * @property {boolean} pointerLock - Is Pointer Lock available?
167
+ * @default
168
+ */
169
+ this.pointerLock = false;
170
+
171
+ /**
172
+ * @property {boolean} typedArray - Does the browser support TypedArrays?
173
+ * @default
174
+ */
175
+ this.typedArray = false;
176
+
177
+ /**
178
+ * @property {boolean} vibration - Does the device support the Vibration API?
179
+ * @default
180
+ */
181
+ this.vibration = false;
182
+
183
+ /**
184
+ * @property {boolean} getUserMedia - Does the device support the getUserMedia API?
185
+ * @default
186
+ */
187
+ this.getUserMedia = true;
188
+
189
+ /**
190
+ * @property {boolean} quirksMode - Is the browser running in strict mode (false) or quirks mode? (true)
191
+ * @default
192
+ */
193
+ this.quirksMode = false;
194
+
195
+ /**
196
+ * @property {boolean} webP - Is the browser support webP
197
+ * @default
198
+ */
199
+ this.webP = false;
200
+
201
+ /**
202
+ * @property {boolean} _webPTestComplete - Is the webP test complete
203
+ * @default
204
+ */
205
+ this._webPTestComplete = false;
206
+
207
+ // Input
208
+
209
+ /**
210
+ * @property {boolean} touch - Is touch available?
211
+ * @default
212
+ */
213
+ this.touch = false;
214
+
215
+ /**
216
+ * @property {boolean} mspointer - Is mspointer available?
217
+ * @default
218
+ */
219
+ this.mspointer = false;
220
+
221
+ /**
222
+ * @property {?string} wheelType - The newest type of Wheel/Scroll event supported: 'wheel', 'mousewheel', 'DOMMouseScroll'
223
+ * @default
224
+ * @protected
225
+ */
226
+ this.wheelEvent = null;
227
+
228
+ // Browser
229
+
230
+ /**
231
+ * @property {boolean} arora - Set to true if running in Arora.
232
+ * @default
233
+ */
234
+ this.arora = false;
235
+
236
+ /**
237
+ * @property {boolean} chrome - Set to true if running in Chrome.
238
+ * @default
239
+ */
240
+ this.chrome = false;
241
+
242
+ /**
243
+ * @property {number} chromeVersion - If running in Chrome this will contain the major version number.
244
+ * @default
245
+ */
246
+ this.chromeVersion = 0;
247
+
248
+ /**
249
+ * @property {boolean} epiphany - Set to true if running in Epiphany.
250
+ * @default
251
+ */
252
+ this.epiphany = false;
253
+
254
+ /**
255
+ * @property {boolean} firefox - Set to true if running in Firefox.
256
+ * @default
257
+ */
258
+ this.firefox = false;
259
+
260
+ /**
261
+ * @property {number} firefoxVersion - If running in Firefox this will contain the major version number.
262
+ * @default
263
+ */
264
+ this.firefoxVersion = 0;
265
+
266
+ /**
267
+ * @property {boolean} ie - Set to true if running in Internet Explorer.
268
+ * @default
269
+ */
270
+ this.ie = false;
271
+
272
+ /**
273
+ * @property {number} ieVersion - If running in Internet Explorer this will contain the major version number. Beyond IE10 you should use Device.trident and Device.tridentVersion.
274
+ * @default
275
+ */
276
+ this.ieVersion = 0;
277
+
278
+ /**
279
+ * @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+)
280
+ * @default
281
+ */
282
+ this.trident = false;
283
+
284
+ /**
285
+ * @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See {@link http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx}
286
+ * @default
287
+ */
288
+ this.tridentVersion = 0;
289
+
290
+ /**
291
+ * @property {boolean} mobileSafari - Set to true if running in Mobile Safari.
292
+ * @default
293
+ */
294
+ this.mobileSafari = false;
295
+
296
+ /**
297
+ * @property {boolean} midori - Set to true if running in Midori.
298
+ * @default
299
+ */
300
+ this.midori = false;
301
+
302
+ /**
303
+ * @property {boolean} opera - Set to true if running in Opera.
304
+ * @default
305
+ */
306
+ this.opera = false;
307
+
308
+ /**
309
+ * @property {boolean} safari - Set to true if running in Safari.
310
+ * @default
311
+ */
312
+ this.safari = false;
313
+
314
+ /**
315
+ * @property {boolean} webApp - Set to true if running as a WebApp, i.e. within a WebView
316
+ * @default
317
+ */
318
+ this.webApp = false;
319
+
320
+ /**
321
+ * @property {boolean} silk - Set to true if running in the Silk browser (as used on the Amazon Kindle)
322
+ * @default
323
+ */
324
+ this.silk = false;
325
+
326
+ // Audio
327
+
328
+ /**
329
+ * @property {boolean} audioData - Are Audio tags available?
330
+ * @default
331
+ */
332
+ this.audioData = false;
333
+
334
+ /**
335
+ * @property {boolean} webAudio - Is the WebAudio API available?
336
+ * @default
337
+ */
338
+ this.webAudio = false;
339
+
340
+ /**
341
+ * @property {boolean} ogg - Can this device play ogg files?
342
+ * @default
343
+ */
344
+ this.ogg = false;
345
+
346
+ /**
347
+ * @property {boolean} opus - Can this device play opus files?
348
+ * @default
349
+ */
350
+ this.opus = false;
351
+
352
+ /**
353
+ * @property {boolean} mp3 - Can this device play mp3 files?
354
+ * @default
355
+ */
356
+ this.mp3 = false;
357
+
358
+ /**
359
+ * @property {boolean} wav - Can this device play wav files?
360
+ * @default
361
+ */
362
+ this.wav = false;
363
+
364
+ /**
365
+ * Can this device play m4a files?
366
+ * @property {boolean} m4a - True if this device can play m4a files.
367
+ * @default
368
+ */
369
+ this.m4a = false;
370
+
371
+ /**
372
+ * @property {boolean} webm - Can this device play webm files?
373
+ * @default
374
+ */
375
+ this.webm = false;
376
+
377
+ // Video
378
+
379
+ /**
380
+ * @property {boolean} oggVideo - Can this device play ogg video files?
381
+ * @default
382
+ */
383
+ this.oggVideo = false;
384
+
385
+ /**
386
+ * @property {boolean} h264Video - Can this device play h264 mp4 video files?
387
+ * @default
388
+ */
389
+ this.h264Video = false;
390
+
391
+ /**
392
+ * @property {boolean} mp4Video - Can this device play h264 mp4 video files?
393
+ * @default
394
+ */
395
+ this.mp4Video = false;
396
+
397
+ /**
398
+ * @property {boolean} webmVideo - Can this device play webm video files?
399
+ * @default
400
+ */
401
+ this.webmVideo = false;
402
+
403
+ /**
404
+ * @property {boolean} vp9Video - Can this device play vp9 video files?
405
+ * @default
406
+ */
407
+ this.vp9Video = false;
408
+
409
+ /**
410
+ * @property {boolean} hlsVideo - Can this device play hls video files?
411
+ * @default
412
+ */
413
+ this.hlsVideo = false;
414
+
415
+ // Device
416
+
417
+ /**
418
+ * @property {boolean} iPhone - Is running on iPhone?
419
+ * @default
420
+ */
421
+ this.iPhone = false;
422
+
423
+ /**
424
+ * @property {boolean} iPhone4 - Is running on iPhone4?
425
+ * @default
426
+ */
427
+ this.iPhone4 = false;
428
+
429
+ /**
430
+ * @property {boolean} iPhone5 - Is running on iPhone5?
431
+ * @default
432
+ */
433
+ this.iPhone5 = false;
434
+
435
+ /**
436
+ * @property {boolean} iPad - Is running on iPad?
437
+ * @default
438
+ */
439
+ this.iPad = false;
440
+
441
+ // Device features
442
+
443
+ /**
444
+ * @property {number} pixelRatio - PixelRatio of the host device?
445
+ * @default
446
+ */
447
+ this.pixelRatio = 0;
448
+
449
+ /**
450
+ * @property {boolean} littleEndian - Is the device big or little endian? (only detected if the browser supports TypedArrays)
451
+ * @default
452
+ */
453
+ this.littleEndian = false;
454
+
455
+ /**
456
+ * @property {boolean} LITTLE_ENDIAN - Same value as `littleEndian`.
457
+ * @default
458
+ */
459
+ this.LITTLE_ENDIAN = false;
460
+
461
+ /**
462
+ * @property {boolean} support32bit - Does the device context support 32bit pixel manipulation using array buffer views?
463
+ * @default
464
+ */
465
+ this.support32bit = false;
466
+
467
+ /**
468
+ * @property {boolean} fullscreen - Does the browser support the Full Screen API?
469
+ * @default
470
+ */
471
+ this.fullscreen = false;
472
+
473
+ /**
474
+ * @property {string} requestFullscreen - If the browser supports the Full Screen API this holds the call you need to use to activate it.
475
+ * @default
476
+ */
477
+ this.requestFullscreen = '';
478
+
479
+ /**
480
+ * @property {string} cancelFullscreen - If the browser supports the Full Screen API this holds the call you need to use to cancel it.
481
+ * @default
482
+ */
483
+ this.cancelFullscreen = '';
484
+
485
+ /**
486
+ * @property {boolean} fullscreenKeyboard - Does the browser support access to the Keyboard during Full Screen mode?
487
+ * @default
488
+ */
489
+ this.fullscreenKeyboard = false;
490
+
491
+ /**
492
+ * Enum for possible screen orientations.
493
+ * @readonly
494
+ * @enum {string}
495
+ */
496
+ this.ScreenOrientation = {
497
+ LANDSCAPE: 'landscape',
498
+ PORTRAIT: 'portrait'
499
+ };
500
+
501
+ };
502
+
503
+ // Device is really a singleton/static entity; instantiate it
504
+ // and add new methods directly sans-prototype.
505
+ LibDevice = new LibDevice();
506
+
507
+ /**
508
+ * Add a device-ready handler and ensure the device ready sequence is started.
509
+ *
510
+ * Phaser.Device will _not_ activate or initialize until at least one `whenReady` handler is added,
511
+ * which is normally done automatically be calling `new Phaser.Game(..)`.
512
+ *
513
+ * The handler is invoked when the device is considered "ready", which may be immediately
514
+ * if the device is already "ready". See {@link Phaser.Device#deviceReadyAt deviceReadyAt}.
515
+ *
516
+ * @method
517
+ * @param {Function} handler - Callback to invoke when the device is ready. It is invoked with the given context the Phaser.Device object is supplied as the first argument.
518
+ * @param {Object} [context] - Context in which to invoke the handler
519
+ * @param {Boolean} [nonPrimer=false] - If true the device ready check will not be started.
520
+ */
521
+ LibDevice.whenReady = function (callback, context, nonPrimer) {
522
+
523
+ let readyCheck = this._readyCheck;
524
+
525
+ if (this.deviceReadyAt || !readyCheck) {
526
+ callback.call(context, this);
527
+ }
528
+ else if (readyCheck._monitor || nonPrimer) {
529
+ readyCheck._queue = readyCheck._queue || [];
530
+ readyCheck._queue.push([callback, context]);
531
+ }
532
+ else {
533
+ readyCheck._monitor = readyCheck.bind(this);
534
+ readyCheck._queue = readyCheck._queue || [];
535
+ readyCheck._queue.push([callback, context]);
536
+
537
+ let cordova = typeof window.cordova !== 'undefined';
538
+ let cocoonJS = navigator['isCocoonJS'];
539
+
540
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
541
+ // Why is there an additional timeout here?
542
+ window.setTimeout(readyCheck._monitor, 0);
543
+ }
544
+ else if (cordova && !cocoonJS) {
545
+ // Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready
546
+ // Cordova, but NOT Cocoon?
547
+ document.addEventListener('deviceready', readyCheck._monitor, false);
548
+ }
549
+ else {
550
+ document.addEventListener('DOMContentLoaded', readyCheck._monitor, false);
551
+ window.addEventListener('load', readyCheck._monitor, false);
552
+ }
553
+ }
554
+
555
+ };
556
+
557
+ /**
558
+ * Internal method used for checking when the device is ready.
559
+ * This function is removed from Phaser.Device when the device becomes ready.
560
+ *
561
+ * @method
562
+ * @private
563
+ */
564
+ LibDevice._readyCheck = function () {
565
+
566
+ let readyCheck = this._readyCheck;
567
+
568
+ if (!document.body || !this._webPTestComplete) {
569
+ window.setTimeout(readyCheck._monitor, 20);
570
+ }
571
+ else if (!this.deviceReadyAt) {
572
+ this.deviceReadyAt = Date.now();
573
+
574
+ document.removeEventListener('deviceready', readyCheck._monitor);
575
+ document.removeEventListener('DOMContentLoaded', readyCheck._monitor);
576
+ window.removeEventListener('load', readyCheck._monitor);
577
+
578
+ this._initialize();
579
+ this.initialized = true;
580
+
581
+ let item;
582
+ while ((item = readyCheck._queue.shift())) {
583
+ let callback = item[0];
584
+ let context = item[1];
585
+ callback.call(context, this);
586
+ }
587
+
588
+ // Remove no longer useful methods and properties.
589
+ this._readyCheck = null;
590
+ this._initialize = null;
591
+ }
592
+
593
+ };
594
+
595
+ /**
596
+ * Internal method to initialize the capability checks.
597
+ * This function is removed from Phaser.Device once the device is initialized.
598
+ *
599
+ * @method
600
+ * @private
601
+ */
602
+ LibDevice._initialize = function () {
603
+
604
+ let device = this;
605
+
606
+ /**
607
+ * Check which OS is game running on.
608
+ */
609
+ function _checkOS() {
610
+
611
+ let ua = navigator.userAgent;
612
+
613
+ if (/Playstation Vita/.test(ua)) {
614
+ device.vita = true;
615
+ }
616
+ else if (/Kindle/.test(ua) || /\bKF[A-Z][A-Z]+/.test(ua) || /Silk.*Mobile Safari/.test(ua)) {
617
+ device.kindle = true;
618
+ // This will NOT detect early generations of Kindle Fire, I think there is no reliable way...
619
+ // E.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-80) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true"
620
+ }
621
+ else if (/Android/.test(ua)) {
622
+ device.android = true;
623
+ }
624
+ else if (/CrOS/.test(ua)) {
625
+ device.chromeOS = true;
626
+ }
627
+ else if (/iP[ao]d|iPhone/i.test(ua)) {
628
+ device.iOS = true;
629
+ }
630
+ else if (/Linux/.test(ua)) {
631
+ device.linux = true;
632
+ }
633
+ else if (/Mac OS/.test(ua)) {
634
+ device.macOS = true;
635
+ }
636
+ else if (/Windows/.test(ua)) {
637
+ device.windows = true;
638
+ }
639
+
640
+ if (/Windows Phone/i.test(ua) || /IEMobile/i.test(ua)) {
641
+ device.android = false;
642
+ device.iOS = false;
643
+ device.macOS = false;
644
+ device.windows = true;
645
+ device.windowsPhone = true;
646
+ }
647
+
648
+ let silk = /Silk/.test(ua); // detected in browsers
649
+
650
+ if (device.windows || device.macOS || (device.linux && !silk) || device.chromeOS) {
651
+ device.desktop = true;
652
+ }
653
+
654
+ // Windows Phone / Table reset
655
+ if (device.windowsPhone || ((/Windows NT/i.test(ua)) && (/Touch/i.test(ua)))) {
656
+ device.desktop = false;
657
+ }
658
+
659
+ }
660
+
661
+ /**
662
+ * Check HTML5 features of the host environment.
663
+ */
664
+ function _checkFeatures() {
665
+
666
+ device.canvas = !!window['CanvasRenderingContext2D'] || device.cocoonJS;
667
+
668
+ try {
669
+ device.localStorage = !!localStorage.getItem;
670
+ } catch (error) {
671
+ device.localStorage = false;
672
+ }
673
+
674
+ device.file = !!window['File'] && !!window['FileReader'] && !!window['FileList'] && !!window['Blob'];
675
+ device.fileSystem = !!window['requestFileSystem'];
676
+
677
+ device.webGL = (function () { try { let canvas = document.createElement('canvas'); /*Force screencanvas to false*/ canvas.screencanvas = false; return !!window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')); } catch (e) { return false; } })();
678
+ device.webGL = !!device.webGL;
679
+
680
+ device.worker = !!window['Worker'];
681
+
682
+ device.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
683
+
684
+ device.quirksMode = (document.compatMode === 'CSS1Compat') ? false : true;
685
+
686
+ navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
687
+
688
+ window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
689
+
690
+ device.getUserMedia = device.getUserMedia && !!navigator.getUserMedia && !!window.URL;
691
+
692
+ // Older versions of firefox (< 21) apparently claim support but user media does not actually work
693
+ if (device.firefox && device.firefoxVersion < 21) {
694
+ device.getUserMedia = false;
695
+ }
696
+
697
+ // Excludes iOS versions as they generally wrap UIWebView (eg. Safari WebKit) and it
698
+ // is safer to not try and use the fast copy-over method.
699
+ if (!device.iOS && (device.ie || device.firefox || device.chrome)) {
700
+ device.canvasBitBltShift = true;
701
+ }
702
+
703
+ // Known not to work
704
+ if (device.safari || device.mobileSafari) {
705
+ device.canvasBitBltShift = false;
706
+ }
707
+
708
+ }
709
+
710
+ /**
711
+ * Checks/configures letious input.
712
+ */
713
+ function _checkInput() {
714
+
715
+ if ('ontouchstart' in document.documentElement || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints >= 1)) {
716
+ device.touch = true;
717
+ }
718
+
719
+ if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled) {
720
+ device.mspointer = true;
721
+ }
722
+
723
+ if (!device.cocoonJS) {
724
+ // See https://developer.mozilla.org/en-US/docs/Web/Events/wheel
725
+ if ('onwheel' in window || (device.ie && 'WheelEvent' in window)) {
726
+ // DOM3 Wheel Event: FF 17+, IE 9+, Chrome 31+, Safari 7+
727
+ device.wheelEvent = 'wheel';
728
+ }
729
+ else if ('onmousewheel' in window) {
730
+ // Non-FF legacy: IE 6-9, Chrome 1-31, Safari 5-7.
731
+ device.wheelEvent = 'mousewheel';
732
+ }
733
+ else if (device.firefox && 'MouseScrollEvent' in window) {
734
+ // FF prior to 17. This should probably be scrubbed.
735
+ device.wheelEvent = 'DOMMouseScroll';
736
+ }
737
+ }
738
+
739
+ }
740
+
741
+ /**
742
+ * Checks for support of the Full Screen API.
743
+ */
744
+ function _checkFullScreenSupport() {
745
+
746
+ let fs = [
747
+ 'requestFullscreen',
748
+ 'requestFullScreen',
749
+ 'webkitRequestFullscreen',
750
+ 'webkitRequestFullScreen',
751
+ 'msRequestFullscreen',
752
+ 'msRequestFullScreen',
753
+ 'mozRequestFullScreen',
754
+ 'mozRequestFullscreen'
755
+ ];
756
+
757
+ let element = document.createElement('div');
758
+
759
+ for (let i = 0; i < fs.length; i++) {
760
+ if (element[fs[i]]) {
761
+ device.fullscreen = true;
762
+ device.requestFullscreen = fs[i];
763
+ break;
764
+ }
765
+ }
766
+
767
+ let cfs = [
768
+ 'cancelFullScreen',
769
+ 'exitFullscreen',
770
+ 'webkitCancelFullScreen',
771
+ 'webkitExitFullscreen',
772
+ 'msCancelFullScreen',
773
+ 'msExitFullscreen',
774
+ 'mozCancelFullScreen',
775
+ 'mozExitFullscreen'
776
+ ];
777
+
778
+ if (device.fullscreen) {
779
+ for (let i = 0; i < cfs.length; i++) {
780
+ if (document[cfs[i]]) {
781
+ device.cancelFullscreen = cfs[i];
782
+ break;
783
+ }
784
+ }
785
+ }
786
+
787
+ // Keyboard Input?
788
+ if (window['Element'] && Element['ALLOW_KEYBOARD_INPUT']) {
789
+ device.fullscreenKeyboard = true;
790
+ }
791
+
792
+ }
793
+
794
+ /**
795
+ * Check what browser is game running in.
796
+ */
797
+ function _checkBrowser() {
798
+
799
+ let ua = navigator.userAgent;
800
+
801
+ if (/Arora/.test(ua)) {
802
+ device.arora = true;
803
+ }
804
+ else if (/Chrome\/(\d+)/.test(ua) && !device.windowsPhone) {
805
+ device.chrome = true;
806
+ device.chromeVersion = parseInt(RegExp.$1, 10);
807
+ }
808
+ else if (/Epiphany/.test(ua)) {
809
+ device.epiphany = true;
810
+ }
811
+ else if (/Firefox\D+(\d+)/.test(ua)) {
812
+ device.firefox = true;
813
+ device.firefoxVersion = parseInt(RegExp.$1, 10);
814
+ }
815
+ else if (/AppleWebKit/.test(ua) && device.iOS) {
816
+ device.mobileSafari = true;
817
+ }
818
+ else if (/MSIE (\d+\.\d+);/.test(ua)) {
819
+ device.ie = true;
820
+ device.ieVersion = parseInt(RegExp.$1, 10);
821
+ }
822
+ else if (/Midori/.test(ua)) {
823
+ device.midori = true;
824
+ }
825
+ else if (/Opera/.test(ua)) {
826
+ device.opera = true;
827
+ }
828
+ else if (/Safari/.test(ua) && !device.windowsPhone) {
829
+ device.safari = true;
830
+ }
831
+ else if (/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/.test(ua)) {
832
+ device.ie = true;
833
+ device.trident = true;
834
+ device.tridentVersion = parseInt(RegExp.$1, 10);
835
+ device.ieVersion = parseInt(RegExp.$3, 10);
836
+ }
837
+
838
+ // Silk gets its own if clause because its ua also contains 'Safari'
839
+ if (/Silk/.test(ua)) {
840
+ device.silk = true;
841
+ }
842
+
843
+ // WebApp mode in iOS
844
+ if (navigator['standalone']) {
845
+ device.webApp = true;
846
+ }
847
+
848
+ if (typeof window.cordova !== "undefined") {
849
+ device.cordova = true;
850
+ }
851
+
852
+ if (typeof process !== "undefined" && typeof require !== "undefined") {
853
+ device.node = true;
854
+ }
855
+
856
+ if (device.node && typeof process.versions === 'object') {
857
+ device.nodeWebkit = !!process.versions['node-webkit'];
858
+
859
+ device.electron = !!process.versions.electron;
860
+ }
861
+
862
+ if (navigator['isCocoonJS']) {
863
+ device.cocoonJS = true;
864
+ }
865
+
866
+ if (device.cocoonJS) {
867
+ try {
868
+ device.cocoonJSApp = (typeof CocoonJS !== "undefined");
869
+ }
870
+ catch (error) {
871
+ device.cocoonJSApp = false;
872
+ }
873
+ }
874
+
875
+ if (typeof window.ejecta !== "undefined") {
876
+ device.ejecta = true;
877
+ }
878
+
879
+ if (/Crosswalk/.test(ua)) {
880
+ device.crosswalk = true;
881
+ }
882
+
883
+ }
884
+
885
+ /**
886
+ * Check video support.
887
+ */
888
+ function _checkVideo() {
889
+
890
+ let videoElement = document.createElement("video");
891
+ let result = false;
892
+
893
+ try {
894
+ if (result = !!videoElement.canPlayType) {
895
+ if (videoElement.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, '')) {
896
+ device.oggVideo = true;
897
+ }
898
+
899
+ if (videoElement.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, '')) {
900
+ // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
901
+ device.h264Video = true;
902
+ device.mp4Video = true;
903
+ }
904
+
905
+ if (videoElement.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, '')) {
906
+ device.webmVideo = true;
907
+ }
908
+
909
+ if (videoElement.canPlayType('video/webm; codecs="vp9"').replace(/^no$/, '')) {
910
+ device.vp9Video = true;
911
+ }
912
+
913
+ if (videoElement.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/, '')) {
914
+ device.hlsVideo = true;
915
+ }
916
+ }
917
+ } catch (e) { }
918
+ }
919
+
920
+ /**
921
+ * Check audio support.
922
+ */
923
+ function _checkAudio() {
924
+
925
+ device.audioData = !!(window['Audio']);
926
+ device.webAudio = !!(window['AudioContext'] || window['webkitAudioContext']);
927
+ let audioElement = document.createElement('audio');
928
+ let result = false;
929
+
930
+ try {
931
+ if (result = !!audioElement.canPlayType) {
932
+ if (audioElement.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '')) {
933
+ device.ogg = true;
934
+ }
935
+
936
+ if (audioElement.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/, '') || audioElement.canPlayType('audio/opus;').replace(/^no$/, '')) {
937
+ device.opus = true;
938
+ }
939
+
940
+ if (audioElement.canPlayType('audio/mpeg;').replace(/^no$/, '')) {
941
+ device.mp3 = true;
942
+ }
943
+
944
+ // Mimetypes accepted:
945
+ // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
946
+ // bit.ly/iphoneoscodecs
947
+ if (audioElement.canPlayType('audio/wav; codecs="1"').replace(/^no$/, '')) {
948
+ device.wav = true;
949
+ }
950
+
951
+ if (audioElement.canPlayType('audio/x-m4a;') || audioElement.canPlayType('audio/aac;').replace(/^no$/, '')) {
952
+ device.m4a = true;
953
+ }
954
+
955
+ if (audioElement.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, '')) {
956
+ device.webm = true;
957
+ }
958
+ }
959
+ } catch (e) {
960
+ }
961
+
962
+ }
963
+
964
+ /**
965
+ * Check PixelRatio, iOS device, Vibration API, ArrayBuffers and endianess.
966
+ */
967
+ function _checkDevice() {
968
+
969
+ device.pixelRatio = window['devicePixelRatio'] || 1;
970
+ device.iPhone = navigator.userAgent.toLowerCase().indexOf('iphone') != -1;
971
+ device.iPhone4 = (device.pixelRatio == 2 && device.iPhone);
972
+ device.iPhone5 = device.pixelRatio === 2 && device.iPhone &&
973
+ ((screen.availWidth === 320 && screen.availHeight === 568) || (screen.availWidth === 568 && screen.availHeight === 320));
974
+ device.iPad = navigator.userAgent.toLowerCase().indexOf('ipad') != -1;
975
+
976
+ if (typeof Int8Array !== 'undefined') {
977
+ device.typedArray = true;
978
+ }
979
+ else {
980
+ device.typedArray = false;
981
+ }
982
+
983
+ if (typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined' && typeof Uint32Array !== 'undefined') {
984
+ device.littleEndian = _checkIsLittleEndian();
985
+ device.LITTLE_ENDIAN = device.littleEndian;
986
+ }
987
+
988
+ device.support32bit = (typeof ArrayBuffer !== "undefined" && typeof Uint8ClampedArray !== "undefined" && typeof Int32Array !== "undefined" && device.littleEndian !== null && _checkIsUint8ClampedImageData());
989
+
990
+ navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
991
+
992
+ if (navigator.vibrate) {
993
+ device.vibration = true;
994
+ }
995
+
996
+ }
997
+
998
+ /**
999
+ * Check Little or Big Endian system.
1000
+ *
1001
+ * @author Matt DesLauriers (@mattdesl)
1002
+ */
1003
+ function _checkIsLittleEndian() {
1004
+
1005
+ let a = new ArrayBuffer(4);
1006
+ let b = new Uint8Array(a);
1007
+ let c = new Uint32Array(a);
1008
+
1009
+ b[0] = 0xa1;
1010
+ b[1] = 0xb2;
1011
+ b[2] = 0xc3;
1012
+ b[3] = 0xd4;
1013
+
1014
+ if (c[0] == 0xd4c3b2a1) {
1015
+ return true;
1016
+ }
1017
+
1018
+ if (c[0] == 0xa1b2c3d4) {
1019
+ return false;
1020
+ }
1021
+ else {
1022
+ // Could not determine endianness
1023
+ return null;
1024
+ }
1025
+
1026
+ }
1027
+
1028
+ /**
1029
+ * Test to see if ImageData uses CanvasPixelArray or Uint8ClampedArray.
1030
+ *
1031
+ * @author Matt DesLauriers (@mattdesl)
1032
+ */
1033
+ function _checkIsUint8ClampedImageData() {
1034
+
1035
+ if (Uint8ClampedArray === undefined) {
1036
+ return false;
1037
+ }
1038
+
1039
+ let elem = document.createElement('canvas');
1040
+ let ctx = elem.getContext('2d');
1041
+
1042
+ if (!ctx) {
1043
+ return false;
1044
+ }
1045
+
1046
+ let image = ctx.createImageData(1, 1);
1047
+
1048
+ return image.data instanceof Uint8ClampedArray;
1049
+
1050
+ }
1051
+
1052
+ /**
1053
+ * Check whether the host environment support 3D CSS.
1054
+ */
1055
+ function _checkCSS3D() {
1056
+
1057
+ let el = document.createElement('p');
1058
+ let has3d;
1059
+ let transforms = {
1060
+ 'webkitTransform': '-webkit-transform',
1061
+ 'OTransform': '-o-transform',
1062
+ 'msTransform': '-ms-transform',
1063
+ 'MozTransform': '-moz-transform',
1064
+ 'transform': 'transform'
1065
+ };
1066
+
1067
+ // Add it to the body to get the computed style.
1068
+ document.body.insertBefore(el, null);
1069
+
1070
+ for (let t in transforms) {
1071
+ if (el.style[t] !== undefined) {
1072
+ el.style[t] = "translate3d(1px,1px,1px)";
1073
+ has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
1074
+ }
1075
+ }
1076
+
1077
+ document.body.removeChild(el);
1078
+ device.css3D = (has3d !== undefined && has3d.length > 0 && has3d !== "none");
1079
+
1080
+ }
1081
+
1082
+ // Run the checks
1083
+ _checkOS();
1084
+ _checkAudio();
1085
+ _checkVideo();
1086
+ _checkBrowser();
1087
+ _checkCSS3D();
1088
+ _checkDevice();
1089
+ _checkFeatures();
1090
+ _checkFullScreenSupport();
1091
+ _checkInput();
1092
+
1093
+ };
1094
+
1095
+ /**
1096
+ * Check whether the host environment can play audio.
1097
+ *
1098
+ * @method canPlayAudio
1099
+ * @memberof Phaser.Device.prototype
1100
+ * @param {String} type - One of 'mp3, 'ogg', 'm4a', 'wav', 'webm' or 'opus'.
1101
+ * @return {boolean} True if the given file type is supported by the browser, otherwise false.
1102
+ */
1103
+ LibDevice.canPlayAudio = function (type) {
1104
+
1105
+ if (type === 'mp3' && this.mp3) {
1106
+ return true;
1107
+ }
1108
+ else if (type === 'ogg' && (this.ogg || this.opus)) {
1109
+ return true;
1110
+ }
1111
+ else if (type === 'm4a' && this.m4a) {
1112
+ return true;
1113
+ }
1114
+ else if (type === 'opus' && this.opus) {
1115
+ return true;
1116
+ }
1117
+ else if (type === 'wav' && this.wav) {
1118
+ return true;
1119
+ }
1120
+ else if (type === 'webm' && this.webm) {
1121
+ return true;
1122
+ }
1123
+
1124
+ return false;
1125
+
1126
+ };
1127
+
1128
+ /**
1129
+ * Check whether the host environment can play video files.
1130
+ *
1131
+ * @method canPlayVideo
1132
+ * @memberof Phaser.Device.prototype
1133
+ * @param {String} type - One of 'mp4, 'ogg', 'webm' or 'mpeg'.
1134
+ * @return {boolean} True if the given file type is supported by the browser, otherwise false.
1135
+ */
1136
+ LibDevice.canPlayVideo = function (type) {
1137
+
1138
+ if (type === 'webm' && (this.webmVideo || this.vp9Video)) {
1139
+ return true;
1140
+ }
1141
+ else if (type === 'mp4' && (this.mp4Video || this.h264Video)) {
1142
+ return true;
1143
+ }
1144
+ else if ((type === 'ogg' || type === 'ogv') && this.oggVideo) {
1145
+ return true;
1146
+ }
1147
+ else if (type === 'mpeg' && this.hlsVideo) {
1148
+ return true;
1149
+ }
1150
+
1151
+ return false;
1152
+
1153
+ };
1154
+
1155
+ /**
1156
+ * Check whether the console is open.
1157
+ * Note that this only works in Firefox with Firebug and earlier versions of Chrome.
1158
+ * It used to work in Chrome, but then they removed the ability: {@link http://src.chromium.org/viewvc/blink?view=revision&revision=151136}
1159
+ *
1160
+ * @method isConsoleOpen
1161
+ * @memberof Phaser.Device.prototype
1162
+ */
1163
+ LibDevice.isConsoleOpen = function () {
1164
+
1165
+ if (window.console && window.console['firebug']) {
1166
+ return true;
1167
+ }
1168
+
1169
+ if (window.console) {
1170
+ console.profile();
1171
+ console.profileEnd();
1172
+
1173
+ if (console.clear) {
1174
+ console.clear();
1175
+ }
1176
+
1177
+ if (console['profiles']) {
1178
+ return console['profiles'].length > 0;
1179
+ }
1180
+ }
1181
+
1182
+ return false;
1183
+
1184
+ };
1185
+
1186
+ /**
1187
+ * Detect if the host is a an Android Stock browser.
1188
+ * This is available before the device "ready" event.
1189
+ *
1190
+ * Authors might want to scale down on effects and switch to the CANVAS rendering method on those devices.
1191
+ *
1192
+ * @example
1193
+ * let defaultRenderingMode = Phaser.Device.isAndroidStockBrowser() ? Phaser.CANVAS : Phaser.AUTO;
1194
+ *
1195
+ * @method isAndroidStockBrowser
1196
+ * @memberof Phaser.Device.prototype
1197
+ */
1198
+ LibDevice.isAndroidStockBrowser = function () {
1199
+
1200
+ let matches = window.navigator.userAgent.match(/Android.*AppleWebKit\/([\d.]+)/);
1201
+ return matches && matches[1] < 537;
1202
+
1203
+ };
1204
+
1205
+ //webP check
1206
+ (function () {
1207
+ const webP = new Image();
1208
+ webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
1209
+ webP.onload = webP.onerror = function () {
1210
+ LibDevice.webP = (webP.height === 2);
1211
+ LibDevice._webPTestComplete = true;
1212
+ };
1213
+ })();
1214
+
1215
+ export default LibDevice;