browser.ts 5.6 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  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';
J
Johannes Rieken 已提交
9 10
import Event, { Emitter } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
E
Erich Gamma 已提交
11

12
class WindowManager {
E
Erich Gamma 已提交
13

14 15 16
	public static INSTANCE = new WindowManager();

	private _fullscreen: boolean;
E
Erich Gamma 已提交
17

18
	private _zoomLevel: number = 0;
B
Benjamin Pasero 已提交
19 20
	private _zoomFactor: number = 0;

21 22
	private _pixelRatioCache: number = 0;
	private _pixelRatioComputed: boolean = false;
E
Erich Gamma 已提交
23

24
	private _onDidChangeZoomLevel: Emitter<number> = new Emitter<number>();
J
Johannes Rieken 已提交
25
	public onDidChangeZoomLevel: Event<number> = this._onDidChangeZoomLevel.event;
26

27 28 29
	private _onDidChangeFullscreen: Emitter<void> = new Emitter<void>();
	public onDidChangeFullscreen: Event<void> = this._onDidChangeFullscreen.event;

30 31 32
	public getZoomLevel(): number {
		return this._zoomLevel;
	}
E
Erich Gamma 已提交
33

J
Johannes Rieken 已提交
34
	public setZoomLevel(zoomLevel: number): void {
35 36 37
		if (this._zoomLevel === zoomLevel) {
			return;
		}
E
Erich Gamma 已提交
38

39
		this._zoomLevel = zoomLevel;
40
		this._pixelRatioComputed = false;
41 42
		this._onDidChangeZoomLevel.fire(this._zoomLevel);
	}
43

B
Benjamin Pasero 已提交
44 45 46 47 48 49 50 51
	public getZoomFactor(): number {
		return this._zoomFactor;
	}

	public setZoomFactor(zoomFactor: number): void {
		this._zoomFactor = zoomFactor;
	}

52 53 54 55 56 57 58 59 60 61 62
	public getPixelRatio(): number {
		if (!this._pixelRatioComputed) {
			this._pixelRatioCache = this._computePixelRatio();
			this._pixelRatioComputed = true;
		}
		return this._pixelRatioCache;
	}

	private _computePixelRatio(): number {
		let ctx = document.createElement('canvas').getContext('2d');
		let dpr = window.devicePixelRatio || 1;
J
Johannes Rieken 已提交
63 64 65 66 67
		let bsr = (<any>ctx).webkitBackingStorePixelRatio ||
			(<any>ctx).mozBackingStorePixelRatio ||
			(<any>ctx).msBackingStorePixelRatio ||
			(<any>ctx).oBackingStorePixelRatio ||
			(<any>ctx).backingStorePixelRatio || 1;
68 69
		return dpr / bsr;
	}
70 71 72 73 74 75 76 77 78 79 80 81 82

	public setFullscreen(fullscreen: boolean): void {
		if (this._fullscreen === fullscreen) {
			return;
		}

		this._fullscreen = fullscreen;
		this._onDidChangeFullscreen.fire();
	}

	public isFullscreen(): boolean {
		return this._fullscreen;
	}
83
}
E
Erich Gamma 已提交
84

B
Benjamin Pasero 已提交
85
/** A zoom index, e.g. 1, 2, 3 */
86
export function getZoomLevel(): number {
87
	return WindowManager.INSTANCE.getZoomLevel();
88
}
B
Benjamin Pasero 已提交
89 90
/** The zoom scale for an index, e.g. 1, 1.2, 1.4 */
export function getZoomFactor(): number {
91
	return WindowManager.INSTANCE.getZoomFactor();
B
Benjamin Pasero 已提交
92
}
93
export function getPixelRatio(): number {
94
	return WindowManager.INSTANCE.getPixelRatio();
95
}
J
Johannes Rieken 已提交
96
export function setZoomLevel(zoomLevel: number): void {
97
	WindowManager.INSTANCE.setZoomLevel(zoomLevel);
98
}
B
Benjamin Pasero 已提交
99
export function setZoomFactor(zoomFactor: number): void {
100
	WindowManager.INSTANCE.setZoomFactor(zoomFactor);
B
Benjamin Pasero 已提交
101
}
J
Johannes Rieken 已提交
102
export function onDidChangeZoomLevel(callback: (zoomLevel: number) => void): IDisposable {
103 104 105 106 107 108 109 110 111 112
	return WindowManager.INSTANCE.onDidChangeZoomLevel(callback);
}
export function setFullscreen(fullscreen: boolean): void {
	WindowManager.INSTANCE.setFullscreen(fullscreen);
}
export function isFullscreen(): boolean {
	return WindowManager.INSTANCE.isFullscreen();
}
export function onDidChangeFullscreen(callback: () => void): IDisposable {
	return WindowManager.INSTANCE.onDidChangeFullscreen(callback);
113
}
E
Erich Gamma 已提交
114

115
const userAgent = navigator.userAgent;
E
Erich Gamma 已提交
116 117 118 119 120 121 122 123 124 125

// 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;
126 127
export const isEdge = (userAgent.indexOf('Edge/') >= 0);
export const isEdgeOrIE = isEdge || isIE11 || isIE10 || isIE9;
E
Erich Gamma 已提交
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

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;

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

B
Benjamin Pasero 已提交
148
	let supported = false;
149
	let element = document.createElement('div');
B
Benjamin Pasero 已提交
150 151 152
	let properties = ['animationName', 'webkitAnimationName', 'msAnimationName', 'MozAnimationName', 'OAnimationName'];
	for (let i = 0; i < properties.length; i++) {
		let property = properties[i];
E
Erich Gamma 已提交
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
		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;
}

B
Benjamin Pasero 已提交
168
export function supportsExecCommand(command: string): boolean {
E
Erich Gamma 已提交
169 170 171 172 173
	return (
		(isIE11orEarlier || Platform.isNative)
		&& document.queryCommandSupported(command)
	);
}