EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
browser.js
Go to the documentation of this file.
1/*
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2019 The noVNC Authors
4 * Licensed under MPL 2.0 (see LICENSE.txt)
5 *
6 * See README.md for usage and integration instructions.
7 *
8 * Browser feature support detection
9 */
10
11import * as Log from './logging.js';
12
13// Touch detection
14export let isTouchDevice = ('ontouchstart' in document.documentElement) ||
15 // requried for Chrome debugger
16 (document.ontouchstart !== undefined) ||
17 // required for MS Surface
18 (navigator.maxTouchPoints > 0) ||
19 (navigator.msMaxTouchPoints > 0);
20window.addEventListener('touchstart', function onFirstTouch() {
21 isTouchDevice = true;
22 window.removeEventListener('touchstart', onFirstTouch, false);
23}, false);
24
25
26// The goal is to find a certain physical width, the devicePixelRatio
27// brings us a bit closer but is not optimal.
28export let dragThreshold = 10 * (window.devicePixelRatio || 1);
29
30let _supportsCursorURIs = false;
31
32try {
33 const target = document.createElement('canvas');
34 target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
35
36 if (target.style.cursor.indexOf("url") === 0) {
37 Log.Info("Data URI scheme cursor supported");
38 _supportsCursorURIs = true;
39 } else {
40 Log.Warn("Data URI scheme cursor not supported");
41 }
42} catch (exc) {
43 Log.Error("Data URI scheme cursor test exception: " + exc);
44}
45
46export const supportsCursorURIs = _supportsCursorURIs;
47
48let _hasScrollbarGutter = true;
49try {
50 // Create invisible container
51 const container = document.createElement('div');
52 container.style.visibility = 'hidden';
53 container.style.overflow = 'scroll'; // forcing scrollbars
54 document.body.appendChild(container);
55
56 // Create a div and place it in the container
57 const child = document.createElement('div');
58 container.appendChild(child);
59
60 // Calculate the difference between the container's full width
61 // and the child's width - the difference is the scrollbars
62 const scrollbarWidth = (container.offsetWidth - child.offsetWidth);
63
64 // Clean up
65 container.parentNode.removeChild(container);
66
67 _hasScrollbarGutter = scrollbarWidth != 0;
68} catch (exc) {
69 Log.Error("Scrollbar test exception: " + exc);
70}
71export const hasScrollbarGutter = _hasScrollbarGutter;
72
73/*
74 * The functions for detection of platforms and browsers below are exported
75 * but the use of these should be minimized as much as possible.
76 *
77 * It's better to use feature detection than platform detection.
78 */
79
80/* OS */
81
82export function isMac() {
83 return !!(/mac/i).exec(navigator.platform);
84}
85
86export function isWindows() {
87 return !!(/win/i).exec(navigator.platform);
88}
89
90export function isIOS() {
91 return (!!(/ipad/i).exec(navigator.platform) ||
92 !!(/iphone/i).exec(navigator.platform) ||
93 !!(/ipod/i).exec(navigator.platform));
94}
95
96export function isAndroid() {
97 /* Android sets navigator.platform to Linux :/ */
98 return !!navigator.userAgent.match('Android ');
99}
100
101export function isChromeOS() {
102 /* ChromeOS sets navigator.platform to Linux :/ */
103 return !!navigator.userAgent.match(' CrOS ');
104}
105
106/* Browser */
107
108export function isSafari() {
109 return !!navigator.userAgent.match('Safari/...') &&
110 !navigator.userAgent.match('Chrome/...') &&
111 !navigator.userAgent.match('Chromium/...') &&
112 !navigator.userAgent.match('Epiphany/...');
113}
114
115export function isFirefox() {
116 return !!navigator.userAgent.match('Firefox/...') &&
117 !navigator.userAgent.match('Seamonkey/...');
118}
119
120export function isChrome() {
121 return !!navigator.userAgent.match('Chrome/...') &&
122 !navigator.userAgent.match('Chromium/...') &&
123 !navigator.userAgent.match('Edg/...') &&
124 !navigator.userAgent.match('OPR/...');
125}
126
127export function isChromium() {
128 return !!navigator.userAgent.match('Chromium/...');
129}
130
131export function isOpera() {
132 return !!navigator.userAgent.match('OPR/...');
133}
134
135export function isEdge() {
136 return !!navigator.userAgent.match('Edg/...');
137}
138
139/* Engine */
140
141export function isGecko() {
142 return !!navigator.userAgent.match('Gecko/...');
143}
144
145export function isWebKit() {
146 return !!navigator.userAgent.match('AppleWebKit/...') &&
147 !navigator.userAgent.match('Chrome/...');
148}
149
150export function isBlink() {
151 return !!navigator.userAgent.match('Chrome/...');
152}