// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:meta/meta.dart'; /// The JavaScript bootstrap script to support in-browser hot restart. /// /// The [requireUrl] loads our cached RequireJS script file. The [mapperUrl] /// loads the special Dart stack trace mapper. The [entrypoint] is the /// actual main.dart file. /// /// 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. String generateBootstrapScript({ @required String requireUrl, @required String mapperUrl, }) { return ''' "use strict"; // Attach source mapping. var mapperEl = document.createElement("script"); mapperEl.defer = true; mapperEl.async = false; mapperEl.src = "$mapperUrl"; document.head.appendChild(mapperEl); // Attach require JS. var requireEl = document.createElement("script"); requireEl.defer = true; requireEl.async = false; requireEl.src = "$requireUrl"; // This attribute tells require JS what to load as main (defined below). requireEl.setAttribute("data-main", "main_module.bootstrap"); document.head.appendChild(requireEl); '''; } /// Generate a synthetic main module which captures the application's main /// method. /// /// RE: Object.keys usage in app.main: /// This attaches the main entrypoint and hot reload functionality to the window. /// The app module will have a single property which contains the actual application /// code. The property name is based off of the entrypoint that is generated, for example /// the file `foo/bar/baz.dart` will generate a property named approximately /// `foo__bar__baz`. Rather than attempt to guess, we assume the first property of /// this object is the module. String generateMainModule({ @required String entrypoint, @required bool nullAssertions, }) { return '''/* ENTRYPOINT_EXTENTION_MARKER */ // Create the main module loaded below. define("main_module.bootstrap", ["$entrypoint", "dart_sdk"], function(app, dart_sdk) { dart_sdk.dart.setStartAsyncSynchronously(true); dart_sdk._debugger.registerDevtoolsFormatter(); if ($nullAssertions) { dart_sdk.dart.nonNullAsserts(true); } // See the generateMainModule doc comment. var child = {}; child.main = app[Object.keys(app)[0]].main; /* MAIN_EXTENSION_MARKER */ child.main(); window.\$dartLoader = {}; window.\$dartLoader.rootDirectories = []; if (window.\$requireLoader) { window.\$requireLoader.getModuleLibraries = dart_sdk.dart.getModuleLibraries; } if (window.\$dartStackTraceUtility && !window.\$dartStackTraceUtility.ready) { window.\$dartStackTraceUtility.ready = true; let dart = dart_sdk.dart; window.\$dartStackTraceUtility.setSourceMapProvider(function(url) { var baseUrl = window.location.protocol + '//' + window.location.host; url = url.replace(baseUrl + '/', ''); if (url == 'dart_sdk.js') { return dart.getSourceMap('dart_sdk'); } url = url.replace(".lib.js", ""); return dart.getSourceMap(url); }); } }); '''; }