Skip to content

[web] Migrate Flutter Web DOM usage to JS static interop - 2 #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions lib/web_ui/lib/src/engine/browser_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:html' as html;

import 'package:meta/meta.dart';

import 'dom.dart';

// 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.
//
Expand Down Expand Up @@ -65,8 +65,8 @@ BrowserEngine get browserEngine {
}

BrowserEngine _detectBrowserEngine() {
final String vendor = html.window.navigator.vendor;
final String agent = html.window.navigator.userAgent.toLowerCase();
final String vendor = domWindow.navigator.vendor;
final String agent = domWindow.navigator.userAgent.toLowerCase();
return detectBrowserEngineByVendorAgent(vendor, agent);
}

Expand Down Expand Up @@ -167,14 +167,14 @@ OperatingSystem detectOperatingSystem({
String? overrideUserAgent,
int? overrideMaxTouchPoints,
}) {
final String platform = overridePlatform ?? html.window.navigator.platform!;
final String userAgent = overrideUserAgent ?? html.window.navigator.userAgent;
final String platform = overridePlatform ?? domWindow.navigator.platform!;
final String userAgent = overrideUserAgent ?? domWindow.navigator.userAgent;

if (platform.startsWith('Mac')) {
// iDevices requesting a "desktop site" spoof their UA so it looks like a Mac.
// This checks if we're in a touch device, or on a real mac.
final int maxTouchPoints =
overrideMaxTouchPoints ?? html.window.navigator.maxTouchPoints ?? 0;
overrideMaxTouchPoints ?? domWindow.navigator.maxTouchPoints ?? 0;
if (maxTouchPoints > 2) {
return OperatingSystem.iOs;
}
Expand Down Expand Up @@ -233,7 +233,7 @@ bool get isIOS15 {
return debugIsIOS15!;
}
return operatingSystem == OperatingSystem.iOs &&
html.window.navigator.userAgent.contains('OS 15_');
domWindow.navigator.userAgent.contains('OS 15_');
}

/// Use in tests to simulate the detection of iOS 15.
Expand All @@ -256,7 +256,7 @@ int get webGLVersion =>
///
/// Our CanvasKit backend is affected due to: https://github.com/emscripten-core/emscripten/issues/11819
int _detectWebGLVersion() {
final html.CanvasElement canvas = html.CanvasElement(
final DomCanvasElement canvas = DomCanvasElement(
width: 1,
height: 1,
);
Expand Down
44 changes: 43 additions & 1 deletion lib/web_ui/lib/src/engine/dom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,30 @@ class DomWindow {}

extension DomWindowExtension on DomWindow {
external DomDocument get document;
external DomNavigator get navigator;
}

@JS('window')
external DomWindow get domWindow;

@JS()
@staticInterop
class DomNavigator {}

extension DomNavigatorExtension on DomNavigator {
external int? get maxTouchPoints;
external String get vendor;
external String? get platform;
external String get userAgent;
}

@JS()
@staticInterop
class DomDocument {}

extension DomDocumentExtension on DomDocument {
external /* List<Node> */ List<Object?> querySelectorAll(String selectors);
external DomHTMLElement createElement(String name, [dynamic options]);
}

@JS()
Expand All @@ -42,9 +55,38 @@ class DomHTMLMetaElement {}

extension DomHTMLMetaElementExtension on DomHTMLMetaElement {
external String get name;
external set name(String value);
external String get content;
}

external set name(String value);
@JS()
@staticInterop
class DomCanvasElement extends DomHTMLElement {
factory DomCanvasElement({int? width, int? height}) {
final DomCanvasElement canvas =
domWindow.document.createElement('canvas') as DomCanvasElement;
if (width != null) {
canvas.width = width;
}
if (height != null) {
canvas.height = height;
}
return canvas;
}
}

extension DomCanvasElementExtension on DomCanvasElement {
external int? get width;
external set width(int? value);
external int? get height;
external set height(int? value);

Object? getContext(String contextType, [Map<dynamic, dynamic>? attributes]) {
return js_util.callMethod(this, 'getContext', <Object?>[
contextType,
if (attributes != null) js_util.jsify(attributes)
]);
}
}

Object? domGetConstructor(String constructorName) =>
Expand Down