SPB Git forge

spb/admin-ka

Public
41commits 1branches 0releases
172.9 MBsize
maindefault branch
19 days agolast push
JavaScript 65.5% Python 17.8% CSS 13% HTML 3.7%
7.6 KB · 234 lines javascript
Raw Blame History
1/*2 * noVNC: HTML5 VNC client3 * Copyright (C) 2019 The noVNC authors4 * Licensed under MPL 2.0 (see LICENSE.txt)5 *6 * See README.md for usage and integration instructions.7 *8 * Browser feature support detection9 */1011import * as Log from './logging.js';12import Base64 from '../base64.js';1314// Touch detection15export let isTouchDevice = ('ontouchstart' in document.documentElement) ||16                                 // required for Chrome debugger17                                 (document.ontouchstart !== undefined) ||18                                 // required for MS Surface19                                 (navigator.maxTouchPoints > 0) ||20                                 (navigator.msMaxTouchPoints > 0);21window.addEventListener('touchstart', function onFirstTouch() {22    isTouchDevice = true;23    window.removeEventListener('touchstart', onFirstTouch, false);24}, false);252627// The goal is to find a certain physical width, the devicePixelRatio28// brings us a bit closer but is not optimal.29export let dragThreshold = 10 * (window.devicePixelRatio || 1);3031let _supportsCursorURIs = false;3233try {34    const target = document.createElement('canvas');35    target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';3637    if (target.style.cursor.indexOf("url") === 0) {38        Log.Info("Data URI scheme cursor supported");39        _supportsCursorURIs = true;40    } else {41        Log.Warn("Data URI scheme cursor not supported");42    }43} catch (exc) {44    Log.Error("Data URI scheme cursor test exception: " + exc);45}4647export const supportsCursorURIs = _supportsCursorURIs;4849let _hasScrollbarGutter = true;50try {51    // Create invisible container52    const container = document.createElement('div');53    container.style.visibility = 'hidden';54    container.style.overflow = 'scroll'; // forcing scrollbars55    document.body.appendChild(container);5657    // Create a div and place it in the container58    const child = document.createElement('div');59    container.appendChild(child);6061    // Calculate the difference between the container's full width62    // and the child's width - the difference is the scrollbars63    const scrollbarWidth = (container.offsetWidth - child.offsetWidth);6465    // Clean up66    container.parentNode.removeChild(container);6768    _hasScrollbarGutter = scrollbarWidth != 0;69} catch (exc) {70    Log.Error("Scrollbar test exception: " + exc);71}72export const hasScrollbarGutter = _hasScrollbarGutter;7374export let supportsWebCodecsH264Decode = false;7576async function _checkWebCodecsH264DecodeSupport() {77    if (!('VideoDecoder' in window)) {78        return false;79    }8081    // We'll need to make do with some placeholders here82    const config = {83        codec: 'avc1.42401f',84        codedWidth: 1920,85        codedHeight: 1080,86        optimizeForLatency: true,87    };8889    let support = await VideoDecoder.isConfigSupported(config);90    if (!support.supported) {91        return false;92    }9394    // Firefox incorrectly reports supports for H.264 under some95    // circumstances, so we need to actually test a real frame96    // https://bugzilla.mozilla.org/show_bug.cgi?id=19323929798    const data = new Uint8Array(Base64.decode(99        'AAAAAWdCwBTZnpuAgICgAAADACAAAAZB4oVNAAAAAWjJYyyAAAABBgX//4Hc' +100        'Rem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTY0IHIzMTA4IDMxZTE5Zjkg' +101        'LSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDIz' +102        'IC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9u' +103        'czogY2FiYWM9MCByZWY9NSBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjB4' +104        'MTExIG1lPWhleCBzdWJtZT04IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4' +105        'ZWRfcmVmPTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0yIDh4' +106        'OGRjdD0wIGNxbT0wIGRlYWR6b25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJv' +107        'bWFfcXBfb2Zmc2V0PS0yIHRocmVhZHM9MSBsb29rYWhlYWRfdGhyZWFkcz0x' +108        'IHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9' +109        'MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVz' +110        'PTAgd2VpZ2h0cD0wIGtleWludD1pbmZpbml0ZSBrZXlpbnRfbWluPTI1IHNj' +111        'ZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NTAgcmM9' +112        'YWJyIG1idHJlZT0xIGJpdHJhdGU9NDAwIHJhdGV0b2w9MS4wIHFjb21wPTAu' +113        'NjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFx' +114        'PTE6MS4wMACAAAABZYiEBrxmKAAPVccAAS044AA5DRJMnkycJk4TPw=='));115116    let gotframe = false;117    let error = null;118119    let decoder = new VideoDecoder({120        output: (frame) => { gotframe = true; },121        error: (e) => { error = e; },122    });123    let chunk = new EncodedVideoChunk({124        timestamp: 0,125        type: 'key',126        data: data,127    });128129    decoder.configure(config);130    decoder.decode(chunk);131    try {132        await decoder.flush();133    } catch (e) {134        // Firefox incorrectly throws an exception here135        // https://bugzilla.mozilla.org/show_bug.cgi?id=1932566136        error = e;137    }138139    // Firefox fails to deliver the error on Windows, so we need to140    // check if we got a frame instead141    // https://bugzilla.mozilla.org/show_bug.cgi?id=1932579142    if (!gotframe) {143        return false;144    }145146    if (error !== null) {147        return false;148    }149150    return true;151}152supportsWebCodecsH264Decode = await _checkWebCodecsH264DecodeSupport();153154/*155 * The functions for detection of platforms and browsers below are exported156 * but the use of these should be minimized as much as possible.157 *158 * It's better to use feature detection than platform detection.159 */160161/* OS */162163export function isMac() {164    return !!(/mac/i).exec(navigator.platform);165}166167export function isWindows() {168    return !!(/win/i).exec(navigator.platform);169}170171export function isIOS() {172    return (!!(/ipad/i).exec(navigator.platform) ||173            !!(/iphone/i).exec(navigator.platform) ||174            !!(/ipod/i).exec(navigator.platform));175}176177export function isAndroid() {178    /* Android sets navigator.platform to Linux :/ */179    return !!navigator.userAgent.match('Android ');180}181182export function isChromeOS() {183    /* ChromeOS sets navigator.platform to Linux :/ */184    return !!navigator.userAgent.match(' CrOS ');185}186187/* Browser */188189export function isSafari() {190    return !!navigator.userAgent.match('Safari/...') &&191           !navigator.userAgent.match('Chrome/...') &&192           !navigator.userAgent.match('Chromium/...') &&193           !navigator.userAgent.match('Epiphany/...');194}195196export function isFirefox() {197    return !!navigator.userAgent.match('Firefox/...') &&198           !navigator.userAgent.match('Seamonkey/...');199}200201export function isChrome() {202    return !!navigator.userAgent.match('Chrome/...') &&203           !navigator.userAgent.match('Chromium/...') &&204           !navigator.userAgent.match('Edg/...') &&205           !navigator.userAgent.match('OPR/...');206}207208export function isChromium() {209    return !!navigator.userAgent.match('Chromium/...');210}211212export function isOpera() {213    return !!navigator.userAgent.match('OPR/...');214}215216export function isEdge() {217    return !!navigator.userAgent.match('Edg/...');218}219220/* Engine */221222export function isGecko() {223    return !!navigator.userAgent.match('Gecko/...');224}225226export function isWebKit() {227    return !!navigator.userAgent.match('AppleWebKit/...') &&228           !navigator.userAgent.match('Chrome/...');229}230231export function isBlink() {232    return !!navigator.userAgent.match('Chrome/...');233}234