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 { ...@@ -855,6 +855,7 @@ class WebDevFS implements DevFS {
generateBootstrapScript( generateBootstrapScript(
requireUrl: 'require.js', requireUrl: 'require.js',
mapperUrl: 'stack_trace_mapper.js', mapperUrl: 'stack_trace_mapper.js',
generateLoadingIndicator: enableDwds,
), ),
); );
webAssetServer.writeFile( webAssetServer.writeFile(
......
...@@ -13,13 +13,74 @@ import 'package:package_config/package_config.dart'; ...@@ -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, /// This file is served when the browser requests "main.dart.js" in debug mode,
/// and is responsible for bootstrapping the RequireJS modules and attaching /// and is responsible for bootstrapping the RequireJS modules and attaching
/// the hot reload hooks. /// 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({ String generateBootstrapScript({
required String requireUrl, required String requireUrl,
required String mapperUrl, required String mapperUrl,
required bool generateLoadingIndicator,
}) { }) {
return ''' return '''
"use strict"; "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 = ` var styles = `
.flutter-loader { .flutter-loader {
width: 100%; width: 100%;
...@@ -93,49 +154,6 @@ document.addEventListener('dart-app-ready', function (e) { ...@@ -93,49 +154,6 @@ document.addEventListener('dart-app-ready', function (e) {
loader.parentNode.removeChild(loader); loader.parentNode.removeChild(loader);
styleSheet.parentNode.removeChild(styleSheet); 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() { ...@@ -12,6 +12,7 @@ void main() {
final String result = generateBootstrapScript( final String result = generateBootstrapScript(
requireUrl: 'require.js', requireUrl: 'require.js',
mapperUrl: 'mapper.js', mapperUrl: 'mapper.js',
generateLoadingIndicator: true,
); );
// require js source is interpolated correctly. // require js source is interpolated correctly.
expect(result, contains('"requireJs": "require.js"')); expect(result, contains('"requireJs": "require.js"'));
...@@ -27,16 +28,28 @@ void main() { ...@@ -27,16 +28,28 @@ void main() {
final String result = generateBootstrapScript( final String result = generateBootstrapScript(
requireUrl: 'require.js', requireUrl: 'require.js',
mapperUrl: 'mapper.js', mapperUrl: 'mapper.js',
generateLoadingIndicator: true,
); );
expect(result, contains('"flutter-loader"')); expect(result, contains('"flutter-loader"'));
expect(result, contains('"indeterminate"')); 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 // https://github.com/flutter/flutter/issues/107742
test('generateBootstrapScript loading indicator does not trigger scrollbars', () { test('generateBootstrapScript loading indicator does not trigger scrollbars', () {
final String result = generateBootstrapScript( final String result = generateBootstrapScript(
requireUrl: 'require.js', requireUrl: 'require.js',
mapperUrl: 'mapper.js', mapperUrl: 'mapper.js',
generateLoadingIndicator: true,
); );
// See: https://regexr.com/6q0ft // 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