All files / mobile.startup Browser.js

96.66% Statements 29/30
93.75% Branches 15/16
100% Functions 7/7
96.66% Lines 29/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112  1x                               3x 41x   41x 41x 24x   17x   3x 3x                     10x 10x     1x                     14x 14x   14x 8x         4x   2x   2x         6x                     2x     2x                 1x             1x   18x 1x 1x   18x     1x  
var
	util = require( './util' ),
	browser;
 
/**
 * Memoize a class method. Caches the result of the method based on the
 * arguments. Instances do not share a cache.
 *
 * @param {Function} method Method to be memoized
 * @return {Function}
 */
function memoize( method ) {
	/**
	 * Memoized version of the method
	 *
	 * @return {Function}
	 */
	var memoized = function () {
		var cache = this[ '__cache' + memoized.cacheId ] ||
			( this[ '__cache' + memoized.cacheId ] = {} ),
			key = [].join.call( arguments, '|' );
		if ( Object.prototype.hasOwnProperty.call( cache, key ) ) {
			return cache[ key ];
		}
		return ( cache[ key ] = method.apply( this, arguments ) );
	};
	memoized.cacheId = Date.now().toString() + Math.random().toString();
	return memoized;
}
 
/**
 * Representation of user's current browser
 *
 * @class Browser
 * @param {string} ua the user agent of the current browser
 * @param {jQuery.Object} $container an element to associate with the Browser object
 */
function Browser( ua, $container ) {
	this.userAgent = ua;
	this.$el = $container;
}
 
Browser.prototype = {
	/**
	 * Returns whether the current browser is an ios device.
	 * FIXME: jquery.client does not support iPad detection so we cannot use it.
	 *
	 * @memberof Browser
	 * @instance
	 * @param {number} [version] integer describing a specific version you want to test against.
	 * @return {boolean}
	 */
	isIos: memoize( function ( version ) {
		var ua = this.userAgent,
			ios = /ipad|iphone|ipod/i.test( ua );
 
		if ( ios && version ) {
			switch ( version ) {
				case 8:
					// Test UA for iOS8. Or for simulator look for Version 8
					// In the iOS simulator the OS is the host machine OS version
					// This makes testing in iOS8 simulator work as expected
					return /OS 8_/.test( ua ) || /Version\/8/.test( ua );
				case 4:
					return /OS 4_/.test( ua );
				case 5:
					return /OS 5_/.test( ua );
				default:
					return false;
			}
		} else {
			return ios;
		}
	} ),
	/**
	 * Determine if a device has a widescreen.
	 *
	 * @memberof Browser
	 * @instance
	 * @return {boolean}
	 */
	isWideScreen: memoize( () => {
		var val = parseInt( mw.config.get( 'wgMFDeviceWidthTablet' ), 10 );
		// Check viewport width to determine mobile vs tablet.
		// Note: Mobile devices held in landscape mode might receive tablet treatment.
		return window.innerWidth >= val;
	} ),
	/**
	 * Whether touchstart and other touch events are supported by the current browser.
	 *
	 * @memberof Browser
	 * @instance
	 * @return {boolean}
	 */
	supportsTouchEvents: memoize( () => 'ontouchstart' in window )
};
 
/**
 * @memberof Browser
 * @return {Browser}
 */
Browser.getSingleton = function () {
	var $html;
	if ( !browser ) {
		$html = util.getDocument();
		browser = new Browser( window.navigator.userAgent, $html );
	}
	return browser;
};
 
module.exports = Browser;