2013-08-28 06:02:55 +00:00
/ * *
2013-10-01 12:54:29 +00:00
* @ author Richard Davey < rich @ photonstorm . com >
2014-02-05 05:54:25 +00:00
* @ copyright 2014 Photon Storm Ltd .
2013-10-01 12:54:29 +00:00
* @ license { @ link https : //github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
* /
/ * *
2014-11-14 02:06:45 +00:00
* @ classdesc
* Detects device support capabilities and is responsible for device intialization - see { @ link Phaser . Device . whenReady whenReady } .
2013-10-01 12:54:29 +00:00
*
2014-11-14 02:06:45 +00:00
* This class represents a singleton object that can be accessed directly as ` game.device `
* ( or , as a fallback , ` Phaser.Device ` when a game instance is not available ) without the need to instantiate it .
*
* Unless otherwise noted the device capabilities are only guaranteed after initialization . Initialization
* occurs automatically and is guaranteed complete before { @ link Phaser . Game } begins its "boot" phase .
* Feature detection can be modified in the { @ link Phaser . Device . onInitialized onInitialized } signal .
*
* When checking features using the exposed properties only the * truth - iness * of the value should be relied upon
* unless the documentation states otherwise : properties may return ` false ` , ` '' ` , ` null ` , or even ` undefined `
* when indicating the lack of a feature .
*
* Uses elements from System . js by MrDoob and Modernizr
*
* @ description
* It is not possible to instantiate the Device class manually .
*
* @ class
* @ protected
2013-08-28 06:02:55 +00:00
* /
2014-11-14 02:06:45 +00:00
Phaser . Device = function ( ) {
2014-02-25 21:16:56 +00:00
/ * *
2014-11-14 02:06:45 +00:00
* The time the device became ready .
* @ property { integer } deviceReadyAt
* @ protected
2014-02-25 21:16:56 +00:00
* /
2014-11-14 02:06:45 +00:00
this . deviceReadyAt = 0 ;
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
/ * *
* The time as which initialization has completed .
* @ property { boolean } initialized
* @ protected
* /
this . initialized = false ;
// Browser / Host / Operating System
2013-08-28 06:02:55 +00:00
/ * *
2014-11-14 02:06:45 +00:00
* @ property { boolean } desktop - Is running on a desktop ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . desktop = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } iOS - Is running on iOS ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . iOS = false ;
2013-11-26 15:29:03 +00:00
/ * *
* @ property { boolean } cocoonJS - Is the game running under CocoonJS ?
* @ default
* /
this . cocoonJS = false ;
2014-08-11 16:33:06 +00:00
2014-08-30 00:58:19 +00:00
/ * *
* @ property { boolean } cocoonJSApp - Is this game running with CocoonJS . App ?
* @ default
* /
this . cocoonJSApp = false ;
2014-08-11 16:33:06 +00:00
/ * *
* @ property { boolean } cordova - Is the game running under Apache Cordova ?
* @ default
* /
this . cordova = false ;
2014-08-21 21:37:51 +00:00
2014-08-28 02:00:14 +00:00
/ * *
* @ property { boolean } node - Is the game running under Node . js ?
* @ default
* /
this . node = false ;
2014-08-21 21:37:51 +00:00
/ * *
* @ property { boolean } nodeWebkit - Is the game running under Node - Webkit ?
* @ default
2014-08-22 00:37:27 +00:00
* /
2014-08-21 21:37:51 +00:00
this . nodeWebkit = false ;
2013-12-24 03:18:55 +00:00
/ * *
2014-04-14 15:40:14 +00:00
* @ property { boolean } ejecta - Is the game running under Ejecta ?
* @ default
* /
2013-12-24 03:18:55 +00:00
this . ejecta = false ;
2014-04-14 15:40:14 +00:00
/ * *
* @ property { boolean } crosswalk - Is the game running under the Intel Crosswalk XDK ?
* @ default
* /
this . crosswalk = false ;
2013-08-28 06:02:55 +00:00
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } android - Is running on android ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . android = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } chromeOS - Is running on chromeOS ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . chromeOS = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } linux - Is running on linux ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . linux = false ;
/ * *
2013-10-02 07:46:42 +00:00
* @ property { boolean } macOS - Is running on macOS ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . macOS = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } windows - Is running on windows ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . windows = false ;
2014-03-02 10:56:39 +00:00
/ * *
* @ property { boolean } windowsPhone - Is running on a Windows Phone ?
* @ default
* /
this . windowsPhone = false ;
2013-08-28 06:02:55 +00:00
// Features
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } canvas - Is canvas available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . canvas = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } file - Is file available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . file = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } fileSystem - Is fileSystem available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . fileSystem = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } localStorage - Is localStorage available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . localStorage = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } webGL - Is webGL available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . webGL = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } worker - Is worker available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . worker = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } css3D - Is css3D available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . css3D = false ;
2014-03-23 07:59:28 +00:00
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } pointerLock - Is Pointer Lock available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-09-09 18:59:31 +00:00
* /
this . pointerLock = false ;
2013-11-20 02:28:28 +00:00
/ * *
* @ property { boolean } typedArray - Does the browser support TypedArrays ?
* @ default
* /
this . typedArray = false ;
2013-12-13 14:04:14 +00:00
/ * *
* @ property { boolean } vibration - Does the device support the Vibration API ?
* @ default
* /
this . vibration = false ;
2014-03-18 15:11:48 +00:00
/ * *
* @ property { boolean } getUserMedia - Does the device support the getUserMedia API ?
* @ default
* /
this . getUserMedia = false ;
2014-01-08 11:21:30 +00:00
/ * *
* @ property { boolean } quirksMode - Is the browser running in strict mode ( false ) or quirks mode ? ( true )
* @ default
* /
this . quirksMode = false ;
2014-11-12 21:24:03 +00:00
// Input
/ * *
* @ property { boolean } touch - Is touch available ?
* @ default
* /
this . touch = false ;
/ * *
* @ property { boolean } mspointer - Is mspointer available ?
* @ default
* /
this . mspointer = false ;
/ * *
* @ property { string | null } wheelType - The newest type of Wheel / Scroll event supported : 'wheel' , 'mousewheel' , 'DOMMouseScroll'
* @ default
* @ protected
* /
this . wheelEvent = null ;
2013-08-28 06:02:55 +00:00
// Browser
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } arora - Set to true if running in Arora .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . arora = false ;
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } chrome - Set to true if running in Chrome .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . chrome = false ;
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } epiphany - Set to true if running in Epiphany .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . epiphany = false ;
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } firefox - Set to true if running in Firefox .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . firefox = false ;
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } ie - Set to true if running in Internet Explorer .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . ie = false ;
/ * *
2014-02-10 02:23:45 +00:00
* @ 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 .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . ieVersion = 0 ;
2013-12-13 14:04:14 +00:00
/ * *
* @ property { boolean } trident - Set to true if running a Trident version of Internet Explorer ( IE11 + )
* @ default
* /
this . trident = false ;
/ * *
2014-11-14 02:06:45 +00:00
* @ 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}
2013-12-13 14:04:14 +00:00
* @ default
* /
this . tridentVersion = 0 ;
2013-08-28 06:02:55 +00:00
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } mobileSafari - Set to true if running in Mobile Safari .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . mobileSafari = false ;
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } midori - Set to true if running in Midori .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . midori = false ;
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } opera - Set to true if running in Opera .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . opera = false ;
/ * *
2013-11-20 02:28:28 +00:00
* @ property { boolean } safari - Set to true if running in Safari .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . safari = false ;
2013-11-20 02:28:28 +00:00
/ * *
* @ property { boolean } webApp - Set to true if running as a WebApp , i . e . within a WebView
* @ default
* /
2013-08-28 06:02:55 +00:00
this . webApp = false ;
2013-12-17 05:07:00 +00:00
/ * *
* @ property { boolean } silk - Set to true if running in the Silk browser ( as used on the Amazon Kindle )
* @ default
* /
this . silk = false ;
2013-08-28 06:02:55 +00:00
// Audio
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } audioData - Are Audio tags available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . audioData = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } webAudio - Is the WebAudio API available ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . webAudio = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } ogg - Can this device play ogg files ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . ogg = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } opus - Can this device play opus files ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . opus = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } mp3 - Can this device play mp3 files ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . mp3 = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } wav - Can this device play wav files ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . wav = false ;
2013-11-20 02:28:28 +00:00
2013-08-28 06:02:55 +00:00
/ * *
* Can this device play m4a files ?
2013-10-01 15:39:39 +00:00
* @ property { boolean } m4a - True if this device can play m4a files .
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . m4a = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } webm - Can this device play webm files ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . webm = false ;
// Device
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } iPhone - Is running on iPhone ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . iPhone = false ;
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } iPhone4 - Is running on iPhone4 ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . iPhone4 = false ;
2014-03-23 07:59:28 +00:00
/ * *
2013-10-01 15:39:39 +00:00
* @ property { boolean } iPad - Is running on iPad ?
2013-10-01 12:54:29 +00:00
* @ default
2013-08-28 06:02:55 +00:00
* /
this . iPad = false ;
/ * *
2013-10-01 12:54:29 +00:00
* @ property { number } pixelRatio - PixelRatio of the host device ?
* @ default
2013-08-28 06:02:55 +00:00
* /
this . pixelRatio = 0 ;
2013-11-18 20:27:40 +00:00
/ * *
* @ property { boolean } littleEndian - Is the device big or little endian ? ( only detected if the browser supports TypedArrays )
* @ default
* /
this . littleEndian = false ;
2014-11-14 02:06:45 +00:00
/ * *
* @ property { boolean } LITTLE _ENDIAN - Same value as ` littleEndian ` .
* @ default
* /
this . LITTLE _ENDIAN = false ;
2014-04-24 02:49:49 +00:00
/ * *
* @ property { boolean } support32bit - Does the device context support 32 bit pixel manipulation using array buffer views ?
* @ default
* /
this . support32bit = false ;
2014-02-25 21:16:56 +00:00
/ * *
* @ property { boolean } fullscreen - Does the browser support the Full Screen API ?
* @ default
* /
this . fullscreen = false ;
/ * *
* @ property { string } requestFullscreen - If the browser supports the Full Screen API this holds the call you need to use to activate it .
* @ default
* /
this . requestFullscreen = '' ;
/ * *
* @ property { string } cancelFullscreen - If the browser supports the Full Screen API this holds the call you need to use to cancel it .
* @ default
* /
this . cancelFullscreen = '' ;
/ * *
* @ property { boolean } fullscreenKeyboard - Does the browser support access to the Keyboard during Full Screen mode ?
* @ default
* /
this . fullscreenKeyboard = false ;
2014-11-14 02:06:45 +00:00
} ;
// Device is really a singleton/static entity; instantiate it
// and add new methods directly sans-prototype.
Phaser . Device = new Phaser . Device ( ) ;
/ * *
* This signal is dispatched after device initialization occurs but before any of the ready
* callbacks ( see { @ link Phaser . Device . whenReady whenReady } ) have been invoked .
*
* Local "patching" for a particular device can / should be done in this event .
*
* _Note _ : This signal is removed after the device has been readied ; if a handler has not been
* added _before _ ` new Phaser.Game(..) ` it is probably too late .
*
* @ type { ? Phaser . Signal }
* @ static
* /
Phaser . Device . onInitialized = new Phaser . Signal ( ) ;
/ * *
* Add a device - ready handler and ensure the device ready sequence is started .
*
* Phaser . Device will _not _ activate or initialize until at least one ` whenReady ` handler is added ,
* which is normally done automatically be calling ` new Phaser.Game(..) ` .
*
* The handler is invoked when the device is considered "ready" , which may be immediately
* if the device is already "ready" . See { @ link Phaser . Device # deviceReadyAt deviceReadyAt } .
*
* @ method
* @ param { function } handler - Callback to invoke when the device is ready
* @ param { object } [ context ] - Context in which to invoke the handler
* /
Phaser . Device . whenReady = function ( callback , context ) {
var readyCheck = this . _readyCheck ;
if ( this . deviceReadyAt || ! readyCheck )
{
callback . call ( context ) ;
}
else if ( readyCheck . _monitor )
{
readyCheck . _queue . push ( [ callback , context ] ) ;
}
else
{
readyCheck . _monitor = readyCheck . bind ( this ) ;
readyCheck . _queue = [ ] ;
readyCheck . _queue . push ( [ callback , context ] ) ;
var cordova = typeof window . cordova !== 'undefined' ;
var cocoonJS = navigator [ 'isCocoonJS' ] ;
if ( document . readyState === 'complete' || document . readyState === 'interactive' )
{
// Why is there an additional timeout here?
window . setTimeout ( readyCheck . _monitor , 0 ) ;
}
else if ( cordova && ! cocoonJS )
{
// Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready
// Cordova, but NOT Cocoon?
document . addEventListener ( 'deviceready' , readyCheck . _monitor , false ) ;
}
else
{
document . addEventListener ( 'DOMContentLoaded' , readyCheck . _monitor , false ) ;
window . addEventListener ( 'load' , readyCheck . _monitor , false ) ;
}
}
2014-03-23 07:59:28 +00:00
2013-08-28 06:02:55 +00:00
} ;
2014-11-14 02:06:45 +00:00
/ * *
* Internal method used for checking when the device is ready .
* This function is removed from Phaser . Device when the device becomes ready .
*
* @ method
* @ private
* /
Phaser . Device . _readyCheck = function ( ) {
var readyCheck = this . _readyCheck ;
if ( ! document . body )
{
window . setTimeout ( readyCheck . _monitor , 20 ) ;
}
else if ( ! this . deviceReadyAt )
{
this . deviceReadyAt = Date . now ( ) ;
document . removeEventListener ( 'deviceready' , readyCheck . _monitor ) ;
document . removeEventListener ( 'DOMContentLoaded' , readyCheck . _monitor ) ;
window . removeEventListener ( 'load' , readyCheck . _monitor ) ;
this . _initialize ( ) ;
this . initialized = true ;
2014-04-25 01:45:27 +00:00
2014-11-14 02:06:45 +00:00
this . onInitialized . dispatch ( this ) ;
var item ;
while ( ( item = readyCheck . _queue . shift ( ) ) )
{
var callback = item [ 0 ] ;
var context = item [ 1 ] ;
callback . call ( context ) ;
}
// Remove no longer useful methods and properties.
this . _readyCheck = null ;
this . _initialize = null ;
this . onInitialized = null ;
}
} ;
/ * *
* Internal method to initialize the capability checks .
* This function is removed from Phaser . Device once the device is initialized .
*
* @ method
* @ private
* /
Phaser . Device . _initialize = function ( ) {
var device = this ;
2013-08-28 06:02:55 +00:00
/ * *
* Check which OS is game running on .
* /
2014-11-14 02:06:45 +00:00
function _checkOS ( ) {
2013-08-28 06:02:55 +00:00
var ua = navigator . userAgent ;
2014-07-31 13:40:59 +00:00
if ( /Playstation Vita/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . vita = true ;
2014-07-31 13:40:59 +00:00
}
else if ( /Kindle/ . test ( ua ) || /\bKF[A-Z][A-Z]+/ . test ( ua ) || /Silk.*Mobile Safari/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . kindle = true ;
2014-07-31 13:40:59 +00:00
// This will NOT detect early generations of Kindle Fire, I think there is no reliable way...
// 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"
}
else if ( /Android/ . test ( ua ) )
2013-12-17 05:07:00 +00:00
{
2014-11-14 02:06:45 +00:00
device . android = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /CrOS/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . chromeOS = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /iP[ao]d|iPhone/i . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . iOS = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Linux/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . linux = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Mac OS/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . macOS = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Windows/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . windows = true ;
2014-03-02 10:56:39 +00:00
if ( /Windows Phone/i . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . windowsPhone = true ;
2014-03-02 10:56:39 +00:00
}
2013-08-28 06:02:55 +00:00
}
2014-11-14 02:06:45 +00:00
if ( device . windows || device . macOS || ( device . linux && device . silk === false ) || device . chromeOS )
2013-12-17 05:07:00 +00:00
{
2014-11-14 02:06:45 +00:00
device . desktop = true ;
2013-08-28 06:02:55 +00:00
}
2014-03-02 10:56:39 +00:00
// Windows Phone / Table reset
2014-11-14 02:06:45 +00:00
if ( device . windowsPhone || ( ( /Windows NT/i . test ( ua ) ) && ( /Touch/i . test ( ua ) ) ) )
2014-03-02 10:56:39 +00:00
{
2014-11-14 02:06:45 +00:00
device . desktop = false ;
2014-03-02 10:56:39 +00:00
}
2014-11-14 02:06:45 +00:00
}
2013-08-28 06:02:55 +00:00
/ * *
* Check HTML5 features of the host environment .
* /
2014-11-14 02:06:45 +00:00
function _checkFeatures ( ) {
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
device . canvas = ! ! window [ 'CanvasRenderingContext2D' ] || device . cocoonJS ;
2013-08-28 06:02:55 +00:00
try {
2014-11-14 02:06:45 +00:00
device . localStorage = ! ! localStorage . getItem ;
2013-08-28 06:02:55 +00:00
} catch ( error ) {
2014-11-14 02:06:45 +00:00
device . localStorage = false ;
2013-08-28 06:02:55 +00:00
}
2014-11-14 02:06:45 +00:00
device . file = ! ! window [ 'File' ] && ! ! window [ 'FileReader' ] && ! ! window [ 'FileList' ] && ! ! window [ 'Blob' ] ;
device . fileSystem = ! ! window [ 'requestFileSystem' ] ;
device . webGL = ( function ( ) { try { var 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 ; } } ) ( ) ;
2013-10-23 14:13:21 +00:00
2014-11-14 02:06:45 +00:00
if ( device . webGL === null || device . webGL === false )
2013-10-23 14:13:21 +00:00
{
2014-11-14 02:06:45 +00:00
device . webGL = false ;
2013-10-23 14:13:21 +00:00
}
else
{
2014-11-14 02:06:45 +00:00
device . webGL = true ;
2013-10-23 14:13:21 +00:00
}
2014-11-14 02:06:45 +00:00
device . worker = ! ! window [ 'Worker' ] ;
2014-03-23 07:59:28 +00:00
2014-11-14 02:06:45 +00:00
device . pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document ;
2014-11-12 21:24:03 +00:00
2014-11-14 02:06:45 +00:00
device . quirksMode = ( document . compatMode === 'CSS1Compat' ) ? false : true ;
2014-11-12 21:24:03 +00:00
2014-11-14 02:06:45 +00:00
device . getUserMedia = ! ! ( navigator . getUserMedia || navigator . webkitGetUserMedia || navigator . mozGetUserMedia || navigator . msGetUserMedia ) ;
2014-11-12 21:24:03 +00:00
2014-11-14 02:06:45 +00:00
}
2014-11-12 21:24:03 +00:00
/ * *
* Checks / configures various input .
* /
2014-11-14 02:06:45 +00:00
function _checkInput ( ) {
2014-11-12 21:24:03 +00:00
if ( 'ontouchstart' in document . documentElement ||
( window . navigator . maxTouchPoints && window . navigator . maxTouchPoints > 1 ) )
2013-12-17 05:07:00 +00:00
{
2014-11-14 02:06:45 +00:00
device . touch = true ;
2013-08-28 06:02:55 +00:00
}
2013-12-17 05:07:00 +00:00
if ( window . navigator . msPointerEnabled || window . navigator . pointerEnabled )
{
2014-11-14 02:06:45 +00:00
device . mspointer = true ;
2013-08-28 06:02:55 +00:00
}
2014-03-23 07:59:28 +00:00
2014-11-14 02:06:45 +00:00
if ( ! device . cocoonJS )
2014-11-12 21:24:03 +00:00
{
// See https://developer.mozilla.org/en-US/docs/Web/Events/wheel
2014-11-14 02:06:45 +00:00
if ( 'onwheel' in window || ( device . ie && 'WheelEvent' in window ) )
2014-11-12 21:24:03 +00:00
{
// DOM3 Wheel Event: FF 17+, IE 9+, Chrome 31+, Safari 7+
2014-11-14 02:06:45 +00:00
device . wheelEvent = 'wheel' ;
2014-11-12 21:24:03 +00:00
}
else if ( 'onmousewheel' in window )
{
// Non-FF legacy: IE 6-9, Chrome 1-31, Safari 5-7.
2014-11-14 02:06:45 +00:00
device . wheelEvent = 'mousewheel' ;
2014-11-12 21:24:03 +00:00
}
2014-11-14 02:06:45 +00:00
else if ( device . firefox && 'MouseScrollEvent' in window )
2014-11-12 21:24:03 +00:00
{
// FF prior to 17. This should probably be scrubbed.
2014-11-14 02:06:45 +00:00
device . wheelEvent = 'DOMMouseScroll' ;
2014-11-12 21:24:03 +00:00
}
}
2014-02-25 21:16:56 +00:00
2014-11-14 02:06:45 +00:00
}
2014-02-25 21:16:56 +00:00
/ * *
* Checks for support of the Full Screen API .
* /
2014-11-14 02:06:45 +00:00
function _checkFullScreenSupport ( ) {
2014-02-25 21:16:56 +00:00
var fs = [
'requestFullscreen' ,
'requestFullScreen' ,
'webkitRequestFullscreen' ,
'webkitRequestFullScreen' ,
'msRequestFullscreen' ,
'msRequestFullScreen' ,
'mozRequestFullScreen' ,
'mozRequestFullscreen'
] ;
2014-11-14 02:06:45 +00:00
var element = document . createElement ( 'div' ) ;
2014-02-25 21:16:56 +00:00
for ( var i = 0 ; i < fs . length ; i ++ )
{
2014-11-14 02:06:45 +00:00
if ( element [ fs [ i ] ] )
2014-02-25 21:16:56 +00:00
{
2014-11-14 02:06:45 +00:00
device . fullscreen = true ;
device . requestFullscreen = fs [ i ] ;
2014-07-01 15:50:33 +00:00
break ;
2014-02-25 21:16:56 +00:00
}
}
var cfs = [
'cancelFullScreen' ,
'exitFullscreen' ,
'webkitCancelFullScreen' ,
'webkitExitFullscreen' ,
'msCancelFullScreen' ,
'msExitFullscreen' ,
'mozCancelFullScreen' ,
'mozExitFullscreen'
] ;
2014-11-14 02:06:45 +00:00
if ( device . fullscreen )
2014-02-25 21:16:56 +00:00
{
for ( var i = 0 ; i < cfs . length ; i ++ )
{
2014-07-01 14:45:38 +00:00
if ( document [ cfs [ i ] ] )
2014-02-25 21:16:56 +00:00
{
2014-11-14 02:06:45 +00:00
device . cancelFullscreen = cfs [ i ] ;
2014-07-01 15:50:33 +00:00
break ;
2014-02-25 21:16:56 +00:00
}
}
}
// Keyboard Input?
if ( window [ 'Element' ] && Element [ 'ALLOW_KEYBOARD_INPUT' ] )
{
2014-11-14 02:06:45 +00:00
device . fullscreenKeyboard = true ;
2014-02-25 21:16:56 +00:00
}
2014-11-14 02:06:45 +00:00
}
2013-08-28 06:02:55 +00:00
/ * *
* Check what browser is game running in .
* /
2014-11-14 02:06:45 +00:00
function _checkBrowser ( ) {
2013-08-28 06:02:55 +00:00
var ua = navigator . userAgent ;
2013-12-17 05:07:00 +00:00
if ( /Arora/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . arora = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Chrome/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . chrome = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Epiphany/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . epiphany = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Firefox/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . firefox = true ;
2013-12-17 05:07:00 +00:00
}
2014-11-14 02:06:45 +00:00
else if ( /AppleWebKit/ . test ( ua ) && device . iOS )
2013-12-17 05:07:00 +00:00
{
2014-11-14 02:06:45 +00:00
device . mobileSafari = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /MSIE (\d+\.\d+);/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . ie = true ;
device . ieVersion = parseInt ( RegExp . $1 , 10 ) ;
2013-12-17 05:07:00 +00:00
}
else if ( /Midori/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . midori = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Opera/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . opera = true ;
2013-12-17 05:07:00 +00:00
}
else if ( /Safari/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . safari = true ;
2013-12-17 05:07:00 +00:00
}
2014-03-16 00:39:42 +00:00
else if ( /Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/ . test ( ua ) )
2013-12-17 05:07:00 +00:00
{
2014-11-14 02:06:45 +00:00
device . ie = true ;
device . trident = true ;
device . tridentVersion = parseInt ( RegExp . $1 , 10 ) ;
device . ieVersion = parseInt ( RegExp . $3 , 10 ) ;
2013-08-28 06:02:55 +00:00
}
2014-05-08 04:28:27 +00:00
//Silk gets its own if clause because its ua also contains 'Safari'
if ( /Silk/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . silk = true ;
2014-05-08 04:28:27 +00:00
}
2013-08-28 06:02:55 +00:00
// WebApp mode in iOS
2013-12-17 05:07:00 +00:00
if ( navigator [ 'standalone' ] )
{
2014-11-14 02:06:45 +00:00
device . webApp = true ;
2013-08-28 06:02:55 +00:00
}
2014-08-11 16:33:06 +00:00
if ( typeof window . cordova !== "undefined" )
{
2014-11-14 02:06:45 +00:00
device . cordova = true ;
2014-08-11 16:33:06 +00:00
}
2014-08-21 21:37:51 +00:00
2014-08-31 09:16:53 +00:00
if ( typeof process !== "undefined" && typeof require !== "undefined" )
2014-08-21 21:37:51 +00:00
{
2014-11-14 02:06:45 +00:00
device . node = true ;
2014-08-28 02:00:14 +00:00
}
2014-11-14 02:06:45 +00:00
if ( device . node )
2014-08-28 02:00:14 +00:00
{
try {
2014-11-14 02:06:45 +00:00
device . nodeWebkit = ( typeof require ( 'nw.gui' ) !== "undefined" ) ;
2014-08-31 09:16:53 +00:00
}
catch ( error )
{
2014-11-14 02:06:45 +00:00
device . nodeWebkit = false ;
2014-08-28 02:00:14 +00:00
}
2014-08-21 21:37:51 +00:00
}
2013-12-17 05:07:00 +00:00
if ( navigator [ 'isCocoonJS' ] )
{
2014-11-14 02:06:45 +00:00
device . cocoonJS = true ;
2013-11-26 15:29:03 +00:00
}
2014-08-30 00:58:19 +00:00
2014-11-14 02:06:45 +00:00
if ( device . cocoonJS )
2014-08-30 00:58:19 +00:00
{
try {
2014-11-14 02:06:45 +00:00
device . cocoonJSApp = ( typeof CocoonJS !== "undefined" ) ;
2014-08-31 09:16:53 +00:00
}
catch ( error )
{
2014-11-14 02:06:45 +00:00
device . cocoonJSApp = false ;
2014-08-30 00:58:19 +00:00
}
}
2013-11-26 15:29:03 +00:00
2013-12-24 03:18:55 +00:00
if ( typeof window . ejecta !== "undefined" )
{
2014-11-14 02:06:45 +00:00
device . ejecta = true ;
2013-12-24 03:18:55 +00:00
}
2014-04-14 15:40:14 +00:00
if ( /Crosswalk/ . test ( ua ) )
{
2014-11-14 02:06:45 +00:00
device . crosswalk = true ;
2014-04-14 15:40:14 +00:00
}
2014-11-14 02:06:45 +00:00
}
2013-08-28 06:02:55 +00:00
/ * *
* Check audio support .
* /
2014-11-14 02:06:45 +00:00
function _checkAudio ( ) {
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
device . audioData = ! ! ( window [ 'Audio' ] ) ;
device . webAudio = ! ! ( window [ 'webkitAudioContext' ] || window [ 'AudioContext' ] ) ;
2013-08-28 06:02:55 +00:00
var audioElement = document . createElement ( 'audio' ) ;
var result = false ;
try {
if ( result = ! ! audioElement . canPlayType ) {
2014-03-23 07:59:28 +00:00
2013-08-28 06:02:55 +00:00
if ( audioElement . canPlayType ( 'audio/ogg; codecs="vorbis"' ) . replace ( /^no$/ , '' ) ) {
2014-11-14 02:06:45 +00:00
device . ogg = true ;
2013-08-28 06:02:55 +00:00
}
2014-10-13 12:52:41 +00:00
if ( audioElement . canPlayType ( 'audio/ogg; codecs="opus"' ) . replace ( /^no$/ , '' ) || audioElement . canPlayType ( 'audio/opus;' ) . replace ( /^no$/ , '' ) ) {
2014-11-14 02:06:45 +00:00
device . opus = true ;
2013-08-28 06:02:55 +00:00
}
if ( audioElement . canPlayType ( 'audio/mpeg;' ) . replace ( /^no$/ , '' ) ) {
2014-11-14 02:06:45 +00:00
device . mp3 = true ;
2013-08-28 06:02:55 +00:00
}
// Mimetypes accepted:
// developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
// bit.ly/iphoneoscodecs
if ( audioElement . canPlayType ( 'audio/wav; codecs="1"' ) . replace ( /^no$/ , '' ) ) {
2014-11-14 02:06:45 +00:00
device . wav = true ;
2013-08-28 06:02:55 +00:00
}
if ( audioElement . canPlayType ( 'audio/x-m4a;' ) || audioElement . canPlayType ( 'audio/aac;' ) . replace ( /^no$/ , '' ) ) {
2014-11-14 02:06:45 +00:00
device . m4a = true ;
2013-08-28 06:02:55 +00:00
}
if ( audioElement . canPlayType ( 'audio/webm; codecs="vorbis"' ) . replace ( /^no$/ , '' ) ) {
2014-11-14 02:06:45 +00:00
device . webm = true ;
2013-08-28 06:02:55 +00:00
}
}
} catch ( e ) {
}
2014-11-14 02:06:45 +00:00
}
2013-08-28 06:02:55 +00:00
/ * *
2014-04-23 22:35:36 +00:00
* Check PixelRatio , iOS device , Vibration API , ArrayBuffers and endianess .
2013-08-28 06:02:55 +00:00
* /
2014-11-14 02:06:45 +00:00
function _checkDevice ( ) {
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
device . pixelRatio = window [ 'devicePixelRatio' ] || 1 ;
device . iPhone = navigator . userAgent . toLowerCase ( ) . indexOf ( 'iphone' ) != - 1 ;
device . iPhone4 = ( device . pixelRatio == 2 && device . iPhone ) ;
device . iPad = navigator . userAgent . toLowerCase ( ) . indexOf ( 'ipad' ) != - 1 ;
2013-08-28 06:02:55 +00:00
2013-11-18 20:27:40 +00:00
if ( typeof Int8Array !== 'undefined' )
{
2014-11-14 02:06:45 +00:00
device . typedArray = true ;
2013-11-20 02:28:28 +00:00
}
else
{
2014-11-14 02:06:45 +00:00
device . typedArray = false ;
2013-11-18 20:27:40 +00:00
}
2014-04-23 22:35:36 +00:00
if ( typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined' && typeof Uint32Array !== 'undefined' )
{
2014-11-14 02:06:45 +00:00
device . littleEndian = _checkIsLittleEndian ( this ) ;
device . LITTLE _ENDIAN = device . littleEndian ;
2014-04-23 22:35:36 +00:00
}
2014-11-14 02:06:45 +00:00
device . support32bit = ( typeof ArrayBuffer !== "undefined" && typeof Uint8ClampedArray !== "undefined" && typeof Int32Array !== "undefined" && device . littleEndian !== null && _checkIsUint8ClampedImageData ( this ) ) ;
2014-04-24 02:49:49 +00:00
2013-12-13 14:04:14 +00:00
navigator . vibrate = navigator . vibrate || navigator . webkitVibrate || navigator . mozVibrate || navigator . msVibrate ;
2014-03-23 07:59:28 +00:00
2013-12-13 14:04:14 +00:00
if ( navigator . vibrate )
{
2014-11-14 02:06:45 +00:00
device . vibration = true ;
2013-12-13 14:04:14 +00:00
}
2014-11-14 02:06:45 +00:00
}
2013-08-28 06:02:55 +00:00
2014-04-23 22:35:36 +00:00
/ * *
* Check Little or Big Endian system .
2014-11-14 02:06:45 +00:00
*
2014-04-23 22:35:36 +00:00
* @ author Matt DesLauriers ( @ mattdesl )
* /
2014-11-14 02:06:45 +00:00
function _checkIsLittleEndian ( ) {
2014-04-23 22:35:36 +00:00
var a = new ArrayBuffer ( 4 ) ;
var b = new Uint8Array ( a ) ;
var c = new Uint32Array ( a ) ;
b [ 0 ] = 0xa1 ;
b [ 1 ] = 0xb2 ;
b [ 2 ] = 0xc3 ;
b [ 3 ] = 0xd4 ;
if ( c [ 0 ] == 0xd4c3b2a1 )
{
return true ;
}
if ( c [ 0 ] == 0xa1b2c3d4 )
{
return false ;
}
else
{
// Could not determine endianness
return null ;
}
2014-11-14 02:06:45 +00:00
}
2014-04-23 22:35:36 +00:00
2014-04-24 02:49:49 +00:00
/ * *
* Test to see if ImageData uses CanvasPixelArray or Uint8ClampedArray .
2014-11-14 02:06:45 +00:00
*
2014-04-24 02:49:49 +00:00
* @ author Matt DesLauriers ( @ mattdesl )
* /
2014-11-14 02:06:45 +00:00
function _checkIsUint8ClampedImageData ( ) {
2014-04-24 02:49:49 +00:00
if ( typeof Uint8ClampedArray === "undefined" )
{
return false ;
}
var elem = document . createElement ( 'canvas' ) ;
var ctx = elem . getContext ( '2d' ) ;
if ( ! ctx )
{
return false ;
}
var image = ctx . createImageData ( 1 , 1 ) ;
2014-07-23 14:21:06 +00:00
2014-04-24 02:49:49 +00:00
return image . data instanceof Uint8ClampedArray ;
2014-11-14 02:06:45 +00:00
}
2014-04-24 02:49:49 +00:00
2013-08-28 06:02:55 +00:00
/ * *
* Check whether the host environment support 3 D CSS .
* /
2014-11-14 02:06:45 +00:00
function _checkCSS3D ( ) {
2013-10-03 00:21:08 +00:00
2013-08-28 06:02:55 +00:00
var el = document . createElement ( 'p' ) ;
var has3d ;
var transforms = {
'webkitTransform' : '-webkit-transform' ,
'OTransform' : '-o-transform' ,
'msTransform' : '-ms-transform' ,
'MozTransform' : '-moz-transform' ,
'transform' : 'transform'
} ;
2013-10-03 00:21:08 +00:00
2013-08-28 06:02:55 +00:00
// Add it to the body to get the computed style.
document . body . insertBefore ( el , null ) ;
2013-12-17 05:07:00 +00:00
for ( var t in transforms )
{
if ( el . style [ t ] !== undefined )
{
2013-08-28 06:02:55 +00:00
el . style [ t ] = "translate3d(1px,1px,1px)" ;
has3d = window . getComputedStyle ( el ) . getPropertyValue ( transforms [ t ] ) ;
}
}
2014-03-23 07:59:28 +00:00
2013-08-28 06:02:55 +00:00
document . body . removeChild ( el ) ;
2014-11-14 02:06:45 +00:00
device . css3D = ( has3d !== undefined && has3d . length > 0 && has3d !== "none" ) ;
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
}
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
// Run the checks
_checkOS ( this ) ;
_checkAudio ( this ) ;
_checkBrowser ( this ) ;
_checkCSS3D ( this ) ;
_checkDevice ( this ) ;
_checkFeatures ( this ) ;
_checkFullScreenSupport ( this ) ;
_checkInput ( this ) ;
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
} ;
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
/ * *
* Check whether the host environment can play audio .
*
* @ method canPlayAudio
* @ memberof Phaser . Device . prototype
* @ param { string } type - One of 'mp3, ' ogg ', ' m4a ', ' wav ', ' webm ' or ' opus ' .
* @ return { boolean } True if the given file type is supported by the browser , otherwise false .
* /
Phaser . Device . canPlayAudio = function ( type ) {
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
if ( type == 'mp3' && this . mp3 )
{
return true ;
}
else if ( type == 'ogg' && ( this . ogg || this . opus ) )
{
return true ;
}
else if ( type == 'm4a' && this . m4a )
{
return true ;
}
else if ( type == 'opus' && this . opus )
{
return true ;
}
else if ( type == 'wav' && this . wav )
{
return true ;
}
else if ( type == 'webm' && this . webm )
{
return true ;
}
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
return false ;
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
} ;
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
/ * *
* Check whether the console is open .
* Note that this only works in Firefox with Firebug and earlier versions of Chrome .
* It used to work in Chrome , but then they removed the ability : { @ link http : //src.chromium.org/viewvc/blink?view=revision&revision=151136}
*
* @ method isConsoleOpen
* @ memberof Phaser . Device . prototype
* /
Phaser . Device . isConsoleOpen = function ( ) {
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
if ( window . console && window . console [ 'firebug' ] )
{
return true ;
}
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
if ( window . console )
{
console . profile ( ) ;
console . profileEnd ( ) ;
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
if ( console . clear )
{
console . clear ( ) ;
}
2013-08-28 06:02:55 +00:00
2014-11-14 02:06:45 +00:00
if ( console [ 'profiles' ] )
{
return console [ 'profiles' ] . length > 0 ;
}
2013-08-28 06:02:55 +00:00
}
2014-11-14 02:06:45 +00:00
return false ;
2013-12-30 16:54:00 +00:00
2014-11-14 02:06:45 +00:00
} ;
2014-07-10 16:00:29 +00:00
/ * *
2014-11-14 02:06:45 +00:00
* Detect if the host is a an Android Stock browser .
* This is available before the device "ready" event .
*
* Authors might want to scale down on effects and switch to the CANVAS rendering method on those devices .
*
* @ example
* var defaultRenderingMode = Phaser . Device . isAndroidStockBrowser ( ) ? Phaser . CANVAS : Phaser . AUTO ;
2014-07-10 16:00:29 +00:00
*
2014-11-14 02:06:45 +00:00
* @ method isAndroidStockBrowser
* @ memberof Phaser . Device . prototype
2014-07-10 16:00:29 +00:00
* /
Phaser . Device . isAndroidStockBrowser = function ( )
{
var matches = window . navigator . userAgent . match ( /Android.*AppleWebKit\/([\d.]+)/ ) ;
return matches && matches [ 1 ] < 537 ;
} ;