@@ -47,7 +47,7 @@ const TEMPLATE_FUNCTIONS: Context["fn"] = {
4747 } ,
4848}
4949
50- interface StaticBuildOptions {
50+ export interface StaticBuildOptions {
5151 /** Specify an input folder containing website source files */
5252 inputDirectory : string
5353 /** Specify an output folder for the website to be built to */
@@ -326,9 +326,19 @@ function collectAssetsFromDocument(
326326 // if this is done! ~600ms to ~130ms!
327327 for ( const element of document . querySelectorAll ( "*" ) ) {
328328 for ( const [ name , value ] of Object . entries ( element . attributes ) ) {
329- if ( ! value ) continue
330- if ( ! value . includes ( "/" ) ) continue
331- if ( ! value . startsWith ( inputDirectory ) ) continue
329+ if ( ! value ) {
330+ logger ?. info ( `Skipping "${ name } " attribute on <${ element . tagName . toLowerCase ( ) } >, value is empty or non-existent` )
331+ continue
332+ }
333+
334+ if ( ! value . includes ( "/" ) ) {
335+ logger ?. info ( `Skipping "${ name } " attribute on <${ element . tagName . toLowerCase ( ) } >, value does not contain \"/\"` )
336+ continue
337+ }
338+
339+ if ( ! value . startsWith ( inputDirectory ) ) {
340+ logger ?. info ( `Skipping "${ name } " attribute on <${ element . tagName . toLowerCase ( ) } >, value does not start with input directory path` )
341+ }
332342
333343 const absoluteInputPath = value
334344
@@ -338,7 +348,7 @@ function collectAssetsFromDocument(
338348 }
339349
340350 if ( fs . statSync ( absoluteInputPath ) . isDirectory ( ) ) {
341- logger ?. error ( `Skipping asset, it's a directory: ${ absoluteInputPath } ` )
351+ logger ?. error ( `Skipping asset, path is a directory: ${ absoluteInputPath } ` )
342352 continue
343353 }
344354
@@ -474,7 +484,7 @@ function renderHTMLPage(
474484
475485 if ( options . watch ) {
476486 preTemplateDocument . append (
477- `<sb:include src="./node_modules/@anthonyec/staticbuild/dist/partials/reloader .html" port="${ reloader . getPort ( ) } " />` ,
487+ `<sb:include src="./node_modules/@anthonyec/staticbuild/dist/partials/_reloader .html" port="${ reloader . getPort ( ) } " />` ,
478488 )
479489 }
480490
@@ -525,48 +535,48 @@ function renderHTMLPage(
525535 let document = parseHTML ( html )
526536 resolveAttributesToAbsoluteInputPaths ( currentDirectory , document )
527537
528- // Import all the include tags recursively.
529- const includeStack = Array . from ( document . querySelectorAll ( "sb\\:include" ) )
538+ // Resolve and inline all `<sb:include>` tags.
539+ //
540+ // This iteratively finds the first include element and replaces it with it's
541+ // rendered contents. This continues until no include elements are found. Nested
542+ // includes are handled naturally as newly inserted content is re-scanned.
543+ let currentIncludeElement = document . querySelector ( "sb\\:include" )
544+
545+ while ( currentIncludeElement ) {
546+ const src = currentIncludeElement . getAttribute ( "src" )
530547
531- while ( includeStack . length ) {
532- const element = includeStack . pop ( )
533- if ( ! element ) break
534-
535- const src = element . getAttribute ( "src" )
536-
537548 if ( ! src ) {
538- element . remove ( )
539- continue
549+ currentIncludeElement . remove ( )
550+ break
540551 }
541-
552+
542553 if ( ! path . basename ( src ) . startsWith ( "_" ) ) {
543554 options . logger ?. error ( `Included filenames must start with an underscore: ${ path . basename ( src ) } ` )
544- element . remove ( )
545- continue
555+ currentIncludeElement . remove ( )
556+ break
546557 }
547-
558+
548559 if ( ! fs . existsSync ( src ) ) {
549560 options . logger ?. error ( `Could not find include: ${ src } ` )
550- element . remove ( )
551- continue
561+ currentIncludeElement . remove ( )
562+ break
552563 }
553-
564+
554565 const includeContents = fs . readFileSync ( src , "utf8" )
555566 const includeDocument = parseHTML ( includeContents )
556567 resolveAttributesToAbsoluteInputPaths ( path . dirname ( src ) , includeDocument )
557-
568+
558569 const includeHtml = Mustache . render ( includeDocument . toString ( ) , {
559570 ...context ,
560571 attributes : {
561- ...element . attributes ,
562- uid : hash ( src + includeStack . length ) ,
563- children : element . innerHTML ,
572+ ...currentIncludeElement . attributes ,
573+ children : currentIncludeElement . innerHTML ,
564574 } ,
565575 } )
566-
567- element . replaceWith ( includeHtml )
568- includeStack . push ( ... Array . from ( document . querySelectorAll ( "sb\\:include" ) ) )
569-
576+
577+ currentIncludeElement . replaceWith ( includeHtml )
578+ currentIncludeElement = document . querySelector ( "sb\\:include" )
579+
570580 dependencies . add ( src )
571581 }
572582
0 commit comments