part of dart._engine;
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.




/// A flag to check if the current browser is running on a laptop/desktop device.
bool get isDesktop => ui_web.browser.isDesktop;

/// A flag to check if the current browser is running on a mobile device.
///
/// Flutter web considers "mobile" everything that's not [isDesktop].
bool get isMobile => ui_web.browser.isMobile;

/// Whether the current browser is [ui_web.BrowserEngine.blink] (Chrom(e|ium)).
bool get isChromium => ui_web.browser.isChromium;

/// Whether the current browser is [ui_web.BrowserEngine.webkit] (Safari).
bool get isSafari => ui_web.browser.isSafari;

/// Whether the current browser is [ui_web.BrowserEngine.firefox].
bool get isFirefox => ui_web.browser.isFirefox;

/// Whether the current browser is Edge.
bool get isEdge => ui_web.browser.isEdge;

/// Whether we are running from a wasm module compiled with dart2wasm.
///
/// Note: Currently the ffi library is available from dart2wasm but not dart2js
/// or dartdevc.
bool get isWasm => ui_web.browser.isWasm;

// Whether the detected `operatingSystem` is `OperatingSystem.iOs`.
bool get _isIOS => ui_web.browser.operatingSystem == ui_web.OperatingSystem.iOs;

/// Whether the browser is running on macOS or iOS.
///
/// - See [operatingSystem].
/// - See [OperatingSystem].
bool get isMacOrIOS => _isIOS || ui_web.browser.operatingSystem == ui_web.OperatingSystem.macOs;

/// Detect iOS 15.
bool get isIOS15 => debugIsIOS15 ?? _isIOS && ui_web.browser.userAgent.contains('OS 15_');

/// Use in tests to simulate the detection of iOS 15.
bool? debugIsIOS15;

/// Detect if running on Chrome version 110 or older.
///
/// These versions of Chrome have a bug which causes rendering to be flipped
/// upside down when using `createImageBitmap`: see
/// https://chromium.googlesource.com/chromium/src/+/a7f9b00e422a1755918f8ca5500380f98b6fddf2
// TODO(harryterkelsen): Remove this check once we stop supporting Chrome 110
// and earlier, https://github.com/flutter/flutter/issues/139186.
bool get isChrome110OrOlder {
  if (debugIsChrome110OrOlder != null) {
    return debugIsChrome110OrOlder!;
  }
  if (_cachedIsChrome110OrOlder != null) {
    return _cachedIsChrome110OrOlder!;
  }
  final RegExp chromeRegexp = RegExp(r'Chrom(e|ium)\/([0-9]+)\.');
  final RegExpMatch? match = chromeRegexp.firstMatch(ui_web.browser.userAgent);
  if (match != null) {
    final int chromeVersion = int.parse(match.group(2)!);
    return _cachedIsChrome110OrOlder = chromeVersion <= 110;
  }
  return _cachedIsChrome110OrOlder = false;
}

// Cache the result of checking if the app is running on Chrome 110 on Windows
// since we check this on every frame.
bool? _cachedIsChrome110OrOlder;

/// Used in tests to simulate the detection of Chrome 110 or older on Windows.
bool? debugIsChrome110OrOlder;

/// Returns true if the browser is iOS Safari, false otherwise.
bool get isIosSafari => debugEmulateIosSafari || _isActualIosSafari;

bool get _isActualIosSafari =>
    ui_web.browser.browserEngine == ui_web.BrowserEngine.webkit &&
    ui_web.browser.operatingSystem == ui_web.OperatingSystem.iOs;

/// If set to true pretends that the current browser is iOS Safari.
///
/// Useful for tests. Do not use in production code.

bool debugEmulateIosSafari = false;

/// html webgl version qualifier constants.
abstract class WebGLVersion {
  /// WebGL 1.0 is based on OpenGL ES 2.0 / GLSL 1.00
  static const int webgl1 = 1;

  /// WebGL 2.0 is based on OpenGL ES 3.0 / GLSL 3.00
  static const int webgl2 = 2;
}

/// The highest WebGL version supported by the current browser, or -1 if WebGL
/// is not supported.
int get webGLVersion => _cachedWebGLVersion ?? (_cachedWebGLVersion = _detectWebGLVersion());

int? _cachedWebGLVersion;

/// Detects the highest WebGL version supported by the current browser, or
/// -1 if WebGL is not supported.
///
/// Chrome reports that `WebGL2RenderingContext` is available even when WebGL 2 is
/// disabled due hardware-specific issues. This happens, for example, on Chrome on
/// Moto E5. Therefore checking for the presence of `WebGL2RenderingContext` or
/// using the current [browserEngine] is insufficient.
///
/// Our CanvasKit backend is affected due to: https://github.com/emscripten-core/emscripten/issues/11819
int _detectWebGLVersion() {
  final DomHTMLCanvasElement canvas = createDomCanvasElement(width: 1, height: 1);
  if (canvas.getContext('webgl2') != null) {
    if (_workAroundBug91333) {
      return WebGLVersion.webgl1;
    }
    return WebGLVersion.webgl2;
  }
  if (canvas.getContext('webgl') != null) {
    return WebGLVersion.webgl1;
  }
  return -1;
}

// iOS 15 launched WebGL 2.0, but there's something broken about it, which
// leads to apps failing to load. For now, we're forcing WebGL 1 on iOS.
//
// TODO(yjbanov): https://github.com/flutter/flutter/issues/91333
bool get _workAroundBug91333 => _isIOS;

/// Whether the current browser supports the Chromium variant of CanvasKit.
bool get browserSupportsCanvaskitChromium =>
    domIntl.v8BreakIterator != null && domIntl.Segmenter != null;

/// Whether the current browser is Safari 17.4 or newer.
///
/// Safari 17.4 introduced support for aria-description.
bool get isSafari174OrNewer {
  if (!isSafari) {
    return false;
  }
  final RegExp safariRegexp = RegExp(r'Version\/([0-9]+)\.([0-9]+)');
  final RegExpMatch? match = safariRegexp.firstMatch(ui_web.browser.userAgent);
  if (match != null) {
    final int majorVersion = int.parse(match.group(1)!);
    final int minorVersion = int.parse(match.group(2)!);
    return majorVersion > 17 || (majorVersion == 17 && minorVersion >= 4);
  }
  return false;
}

/// Whether the current browser is Firefox 119 or newer.
///
/// Firefox 119 introduced support for aria-description.
bool get isFirefox119OrNewer {
  if (!isFirefox) {
    return false;
  }
  final RegExp firefoxRegexp = RegExp(r'Firefox\/([0-9]+)');
  final RegExpMatch? match = firefoxRegexp.firstMatch(ui_web.browser.userAgent);
  if (match != null) {
    final int version = int.parse(match.group(1)!);
    return version >= 119;
  }
  return false;
}
