mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Reverts "Reland "Output .js files as ES6 modules. (#52023)" (#53688)" (flutter/engine#53709)
Reverts: flutter/engine#53688 Initiated by: jiahaog Reason for reverting: canvaskit.js cannot be loaded in an internal end to end test - see b/350885206 Original PR Author: eyebrowsoffire Reviewed By: {ditman} This change reverts the following previous change: This is an attempt to reland https://github.com/flutter/engine/pull/52023. The issue previously is that if it was not specified by the user, the default CanvasKit base URL did not have a leading slash, which does not work when doing dynamic imports.
This commit is contained in:
parent
76fb118a73
commit
607d1e1bb5
2
DEPS
2
DEPS
@ -277,7 +277,7 @@ allowed_hosts = [
|
||||
]
|
||||
|
||||
deps = {
|
||||
'src': 'https://github.com/flutter/buildroot.git' + '@' + 'e265c359126b24351f534080fb22edaa159f2215',
|
||||
'src': 'https://github.com/flutter/buildroot.git' + '@' + '8c2d66fa4e6298894425f5bdd0591bc5b1154c53',
|
||||
|
||||
'src/flutter/third_party/depot_tools':
|
||||
Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '580b4ff3f5cd0dcaa2eacda28cefe0f45320e8f7',
|
||||
|
||||
@ -6,11 +6,11 @@ import { createWasmInstantiator } from "./instantiate_wasm.js";
|
||||
import { joinPathSegments } from "./utils.js";
|
||||
|
||||
export const loadCanvasKit = (deps, config, browserEnvironment, canvasKitBaseUrl) => {
|
||||
window.flutterCanvasKitLoaded = (async () => {
|
||||
if (window.flutterCanvasKit) {
|
||||
// The user has set this global variable ahead of time, so we just return that.
|
||||
return window.flutterCanvasKit;
|
||||
}
|
||||
if (window.flutterCanvasKit) {
|
||||
// The user has set this global variable ahead of time, so we just return that.
|
||||
return Promise.resolve(window.flutterCanvasKit);
|
||||
}
|
||||
window.flutterCanvasKitLoaded = new Promise((resolve, reject) => {
|
||||
const supportsChromiumCanvasKit = browserEnvironment.hasChromiumBreakIterators && browserEnvironment.hasImageCodecs;
|
||||
if (!supportsChromiumCanvasKit && config.canvasKitVariant == "chromium") {
|
||||
throw "Chromium CanvasKit variant specifically requested, but unsupported in this browser";
|
||||
@ -25,11 +25,24 @@ export const loadCanvasKit = (deps, config, browserEnvironment, canvasKitBaseUrl
|
||||
canvasKitUrl = deps.flutterTT.policy.createScriptURL(canvasKitUrl);
|
||||
}
|
||||
const wasmInstantiator = createWasmInstantiator(joinPathSegments(baseUrl, "canvaskit.wasm"));
|
||||
const canvasKitModule = await import(canvasKitUrl);
|
||||
window.flutterCanvasKit = await canvasKitModule.default({
|
||||
instantiateWasm: wasmInstantiator,
|
||||
const script = document.createElement("script");
|
||||
script.src = canvasKitUrl;
|
||||
if (config.nonce) {
|
||||
script.nonce = config.nonce;
|
||||
}
|
||||
script.addEventListener("load", async () => {
|
||||
try {
|
||||
const canvasKit = await CanvasKitInit({
|
||||
instantiateWasm: wasmInstantiator,
|
||||
});
|
||||
window.flutterCanvasKit = canvasKit;
|
||||
resolve(canvasKit);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
return window.flutterCanvasKit;
|
||||
})();
|
||||
script.addEventListener("error", reject);
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
return window.flutterCanvasKitLoaded;
|
||||
}
|
||||
|
||||
@ -5,28 +5,43 @@
|
||||
import { createWasmInstantiator } from "./instantiate_wasm.js";
|
||||
import { joinPathSegments } from "./utils.js";
|
||||
|
||||
export const loadSkwasm = async (deps, config, browserEnvironment, baseUrl) => {
|
||||
let skwasmUrl = joinPathSegments(baseUrl, "skwasm.js");
|
||||
if (deps.flutterTT.policy) {
|
||||
skwasmUrl = deps.flutterTT.policy.createScriptURL(skwasmUrl);
|
||||
}
|
||||
const wasmInstantiator = createWasmInstantiator(joinPathSegments(baseUrl, "skwasm.wasm"));
|
||||
const skwasm = await import(skwasmUrl);
|
||||
return await skwasm.default({
|
||||
instantiateWasm: wasmInstantiator,
|
||||
locateFile: (fileName, scriptDirectory) => {
|
||||
// When hosted via a CDN or some other url that is not the same
|
||||
// origin as the main script of the page, we will fail to create
|
||||
// a web worker with the .worker.js script. This workaround will
|
||||
// make sure that the worker JS can be loaded regardless of where
|
||||
// it is hosted.
|
||||
const url = scriptDirectory + fileName;
|
||||
if (url.endsWith('.worker.js')) {
|
||||
return URL.createObjectURL(new Blob(
|
||||
[`importScripts('${url}');`],
|
||||
{ 'type': 'application/javascript' }));
|
||||
}
|
||||
return url;
|
||||
export const loadSkwasm = (deps, config, browserEnvironment, baseUrl) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let skwasmUrl = joinPathSegments(baseUrl, "skwasm.js");
|
||||
if (deps.flutterTT.policy) {
|
||||
skwasmUrl = deps.flutterTT.policy.createScriptURL(skwasmUrl);
|
||||
}
|
||||
const wasmInstantiator = createWasmInstantiator(joinPathSegments(baseUrl, "skwasm.wasm"));
|
||||
const script = document.createElement("script");
|
||||
script.src = skwasmUrl;
|
||||
if (config.nonce) {
|
||||
script.nonce = config.nonce;
|
||||
}
|
||||
script.addEventListener("load", async () => {
|
||||
try {
|
||||
const skwasmInstance = await skwasm({
|
||||
instantiateWasm: wasmInstantiator,
|
||||
locateFile: (fileName, scriptDirectory) => {
|
||||
// When hosted via a CDN or some other url that is not the same
|
||||
// origin as the main script of the page, we will fail to create
|
||||
// a web worker with the .worker.js script. This workaround will
|
||||
// make sure that the worker JS can be loaded regardless of where
|
||||
// it is hosted.
|
||||
const url = scriptDirectory + fileName;
|
||||
if (url.endsWith(".worker.js")) {
|
||||
return URL.createObjectURL(new Blob(
|
||||
[`importScripts("${url}");`],
|
||||
{ "type": "application/javascript" }));
|
||||
}
|
||||
return url;
|
||||
}
|
||||
});
|
||||
resolve(skwasmInstance);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
script.addEventListener("error", reject);
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
@ -259,13 +259,12 @@ extension CanvasKitExtension on CanvasKit {
|
||||
);
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class CanvasKitModule {}
|
||||
@JS('window.CanvasKitInit')
|
||||
external JSAny _CanvasKitInit(CanvasKitInitOptions options);
|
||||
|
||||
extension CanvasKitModuleExtension on CanvasKitModule {
|
||||
@JS('default')
|
||||
external JSPromise<JSAny> defaultExport(CanvasKitInitOptions options);
|
||||
Future<CanvasKit> CanvasKitInit(CanvasKitInitOptions options) {
|
||||
return js_util.promiseToFuture<CanvasKit>(
|
||||
_CanvasKitInit(options).toObjectShallow);
|
||||
}
|
||||
|
||||
typedef LocateFileCallback = String Function(String file, String unusedBase);
|
||||
@ -3662,11 +3661,11 @@ String canvasKitWasmModuleUrl(String file, String canvasKitBase) =>
|
||||
/// Downloads the CanvasKit JavaScript, then calls `CanvasKitInit` to download
|
||||
/// and intialize the CanvasKit wasm.
|
||||
Future<CanvasKit> downloadCanvasKit() async {
|
||||
final CanvasKitModule canvasKitModule = await _downloadOneOf(_canvasKitJsUrls);
|
||||
await _downloadOneOf(_canvasKitJsUrls);
|
||||
|
||||
final CanvasKit canvasKit = (await canvasKitModule.defaultExport(CanvasKitInitOptions(
|
||||
final CanvasKit canvasKit = await CanvasKitInit(CanvasKitInitOptions(
|
||||
locateFile: createLocateFileCallback(canvasKitWasmModuleUrl),
|
||||
)).toDart) as CanvasKit;
|
||||
));
|
||||
|
||||
if (canvasKit.ParagraphBuilder.RequiresClientICU() && !browserSupportsCanvaskitChromium) {
|
||||
throw Exception(
|
||||
@ -3682,12 +3681,10 @@ Future<CanvasKit> downloadCanvasKit() async {
|
||||
/// downloads it.
|
||||
///
|
||||
/// If none of the URLs can be downloaded, throws an [Exception].
|
||||
Future<CanvasKitModule> _downloadOneOf(Iterable<String> urls) async {
|
||||
Future<void> _downloadOneOf(Iterable<String> urls) async {
|
||||
for (final String url in urls) {
|
||||
try {
|
||||
return await _downloadCanvasKitJs(url);
|
||||
} catch (_) {
|
||||
continue;
|
||||
if (await _downloadCanvasKitJs(url)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3701,7 +3698,32 @@ Future<CanvasKitModule> _downloadOneOf(Iterable<String> urls) async {
|
||||
///
|
||||
/// Returns a [Future] that completes with `true` if the CanvasKit JavaScript
|
||||
/// file was successfully downloaded, or `false` if it failed.
|
||||
Future<CanvasKitModule> _downloadCanvasKitJs(String url) async {
|
||||
final JSAny scriptUrl = createTrustedScriptUrl(url);
|
||||
return (await importModule(scriptUrl).toDart) as CanvasKitModule;
|
||||
Future<bool> _downloadCanvasKitJs(String url) {
|
||||
final DomHTMLScriptElement canvasKitScript =
|
||||
createDomHTMLScriptElement(configuration.nonce);
|
||||
canvasKitScript.src = createTrustedScriptUrl(url);
|
||||
|
||||
final Completer<bool> canvasKitLoadCompleter = Completer<bool>();
|
||||
|
||||
late final DomEventListener loadCallback;
|
||||
late final DomEventListener errorCallback;
|
||||
|
||||
void loadEventHandler(DomEvent _) {
|
||||
canvasKitScript.remove();
|
||||
canvasKitLoadCompleter.complete(true);
|
||||
}
|
||||
void errorEventHandler(DomEvent errorEvent) {
|
||||
canvasKitScript.remove();
|
||||
canvasKitLoadCompleter.complete(false);
|
||||
}
|
||||
|
||||
loadCallback = createDomEventListener(loadEventHandler);
|
||||
errorCallback = createDomEventListener(errorEventHandler);
|
||||
|
||||
canvasKitScript.addEventListener('load', loadCallback);
|
||||
canvasKitScript.addEventListener('error', errorCallback);
|
||||
|
||||
domDocument.head!.appendChild(canvasKitScript);
|
||||
|
||||
return canvasKitLoadCompleter.future;
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ class FlutterConfiguration {
|
||||
_configuration?.canvasKitBaseUrl ?? _defaultCanvasKitBaseUrl;
|
||||
static const String _defaultCanvasKitBaseUrl = String.fromEnvironment(
|
||||
'FLUTTER_WEB_CANVASKIT_URL',
|
||||
defaultValue: '/canvaskit/',
|
||||
defaultValue: 'canvaskit/',
|
||||
);
|
||||
|
||||
/// The variant of CanvasKit to download.
|
||||
|
||||
@ -3383,16 +3383,16 @@ final DomTrustedTypePolicy _ttPolicy = domWindow.trustedTypes!.createPolicy(
|
||||
|
||||
/// Converts a String `url` into a [DomTrustedScriptURL] object when the
|
||||
/// Trusted Types API is available, else returns the unmodified `url`.
|
||||
JSAny createTrustedScriptUrl(String url) {
|
||||
Object createTrustedScriptUrl(String url) {
|
||||
if (domWindow.trustedTypes != null) {
|
||||
// Pass `url` through Flutter Engine's TrustedType policy.
|
||||
final DomTrustedScriptURL trustedUrl = _ttPolicy.createScriptURL(url);
|
||||
|
||||
assert(trustedUrl.url != '', 'URL: $url rejected by TrustedTypePolicy');
|
||||
|
||||
return trustedUrl as JSAny;
|
||||
return trustedUrl;
|
||||
}
|
||||
return url.toJS;
|
||||
return url;
|
||||
}
|
||||
|
||||
DomMessageChannel createDomMessageChannel() => DomMessageChannel();
|
||||
|
||||
@ -18,6 +18,13 @@ void testMain() {
|
||||
// Initialize CanvasKit...
|
||||
await bootstrapAndRunApp();
|
||||
|
||||
// CanvasKitInit should be defined...
|
||||
expect(
|
||||
js_util.hasProperty(domWindow, 'CanvasKitInit'),
|
||||
isTrue,
|
||||
reason: 'CanvasKitInit should be defined on Window',
|
||||
);
|
||||
|
||||
// window.exports and window.module should be undefined!
|
||||
expect(
|
||||
js_util.hasProperty(domWindow, 'exports'),
|
||||
|
||||
@ -22,16 +22,16 @@ void testMain() {
|
||||
test('initializes with null', () async {
|
||||
final FlutterConfiguration config = FlutterConfiguration.legacy(null);
|
||||
|
||||
expect(config.canvasKitBaseUrl, '/canvaskit/'); // _defaultCanvasKitBaseUrl
|
||||
expect(config.canvasKitBaseUrl, 'canvaskit/'); // _defaultCanvasKitBaseUrl
|
||||
});
|
||||
|
||||
test('legacy constructor initializes with a Js Object', () async {
|
||||
final FlutterConfiguration config = FlutterConfiguration.legacy(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitBaseUrl': '/some_other_url/',
|
||||
'canvasKitBaseUrl': 'some_other_url/',
|
||||
}) as JsFlutterConfiguration);
|
||||
|
||||
expect(config.canvasKitBaseUrl, '/some_other_url/');
|
||||
expect(config.canvasKitBaseUrl, 'some_other_url/');
|
||||
});
|
||||
});
|
||||
|
||||
@ -39,13 +39,13 @@ void testMain() {
|
||||
test('throws assertion error if already initialized from JS', () async {
|
||||
final FlutterConfiguration config = FlutterConfiguration.legacy(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitBaseUrl': '/some_other_url/',
|
||||
'canvasKitBaseUrl': 'some_other_url/',
|
||||
}) as JsFlutterConfiguration);
|
||||
|
||||
expect(() {
|
||||
config.setUserConfiguration(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitBaseUrl': '/yet_another_url/',
|
||||
'canvasKitBaseUrl': 'yet_another_url/',
|
||||
}) as JsFlutterConfiguration);
|
||||
}, throwsAssertionError);
|
||||
});
|
||||
@ -55,10 +55,10 @@ void testMain() {
|
||||
|
||||
config.setUserConfiguration(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitBaseUrl': '/one_more_url/',
|
||||
'canvasKitBaseUrl': 'one_more_url/',
|
||||
}) as JsFlutterConfiguration);
|
||||
|
||||
expect(config.canvasKitBaseUrl, '/one_more_url/');
|
||||
expect(config.canvasKitBaseUrl, 'one_more_url/');
|
||||
});
|
||||
|
||||
test('can receive non-existing properties without crashing', () async {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user