Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 6cafacf

Browse files
authored
Reland "[web] Better way to detect CanvasKit variant (#40154)" (#40347)
Reland "[web] Better way to detect CanvasKit variant (#40154)"
1 parent 9a2a453 commit 6cafacf

File tree

5 files changed

+40
-63
lines changed

5 files changed

+40
-63
lines changed

lib/web_ui/lib/src/engine/browser_detection.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,4 @@ int _detectWebGLVersion() {
268268
}
269269

270270
/// Whether the current browser supports the Chromium variant of CanvasKit.
271-
const bool browserSupportsCanvaskitChromium = false;
272-
// TODO(mdebbar): Uncomment this to enable real detection of browser support.
273-
// final bool browserSupportsCanvaskitChromium = domIntl.v8BreakIterator != null;
271+
final bool browserSupportsCanvaskitChromium = domIntl.v8BreakIterator != null;

lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart

Lines changed: 35 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,9 @@ import 'renderer.dart';
2828
/// Entrypoint into the CanvasKit API.
2929
late CanvasKit canvasKit;
3030

31-
late CanvasKitVariant _canvasKitVariant;
32-
33-
/// Which variant of CanvasKit we are using.
34-
CanvasKitVariant get canvasKitVariant => _canvasKitVariant;
35-
set canvasKitVariant(CanvasKitVariant value) {
36-
if (value == CanvasKitVariant.auto) {
37-
throw ArgumentError.value(
38-
value,
39-
'value',
40-
'CanvasKitVariant.auto is not a valid value for canvasKitVariant',
41-
);
42-
}
43-
_canvasKitVariant = value;
44-
}
45-
31+
// TODO(mdebbar): Turn this on when CanvasKit Chromium is ready.
32+
// https://github.com/flutter/flutter/issues/122329
33+
const bool _enableCanvasKitChromiumInAutoMode = false;
4634

4735
/// Sets the [CanvasKit] object on `window` so we can use `@JS()` to bind to
4836
/// static APIs.
@@ -1884,6 +1872,13 @@ extension SkParagraphBuilderNamespaceExtension on SkParagraphBuilderNamespace {
18841872
SkParagraphStyle paragraphStyle,
18851873
TypefaceFontProvider? fontManager,
18861874
);
1875+
1876+
bool RequiresClientICU() {
1877+
if (!js_util.hasProperty(this, 'RequiresClientICU')) {
1878+
return false;
1879+
}
1880+
return js_util.callMethod(this, 'RequiresClientICU', const <Object>[],) as bool;
1881+
}
18871882
}
18881883

18891884
@JS()
@@ -2699,47 +2694,26 @@ void patchCanvasKitModule(DomHTMLScriptElement canvasKitScript) {
26992694
}
27002695
}
27012696

2702-
String get _canvasKitBaseUrl => configuration.canvasKitBaseUrl;
2703-
27042697
const String _kFullCanvasKitJsFileName = 'canvaskit.js';
27052698
const String _kChromiumCanvasKitJsFileName = 'chromium/canvaskit.js';
27062699

2707-
// TODO(mdebbar): Replace this with a Record once it's supported in Dart.
2708-
class _CanvasKitVariantUrl {
2709-
const _CanvasKitVariantUrl(this.url, this.variant)
2710-
: assert(
2711-
variant != CanvasKitVariant.auto,
2712-
'CanvasKitVariant.auto cannot have a url',
2713-
);
2714-
2715-
final String url;
2716-
final CanvasKitVariant variant;
2717-
2718-
static _CanvasKitVariantUrl chromium = _CanvasKitVariantUrl(
2719-
'$_canvasKitBaseUrl$_kChromiumCanvasKitJsFileName',
2720-
CanvasKitVariant.chromium,
2721-
);
2722-
2723-
static _CanvasKitVariantUrl full = _CanvasKitVariantUrl(
2724-
'$_canvasKitBaseUrl$_kFullCanvasKitJsFileName',
2725-
CanvasKitVariant.full,
2726-
);
2727-
}
2728-
2729-
List<_CanvasKitVariantUrl> get _canvasKitUrls {
2700+
String get _canvasKitBaseUrl => configuration.canvasKitBaseUrl;
2701+
List<String> get _canvasKitJsFileNames {
27302702
switch (configuration.canvasKitVariant) {
27312703
case CanvasKitVariant.auto:
2732-
return <_CanvasKitVariantUrl>[
2733-
if (browserSupportsCanvaskitChromium) _CanvasKitVariantUrl.chromium,
2734-
_CanvasKitVariantUrl.full,
2704+
return <String>[
2705+
if (_enableCanvasKitChromiumInAutoMode) _kChromiumCanvasKitJsFileName,
2706+
_kFullCanvasKitJsFileName,
27352707
];
27362708
case CanvasKitVariant.full:
2737-
return <_CanvasKitVariantUrl>[_CanvasKitVariantUrl.full];
2709+
return <String>[_kFullCanvasKitJsFileName];
27382710
case CanvasKitVariant.chromium:
2739-
return <_CanvasKitVariantUrl>[_CanvasKitVariantUrl.chromium];
2711+
return <String>[_kChromiumCanvasKitJsFileName];
27402712
}
27412713
}
2742-
2714+
Iterable<String> get _canvasKitJsUrls {
2715+
return _canvasKitJsFileNames.map((String filename) => '$_canvasKitBaseUrl$filename');
2716+
}
27432717
@visibleForTesting
27442718
String canvasKitWasmModuleUrl(String file, String canvasKitBase) =>
27452719
canvasKitBase + file;
@@ -2749,23 +2723,29 @@ String canvasKitWasmModuleUrl(String file, String canvasKitBase) =>
27492723
/// Downloads the CanvasKit JavaScript, then calls `CanvasKitInit` to download
27502724
/// and intialize the CanvasKit wasm.
27512725
Future<CanvasKit> downloadCanvasKit() async {
2752-
await _downloadOneOf(_canvasKitUrls);
2726+
await _downloadOneOf(_canvasKitJsUrls);
27532727

2754-
return CanvasKitInit(CanvasKitInitOptions(
2728+
final CanvasKit canvasKit = await CanvasKitInit(CanvasKitInitOptions(
27552729
locateFile: allowInterop(canvasKitWasmModuleUrl),
27562730
));
2731+
2732+
if (canvasKit.ParagraphBuilder.RequiresClientICU() && !browserSupportsCanvaskitChromium) {
2733+
throw Exception(
2734+
'The CanvasKit variant you are using only works on Chromium browsers. '
2735+
'Please use a different CanvasKit variant, or use a Chromium browser.',
2736+
);
2737+
}
2738+
2739+
return canvasKit;
27572740
}
27582741

2759-
/// Finds the first entry in [urls] that can be downloaded successfully, and
2742+
/// Finds the first URL in [urls] that can be downloaded successfully, and
27602743
/// downloads it.
27612744
///
27622745
/// If none of the URLs can be downloaded, throws an [Exception].
2763-
///
2764-
/// Also sets [canvasKitVariant] to the variant of CanvasKit that was downloaded.
2765-
Future<void> _downloadOneOf(Iterable<_CanvasKitVariantUrl> urls) async {
2766-
for (final _CanvasKitVariantUrl entry in urls) {
2767-
if (await _downloadCanvasKitJs(entry.url)) {
2768-
canvasKitVariant = entry.variant;
2746+
Future<void> _downloadOneOf(Iterable<String> urls) async {
2747+
for (final String url in urls) {
2748+
if (await _downloadCanvasKitJs(url)) {
27692749
return;
27702750
}
27712751
}

lib/web_ui/lib/src/engine/canvaskit/text.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ class CkParagraphBuilder implements ui.ParagraphBuilder {
984984

985985
/// Builds the CkParagraph with the builder and deletes the builder.
986986
SkParagraph _buildSkParagraph() {
987-
if (canvasKitVariant == CanvasKitVariant.chromium) {
987+
if (canvasKit.ParagraphBuilder.RequiresClientICU()) {
988988
injectClientICU(_paragraphBuilder);
989989
}
990990
final SkParagraph result = _paragraphBuilder.build();

lib/web_ui/lib/src/engine/canvaskit/text_fragmenter.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ import 'dart:typed_data';
77
import '../dom.dart';
88
import '../text/line_breaker.dart';
99
import 'canvaskit_api.dart';
10-
import 'renderer.dart';
1110

1211
/// Injects required ICU data into the [builder].
1312
///
1413
/// This should only be used with the CanvasKit Chromium variant that's compiled
1514
/// without ICU data.
1615
void injectClientICU(SkParagraphBuilder builder) {
1716
assert(
18-
canvasKitVariant == CanvasKitVariant.chromium,
17+
canvasKit.ParagraphBuilder.RequiresClientICU(),
1918
'This method should only be used with the CanvasKit Chromium variant.',
2019
);
2120

lib/web_ui/test/canvaskit/canvaskit_api_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,7 +1624,7 @@ void _paragraphTests() {
16241624
builder.pushStyle(
16251625
canvasKit.TextStyle(SkTextStyleProperties()..halfLeading = true));
16261626
builder.pop();
1627-
if (canvasKitVariant == CanvasKitVariant.chromium) {
1627+
if (canvasKit.ParagraphBuilder.RequiresClientICU()) {
16281628
injectClientICU(builder);
16291629
}
16301630
final SkParagraph paragraph = builder.build();
@@ -1742,7 +1742,7 @@ void _paragraphTests() {
17421742
);
17431743
builder.addText('hello');
17441744

1745-
if (canvasKitVariant == CanvasKitVariant.chromium) {
1745+
if (canvasKit.ParagraphBuilder.RequiresClientICU()) {
17461746
injectClientICU(builder);
17471747
}
17481748

0 commit comments

Comments
 (0)