browser.ts 5.3 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import types = require('vs/base/common/types');
import * as Platform from 'vs/base/common/platform';

interface ISafeWindow {
	Worker: any;
}

interface ISafeDocument {
B
Benjamin Pasero 已提交
15 16 17
	URL: string;
	createElement(tagName: 'div'): HTMLDivElement;
	createElement(tagName: string): HTMLElement;
E
Erich Gamma 已提交
18 19 20
}

interface INavigator {
B
Benjamin Pasero 已提交
21
	userAgent: string;
E
Erich Gamma 已提交
22 23 24
}

interface IGlobalScope {
B
Benjamin Pasero 已提交
25 26
	navigator: INavigator;
	document: ISafeDocument;
E
Erich Gamma 已提交
27
	history: {
B
Benjamin Pasero 已提交
28
		pushState: any
E
Erich Gamma 已提交
29 30 31
	};
}

B
Benjamin Pasero 已提交
32
const globals = <IGlobalScope><any>(typeof self === 'object' ? self : global);
E
Erich Gamma 已提交
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

// MAC:
// chrome: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.100 Safari/535.2"
// safari: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22"
//
// WINDOWS:
// chrome: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.102 Safari/535.2"
// IE: "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MS-RTC LM 8; InfoPath.3; Zune 4.7)"
// Opera:	"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.9.168 Version/11.52"
// FF: "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0"

// LINUX:
// chrome: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36"
// firefox: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0"

B
Benjamin Pasero 已提交
48
const userAgent = globals.navigator ? globals.navigator.userAgent : '';
E
Erich Gamma 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

// DOCUMENTED FOR FUTURE REFERENCE:
// When running IE11 in IE10 document mode, the code below will identify the browser as being IE10,
// which is correct because IE11 in IE10 document mode will reimplement all the bugs of IE10
export const isIE11 = (userAgent.indexOf('Trident') >= 0 && userAgent.indexOf('MSIE') < 0);
export const isIE10 = (userAgent.indexOf('MSIE 10') >= 0);
export const isIE9 = (userAgent.indexOf('MSIE 9') >= 0);
export const isIE11orEarlier = isIE11 || isIE10 || isIE9;
export const isIE10orEarlier = isIE10 || isIE9;
export const isIE10orLater = isIE11 || isIE10;

export const isOpera = (userAgent.indexOf('Opera') >= 0);
export const isFirefox = (userAgent.indexOf('Firefox') >= 0);
export const isWebKit = (userAgent.indexOf('AppleWebKit') >= 0);
export const isChrome = (userAgent.indexOf('Chrome') >= 0);
export const isSafari = (userAgent.indexOf('Chrome') === -1) && (userAgent.indexOf('Safari') >= 0);
export const isIPad = (userAgent.indexOf('iPad') >= 0);

export const canUseTranslate3d = !isIE9 && !isFirefox;

export const enableEmptySelectionClipboard = isWebKit;

B
Benjamin Pasero 已提交
71 72
let _disablePushState = false;

E
Erich Gamma 已提交
73 74 75 76 77
/**
 * Returns if the browser supports the history.pushState function or not.
 */
export function canPushState() {
	return (!_disablePushState && globals.history && globals.history.pushState);
A
tslint  
Alex Dima 已提交
78
}
E
Erich Gamma 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

/**
 * Helpful when we detect that pushing state does not work for some reason (e.g. FF prevents pushState for security reasons in some cases)
 */
export function disablePushState() {
	_disablePushState = true;
}

/**
 * Returns if the browser supports CSS 3 animations.
 */
export function hasCSSAnimationSupport() {
	if (this._hasCSSAnimationSupport === true || this._hasCSSAnimationSupport === false) {
		return this._hasCSSAnimationSupport;
	}

	if (!globals.document) {
		return false;
	}

B
Benjamin Pasero 已提交
99 100 101 102 103
	let supported = false;
	let element = globals.document.createElement('div');
	let properties = ['animationName', 'webkitAnimationName', 'msAnimationName', 'MozAnimationName', 'OAnimationName'];
	for (let i = 0; i < properties.length; i++) {
		let property = properties[i];
E
Erich Gamma 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
		if (!types.isUndefinedOrNull(element.style[property]) || element.style.hasOwnProperty(property)) {
			supported = true;
			break;
		}
	}

	if (supported) {
		this._hasCSSAnimationSupport = true;
	} else {
		this._hasCSSAnimationSupport = false;
	}

	return this._hasCSSAnimationSupport;
}

/**
 * Returns if the browser supports the provided video mime type or not.
 */
B
Benjamin Pasero 已提交
122
export function canPlayVideo(type: string) {
E
Erich Gamma 已提交
123 124 125 126
	if (!globals.document) {
		return false;
	}

B
Benjamin Pasero 已提交
127
	let video: HTMLVideoElement = <HTMLVideoElement>globals.document.createElement('video');
E
Erich Gamma 已提交
128
	if (video.canPlayType) {
B
Benjamin Pasero 已提交
129
		let canPlay = video.canPlayType(type);
E
Erich Gamma 已提交
130 131 132 133 134 135 136 137 138 139

		return canPlay === 'maybe' || canPlay === 'probably';
	}

	return false;
}

/**
 * Returns if the browser supports the provided audio mime type or not.
 */
B
Benjamin Pasero 已提交
140
export function canPlayAudio(type: string) {
E
Erich Gamma 已提交
141 142 143 144
	if (!globals.document) {
		return false;
	}

B
Benjamin Pasero 已提交
145
	let audio: HTMLAudioElement = <HTMLAudioElement>globals.document.createElement('audio');
E
Erich Gamma 已提交
146
	if (audio.canPlayType) {
B
Benjamin Pasero 已提交
147
		let canPlay = audio.canPlayType(type);
E
Erich Gamma 已提交
148 149 150 151 152 153 154

		return canPlay === 'maybe' || canPlay === 'probably';
	}

	return false;
}

B
Benjamin Pasero 已提交
155 156
export function isInWebWorker(): boolean {
	return !globals.document && typeof ((<any>globals).importScripts) !== 'undefined';
E
Erich Gamma 已提交
157 158
}

B
Benjamin Pasero 已提交
159
export function supportsExecCommand(command: string): boolean {
E
Erich Gamma 已提交
160 161 162 163 164
	return (
		(isIE11orEarlier || Platform.isNative)
		&& document.queryCommandSupported(command)
	);
}