Unverified Commit 0f082889 authored by Yegor's avatar Yegor Committed by GitHub

[web] remove loading indicator in -d web-server builds (#136482)

Fixes https://github.com/flutter/flutter/issues/135226
parent 5f796b29
......@@ -855,6 +855,7 @@ class WebDevFS implements DevFS {
generateBootstrapScript(
requireUrl: 'require.js',
mapperUrl: 'stack_trace_mapper.js',
generateLoadingIndicator: enableDwds,
),
);
webAssetServer.writeFile(
......
......@@ -13,13 +13,74 @@ import 'package:package_config/package_config.dart';
/// This file is served when the browser requests "main.dart.js" in debug mode,
/// and is responsible for bootstrapping the RequireJS modules and attaching
/// the hot reload hooks.
///
/// If `generateLoadingIndicator` is true, embeds a loading indicator onto the
/// web page that's visible while the Flutter app is loading.
String generateBootstrapScript({
required String requireUrl,
required String mapperUrl,
required bool generateLoadingIndicator,
}) {
return '''
"use strict";
${generateLoadingIndicator ? _generateLoadingIndicator() : ''}
// A map containing the URLs for the bootstrap scripts in debug.
let _scriptUrls = {
"mapper": "$mapperUrl",
"requireJs": "$requireUrl"
};
// Create a TrustedTypes policy so we can attach Scripts...
let _ttPolicy;
if (window.trustedTypes) {
_ttPolicy = trustedTypes.createPolicy("flutter-tools-bootstrap", {
createScriptURL: (url) => {
let scriptUrl = _scriptUrls[url];
if (!scriptUrl) {
console.error("Unknown Flutter Web bootstrap resource!", url);
}
return scriptUrl;
}
});
}
// Creates a TrustedScriptURL for a given `scriptName`.
// See `_scriptUrls` and `_ttPolicy` above.
function getTTScriptUrl(scriptName) {
let defaultUrl = _scriptUrls[scriptName];
return _ttPolicy ? _ttPolicy.createScriptURL(scriptName) : defaultUrl;
}
// Attach source mapping.
var mapperEl = document.createElement("script");
mapperEl.defer = true;
mapperEl.async = false;
mapperEl.src = getTTScriptUrl("mapper");
document.head.appendChild(mapperEl);
// Attach require JS.
var requireEl = document.createElement("script");
requireEl.defer = true;
requireEl.async = false;
requireEl.src = getTTScriptUrl("requireJs");
// This attribute tells require JS what to load as main (defined below).
requireEl.setAttribute("data-main", "main_module.bootstrap");
document.head.appendChild(requireEl);
''';
}
/// Creates a visual animated loading indicator and puts it on the page to
/// provide feedback to the developer that the app is being loaded. Otherwise,
/// the developer would be staring at a blank page wondering if the app will
/// come up or not.
///
/// This indicator should only be used when DWDS is enabled, e.g. with the
/// `-d chrome` option. Debug builds without DWDS, e.g. `flutter run -d web-server`
/// or `flutter build web --debug` should not use this indicator.
String _generateLoadingIndicator() {
return '''
var styles = `
.flutter-loader {
width: 100%;
......@@ -93,49 +154,6 @@ document.addEventListener('dart-app-ready', function (e) {
loader.parentNode.removeChild(loader);
styleSheet.parentNode.removeChild(styleSheet);
});
// A map containing the URLs for the bootstrap scripts in debug.
let _scriptUrls = {
"mapper": "$mapperUrl",
"requireJs": "$requireUrl"
};
// Create a TrustedTypes policy so we can attach Scripts...
let _ttPolicy;
if (window.trustedTypes) {
_ttPolicy = trustedTypes.createPolicy("flutter-tools-bootstrap", {
createScriptURL: (url) => {
let scriptUrl = _scriptUrls[url];
if (!scriptUrl) {
console.error("Unknown Flutter Web bootstrap resource!", url);
}
return scriptUrl;
}
});
}
// Creates a TrustedScriptURL for a given `scriptName`.
// See `_scriptUrls` and `_ttPolicy` above.
function getTTScriptUrl(scriptName) {
let defaultUrl = _scriptUrls[scriptName];
return _ttPolicy ? _ttPolicy.createScriptURL(scriptName) : defaultUrl;
}
// Attach source mapping.
var mapperEl = document.createElement("script");
mapperEl.defer = true;
mapperEl.async = false;
mapperEl.src = getTTScriptUrl("mapper");
document.head.appendChild(mapperEl);
// Attach require JS.
var requireEl = document.createElement("script");
requireEl.defer = true;
requireEl.async = false;
requireEl.src = getTTScriptUrl("requireJs");
// This attribute tells require JS what to load as main (defined below).
requireEl.setAttribute("data-main", "main_module.bootstrap");
document.head.appendChild(requireEl);
''';
}
......
......@@ -12,6 +12,7 @@ void main() {
final String result = generateBootstrapScript(
requireUrl: 'require.js',
mapperUrl: 'mapper.js',
generateLoadingIndicator: true,
);
// require js source is interpolated correctly.
expect(result, contains('"requireJs": "require.js"'));
......@@ -27,16 +28,28 @@ void main() {
final String result = generateBootstrapScript(
requireUrl: 'require.js',
mapperUrl: 'mapper.js',
generateLoadingIndicator: true,
);
expect(result, contains('"flutter-loader"'));
expect(result, contains('"indeterminate"'));
});
test('generateBootstrapScript does not include loading indicator', () {
final String result = generateBootstrapScript(
requireUrl: 'require.js',
mapperUrl: 'mapper.js',
generateLoadingIndicator: false,
);
expect(result, isNot(contains('"flutter-loader"')));
expect(result, isNot(contains('"indeterminate"')));
});
// https://github.com/flutter/flutter/issues/107742
test('generateBootstrapScript loading indicator does not trigger scrollbars', () {
final String result = generateBootstrapScript(
requireUrl: 'require.js',
mapperUrl: 'mapper.js',
generateLoadingIndicator: true,
);
// See: https://regexr.com/6q0ft
......
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