1010using  Microsoft . AspNetCore . Http ; 
1111using  Microsoft . Extensions . DependencyInjection ; 
1212using  Microsoft . Extensions . FileProviders ; 
13+ using  Microsoft . Extensions . FileProviders . Physical ; 
1314using  Microsoft . Extensions . Hosting ; 
1415using  Microsoft . Extensions . Logging ; 
16+ using  Microsoft . Extensions . Primitives ; 
1517using  Westwind . AspNetCore . LiveReload ; 
18+ using  IFileInfo  =  Microsoft . Extensions . FileProviders . IFileInfo ; 
1619
1720namespace  Documentation . Builder . Http ; 
1821
1922public  class  DocumentationWebHost 
2023{ 
2124	private  readonly  WebApplication  _webApplication ; 
2225
23- 	private  readonly  string  _staticFilesDirectory  = 
24- 		Path . Combine ( Paths . Root . FullName ,  "docs" ,  "source" ,  "_static" ) ; 
26+ 	private  readonly  string  _staticFilesDirectory ; 
2527
2628	public  DocumentationWebHost ( string ?  path ,  ILoggerFactory  logger ,  IFileSystem  fileSystem ) 
2729	{ 
@@ -40,6 +42,15 @@ public DocumentationWebHost(string? path, ILoggerFactory logger, IFileSystem fil
4042		builder . Services . AddSingleton ( logger ) ; 
4143		builder . Logging . SetMinimumLevel ( LogLevel . Warning ) ; 
4244
45+ 		_staticFilesDirectory  =  Path . Combine ( context . SourcePath . FullName ,  "_static" ) ; 
46+ 		#if DEBUG 
47+ 		// this attempts to serve files directly from their source rather than the embedded resourses during development. 
48+ 		// this allows us to change js/css files without restarting the webserver 
49+ 		var  solutionRoot  =  Paths . GetSolutionDirectory ( ) ; 
50+ 		if  ( solutionRoot  !=  null ) 
51+ 			_staticFilesDirectory  =  Path . Combine ( solutionRoot . FullName ,  "src" ,  "Elastic.Markdown" ,  "_static" ) ; 
52+ 		#endif
53+ 
4354		_webApplication  =  builder . Build ( ) ; 
4455		SetUpRoutes ( ) ; 
4556	} 
@@ -52,7 +63,7 @@ private void SetUpRoutes()
5263		_webApplication . UseLiveReload ( ) ; 
5364		_webApplication . UseStaticFiles ( new  StaticFileOptions 
5465		{ 
55- 			FileProvider  =  new  PhysicalFileProvider ( _staticFilesDirectory ) , 
66+ 			FileProvider  =  new  EmbeddedOrPhysicalFileProvider ( _staticFilesDirectory ) , 
5667			RequestPath  =  "/_static" 
5768		} ) ; 
5869		_webApplication . UseRouting ( ) ; 
@@ -86,3 +97,40 @@ private static async Task<IResult> ServeDocumentationFile(ReloadableGeneratorSta
8697		} 
8798	} 
8899} 
100+ 
101+ 
102+ public  class  EmbeddedOrPhysicalFileProvider  :  IFileProvider 
103+ { 
104+ 	private  readonly  EmbeddedFileProvider  _embeddedProvider ; 
105+ 	private  readonly  PhysicalFileProvider  _fileProvider ; 
106+ 
107+ 	public  EmbeddedOrPhysicalFileProvider ( string  root ) 
108+ 	{ 
109+ 		_embeddedProvider  =  new  EmbeddedFileProvider ( typeof ( BuildContext ) . Assembly ,  "Elastic.Markdown._static" ) ; 
110+ 		_fileProvider  =  new  PhysicalFileProvider ( root ) ; 
111+ 	} 
112+ 
113+ 	public  IDirectoryContents  GetDirectoryContents ( string  subpath ) 
114+ 	{ 
115+ 		var  contents  =  _fileProvider . GetDirectoryContents ( subpath ) ; 
116+ 		if  ( ! contents . Exists ) 
117+ 			contents  =  _embeddedProvider . GetDirectoryContents ( subpath ) ; 
118+ 		return  contents ; 
119+ 	} 
120+ 
121+ 	public  IFileInfo  GetFileInfo ( string  subpath ) 
122+ 	{ 
123+ 		var  fileInfo  =  _fileProvider . GetFileInfo ( subpath . Replace ( "/_static" ,  "" ) ) ; 
124+ 		if  ( ! fileInfo . Exists ) 
125+ 			fileInfo  =  _embeddedProvider . GetFileInfo ( subpath ) ; 
126+ 		return  fileInfo ; 
127+ 	} 
128+ 
129+ 	public  IChangeToken  Watch ( string  filter ) 
130+ 	{ 
131+ 		var  changeToken  =  _fileProvider . Watch ( filter ) ; 
132+ 		if  ( changeToken  is  NullChangeToken ) 
133+ 			changeToken  =  _embeddedProvider . Watch ( filter ) ; 
134+ 		return  changeToken ; 
135+ 	} 
136+ } 
0 commit comments