Unverified Commit b7eaad8b authored by David Iglesias's avatar David Iglesias Committed by GitHub

[tool][web] Fix flutter.js in Safari 13 (#104761)

parent 812641b9
...@@ -27,14 +27,23 @@ _flutter.loader = null; ...@@ -27,14 +27,23 @@ _flutter.loader = null;
(function() { (function() {
"use strict"; "use strict";
class FlutterLoader { class FlutterLoader {
// TODO: Move the below methods to "#private" once supported by all the browsers /**
// we support. In the meantime, we use the "revealing module" pattern. * Creates a FlutterLoader, and initializes its instance methods.
*/
constructor() {
// TODO: Move the below methods to "#private" once supported by all the browsers
// we support. In the meantime, we use the "revealing module" pattern.
// Watchdog to prevent injecting the main entrypoint multiple times. // Watchdog to prevent injecting the main entrypoint multiple times.
_scriptLoaded = null; this._scriptLoaded = null;
// Resolver for the pending promise returned by loadEntrypoint. // Resolver for the pending promise returned by loadEntrypoint.
_didCreateEngineInitializerResolve = null; this._didCreateEngineInitializerResolve = null;
// Called by Flutter web.
// Bound to `this` now, so "this" is preserved across JS <-> Flutter jumps.
this.didCreateEngineInitializer = this._didCreateEngineInitializer.bind(this);
}
/** /**
* Initializes the main.dart.js with/without serviceWorker. * Initializes the main.dart.js with/without serviceWorker.
...@@ -51,19 +60,19 @@ _flutter.loader = null; ...@@ -51,19 +60,19 @@ _flutter.loader = null;
} }
/** /**
* Resolves the promise created by loadEntrypoint. Called by Flutter. * Resolves the promise created by loadEntrypoint.
* Needs to be weirdly bound like it is, so "this" is preserved across * Called by Flutter through the public `didCreateEngineInitializer` method,
* the JS <-> Flutter jumps. * which is bound to the correct instance of the FlutterLoader on the page.
* @param {*} engineInitializer * @param {*} engineInitializer
*/ */
didCreateEngineInitializer = (function(engineInitializer) { _didCreateEngineInitializer(engineInitializer) {
if (typeof this._didCreateEngineInitializerResolve != "function") { if (typeof this._didCreateEngineInitializerResolve != "function") {
console.warn("Do not call didCreateEngineInitializer by hand. Start with loadEntrypoint instead."); console.warn("Do not call didCreateEngineInitializer by hand. Start with loadEntrypoint instead.");
} }
this._didCreateEngineInitializerResolve(engineInitializer); this._didCreateEngineInitializerResolve(engineInitializer);
// Remove this method after it's done, so Flutter Web can hot restart. // Remove the public method after it's done, so Flutter Web can hot restart.
delete this.didCreateEngineInitializer; delete this.didCreateEngineInitializer;
}).bind(this); }
_loadEntrypoint(entrypointUrl) { _loadEntrypoint(entrypointUrl) {
if (!this._scriptLoaded) { if (!this._scriptLoaded) {
...@@ -71,7 +80,11 @@ _flutter.loader = null; ...@@ -71,7 +80,11 @@ _flutter.loader = null;
let scriptTag = document.createElement("script"); let scriptTag = document.createElement("script");
scriptTag.src = entrypointUrl; scriptTag.src = entrypointUrl;
scriptTag.type = "application/javascript"; scriptTag.type = "application/javascript";
this._didCreateEngineInitializerResolve = resolve; // Cache the resolve, so it can be called from Flutter. // Cache the resolve, so it can be called from Flutter.
// Note: Flutter hot restart doesn't re-create this promise, so this
// can only be called once. Instead, we need to model this as a stream
// of `engineCreated` events coming from Flutter that are handled by JS.
this._didCreateEngineInitializerResolve = resolve;
scriptTag.addEventListener("error", reject); scriptTag.addEventListener("error", reject);
document.body.append(scriptTag); document.body.append(scriptTag);
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment