1818import java .io .IOException ;
1919import java .io .InputStream ;
2020import java .io .UncheckedIOException ;
21+ import java .util .Optional ;
2122import java .util .regex .Pattern ;
2223
2324import org .jsoup .nodes .Document ;
2425import org .jsoup .nodes .Element ;
2526import org .slf4j .Logger ;
2627import org .slf4j .LoggerFactory ;
28+ import org .slf4j .event .Level ;
2729
2830import com .vaadin .flow .server .ServiceInitEvent ;
31+ import com .vaadin .flow .server .VaadinRequest ;
2932import com .vaadin .flow .server .VaadinServiceInitListener ;
3033import com .vaadin .flow .server .communication .IndexHtmlRequestListener ;
3134
@@ -36,7 +39,8 @@ public class XHRReloadVaadinServiceInitListener implements VaadinServiceInitList
3639{
3740 private static final Logger LOG = LoggerFactory .getLogger (XHRReloadVaadinServiceInitListener .class );
3841
39- protected final String scriptContents ;
42+ protected final Element scriptElement ;
43+ protected boolean scriptAttachErrorAlreadyLogged ;
4044
4145 public XHRReloadVaadinServiceInitListener (final XHRReloadConfig config )
4246 {
@@ -48,11 +52,21 @@ public XHRReloadVaadinServiceInitListener(final XHRReloadConfig config)
4852 }
4953
5054 // Remove comments
51- this . scriptContents = Pattern .compile (
55+ final String scriptContents = Pattern .compile (
5256 "\\ /\\ *[\\ s\\ S]*?\\ *\\ /|(?<=[^:])\\ /\\ /.*|^\\ /\\ /.*" )
5357 .matcher (new String (is .readAllBytes ()))
5458 .replaceAll ("" )
5559 .trim ();
60+
61+ if (scriptContents .isBlank ())
62+ {
63+ LOG .error ("Script loaded from {} is empty" , config .getResourceLocation ());
64+ }
65+
66+ this .scriptElement = new Element ("script" )
67+ .attr ("type" , "text/javascript" )
68+ .html (scriptContents );
69+ LOG .trace ("Built scriptElement: {}" , this .scriptElement );
5670 }
5771 catch (final IOException e )
5872 {
@@ -65,11 +79,32 @@ public void serviceInit(final ServiceInitEvent event)
6579 {
6680 event .addIndexHtmlRequestListener ((IndexHtmlRequestListener )resp -> {
6781 final Document document = resp .getDocument ();
68-
6982 final Element body = document .body ();
70- body .prependElement ("script" )
71- .attr ("type" , "text/javascript" )
72- .html (this .scriptContents );
83+
84+ try
85+ {
86+ body .prependChild (this .scriptElement .clone ());
87+ }
88+ catch (final Exception ex )
89+ {
90+ LOG .atLevel (this .scriptAttachErrorAlreadyLogged
91+ ? Level .DEBUG
92+ : Level .WARN )
93+ .setMessage (
94+ "Failed to attach XHRReloadScript. {}"
95+ + "Details: path={} body={}" )
96+ .addArgument (!this .scriptAttachErrorAlreadyLogged
97+ ? "Subsequent errors will be logged at DEBUG. "
98+ : "" )
99+ .addArgument (() ->
100+ Optional .ofNullable (resp .getVaadinRequest ())
101+ .map (VaadinRequest ::getPathInfo )
102+ .orElse ("?" ))
103+ .addArgument (body )
104+ .addArgument (ex )
105+ .log ();
106+ this .scriptAttachErrorAlreadyLogged = true ;
107+ }
73108 });
74109
75110 LOG .debug ("Applied serviceInit" );
0 commit comments