@@ -8,8 +8,6 @@ import 'dart:typed_data';
8
8
import 'package:dwds/data/build_result.dart' ;
9
9
// ignore: import_of_legacy_library_into_null_safe
10
10
import 'package:dwds/dwds.dart' ;
11
- import 'package:html/dom.dart' ;
12
- import 'package:html/parser.dart' ;
13
11
import 'package:logging/logging.dart' as logging;
14
12
import 'package:meta/meta.dart' ;
15
13
import 'package:mime/mime.dart' as mime;
@@ -29,14 +27,14 @@ import '../base/platform.dart';
29
27
import '../build_info.dart' ;
30
28
import '../build_system/targets/scene_importer.dart' ;
31
29
import '../build_system/targets/shader_compiler.dart' ;
32
- import '../build_system/targets/web.dart' ;
33
30
import '../bundle_builder.dart' ;
34
31
import '../cache.dart' ;
35
32
import '../compile.dart' ;
36
33
import '../convert.dart' ;
37
34
import '../dart/package_map.dart' ;
38
35
import '../devfs.dart' ;
39
36
import '../globals.dart' as globals;
37
+ import '../html_utils.dart' ;
40
38
import '../project.dart' ;
41
39
import '../vmservice.dart' ;
42
40
import '../web/bootstrap.dart' ;
@@ -136,9 +134,7 @@ class WebAssetServer implements AssetReader {
136
134
this ._modules,
137
135
this ._digests,
138
136
this ._nullSafetyMode,
139
- ) : basePath = _parseBasePathFromIndexHtml (globals.fs.currentDirectory
140
- .childDirectory ('web' )
141
- .childFile ('index.html' ));
137
+ ) : basePath = _getIndexHtml ().getBaseHref ();
142
138
143
139
// Fallback to "application/octet-stream" on null which
144
140
// makes no claims as to the structure of the data.
@@ -299,7 +295,7 @@ class WebAssetServer implements AssetReader {
299
295
server,
300
296
PackageUriMapper (packageConfig),
301
297
digestProvider,
302
- server.basePath! ,
298
+ server.basePath,
303
299
).strategy,
304
300
expressionCompiler: expressionCompiler,
305
301
spawnDds: enableDds,
@@ -345,12 +341,11 @@ class WebAssetServer implements AssetReader {
345
341
@visibleForTesting
346
342
Uint8List ? getMetadata (String path) => _webMemoryFS.metadataFiles[path];
347
343
348
- @visibleForTesting
349
-
350
344
/// The base path to serve from.
351
345
///
352
346
/// It should have no leading or trailing slashes.
353
- String ? basePath = '' ;
347
+ @visibleForTesting
348
+ String basePath;
354
349
355
350
// handle requests for JavaScript source, dart sources maps, or asset files.
356
351
@visibleForTesting
@@ -496,27 +491,20 @@ class WebAssetServer implements AssetReader {
496
491
WebRendererMode webRenderer = WebRendererMode .html;
497
492
498
493
shelf.Response _serveIndex () {
494
+
495
+ final IndexHtml indexHtml = _getIndexHtml ();
496
+
497
+ indexHtml.applySubstitutions (
498
+ // Currently, we don't support --base-href for the "run" command.
499
+ baseHref: '/' ,
500
+ serviceWorkerVersion: null ,
501
+ );
502
+
499
503
final Map <String , String > headers = < String , String > {
500
504
HttpHeaders .contentTypeHeader: 'text/html' ,
505
+ HttpHeaders .contentLengthHeader: indexHtml.content.length.toString (),
501
506
};
502
- final File indexFile = globals.fs.currentDirectory
503
- .childDirectory ('web' )
504
- .childFile ('index.html' );
505
-
506
- if (indexFile.existsSync ()) {
507
- String indexFileContent = indexFile.readAsStringSync ();
508
- if (indexFileContent.contains (kBaseHrefPlaceholder)) {
509
- indexFileContent = indexFileContent.replaceAll (kBaseHrefPlaceholder, '/' );
510
- headers[HttpHeaders .contentLengthHeader] = indexFileContent.length.toString ();
511
- return shelf.Response .ok (indexFileContent,headers: headers);
512
- }
513
- headers[HttpHeaders .contentLengthHeader] =
514
- indexFile.lengthSync ().toString ();
515
- return shelf.Response .ok (indexFile.openRead (), headers: headers);
516
- }
517
-
518
- headers[HttpHeaders .contentLengthHeader] = _kDefaultIndex.length.toString ();
519
- return shelf.Response .ok (_kDefaultIndex, headers: headers);
507
+ return shelf.Response .ok (indexHtml.content, headers: headers);
520
508
}
521
509
522
510
// Attempt to resolve `path` to a dart file.
@@ -783,9 +771,9 @@ class WebDevFS implements DevFS {
783
771
webAssetServer.webRenderer = WebRendererMode .canvaskit;
784
772
}
785
773
if (hostname == 'any' ) {
786
- _baseUri = Uri .http ('localhost:$selectedPort ' , webAssetServer.basePath! );
774
+ _baseUri = Uri .http ('localhost:$selectedPort ' , webAssetServer.basePath);
787
775
} else {
788
- _baseUri = Uri .http ('$hostname :$selectedPort ' , webAssetServer.basePath! );
776
+ _baseUri = Uri .http ('$hostname :$selectedPort ' , webAssetServer.basePath);
789
777
}
790
778
return _baseUri! ;
791
779
}
@@ -977,12 +965,11 @@ class ReleaseAssetServer {
977
965
final FileSystemUtils _fileSystemUtils;
978
966
final Platform _platform;
979
967
980
- @visibleForTesting
981
-
982
968
/// The base path to serve from.
983
969
///
984
970
/// It should have no leading or trailing slashes.
985
- final String ? basePath;
971
+ @visibleForTesting
972
+ final String basePath;
986
973
987
974
// Locations where source files, assets, or source maps may be located.
988
975
List <Uri > _searchPaths () => < Uri > [
@@ -1070,67 +1057,21 @@ Future<Directory> _loadDwdsDirectory(
1070
1057
return fileSystem.directory (packageConfig['dwds' ]! .packageUriRoot);
1071
1058
}
1072
1059
1073
- String ? _stripBasePath (String path, String ? basePath) {
1074
- path = _stripLeadingSlashes (path);
1075
- if (basePath != null && path.startsWith (basePath)) {
1060
+ String ? _stripBasePath (String path, String basePath) {
1061
+ path = stripLeadingSlash (path);
1062
+ if (path.startsWith (basePath)) {
1076
1063
path = path.substring (basePath.length);
1077
1064
} else {
1078
1065
// The given path isn't under base path, return null to indicate that.
1079
1066
return null ;
1080
1067
}
1081
- return _stripLeadingSlashes (path);
1082
- }
1083
-
1084
- String _stripLeadingSlashes (String path) {
1085
- while (path.startsWith ('/' )) {
1086
- path = path.substring (1 );
1087
- }
1088
- return path;
1089
- }
1090
-
1091
- String _stripTrailingSlashes (String path) {
1092
- while (path.endsWith ('/' )) {
1093
- path = path.substring (0 , path.length - 1 );
1094
- }
1095
- return path;
1068
+ return stripLeadingSlash (path);
1096
1069
}
1097
1070
1098
- String ? _parseBasePathFromIndexHtml (File indexHtml) {
1071
+ IndexHtml _getIndexHtml () {
1072
+ final File indexHtml =
1073
+ globals.fs.currentDirectory.childDirectory ('web' ).childFile ('index.html' );
1099
1074
final String htmlContent =
1100
1075
indexHtml.existsSync () ? indexHtml.readAsStringSync () : _kDefaultIndex;
1101
- final Document document = parse (htmlContent);
1102
- final Element ? baseElement = document.querySelector ('base' );
1103
- String ? baseHref =
1104
- baseElement? .attributes == null ? null : baseElement! .attributes['href' ];
1105
-
1106
- if (baseHref == null || baseHref == kBaseHrefPlaceholder) {
1107
- baseHref = '' ;
1108
- } else if (! baseHref.startsWith ('/' )) {
1109
- throw ToolExit (
1110
- 'Error: The base href in "web/index.html" must be absolute (i.e. start '
1111
- 'with a "/"), but found: `${baseElement !.outerHtml }`.\n '
1112
- '$basePathExample ' ,
1113
- );
1114
- } else if (! baseHref.endsWith ('/' )) {
1115
- throw ToolExit (
1116
- 'Error: The base href in "web/index.html" must end with a "/", but found: `${baseElement !.outerHtml }`.\n '
1117
- '$basePathExample ' ,
1118
- );
1119
- } else {
1120
- baseHref = _stripLeadingSlashes (_stripTrailingSlashes (baseHref));
1121
- }
1122
-
1123
- return baseHref;
1076
+ return IndexHtml (htmlContent);
1124
1077
}
1125
-
1126
- const String basePathExample = '''
1127
- For example, to serve from the root use:
1128
-
1129
- <base href="/">
1130
-
1131
- To serve from a subpath "foo" (i.e. http://localhost:8080/foo/ instead of http://localhost:8080/) use:
1132
-
1133
- <base href="/foo/">
1134
-
1135
- For more information, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
1136
- ''' ;
0 commit comments