Skip to content

Commit 2b5ef64

Browse files
Skwasm heavy (#166619)
This produces a build of Skwasm that works on Firefox and Safari. This means we use `SkAnimatedImage` for animated gifs and webps and use builtin ICU data in Skia. I have unit test suites for Safari and Firefox with dart2wasm and both `ui` and `engine` test sets. However, there are a few issues with running these on CI: * Safari+dart2wasm doesn't work yet until the CI bots are upgraded to macOS 15, so these have been disabled on CI for now (but you can run the unit test suite locally). * Firefox+ui doesn't work because our Linux bots have no GPU and therefore no WebGL2 support, so that one is disabled. Firefox+dart2wasm with the `engine` suite is enabled on CI though. I did make some changes to the host page for our unit test harness so that Safari actually works though. Even though we're not running on CI, you can still run locally if you have macOS 15.
1 parent 018c6d4 commit 2b5ef64

30 files changed

Lines changed: 755 additions & 250 deletions

‎engine/src/flutter/ci/builders/linux_web_engine_test.json‎

Lines changed: 13 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -193,25 +193,12 @@
193193
"--suite=chrome-dart2js-canvaskit-ui",
194194
"--suite=chrome-full-dart2js-canvaskit-canvaskit",
195195
"--suite=chrome-full-dart2js-canvaskit-ui",
196-
"--suite=edge-dart2js-canvaskit-engine",
197-
"--suite=edge-dart2js-canvaskit-canvaskit",
198-
"--suite=edge-dart2js-canvaskit-ui",
199-
"--suite=edge-full-dart2js-canvaskit-canvaskit",
200-
"--suite=edge-full-dart2js-canvaskit-ui",
201-
"--suite=firefox-dart2js-canvaskit-engine",
202-
"--suite=firefox-dart2js-canvaskit-canvaskit",
203-
"--suite=firefox-dart2js-canvaskit-ui",
204-
"--suite=safari-dart2js-canvaskit-engine",
205-
"--suite=safari-dart2js-canvaskit-canvaskit",
206-
"--suite=safari-dart2js-canvaskit-ui",
207196
"--suite=chrome-dart2wasm-canvaskit-engine",
208197
"--suite=chrome-coi-dart2wasm-skwasm-ui",
209198
"--suite=chrome-force-st-dart2wasm-skwasm-ui",
210199
"--suite=chrome-fallbacks",
211200
"--suite=chrome-coi-fallbacks",
212-
"--suite=chrome-force-st-fallbacks",
213-
"--suite=firefox-fallbacks",
214-
"--suite=safari-fallbacks"
201+
"--suite=chrome-force-st-fallbacks"
215202
],
216203
"script": "flutter/lib/web_ui/dev/felt"
217204
},
@@ -331,6 +318,7 @@
331318
"web_tests/test_bundles/dart2js-canvaskit-engine",
332319
"web_tests/test_bundles/dart2js-canvaskit-canvaskit",
333320
"web_tests/test_bundles/dart2js-canvaskit-ui",
321+
"web_tests/test_bundles/dart2wasm-canvaskit-engine",
334322
"web_tests/test_bundles/fallbacks"
335323
],
336324
"test_dependencies": [
@@ -349,30 +337,11 @@
349337
"parameters": [
350338
"test",
351339
"--copy-artifacts",
352-
"--suite=chrome-dart2js-canvaskit-engine",
353-
"--suite=chrome-dart2js-canvaskit-canvaskit",
354-
"--suite=chrome-dart2js-canvaskit-ui",
355-
"--suite=chrome-full-dart2js-canvaskit-canvaskit",
356-
"--suite=chrome-full-dart2js-canvaskit-ui",
357-
"--suite=edge-dart2js-canvaskit-engine",
358-
"--suite=edge-dart2js-canvaskit-canvaskit",
359-
"--suite=edge-dart2js-canvaskit-ui",
360-
"--suite=edge-full-dart2js-canvaskit-canvaskit",
361-
"--suite=edge-full-dart2js-canvaskit-ui",
362340
"--suite=firefox-dart2js-canvaskit-engine",
363341
"--suite=firefox-dart2js-canvaskit-canvaskit",
364342
"--suite=firefox-dart2js-canvaskit-ui",
365-
"--suite=safari-dart2js-canvaskit-engine",
366-
"--suite=safari-dart2js-canvaskit-canvaskit",
367-
"--suite=safari-dart2js-canvaskit-ui",
368-
"--suite=chrome-dart2wasm-canvaskit-engine",
369-
"--suite=chrome-coi-dart2wasm-skwasm-ui",
370-
"--suite=chrome-force-st-dart2wasm-skwasm-ui",
371-
"--suite=chrome-fallbacks",
372-
"--suite=chrome-coi-fallbacks",
373-
"--suite=chrome-force-st-fallbacks",
374-
"--suite=firefox-fallbacks",
375-
"--suite=safari-fallbacks"
343+
"--suite=firefox-dart2wasm-canvaskit-engine",
344+
"--suite=firefox-fallbacks"
376345
],
377346
"script": "flutter/lib/web_ui/dev/felt"
378347
},
@@ -403,6 +372,15 @@
403372
],
404373
"script": "flutter/lib/web_ui/dev/felt"
405374
},
375+
{
376+
"name": "run suite firefox-dart2wasm-canvaskit-engine",
377+
"parameters": [
378+
"test",
379+
"--run",
380+
"--suite=firefox-dart2wasm-canvaskit-engine"
381+
],
382+
"script": "flutter/lib/web_ui/dev/felt"
383+
},
406384
{
407385
"name": "run suite firefox-fallbacks",
408386
"parameters": [
@@ -444,29 +422,9 @@
444422
"parameters": [
445423
"test",
446424
"--copy-artifacts",
447-
"--suite=chrome-dart2js-canvaskit-engine",
448-
"--suite=chrome-dart2js-canvaskit-canvaskit",
449-
"--suite=chrome-dart2js-canvaskit-ui",
450-
"--suite=chrome-full-dart2js-canvaskit-canvaskit",
451-
"--suite=chrome-full-dart2js-canvaskit-ui",
452-
"--suite=edge-dart2js-canvaskit-engine",
453-
"--suite=edge-dart2js-canvaskit-canvaskit",
454-
"--suite=edge-dart2js-canvaskit-ui",
455-
"--suite=edge-full-dart2js-canvaskit-canvaskit",
456-
"--suite=edge-full-dart2js-canvaskit-ui",
457-
"--suite=firefox-dart2js-canvaskit-engine",
458-
"--suite=firefox-dart2js-canvaskit-canvaskit",
459-
"--suite=firefox-dart2js-canvaskit-ui",
460425
"--suite=safari-dart2js-canvaskit-engine",
461426
"--suite=safari-dart2js-canvaskit-canvaskit",
462427
"--suite=safari-dart2js-canvaskit-ui",
463-
"--suite=chrome-dart2wasm-canvaskit-engine",
464-
"--suite=chrome-coi-dart2wasm-skwasm-ui",
465-
"--suite=chrome-force-st-dart2wasm-skwasm-ui",
466-
"--suite=chrome-fallbacks",
467-
"--suite=chrome-coi-fallbacks",
468-
"--suite=chrome-force-st-fallbacks",
469-
"--suite=firefox-fallbacks",
470428
"--suite=safari-fallbacks"
471429
],
472430
"script": "flutter/lib/web_ui/dev/felt"

‎engine/src/flutter/ci/licenses_golden/licenses_flutter‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52200,6 +52200,7 @@ ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.
5220052200
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/path.dart + ../../../flutter/LICENSE
5220152201
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/path_metrics.dart + ../../../flutter/LICENSE
5220252202
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/picture.dart + ../../../flutter/LICENSE
52203+
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_animated_image.dart + ../../../flutter/LICENSE
5220352204
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_canvas.dart + ../../../flutter/LICENSE
5220452205
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_filters.dart + ../../../flutter/LICENSE
5220552206
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_fonts.dart + ../../../flutter/LICENSE
@@ -52271,6 +52272,8 @@ ORIGIN: ../../../flutter/lib/web_ui/lib/ui_web/src/ui_web/platform_view_registry
5227152272
ORIGIN: ../../../flutter/lib/web_ui/lib/ui_web/src/ui_web/plugins.dart + ../../../flutter/LICENSE
5227252273
ORIGIN: ../../../flutter/lib/web_ui/lib/ui_web/src/ui_web/testing.dart + ../../../flutter/LICENSE
5227352274
ORIGIN: ../../../flutter/lib/web_ui/lib/window.dart + ../../../flutter/LICENSE
52275+
ORIGIN: ../../../flutter/lib/web_ui/skwasm/animated_image.cpp + ../../../flutter/LICENSE
52276+
ORIGIN: ../../../flutter/lib/web_ui/skwasm/animated_image_stub.cpp + ../../../flutter/LICENSE
5227452277
ORIGIN: ../../../flutter/lib/web_ui/skwasm/canvas.cpp + ../../../flutter/LICENSE
5227552278
ORIGIN: ../../../flutter/lib/web_ui/skwasm/contour_measure.cpp + ../../../flutter/LICENSE
5227652279
ORIGIN: ../../../flutter/lib/web_ui/skwasm/data.cpp + ../../../flutter/LICENSE
@@ -52291,6 +52294,8 @@ ORIGIN: ../../../flutter/lib/web_ui/skwasm/surface.h + ../../../flutter/LICENSE
5229152294
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/line_metrics.cpp + ../../../flutter/LICENSE
5229252295
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/paragraph.cpp + ../../../flutter/LICENSE
5229352296
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp + ../../../flutter/LICENSE
52297+
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder_builtin_icu.cpp + ../../../flutter/LICENSE
52298+
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder_client_icu.cpp + ../../../flutter/LICENSE
5229452299
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/paragraph_style.cpp + ../../../flutter/LICENSE
5229552300
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/strut_style.cpp + ../../../flutter/LICENSE
5229652301
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/text_style.cpp + ../../../flutter/LICENSE
@@ -55199,6 +55204,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.da
5519955204
FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/path.dart
5520055205
FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/path_metrics.dart
5520155206
FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/picture.dart
55207+
FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_animated_image.dart
5520255208
FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_canvas.dart
5520355209
FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_filters.dart
5520455210
FILE: ../../../flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/raw_fonts.dart
@@ -55270,6 +55276,8 @@ FILE: ../../../flutter/lib/web_ui/lib/ui_web/src/ui_web/platform_view_registry.d
5527055276
FILE: ../../../flutter/lib/web_ui/lib/ui_web/src/ui_web/plugins.dart
5527155277
FILE: ../../../flutter/lib/web_ui/lib/ui_web/src/ui_web/testing.dart
5527255278
FILE: ../../../flutter/lib/web_ui/lib/window.dart
55279+
FILE: ../../../flutter/lib/web_ui/skwasm/animated_image.cpp
55280+
FILE: ../../../flutter/lib/web_ui/skwasm/animated_image_stub.cpp
5527355281
FILE: ../../../flutter/lib/web_ui/skwasm/canvas.cpp
5527455282
FILE: ../../../flutter/lib/web_ui/skwasm/contour_measure.cpp
5527555283
FILE: ../../../flutter/lib/web_ui/skwasm/data.cpp
@@ -55290,6 +55298,8 @@ FILE: ../../../flutter/lib/web_ui/skwasm/surface.h
5529055298
FILE: ../../../flutter/lib/web_ui/skwasm/text/line_metrics.cpp
5529155299
FILE: ../../../flutter/lib/web_ui/skwasm/text/paragraph.cpp
5529255300
FILE: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp
55301+
FILE: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder_builtin_icu.cpp
55302+
FILE: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder_client_icu.cpp
5529355303
FILE: ../../../flutter/lib/web_ui/skwasm/text/paragraph_style.cpp
5529455304
FILE: ../../../flutter/lib/web_ui/skwasm/text/strut_style.cpp
5529555305
FILE: ../../../flutter/lib/web_ui/skwasm/text/text_style.cpp

‎engine/src/flutter/lib/web_ui/dev/build.dart‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const Map<String, String> targetAliases = <String, String>{
2222
'flutter/third_party/canvaskit:canvaskit_experimental_webparagraph_group',
2323
'skwasm': 'flutter/third_party/canvaskit:skwasm_group',
2424
'skwasm_st': 'flutter/third_party/canvaskit:skwasm_st_group',
25+
'skwasm_heavy': 'flutter/third_party/canvaskit:skwasm_heavy_group',
26+
'skwasm_heavy_st': 'flutter/third_party/canvaskit:skwasm_heavy_st_group',
2527
'archive': 'flutter/web_sdk:flutter_web_sdk_archive',
2628
};
2729

‎engine/src/flutter/lib/web_ui/dev/felt_config.dart‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class RunConfiguration {
4444
this.variant,
4545
this.crossOriginIsolated,
4646
this.forceSingleThreadedSkwasm,
47+
this.wasmAllowList,
4748
);
4849

4950
final String name;
@@ -52,6 +53,7 @@ class RunConfiguration {
5253
final CanvasKitVariant? variant;
5354
final bool crossOriginIsolated;
5455
final bool forceSingleThreadedSkwasm;
56+
final Map<String, bool> wasmAllowList;
5557
}
5658

5759
class ArtifactDependencies {
@@ -190,13 +192,15 @@ class FeltConfig {
190192
final bool crossOriginIsolated = runConfigYaml['cross-origin-isolated'] as bool? ?? false;
191193
final bool forceSingleThreadedSkwasm =
192194
runConfigYaml['force-single-threaded-skwasm'] as bool? ?? false;
195+
final YamlMap wasmAllowList = (runConfigYaml['wasm-allow-list'] as YamlMap?) ?? YamlMap();
193196
final RunConfiguration runConfig = RunConfiguration(
194197
name,
195198
browser,
196199
browserFlags,
197200
variant,
198201
crossOriginIsolated,
199202
forceSingleThreadedSkwasm,
203+
wasmAllowList.cast<String, bool>(),
200204
);
201205
runConfigs.add(runConfig);
202206
if (runConfigsByName.containsKey(name)) {

‎engine/src/flutter/lib/web_ui/dev/firefox.dart‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import 'dart:async';
6+
import 'dart:convert';
67
import 'dart:io';
78

89
import 'package:path/path.dart' as path;
@@ -65,6 +66,8 @@ class Firefox extends Browser {
6566
user_pref("browser.shell.checkDefaultBrowser", false);
6667
user_pref("dom.disable_open_during_load", false);
6768
user_pref("dom.max_script_run_time", 0);
69+
user_pref("trailhead.firstrun.branches", "nofirstrun-empty");
70+
user_pref("browser.aboutwelcome.enabled", false);
6871
''';
6972

7073
final Directory temporaryProfileDirectory = Directory(
@@ -80,21 +83,25 @@ user_pref("dom.max_script_run_time", 0);
8083
temporaryProfileDirectory.createSync(recursive: true);
8184
File(path.join(temporaryProfileDirectory.path, 'prefs.js')).writeAsStringSync(profile);
8285

83-
final bool isMac = Platform.isMacOS;
8486
final List<String> args = <String>[
8587
url.toString(),
8688
'--profile',
8789
temporaryProfileDirectory.path,
8890
if (!debug) '--headless',
8991
'-width $kMaxScreenshotWidth',
9092
'-height $kMaxScreenshotHeight',
91-
// On Mac Firefox uses the -- option prefix, while elsewhere it uses the - prefix.
92-
'${isMac ? '-' : ''}-new-window',
93-
'${isMac ? '-' : ''}-new-instance',
93+
'-new-window',
94+
'-new-instance',
9495
'--start-debugger-server $kDevtoolsPort',
9596
];
9697

9798
final Process process = await Process.start(installation.executable, args);
99+
process.stdout
100+
.transform<String>(const Utf8Decoder(allowMalformed: true))
101+
.listen((String string) => print('[Firefox:stdout] $string'));
102+
process.stderr
103+
.transform<String>(const Utf8Decoder(allowMalformed: true))
104+
.listen((String string) => print('[Firefox:stderr] $string'));
98105

99106
remoteDebuggerCompleter.complete(
100107
getRemoteDebuggerUrl(Uri.parse('http://localhost:$kDevtoolsPort')),

‎engine/src/flutter/lib/web_ui/dev/generate_builder_json.dart‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ class GenerateBuilderJsonCommand extends Command<bool> {
114114
String? specificOS,
115115
String? cpu,
116116
}) {
117-
final enabledSuites = suites.where((suite) => suite.enableCi);
118-
final filteredSuites = enabledSuites.where((suite) => suite.runConfig.browser == browser);
117+
final filteredSuites = suites.where(
118+
(suite) => suite.enableCi && suite.runConfig.browser == browser,
119+
);
119120
final bundles = filteredSuites.map((suite) => suite.testBundle).toSet();
120121
return <String, dynamic>{
121122
'name': '$platform run ${browser.name} suites',
@@ -149,7 +150,7 @@ class GenerateBuilderJsonCommand extends Command<bool> {
149150
'parameters': <String>[
150151
'test',
151152
'--copy-artifacts',
152-
for (final TestSuite suite in enabledSuites) '--suite=${suite.name}',
153+
for (final TestSuite suite in filteredSuites) '--suite=${suite.name}',
153154
],
154155
'script': 'flutter/lib/web_ui/dev/felt',
155156
},

‎engine/src/flutter/lib/web_ui/dev/steps/copy_artifacts_step.dart‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class CopyArtifactsStep implements PipelineStep {
7777
final String canvaskitSourceDirectory;
7878
final String canvaskitChromiumSourceDirectory;
7979
final String skwasmSourceDirectory;
80+
final String skwasmHeavySourceDirectory;
8081
switch (source) {
8182
case LocalArtifactSource(:final mode):
8283
final buildDirectory = getBuildDirectoryForRuntimeMode(mode).path;
@@ -88,6 +89,7 @@ class CopyArtifactsStep implements PipelineStep {
8889
canvaskitSourceDirectory = pathlib.join(buildDirectory, 'canvaskit');
8990
canvaskitChromiumSourceDirectory = pathlib.join(buildDirectory, 'canvaskit_chromium');
9091
skwasmSourceDirectory = pathlib.join(buildDirectory, 'skwasm');
92+
skwasmHeavySourceDirectory = pathlib.join(buildDirectory, 'skwasm_heavy');
9193

9294
case GcsArtifactSource(:final realm):
9395
final artifactsDirectory = (await _downloadArtifacts(realm)).path;
@@ -104,6 +106,7 @@ class CopyArtifactsStep implements PipelineStep {
104106
'chromium',
105107
);
106108
skwasmSourceDirectory = pathlib.join(artifactsDirectory, 'canvaskit');
109+
skwasmHeavySourceDirectory = pathlib.join(artifactsDirectory, 'canvaskit');
107110
}
108111

109112
await environment.webTestsArtifactsDir.create(recursive: true);
@@ -131,6 +134,7 @@ class CopyArtifactsStep implements PipelineStep {
131134
if (artifactDeps.skwasm) {
132135
copied.add('Skwasm');
133136
await copyWasmLibrary('skwasm', skwasmSourceDirectory, 'canvaskit');
137+
await copyWasmLibrary('skwasm_heavy', skwasmHeavySourceDirectory, 'canvaskit');
134138
}
135139
print('Copied artifacts: ${copied.join(', ')}');
136140
}

‎engine/src/flutter/lib/web_ui/dev/test_platform.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ class BrowserPlatform extends PlatformPlugin {
536536
canvasKitVariant: "${getCanvasKitVariant()}",
537537
canvasKitBaseUrl: "/canvaskit",
538538
forceSingleThreadedSkwasm: ${suite.runConfig.forceSingleThreadedSkwasm},
539+
wasmAllowList: ${jsonEncode(suite.runConfig.wasmAllowList)},
539540
},
540541
});
541542
</script>

‎engine/src/flutter/lib/web_ui/flutter_js/src/browser_environment.js‎

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,36 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
const isBlink = () => {
6-
return (navigator.vendor === 'Google Inc.') ||
7-
(navigator.agent === 'Edg/');
5+
/** @type {import("./types").WasmAllowList} */
6+
export const defaultWasmSupport = {
7+
"blink": true,
8+
"gecko": false,
9+
"webkit": false,
10+
"unknown": false,
811
}
912

13+
/**
14+
* @returns {import("./types").BrowserEngine}
15+
*/
16+
const getBrowserEngine = () => {
17+
if ((navigator.vendor === 'Google Inc.') ||
18+
(navigator.userAgent.includes('Edg/'))) {
19+
return "blink";
20+
}
21+
if (navigator.vendor === "Apple Computer, Inc.") {
22+
return "webkit";
23+
}
24+
if (navigator.vendor === "" && navigator.userAgent.includes('Firefox')) {
25+
return "gecko";
26+
}
27+
return "unknown";
28+
}
29+
30+
/** @type {import("./types").BrowserEnvironment} */
31+
const browserEngine = getBrowserEngine();
32+
1033
const hasImageCodecs = () => {
11-
if (typeof ImageDecoder === 'undefined') {
34+
if (typeof ImageDecoder === "undefined") {
1235
return false;
1336
}
1437
// TODO(yjbanov): https://github.com/flutter/flutter/issues/122761
@@ -18,7 +41,7 @@ const hasImageCodecs = () => {
1841
// up potentially incompatible implementations of ImagdeDecoder API. Instead,
1942
// when a new browser engine launches the API, we'll evaluate it and enable it
2043
// explicitly.
21-
return isBlink();
44+
return browserEngine === "blink";
2245
}
2346

2447
const hasChromiumBreakIterators = () => {
@@ -35,10 +58,9 @@ const supportsWasmGC = () => {
3558
return WebAssembly.validate(new Uint8Array(bytes));
3659
}
3760

38-
/**
39-
* @returns {import("./types").BrowserEnvironment}
40-
*/
61+
/** @type {import("./types").BrowserEnvironment} */
4162
export const browserEnvironment = {
63+
browserEngine: browserEngine,
4264
hasImageCodecs: hasImageCodecs(),
4365
hasChromiumBreakIterators: hasChromiumBreakIterators(),
4466
supportsWasmGC: supportsWasmGC(),

0 commit comments

Comments
 (0)